1*219b2ee8SDavid du Colombier #include "defs.h" 2*219b2ee8SDavid du Colombier 3*219b2ee8SDavid du Colombier static int hasslash(char *); 4*219b2ee8SDavid du Colombier static int haspercent(char *); 5*219b2ee8SDavid du Colombier static void rehash(void); 6*219b2ee8SDavid du Colombier 7*219b2ee8SDavid du Colombier /* simple linear hash. hash function is sum of 8*219b2ee8SDavid du Colombier characters mod hash table size. 9*219b2ee8SDavid du Colombier */ 10*219b2ee8SDavid du Colombier static int 11*219b2ee8SDavid du Colombier hashloc(char *s) 12*219b2ee8SDavid du Colombier { 13*219b2ee8SDavid du Colombier int i; 14*219b2ee8SDavid du Colombier int hashval; 15*219b2ee8SDavid du Colombier char *t; 16*219b2ee8SDavid du Colombier 17*219b2ee8SDavid du Colombier hashval = 0; 18*219b2ee8SDavid du Colombier 19*219b2ee8SDavid du Colombier for(t=s; *t!='\0' ; ++t) 20*219b2ee8SDavid du Colombier hashval += *t; 21*219b2ee8SDavid du Colombier 22*219b2ee8SDavid du Colombier hashval %= hashsize; 23*219b2ee8SDavid du Colombier 24*219b2ee8SDavid du Colombier for(i=hashval; 25*219b2ee8SDavid du Colombier hashtab[i]!=0 && !equal(s,hashtab[i]->namep); 26*219b2ee8SDavid du Colombier i = i >= hashsize-1 ? 0 : i+1) ; 27*219b2ee8SDavid du Colombier 28*219b2ee8SDavid du Colombier return i; 29*219b2ee8SDavid du Colombier } 30*219b2ee8SDavid du Colombier 31*219b2ee8SDavid du Colombier 32*219b2ee8SDavid du Colombier nameblkp 33*219b2ee8SDavid du Colombier srchname(char *s) 34*219b2ee8SDavid du Colombier { 35*219b2ee8SDavid du Colombier return hashtab[hashloc(s)] ; 36*219b2ee8SDavid du Colombier } 37*219b2ee8SDavid du Colombier 38*219b2ee8SDavid du Colombier 39*219b2ee8SDavid du Colombier 40*219b2ee8SDavid du Colombier nameblkp 41*219b2ee8SDavid du Colombier makename(char *s) 42*219b2ee8SDavid du Colombier { 43*219b2ee8SDavid du Colombier nameblkp p; 44*219b2ee8SDavid du Colombier 45*219b2ee8SDavid du Colombier if(nhashed > hashthresh) 46*219b2ee8SDavid du Colombier rehash(); 47*219b2ee8SDavid du Colombier 48*219b2ee8SDavid du Colombier ++nhashed; 49*219b2ee8SDavid du Colombier hashtab[hashloc(s)] = p = ALLOC(nameblock); 50*219b2ee8SDavid du Colombier p->nxtnameblock = firstname; 51*219b2ee8SDavid du Colombier p->namep = copys(s); /* make a fresh copy of the string s */ 52*219b2ee8SDavid du Colombier /* p->linep = 0; p->done = 0; p->septype = 0; p->modtime = 0; */ 53*219b2ee8SDavid du Colombier 54*219b2ee8SDavid du Colombier firstname = p; 55*219b2ee8SDavid du Colombier if(mainname==NULL && !haspercent(s) && (*s!='.' || hasslash(s)) ) 56*219b2ee8SDavid du Colombier mainname = p; 57*219b2ee8SDavid du Colombier 58*219b2ee8SDavid du Colombier return p; 59*219b2ee8SDavid du Colombier } 60*219b2ee8SDavid du Colombier 61*219b2ee8SDavid du Colombier 62*219b2ee8SDavid du Colombier static int 63*219b2ee8SDavid du Colombier hasslash(char *s) 64*219b2ee8SDavid du Colombier { 65*219b2ee8SDavid du Colombier for( ; *s ; ++s) 66*219b2ee8SDavid du Colombier if(*s == '/') 67*219b2ee8SDavid du Colombier return YES; 68*219b2ee8SDavid du Colombier return NO; 69*219b2ee8SDavid du Colombier } 70*219b2ee8SDavid du Colombier 71*219b2ee8SDavid du Colombier static int 72*219b2ee8SDavid du Colombier haspercent(char *s) 73*219b2ee8SDavid du Colombier { 74*219b2ee8SDavid du Colombier for( ; *s ; ++s) 75*219b2ee8SDavid du Colombier if(*s == '%') 76*219b2ee8SDavid du Colombier return YES; 77*219b2ee8SDavid du Colombier return NO; 78*219b2ee8SDavid du Colombier } 79*219b2ee8SDavid du Colombier 80*219b2ee8SDavid du Colombier int 81*219b2ee8SDavid du Colombier hasparen(char *s) 82*219b2ee8SDavid du Colombier { 83*219b2ee8SDavid du Colombier for( ; *s ; ++s) 84*219b2ee8SDavid du Colombier if(*s == '(') 85*219b2ee8SDavid du Colombier return YES; 86*219b2ee8SDavid du Colombier return NO; 87*219b2ee8SDavid du Colombier } 88*219b2ee8SDavid du Colombier 89*219b2ee8SDavid du Colombier static void 90*219b2ee8SDavid du Colombier rehash(void) 91*219b2ee8SDavid du Colombier { 92*219b2ee8SDavid du Colombier nameblkp *ohash; 93*219b2ee8SDavid du Colombier nameblkp p, *hp, *endohash; 94*219b2ee8SDavid du Colombier hp = ohash = hashtab; 95*219b2ee8SDavid du Colombier endohash = hashtab + hashsize; 96*219b2ee8SDavid du Colombier 97*219b2ee8SDavid du Colombier newhash(2*hashsize); 98*219b2ee8SDavid du Colombier 99*219b2ee8SDavid du Colombier while( hp<endohash ) 100*219b2ee8SDavid du Colombier if(p = *hp++) 101*219b2ee8SDavid du Colombier hashtab[hashloc(p->namep)] = p; 102*219b2ee8SDavid du Colombier 103*219b2ee8SDavid du Colombier free( (char *) ohash); 104*219b2ee8SDavid du Colombier } 105*219b2ee8SDavid du Colombier 106*219b2ee8SDavid du Colombier 107*219b2ee8SDavid du Colombier void 108*219b2ee8SDavid du Colombier newhash(int newsize) 109*219b2ee8SDavid du Colombier { 110*219b2ee8SDavid du Colombier hashsize = newsize; 111*219b2ee8SDavid du Colombier hashtab = (nameblkp *) ckalloc(hashsize * sizeof(nameblkp)); 112*219b2ee8SDavid du Colombier hashthresh = (2*hashsize)/3; 113*219b2ee8SDavid du Colombier } 114*219b2ee8SDavid du Colombier 115*219b2ee8SDavid du Colombier 116*219b2ee8SDavid du Colombier 117*219b2ee8SDavid du Colombier nameblkp chkname(char *s) 118*219b2ee8SDavid du Colombier { 119*219b2ee8SDavid du Colombier nameblkp p; 120*219b2ee8SDavid du Colombier time_t k; 121*219b2ee8SDavid du Colombier /*TEMP NEW */ 122*219b2ee8SDavid du Colombier if(hasparen(s)) 123*219b2ee8SDavid du Colombier { 124*219b2ee8SDavid du Colombier k = lookarch(s); 125*219b2ee8SDavid du Colombier /*TEMP fprintf(stderr, "chkname(%s): look=%d\n", s, k); */ 126*219b2ee8SDavid du Colombier if(k == 0) 127*219b2ee8SDavid du Colombier return NULL; 128*219b2ee8SDavid du Colombier } 129*219b2ee8SDavid du Colombier if(p = srchname(s)) 130*219b2ee8SDavid du Colombier return p; 131*219b2ee8SDavid du Colombier dirsrch(s); 132*219b2ee8SDavid du Colombier return srchname(s); 133*219b2ee8SDavid du Colombier } 134*219b2ee8SDavid du Colombier 135*219b2ee8SDavid du Colombier 136*219b2ee8SDavid du Colombier 137*219b2ee8SDavid du Colombier char * 138*219b2ee8SDavid du Colombier copys(char *s) 139*219b2ee8SDavid du Colombier { 140*219b2ee8SDavid du Colombier char *t; 141*219b2ee8SDavid du Colombier 142*219b2ee8SDavid du Colombier if( (t = malloc( strlen(s)+1 ) ) == NULL) 143*219b2ee8SDavid du Colombier fatal("out of memory"); 144*219b2ee8SDavid du Colombier strcpy(t, s); 145*219b2ee8SDavid du Colombier return t; 146*219b2ee8SDavid du Colombier } 147*219b2ee8SDavid du Colombier 148*219b2ee8SDavid du Colombier 149*219b2ee8SDavid du Colombier 150*219b2ee8SDavid du Colombier char * 151*219b2ee8SDavid du Colombier concat(char *a, char *b, char *c) /* c = concatenation of a and b */ 152*219b2ee8SDavid du Colombier { 153*219b2ee8SDavid du Colombier char *t; 154*219b2ee8SDavid du Colombier t = c; 155*219b2ee8SDavid du Colombier 156*219b2ee8SDavid du Colombier while(*t = *a++) t++; 157*219b2ee8SDavid du Colombier while(*t++ = *b++); 158*219b2ee8SDavid du Colombier return c; 159*219b2ee8SDavid du Colombier } 160*219b2ee8SDavid du Colombier 161*219b2ee8SDavid du Colombier 162*219b2ee8SDavid du Colombier int 163*219b2ee8SDavid du Colombier suffix(char *a, char *b, char *p) /* is b the suffix of a? if so, set p = prefix */ 164*219b2ee8SDavid du Colombier { 165*219b2ee8SDavid du Colombier char *a0,*b0; 166*219b2ee8SDavid du Colombier a0 = a; 167*219b2ee8SDavid du Colombier b0 = b; 168*219b2ee8SDavid du Colombier 169*219b2ee8SDavid du Colombier while(*a++); 170*219b2ee8SDavid du Colombier while(*b++); 171*219b2ee8SDavid du Colombier 172*219b2ee8SDavid du Colombier if( (a-a0) < (b-b0) ) return 0; 173*219b2ee8SDavid du Colombier 174*219b2ee8SDavid du Colombier while(b>b0) 175*219b2ee8SDavid du Colombier if(*--a != *--b) return 0; 176*219b2ee8SDavid du Colombier 177*219b2ee8SDavid du Colombier while(a0<a) *p++ = *a0++; 178*219b2ee8SDavid du Colombier *p = '\0'; 179*219b2ee8SDavid du Colombier 180*219b2ee8SDavid du Colombier return 1; 181*219b2ee8SDavid du Colombier } 182*219b2ee8SDavid du Colombier 183*219b2ee8SDavid du Colombier int * 184*219b2ee8SDavid du Colombier ckalloc(int n) 185*219b2ee8SDavid du Colombier { 186*219b2ee8SDavid du Colombier int *p; 187*219b2ee8SDavid du Colombier 188*219b2ee8SDavid du Colombier if( p = (int *) calloc(1,n) ) 189*219b2ee8SDavid du Colombier return p; 190*219b2ee8SDavid du Colombier 191*219b2ee8SDavid du Colombier fatal("out of memory"); 192*219b2ee8SDavid du Colombier /* NOTREACHED */ 193*219b2ee8SDavid du Colombier } 194*219b2ee8SDavid du Colombier 195*219b2ee8SDavid du Colombier /* copy string a into b, substituting for arguments */ 196*219b2ee8SDavid du Colombier char * 197*219b2ee8SDavid du Colombier subst(char *a, char *b) 198*219b2ee8SDavid du Colombier { 199*219b2ee8SDavid du Colombier static depth = 0; 200*219b2ee8SDavid du Colombier char *s; 201*219b2ee8SDavid du Colombier char vname[100]; 202*219b2ee8SDavid du Colombier struct varblock *vbp; 203*219b2ee8SDavid du Colombier char closer; 204*219b2ee8SDavid du Colombier 205*219b2ee8SDavid du Colombier if(++depth > 100) 206*219b2ee8SDavid du Colombier fatal("infinitely recursive macro?"); 207*219b2ee8SDavid du Colombier if(a) while(*a) 208*219b2ee8SDavid du Colombier { 209*219b2ee8SDavid du Colombier if(*a!='$' || a[1]=='\0' || *++a=='$') 210*219b2ee8SDavid du Colombier /* if a non-macro character copy it. if $$ or $\0, copy $ */ 211*219b2ee8SDavid du Colombier *b++ = *a++; 212*219b2ee8SDavid du Colombier else { 213*219b2ee8SDavid du Colombier s = vname; 214*219b2ee8SDavid du Colombier if( *a=='(' || *a=='{' ) 215*219b2ee8SDavid du Colombier { 216*219b2ee8SDavid du Colombier closer = ( *a=='(' ? ')' : '}'); 217*219b2ee8SDavid du Colombier ++a; 218*219b2ee8SDavid du Colombier while(*a == ' ') ++a; 219*219b2ee8SDavid du Colombier while(*a!=' ' && *a!=closer && *a!='\0') *s++ = *a++; 220*219b2ee8SDavid du Colombier while(*a!=closer && *a!='\0') ++a; 221*219b2ee8SDavid du Colombier if(*a == closer) ++a; 222*219b2ee8SDavid du Colombier } 223*219b2ee8SDavid du Colombier else *s++ = *a++; 224*219b2ee8SDavid du Colombier 225*219b2ee8SDavid du Colombier *s = '\0'; 226*219b2ee8SDavid du Colombier if( (vbp = varptr(vname)) ->varval != 0) 227*219b2ee8SDavid du Colombier { 228*219b2ee8SDavid du Colombier b = subst(vbp->varval, b); 229*219b2ee8SDavid du Colombier vbp->used = YES; 230*219b2ee8SDavid du Colombier } 231*219b2ee8SDavid du Colombier } 232*219b2ee8SDavid du Colombier } 233*219b2ee8SDavid du Colombier 234*219b2ee8SDavid du Colombier *b = '\0'; 235*219b2ee8SDavid du Colombier --depth; 236*219b2ee8SDavid du Colombier return b; 237*219b2ee8SDavid du Colombier } 238*219b2ee8SDavid du Colombier 239*219b2ee8SDavid du Colombier void 240*219b2ee8SDavid du Colombier setvar(char *v, char *s, int dyn) 241*219b2ee8SDavid du Colombier { 242*219b2ee8SDavid du Colombier struct varblock *p; 243*219b2ee8SDavid du Colombier 244*219b2ee8SDavid du Colombier p = varptr(v); 245*219b2ee8SDavid du Colombier if( ! p->noreset ) 246*219b2ee8SDavid du Colombier { 247*219b2ee8SDavid du Colombier p->varval = s; 248*219b2ee8SDavid du Colombier p->noreset = inarglist; 249*219b2ee8SDavid du Colombier if(p->used && !dyn) 250*219b2ee8SDavid du Colombier fprintf(stderr, "Warning: %s changed after being used\n",v); 251*219b2ee8SDavid du Colombier if(p->export) 252*219b2ee8SDavid du Colombier { 253*219b2ee8SDavid du Colombier /* change string pointed to by environment to new v=s */ 254*219b2ee8SDavid du Colombier char *t; 255*219b2ee8SDavid du Colombier int lenv; 256*219b2ee8SDavid du Colombier lenv = strlen(v); 257*219b2ee8SDavid du Colombier *(p->export) = t = (char *) ckalloc(lenv + strlen(s) + 2); 258*219b2ee8SDavid du Colombier strcpy(t,v); 259*219b2ee8SDavid du Colombier t[lenv] = '='; 260*219b2ee8SDavid du Colombier strcpy(t+lenv+1, s); 261*219b2ee8SDavid du Colombier } 262*219b2ee8SDavid du Colombier else 263*219b2ee8SDavid du Colombier p->export = envpp; 264*219b2ee8SDavid du Colombier } 265*219b2ee8SDavid du Colombier } 266*219b2ee8SDavid du Colombier 267*219b2ee8SDavid du Colombier 268*219b2ee8SDavid du Colombier /* for setting Bradford's *D and *F family of macros whens setting * etc */ 269*219b2ee8SDavid du Colombier void 270*219b2ee8SDavid du Colombier set3var(char *macro, char *value) 271*219b2ee8SDavid du Colombier { 272*219b2ee8SDavid du Colombier char *s; 273*219b2ee8SDavid du Colombier char macjunk[8], *lastslash, *dirpart, *filepart; 274*219b2ee8SDavid du Colombier 275*219b2ee8SDavid du Colombier setvar(macro, value, YES); 276*219b2ee8SDavid du Colombier if(value == CHNULL) 277*219b2ee8SDavid du Colombier dirpart = filepart = CHNULL; 278*219b2ee8SDavid du Colombier else 279*219b2ee8SDavid du Colombier { 280*219b2ee8SDavid du Colombier lastslash = CHNULL; 281*219b2ee8SDavid du Colombier for(s = value; *s; ++s) 282*219b2ee8SDavid du Colombier if(*s == '/') 283*219b2ee8SDavid du Colombier lastslash = s; 284*219b2ee8SDavid du Colombier if(lastslash) 285*219b2ee8SDavid du Colombier { 286*219b2ee8SDavid du Colombier dirpart = copys(value); 287*219b2ee8SDavid du Colombier filepart = dirpart + (lastslash-value); 288*219b2ee8SDavid du Colombier filepart[-1] = '\0'; 289*219b2ee8SDavid du Colombier } 290*219b2ee8SDavid du Colombier else 291*219b2ee8SDavid du Colombier { 292*219b2ee8SDavid du Colombier dirpart = ""; 293*219b2ee8SDavid du Colombier filepart = value; 294*219b2ee8SDavid du Colombier } 295*219b2ee8SDavid du Colombier } 296*219b2ee8SDavid du Colombier setvar(concat(macro, "D", macjunk), dirpart, YES); 297*219b2ee8SDavid du Colombier setvar(concat(macro, "F", macjunk), filepart, YES); 298*219b2ee8SDavid du Colombier } 299*219b2ee8SDavid du Colombier 300*219b2ee8SDavid du Colombier 301*219b2ee8SDavid du Colombier int 302*219b2ee8SDavid du Colombier eqsign(char *a) /*look for arguments with equal signs but not colons */ 303*219b2ee8SDavid du Colombier { 304*219b2ee8SDavid du Colombier char *s, *t; 305*219b2ee8SDavid du Colombier char c; 306*219b2ee8SDavid du Colombier 307*219b2ee8SDavid du Colombier while(*a == ' ') ++a; 308*219b2ee8SDavid du Colombier for(s=a ; *s!='\0' && *s!=':' ; ++s) 309*219b2ee8SDavid du Colombier if(*s == '=') 310*219b2ee8SDavid du Colombier { 311*219b2ee8SDavid du Colombier for(t = a ; *t!='=' && *t!=' ' && *t!='\t' ; ++t ); 312*219b2ee8SDavid du Colombier c = *t; 313*219b2ee8SDavid du Colombier *t = '\0'; 314*219b2ee8SDavid du Colombier 315*219b2ee8SDavid du Colombier for(++s; *s==' ' || *s=='\t' ; ++s); 316*219b2ee8SDavid du Colombier setvar(a, copys(s), NO); 317*219b2ee8SDavid du Colombier *t = c; 318*219b2ee8SDavid du Colombier return YES; 319*219b2ee8SDavid du Colombier } 320*219b2ee8SDavid du Colombier 321*219b2ee8SDavid du Colombier return NO; 322*219b2ee8SDavid du Colombier } 323*219b2ee8SDavid du Colombier 324*219b2ee8SDavid du Colombier struct varblock * 325*219b2ee8SDavid du Colombier varptr(char *v) 326*219b2ee8SDavid du Colombier { 327*219b2ee8SDavid du Colombier struct varblock *vp; 328*219b2ee8SDavid du Colombier 329*219b2ee8SDavid du Colombier /* for compatibility, $(TGS) = $^ */ 330*219b2ee8SDavid du Colombier if(equal(v, "TGS") ) 331*219b2ee8SDavid du Colombier v = "^"; 332*219b2ee8SDavid du Colombier for(vp = firstvar; vp ; vp = vp->nxtvarblock) 333*219b2ee8SDavid du Colombier if(equal(v , vp->varname)) 334*219b2ee8SDavid du Colombier return vp; 335*219b2ee8SDavid du Colombier 336*219b2ee8SDavid du Colombier vp = ALLOC(varblock); 337*219b2ee8SDavid du Colombier vp->nxtvarblock = firstvar; 338*219b2ee8SDavid du Colombier firstvar = vp; 339*219b2ee8SDavid du Colombier vp->varname = copys(v); 340*219b2ee8SDavid du Colombier vp->varval = 0; 341*219b2ee8SDavid du Colombier return vp; 342*219b2ee8SDavid du Colombier } 343*219b2ee8SDavid du Colombier 344*219b2ee8SDavid du Colombier int 345*219b2ee8SDavid du Colombier dynmacro(char *line) 346*219b2ee8SDavid du Colombier { 347*219b2ee8SDavid du Colombier char *s; 348*219b2ee8SDavid du Colombier char endc, *endp; 349*219b2ee8SDavid du Colombier if(!isalpha(line[0])) 350*219b2ee8SDavid du Colombier return NO; 351*219b2ee8SDavid du Colombier for(s=line+1 ; *s && (isalpha(*s) | isdigit(*s)) ; ++s) 352*219b2ee8SDavid du Colombier ; 353*219b2ee8SDavid du Colombier endp = s; 354*219b2ee8SDavid du Colombier while( isspace(*s) ) 355*219b2ee8SDavid du Colombier ++s; 356*219b2ee8SDavid du Colombier if(s[0]!=':' || s[1]!='=') 357*219b2ee8SDavid du Colombier return NO; 358*219b2ee8SDavid du Colombier 359*219b2ee8SDavid du Colombier endc = *endp; 360*219b2ee8SDavid du Colombier *endp = '\0'; 361*219b2ee8SDavid du Colombier setvar(line, copys(s+2), YES); 362*219b2ee8SDavid du Colombier *endp = endc; 363*219b2ee8SDavid du Colombier 364*219b2ee8SDavid du Colombier return YES; 365*219b2ee8SDavid du Colombier } 366*219b2ee8SDavid du Colombier 367*219b2ee8SDavid du Colombier 368*219b2ee8SDavid du Colombier void 369*219b2ee8SDavid du Colombier fatal1(char *s, char *t) 370*219b2ee8SDavid du Colombier { 371*219b2ee8SDavid du Colombier char buf[100]; 372*219b2ee8SDavid du Colombier sprintf(buf, s, t); 373*219b2ee8SDavid du Colombier fatal(buf); 374*219b2ee8SDavid du Colombier } 375*219b2ee8SDavid du Colombier 376*219b2ee8SDavid du Colombier 377*219b2ee8SDavid du Colombier void 378*219b2ee8SDavid du Colombier fatal(char *s) 379*219b2ee8SDavid du Colombier { 380*219b2ee8SDavid du Colombier fflush(stdout); 381*219b2ee8SDavid du Colombier if(s) 382*219b2ee8SDavid du Colombier fprintf(stderr, "Make: %s. Stop.\n", s); 383*219b2ee8SDavid du Colombier else 384*219b2ee8SDavid du Colombier fprintf(stderr, "\nStop.\n"); 385*219b2ee8SDavid du Colombier 386*219b2ee8SDavid du Colombier waitstack(0); 387*219b2ee8SDavid du Colombier exit(1); 388*219b2ee8SDavid du Colombier } 389*219b2ee8SDavid du Colombier 390*219b2ee8SDavid du Colombier 391*219b2ee8SDavid du Colombier 392*219b2ee8SDavid du Colombier /* appends to the chain for $? and $^ */ 393*219b2ee8SDavid du Colombier chainp 394*219b2ee8SDavid du Colombier appendq(chainp head, char *tail) 395*219b2ee8SDavid du Colombier { 396*219b2ee8SDavid du Colombier chainp p, q; 397*219b2ee8SDavid du Colombier 398*219b2ee8SDavid du Colombier p = ALLOC(chain); 399*219b2ee8SDavid du Colombier p->datap = tail; 400*219b2ee8SDavid du Colombier 401*219b2ee8SDavid du Colombier if(head) 402*219b2ee8SDavid du Colombier { 403*219b2ee8SDavid du Colombier for(q = head ; q->nextp ; q = q->nextp) 404*219b2ee8SDavid du Colombier ; 405*219b2ee8SDavid du Colombier q->nextp = p; 406*219b2ee8SDavid du Colombier return head; 407*219b2ee8SDavid du Colombier } 408*219b2ee8SDavid du Colombier else 409*219b2ee8SDavid du Colombier return p; 410*219b2ee8SDavid du Colombier } 411*219b2ee8SDavid du Colombier 412*219b2ee8SDavid du Colombier 413*219b2ee8SDavid du Colombier 414*219b2ee8SDavid du Colombier 415*219b2ee8SDavid du Colombier 416*219b2ee8SDavid du Colombier /* builds the value for $? and $^ */ 417*219b2ee8SDavid du Colombier char * 418*219b2ee8SDavid du Colombier mkqlist(chainp p, char *qbuf) 419*219b2ee8SDavid du Colombier { 420*219b2ee8SDavid du Colombier char *qbufp, *s; 421*219b2ee8SDavid du Colombier 422*219b2ee8SDavid du Colombier if(p == NULL) 423*219b2ee8SDavid du Colombier return ""; 424*219b2ee8SDavid du Colombier 425*219b2ee8SDavid du Colombier qbufp = qbuf; 426*219b2ee8SDavid du Colombier 427*219b2ee8SDavid du Colombier for( ; p ; p = p->nextp) 428*219b2ee8SDavid du Colombier { 429*219b2ee8SDavid du Colombier s = p->datap; 430*219b2ee8SDavid du Colombier if(qbufp+strlen(s) > &qbuf[QBUFMAX-3]) 431*219b2ee8SDavid du Colombier { 432*219b2ee8SDavid du Colombier fprintf(stderr, "$? list too long\n"); 433*219b2ee8SDavid du Colombier break; 434*219b2ee8SDavid du Colombier } 435*219b2ee8SDavid du Colombier while (*s) 436*219b2ee8SDavid du Colombier *qbufp++ = *s++; 437*219b2ee8SDavid du Colombier *qbufp++ = ' '; 438*219b2ee8SDavid du Colombier } 439*219b2ee8SDavid du Colombier *--qbufp = '\0'; 440*219b2ee8SDavid du Colombier return qbuf; 441*219b2ee8SDavid du Colombier } 442*219b2ee8SDavid du Colombier 443*219b2ee8SDavid du Colombier wildp 444*219b2ee8SDavid du Colombier iswild(char *name) 445*219b2ee8SDavid du Colombier { 446*219b2ee8SDavid du Colombier char *s; 447*219b2ee8SDavid du Colombier wildp p; 448*219b2ee8SDavid du Colombier 449*219b2ee8SDavid du Colombier for(s=name; *s; ++s) 450*219b2ee8SDavid du Colombier if(*s == '%') 451*219b2ee8SDavid du Colombier { 452*219b2ee8SDavid du Colombier p = ALLOC(wild); 453*219b2ee8SDavid du Colombier *s = '\0'; 454*219b2ee8SDavid du Colombier p->left = copys(name); 455*219b2ee8SDavid du Colombier *s = '%'; 456*219b2ee8SDavid du Colombier p->right = copys(s+1); 457*219b2ee8SDavid du Colombier p->llen = strlen(p->left); 458*219b2ee8SDavid du Colombier p->rlen = strlen(p->right); 459*219b2ee8SDavid du Colombier p->totlen = p->llen + p->rlen; 460*219b2ee8SDavid du Colombier return p; 461*219b2ee8SDavid du Colombier } 462*219b2ee8SDavid du Colombier return NULL; 463*219b2ee8SDavid du Colombier } 464*219b2ee8SDavid du Colombier 465*219b2ee8SDavid du Colombier 466*219b2ee8SDavid du Colombier char * 467*219b2ee8SDavid du Colombier wildmatch(wildp p, char *name, int len) 468*219b2ee8SDavid du Colombier { 469*219b2ee8SDavid du Colombier char *stem; 470*219b2ee8SDavid du Colombier char *s; 471*219b2ee8SDavid du Colombier char c; 472*219b2ee8SDavid du Colombier 473*219b2ee8SDavid du Colombier if(len < p->totlen || 474*219b2ee8SDavid du Colombier strncmp(name, p->left, p->llen) || 475*219b2ee8SDavid du Colombier strncmp(s = name+len-p->rlen, p->right, p->rlen) ) 476*219b2ee8SDavid du Colombier return CHNULL; 477*219b2ee8SDavid du Colombier 478*219b2ee8SDavid du Colombier /*TEMP fprintf(stderr, "wildmatch(%s)=%s%%%s)\n", name,p->left,p->right); */ 479*219b2ee8SDavid du Colombier c = *s; 480*219b2ee8SDavid du Colombier *s = '\0'; 481*219b2ee8SDavid du Colombier stem = copys(name + p->llen); 482*219b2ee8SDavid du Colombier *s = c; 483*219b2ee8SDavid du Colombier return stem; 484*219b2ee8SDavid du Colombier } 485*219b2ee8SDavid du Colombier 486*219b2ee8SDavid du Colombier 487*219b2ee8SDavid du Colombier 488*219b2ee8SDavid du Colombier /* substitute stem for any % marks */ 489*219b2ee8SDavid du Colombier char * 490*219b2ee8SDavid du Colombier wildsub(char *pat, char *stem) 491*219b2ee8SDavid du Colombier { 492*219b2ee8SDavid du Colombier static char temp[100]; 493*219b2ee8SDavid du Colombier char *s, *t; 494*219b2ee8SDavid du Colombier 495*219b2ee8SDavid du Colombier s = temp; 496*219b2ee8SDavid du Colombier for(; *pat; ++pat) 497*219b2ee8SDavid du Colombier if(*pat == '%') 498*219b2ee8SDavid du Colombier for(t = stem ; *t; ) 499*219b2ee8SDavid du Colombier *s++ = *t++; 500*219b2ee8SDavid du Colombier else 501*219b2ee8SDavid du Colombier *s++ = *pat; 502*219b2ee8SDavid du Colombier *s = '\0'; 503*219b2ee8SDavid du Colombier return temp; 504*219b2ee8SDavid du Colombier } 505