1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1982-2011 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
18*b30d1939SAndy Fiddaman * *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman * File name expansion
23*b30d1939SAndy Fiddaman *
24*b30d1939SAndy Fiddaman * David Korn
25*b30d1939SAndy Fiddaman * AT&T Labs
26*b30d1939SAndy Fiddaman *
27*b30d1939SAndy Fiddaman */
28*b30d1939SAndy Fiddaman
29*b30d1939SAndy Fiddaman #if KSHELL
30*b30d1939SAndy Fiddaman # include "defs.h"
31*b30d1939SAndy Fiddaman # include "variables.h"
32*b30d1939SAndy Fiddaman # include "test.h"
33*b30d1939SAndy Fiddaman #else
34*b30d1939SAndy Fiddaman # include <ast.h>
35*b30d1939SAndy Fiddaman # include <ctype.h>
36*b30d1939SAndy Fiddaman # include <setjmp.h>
37*b30d1939SAndy Fiddaman #endif /* KSHELL */
38*b30d1939SAndy Fiddaman #include <glob.h>
39*b30d1939SAndy Fiddaman #include <ls.h>
40*b30d1939SAndy Fiddaman #include <stak.h>
41*b30d1939SAndy Fiddaman #include <ast_dir.h>
42*b30d1939SAndy Fiddaman #include "io.h"
43*b30d1939SAndy Fiddaman #include "path.h"
44*b30d1939SAndy Fiddaman
45*b30d1939SAndy Fiddaman #if !SHOPT_BRACEPAT
46*b30d1939SAndy Fiddaman # define SHOPT_BRACEPAT 0
47*b30d1939SAndy Fiddaman #endif
48*b30d1939SAndy Fiddaman
49*b30d1939SAndy Fiddaman #if KSHELL
50*b30d1939SAndy Fiddaman # define argbegin argnxt.cp
51*b30d1939SAndy Fiddaman static const char *sufstr;
52*b30d1939SAndy Fiddaman static int suflen;
53*b30d1939SAndy Fiddaman static int scantree(Dt_t*,const char*, struct argnod**);
54*b30d1939SAndy Fiddaman #else
55*b30d1939SAndy Fiddaman # define sh_sigcheck(sig) (0)
56*b30d1939SAndy Fiddaman # define sh_access access
57*b30d1939SAndy Fiddaman # define suflen 0
58*b30d1939SAndy Fiddaman #endif /* KSHELL */
59*b30d1939SAndy Fiddaman
60*b30d1939SAndy Fiddaman
61*b30d1939SAndy Fiddaman /*
62*b30d1939SAndy Fiddaman * This routine builds a list of files that match a given pathname
63*b30d1939SAndy Fiddaman * Uses external routine strgrpmatch() to match each component
64*b30d1939SAndy Fiddaman * A leading . must match explicitly
65*b30d1939SAndy Fiddaman *
66*b30d1939SAndy Fiddaman */
67*b30d1939SAndy Fiddaman
68*b30d1939SAndy Fiddaman #ifndef GLOB_AUGMENTED
69*b30d1939SAndy Fiddaman # define GLOB_AUGMENTED 0
70*b30d1939SAndy Fiddaman #endif
71*b30d1939SAndy Fiddaman
72*b30d1939SAndy Fiddaman #define GLOB_RESCAN 1
73*b30d1939SAndy Fiddaman #define globptr() ((struct glob*)membase)
74*b30d1939SAndy Fiddaman
75*b30d1939SAndy Fiddaman static struct glob *membase;
76*b30d1939SAndy Fiddaman
77*b30d1939SAndy Fiddaman #if GLOB_VERSION >= 20010916L
nextdir(glob_t * gp,char * dir)78*b30d1939SAndy Fiddaman static char *nextdir(glob_t *gp, char *dir)
79*b30d1939SAndy Fiddaman {
80*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
81*b30d1939SAndy Fiddaman Pathcomp_t *pp = (Pathcomp_t*)gp->gl_handle;
82*b30d1939SAndy Fiddaman if(!dir)
83*b30d1939SAndy Fiddaman pp = path_get(shp,"");
84*b30d1939SAndy Fiddaman else
85*b30d1939SAndy Fiddaman pp = pp->next;
86*b30d1939SAndy Fiddaman gp->gl_handle = (void*)pp;
87*b30d1939SAndy Fiddaman if(pp)
88*b30d1939SAndy Fiddaman return(pp->name);
89*b30d1939SAndy Fiddaman return(0);
90*b30d1939SAndy Fiddaman }
91*b30d1939SAndy Fiddaman #endif
92*b30d1939SAndy Fiddaman
path_expand(Shell_t * shp,const char * pattern,struct argnod ** arghead)93*b30d1939SAndy Fiddaman int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
94*b30d1939SAndy Fiddaman {
95*b30d1939SAndy Fiddaman glob_t gdata;
96*b30d1939SAndy Fiddaman register struct argnod *ap;
97*b30d1939SAndy Fiddaman register glob_t *gp= &gdata;
98*b30d1939SAndy Fiddaman register int flags,extra=0;
99*b30d1939SAndy Fiddaman #if SHOPT_BASH
100*b30d1939SAndy Fiddaman register int off;
101*b30d1939SAndy Fiddaman register char *sp, *cp, *cp2;
102*b30d1939SAndy Fiddaman #endif
103*b30d1939SAndy Fiddaman sh_stats(STAT_GLOBS);
104*b30d1939SAndy Fiddaman memset(gp,0,sizeof(gdata));
105*b30d1939SAndy Fiddaman flags = GLOB_GROUP|GLOB_AUGMENTED|GLOB_NOCHECK|GLOB_NOSORT|GLOB_STACK|GLOB_LIST|GLOB_DISC;
106*b30d1939SAndy Fiddaman if(sh_isoption(SH_MARKDIRS))
107*b30d1939SAndy Fiddaman flags |= GLOB_MARK;
108*b30d1939SAndy Fiddaman if(sh_isoption(SH_GLOBSTARS))
109*b30d1939SAndy Fiddaman flags |= GLOB_STARSTAR;
110*b30d1939SAndy Fiddaman #if SHOPT_BASH
111*b30d1939SAndy Fiddaman #if 0
112*b30d1939SAndy Fiddaman if(sh_isoption(SH_BASH) && !sh_isoption(SH_EXTGLOB))
113*b30d1939SAndy Fiddaman flags &= ~GLOB_AUGMENTED;
114*b30d1939SAndy Fiddaman #endif
115*b30d1939SAndy Fiddaman if(sh_isoption(SH_NULLGLOB))
116*b30d1939SAndy Fiddaman flags &= ~GLOB_NOCHECK;
117*b30d1939SAndy Fiddaman if(sh_isoption(SH_NOCASEGLOB))
118*b30d1939SAndy Fiddaman flags |= GLOB_ICASE;
119*b30d1939SAndy Fiddaman #endif
120*b30d1939SAndy Fiddaman if(sh_isstate(SH_COMPLETE))
121*b30d1939SAndy Fiddaman {
122*b30d1939SAndy Fiddaman #if KSHELL
123*b30d1939SAndy Fiddaman extra += scantree(shp->alias_tree,pattern,arghead);
124*b30d1939SAndy Fiddaman extra += scantree(shp->fun_tree,pattern,arghead);
125*b30d1939SAndy Fiddaman # if GLOB_VERSION >= 20010916L
126*b30d1939SAndy Fiddaman gp->gl_nextdir = nextdir;
127*b30d1939SAndy Fiddaman # endif
128*b30d1939SAndy Fiddaman #endif /* KSHELL */
129*b30d1939SAndy Fiddaman flags |= GLOB_COMPLETE;
130*b30d1939SAndy Fiddaman flags &= ~GLOB_NOCHECK;
131*b30d1939SAndy Fiddaman }
132*b30d1939SAndy Fiddaman #if SHOPT_BASH
133*b30d1939SAndy Fiddaman if(off = staktell())
134*b30d1939SAndy Fiddaman sp = stakfreeze(0);
135*b30d1939SAndy Fiddaman if(sh_isoption(SH_BASH))
136*b30d1939SAndy Fiddaman {
137*b30d1939SAndy Fiddaman /*
138*b30d1939SAndy Fiddaman * For bash, FIGNORE is a colon separated list of suffixes to
139*b30d1939SAndy Fiddaman * ignore when doing filename/command completion.
140*b30d1939SAndy Fiddaman * GLOBIGNORE is similar to ksh FIGNORE, but colon separated
141*b30d1939SAndy Fiddaman * instead of being an augmented shell pattern.
142*b30d1939SAndy Fiddaman * Generate shell patterns out of those here.
143*b30d1939SAndy Fiddaman */
144*b30d1939SAndy Fiddaman if(sh_isstate(SH_FCOMPLETE))
145*b30d1939SAndy Fiddaman cp=nv_getval(sh_scoped(shp,FIGNORENOD));
146*b30d1939SAndy Fiddaman else
147*b30d1939SAndy Fiddaman {
148*b30d1939SAndy Fiddaman static Namval_t *GLOBIGNORENOD;
149*b30d1939SAndy Fiddaman if(!GLOBIGNORENOD)
150*b30d1939SAndy Fiddaman GLOBIGNORENOD = nv_open("GLOBIGNORE",shp->var_tree,0);
151*b30d1939SAndy Fiddaman cp=nv_getval(sh_scoped(shp,GLOBIGNORENOD));
152*b30d1939SAndy Fiddaman }
153*b30d1939SAndy Fiddaman if(cp)
154*b30d1939SAndy Fiddaman {
155*b30d1939SAndy Fiddaman flags |= GLOB_AUGMENTED;
156*b30d1939SAndy Fiddaman stakputs("@(");
157*b30d1939SAndy Fiddaman if(!sh_isstate(SH_FCOMPLETE))
158*b30d1939SAndy Fiddaman {
159*b30d1939SAndy Fiddaman stakputs(cp);
160*b30d1939SAndy Fiddaman for(cp=stakptr(off); *cp; cp++)
161*b30d1939SAndy Fiddaman if(*cp == ':')
162*b30d1939SAndy Fiddaman *cp='|';
163*b30d1939SAndy Fiddaman }
164*b30d1939SAndy Fiddaman else
165*b30d1939SAndy Fiddaman {
166*b30d1939SAndy Fiddaman cp2 = strtok(cp, ":");
167*b30d1939SAndy Fiddaman if(!cp2)
168*b30d1939SAndy Fiddaman cp2=cp;
169*b30d1939SAndy Fiddaman do
170*b30d1939SAndy Fiddaman {
171*b30d1939SAndy Fiddaman stakputc('*');
172*b30d1939SAndy Fiddaman stakputs(cp2);
173*b30d1939SAndy Fiddaman if(cp2 = strtok(NULL, ":"))
174*b30d1939SAndy Fiddaman {
175*b30d1939SAndy Fiddaman *(cp2-1)=':';
176*b30d1939SAndy Fiddaman stakputc('|');
177*b30d1939SAndy Fiddaman }
178*b30d1939SAndy Fiddaman } while(cp2);
179*b30d1939SAndy Fiddaman }
180*b30d1939SAndy Fiddaman stakputc(')');
181*b30d1939SAndy Fiddaman gp->gl_fignore = stakfreeze(1);
182*b30d1939SAndy Fiddaman }
183*b30d1939SAndy Fiddaman else if(!sh_isstate(SH_FCOMPLETE) && sh_isoption(SH_DOTGLOB))
184*b30d1939SAndy Fiddaman gp->gl_fignore = "";
185*b30d1939SAndy Fiddaman }
186*b30d1939SAndy Fiddaman else
187*b30d1939SAndy Fiddaman #endif
188*b30d1939SAndy Fiddaman gp->gl_fignore = nv_getval(sh_scoped(shp,FIGNORENOD));
189*b30d1939SAndy Fiddaman if(suflen)
190*b30d1939SAndy Fiddaman gp->gl_suffix = sufstr;
191*b30d1939SAndy Fiddaman gp->gl_intr = &shp->trapnote;
192*b30d1939SAndy Fiddaman suflen = 0;
193*b30d1939SAndy Fiddaman if(memcmp(pattern,"~(N",3)==0)
194*b30d1939SAndy Fiddaman flags &= ~GLOB_NOCHECK;
195*b30d1939SAndy Fiddaman glob(pattern, flags, 0, gp);
196*b30d1939SAndy Fiddaman #if SHOPT_BASH
197*b30d1939SAndy Fiddaman if(off)
198*b30d1939SAndy Fiddaman stakset(sp,off);
199*b30d1939SAndy Fiddaman else
200*b30d1939SAndy Fiddaman stakseek(0);
201*b30d1939SAndy Fiddaman #endif
202*b30d1939SAndy Fiddaman sh_sigcheck(shp);
203*b30d1939SAndy Fiddaman for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap)
204*b30d1939SAndy Fiddaman {
205*b30d1939SAndy Fiddaman ap->argchn.ap = ap->argnxt.ap;
206*b30d1939SAndy Fiddaman if(!ap->argnxt.ap)
207*b30d1939SAndy Fiddaman ap->argchn.ap = *arghead;
208*b30d1939SAndy Fiddaman }
209*b30d1939SAndy Fiddaman if(gp->gl_list)
210*b30d1939SAndy Fiddaman *arghead = (struct argnod*)gp->gl_list;
211*b30d1939SAndy Fiddaman return(gp->gl_pathc+extra);
212*b30d1939SAndy Fiddaman }
213*b30d1939SAndy Fiddaman
214*b30d1939SAndy Fiddaman #if KSHELL
215*b30d1939SAndy Fiddaman
216*b30d1939SAndy Fiddaman /*
217*b30d1939SAndy Fiddaman * scan tree and add each name that matches the given pattern
218*b30d1939SAndy Fiddaman */
scantree(Dt_t * tree,const char * pattern,struct argnod ** arghead)219*b30d1939SAndy Fiddaman static int scantree(Dt_t *tree, const char *pattern, struct argnod **arghead)
220*b30d1939SAndy Fiddaman {
221*b30d1939SAndy Fiddaman register Namval_t *np;
222*b30d1939SAndy Fiddaman register struct argnod *ap;
223*b30d1939SAndy Fiddaman register int nmatch=0;
224*b30d1939SAndy Fiddaman register char *cp;
225*b30d1939SAndy Fiddaman np = (Namval_t*)dtfirst(tree);
226*b30d1939SAndy Fiddaman for(;np && !nv_isnull(np);(np = (Namval_t*)dtnext(tree,np)))
227*b30d1939SAndy Fiddaman {
228*b30d1939SAndy Fiddaman if(strmatch(cp=nv_name(np),pattern))
229*b30d1939SAndy Fiddaman {
230*b30d1939SAndy Fiddaman ap = (struct argnod*)stakseek(ARGVAL);
231*b30d1939SAndy Fiddaman stakputs(cp);
232*b30d1939SAndy Fiddaman ap = (struct argnod*)stakfreeze(1);
233*b30d1939SAndy Fiddaman ap->argbegin = NIL(char*);
234*b30d1939SAndy Fiddaman ap->argchn.ap = *arghead;
235*b30d1939SAndy Fiddaman ap->argflag = ARG_RAW|ARG_MAKE;
236*b30d1939SAndy Fiddaman *arghead = ap;
237*b30d1939SAndy Fiddaman nmatch++;
238*b30d1939SAndy Fiddaman }
239*b30d1939SAndy Fiddaman }
240*b30d1939SAndy Fiddaman return(nmatch);
241*b30d1939SAndy Fiddaman }
242*b30d1939SAndy Fiddaman
243*b30d1939SAndy Fiddaman /*
244*b30d1939SAndy Fiddaman * file name completion
245*b30d1939SAndy Fiddaman * generate the list of files found by adding an suffix to end of name
246*b30d1939SAndy Fiddaman * The number of matches is returned
247*b30d1939SAndy Fiddaman */
248*b30d1939SAndy Fiddaman
path_complete(Shell_t * shp,const char * name,register const char * suffix,struct argnod ** arghead)249*b30d1939SAndy Fiddaman int path_complete(Shell_t *shp,const char *name,register const char *suffix, struct argnod **arghead)
250*b30d1939SAndy Fiddaman {
251*b30d1939SAndy Fiddaman sufstr = suffix;
252*b30d1939SAndy Fiddaman suflen = strlen(suffix);
253*b30d1939SAndy Fiddaman return(path_expand(shp,name,arghead));
254*b30d1939SAndy Fiddaman }
255*b30d1939SAndy Fiddaman
256*b30d1939SAndy Fiddaman #endif
257*b30d1939SAndy Fiddaman
258*b30d1939SAndy Fiddaman #if SHOPT_BRACEPAT
259*b30d1939SAndy Fiddaman
checkfmt(Sfio_t * sp,void * vp,Sffmt_t * fp)260*b30d1939SAndy Fiddaman static int checkfmt(Sfio_t* sp, void* vp, Sffmt_t* fp)
261*b30d1939SAndy Fiddaman {
262*b30d1939SAndy Fiddaman return -1;
263*b30d1939SAndy Fiddaman }
264*b30d1939SAndy Fiddaman
path_generate(Shell_t * shp,struct argnod * todo,struct argnod ** arghead)265*b30d1939SAndy Fiddaman int path_generate(Shell_t *shp,struct argnod *todo, struct argnod **arghead)
266*b30d1939SAndy Fiddaman /*@
267*b30d1939SAndy Fiddaman assume todo!=0;
268*b30d1939SAndy Fiddaman return count satisfying count>=1;
269*b30d1939SAndy Fiddaman @*/
270*b30d1939SAndy Fiddaman {
271*b30d1939SAndy Fiddaman register char *cp;
272*b30d1939SAndy Fiddaman register int brace;
273*b30d1939SAndy Fiddaman register struct argnod *ap;
274*b30d1939SAndy Fiddaman struct argnod *top = 0;
275*b30d1939SAndy Fiddaman struct argnod *apin;
276*b30d1939SAndy Fiddaman char *pat, *rescan;
277*b30d1939SAndy Fiddaman char *format;
278*b30d1939SAndy Fiddaman char comma, range=0;
279*b30d1939SAndy Fiddaman int first, last, incr, count = 0;
280*b30d1939SAndy Fiddaman char tmp[32], end[1];
281*b30d1939SAndy Fiddaman todo->argchn.ap = 0;
282*b30d1939SAndy Fiddaman again:
283*b30d1939SAndy Fiddaman apin = ap = todo;
284*b30d1939SAndy Fiddaman todo = ap->argchn.ap;
285*b30d1939SAndy Fiddaman cp = ap->argval;
286*b30d1939SAndy Fiddaman range = comma = brace = 0;
287*b30d1939SAndy Fiddaman /* first search for {...,...} */
288*b30d1939SAndy Fiddaman while(1) switch(*cp++)
289*b30d1939SAndy Fiddaman {
290*b30d1939SAndy Fiddaman case '{':
291*b30d1939SAndy Fiddaman if(brace++==0)
292*b30d1939SAndy Fiddaman pat = cp;
293*b30d1939SAndy Fiddaman break;
294*b30d1939SAndy Fiddaman case '}':
295*b30d1939SAndy Fiddaman if(--brace>0)
296*b30d1939SAndy Fiddaman break;
297*b30d1939SAndy Fiddaman if(brace==0 && comma && *cp!='(')
298*b30d1939SAndy Fiddaman goto endloop1;
299*b30d1939SAndy Fiddaman comma = brace = 0;
300*b30d1939SAndy Fiddaman break;
301*b30d1939SAndy Fiddaman case '.':
302*b30d1939SAndy Fiddaman if(brace==1 && *cp=='.')
303*b30d1939SAndy Fiddaman {
304*b30d1939SAndy Fiddaman char *endc;
305*b30d1939SAndy Fiddaman incr = 1;
306*b30d1939SAndy Fiddaman if(isdigit(*pat) || *pat=='+' || *pat=='-')
307*b30d1939SAndy Fiddaman {
308*b30d1939SAndy Fiddaman first = strtol(pat,&endc,0);
309*b30d1939SAndy Fiddaman if(endc==(cp-1))
310*b30d1939SAndy Fiddaman {
311*b30d1939SAndy Fiddaman last = strtol(cp+1,&endc,0);
312*b30d1939SAndy Fiddaman if(*endc=='.' && endc[1]=='.')
313*b30d1939SAndy Fiddaman incr = strtol(endc+2,&endc,0);
314*b30d1939SAndy Fiddaman else if(last<first)
315*b30d1939SAndy Fiddaman incr = -1;
316*b30d1939SAndy Fiddaman if(incr)
317*b30d1939SAndy Fiddaman {
318*b30d1939SAndy Fiddaman if(*endc=='%')
319*b30d1939SAndy Fiddaman {
320*b30d1939SAndy Fiddaman Sffmt_t fmt;
321*b30d1939SAndy Fiddaman memset(&fmt, 0, sizeof(fmt));
322*b30d1939SAndy Fiddaman fmt.version = SFIO_VERSION;
323*b30d1939SAndy Fiddaman fmt.form = endc;
324*b30d1939SAndy Fiddaman fmt.extf = checkfmt;
325*b30d1939SAndy Fiddaman sfprintf(sfstdout, "%!", &fmt);
326*b30d1939SAndy Fiddaman if(!(fmt.flags&(SFFMT_LLONG|SFFMT_LDOUBLE)))
327*b30d1939SAndy Fiddaman switch (fmt.fmt)
328*b30d1939SAndy Fiddaman {
329*b30d1939SAndy Fiddaman case 'c':
330*b30d1939SAndy Fiddaman case 'd':
331*b30d1939SAndy Fiddaman case 'i':
332*b30d1939SAndy Fiddaman case 'o':
333*b30d1939SAndy Fiddaman case 'u':
334*b30d1939SAndy Fiddaman case 'x':
335*b30d1939SAndy Fiddaman case 'X':
336*b30d1939SAndy Fiddaman format = endc;
337*b30d1939SAndy Fiddaman endc = fmt.form;
338*b30d1939SAndy Fiddaman break;
339*b30d1939SAndy Fiddaman }
340*b30d1939SAndy Fiddaman }
341*b30d1939SAndy Fiddaman else
342*b30d1939SAndy Fiddaman format = "%d";
343*b30d1939SAndy Fiddaman if(*endc=='}')
344*b30d1939SAndy Fiddaman {
345*b30d1939SAndy Fiddaman cp = endc+1;
346*b30d1939SAndy Fiddaman range = 2;
347*b30d1939SAndy Fiddaman goto endloop1;
348*b30d1939SAndy Fiddaman }
349*b30d1939SAndy Fiddaman }
350*b30d1939SAndy Fiddaman }
351*b30d1939SAndy Fiddaman }
352*b30d1939SAndy Fiddaman else if((cp[2]=='}' || cp[2]=='.' && cp[3]=='.') && ((*pat>='a' && *pat<='z' && cp[1]>='a' && cp[1]<='z') || (*pat>='A' && *pat<='Z' && cp[1]>='A' && cp[1]<='Z')))
353*b30d1939SAndy Fiddaman {
354*b30d1939SAndy Fiddaman first = *pat;
355*b30d1939SAndy Fiddaman last = cp[1];
356*b30d1939SAndy Fiddaman cp += 2;
357*b30d1939SAndy Fiddaman if(*cp=='.')
358*b30d1939SAndy Fiddaman {
359*b30d1939SAndy Fiddaman incr = strtol(cp+2,&endc,0);
360*b30d1939SAndy Fiddaman cp = endc;
361*b30d1939SAndy Fiddaman }
362*b30d1939SAndy Fiddaman else if(first>last)
363*b30d1939SAndy Fiddaman incr = -1;
364*b30d1939SAndy Fiddaman if(incr && *cp=='}')
365*b30d1939SAndy Fiddaman {
366*b30d1939SAndy Fiddaman cp++;
367*b30d1939SAndy Fiddaman range = 1;
368*b30d1939SAndy Fiddaman goto endloop1;
369*b30d1939SAndy Fiddaman }
370*b30d1939SAndy Fiddaman }
371*b30d1939SAndy Fiddaman cp++;
372*b30d1939SAndy Fiddaman }
373*b30d1939SAndy Fiddaman break;
374*b30d1939SAndy Fiddaman case ',':
375*b30d1939SAndy Fiddaman if(brace==1)
376*b30d1939SAndy Fiddaman comma = 1;
377*b30d1939SAndy Fiddaman break;
378*b30d1939SAndy Fiddaman case '\\':
379*b30d1939SAndy Fiddaman cp++;
380*b30d1939SAndy Fiddaman break;
381*b30d1939SAndy Fiddaman case 0:
382*b30d1939SAndy Fiddaman /* insert on stack */
383*b30d1939SAndy Fiddaman ap->argchn.ap = top;
384*b30d1939SAndy Fiddaman top = ap;
385*b30d1939SAndy Fiddaman if(todo)
386*b30d1939SAndy Fiddaman goto again;
387*b30d1939SAndy Fiddaman for(; ap; ap=apin)
388*b30d1939SAndy Fiddaman {
389*b30d1939SAndy Fiddaman apin = ap->argchn.ap;
390*b30d1939SAndy Fiddaman if(!sh_isoption(SH_NOGLOB))
391*b30d1939SAndy Fiddaman brace=path_expand(shp,ap->argval,arghead);
392*b30d1939SAndy Fiddaman else
393*b30d1939SAndy Fiddaman {
394*b30d1939SAndy Fiddaman ap->argchn.ap = *arghead;
395*b30d1939SAndy Fiddaman *arghead = ap;
396*b30d1939SAndy Fiddaman brace=1;
397*b30d1939SAndy Fiddaman }
398*b30d1939SAndy Fiddaman if(brace)
399*b30d1939SAndy Fiddaman {
400*b30d1939SAndy Fiddaman count += brace;
401*b30d1939SAndy Fiddaman (*arghead)->argflag |= ARG_MAKE;
402*b30d1939SAndy Fiddaman }
403*b30d1939SAndy Fiddaman }
404*b30d1939SAndy Fiddaman return(count);
405*b30d1939SAndy Fiddaman }
406*b30d1939SAndy Fiddaman endloop1:
407*b30d1939SAndy Fiddaman rescan = cp;
408*b30d1939SAndy Fiddaman cp = pat-1;
409*b30d1939SAndy Fiddaman *cp = 0;
410*b30d1939SAndy Fiddaman while(1)
411*b30d1939SAndy Fiddaman {
412*b30d1939SAndy Fiddaman brace = 0;
413*b30d1939SAndy Fiddaman if(range)
414*b30d1939SAndy Fiddaman {
415*b30d1939SAndy Fiddaman if(range==1)
416*b30d1939SAndy Fiddaman {
417*b30d1939SAndy Fiddaman pat[0] = first;
418*b30d1939SAndy Fiddaman cp = &pat[1];
419*b30d1939SAndy Fiddaman }
420*b30d1939SAndy Fiddaman else
421*b30d1939SAndy Fiddaman {
422*b30d1939SAndy Fiddaman *(rescan - 1) = 0;
423*b30d1939SAndy Fiddaman sfsprintf(pat=tmp,sizeof(tmp),format,first);
424*b30d1939SAndy Fiddaman *(rescan - 1) = '}';
425*b30d1939SAndy Fiddaman *(cp = end) = 0;
426*b30d1939SAndy Fiddaman }
427*b30d1939SAndy Fiddaman if(incr*(first+incr) > last*incr)
428*b30d1939SAndy Fiddaman *cp = '}';
429*b30d1939SAndy Fiddaman else
430*b30d1939SAndy Fiddaman first += incr;
431*b30d1939SAndy Fiddaman }
432*b30d1939SAndy Fiddaman /* generate each pattern and put on the todo list */
433*b30d1939SAndy Fiddaman else while(1) switch(*++cp)
434*b30d1939SAndy Fiddaman {
435*b30d1939SAndy Fiddaman case '\\':
436*b30d1939SAndy Fiddaman cp++;
437*b30d1939SAndy Fiddaman break;
438*b30d1939SAndy Fiddaman case '{':
439*b30d1939SAndy Fiddaman brace++;
440*b30d1939SAndy Fiddaman break;
441*b30d1939SAndy Fiddaman case ',':
442*b30d1939SAndy Fiddaman if(brace==0)
443*b30d1939SAndy Fiddaman goto endloop2;
444*b30d1939SAndy Fiddaman break;
445*b30d1939SAndy Fiddaman case '}':
446*b30d1939SAndy Fiddaman if(--brace<0)
447*b30d1939SAndy Fiddaman goto endloop2;
448*b30d1939SAndy Fiddaman }
449*b30d1939SAndy Fiddaman endloop2:
450*b30d1939SAndy Fiddaman brace = *cp;
451*b30d1939SAndy Fiddaman *cp = 0;
452*b30d1939SAndy Fiddaman sh_sigcheck(shp);
453*b30d1939SAndy Fiddaman ap = (struct argnod*)stakseek(ARGVAL);
454*b30d1939SAndy Fiddaman ap->argflag = ARG_RAW;
455*b30d1939SAndy Fiddaman ap->argchn.ap = todo;
456*b30d1939SAndy Fiddaman stakputs(apin->argval);
457*b30d1939SAndy Fiddaman stakputs(pat);
458*b30d1939SAndy Fiddaman stakputs(rescan);
459*b30d1939SAndy Fiddaman todo = ap = (struct argnod*)stakfreeze(1);
460*b30d1939SAndy Fiddaman if(brace == '}')
461*b30d1939SAndy Fiddaman break;
462*b30d1939SAndy Fiddaman if(!range)
463*b30d1939SAndy Fiddaman pat = cp+1;
464*b30d1939SAndy Fiddaman }
465*b30d1939SAndy Fiddaman goto again;
466*b30d1939SAndy Fiddaman }
467*b30d1939SAndy Fiddaman
468*b30d1939SAndy Fiddaman #endif /* SHOPT_BRACEPAT */
469