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