Home | History | Annotate | Download | only in genren
      1 #!/usr/bin/perl 
      2 #*
      3 #*******************************************************************************
      4 #*   Copyright (C) 2001-2011, International Business Machines
      5 #*   Corporation and others.  All Rights Reserved.
      6 #*******************************************************************************
      7 #*
      8 #*   file name:  genren.pl
      9 #*   encoding:   US-ASCII
     10 #*   tab size:   8 (not used)
     11 #*   indentation:4
     12 #*
     13 #*   Created by: Vladimir Weinstein
     14 #*   07/19/2001
     15 #*
     16 #*  Used to generate renaming headers.
     17 #*  Run on UNIX platforms (linux) in order to catch all the exports
     18 
     19 use POSIX qw(strftime);
     20 
     21 $headername = 'urename.h';
     22 
     23 $path = substr($0, 0, rindex($0, "/")+1)."../../common/unicode/uversion.h";
     24 
     25 $nmopts = '-Cg -f s';
     26 $post = '';
     27 
     28 $mode = 'POSIX';
     29 
     30 (-e $path) || die "Cannot find uversion.h";
     31 
     32 open(UVERSION, $path);
     33 
     34 while(<UVERSION>) {
     35     if(/\#define U_ICU_VERSION_SUFFIX/) {
     36         chop;
     37         s/\#define U_ICU_VERSION_SUFFIX //;
     38         $U_ICU_VERSION_SUFFIX = "$_";
     39         last;
     40     }
     41 }
     42 
     43 while($ARGV[0] =~ /^-/) { # detects whether there are any arguments
     44     $_ = shift @ARGV;      # extracts the argument for processing
     45     /^-v/ && ($VERBOSE++, next);                      # verbose
     46     /^-h/ && (&printHelpMsgAndExit, next);               # help
     47     /^-o/ && (($headername = shift (@ARGV)), next);   # output file
     48     /^-n/ && (($nmopts = shift (@ARGV)), next);   # nm opts
     49     /^-p/ && (($post = shift (@ARGV)), next);   # nm opts
     50     /^-x/ && (($mode = shift (@ARGV)), next);   # nm opts
     51     /^-S/ && (($U_ICU_VERSION_SUFFIX = shift(@ARGV)), next); # pick the suffix
     52     warn("Invalid option $_\n");
     53     &printHelpMsgAndExit;
     54 }
     55 
     56 unless(@ARGV > 0) {
     57     warn "No libraries, exiting...\n";
     58     &printHelpMsgAndExit;
     59 }
     60 
     61 #$headername = "uren".substr($ARGV[0], 6, index(".", $ARGV[0])-7).".h";
     62     
     63 $HEADERDEF = uc($headername);  # this is building the constant for #define
     64 $HEADERDEF =~ s/\./_/;
     65 
     66     
     67     open HEADER, ">$headername"; # opening a header file
     68 
     69 #We will print our copyright here + warnings
     70 
     71 $YEAR = strftime "%Y",localtime;
     72 
     73 print HEADER <<"EndOfHeaderComment";
     74 /*
     75 *******************************************************************************
     76 *   Copyright (C) 2002-$YEAR, International Business Machines
     77 *   Corporation and others.  All Rights Reserved.
     78 *******************************************************************************
     79 *
     80 *   file name:  $headername
     81 *   encoding:   US-ASCII
     82 *   tab size:   8 (not used)
     83 *   indentation:4
     84 *
     85 *   Created by: Perl script written by Vladimir Weinstein
     86 *
     87 *  Contains data for renaming ICU exports.
     88 *  Gets included by umachine.h
     89 *
     90 *  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
     91 *  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
     92 */
     93 
     94 #ifndef $HEADERDEF
     95 #define $HEADERDEF
     96 
     97 /* Uncomment the following line to disable renaming on platforms
     98    that do not use Autoconf. */
     99 /* #define U_DISABLE_RENAMING 1 */
    100 
    101 #if !U_DISABLE_RENAMING
    102 
    103 /* We need the U_ICU_ENTRY_POINT_RENAME definition. There's a default one in unicode/uvernum.h we can use, but we will give
    104    the platform a chance to define it first.
    105    Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined.
    106  */
    107 #ifndef U_ICU_ENTRY_POINT_RENAME
    108 #include "unicode/umachine.h"
    109 #endif
    110 
    111 /* If we still don't have U_ICU_ENTRY_POINT_RENAME use the default. */
    112 #ifndef U_ICU_ENTRY_POINT_RENAME
    113 #include "unicode/uvernum.h"
    114 #endif
    115 
    116 /* Error out before the following defines cause very strange and unexpected code breakage */
    117 #ifndef U_ICU_ENTRY_POINT_RENAME
    118 #error U_ICU_ENTRY_POINT_RENAME is not defined - cannot continue. Consider defining U_DISABLE_RENAMING if renaming should not be used.
    119 #endif
    120 
    121 EndOfHeaderComment
    122 
    123 $fileCount = 0;
    124 $itemCount = 0;
    125 $symbolCount = 0;
    126 
    127 for(;@ARGV; shift(@ARGV)) {
    128     $fileCount++;
    129     @NMRESULT = `nm $nmopts $ARGV[0] $post`;
    130     if($?) {
    131         warn "Couldn't do 'nm' for $ARGV[0], continuing...\n";
    132         next; # Couldn't do nm for the file
    133     }
    134     if($mode =~ /POSIX/) {
    135         splice @NMRESULT, 0, 6;
    136     } elsif ($mode =~ /Mach-O/) {
    137 #        splice @NMRESULT, 0, 10;
    138     }
    139     foreach (@NMRESULT) { # Process every line of result and stuff it in $_
    140         $itemCount++;
    141         if($mode =~ /POSIX/) {
    142             &verbose("  $_");
    143             ($_, $address, $type) = split(/\|/);
    144             chop $qtype;
    145         } elsif ($mode =~ /Mach-O/) {
    146             if(/^(?:[0-9a-fA-F]){8} ([A-Z]) (?:_)?(.*)$/) {
    147                 ($_, $type) = ($2, $1);
    148             } else {
    149                 next;
    150             }
    151         } else {
    152             die "Unknown mode $mode";
    153         }
    154         &verbose( "type: \"$type\" ");
    155         if(!($type =~ /[UAwW?]/)) {
    156             if(/@@/) { # These would be imports
    157                 &verbose( "Import: $_ \"$type\"\n");
    158                 &verbose( "C++ method: $_\n");
    159             } elsif (/^[^\(]*::/) { # C++ methods, stuff class name in associative array
    160 	        ##  DON'T match    ...  (   foo::bar ...   want :: to be to the left of paren
    161                 ## icu::CharString::~CharString(void) -> CharString
    162                 @CppName = split(/::/); ## remove scope stuff
    163                 
    164                 if(@CppName>1) {
    165                     ## MessageFormat virtual table -> MessageFormat
    166                     if(! ($CppName[0] =~ /icu/ )) {
    167                         # *** WARNING Bad namespace (not 'icu') on ShoeSize::ShoeSize()
    168                         warn "*** WARNING Bad namespace (not 'icu') on $_\n";
    169                         next;
    170                     }
    171                     &verbose ( "(Chopping scope $CppName[0] )");
    172                     @CppName = split(/ /, $CppName[1]); ## remove debug stuff
    173                 }
    174                 ## ures_getUnicodeStringByIndex(UResourceBundle -> ures_getUnicodeStringByIndex
    175                 @CppName = split(/\(/, $CppName[0]); ## remove function args
    176                 if($CppName[0] =~ /^operator/) {
    177                     &verbose ("Skipping C++ function: $_\n");
    178                 } elsif($CppName[0] =~ /^~/) {
    179                     &verbose ("Skipping C++ destructor: $_\n");
    180                 } else {
    181 		    &verbose( " Class: '$CppName[0]': $_ \n");
    182                     $CppClasses{$CppName[0]}++;
    183 		    $symbolCount++;
    184                 }
    185 	    } elsif ( my ($cfn) = m/^([A-Za-z0-9_]*)\(.*/ ) {
    186 		&verbose ( "$ARGV[0]:  got global C++ function  $cfn with '$_'\n" );
    187                 $CFuncs{$cfn}++;
    188 		$symbolCount++;
    189             } elsif ( /\(/) { # These are strange functions
    190                 print STDERR "$ARGV[0]: Not sure what to do with '$_'\n";
    191 	    } elsif ( /^_init/ ) {
    192 		&verbose( "$ARGV[0]: Skipped initializer $_\n" );
    193 	    } elsif ( /^_fini/ ) {
    194 		&verbose( "$ARGV[0]: Skipped finilizer $_\n" );
    195             } elsif ( /icu_/) {
    196                 print STDERR "$ARGV[0]: Skipped strange mangled function $_\n";
    197             } elsif ( /^vtable for /) {
    198                 print STDERR "$ARGV[0]: Skipped vtable $_\n";
    199             } elsif ( /^typeinfo/) {
    200                 print STDERR "$ARGV[0]: Skipped typeinfo $_\n";
    201             } elsif ( /operator\+/ ) {
    202                 print STDERR "$ARGV[0]: Skipped ignored function $_\n";
    203             } else { # This is regular C function 
    204                 &verbose( "C func: $_\n");
    205                 @funcname = split(/[\(\s+]/);
    206                 $CFuncs{$funcname[0]}++;
    207 		$symbolCount++;
    208             }
    209         } else {
    210             &verbose( "Skipped: $_ $1\n");
    211         }
    212     }
    213 }
    214 
    215 if( $fileCount == 0 ) {
    216   die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n";
    217 }
    218 
    219 if( $symbolCount == 0 ) {
    220   die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n";
    221 }
    222 
    223 print " Loaded $symbolCount symbols from $itemCount lines in $fileCount files.\n";
    224 
    225 print HEADER "\n/* C exports renaming data */\n\n";
    226 foreach(sort keys(%CFuncs)) {
    227     print HEADER "#define $_ U_ICU_ENTRY_POINT_RENAME($_)\n";
    228 #    print HEADER "#define $_ $_$U_ICU_VERSION_SUFFIX\n";
    229 }
    230 
    231 print HEADER "\n\n";
    232 print HEADER "/* C++ class names renaming defines */\n\n";
    233 print HEADER "#ifdef XP_CPLUSPLUS\n";
    234 print HEADER "#if !U_HAVE_NAMESPACE\n\n";
    235 foreach(sort keys(%CppClasses)) {
    236     print HEADER "#define $_ U_ICU_ENTRY_POINT_RENAME($_)\n";
    237 }
    238 print HEADER "\n#endif\n";
    239 print HEADER "#endif\n";
    240 print HEADER "\n#endif\n";
    241 print HEADER "\n#endif\n";
    242 
    243 close HEADER;
    244 
    245 sub verbose {
    246     if($VERBOSE) {
    247         print STDERR @_;
    248     }
    249 }
    250 
    251 
    252 sub printHelpMsgAndExit {
    253     print STDERR <<"EndHelpText";
    254 Usage: $0 [OPTIONS] LIBRARY_FILES
    255   Options: 
    256     -v - verbose
    257     -h - help
    258     -o - output file name (defaults to 'urename.h'
    259     -S - suffix (defaults to _MAJOR_MINOR of current ICU version)
    260 Will produce a renaming .h file
    261 
    262 EndHelpText
    263 
    264     exit 0;
    265 
    266 }
    267 
    268