2 * Copyright (c) 2013, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #define LOG(level, fmt, args...) \
36 CFZY_LOG("string", level, fmt, ##args)
38 /* Acts as a asprintf, except that it appends data after buf (if not
39 * NULL), reallocating memory if necessary. */
40 int cfzy_string_asprintf(char **buf, const char *fmt, ...)
44 int offset = 0, buflen, ret;
47 offset = strlen(*buf);
50 ret = vsnprintf(&dummy, 1, fmt, ap);
53 LOG(ERR, "first vsnprintf failed\n");
57 buflen = offset + ret + 1;
58 *buf = realloc(*buf, buflen);
60 LOG(ERR, "asprintf: not enough memory\n");
65 ret = vsnprintf(*buf + offset, buflen - offset, fmt, ap);
68 if (ret >= buflen || ret < 0) {
71 LOG(ERR, "second vsnprintf failed\n");
79 * If the buffer is surrounded by quotes (simple or double), this
80 * function will allocate a new string and remove the quotes properly,
81 * also deleting the backslash in occurences of \\, \" or \'. If the
82 * buffer does not start by a quote, the function just return a
83 * duplicate of the input string. On sucess, the eatlen is updated to
84 * the number of consumed bytes (including quotes if any, but not
85 * including \0). On error, return NULL, in this case *eatlen is
88 char *cfzy_string_unquote(const char *buf, unsigned *eatlen)
97 LOG(ERR, "not enough memory\n");
103 else if (s[0] == '\'')
112 while (*s != delim) {
117 if (*s == '\\' && *(s+1) == delim) {
123 if (*s == '\\' && *(s+1) == '\\') {
135 *eatlen = s - buf + 1;
139 /* quote a string and escape original quotes */
140 char *cfzy_string_quote(const char *src)
145 /* get dst buf len */
146 for (s = 0, d = 0; src[s] != '\0'; s++, d++) {
149 if (src[s] == '\\' && src[s+1] == '"')
153 dst = malloc(d + 3); /* 3 for the 2 quotes and the \0 */
158 for (s = 0, d = 1; src[s] != '\0'; s++, d++) {
161 if (src[s] == '\\' && src[s+1] == '"')