1 /* string-util.c - Extra or enhanced routines for null terminated strings.
3 * Copyright (c) 2012 Jani Nikula
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/ .
18 * Author: Jani Nikula <jani@nikula.org>
22 #include "string-util.h"
29 strtok_len (char *s, const char *delim, size_t *len)
31 /* skip initial delims */
32 s += strspn (s, delim);
35 *len = strcspn (s, delim);
37 return *len ? s : NULL;
41 sanitize_string (const void *ctx, const char *str)
48 out = talloc_strdup (ctx, str);
52 for (loop = out; *loop; loop++) {
53 if (*loop == '\t' || *loop == '\n')
55 else if ((unsigned char)(*loop) < 32)
63 is_unquoted_terminator (unsigned char c)
65 return c == 0 || c <= ' ' || c == ')';
69 make_boolean_term (void *ctx, const char *prefix, const char *term,
70 char **buf, size_t *len)
77 /* Do we need quoting? To be paranoid, we quote anything
78 * containing a quote, even though it only matters at the
79 * beginning, and anything containing non-ASCII text. */
80 for (in = term; *in && !need_quoting; in++)
81 if (is_unquoted_terminator (*in) || *in == '"'
82 || (unsigned char)*in > 127)
86 for (in = term; *in; in++)
87 needed += (*in == '"') ? 2 : 1;
89 needed = strlen (term) + 1;
91 /* Reserve space for the prefix */
93 needed += strlen (prefix) + 1;
95 if ((*buf == NULL) || (needed > *len)) {
97 *buf = talloc_realloc (ctx, *buf, char, *len);
107 /* Copy in the prefix */
109 strcpy (out, prefix);
110 out += strlen (prefix);
114 if (! need_quoting) {
119 /* Quote term by enclosing it in double quotes and doubling any
120 * internal double quotes. */
135 skip_space (const char *str)
137 while (*str && isspace ((unsigned char) *str))
143 parse_boolean_term (void *ctx, const char *str,
144 char **prefix_out, char **term_out)
147 *prefix_out = *term_out = NULL;
150 str = skip_space (str);
151 const char *pos = strchr (str, ':');
152 if (! pos || pos == str)
154 *prefix_out = talloc_strndup (ctx, str, pos - str);
161 /* Implement de-quoting compatible with make_boolean_term. */
163 char *out = talloc_array (ctx, char, strlen (pos));
170 /* Skip the opening quote, find the closing quote, and
171 * un-double doubled internal quotes. */
172 for (++pos; *pos; ) {
176 /* Found the closing quote. */
178 pos = skip_space (pos);
184 /* Did the term terminate without a closing quote or is there
185 * trailing text after the closing quote? */
190 const char *start = pos;
191 /* Check for text after the boolean term. */
192 while (! is_unquoted_terminator (*pos))
194 if (*skip_space (pos)) {
198 /* No trailing text; dup the string so the caller can free
200 *term_out = talloc_strndup (ctx, start, pos - start);
209 talloc_free (*prefix_out);
210 talloc_free (*term_out);