1 static char *sccsid = "@(#)main.c 4.12 (Berkeley) 91/02/28"; 2 # include "defs" 3 /* 4 command make to update programs. 5 Flags: 'd' print out debugging comments 6 'p' print out a version of the input graph 7 's' silent mode--don't print out commands 8 'f' the next argument is the name of the description file; 9 "makefile" is the default 10 'i' ignore error codes from the shell 11 'S' stop after any command fails (normally do parallel work) 12 'n' don't issue, just print, commands 13 't' touch (update time of) files but don't issue command 14 'q' don't do anything, but check if object is up to date; 15 returns exit code 0 if up to date, -1 if not 16 'e' environment variables have precedence over makefiles 17 */ 18 19 struct nameblock *mainname = NULL; 20 struct nameblock *firstname = NULL; 21 struct lineblock *sufflist = NULL; 22 struct varblock *firstvar = NULL; 23 struct pattern *firstpat = NULL; 24 struct dirhdr *firstod = NULL; 25 26 #include <signal.h> 27 int sigivalue = 0; 28 int sigqvalue = 0; 29 int waitpid = 0; 30 31 int dbgflag = NO; 32 int prtrflag = NO; 33 int silflag = NO; 34 int noexflag = NO; 35 int keepgoing = NO; 36 int noruleflag = NO; 37 int touchflag = NO; 38 int questflag = NO; 39 int ndocoms = NO; 40 int ignerr = NO; /* default is to stop on error */ 41 int okdel = YES; 42 int doenvlast = NO; 43 int inarglist; 44 #ifdef pwb 45 char *prompt = ">"; /* other systems -- pick what you want */ 46 #else 47 char *prompt = ""; /* other systems -- pick what you want */ 48 #endif 49 int nopdir = 0; 50 char junkname[20]; 51 char funny[128]; 52 char options[26 + 1] = { '-' }; 53 54 main(argc,argv) 55 int argc; 56 char *argv[]; 57 { 58 register struct nameblock *p; 59 int i, j; 60 int descset, nfargs; 61 TIMETYPE tjunk; 62 char c, *s; 63 static char onechar[2] = "X"; 64 #ifdef unix 65 void intrupt(); 66 #endif 67 char *op = options + 1; 68 69 70 #ifdef METERFILE 71 meter(METERFILE); 72 #endif 73 74 descset = 0; 75 76 funny['\0'] = (META | TERMINAL); 77 for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s) 78 funny[*s] |= META; 79 for(s = "\n\t :;&>|" ; *s ; ++s) 80 funny[*s] |= TERMINAL; 81 82 83 inarglist = 1; 84 for(i=1; i<argc; ++i) 85 if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i])) 86 argv[i] = 0; 87 88 setvar("$","$"); 89 inarglist = 0; 90 91 for (i=1; i<argc; ++i) 92 if (argv[i]!=0 && argv[i][0]=='-') { 93 for (j=1 ; (c=argv[i][j])!='\0' ; ++j) { 94 *op++ = c; 95 switch (c) { 96 97 case 'd': 98 dbgflag = YES; 99 break; 100 101 case 'p': 102 prtrflag = YES; 103 break; 104 105 case 's': 106 silflag = YES; 107 break; 108 109 case 'i': 110 ignerr = YES; 111 break; 112 113 case 'S': 114 keepgoing = NO; 115 break; 116 117 case 'k': 118 keepgoing = YES; 119 break; 120 121 case 'n': 122 noexflag = YES; 123 break; 124 125 case 'r': 126 noruleflag = YES; 127 break; 128 129 case 't': 130 touchflag = YES; 131 break; 132 133 case 'q': 134 questflag = YES; 135 break; 136 137 case 'f': 138 op--; /* don't pass this one */ 139 if(i >= argc-1) 140 fatal("No description argument after -f flag"); 141 if( rddescf(argv[i+1]) ) 142 fatal1("Cannot open %s", argv[i+1]); 143 argv[i+1] = 0; 144 ++descset; 145 break; 146 147 case 'e': 148 doenvlast = YES; 149 break; 150 151 default: 152 onechar[0] = c; /* to make lint happy */ 153 fatal1("Unknown flag argument %s", onechar); 154 } 155 } 156 argv[i] = 0; 157 } 158 159 *op++ = '\0'; 160 if (strcmp(options, "-") == 0) 161 *options = '\0'; 162 setvar("MFLAGS", options); /* MFLAGS=options to make */ 163 164 setvar("MACHINE", MACHINE); 165 166 if (!descset) { 167 if (rddescf("makefile")) 168 rddescf("Makefile"); 169 rddescf(".depend"); 170 } 171 172 if (doenvlast == YES) 173 readenv(); 174 175 if(prtrflag) printdesc(NO); 176 177 if( srchname(".IGNORE") ) ++ignerr; 178 if( srchname(".SILENT") ) silflag = 1; 179 if(p=srchname(".SUFFIXES")) sufflist = p->linep; 180 if( !sufflist ) fprintf(stderr,"No suffix list.\n"); 181 182 #ifdef unix 183 sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; 184 sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; 185 enbint(intrupt); 186 #endif 187 188 nfargs = 0; 189 190 for(i=1; i<argc; ++i) 191 if((s=argv[i]) != 0) 192 { 193 if((p=srchname(s)) == 0) 194 { 195 p = makename(s); 196 } 197 ++nfargs; 198 doname(p, 0, &tjunk); 199 if(dbgflag) printdesc(YES); 200 } 201 202 /* 203 If no file arguments have been encountered, make the first 204 name encountered that doesn't start with a dot 205 */ 206 207 if(nfargs == 0) 208 if(mainname == 0) 209 fatal("No arguments or description file"); 210 else { 211 doname(mainname, 0, &tjunk); 212 if(dbgflag) printdesc(YES); 213 } 214 215 exit(0); 216 } 217 218 #include <sys/stat.h> 219 220 #ifdef unix 221 void 222 intrupt() 223 { 224 struct varblock *varptr(); 225 char *p; 226 TIMETYPE exists(); 227 struct stat sbuf; 228 229 if(okdel && !noexflag && !touchflag && 230 (p = varptr("@")->varval) && 231 (stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) && 232 !isprecious(p) ) 233 { 234 fprintf(stderr, "\n*** %s removed.", p); 235 unlink(p); 236 } 237 238 if(junkname[0]) 239 unlink(junkname); 240 fprintf(stderr, "\n"); 241 exit(2); 242 } 243 244 245 246 247 isprecious(p) 248 char *p; 249 { 250 register struct lineblock *lp; 251 register struct depblock *dp; 252 register struct nameblock *np; 253 254 if(np = srchname(".PRECIOUS")) 255 for(lp = np->linep ; lp ; lp = lp->nxtlineblock) 256 for(dp = lp->depp ; dp ; dp = dp->nxtdepblock) 257 if(! unequal(p, dp->depname->namep)) 258 return(YES); 259 260 return(NO); 261 } 262 263 264 enbint(k) 265 void (*k)(); 266 { 267 if(sigivalue == 0) 268 signal(SIGINT,k); 269 if(sigqvalue == 0) 270 signal(SIGQUIT,k); 271 } 272 #endif 273 274 extern char *builtin[]; 275 276 char **linesptr = builtin; 277 278 FILE * fin; 279 int firstrd = 0; 280 281 282 rddescf(descfile) 283 char *descfile; 284 { 285 FILE * k; 286 287 /* read and parse description */ 288 289 if( !firstrd++ ) 290 { 291 if( !noruleflag ) 292 rdd1( (FILE *) NULL); 293 294 if (doenvlast == NO) 295 readenv(); 296 297 #ifdef pwb 298 { 299 char *nlog, s[BUFSIZ]; 300 nlog = logdir(); 301 if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL) 302 rdd1(k); 303 else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL) 304 rdd1(k); 305 306 if ( (k=fopen("makecomm", "r")) != NULL) 307 rdd1(k); 308 else if ( (k=fopen("Makecomm", "r")) != NULL) 309 rdd1(k); 310 } 311 #endif 312 313 } 314 if(! unequal(descfile, "-")) 315 return( rdd1(stdin) ); 316 317 if( (k = fopen(descfile,"r")) != NULL) 318 return( rdd1(k) ); 319 320 return(1); 321 } 322 323 324 325 326 rdd1(k) 327 FILE * k; 328 { 329 extern int yylineno; 330 extern char *zznextc; 331 332 fin = k; 333 yylineno = 0; 334 zznextc = 0; 335 336 if( yyparse() ) 337 fatal("Description file error"); 338 339 if(fin != NULL && fin != stdin) 340 fclose(fin); 341 342 return(0); 343 } 344 345 printdesc(prntflag) 346 int prntflag; 347 { 348 struct nameblock *p; 349 struct depblock *dp; 350 struct varblock *vp; 351 struct dirhdr *od; 352 struct shblock *sp; 353 struct lineblock *lp; 354 355 #ifdef unix 356 if(prntflag) 357 { 358 printf("Open directories:\n"); 359 for (od = firstod; od; od = od->nxtopendir) 360 printf("\t%d: %s\n", dirfd(od->dirfc), od->dirn); 361 } 362 #endif 363 364 if(firstvar != 0) printf("Macros:\n"); 365 for(vp = firstvar; vp ; vp = vp->nxtvarblock) 366 printf("\t%s = %s\n" , vp->varname , vp->varval); 367 368 for(p = firstname; p; p = p->nxtnameblock) 369 { 370 printf("\n\n%s",p->namep); 371 if(p->linep != 0) printf(":"); 372 if(prntflag) printf(" done=%d",p->done); 373 if(p==mainname) printf(" (MAIN NAME)"); 374 for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 375 { 376 if( dp = lp->depp ) 377 { 378 printf("\n depends on:"); 379 for(; dp ; dp = dp->nxtdepblock) 380 if(dp->depname != 0) 381 printf(" %s ", dp->depname->namep); 382 } 383 384 if(sp = lp->shp) 385 { 386 printf("\n commands:\n"); 387 for( ; sp!=0 ; sp = sp->nxtshblock) 388 printf("\t%s\n", sp->shbp); 389 } 390 } 391 } 392 printf("\n"); 393 fflush(stdout); 394 } 395 396 readenv() 397 { 398 register char **ep, *p; 399 extern char **environ; 400 401 for(ep = environ ; *ep ; ++ep) { 402 for (p = *ep; *p; p++) { 403 if (isalnum(*p)) 404 continue; 405 if (*p == '=') { 406 eqsign(*ep); 407 } 408 break; 409 } 410 } 411 } 412