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 14: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
) {