1*31165Sbostic static char *sccsid = "@(#)main.c 4.9 (Berkeley) 87/05/21"; 22809Swnj # include "defs" 32809Swnj /* 42809Swnj command make to update programs. 52809Swnj Flags: 'd' print out debugging comments 62809Swnj 'p' print out a version of the input graph 72809Swnj 's' silent mode--don't print out commands 82809Swnj 'f' the next argument is the name of the description file; 92809Swnj "makefile" is the default 102809Swnj 'i' ignore error codes from the shell 112809Swnj 'S' stop after any command fails (normally do parallel work) 122809Swnj 'n' don't issue, just print, commands 132809Swnj 't' touch (update time of) files but don't issue command 142809Swnj 'q' don't do anything, but check if object is up to date; 152809Swnj returns exit code 0 if up to date, -1 if not 16*31165Sbostic 'e' environment variables have precedence over makefiles 172809Swnj */ 182809Swnj 192809Swnj struct nameblock *mainname = NULL; 202809Swnj struct nameblock *firstname = NULL; 212809Swnj struct lineblock *sufflist = NULL; 222809Swnj struct varblock *firstvar = NULL; 232809Swnj struct pattern *firstpat = NULL; 246578Smckusick struct dirhdr *firstod = NULL; 252809Swnj 262809Swnj #include <signal.h> 272809Swnj int sigivalue = 0; 282809Swnj int sigqvalue = 0; 292809Swnj int waitpid = 0; 302809Swnj 312809Swnj int dbgflag = NO; 322809Swnj int prtrflag = NO; 332809Swnj int silflag = NO; 342809Swnj int noexflag = NO; 352809Swnj int keepgoing = NO; 362809Swnj int noruleflag = NO; 372809Swnj int touchflag = NO; 382809Swnj int questflag = NO; 392809Swnj int ndocoms = NO; 402809Swnj int ignerr = NO; /* default is to stop on error */ 412809Swnj int okdel = YES; 42*31165Sbostic int doenvlast = NO; 432809Swnj int inarglist; 442809Swnj #ifdef pwb 452809Swnj char *prompt = ">"; /* other systems -- pick what you want */ 462809Swnj #else 472809Swnj char *prompt = ""; /* other systems -- pick what you want */ 482809Swnj #endif 492809Swnj int nopdir = 0; 502809Swnj char junkname[20]; 512809Swnj char funny[128]; 528487Ssam char options[26 + 1] = { '-' }; 532809Swnj 542809Swnj main(argc,argv) 552809Swnj int argc; 562809Swnj char *argv[]; 572809Swnj { 582809Swnj register struct nameblock *p; 592809Swnj int i, j; 602809Swnj int descset, nfargs; 612809Swnj TIMETYPE tjunk; 622809Swnj char c, *s; 632809Swnj static char onechar[2] = "X"; 642809Swnj #ifdef unix 652809Swnj int intrupt(); 6617420Sralph #endif 678487Ssam char *op = options + 1; 682809Swnj 692809Swnj 702809Swnj #ifdef METERFILE 712809Swnj meter(METERFILE); 722809Swnj #endif 732809Swnj 742809Swnj descset = 0; 752809Swnj 762809Swnj funny['\0'] = (META | TERMINAL); 772809Swnj for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s) 782809Swnj funny[*s] |= META; 792809Swnj for(s = "\n\t :;&>|" ; *s ; ++s) 802809Swnj funny[*s] |= TERMINAL; 812809Swnj 822809Swnj 832809Swnj inarglist = 1; 842809Swnj for(i=1; i<argc; ++i) 852809Swnj if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i])) 862809Swnj argv[i] = 0; 872809Swnj 882809Swnj setvar("$","$"); 892809Swnj inarglist = 0; 902809Swnj 918487Ssam for (i=1; i<argc; ++i) 928487Ssam if (argv[i]!=0 && argv[i][0]=='-') { 938487Ssam for (j=1 ; (c=argv[i][j])!='\0' ; ++j) { 948487Ssam *op++ = c; 958487Ssam switch (c) { 962809Swnj 978487Ssam case 'd': 988487Ssam dbgflag = YES; 998487Ssam break; 1002809Swnj 1018487Ssam case 'p': 1028487Ssam prtrflag = YES; 1038487Ssam break; 1042809Swnj 1058487Ssam case 's': 1068487Ssam silflag = YES; 1078487Ssam break; 1082809Swnj 1098487Ssam case 'i': 1108487Ssam ignerr = YES; 1118487Ssam break; 1122809Swnj 1138487Ssam case 'S': 1148487Ssam keepgoing = NO; 1158487Ssam break; 1162809Swnj 1178487Ssam case 'k': 1188487Ssam keepgoing = YES; 1198487Ssam break; 1202809Swnj 1218487Ssam case 'n': 1228487Ssam noexflag = YES; 1238487Ssam break; 1242809Swnj 1258487Ssam case 'r': 1268487Ssam noruleflag = YES; 1278487Ssam break; 1282809Swnj 1298487Ssam case 't': 1308487Ssam touchflag = YES; 1318487Ssam break; 1322809Swnj 1338487Ssam case 'q': 1348487Ssam questflag = YES; 1358487Ssam break; 1368487Ssam 1378487Ssam case 'f': 1388487Ssam op--; /* don't pass this one */ 1398487Ssam if(i >= argc-1) 1408487Ssam fatal("No description argument after -f flag"); 1418487Ssam if( rddescf(argv[i+1]) ) 1422809Swnj fatal1("Cannot open %s", argv[i+1]); 1438487Ssam argv[i+1] = 0; 1448487Ssam ++descset; 1458487Ssam break; 1462809Swnj 147*31165Sbostic case 'e': 148*31165Sbostic doenvlast = YES; 149*31165Sbostic break; 150*31165Sbostic 1518487Ssam default: 1528487Ssam onechar[0] = c; /* to make lint happy */ 1538487Ssam fatal1("Unknown flag argument %s", onechar); 1548487Ssam } 1552809Swnj } 1568487Ssam argv[i] = 0; 1572809Swnj } 1582809Swnj 1598487Ssam *op++ = '\0'; 1608502Ssam if (strcmp(options, "-") == 0) 1618502Ssam *options = '\0'; 1628487Ssam setvar("MFLAGS", options); /* MFLAGS=options to make */ 1638487Ssam 164*31165Sbostic setvar("MACHINE", MACHINE); 165*31165Sbostic 1662809Swnj if( !descset ) 1672809Swnj #ifdef unix 1682809Swnj if( rddescf("makefile") ) rddescf("Makefile"); 1692809Swnj #endif 1702809Swnj #ifdef gcos 1712809Swnj rddescf("makefile"); 1722809Swnj #endif 1732809Swnj 174*31165Sbostic if (doenvlast == YES) 175*31165Sbostic readenv(); 176*31165Sbostic 1772809Swnj if(prtrflag) printdesc(NO); 1782809Swnj 1792809Swnj if( srchname(".IGNORE") ) ++ignerr; 1802809Swnj if( srchname(".SILENT") ) silflag = 1; 1812809Swnj if(p=srchname(".SUFFIXES")) sufflist = p->linep; 1822809Swnj if( !sufflist ) fprintf(stderr,"No suffix list.\n"); 1832809Swnj 1842809Swnj #ifdef unix 1852809Swnj sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; 1862809Swnj sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; 1872809Swnj enbint(intrupt); 1882809Swnj #endif 1892809Swnj 1902809Swnj nfargs = 0; 1912809Swnj 1922809Swnj for(i=1; i<argc; ++i) 1932809Swnj if((s=argv[i]) != 0) 1942809Swnj { 1952809Swnj if((p=srchname(s)) == 0) 1962809Swnj { 1972809Swnj p = makename(s); 1982809Swnj } 1992809Swnj ++nfargs; 2002809Swnj doname(p, 0, &tjunk); 2012809Swnj if(dbgflag) printdesc(YES); 2022809Swnj } 2032809Swnj 2042809Swnj /* 2052809Swnj If no file arguments have been encountered, make the first 2062809Swnj name encountered that doesn't start with a dot 2072809Swnj */ 2082809Swnj 2092809Swnj if(nfargs == 0) 2102809Swnj if(mainname == 0) 2112809Swnj fatal("No arguments or description file"); 2122809Swnj else { 2132809Swnj doname(mainname, 0, &tjunk); 2142809Swnj if(dbgflag) printdesc(YES); 2152809Swnj } 2162809Swnj 2172809Swnj exit(0); 2182809Swnj } 2192809Swnj 22011395Ssam #include <sys/stat.h> 2212809Swnj 2222809Swnj #ifdef unix 2232809Swnj intrupt() 2242809Swnj { 2252809Swnj struct varblock *varptr(); 2262809Swnj char *p; 2272809Swnj TIMETYPE exists(); 22811395Ssam struct stat sbuf; 2292809Swnj 2302809Swnj if(okdel && !noexflag && !touchflag && 23111395Ssam (p = varptr("@")->varval) && 23211395Ssam (stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) && 23311395Ssam !isprecious(p) ) 2342809Swnj { 2352809Swnj fprintf(stderr, "\n*** %s removed.", p); 2362809Swnj unlink(p); 2372809Swnj } 2382809Swnj 2392809Swnj if(junkname[0]) 2402809Swnj unlink(junkname); 2412809Swnj fprintf(stderr, "\n"); 2422809Swnj exit(2); 2432809Swnj } 2442809Swnj 2452809Swnj 2462809Swnj 2472809Swnj 2482809Swnj isprecious(p) 2492809Swnj char *p; 2502809Swnj { 2512809Swnj register struct lineblock *lp; 2522809Swnj register struct depblock *dp; 2532809Swnj register struct nameblock *np; 2542809Swnj 2552809Swnj if(np = srchname(".PRECIOUS")) 2562809Swnj for(lp = np->linep ; lp ; lp = lp->nxtlineblock) 2572809Swnj for(dp = lp->depp ; dp ; dp = dp->nxtdepblock) 2582809Swnj if(! unequal(p, dp->depname->namep)) 2592809Swnj return(YES); 2602809Swnj 2612809Swnj return(NO); 2622809Swnj } 2632809Swnj 2642809Swnj 2652809Swnj enbint(k) 2662809Swnj int (*k)(); 2672809Swnj { 2682809Swnj if(sigivalue == 0) 2692809Swnj signal(SIGINT,k); 2702809Swnj if(sigqvalue == 0) 2712809Swnj signal(SIGQUIT,k); 2722809Swnj } 2732809Swnj #endif 2742809Swnj 2752809Swnj extern char *builtin[]; 2762809Swnj 2772809Swnj char **linesptr = builtin; 2782809Swnj 2792809Swnj FILE * fin; 2802809Swnj int firstrd = 0; 2812809Swnj 2822809Swnj 2832809Swnj rddescf(descfile) 2842809Swnj char *descfile; 2852809Swnj { 2862809Swnj FILE * k; 2872809Swnj 2882809Swnj /* read and parse description */ 2892809Swnj 2902809Swnj if( !firstrd++ ) 2912809Swnj { 2922809Swnj if( !noruleflag ) 2932809Swnj rdd1( (FILE *) NULL); 2942809Swnj 295*31165Sbostic if (doenvlast == NO) 296*31165Sbostic readenv(); 297*31165Sbostic 2982809Swnj #ifdef pwb 2992809Swnj { 30024493Sbloom char *nlog, s[BUFSIZ]; 3012809Swnj nlog = logdir(); 3022809Swnj if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL) 3032809Swnj rdd1(k); 3042809Swnj else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL) 3052809Swnj rdd1(k); 3062809Swnj 3072809Swnj if ( (k=fopen("makecomm", "r")) != NULL) 3082809Swnj rdd1(k); 3092809Swnj else if ( (k=fopen("Makecomm", "r")) != NULL) 3102809Swnj rdd1(k); 3112809Swnj } 3122809Swnj #endif 3132809Swnj 3142809Swnj } 3152809Swnj if(! unequal(descfile, "-")) 3162809Swnj return( rdd1(stdin) ); 3172809Swnj 3182809Swnj if( (k = fopen(descfile,"r")) != NULL) 3192809Swnj return( rdd1(k) ); 3202809Swnj 3212809Swnj return(1); 3222809Swnj } 3232809Swnj 3242809Swnj 3252809Swnj 3262809Swnj 3272809Swnj rdd1(k) 3282809Swnj FILE * k; 3292809Swnj { 3302809Swnj extern int yylineno; 3312809Swnj extern char *zznextc; 3322809Swnj 3332809Swnj fin = k; 3342809Swnj yylineno = 0; 3352809Swnj zznextc = 0; 3362809Swnj 3372809Swnj if( yyparse() ) 3382809Swnj fatal("Description file error"); 3392809Swnj 34025774Sdonn if(fin != NULL && fin != stdin) 3412809Swnj fclose(fin); 3422809Swnj 3432809Swnj return(0); 3442809Swnj } 3452809Swnj 3462809Swnj printdesc(prntflag) 3472809Swnj int prntflag; 3482809Swnj { 3492809Swnj struct nameblock *p; 3502809Swnj struct depblock *dp; 3512809Swnj struct varblock *vp; 3526578Smckusick struct dirhdr *od; 3532809Swnj struct shblock *sp; 3542809Swnj struct lineblock *lp; 3552809Swnj 3562809Swnj #ifdef unix 3572809Swnj if(prntflag) 3582809Swnj { 3592809Swnj printf("Open directories:\n"); 3602809Swnj for (od = firstod; od; od = od->nxtopendir) 3616578Smckusick printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn); 3622809Swnj } 3632809Swnj #endif 3642809Swnj 3652809Swnj if(firstvar != 0) printf("Macros:\n"); 3662809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock) 3672809Swnj printf("\t%s = %s\n" , vp->varname , vp->varval); 3682809Swnj 3692809Swnj for(p = firstname; p; p = p->nxtnameblock) 3702809Swnj { 3712809Swnj printf("\n\n%s",p->namep); 3722809Swnj if(p->linep != 0) printf(":"); 3732809Swnj if(prntflag) printf(" done=%d",p->done); 3742809Swnj if(p==mainname) printf(" (MAIN NAME)"); 3752809Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 3762809Swnj { 3772809Swnj if( dp = lp->depp ) 3782809Swnj { 3792809Swnj printf("\n depends on:"); 3802809Swnj for(; dp ; dp = dp->nxtdepblock) 3812809Swnj if(dp->depname != 0) 3822809Swnj printf(" %s ", dp->depname->namep); 3832809Swnj } 3842809Swnj 3852809Swnj if(sp = lp->shp) 3862809Swnj { 3872809Swnj printf("\n commands:\n"); 3882809Swnj for( ; sp!=0 ; sp = sp->nxtshblock) 3892809Swnj printf("\t%s\n", sp->shbp); 3902809Swnj } 3912809Swnj } 3922809Swnj } 3932809Swnj printf("\n"); 3942809Swnj fflush(stdout); 3952809Swnj } 396*31165Sbostic 397*31165Sbostic readenv() 398*31165Sbostic { 399*31165Sbostic register char **ep, *p; 400*31165Sbostic extern char **environ; 401*31165Sbostic 402*31165Sbostic for(ep = environ ; *ep ; ++ep) { 403*31165Sbostic for (p = *ep; *p; p++) { 404*31165Sbostic if (isalnum(*p)) 405*31165Sbostic continue; 406*31165Sbostic if (*p == '=') { 407*31165Sbostic eqsign(*ep); 408*31165Sbostic } 409*31165Sbostic break; 410*31165Sbostic } 411*31165Sbostic } 412*31165Sbostic } 413