Add LID capability to oonf_layer2 and l2config subsystem
[oonf.git] / include / oonf / libcommon / string.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #ifndef COMMON_STRING_H_
47 #define COMMON_STRING_H_
48
49 #include <ctype.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <strings.h>
53
54 #include <oonf/oonf.h>
55
56 enum
57 {
58   /*! block size for allocated string arrays */
59   STRARRAY_BLOCKSIZE = 64
60 };
61
62 /**
63  * Macro to statically initialize a string array
64  * @param str string array representation
65  */
66 #define STRARRAY_INIT(str)                                                                                             \
67   { .value = (str), .length = sizeof(str) }
68
69 /**
70  * Represents a string or an array of strings
71  * The strings (including the zero byte) are just appended
72  * into a large binary buffer. The struct contains a pointer
73  * to the first string and the size of the binary buffer
74  *
75  * typically append operations are done by realloc() calls
76  * while remove operations are done with memmove
77  */
78 struct strarray {
79   /*! pointer to the first string */
80   char *value;
81
82   /*! total length of all strings including zero-bytes */
83   size_t length;
84 };
85
86 /**
87  * Constant value variant of strarray
88  */
89 struct const_strarray {
90   /*! pointer to the first string */
91   const char *value;
92
93   /*! total length of all strings including zero-bytes */
94   size_t length;
95 };
96
97 EXPORT char *strscpy(char *dest, const char *src, size_t size);
98 EXPORT char *strscat(char *dest, const char *src, size_t size);
99 EXPORT char *str_trim(char *ptr);
100 EXPORT const char *str_hasnextword(const char *buffer, const char *word);
101 EXPORT const char *str_cpynextword(char *dst, const char *buffer, size_t len);
102 EXPORT const char *str_skipnextword(const char *src);
103 EXPORT size_t str_countwords(const char *src);
104
105 EXPORT bool str_is_printable(const char *value);
106
107 EXPORT ssize_t strhex_from_bin(char *buffer, size_t buffer_len, const uint8_t *src, size_t srclen);
108 EXPORT ssize_t strhex_to_bin(uint8_t *buffer, size_t buffer_len, const char *src);
109
110 EXPORT int strarray_copy(struct strarray *dst, const struct strarray *src);
111 EXPORT int strarray_append(struct strarray *, const char *);
112 EXPORT int strarray_prepend(struct strarray *array, const char *string);
113 EXPORT void strarray_remove_ext(struct strarray *, char *, bool);
114
115 EXPORT char *strarray_get(const struct strarray *array, size_t idx);
116 EXPORT size_t strarray_get_count(const struct strarray *array);
117
118 EXPORT int strarray_cmp(const struct strarray *a1, const struct strarray *a2);
119
120 /**
121  * @param c character
122  * @return true if character is printable, false otherwise
123  */
124 static INLINE bool
125 str_char_is_printable(char c) {
126   unsigned char uc = (unsigned char)c;
127   return !(uc < 32 || uc == 127 || uc == 255);
128 }
129
130 /**
131  * @param string string
132  * @param pattern pattern that might be in the string
133  * @return true if string starts with the pattern, false otherwise
134  */
135 static INLINE bool
136 str_startswith(const char *string, const char *pattern) {
137   return strncmp(string, pattern, strlen(pattern)) == 0;
138 }
139
140 /**
141  * This function tests if a string starts with a pattern,
142  * ignoring upper/lowercase
143  * @param string string
144  * @param pattern pattern that might be in the string
145  * @return true if string starts with the pattern, false otherwise
146  */
147 static INLINE bool
148 str_startswith_nocase(const char *string, const char *pattern) {
149   return strncasecmp(string, pattern, strlen(pattern)) == 0;
150 }
151
152 /**
153  * @param string string
154  * @param pattern pattern that might be in the string
155  * @return true if string ends with the pattern, false otherwise
156  */
157 static INLINE bool
158 str_endswith(const char *string, const char *pattern) {
159   size_t s_len, p_len;
160
161   s_len = strlen(string);
162   p_len = strlen(pattern);
163
164   return s_len > p_len && strcmp(&string[s_len - p_len], pattern) == 0;
165 }
166
167 /**
168  * This function tests if a string ends with a pattern,
169  * ignoring upper/lowercase
170  * @param string string
171  * @param pattern pattern that might be in the string
172  * @return true if string ends with the pattern, false otherwise
173  */
174 static INLINE bool
175 str_endswith_nocase(const char *string, const char *pattern) {
176   size_t s_len, p_len;
177
178   s_len = strlen(string);
179   p_len = strlen(pattern);
180
181   return s_len > p_len && strcasecmp(&string[s_len - p_len], pattern) == 0;
182 }
183
184 /**
185  * Copy a constant string array into a second array
186  * @param dst target array
187  * @param src constant source array
188  * @return 0 if array was copied, -1 if an error happened
189  */
190 static INLINE int
191 strarray_copy_c(struct strarray *dst, const struct const_strarray *src) {
192   return strarray_copy(dst, (const struct strarray *)src);
193 }
194
195 /**
196  * Get a string of an string array
197  * @param array source array
198  * @param idx index of string to be extracted
199  * @return string at the specified index, NULL if not found
200  */
201 static INLINE const char *
202 strarray_get_c(const struct const_strarray *array, size_t idx) {
203   return strarray_get((const struct strarray *)array, idx);
204 }
205
206 /**
207  * @param array constant string array
208  * @return number of strings in string array
209  */
210 static INLINE size_t
211 strarray_get_count_c(const struct const_strarray *array) {
212   return strarray_get_count((const struct strarray *)array);
213 }
214
215 /**
216  * Initialize string array object
217  * @param array pointer to string array object
218  */
219 static INLINE void
220 strarray_init(struct strarray *array) {
221   memset(array, 0, sizeof(*array));
222 }
223
224 /**
225  * Free memory of string array object
226  * @param array pointer to string array object
227  */
228 static INLINE void
229 strarray_free(struct strarray *array) {
230   free(array->value);
231   strarray_init(array);
232 }
233
234 /**
235  * @param array pointer to string array object
236  * @return true if the array is empty, false otherwise
237  */
238 static INLINE bool
239 strarray_is_empty(const struct strarray *array) {
240   return array->value == NULL;
241 }
242
243 /**
244  * @param array pointer to constant string array object
245  * @return true if the array is empty, false otherwise
246  */
247 static INLINE bool
248 strarray_is_empty_c(const struct const_strarray *array) {
249   return array->value == NULL;
250 }
251
252 /**
253  * Remove an element from a string array
254  * @param array pointer to string array object
255  * @param element an element to be removed from the array
256  */
257 static INLINE void
258 strarray_remove(struct strarray *array, char *element) {
259   strarray_remove_ext(array, element, true);
260 }
261
262 /**
263  * @param array pointer to strarray object
264  * @return pointer to first string of string array
265  */
266 static INLINE char *
267 strarray_get_first(const struct strarray *array) {
268   return array->value;
269 }
270
271 /**
272  * @param array pointer to constant strarray object
273  * @return pointer to first string of string array
274  */
275 static INLINE const char *
276 strarray_get_first_c(const struct const_strarray *array) {
277   return array->value;
278 }
279
280 /**
281  * Do not call this function for the last string in
282  * a string array.
283  * @param current pointer to a string in array
284  * @return pointer to next string in string array
285  */
286 static INLINE char *
287 strarray_get_next(char *current) {
288   return current + strlen(current) + 1;
289 }
290
291 /**
292  * Do not call this function for the last string in
293  * a string array.
294  * @param current pointer to a string in constant array
295  * @return pointer to next string in string array
296  */
297 static INLINE const char *
298 strarray_get_next_c(const char *current) {
299   return current + strlen(current) + 1;
300 }
301
302 /**
303  * @param array pointer to strarray object
304  * @param current pointer to a string in array
305  * @return pointer to next string in string array,
306  *   NULL if there is no further string
307  */
308 static INLINE char *
309 strarray_get_next_safe(const struct strarray *array, char *current) {
310   char *next;
311
312   next = current + strlen(current) + 1;
313   if (next > array->value + array->length) {
314     return NULL;
315   }
316   return next;
317 }
318
319 /**
320  * @param array pointer to constant strarray object
321  * @param current pointer to a string in array
322  * @return pointer to next string in string array,
323  *   NULL if there is no further string
324  */
325 static INLINE const char *
326 strarray_get_next_safe_c(const struct const_strarray *array, const char *current) {
327   const char *next;
328
329   next = current + strlen(current) + 1;
330   if (next > array->value + array->length) {
331     return NULL;
332   }
333   return next;
334 }
335
336 /**
337  * Compare two constant stringarrays
338  * @param a1 pointer to array 1
339  * @param a2 pointer to array 2
340  * @return <0 if a1 is 'smaller' than a2, >0 if a1 is 'larger' than a2,
341  *   0 if both are the same.
342  */
343 static INLINE int
344 strarray_cmp_c(const struct const_strarray *a1, const struct const_strarray *a2) {
345   return strarray_cmp((const struct strarray *)a1, (const struct strarray *)a2);
346 }
347
348 /**
349  * Loop over an array of strings. This loop should not be used if elements are
350  * removed from the array during the loop.
351  *
352  * @param array pointer to strarray object
353  * @param charptr pointer to loop variable
354  */
355 #define strarray_for_each_element(array, charptr)                                                                      \
356   for (charptr = (array)->value; charptr != NULL && (size_t)charptr < (size_t)(array)->value + (array)->length;        \
357        charptr += strlen(charptr) + 1)
358
359 #endif