1*46778Sbostic static char *sccsid = "@(#)main.c 4.12 (Berkeley) 91/02/28";
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
main(argc,argv)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
65*46778Sbostic void 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
16635486Sbostic if (!descset) {
16735486Sbostic if (rddescf("makefile"))
16835486Sbostic rddescf("Makefile");
16935486Sbostic rddescf(".depend");
17035486Sbostic }
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
221*46778Sbostic void
intrupt()2222809Swnj intrupt()
2232809Swnj {
2242809Swnj struct varblock *varptr();
2252809Swnj char *p;
2262809Swnj TIMETYPE exists();
22711395Ssam struct stat sbuf;
2282809Swnj
2292809Swnj if(okdel && !noexflag && !touchflag &&
23011395Ssam (p = varptr("@")->varval) &&
23111395Ssam (stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) &&
23211395Ssam !isprecious(p) )
2332809Swnj {
2342809Swnj fprintf(stderr, "\n*** %s removed.", p);
2352809Swnj unlink(p);
2362809Swnj }
2372809Swnj
2382809Swnj if(junkname[0])
2392809Swnj unlink(junkname);
2402809Swnj fprintf(stderr, "\n");
2412809Swnj exit(2);
2422809Swnj }
2432809Swnj
2442809Swnj
2452809Swnj
2462809Swnj
isprecious(p)2472809Swnj isprecious(p)
2482809Swnj char *p;
2492809Swnj {
2502809Swnj register struct lineblock *lp;
2512809Swnj register struct depblock *dp;
2522809Swnj register struct nameblock *np;
2532809Swnj
2542809Swnj if(np = srchname(".PRECIOUS"))
2552809Swnj for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
2562809Swnj for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
2572809Swnj if(! unequal(p, dp->depname->namep))
2582809Swnj return(YES);
2592809Swnj
2602809Swnj return(NO);
2612809Swnj }
2622809Swnj
2632809Swnj
2642809Swnj enbint(k)
265*46778Sbostic void (*k)();
2662809Swnj {
2672809Swnj if(sigivalue == 0)
2682809Swnj signal(SIGINT,k);
2692809Swnj if(sigqvalue == 0)
2702809Swnj signal(SIGQUIT,k);
2712809Swnj }
2722809Swnj #endif
2732809Swnj
2742809Swnj extern char *builtin[];
2752809Swnj
2762809Swnj char **linesptr = builtin;
2772809Swnj
2782809Swnj FILE * fin;
2792809Swnj int firstrd = 0;
2802809Swnj
2812809Swnj
rddescf(descfile)2822809Swnj rddescf(descfile)
2832809Swnj char *descfile;
2842809Swnj {
2852809Swnj FILE * k;
2862809Swnj
2872809Swnj /* read and parse description */
2882809Swnj
2892809Swnj if( !firstrd++ )
2902809Swnj {
2912809Swnj if( !noruleflag )
2922809Swnj rdd1( (FILE *) NULL);
2932809Swnj
29431165Sbostic if (doenvlast == NO)
29531165Sbostic readenv();
29631165Sbostic
2972809Swnj #ifdef pwb
2982809Swnj {
29924493Sbloom char *nlog, s[BUFSIZ];
3002809Swnj nlog = logdir();
3012809Swnj if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
3022809Swnj rdd1(k);
3032809Swnj else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
3042809Swnj rdd1(k);
3052809Swnj
3062809Swnj if ( (k=fopen("makecomm", "r")) != NULL)
3072809Swnj rdd1(k);
3082809Swnj else if ( (k=fopen("Makecomm", "r")) != NULL)
3092809Swnj rdd1(k);
3102809Swnj }
3112809Swnj #endif
3122809Swnj
3132809Swnj }
3142809Swnj if(! unequal(descfile, "-"))
3152809Swnj return( rdd1(stdin) );
3162809Swnj
3172809Swnj if( (k = fopen(descfile,"r")) != NULL)
3182809Swnj return( rdd1(k) );
3192809Swnj
3202809Swnj return(1);
3212809Swnj }
3222809Swnj
3232809Swnj
3242809Swnj
3252809Swnj
rdd1(k)3262809Swnj rdd1(k)
3272809Swnj FILE * k;
3282809Swnj {
3292809Swnj extern int yylineno;
3302809Swnj extern char *zznextc;
3312809Swnj
3322809Swnj fin = k;
3332809Swnj yylineno = 0;
3342809Swnj zznextc = 0;
3352809Swnj
3362809Swnj if( yyparse() )
3372809Swnj fatal("Description file error");
3382809Swnj
33925774Sdonn if(fin != NULL && fin != stdin)
3402809Swnj fclose(fin);
3412809Swnj
3422809Swnj return(0);
3432809Swnj }
3442809Swnj
printdesc(prntflag)3452809Swnj printdesc(prntflag)
3462809Swnj int prntflag;
3472809Swnj {
3482809Swnj struct nameblock *p;
3492809Swnj struct depblock *dp;
3502809Swnj struct varblock *vp;
3516578Smckusick struct dirhdr *od;
3522809Swnj struct shblock *sp;
3532809Swnj struct lineblock *lp;
3542809Swnj
3552809Swnj #ifdef unix
3562809Swnj if(prntflag)
3572809Swnj {
3582809Swnj printf("Open directories:\n");
3592809Swnj for (od = firstod; od; od = od->nxtopendir)
36032620Sbostic printf("\t%d: %s\n", dirfd(od->dirfc), od->dirn);
3612809Swnj }
3622809Swnj #endif
3632809Swnj
3642809Swnj if(firstvar != 0) printf("Macros:\n");
3652809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
3662809Swnj printf("\t%s = %s\n" , vp->varname , vp->varval);
3672809Swnj
3682809Swnj for(p = firstname; p; p = p->nxtnameblock)
3692809Swnj {
3702809Swnj printf("\n\n%s",p->namep);
3712809Swnj if(p->linep != 0) printf(":");
3722809Swnj if(prntflag) printf(" done=%d",p->done);
3732809Swnj if(p==mainname) printf(" (MAIN NAME)");
3742809Swnj for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
3752809Swnj {
3762809Swnj if( dp = lp->depp )
3772809Swnj {
3782809Swnj printf("\n depends on:");
3792809Swnj for(; dp ; dp = dp->nxtdepblock)
3802809Swnj if(dp->depname != 0)
3812809Swnj printf(" %s ", dp->depname->namep);
3822809Swnj }
3832809Swnj
3842809Swnj if(sp = lp->shp)
3852809Swnj {
3862809Swnj printf("\n commands:\n");
3872809Swnj for( ; sp!=0 ; sp = sp->nxtshblock)
3882809Swnj printf("\t%s\n", sp->shbp);
3892809Swnj }
3902809Swnj }
3912809Swnj }
3922809Swnj printf("\n");
3932809Swnj fflush(stdout);
3942809Swnj }
39531165Sbostic
readenv()39631165Sbostic readenv()
39731165Sbostic {
39831165Sbostic register char **ep, *p;
39931165Sbostic extern char **environ;
40031165Sbostic
40131165Sbostic for(ep = environ ; *ep ; ++ep) {
40231165Sbostic for (p = *ep; *p; p++) {
40331165Sbostic if (isalnum(*p))
40431165Sbostic continue;
40531165Sbostic if (*p == '=') {
40631165Sbostic eqsign(*ep);
40731165Sbostic }
40831165Sbostic break;
40931165Sbostic }
41031165Sbostic }
41131165Sbostic }
412