1 static char *sccsid = "@(#)doname.c 4.8 (Berkeley) 85/09/18"; 2 #include "defs" 3 #include <strings.h> 4 #include <signal.h> 5 6 /* BASIC PROCEDURE. RECURSIVE. */ 7 8 /* 9 p->done = 0 don't know what to do yet 10 p->done = 1 file in process of being updated 11 p->done = 2 file already exists in current state 12 p->done = 3 file make failed 13 */ 14 15 extern char *sys_siglist[]; 16 17 doname(p, reclevel, tval) 18 register struct nameblock *p; 19 int reclevel; 20 TIMETYPE *tval; 21 { 22 int errstat; 23 int okdel1; 24 int didwork; 25 TIMETYPE td, td1, tdep, ptime, ptime1, prestime(); 26 register struct depblock *q; 27 struct depblock *qtemp, *srchdir(), *suffp, *suffp1; 28 struct nameblock *p1, *p2; 29 struct shblock *implcom, *explcom; 30 register struct lineblock *lp; 31 struct lineblock *lp1, *lp2; 32 char sourcename[BUFSIZ], prefix[BUFSIZ], temp[BUFSIZ], concsuff[20]; 33 char *pnamep, *p1namep, *cp; 34 char *mkqlist(); 35 struct chain *qchain, *appendq(); 36 37 if(p == 0) 38 { 39 *tval = 0; 40 return(0); 41 } 42 43 if(dbgflag) 44 { 45 printf("doname(%s,%d)\n",p->namep,reclevel); 46 fflush(stdout); 47 } 48 49 if(p->done > 0) 50 { 51 *tval = p->modtime; 52 return(p->done == 3); 53 } 54 55 errstat = 0; 56 tdep = 0; 57 implcom = 0; 58 explcom = 0; 59 ptime = exists(p); 60 ptime1 = 0; 61 didwork = NO; 62 p->done = 1; /* avoid infinite loops */ 63 64 qchain = NULL; 65 66 /* Expand any names that have embedded metacharaters */ 67 68 for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 69 for(q = lp->depp ; q ; q=qtemp ) 70 { 71 qtemp = q->nxtdepblock; 72 expand(q); 73 } 74 75 /* make sure all dependents are up to date */ 76 77 for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 78 { 79 td = 0; 80 for(q = lp->depp ; q ; q = q->nxtdepblock) 81 { 82 errstat += doname(q->depname, reclevel+1, &td1); 83 if(dbgflag) 84 printf("TIME(%s)=%ld\n", q->depname->namep, td1); 85 if(td1 > td) td = td1; 86 if(ptime < td1) 87 qchain = appendq(qchain, q->depname->namep); 88 } 89 if(p->septype == SOMEDEPS) 90 { 91 if(lp->shp!=0) 92 if( ptime<td || (ptime==0 && td==0) || lp->depp==0) 93 { 94 okdel1 = okdel; 95 okdel = NO; 96 setvar("@", p->namep); 97 setvar("?", mkqlist(qchain) ); 98 qchain = NULL; 99 if( !questflag ) 100 errstat += docom(lp->shp); 101 setvar("@", (char *) NULL); 102 okdel = okdel1; 103 ptime1 = prestime(); 104 didwork = YES; 105 } 106 } 107 108 else { 109 if(lp->shp != 0) 110 { 111 if(explcom) 112 fprintf(stderr, "Too many command lines for `%s'\n", 113 p->namep); 114 else explcom = lp->shp; 115 } 116 117 if(td > tdep) tdep = td; 118 } 119 } 120 121 /* Look for implicit dependents, using suffix rules */ 122 123 for(lp = sufflist ; lp ; lp = lp->nxtlineblock) 124 for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) 125 { 126 pnamep = suffp->depname->namep; 127 if(suffix(p->namep , pnamep , prefix)) 128 { 129 130 srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); 131 for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) 132 for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) 133 { 134 p1namep = suffp1->depname->namep; 135 if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && 136 (p2=srchname(concat(prefix, p1namep ,sourcename))) ) 137 { 138 errstat += doname(p2, reclevel+1, &td); 139 if(ptime < td) 140 qchain = appendq(qchain, p2->namep); 141 if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); 142 if(td > tdep) tdep = td; 143 setvar("*", prefix); 144 if (p2->alias) setvar("<", copys(p2->alias)); 145 else setvar("<", copys(p2->namep)); 146 for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 147 if(implcom = lp2->shp) break; 148 goto endloop; 149 } 150 } 151 cp = rindex(prefix, '/'); 152 if (cp++ == 0) 153 cp = prefix; 154 setvar("*", cp); 155 } 156 } 157 158 endloop: 159 160 161 if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) 162 { 163 ptime = (tdep>0 ? tdep : prestime() ); 164 setvar("@", p->namep); 165 setvar("?", mkqlist(qchain) ); 166 if(explcom) 167 errstat += docom(explcom); 168 else if(implcom) 169 errstat += docom(implcom); 170 else if(p->septype == 0) 171 if(p1=srchname(".DEFAULT")) 172 { 173 if (p->alias) setvar("<", p->alias); 174 else setvar("<", p->namep); 175 for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) 176 if(implcom = lp2->shp) 177 { 178 errstat += docom(implcom); 179 break; 180 } 181 } 182 else if(keepgoing) 183 { 184 printf("Don't know how to make %s\n", p->namep); 185 ++errstat; 186 } 187 else 188 fatal1(" Don't know how to make %s", p->namep); 189 190 setvar("@", (char *) NULL); 191 if(noexflag || (ptime = exists(p)) == 0) 192 ptime = prestime(); 193 } 194 195 else if(errstat!=0 && reclevel==0) 196 printf("`%s' not remade because of errors\n", p->namep); 197 198 else if(!questflag && reclevel==0 && didwork==NO) 199 printf("`%s' is up to date.\n", p->namep); 200 201 if(questflag && reclevel==0) 202 exit(ndocoms>0 ? -1 : 0); 203 204 p->done = (errstat ? 3 : 2); 205 if(ptime1 > ptime) ptime = ptime1; 206 p->modtime = ptime; 207 *tval = ptime; 208 return(errstat); 209 } 210 211 docom(q) 212 struct shblock *q; 213 { 214 char *s; 215 struct varblock *varptr(); 216 int ign, nopr; 217 char string[OUTMAX]; 218 char string2[OUTMAX]; 219 220 ++ndocoms; 221 if(questflag) 222 return(NO); 223 224 if(touchflag) 225 { 226 s = varptr("@")->varval; 227 if(!silflag) 228 printf("touch(%s)\n", s); 229 if(!noexflag) 230 touch(YES, s); 231 } 232 233 else for( ; q ; q = q->nxtshblock ) 234 { 235 subst(q->shbp,string2); 236 fixname(string2, string); 237 238 ign = ignerr; 239 nopr = NO; 240 for(s = string ; *s=='-' || *s=='@' ; ++s) 241 if(*s == '-') ign = YES; 242 else nopr = YES; 243 244 if( docom1(s, ign, nopr) && !ign) 245 if(keepgoing) 246 return(YES); 247 else fatal( (char *) NULL); 248 } 249 return(NO); 250 } 251 252 253 254 docom1(comstring, nohalt, noprint) 255 register char *comstring; 256 int nohalt, noprint; 257 { 258 register int status; 259 260 if(comstring[0] == '\0') return(0); 261 262 if(!silflag && (!noprint || noexflag) ) 263 { 264 printf("%s%s\n", (noexflag ? "" : prompt), comstring); 265 fflush(stdout); 266 } 267 268 if(noexflag) return(0); 269 270 if( status = dosys(comstring, nohalt) ) 271 { 272 unsigned sig = status & 0177; 273 if( sig ) { 274 if (sig < NSIG && sys_siglist[sig] != NULL && 275 *sys_siglist[sig] != '\0') 276 printf("*** %s", sys_siglist[sig]); 277 else 278 printf("*** Signal %d", sig); 279 if (status & 0200) 280 printf(" - core dumped"); 281 } else 282 printf("*** Exit %d", status>>8 ); 283 284 if(nohalt) printf(" (ignored)\n"); 285 else printf("\n"); 286 fflush(stdout); 287 } 288 289 return(status); 290 } 291 292 293 /* 294 If there are any Shell meta characters in the name, 295 expand into a list, after searching directory 296 */ 297 298 expand(q) 299 register struct depblock *q; 300 { 301 register char *s; 302 char *s1; 303 struct depblock *p, *srchdir(); 304 305 if (q->depname == NULL) 306 return; 307 s1 = q->depname->namep; 308 for(s=s1 ; ;) switch(*s++) 309 { 310 case '\0': 311 return; 312 313 case '*': 314 case '?': 315 case '[': 316 if( p = srchdir(s1 , YES, q->nxtdepblock) ) 317 { 318 q->nxtdepblock = p; 319 q->depname = 0; 320 } 321 return; 322 } 323 } 324