~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/tools/apinames.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, 2009, 2010
 
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.1"
 
26
 
 
27
#define  LINEBUFF_SIZE  1024
 
28
 
 
29
typedef 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
 
 
36
} OutputFormat;
 
37
 
 
38
 
 
39
static void
 
40
panic( const char*  message )
 
41
{
 
42
  fprintf( stderr, "PANIC: %s\n", message );
 
43
  exit(2);
 
44
}
 
45
 
 
46
 
 
47
typedef struct  NameRec_
 
48
{
 
49
  char*         name;
 
50
  unsigned int  hash;
 
51
 
 
52
} NameRec, *Name;
 
53
 
 
54
static Name  the_names;
 
55
static int   num_names;
 
56
static int   max_names;
 
57
 
 
58
static void
 
59
names_add( const char*  name,
 
60
           const char*  end )
 
61
{
 
62
  int   nn, len, h;
 
63
  Name  nm;
 
64
 
 
65
  if ( end <= name )
 
66
    return;
 
67
 
 
68
  /* compute hash value */
 
69
  len = (int)(end - name);
 
70
  h   = 0;
 
71
  for ( nn = 0; nn < len; nn++ )
 
72
    h = h*33 + name[nn];
 
73
 
 
74
  /* check for an pre-existing name */
 
75
  for ( nn = 0; nn < num_names; nn++ )
 
76
  {
 
77
    nm = the_names + nn;
 
78
 
 
79
    if ( (int)nm->hash                 == h &&
 
80
         memcmp( name, nm->name, len ) == 0 &&
 
81
         nm->name[len]                 == 0 )
 
82
      return;
 
83
  }
 
84
 
 
85
  /* add new name */
 
86
  if ( num_names >= max_names )
 
87
  {
 
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" );
 
92
  }
 
93
  nm = &the_names[num_names++];
 
94
 
 
95
  nm->hash = h;
 
96
  nm->name = (char*)malloc( len+1 );
 
97
  if ( nm->name == NULL )
 
98
    panic( "not enough memory" );
 
99
 
 
100
  memcpy( nm->name, name, len );
 
101
  nm->name[len] = 0;
 
102
}
 
103
 
 
104
 
 
105
static int
 
106
name_compare( const void*  name1,
 
107
              const void*  name2 )
 
108
{
 
109
  Name  n1 = (Name)name1;
 
110
  Name  n2 = (Name)name2;
 
111
 
 
112
  return strcmp( n1->name, n2->name );
 
113
}
 
114
 
 
115
static void
 
116
names_sort( void )
 
117
{
 
118
  qsort( the_names, (size_t)num_names, sizeof(the_names[0]), name_compare );
 
119
}
 
120
 
 
121
 
 
122
static void
 
123
names_dump( FILE*         out,
 
124
            OutputFormat  format,
 
125
            const char*   dll_name )
 
126
{
 
127
  int  nn;
 
128
 
 
129
 
 
130
  switch ( format )
 
131
  {
 
132
    case OUTPUT_WINDOWS_DEF:
 
133
      if ( dll_name )
 
134
        fprintf( out, "LIBRARY %s\n", dll_name );
 
135
 
 
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 );
 
140
      break;
 
141
 
 
142
    case OUTPUT_BORLAND_DEF:
 
143
      if ( dll_name )
 
144
        fprintf( out, "LIBRARY %s\n", dll_name );
 
145
 
 
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 );
 
150
      break;
 
151
 
 
152
    case OUTPUT_WATCOM_LBC:
 
153
      {
 
154
        /* we must omit the .dll suffix from the library name */
 
155
        char         temp[512];
 
156
        const char*  dot;
 
157
 
 
158
 
 
159
        if ( dll_name == NULL )
 
160
        {
 
161
          fprintf( stderr,
 
162
                   "you must provide a DLL name with the -d option!\n" );
 
163
          exit( 4 );
 
164
        }
 
165
 
 
166
        dot = strchr( dll_name, '.' );
 
167
        if ( dot != NULL )
 
168
        {
 
169
          int  len = dot - dll_name;
 
170
 
 
171
 
 
172
          if ( len > (int)( sizeof( temp ) - 1 ) )
 
173
            len = sizeof ( temp ) - 1;
 
174
 
 
175
          memcpy( temp, dll_name, len );
 
176
          temp[len] = 0;
 
177
 
 
178
          dll_name = (const char*)temp;
 
179
        }
 
180
 
 
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 );
 
184
      }
 
185
      break;
 
186
 
 
187
    default:  /* LIST */
 
188
      for ( nn = 0; nn < num_names; nn++ )
 
189
        fprintf( out, "%s\n", the_names[nn].name );
 
190
  }
 
191
}
 
192
 
 
193
 
 
194
 
 
195
 
 
196
/* states of the line parser */
 
197
 
 
198
typedef enum  State_
 
199
{
 
200
  STATE_START = 0,  /* waiting for FT_EXPORT keyword and return type */
 
201
  STATE_TYPE        /* type was read, waiting for function name      */
 
202
 
 
203
} State;
 
204
 
 
205
static int
 
206
read_header_file( FILE*  file, int  verbose )
 
207
{
 
208
  static char  buff[ LINEBUFF_SIZE+1 ];
 
209
  State        state = STATE_START;
 
210
 
 
211
  while ( !feof( file ) )
 
212
  {
 
213
    char*  p;
 
214
 
 
215
    if ( !fgets( buff, LINEBUFF_SIZE, file ) )
 
216
      break;
 
217
 
 
218
    p = buff;
 
219
 
 
220
    while ( *p && (*p == ' ' || *p == '\\') )  /* skip leading whitespace */
 
221
      p++;
 
222
 
 
223
    if ( *p == '\n' || *p == '\r' )  /* skip empty lines */
 
224
      continue;
 
225
 
 
226
    switch ( state )
 
227
    {
 
228
      case STATE_START:
 
229
        {
 
230
          if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
 
231
            break;
 
232
 
 
233
          p += 10;
 
234
          for (;;)
 
235
          {
 
236
            if ( *p == 0 || *p == '\n' || *p == '\r' )
 
237
              goto NextLine;
 
238
 
 
239
            if ( *p == ')' )
 
240
            {
 
241
              p++;
 
242
              break;
 
243
            }
 
244
 
 
245
            p++;
 
246
          }
 
247
 
 
248
          state = STATE_TYPE;
 
249
 
 
250
         /* sometimes, the name is just after the FT_EXPORT(...), so
 
251
          * skip whitespace, and fall-through if we find an alphanumeric
 
252
          * character
 
253
          */
 
254
          while ( *p == ' ' || *p == '\t' )
 
255
            p++;
 
256
 
 
257
          if ( !isalpha(*p) )
 
258
            break;
 
259
        }
 
260
        /* fall-through */
 
261
 
 
262
      case STATE_TYPE:
 
263
        {
 
264
          char*   name = p;
 
265
 
 
266
          while ( isalnum(*p) || *p == '_' )
 
267
            p++;
 
268
 
 
269
          if ( p > name )
 
270
          {
 
271
            if ( verbose )
 
272
              fprintf( stderr, ">>> %.*s\n", (int)(p - name), name );
 
273
 
 
274
            names_add( name, p );
 
275
          }
 
276
 
 
277
          state = STATE_START;
 
278
        }
 
279
        break;
 
280
 
 
281
      default:
 
282
        ;
 
283
    }
 
284
 
 
285
  NextLine:
 
286
    ;
 
287
  }
 
288
 
 
289
  return 0;
 
290
}
 
291
 
 
292
 
 
293
static void
 
294
usage( void )
 
295
{
 
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"
 
301
 
 
302
   "usage: %s header1 [options] [header2 ...]\n\n"
 
303
 
 
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"
 
311
   "\n";
 
312
 
 
313
  fprintf( stderr,
 
314
           format,
 
315
           PROGRAM_NAME,
 
316
           PROGRAM_VERSION,
 
317
           PROGRAM_NAME
 
318
           );
 
319
  exit(1);
 
320
}
 
321
 
 
322
 
 
323
int  main( int argc, const char* const*  argv )
 
324
{
 
325
  int           from_stdin = 0;
 
326
  int           verbose = 0;
 
327
  OutputFormat  format = OUTPUT_LIST;  /* the default */
 
328
  FILE*         out    = stdout;
 
329
  const char*   library_name = NULL;
 
330
 
 
331
  if ( argc < 2 )
 
332
    usage();
 
333
 
 
334
  /* '-' used as a single argument means read source file from stdin */
 
335
  while ( argc > 1 && argv[1][0] == '-' )
 
336
  {
 
337
    const char*  arg = argv[1];
 
338
 
 
339
    switch ( arg[1] )
 
340
    {
 
341
      case 'v':
 
342
        verbose = 1;
 
343
        break;
 
344
 
 
345
      case 'o':
 
346
        if ( arg[2] == 0 )
 
347
        {
 
348
          if ( argc < 2 )
 
349
            usage();
 
350
 
 
351
          arg = argv[2];
 
352
          argv++;
 
353
          argc--;
 
354
        }
 
355
        else
 
356
          arg += 2;
 
357
 
 
358
        out = fopen( arg, "wt" );
 
359
        if ( out == NULL )
 
360
        {
 
361
          fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
 
362
          exit(3);
 
363
        }
 
364
        break;
 
365
 
 
366
      case 'd':
 
367
        if ( arg[2] == 0 )
 
368
        {
 
369
          if ( argc < 2 )
 
370
            usage();
 
371
 
 
372
          arg = argv[2];
 
373
          argv++;
 
374
          argc--;
 
375
        }
 
376
        else
 
377
          arg += 2;
 
378
 
 
379
        library_name = arg;
 
380
        break;
 
381
 
 
382
      case 'w':
 
383
        format = OUTPUT_WINDOWS_DEF;
 
384
        switch ( arg[2] )
 
385
        {
 
386
          case 'B':
 
387
            format = OUTPUT_BORLAND_DEF;
 
388
            break;
 
389
 
 
390
          case 'W':
 
391
            format = OUTPUT_WATCOM_LBC;
 
392
            break;
 
393
 
 
394
          case 0:
 
395
            break;
 
396
 
 
397
          default:
 
398
            usage();
 
399
        }
 
400
        break;
 
401
 
 
402
      case 0:
 
403
        from_stdin = 1;
 
404
        break;
 
405
 
 
406
      default:
 
407
        usage();
 
408
    }
 
409
 
 
410
    argc--;
 
411
    argv++;
 
412
  }
 
413
 
 
414
  if ( from_stdin )
 
415
  {
 
416
    read_header_file( stdin, verbose );
 
417
  }
 
418
  else
 
419
  {
 
420
    for ( --argc, argv++; argc > 0; argc--, argv++ )
 
421
    {
 
422
      FILE*  file = fopen( argv[0], "rb" );
 
423
 
 
424
      if ( file == NULL )
 
425
        fprintf( stderr, "unable to open '%s'\n", argv[0] );
 
426
      else
 
427
      {
 
428
        if ( verbose )
 
429
          fprintf( stderr, "opening '%s'\n", argv[0] );
 
430
 
 
431
        read_header_file( file, verbose );
 
432
        fclose( file );
 
433
      }
 
434
    }
 
435
  }
 
436
 
 
437
  if ( num_names == 0 )
 
438
    panic( "could not find exported functions !!\n" );
 
439
 
 
440
  names_sort();
 
441
  names_dump( out, format, library_name );
 
442
 
 
443
  if ( out != stdout )
 
444
    fclose( out );
 
445
 
 
446
  return 0;
 
447
}