![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
strings.h
Go to the documentation of this file.
00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 1999 - 2006, Digium, Inc. 00005 * 00006 * Mark Spencer <markster@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 /*! \file 00020 * \brief String manipulation functions 00021 */ 00022 00023 #ifndef _ASTERISK_STRINGS_H 00024 #define _ASTERISK_STRINGS_H 00025 00026 #include <string.h> 00027 #include <stdarg.h> 00028 00029 #include "asterisk/inline_api.h" 00030 #include "asterisk/compiler.h" 00031 #include "asterisk/compat.h" 00032 #include "asterisk/utils.h" 00033 #include "asterisk/threadstorage.h" 00034 00035 /* You may see casts in this header that may seem useless but they ensure this file is C++ clean */ 00036 00037 static force_inline int ast_strlen_zero(const char *s) 00038 { 00039 return (!s || (*s == '\0')); 00040 } 00041 00042 /*! \brief returns the equivalent of logic or for strings: 00043 * first one if not empty, otherwise second one. 00044 */ 00045 #define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b)) 00046 00047 /*! 00048 \brief Gets a pointer to the first non-whitespace character in a string. 00049 \param ast_skip_blanks function being used 00050 \param str the input string 00051 \return a pointer to the first non-whitespace character 00052 */ 00053 AST_INLINE_API( 00054 char *ast_skip_blanks(const char *str), 00055 { 00056 while (*str && *str < 33) 00057 str++; 00058 return (char *)str; 00059 } 00060 ) 00061 00062 /*! 00063 \brief Trims trailing whitespace characters from a string. 00064 \param ast_trim_blanks function being used 00065 \param str the input string 00066 \return a pointer to the modified string 00067 */ 00068 AST_INLINE_API( 00069 char *ast_trim_blanks(char *str), 00070 { 00071 char *work = str; 00072 00073 if (work) { 00074 work += strlen(work) - 1; 00075 /* It's tempting to only want to erase after we exit this loop, 00076 but since ast_trim_blanks *could* receive a constant string 00077 (which we presumably wouldn't have to touch), we shouldn't 00078 actually set anything unless we must, and it's easier just 00079 to set each position to \0 than to keep track of a variable 00080 for it */ 00081 while ((work >= str) && *work < 33) 00082 *(work--) = '\0'; 00083 } 00084 return str; 00085 } 00086 ) 00087 00088 /*! 00089 \brief Gets a pointer to first whitespace character in a string. 00090 \param ast_skip_noblanks function being used 00091 \param str the input string 00092 \return a pointer to the first whitespace character 00093 */ 00094 AST_INLINE_API( 00095 char *ast_skip_nonblanks(char *str), 00096 { 00097 while (*str && *str > 32) 00098 str++; 00099 return str; 00100 } 00101 ) 00102 00103 /*! 00104 \brief Strip leading/trailing whitespace from a string. 00105 \param s The string to be stripped (will be modified). 00106 \return The stripped string. 00107 00108 This functions strips all leading and trailing whitespace 00109 characters from the input string, and returns a pointer to 00110 the resulting string. The string is modified in place. 00111 */ 00112 AST_INLINE_API( 00113 char *ast_strip(char *s), 00114 { 00115 s = ast_skip_blanks(s); 00116 if (s) 00117 ast_trim_blanks(s); 00118 return s; 00119 } 00120 ) 00121 00122 /*! 00123 \brief Strip leading/trailing whitespace and quotes from a string. 00124 \param s The string to be stripped (will be modified). 00125 \param beg_quotes The list of possible beginning quote characters. 00126 \param end_quotes The list of matching ending quote characters. 00127 \return The stripped string. 00128 00129 This functions strips all leading and trailing whitespace 00130 characters from the input string, and returns a pointer to 00131 the resulting string. The string is modified in place. 00132 00133 It can also remove beginning and ending quote (or quote-like) 00134 characters, in matching pairs. If the first character of the 00135 string matches any character in beg_quotes, and the last 00136 character of the string is the matching character in 00137 end_quotes, then they are removed from the string. 00138 00139 Examples: 00140 \code 00141 ast_strip_quoted(buf, "\"", "\""); 00142 ast_strip_quoted(buf, "'", "'"); 00143 ast_strip_quoted(buf, "[{(", "]})"); 00144 \endcode 00145 */ 00146 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes); 00147 00148 /*! 00149 \brief Size-limited null-terminating string copy. 00150 \param ast_copy_string function being used 00151 \param dst The destination buffer. 00152 \param src The source string 00153 \param size The size of the destination buffer 00154 \return Nothing. 00155 00156 This is similar to \a strncpy, with two important differences: 00157 - the destination buffer will \b always be null-terminated 00158 - the destination buffer is not filled with zeros past the copied string length 00159 These differences make it slightly more efficient, and safer to use since it will 00160 not leave the destination buffer unterminated. There is no need to pass an artificially 00161 reduced buffer size to this function (unlike \a strncpy), and the buffer does not need 00162 to be initialized to zeroes prior to calling this function. 00163 */ 00164 AST_INLINE_API( 00165 void ast_copy_string(char *dst, const char *src, size_t size), 00166 { 00167 while (*src && size) { 00168 *dst++ = *src++; 00169 size--; 00170 } 00171 if (__builtin_expect(!size, 0)) 00172 dst--; 00173 *dst = '\0'; 00174 } 00175 ) 00176 00177 00178 /*! 00179 \brief Build a string in a buffer, designed to be called repeatedly 00180 00181 \note This method is not recommended. New code should use ast_str_*() instead. 00182 00183 This is a wrapper for snprintf, that properly handles the buffer pointer 00184 and buffer space available. 00185 00186 \param buffer current position in buffer to place string into (will be updated on return) 00187 \param space remaining space in buffer (will be updated on return) 00188 \param fmt printf-style format string 00189 \return 0 on success, non-zero on failure. 00190 */ 00191 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); 00192 00193 /*! 00194 \brief Build a string in a buffer, designed to be called repeatedly 00195 00196 This is a wrapper for snprintf, that properly handles the buffer pointer 00197 and buffer space available. 00198 00199 \return 0 on success, non-zero on failure. 00200 \param buffer current position in buffer to place string into (will be updated on return) 00201 \param space remaining space in buffer (will be updated on return) 00202 \param fmt printf-style format string 00203 \param ap varargs list of arguments for format 00204 */ 00205 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap); 00206 00207 /*! Make sure something is true */ 00208 /*! 00209 * Determine if a string containing a boolean value is "true". 00210 * This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1". 00211 * 00212 * Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise. 00213 */ 00214 int ast_true(const char *val); 00215 00216 /*! Make sure something is false */ 00217 /*! 00218 * Determine if a string containing a boolean value is "false". 00219 * This function checks to see whether a string passed to it is an indication of an "false" value. It checks to see if the string is "no", "false", "n", "f", "off" or "0". 00220 * 00221 * Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise. 00222 */ 00223 int ast_false(const char *val); 00224 00225 /* 00226 \brief Join an array of strings into a single string. 00227 \param s the resulting string buffer 00228 \param len the length of the result buffer, s 00229 \param w an array of strings to join 00230 00231 This function will join all of the strings in the array 'w' into a single 00232 string. It will also place a space in the result buffer in between each 00233 string from 'w'. 00234 */ 00235 void ast_join(char *s, size_t len, char * const w[]); 00236 00237 /* 00238 \brief Parse a time (integer) string. 00239 \param src String to parse 00240 \param dst Destination 00241 \param _default Value to use if the string does not contain a valid time 00242 \param consumed The number of characters 'consumed' in the string by the parse (see 'man sscanf' for details) 00243 \return zero on success, non-zero on failure 00244 */ 00245 int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed); 00246 00247 /* The realloca lets us ast_restrdupa(), but you can't mix any other ast_strdup calls! */ 00248 00249 struct ast_realloca { 00250 char *ptr; 00251 int alloclen; 00252 }; 00253 00254 #define ast_restrdupa(ra, s) \ 00255 ({ \ 00256 if ((ra)->ptr && strlen(s) + 1 < (ra)->alloclen) { \ 00257 strcpy((ra)->ptr, s); \ 00258 } else { \ 00259 (ra)->ptr = alloca(strlen(s) + 1 - (ra)->alloclen); \ 00260 if ((ra)->ptr) (ra)->alloclen = strlen(s) + 1; \ 00261 } \ 00262 (ra)->ptr; \ 00263 }) 00264 00265 /*! 00266 * Support for dynamic strings. 00267 * 00268 * A dynamic string is just a C string prefixed by a few control fields 00269 * that help setting/appending/extending it using a printf-like syntax. 00270 * 00271 * One should never declare a variable with this type, but only a pointer 00272 * to it, e.g. 00273 * 00274 * struct ast_str *ds; 00275 * 00276 * The pointer can be initialized with the following: 00277 * 00278 * ds = ast_str_create(init_len); 00279 * creates a malloc()'ed dynamic string; 00280 * 00281 * ds = ast_str_alloca(init_len); 00282 * creates a string on the stack (not very dynamic!). 00283 * 00284 * ds = ast_str_thread_get(ts, init_len) 00285 * creates a malloc()'ed dynamic string associated to 00286 * the thread-local storage key ts 00287 * 00288 * Finally, the string can be manipulated with the following: 00289 * 00290 * ast_str_set(&buf, max_len, fmt, ...) 00291 * ast_str_append(&buf, max_len, fmt, ...) 00292 * 00293 * and their varargs variant 00294 * 00295 * ast_str_set_va(&buf, max_len, ap) 00296 * ast_str_append_va(&buf, max_len, ap) 00297 * 00298 * \arg max_len The maximum allowed length, reallocating if needed. 00299 * 0 means unlimited, -1 means "at most the available space" 00300 * 00301 * \return All the functions return <0 in case of error, or the 00302 * length of the string added to the buffer otherwise. 00303 */ 00304 00305 /*! \brief The descriptor of a dynamic string 00306 * XXX storage will be optimized later if needed 00307 * We use the ts field to indicate the type of storage. 00308 * Three special constants indicate malloc, alloca() or static 00309 * variables, all other values indicate a 00310 * struct ast_threadstorage pointer. 00311 */ 00312 struct ast_str { 00313 size_t len; /*!< The current maximum length of the string */ 00314 size_t used; /*!< Amount of space used */ 00315 struct ast_threadstorage *ts; /*!< What kind of storage is this ? */ 00316 #define DS_MALLOC ((struct ast_threadstorage *)1) 00317 #define DS_ALLOCA ((struct ast_threadstorage *)2) 00318 #define DS_STATIC ((struct ast_threadstorage *)3) /* not supported yet */ 00319 char str[0]; /*!< The string buffer */ 00320 }; 00321 00322 /*! 00323 * \brief Create a malloc'ed dynamic length string 00324 * 00325 * \arg init_len This is the initial length of the string buffer 00326 * 00327 * \return This function returns a pointer to the dynamic string length. The 00328 * result will be NULL in the case of a memory allocation error. 00329 * 00330 * \note The result of this function is dynamically allocated memory, and must 00331 * be free()'d after it is no longer needed. 00332 */ 00333 AST_INLINE_API( 00334 struct ast_str * attribute_malloc ast_str_create(size_t init_len), 00335 { 00336 struct ast_str *buf; 00337 00338 buf = (struct ast_str *)ast_calloc(1, sizeof(*buf) + init_len); 00339 if (buf == NULL) 00340 return NULL; 00341 00342 buf->len = init_len; 00343 buf->used = 0; 00344 buf->ts = DS_MALLOC; 00345 00346 return buf; 00347 } 00348 ) 00349 00350 /*! \brief Reset the content of a dynamic string. 00351 * Useful before a series of ast_str_append. 00352 */ 00353 AST_INLINE_API( 00354 void ast_str_reset(struct ast_str *buf), 00355 { 00356 if (buf) { 00357 buf->used = 0; 00358 if (buf->len) 00359 buf->str[0] = '\0'; 00360 } 00361 } 00362 ) 00363 00364 /* 00365 * AST_INLINE_API() is a macro that takes a block of code as an argument. 00366 * Using preprocessor #directives in the argument is not supported by all 00367 * compilers, and it is a bit of an obfuscation anyways, so avoid it. 00368 * As a workaround, define a macro that produces either its argument 00369 * or nothing, and use that instead of #ifdef/#endif within the 00370 * argument to AST_INLINE_API(). 00371 */ 00372 #if defined(DEBUG_THREADLOCALS) 00373 #define _DB1(x) x 00374 #else 00375 #define _DB1(x) 00376 #endif 00377 00378 /*! 00379 * Make space in a new string (e.g. to read in data from a file) 00380 */ 00381 AST_INLINE_API( 00382 int ast_str_make_space(struct ast_str **buf, size_t new_len), 00383 { 00384 _DB1(struct ast_str *old_buf = *buf;) 00385 00386 if (new_len <= (*buf)->len) 00387 return 0; /* success */ 00388 if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC) 00389 return -1; /* cannot extend */ 00390 *buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str)); 00391 if (*buf == NULL) /* XXX watch out, we leak memory here */ 00392 return -1; 00393 if ((*buf)->ts != DS_MALLOC) { 00394 pthread_setspecific((*buf)->ts->key, *buf); 00395 _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));) 00396 } 00397 00398 (*buf)->len = new_len; 00399 return 0; 00400 } 00401 ) 00402 00403 #define ast_str_alloca(init_len) \ 00404 ({ \ 00405 struct ast_str *buf; \ 00406 buf = alloca(sizeof(*buf) + init_len); \ 00407 buf->len = init_len; \ 00408 buf->used = 0; \ 00409 buf->ts = DS_ALLOCA; \ 00410 buf->str[0] = '\0'; \ 00411 (buf); \ 00412 }) 00413 00414 00415 /*! 00416 * \brief Retrieve a thread locally stored dynamic string 00417 * 00418 * \arg ts This is a pointer to the thread storage structure declared by using 00419 * the AST_THREADSTORAGE macro. If declared with 00420 * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be 00421 * (&my_buf). 00422 * \arg init_len This is the initial length of the thread's dynamic string. The 00423 * current length may be bigger if previous operations in this thread have 00424 * caused it to increase. 00425 * 00426 * \return This function will return the thread locally stored dynamic string 00427 * associated with the thread storage management variable passed as the 00428 * first argument. 00429 * The result will be NULL in the case of a memory allocation error. 00430 * 00431 * Example usage: 00432 * \code 00433 * AST_THREADSTORAGE(my_str, my_str_init); 00434 * #define MY_STR_INIT_SIZE 128 00435 * ... 00436 * void my_func(const char *fmt, ...) 00437 * { 00438 * struct ast_str *buf; 00439 * 00440 * if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE))) 00441 * return; 00442 * ... 00443 * } 00444 * \endcode 00445 */ 00446 #if !defined(DEBUG_THREADLOCALS) 00447 AST_INLINE_API( 00448 struct ast_str *ast_str_thread_get(struct ast_threadstorage *ts, 00449 size_t init_len), 00450 { 00451 struct ast_str *buf; 00452 00453 buf = (struct ast_str *)ast_threadstorage_get(ts, sizeof(*buf) + init_len); 00454 if (buf == NULL) 00455 return NULL; 00456 00457 if (!buf->len) { 00458 buf->len = init_len; 00459 buf->used = 0; 00460 buf->ts = ts; 00461 } 00462 00463 return buf; 00464 } 00465 ) 00466 #else /* defined(DEBUG_THREADLOCALS) */ 00467 AST_INLINE_API( 00468 struct ast_str *__ast_str_thread_get(struct ast_threadstorage *ts, 00469 size_t init_len, const char *file, const char *function, unsigned int line), 00470 { 00471 struct ast_str *buf; 00472 00473 buf = (struct ast_str *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line); 00474 if (buf == NULL) 00475 return NULL; 00476 00477 if (!buf->len) { 00478 buf->len = init_len; 00479 buf->used = 0; 00480 buf->ts = ts; 00481 } 00482 00483 return buf; 00484 } 00485 ) 00486 00487 #define ast_str_thread_get(ts, init_len) __ast_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__) 00488 #endif /* defined(DEBUG_THREADLOCALS) */ 00489 00490 /*! 00491 * \brief Error codes from __ast_str_helper() 00492 * The undelying processing to manipulate dynamic string is done 00493 * by __ast_str_helper(), which can return a success, a 00494 * permanent failure (e.g. no memory), or a temporary one (when 00495 * the string needs to be reallocated, and we must run va_start() 00496 * again; XXX this convoluted interface is only here because 00497 * FreeBSD 4 lacks va_copy, but this will be fixed and the 00498 * interface simplified). 00499 */ 00500 enum { 00501 /*! An error has occured and the contents of the dynamic string 00502 * are undefined */ 00503 AST_DYNSTR_BUILD_FAILED = -1, 00504 /*! The buffer size for the dynamic string had to be increased, and 00505 * __ast_str_helper() needs to be called again after 00506 * a va_end() and va_start(). 00507 */ 00508 AST_DYNSTR_BUILD_RETRY = -2 00509 }; 00510 00511 /*! 00512 * \brief Set a dynamic string from a va_list 00513 * 00514 * \arg buf This is the address of a pointer to a struct ast_str. 00515 * If it is retrieved using ast_str_thread_get, the 00516 struct ast_threadstorage pointer will need to 00517 * be updated in the case that the buffer has to be reallocated to 00518 * accommodate a longer string than what it currently has space for. 00519 * \arg max_len This is the maximum length to allow the string buffer to grow 00520 * to. If this is set to 0, then there is no maximum length. 00521 * \arg fmt This is the format string (printf style) 00522 * \arg ap This is the va_list 00523 * 00524 * \return The return value of this function is the same as that of the printf 00525 * family of functions. 00526 * 00527 * Example usage (the first part is only for thread-local storage) 00528 * \code 00529 * AST_THREADSTORAGE(my_str, my_str_init); 00530 * #define MY_STR_INIT_SIZE 128 00531 * ... 00532 * void my_func(const char *fmt, ...) 00533 * { 00534 * struct ast_str *buf; 00535 * va_list ap; 00536 * 00537 * if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE))) 00538 * return; 00539 * ... 00540 * va_start(fmt, ap); 00541 * ast_str_set_va(&buf, 0, fmt, ap); 00542 * va_end(ap); 00543 * 00544 * printf("This is the string we just built: %s\n", buf->str); 00545 * ... 00546 * } 00547 * \endcode 00548 * 00549 * \note: the following two functions must be implemented as macros 00550 * because we must do va_end()/va_start() on the original arguments. 00551 */ 00552 #define ast_str_set_va(buf, max_len, fmt, ap) \ 00553 ({ \ 00554 int __res; \ 00555 while ((__res = __ast_str_helper(buf, max_len, \ 00556 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \ 00557 va_end(ap); \ 00558 va_start(ap, fmt); \ 00559 } \ 00560 (__res); \ 00561 }) 00562 00563 /*! 00564 * \brief Append to a dynamic string using a va_list 00565 * 00566 * Same as ast_str_set_va(), but append to the current content. 00567 */ 00568 #define ast_str_append_va(buf, max_len, fmt, ap) \ 00569 ({ \ 00570 int __res; \ 00571 while ((__res = __ast_str_helper(buf, max_len, \ 00572 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \ 00573 va_end(ap); \ 00574 va_start(ap, fmt); \ 00575 } \ 00576 (__res); \ 00577 }) 00578 00579 /*! 00580 * \brief Core functionality of ast_str_(set|append)_va 00581 * 00582 * The arguments to this function are the same as those described for 00583 * ast_str_set_va except for an addition argument, append. 00584 * If append is non-zero, this will append to the current string instead of 00585 * writing over it. 00586 * 00587 * In the case that this function is called and the buffer was not large enough 00588 * to hold the result, the partial write will be truncated, and the result 00589 * AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size 00590 * was increased, and the function should be called a second time. 00591 * 00592 * A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error. 00593 * 00594 * A return value greater than or equal to zero indicates the number of 00595 * characters that have been written, not including the terminating '\0'. 00596 * In the append case, this only includes the number of characters appended. 00597 * 00598 * \note This function should never need to be called directly. It should 00599 * through calling one of the other functions or macros defined in this 00600 * file. 00601 */ 00602 int __ast_str_helper(struct ast_str **buf, size_t max_len, 00603 int append, const char *fmt, va_list ap); 00604 00605 /*! 00606 * \brief Set a dynamic string using variable arguments 00607 * 00608 * \arg buf This is the address of a pointer to a struct ast_str which should 00609 * have been retrieved using ast_str_thread_get. It will need to 00610 * be updated in the case that the buffer has to be reallocated to 00611 * accomodate a longer string than what it currently has space for. 00612 * \arg max_len This is the maximum length to allow the string buffer to grow 00613 * to. If this is set to 0, then there is no maximum length. 00614 * If set to -1, we are bound to the current maximum length. 00615 * \arg fmt This is the format string (printf style) 00616 * 00617 * \return The return value of this function is the same as that of the printf 00618 * family of functions. 00619 * 00620 * All the rest is the same as ast_str_set_va() 00621 */ 00622 AST_INLINE_API( 00623 int __attribute__ ((format (printf, 3, 4))) ast_str_set( 00624 struct ast_str **buf, size_t max_len, const char *fmt, ...), 00625 { 00626 int res; 00627 va_list ap; 00628 00629 va_start(ap, fmt); 00630 res = ast_str_set_va(buf, max_len, fmt, ap); 00631 va_end(ap); 00632 00633 return res; 00634 } 00635 ) 00636 00637 /*! 00638 * \brief Append to a thread local dynamic string 00639 * 00640 * The arguments, return values, and usage of this function are the same as 00641 * ast_str_set(), but the new data is appended to the current value. 00642 */ 00643 AST_INLINE_API( 00644 int __attribute__ ((format (printf, 3, 4))) ast_str_append( 00645 struct ast_str **buf, size_t max_len, const char *fmt, ...), 00646 { 00647 int res; 00648 va_list ap; 00649 00650 va_start(ap, fmt); 00651 res = ast_str_append_va(buf, max_len, fmt, ap); 00652 va_end(ap); 00653 00654 return res; 00655 } 00656 ) 00657 00658 #endif /* _ASTERISK_STRINGS_H */