xref: /csrg-svn/old/make/main.c (revision 25774)
1*25774Sdonn static	char *sccsid = "@(#)main.c	4.8 (Berkeley) 86/01/09";
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();
6417420Sralph #endif
658487Ssam char *op = options + 1;
662809Swnj 
672809Swnj 
682809Swnj #ifdef METERFILE
692809Swnj meter(METERFILE);
702809Swnj #endif
712809Swnj 
722809Swnj descset = 0;
732809Swnj 
742809Swnj funny['\0'] = (META | TERMINAL);
752809Swnj for(s = "=|^();&<>*?[]:$`'\"\\\n" ; *s ; ++s)
762809Swnj 	funny[*s] |= META;
772809Swnj for(s = "\n\t :;&>|" ; *s ; ++s)
782809Swnj 	funny[*s] |= TERMINAL;
792809Swnj 
802809Swnj 
812809Swnj inarglist = 1;
822809Swnj for(i=1; i<argc; ++i)
832809Swnj 	if(argv[i]!=0 && argv[i][0]!='-' && eqsign(argv[i]))
842809Swnj 		argv[i] = 0;
852809Swnj 
862809Swnj setvar("$","$");
872809Swnj inarglist = 0;
882809Swnj 
898487Ssam for (i=1; i<argc; ++i)
908487Ssam 	if (argv[i]!=0 && argv[i][0]=='-') {
918487Ssam 		for (j=1 ; (c=argv[i][j])!='\0' ; ++j) {
928487Ssam 			*op++ = c;
938487Ssam 			switch (c) {
942809Swnj 
958487Ssam 			case 'd':
968487Ssam 				dbgflag = YES;
978487Ssam 				break;
982809Swnj 
998487Ssam 			case 'p':
1008487Ssam 				prtrflag = YES;
1018487Ssam 				break;
1022809Swnj 
1038487Ssam 			case 's':
1048487Ssam 				silflag = YES;
1058487Ssam 				break;
1062809Swnj 
1078487Ssam 			case 'i':
1088487Ssam 				ignerr = YES;
1098487Ssam 				break;
1102809Swnj 
1118487Ssam 			case 'S':
1128487Ssam 				keepgoing = NO;
1138487Ssam 				break;
1142809Swnj 
1158487Ssam 			case 'k':
1168487Ssam 				keepgoing = YES;
1178487Ssam 				break;
1182809Swnj 
1198487Ssam 			case 'n':
1208487Ssam 				noexflag = YES;
1218487Ssam 				break;
1222809Swnj 
1238487Ssam 			case 'r':
1248487Ssam 				noruleflag = YES;
1258487Ssam 				break;
1262809Swnj 
1278487Ssam 			case 't':
1288487Ssam 				touchflag = YES;
1298487Ssam 				break;
1302809Swnj 
1318487Ssam 			case 'q':
1328487Ssam 				questflag = YES;
1338487Ssam 				break;
1348487Ssam 
1358487Ssam 			case 'f':
1368487Ssam 				op--;		/* don't pass this one */
1378487Ssam 				if(i >= argc-1)
1388487Ssam 				  fatal("No description argument after -f flag");
1398487Ssam 				if( rddescf(argv[i+1]) )
1402809Swnj 				fatal1("Cannot open %s", argv[i+1]);
1418487Ssam 				argv[i+1] = 0;
1428487Ssam 				++descset;
1438487Ssam 				break;
1442809Swnj 
1458487Ssam 			default:
1468487Ssam 				onechar[0] = c;	/* to make lint happy */
1478487Ssam 				fatal1("Unknown flag argument %s", onechar);
1488487Ssam 			}
1492809Swnj 		}
1508487Ssam 		argv[i] = 0;
1512809Swnj 	}
1522809Swnj 
1538487Ssam *op++ = '\0';
1548502Ssam if (strcmp(options, "-") == 0)
1558502Ssam 	*options = '\0';
1568487Ssam setvar("MFLAGS", options);		/* MFLAGS=options to make */
1578487Ssam 
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 
20911395Ssam #include <sys/stat.h>
2102809Swnj 
2112809Swnj #ifdef unix
2122809Swnj intrupt()
2132809Swnj {
2142809Swnj struct varblock *varptr();
2152809Swnj char *p;
2162809Swnj TIMETYPE exists();
21711395Ssam struct stat sbuf;
2182809Swnj 
2192809Swnj if(okdel && !noexflag && !touchflag &&
22011395Ssam 	(p = varptr("@")->varval) &&
22111395Ssam 	(stat(p, &sbuf) >= 0 && (sbuf.st_mode&S_IFMT) == S_IFREG) &&
22211395Ssam 	!isprecious(p) )
2232809Swnj 		{
2242809Swnj 		fprintf(stderr, "\n***  %s removed.", p);
2252809Swnj 		unlink(p);
2262809Swnj 		}
2272809Swnj 
2282809Swnj if(junkname[0])
2292809Swnj 	unlink(junkname);
2302809Swnj fprintf(stderr, "\n");
2312809Swnj exit(2);
2322809Swnj }
2332809Swnj 
2342809Swnj 
2352809Swnj 
2362809Swnj 
2372809Swnj isprecious(p)
2382809Swnj char *p;
2392809Swnj {
2402809Swnj register struct lineblock *lp;
2412809Swnj register struct depblock *dp;
2422809Swnj register struct nameblock *np;
2432809Swnj 
2442809Swnj if(np = srchname(".PRECIOUS"))
2452809Swnj 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
2462809Swnj 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
2472809Swnj 			if(! unequal(p, dp->depname->namep))
2482809Swnj 				return(YES);
2492809Swnj 
2502809Swnj return(NO);
2512809Swnj }
2522809Swnj 
2532809Swnj 
2542809Swnj enbint(k)
2552809Swnj int (*k)();
2562809Swnj {
2572809Swnj if(sigivalue == 0)
2582809Swnj 	signal(SIGINT,k);
2592809Swnj if(sigqvalue == 0)
2602809Swnj 	signal(SIGQUIT,k);
2612809Swnj }
2622809Swnj #endif
2632809Swnj 
2642809Swnj extern char *builtin[];
2652809Swnj 
2662809Swnj char **linesptr	= builtin;
2672809Swnj 
2682809Swnj FILE * fin;
2692809Swnj int firstrd	= 0;
2702809Swnj 
2712809Swnj 
2722809Swnj rddescf(descfile)
2732809Swnj char *descfile;
2742809Swnj {
2752809Swnj FILE * k;
2762809Swnj 
2772809Swnj /* read and parse description */
2782809Swnj 
2792809Swnj if( !firstrd++ )
2802809Swnj 	{
2812809Swnj 	if( !noruleflag )
2822809Swnj 		rdd1( (FILE *) NULL);
2832809Swnj 
2842809Swnj #ifdef pwb
2852809Swnj 		{
28624493Sbloom 		char *nlog, s[BUFSIZ];
2872809Swnj 		nlog = logdir();
2882809Swnj 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
2892809Swnj 			rdd1(k);
2902809Swnj 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
2912809Swnj 			rdd1(k);
2922809Swnj 
2932809Swnj 		if ( (k=fopen("makecomm", "r")) != NULL)
2942809Swnj 			rdd1(k);
2952809Swnj 		else if ( (k=fopen("Makecomm", "r")) != NULL)
2962809Swnj 			rdd1(k);
2972809Swnj 		}
2982809Swnj #endif
2992809Swnj 
3002809Swnj 	}
3012809Swnj if(! unequal(descfile, "-"))
3022809Swnj 	return( rdd1(stdin) );
3032809Swnj 
3042809Swnj if( (k = fopen(descfile,"r")) != NULL)
3052809Swnj 	return( rdd1(k) );
3062809Swnj 
3072809Swnj return(1);
3082809Swnj }
3092809Swnj 
3102809Swnj 
3112809Swnj 
3122809Swnj 
3132809Swnj rdd1(k)
3142809Swnj FILE * k;
3152809Swnj {
3162809Swnj extern int yylineno;
3172809Swnj extern char *zznextc;
3182809Swnj 
3192809Swnj fin = k;
3202809Swnj yylineno = 0;
3212809Swnj zznextc = 0;
3222809Swnj 
3232809Swnj if( yyparse() )
3242809Swnj 	fatal("Description file error");
3252809Swnj 
326*25774Sdonn if(fin != NULL && fin != stdin)
3272809Swnj 	fclose(fin);
3282809Swnj 
3292809Swnj return(0);
3302809Swnj }
3312809Swnj 
3322809Swnj printdesc(prntflag)
3332809Swnj int prntflag;
3342809Swnj {
3352809Swnj struct nameblock *p;
3362809Swnj struct depblock *dp;
3372809Swnj struct varblock *vp;
3386578Smckusick struct dirhdr *od;
3392809Swnj struct shblock *sp;
3402809Swnj struct lineblock *lp;
3412809Swnj 
3422809Swnj #ifdef unix
3432809Swnj if(prntflag)
3442809Swnj 	{
3452809Swnj 	printf("Open directories:\n");
3462809Swnj 	for (od = firstod; od; od = od->nxtopendir)
3476578Smckusick 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
3482809Swnj 	}
3492809Swnj #endif
3502809Swnj 
3512809Swnj if(firstvar != 0) printf("Macros:\n");
3522809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
3532809Swnj 	printf("\t%s = %s\n" , vp->varname , vp->varval);
3542809Swnj 
3552809Swnj for(p = firstname; p; p = p->nxtnameblock)
3562809Swnj 	{
3572809Swnj 	printf("\n\n%s",p->namep);
3582809Swnj 	if(p->linep != 0) printf(":");
3592809Swnj 	if(prntflag) printf("  done=%d",p->done);
3602809Swnj 	if(p==mainname) printf("  (MAIN NAME)");
3612809Swnj 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
3622809Swnj 		{
3632809Swnj 		if( dp = lp->depp )
3642809Swnj 			{
3652809Swnj 			printf("\n depends on:");
3662809Swnj 			for(; dp ; dp = dp->nxtdepblock)
3672809Swnj 				if(dp->depname != 0)
3682809Swnj 					printf(" %s ", dp->depname->namep);
3692809Swnj 			}
3702809Swnj 
3712809Swnj 		if(sp = lp->shp)
3722809Swnj 			{
3732809Swnj 			printf("\n commands:\n");
3742809Swnj 			for( ; sp!=0 ; sp = sp->nxtshblock)
3752809Swnj 				printf("\t%s\n", sp->shbp);
3762809Swnj 			}
3772809Swnj 		}
3782809Swnj 	}
3792809Swnj printf("\n");
3802809Swnj fflush(stdout);
3812809Swnj }
382