"Fossies" - the Fresh Open Source Software Archive 
Member "SDL2_ttf-2.20.2/external/freetype/src/tools/apinames.c" (25 May 2022, 10796 Bytes) of package /linux/misc/SDL2_ttf-2.20.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "apinames.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * This little program is used to parse the FreeType headers and
3 * find the declaration of all public APIs. This is easy, because
4 * they all look like the following:
5 *
6 * FT_EXPORT( return_type )
7 * function_name( function arguments );
8 *
9 * You must pass the list of header files as arguments. Wildcards are
10 * accepted if you are using GCC for compilation (and probably by
11 * other compilers too).
12 *
13 * Author: FreeType team, 2005-2019
14 *
15 * This code is explicitly placed into the public domain.
16 *
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23
24 #define PROGRAM_NAME "apinames"
25 #define PROGRAM_VERSION "0.4"
26
27 #define LINEBUFF_SIZE 1024
28
29
30 typedef enum OutputFormat_
31 {
32 OUTPUT_LIST = 0, /* output the list of names, one per line */
33 OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */
34 OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */
35 OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */
36 OUTPUT_VMS_OPT, /* output an OpenVMS Linker Option File */
37 OUTPUT_NETWARE_IMP, /* output a NetWare ImportFile */
38 OUTPUT_GNU_VERMAP /* output a version map for GNU or Solaris linker */
39
40 } OutputFormat;
41
42
43 static void
44 panic( const char* message )
45 {
46 fprintf( stderr, "PANIC: %s\n", message );
47 exit(2);
48 }
49
50
51 typedef struct NameRec_
52 {
53 char* name;
54 unsigned int hash;
55
56 } NameRec, *Name;
57
58
59 static Name the_names;
60 static int num_names;
61 static int max_names;
62
63
64 static void
65 names_add( const char* name,
66 const char* end )
67 {
68 unsigned int h;
69 int nn, len;
70 Name nm;
71
72
73 if ( end <= name )
74 return;
75
76 /* compute hash value */
77 len = (int)( end - name );
78 h = 0;
79
80 for ( nn = 0; nn < len; nn++ )
81 h = h * 33 + name[nn];
82
83 /* check for an pre-existing name */
84 for ( nn = 0; nn < num_names; nn++ )
85 {
86 nm = the_names + nn;
87
88 if ( (int)nm->hash == h &&
89 memcmp( name, nm->name, len ) == 0 &&
90 nm->name[len] == 0 )
91 return;
92 }
93
94 /* add new name */
95 if ( num_names >= max_names )
96 {
97 max_names += ( max_names >> 1 ) + 4;
98 the_names = (NameRec*)realloc( the_names,
99 sizeof ( the_names[0] ) * max_names );
100 if ( !the_names )
101 panic( "not enough memory" );
102 }
103 nm = &the_names[num_names++];
104
105 nm->hash = h;
106 nm->name = (char*)malloc( len + 1 );
107 if ( !nm->name )
108 panic( "not enough memory" );
109
110 memcpy( nm->name, name, len );
111 nm->name[len] = 0;
112 }
113
114
115 static int
116 name_compare( const void* name1,
117 const void* name2 )
118 {
119 Name n1 = (Name)name1;
120 Name n2 = (Name)name2;
121
122 return strcmp( n1->name, n2->name );
123 }
124
125
126 static void
127 names_sort( void )
128 {
129 qsort( the_names, (size_t)num_names,
130 sizeof ( the_names[0] ), name_compare );
131 }
132
133
134 static void
135 names_dump( FILE* out,
136 OutputFormat format,
137 const char* dll_name )
138 {
139 int nn;
140
141
142 switch ( format )
143 {
144 case OUTPUT_WINDOWS_DEF:
145 if ( dll_name )
146 fprintf( out, "LIBRARY %s\n", dll_name );
147
148 fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
149 fprintf( out, "EXPORTS\n" );
150
151 for ( nn = 0; nn < num_names; nn++ )
152 fprintf( out, " %s\n", the_names[nn].name );
153
154 break;
155
156 case OUTPUT_BORLAND_DEF:
157 if ( dll_name )
158 fprintf( out, "LIBRARY %s\n", dll_name );
159
160 fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
161 fprintf( out, "EXPORTS\n" );
162
163 for ( nn = 0; nn < num_names; nn++ )
164 fprintf( out, " _%s\n", the_names[nn].name );
165
166 break;
167
168 case OUTPUT_WATCOM_LBC:
169 {
170 const char* dot;
171
172
173 if ( !dll_name )
174 {
175 fprintf( stderr,
176 "you must provide a DLL name with the -d option!\n" );
177 exit( 4 );
178 }
179
180 /* we must omit the `.dll' suffix from the library name */
181 dot = strchr( dll_name, '.' );
182 if ( dot )
183 {
184 char temp[512];
185 int len = dot - dll_name;
186
187
188 if ( len > (int)( sizeof ( temp ) - 1 ) )
189 len = sizeof ( temp ) - 1;
190
191 memcpy( temp, dll_name, len );
192 temp[len] = 0;
193
194 dll_name = (const char*)temp;
195 }
196
197 for ( nn = 0; nn < num_names; nn++ )
198 fprintf( out, "++_%s.%s.%s\n",
199 the_names[nn].name, dll_name, the_names[nn].name );
200 }
201
202 break;
203
204 case OUTPUT_VMS_OPT:
205 fprintf( out, "GSMATCH=LEQUAL,2,0\n"
206 "CASE_SENSITIVE=YES\n"
207 "SYMBOL_VECTOR=(-\n" );
208 for ( nn = 0; nn < num_names - 1; nn++ )
209 fprintf( out, " %s=PROCEDURE,-\n", the_names[nn].name );
210 fprintf( out, " %s=PROCEDURE)\n", the_names[num_names - 1].name );
211
212 break;
213
214 case OUTPUT_NETWARE_IMP:
215 if ( dll_name )
216 fprintf( out, " (%s)\n", dll_name );
217
218 for ( nn = 0; nn < num_names - 1; nn++ )
219 fprintf( out, " %s,\n", the_names[nn].name );
220 fprintf( out, " %s\n", the_names[num_names - 1].name );
221
222 break;
223
224 case OUTPUT_GNU_VERMAP:
225 fprintf( out, "{\n\tglobal:\n" );
226
227 for ( nn = 0; nn < num_names; nn++ )
228 fprintf( out, "\t\t%s;\n", the_names[nn].name );
229
230 fprintf( out, "\tlocal:\n\t\t*;\n};\n" );
231
232 break;
233
234 default: /* LIST */
235 for ( nn = 0; nn < num_names; nn++ )
236 fprintf( out, "%s\n", the_names[nn].name );
237
238 break;
239 }
240 }
241
242
243 /* states of the line parser */
244
245 typedef enum State_
246 {
247 STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */
248 STATE_TYPE /* type was read, waiting for function name */
249
250 } State;
251
252
253 static int
254 read_header_file( FILE* file,
255 int verbose )
256 {
257 static char buff[LINEBUFF_SIZE + 1];
258 State state = STATE_START;
259
260
261 while ( !feof( file ) )
262 {
263 char* p;
264
265
266 if ( !fgets( buff, LINEBUFF_SIZE, file ) )
267 break;
268
269 p = buff;
270
271 /* skip leading whitespace */
272 while ( *p && ( *p == ' ' || *p == '\\' ) )
273 p++;
274
275 /* skip empty lines */
276 if ( *p == '\n' || *p == '\r' )
277 continue;
278
279 switch ( state )
280 {
281 case STATE_START:
282 if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
283 break;
284
285 p += 10;
286 for (;;)
287 {
288 if ( *p == 0 || *p == '\n' || *p == '\r' )
289 goto NextLine;
290
291 if ( *p == ')' )
292 {
293 p++;
294 break;
295 }
296
297 p++;
298 }
299
300 state = STATE_TYPE;
301
302 /*
303 * Sometimes, the name is just after `FT_EXPORT(...)', so skip
304 * whitespace and fall-through if we find an alphanumeric character.
305 */
306 while ( *p == ' ' || *p == '\t' )
307 p++;
308
309 if ( !isalpha( *p ) )
310 break;
311
312 /* fall-through */
313
314 case STATE_TYPE:
315 {
316 char* name = p;
317
318
319 while ( isalnum( *p ) || *p == '_' )
320 p++;
321
322 if ( p > name )
323 {
324 if ( verbose )
325 fprintf( stderr, ">>> %.*s\n", (int)( p - name ), name );
326
327 names_add( name, p );
328 }
329
330 state = STATE_START;
331 }
332
333 break;
334
335 default:
336 ;
337 }
338
339 NextLine:
340 ;
341 } /* end of while loop */
342
343 return 0;
344 }
345
346
347 static void
348 usage( void )
349 {
350 static const char* const format =
351 "%s %s: extract FreeType API names from header files\n"
352 "\n"
353 "This program extracts the list of public FreeType API functions.\n"
354 "It receives a list of header files as an argument and\n"
355 "generates a sorted list of unique identifiers in various formats.\n"
356 "\n"
357 "usage: %s header1 [options] [header2 ...]\n"
358 "\n"
359 "options: - parse the contents of stdin, ignore arguments\n"
360 " -v verbose mode, output sent to standard error\n"
361 " -oFILE write output to FILE instead of standard output\n"
362 " -dNAME indicate DLL file name, 'freetype.dll' by default\n"
363 " -w output .DEF file for Visual C++ and Mingw\n"
364 " -wB output .DEF file for Borland C++\n"
365 " -wW output Watcom Linker Response File\n"
366 " -wV output OpenVMS Linker Options File\n"
367 " -wN output NetWare Import File\n"
368 " -wL output version map for GNU or Solaris linker\n"
369 "\n";
370
371 fprintf( stderr,
372 format,
373 PROGRAM_NAME,
374 PROGRAM_VERSION,
375 PROGRAM_NAME );
376
377 exit( 1 );
378 }
379
380
381 int
382 main( int argc,
383 const char* const* argv )
384 {
385 int from_stdin = 0;
386 int verbose = 0;
387 OutputFormat format = OUTPUT_LIST; /* the default */
388 FILE* out = stdout;
389 const char* library_name = NULL;
390
391
392 if ( argc < 2 )
393 usage();
394
395 /* `-' used as a single argument means read source file from stdin */
396 while ( argc > 1 && argv[1][0] == '-' )
397 {
398 const char* arg = argv[1];
399
400
401 switch ( arg[1] )
402 {
403 case 'v':
404 verbose = 1;
405
406 break;
407
408 case 'o':
409 if ( arg[2] == 0 )
410 {
411 if ( argc < 2 )
412 usage();
413
414 arg = argv[2];
415 argv++;
416 argc--;
417 }
418 else
419 arg += 2;
420
421 out = fopen( arg, "wt" );
422 if ( !out )
423 {
424 fprintf( stderr, "could not open '%s' for writing\n", arg );
425 exit( 3 );
426 }
427
428 break;
429
430 case 'd':
431 if ( arg[2] == 0 )
432 {
433 if ( argc < 2 )
434 usage();
435
436 arg = argv[2];
437 argv++;
438 argc--;
439 }
440 else
441 arg += 2;
442
443 library_name = arg;
444
445 break;
446
447 case 'w':
448 format = OUTPUT_WINDOWS_DEF;
449
450 switch ( arg[2] )
451 {
452 case 'B':
453 format = OUTPUT_BORLAND_DEF;
454 break;
455
456 case 'W':
457 format = OUTPUT_WATCOM_LBC;
458 break;
459
460 case 'V':
461 format = OUTPUT_VMS_OPT;
462 break;
463
464 case 'N':
465 format = OUTPUT_NETWARE_IMP;
466 break;
467
468 case 'L':
469 format = OUTPUT_GNU_VERMAP;
470 break;
471
472 case 0:
473 break;
474
475 default:
476 usage();
477 }
478
479 break;
480
481 case 0:
482 from_stdin = 1;
483
484 break;
485
486 default:
487 usage();
488 }
489
490 argc--;
491 argv++;
492
493 } /* end of while loop */
494
495 if ( from_stdin )
496 read_header_file( stdin, verbose );
497 else
498 {
499 for ( --argc, argv++; argc > 0; argc--, argv++ )
500 {
501 FILE* file = fopen( argv[0], "rb" );
502
503
504 if ( !file )
505 fprintf( stderr, "unable to open '%s'\n", argv[0] );
506 else
507 {
508 if ( verbose )
509 fprintf( stderr, "opening '%s'\n", argv[0] );
510
511 read_header_file( file, verbose );
512 fclose( file );
513 }
514 }
515 }
516
517 if ( num_names == 0 )
518 panic( "could not find exported functions\n" );
519
520 names_sort();
521 names_dump( out, format, library_name );
522
523 if ( out != stdout )
524 fclose( out );
525
526 return 0;
527 }
528
529
530 /* END */