| Index: third_party/freetype2/src/src/tools/apinames.c
|
| diff --git a/third_party/freetype2/src/src/tools/apinames.c b/third_party/freetype2/src/src/tools/apinames.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9f81b1a6c72c4a0f64e720b361a34b9536631640
|
| --- /dev/null
|
| +++ b/third_party/freetype2/src/src/tools/apinames.c
|
| @@ -0,0 +1,466 @@
|
| +/*
|
| + * This little program is used to parse the FreeType headers and
|
| + * find the declaration of all public APIs. This is easy, because
|
| + * they all look like the following:
|
| + *
|
| + * FT_EXPORT( return_type )
|
| + * function_name( function arguments );
|
| + *
|
| + * You must pass the list of header files as arguments. Wildcards are
|
| + * accepted if you are using GCC for compilation (and probably by
|
| + * other compilers too).
|
| + *
|
| + * Author: David Turner, 2005, 2006, 2008-2013, 2015
|
| + *
|
| + * This code is explicitly placed into the public domain.
|
| + *
|
| + */
|
| +
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +#include <string.h>
|
| +#include <ctype.h>
|
| +
|
| +#define PROGRAM_NAME "apinames"
|
| +#define PROGRAM_VERSION "0.2"
|
| +
|
| +#define LINEBUFF_SIZE 1024
|
| +
|
| +typedef enum OutputFormat_
|
| +{
|
| + OUTPUT_LIST = 0, /* output the list of names, one per line */
|
| + OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */
|
| + OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */
|
| + OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */
|
| + OUTPUT_NETWARE_IMP /* output a NetWare ImportFile */
|
| +
|
| +} OutputFormat;
|
| +
|
| +
|
| +static void
|
| +panic( const char* message )
|
| +{
|
| + fprintf( stderr, "PANIC: %s\n", message );
|
| + exit(2);
|
| +}
|
| +
|
| +
|
| +typedef struct NameRec_
|
| +{
|
| + char* name;
|
| + unsigned int hash;
|
| +
|
| +} NameRec, *Name;
|
| +
|
| +static Name the_names;
|
| +static int num_names;
|
| +static int max_names;
|
| +
|
| +static void
|
| +names_add( const char* name,
|
| + const char* end )
|
| +{
|
| + unsigned int h;
|
| + int nn, len;
|
| + Name nm;
|
| +
|
| + if ( end <= name )
|
| + return;
|
| +
|
| + /* compute hash value */
|
| + len = (int)(end - name);
|
| + h = 0;
|
| + for ( nn = 0; nn < len; nn++ )
|
| + h = h*33 + name[nn];
|
| +
|
| + /* check for an pre-existing name */
|
| + for ( nn = 0; nn < num_names; nn++ )
|
| + {
|
| + nm = the_names + nn;
|
| +
|
| + if ( (int)nm->hash == h &&
|
| + memcmp( name, nm->name, len ) == 0 &&
|
| + nm->name[len] == 0 )
|
| + return;
|
| + }
|
| +
|
| + /* add new name */
|
| + if ( num_names >= max_names )
|
| + {
|
| + max_names += (max_names >> 1) + 4;
|
| + the_names = (NameRec*)realloc( the_names,
|
| + sizeof ( the_names[0] ) * max_names );
|
| + if ( the_names == NULL )
|
| + panic( "not enough memory" );
|
| + }
|
| + nm = &the_names[num_names++];
|
| +
|
| + nm->hash = h;
|
| + nm->name = (char*)malloc( len+1 );
|
| + if ( nm->name == NULL )
|
| + panic( "not enough memory" );
|
| +
|
| + memcpy( nm->name, name, len );
|
| + nm->name[len] = 0;
|
| +}
|
| +
|
| +
|
| +static int
|
| +name_compare( const void* name1,
|
| + const void* name2 )
|
| +{
|
| + Name n1 = (Name)name1;
|
| + Name n2 = (Name)name2;
|
| +
|
| + return strcmp( n1->name, n2->name );
|
| +}
|
| +
|
| +static void
|
| +names_sort( void )
|
| +{
|
| + qsort( the_names, (size_t)num_names,
|
| + sizeof ( the_names[0] ), name_compare );
|
| +}
|
| +
|
| +
|
| +static void
|
| +names_dump( FILE* out,
|
| + OutputFormat format,
|
| + const char* dll_name )
|
| +{
|
| + int nn;
|
| +
|
| +
|
| + switch ( format )
|
| + {
|
| + case OUTPUT_WINDOWS_DEF:
|
| + if ( dll_name )
|
| + fprintf( out, "LIBRARY %s\n", dll_name );
|
| +
|
| + fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
|
| + fprintf( out, "EXPORTS\n" );
|
| + for ( nn = 0; nn < num_names; nn++ )
|
| + fprintf( out, " %s\n", the_names[nn].name );
|
| + break;
|
| +
|
| + case OUTPUT_BORLAND_DEF:
|
| + if ( dll_name )
|
| + fprintf( out, "LIBRARY %s\n", dll_name );
|
| +
|
| + fprintf( out, "DESCRIPTION FreeType 2 DLL\n" );
|
| + fprintf( out, "EXPORTS\n" );
|
| + for ( nn = 0; nn < num_names; nn++ )
|
| + fprintf( out, " _%s\n", the_names[nn].name );
|
| + break;
|
| +
|
| + case OUTPUT_WATCOM_LBC:
|
| + {
|
| + const char* dot;
|
| + char temp[512];
|
| +
|
| +
|
| + if ( dll_name == NULL )
|
| + {
|
| + fprintf( stderr,
|
| + "you must provide a DLL name with the -d option!\n" );
|
| + exit( 4 );
|
| + }
|
| +
|
| + /* we must omit the .dll suffix from the library name */
|
| + dot = strchr( dll_name, '.' );
|
| + if ( dot != NULL )
|
| + {
|
| + int len = dot - dll_name;
|
| +
|
| +
|
| + if ( len > (int)( sizeof ( temp ) - 1 ) )
|
| + len = sizeof ( temp ) - 1;
|
| +
|
| + memcpy( temp, dll_name, len );
|
| + temp[len] = 0;
|
| +
|
| + dll_name = (const char*)temp;
|
| + }
|
| +
|
| + for ( nn = 0; nn < num_names; nn++ )
|
| + fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name,
|
| + the_names[nn].name );
|
| + }
|
| + break;
|
| +
|
| + case OUTPUT_NETWARE_IMP:
|
| + {
|
| + if ( dll_name != NULL )
|
| + fprintf( out, " (%s)\n", dll_name );
|
| + for ( nn = 0; nn < num_names - 1; nn++ )
|
| + fprintf( out, " %s,\n", the_names[nn].name );
|
| + fprintf( out, " %s\n", the_names[num_names - 1].name );
|
| + }
|
| + break;
|
| +
|
| + default: /* LIST */
|
| + for ( nn = 0; nn < num_names; nn++ )
|
| + fprintf( out, "%s\n", the_names[nn].name );
|
| + }
|
| +}
|
| +
|
| +
|
| +
|
| +
|
| +/* states of the line parser */
|
| +
|
| +typedef enum State_
|
| +{
|
| + STATE_START = 0, /* waiting for FT_EXPORT keyword and return type */
|
| + STATE_TYPE /* type was read, waiting for function name */
|
| +
|
| +} State;
|
| +
|
| +static int
|
| +read_header_file( FILE* file, int verbose )
|
| +{
|
| + static char buff[LINEBUFF_SIZE + 1];
|
| + State state = STATE_START;
|
| +
|
| + while ( !feof( file ) )
|
| + {
|
| + char* p;
|
| +
|
| + if ( !fgets( buff, LINEBUFF_SIZE, file ) )
|
| + break;
|
| +
|
| + p = buff;
|
| +
|
| + while ( *p && (*p == ' ' || *p == '\\') ) /* skip leading whitespace */
|
| + p++;
|
| +
|
| + if ( *p == '\n' || *p == '\r' ) /* skip empty lines */
|
| + continue;
|
| +
|
| + switch ( state )
|
| + {
|
| + case STATE_START:
|
| + {
|
| + if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
|
| + break;
|
| +
|
| + p += 10;
|
| + for (;;)
|
| + {
|
| + if ( *p == 0 || *p == '\n' || *p == '\r' )
|
| + goto NextLine;
|
| +
|
| + if ( *p == ')' )
|
| + {
|
| + p++;
|
| + break;
|
| + }
|
| +
|
| + p++;
|
| + }
|
| +
|
| + state = STATE_TYPE;
|
| +
|
| + /* sometimes, the name is just after the FT_EXPORT(...), so
|
| + * skip whitespace, and fall-through if we find an alphanumeric
|
| + * character
|
| + */
|
| + while ( *p == ' ' || *p == '\t' )
|
| + p++;
|
| +
|
| + if ( !isalpha(*p) )
|
| + break;
|
| + }
|
| + /* fall-through */
|
| +
|
| + case STATE_TYPE:
|
| + {
|
| + char* name = p;
|
| +
|
| + while ( isalnum(*p) || *p == '_' )
|
| + p++;
|
| +
|
| + if ( p > name )
|
| + {
|
| + if ( verbose )
|
| + fprintf( stderr, ">>> %.*s\n", (int)(p - name), name );
|
| +
|
| + names_add( name, p );
|
| + }
|
| +
|
| + state = STATE_START;
|
| + }
|
| + break;
|
| +
|
| + default:
|
| + ;
|
| + }
|
| +
|
| + NextLine:
|
| + ;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +static void
|
| +usage( void )
|
| +{
|
| + static const char* const format =
|
| + "%s %s: extract FreeType API names from header files\n\n"
|
| + "this program is used to extract the list of public FreeType API\n"
|
| + "functions. It receives the list of header files as argument and\n"
|
| + "generates a sorted list of unique identifiers\n\n"
|
| +
|
| + "usage: %s header1 [options] [header2 ...]\n\n"
|
| +
|
| + "options: - : parse the content of stdin, ignore arguments\n"
|
| + " -v : verbose mode, output sent to standard error\n"
|
| + " -oFILE : write output to FILE instead of standard output\n"
|
| + " -dNAME : indicate DLL file name, 'freetype.dll' by default\n"
|
| + " -w : output .DEF file for Visual C++ and Mingw\n"
|
| + " -wB : output .DEF file for Borland C++\n"
|
| + " -wW : output Watcom Linker Response File\n"
|
| + " -wN : output NetWare Import File\n"
|
| + "\n";
|
| +
|
| + fprintf( stderr,
|
| + format,
|
| + PROGRAM_NAME,
|
| + PROGRAM_VERSION,
|
| + PROGRAM_NAME
|
| + );
|
| + exit(1);
|
| +}
|
| +
|
| +
|
| +int main( int argc, const char* const* argv )
|
| +{
|
| + int from_stdin = 0;
|
| + int verbose = 0;
|
| + OutputFormat format = OUTPUT_LIST; /* the default */
|
| + FILE* out = stdout;
|
| + const char* library_name = NULL;
|
| +
|
| + if ( argc < 2 )
|
| + usage();
|
| +
|
| + /* '-' used as a single argument means read source file from stdin */
|
| + while ( argc > 1 && argv[1][0] == '-' )
|
| + {
|
| + const char* arg = argv[1];
|
| +
|
| + switch ( arg[1] )
|
| + {
|
| + case 'v':
|
| + verbose = 1;
|
| + break;
|
| +
|
| + case 'o':
|
| + if ( arg[2] == 0 )
|
| + {
|
| + if ( argc < 2 )
|
| + usage();
|
| +
|
| + arg = argv[2];
|
| + argv++;
|
| + argc--;
|
| + }
|
| + else
|
| + arg += 2;
|
| +
|
| + out = fopen( arg, "wt" );
|
| + if ( out == NULL )
|
| + {
|
| + fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
|
| + exit(3);
|
| + }
|
| + break;
|
| +
|
| + case 'd':
|
| + if ( arg[2] == 0 )
|
| + {
|
| + if ( argc < 2 )
|
| + usage();
|
| +
|
| + arg = argv[2];
|
| + argv++;
|
| + argc--;
|
| + }
|
| + else
|
| + arg += 2;
|
| +
|
| + library_name = arg;
|
| + break;
|
| +
|
| + case 'w':
|
| + format = OUTPUT_WINDOWS_DEF;
|
| + switch ( arg[2] )
|
| + {
|
| + case 'B':
|
| + format = OUTPUT_BORLAND_DEF;
|
| + break;
|
| +
|
| + case 'W':
|
| + format = OUTPUT_WATCOM_LBC;
|
| + break;
|
| +
|
| + case 'N':
|
| + format = OUTPUT_NETWARE_IMP;
|
| + break;
|
| +
|
| + case 0:
|
| + break;
|
| +
|
| + default:
|
| + usage();
|
| + }
|
| + break;
|
| +
|
| + case 0:
|
| + from_stdin = 1;
|
| + break;
|
| +
|
| + default:
|
| + usage();
|
| + }
|
| +
|
| + argc--;
|
| + argv++;
|
| + }
|
| +
|
| + if ( from_stdin )
|
| + {
|
| + read_header_file( stdin, verbose );
|
| + }
|
| + else
|
| + {
|
| + for ( --argc, argv++; argc > 0; argc--, argv++ )
|
| + {
|
| + FILE* file = fopen( argv[0], "rb" );
|
| +
|
| + if ( file == NULL )
|
| + fprintf( stderr, "unable to open '%s'\n", argv[0] );
|
| + else
|
| + {
|
| + if ( verbose )
|
| + fprintf( stderr, "opening '%s'\n", argv[0] );
|
| +
|
| + read_header_file( file, verbose );
|
| + fclose( file );
|
| + }
|
| + }
|
| + }
|
| +
|
| + if ( num_names == 0 )
|
| + panic( "could not find exported functions !!\n" );
|
| +
|
| + names_sort();
|
| + names_dump( out, format, library_name );
|
| +
|
| + if ( out != stdout )
|
| + fclose( out );
|
| +
|
| + return 0;
|
| +}
|
|
|