Home | History | Annotate | Download | only in genmk
      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
     86 pProj( s, t )
     87 char *s;
     88 char *t;
     89 {
     90 	project = t;
     91 }
     92 
     93 static void
     94 pUL( s )
     95 char *s;
     96 {
     97 	user_lexer = 1;
     98 }
     99 
    100 static void
    101 pCPP( s )
    102 char *s;
    103 {
    104 	gen_CPP = 1;
    105 }
    106 
    107 static void
    108 pUT( s, t )
    109 char *s;
    110 char *t;
    111 {
    112 	user_token_types = t;
    113 }
    114 
    115 static void
    116 pTrees( s )
    117 char *s;
    118 {
    119 	gen_trees = 1;
    120 }
    121 
    122 static void
    123 pHoist( s )
    124 char *s;
    125 {
    126 	gen_hoist = 1;
    127 }
    128 
    129 static void
    130 #ifdef __STDC__
    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__
    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__
    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__
    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__
    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__
    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__
    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__
    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 
    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 
    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 
    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 
    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 
    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__
    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 
    742 void fatal( err_)
    743 char *err_;
    744 {
    745     fprintf(stderr, "genmk: %s\n", err_);
    746     exit(1);
    747 }
    748 
    749 void warn( err_)
    750 char *err_;
    751 {
    752     fprintf(stderr, "genmk: %s\n", err_);
    753 }
    754 
    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