1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright 2009-2010 SN Systems Ltd. All rights reserved.
3*4d9fdb46SRobert Mustacchi Portions Copyright 2009-2018 David Anderson. All rights reserved.
4*4d9fdb46SRobert Mustacchi
5*4d9fdb46SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
6*4d9fdb46SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
7*4d9fdb46SRobert Mustacchi as published by the Free Software Foundation.
8*4d9fdb46SRobert Mustacchi
9*4d9fdb46SRobert Mustacchi This program is distributed in the hope that it would be useful, but
10*4d9fdb46SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
11*4d9fdb46SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*4d9fdb46SRobert Mustacchi
13*4d9fdb46SRobert Mustacchi Further, this software is distributed without any warranty that it is
14*4d9fdb46SRobert Mustacchi free of the rightful claim of any third person regarding infringement
15*4d9fdb46SRobert Mustacchi or the like. Any license provided herein, whether implied or
16*4d9fdb46SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
17*4d9fdb46SRobert Mustacchi any, provided herein do not apply to combinations of this program with
18*4d9fdb46SRobert Mustacchi other software, or any other product whatsoever.
19*4d9fdb46SRobert Mustacchi
20*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
21*4d9fdb46SRobert Mustacchi License along with this program; if not, write the Free Software
22*4d9fdb46SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*4d9fdb46SRobert Mustacchi USA.
24*4d9fdb46SRobert Mustacchi
25*4d9fdb46SRobert Mustacchi */
26*4d9fdb46SRobert Mustacchi
27*4d9fdb46SRobert Mustacchi #include "config.h"
28*4d9fdb46SRobert Mustacchi #ifdef _WIN32
29*4d9fdb46SRobert Mustacchi #define _CRT_SECURE_NO_WARNINGS
30*4d9fdb46SRobert Mustacchi #endif /* _WIN32 */
31*4d9fdb46SRobert Mustacchi
32*4d9fdb46SRobert Mustacchi #include <stdio.h>
33*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
34*4d9fdb46SRobert Mustacchi #include <stdlib.h>
35*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
36*4d9fdb46SRobert Mustacchi #include <errno.h> /* For errno declaration. */
37*4d9fdb46SRobert Mustacchi #include <ctype.h>
38*4d9fdb46SRobert Mustacchi #include <string.h>
39*4d9fdb46SRobert Mustacchi #include "dwgetopt.h"
40*4d9fdb46SRobert Mustacchi #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */
41*4d9fdb46SRobert Mustacchi
42*4d9fdb46SRobert Mustacchi /* gennames.c
43*4d9fdb46SRobert Mustacchi Prints routines to return constant name for the associated value
44*4d9fdb46SRobert Mustacchi (such as the TAG name string for a particular tag).
45*4d9fdb46SRobert Mustacchi
46*4d9fdb46SRobert Mustacchi The input is dwarf.h
47*4d9fdb46SRobert Mustacchi For each set of names with a common prefix, we create a routine
48*4d9fdb46SRobert Mustacchi to return the name given the value.
49*4d9fdb46SRobert Mustacchi Also print header file that gives prototypes of routines.
50*4d9fdb46SRobert Mustacchi To handle cases where there are multiple names for a single
51*4d9fdb46SRobert Mustacchi value (DW_AT_* has some due to ambiguities in the DWARF2 spec)
52*4d9fdb46SRobert Mustacchi we take the first of a given value as the definitive name.
53*4d9fdb46SRobert Mustacchi TAGs, Attributes, etc are given distinct checks.
54*4d9fdb46SRobert Mustacchi
55*4d9fdb46SRobert Mustacchi There are multiple output files as some people find one
56*4d9fdb46SRobert Mustacchi form more pleasant than the other.
57*4d9fdb46SRobert Mustacchi
58*4d9fdb46SRobert Mustacchi The doprinting argument is so that when used by tag_tree.c,
59*4d9fdb46SRobert Mustacchi and tag_attr.c that we don't get irritating messages on stderr
60*4d9fdb46SRobert Mustacchi when those dwarfdump built-time applications are run.
61*4d9fdb46SRobert Mustacchi
62*4d9fdb46SRobert Mustacchi Some compilers generate better code for switch statements than
63*4d9fdb46SRobert Mustacchi others, so the -s and -t options let the user decide which
64*4d9fdb46SRobert Mustacchi is better for their compiler (when building dwarfdump):
65*4d9fdb46SRobert Mustacchi a simple switch or code doing binary search.
66*4d9fdb46SRobert Mustacchi This choice affects the runtime speed of dwarfdump. */
67*4d9fdb46SRobert Mustacchi
68*4d9fdb46SRobert Mustacchi typedef int boolean;
69*4d9fdb46SRobert Mustacchi #define TRUE 1
70*4d9fdb46SRobert Mustacchi #define FALSE 0
71*4d9fdb46SRobert Mustacchi #define FAILED 1
72*4d9fdb46SRobert Mustacchi
73*4d9fdb46SRobert Mustacchi static void OpenAllFiles(void);
74*4d9fdb46SRobert Mustacchi static void WriteFileTrailers(void);
75*4d9fdb46SRobert Mustacchi static void CloseAllFiles(void);
76*4d9fdb46SRobert Mustacchi static void GenerateInitialFileLines(void);
77*4d9fdb46SRobert Mustacchi static void GenerateOneSet(void);
78*4d9fdb46SRobert Mustacchi #ifdef TRACE_ARRAY
79*4d9fdb46SRobert Mustacchi static void PrintArray(void);
80*4d9fdb46SRobert Mustacchi #endif /* TRACE_ARRAY */
81*4d9fdb46SRobert Mustacchi static boolean is_skippable_line(char *pLine);
82*4d9fdb46SRobert Mustacchi static void ParseDefinitionsAndWriteOutput(void);
83*4d9fdb46SRobert Mustacchi
84*4d9fdb46SRobert Mustacchi /* We don't need really long lines: the input file is simple. */
85*4d9fdb46SRobert Mustacchi #define MAX_LINE_SIZE 1000
86*4d9fdb46SRobert Mustacchi /* We don't need a variable array size, it just has to be big enough. */
87*4d9fdb46SRobert Mustacchi #define ARRAY_SIZE 300
88*4d9fdb46SRobert Mustacchi
89*4d9fdb46SRobert Mustacchi #define MAX_NAME_LEN 64
90*4d9fdb46SRobert Mustacchi
91*4d9fdb46SRobert Mustacchi /* To store entries from dwarf.h */
92*4d9fdb46SRobert Mustacchi typedef struct {
93*4d9fdb46SRobert Mustacchi char name[MAX_NAME_LEN]; /* short name */
94*4d9fdb46SRobert Mustacchi unsigned value; /* value */
95*4d9fdb46SRobert Mustacchi /* Original spot in array. Lets us guarantee a stable sort. */
96*4d9fdb46SRobert Mustacchi unsigned original_position;
97*4d9fdb46SRobert Mustacchi } array_data;
98*4d9fdb46SRobert Mustacchi
99*4d9fdb46SRobert Mustacchi /* A group_array is a grouping from dwarf.h.
100*4d9fdb46SRobert Mustacchi All the TAGs are one group, all the
101*4d9fdb46SRobert Mustacchi FORMs are another group, and so on. */
102*4d9fdb46SRobert Mustacchi static array_data group_array[ARRAY_SIZE];
103*4d9fdb46SRobert Mustacchi static unsigned array_count = 0;
104*4d9fdb46SRobert Mustacchi
105*4d9fdb46SRobert Mustacchi typedef int (*compfn)(const void *,const void *);
106*4d9fdb46SRobert Mustacchi static int Compare(array_data *,array_data *);
107*4d9fdb46SRobert Mustacchi
108*4d9fdb46SRobert Mustacchi static const char *prefix_root = "DW_";
109*4d9fdb46SRobert Mustacchi static const unsigned prefix_root_len = 3;
110*4d9fdb46SRobert Mustacchi
111*4d9fdb46SRobert Mustacchi /* f_dwarf_in is the input dwarf.h. The others are output files. */
112*4d9fdb46SRobert Mustacchi static FILE *f_dwarf_in;
113*4d9fdb46SRobert Mustacchi static FILE *f_names_h;
114*4d9fdb46SRobert Mustacchi static FILE *f_names_c;
115*4d9fdb46SRobert Mustacchi static FILE *f_names_enum_h;
116*4d9fdb46SRobert Mustacchi static FILE *f_names_new_h;
117*4d9fdb46SRobert Mustacchi
118*4d9fdb46SRobert Mustacchi /* Size unchecked, but large enough. */
119*4d9fdb46SRobert Mustacchi static char prefix[200] = "";
120*4d9fdb46SRobert Mustacchi
121*4d9fdb46SRobert Mustacchi static const char *usage[] = {
122*4d9fdb46SRobert Mustacchi "Usage: gennames <options>",
123*4d9fdb46SRobert Mustacchi " -i input-table-path",
124*4d9fdb46SRobert Mustacchi " -o output-table-path",
125*4d9fdb46SRobert Mustacchi " -s use 'switch' in generation",
126*4d9fdb46SRobert Mustacchi " -t use 'tables' in generation",
127*4d9fdb46SRobert Mustacchi "",
128*4d9fdb46SRobert Mustacchi };
129*4d9fdb46SRobert Mustacchi
130*4d9fdb46SRobert Mustacchi static void
print_args(int argc,char * argv[])131*4d9fdb46SRobert Mustacchi print_args(int argc, char *argv[])
132*4d9fdb46SRobert Mustacchi {
133*4d9fdb46SRobert Mustacchi int index;
134*4d9fdb46SRobert Mustacchi printf("Arguments: ");
135*4d9fdb46SRobert Mustacchi for (index = 1; index < argc; ++index) {
136*4d9fdb46SRobert Mustacchi printf("%s ",argv[index]);
137*4d9fdb46SRobert Mustacchi }
138*4d9fdb46SRobert Mustacchi printf("\n");
139*4d9fdb46SRobert Mustacchi }
140*4d9fdb46SRobert Mustacchi
141*4d9fdb46SRobert Mustacchi
142*4d9fdb46SRobert Mustacchi char *program_name = 0;
143*4d9fdb46SRobert Mustacchi static char *input_name = 0;
144*4d9fdb46SRobert Mustacchi static char *output_name = 0;
145*4d9fdb46SRobert Mustacchi static boolean use_switch = TRUE;
146*4d9fdb46SRobert Mustacchi static boolean use_tables = FALSE;
147*4d9fdb46SRobert Mustacchi
148*4d9fdb46SRobert Mustacchi static void
print_version(const char * name)149*4d9fdb46SRobert Mustacchi print_version(const char * name)
150*4d9fdb46SRobert Mustacchi {
151*4d9fdb46SRobert Mustacchi #ifdef _DEBUG
152*4d9fdb46SRobert Mustacchi const char *acType = "Debug";
153*4d9fdb46SRobert Mustacchi #else
154*4d9fdb46SRobert Mustacchi const char *acType = "Release";
155*4d9fdb46SRobert Mustacchi #endif /* _DEBUG */
156*4d9fdb46SRobert Mustacchi
157*4d9fdb46SRobert Mustacchi printf("%s [%s %s]\n",name,DW_VERSION_DATE_STR,acType);
158*4d9fdb46SRobert Mustacchi }
159*4d9fdb46SRobert Mustacchi
160*4d9fdb46SRobert Mustacchi
161*4d9fdb46SRobert Mustacchi static void
print_usage_message(const char * options[])162*4d9fdb46SRobert Mustacchi print_usage_message(const char *options[])
163*4d9fdb46SRobert Mustacchi {
164*4d9fdb46SRobert Mustacchi int index;
165*4d9fdb46SRobert Mustacchi for (index = 0; *options[index]; ++index) {
166*4d9fdb46SRobert Mustacchi printf("%s\n",options[index]);
167*4d9fdb46SRobert Mustacchi }
168*4d9fdb46SRobert Mustacchi }
169*4d9fdb46SRobert Mustacchi
170*4d9fdb46SRobert Mustacchi
171*4d9fdb46SRobert Mustacchi /* process arguments */
172*4d9fdb46SRobert Mustacchi static void
process_args(int argc,char * argv[])173*4d9fdb46SRobert Mustacchi process_args(int argc, char *argv[])
174*4d9fdb46SRobert Mustacchi {
175*4d9fdb46SRobert Mustacchi int c = 0;
176*4d9fdb46SRobert Mustacchi boolean usage_error = FALSE;
177*4d9fdb46SRobert Mustacchi
178*4d9fdb46SRobert Mustacchi program_name = argv[0];
179*4d9fdb46SRobert Mustacchi
180*4d9fdb46SRobert Mustacchi while ((c = dwgetopt(argc, argv, "i:o:st")) != EOF) {
181*4d9fdb46SRobert Mustacchi switch (c) {
182*4d9fdb46SRobert Mustacchi case 'i':
183*4d9fdb46SRobert Mustacchi input_name = dwoptarg;
184*4d9fdb46SRobert Mustacchi break;
185*4d9fdb46SRobert Mustacchi case 'o':
186*4d9fdb46SRobert Mustacchi output_name = dwoptarg;
187*4d9fdb46SRobert Mustacchi break;
188*4d9fdb46SRobert Mustacchi case 's':
189*4d9fdb46SRobert Mustacchi use_switch = TRUE;
190*4d9fdb46SRobert Mustacchi use_tables = FALSE;
191*4d9fdb46SRobert Mustacchi break;
192*4d9fdb46SRobert Mustacchi case 't':
193*4d9fdb46SRobert Mustacchi use_switch = FALSE;
194*4d9fdb46SRobert Mustacchi use_tables = TRUE;
195*4d9fdb46SRobert Mustacchi break;
196*4d9fdb46SRobert Mustacchi default:
197*4d9fdb46SRobert Mustacchi usage_error = TRUE;
198*4d9fdb46SRobert Mustacchi break;
199*4d9fdb46SRobert Mustacchi }
200*4d9fdb46SRobert Mustacchi }
201*4d9fdb46SRobert Mustacchi
202*4d9fdb46SRobert Mustacchi if (usage_error || 1 == dwoptind || dwoptind != argc) {
203*4d9fdb46SRobert Mustacchi print_usage_message(usage);
204*4d9fdb46SRobert Mustacchi exit(FAILED);
205*4d9fdb46SRobert Mustacchi }
206*4d9fdb46SRobert Mustacchi }
207*4d9fdb46SRobert Mustacchi
208*4d9fdb46SRobert Mustacchi int
main(int argc,char ** argv)209*4d9fdb46SRobert Mustacchi main(int argc,char **argv)
210*4d9fdb46SRobert Mustacchi {
211*4d9fdb46SRobert Mustacchi print_version(argv[0]);
212*4d9fdb46SRobert Mustacchi print_args(argc,argv);
213*4d9fdb46SRobert Mustacchi process_args(argc,argv);
214*4d9fdb46SRobert Mustacchi OpenAllFiles();
215*4d9fdb46SRobert Mustacchi GenerateInitialFileLines();
216*4d9fdb46SRobert Mustacchi ParseDefinitionsAndWriteOutput();
217*4d9fdb46SRobert Mustacchi WriteFileTrailers();
218*4d9fdb46SRobert Mustacchi CloseAllFiles();
219*4d9fdb46SRobert Mustacchi return 0;
220*4d9fdb46SRobert Mustacchi }
221*4d9fdb46SRobert Mustacchi
222*4d9fdb46SRobert Mustacchi /* Print the array used to hold the tags, attributes values */
223*4d9fdb46SRobert Mustacchi #ifdef TRACE_ARRAY
224*4d9fdb46SRobert Mustacchi static void
PrintArray(void)225*4d9fdb46SRobert Mustacchi PrintArray(void)
226*4d9fdb46SRobert Mustacchi {
227*4d9fdb46SRobert Mustacchi int i;
228*4d9fdb46SRobert Mustacchi for (i = 0; i < array_count; ++i) {
229*4d9fdb46SRobert Mustacchi printf("%d: Name %s_%s, Value 0x%04x\n",
230*4d9fdb46SRobert Mustacchi i,prefix,
231*4d9fdb46SRobert Mustacchi array[i].name,
232*4d9fdb46SRobert Mustacchi array[i].value);
233*4d9fdb46SRobert Mustacchi }
234*4d9fdb46SRobert Mustacchi }
235*4d9fdb46SRobert Mustacchi #endif /* TRACE_ARRAY */
236*4d9fdb46SRobert Mustacchi
237*4d9fdb46SRobert Mustacchi /* By including original position we force a stable sort */
238*4d9fdb46SRobert Mustacchi static int
Compare(array_data * elem1,array_data * elem2)239*4d9fdb46SRobert Mustacchi Compare(array_data *elem1,array_data *elem2)
240*4d9fdb46SRobert Mustacchi {
241*4d9fdb46SRobert Mustacchi if (elem1->value < elem2->value) {
242*4d9fdb46SRobert Mustacchi return -1;
243*4d9fdb46SRobert Mustacchi }
244*4d9fdb46SRobert Mustacchi if (elem1->value > elem2->value) {
245*4d9fdb46SRobert Mustacchi return 1;
246*4d9fdb46SRobert Mustacchi }
247*4d9fdb46SRobert Mustacchi if (elem1->original_position < elem2->original_position) {
248*4d9fdb46SRobert Mustacchi return -1;
249*4d9fdb46SRobert Mustacchi }
250*4d9fdb46SRobert Mustacchi if (elem1->original_position > elem2->original_position) {
251*4d9fdb46SRobert Mustacchi return 1;
252*4d9fdb46SRobert Mustacchi }
253*4d9fdb46SRobert Mustacchi return 0;
254*4d9fdb46SRobert Mustacchi }
255*4d9fdb46SRobert Mustacchi
256*4d9fdb46SRobert Mustacchi static FILE *
open_path(const char * base,const char * file,const char * direction)257*4d9fdb46SRobert Mustacchi open_path(const char *base, const char *file, const char *direction)
258*4d9fdb46SRobert Mustacchi {
259*4d9fdb46SRobert Mustacchi FILE *f = 0;
260*4d9fdb46SRobert Mustacchi /* POSIX PATH_MAX would suffice, normally stdio BUFSIZ is larger
261*4d9fdb46SRobert Mustacchi than PATH_MAX */
262*4d9fdb46SRobert Mustacchi static char path_name[BUFSIZ];
263*4d9fdb46SRobert Mustacchi
264*4d9fdb46SRobert Mustacchi /* 2 == space for / and NUL */
265*4d9fdb46SRobert Mustacchi size_t netlen = strlen(file) +strlen(base) + 2;
266*4d9fdb46SRobert Mustacchi
267*4d9fdb46SRobert Mustacchi if (netlen >= BUFSIZ) {
268*4d9fdb46SRobert Mustacchi printf("Error opening '%s/%s', name too long\n",base,file);
269*4d9fdb46SRobert Mustacchi exit(1);
270*4d9fdb46SRobert Mustacchi }
271*4d9fdb46SRobert Mustacchi
272*4d9fdb46SRobert Mustacchi strcpy(path_name,base);
273*4d9fdb46SRobert Mustacchi strcat(path_name,"/");
274*4d9fdb46SRobert Mustacchi strcat(path_name,file);
275*4d9fdb46SRobert Mustacchi
276*4d9fdb46SRobert Mustacchi f = fopen(path_name,direction);
277*4d9fdb46SRobert Mustacchi if (!f) {
278*4d9fdb46SRobert Mustacchi printf("Error opening '%s'\n",path_name);
279*4d9fdb46SRobert Mustacchi exit(1);
280*4d9fdb46SRobert Mustacchi }
281*4d9fdb46SRobert Mustacchi return f;
282*4d9fdb46SRobert Mustacchi }
283*4d9fdb46SRobert Mustacchi
284*4d9fdb46SRobert Mustacchi /* Open files and write the basic headers */
285*4d9fdb46SRobert Mustacchi static void
OpenAllFiles(void)286*4d9fdb46SRobert Mustacchi OpenAllFiles(void)
287*4d9fdb46SRobert Mustacchi {
288*4d9fdb46SRobert Mustacchi const char *dwarf_h = "dwarf.h";
289*4d9fdb46SRobert Mustacchi const char *names_h = "dwarf_names.h";
290*4d9fdb46SRobert Mustacchi const char *names_c = "dwarf_names.c";
291*4d9fdb46SRobert Mustacchi const char *names_enum_h = "dwarf_names_enum.h";
292*4d9fdb46SRobert Mustacchi const char *names_new_h = "dwarf_names_new.h";
293*4d9fdb46SRobert Mustacchi
294*4d9fdb46SRobert Mustacchi f_dwarf_in = open_path(input_name,dwarf_h,"r");
295*4d9fdb46SRobert Mustacchi f_names_enum_h = open_path(output_name,names_enum_h,"w");
296*4d9fdb46SRobert Mustacchi f_names_new_h = open_path(output_name,names_new_h,"w");
297*4d9fdb46SRobert Mustacchi f_names_h = open_path(output_name,names_h,"w");
298*4d9fdb46SRobert Mustacchi f_names_c = open_path(output_name,names_c,"w");
299*4d9fdb46SRobert Mustacchi }
300*4d9fdb46SRobert Mustacchi
301*4d9fdb46SRobert Mustacchi static void
GenerateInitialFileLines(void)302*4d9fdb46SRobert Mustacchi GenerateInitialFileLines(void)
303*4d9fdb46SRobert Mustacchi {
304*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_enum.h' */
305*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"/* Automatically generated, do not edit. */\n");
306*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"/* Generated sourcedate %s */\n",
307*4d9fdb46SRobert Mustacchi DW_VERSION_DATE_STR);
308*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"\n/* BEGIN FILE */\n\n");
309*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"#ifndef __DWARF_NAMES_ENUM_H__\n");
310*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"#define __DWARF_NAMES_ENUM_H__\n");
311*4d9fdb46SRobert Mustacchi
312*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_new.h' */
313*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"/* Automatically generated, do not edit. */\n");
314*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"/* Generated sourcedate %s */\n",
315*4d9fdb46SRobert Mustacchi DW_VERSION_DATE_STR);
316*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"\n/* BEGIN FILE */\n\n");
317*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"/* define DWARF_PRINT_PREFIX before this\n");
318*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h," point if you wish to. */\n");
319*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#ifndef DWARF_PRINT_PREFIX\n");
320*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#define DWARF_PRINT_PREFIX dwarf_\n");
321*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#endif\n");
322*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#define dw_glue(x,y) x##y\n");
323*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#define dw_glue2(x,y) dw_glue(x,y)\n");
324*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"#define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x)\n");
325*4d9fdb46SRobert Mustacchi
326*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.h' */
327*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"/* Generated routines, do not edit. */\n");
328*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"/* Generated sourcedate %s */\n",
329*4d9fdb46SRobert Mustacchi DW_VERSION_DATE_STR);
330*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"\n/* BEGIN FILE */\n\n");
331*4d9fdb46SRobert Mustacchi
332*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#ifndef DWARF_NAMES_H\n");
333*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#define DWARF_NAMES_H\n\n");
334*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#ifdef __cplusplus\n");
335*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"extern \"C\" {\n");
336*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#endif /* __cplusplus */\n\n");
337*4d9fdb46SRobert Mustacchi
338*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.c' */
339*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"/* Generated routines, do not edit. */\n");
340*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"/* Generated sourcedate %s */\n",
341*4d9fdb46SRobert Mustacchi DW_VERSION_DATE_STR);
342*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"\n/* BEGIN FILE */\n\n");
343*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"#include \"dwarf.h\"\n\n");
344*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"#include \"libdwarf.h\"\n\n");
345*4d9fdb46SRobert Mustacchi
346*4d9fdb46SRobert Mustacchi if (use_tables) {
347*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"typedef struct Names_Data {\n");
348*4d9fdb46SRobert Mustacchi fprintf(f_names_c," const char *l_name; \n");
349*4d9fdb46SRobert Mustacchi fprintf(f_names_c," unsigned value; \n");
350*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"} Names_Data;\n\n");
351*4d9fdb46SRobert Mustacchi
352*4d9fdb46SRobert Mustacchi /* Generate code to find an entry */
353*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"/* Use standard binary search to get entry */\n");
354*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"static int\nfind_entry(Names_Data *table,"
355*4d9fdb46SRobert Mustacchi "const int last,unsigned value, const char **s_out)\n");
356*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"{\n");
357*4d9fdb46SRobert Mustacchi fprintf(f_names_c," int low = 0;\n");
358*4d9fdb46SRobert Mustacchi fprintf(f_names_c," int high = last;\n");
359*4d9fdb46SRobert Mustacchi fprintf(f_names_c," int mid;\n");
360*4d9fdb46SRobert Mustacchi fprintf(f_names_c," unsigned maxval = table[last-1].value;\n");
361*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"\n");
362*4d9fdb46SRobert Mustacchi fprintf(f_names_c," if (value > maxval) {\n");
363*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n");
364*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
365*4d9fdb46SRobert Mustacchi fprintf(f_names_c," while (low < high) {\n");
366*4d9fdb46SRobert Mustacchi fprintf(f_names_c," mid = low + ((high - low) / 2);\n");
367*4d9fdb46SRobert Mustacchi fprintf(f_names_c," if(mid == last) {\n");
368*4d9fdb46SRobert Mustacchi fprintf(f_names_c," break;\n");
369*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
370*4d9fdb46SRobert Mustacchi fprintf(f_names_c," if (table[mid].value < value) {\n");
371*4d9fdb46SRobert Mustacchi fprintf(f_names_c," low = mid + 1;\n");
372*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
373*4d9fdb46SRobert Mustacchi fprintf(f_names_c," else {\n");
374*4d9fdb46SRobert Mustacchi fprintf(f_names_c," high = mid;\n");
375*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
376*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
377*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"\n");
378*4d9fdb46SRobert Mustacchi fprintf(f_names_c," if (low < last && table[low].value == value) {\n");
379*4d9fdb46SRobert Mustacchi fprintf(f_names_c," /* Found: low is the entry */\n");
380*4d9fdb46SRobert Mustacchi fprintf(f_names_c," *s_out = table[low].l_name;\n");
381*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return DW_DLV_OK;\n");
382*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
383*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n");
384*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"}\n");
385*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"\n");
386*4d9fdb46SRobert Mustacchi }
387*4d9fdb46SRobert Mustacchi }
388*4d9fdb46SRobert Mustacchi
389*4d9fdb46SRobert Mustacchi /* Close files and write basic trailers */
390*4d9fdb46SRobert Mustacchi static void
WriteFileTrailers(void)391*4d9fdb46SRobert Mustacchi WriteFileTrailers(void)
392*4d9fdb46SRobert Mustacchi {
393*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_enum.h' */
394*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"#endif /* __DWARF_NAMES_ENUM_H__ */\n");
395*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"\n/* END FILE */\n");
396*4d9fdb46SRobert Mustacchi
397*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_new.h' */
398*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"\n/* END FILE */\n");
399*4d9fdb46SRobert Mustacchi
400*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.h' */
401*4d9fdb46SRobert Mustacchi
402*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"\n#ifdef __cplusplus\n");
403*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"}\n");
404*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#endif /* __cplusplus */\n\n");
405*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"#endif /* DWARF_NAMES_H */\n");
406*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"\n/* END FILE */\n");
407*4d9fdb46SRobert Mustacchi
408*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.c' */
409*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"\n/* END FILE */\n");
410*4d9fdb46SRobert Mustacchi }
411*4d9fdb46SRobert Mustacchi
412*4d9fdb46SRobert Mustacchi static void
CloseAllFiles(void)413*4d9fdb46SRobert Mustacchi CloseAllFiles(void)
414*4d9fdb46SRobert Mustacchi {
415*4d9fdb46SRobert Mustacchi fclose(f_dwarf_in);
416*4d9fdb46SRobert Mustacchi fclose(f_names_enum_h);
417*4d9fdb46SRobert Mustacchi fclose(f_names_new_h);
418*4d9fdb46SRobert Mustacchi fclose(f_names_h);
419*4d9fdb46SRobert Mustacchi fclose(f_names_c);
420*4d9fdb46SRobert Mustacchi }
421*4d9fdb46SRobert Mustacchi
422*4d9fdb46SRobert Mustacchi /* Write the table and code for a common set of names */
423*4d9fdb46SRobert Mustacchi static void
GenerateOneSet(void)424*4d9fdb46SRobert Mustacchi GenerateOneSet(void)
425*4d9fdb46SRobert Mustacchi {
426*4d9fdb46SRobert Mustacchi unsigned u;
427*4d9fdb46SRobert Mustacchi unsigned prev_value = 0;
428*4d9fdb46SRobert Mustacchi size_t len;
429*4d9fdb46SRobert Mustacchi char *prefix_id = prefix + prefix_root_len;
430*4d9fdb46SRobert Mustacchi unsigned actual_array_count = 0;
431*4d9fdb46SRobert Mustacchi
432*4d9fdb46SRobert Mustacchi #ifdef TRACE_ARRAY
433*4d9fdb46SRobert Mustacchi printf("List before sorting:\n");
434*4d9fdb46SRobert Mustacchi PrintArray();
435*4d9fdb46SRobert Mustacchi #endif /* TRACE_ARRAY */
436*4d9fdb46SRobert Mustacchi
437*4d9fdb46SRobert Mustacchi /* Sort the array, because the values in 'libdwarf.h' are not in
438*4d9fdb46SRobert Mustacchi ascending order; if we use '-t' we must be sure the values are
439*4d9fdb46SRobert Mustacchi sorted, for the binary search to work properly.
440*4d9fdb46SRobert Mustacchi We want a stable sort, hence mergesort. */
441*4d9fdb46SRobert Mustacchi qsort((void *)&group_array,array_count,sizeof(array_data),(compfn)Compare);
442*4d9fdb46SRobert Mustacchi
443*4d9fdb46SRobert Mustacchi #ifdef TRACE_ARRAY
444*4d9fdb46SRobert Mustacchi printf("\nList after sorting:\n");
445*4d9fdb46SRobert Mustacchi PrintArray();
446*4d9fdb46SRobert Mustacchi #endif /* TRACE_ARRAY */
447*4d9fdb46SRobert Mustacchi
448*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_enum.h' */
449*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"\nenum Dwarf_%s_e {\n",prefix_id);
450*4d9fdb46SRobert Mustacchi
451*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_new.h' */
452*4d9fdb46SRobert Mustacchi fprintf(f_names_new_h,"int DWPREFIX(get_%s_name) (unsigned int, const char **);\n",prefix_id);
453*4d9fdb46SRobert Mustacchi
454*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.h' and libdwarf.h */
455*4d9fdb46SRobert Mustacchi fprintf(f_names_h,"extern int dwarf_get_%s_name(unsigned int /*val_in*/, const char ** /*s_out */);\n",prefix_id);
456*4d9fdb46SRobert Mustacchi
457*4d9fdb46SRobert Mustacchi /* Generate code for 'dwarf_names.c' */
458*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"/* ARGSUSED */\n");
459*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"int\n");
460*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"dwarf_get_%s_name (unsigned int val,const char ** s_out)\n",prefix_id);
461*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"{\n");
462*4d9fdb46SRobert Mustacchi if (use_tables) {
463*4d9fdb46SRobert Mustacchi fprintf(f_names_c," static Names_Data Dwarf_%s_n[] = {\n",prefix_id);
464*4d9fdb46SRobert Mustacchi } else {
465*4d9fdb46SRobert Mustacchi fprintf(f_names_c," switch (val) {\n");
466*4d9fdb46SRobert Mustacchi }
467*4d9fdb46SRobert Mustacchi
468*4d9fdb46SRobert Mustacchi for (u = 0; u < array_count; ++u) {
469*4d9fdb46SRobert Mustacchi /* Check if value already dumped */
470*4d9fdb46SRobert Mustacchi if (u > 0 && group_array[u].value == prev_value) {
471*4d9fdb46SRobert Mustacchi fprintf(f_names_c,
472*4d9fdb46SRobert Mustacchi " /* Skipping alternate spelling of value 0x%x. %s_%s */\n",
473*4d9fdb46SRobert Mustacchi (unsigned)prev_value,
474*4d9fdb46SRobert Mustacchi prefix,
475*4d9fdb46SRobert Mustacchi group_array[u].name);
476*4d9fdb46SRobert Mustacchi continue;
477*4d9fdb46SRobert Mustacchi }
478*4d9fdb46SRobert Mustacchi prev_value = group_array[u].value;
479*4d9fdb46SRobert Mustacchi
480*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names_enum.h'.
481*4d9fdb46SRobert Mustacchi The 39 just makes nice formatting in the output. */
482*4d9fdb46SRobert Mustacchi len = 39 - strlen(prefix);
483*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h," %s_%-*s = 0x%04x",
484*4d9fdb46SRobert Mustacchi prefix,(int)len,group_array[u].name,group_array[u].value);
485*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,(u + 1 < array_count) ? ",\n" : "\n");
486*4d9fdb46SRobert Mustacchi
487*4d9fdb46SRobert Mustacchi /* Generate entries for 'dwarf_names.c' */
488*4d9fdb46SRobert Mustacchi if (use_tables) {
489*4d9fdb46SRobert Mustacchi fprintf(f_names_c," {/* %3u */ \"%s_%s\", ",
490*4d9fdb46SRobert Mustacchi actual_array_count,prefix,group_array[u].name);
491*4d9fdb46SRobert Mustacchi fprintf(f_names_c," %s_%s}", prefix,group_array[u].name);
492*4d9fdb46SRobert Mustacchi fprintf(f_names_c,(u + 1 < array_count) ? ",\n" : "\n");
493*4d9fdb46SRobert Mustacchi } else {
494*4d9fdb46SRobert Mustacchi fprintf(f_names_c," case %s_%s:\n",
495*4d9fdb46SRobert Mustacchi prefix,group_array[u].name);
496*4d9fdb46SRobert Mustacchi fprintf(f_names_c," *s_out = \"%s_%s\";\n",
497*4d9fdb46SRobert Mustacchi prefix,group_array[u].name);
498*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return DW_DLV_OK;\n");
499*4d9fdb46SRobert Mustacchi }
500*4d9fdb46SRobert Mustacchi ++actual_array_count;
501*4d9fdb46SRobert Mustacchi }
502*4d9fdb46SRobert Mustacchi
503*4d9fdb46SRobert Mustacchi /* Closing entries for 'dwarf_names_enum.h' */
504*4d9fdb46SRobert Mustacchi fprintf(f_names_enum_h,"};\n");
505*4d9fdb46SRobert Mustacchi
506*4d9fdb46SRobert Mustacchi if (use_tables) {
507*4d9fdb46SRobert Mustacchi /* Closing entries for 'dwarf_names.c' */
508*4d9fdb46SRobert Mustacchi fprintf(f_names_c," };\n\n");
509*4d9fdb46SRobert Mustacchi
510*4d9fdb46SRobert Mustacchi /* Closing code for 'dwarf_names.c' */
511*4d9fdb46SRobert Mustacchi fprintf(f_names_c," const int last_entry = %d;\n",actual_array_count);
512*4d9fdb46SRobert Mustacchi fprintf(f_names_c," /* find the entry */\n");
513*4d9fdb46SRobert Mustacchi fprintf(f_names_c," int r = find_entry(Dwarf_%s_n,last_entry,val,s_out);\n",prefix_id);
514*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return r;\n");
515*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"}\n");
516*4d9fdb46SRobert Mustacchi } else {
517*4d9fdb46SRobert Mustacchi fprintf(f_names_c," }\n");
518*4d9fdb46SRobert Mustacchi fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n");
519*4d9fdb46SRobert Mustacchi fprintf(f_names_c,"}\n");
520*4d9fdb46SRobert Mustacchi }
521*4d9fdb46SRobert Mustacchi
522*4d9fdb46SRobert Mustacchi /* Mark the group_array as empty */
523*4d9fdb46SRobert Mustacchi array_count = 0;
524*4d9fdb46SRobert Mustacchi }
525*4d9fdb46SRobert Mustacchi
526*4d9fdb46SRobert Mustacchi /* Detect empty lines (and other lines we do not want to read) */
527*4d9fdb46SRobert Mustacchi static boolean
is_skippable_line(char * pLine)528*4d9fdb46SRobert Mustacchi is_skippable_line(char *pLine)
529*4d9fdb46SRobert Mustacchi {
530*4d9fdb46SRobert Mustacchi boolean empty = TRUE;
531*4d9fdb46SRobert Mustacchi
532*4d9fdb46SRobert Mustacchi for (; *pLine && empty; ++pLine) {
533*4d9fdb46SRobert Mustacchi empty = isspace(*pLine);
534*4d9fdb46SRobert Mustacchi }
535*4d9fdb46SRobert Mustacchi return empty;
536*4d9fdb46SRobert Mustacchi }
537*4d9fdb46SRobert Mustacchi
538*4d9fdb46SRobert Mustacchi static void
safe_strncpy(char * out,unsigned out_len,char * in,unsigned in_len)539*4d9fdb46SRobert Mustacchi safe_strncpy(char *out, unsigned out_len,
540*4d9fdb46SRobert Mustacchi char *in,unsigned in_len)
541*4d9fdb46SRobert Mustacchi {
542*4d9fdb46SRobert Mustacchi if(in_len >= out_len) {
543*4d9fdb46SRobert Mustacchi fprintf(stderr,"Impossible input line from dwarf.h. Giving up. \n");
544*4d9fdb46SRobert Mustacchi fprintf(stderr,"Length %u is too large, limited to %u.\n",
545*4d9fdb46SRobert Mustacchi in_len,out_len);
546*4d9fdb46SRobert Mustacchi exit(1);
547*4d9fdb46SRobert Mustacchi }
548*4d9fdb46SRobert Mustacchi strncpy(out,in,in_len);
549*4d9fdb46SRobert Mustacchi }
550*4d9fdb46SRobert Mustacchi
551*4d9fdb46SRobert Mustacchi
552*4d9fdb46SRobert Mustacchi /* Parse the 'dwarf.h' file and generate the tables */
553*4d9fdb46SRobert Mustacchi static void
ParseDefinitionsAndWriteOutput(void)554*4d9fdb46SRobert Mustacchi ParseDefinitionsAndWriteOutput(void)
555*4d9fdb46SRobert Mustacchi {
556*4d9fdb46SRobert Mustacchi char new_prefix[64];
557*4d9fdb46SRobert Mustacchi char *second_underscore = NULL;
558*4d9fdb46SRobert Mustacchi char type[1000];
559*4d9fdb46SRobert Mustacchi char name[1000];
560*4d9fdb46SRobert Mustacchi char value[1000];
561*4d9fdb46SRobert Mustacchi char extra[1000];
562*4d9fdb46SRobert Mustacchi char line_in[MAX_LINE_SIZE];
563*4d9fdb46SRobert Mustacchi int pending = FALSE;
564*4d9fdb46SRobert Mustacchi int prefix_len = 0;
565*4d9fdb46SRobert Mustacchi
566*4d9fdb46SRobert Mustacchi /* Process each line from 'dwarf.h' */
567*4d9fdb46SRobert Mustacchi while (!feof(f_dwarf_in)) {
568*4d9fdb46SRobert Mustacchi /* errno is cleared here so printing errno after
569*4d9fdb46SRobert Mustacchi the fgets is showing errno as set by fgets. */
570*4d9fdb46SRobert Mustacchi char *fgbad = 0;
571*4d9fdb46SRobert Mustacchi errno = 0;
572*4d9fdb46SRobert Mustacchi fgbad = fgets(line_in,sizeof(line_in),f_dwarf_in);
573*4d9fdb46SRobert Mustacchi if(!fgbad) {
574*4d9fdb46SRobert Mustacchi if(feof(f_dwarf_in)) {
575*4d9fdb46SRobert Mustacchi break;
576*4d9fdb46SRobert Mustacchi }
577*4d9fdb46SRobert Mustacchi /* Is error. errno must be set. */
578*4d9fdb46SRobert Mustacchi fprintf(stderr,"Error reading dwarf.h!. Errno %d\n",errno);
579*4d9fdb46SRobert Mustacchi exit(1);
580*4d9fdb46SRobert Mustacchi }
581*4d9fdb46SRobert Mustacchi if (is_skippable_line(line_in)) {
582*4d9fdb46SRobert Mustacchi continue;
583*4d9fdb46SRobert Mustacchi }
584*4d9fdb46SRobert Mustacchi sscanf(line_in,"%s %s %s %s",type,name,value,extra);
585*4d9fdb46SRobert Mustacchi if (strcmp(type,"#define") ||
586*4d9fdb46SRobert Mustacchi strncmp(name,prefix_root,prefix_root_len)) {
587*4d9fdb46SRobert Mustacchi continue;
588*4d9fdb46SRobert Mustacchi }
589*4d9fdb46SRobert Mustacchi
590*4d9fdb46SRobert Mustacchi second_underscore = strchr(name + prefix_root_len,'_');
591*4d9fdb46SRobert Mustacchi prefix_len = (int)(second_underscore - name);
592*4d9fdb46SRobert Mustacchi safe_strncpy(new_prefix,sizeof(new_prefix),name,prefix_len);
593*4d9fdb46SRobert Mustacchi new_prefix[prefix_len] = 0;
594*4d9fdb46SRobert Mustacchi
595*4d9fdb46SRobert Mustacchi /* Check for new prefix set */
596*4d9fdb46SRobert Mustacchi if (strcmp(prefix,new_prefix)) {
597*4d9fdb46SRobert Mustacchi if (pending) {
598*4d9fdb46SRobert Mustacchi /* Generate current prefix set */
599*4d9fdb46SRobert Mustacchi GenerateOneSet();
600*4d9fdb46SRobert Mustacchi }
601*4d9fdb46SRobert Mustacchi pending = TRUE;
602*4d9fdb46SRobert Mustacchi strcpy(prefix,new_prefix);
603*4d9fdb46SRobert Mustacchi }
604*4d9fdb46SRobert Mustacchi
605*4d9fdb46SRobert Mustacchi /* Be sure we have a valid entry */
606*4d9fdb46SRobert Mustacchi if (array_count >= ARRAY_SIZE) {
607*4d9fdb46SRobert Mustacchi printf("Too many entries for current group_array size of %d",ARRAY_SIZE);
608*4d9fdb46SRobert Mustacchi exit(1);
609*4d9fdb46SRobert Mustacchi }
610*4d9fdb46SRobert Mustacchi
611*4d9fdb46SRobert Mustacchi /* Move past the second underscore */
612*4d9fdb46SRobert Mustacchi ++second_underscore;
613*4d9fdb46SRobert Mustacchi
614*4d9fdb46SRobert Mustacchi {
615*4d9fdb46SRobert Mustacchi unsigned long v = strtoul(value,NULL,16);
616*4d9fdb46SRobert Mustacchi /* Some values are duplicated, that is ok.
617*4d9fdb46SRobert Mustacchi After the sort we will weed out the duplicate values,
618*4d9fdb46SRobert Mustacchi see GenerateOneSet(). */
619*4d9fdb46SRobert Mustacchi /* Record current entry */
620*4d9fdb46SRobert Mustacchi if (strlen(second_underscore) >= MAX_NAME_LEN) {
621*4d9fdb46SRobert Mustacchi printf("Too long a name %s for max len %d\n",
622*4d9fdb46SRobert Mustacchi second_underscore,MAX_NAME_LEN);
623*4d9fdb46SRobert Mustacchi exit(1);
624*4d9fdb46SRobert Mustacchi }
625*4d9fdb46SRobert Mustacchi strcpy(group_array[array_count].name,second_underscore);
626*4d9fdb46SRobert Mustacchi group_array[array_count].value = v;
627*4d9fdb46SRobert Mustacchi group_array[array_count].original_position = array_count;
628*4d9fdb46SRobert Mustacchi ++array_count;
629*4d9fdb46SRobert Mustacchi }
630*4d9fdb46SRobert Mustacchi }
631*4d9fdb46SRobert Mustacchi if (pending) {
632*4d9fdb46SRobert Mustacchi /* Generate final prefix set */
633*4d9fdb46SRobert Mustacchi GenerateOneSet();
634*4d9fdb46SRobert Mustacchi }
635*4d9fdb46SRobert Mustacchi }
636