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