change ast_strlen_zero to also check for the string to be defined
[asterisk/asterisk.git] / include / asterisk / strings.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief String manipulation functions
21  */
22
23 #ifndef _ASTERISK_STRINGS_H
24 #define _ASTERISK_STRINGS_H
25
26 #include <string.h>
27 #include <stdarg.h>
28
29 #include "asterisk/inline_api.h"
30 #include "asterisk/compiler.h"
31 #include "asterisk/compat.h"
32
33 static inline int ast_strlen_zero(const char *s)
34 {
35         return (!s || (*s == '\0'));
36 }
37
38 /*!
39   \brief Gets a pointer to the first non-whitespace character in a string.
40   \param str the input string
41   \return a pointer to the first non-whitespace character
42  */
43 AST_INLINE_API(
44 char *ast_skip_blanks(char *str),
45 {
46         while (*str && *str < 33)
47                 str++;
48         return str;
49 }
50 )
51
52 /*!
53   \brief Trims trailing whitespace characters from a string.
54   \param str the input string
55   \return a pointer to the NULL following the string
56  */
57 AST_INLINE_API(
58 char *ast_trim_blanks(char *str),
59 {
60         char *work = str;
61
62         if (work) {
63                 work += strlen(work) - 1;
64                 /* It's tempting to only want to erase after we exit this loop, 
65                    but since ast_trim_blanks *could* receive a constant string
66                    (which we presumably wouldn't have to touch), we shouldn't
67                    actually set anything unless we must, and it's easier just
68                    to set each position to \0 than to keep track of a variable
69                    for it */
70                 while ((work >= str) && *work < 33)
71                         *(work--) = '\0';
72         }
73         return str;
74 }
75 )
76
77 /*!
78   \brief Gets a pointer to first whitespace character in a string.
79   \param str the input string
80   \return a pointer to the first whitespace character
81  */
82 AST_INLINE_API(
83 char *ast_skip_nonblanks(char *str),
84 {
85         while (*str && *str > 32)
86                 str++;
87         return str;
88 }
89 )
90   
91 /*!
92   \brief Strip leading/trailing whitespace from a string.
93   \param s The string to be stripped (will be modified).
94   \return The stripped string.
95
96   This functions strips all leading and trailing whitespace
97   characters from the input string, and returns a pointer to
98   the resulting string. The string is modified in place.
99 */
100 AST_INLINE_API(
101 char *ast_strip(char *s),
102 {
103         s = ast_skip_blanks(s);
104         if (s)
105                 ast_trim_blanks(s);
106         return s;
107
108 )
109
110 /*!
111   \brief Strip leading/trailing whitespace and quotes from a string.
112   \param s The string to be stripped (will be modified).
113   \param beg_quotes The list of possible beginning quote characters.
114   \param end_quotes The list of matching ending quote characters.
115   \return The stripped string.
116
117   This functions strips all leading and trailing whitespace
118   characters from the input string, and returns a pointer to
119   the resulting string. The string is modified in place.
120
121   It can also remove beginning and ending quote (or quote-like)
122   characters, in matching pairs. If the first character of the
123   string matches any character in beg_quotes, and the last
124   character of the string is the matching character in
125   end_quotes, then they are removed from the string.
126
127   Examples:
128   \code
129   ast_strip_quoted(buf, "\"", "\"");
130   ast_strip_quoted(buf, "'", "'");
131   ast_strip_quoted(buf, "[{(", "]})");
132   \endcode
133  */
134 char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes);
135
136 /*!
137   \brief Size-limited null-terminating string copy.
138   \param dst The destination buffer.
139   \param src The source string
140   \param size The size of the destination buffer
141   \return Nothing.
142
143   This is similar to \a strncpy, with two important differences:
144     - the destination buffer will \b always be null-terminated
145     - the destination buffer is not filled with zeros past the copied string length
146   These differences make it slightly more efficient, and safer to use since it will
147   not leave the destination buffer unterminated. There is no need to pass an artificially
148   reduced buffer size to this function (unlike \a strncpy), and the buffer does not need
149   to be initialized to zeroes prior to calling this function.
150 */
151 AST_INLINE_API(
152 void ast_copy_string(char *dst, const char *src, size_t size),
153 {
154         while (*src && size) {
155                 *dst++ = *src++;
156                 size--;
157         }
158         if (__builtin_expect(!size, 0))
159                 dst--;
160         *dst = '\0';
161 }
162 )
163
164 /*!
165   \brief Build a string in a buffer, designed to be called repeatedly
166   
167   This is a wrapper for snprintf, that properly handles the buffer pointer
168   and buffer space available.
169
170   \return 0 on success, non-zero on failure.
171   \param buffer current position in buffer to place string into (will be updated on return)
172   \param space remaining space in buffer (will be updated on return)
173   \param fmt printf-style format string
174 */
175 int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
176
177 /*!
178   \brief Build a string in a buffer, designed to be called repeatedly
179   
180   This is a wrapper for snprintf, that properly handles the buffer pointer
181   and buffer space available.
182
183   \return 0 on success, non-zero on failure.
184   \param buffer current position in buffer to place string into (will be updated on return)
185   \param space remaining space in buffer (will be updated on return)
186   \param fmt printf-style format string
187   \param ap varargs list of arguments for format
188 */
189 int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap);
190
191 /*! Make sure something is true */
192 /*!
193  * Determine if a string containing a boolean value is "true".
194  * 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".  
195  *
196  * Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.
197  */
198 int ast_true(const char *val);
199
200 /*! Make sure something is false */
201 /*!
202  * Determine if a string containing a boolean value is "false".
203  * 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".  
204  *
205  * Returns 0 if val is a NULL pointer, -1 if "false", and 0 otherwise.
206  */
207 int ast_false(const char *val);
208
209 /* The realloca lets us ast_restrdupa(), but you can't mix any other ast_strdup calls! */
210
211 struct ast_realloca {
212         char *ptr;
213         int alloclen;
214 };
215
216 #define ast_restrdupa(ra, s) \
217         ({ \
218                 if ((ra)->ptr && strlen(s) + 1 < (ra)->alloclen) { \
219                         strcpy((ra)->ptr, s); \
220                 } else { \
221                         (ra)->ptr = alloca(strlen(s) + 1 - (ra)->alloclen); \
222                         if ((ra)->ptr) (ra)->alloclen = strlen(s) + 1; \
223                 } \
224                 (ra)->ptr; \
225         })
226
227 #ifndef HAVE_STRCASESTR
228 char *strcasestr(const char *, const char *);
229 #endif
230
231 #if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
232 char *strndup(const char *, size_t);
233 #endif
234
235 #ifndef HAVE_STRNLEN
236 size_t strnlen(const char *, size_t);
237 #endif
238
239 #if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
240 int vasprintf(char **strp, const char *fmt, va_list ap);
241 #endif
242
243 #ifndef HAVE_STRTOQ
244 uint64_t strtoq(const char *nptr, char **endptr, int base);
245 #endif
246
247 #endif /* _ASTERISK_STRINGS_H */