]> git.saurik.com Git - apple/libc.git/blame - gen/wordexp.c
Libc-391.2.3.tar.gz
[apple/libc.git] / gen / wordexp.c
CommitLineData
59e0d9fe
A
1/*
2 * Copyright 1994, University Corporation for Atmospheric Research
3 * See ../COPYRIGHT file for copying and redistribution conditions.
4 */
5/*
6 * Reproduction of ../COPYRIGHT file:
7 *
8 *********************************************************************
9
10Copyright 1995-2002 University Corporation for Atmospheric Research/Unidata
11
12Portions of this software were developed by the Unidata Program at the
13University Corporation for Atmospheric Research.
14
15Access and use of this software shall impose the following obligations
16and understandings on the user. The user is granted the right, without
17any fee or cost, to use, copy, modify, alter, enhance and distribute
18this software, and any derivative works thereof, and its supporting
19documentation for any purpose whatsoever, provided that this entire
20notice appears in all copies of the software, derivative works and
21supporting documentation. Further, UCAR requests that the user credit
22UCAR/Unidata in any publications that result from the use of this
23software or in any product that includes this software. The names UCAR
24and/or Unidata, however, may not be used in any advertising or publicity
25to endorse or promote any products or commercial entity unless specific
26written permission is obtained from UCAR/Unidata. The user also
27understands that UCAR/Unidata is not obligated to provide the user with
28any support, consulting, training or assistance of any kind with regard
29to the use, operation and performance of this software nor to provide
30the user with any updates, revisions, new versions or "bug fixes."
31
32THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
33IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
36INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
37FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
38NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
39WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
40
41 *********************************************************************
42 */
43
44/* $Id: wordexp.c,v 1.13 2002/12/26 16:46:46 steve Exp $ */
45
46#if 0
47#include "ldmconfig.h"
48#endif
49
50/*
51 * Hack to provide POSIX 1003.2-1992 _interface_.
52 * NOT fully functional
53 */
54
3d9156a7
A
55#include "xlocale_private.h"
56
59e0d9fe
A
57#include <stdlib.h>
58#include <string.h>
59#include <ctype.h>
60
61#include "wordexp.h"
62
63
64
65/*
66 * Translate return value from wordexp() into a string
67 */
68const char *
69s_wrde_err(int wrde_err)
70{
71 switch(wrde_err) {
72 case 0: return "No Error";
73 case WRDE_BADCHAR: return "WRDE_BADCHAR";
74 case WRDE_BADVAL: return "WRDE_BADVAL";
75 case WRDE_CMDSUB: return "WRDE_CMDSUB";
76 case WRDE_NOSPACE: return "WRDE_NOSPACE";
77 case WRDE_SYNTAX: return "WRDE_SYNTAX";
78 }
79 /* default */
80 return "Unknown Error";
81}
82
83
84/*ARGSUSED*/
85int
86wordexp(const char *words, wordexp_t *pwordexp, int flags)
87{
88 const char *ccp;
89 char **argv;
90 const char *buf;
91 size_t argc;
92 enum states {ARGSTART, IN_QUOTE, NOT_IN_QUOTE, DONE};
93 enum classes {EOS, SPACE, QUOTE, OTHER};
94 int state = ARGSTART;
95 char *argbuf;
96 const char *sp;
97 char *dp;
98 int status = 0;
3d9156a7 99 locale_t loc = __current_locale();
59e0d9fe
A
100
101 /* devour leading white space */
3d9156a7 102 for(ccp = words; *ccp != 0 && isspace_l(*ccp, loc); )
59e0d9fe
A
103 ccp++;
104 /* skip comments */
105 if(*ccp == '#')
106 {
107 pwordexp->we_wordc = 0;
108 pwordexp->we_wordv = NULL;
109 return 0;
110 }
111
112/* If every other character was a space ... */
113#define MAXNARGS(str) ((strlen(str) +1)/2 +1)
114 argv = (char **)calloc(MAXNARGS(ccp), sizeof(char *));
115 if(argv == NULL)
116 return WRDE_NOSPACE;
117
118 buf = ccp;
119
120 argbuf = malloc(strlen(words)+1); /* where each arg is built */
121 if (argbuf == NULL)
122 {
123 free(argv);
124 return WRDE_NOSPACE;
125 }
126
127 sp = buf;
128 dp = argbuf;
129 argc = 0;
130 while(state != DONE)
131 {
132 int class;
133
134 if (*sp == 0)
135 class = EOS;
3d9156a7 136 else if (isspace_l(*sp, loc))
59e0d9fe
A
137 class = SPACE;
138 else if (*sp == '"')
139 class = QUOTE;
140 else
141 class = OTHER;
142 switch (state) {
143 case ARGSTART:
144 switch(class) {
145 case EOS:
146 state = DONE;
147 break;
148 case SPACE:
149 sp++;
150 break;
151 case QUOTE:
152 sp++;
153 state = IN_QUOTE;
154 break;
155 case OTHER:
156 *dp++ = *sp++;
157 state = NOT_IN_QUOTE;
158 break;
159 }
160 break;
161 case IN_QUOTE:
162 switch(class) {
163 case EOS: /* unmatched quote */
164 state = DONE;
165 status = WRDE_SYNTAX;
166 break;
167 case QUOTE:
168 sp++;
169 state = NOT_IN_QUOTE;
170 break;
171 case SPACE:
172 case OTHER:
173 *dp++ = *sp++;
174 break;
175 }
176 break;
177 case NOT_IN_QUOTE:
178 switch(class) {
179 case EOS:
180 *dp = 0;
181 dp = argbuf;
182 argv[argc++] = strdup(argbuf);
183 state = DONE;
184 break;
185 case SPACE:
186 *dp = 0;
187 dp = argbuf;
188 argv[argc++] = strdup(argbuf);
189 sp++;
190 state = ARGSTART;
191 break;
192 case QUOTE:
193 sp++;
194 state = IN_QUOTE;
195 break;
196 case OTHER:
197 *dp++ = *sp++;
198 break;
199 }
200 break;
201 }
202 }
203 argv[argc] = NULL;
204
205 pwordexp->we_wordc = argc;
206 pwordexp->we_wordv = argv;
207
208 free(argbuf);
209
210 return status;
211}
212
213
214void
215wordfree(wordexp_t *pwordexp)
216{
217 if(pwordexp == NULL || pwordexp->we_wordv == NULL)
218 return;
219 if(*pwordexp->we_wordv)
220 free(*pwordexp->we_wordv);
221 free(pwordexp->we_wordv);
222}
223
224
225#if TEST
226
227#include <stdio.h>
228#include <stdlib.h>
229#include <string.h>
230
231int
232main(int argc, char *argv[])
233{
234 char strbuf[1024];
235 wordexp_t wrdexp;
236 int status;
237 char **cpp;
238
239 while(fgets(strbuf, sizeof(strbuf), stdin) != NULL)
240 {
241 {
242 char *cp = strrchr(strbuf,'\n');
243 if(cp)
244 *cp = 0;
245 }
246 fprintf(stdout, "\t%s\n", strbuf);
247 status = wordexp(strbuf, &wrdexp, WRDE_SHOWERR);
248 if(status)
249 {
250 fprintf(stderr, "wordexp: %s\n", s_wrde_err(status));
251 continue;
252 }
253 /* else */
254 fprintf(stdout, "\t%d:\n", wrdexp.we_wordc);
255 for(cpp = wrdexp.we_wordv;
256 cpp < &wrdexp.we_wordv[wrdexp.we_wordc]; cpp++)
257 {
258 fprintf(stdout, "\t\t%s\n", *cpp);
259 }
260 wordfree(&wrdexp);
261
262 }
263 exit(EXIT_SUCCESS);
264}
265
266#endif /* TEST */