ReactOS 0.4.15-dev-8413-gc1c91f2
apinames.c
Go to the documentation of this file.
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: David Turner, 2005, 2006, 2008-2013, 2015
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.2"
26
27#define LINEBUFF_SIZE 1024
28
29typedef enum OutputFormat_
30{
31 OUTPUT_LIST = 0, /* output the list of names, one per line */
32 OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */
33 OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */
34 OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */
35 OUTPUT_NETWARE_IMP /* output a NetWare ImportFile */
36
38
39
40static void
41panic( const char* message )
42{
43 fprintf( stderr, "PANIC: %s\n", message );
44 exit(2);
45}
46
47
48typedef struct NameRec_
49{
50 char* name;
51 unsigned int hash;
52
54
56static int num_names;
57static int max_names;
58
59static void
60names_add( const char* name,
61 const char* end )
62{
63 unsigned int h;
64 int nn, len;
65 Name nm;
66
67 if ( end <= name )
68 return;
69
70 /* compute hash value */
71 len = (int)(end - name);
72 h = 0;
73 for ( nn = 0; nn < len; nn++ )
74 h = h*33 + name[nn];
75
76 /* check for an pre-existing name */
77 for ( nn = 0; nn < num_names; nn++ )
78 {
79 nm = the_names + nn;
80
81 if ( (int)nm->hash == h &&
82 memcmp( name, nm->name, len ) == 0 &&
83 nm->name[len] == 0 )
84 return;
85 }
86
87 /* add new name */
88 if ( num_names >= max_names )
89 {
90 max_names += (max_names >> 1) + 4;
92 sizeof ( the_names[0] ) * max_names );
93 if ( !the_names )
94 panic( "not enough memory" );
95 }
96 nm = &the_names[num_names++];
97
98 nm->hash = h;
99 nm->name = (char*)malloc( len+1 );
100 if ( !nm->name )
101 panic( "not enough memory" );
102
103 memcpy( nm->name, name, len );
104 nm->name[len] = 0;
105}
106
107
108static int
109name_compare( const void* name1,
110 const void* name2 )
111{
112 Name n1 = (Name)name1;
113 Name n2 = (Name)name2;
114
115 return strcmp( n1->name, n2->name );
116}
117
118static void
120{
121 qsort( the_names, (size_t)num_names,
122 sizeof ( the_names[0] ), name_compare );
123}
124
125
126static void
129 const char* dll_name )
130{
131 int nn;
132
133
134 switch ( format )
135 {
137 if ( dll_name )
138 fprintf( out, "LIBRARY %s\n", dll_name );
139
140 fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
141 fprintf( out, "EXPORTS\n" );
142 for ( nn = 0; nn < num_names; nn++ )
143 fprintf( out, " %s\n", the_names[nn].name );
144 break;
145
147 if ( dll_name )
148 fprintf( out, "LIBRARY %s\n", dll_name );
149
150 fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
151 fprintf( out, "EXPORTS\n" );
152 for ( nn = 0; nn < num_names; nn++ )
153 fprintf( out, " _%s\n", the_names[nn].name );
154 break;
155
157 {
158 const char* dot;
159 char temp[512];
160
161
162 if ( !dll_name )
163 {
165 "you must provide a DLL name with the -d option!\n" );
166 exit( 4 );
167 }
168
169 /* we must omit the .dll suffix from the library name */
170 dot = strchr( dll_name, '.' );
171 if ( dot )
172 {
173 int len = dot - dll_name;
174
175
176 if ( len > (int)( sizeof ( temp ) - 1 ) )
177 len = sizeof ( temp ) - 1;
178
179 memcpy( temp, dll_name, len );
180 temp[len] = 0;
181
182 dll_name = (const char*)temp;
183 }
184
185 for ( nn = 0; nn < num_names; nn++ )
186 fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name,
187 the_names[nn].name );
188 }
189 break;
190
192 {
193 if ( dll_name )
194 fprintf( out, " (%s)\n", dll_name );
195 for ( nn = 0; nn < num_names - 1; nn++ )
196 fprintf( out, " %s,\n", the_names[nn].name );
197 fprintf( out, " %s\n", the_names[num_names - 1].name );
198 }
199 break;
200
201 default: /* LIST */
202 for ( nn = 0; nn < num_names; nn++ )
203 fprintf( out, "%s\n", the_names[nn].name );
204 }
205}
206
207
208
209
210/* states of the line parser */
211
212typedef enum State_
213{
214 STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */
215 STATE_TYPE /* type was read, waiting for function name */
216
218
219static int
221{
222 static char buff[LINEBUFF_SIZE + 1];
224
225 while ( !feof( file ) )
226 {
227 char* p;
228
229 if ( !fgets( buff, LINEBUFF_SIZE, file ) )
230 break;
231
232 p = buff;
233
234 while ( *p && (*p == ' ' || *p == '\\') ) /* skip leading whitespace */
235 p++;
236
237 if ( *p == '\n' || *p == '\r' ) /* skip empty lines */
238 continue;
239
240 switch ( state )
241 {
242 case STATE_START:
243 {
244 if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
245 break;
246
247 p += 10;
248 for (;;)
249 {
250 if ( *p == 0 || *p == '\n' || *p == '\r' )
251 goto NextLine;
252
253 if ( *p == ')' )
254 {
255 p++;
256 break;
257 }
258
259 p++;
260 }
261
263
264 /* sometimes, the name is just after the FT_EXPORT(...), so
265 * skip whitespace, and fall-through if we find an alphanumeric
266 * character
267 */
268 while ( *p == ' ' || *p == '\t' )
269 p++;
270
271 if ( !isalpha(*p) )
272 break;
273 }
274 /* fall-through */
275
276 case STATE_TYPE:
277 {
278 char* name = p;
279
280 while ( isalnum(*p) || *p == '_' )
281 p++;
282
283 if ( p > name )
284 {
285 if ( verbose )
286 fprintf( stderr, ">>> %.*s\n", (int)(p - name), name );
287
288 names_add( name, p );
289 }
290
292 }
293 break;
294
295 default:
296 ;
297 }
298
299 NextLine:
300 ;
301 }
302
303 return 0;
304}
305
306
307static void
308usage( void )
309{
310 static const char* const format =
311 "%s %s: extract FreeType API names from header files\n\n"
312 "this program is used to extract the list of public FreeType API\n"
313 "functions. It receives the list of header files as argument and\n"
314 "generates a sorted list of unique identifiers\n\n"
315
316 "usage: %s header1 [options] [header2 ...]\n\n"
317
318 "options: - : parse the content of stdin, ignore arguments\n"
319 " -v : verbose mode, output sent to standard error\n"
320 " -oFILE : write output to FILE instead of standard output\n"
321 " -dNAME : indicate DLL file name, 'freetype.dll' by default\n"
322 " -w : output .DEF file for Visual C++ and Mingw\n"
323 " -wB : output .DEF file for Borland C++\n"
324 " -wW : output Watcom Linker Response File\n"
325 " -wN : output NetWare Import File\n"
326 "\n";
327
329 format,
333 );
334 exit(1);
335}
336
337
338int main( int argc, const char* const* argv )
339{
340 int from_stdin = 0;
341 int verbose = 0;
342 OutputFormat format = OUTPUT_LIST; /* the default */
343 FILE* out = stdout;
344 const char* library_name = NULL;
345
346 if ( argc < 2 )
347 usage();
348
349 /* '-' used as a single argument means read source file from stdin */
350 while ( argc > 1 && argv[1][0] == '-' )
351 {
352 const char* arg = argv[1];
353
354 switch ( arg[1] )
355 {
356 case 'v':
357 verbose = 1;
358 break;
359
360 case 'o':
361 if ( arg[2] == 0 )
362 {
363 if ( argc < 2 )
364 usage();
365
366 arg = argv[2];
367 argv++;
368 argc--;
369 }
370 else
371 arg += 2;
372
373 out = fopen( arg, "wt" );
374 if ( !out )
375 {
376 fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
377 exit(3);
378 }
379 break;
380
381 case 'd':
382 if ( arg[2] == 0 )
383 {
384 if ( argc < 2 )
385 usage();
386
387 arg = argv[2];
388 argv++;
389 argc--;
390 }
391 else
392 arg += 2;
393
394 library_name = arg;
395 break;
396
397 case 'w':
399 switch ( arg[2] )
400 {
401 case 'B':
403 break;
404
405 case 'W':
407 break;
408
409 case 'N':
411 break;
412
413 case 0:
414 break;
415
416 default:
417 usage();
418 }
419 break;
420
421 case 0:
422 from_stdin = 1;
423 break;
424
425 default:
426 usage();
427 }
428
429 argc--;
430 argv++;
431 }
432
433 if ( from_stdin )
434 {
436 }
437 else
438 {
439 for ( --argc, argv++; argc > 0; argc--, argv++ )
440 {
441 FILE* file = fopen( argv[0], "rb" );
442
443 if ( !file )
444 fprintf( stderr, "unable to open '%s'\n", argv[0] );
445 else
446 {
447 if ( verbose )
448 fprintf( stderr, "opening '%s'\n", argv[0] );
449
451 fclose( file );
452 }
453 }
454 }
455
456 if ( num_names == 0 )
457 panic( "could not find exported functions !!\n" );
458
459 names_sort();
460 names_dump( out, format, library_name );
461
462 if ( out != stdout )
463 fclose( out );
464
465 return 0;
466}
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isalpha(c)
Definition: acclib.h:74
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static Name the_names
Definition: apinames.c:55
static void names_dump(FILE *out, OutputFormat format, const char *dll_name)
Definition: apinames.c:127
#define PROGRAM_VERSION
Definition: apinames.c:25
#define PROGRAM_NAME
Definition: apinames.c:24
static void names_sort(void)
Definition: apinames.c:119
static void panic(const char *message)
Definition: apinames.c:41
struct NameRec_ NameRec
static int name_compare(const void *name1, const void *name2)
Definition: apinames.c:109
static int read_header_file(FILE *file, int verbose)
Definition: apinames.c:220
State_
Definition: apinames.c:213
@ STATE_START
Definition: apinames.c:214
@ STATE_TYPE
Definition: apinames.c:215
#define LINEBUFF_SIZE
Definition: apinames.c:27
enum OutputFormat_ OutputFormat
static void names_add(const char *name, const char *end)
Definition: apinames.c:60
static int num_names
Definition: apinames.c:56
static void usage(void)
Definition: apinames.c:308
static int max_names
Definition: apinames.c:57
OutputFormat_
Definition: apinames.c:30
@ OUTPUT_WATCOM_LBC
Definition: apinames.c:34
@ OUTPUT_WINDOWS_DEF
Definition: apinames.c:32
@ OUTPUT_NETWARE_IMP
Definition: apinames.c:35
@ OUTPUT_LIST
Definition: apinames.c:31
@ OUTPUT_BORLAND_DEF
Definition: apinames.c:33
enum State_ State
struct NameRec_ * Name
Definition: cdprocs.h:460
static int state
Definition: maze.c:121
#define realloc
Definition: debug_ros.c:6
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
STATE_TYPE
Definition: effect.c:103
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
int main()
Definition: test.c:6
static unsigned char buff[32768]
Definition: fatten.c:17
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static WCHAR name1[]
Definition: record.c:34
static WCHAR name2[]
Definition: record.c:35
#define argv
Definition: mplay32.c:18
static FILE * out
Definition: regtests2xml.c:44
#define verbose
Definition: rosglue.h:36
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
static calc_node_t temp
Definition: rpn_ieee.c:38
#define exit(n)
Definition: config.h:202
BOOLEAN NextLine(PCHAR LineBuffer, ULONG BufferSize, FILE *File)
Definition: parser.c:230
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
char * name
Definition: apinames.c:50
unsigned int hash
Definition: apinames.c:51
Definition: fci.c:127
Definition: tftpd.h:60
Definition: name.c:39
void * arg
Definition: msvc.h:10