2 * Copyright (c) 2004 Joerg Sonnenberger <joerg@bec.de>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. 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.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * $DragonFly: src/lib/libiberty/argv.c,v 1.1 2004/10/23 12:15:21 joerg Exp $
29 #include <libiberty.h>
33 #define IS_SEP(x) ((x) == ' ' || (x) == '\t')
36 * Return the first character of the next word.
37 * len is the word len after quoting and escaping has been removed.
40 find_next_word(const char *arg, size_t *len)
42 enum {NOQUOTE, SQUOTE, DQUOTE} in_quote = NOQUOTE;
46 while (*arg != '\0') {
47 if (IS_SEP(*arg) && in_quote == NOQUOTE) {
49 } else if (*arg == '\\') {
54 } else if (*arg == '"') {
55 if (in_quote == NOQUOTE)
57 else if (in_quote == DQUOTE)
61 } else if (*arg == '\'') {
62 if (in_quote == NOQUOTE)
64 else if (in_quote == SQUOTE)
77 copy_word(const char *arg, const char *end, size_t len)
79 char *buf, *buf_begin;
80 enum {NOQUOTE, SQUOTE, DQUOTE} in_quote = NOQUOTE;
84 buf_begin = buf = malloc(len + 1);
86 for (; arg < end; arg++) {
92 } else if (*arg == '"') {
93 if (in_quote == NOQUOTE)
95 else if (in_quote == DQUOTE)
99 } else if (*arg == '\'') {
100 if (in_quote == NOQUOTE)
102 else if (in_quote == SQUOTE)
115 buildargv(const char *arg)
118 const char *begin_arg;
127 argv = malloc(sizeof(char *));
132 while (*arg != '\0') {
133 /* Skip leading white space. */
140 arg = find_next_word(arg, &len);
142 tmp = realloc(argv, (args + 2) * sizeof(char *));
147 argv[args] = copy_word(begin_arg, arg, len);
148 if (argv[args] == NULL)
155 * The argument might be only white space, in that case,
156 * an empty argument list should be returned.
159 tmp = realloc(argv, 2 * sizeof(char *));
164 argv[0] = strdup("");
176 freeargv(char **argv)
183 for (orig_argv = argv; *argv != NULL; argv++)
190 dupargv(char * const *argv)
192 char * const *orig_argv;
193 char **new_argv, **new_argv2;
197 for (len = 0; *argv != NULL; argv++)
200 new_argv = malloc((len+1) * sizeof(char *));
202 new_argv2 = new_argv;
203 for (; orig_argv != NULL; orig_argv++, new_argv++) {
204 *new_argv = strdup(*orig_argv);
205 if (*new_argv == NULL) {