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