Python: Give goto_url_hook only one argument, like follow_url_hook.
[elinks.git] / src / util / string.h
blob4e04bac6f58c3de85783cabf13de2b430f9ce331
1 #ifndef EL__UTIL_STRING_H
2 #define EL__UTIL_STRING_H
4 /* To these two functions, same remark applies as to copy_string() or
5 * straconcat(). */
7 #include <ctype.h>
8 #include <string.h>
10 #include "osdep/ascii.h"
11 #include "util/error.h"
12 #include "util/lists.h"
13 #include "util/memdebug.h"
14 #include "util/memory.h"
17 #ifndef DEBUG_MEMLEAK
19 /* Autoallocation string constructors: */
21 /* Note that, contrary to the utilities using the string struct, these
22 * functions are NOT granular, thus you can't simply reuse strings allocated by
23 * these in add_to_string()-style functions. */
25 /* Allocates NUL terminated string with @len bytes from @src.
26 * If @src == NULL or @len < 0 only one byte is allocated and set it to 0. */
27 /* Returns the string or NULL on allocation failure. */
28 unsigned char *memacpy(unsigned char *src, int len);
30 /* Allocated NUL terminated string with the content of @src. */
31 unsigned char *stracpy(unsigned char *src);
33 #else /* DEBUG_MEMLEAK */
35 unsigned char *debug_memacpy(unsigned char *, int, unsigned char *, int);
36 #define memacpy(s, l) debug_memacpy(__FILE__, __LINE__, s, l)
38 unsigned char *debug_stracpy(unsigned char *, int, unsigned char *);
39 #define stracpy(s) debug_stracpy(__FILE__, __LINE__, s)
41 #endif /* DEBUG_MEMLEAK */
44 /* Concatenates @src to @str. */
45 /* If reallocation of @str fails @str is not touched. */
46 void add_to_strn(unsigned char **str, unsigned char *src);
48 /* Inserts @seqlen chars from @seq at position @pos in the @dst string. */
49 /* If reallocation of @dst fails it is not touched and NULL is returned. */
50 unsigned char *
51 insert_in_string(unsigned char **dst, int pos, unsigned char *seq, int seqlen);
53 /* Takes a list of strings where the last parameter _must_ be NULL and
54 * concatenates them. */
55 /* Returns the allocated string or NULL on allocation failure. */
56 /* Example:
57 * unsigned char *abc = straconcat("A", "B", "C", NULL);
58 * if (abc) return;
59 * printf("%s", abc); -> print "ABC"
60 * mem_free(abc); -> free memory used by @abc */
61 unsigned char *straconcat(unsigned char *str, ...);
64 /* Misc. utility string functions. */
66 /* Compare two strings, handling correctly @s1 or @s2 being NULL. */
67 int xstrcmp(unsigned char *s1, unsigned char *s2);
69 /* Copies at most @len chars into @dst. Ensures null termination of @dst. */
70 unsigned char *safe_strncpy(unsigned char *dst, const unsigned char *src, size_t len);
72 /* strlcmp() is the middle child of history, everyone is using it differently.
73 * On some weird *systems* it seems to be defined (equivalent to strcasecmp()),
74 * so we'll better use our #define redir. */
76 /* This routine compares string @s1 of length @n1 with string @s2 of length
77 * @n2.
79 * This acts identically to strcmp() but for non-zero-terminated strings,
80 * rather than being similiar to strncmp(). That means, it fails if @n1 != @n2,
81 * thus you may use it for testing whether @s2 matches *full* @s1, not only its
82 * start (which can be a security hole, ie. in the cookies domain checking).
84 * @n1 or @n2 may be -1, which is same as strlen(@s[12]) but possibly more
85 * effective (in the future ;-). */
86 /* Returns zero if the strings match or undefined non-zero value if they
87 * differ. (The non-zero return value is _not_ same as for the standard
88 * strcmp() family.) */
89 #define strlcmp(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcmp(a,b,c,d))
90 int elinks_strlcmp(const unsigned char *s1, size_t n1,
91 const unsigned char *s2, size_t n2);
93 /* Acts identically to strlcmp(), except for being case insensitive. */
94 #define strlcasecmp(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcasecmp(a,b,c,d))
95 int elinks_strlcasecmp(const unsigned char *s1, size_t n1,
96 const unsigned char *s2, size_t n2);
99 #define skip_space(S) \
100 do { while (isspace(*(S))) (S)++; } while (0)
102 #define skip_nonspace(S) \
103 do { while (*(S) && !isspace(*(S))) (S)++; } while (0)
105 #undef isdigit
106 #define isdigit(c) ((c) >= '0' && (c) <= '9')
107 #define isquote(c) ((c) == '"' || (c) == '\'')
108 #define isasciialpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
109 #define isasciialnum(c) (isasciialpha(c) || isdigit(c))
110 #define isident(c) (isasciialnum(c) || (c) == '_' || (c) == '-')
112 /* Char is safe to write to the terminal screen */
113 #define isscreensafe(c) ((c) >= ' ' && (c) != ASCII_DEL)
116 /* String debugging using magic number, it may catch some errors. */
117 #ifdef CONFIG_DEBUG
118 #define DEBUG_STRING
119 #endif
121 struct string {
122 #ifdef DEBUG_STRING
123 int magic;
124 #endif
125 unsigned char *source;
126 int length;
130 /* The granularity used for the struct string based utilities. */
131 #define STRING_GRANULARITY 0xFF
133 #ifdef DEBUG_STRING
134 #define STRING_MAGIC 0x2E5BF271
135 #define check_string_magic(x) assertm((x)->magic == STRING_MAGIC, "String magic check failed.")
136 #define set_string_magic(x) do { (x)->magic = STRING_MAGIC; } while (0)
137 #define NULL_STRING { STRING_MAGIC, NULL, 0 }
138 #define INIT_STRING(s, l) { STRING_MAGIC, s, l }
139 #else
140 #define check_string_magic(x)
141 #define set_string_magic(x)
142 #define NULL_STRING { NULL, 0 }
143 #define INIT_STRING(s, l) { s, l }
144 #endif
146 /* Initializes the passed string struct by preallocating the @source member. */
147 #ifdef DEBUG_MEMLEAK
148 struct string *init_string__(unsigned char *file, int line, struct string *string);
149 #define init_string(string) init_string__(__FILE__, __LINE__, string)
150 #else
151 struct string *init_string(struct string *string);
152 #endif
154 /* Resets @string and free()s the @source member. */
155 void done_string(struct string *string);
158 struct string *add_to_string(struct string *string,
159 const unsigned char *source);
160 struct string *add_char_to_string(struct string *string, unsigned char character);
161 struct string *add_string_to_string(struct string *to, struct string *from);
162 struct string *add_file_to_string(struct string *string, unsigned char *filename);
163 struct string *add_crlf_to_string(struct string *string);
165 /* Adds each C string to @string until a terminating NULL is met. */
166 struct string *string_concat(struct string *string, ...);
168 /* Extends the string with @times number of @character. */
169 struct string *add_xchar_to_string(struct string *string, unsigned char character, int times);
171 /* Add printf-style format string to @string. */
172 struct string *add_format_to_string(struct string *string, unsigned char *format, ...);
174 /* Get a regular newly allocated stream of bytes from @string. */
175 static unsigned char *squeezastring(struct string *string);
178 static inline unsigned char *
179 squeezastring(struct string *string)
181 return memacpy(string->source, string->length);
185 #undef realloc_string
187 #define realloc_string(str, size) \
188 mem_align_alloc(&(str)->source, (str)->length, (size) + 1, \
189 STRING_GRANULARITY)
191 #ifdef DEBUG_MEMLEAK
193 #define add_bytes_to_string(string, bytes, length) \
194 add_bytes_to_string__(__FILE__, __LINE__, string, bytes, length)
196 #define debug_realloc_string(str, size) \
197 mem_align_alloc__(file, line, (void **) &(str)->source, (str)->length, (size) + 1, \
198 sizeof(unsigned char), STRING_GRANULARITY)
200 #else
202 #define add_bytes_to_string(string, bytes, length) \
203 add_bytes_to_string__(string, bytes, length)
205 #define debug_realloc_string(str, size) realloc_string(str, size)
207 #endif
209 static inline struct string *
210 add_bytes_to_string__(
211 #ifdef DEBUG_MEMLEAK
212 unsigned char *file, int line,
213 #endif
214 struct string *string, const unsigned char *bytes,
215 int length)
217 int newlength;
219 assertm(string && bytes && length >= 0, "[add_bytes_to_string]");
220 if_assert_failed { return NULL; }
222 check_string_magic(string);
224 if (length == 0) return string;
226 newlength = string->length + length;
227 if (!debug_realloc_string(string, newlength))
228 return NULL;
230 memcpy(string->source + string->length, bytes, length);
231 string->source[newlength] = 0;
232 string->length = newlength;
234 return string;
238 struct string_list_item {
239 LIST_HEAD(struct string_list_item);
241 struct string string;
244 /* Adds @string with @length chars to the list. If length is -1 it will be set
245 * to the return value of strlen(). */
246 struct string *
247 add_to_string_list(struct list_head *list, const unsigned char *string,
248 int length);
250 void free_string_list(struct list_head *list);
253 /* Returns an empty C string or @str if different from NULL. */
254 #define empty_string_or_(str) ((str) ? (unsigned char *) (str) : (unsigned char *) "")
256 /* Allocated copy if not NULL or returns NULL. */
257 #define null_or_stracpy(str) ((str) ? stracpy(str) : NULL)
259 #endif /* EL__UTIL_STRING_H */