xref: /csrg-svn/old/make/main.c (revision 8487)
1*8487Ssam static	char *sccsid = "@(#)main.c	4.3 (Berkeley) 82/10/10";
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
162809Swnj */
172809Swnj 
182809Swnj struct nameblock *mainname	= NULL;
192809Swnj struct nameblock *firstname	= NULL;
202809Swnj struct lineblock *sufflist	= NULL;
212809Swnj struct varblock *firstvar	= NULL;
222809Swnj struct pattern *firstpat	= NULL;
236578Smckusick struct dirhdr *firstod		= NULL;
242809Swnj 
252809Swnj #include <signal.h>
262809Swnj int sigivalue	= 0;
272809Swnj int sigqvalue	= 0;
282809Swnj int waitpid	= 0;
292809Swnj 
302809Swnj int dbgflag	= NO;
312809Swnj int prtrflag	= NO;
322809Swnj int silflag	= NO;
332809Swnj int noexflag	= NO;
342809Swnj int keepgoing	= NO;
352809Swnj int noruleflag	= NO;
362809Swnj int touchflag	= NO;
372809Swnj int questflag	= NO;
382809Swnj int ndocoms	= NO;
392809Swnj int ignerr	= NO;    /* default is to stop on error */
402809Swnj int okdel	= YES;
412809Swnj int inarglist;
422809Swnj #ifdef pwb
432809Swnj char *prompt	= ">";	/* other systems -- pick what you want */
442809Swnj #else
452809Swnj char *prompt	= "";	/* other systems -- pick what you want */
462809Swnj #endif
472809Swnj int nopdir	= 0;
482809Swnj char junkname[20];
492809Swnj char funny[128];
50*8487Ssam char	options[26 + 1] = { '-' };
512809Swnj 
522809Swnj main(argc,argv)
532809Swnj int argc;
542809Swnj char *argv[];
552809Swnj {
562809Swnj register struct nameblock *p;
572809Swnj int i, j;
582809Swnj int descset, nfargs;
592809Swnj TIMETYPE tjunk;
602809Swnj char c, *s;
612809Swnj static char onechar[2] = "X";
622809Swnj #ifdef unix
632809Swnj int intrupt();
64*8487Ssam char *op = options + 1;
652809Swnj 
662809Swnj 
672809Swnj 
682809Swnj #endif
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 
91*8487Ssam for (i=1; i<argc; ++i)
92*8487Ssam 	if (argv[i]!=0 && argv[i][0]=='-') {
93*8487Ssam 		for (j=1 ; (c=argv[i][j])!='\0' ; ++j) {
94*8487Ssam 			*op++ = c;
95*8487Ssam 			switch (c) {
962809Swnj 
97*8487Ssam 			case 'd':
98*8487Ssam 				dbgflag = YES;
99*8487Ssam 				break;
1002809Swnj 
101*8487Ssam 			case 'p':
102*8487Ssam 				prtrflag = YES;
103*8487Ssam 				break;
1042809Swnj 
105*8487Ssam 			case 's':
106*8487Ssam 				silflag = YES;
107*8487Ssam 				break;
1082809Swnj 
109*8487Ssam 			case 'i':
110*8487Ssam 				ignerr = YES;
111*8487Ssam 				break;
1122809Swnj 
113*8487Ssam 			case 'S':
114*8487Ssam 				keepgoing = NO;
115*8487Ssam 				break;
1162809Swnj 
117*8487Ssam 			case 'k':
118*8487Ssam 				keepgoing = YES;
119*8487Ssam 				break;
1202809Swnj 
121*8487Ssam 			case 'n':
122*8487Ssam 				noexflag = YES;
123*8487Ssam 				break;
1242809Swnj 
125*8487Ssam 			case 'r':
126*8487Ssam 				noruleflag = YES;
127*8487Ssam 				break;
1282809Swnj 
129*8487Ssam 			case 't':
130*8487Ssam 				touchflag = YES;
131*8487Ssam 				break;
1322809Swnj 
133*8487Ssam 			case 'q':
134*8487Ssam 				questflag = YES;
135*8487Ssam 				break;
136*8487Ssam 
137*8487Ssam 			case 'f':
138*8487Ssam 				op--;		/* don't pass this one */
139*8487Ssam 				if(i >= argc-1)
140*8487Ssam 				  fatal("No description argument after -f flag");
141*8487Ssam 				if( rddescf(argv[i+1]) )
1422809Swnj 				fatal1("Cannot open %s", argv[i+1]);
143*8487Ssam 				argv[i+1] = 0;
144*8487Ssam 				++descset;
145*8487Ssam 				break;
1462809Swnj 
147*8487Ssam 			default:
148*8487Ssam 				onechar[0] = c;	/* to make lint happy */
149*8487Ssam 				fatal1("Unknown flag argument %s", onechar);
150*8487Ssam 			}
1512809Swnj 		}
152*8487Ssam 		argv[i] = 0;
1532809Swnj 	}
1542809Swnj 
155*8487Ssam *op++ = '\0';
156*8487Ssam setvar("MFLAGS", options);		/* MFLAGS=options to make */
157*8487Ssam 
1582809Swnj if( !descset )
1592809Swnj #ifdef unix
1602809Swnj 	if( rddescf("makefile") )  rddescf("Makefile");
1612809Swnj #endif
1622809Swnj #ifdef gcos
1632809Swnj 	rddescf("makefile");
1642809Swnj #endif
1652809Swnj 
1662809Swnj if(prtrflag) printdesc(NO);
1672809Swnj 
1682809Swnj if( srchname(".IGNORE") ) ++ignerr;
1692809Swnj if( srchname(".SILENT") ) silflag = 1;
1702809Swnj if(p=srchname(".SUFFIXES")) sufflist = p->linep;
1712809Swnj if( !sufflist ) fprintf(stderr,"No suffix list.\n");
1722809Swnj 
1732809Swnj #ifdef unix
1742809Swnj sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
1752809Swnj sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
1762809Swnj enbint(intrupt);
1772809Swnj #endif
1782809Swnj 
1792809Swnj nfargs = 0;
1802809Swnj 
1812809Swnj for(i=1; i<argc; ++i)
1822809Swnj 	if((s=argv[i]) != 0)
1832809Swnj 		{
1842809Swnj 		if((p=srchname(s)) == 0)
1852809Swnj 			{
1862809Swnj 			p = makename(s);
1872809Swnj 			}
1882809Swnj 		++nfargs;
1892809Swnj 		doname(p, 0, &tjunk);
1902809Swnj 		if(dbgflag) printdesc(YES);
1912809Swnj 		}
1922809Swnj 
1932809Swnj /*
1942809Swnj If no file arguments have been encountered, make the first
1952809Swnj name encountered that doesn't start with a dot
1962809Swnj */
1972809Swnj 
1982809Swnj if(nfargs == 0)
1992809Swnj 	if(mainname == 0)
2002809Swnj 		fatal("No arguments or description file");
2012809Swnj 	else	{
2022809Swnj 		doname(mainname, 0, &tjunk);
2032809Swnj 		if(dbgflag) printdesc(YES);
2042809Swnj 		}
2052809Swnj 
2062809Swnj exit(0);
2072809Swnj }
2082809Swnj 
2092809Swnj 
2102809Swnj 
2112809Swnj #ifdef unix
2122809Swnj intrupt()
2132809Swnj {
2142809Swnj struct varblock *varptr();
2152809Swnj char *p;
2162809Swnj TIMETYPE exists();
2172809Swnj 
2182809Swnj if(okdel && !noexflag && !touchflag &&
2192809Swnj 	(p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
2202809Swnj 		{
2212809Swnj 		fprintf(stderr, "\n***  %s removed.", p);
2222809Swnj 		unlink(p);
2232809Swnj 		}
2242809Swnj 
2252809Swnj if(junkname[0])
2262809Swnj 	unlink(junkname);
2272809Swnj fprintf(stderr, "\n");
2282809Swnj exit(2);
2292809Swnj }
2302809Swnj 
2312809Swnj 
2322809Swnj 
2332809Swnj 
2342809Swnj isprecious(p)
2352809Swnj char *p;
2362809Swnj {
2372809Swnj register struct lineblock *lp;
2382809Swnj register struct depblock *dp;
2392809Swnj register struct nameblock *np;
2402809Swnj 
2412809Swnj if(np = srchname(".PRECIOUS"))
2422809Swnj 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
2432809Swnj 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
2442809Swnj 			if(! unequal(p, dp->depname->namep))
2452809Swnj 				return(YES);
2462809Swnj 
2472809Swnj return(NO);
2482809Swnj }
2492809Swnj 
2502809Swnj 
2512809Swnj enbint(k)
2522809Swnj int (*k)();
2532809Swnj {
2542809Swnj if(sigivalue == 0)
2552809Swnj 	signal(SIGINT,k);
2562809Swnj if(sigqvalue == 0)
2572809Swnj 	signal(SIGQUIT,k);
2582809Swnj }
2592809Swnj #endif
2602809Swnj 
2612809Swnj extern char *builtin[];
2622809Swnj 
2632809Swnj char **linesptr	= builtin;
2642809Swnj 
2652809Swnj FILE * fin;
2662809Swnj int firstrd	= 0;
2672809Swnj 
2682809Swnj 
2692809Swnj rddescf(descfile)
2702809Swnj char *descfile;
2712809Swnj {
2722809Swnj FILE * k;
2732809Swnj 
2742809Swnj /* read and parse description */
2752809Swnj 
2762809Swnj if( !firstrd++ )
2772809Swnj 	{
2782809Swnj 	if( !noruleflag )
2792809Swnj 		rdd1( (FILE *) NULL);
2802809Swnj 
2812809Swnj #ifdef pwb
2822809Swnj 		{
2832809Swnj 		char *nlog, s[100];
2842809Swnj 		nlog = logdir();
2852809Swnj 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
2862809Swnj 			rdd1(k);
2872809Swnj 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
2882809Swnj 			rdd1(k);
2892809Swnj 
2902809Swnj 		if ( (k=fopen("makecomm", "r")) != NULL)
2912809Swnj 			rdd1(k);
2922809Swnj 		else if ( (k=fopen("Makecomm", "r")) != NULL)
2932809Swnj 			rdd1(k);
2942809Swnj 		}
2952809Swnj #endif
2962809Swnj 
2972809Swnj 	}
2982809Swnj if(! unequal(descfile, "-"))
2992809Swnj 	return( rdd1(stdin) );
3002809Swnj 
3012809Swnj if( (k = fopen(descfile,"r")) != NULL)
3022809Swnj 	return( rdd1(k) );
3032809Swnj 
3042809Swnj return(1);
3052809Swnj }
3062809Swnj 
3072809Swnj 
3082809Swnj 
3092809Swnj 
3102809Swnj rdd1(k)
3112809Swnj FILE * k;
3122809Swnj {
3132809Swnj extern int yylineno;
3142809Swnj extern char *zznextc;
3152809Swnj 
3162809Swnj fin = k;
3172809Swnj yylineno = 0;
3182809Swnj zznextc = 0;
3192809Swnj 
3202809Swnj if( yyparse() )
3212809Swnj 	fatal("Description file error");
3222809Swnj 
3232809Swnj if(fin != NULL)
3242809Swnj 	fclose(fin);
3252809Swnj 
3262809Swnj return(0);
3272809Swnj }
3282809Swnj 
3292809Swnj printdesc(prntflag)
3302809Swnj int prntflag;
3312809Swnj {
3322809Swnj struct nameblock *p;
3332809Swnj struct depblock *dp;
3342809Swnj struct varblock *vp;
3356578Smckusick struct dirhdr *od;
3362809Swnj struct shblock *sp;
3372809Swnj struct lineblock *lp;
3382809Swnj 
3392809Swnj #ifdef unix
3402809Swnj if(prntflag)
3412809Swnj 	{
3422809Swnj 	printf("Open directories:\n");
3432809Swnj 	for (od = firstod; od; od = od->nxtopendir)
3446578Smckusick 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
3452809Swnj 	}
3462809Swnj #endif
3472809Swnj 
3482809Swnj if(firstvar != 0) printf("Macros:\n");
3492809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
3502809Swnj 	printf("\t%s = %s\n" , vp->varname , vp->varval);
3512809Swnj 
3522809Swnj for(p = firstname; p; p = p->nxtnameblock)
3532809Swnj 	{
3542809Swnj 	printf("\n\n%s",p->namep);
3552809Swnj 	if(p->linep != 0) printf(":");
3562809Swnj 	if(prntflag) printf("  done=%d",p->done);
3572809Swnj 	if(p==mainname) printf("  (MAIN NAME)");
3582809Swnj 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
3592809Swnj 		{
3602809Swnj 		if( dp = lp->depp )
3612809Swnj 			{
3622809Swnj 			printf("\n depends on:");
3632809Swnj 			for(; dp ; dp = dp->nxtdepblock)
3642809Swnj 				if(dp->depname != 0)
3652809Swnj 					printf(" %s ", dp->depname->namep);
3662809Swnj 			}
3672809Swnj 
3682809Swnj 		if(sp = lp->shp)
3692809Swnj 			{
3702809Swnj 			printf("\n commands:\n");
3712809Swnj 			for( ; sp!=0 ; sp = sp->nxtshblock)
3722809Swnj 				printf("\t%s\n", sp->shbp);
3732809Swnj 			}
3742809Swnj 		}
3752809Swnj 	}
3762809Swnj printf("\n");
3772809Swnj fflush(stdout);
3782809Swnj }
379