"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 */