Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / config / util / makestrs.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: makestrs.c /main/11 1998/02/06 11:24:15 kaleb $ */
24
25 /*
26
27 Copyright (c) 1991, 1998 The Open Group
28
29 All Rights Reserved.
30
31 The above copyright notice and this permission notice shall be included in
32 all copies or substantial portions of the Software.
33
34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
37 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
38 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
41 Except as contained in this notice, the name of The Open Group shall not be
42 used in advertising or otherwise to promote the sale, use or other dealings
43 in this Software without prior written authorization from The Open Group.
44
45 */
46
47 /* Constructs string definitions */
48
49 #include <stdio.h>
50 #include <X11/Xos.h>
51 #ifndef X_NOT_STDC_ENV
52 #include <stdlib.h>
53 #else
54 char *malloc();
55 #endif
56 #if defined(macII) && !defined(__STDC__)  /* stdlib.h fails to define these */
57 char *malloc();
58 #endif /* macII */
59
60 typedef struct _TableEnt {
61     struct _TableEnt* next;
62     char* left;
63     char* right;
64     int offset;
65 } TableEnt;
66
67 typedef struct _Table {
68     struct _Table* next;
69     TableEnt* tableent;
70     TableEnt* tableentcurrent;
71     TableEnt** tableenttail;
72     char* name;
73     int offset;
74 } Table;
75
76 typedef struct _File {
77     struct _File* next;
78     FILE* tmpl;
79     char* name;
80     Table* table;
81     Table* tablecurrent;
82     Table** tabletail;
83 } File;
84
85 static File* file = NULL;
86 static File* filecurrent = NULL;
87 static File** filetail = &file;
88 static char* conststr;
89 static char* prefixstr = NULL;
90 static char* featurestr = NULL;
91 static char* ctmplstr = NULL;
92 static char* fileprotstr;
93 static char* externrefstr;
94 static char* externdefstr;
95
96 #define X_DEFAULT_ABI   0
97 #define X_ARRAYPER_ABI  1
98 #define X_INTEL_ABI     2
99 #define X_INTEL_ABI_BC  3
100 #define X_SPARC_ABI     4
101 #define X_FUNCTION_ABI  5
102
103 #define X_MAGIC_STRING "<<<STRING_TABLE_GOES_HERE>>>"
104
105 static void WriteHeaderProlog (f, phile)
106     FILE* f;
107     File* phile;
108 {
109     Table* t;
110     TableEnt* te;
111
112     (void) fprintf (f, "#ifdef %s\n", featurestr);
113     for (t = phile->table; t; t = t->next)
114         for (te = t->tableent; te; te = te->next) {
115             if (strcmp (te->left, "RAtom") == 0) {
116                 (void) fprintf (f, 
117                         "#ifndef %s%s\n#define %s%s \"%s\"\n#endif\n",
118                         prefixstr, te->left, prefixstr, te->left, te->right);
119             } else {
120                 (void) fprintf (f, 
121                         "#define %s%s \"%s\"\n",
122                         prefixstr, te->left, te->right);
123             }
124         }
125     (void) fprintf (f, "%s", "#else\n");
126 }
127
128 static void IntelABIWriteHeader (f, phile)
129     FILE* f;
130     File* phile;
131 {
132     Table* t;
133     TableEnt* te;
134
135     WriteHeaderProlog (f, phile);
136
137     for (t = phile->table; t; t = t->next) {
138       (void) fprintf (f, "%s %sConst char %s[];\n", 
139                       externrefstr, conststr ? conststr : fileprotstr, t->name);
140         for (te = t->tableent; te; te = te->next)
141             (void) fprintf (f, 
142                 "#ifndef %s%s\n#define %s%s ((char*)&%s[%d])\n#endif\n",
143                 prefixstr, te->left, prefixstr, te->left, t->name, te->offset);
144     }
145
146     (void) fprintf (f, "#endif /* %s */\n", featurestr);
147 }
148
149 static void SPARCABIWriteHeader (f, phile)
150     FILE* f;
151     File* phile;
152 {
153     Table* t;
154     TableEnt* te;
155
156     for (t = phile->table; t; t = t->next)
157         for (te = t->tableent; te; te = te->next)
158             (void) fprintf (f, "#define %s%s \"%s\"\n",
159                             prefixstr, te->left, te->right);
160 }
161
162 static void FunctionWriteHeader (f, phile)
163     FILE* f;
164     File* phile;
165 {
166     Table* t;
167     TableEnt* te;
168
169     WriteHeaderProlog (f, phile);
170
171     (void) fprintf (f, "%s %sConst char* %s();\n", 
172                     externrefstr, conststr ? conststr : fileprotstr, 
173                     phile->table->name);
174
175     for (t = phile->table; t; t = t->next)
176         for (te = t->tableent; te; te = te->next)
177             (void) fprintf (f, 
178                 "#ifndef %s%s\n#define %s%s (%s(%d))\n#endif\n",
179                 prefixstr, te->left, prefixstr, te->left, phile->table->name, 
180                 te->offset);
181
182     (void) fprintf (f, "#endif /* %s */\n", featurestr);
183 }
184
185 static void ArrayperWriteHeader (f, phile)
186     FILE* f;
187     File* phile;
188 {
189     Table* t;
190     TableEnt* te;
191
192     WriteHeaderProlog (f, phile);
193
194     for (t = phile->table; t; t = t->next)
195         for (te = t->tableent; te; te = te->next)
196             (void) fprintf (f, 
197                             "#ifndef %s%s\n%s %sConst char %s%s[];\n#endif\n",
198                             prefixstr, te->left, 
199                             externrefstr, conststr ? conststr : fileprotstr, 
200                             prefixstr, te->left);
201
202     (void) fprintf (f, "#endif /* %s */\n", featurestr);
203 }
204
205 static void DefaultWriteHeader (f, phile)
206     FILE* f;
207     File* phile;
208 {
209     Table* t;
210     TableEnt* te;
211
212     WriteHeaderProlog (f, phile);
213
214     (void) fprintf (f, "%s %sConst char %s[];\n", 
215                     externrefstr, conststr ? conststr : fileprotstr, 
216                     phile->table->name);
217
218     for (t = phile->table; t; t = t->next)
219         for (te = t->tableent; te; te = te->next)
220             (void) fprintf (f, 
221                 "#ifndef %s%s\n#define %s%s ((char*)&%s[%d])\n#endif\n",
222                 prefixstr, te->left, prefixstr, te->left, phile->table->name, 
223                 te->offset);
224
225     (void) fprintf (f, "#endif /* %s */\n", featurestr);
226 }
227
228 static void CopyTmplProlog (tmpl, f)
229     FILE* tmpl;
230     FILE* f;
231 {
232     char buf[1024];
233     static char* magic_string = X_MAGIC_STRING;
234     int magic_string_len = strlen (magic_string);
235
236     while (fgets (buf, sizeof buf, tmpl)) {
237         if (strncmp (buf, magic_string, magic_string_len) == 0) {
238             return;
239         }
240         (void) fputs (buf, f);
241     }
242 }
243
244 static void CopyTmplEpilog (tmpl, f)
245     FILE* tmpl;
246     FILE* f;
247 {
248     char buf[1024];
249
250     while (fgets (buf, sizeof buf, tmpl))
251         (void) fputs (buf, f);
252 }
253
254 static char* abistring[] = {
255     "Default", "Array per string", "Intel", "Intel BC", "SPARC", "Function" };
256
257 static void WriteHeader (tagline, phile, abi)
258     char* tagline;
259     File* phile;
260     int abi;
261 {
262     FILE* f;
263     char* tmp;
264     Table* t;
265     TableEnt* te;
266     static void (*headerproc[])() = { 
267         DefaultWriteHeader, ArrayperWriteHeader,
268         IntelABIWriteHeader, IntelABIWriteHeader,
269         SPARCABIWriteHeader, FunctionWriteHeader };
270
271     if ((f = fopen (phile->name, "w+")) == NULL) exit (1);
272
273     if (phile->tmpl) CopyTmplProlog (phile->tmpl, f);
274
275     (void) fprintf (f, 
276         "%s\n%s\n/* %s ABI version -- Do not edit */\n", 
277         "/* $TOG: makestrs.c /main/11 1998/02/06 11:24:15 kaleb $ */",
278         "/* This file is automatically generated. */",
279         abistring[abi]);
280
281     if (tagline) (void) fprintf (f, "/* %s */\n\n", tagline);
282
283     /* do the right thing for Motif, i.e. avoid _XmXmStrDefs_h_ */
284     if (strcmp (prefixstr, "Xm") == 0) {
285         if ((fileprotstr = malloc (strlen (phile->name) + 3)) == NULL)
286            exit (1);
287         (void) sprintf (fileprotstr, "_%s_", phile->name);
288     } else {
289         if ((fileprotstr = malloc (strlen (phile->name) + strlen (prefixstr) +  3)) == NULL)
290            exit (1);
291         (void) sprintf (fileprotstr, "_%s%s_", prefixstr, phile->name);
292     }
293
294     for (tmp = fileprotstr; *tmp; tmp++) if (*tmp == '.') *tmp = '_';
295
296     (*headerproc[abi])(f, phile);
297
298     if (phile->tmpl) CopyTmplEpilog (phile->tmpl, f);
299
300     (void) free (fileprotstr);
301     (void) fclose (phile->tmpl);
302     (void) fclose (f);
303 }
304
305 static void WriteSourceLine (te, abi, fudge)
306     TableEnt* te;
307     int abi;
308 {
309     char* c;
310
311     for (c = te->right; *c; c++) (void) printf ("'%c',", *c);
312     (void) printf ("%c", '0');
313     if (te->next || fudge) (void) printf ("%c", ',');
314     (void) printf ("%s", "\n");
315 }
316
317 static char* const_string = "%s %sConst char %s[] = {\n";
318
319 static void IntelABIWriteSource (abi)
320     int abi;
321 {
322     File* phile;
323
324     for (phile = file; phile; phile = phile->next) {
325         Table* t;
326         TableEnt* te;
327
328         for (t = phile->table; t; t = t->next) {
329             (void) printf (const_string, externdefstr, 
330                            conststr ? conststr : "", t->name);
331             for (te = t->tableent; te; te = te->next)
332                 WriteSourceLine (te, abi, 0);
333             (void) printf ("%s\n\n", "};");
334         }
335     }
336 }
337
338 static void IntelABIBCWriteSource (abi)
339     int abi;
340 {
341     File* phile;
342
343     for (phile = file; phile; phile = phile->next) {
344         Table* t;
345         TableEnt* te;
346
347         (void) printf (const_string, externdefstr, 
348                        conststr ? conststr : "", phile->table->name);
349
350         for (t = phile->table; t; t = t->next) 
351             for (te = t->tableent; te; te = te->next)
352                 WriteSourceLine (te, abi, t->next ? 1 : 0);
353         (void) printf ("%s\n\n", "};");
354
355         if (phile->table->next) {
356             (void) printf (const_string, externdefstr, 
357                            conststr ? conststr : "", phile->table->next->name);
358             for (t = phile->table->next; t; t = t->next) 
359                 for (te = t->tableent; te; te = te->next)
360                     WriteSourceLine (te, abi, 0);
361             (void) printf ("%s\n\n", "};");
362         }
363     }
364 }
365
366 static void FunctionWriteSource (abi)
367     int abi;
368 {
369     File* phile;
370
371     for (phile = file; phile; phile = phile->next) {
372         Table* t;
373         TableEnt* te;
374
375         (void) printf ("static %sConst char _%s[] = {\n", 
376                        conststr ? conststr : "", phile->table->name);
377
378         for (t = phile->table; t; t = t->next) 
379             for (te = t->tableent; te; te = te->next)
380                 WriteSourceLine (te, abi, t->next ? 1 : 0);
381         (void) printf ("%s\n\n", "};");
382
383         (void) printf ("%sConst char* %s(index)\n    int index;\n{\n    return &_%s[index];\n}\n\n",
384                        conststr ? conststr : "", 
385                        phile->table->name, phile->table->name);
386     }
387 }
388
389 static void ArrayperWriteSource (abi)
390     int abi;
391 {
392     File* phile;
393     static int done_atom;
394
395     for (phile = file; phile; phile = phile->next) {
396         Table* t;
397         TableEnt* te;
398
399         for (t = phile->table; t; t = t->next) 
400             for (te = t->tableent; te; te = te->next) {
401                 if (strcmp (te->left, "RAtom") == 0) {
402                     if (done_atom) return;
403                     done_atom = 1;
404                 }
405                 (void) printf ("%s %sConst char %s%s[] = \"%s\";\n",
406                                externdefstr, conststr ? conststr : prefixstr, 
407                                te->left, te->right);
408             }
409     }
410 }
411
412 static void DefaultWriteSource (abi)
413     int abi;
414 {
415     File* phile;
416
417     for (phile = file; phile; phile = phile->next) {
418         Table* t;
419         TableEnt* te;
420
421         (void) printf (const_string, externdefstr, conststr ? conststr : "",
422                        phile->table->name);
423
424         for (t = phile->table; t; t = t->next) 
425             for (te = t->tableent; te; te = te->next)
426                 WriteSourceLine (te, abi, t->next ? 1 : 0);
427         (void) printf ("%s\n\n", "};");
428     }
429 }
430
431 static void WriteSource(tagline, abi)
432     char* tagline;
433     int abi;
434 {
435     static void (*sourceproc[])() = { 
436         DefaultWriteSource, ArrayperWriteSource,
437         IntelABIWriteSource, IntelABIBCWriteSource,
438         DefaultWriteSource, FunctionWriteSource };
439
440     FILE* tmpl;
441
442     if (ctmplstr) {
443         tmpl = fopen (ctmplstr, "r");
444
445         if (tmpl) CopyTmplProlog (tmpl, stdout);
446         else {
447             (void) fprintf (stderr, "Expected template %s, not found\n",
448                             ctmplstr);
449             exit (1);
450         }
451     } else
452         tmpl = NULL;
453
454
455     (void) printf ("%s\n%s\n/* %s ABI version -- Do not edit */\n", 
456                    "/* $TOG: makestrs.c /main/11 1998/02/06 11:24:15 kaleb $ */",
457                    "/* This file is automatically generated. */",
458                    abistring[abi]);
459
460     if (tagline) (void) printf ("/* %s */\n\n", tagline);
461
462     (*sourceproc[abi])(abi);
463
464     if (tmpl) CopyTmplEpilog (tmpl, stdout);
465 }
466
467 static void DoLine(buf)
468     char* buf;
469 {
470 #define X_NO_TOKEN 0
471 #define X_FILE_TOKEN 1
472 #define X_TABLE_TOKEN 2
473 #define X_PREFIX_TOKEN 3
474 #define X_FEATURE_TOKEN 4
475 #define X_EXTERNREF_TOKEN 5
476 #define X_EXTERNDEF_TOKEN 6
477 #define X_CTMPL_TOKEN 7
478 #define X_HTMPL_TOKEN 8
479 #define X_CONST_TOKEN 9
480
481     int token;
482     char lbuf[1024];
483     static char* file_str = "#file";
484     static char* table_str = "#table";
485     static char* prefix_str = "#prefix";
486     static char* feature_str = "#feature";
487     static char* externref_str = "#externref";
488     static char* externdef_str = "#externdef";
489     static char* ctmpl_str = "#ctmpl";
490     static char* htmpl_str = "#htmpl";
491     static char* const_str = "#const";
492
493     if (strncmp (buf, file_str, strlen (file_str)) == 0) 
494         token = X_FILE_TOKEN;
495     else if (strncmp (buf, table_str, strlen (table_str)) == 0) 
496         token = X_TABLE_TOKEN;
497     else if (strncmp (buf, prefix_str, strlen (prefix_str)) == 0) 
498         token = X_PREFIX_TOKEN;
499     else if (strncmp (buf, feature_str, strlen (feature_str)) == 0) 
500         token = X_FEATURE_TOKEN;
501     else if (strncmp (buf, externref_str, strlen (externref_str)) == 0) 
502         token = X_EXTERNREF_TOKEN;
503     else if (strncmp (buf, externdef_str, strlen (externdef_str)) == 0) 
504         token = X_EXTERNDEF_TOKEN;
505     else if (strncmp (buf, ctmpl_str, strlen (ctmpl_str)) == 0) 
506         token = X_CTMPL_TOKEN;
507     else if (strncmp (buf, htmpl_str, strlen (htmpl_str)) == 0) 
508         token = X_HTMPL_TOKEN;
509     else if (strncmp (buf, const_str, strlen (const_str)) == 0) 
510         token = X_CONST_TOKEN;
511     else
512         token = X_NO_TOKEN;
513
514     switch (token) {
515     case X_FILE_TOKEN:
516         {
517             File* phile;
518
519             if ((phile = (File*) malloc (sizeof(File))) == NULL) 
520                 exit(1);
521             if ((phile->name = malloc (strlen (buf + strlen (file_str)) + 1)) == NULL) 
522                 exit(1);
523             (void) strcpy (phile->name, buf + strlen (file_str) + 1);
524             phile->table = NULL;
525             phile->tablecurrent = NULL;
526             phile->tabletail = &phile->table;
527             phile->next = NULL;
528             phile->tmpl = NULL;
529
530             *filetail = phile;
531             filetail = &phile->next;
532             filecurrent = phile;
533         }
534         break;
535     case X_TABLE_TOKEN:
536         {
537             Table* table;
538             if ((table = (Table*) malloc (sizeof(Table))) == NULL) 
539                 exit(1);
540             if ((table->name = malloc (strlen (buf + strlen (table_str)) + 1)) == NULL) 
541                 exit(1);
542             (void) strcpy (table->name, buf + strlen (table_str) + 1);
543             table->tableent = NULL;
544             table->tableentcurrent = NULL;
545             table->tableenttail = &table->tableent;
546             table->next = NULL;
547             table->offset = 0;
548
549             *filecurrent->tabletail = table;
550             filecurrent->tabletail = &table->next;
551             filecurrent->tablecurrent = table;
552         }
553         break;
554     case X_PREFIX_TOKEN:
555         if ((prefixstr = malloc (strlen (buf + strlen (prefix_str)) + 1)) == NULL) 
556             exit(1);
557         (void) strcpy (prefixstr, buf + strlen (prefix_str) + 1);
558         break;
559     case X_FEATURE_TOKEN:
560         if ((featurestr = malloc (strlen (buf + strlen (feature_str)) + 1)) == NULL) 
561             exit(1);
562         (void) strcpy (featurestr, buf + strlen (feature_str) + 1);
563         break;
564     case X_EXTERNREF_TOKEN:
565         if ((externrefstr = malloc (strlen (buf + strlen (externref_str)) + 1)) == NULL) 
566             exit(1);
567         (void) strcpy (externrefstr, buf + strlen (externref_str) + 1);
568         break;
569     case X_EXTERNDEF_TOKEN:
570         if ((externdefstr = malloc (strlen (buf + strlen (externdef_str)) + 1)) == NULL) 
571             exit(1);
572         (void) strcpy (externdefstr, buf + strlen (externdef_str) + 1);
573         break;
574     case X_CTMPL_TOKEN:
575         if ((ctmplstr = malloc (strlen (buf + strlen (ctmpl_str)) + 1)) == NULL) 
576             exit(1);
577         (void) strcpy (ctmplstr, buf + strlen (ctmpl_str) + 1);
578         break;
579     case X_HTMPL_TOKEN:
580         if ((filecurrent->tmpl = fopen (buf + strlen (htmpl_str) + 1, "r")) == NULL) {
581             (void) fprintf (stderr, 
582                             "Expected template %s, not found\n", htmpl_str);
583             exit (1);
584         }
585         break;
586     case X_CONST_TOKEN:
587         if ((conststr = malloc (strlen (buf + strlen (const_str)) + 1)) == NULL)
588             exit(1);
589         (void) strcpy (conststr, buf + strlen (const_str) + 1);
590         break;
591     default:
592         {
593             char* right;
594             TableEnt* tableent;
595             int llen;
596             int rlen;
597             int len;
598
599             if (right = index(buf, ' '))
600                 *right++ = 0;
601             else
602                 right = buf + 1;
603             if (buf[0] == 'H') {
604                 strcpy (lbuf, prefixstr);
605                 strcat (lbuf, right);
606                 right = lbuf;
607             }
608
609             llen = len = strlen(buf) + 1;
610             rlen = strlen(right) + 1;
611             if (right != buf + 1) len += rlen;
612             if ((tableent = (TableEnt*)malloc(sizeof(TableEnt) + len)) == NULL)
613                 exit(1);
614             tableent->left = (char *)(tableent + 1);
615             strcpy(tableent->left, buf);
616             if (llen != len) {
617                 tableent->right = tableent->left + llen;
618                 strcpy(tableent->right, right);
619             } else {
620                 tableent->right = tableent->left + 1;
621             }
622             tableent->next = NULL;
623
624             *filecurrent->tablecurrent->tableenttail = tableent;
625             filecurrent->tablecurrent->tableenttail = &tableent->next;
626             filecurrent->tablecurrent->tableentcurrent = tableent;
627         }
628         break;
629     }
630 }
631
632 static void IntelABIIndexEntries (file)
633     File* file;
634 {
635     Table* t;
636     TableEnt* te;
637
638     for (t = file->table; t; t = t->next)
639         for (te = t->tableent; te; te = te->next) {
640             te->offset = t->offset;
641             t->offset += strlen (te->right);
642             t->offset++;
643     }
644 }
645
646 static void DefaultIndexEntries (file)
647     File* file;
648 {
649     Table* t;
650     TableEnt* te;
651     int offset = 0;
652
653     for (t = file->table; t; t = t->next)
654         for (te = t->tableent; te; te = te->next) {
655             te->offset = offset;
656             offset += strlen (te->right);
657             offset++;
658     }
659 }
660
661 static void IndexEntries (file,abi)
662     File* file;
663     int abi;
664 {
665     switch (abi) {
666     case X_SPARC_ABI:
667         break;
668     case X_INTEL_ABI:
669     case X_INTEL_ABI_BC:
670         IntelABIIndexEntries (file);
671         break;
672     default:
673         DefaultIndexEntries (file);
674         break;
675     }
676 }
677
678 static char* DoComment (line)
679     char* line;
680 {
681     char* tag;
682     char* eol;
683     char* ret;
684     int len;
685
686     /* assume that the first line with two '$' in it is the RCS tag line */
687     if ((tag = index (line, '$')) == NULL) return NULL;
688     if ((eol = index (tag + 1, '$')) == NULL) return NULL;
689     len = eol - tag;
690     if ((ret = malloc (len)) == NULL)
691         exit (1);
692     (void) strncpy (ret, tag + 1, len - 1);
693     ret[len - 2] = 0;
694     return ret;
695 }
696
697 int main(argc, argv)
698     int argc;
699     char** argv;
700 {
701     int len, i;
702     char* tagline = NULL;
703     File* phile;
704     FILE *f;
705     char buf[1024];
706     int abi = 
707 #ifndef ARRAYPERSTR
708         X_DEFAULT_ABI;
709 #else
710         X_ARRAYPER_ABI;
711 #endif
712
713     f = stdin;
714     if (argc > 1) {
715         for (i = 1; i < argc; i++) {
716             if (strcmp (argv[i], "-f") == 0) {
717                 if (++i < argc)
718                     f = fopen (argv[i], "r");
719                 else
720                     return 1;
721             }
722             if (strcmp (argv[i], "-sparcabi") == 0)
723                 abi = X_SPARC_ABI;
724             if (strcmp (argv[i], "-intelabi") == 0)
725                 abi = X_INTEL_ABI;
726             if (strcmp (argv[i], "-functionabi") == 0)
727                 abi = X_FUNCTION_ABI;
728             if (strcmp (argv[i], "-earlyR6bc") == 0 && abi == X_INTEL_ABI)
729                 abi = X_INTEL_ABI_BC;
730             if (strcmp (argv[i], "-arrayperabi") == 0)
731                 abi = X_ARRAYPER_ABI;
732 #ifdef ARRAYPERSTR
733             if (strcmp (argv[i], "-defaultabi") == 0)
734                 abi = X_DEFAULT_ABI;
735 #endif
736         }
737     }
738
739     if (f == NULL) return 1;
740     while (fgets(buf, sizeof buf, f)) {
741         if (!buf[0] || buf[0] == '\n') 
742             continue;
743         if (buf[0] == '!') {
744             if (tagline) continue;
745             tagline = DoComment (buf);
746             continue;
747         }
748         if (buf[(len = strlen (buf) - 1)] == '\n') buf[len] = '\0';
749         DoLine(buf);
750     }
751     for (phile = file; phile; phile = phile->next) {
752         if (abi != X_ARRAYPER_ABI) IndexEntries (phile, abi);
753         WriteHeader (tagline, phile, abi);
754     }
755     WriteSource(tagline, abi);
756     return 0;
757 }
758