1219b2ee8SDavid du Colombier #include "defs.h"
2219b2ee8SDavid du Colombier
3219b2ee8SDavid du Colombier static int hasslash(char *);
4219b2ee8SDavid du Colombier static int haspercent(char *);
5219b2ee8SDavid du Colombier static void rehash(void);
6219b2ee8SDavid du Colombier
7219b2ee8SDavid du Colombier /* simple linear hash. hash function is sum of
8219b2ee8SDavid du Colombier characters mod hash table size.
9219b2ee8SDavid du Colombier */
10219b2ee8SDavid du Colombier static int
hashloc(char * s)11219b2ee8SDavid du Colombier hashloc(char *s)
12219b2ee8SDavid du Colombier {
13219b2ee8SDavid du Colombier int i;
14219b2ee8SDavid du Colombier int hashval;
15219b2ee8SDavid du Colombier char *t;
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier hashval = 0;
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier for(t=s; *t!='\0' ; ++t)
20219b2ee8SDavid du Colombier hashval += *t;
21219b2ee8SDavid du Colombier
22219b2ee8SDavid du Colombier hashval %= hashsize;
23219b2ee8SDavid du Colombier
24219b2ee8SDavid du Colombier for(i=hashval;
25219b2ee8SDavid du Colombier hashtab[i]!=0 && !equal(s,hashtab[i]->namep);
26219b2ee8SDavid du Colombier i = i >= hashsize-1 ? 0 : i+1) ;
27219b2ee8SDavid du Colombier
28219b2ee8SDavid du Colombier return i;
29219b2ee8SDavid du Colombier }
30219b2ee8SDavid du Colombier
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier nameblkp
srchname(char * s)33219b2ee8SDavid du Colombier srchname(char *s)
34219b2ee8SDavid du Colombier {
35219b2ee8SDavid du Colombier return hashtab[hashloc(s)] ;
36219b2ee8SDavid du Colombier }
37219b2ee8SDavid du Colombier
38219b2ee8SDavid du Colombier
39219b2ee8SDavid du Colombier
40219b2ee8SDavid du Colombier nameblkp
makename(char * s)41219b2ee8SDavid du Colombier makename(char *s)
42219b2ee8SDavid du Colombier {
43219b2ee8SDavid du Colombier nameblkp p;
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier if(nhashed > hashthresh)
46219b2ee8SDavid du Colombier rehash();
47219b2ee8SDavid du Colombier
48219b2ee8SDavid du Colombier ++nhashed;
49219b2ee8SDavid du Colombier hashtab[hashloc(s)] = p = ALLOC(nameblock);
50219b2ee8SDavid du Colombier p->nxtnameblock = firstname;
51219b2ee8SDavid du Colombier p->namep = copys(s); /* make a fresh copy of the string s */
52219b2ee8SDavid du Colombier /* p->linep = 0; p->done = 0; p->septype = 0; p->modtime = 0; */
53219b2ee8SDavid du Colombier
54219b2ee8SDavid du Colombier firstname = p;
55219b2ee8SDavid du Colombier if(mainname==NULL && !haspercent(s) && (*s!='.' || hasslash(s)) )
56219b2ee8SDavid du Colombier mainname = p;
57219b2ee8SDavid du Colombier
58219b2ee8SDavid du Colombier return p;
59219b2ee8SDavid du Colombier }
60219b2ee8SDavid du Colombier
61219b2ee8SDavid du Colombier
62219b2ee8SDavid du Colombier static int
hasslash(char * s)63219b2ee8SDavid du Colombier hasslash(char *s)
64219b2ee8SDavid du Colombier {
65219b2ee8SDavid du Colombier for( ; *s ; ++s)
66219b2ee8SDavid du Colombier if(*s == '/')
67219b2ee8SDavid du Colombier return YES;
68219b2ee8SDavid du Colombier return NO;
69219b2ee8SDavid du Colombier }
70219b2ee8SDavid du Colombier
71219b2ee8SDavid du Colombier static int
haspercent(char * s)72219b2ee8SDavid du Colombier haspercent(char *s)
73219b2ee8SDavid du Colombier {
74219b2ee8SDavid du Colombier for( ; *s ; ++s)
75219b2ee8SDavid du Colombier if(*s == '%')
76219b2ee8SDavid du Colombier return YES;
77219b2ee8SDavid du Colombier return NO;
78219b2ee8SDavid du Colombier }
79219b2ee8SDavid du Colombier
80219b2ee8SDavid du Colombier int
hasparen(char * s)81219b2ee8SDavid du Colombier hasparen(char *s)
82219b2ee8SDavid du Colombier {
83219b2ee8SDavid du Colombier for( ; *s ; ++s)
84219b2ee8SDavid du Colombier if(*s == '(')
85219b2ee8SDavid du Colombier return YES;
86219b2ee8SDavid du Colombier return NO;
87219b2ee8SDavid du Colombier }
88219b2ee8SDavid du Colombier
89219b2ee8SDavid du Colombier static void
rehash(void)90219b2ee8SDavid du Colombier rehash(void)
91219b2ee8SDavid du Colombier {
92219b2ee8SDavid du Colombier nameblkp *ohash;
93219b2ee8SDavid du Colombier nameblkp p, *hp, *endohash;
94219b2ee8SDavid du Colombier hp = ohash = hashtab;
95219b2ee8SDavid du Colombier endohash = hashtab + hashsize;
96219b2ee8SDavid du Colombier
97219b2ee8SDavid du Colombier newhash(2*hashsize);
98219b2ee8SDavid du Colombier
99219b2ee8SDavid du Colombier while( hp<endohash )
100219b2ee8SDavid du Colombier if(p = *hp++)
101219b2ee8SDavid du Colombier hashtab[hashloc(p->namep)] = p;
102219b2ee8SDavid du Colombier
103219b2ee8SDavid du Colombier free( (char *) ohash);
104219b2ee8SDavid du Colombier }
105219b2ee8SDavid du Colombier
106219b2ee8SDavid du Colombier
107219b2ee8SDavid du Colombier void
newhash(int newsize)108219b2ee8SDavid du Colombier newhash(int newsize)
109219b2ee8SDavid du Colombier {
110219b2ee8SDavid du Colombier hashsize = newsize;
111219b2ee8SDavid du Colombier hashtab = (nameblkp *) ckalloc(hashsize * sizeof(nameblkp));
112219b2ee8SDavid du Colombier hashthresh = (2*hashsize)/3;
113219b2ee8SDavid du Colombier }
114219b2ee8SDavid du Colombier
115219b2ee8SDavid du Colombier
116219b2ee8SDavid du Colombier
chkname(char * s)117219b2ee8SDavid du Colombier nameblkp chkname(char *s)
118219b2ee8SDavid du Colombier {
119219b2ee8SDavid du Colombier nameblkp p;
120219b2ee8SDavid du Colombier time_t k;
121219b2ee8SDavid du Colombier /*TEMP NEW */
122219b2ee8SDavid du Colombier if(hasparen(s))
123219b2ee8SDavid du Colombier {
124219b2ee8SDavid du Colombier k = lookarch(s);
125219b2ee8SDavid du Colombier /*TEMP fprintf(stderr, "chkname(%s): look=%d\n", s, k); */
126219b2ee8SDavid du Colombier if(k == 0)
127219b2ee8SDavid du Colombier return NULL;
128219b2ee8SDavid du Colombier }
129219b2ee8SDavid du Colombier if(p = srchname(s))
130219b2ee8SDavid du Colombier return p;
131219b2ee8SDavid du Colombier dirsrch(s);
132219b2ee8SDavid du Colombier return srchname(s);
133219b2ee8SDavid du Colombier }
134219b2ee8SDavid du Colombier
135219b2ee8SDavid du Colombier
136219b2ee8SDavid du Colombier
137219b2ee8SDavid du Colombier char *
copys(char * s)138219b2ee8SDavid du Colombier copys(char *s)
139219b2ee8SDavid du Colombier {
140219b2ee8SDavid du Colombier char *t;
141219b2ee8SDavid du Colombier
142219b2ee8SDavid du Colombier if( (t = malloc( strlen(s)+1 ) ) == NULL)
143219b2ee8SDavid du Colombier fatal("out of memory");
144219b2ee8SDavid du Colombier strcpy(t, s);
145219b2ee8SDavid du Colombier return t;
146219b2ee8SDavid du Colombier }
147219b2ee8SDavid du Colombier
148219b2ee8SDavid du Colombier
149219b2ee8SDavid du Colombier
150219b2ee8SDavid du Colombier char *
concat(char * a,char * b,char * c)151219b2ee8SDavid du Colombier concat(char *a, char *b, char *c) /* c = concatenation of a and b */
152219b2ee8SDavid du Colombier {
153219b2ee8SDavid du Colombier char *t;
154219b2ee8SDavid du Colombier t = c;
155219b2ee8SDavid du Colombier
156219b2ee8SDavid du Colombier while(*t = *a++) t++;
157219b2ee8SDavid du Colombier while(*t++ = *b++);
158219b2ee8SDavid du Colombier return c;
159219b2ee8SDavid du Colombier }
160219b2ee8SDavid du Colombier
161219b2ee8SDavid du Colombier
162219b2ee8SDavid du Colombier int
suffix(char * a,char * b,char * p)163219b2ee8SDavid du Colombier suffix(char *a, char *b, char *p) /* is b the suffix of a? if so, set p = prefix */
164219b2ee8SDavid du Colombier {
165219b2ee8SDavid du Colombier char *a0,*b0;
166219b2ee8SDavid du Colombier a0 = a;
167219b2ee8SDavid du Colombier b0 = b;
168219b2ee8SDavid du Colombier
169219b2ee8SDavid du Colombier while(*a++);
170219b2ee8SDavid du Colombier while(*b++);
171219b2ee8SDavid du Colombier
172219b2ee8SDavid du Colombier if( (a-a0) < (b-b0) ) return 0;
173219b2ee8SDavid du Colombier
174219b2ee8SDavid du Colombier while(b>b0)
175219b2ee8SDavid du Colombier if(*--a != *--b) return 0;
176219b2ee8SDavid du Colombier
177219b2ee8SDavid du Colombier while(a0<a) *p++ = *a0++;
178219b2ee8SDavid du Colombier *p = '\0';
179219b2ee8SDavid du Colombier
180219b2ee8SDavid du Colombier return 1;
181219b2ee8SDavid du Colombier }
182219b2ee8SDavid du Colombier
183219b2ee8SDavid du Colombier int *
ckalloc(int n)184219b2ee8SDavid du Colombier ckalloc(int n)
185219b2ee8SDavid du Colombier {
186219b2ee8SDavid du Colombier int *p;
187219b2ee8SDavid du Colombier
188219b2ee8SDavid du Colombier if( p = (int *) calloc(1,n) )
189219b2ee8SDavid du Colombier return p;
190219b2ee8SDavid du Colombier
191219b2ee8SDavid du Colombier fatal("out of memory");
192219b2ee8SDavid du Colombier /* NOTREACHED */
193027288c8SDavid du Colombier return 0;
194219b2ee8SDavid du Colombier }
195219b2ee8SDavid du Colombier
196219b2ee8SDavid du Colombier /* copy string a into b, substituting for arguments */
197219b2ee8SDavid du Colombier char *
subst(char * a,char * b,char * e)198*9b7bf7dfSDavid du Colombier subst(char *a, char *b, char *e)
199219b2ee8SDavid du Colombier {
200219b2ee8SDavid du Colombier static depth = 0;
201219b2ee8SDavid du Colombier char *s;
202219b2ee8SDavid du Colombier char vname[100];
203219b2ee8SDavid du Colombier struct varblock *vbp;
204219b2ee8SDavid du Colombier char closer;
205219b2ee8SDavid du Colombier
206219b2ee8SDavid du Colombier if(++depth > 100)
207219b2ee8SDavid du Colombier fatal("infinitely recursive macro?");
208219b2ee8SDavid du Colombier if(a) while(*a)
209219b2ee8SDavid du Colombier {
210219b2ee8SDavid du Colombier if(*a!='$' || a[1]=='\0' || *++a=='$')
211219b2ee8SDavid du Colombier /* if a non-macro character copy it. if $$ or $\0, copy $ */
212219b2ee8SDavid du Colombier *b++ = *a++;
213219b2ee8SDavid du Colombier else {
214219b2ee8SDavid du Colombier s = vname;
215219b2ee8SDavid du Colombier if( *a=='(' || *a=='{' )
216219b2ee8SDavid du Colombier {
217219b2ee8SDavid du Colombier closer = ( *a=='(' ? ')' : '}');
218219b2ee8SDavid du Colombier ++a;
219219b2ee8SDavid du Colombier while(*a == ' ') ++a;
220219b2ee8SDavid du Colombier while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++;
221219b2ee8SDavid du Colombier while(*a!=closer && *a!='\0') ++a;
222219b2ee8SDavid du Colombier if(*a == closer) ++a;
223219b2ee8SDavid du Colombier }
224219b2ee8SDavid du Colombier else *s++ = *a++;
225219b2ee8SDavid du Colombier
226219b2ee8SDavid du Colombier *s = '\0';
227219b2ee8SDavid du Colombier if( (vbp = varptr(vname)) ->varval != 0)
228219b2ee8SDavid du Colombier {
229*9b7bf7dfSDavid du Colombier b = subst(vbp->varval, b, e);
230219b2ee8SDavid du Colombier vbp->used = YES;
231219b2ee8SDavid du Colombier }
232219b2ee8SDavid du Colombier }
233*9b7bf7dfSDavid du Colombier if(b >= e)
234*9b7bf7dfSDavid du Colombier fatal("macro expanded too far");
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier
237219b2ee8SDavid du Colombier *b = '\0';
238219b2ee8SDavid du Colombier --depth;
239219b2ee8SDavid du Colombier return b;
240219b2ee8SDavid du Colombier }
241219b2ee8SDavid du Colombier
242219b2ee8SDavid du Colombier void
setvar(char * v,char * s,int dyn)243219b2ee8SDavid du Colombier setvar(char *v, char *s, int dyn)
244219b2ee8SDavid du Colombier {
245219b2ee8SDavid du Colombier struct varblock *p;
246219b2ee8SDavid du Colombier
247219b2ee8SDavid du Colombier p = varptr(v);
248219b2ee8SDavid du Colombier if( ! p->noreset )
249219b2ee8SDavid du Colombier {
250219b2ee8SDavid du Colombier p->varval = s;
251219b2ee8SDavid du Colombier p->noreset = inarglist;
252219b2ee8SDavid du Colombier if(p->used && !dyn)
253219b2ee8SDavid du Colombier fprintf(stderr, "Warning: %s changed after being used\n",v);
254219b2ee8SDavid du Colombier if(p->export)
255219b2ee8SDavid du Colombier {
256219b2ee8SDavid du Colombier /* change string pointed to by environment to new v=s */
257219b2ee8SDavid du Colombier char *t;
258219b2ee8SDavid du Colombier int lenv;
259219b2ee8SDavid du Colombier lenv = strlen(v);
260219b2ee8SDavid du Colombier *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2);
261219b2ee8SDavid du Colombier strcpy(t,v);
262219b2ee8SDavid du Colombier t[lenv] = '=';
263219b2ee8SDavid du Colombier strcpy(t+lenv+1, s);
264219b2ee8SDavid du Colombier }
265219b2ee8SDavid du Colombier else
266219b2ee8SDavid du Colombier p->export = envpp;
267219b2ee8SDavid du Colombier }
268219b2ee8SDavid du Colombier }
269219b2ee8SDavid du Colombier
270219b2ee8SDavid du Colombier
271219b2ee8SDavid du Colombier /* for setting Bradford's *D and *F family of macros whens setting * etc */
272219b2ee8SDavid du Colombier void
set3var(char * macro,char * value)273219b2ee8SDavid du Colombier set3var(char *macro, char *value)
274219b2ee8SDavid du Colombier {
275219b2ee8SDavid du Colombier char *s;
276219b2ee8SDavid du Colombier char macjunk[8], *lastslash, *dirpart, *filepart;
277219b2ee8SDavid du Colombier
278219b2ee8SDavid du Colombier setvar(macro, value, YES);
279219b2ee8SDavid du Colombier if(value == CHNULL)
280219b2ee8SDavid du Colombier dirpart = filepart = CHNULL;
281219b2ee8SDavid du Colombier else
282219b2ee8SDavid du Colombier {
283219b2ee8SDavid du Colombier lastslash = CHNULL;
284219b2ee8SDavid du Colombier for(s = value; *s; ++s)
285219b2ee8SDavid du Colombier if(*s == '/')
286219b2ee8SDavid du Colombier lastslash = s;
287219b2ee8SDavid du Colombier if(lastslash)
288219b2ee8SDavid du Colombier {
289219b2ee8SDavid du Colombier dirpart = copys(value);
290219b2ee8SDavid du Colombier filepart = dirpart + (lastslash-value);
291219b2ee8SDavid du Colombier filepart[-1] = '\0';
292219b2ee8SDavid du Colombier }
293219b2ee8SDavid du Colombier else
294219b2ee8SDavid du Colombier {
295219b2ee8SDavid du Colombier dirpart = "";
296219b2ee8SDavid du Colombier filepart = value;
297219b2ee8SDavid du Colombier }
298219b2ee8SDavid du Colombier }
299219b2ee8SDavid du Colombier setvar(concat(macro, "D", macjunk), dirpart, YES);
300219b2ee8SDavid du Colombier setvar(concat(macro, "F", macjunk), filepart, YES);
301219b2ee8SDavid du Colombier }
302219b2ee8SDavid du Colombier
303219b2ee8SDavid du Colombier
304219b2ee8SDavid du Colombier int
eqsign(char * a)305219b2ee8SDavid du Colombier eqsign(char *a) /*look for arguments with equal signs but not colons */
306219b2ee8SDavid du Colombier {
307219b2ee8SDavid du Colombier char *s, *t;
308219b2ee8SDavid du Colombier char c;
309219b2ee8SDavid du Colombier
310219b2ee8SDavid du Colombier while(*a == ' ') ++a;
311219b2ee8SDavid du Colombier for(s=a ; *s!='\0' && *s!=':' ; ++s)
312219b2ee8SDavid du Colombier if(*s == '=')
313219b2ee8SDavid du Colombier {
314219b2ee8SDavid du Colombier for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t );
315219b2ee8SDavid du Colombier c = *t;
316219b2ee8SDavid du Colombier *t = '\0';
317219b2ee8SDavid du Colombier
318219b2ee8SDavid du Colombier for(++s; *s==' ' || *s=='\t' ; ++s);
319219b2ee8SDavid du Colombier setvar(a, copys(s), NO);
320219b2ee8SDavid du Colombier *t = c;
321219b2ee8SDavid du Colombier return YES;
322219b2ee8SDavid du Colombier }
323219b2ee8SDavid du Colombier
324219b2ee8SDavid du Colombier return NO;
325219b2ee8SDavid du Colombier }
326219b2ee8SDavid du Colombier
327219b2ee8SDavid du Colombier struct varblock *
varptr(char * v)328219b2ee8SDavid du Colombier varptr(char *v)
329219b2ee8SDavid du Colombier {
330219b2ee8SDavid du Colombier struct varblock *vp;
331219b2ee8SDavid du Colombier
332219b2ee8SDavid du Colombier /* for compatibility, $(TGS) = $^ */
333219b2ee8SDavid du Colombier if(equal(v, "TGS") )
334219b2ee8SDavid du Colombier v = "^";
335219b2ee8SDavid du Colombier for(vp = firstvar; vp ; vp = vp->nxtvarblock)
336219b2ee8SDavid du Colombier if(equal(v , vp->varname))
337219b2ee8SDavid du Colombier return vp;
338219b2ee8SDavid du Colombier
339219b2ee8SDavid du Colombier vp = ALLOC(varblock);
340219b2ee8SDavid du Colombier vp->nxtvarblock = firstvar;
341219b2ee8SDavid du Colombier firstvar = vp;
342219b2ee8SDavid du Colombier vp->varname = copys(v);
343219b2ee8SDavid du Colombier vp->varval = 0;
344219b2ee8SDavid du Colombier return vp;
345219b2ee8SDavid du Colombier }
346219b2ee8SDavid du Colombier
347219b2ee8SDavid du Colombier int
dynmacro(char * line)348219b2ee8SDavid du Colombier dynmacro(char *line)
349219b2ee8SDavid du Colombier {
350219b2ee8SDavid du Colombier char *s;
351219b2ee8SDavid du Colombier char endc, *endp;
352219b2ee8SDavid du Colombier if(!isalpha(line[0]))
353219b2ee8SDavid du Colombier return NO;
354219b2ee8SDavid du Colombier for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s)
355219b2ee8SDavid du Colombier ;
356219b2ee8SDavid du Colombier endp = s;
357219b2ee8SDavid du Colombier while( isspace(*s) )
358219b2ee8SDavid du Colombier ++s;
359219b2ee8SDavid du Colombier if(s[0]!=':' || s[1]!='=')
360219b2ee8SDavid du Colombier return NO;
361219b2ee8SDavid du Colombier
362219b2ee8SDavid du Colombier endc = *endp;
363219b2ee8SDavid du Colombier *endp = '\0';
364219b2ee8SDavid du Colombier setvar(line, copys(s+2), YES);
365219b2ee8SDavid du Colombier *endp = endc;
366219b2ee8SDavid du Colombier
367219b2ee8SDavid du Colombier return YES;
368219b2ee8SDavid du Colombier }
369219b2ee8SDavid du Colombier
370219b2ee8SDavid du Colombier
371219b2ee8SDavid du Colombier void
fatal1(char * s,char * t)372219b2ee8SDavid du Colombier fatal1(char *s, char *t)
373219b2ee8SDavid du Colombier {
374219b2ee8SDavid du Colombier char buf[100];
375219b2ee8SDavid du Colombier sprintf(buf, s, t);
376219b2ee8SDavid du Colombier fatal(buf);
377219b2ee8SDavid du Colombier }
378219b2ee8SDavid du Colombier
379219b2ee8SDavid du Colombier
380219b2ee8SDavid du Colombier void
fatal(char * s)381219b2ee8SDavid du Colombier fatal(char *s)
382219b2ee8SDavid du Colombier {
383219b2ee8SDavid du Colombier fflush(stdout);
384219b2ee8SDavid du Colombier if(s)
385219b2ee8SDavid du Colombier fprintf(stderr, "Make: %s. Stop.\n", s);
386219b2ee8SDavid du Colombier else
387219b2ee8SDavid du Colombier fprintf(stderr, "\nStop.\n");
388219b2ee8SDavid du Colombier
389219b2ee8SDavid du Colombier waitstack(0);
390219b2ee8SDavid du Colombier exit(1);
391219b2ee8SDavid du Colombier }
392219b2ee8SDavid du Colombier
393219b2ee8SDavid du Colombier
394219b2ee8SDavid du Colombier
395219b2ee8SDavid du Colombier /* appends to the chain for $? and $^ */
396219b2ee8SDavid du Colombier chainp
appendq(chainp head,char * tail)397219b2ee8SDavid du Colombier appendq(chainp head, char *tail)
398219b2ee8SDavid du Colombier {
399219b2ee8SDavid du Colombier chainp p, q;
400219b2ee8SDavid du Colombier
401219b2ee8SDavid du Colombier p = ALLOC(chain);
402219b2ee8SDavid du Colombier p->datap = tail;
403219b2ee8SDavid du Colombier
404219b2ee8SDavid du Colombier if(head)
405219b2ee8SDavid du Colombier {
406219b2ee8SDavid du Colombier for(q = head ; q->nextp ; q = q->nextp)
407219b2ee8SDavid du Colombier ;
408219b2ee8SDavid du Colombier q->nextp = p;
409219b2ee8SDavid du Colombier return head;
410219b2ee8SDavid du Colombier }
411219b2ee8SDavid du Colombier else
412219b2ee8SDavid du Colombier return p;
413219b2ee8SDavid du Colombier }
414219b2ee8SDavid du Colombier
415219b2ee8SDavid du Colombier
416219b2ee8SDavid du Colombier
417219b2ee8SDavid du Colombier
418219b2ee8SDavid du Colombier
419219b2ee8SDavid du Colombier /* builds the value for $? and $^ */
420219b2ee8SDavid du Colombier char *
mkqlist(chainp p,char * qbuf)421219b2ee8SDavid du Colombier mkqlist(chainp p, char *qbuf)
422219b2ee8SDavid du Colombier {
423219b2ee8SDavid du Colombier char *qbufp, *s;
424219b2ee8SDavid du Colombier
425219b2ee8SDavid du Colombier if(p == NULL)
426219b2ee8SDavid du Colombier return "";
427219b2ee8SDavid du Colombier
428219b2ee8SDavid du Colombier qbufp = qbuf;
429219b2ee8SDavid du Colombier
430219b2ee8SDavid du Colombier for( ; p ; p = p->nextp)
431219b2ee8SDavid du Colombier {
432219b2ee8SDavid du Colombier s = p->datap;
433219b2ee8SDavid du Colombier if(qbufp+strlen(s) > &qbuf[QBUFMAX-3])
434219b2ee8SDavid du Colombier {
435219b2ee8SDavid du Colombier fprintf(stderr, "$? list too long\n");
436219b2ee8SDavid du Colombier break;
437219b2ee8SDavid du Colombier }
438219b2ee8SDavid du Colombier while (*s)
439219b2ee8SDavid du Colombier *qbufp++ = *s++;
440219b2ee8SDavid du Colombier *qbufp++ = ' ';
441219b2ee8SDavid du Colombier }
442219b2ee8SDavid du Colombier *--qbufp = '\0';
443219b2ee8SDavid du Colombier return qbuf;
444219b2ee8SDavid du Colombier }
445219b2ee8SDavid du Colombier
446219b2ee8SDavid du Colombier wildp
iswild(char * name)447219b2ee8SDavid du Colombier iswild(char *name)
448219b2ee8SDavid du Colombier {
449219b2ee8SDavid du Colombier char *s;
450219b2ee8SDavid du Colombier wildp p;
451219b2ee8SDavid du Colombier
452219b2ee8SDavid du Colombier for(s=name; *s; ++s)
453219b2ee8SDavid du Colombier if(*s == '%')
454219b2ee8SDavid du Colombier {
455219b2ee8SDavid du Colombier p = ALLOC(wild);
456219b2ee8SDavid du Colombier *s = '\0';
457219b2ee8SDavid du Colombier p->left = copys(name);
458219b2ee8SDavid du Colombier *s = '%';
459219b2ee8SDavid du Colombier p->right = copys(s+1);
460219b2ee8SDavid du Colombier p->llen = strlen(p->left);
461219b2ee8SDavid du Colombier p->rlen = strlen(p->right);
462219b2ee8SDavid du Colombier p->totlen = p->llen + p->rlen;
463219b2ee8SDavid du Colombier return p;
464219b2ee8SDavid du Colombier }
465219b2ee8SDavid du Colombier return NULL;
466219b2ee8SDavid du Colombier }
467219b2ee8SDavid du Colombier
468219b2ee8SDavid du Colombier
469219b2ee8SDavid du Colombier char *
wildmatch(wildp p,char * name,int len)470219b2ee8SDavid du Colombier wildmatch(wildp p, char *name, int len)
471219b2ee8SDavid du Colombier {
472219b2ee8SDavid du Colombier char *stem;
473219b2ee8SDavid du Colombier char *s;
474219b2ee8SDavid du Colombier char c;
475219b2ee8SDavid du Colombier
476219b2ee8SDavid du Colombier if(len < p->totlen ||
477219b2ee8SDavid du Colombier strncmp(name, p->left, p->llen) ||
478219b2ee8SDavid du Colombier strncmp(s = name+len-p->rlen, p->right, p->rlen) )
479219b2ee8SDavid du Colombier return CHNULL;
480219b2ee8SDavid du Colombier
481219b2ee8SDavid du Colombier /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */
482219b2ee8SDavid du Colombier c = *s;
483219b2ee8SDavid du Colombier *s = '\0';
484219b2ee8SDavid du Colombier stem = copys(name + p->llen);
485219b2ee8SDavid du Colombier *s = c;
486219b2ee8SDavid du Colombier return stem;
487219b2ee8SDavid du Colombier }
488219b2ee8SDavid du Colombier
489219b2ee8SDavid du Colombier
490219b2ee8SDavid du Colombier
491219b2ee8SDavid du Colombier /* substitute stem for any % marks */
492219b2ee8SDavid du Colombier char *
wildsub(char * pat,char * stem)493219b2ee8SDavid du Colombier wildsub(char *pat, char *stem)
494219b2ee8SDavid du Colombier {
495219b2ee8SDavid du Colombier static char temp[100];
496219b2ee8SDavid du Colombier char *s, *t;
497219b2ee8SDavid du Colombier
498219b2ee8SDavid du Colombier s = temp;
499219b2ee8SDavid du Colombier for(; *pat; ++pat)
500219b2ee8SDavid du Colombier if(*pat == '%')
501219b2ee8SDavid du Colombier for(t = stem ; *t; )
502219b2ee8SDavid du Colombier *s++ = *t++;
503219b2ee8SDavid du Colombier else
504219b2ee8SDavid du Colombier *s++ = *pat;
505219b2ee8SDavid du Colombier *s = '\0';
506219b2ee8SDavid du Colombier return temp;
507219b2ee8SDavid du Colombier }
508