1*35486Sbostic static char *sccsid = "@(#)main.c 4.11 (Berkeley) 88/09/13"; 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 1631165Sbostic '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; 4231165Sbostic 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 14731165Sbostic case 'e': 14831165Sbostic doenvlast = YES; 14931165Sbostic break; 15031165Sbostic 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 16431165Sbostic setvar("MACHINE", MACHINE); 16531165Sbostic 166*35486Sbostic if (!descset) { 167*35486Sbostic if (rddescf("makefile")) 168*35486Sbostic rddescf("Makefile"); 169*35486Sbostic rddescf(".depend"); 170*35486Sbostic } 1712809Swnj 17231165Sbostic if (doenvlast == YES) 17331165Sbostic readenv(); 17431165Sbostic 1752809Swnj if(prtrflag) printdesc(NO); 1762809Swnj 1772809Swnj if( srchname(".IGNORE") ) ++ignerr; 1782809Swnj if( srchname(".SILENT") ) silflag = 1; 1792809Swnj if(p=srchname(".SUFFIXES")) sufflist = p->linep; 1802809Swnj if( !sufflist ) fprintf(stderr,"No suffix list.\n"); 1812809Swnj 1822809Swnj #ifdef unix 1832809Swnj sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; 1842809Swnj sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; 1852809Swnj enbint(intrupt); 1862809Swnj #endif 1872809Swnj 1882809Swnj nfargs = 0; 1892809Swnj 1902809Swnj for(i=1; i<argc; ++i) 1912809Swnj if((s=argv[i]) != 0) 1922809Swnj { 1932809Swnj if((p=srchname(s)) == 0) 1942809Swnj { 1952809Swnj p = makename(s); 1962809Swnj } 1972809Swnj ++nfargs; 1982809Swnj doname(p, 0, &tjunk); 1992809Swnj if(dbgflag) printdesc(YES); 2002809Swnj } 2012809Swnj 2022809Swnj /* 2032809Swnj If no file arguments have been encountered, make the first 2042809Swnj name encountered that doesn't start with a dot 2052809Swnj */ 2062809Swnj 2072809Swnj if(nfargs == 0) 2082809Swnj if(mainname == 0) 2092809Swnj fatal("No arguments or description file"); 2102809Swnj else { 2112809Swnj doname(mainname, 0, &tjunk); 2122809Swnj if(dbgflag) printdesc(YES); 2132809Swnj } 2142809Swnj 2152809Swnj exit(0); 2162809Swnj } 2172809Swnj 21811395Ssam #include <sys/stat.h> 2192809Swnj 2202809Swnj #ifdef unix 2212809Swnj intrupt() 2222809Swnj { 2232809Swnj struct varblock *varptr(); 2242809Swnj char *p; 2252809Swnj TIMETYPE exists(); 22611395Ssam struct stat sbuf; 2272809Swnj 2282809Swnj if(okdel && !noexflag && !touchflag && 22911395Ssam (p = varptr("@")->varval) && 23011395Ssam (stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) && 23111395Ssam !isprecious(p) ) 2322809Swnj { 2332809Swnj fprintf(stderr, "\n*** %s removed.", p); 2342809Swnj unlink(p); 2352809Swnj } 2362809Swnj 2372809Swnj if(junkname[0]) 2382809Swnj unlink(junkname); 2392809Swnj fprintf(stderr, "\n"); 2402809Swnj exit(2); 2412809Swnj } 2422809Swnj 2432809Swnj 2442809Swnj 2452809Swnj 2462809Swnj isprecious(p) 2472809Swnj char *p; 2482809Swnj { 2492809Swnj register struct lineblock *lp; 2502809Swnj register struct depblock *dp; 2512809Swnj register struct nameblock *np; 2522809Swnj 2532809Swnj if(np = srchname(".PRECIOUS")) 2542809Swnj for(lp = np->linep ; lp ; lp = lp->nxtlineblock) 2552809Swnj for(dp = lp->depp ; dp ; dp = dp->nxtdepblock) 2562809Swnj if(! unequal(p, dp->depname->namep)) 2572809Swnj return(YES); 2582809Swnj 2592809Swnj return(NO); 2602809Swnj } 2612809Swnj 2622809Swnj 2632809Swnj enbint(k) 2642809Swnj int (*k)(); 2652809Swnj { 2662809Swnj if(sigivalue == 0) 2672809Swnj signal(SIGINT,k); 2682809Swnj if(sigqvalue == 0) 2692809Swnj signal(SIGQUIT,k); 2702809Swnj } 2712809Swnj #endif 2722809Swnj 2732809Swnj extern char *builtin[]; 2742809Swnj 2752809Swnj char **linesptr = builtin; 2762809Swnj 2772809Swnj FILE * fin; 2782809Swnj int firstrd = 0; 2792809Swnj 2802809Swnj 2812809Swnj rddescf(descfile) 2822809Swnj char *descfile; 2832809Swnj { 2842809Swnj FILE * k; 2852809Swnj 2862809Swnj /* read and parse description */ 2872809Swnj 2882809Swnj if( !firstrd++ ) 2892809Swnj { 2902809Swnj if( !noruleflag ) 2912809Swnj rdd1( (FILE *) NULL); 2922809Swnj 29331165Sbostic if (doenvlast == NO) 29431165Sbostic readenv(); 29531165Sbostic 2962809Swnj #ifdef pwb 2972809Swnj { 29824493Sbloom char *nlog, s[BUFSIZ]; 2992809Swnj nlog = logdir(); 3002809Swnj if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL) 3012809Swnj rdd1(k); 3022809Swnj else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL) 3032809Swnj rdd1(k); 3042809Swnj 3052809Swnj if ( (k=fopen("makecomm", "r")) != NULL) 3062809Swnj rdd1(k); 3072809Swnj else if ( (k=fopen("Makecomm", "r")) != NULL) 3082809Swnj rdd1(k); 3092809Swnj } 3102809Swnj #endif 3112809Swnj 3122809Swnj } 3132809Swnj if(! unequal(descfile, "-")) 3142809Swnj return( rdd1(stdin) ); 3152809Swnj 3162809Swnj if( (k = fopen(descfile,"r")) != NULL) 3172809Swnj return( rdd1(k) ); 3182809Swnj 3192809Swnj return(1); 3202809Swnj } 3212809Swnj 3222809Swnj 3232809Swnj 3242809Swnj 3252809Swnj rdd1(k) 3262809Swnj FILE * k; 3272809Swnj { 3282809Swnj extern int yylineno; 3292809Swnj extern char *zznextc; 3302809Swnj 3312809Swnj fin = k; 3322809Swnj yylineno = 0; 3332809Swnj zznextc = 0; 3342809Swnj 3352809Swnj if( yyparse() ) 3362809Swnj fatal("Description file error"); 3372809Swnj 33825774Sdonn if(fin != NULL && fin != stdin) 3392809Swnj fclose(fin); 3402809Swnj 3412809Swnj return(0); 3422809Swnj } 3432809Swnj 3442809Swnj printdesc(prntflag) 3452809Swnj int prntflag; 3462809Swnj { 3472809Swnj struct nameblock *p; 3482809Swnj struct depblock *dp; 3492809Swnj struct varblock *vp; 3506578Smckusick struct dirhdr *od; 3512809Swnj struct shblock *sp; 3522809Swnj struct lineblock *lp; 3532809Swnj 3542809Swnj #ifdef unix 3552809Swnj if(prntflag) 3562809Swnj { 3572809Swnj printf("Open directories:\n"); 3582809Swnj for (od = firstod; od; od = od->nxtopendir) 35932620Sbostic printf("\t%d: %s\n", dirfd(od->dirfc), od->dirn); 3602809Swnj } 3612809Swnj #endif 3622809Swnj 3632809Swnj if(firstvar != 0) printf("Macros:\n"); 3642809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock) 3652809Swnj printf("\t%s = %s\n" , vp->varname , vp->varval); 3662809Swnj 3672809Swnj for(p = firstname; p; p = p->nxtnameblock) 3682809Swnj { 3692809Swnj printf("\n\n%s",p->namep); 3702809Swnj if(p->linep != 0) printf(":"); 3712809Swnj if(prntflag) printf(" done=%d",p->done); 3722809Swnj if(p==mainname) printf(" (MAIN NAME)"); 3732809Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock) 3742809Swnj { 3752809Swnj if( dp = lp->depp ) 3762809Swnj { 3772809Swnj printf("\n depends on:"); 3782809Swnj for(; dp ; dp = dp->nxtdepblock) 3792809Swnj if(dp->depname != 0) 3802809Swnj printf(" %s ", dp->depname->namep); 3812809Swnj } 3822809Swnj 3832809Swnj if(sp = lp->shp) 3842809Swnj { 3852809Swnj printf("\n commands:\n"); 3862809Swnj for( ; sp!=0 ; sp = sp->nxtshblock) 3872809Swnj printf("\t%s\n", sp->shbp); 3882809Swnj } 3892809Swnj } 3902809Swnj } 3912809Swnj printf("\n"); 3922809Swnj fflush(stdout); 3932809Swnj } 39431165Sbostic 39531165Sbostic readenv() 39631165Sbostic { 39731165Sbostic register char **ep, *p; 39831165Sbostic extern char **environ; 39931165Sbostic 40031165Sbostic for(ep = environ ; *ep ; ++ep) { 40131165Sbostic for (p = *ep; *p; p++) { 40231165Sbostic if (isalnum(*p)) 40331165Sbostic continue; 40431165Sbostic if (*p == '=') { 40531165Sbostic eqsign(*ep); 40631165Sbostic } 40731165Sbostic break; 40831165Sbostic } 40931165Sbostic } 41031165Sbostic } 411