1 /*
2  * genmk -- a program to make makefiles for PCCTS
3  *
4  * ANTLR 1.33MR10
5  * Terence John Parr 1989 - 1998
6  * Purdue University
7  * U of MN
8  */
9 
10 #include <stdio.h>
11 #include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */
12 
13 #ifdef VAXC
14 #define DIE		return 0;
15 #define DONE	return 1;
16 #else
17 #define DIE		return 1;
18 #define DONE	return 0;
19 #endif
20 
21 #ifndef require
22 #define require(expr, err) {if ( !(expr) ) fatal(err);}
23 #endif
24 
25 #define MAX_FILES	50
26 #define MAX_CLASSES	50
27 
28 char *RENAME_OBJ_FLAG="-o",
29      *RENAME_EXE_FLAG="-o";
30 
31 char *dlg = "parser.dlg";
32 char *err = "err.c";
33 char *hdr = "stdpccts.h";
34 char *tok = "tokens.h";
35 char *mode = "mode.h";
36 char *scan = "scan";
37 
38 char ATOKENBUFFER_O[100];
39 char APARSER_O[100];
40 char ASTBASE_O[100];
41 char PCCTSAST_O[100];
42 char LIST_O[100];
43 char DLEXERBASE_O[100];
44 
45 /* Option flags */
46 static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
47 static int	num_files = 0;
48 static int	num_classes = 0;
49 static int	user_lexer = 0;
50 static char	*user_token_types = NULL;
51 static int	gen_CPP = 0;
52 static char *outdir=".";
53 static char *dlg_class = "DLGLexer";
54 static int	gen_trees = 0;
55 static int  gen_hoist = 0;
56 static char cfiles[1600]="";
57 static char *compilerCCC="CC";
58 static char *compilerCC="cc";
59 static char *pccts_path="/usr/local/pccts";
60 
61 void help();
62 void mk();
63 void pfiles();
64 void pclasses();
65 void fatal();
66 void warn();
67 
68 typedef struct _Opt {
69 			char *option;
70 			int  arg;
71 #ifdef __cplusplus
72 			void (*process)(...);
73 #else
74 			void (*process)();
75 #endif
76 			char *descr;
77 		} Opt;
78 
79 #ifdef __STDC__
80 static void ProcessArgs(int, char **, Opt *);
81 #else
82 static void ProcessArgs();
83 #endif
84 
85 static void
pProj(s,t)86 pProj( s, t )
87 char *s;
88 char *t;
89 {
90 	project = t;
91 }
92 
93 static void
pUL(s)94 pUL( s )
95 char *s;
96 {
97 	user_lexer = 1;
98 }
99 
100 static void
pCPP(s)101 pCPP( s )
102 char *s;
103 {
104 	gen_CPP = 1;
105 }
106 
107 static void
pUT(s,t)108 pUT( s, t )
109 char *s;
110 char *t;
111 {
112 	user_token_types = t;
113 }
114 
115 static void
pTrees(s)116 pTrees( s )
117 char *s;
118 {
119 	gen_trees = 1;
120 }
121 
122 static void
pHoist(s)123 pHoist( s )
124 char *s;
125 {
126 	gen_hoist = 1;
127 }
128 
129 static void
130 #ifdef __STDC__
pFile(char * s)131 pFile( char *s )
132 #else
133 pFile( s )
134 char *s;
135 #endif
136 {
137 	if ( *s=='-' )
138 	{
139 		fprintf(stderr, "invalid option: '%s'; ignored...",s);
140 		return;
141 	}
142 
143 	require(num_files<MAX_FILES, "exceeded max # of input files");
144 	files[num_files++] = s;
145 }
146 
147 static void
148 #ifdef __STDC__
pClass(char * s,char * t)149 pClass( char *s, char *t )
150 #else
151 pClass( s, t )
152 char *s;
153 char *t;
154 #endif
155 {
156 	require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
157 	classes[num_classes++] = t;
158 }
159 
160 static void
161 #ifdef __STDC__
pDLGClass(char * s,char * t)162 pDLGClass( char *s, char *t )
163 #else
164 pDLGClass( s, t )
165 char *s;
166 char *t;
167 #endif
168 {
169 	if ( !gen_CPP ) {
170 		fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
171 	}
172 	else dlg_class = t;
173 }
174 
175 static void
176 #ifdef __STDC__
pOdir(char * s,char * t)177 pOdir( char *s, char *t )
178 #else
179 pOdir( s, t )
180 char *s;
181 char *t;
182 #endif
183 {
184 	outdir = t;
185 }
186 
187 static void
188 #ifdef __STDC__
pHdr(char * s,char * t)189 pHdr( char *s, char *t )
190 #else
191 pHdr( s, t )
192 char *s;
193 char *t;
194 #endif
195 {
196 	hdr = t;
197 }
198 
199 static void
200 #ifdef __STDC__
pCFiles(char * s,char * t)201 pCFiles( char *s, char *t )
202 #else
203 pCFiles( s, t )
204 char *s;
205 char *t;
206 #endif
207 {
208 	strcat(strcat(cfiles," "), t);
209 }
210 
211 static void
212 #ifdef __STDC__
pCompiler(char * s,char * t)213 pCompiler( char *s, char *t )
214 #else
215 pCompiler( s, t )
216 char *s;
217 char *t;
218 #endif
219 {
220         compilerCCC = t;
221 	compilerCC = t;
222 }
223 
224 static void
225 #ifdef __STDC__
ppccts_path(char * s,char * t)226 ppccts_path( char *s, char *t )
227 #else
228 ppccts_path( s, t )
229 char *s;
230 char *t;
231 #endif
232 {
233         pccts_path = t;
234 }
235 
236 Opt options[] = {
237     { "-CC", 0,	pCPP,			"Generate C++ output"},
238     { "-class", 1,	pClass,		"Name of a grammar class defined in grammar (if C++)"},
239     { "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
240     { "-header", 1,pHdr,		"Name of ANTLR standard header info (default=no file)"},
241     { "-o", 1,	pOdir,			"Directory where output files should go (default=\".\")"},
242     { "-project", 1,	pProj,	"Name of executable to create (default=t)"},
243     { "-token-types", 1, pUT,	"Token types are in this file (don't use tokens.h)"},
244     { "-trees", 0, pTrees,		"Generate ASTs"},
245     { "-user-lexer", 0,	pUL,	"Do not create a DLG-based scanner"},
246     { "-mrhoist",0,pHoist,      "Maintenance release style hoisting"},
247     { "-cfiles",1,pCFiles,      "Additional files in C or C++ to compile"},
248     { "-pccts_path",1,ppccts_path,
249               "Path for $PCCTS directory (default is /usr/local/pccts)"},
250     { "-compiler",1,pCompiler,
251               "Default compiler (default is CC/cc)"},
252     { "*", 0,pFile, 	        "" },	/* anything else is a file */
253 	{ NULL, 0, NULL, NULL }
254 };
255 
256 extern char *DIR();
257 
main(argc,argv)258 int main(argc, argv)
259 int argc;
260 char **argv;
261 {
262 	if ( argc == 1 ) { help(); DIE; }
263 	ProcessArgs(argc-1, &(argv[1]), options);
264 
265 	strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
266 	ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
267 	strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);
268 	strcpy(APARSER_O, APARSER_C);
269 	APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';
270 	strcat(APARSER_O, OBJ_FILE_SUFFIX);
271 
272 	strcpy(ASTBASE_O, ASTBASE_C);
273 	ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
274 	strcat(ASTBASE_O, OBJ_FILE_SUFFIX);
275 
276 	strcpy(PCCTSAST_O, PCCTSAST_C);
277 	PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
278 	strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);
279 
280 	strcpy(LIST_O, LIST_C);
281 	LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
282 	strcat(LIST_O, OBJ_FILE_SUFFIX);
283 
284 	strcpy(DLEXERBASE_O, DLEXERBASE_C);
285 	DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
286 	strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);
287 
288 	if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
289 	if ( !gen_CPP && num_classes>0 ) {
290 		warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
291 		gen_CPP=1;
292 	}
293 	if ( gen_CPP && num_classes==0 ) {
294 		fatal("must define classes >0 grammar classes in C++ mode\n");
295 	}
296 
297 	mk(project, files, num_files, argc, argv);
298 	DONE;
299 }
300 
help()301 void help()
302 {
303 	Opt *p = options;
304 	static char buf[1000+1];
305 
306 	fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
307 	while ( p->option!=NULL && *(p->option) != '*' )
308 	{
309 		buf[0]='\0';
310 		if ( p->arg ) sprintf(buf, "%s ___", p->option);
311 		else strcpy(buf, p->option);
312 		fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);
313 		p++;
314 	}
315 }
316 
mk(project,files,n,argc,argv)317 void mk(project, files, n, argc, argv)
318 char *project;
319 char **files;
320 int n;
321 int argc;
322 char **argv;
323 {
324 	int i;
325 
326 	printf("#\n");
327 	printf("# PCCTS makefile for: ");
328 	pfiles(files, n, NULL);
329 	printf("\n");
330 	printf("#\n");
331 	printf("# Created from:");
332 	for (i=0; i<argc; i++) printf(" %s", argv[i]);
333 	printf("\n");
334 	printf("#\n");
335 	printf("# PCCTS release 1.33MR21\n");
336 	printf("# Project: %s\n", project);
337 	if ( gen_CPP ) printf("# C++ output\n");
338 	else printf("# C output\n");
339 	if ( user_lexer ) printf("# User-defined scanner\n");
340 	else printf("# DLG scanner\n");
341 	if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
342 	else printf("# ANTLR-defined token types\n");
343 	printf("#\n");
344 	printf(".SUFFIXES:\n.SUFFIXES:      .o .cpp .c .h .g .i .dlg\n");
345 	if ( user_token_types!=NULL ) {
346 		printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
347 		printf("TOKENS = %s", user_token_types);
348 	}
349 	else printf("TOKENS = %stokens.h", DIR());
350 	printf("\n");
351 	printf("#\n");
352 	printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
353 	printf("DLG_FILE = %s%s\n", DIR(), dlg);
354 	printf("ERR = %serr\n", DIR());
355 	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
356 	else printf("HDR_FILE =\n");
357 	if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
358 	if ( !gen_CPP ) printf("SCAN = %s\n", scan);
359 	else printf("SCAN = %s%s\n", DIR(), dlg_class);
360 
361 	printf("PCCTS = %s\n",pccts_path);
362 	printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
363 	printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
364 	printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
365 	printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
366 	printf("CFLAGS = -I. -I$(ANTLR_H)");
367 	if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
368     printf(" $(COTHER)");
369 	printf("\n");
370 	printf("AFLAGS =");
371 	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
372 	if ( user_lexer ) printf(" -gx");
373 	if ( gen_CPP ) printf(" -CC");
374 	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
375 	if ( gen_trees ) printf(" -gt");
376     if ( gen_hoist ) {
377       printf(" -mrhoist on") ;
378     } else {
379       printf(" -mrhoist off");
380     };
381     printf(" $(AOTHER)");
382 	printf("\n");
383 	printf("DFLAGS = -C2 -i");
384 	if ( gen_CPP ) printf(" -CC");
385 	if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
386 	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
387     printf(" $(DOTHER)");
388 	printf("\n");
389 	printf("GRM = ");
390 	pfiles(files, n, NULL);
391 	printf("\n");
392 	printf("MYFILES = %s\n",cfiles);
393 	printf("SRC = ");
394 	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
395 	else pfiles(files, n, "c");
396 	if ( gen_CPP ) {
397 		printf(" \\\n     ");
398 		printf(" ");
399 		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
400 		printf(" \\\n      ");
401 		printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);
402 		if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);
403 		if ( gen_trees ) {
404 			printf(" \\\n      ");
405 			printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);
406 			printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);
407 /*			printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */
408 			printf(" \\\n      ");
409 		}
410 		printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);
411 	}
412 	if ( !user_lexer ) {
413 		if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);
414 		else printf(" %s$(SCAN).c", DIR());
415 	}
416 	if ( !gen_CPP ) printf(" $(ERR).c");
417 	printf("\\\n	$(MYFILES)\n");
418 	printf("OBJ = ");
419 	pfiles(files, n, "o");
420 	if ( gen_CPP ) {
421 		printf(" \\\n     ");
422 		printf(" ");
423 		pclasses(classes, num_classes, "o");
424 		printf(" \\\n      ");
425 		printf(" %s%s", DIR(), APARSER_O);
426 		if ( !user_lexer ) {
427 			printf(" %s%s", DIR(), DLEXERBASE_O);
428 		}
429 		if ( gen_trees ) {
430 			printf(" \\\n      ");
431 			printf("%s%s", DIR(), ASTBASE_O);
432 			printf(" %s%s", DIR(), PCCTSAST_O);
433 /*			printf(" %s%s", DIR(), LIST_O); */
434 			printf(" \\\n      ");
435 		}
436 		printf(" %s%s", DIR(), ATOKENBUFFER_O);
437 	}
438 	if ( !user_lexer ) {
439 		if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);
440 		else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);
441 	}
442 	if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);
443 	printf("\\\n	$(MYFILES:.cpp=.o)\n");
444 
445 	printf("ANTLR_SPAWN = ");
446 	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
447 	else pfiles(files, n, "c");
448 	if ( gen_CPP ) {
449 		printf(" ");
450 		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
451 		printf(" \\\n              ");
452 		pclasses(classes, num_classes, "h");
453 		if ( strcmp(hdr,"stdpccts.h")!=0 ) {
454 			printf(" \\\n              ");
455 			printf("$(HDR_FILE) stdpccts.h");
456 		}
457 	}
458 	if ( user_lexer ) {
459 		if ( !user_token_types ) printf(" $(TOKENS)");
460 	}
461 	else {
462 		printf(" $(DLG_FILE)");
463 		if ( !user_token_types ) printf(" $(TOKENS)");
464 	}
465 	if ( !gen_CPP ) printf(" $(ERR).c");
466 	printf("\n");
467 
468 	if ( !user_lexer ) {
469 		if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);
470 		else printf("DLG_SPAWN = %s$(SCAN).c", DIR());
471 		if ( gen_CPP ) printf(" $(SCAN).h");
472 		if ( !gen_CPP ) printf(" $(MOD_FILE)");
473 		printf("\n");
474 	}
475 
476 	if ( gen_CPP ) {
477 		printf("CCC = %s\n",compilerCCC);
478 	}
479 	else printf("CC = %s\n",compilerCC);
480 
481 	/* set up dependencies */
482 	printf("\n%s : $(OBJ) $(SRC)\n", project);
483 	printf("	%s %s %s $(CFLAGS) $(OBJ)\n",
484 		   gen_CPP?"$(CCC)":"$(CC)",
485 		   RENAME_EXE_FLAG,
486 		   project);
487 	printf("\n");
488 
489 	/* implicit rules */
490 
491 	if(gen_CPP)
492 		printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");
493 
494 	printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",
495 			gen_CPP?"$(CCC)":"$(CC)");
496 
497 	/* how to compile parser files */
498 
499 	for (i=0; i<num_files; i++)
500 	{
501 		pfiles(&files[i], 1, "o");
502 		if ( user_lexer ) {
503 			printf(" : $(TOKENS)");
504 		}
505 		else {
506 			if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");
507 			else printf(" : $(MOD_FILE) $(TOKENS)");
508 		}
509 		printf(" ");
510 		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
511 		else pfiles(&files[i], 1, "c");
512 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
513 		printf("\n");
514 		printf("	%s -c $(CFLAGS) %s ",
515 		       gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
516 		pfiles(&files[i], 1, "o");
517 		printf(" ");
518 		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
519 		else pfiles(&files[i], 1, "c");
520 		printf("\n\n");
521 	}
522 
523 	/* how to compile err.c */
524 	if ( !gen_CPP ) {
525 		printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);
526 		if ( !user_lexer ) printf(" $(TOKENS)");
527 		printf("\n");
528 		printf("	%s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",
529 			   gen_CPP?"$(CCC)":"$(CC)",
530 			   RENAME_OBJ_FLAG,
531 			   OBJ_FILE_SUFFIX);
532 		printf("\n\n");
533 	}
534 
535 	/* how to compile Class.c */
536 	for (i=0; i<num_classes; i++)
537 	{
538 		pclasses(&classes[i], 1, "o");
539 		if ( user_lexer ) {
540 			printf(" : $(TOKENS)");
541 		}
542 		else {
543 			printf(" : $(TOKENS) $(SCAN).h");
544 		}
545 		printf(" ");
546 		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
547 		printf(" ");
548 		pclasses(&classes[i], 1, "h");
549 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
550 		printf("\n");
551 		printf("	%s -c $(CFLAGS) %s ",
552 			   gen_CPP?"$(CCC)":"$(CC)",
553 			   RENAME_OBJ_FLAG);
554 		pclasses(&classes[i], 1, "o");
555 		printf(" ");
556 		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
557 		printf("\n\n");
558 	}
559 
560 	/* how to compile scan.c */
561 	if ( !user_lexer ) {
562 		if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);
563 		else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());
564 		if ( !user_lexer ) printf(" $(TOKENS)");
565 		printf("\n");
566 		if ( gen_CPP ) printf("	$(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",
567 							  RENAME_OBJ_FLAG,
568 							  OBJ_FILE_SUFFIX,
569 							  CPP_FILE_SUFFIX);
570 		else printf("	$(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",
571 					RENAME_OBJ_FLAG,
572 					DIR(),
573 					OBJ_FILE_SUFFIX,
574 					DIR());
575 		printf("\n\n");
576 	}
577 
578 	printf("$(ANTLR_SPAWN) : $(GRM)\n");
579 	printf("	$(ANTLR) $(AFLAGS) $(GRM)\n");
580 
581 	if ( !user_lexer )
582 	{
583 		printf("\n");
584 		printf("$(DLG_SPAWN) : $(DLG_FILE)\n");
585 		if ( gen_CPP ) printf("	$(DLG) $(DFLAGS) $(DLG_FILE)\n");
586 		else printf("	$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");
587 	}
588 
589 	/* do the makes for ANTLR/DLG support */
590 	if ( gen_CPP ) {
591 		printf("\n");
592 		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
593 		printf("	%s -c $(CFLAGS) %s ",
594 			   gen_CPP?"$(CCC)":"$(CC)",
595 			   RENAME_OBJ_FLAG);
596 		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
597 		printf("\n");
598 		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
599 		printf("	%s -c $(CFLAGS) %s ",
600 			   gen_CPP?"$(CCC)":"$(CC)",
601 			   RENAME_OBJ_FLAG);
602 		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
603 		if ( !user_lexer ) {
604 			printf("\n");
605 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
606 			printf("	%s -c $(CFLAGS) %s ",
607 				   gen_CPP?"$(CCC)":"$(CC)",
608 				   RENAME_OBJ_FLAG);
609 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
610 		}
611 		if ( gen_trees ) {
612 			printf("\n");
613 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
614 			printf("	%s -c $(CFLAGS) %s ",
615 				   gen_CPP?"$(CCC)":"$(CC)",
616 				   RENAME_OBJ_FLAG);
617 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
618 			printf("\n");
619 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
620 			printf("	%s -c $(CFLAGS) %s ",
621 				   gen_CPP?"$(CCC)":"$(CC)",
622 				   RENAME_OBJ_FLAG);
623 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
624 			printf("\n");
625 /*
626 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
627 			printf("	%s -c $(CFLAGS) %s ",
628 			       gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
629 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
630 */
631 		}
632 	}
633 
634 	/* clean and scrub targets */
635 
636 	printf("\nclean:\n");
637 	printf("	rm -f *%s core %s", OBJ_FILE_SUFFIX, project);
638 	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
639 	printf("\n");
640 
641 	printf("\nscrub:\n");
642 	printf("	rm -f *%s core %s", OBJ_FILE_SUFFIX, project);
643 	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
644 	printf(" $(ANTLR_SPAWN)");
645 	if ( !user_lexer ) printf(" $(DLG_SPAWN)");
646 	printf("\n");
647 }
648 
pfiles(files,n,suffix)649 void pfiles(files, n, suffix)
650 char **files;
651 int n;
652 char *suffix;
653 {
654 	int first=1;
655 
656 	while ( n>0 )
657 	{
658 		char *p = &(*files)[strlen(*files)-1];
659 		if ( !first ) putchar(' ');
660 		first=0;
661 		while ( p > *files && *p != '.' ) --p;
662 		if ( p == *files )
663 		{
664 			fprintf(stderr,
665 					"genmk: filenames must be file.suffix format: %s\n",
666 					*files);
667 			exit(-1);
668 		}
669 		if ( suffix == NULL ) printf("%s", *files);
670 		else
671 		{
672 			*p = '\0';
673 			printf("%s", DIR());
674 			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);
675 			else printf("%s.%s", *files, suffix);
676 			*p = '.';
677 		}
678 		files++;
679 		--n;
680 	}
681 }
682 
pclasses(classes,n,suffix)683 void pclasses(classes, n, suffix)
684 char **classes;
685 int n;
686 char *suffix;
687 {
688 	int first=1;
689 
690 	while ( n>0 )
691 	{
692 		if ( !first ) putchar(' ');
693 		first=0;
694 		if ( suffix == NULL ) printf("%s", *classes);
695 		else {
696 			printf("%s", DIR());
697 			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);
698 			else printf("%s.%s", *classes, suffix);
699 		}
700 		classes++;
701 		--n;
702 	}
703 }
704 
705 static void
706 #ifdef __STDC__
ProcessArgs(int argc,char ** argv,Opt * options)707 ProcessArgs( int argc, char **argv, Opt *options )
708 #else
709 ProcessArgs( argc, argv, options )
710 int argc;
711 char **argv;
712 Opt *options;
713 #endif
714 {
715 	Opt *p;
716 	require(argv!=NULL, "ProcessArgs: command line NULL");
717 
718 	while ( argc-- > 0 )
719 	{
720 		p = options;
721 		while ( p->option != NULL )
722 		{
723 			if ( strcmp(p->option, "*") == 0 ||
724 				 strcmp(p->option, *argv) == 0 )
725 			{
726 				if ( p->arg )
727 				{
728 					(*p->process)( *argv, *(argv+1) );
729 					argv++;
730 					argc--;
731 				}
732 				else
733 					(*p->process)( *argv );
734 				break;
735 			}
736 			p++;
737 		}
738 		argv++;
739 	}
740 }
741 
fatal(err_)742 void fatal( err_)
743 char *err_;
744 {
745     fprintf(stderr, "genmk: %s\n", err_);
746     exit(1);
747 }
748 
warn(err_)749 void warn( err_)
750 char *err_;
751 {
752     fprintf(stderr, "genmk: %s\n", err_);
753 }
754 
DIR()755 char *DIR()
756 {
757 	static char buf[200+1];
758 
759 	if ( strcmp(outdir,TopDirectory)==0 ) return "";
760 	sprintf(buf, "%s%s", outdir, DirectorySymbol);
761 	return buf;
762 }
763