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