xref: /csrg-svn/local/toolchest/ksh/sh/args.c (revision 35126)
1*35126Smarc /*
2*35126Smarc 
3*35126Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35126Smarc  *      All Rights Reserved
5*35126Smarc 
6*35126Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35126Smarc  *      CODE OF AT&T.
8*35126Smarc  *      The copyright notice above does not
9*35126Smarc  *      evidence any actual or intended
10*35126Smarc  *      publication of such source code.
11*35126Smarc 
12*35126Smarc  */
13*35126Smarc /* @(#)args.c	1.1 */
14*35126Smarc /*
15*35126Smarc  * UNIX shell
16*35126Smarc  *
17*35126Smarc  * S. R. Bourne
18*35126Smarc  * Rewritten by David Korn
19*35126Smarc  * AT&T Bell Laboratories
20*35126Smarc  *
21*35126Smarc  */
22*35126Smarc 
23*35126Smarc #include	"flags.h"
24*35126Smarc #include	"defs.h"
25*35126Smarc #include	"sym.h"
26*35126Smarc #include	"mode.h"
27*35126Smarc #include	"name.h"
28*35126Smarc #include	"io.h"
29*35126Smarc #include	"builtins.h"
30*35126Smarc #include	"brkincr.h"
31*35126Smarc #include	"stak.h"
32*35126Smarc #ifdef DEVFD
33*35126Smarc # ifdef JOBS
34*35126Smarc #include	"jobs.h"
35*35126Smarc # endif /* JOBS */
36*35126Smarc #endif	/* DEVFD */
37*35126Smarc 
38*35126Smarc 
39*35126Smarc void	arg_set();
40*35126Smarc void	arg_reset();
41*35126Smarc void	arg_clear();
42*35126Smarc DOLPTR	arg_free();
43*35126Smarc DOLPTR	arg_use();
44*35126Smarc DOLPTR	arg_new();
45*35126Smarc int	arg_opts();
46*35126Smarc char	**arg_build();
47*35126Smarc char	*arg_dolminus();
48*35126Smarc #ifdef DEVFD
49*35126Smarc void	close_pipes();
50*35126Smarc #endif	/* DEVFD */
51*35126Smarc 
52*35126Smarc extern char *malloc();
53*35126Smarc extern char *macro();
54*35126Smarc extern char *movstr();
55*35126Smarc extern char *strchr();
56*35126Smarc extern char *itos();
57*35126Smarc extern void assign();
58*35126Smarc extern void failed();
59*35126Smarc extern void chkpipe();
60*35126Smarc extern void exitsh();
61*35126Smarc extern void free();
62*35126Smarc extern void gsort();
63*35126Smarc extern void trim();
64*35126Smarc extern void p_str();
65*35126Smarc extern void p_nchr();
66*35126Smarc extern void p_setout();
67*35126Smarc extern char *qvalup();
68*35126Smarc 
69*35126Smarc static int	arg_expand();
70*35126Smarc static DOLPTR	copyargs();
71*35126Smarc static void	print_opts();
72*35126Smarc static int	split();
73*35126Smarc 
74*35126Smarc static char	*null;
75*35126Smarc static DOLPTR argfor;	/* linked list of blocks to be cleaned up */
76*35126Smarc static DOLPTR dolh;
77*35126Smarc static char flagadr[12];
78*35126Smarc static const char flagchar[] =
79*35126Smarc {
80*35126Smarc 	'i',	'n',	'v',	't',	's',	'x',	'e',	'r',	'k',
81*35126Smarc 	'u', 'f',	'a',	'm',	'h',	'p',	'c', 0
82*35126Smarc };
83*35126Smarc static const optflag flagval[]  =
84*35126Smarc {
85*35126Smarc 	INTFLG,	NOEXEC,	READPR,	ONEFLG, STDFLG,	EXECPR,	ERRFLG,	RSHFLG,	KEYFLG,
86*35126Smarc 	NOSET,	NOGLOB,	ALLEXP,	MONITOR, HASHALL, PRIVM, CFLAG, 0
87*35126Smarc };
88*35126Smarc 
89*35126Smarc /* ======== option handling	======== */
90*35126Smarc 
91*35126Smarc /*
92*35126Smarc  *  This routine turns options on and off
93*35126Smarc  *  The options "sicr" are illegal from set command.
94*35126Smarc  *  The -o option is used to set option by name
95*35126Smarc  *  This routine returns the number of non-option arguments
96*35126Smarc  */
97*35126Smarc 
arg_opts(argc,argv)98*35126Smarc int arg_opts(argc,argv)
99*35126Smarc char **argv;
100*35126Smarc int  argc;
101*35126Smarc {
102*35126Smarc 	register char *cp;
103*35126Smarc 	register int c;
104*35126Smarc 	register char **argp=argv;
105*35126Smarc 	register char *flagc;
106*35126Smarc 	register optflag newflags=flags;
107*35126Smarc 	register optflag opt;
108*35126Smarc 	char minus;
109*35126Smarc 	int sort = 0;
110*35126Smarc 	int setflag = eq(*argp,bset);
111*35126Smarc 	while((cp= *++argp) && ((c= *cp) == '-' || c=='+'))
112*35126Smarc 	{
113*35126Smarc 		minus = (c == '-');
114*35126Smarc 		argc--;
115*35126Smarc 		if((c= *++cp)==0)
116*35126Smarc 		{
117*35126Smarc 			newflags &= ~(EXECPR|READPR);
118*35126Smarc 			argp++;
119*35126Smarc 			break;
120*35126Smarc 		}
121*35126Smarc 		else if(c == '-')
122*35126Smarc 		{
123*35126Smarc 			if(setflag)
124*35126Smarc 				states |= RWAIT;
125*35126Smarc 			argp++;
126*35126Smarc 			break;
127*35126Smarc 		}
128*35126Smarc 		while(c= *cp++)
129*35126Smarc 		{
130*35126Smarc 			if(setflag)
131*35126Smarc 			{
132*35126Smarc 				if(c=='s')
133*35126Smarc 				{
134*35126Smarc 					sort++;
135*35126Smarc 					continue;
136*35126Smarc 				}
137*35126Smarc 				else if(strchr("icr",c))
138*35126Smarc 					failed(argv[1], badopt);
139*35126Smarc 			}
140*35126Smarc 			if(c=='c' && minus && argc>=2 && comdiv==0)
141*35126Smarc 			{
142*35126Smarc 				comdiv= *++argp;
143*35126Smarc 				argc--;
144*35126Smarc 				newflags |= CFLAG;
145*35126Smarc 				continue;
146*35126Smarc 			}
147*35126Smarc 			if(flagc=strchr(flagchar,c))
148*35126Smarc 				opt = flagval[flagc-flagchar];
149*35126Smarc 			else if(c != 'o')
150*35126Smarc 				failed(argv[1],badopt);
151*35126Smarc 			else
152*35126Smarc 			{
153*35126Smarc 				argp++;
154*35126Smarc 				if(*argp==NULL)
155*35126Smarc 				{
156*35126Smarc 					print_opts(newflags);
157*35126Smarc 					argp--;
158*35126Smarc 					continue;
159*35126Smarc 				}
160*35126Smarc 				else
161*35126Smarc 				{
162*35126Smarc 					argc--;
163*35126Smarc 					c=syslook(*argp,option_flags);
164*35126Smarc 					opt = 1L<<c;
165*35126Smarc 					if(opt&(1|INTFLG|RSHFLG))
166*35126Smarc 						failed(*argp,badopt);
167*35126Smarc 				}
168*35126Smarc 			}
169*35126Smarc 			if(minus)
170*35126Smarc 			{
171*35126Smarc #if ESH || VSH
172*35126Smarc 				if(opt&(EDITVI|EMACS|GMACS))
173*35126Smarc 					newflags &= ~ (EDITVI|EMACS|GMACS);
174*35126Smarc #endif
175*35126Smarc 				newflags |= opt;
176*35126Smarc 			}
177*35126Smarc 			else
178*35126Smarc 				newflags &= ~opt;
179*35126Smarc 		}
180*35126Smarc 	}
181*35126Smarc 	/* cannot set -n for interactive shells since there is no way out */
182*35126Smarc 	if(is_option(INTFLG))
183*35126Smarc 		newflags &= ~NOEXEC;
184*35126Smarc #ifdef RAWONLY
185*35126Smarc 	if(is_option(EDITVI))
186*35126Smarc 		newflags |= VIRAW;
187*35126Smarc #endif	/* RAWONLY */
188*35126Smarc 	if(sort)
189*35126Smarc 	{
190*35126Smarc 		if(argc>1)
191*35126Smarc 			gsort(argp,argc-1);
192*35126Smarc 		else
193*35126Smarc 			gsort(dolv+1,dolc);
194*35126Smarc 	}
195*35126Smarc 	if((newflags&PRIVM) && !is_option(PRIVM))
196*35126Smarc 		assign(PATHNOD,defpath);
197*35126Smarc 	flags = newflags;
198*35126Smarc 	return(argc);
199*35126Smarc }
200*35126Smarc 
201*35126Smarc /*
202*35126Smarc  * returns the value of $-
203*35126Smarc  */
204*35126Smarc 
arg_dolminus()205*35126Smarc char *arg_dolminus()
206*35126Smarc {
207*35126Smarc 	register char *flagc=flagchar;
208*35126Smarc 	register char *flagp=flagadr;
209*35126Smarc 	while(*flagc)
210*35126Smarc 	{
211*35126Smarc 		if(flags&flagval[flagc-flagchar])
212*35126Smarc 			*flagp++ = *flagc;
213*35126Smarc 		flagc++;
214*35126Smarc 	}
215*35126Smarc 	*flagp++=0;
216*35126Smarc 	return(flagadr);
217*35126Smarc }
218*35126Smarc 
219*35126Smarc /*
220*35126Smarc  * set up positional parameters
221*35126Smarc  */
222*35126Smarc 
arg_set(argi)223*35126Smarc void arg_set(argi)
224*35126Smarc char *argi[];
225*35126Smarc {
226*35126Smarc 	register char **argp=argi;
227*35126Smarc 	register int size = 0; /* count number of bytes needed for strings */
228*35126Smarc 	register int 	argn=0;
229*35126Smarc 	register char *cp;
230*35126Smarc 	/* count args and number of bytes of arglist */
231*35126Smarc 	while((cp=(char*)*argp++) != ENDARGS)
232*35126Smarc 	{
233*35126Smarc 		size += strlen(cp);
234*35126Smarc 	}
235*35126Smarc 	/* free old ones unless on for loop chain */
236*35126Smarc 	argn = argp - argi;
237*35126Smarc 	arg_free(dolh,0);
238*35126Smarc 	dolh=copyargs(argi, --argn, size);
239*35126Smarc 	dolc=argn-1;
240*35126Smarc }
241*35126Smarc 
242*35126Smarc /*
243*35126Smarc  * free the argument list if the use count is 1
244*35126Smarc  * If count is greater than 1 decrement count and return same blk
245*35126Smarc  * Free the argument list if the use count is 1 and return next blk
246*35126Smarc  * Delete the blk from the argfor chain
247*35126Smarc  * If flag is set, then the block dolh is not freed
248*35126Smarc  */
249*35126Smarc 
arg_free(blk,flag)250*35126Smarc DOLPTR arg_free(blk,flag)
251*35126Smarc DOLPTR 	blk;
252*35126Smarc {
253*35126Smarc 	register DOLPTR	argr=blk;
254*35126Smarc 	register DOLPTR	argblk;
255*35126Smarc 	if(argblk=argr)
256*35126Smarc 	{
257*35126Smarc 		if((--argblk->doluse)==0)
258*35126Smarc 		{
259*35126Smarc 			if(flag && argblk==dolh)
260*35126Smarc 				dolh->doluse = 1;
261*35126Smarc 			else
262*35126Smarc 			{
263*35126Smarc 				/* delete from chain */
264*35126Smarc 				if(argfor == argblk)
265*35126Smarc 					argfor = argblk->dolnxt;
266*35126Smarc 				else
267*35126Smarc 				{
268*35126Smarc 					for(argr=argfor;argr;argr=argr->dolnxt)
269*35126Smarc 						if(argr->dolnxt==argblk)
270*35126Smarc 							break;
271*35126Smarc 					if(argr==0)
272*35126Smarc 					{
273*35126Smarc 						return(NULL);
274*35126Smarc 					}
275*35126Smarc 					argr->dolnxt = argblk->dolnxt;
276*35126Smarc 				}
277*35126Smarc 				free((char*)argblk);
278*35126Smarc 			}
279*35126Smarc 			argr = argblk->dolnxt;
280*35126Smarc 		}
281*35126Smarc 	}
282*35126Smarc 	return(argr);
283*35126Smarc }
284*35126Smarc 
285*35126Smarc /*
286*35126Smarc  * grab space for arglist and link argblock for cleanup
287*35126Smarc  * The strings are copied after the argment vector
288*35126Smarc  */
289*35126Smarc 
copyargs(from,n,size)290*35126Smarc static DOLPTR copyargs(from, n, size)
291*35126Smarc char *from[];
292*35126Smarc {
293*35126Smarc 	register DOLPTR dp=(DOLPTR)malloc((unsigned)(DOLTYPE + n*sizeof(char*) + size + n));
294*35126Smarc 	register char **pp;
295*35126Smarc 	register char *sp;
296*35126Smarc 	dp->doluse=1;	/* use count */
297*35126Smarc 	/* link into chain */
298*35126Smarc 	dp->dolnxt = argfor;
299*35126Smarc 	argfor = dp;
300*35126Smarc 	pp= dp->dolarg;
301*35126Smarc 	dolv=pp;
302*35126Smarc 	sp = (char*)dp + DOLTYPE + n*sizeof(char*);
303*35126Smarc 	while(n--)
304*35126Smarc 	{
305*35126Smarc 		*pp++ = sp;
306*35126Smarc 		sp = movstr(*from++,sp) + 1;
307*35126Smarc 	}
308*35126Smarc 	*pp = ENDARGS;
309*35126Smarc 	return(dp);
310*35126Smarc }
311*35126Smarc 
312*35126Smarc /*
313*35126Smarc  *  used to set new argument chain for functions
314*35126Smarc  */
315*35126Smarc 
arg_new(argi,savargfor)316*35126Smarc DOLPTR arg_new(argi,savargfor)
317*35126Smarc char *argi[];
318*35126Smarc DOLPTR *savargfor;
319*35126Smarc {
320*35126Smarc 	register DOLPTR olddolh = dolh;
321*35126Smarc 	*savargfor = argfor;
322*35126Smarc 	dolh = NULL;
323*35126Smarc 	argfor = NULL;
324*35126Smarc 	arg_set(argi);
325*35126Smarc 	return(olddolh);
326*35126Smarc }
327*35126Smarc 
328*35126Smarc /*
329*35126Smarc  * reset arguments as they were before function
330*35126Smarc  */
331*35126Smarc 
arg_reset(blk,afor)332*35126Smarc void arg_reset(blk,afor)
333*35126Smarc DOLPTR blk;
334*35126Smarc DOLPTR afor;
335*35126Smarc {
336*35126Smarc 	while(argfor=arg_free(argfor,0));
337*35126Smarc 	dolh = blk;
338*35126Smarc 	argfor = afor;
339*35126Smarc }
340*35126Smarc 
arg_clear()341*35126Smarc void arg_clear()
342*35126Smarc {
343*35126Smarc 	/* force `for' $* lists to go away */
344*35126Smarc 	while(argfor=arg_free(argfor,1));
345*35126Smarc 	/* clean up io files */
346*35126Smarc 	argfor = dolh;
347*35126Smarc 	while(pop(0));
348*35126Smarc #ifdef DEVFD
349*35126Smarc 	close_pipes();
350*35126Smarc #endif	/* DEVFD */
351*35126Smarc }
352*35126Smarc 
353*35126Smarc /*
354*35126Smarc  * increase the use count so that an arg_set will not make it go away
355*35126Smarc  */
356*35126Smarc 
arg_use()357*35126Smarc DOLPTR arg_use()
358*35126Smarc {
359*35126Smarc 	register DOLPTR dh;
360*35126Smarc 	if(dh=dolh)
361*35126Smarc 		dh->doluse++;
362*35126Smarc 	return(dh);
363*35126Smarc }
364*35126Smarc 
365*35126Smarc /*
366*35126Smarc  *  Print option settings on standard output
367*35126Smarc  */
368*35126Smarc 
print_opts(oflags)369*35126Smarc static void print_opts(oflags)
370*35126Smarc #ifndef pdp11
371*35126Smarc register
372*35126Smarc #endif	/* pdp11 */
373*35126Smarc optflag oflags;
374*35126Smarc {
375*35126Smarc 	register SYSPTR	syscan = option_flags;
376*35126Smarc #ifndef pdp11
377*35126Smarc 	register
378*35126Smarc #endif	/* pdp11 */
379*35126Smarc 	optflag value;
380*35126Smarc 	p_setout(standout);
381*35126Smarc 	p_str(opt_heading,NL);
382*35126Smarc 	while(value=syscan->sysval)
383*35126Smarc 	{
384*35126Smarc 		value = 1<<value;
385*35126Smarc 		p_str(syscan->sysnam,SP);
386*35126Smarc 		p_nchr(SP,16-strlen(syscan->sysnam));
387*35126Smarc 		if(oflags&value)
388*35126Smarc 			p_str(on_,NL);
389*35126Smarc 		else
390*35126Smarc 			p_str(off_,NL);
391*35126Smarc 		syscan++;
392*35126Smarc 	}
393*35126Smarc }
394*35126Smarc 
395*35126Smarc 
396*35126Smarc /*
397*35126Smarc  * build an argument list
398*35126Smarc  */
399*35126Smarc 
arg_build(nargs,comptr)400*35126Smarc char **arg_build(nargs,comptr)
401*35126Smarc int 	*nargs;
402*35126Smarc COMPTR	comptr;
403*35126Smarc {
404*35126Smarc 	register ARGPTR	argp;
405*35126Smarc 	{
406*35126Smarc 		register COMPTR	ac = comptr;
407*35126Smarc 		register ARGPTR	schain;
408*35126Smarc 		/* see if the arguments have already been expanded */
409*35126Smarc 		if(ac->comarg==NULL)
410*35126Smarc 		{
411*35126Smarc 			*nargs = 0;
412*35126Smarc 			return(&null);
413*35126Smarc 		}
414*35126Smarc 		else if((ac->comtyp&COMSCAN)==0)
415*35126Smarc 		{
416*35126Smarc 			*nargs = ((DOLPTR)ac->comarg)->doluse;
417*35126Smarc 			return(((DOLPTR)ac->comarg)->dolarg+1);
418*35126Smarc 		}
419*35126Smarc 		schain = gchain;
420*35126Smarc 		gchain = NULL;
421*35126Smarc 		*nargs = arg_expand(ac);
422*35126Smarc 		argp = gchain;
423*35126Smarc 		gchain = schain;
424*35126Smarc 	}
425*35126Smarc 	{
426*35126Smarc 		register char	**comargn;
427*35126Smarc 		register int	argn;
428*35126Smarc 		register char	**comargm;
429*35126Smarc 		argn = *nargs;
430*35126Smarc 		argn++;	/* allow room to prepend interpreter name */
431*35126Smarc 		comargn=(char **) getstak(BYTESPERWORD*argn+BYTESPERWORD);
432*35126Smarc 		comargm = comargn += argn;
433*35126Smarc 		*comargn = ENDARGS;
434*35126Smarc 		while(argp)
435*35126Smarc 		{
436*35126Smarc 			*--comargn = argp->argval;
437*35126Smarc 			if((argp->argflag&A_RAW)==0)
438*35126Smarc 				trim(*comargn);
439*35126Smarc 			if((argp=argp->argchn)==0 || (argp->argflag&A_MAKE))
440*35126Smarc 			{
441*35126Smarc 				if((argn=comargm-comargn)>1)
442*35126Smarc 					gsort(comargn,argn);
443*35126Smarc 				comargm = comargn;
444*35126Smarc 			}
445*35126Smarc 		}
446*35126Smarc 		return(comargn);
447*35126Smarc 	}
448*35126Smarc }
449*35126Smarc 
450*35126Smarc #ifdef DEVFD
451*35126Smarc static FILE *to_close[15];
452*35126Smarc 
close_pipes()453*35126Smarc void close_pipes()
454*35126Smarc {
455*35126Smarc 	register FILE **fd = to_close;
456*35126Smarc 	while(*fd)
457*35126Smarc 	{
458*35126Smarc 		fclose(*fd);
459*35126Smarc 		*fd++ = NULL;
460*35126Smarc 	}
461*35126Smarc }
462*35126Smarc #endif	/* DEVFD */
463*35126Smarc 
464*35126Smarc /* Argument list generation */
465*35126Smarc 
arg_expand(ac)466*35126Smarc static int arg_expand(ac)
467*35126Smarc COMPTR		ac;
468*35126Smarc {
469*35126Smarc 	register ARGPTR	argp;
470*35126Smarc 	register int 	count=0;
471*35126Smarc #ifdef DEVFD
472*35126Smarc 	int indx = 0;
473*35126Smarc 	close_pipes();
474*35126Smarc #endif	/* DEVFD */
475*35126Smarc 	if(ac)
476*35126Smarc 	{
477*35126Smarc 		argp = ac->comarg;
478*35126Smarc 		while(argp)
479*35126Smarc 		{
480*35126Smarc 			argp->argflag &= ~A_MAKE;
481*35126Smarc #ifdef DEVFD
482*35126Smarc 			if(*argp->argval==0 && (argp->argflag&A_EXP))
483*35126Smarc 			{
484*35126Smarc 				/* argument of the form (cmd) */
485*35126Smarc 				register ARGPTR ap;
486*35126Smarc 				char *cp;
487*35126Smarc 				FILE *pv[2];
488*35126Smarc 				int fd;
489*35126Smarc 				ap = (ARGPTR)locstak();
490*35126Smarc 				ap->argflag |= A_MAKE;
491*35126Smarc 				ap->argflag &= ~A_RAW;
492*35126Smarc 				ap->argchn= gchain;
493*35126Smarc 				gchain = ap;
494*35126Smarc 				count++;
495*35126Smarc 				cp = movstr(devfd,ap->argval);
496*35126Smarc 				chkpipe(pv);
497*35126Smarc 				fd = argp->argflag&A_RAW;
498*35126Smarc 				endstak(movstr(itos(fileno(pv[fd])),cp));
499*35126Smarc 				if(fd)
500*35126Smarc 					execute((TREPTR)argp->argchn,states&ERRFLG,pv,(FILE**)0);
501*35126Smarc 				else
502*35126Smarc 					execute((TREPTR)argp->argchn,states&ERRFLG,(FILE**)0,pv);
503*35126Smarc #ifdef JOBS
504*35126Smarc 				jobstat.j_flag++;
505*35126Smarc #endif	/* JOBS */
506*35126Smarc 				fclose(pv[1-fd]);
507*35126Smarc 				to_close[indx++] = pv[fd];
508*35126Smarc 			}
509*35126Smarc 			else
510*35126Smarc #endif	/* DEVFD */
511*35126Smarc 			if((argp->argflag&A_RAW)==0)
512*35126Smarc 			{
513*35126Smarc 				register char *ap; ap = argp->argval;
514*35126Smarc 				if(argp->argflag&A_MAC)
515*35126Smarc 					ap = macro(ap);
516*35126Smarc 				count += split(ap,argp->argflag&A_MAC);
517*35126Smarc 			}
518*35126Smarc 			else
519*35126Smarc 			{
520*35126Smarc 				argp->argchn= gchain;
521*35126Smarc 				gchain = argp;
522*35126Smarc 				argp->argflag |= A_MAKE;
523*35126Smarc 				count++;
524*35126Smarc 			}
525*35126Smarc 			argp = argp->argnxt;
526*35126Smarc 		}
527*35126Smarc 	}
528*35126Smarc 	return(count);
529*35126Smarc }
530*35126Smarc 
split(s,macflg)531*35126Smarc static int split(s,macflg) /* blank interpretation routine */
532*35126Smarc char *s;
533*35126Smarc {
534*35126Smarc 	register char *argp;
535*35126Smarc 	register int 	c;
536*35126Smarc 	register ARGPTR ap;
537*35126Smarc 	int 	count=0;
538*35126Smarc 	int expflag = (is_option(NOGLOB)==0);
539*35126Smarc 	char *seps = (macflg?qvalup(IFSNOD):NULL);
540*35126Smarc 	if(seps==NULL || *seps==0)
541*35126Smarc 		seps = sptbnl;
542*35126Smarc 	while(1)
543*35126Smarc 	{
544*35126Smarc 		if(trapnote&SIGSET)
545*35126Smarc 			exitsh(SIGFAIL);
546*35126Smarc 		ap = (ARGPTR)locstak();
547*35126Smarc 		argp = ap->argval;
548*35126Smarc 		while(c= *s++)
549*35126Smarc 		{
550*35126Smarc 			if(c == ESCAPE)
551*35126Smarc 			{
552*35126Smarc 				c = *s++;
553*35126Smarc 				if(c!='/')
554*35126Smarc 					*argp++ = ESCAPE;
555*35126Smarc 			}
556*35126Smarc 			else if(strchr(seps,c))
557*35126Smarc 				break;
558*35126Smarc 			if(argp >= brkend)
559*35126Smarc 				setbrk(BRKINCR);
560*35126Smarc 			*argp++ = c;
561*35126Smarc 		}
562*35126Smarc 	/* This allows contiguous visible delimiters to count as delimiters */
563*35126Smarc 		if(argp==ap->argval)
564*35126Smarc 		{
565*35126Smarc 			if(c==0)
566*35126Smarc 				return(count);
567*35126Smarc 			if(macflg==0 || strchr(sptbnl,c))
568*35126Smarc 				continue;
569*35126Smarc 		}
570*35126Smarc 		else if(c==0)
571*35126Smarc 		{
572*35126Smarc 			s--;
573*35126Smarc 		}
574*35126Smarc 		/* file name generation */
575*35126Smarc 		endstak(argp);
576*35126Smarc 		ap->argflag &= ~(A_RAW|A_MAKE);
577*35126Smarc 		if(expflag && (c=expand(ap->argval,0)))
578*35126Smarc 			count += c;
579*35126Smarc 		else
580*35126Smarc 		{
581*35126Smarc 			count++;
582*35126Smarc 			ap->argchn= gchain;
583*35126Smarc 			gchain = ap;
584*35126Smarc 		}
585*35126Smarc 		gchain->argflag |= A_MAKE;
586*35126Smarc 	}
587*35126Smarc }
588