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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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