Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:00:57 2007

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 */

Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen