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:
6
* FT_EXPORT( return_type )
7
* function_name( function arguments );
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).
13
* Author: David Turner, 2005, 2006, 2008, 2009, 2010
15
* This code is explicitly placed into the public domain.
24
#define PROGRAM_NAME "apinames"
25
#define PROGRAM_VERSION "0.1"
27
#define LINEBUFF_SIZE 1024
29
typedef enum OutputFormat_
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 */
40
panic( const char* message )
42
fprintf( stderr, "PANIC: %s\n", message );
47
typedef struct NameRec_
54
static Name the_names;
59
names_add( const char* name,
68
/* compute hash value */
69
len = (int)(end - name);
71
for ( nn = 0; nn < len; nn++ )
74
/* check for an pre-existing name */
75
for ( nn = 0; nn < num_names; nn++ )
79
if ( (int)nm->hash == h &&
80
memcmp( name, nm->name, len ) == 0 &&
86
if ( num_names >= max_names )
88
max_names += (max_names >> 1) + 4;
89
the_names = (NameRec*)realloc( the_names, sizeof(the_names[0])*max_names );
90
if ( the_names == NULL )
91
panic( "not enough memory" );
93
nm = &the_names[num_names++];
96
nm->name = (char*)malloc( len+1 );
97
if ( nm->name == NULL )
98
panic( "not enough memory" );
100
memcpy( nm->name, name, len );
106
name_compare( const void* name1,
109
Name n1 = (Name)name1;
110
Name n2 = (Name)name2;
112
return strcmp( n1->name, n2->name );
118
qsort( the_names, (size_t)num_names, sizeof(the_names[0]), name_compare );
123
names_dump( FILE* out,
125
const char* dll_name )
132
case OUTPUT_WINDOWS_DEF:
134
fprintf( out, "LIBRARY %s\n", dll_name );
136
fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
137
fprintf( out, "EXPORTS\n" );
138
for ( nn = 0; nn < num_names; nn++ )
139
fprintf( out, " %s\n", the_names[nn].name );
142
case OUTPUT_BORLAND_DEF:
144
fprintf( out, "LIBRARY %s\n", dll_name );
146
fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
147
fprintf( out, "EXPORTS\n" );
148
for ( nn = 0; nn < num_names; nn++ )
149
fprintf( out, " _%s\n", the_names[nn].name );
152
case OUTPUT_WATCOM_LBC:
154
/* we must omit the .dll suffix from the library name */
159
if ( dll_name == NULL )
162
"you must provide a DLL name with the -d option!\n" );
166
dot = strchr( dll_name, '.' );
169
int len = dot - dll_name;
172
if ( len > (int)( sizeof( temp ) - 1 ) )
173
len = sizeof ( temp ) - 1;
175
memcpy( temp, dll_name, len );
178
dll_name = (const char*)temp;
181
for ( nn = 0; nn < num_names; nn++ )
182
fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name,
183
the_names[nn].name );
188
for ( nn = 0; nn < num_names; nn++ )
189
fprintf( out, "%s\n", the_names[nn].name );
196
/* states of the line parser */
200
STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */
201
STATE_TYPE /* type was read, waiting for function name */
206
read_header_file( FILE* file, int verbose )
208
static char buff[ LINEBUFF_SIZE+1 ];
209
State state = STATE_START;
211
while ( !feof( file ) )
215
if ( !fgets( buff, LINEBUFF_SIZE, file ) )
220
while ( *p && (*p == ' ' || *p == '\\') ) /* skip leading whitespace */
223
if ( *p == '\n' || *p == '\r' ) /* skip empty lines */
230
if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
236
if ( *p == 0 || *p == '\n' || *p == '\r' )
250
/* sometimes, the name is just after the FT_EXPORT(...), so
251
* skip whitespace, and fall-through if we find an alphanumeric
254
while ( *p == ' ' || *p == '\t' )
266
while ( isalnum(*p) || *p == '_' )
272
fprintf( stderr, ">>> %.*s\n", (int)(p - name), name );
274
names_add( name, p );
296
static const char* const format =
297
"%s %s: extract FreeType API names from header files\n\n"
298
"this program is used to extract the list of public FreeType API\n"
299
"functions. It receives the list of header files as argument and\n"
300
"generates a sorted list of unique identifiers\n\n"
302
"usage: %s header1 [options] [header2 ...]\n\n"
304
"options: - : parse the content of stdin, ignore arguments\n"
305
" -v : verbose mode, output sent to standard error\n"
306
" -oFILE : write output to FILE instead of standard output\n"
307
" -dNAME : indicate DLL file name, 'freetype.dll' by default\n"
308
" -w : output .DEF file for Visual C++ and Mingw\n"
309
" -wB : output .DEF file for Borland C++\n"
310
" -wW : output Watcom Linker Response File\n"
323
int main( int argc, const char* const* argv )
327
OutputFormat format = OUTPUT_LIST; /* the default */
329
const char* library_name = NULL;
334
/* '-' used as a single argument means read source file from stdin */
335
while ( argc > 1 && argv[1][0] == '-' )
337
const char* arg = argv[1];
358
out = fopen( arg, "wt" );
361
fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
383
format = OUTPUT_WINDOWS_DEF;
387
format = OUTPUT_BORLAND_DEF;
391
format = OUTPUT_WATCOM_LBC;
416
read_header_file( stdin, verbose );
420
for ( --argc, argv++; argc > 0; argc--, argv++ )
422
FILE* file = fopen( argv[0], "rb" );
425
fprintf( stderr, "unable to open '%s'\n", argv[0] );
429
fprintf( stderr, "opening '%s'\n", argv[0] );
431
read_header_file( file, verbose );
437
if ( num_names == 0 )
438
panic( "could not find exported functions !!\n" );
441
names_dump( out, format, library_name );