xref: /csrg-svn/old/make/main.c (revision 6578)
1*6578Smckusick static	char *sccsid = "@(#)main.c	4.2 (Berkeley) 82/04/20";
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;
23*6578Smckusick 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];
502809Swnj 
512809Swnj main(argc,argv)
522809Swnj int argc;
532809Swnj char *argv[];
542809Swnj {
552809Swnj register struct nameblock *p;
562809Swnj int i, j;
572809Swnj int descset, nfargs;
582809Swnj TIMETYPE tjunk;
592809Swnj char c, *s;
602809Swnj static char onechar[2] = "X";
612809Swnj #ifdef unix
622809Swnj int intrupt();
632809Swnj 
642809Swnj 
652809Swnj 
662809Swnj #endif
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 
892809Swnj for(i=1; i<argc; ++i)
902809Swnj     if(argv[i]!=0 && argv[i][0]=='-')
912809Swnj 	{
922809Swnj 	for(j=1 ; (c=argv[i][j])!='\0' ; ++j)  switch(c)
932809Swnj 		{
942809Swnj 		case 'd':
952809Swnj 			dbgflag = YES;
962809Swnj 			break;
972809Swnj 
982809Swnj 		case 'p':
992809Swnj 			prtrflag = YES;
1002809Swnj 			break;
1012809Swnj 
1022809Swnj 		case 's':
1032809Swnj 			silflag = YES;
1042809Swnj 			break;
1052809Swnj 
1062809Swnj 		case 'i':
1072809Swnj 			ignerr = YES;
1082809Swnj 			break;
1092809Swnj 
1102809Swnj 		case 'S':
1112809Swnj 			keepgoing = NO;
1122809Swnj 			break;
1132809Swnj 
1142809Swnj 		case 'k':
1152809Swnj 			keepgoing = YES;
1162809Swnj 			break;
1172809Swnj 
1182809Swnj 		case 'n':
1192809Swnj 			noexflag = YES;
1202809Swnj 			break;
1212809Swnj 
1222809Swnj 		case 'r':
1232809Swnj 			noruleflag = YES;
1242809Swnj 			break;
1252809Swnj 
1262809Swnj 		case 't':
1272809Swnj 			touchflag = YES;
1282809Swnj 			break;
1292809Swnj 
1302809Swnj 		case 'q':
1312809Swnj 			questflag = YES;
1322809Swnj 			break;
1332809Swnj 
1342809Swnj 		case 'f':
1352809Swnj 			if(i >= argc-1)
1362809Swnj 			  fatal("No description argument after -f flag");
1372809Swnj 			if( rddescf(argv[i+1]) )
1382809Swnj 				fatal1("Cannot open %s", argv[i+1]);
1392809Swnj 			argv[i+1] = 0;
1402809Swnj 			++descset;
1412809Swnj 			break;
1422809Swnj 
1432809Swnj 		default:
1442809Swnj 			onechar[0] = c;	/* to make lint happy */
1452809Swnj 			fatal1("Unknown flag argument %s", onechar);
1462809Swnj 		}
1472809Swnj 
1482809Swnj 	argv[i] = 0;
1492809Swnj 	}
1502809Swnj 
1512809Swnj if( !descset )
1522809Swnj #ifdef unix
1532809Swnj 	if( rddescf("makefile") )  rddescf("Makefile");
1542809Swnj #endif
1552809Swnj #ifdef gcos
1562809Swnj 	rddescf("makefile");
1572809Swnj #endif
1582809Swnj 
1592809Swnj if(prtrflag) printdesc(NO);
1602809Swnj 
1612809Swnj if( srchname(".IGNORE") ) ++ignerr;
1622809Swnj if( srchname(".SILENT") ) silflag = 1;
1632809Swnj if(p=srchname(".SUFFIXES")) sufflist = p->linep;
1642809Swnj if( !sufflist ) fprintf(stderr,"No suffix list.\n");
1652809Swnj 
1662809Swnj #ifdef unix
1672809Swnj sigivalue = (int) signal(SIGINT, SIG_IGN) & 01;
1682809Swnj sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01;
1692809Swnj enbint(intrupt);
1702809Swnj #endif
1712809Swnj 
1722809Swnj nfargs = 0;
1732809Swnj 
1742809Swnj for(i=1; i<argc; ++i)
1752809Swnj 	if((s=argv[i]) != 0)
1762809Swnj 		{
1772809Swnj 		if((p=srchname(s)) == 0)
1782809Swnj 			{
1792809Swnj 			p = makename(s);
1802809Swnj 			}
1812809Swnj 		++nfargs;
1822809Swnj 		doname(p, 0, &tjunk);
1832809Swnj 		if(dbgflag) printdesc(YES);
1842809Swnj 		}
1852809Swnj 
1862809Swnj /*
1872809Swnj If no file arguments have been encountered, make the first
1882809Swnj name encountered that doesn't start with a dot
1892809Swnj */
1902809Swnj 
1912809Swnj if(nfargs == 0)
1922809Swnj 	if(mainname == 0)
1932809Swnj 		fatal("No arguments or description file");
1942809Swnj 	else	{
1952809Swnj 		doname(mainname, 0, &tjunk);
1962809Swnj 		if(dbgflag) printdesc(YES);
1972809Swnj 		}
1982809Swnj 
1992809Swnj exit(0);
2002809Swnj }
2012809Swnj 
2022809Swnj 
2032809Swnj 
2042809Swnj #ifdef unix
2052809Swnj intrupt()
2062809Swnj {
2072809Swnj struct varblock *varptr();
2082809Swnj char *p;
2092809Swnj TIMETYPE exists();
2102809Swnj 
2112809Swnj if(okdel && !noexflag && !touchflag &&
2122809Swnj 	(p = varptr("@")->varval) && exists(p)>0 && !isprecious(p) )
2132809Swnj 		{
2142809Swnj 		fprintf(stderr, "\n***  %s removed.", p);
2152809Swnj 		unlink(p);
2162809Swnj 		}
2172809Swnj 
2182809Swnj if(junkname[0])
2192809Swnj 	unlink(junkname);
2202809Swnj fprintf(stderr, "\n");
2212809Swnj exit(2);
2222809Swnj }
2232809Swnj 
2242809Swnj 
2252809Swnj 
2262809Swnj 
2272809Swnj isprecious(p)
2282809Swnj char *p;
2292809Swnj {
2302809Swnj register struct lineblock *lp;
2312809Swnj register struct depblock *dp;
2322809Swnj register struct nameblock *np;
2332809Swnj 
2342809Swnj if(np = srchname(".PRECIOUS"))
2352809Swnj 	for(lp = np->linep ; lp ; lp = lp->nxtlineblock)
2362809Swnj 		for(dp = lp->depp ; dp ; dp = dp->nxtdepblock)
2372809Swnj 			if(! unequal(p, dp->depname->namep))
2382809Swnj 				return(YES);
2392809Swnj 
2402809Swnj return(NO);
2412809Swnj }
2422809Swnj 
2432809Swnj 
2442809Swnj enbint(k)
2452809Swnj int (*k)();
2462809Swnj {
2472809Swnj if(sigivalue == 0)
2482809Swnj 	signal(SIGINT,k);
2492809Swnj if(sigqvalue == 0)
2502809Swnj 	signal(SIGQUIT,k);
2512809Swnj }
2522809Swnj #endif
2532809Swnj 
2542809Swnj extern char *builtin[];
2552809Swnj 
2562809Swnj char **linesptr	= builtin;
2572809Swnj 
2582809Swnj FILE * fin;
2592809Swnj int firstrd	= 0;
2602809Swnj 
2612809Swnj 
2622809Swnj rddescf(descfile)
2632809Swnj char *descfile;
2642809Swnj {
2652809Swnj FILE * k;
2662809Swnj 
2672809Swnj /* read and parse description */
2682809Swnj 
2692809Swnj if( !firstrd++ )
2702809Swnj 	{
2712809Swnj 	if( !noruleflag )
2722809Swnj 		rdd1( (FILE *) NULL);
2732809Swnj 
2742809Swnj #ifdef pwb
2752809Swnj 		{
2762809Swnj 		char *nlog, s[100];
2772809Swnj 		nlog = logdir();
2782809Swnj 		if ( (k=fopen( concat(nlog,"/makecomm",s), "r")) != NULL)
2792809Swnj 			rdd1(k);
2802809Swnj 		else if ( (k=fopen( concat(nlog,"/Makecomm",s), "r")) != NULL)
2812809Swnj 			rdd1(k);
2822809Swnj 
2832809Swnj 		if ( (k=fopen("makecomm", "r")) != NULL)
2842809Swnj 			rdd1(k);
2852809Swnj 		else if ( (k=fopen("Makecomm", "r")) != NULL)
2862809Swnj 			rdd1(k);
2872809Swnj 		}
2882809Swnj #endif
2892809Swnj 
2902809Swnj 	}
2912809Swnj if(! unequal(descfile, "-"))
2922809Swnj 	return( rdd1(stdin) );
2932809Swnj 
2942809Swnj if( (k = fopen(descfile,"r")) != NULL)
2952809Swnj 	return( rdd1(k) );
2962809Swnj 
2972809Swnj return(1);
2982809Swnj }
2992809Swnj 
3002809Swnj 
3012809Swnj 
3022809Swnj 
3032809Swnj rdd1(k)
3042809Swnj FILE * k;
3052809Swnj {
3062809Swnj extern int yylineno;
3072809Swnj extern char *zznextc;
3082809Swnj 
3092809Swnj fin = k;
3102809Swnj yylineno = 0;
3112809Swnj zznextc = 0;
3122809Swnj 
3132809Swnj if( yyparse() )
3142809Swnj 	fatal("Description file error");
3152809Swnj 
3162809Swnj if(fin != NULL)
3172809Swnj 	fclose(fin);
3182809Swnj 
3192809Swnj return(0);
3202809Swnj }
3212809Swnj 
3222809Swnj printdesc(prntflag)
3232809Swnj int prntflag;
3242809Swnj {
3252809Swnj struct nameblock *p;
3262809Swnj struct depblock *dp;
3272809Swnj struct varblock *vp;
328*6578Smckusick struct dirhdr *od;
3292809Swnj struct shblock *sp;
3302809Swnj struct lineblock *lp;
3312809Swnj 
3322809Swnj #ifdef unix
3332809Swnj if(prntflag)
3342809Swnj 	{
3352809Swnj 	printf("Open directories:\n");
3362809Swnj 	for (od = firstod; od; od = od->nxtopendir)
337*6578Smckusick 		printf("\t%d: %s\n", od->dirfc->dd_fd, od->dirn);
3382809Swnj 	}
3392809Swnj #endif
3402809Swnj 
3412809Swnj if(firstvar != 0) printf("Macros:\n");
3422809Swnj for(vp = firstvar; vp ; vp = vp->nxtvarblock)
3432809Swnj 	printf("\t%s = %s\n" , vp->varname , vp->varval);
3442809Swnj 
3452809Swnj for(p = firstname; p; p = p->nxtnameblock)
3462809Swnj 	{
3472809Swnj 	printf("\n\n%s",p->namep);
3482809Swnj 	if(p->linep != 0) printf(":");
3492809Swnj 	if(prntflag) printf("  done=%d",p->done);
3502809Swnj 	if(p==mainname) printf("  (MAIN NAME)");
3512809Swnj 	for(lp = p->linep ; lp ; lp = lp->nxtlineblock)
3522809Swnj 		{
3532809Swnj 		if( dp = lp->depp )
3542809Swnj 			{
3552809Swnj 			printf("\n depends on:");
3562809Swnj 			for(; dp ; dp = dp->nxtdepblock)
3572809Swnj 				if(dp->depname != 0)
3582809Swnj 					printf(" %s ", dp->depname->namep);
3592809Swnj 			}
3602809Swnj 
3612809Swnj 		if(sp = lp->shp)
3622809Swnj 			{
3632809Swnj 			printf("\n commands:\n");
3642809Swnj 			for( ; sp!=0 ; sp = sp->nxtshblock)
3652809Swnj 				printf("\t%s\n", sp->shbp);
3662809Swnj 			}
3672809Swnj 		}
3682809Swnj 	}
3692809Swnj printf("\n");
3702809Swnj fflush(stdout);
3712809Swnj }
372