xref: /csrg-svn/old/make/main.c (revision 11395)
1*11395Ssam static	char *sccsid = "@(#)main.c	4.5 (Berkeley) 83/03/03";
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];
508487Ssam 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();
648487Ssam 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 
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 
1478487Ssam 			default:
1488487Ssam 				onechar[0] = c;	/* to make lint happy */
1498487Ssam 				fatal1("Unknown flag argument %s", onechar);
1508487Ssam 			}
1512809Swnj 		}
1528487Ssam 		argv[i] = 0;
1532809Swnj 	}
1542809Swnj 
1558487Ssam *op++ = '\0';
1568502Ssam if (strcmp(options, "-") == 0)
1578502Ssam 	*options = '\0';
1588487Ssam setvar("MFLAGS", options);		/* MFLAGS=options to make */
1598487Ssam 
1602809Swnj if( !descset )
1612809Swnj #ifdef unix
1622809Swnj 	if( rddescf("makefile") )  rddescf("Makefile");
1632809Swnj #endif
1642809Swnj #ifdef gcos
1652809Swnj 	rddescf("makefile");
1662809Swnj #endif
1672809Swnj 
1682809Swnj if(prtrflag) printdesc(NO);
1692809Swnj 
1702809Swnj if( srchname(".IGNORE") ) ++ignerr;
1712809Swnj if( srchname(".SILENT") ) silflag = 1;
1722809Swnj if(p=srchname(".SUFFIXES")) sufflist = p->linep;
1732809Swnj if( !sufflist ) fprintf(stderr,"No suffix list.\n");
1742809Swnj 
1752809Swnj #ifdef unix
1762809Swnj sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
1772809Swnj sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
1782809Swnj enbint(intrupt);
1792809Swnj #endif
1802809Swnj 
1812809Swnj nfargs = 0;
1822809Swnj 
1832809Swnj for(i=1; i<argc; ++i)
1842809Swnj 	if((s=argv[i]) != 0)
1852809Swnj 		{
1862809Swnj 		if((p=srchname(s)) == 0)
1872809Swnj 			{
1882809Swnj 			p = makename(s);
1892809Swnj 			}
1902809Swnj 		++nfargs;
1912809Swnj 		doname(p, 0, &tjunk);
1922809Swnj 		if(dbgflag) printdesc(YES);
1932809Swnj 		}
1942809Swnj 
1952809Swnj /*
1962809Swnj If no file arguments have been encountered, make the first
1972809Swnj name encountered that doesn't start with a dot
1982809Swnj */
1992809Swnj 
2002809Swnj if(nfargs == 0)
2012809Swnj 	if(mainname == 0)
2022809Swnj 		fatal("No arguments or description file");
2032809Swnj 	else	{
2042809Swnj 		doname(mainname, 0, &tjunk);
2052809Swnj 		if(dbgflag) printdesc(YES);
2062809Swnj 		}
2072809Swnj 
2082809Swnj exit(0);
2092809Swnj }
2102809Swnj 
211*11395Ssam #include <sys/stat.h>
2122809Swnj 
2132809Swnj #ifdef unix
2142809Swnj intrupt()
2152809Swnj {
2162809Swnj struct varblock *varptr();
2172809Swnj char *p;
2182809Swnj TIMETYPE exists();
219*11395Ssam struct stat sbuf;
2202809Swnj 
2212809Swnj if(okdel && !noexflag && !touchflag &&
222*11395Ssam 	(p = varptr("@")->varval) &&
223*11395Ssam 	(stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) &&
224*11395Ssam 	!isprecious(p) )
2252809Swnj 		{
2262809Swnj 		fprintf(stderr, "\n***  %s removed.", p);
2272809Swnj 		unlink(p);
2282809Swnj 		}
2292809Swnj 
2302809Swnj if(junkname[0])
2312809Swnj 	unlink(junkname);
2322809Swnj fprintf(stderr, "\n");
2332809Swnj exit(2);
2342809Swnj }
2352809Swnj 
2362809Swnj 
2372809Swnj 
2382809Swnj 
2392809Swnj isprecious(p)
2402809Swnj char *p;
2412809Swnj {
2422809Swnj register struct lineblock *lp;
2432809Swnj register struct depblock *dp;
2442809Swnj register struct nameblock *np;
2452809Swnj 
2462809Swnj if(np = srchname(".PRECIOUS"))
2472809Swnj 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
2482809Swnj 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
2492809Swnj 			if(! unequal(p, dp->depname->namep))
2502809Swnj 				return(YES);
2512809Swnj 
2522809Swnj return(NO);
2532809Swnj }
2542809Swnj 
2552809Swnj 
2562809Swnj enbint(k)
2572809Swnj int (*k)();
2582809Swnj {
2592809Swnj if(sigivalue == 0)
2602809Swnj 	signal(SIGINT,k);
2612809Swnj if(sigqvalue == 0)
2622809Swnj 	signal(SIGQUIT,k);
2632809Swnj }
2642809Swnj #endif
2652809Swnj 
2662809Swnj extern char *builtin[];
2672809Swnj 
2682809Swnj char **linesptr	= builtin;
2692809Swnj 
2702809Swnj FILE * fin;
2712809Swnj int firstrd	= 0;
2722809Swnj 
2732809Swnj 
2742809Swnj rddescf(descfile)
2752809Swnj char *descfile;
2762809Swnj {
2772809Swnj FILE * k;
2782809Swnj 
2792809Swnj /* read and parse description */
2802809Swnj 
2812809Swnj if( !firstrd++ )
2822809Swnj 	{
2832809Swnj 	if( !noruleflag )
2842809Swnj 		rdd1( (FILE *) NULL);
2852809Swnj 
2862809Swnj #ifdef pwb
2872809Swnj 		{
2882809Swnj 		char *nlog, s[100];
2892809Swnj 		nlog = logdir();
2902809Swnj 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
2912809Swnj 			rdd1(k);
2922809Swnj 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
2932809Swnj 			rdd1(k);
2942809Swnj 
2952809Swnj 		if ( (k=fopen("makecomm", "r")) != NULL)
2962809Swnj 			rdd1(k);
2972809Swnj 		else if ( (k=fopen("Makecomm", "r")) != NULL)
2982809Swnj 			rdd1(k);
2992809Swnj 		}
3002809Swnj #endif
3012809Swnj 
3022809Swnj 	}
3032809Swnj if(! unequal(descfile, "-"))
3042809Swnj 	return( rdd1(stdin) );
3052809Swnj 
3062809Swnj if( (k = fopen(descfile,"r")) != NULL)
3072809Swnj 	return( rdd1(k) );
3082809Swnj 
3092809Swnj return(1);
3102809Swnj }
3112809Swnj 
3122809Swnj 
3132809Swnj 
3142809Swnj 
3152809Swnj rdd1(k)
3162809Swnj FILE * k;
3172809Swnj {
3182809Swnj extern int yylineno;
3192809Swnj extern char *zznextc;
3202809Swnj 
3212809Swnj fin = k;
3222809Swnj yylineno = 0;
3232809Swnj zznextc = 0;
3242809Swnj 
3252809Swnj if( yyparse() )
3262809Swnj 	fatal("Description file error");
3272809Swnj 
3282809Swnj if(fin != NULL)
3292809Swnj 	fclose(fin);
3302809Swnj 
3312809Swnj return(0);
3322809Swnj }
3332809Swnj 
3342809Swnj printdesc(prntflag)
3352809Swnj int prntflag;
3362809Swnj {
3372809Swnj struct nameblock *p;
3382809Swnj struct depblock *dp;
3392809Swnj struct varblock *vp;
3406578Smckusick struct dirhdr *od;
3412809Swnj struct shblock *sp;
3422809Swnj struct lineblock *lp;
3432809Swnj 
3442809Swnj #ifdef unix
3452809Swnj if(prntflag)
3462809Swnj 	{
3472809Swnj 	printf("Open directories:\n");
3482809Swnj 	for (od = firstod; od; od = od->nxtopendir)
3496578Smckusick 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
3502809Swnj 	}
3512809Swnj #endif
3522809Swnj 
3532809Swnj if(firstvar != 0) printf("Macros:\n");
3542809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
3552809Swnj 	printf("\t%s = %s\n" , vp->varname , vp->varval);
3562809Swnj 
3572809Swnj for(p = firstname; p; p = p->nxtnameblock)
3582809Swnj 	{
3592809Swnj 	printf("\n\n%s",p->namep);
3602809Swnj 	if(p->linep != 0) printf(":");
3612809Swnj 	if(prntflag) printf("  done=%d",p->done);
3622809Swnj 	if(p==mainname) printf("  (MAIN NAME)");
3632809Swnj 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
3642809Swnj 		{
3652809Swnj 		if( dp = lp->depp )
3662809Swnj 			{
3672809Swnj 			printf("\n depends on:");
3682809Swnj 			for(; dp ; dp = dp->nxtdepblock)
3692809Swnj 				if(dp->depname != 0)
3702809Swnj 					printf(" %s ", dp->depname->namep);
3712809Swnj 			}
3722809Swnj 
3732809Swnj 		if(sp = lp->shp)
3742809Swnj 			{
3752809Swnj 			printf("\n commands:\n");
3762809Swnj 			for( ; sp!=0 ; sp = sp->nxtshblock)
3772809Swnj 				printf("\t%s\n", sp->shbp);
3782809Swnj 			}
3792809Swnj 		}
3802809Swnj 	}
3812809Swnj printf("\n");
3822809Swnj fflush(stdout);
3832809Swnj }
384