9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

main.c (4791B)


      1 #include	"mk.h"
      2 
      3 #define		MKFILE		"mkfile"
      4 
      5 int debug;
      6 Rule *rules, *metarules;
      7 int nflag = 0;
      8 int tflag = 0;
      9 int iflag = 0;
     10 int kflag = 0;
     11 int aflag = 0;
     12 int uflag = 0;
     13 char *explain = 0;
     14 Word *target1;
     15 int nreps = 1;
     16 Job *jobs;
     17 Biobuf bout;
     18 Rule *patrule;
     19 void badusage(void);
     20 #ifdef	PROF
     21 short buf[10000];
     22 #endif
     23 
     24 int
     25 main(int argc, char **argv)
     26 {
     27 	Word *w;
     28 	char *s, *temp;
     29 	char *files[256], **f = files, **ff;
     30 	int sflag = 0;
     31 	int i;
     32 	int tfd = -1;
     33 	Biobuf tb;
     34 	Bufblock *buf;
     35 	Bufblock *whatif;
     36 
     37 	/*
     38 	 *  start with a copy of the current environment variables
     39 	 *  instead of sharing them
     40 	 */
     41 
     42 	Binit(&bout, 1, OWRITE);
     43 	buf = newbuf();
     44 	whatif = 0;
     45 	USED(argc);
     46 	for(argv++; *argv && (**argv == '-'); argv++)
     47 	{
     48 		bufcpy(buf, argv[0], strlen(argv[0]));
     49 		insert(buf, ' ');
     50 		switch(argv[0][1])
     51 		{
     52 		case 'a':
     53 			aflag = 1;
     54 			break;
     55 		case 'd':
     56 			if(*(s = &argv[0][2]))
     57 				while(*s) switch(*s++)
     58 				{
     59 				case 'p':	debug |= D_PARSE; break;
     60 				case 'g':	debug |= D_GRAPH; break;
     61 				case 'e':	debug |= D_EXEC; break;
     62 				}
     63 			else
     64 				debug = 0xFFFF;
     65 			break;
     66 		case 'e':
     67 			explain = &argv[0][2];
     68 			break;
     69 		case 'f':
     70 			if(*++argv == 0)
     71 				badusage();
     72 			*f++ = *argv;
     73 			bufcpy(buf, argv[0], strlen(argv[0]));
     74 			insert(buf, ' ');
     75 			break;
     76 		case 'i':
     77 			iflag = 1;
     78 			break;
     79 		case 'k':
     80 			kflag = 1;
     81 			break;
     82 		case 'n':
     83 			nflag = 1;
     84 			break;
     85 		case 's':
     86 			sflag = 1;
     87 			break;
     88 		case 't':
     89 			tflag = 1;
     90 			break;
     91 		case 'u':
     92 			uflag = 1;
     93 			break;
     94 		case 'w':
     95 			if(whatif == 0)
     96 				whatif = newbuf();
     97 			else
     98 				insert(whatif, ' ');
     99 			if(argv[0][2])
    100 				bufcpy(whatif, &argv[0][2], strlen(&argv[0][2]));
    101 			else {
    102 				if(*++argv == 0)
    103 					badusage();
    104 				bufcpy(whatif, &argv[0][0], strlen(&argv[0][0]));
    105 			}
    106 			break;
    107 		default:
    108 			badusage();
    109 		}
    110 	}
    111 #ifdef	PROF
    112 	{
    113 		extern etext();
    114 		monitor(main, etext, buf, sizeof buf, 300);
    115 	}
    116 #endif
    117 
    118 	if(aflag)
    119 		iflag = 1;
    120 	usage();
    121 	syminit();
    122 	initshell();
    123 	initenv();
    124 	usage();
    125 
    126 	/*
    127 		assignment args become null strings
    128 	*/
    129 	temp = 0;
    130 	for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){
    131 		bufcpy(buf, argv[i], strlen(argv[i]));
    132 		insert(buf, ' ');
    133 		if(tfd < 0){
    134 			temp = maketmp(&tfd);
    135 			if(temp == 0) {
    136 				fprint(2, "temp file: %r\n");
    137 				Exit();
    138 			}
    139 			Binit(&tb, tfd, OWRITE);
    140 		}
    141 		Bprint(&tb, "%s\n", argv[i]);
    142 		*argv[i] = 0;
    143 	}
    144 	if(tfd >= 0){
    145 		Bflush(&tb);
    146 		LSEEK(tfd, 0L, 0);
    147 		parse("command line args", tfd, 1);
    148 		remove(temp);
    149 	}
    150 
    151 	if (buf->current != buf->start) {
    152 		buf->current--;
    153 		insert(buf, 0);
    154 	}
    155 	symlook("MKFLAGS", S_VAR, (void *) stow(buf->start));
    156 	buf->current = buf->start;
    157 	for(i = 0; argv[i]; i++){
    158 		if(*argv[i] == 0) continue;
    159 		if(i)
    160 			insert(buf, ' ');
    161 		bufcpy(buf, argv[i], strlen(argv[i]));
    162 	}
    163 	insert(buf, 0);
    164 	symlook("MKARGS", S_VAR, (void *) stow(buf->start));
    165 	freebuf(buf);
    166 
    167 	if(f == files){
    168 		if(access(MKFILE, 4) == 0)
    169 			parse(MKFILE, open(MKFILE, 0), 0);
    170 	} else
    171 		for(ff = files; ff < f; ff++)
    172 			parse(*ff, open(*ff, 0), 0);
    173 	if(DEBUG(D_PARSE)){
    174 		dumpw("default targets", target1);
    175 		dumpr("rules", rules);
    176 		dumpr("metarules", metarules);
    177 		dumpv("variables");
    178 	}
    179 	if(whatif){
    180 		insert(whatif, 0);
    181 		timeinit(whatif->start);
    182 		freebuf(whatif);
    183 	}
    184 	execinit();
    185 	/* skip assignment args */
    186 	while(*argv && (**argv == 0))
    187 		argv++;
    188 
    189 	catchnotes();
    190 	if(*argv == 0){
    191 		if(target1)
    192 			for(w = target1; w; w = w->next)
    193 				mk(w->s);
    194 		else {
    195 			fprint(2, "mk: nothing to mk\n");
    196 			Exit();
    197 		}
    198 	} else {
    199 		if(sflag){
    200 			for(; *argv; argv++)
    201 				if(**argv)
    202 					mk(*argv);
    203 		} else {
    204 			Word *head, *tail, *t;
    205 
    206 			/* fake a new rule with all the args as prereqs */
    207 			tail = 0;
    208 			t = 0;
    209 			for(; *argv; argv++)
    210 				if(**argv){
    211 					if(tail == 0)
    212 						tail = t = newword(*argv);
    213 					else {
    214 						t->next = newword(*argv);
    215 						t = t->next;
    216 					}
    217 				}
    218 			if(tail->next == 0)
    219 				mk(tail->s);
    220 			else {
    221 				head = newword("command line arguments");
    222 				addrules(head, tail, strdup(""), VIR, mkinline, 0);
    223 				mk(head->s);
    224 			}
    225 		}
    226 	}
    227 	if(uflag)
    228 		prusage();
    229 	exits(0);
    230 	return 0;
    231 }
    232 
    233 void
    234 badusage(void)
    235 {
    236 
    237 	fprint(2, "Usage: mk [-f file] [-n] [-a] [-e] [-t] [-k] [-i] [-d[egp]] [targets ...]\n");
    238 	Exit();
    239 }
    240 
    241 void *
    242 Malloc(int n)
    243 {
    244 	register void *s;
    245 
    246 	s = malloc(n);
    247 	if(!s) {
    248 		fprint(2, "mk: cannot alloc %d bytes\n", n);
    249 		Exit();
    250 	}
    251 	return(s);
    252 }
    253 
    254 void *
    255 Realloc(void *s, int n)
    256 {
    257 	if(s)
    258 		s = realloc(s, n);
    259 	else
    260 		s = malloc(n);
    261 	if(!s) {
    262 		fprint(2, "mk: cannot alloc %d bytes\n", n);
    263 		Exit();
    264 	}
    265 	return(s);
    266 }
    267 
    268 void
    269 assert(char *s, int n)
    270 {
    271 	if(!n){
    272 		fprint(2, "mk: Assertion ``%s'' failed.\n", s);
    273 		Exit();
    274 	}
    275 }
    276 
    277 void
    278 regerror(char *s)
    279 {
    280 	if(patrule)
    281 		fprint(2, "mk: %s:%d: regular expression error; %s\n",
    282 			patrule->file, patrule->line, s);
    283 	else
    284 		fprint(2, "mk: %s:%d: regular expression error; %s\n",
    285 			infile, mkinline, s);
    286 	Exit();
    287 }