Retry only for https protocol
[elinks.git] / src / util / string.h
blob509453da02622abc03adff6b693482e6841766b8
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 /** @name Autoallocation string constructors:
20 * Note that, contrary to the utilities using the string struct, these
21 * functions are NOT granular, thus you can't simply reuse strings allocated by
22 * these in add_to_string()-style functions.
23 * @{ */
25 /** Allocates NUL terminated string with @a len bytes from @a src.
26 * If @a src == NULL or @a 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(const unsigned char *src, int len);
30 /** Allocated NUL terminated string with the content of @a src. */
31 unsigned char *stracpy(const unsigned char *src);
33 /** @} */
35 #else /* DEBUG_MEMLEAK */
37 unsigned char *debug_memacpy(const unsigned char *, int, const unsigned char *, int);
38 #define memacpy(s, l) debug_memacpy(__FILE__, __LINE__, s, l)
40 unsigned char *debug_stracpy(const unsigned char *, int, const unsigned char *);
41 #define stracpy(s) debug_stracpy(__FILE__, __LINE__, s)
43 #endif /* DEBUG_MEMLEAK */
46 /** Concatenates @a src to @a str.
47 * If reallocation of @a str fails @a str is not touched. */
48 void add_to_strn(unsigned char **str, const unsigned char *src);
50 /** Inserts @a seqlen chars from @a seq at position @a pos in the @a
51 * dst string.
52 * If reallocation of @a dst fails it is not touched and NULL is returned. */
53 unsigned char *insert_in_string(unsigned char **dst, int pos,
54 const unsigned char *seq, int seqlen);
56 /** Takes a list of strings where the last parameter _must_ be
57 * (unsigned char *) NULL and concatenates them.
59 * @returns the allocated string or NULL on allocation failure.
61 * Example: @code
62 * unsigned char *abc = straconcat("A", "B", "C", (unsigned char *) NULL);
63 * if (abc) return;
64 * printf("%s", abc); -> print "ABC"
65 * mem_free(abc); -> free memory used by @abc
66 * @endcode */
67 unsigned char *straconcat(const unsigned char *str, ...);
70 /** @name Misc. utility string functions.
71 * @{ */
73 /** Compare two strings, handling correctly @a s1 or @a s2 being NULL. */
74 int xstrcmp(const unsigned char *s1, const unsigned char *s2);
76 /** Copies at most @a len chars into @a dst. Ensures null termination of @a dst. */
77 unsigned char *safe_strncpy(unsigned char *dst, const unsigned char *src, size_t len);
79 /* strlcmp() is the middle child of history, everyone is using it differently.
80 * On some weird *systems* it seems to be defined (equivalent to strcasecmp()),
81 * so we'll better use our #define redir. */
83 /** This routine compares string @a s1 of length @a n1 with string @a s2
84 * of length @a n2.
86 * This acts identically to strcmp() but for non-zero-terminated strings,
87 * rather than being similiar to strncmp(). That means, it fails if @a n1
88 * != @a n2, thus you may use it for testing whether @a s2 matches *full*
89 * @a s1, not only its start (which can be a security hole, e.g. in the
90 * cookies domain checking).
92 * @a n1 or @a n2 may be -1, which is same as strlen(@a s1 or @a s2) but
93 * possibly more effective (in the future ;-).
95 * @returns zero if the strings match or undefined non-zero value if they
96 * differ. (The non-zero return value is _not_ same as for the standard
97 * strcmp() family.) */
98 #define strlcmp(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcmp(a,b,c,d))
99 int elinks_strlcmp(const unsigned char *s1, size_t n1,
100 const unsigned char *s2, size_t n2);
102 /** Acts identically to strlcmp(), except for being case insensitive. */
103 #define strlcasecmp(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcasecmp(a,b,c,d,0))
104 #define c_strlcasecmp(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcasecmp(a,b,c,d,1))
105 int elinks_strlcasecmp(const unsigned char *s1, size_t n1,
106 const unsigned char *s2, size_t n2,
107 const int locale_indep);
109 #define strlcasestr(a,b,c,d) (errfile = __FILE__, errline = __LINE__, elinks_strlcasestr(a,b,c,d))
110 char *elinks_strlcasestr(const char *haystack, const int haystackl,
111 const char *needle, const int needlel);
113 /* strcasecmp and strncasecmp which work as if they are
114 * in the C locale */
115 int c_strcasecmp(const char *s1, const char *s2);
116 int c_strncasecmp(const char *s1, const char *s2, size_t n);
118 /* strcasestr function which works as if it is in the C locale. */
119 char * c_strcasestr(const char *haystack, const char *needle);
121 /** @} */
124 #define skip_space(S) \
125 do { while (isspace(*(S))) (S)++; } while (0)
127 #define skip_nonspace(S) \
128 do { while (*(S) && !isspace(*(S))) (S)++; } while (0)
130 #undef isdigit
131 #define isdigit(c) ((c) >= '0' && (c) <= '9')
132 #define isquote(c) ((c) == '"' || (c) == '\'')
133 #define isasciialpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
134 #define isasciialnum(c) (isasciialpha(c) || isdigit(c))
135 #define isident(c) (isasciialnum(c) || (c) == '_' || (c) == '-')
137 /** Char is safe to write to the terminal screen. Cannot test for C1
138 * control characters (0x80 to 0x9F) because this is also used for
139 * non-ISO-8859 charsets. */
140 #define isscreensafe(c) ((c) >= ' ' && (c) != ASCII_DEL)
142 /** Like isscreensafe() but takes Unicode values and so can check for C1. */
143 #define isscreensafe_ucs(c) (((c) >= 0x20 && (c) <= 0x7E) || (c) >= 0xA0)
146 /** String debugging using magic number, it may catch some errors. */
147 #ifdef CONFIG_DEBUG
148 #define DEBUG_STRING
149 #endif
151 struct string {
152 #ifdef DEBUG_STRING
153 int magic;
154 #endif
155 unsigned char *source;
156 int length;
160 /** The granularity used for the struct string based utilities. */
161 #define STRING_GRANULARITY 0xFF
163 #ifdef DEBUG_STRING
164 #define STRING_MAGIC 0x2E5BF271
165 #define check_string_magic(x) assertm((x)->magic == STRING_MAGIC, "String magic check failed.")
166 #define set_string_magic(x) do { (x)->magic = STRING_MAGIC; } while (0)
167 #define NULL_STRING { STRING_MAGIC, NULL, 0 }
168 #define INIT_STRING(s, l) { STRING_MAGIC, s, l }
169 #else
170 #define check_string_magic(x)
171 #define set_string_magic(x)
172 #define NULL_STRING { NULL, 0 }
173 #define INIT_STRING(s, l) { s, l }
174 #endif
176 /** Initializes the passed string struct by preallocating the
177 * string.source member.
178 * @returns @a string if successful, or NULL if out of memory.
179 * @post done_string(@a string) is safe, even if this returned NULL.
180 * @relates string */
181 #ifdef DEBUG_MEMLEAK
182 struct string *init_string__(const unsigned char *file, int line, struct string *string);
183 #define init_string(string) init_string__(__FILE__, __LINE__, string)
184 #else
185 struct string *init_string(struct string *string);
186 #endif
188 /** Resets @a string and free()s the string.source member.
189 * @relates string */
190 void done_string(struct string *string);
193 struct string *add_to_string(struct string *string,
194 const unsigned char *source);
195 struct string *add_char_to_string(struct string *string, unsigned char character);
196 struct string *add_string_to_string(struct string *to, const struct string *from);
197 struct string *add_file_to_string(struct string *string, const unsigned char *filename);
198 struct string *add_crlf_to_string(struct string *string);
200 /** Adds each C string to @a string until a terminating
201 * (unsigned char *) NULL is met.
202 * @relates string */
203 struct string *string_concat(struct string *string, ...);
205 /** Extends the string with @a times number of @a character.
206 * @relates string */
207 struct string *add_xchar_to_string(struct string *string, unsigned char character, int times);
209 /** Add printf()-style format string to @a string.
210 * @relates string */
211 struct string *add_format_to_string(struct string *string, const unsigned char *format, ...);
213 /** Get a regular newly allocated stream of bytes from @a string.
214 * @relates string */
215 static unsigned char *squeezastring(struct string *string);
218 static inline unsigned char *
219 squeezastring(struct string *string)
221 return memacpy(string->source, string->length);
225 #undef realloc_string
227 #define realloc_string(str, size) \
228 mem_align_alloc(&(str)->source, (str)->length, (size) + 1, \
229 STRING_GRANULARITY)
231 #ifdef DEBUG_MEMLEAK
233 #define add_bytes_to_string(string, bytes, length) \
234 add_bytes_to_string__(__FILE__, __LINE__, string, bytes, length)
236 #define debug_realloc_string(str, size) \
237 mem_align_alloc__(file, line, (void **) &(str)->source, (str)->length, (size) + 1, \
238 sizeof(unsigned char), STRING_GRANULARITY)
240 #else
242 #define add_bytes_to_string(string, bytes, length) \
243 add_bytes_to_string__(string, bytes, length)
245 #define debug_realloc_string(str, size) realloc_string(str, size)
247 #endif
249 static inline struct string *
250 add_bytes_to_string__(
251 #ifdef DEBUG_MEMLEAK
252 const unsigned char *file, int line,
253 #endif
254 struct string *string, const unsigned char *bytes,
255 int length)
257 int newlength;
259 assertm(string && bytes && length >= 0, "[add_bytes_to_string]");
260 if_assert_failed { return NULL; }
262 check_string_magic(string);
264 if (length == 0) return string;
266 newlength = string->length + length;
267 if (!debug_realloc_string(string, newlength))
268 return NULL;
270 memcpy(string->source + string->length, bytes, length);
271 string->source[newlength] = 0;
272 string->length = newlength;
274 return string;
278 struct string_list_item {
279 LIST_HEAD(struct string_list_item);
281 struct string string;
284 /** Adds @a string with @a length chars to the list. If @a length is -1
285 * it will be set to the return value of strlen().
286 * @relates string_list_item */
287 struct string *
288 add_to_string_list(LIST_OF(struct string_list_item) *list,
289 const unsigned char *string, int length);
291 void free_string_list(LIST_OF(struct string_list_item) *list);
294 /** Returns an empty C string or @a str if different from NULL. */
295 #define empty_string_or_(str) ((str) ? (unsigned char *) (str) : (unsigned char *) "")
297 /** Allocated copy if not NULL or returns NULL. */
298 #define null_or_stracpy(str) ((str) ? stracpy(str) : NULL)
300 #endif /* EL__UTIL_STRING_H */