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