]> pd.if.org Git - pccts/blob - antlr/lex.c
auto commit for import
[pccts] / antlr / lex.c
1 /*
2  * lex.c        --      Generate all of the lexical type files: parser.dlg tokens.h
3  *
4  * $Id: lex.c,v 1.4 95/09/26 12:58:36 parrt Exp $
5  * $Revision: 1.4 $
6  *
7  * SOFTWARE RIGHTS
8  *
9  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
10  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
11  * company may do whatever they wish with source code distributed with
12  * PCCTS or the code generated by PCCTS, including the incorporation of
13  * PCCTS, or its output, into commerical software.
14  * 
15  * We encourage users to develop software with PCCTS.  However, we do ask
16  * that credit is given to us for developing PCCTS.  By "credit",
17  * we mean that if you incorporate our source code into one of your
18  * programs (commercial product, research project, or otherwise) that you
19  * acknowledge this fact somewhere in the documentation, research report,
20  * etc...  If you like PCCTS and have developed a nice tool with the
21  * output, please mention that you developed it using PCCTS.  In
22  * addition, we ask that this header remain intact in our source code.
23  * As long as these guidelines are kept, we expect to continue enhancing
24  * this system and expect to make other tools available as they are
25  * completed.
26  *
27  * ANTLR 1.33
28  * Terence Parr
29  * Parr Research Corporation
30  * with Purdue University and AHPCRC, University of Minnesota
31  * 1989-1995
32  */
33 #include <stdio.h>
34 #include <ctype.h>
35 #ifdef __cplusplus
36 #ifndef __STDC__
37 #define __STDC__
38 #endif
39 #endif
40 #include "set.h"
41 #include "syn.h"
42 #include "hash.h"
43 #include "generic.h"
44
45 #define DLGErrorString "invalid token"
46
47 /* Generate a complete lexical description of the lexemes found in the grammar */
48 void
49 #ifdef __STDC__
50 genLexDescr( void )
51 #else
52 genLexDescr( )
53 #endif
54 {
55         ListNode *p;
56         FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
57         require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
58         special_fopen_actions(OutMetaName(DlgFileName));
59
60         fprintf(dlgFile, "<<\n");
61         fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", DlgFileName);
62         fprintf(dlgFile, " *\n");
63         fprintf(dlgFile, " * Generated from:");
64         {int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
65         fprintf(dlgFile, "\n");
66         fprintf(dlgFile, " *\n");
67         fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
68         fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
69         fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
70         fprintf(dlgFile, " * ANTLR Version %s\n", Version);
71         fprintf(dlgFile, " */\n\n");
72         if ( GenCC )
73         {
74                 if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
75                 else fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
76                 fprintf(dlgFile, "#include \"%s\"\n", ATOKEN_H);
77                 if ( GenAST ) fprintf(dlgFile, "#include \"%s\"\n", ASTBASE_H);
78                 if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
79         }
80         else
81         {
82                 fprintf(dlgFile, "#include <stdio.h>\n");
83                 fprintf(dlgFile, "#define ANTLR_VERSION %s\n", VersionDef);
84                 if ( strcmp(ParserName, DefaultParserName)!=0 )
85                         fprintf(dlgFile, "#define %s %s\n", DefaultParserName, ParserName);
86                 if ( strcmp(ParserName, DefaultParserName)!=0 )
87                         fprintf(dlgFile, "#include \"%s\"\n", RemapFileName);
88                 if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
89                 if ( FoundGuessBlk )
90                 {
91                         fprintf(dlgFile, "#define ZZCAN_GUESS\n");
92                         fprintf(dlgFile, "#include <setjmp.h>\n");
93                 }
94                 if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
95                 if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
96                 fprintf(dlgFile, "#include \"antlr.h\"\n");
97                 if ( GenAST ) {
98                         fprintf(dlgFile, "#include \"ast.h\"\n");
99                 }
100                 if ( UserDefdTokens )
101                         fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
102                 /* still need this one as it has the func prototypes */
103                 fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
104                 fprintf(dlgFile, "#include \"dlgdef.h\"\n");
105                 fprintf(dlgFile, "LOOKAHEAD\n");
106                 fprintf(dlgFile, "void zzerraction()\n");
107                 fprintf(dlgFile, "{\n");
108                 fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
109                 fprintf(dlgFile, "\tzzadvance();\n");
110                 fprintf(dlgFile, "\tzzskip();\n");
111                 fprintf(dlgFile, "}\n");
112         }
113         fprintf(dlgFile, ">>\n\n");
114
115         /* dump all actions */
116     if (LexActions != NULL)
117     {
118         for (p = LexActions->next; p!=NULL; p=p->next)
119                 {
120                         fprintf(dlgFile, "<<\n");
121                         dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
122                         fprintf(dlgFile, ">>\n");
123                 }
124         }
125         /* dump all regular expression rules/actions (skip sentinel node) */
126         if ( ExprOrder == NULL ) {
127                 warnNoFL("no regular expressions found in grammar");
128         }
129         else dumpLexClasses(dlgFile);
130         fprintf(dlgFile, "%%%%\n");
131         fclose( dlgFile );
132 }
133
134 /* For each lexical class, scan ExprOrder looking for expressions
135  * in that lexical class.  Print out only those that match.
136  * Each element of the ExprOrder list has both an expr and an lclass
137  * field.
138  */
139 void
140 #ifdef __STDC__
141 dumpLexClasses( FILE *dlgFile )
142 #else
143 dumpLexClasses( dlgFile )
144 FILE *dlgFile;
145 #endif
146 {
147         int i;
148         TermEntry *t;
149         ListNode *p;
150         Expr *q;
151
152         for (i=0; i<NumLexClasses; i++)
153         {
154                 fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
155                 for (p=ExprOrder->next; p!=NULL; p=p->next)
156                 {
157                         q = (Expr *) p->elem;
158                         if ( q->lclass != i ) continue;
159                         lexmode(i);
160                         t = (TermEntry *) hash_get(Texpr, q->expr);
161                         require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
162                         if ( t->token == EpToken ) continue;
163                         fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
164                         /* replace " killed by StripQuotes() */
165                         q->expr[ strlen(q->expr) ] = '"';
166                         if ( !GenCC ) {
167                                 if ( TokenString(t->token) != NULL )
168                                         fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
169                                 else
170                                         fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
171                         }
172                         if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
173                         if ( GenCC ) {
174                                 if ( TokenString(t->token) != NULL )
175                                         fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
176                                 else
177                                         fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);
178                         }
179                         fprintf(dlgFile, "\t>>\n\n");
180                 }
181         }
182 }
183
184 /* Strip the leading path (if any) from a filename */
185 char *
186 #ifdef __STDC__
187 StripPath( char *fileName )
188 #else
189 StripPath( fileName )
190 char *fileName;
191 #endif
192 {
193         char *p;
194         static char dirSym[2] = DirectorySymbol;
195
196         if(NULL != (p = strrchr(fileName, dirSym[0])))
197                 p++;
198         else
199                 p = fileName;
200
201         return(p);
202 }
203
204 /* Generate a list of #defines && list of struct definitions for
205  * aggregate retv's */
206 void
207 #ifdef __STDC__
208 genDefFile( void )
209 #else
210 genDefFile( )
211 #endif
212 {
213         int i;
214
215         /* If C++ mode and #tokdef used, then don't need anything in here since
216          * C++ puts all definitions in the class file name.
217          */
218         if ( GenCC && UserTokenDefsFile ) return;
219
220         DefFile = fopen(OutMetaName(DefFileName), "w");
221         require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
222         special_fopen_actions(OutMetaName(DefFileName));
223
224         fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));
225         fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));
226
227         fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
228         fprintf(DefFile, " *\n");
229         fprintf(DefFile, " * Generated from:");
230         for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
231         fprintf(DefFile, "\n");
232         fprintf(DefFile, " *\n");
233         fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
234         fprintf(DefFile, " * Purdue University Electrical Engineering\n");
235         fprintf(DefFile, " * ANTLR Version %s\n", Version);
236         fprintf(DefFile, " */\n");
237
238         if ( !GenCC && LexGen ) {
239                 fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
240                                 TokenInd!=NULL?TokenInd[EofToken]:EofToken);
241         }
242
243         if ( !UserDefdTokens )
244         {
245                 int first=1;
246
247                 if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");
248                 for (i=1; i<TokenNum; i++)
249                 {
250                         /* Don't do EpToken or expr w/o labels */
251                         if ( TokenString(i)!=NULL && i != EpToken )
252                         {
253                                 TermEntry *p;
254                                 
255                                 if ( WarningLevel>1 )
256                                 {
257                                         int j;
258                                         /* look in all lexclasses for the reg expr */
259                                         for (j=0; j<NumLexClasses; j++)
260                                         {
261                                                 lexmode(j);
262                                                 if ( ExprString(i)!=NULL ) break;
263                                         }
264                                         if ( j>=NumLexClasses )
265                                         {
266                                                 warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
267                                         }
268                                 }
269                                 require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
270                                                 "token not in sym tab when it should be");
271                                 if ( !p->classname )
272                                 {
273                                         if ( GenCC ) {
274                                                 if ( !first ) fprintf(DefFile, ",\n");
275                                                 first = 0;
276                                                 fprintf(DefFile, "\t%s=%d", TokenString(i), i);
277                                         }
278                                         else
279                                                 fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
280                                 }
281                         }
282                 }
283                 if ( GenCC ) fprintf(DefFile, "};\n");
284         }
285
286         if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
287
288         fprintf(DefFile, "\n#endif\n");
289 }
290
291 void
292 #ifdef __STDC__
293 GenRemapFile( void )
294 #else
295 GenRemapFile( )
296 #endif
297 {
298         if ( strcmp(ParserName, DefaultParserName)!=0 )
299         {
300                 FILE *f;
301                 int i;
302
303                 f = fopen(OutMetaName(RemapFileName), "w");
304                 require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
305                 special_fopen_actions(OutMetaName(RemapFileName));
306
307                 fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
308                 fprintf(f, " *\n");
309                 fprintf(f, " * Generated from:");
310                 for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
311                 fprintf(f, "\n");
312                 fprintf(f, " *\n");
313                 fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1994\n");
314                 fprintf(f, " * Purdue University Electrical Engineering\n");
315                 fprintf(f, " * ANTLR Version %s\n", Version);
316                 fprintf(f, " */\n");
317
318                 GenRuleFuncRedefs(f, SynDiag);
319                 GenPredefinedSymbolRedefs(f);
320                 if ( GenAST ) GenASTSymbolRedefs(f);
321                 GenSetRedefs(f);
322
323                 fclose(f);
324         }
325 }
326
327 /* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
328 void
329 #ifdef __STDC__
330 GenRuleFuncRedefs( FILE *f, Junction *p )
331 #else
332 GenRuleFuncRedefs( f, p )
333 FILE *f;
334 Junction *p;
335 #endif
336 {
337         fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
338         while ( p!=NULL )
339         {
340                 fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
341                 p = (Junction *)p->p2;
342         }
343 }
344
345 /* Generate a bunch of #defines that rename all standard symbols to be
346  * "ParserName_symbol".  The list of standard symbols to change is in
347  * globals.c.
348  */
349 void
350 #ifdef __STDC__
351 GenPredefinedSymbolRedefs( FILE *f )
352 #else
353 GenPredefinedSymbolRedefs( f )
354 FILE *f;
355 #endif
356 {
357         char **p;
358
359         fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
360         for (p = &StandardSymbols[0]; *p!=NULL; p++)
361         {
362                 fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
363         }
364 }
365
366 /* Generate a bunch of #defines that rename all AST symbols to be
367  * "ParserName_symbol".  The list of AST symbols to change is in
368  * globals.c.
369  */
370 void
371 #ifdef __STDC__
372 GenASTSymbolRedefs( FILE *f )
373 #else
374 GenASTSymbolRedefs( f )
375 FILE *f;
376 #endif
377 {
378         char **p;
379
380         fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
381         for (p = &ASTSymbols[0]; *p!=NULL; p++)
382         {
383                 fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
384         }
385 }
386
387 /* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match
388  * use in bits.c (DumpSetWd() etc...)
389  */
390 void
391 #ifdef __STDC__
392 GenSetRedefs( FILE *f )
393 #else
394 GenSetRedefs( f )
395 FILE *f;
396 #endif
397 {
398         int i;
399
400         for (i=1; i<=wordnum; i++)
401         {
402                 fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
403         }
404         for (i=1; i<=esetnum; i++)
405         {
406                 fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
407         }
408 }
409
410 /* Find all return types/parameters that require structs and def
411  * all rules with ret types.
412  */
413 void
414 #ifdef __STDC__
415 GenRulePrototypes( FILE *f, Junction *p )
416 #else
417 GenRulePrototypes( f, p )
418 FILE *f;
419 Junction *p;
420 #endif
421 {
422         int i;
423
424         i = 1;
425         while ( p!=NULL )
426         {
427                 if ( p->ret != NULL )
428                 {
429                         if ( HasComma(p->ret) )
430                         {
431                                 DumpRetValStruct(f, p->ret, i);
432                         }
433                         fprintf(f, "\n#ifdef __STDC__\n");
434                         if ( HasComma(p->ret) )
435                         {
436                                 fprintf(f, "extern struct _rv%d", i);
437                         }
438                         else
439                         {
440                                 fprintf(f, "extern ");
441                                 DumpType(p->ret, f);
442                         }
443                         fprintf(f, " %s%s(", RulePrefix, p->rname);
444                         DumpANSIFunctionArgDef(f,p);
445                         fprintf(f, ";\n");
446 #ifdef OLD
447                         if ( p->pdecl != NULL || GenAST )
448                         {
449                                 if ( GenAST ) {
450                                         fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
451                                 }
452                                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
453                         }
454                         else fprintf(f, "void");
455                         fprintf(f, ");\n");
456 #endif
457                         fprintf(f, "#else\n");
458                         if ( HasComma(p->ret) )
459                         {
460                                 fprintf(f, "extern struct _rv%d", i);
461                         }
462                         else
463                         {
464                                 fprintf(f, "extern ");
465                                 DumpType(p->ret, f);
466                         }
467                         fprintf(f, " %s%s();\n", RulePrefix, p->rname);
468                         fprintf(f, "#endif\n");
469                 }
470                 else
471                 {
472                         fprintf(f, "\n#ifdef __STDC__\n");
473                         fprintf(f, "void %s%s(", RulePrefix, p->rname);
474                         DumpANSIFunctionArgDef(f,p);
475                         fprintf(f, ";\n");
476 #ifdef OLD
477                         if ( p->pdecl != NULL || GenAST )
478                         {
479                                 if ( GenAST ) {
480                                         fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
481                                 }
482                                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
483                         }
484                         else fprintf(f, "void");
485                         fprintf(f, ");\n");
486 #endif
487                         fprintf(f, "#else\n");
488                         fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
489                         fprintf(f, "#endif\n");
490                 }
491                 i++;
492                 p = (Junction *)p->p2;
493         }
494 }
495
496 /* Define all rules in the class.h file; generate any required
497  * struct definitions first, however.
498  */
499 void
500 #ifdef __STDC__
501 GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
502 #else
503 GenRuleMemberDeclarationsForCC( f, q )
504 FILE *f;
505 Junction *q;
506 #endif
507 {
508         Junction *p = q;
509         int i;
510
511         fprintf(f, "private:\n");
512
513         /* Dump dflt handler declaration */
514         fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
515
516         fprintf(f, "public:\n");
517
518         /* Dump return value structs */
519         i = 1;
520         while ( p!=NULL )
521         {
522                 if ( p->ret != NULL )
523                 {
524                         if ( HasComma(p->ret) )
525                         {
526                                 DumpRetValStruct(f, p->ret, i);
527                         }
528                 }
529                 i++;
530                 p = (Junction *)p->p2;
531         }
532
533         /* Dump member func defs && CONSTRUCTOR */
534         fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
535 /*
536         fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",
537                            CurrentClassName);
538 */
539
540         i = 1;
541         p = q;
542         while ( p!=NULL )
543         {
544                 if ( p->ret != NULL )
545                 {
546                         if ( HasComma(p->ret) )
547                         {
548                                 fprintf(f, "\tstruct _rv%d", i);
549                         }
550                         else
551                         {
552                                 fprintf(f, "\t");
553                                 DumpType(p->ret, f);
554                         }
555                         fprintf(f, " %s(", p->rname);
556                         DumpANSIFunctionArgDef(f,p);
557                         fprintf(f, ";\n");
558 #ifdef OLD
559                         if ( p->pdecl != NULL || GenAST )
560                         {
561                                 if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
562                                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
563                         }
564                         fprintf(f, ");\n");
565 #endif
566                 }
567                 else
568                 {
569                         fprintf(f, "\tvoid %s(", p->rname);
570                         DumpANSIFunctionArgDef(f,p);
571                         fprintf(f, ";\n");
572 #ifdef OLD
573                         if ( p->pdecl != NULL || GenAST )
574                         {
575                                 if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
576                                 if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
577                         }
578                         fprintf(f, ");\n");
579 #endif
580                 }
581                 i++;
582                 p = (Junction *)p->p2;
583         }
584 }
585
586 /* Given a list of ANSI-style parameter declarations, print out a
587  * comma-separated list of the symbols (w/o types).
588  * Basically, we look for a comma, then work backwards until start of
589  * the symbol name.  Then print it out until 1st non-alnum char.  Now,
590  * move on to next parameter.
591  */
592 void
593 #ifdef __STDC__
594 DumpListOfParmNames( char *pdecl, FILE *output )
595 #else
596 DumpListOfParmNames( pdecl, output )
597 char *pdecl;
598 FILE *output;
599 #endif
600 {
601         int firstTime = 1, done = 0;
602         require(output!=NULL, "DumpListOfParmNames: NULL parm");
603
604         if ( pdecl == NULL ) return;
605         while ( !done )
606         {
607                 if ( !firstTime ) putc(',', output);
608                 done = DumpNextNameInDef(&pdecl, output);
609                 firstTime = 0;
610         }
611 }
612
613 /* given a list of parameters or return values, dump the next
614  * name to output.  Return 1 if last one just printed, 0 if more to go.
615  */
616 int
617 #ifdef __STDC__
618 DumpNextNameInDef( char **q, FILE *output )
619 #else
620 DumpNextNameInDef( q, output )
621 char **q;
622 FILE *output;
623 #endif
624 {
625         char *p = *q;           /* where did we leave off? */
626         int done=0;
627
628         while ( *p!='\0' && *p!=',' ) p++;              /* find end of decl */
629         if ( *p == '\0' ) done = 1;
630         while ( !isalnum(*p) && *p!='_' ) --p;  /* scan back until valid var character */
631         while ( isalnum(*p) || *p=='_' ) --p;   /* scan back until beginning of variable */
632         p++;                                            /* move to start of variable */
633         while ( isalnum(*p) || *p=='_'  ) {putc(*p, output); p++;}
634         while ( *p!='\0' && *p!=',' ) p++;              /* find end of decl */
635         p++;                            /* move past this parameter */
636
637         *q = p;                         /* record where we left off */
638         return done;
639 }
640
641 /* Given a list of ANSI-style parameter declarations, dump K&R-style
642  * declarations, one per line for each parameter.  Basically, convert
643  * comma to semi-colon, newline.
644  */
645 void
646 #ifdef __STDC__
647 DumpOldStyleParms( char *pdecl, FILE *output )
648 #else
649 DumpOldStyleParms( pdecl, output )
650 char *pdecl;
651 FILE *output;
652 #endif
653 {
654         require(output!=NULL, "DumpOldStyleParms: NULL parm");
655
656         if ( pdecl == NULL ) return;
657         while ( *pdecl != '\0' )
658         {
659                 if ( *pdecl == ',' )
660                 {
661                         pdecl++;
662                         putc(';', output); putc('\n', output);
663                         while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
664                 }
665                 else {putc(*pdecl, output); pdecl++;}
666         }
667         putc(';', output);
668         putc('\n', output);
669 }
670
671 /* Take in a type definition (type + symbol) and print out type only */
672 void
673 #ifdef __STDC__
674 DumpType( char *s, FILE *f )
675 #else
676 DumpType( s, f )
677 char *s;
678 FILE *f;
679 #endif
680 {
681         char *p, *end;
682         require(s!=NULL, "DumpType: invalid type string");
683
684         p = &s[strlen(s)-1];            /* start at end of string and work back */
685         /* scan back until valid variable character */
686         while ( !isalnum(*p) && *p!='_' ) --p;
687         /* scan back until beginning of variable */
688         while ( isalnum(*p) || *p=='_' ) --p;
689         if ( p<=s )
690         {
691                 warnNoFL(eMsg1("invalid parameter/return value: '%s'",s));
692                 return;
693         }
694         end = p;                                        /* here is where we stop printing alnum */
695         p = s;
696         while ( p!=end ) {putc(*p, f); p++;} /* dump until just before variable */
697         while ( *p!='\0' )                                       /* dump rest w/o variable */
698         {
699                 if ( !isalnum(*p) && *p!='_' ) putc(*p, f);
700                 p++;
701         }
702 }
703
704 /* check to see if string e is a word in string s */
705 int
706 #ifdef __STDC__
707 strmember( char *s, char *e )
708 #else
709 strmember( s, e )
710 char *s;
711 char *e;
712 #endif
713 {
714     register char *p;
715     require(s!=NULL&&e!=NULL, "strmember: NULL string");
716     
717     if ( *e=='\0' ) return 1;   /* empty string is always member */
718     do {
719         while ( *s!='\0' && !isalnum(*s) && *s!='_' )
720         ++s;
721         p = e;
722         while ( *p!='\0' && *p==*s ) {p++; s++;}
723         if ( *p=='\0' ) {
724             if ( *s=='\0' ) return 1;
725             if ( !isalnum (*s) && *s != '_' ) return 1;
726         }
727         while ( isalnum(*s) || *s == '_' )
728         ++s;
729     } while ( *s!='\0' );
730     return 0;
731 }
732
733 int
734 #ifdef __STDC__
735 HasComma( char *s )
736 #else
737 HasComma( s )
738 char *s;
739 #endif
740 {
741         while (*s!='\0')
742                 if ( *s++ == ',' ) return 1;
743         return 0;
744 }
745
746 void
747 #ifdef __STDC__
748 DumpRetValStruct( FILE *f, char *ret, int i )
749 #else
750 DumpRetValStruct( f, ret, i )
751 FILE *f;
752 char *ret;
753 int i;
754 #endif
755 {
756         fprintf(f, "\nstruct _rv%d {\n", i);
757         while ( *ret != '\0' )
758         {
759                  while ( *ret==' ' || *ret=='\t' ) ret++; /* ignore white */
760                  putc('\t', f);
761                  while ( *ret!=',' && *ret!='\0' ) {putc(*ret,f); ret++;}
762                  if ( *ret == ',' ) {putc(';', f); putc('\n', f); ret++;}
763         }
764         fprintf(f, ";\n};\n");
765 }
766
767 /* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
768 char *
769 #ifdef __STDC__
770 StripQuotes( char *s )
771 #else
772 StripQuotes( s )
773 char *s;
774 #endif
775 {
776         if ( *s == '"' )
777         {
778                 s[ strlen(s)-1 ] = '\0';    /* remove last quote */
779                 return( s+1 );                          /* return address past initial quote */
780         }
781         return( s );
782 }
783