sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / libast / common / comp / wordexp.c
bloba1b6ede45a9b8644dadd0f4944bc7c83b36802ba
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
24 * POSIX 1003.2 wordexp implementation
25 */
27 #include <ast.h>
28 #include <wordexp.h>
29 #include <stak.h>
31 struct list
33 struct list *next;
37 * elimnates shell quoting as inserted with sh_fmtq
38 * result relaces <string>
39 * length of resulting string is returned.
41 static int sh_unquote(char* string)
43 register char *sp=string, *dp;
44 register int c;
45 while((c= *sp) && c!='\'')
46 sp++;
47 if(c==0)
48 return(sp-string);
49 if((dp=sp) > string && sp[-1]=='$')
51 register int n=stresc(sp+1);
52 /* copy all but trailing ' */
53 while(--n>0)
54 *dp++ = *++sp;
56 else
58 while((c= *++sp) && c!='\'')
59 *dp++ = c;
61 *dp=0;
62 return(dp-string);
65 int wordexp(const char *string, wordexp_t *wdarg, register int flags)
67 register Sfio_t *iop;
68 register char *cp=(char*)string;
69 register int c,quoted=0,literal=0,ac=0;
70 int offset;
71 char *savebase,**av;
72 if(offset=staktell())
73 savebase = stakfreeze(0);
74 if(flags&WRDE_REUSE)
75 wordfree(wdarg);
76 else if(!(flags&WRDE_APPEND))
78 wdarg->we_wordv = 0;
79 wdarg->we_wordc = 0;
81 if(flags&WRDE_UNDEF)
82 stakwrite("set -u\n",7);
83 if(!(flags&WRDE_SHOWERR))
84 stakwrite("exec 2> /dev/null\n",18);
85 stakwrite("print -f \"%q\\n\" ",16);
86 if(*cp=='#')
87 stakputc('\\');
88 while(c = *cp++)
90 if(c=='\'' && !quoted)
91 literal = !literal;
92 else if(!literal)
94 if(c=='\\' && (!quoted || strchr("\\\"`\n$",c)))
96 stakputc('\\');
97 if(c= *cp)
98 cp++;
99 else
100 c = '\\';
102 else if(c=='"')
103 quoted = !quoted;
104 else if(c=='`' || (c=='$' && *cp=='('))
106 if(flags&WRDE_NOCMD)
108 c=WRDE_CMDSUB;
109 goto err;
111 /* only the shell can parse the rest */
112 stakputs(cp-1);
113 break;
115 else if(!quoted && strchr("|&\n;<>"+ac,c))
117 c=WRDE_BADCHAR;
118 goto err;
120 else if(c=='(') /* allow | and & inside pattern */
121 ac=2;
123 stakputc(c);
125 stakputc(0);
126 if(!(iop = sfpopen((Sfio_t*)0,stakptr(0),"r")))
128 c = WRDE_NOSHELL;
129 goto err;
131 stakseek(0);
132 ac = 0;
133 while((c=sfgetc(iop)) != EOF)
135 if(c=='\'')
136 quoted = ! quoted;
137 else if(!quoted && (c==' ' || c=='\n'))
139 ac++;
140 c = 0;
142 stakputc(c);
144 if(c=sfclose(iop))
146 if(c==3 || !(flags&WRDE_UNDEF))
147 c=WRDE_SYNTAX;
148 else
149 c=WRDE_BADVAL;
150 goto err;
152 c = ac+2;
153 if(flags&WRDE_DOOFFS)
154 c += wdarg->we_offs;
155 if(flags&WRDE_APPEND)
156 av = reallocarray((void *)&wdarg->we_wordv[-1],
157 wdarg->we_wordc + c, sizeof (char *));
158 else if(av = (char**)malloc(c*sizeof(char*)))
160 if(flags&WRDE_DOOFFS)
161 memset(av,0,(wdarg->we_offs+1)*sizeof(char*));
162 else
163 av[0] = 0;
165 if(!av)
166 return(WRDE_NOSPACE);
167 c = staktell();
168 if(!(cp = (char*)malloc(sizeof(char*)+c)))
170 c=WRDE_NOSPACE;
171 goto err;
173 ((struct list*)cp)->next = (struct list*)(*av);
174 *av++ = (char*)cp;
175 cp += sizeof(char*);
176 wdarg->we_wordv = av;
177 if(flags&WRDE_APPEND)
178 av += wdarg->we_wordc;
179 wdarg->we_wordc += ac;
180 if(flags&WRDE_DOOFFS)
181 av += wdarg->we_offs;
182 memcpy((void*)cp,stakptr(offset),c);
183 while(ac-- > 0)
185 *av++ = cp;
186 sh_unquote(cp);
187 while(c= *cp++);
189 *av = 0;
190 c=0;
191 err:
192 if(offset)
193 stakset(savebase,offset);
194 else
195 stakseek(0);
196 return(c);
200 * free fields in <wdarg>
202 int wordfree(register wordexp_t *wdarg)
204 struct list *arg, *argnext;
205 if(wdarg->we_wordv)
207 argnext = (struct list*)wdarg->we_wordv[-1];
208 while(arg=argnext)
210 argnext = arg->next;
211 free((void*)arg);
213 free((void*)&wdarg->we_wordv[-1]);
214 wdarg->we_wordv = 0;
216 wdarg->we_wordc=0;
217 return(0);