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