1 /*
2  * genmk -- a program to make makefiles for PCCTS
3  *
4  * ANTLR 1.33MR23
5  * Terence John Parr 1989 - 2000
6  * Purdue University
7  * U of MN
8  */
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include "pcctscfg.h" /* be sensitive to what ANTLR/DLG call the files */
13 
14 #ifdef VAXC
15 #define DIE		return 0;
16 #define DONE	return 1;
17 #else
18 #define DIE		return 1;
19 #define DONE	return 0;
20 #endif
21 
22 #ifndef require
23 #define require(expr, err) {if ( !(expr) ) fatal(err);}
24 #endif
25 
26 #define MAX_FILES	50
27 #define MAX_CFILES	1600
28 #define MAX_SFILES	50
29 #define MAX_SORS	50
30 #define MAX_CLASSES	50
31 
32 char *RENAME_OBJ_FLAG="-o",
33      *RENAME_EXE_FLAG="-o";
34 
35 char *dlg = "parser.dlg";
36 char *err = "err.c";
37 char *hdr = "stdpccts.h";
38 char *tok = "tokens.h";
39 char *mode = "mode.h";
40 char *scan = "scan";
41 
42 char ATOKENBUFFER_O[100];
43 char APARSER_O[100];
44 char ASTBASE_O[100];
45 char PCCTSAST_O[100];
46 char LIST_O[100];
47 char DLEXERBASE_O[100];
48 
49 /* Option flags */
50 static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
51 static char *cfiles[MAX_CFILES];
52 static char *sfiles[MAX_SORS][MAX_SFILES],*sclasses[MAX_SORS];
53 static int  num_sfiles[MAX_SORS]; /*sorcerer files in group */
54 static int  num_sors = 0; /*sorcerer groups */
55 static int  num_files = 0; /* grammar files */
56 static int  num_cfiles = 0; /* additional C/C++ files */
57 static int  num_classes = 0; /* ANTLR classes */
58 static int  user_lexer = 0;
59 static char *user_token_types = NULL;
60 static int  gen_CPP = 0;
61 static char *outdir=".";
62 static char *dlg_class = "DLGLexer";
63 static int  gen_trees = 0;
64 static int  gen_hoist = 0;
65 static int  nondef_comp = 0; /* 1=compiler is non default */
66 static char *compilerCCC="CC";
67 static char *compilerCC="cc";
68 static char *pccts_path="/usr/local/pccts";
69 
70 #ifdef __STDC__
71 void help(void);
72 void mk(char *project, char **files, int n, int argc, char **argv);
73 void pfiles(char **files, int n, char *suffix);
74 void fatal(char *msg);
75 void warn(char *msg);
76 #else
77 void help();
78 void mk();
79 void pfiles();
80 void fatal();
81 void warn();
82 #endif
83 
84 typedef struct _Opt {
85 			char *option;
86 			int arg;
87 #ifdef __cplusplus
88 			void (*process)(...);
89 #else
90 			void (*process)();
91 #endif
92 			char *descr;
93 		} Opt;
94 
95 #ifdef __STDC__
96 static void ProcessArgs(int, char **, Opt *);
97 #else
98 static void ProcessArgs();
99 #endif
100 
101 static void
102 #ifdef __STDC__
pProj(char * s,char * t)103 pProj(char *s, char *t )
104 #else
105 pProj( s, t )
106 char *s;
107 char *t;
108 #endif
109 {
110 	project = t;
111 }
112 
113 static void
114 #ifdef __STDC__
pUL(char * s)115 pUL( char *s )
116 #else
117 pUL( s )
118 char *s;
119 #endif
120 {
121 	user_lexer = 1;
122 }
123 
124 static void
125 #ifdef __STDC__
pCPP(char * s)126 pCPP( char *s )
127 #else
128 pCPP( s )
129 char *s;
130 #endif
131 {
132 	gen_CPP = 1;
133 }
134 
135 static void
136 #ifdef __STDC__
pUT(char * s,char * t)137 pUT( char *s, char *t )
138 #else
139 pUT( s, t )
140 char *s;
141 char *t;
142 #endif
143 {
144 	user_token_types = t;
145 }
146 
147 static void
148 #ifdef __STDC__
pTrees(char * s)149 pTrees( char *s )
150 #else
151 pTrees( s )
152 char *s;
153 #endif
154 {
155 	gen_trees = 1;
156 }
157 
158 static void
159 #ifdef __STDC__
pHoist(char * s)160 pHoist( char *s )
161 #else
162 pHoist( s )
163 char *s;
164 #endif
165 {
166 	gen_hoist = 1;
167 }
168 
169 static void
170 #ifdef __STDC__
pSor(char * s)171 pSor( char *s )
172 #else
173 pSor( s )
174 char *s;
175 #endif
176 {
177 	require(num_sors<MAX_SORS, "exceeded max # of sorcerer groups");
178 	num_sors++;
179 	pTrees(NULL); /* silently turn on tree generation */
180 }
181 
182 static void
183 #ifdef __STDC__
pSFiles(char * s,char * t)184 pSFiles( char *s, char *t )
185 #else
186 pSFiles( s, t )
187 char *s;
188 char *t;
189 #endif
190 {
191 	if (num_sors==0)
192 	{
193 		pSor(NULL);
194 		warn("sorcerer input file before any '-sor' option");
195 	}
196 
197 	require(num_sfiles[num_sors-1]<MAX_SFILES,
198 		 "exceeded max # of sorcerer input files");
199 	sfiles[num_sors-1][num_sfiles[num_sors-1]++] = t;
200 }
201 
202 static void
203 #ifdef __STDC__
pCFiles(char * s,char * t)204 pCFiles( char *s, char *t )
205 #else
206 pCFiles( s, t )
207 char *s;
208 char *t;
209 #endif
210 {
211 	require(num_cfiles<MAX_CFILES, "exceeded max # of C/C++ input files");
212 	cfiles[num_cfiles++] = t;
213 }
214 
215 int
216 #ifdef __STDC__
isKnownSuffix(char * s)217 isKnownSuffix( char *s )
218 #else
219 isKnownSuffix( s )
220 	char *s;
221 #endif
222 {
223 	if(s==NULL) return 0;
224 	if (strcasecmp(s,".c")==0) return 1;
225 	if (strcasecmp(s,".cc")==0) return 1;
226 	if (strcasecmp(s,".cpp")==0) return 1;
227 	if (strcasecmp(s,".cxx")==0) return 1;
228 	if (strcasecmp(s,CPP_FILE_SUFFIX)==0) return 1;
229 	if (strcasecmp(s,".sor")==0) return 2;
230 	return 0;
231 }
232 
233 static void
234 #ifdef __STDC__
pFile(char * s)235 pFile( char *s )
236 #else
237 pFile( s )
238 char *s;
239 #endif
240 {
241 	if ( *s=='-' )
242 	{
243 		fprintf(stderr, "invalid option: '%s'; ignored...",s);
244 		return;
245 	}
246 	switch(isKnownSuffix(strrchr(s,'.')))
247 	{
248 	 case 1: /* c/c++ */
249 		pCFiles("-cfiles",s);
250 		return;
251 	 case 2: /* sorcerer */
252 		pSFiles("",s);
253 		return;
254 	 default: /* grammar (ANTLR) */
255 		break;
256 	}
257 	require(num_files<MAX_FILES, "exceeded max # of input files");
258 	files[num_files++] = s;
259 }
260 
261 static void
262 #ifdef __STDC__
pClass(char * s,char * t)263 pClass( char *s, char *t )
264 #else
265 pClass( s, t )
266 char *s;
267 char *t;
268 #endif
269 {
270 	if (num_sors==0)
271 	{
272 		require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
273 		classes[num_classes++] = t;
274 	} else
275 	{
276 		sclasses[num_sors-1] = t; /* one class per sorcerer group (last valid) */
277 	}
278 }
279 
280 static void
281 #ifdef __STDC__
pDLGClass(char * s,char * t)282 pDLGClass( char *s, char *t )
283 #else
284 pDLGClass( s, t )
285 char *s;
286 char *t;
287 #endif
288 {
289 	if ( !gen_CPP ) {
290 		fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
291 	}
292 	else dlg_class = t;
293 }
294 
295 static void
296 #ifdef __STDC__
pOdir(char * s,char * t)297 pOdir( char *s, char *t )
298 #else
299 pOdir( s, t )
300 char *s;
301 char *t;
302 #endif
303 {
304 	outdir = t;
305 }
306 
307 static void
308 #ifdef __STDC__
pHdr(char * s,char * t)309 pHdr( char *s, char *t )
310 #else
311 pHdr( s, t )
312 char *s;
313 char *t;
314 #endif
315 {
316 	hdr = t;
317 }
318 
319 static void
320 #ifdef __STDC__
pCompiler(char * s,char * t)321 pCompiler( char *s, char *t )
322 #else
323 pCompiler( s, t )
324 char *s;
325 char *t;
326 #endif
327 {
328 	compilerCCC = t;
329 	compilerCC = t;
330 	nondef_comp = 1;
331 }
332 
333 static void
334 #ifdef __STDC__
ppccts_path(char * s,char * t)335 ppccts_path( char *s, char *t )
336 #else
337 ppccts_path( s, t )
338 char *s;
339 char *t;
340 #endif
341 {
342 	pccts_path = t;
343 }
344 
345 Opt options[] = {
346 	{ "-CC", 0,	pCPP,			"Generate C++ output"},
347 	{ "-class", 1,	pClass,		"Name of a grammar class defined in grammar (if C++)"},
348 	{ "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
349 	{ "-header", 1,pHdr,		"Name of ANTLR standard header info (default=no file)"},
350 	{ "-o", 1,	pOdir,			"Directory where output files should go (default=\".\")"},
351 	{ "-project", 1,	pProj,	"Name of executable to create (default=t)"},
352 	{ "-token-types", 1, pUT,	"Token types are in this file (don't use tokens.h)"},
353 	{ "-trees", 0, pTrees,		"Generate ASTs"},
354 	{ "-user-lexer", 0,	pUL,	"Do not create a DLG-based scanner"},
355 	{ "-mrhoist",0,pHoist,      "Maintenance release style hoisting"},
356 	{ "-cfiles",1,pCFiles,      "Additional files in C or C++ to compile"},
357 	{ "-sor",0,pSor,           "Start of sorcerer group"},
358 	{ "-pccts_path",1,ppccts_path,
359 			"Path for $PCCTS directory (default is /usr/local/pccts)"},
360 	{ "-compiler",1,pCompiler,
361 			"Default compiler (default is CC/cc)"},
362 	{ "*", 0,pFile, 	        "" },	/* anything else is a file */
363 	{ NULL, 0, NULL, NULL }
364 };
365 
366 #ifdef __STDC__
367 extern char *DIR(void);
368 #else
369 extern char *DIR();
370 #endif
371 
372 #ifdef __STDC__
main(int argc,char ** argv)373 int main(int argc, char **argv)
374 #else
375 int main(argc, argv)
376 int argc;
377 char **argv;
378 #endif
379 {
380 	int i;
381 
382 	if ( argc == 1 ) { help(); DIE; }
383 	for(i=0;i<MAX_SORS;i++) num_sfiles[i]=0;
384 
385 	ProcessArgs(argc-1, &(argv[1]), options);
386 
387 	strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
388 	ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
389 	strcat(ATOKENBUFFER_O, OBJ_FILE_SUFFIX);
390 	strcpy(APARSER_O, APARSER_C);
391 	APARSER_O[strlen(APARSER_O)-strlen(CPP_FILE_SUFFIX)] = '\0';
392 	strcat(APARSER_O, OBJ_FILE_SUFFIX);
393 
394 	strcpy(ASTBASE_O, ASTBASE_C);
395 	ASTBASE_O[strlen(ASTBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
396 	strcat(ASTBASE_O, OBJ_FILE_SUFFIX);
397 
398 	strcpy(PCCTSAST_O, PCCTSAST_C);
399 	PCCTSAST_O[strlen(PCCTSAST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
400 	strcat(PCCTSAST_O, OBJ_FILE_SUFFIX);
401 
402 	strcpy(LIST_O, LIST_C);
403 	LIST_O[strlen(LIST_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
404 	strcat(LIST_O, OBJ_FILE_SUFFIX);
405 
406 	strcpy(DLEXERBASE_O, DLEXERBASE_C);
407 	DLEXERBASE_O[strlen(DLEXERBASE_C)-strlen(CPP_FILE_SUFFIX)] = '\0';
408 	strcat(DLEXERBASE_O, OBJ_FILE_SUFFIX);
409 
410 	if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
411 	if ( !gen_CPP && num_classes>0 ) {
412 		warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
413 		gen_CPP=1;
414 	}
415 	if (!gen_CPP && num_sors) {
416 		warn("can't define sorcerer group in C mode (yet); turning on C++ mode...\n");
417 		gen_CPP=1;
418 	}
419 	if ( gen_CPP && num_classes==0 ) {
420 		fatal("must define classes >0 grammar classes in C++ mode\n");
421 	}
422 
423 	mk(project, files, num_files, argc, argv);
424 	DONE;
425 }
426 
427 #ifdef __STDC__
help(void)428 void help(void)
429 #else
430 void help()
431 #endif
432 {
433 	Opt *p = options;
434 	static char buf[1000+1];
435 
436 	fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
437 	while ( p->option!=NULL && *(p->option) != '*' )
438 	{
439 		buf[0]='\0';
440 		if ( p->arg ) sprintf(buf, "%s ___", p->option);
441 		else strcpy(buf, p->option);
442 		fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);
443 		p++;
444 	}
445 }
446 
447 #ifdef __STDC__
mk(char * project,char ** files,int n,int argc,char ** argv)448 void mk(char *project, char **files, int n, int argc, char **argv)
449 #else
450 void mk(project, files, n, argc, argv)
451 char *project;
452 char **files;
453 int n;
454 int argc;
455 char **argv;
456 #endif
457 {
458 	int i,j;
459 
460 	printf("#\n");
461 	printf("# PCCTS makefile for: ");
462 	pfiles(files, n, NULL);
463 	printf("\n");
464 	printf("#\n");
465 	printf("# Created from:");
466 	for (i=0; i<argc; i++) printf(" %s", argv[i]);
467 	printf("\n");
468 	printf("#\n");
469 	printf("# PCCTS release 1.33MR23\n");
470 	printf("# Project: %s\n", project);
471 	if ( gen_CPP ) printf("# C++ output\n");
472 	else printf("# C output\n");
473 	if ( user_lexer ) printf("# User-defined scanner\n");
474 	else printf("# DLG scanner\n");
475 	if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
476 	else printf("# ANTLR-defined token types\n");
477 	printf("#\n");
478 /***********
479 	printf(".SUFFIXES:\n.SUFFIXES:\t.o .cpp .c .h .g .i .dlg .sor\n");
480  ***********/
481 	if ( user_token_types!=NULL ) {
482 		printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
483 		printf("TOKENS = %s", user_token_types);
484 	}
485 	else printf("TOKENS = %stokens.h", DIR());
486 	printf("\n");
487 	printf("#\n");
488 	printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
489 	printf("DLG_FILE = %s%s\n", DIR(), dlg);
490 	printf("ERR = %serr\n", DIR());
491 	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
492 	else printf("HDR_FILE =\n");
493 	if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
494 	if ( !gen_CPP ) printf("SCAN = %s\n", scan);
495 	else printf("SCAN = %s%s\n", DIR(), dlg_class);
496 
497 	printf("PCCTS = %s\n",pccts_path);
498 	printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
499 	if (num_sors>0) {
500 		printf("SOR_H = $(PCCTS)%ssorcerer%sh\n", DirectorySymbol, DirectorySymbol);
501 		printf("SOR_LIB = $(PCCTS)%ssorcerer%slib\n",
502 			 	DirectorySymbol, DirectorySymbol);
503 	}
504 	printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
505 	printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
506 	printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
507 	if (num_sors>0) printf("SOR = $(BIN)%ssor\n", DirectorySymbol);
508 	printf("CFLAGS = -I. -I$(ANTLR_H)");
509 	if (num_sors>0) printf(" -I$(SOR_H)");
510 	if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
511 	printf(" $(COTHER)");
512 	printf("\n");
513 	printf("AFLAGS =");
514 	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
515 	if ( user_lexer ) printf(" -gx");
516 	if ( gen_CPP ) printf(" -CC");
517 	if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
518 	if ( gen_trees ) printf(" -gt");
519 	if ( gen_hoist ) {
520 		printf(" -mrhoist on") ;
521 	} else {
522 		printf(" -mrhoist off");
523 	};
524 	printf(" $(AOTHER)");
525 	printf("\n");
526 	printf("DFLAGS = -C2 -i");
527 	if ( gen_CPP ) printf(" -CC");
528 	if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
529 	if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
530 	printf(" $(DOTHER)");
531 	printf("\n");
532 	if (num_sors>0)
533 	{
534 		printf("SFLAGS = -CPP");
535 		if ( strcmp(outdir,".")!=0 ) printf(" -out-dir %s", outdir);
536 		printf(" $(SOTHER)\n");
537 	}
538 	printf("GRM = ");
539 	pfiles(files, n, NULL);
540 	printf("\n");
541 	printf("SRC = ");
542 	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
543 	else pfiles(files, n, "c");
544 	if ( gen_CPP ) {
545 		printf(" \\\n\t");
546 		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
547 		printf(" \\\n\t");
548 		printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);
549 		if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);
550 		if ( gen_trees ) {
551 			printf(" \\\n\t");
552 			printf("$(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);
553 			printf(" $(ANTLR_H)%s%s", DirectorySymbol, PCCTSAST_C);
554 /*			printf(" $(ANTLR_H)%s%s", DirectorySymbol, LIST_C); */
555 			printf(" \\\n\t");
556 		}
557 		printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);
558 	}
559 	if ( !user_lexer ) {
560 		if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);
561 		else printf(" %s$(SCAN).c", DIR());
562 	}
563 	if ( !gen_CPP ) printf(" $(ERR).c");
564 	for (i=0;i<num_sors;i++)
565 	{
566 		printf(" \\\n\t");
567 		pclasses(&sclasses[i],1,CPP_FILE_SUFFIX_NO_DOT);
568 		printf(" ");
569 		pfiles(&sfiles[i][0],num_sfiles[i],CPP_FILE_SUFFIX_NO_DOT);
570 	}
571 	if(num_sors>0)
572 		printf(" \\\n\t$(SOR_LIB)%sSTreeParser.cpp", DirectorySymbol);
573 	if (num_cfiles>0)
574 	{
575 		printf(" \\\n\t");
576 		pfiles(cfiles,num_cfiles,NULL);
577 	}
578 	printf("\n\n");
579 	printf("OBJ = ");
580 	pfiles(files, n, "o");
581 	if ( gen_CPP ) {
582 		printf(" \\\n\t");
583 		pclasses(classes, num_classes, "o");
584 		printf(" \\\n\t");
585 		printf("%s%s", DIR(), APARSER_O);
586 		if ( !user_lexer ) {
587 			printf(" %s%s", DIR(), DLEXERBASE_O);
588 		}
589 		if ( gen_trees ) {
590 			printf(" \\\n\t");
591 			printf("%s%s", DIR(), ASTBASE_O);
592 			printf(" %s%s", DIR(), PCCTSAST_O);
593 /*			printf(" %s%s", DIR(), LIST_O); */
594 			printf(" \\\n\t");
595 		}
596 		printf(" %s%s", DIR(), ATOKENBUFFER_O);
597 	}
598 	if ( !user_lexer ) {
599 		if ( gen_CPP ) printf(" $(SCAN)%s", OBJ_FILE_SUFFIX);
600 		else printf(" %s$(SCAN)%s", DIR(), OBJ_FILE_SUFFIX);
601 	}
602 	if ( !gen_CPP ) printf(" $(ERR)%s", OBJ_FILE_SUFFIX);
603 	for (i=0;i<num_sors;i++)
604 	{
605 		printf(" \\\n\t");
606 		pclasses(&sclasses[i],1,"o");
607 		printf(" ");
608 		pfiles(&sfiles[i][0],num_sfiles[i],"o");
609 	}
610 	if(num_sors>0) printf(" \\\n\tSTreeParser.o");
611 	if (num_cfiles>0)
612 	{
613 		printf(" \\\n\t");
614 		pfiles(cfiles,num_cfiles,"o");
615 	}
616 	printf("\n\n");
617 
618 	printf("ANTLR_SPAWN = ");
619 	if ( gen_CPP ) pfiles(files, n, CPP_FILE_SUFFIX_NO_DOT);
620 	else pfiles(files, n, "c");
621 	if ( gen_CPP ) {
622 		printf(" ");
623 		pclasses(classes, num_classes, CPP_FILE_SUFFIX_NO_DOT);
624 		printf(" \\\n\t\t");
625 		pclasses(classes, num_classes, "h");
626 		if ( strcmp(hdr,"stdpccts.h")!=0 ) {
627 			printf(" \\\n\t\t");
628 			printf("$(HDR_FILE) stdpccts.h");
629 		}
630 	}
631 	if ( user_lexer ) {
632 		if ( !user_token_types ) printf(" $(TOKENS)");
633 	}
634 	else {
635 		printf(" $(DLG_FILE)");
636 		if ( !user_token_types ) printf(" $(TOKENS)");
637 	}
638 	if ( !gen_CPP ) printf(" $(ERR).c");
639 	printf("\n");
640 
641 	if ( !user_lexer ) {
642 		if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);
643 		else printf("DLG_SPAWN = %s$(SCAN).c", DIR());
644 		if ( gen_CPP ) printf(" $(SCAN).h");
645 		if ( !gen_CPP ) printf(" $(MOD_FILE)");
646 		printf("\n");
647 	}
648 
649 	if ( gen_CPP ) {
650 		if ( !nondef_comp )
651 			printf("ifdef CXX\nCCC = $(CXX)\nendif\n\nifndef CCC\n");
652 		printf("CCC = %s\n",compilerCCC);
653 		if ( !nondef_comp ) printf("endif\n\n");
654 	}
655 	else
656 	{
657 		if ( !nondef_comp ) printf("ifndef CC\n");
658 		printf("CC = %s\n",compilerCC);
659 		if ( !nondef_comp ) printf("endif\n\n");
660 	}
661 
662 	/* set up dependencies */
663 	printf("\n%s : $(SRC) $(OBJ)\n", project);
664 	printf("\t%s %s %s $(CFLAGS) $(OBJ)\n",
665 		gen_CPP?"$(CCC)":"$(CC)",
666 		RENAME_EXE_FLAG,
667 		project);
668 	printf("\n");
669 
670 	/* implicit rules */
671 
672 /*	if(gen_CPP)
673 		printf("%%.o : %%.cpp\n\t$(CCC) -c $(CFLAGS) $<\n\n");
674 
675 	printf("%%.o : %%.c\n\t%s -c $(CFLAGS) $<\n\n",
676 			gen_CPP?"$(CCC)":"$(CC)");
677 */
678 	/* how to compile parser files */
679 
680 	for (i=0; i<num_files; i++)
681 	{
682 		pfiles(&files[i], 1, "o");
683 		if ( user_lexer ) {
684 			printf(" : $(TOKENS)");
685 		}
686 		else {
687 			if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");
688 			else printf(" : $(MOD_FILE) $(TOKENS)");
689 		}
690 		printf(" ");
691 		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
692 		else pfiles(&files[i], 1, "c");
693 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
694 		printf("\n");
695 		printf("\t%s -c $(CFLAGS) %s ",
696 			gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
697 		pfiles(&files[i], 1, "o");
698 		printf(" ");
699 		if ( gen_CPP ) pfiles(&files[i], 1, CPP_FILE_SUFFIX_NO_DOT);
700 		else pfiles(&files[i], 1, "c");
701 		printf("\n\n");
702 	}
703 
704 	for (i=0; i<num_cfiles; i++)
705 	{
706 		pfiles(&cfiles[i], 1, "o");
707 		printf(" : ");
708 		pfiles(&cfiles[i], 1, NULL);
709 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
710 /***	printf(" "); ***/
711 /***	pfiles(&cfiles[i], 1, "h"); ***/
712 		printf("\n");
713 		printf("\t%s -c $(CFLAGS) %s ",
714 			gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
715 		pfiles(&cfiles[i], 1, "o");
716 		printf(" ");
717 		pfiles(&cfiles[i], 1, NULL);
718 		printf("\n\n");
719 
720 /*
721  *		pfiles(&cfiles[i], 1, "h");
722  *		printf(" :\ntouch ");
723  *		pfiles(&cfiles[i], 1, "h");
724  *		printf("\n\n");
725  */
726 	}
727 
728 	/* how to compile err.c */
729 	if ( !gen_CPP ) {
730 		printf("$(ERR)%s : $(ERR).c", OBJ_FILE_SUFFIX);
731 		if ( !user_lexer ) printf(" $(TOKENS)");
732 		printf("\n");
733 		printf("\t%s -c $(CFLAGS) %s $(ERR)%s $(ERR).c",
734 			gen_CPP?"$(CCC)":"$(CC)",
735 			RENAME_OBJ_FLAG,
736 			OBJ_FILE_SUFFIX);
737 		printf("\n\n");
738 	}
739 
740 	/* how to compile Class.c */
741 	for (i=0; i<num_classes; i++)
742 	{
743 		pclasses(&classes[i], 1, "o");
744 		if ( user_lexer ) {
745 			printf(" : $(TOKENS)");
746 		}
747 		else {
748 			printf(" : $(TOKENS) $(SCAN).h");
749 		}
750 		printf(" ");
751 		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
752 		printf(" ");
753 		pclasses(&classes[i], 1, "h");
754 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
755 		printf("\n");
756 		printf("\t%s -c $(CFLAGS) %s ",
757 			gen_CPP?"$(CCC)":"$(CC)",
758 			RENAME_OBJ_FLAG);
759 		pclasses(&classes[i], 1, "o");
760 		printf(" ");
761 		pclasses(&classes[i], 1, CPP_FILE_SUFFIX_NO_DOT);
762 		printf("\n\n");
763 	}
764 
765 	/* how to compile scan.c */
766 	if ( !user_lexer ) {
767 		if ( gen_CPP ) printf("$(SCAN)%s : $(SCAN)%s", OBJ_FILE_SUFFIX, CPP_FILE_SUFFIX);
768 		else printf("%s$(SCAN)%s : %s$(SCAN).c", DIR(), OBJ_FILE_SUFFIX, DIR());
769 		if ( !user_lexer ) printf(" $(TOKENS)");
770 		printf("\n");
771 		if ( gen_CPP ) printf("\t$(CCC) -c $(CFLAGS) %s $(SCAN)%s $(SCAN)%s",
772 							RENAME_OBJ_FLAG,
773 							OBJ_FILE_SUFFIX,
774 							CPP_FILE_SUFFIX);
775 		else printf("\t$(CC) -c $(CFLAGS) %s %s$(SCAN)%s %s$(SCAN).c",
776 					RENAME_OBJ_FLAG,
777 					DIR(),
778 					OBJ_FILE_SUFFIX,
779 					DIR());
780 		printf("\n\n");
781 	}
782 /* how to compile sorcerer classes */
783 	for (i=0;i<num_sors;i++)
784 	{
785 		pclasses(&sclasses[i], 1, "o");
786 		printf(" : ");
787 		pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
788 		printf(" ");
789 		pclasses(&sclasses[i], 1, "h");
790 		if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
791 		printf("\n");
792 		printf("\t%s -c $(CFLAGS) %s ",
793 				gen_CPP?"$(CCC)":"$(CC)",
794 				RENAME_OBJ_FLAG);
795 		pclasses(&sclasses[i], 1, "o");
796 		printf(" ");
797 		pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
798 		printf("\n\n");
799 /* how to compile i-th sorcerer's files*/
800 		for (j=0; j<num_sfiles[i]; j++)
801 		{
802 			pfiles(&sfiles[i][j], 1, "o");
803 			printf(" : ");
804 			if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);
805 			else pfiles(&sfiles[i][j], 1, "c");
806 			if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
807 			printf("\n");
808 			printf("\t%s -c $(CFLAGS) %s ",
809 					gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
810 			pfiles(&sfiles[i][j], 1, "o");
811 			printf(" ");
812 			if ( gen_CPP ) pfiles(&sfiles[i][j], 1, CPP_FILE_SUFFIX_NO_DOT);
813 			else pfiles(&sfiles[i][j], 1, "c");
814 			printf("\n\n");
815 		}
816 		if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);
817 		else pfiles(&sfiles[i][0], num_sfiles[i], "c");
818 		if ( gen_CPP )
819 		{
820 			printf(" ");
821 			pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
822 			printf(" ");
823 			pclasses(&sclasses[i], 1, "h");
824 			if ( strcmp(hdr,"stdpccts.h")!=0 )
825 			{
826 				printf(" ");
827 				printf("$(HDR_FILE) stdpccts.h");
828 			}
829 		}
830 		printf(" : ");
831 		pfiles(&sfiles[i][0],num_sfiles[i],NULL);
832 		printf("\n\t$(SOR) $(SFLAGS) ");
833 		pfiles(&sfiles[i][0],num_sfiles[i],NULL);
834 		printf("\n\n");
835 	}
836 	if(num_sors>0)
837 	{
838 		printf("STreeParser%s : $(SOR_LIB)%sSTreeParser.cpp\n",
839 				OBJ_FILE_SUFFIX,DirectorySymbol);
840 		printf("\t%s -c $(CFLAGS) %s ",
841 				gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
842 		printf("STreeParser%s ",OBJ_FILE_SUFFIX);
843 		printf("$(SOR_LIB)%sSTreeParser.cpp\n\n",DirectorySymbol);
844 	}
845 
846 	printf("$(ANTLR_SPAWN) : $(GRM)\n");
847 	printf("\t$(ANTLR) $(AFLAGS) $(GRM)\n");
848 
849 	if ( !user_lexer )
850 	{
851 		printf("\n");
852 		printf("$(DLG_SPAWN) : $(DLG_FILE)\n");
853 		if ( gen_CPP ) printf("\t$(DLG) $(DFLAGS) $(DLG_FILE)\n");
854 		else printf("\t$(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");
855 	}
856 
857 	/* do the makes for ANTLR/DLG support */
858 	if ( gen_CPP ) {
859 		printf("\n");
860 		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
861 		printf("\t%s -c $(CFLAGS) %s ",
862 				gen_CPP?"$(CCC)":"$(CC)",
863 				RENAME_OBJ_FLAG);
864 		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
865 		printf("\n");
866 		printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
867 		printf("\t%s -c $(CFLAGS) %s ",
868 				gen_CPP?"$(CCC)":"$(CC)",
869 				RENAME_OBJ_FLAG);
870 		printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
871 		if ( !user_lexer ) {
872 			printf("\n");
873 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
874 			printf("\t%s -c $(CFLAGS) %s ",
875 					gen_CPP?"$(CCC)":"$(CC)",
876 					RENAME_OBJ_FLAG);
877 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
878 		}
879 		if ( gen_trees ) {
880 			printf("\n");
881 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
882 			printf("\t%s -c $(CFLAGS) %s ",
883 					gen_CPP?"$(CCC)":"$(CC)",
884 					RENAME_OBJ_FLAG);
885 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
886 			printf("\n");
887 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
888 			printf("\t%s -c $(CFLAGS) %s ",
889 					gen_CPP?"$(CCC)":"$(CC)",
890 					RENAME_OBJ_FLAG);
891 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), PCCTSAST_O, DirectorySymbol, PCCTSAST_C);
892 			printf("\n");
893 /*
894 			printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
895 			printf("\t%s -c $(CFLAGS) %s ",
896 					gen_CPP?"$(CCC)":"$(CC)",RENAME_OBJ_FLAG);
897 			printf("%s%s $(ANTLR_H)%s%s\n", DIR(), LIST_O, DirectorySymbol, LIST_C);
898 */
899 		}
900 	}
901 
902 	/* clean and scrub targets */
903 
904 	printf("\nclean:\n");
905 	printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project);
906 	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX);
907 	printf("\n");
908 
909 	printf("\nscrub: clean\n");
910 /*	printf("\trm -f *%s core %s", OBJ_FILE_SUFFIX, project); */
911 /*	if ( strcmp(outdir, ".")!=0 ) printf(" %s*%s", DIR(), OBJ_FILE_SUFFIX); */
912 	printf("\trm -f $(ANTLR_SPAWN)");
913 	if ( !user_lexer ) printf(" $(DLG_SPAWN)");
914 	for (i=0;i<num_sors;i++)
915 	{
916 		printf(" ");
917 		if ( gen_CPP ) pfiles(&sfiles[i][0], num_sfiles[i], CPP_FILE_SUFFIX_NO_DOT);
918 		else pfiles(&sfiles[i][0], num_sfiles[i], "c");
919 		if ( gen_CPP )
920 		{
921 			printf(" ");
922 			pclasses(&sclasses[i], 1, CPP_FILE_SUFFIX_NO_DOT);
923 			printf(" ");
924 			pclasses(&sclasses[i], 1, "h");
925 		}
926 	}
927 	printf("\n\n");
928 }
929 
930 #ifdef __STDC__
pfiles(char ** files,int n,char * suffix)931 void pfiles(char **files, int n, char *suffix)
932 #else
933 void pfiles(files, n, suffix)
934 char **files;
935 int n;
936 char *suffix;
937 #endif
938 {
939 	int first=1;
940 
941 	while ( n>0 )
942 	{
943 		char *p = &(*files)[strlen(*files)-1];
944 		if ( !first ) putchar(' ');
945 		first=0;
946 		while ( p > *files && *p != '.' ) --p;
947 		if ( p == *files )
948 		{
949 			fprintf(stderr,
950 					"genmk: filenames must be file.suffix format: %s\n",
951 					*files);
952 			exit(-1);
953 		}
954 		if ( suffix == NULL ) printf("%s", *files);
955 		else
956 		{
957 			*p = '\0';
958 			printf("%s", DIR());
959 			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *files, OBJ_FILE_SUFFIX);
960 			else printf("%s.%s", *files, suffix);
961 			*p = '.';
962 		}
963 		files++;
964 		--n;
965 	}
966 }
967 
968 #ifdef __STDC__
pclasses(char ** classes,int n,char * suffix)969 pclasses(char **classes, int n, char *suffix)
970 #else
971 pclasses(classes, n, suffix)
972 char **classes;
973 int n;
974 char *suffix;
975 #endif
976 {
977 	int first=1;
978 
979 	while ( n>0 )
980 	{
981 		if ( !first ) putchar(' ');
982 		first=0;
983 		if ( suffix == NULL ) printf("%s", *classes);
984 		else {
985 			printf("%s", DIR());
986 			if ( strcmp(suffix, "o")==0 ) printf("%s%s", *classes, OBJ_FILE_SUFFIX);
987 			else printf("%s.%s", *classes, suffix);
988 		}
989 		classes++;
990 		--n;
991 	}
992 }
993 
994 static void
995 #ifdef __STDC__
ProcessArgs(int argc,char ** argv,Opt * options)996 ProcessArgs( int argc, char **argv, Opt *options )
997 #else
998 ProcessArgs( argc, argv, options )
999 int argc;
1000 char **argv;
1001 Opt *options;
1002 #endif
1003 {
1004 	Opt *p;
1005 	require(argv!=NULL, "ProcessArgs: command line NULL");
1006 
1007 	while ( argc-- > 0 )
1008 	{
1009 		p = options;
1010 		while ( p->option != NULL )
1011 		{
1012 			if ( strcmp(p->option, "*") == 0 ||
1013 				 strcmp(p->option, *argv) == 0 )
1014 			{
1015 				if ( p->arg )
1016 				{
1017 					(*p->process)( *argv, *(argv+1) );
1018 					argv++;
1019 					argc--;
1020 				}
1021 				else
1022 					(*p->process)( *argv );
1023 				break;
1024 			}
1025 			p++;
1026 		}
1027 		argv++;
1028 	}
1029 }
1030 
1031 #ifdef __STDC__
fatal(char * err_)1032 void fatal( char *err_)
1033 #else
1034 void fatal( err_)
1035 char *err_;
1036 #endif
1037 {
1038 	fprintf(stderr, "genmk: %s\n", err_);
1039 	exit(1);
1040 }
1041 
1042 #ifdef __STDC__
warn(char * err_)1043 void warn( char *err_)
1044 #else
1045 void warn( err_)
1046 char *err_;
1047 #endif
1048 {
1049 	fprintf(stderr, "genmk: %s\n", err_);
1050 }
1051 
1052 #ifdef __STDC__
DIR(void)1053 char *DIR(void)
1054 #else
1055 char *DIR()
1056 #endif
1057 {
1058 	static char buf[200+1];
1059 
1060 	if ( strcmp(outdir,TopDirectory)==0 ) return "";
1061 	sprintf(buf, "%s%s", outdir, DirectorySymbol);
1062 	return buf;
1063 }
1064