xref: /csrg-svn/old/make/main.c (revision 31165)
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