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