1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 * POSIX 1003.2 wordexp implementation
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
;
45 while((c
= *sp
) && c
!='\'')
49 if((dp
=sp
) > string
&& sp
[-1]=='$')
51 register int n
=stresc(sp
+1);
52 /* copy all but trailing ' */
58 while((c
= *++sp
) && c
!='\'')
65 int wordexp(const char *string
, wordexp_t
*wdarg
, register int flags
)
68 register char *cp
=(char*)string
;
69 register int c
,quoted
=0,literal
=0,ac
=0;
73 savebase
= stakfreeze(0);
76 else if(!(flags
&WRDE_APPEND
))
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);
90 if(c
=='\'' && !quoted
)
94 if(c
=='\\' && (!quoted
|| strchr("\\\"`\n$",c
)))
104 else if(c
=='`' || (c
=='$' && *cp
=='('))
111 /* only the shell can parse the rest */
115 else if(!quoted
&& strchr("|&\n;<>"+ac
,c
))
120 else if(c
=='(') /* allow | and & inside pattern */
126 if(!(iop
= sfpopen((Sfio_t
*)0,stakptr(0),"r")))
133 while((c
=sfgetc(iop
)) != EOF
)
137 else if(!quoted
&& (c
==' ' || c
=='\n'))
146 if(c
==3 || !(flags
&WRDE_UNDEF
))
153 if(flags
&WRDE_DOOFFS
)
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*));
166 return(WRDE_NOSPACE
);
168 if(!(cp
= (char*)malloc(sizeof(char*)+c
)))
173 ((struct list
*)cp
)->next
= (struct list
*)(*av
);
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
);
193 stakset(savebase
,offset
);
200 * free fields in <wdarg>
202 int wordfree(register wordexp_t
*wdarg
)
204 struct list
*arg
, *argnext
;
207 argnext
= (struct list
*)wdarg
->we_wordv
[-1];
213 free((void*)&wdarg
->we_wordv
[-1]);