@@ -4,10 +4,16 @@ All rights reserved.
44
55This software file is hereby placed in the public domain.
66For use by anyone for any purpose.
7+
8+ This code is not in libdwarf itself, it simply checks
9+ some information in dwarf.h and emits source file
10+ into the libdwarf source directory (which code
11+ gets compiled into libdwarf)
712*/
813
14+ #include <config.h> /* for PACKAGE_VERSION */
915#include <stdio.h> /* FILE fclose() fopen() fprintf() printf() */
10- #include <stdlib.h> /* exit() getenv() */
16+ #include <stdlib.h> /* exit() getenv() qsort() */
1117#include <string.h> /* strcmp() strcpy() strncmp() strlen() */
1218
1319#include "dwarf.h"
@@ -18,10 +24,13 @@ static char *input_name = 0;
1824static char pathbuf [BUFSIZ ];
1925static char buffer [BUFSIZ ];
2026
27+ /* This for the output into dwarf_lname_version.c */
28+ static char outpath [BUFSIZ ];
29+
2130#define FALSE 0
2231#define TRUE 1
2332
24- static unsigned tcount = sizeof (lnsix ) / sizeof (lnsix [0 ]);
33+ static unsigned int tcount = sizeof (lnsix ) / sizeof (lnsix [0 ]);
2534static unsigned int touchcounts [sizeof (lnsix ) / sizeof (lnsix [0 ])];
2635
2736static void
@@ -39,53 +48,53 @@ safe_strcpy(char *targ,char *src,unsigned targlen, unsigned srclen)
3948static void
4049validatetouchcount (char * curdefname ,unsigned long v )
4150{
42- if (v >= tcount ) {
43- printf ("ERROR: For LNAME id 0x%04lx there is "
44- "No count available, limit is %x. Something wrong!\n" ,
45- v ,tcount );
46- exit (EXIT_FAILURE );
47- }
48- if (touchcounts [v ]) {
49- printf ("ERROR: For LNAME id 0x%04lx we are double "
50- "counting at count 0x%x . Something wrong!\n" ,
51- v ,touchcounts [v ]);
52- exit (EXIT_FAILURE );
53- }
54- ++ touchcounts [v ];
55- if (lnsix [v ].ln_value != v ) {
56- printf ("ERROR: For LNAME id 0x%04lx not at the "
57- "correct entry vs "
58- " ln_value 0x%04x\n" ,
59- v ,lnsix [v ].ln_value );
60- exit (EXIT_FAILURE );
61- }
62- if (strcmp (curdefname ,lnsix [v ].ln_name )) {
63- printf ("ERROR: For LNAME id 0x%04lx we find the"
64- " wrong string! name %s lnsixname %s \n" ,
65- v , curdefname ,lnsix [v ].ln_name );
66- exit (EXIT_FAILURE );
67- }
51+ if (v >= tcount ) {
52+ printf ("ERROR: For LNAME id 0x%04lx there is "
53+ "No count available, limit is %x. Something wrong!\n" ,
54+ v ,tcount );
55+ exit (EXIT_FAILURE );
56+ }
57+ if (touchcounts [v ]) {
58+ printf ("ERROR: For LNAME id 0x%04lx we are double "
59+ "counting at count 0x%x . Something wrong!\n" ,
60+ v ,touchcounts [v ]);
61+ exit (EXIT_FAILURE );
62+ }
63+ ++ touchcounts [v ];
64+ if (lnsix [v ].ln_value != v ) {
65+ printf ("ERROR: For LNAME id 0x%04lx not at the "
66+ "correct entry vs "
67+ " ln_value 0x%04x\n" ,
68+ v ,lnsix [v ].ln_value );
69+ exit (EXIT_FAILURE );
70+ }
71+ if (strcmp (curdefname ,lnsix [v ].ln_name )) {
72+ printf ("ERROR: For LNAME id 0x%04lx we find the"
73+ " wrong string! name %s lnsixname %s \n" ,
74+ v , curdefname ,lnsix [v ].ln_name );
75+ exit (EXIT_FAILURE );
76+ }
6877}
78+
6979static void
70- validatefinaltouchcount ()
80+ validatefinaltouchcount (void )
7181{
72- unsigned long i = 1 ;
73- /* Skip [0], it is not real, just a placeholder.
74- 0 is not a valid LNAME id */
75- for ( ; i < tcount ; ++ i ) {
76- if (touchcounts [i ] != 1 ) {
77- printf (" ERROR: an entry in the LNAMES list "
78- " with DW_LNAME id 0x%04lx has touchcount"
79- " %u which indicates an error comparing "
80- " dwarf.h and the lnsix table here.\n" ,
81- i ,touchcounts [i ]);
82+ unsigned long i = 1 ;
83+ /* Skip [0], it is not real, just a placeholder.
84+ 0 is not a valid LNAME id */
85+ for ( ; i < tcount ; ++ i ) {
86+ if (touchcounts [i ] != 1 ) {
87+ printf (" ERROR: an entry in the LNAMES list "
88+ " with DW_LNAME id 0x%04lx has touchcount"
89+ " %u which indicates an error comparing "
90+ " dwarf.h and the lnsix table here.\n" ,
91+ i ,touchcounts [i ]);
8292 exit (EXIT_FAILURE );
83- }
84- }
93+ }
94+ }
8595}
8696
87-
88- /* Writes a complete new function
97+ /* Writes a complete new function
8998 int dwarf_language_version_data(..)
9099 in
91100 dwarf_lname_version.c
@@ -94,22 +103,173 @@ validatefinaltouchcount()
94103 that function.
95104
96105 We avoid anything in the new source file
97- representing date or time as we want
106+ representing date or time as we want
98107 re-running this (if no changes in dwarf_lname_data.h)
99108 outputs bit-for-bit identical dwarf_lname_version.c .
100109*/
101110
111+ #if 0 /* debug dump function */
112+ static void
113+ dump_table (void )
114+ {
115+ unsigned i = 0 ;
116+
117+ printf ("lnsix table\n" );
118+ for ( ; i < tcount ; ++ i ) {
119+ struct lnsix_s * e = & lnsix [i ];
120+ printf ("[ %2u] %-16s, %s,0x%04u,%u,%s;\n" ,
121+ i ,
122+ e -> ln_informal ,
123+ e -> ln_name ,
124+ e -> ln_value ,
125+ e -> ln_low_bound ,
126+ e -> ln_vscheme );
127+ }
128+ fflush (stdout );
129+ }
130+ #endif /* debug dump function */
131+
132+ static int
133+ qcompar (const void * lh_i ,const void * rh_i )
134+ {
135+ const struct lnsix_s * lh = 0 ;
136+ const struct lnsix_s * rh = 0 ;
137+ int res = 0 ;
138+ int res1 = 0 ;
139+ int res2 = 0 ;
140+
141+ lh = lh_i ;
142+ rh = rh_i ;
143+ res = strcmp (lh -> ln_vscheme ,rh -> ln_vscheme );
144+ if (res ) {
145+ return res ;
146+ }
147+ res1 = lh -> ln_low_bound - rh -> ln_low_bound ;
148+ if (res1 ) {
149+ return res1 ;
150+ }
151+ res2 = strcmp (lh -> ln_name ,rh -> ln_name );
152+ return res2 ;
153+ }
154+
155+ static int
156+ same_switch_part (struct lnsix_s * lh ,struct lnsix_s * rh ) {
157+ if (strcmp (lh -> ln_vscheme ,rh -> ln_vscheme )) {
158+ return FALSE;
159+ }
160+ if (lh -> ln_low_bound != rh -> ln_low_bound ) {
161+ return FALSE;
162+ }
163+ return TRUE;
164+ }
165+
166+ static void
167+ print_return_values (FILE * outfile ,struct lnsix_s * cur )
168+ {
169+ fprintf (outfile ," *dw_default_lower_bound = %u;\n" ,
170+ cur -> ln_low_bound );
171+ if (!strcmp (cur -> ln_vscheme ,"" )) {
172+ fprintf (outfile ," *dw_version_scheme = 0;\n" );
173+ } else {
174+ fprintf (outfile ," *dw_version_scheme = \"%s\";\n" ,
175+ cur -> ln_vscheme );
176+ }
177+ fprintf (outfile ,
178+ " return DW_DLV_OK;\n" );
179+ }
102180
181+ static struct lnsix_s zerosix ;
103182static void
104- write_new_query_function ( char * path )
183+ print_table_entries ( FILE * outfile )
105184{
106-
107- printf ("Query function not complete. %s\n" ,path );
185+ /* The zero entry is not relevant, a placeholder. */
186+ unsigned i = 1 ;
187+ signed int sublist_start = -1 ;
188+ struct lnsix_s sublist_entry ;
189+ struct lnsix_s * cur = 0 ;
190+ unsigned k = 0 ;
191+
192+ sublist_entry = zerosix ;
193+ for ( ;i < tcount ; ++ i ) {
194+ if (sublist_start < 0 ) {
195+ sublist_entry = lnsix [i ];
196+ sublist_start = i ;
197+ continue ;
198+ }
199+ cur = & lnsix [i ];
200+ if (same_switch_part (& sublist_entry ,cur )) {
201+ continue ;
202+ }
203+ /* now print switch cases */
204+ for (k = sublist_start ; k < i ; ++ k ) {
205+ fprintf (outfile ," case %s:\n" ,
206+ lnsix [k ].ln_name );
207+ }
208+ print_return_values (outfile ,& sublist_entry );
209+ sublist_start = i ;
210+ sublist_entry = lnsix [i ];
211+ }
212+ for (k = sublist_start ; k < i ; ++ k ) {
213+ fprintf (outfile ," case %s:\n" ,
214+ lnsix [k ].ln_name );
215+ }
216+ print_return_values (outfile ,& sublist_entry );
217+ fprintf (outfile ," default:\n" );
218+ fprintf (outfile ," break;\n" );
108219}
220+
221+ static void
222+ write_new_query_function (FILE * outfile )
223+ {
224+ qsort (& lnsix [0 ],tcount ,sizeof (struct lnsix_s ), qcompar );
225+ fprintf (outfile ,"/* Generated code, do not edit. */\n" );
226+ fprintf (outfile ,"/* Generated for source version %s */\n" ,
227+ PACKAGE_VERSION );
228+ fprintf (outfile , "\n" );
229+ fprintf (outfile , "#include \"dwarf.h\"\n" );
230+ fprintf (outfile , "#include \"libdwarf.h\"\n" );
231+
232+ fprintf (outfile , "int\n" );
233+ fprintf (outfile , "dwarf_language_version_data(\n" );
234+ fprintf (outfile , " Dwarf_Unsigned dw_lname,\n" );
235+ fprintf (outfile , " int *dw_default_lower_bound,\n" );
236+ fprintf (outfile , " const char **dw_version_scheme)\n" );
237+
238+ fprintf (outfile , "{\n" );
239+ fprintf (outfile , " switch(dw_lname) {\n" );
240+ print_table_entries (outfile );
241+ fprintf (outfile , " }\n" );
242+ fprintf (outfile , " return DW_DLV_NO_ENTRY;\n" );
243+ /* insert the details here. */
244+ fprintf (outfile , "}\n" );
245+ }
246+ static void
247+ setup_new_query_function (char * path )
248+ {
249+ FILE * outfile = 0 ;
250+ size_t pathlen = strlen (path );
251+ char * outsuffix = "/src/lib/libdwarf/dwarf_lname_version.c" ;
252+
253+ safe_strcpy (outpath ,path ,(unsigned )sizeof (outpath ),
254+ (unsigned )pathlen );
255+ safe_strcpy (outpath + pathlen ,outsuffix ,
256+ (unsigned )sizeof (outpath )- (unsigned )pathlen ,
257+ (unsigned )strlen (outsuffix ));
258+ outfile = fopen (outpath ,"w" );
259+ if (!outfile ) {
260+ printf ("ERROR building dwarf_lname_version.c FAILED."
261+ "Unable to open %s for output\n" ,outpath );
262+ exit (EXIT_FAILURE );
263+ }
264+ write_new_query_function (outfile );
265+ fclose (outfile );
266+ }
267+
109268/* Issue error message and exit there is a mismatch,
110- this should never fail.
269+ this should never fail.
111270 It verifies that dwarf.h DW_LNAME values match
112- exactly the LNAME values in dwarf_lname_data.h*/
271+ exactly the LNAME values in dwarf_lname_data.h */
272+
113273static void
114274check_if_lname_complete (char * path )
115275{
@@ -199,7 +359,7 @@ check_if_lname_complete(char *path)
199359 lastvalue = v ;
200360 validatetouchcount (curdefname ,v );
201361 continue ;
202- }
362+ }
203363 if (lastvalue == v ) {
204364 printf ("define line %u: DW_LNAME number value "
205365 " 0x%lx duplicated.\n" ,
@@ -254,7 +414,7 @@ int main(int argc, char**argv)
254414 exit (EXIT_FAILURE );
255415
256416 }
257- safe_strcpy (pathbuf ,path ,sizeof (pathbuf ),len );
417+ safe_strcpy (pathbuf ,path ,( unsigned ) sizeof (pathbuf ),( unsigned ) len );
258418 {
259419 size_t remaining = sizeof (pathbuf ) - len - 1 ;
260420 size_t tailpathlen = strlen (tailpath );
@@ -266,12 +426,12 @@ int main(int argc, char**argv)
266426 }
267427 /* Notice tailpath has a leading / */
268428 safe_strcpy (pathbuf + len ,(char * )tailpath ,
269- remaining ,tailpathlen );
429+ ( unsigned ) remaining ,( unsigned ) tailpathlen );
270430 }
271431 input_name = pathbuf ;
272432
273433 check_if_lname_complete (pathbuf );
274- write_new_query_function ( pathbuf );
434+ setup_new_query_function ( path );
275435
276436 return 0 ;
277437}
0 commit comments