michael@0: #!/usr/bin/perl michael@0: #* michael@0: #******************************************************************************* michael@0: #* Copyright (C) 2001-2012, International Business Machines michael@0: #* Corporation and others. All Rights Reserved. michael@0: #******************************************************************************* michael@0: #* michael@0: #* file name: genren.pl michael@0: #* encoding: US-ASCII michael@0: #* tab size: 8 (not used) michael@0: #* indentation:4 michael@0: #* michael@0: #* Created by: Vladimir Weinstein michael@0: #* 07/19/2001 michael@0: #* michael@0: #* Used to generate renaming headers. michael@0: #* Run on UNIX platforms (linux) in order to catch all the exports michael@0: michael@0: use POSIX qw(strftime); michael@0: michael@0: $headername = 'urename.h'; michael@0: michael@0: $path = substr($0, 0, rindex($0, "/")+1)."../../common/unicode/uversion.h"; michael@0: michael@0: $nmopts = '-Cg -f s'; michael@0: $post = ''; michael@0: michael@0: $mode = 'POSIX'; michael@0: michael@0: (-e $path) || die "Cannot find uversion.h"; michael@0: michael@0: open(UVERSION, $path); michael@0: michael@0: while() { michael@0: if(/\#define U_ICU_VERSION_SUFFIX/) { michael@0: chop; michael@0: s/\#define U_ICU_VERSION_SUFFIX //; michael@0: $U_ICU_VERSION_SUFFIX = "$_"; michael@0: last; michael@0: } michael@0: } michael@0: michael@0: while($ARGV[0] =~ /^-/) { # detects whether there are any arguments michael@0: $_ = shift @ARGV; # extracts the argument for processing michael@0: /^-v/ && ($VERBOSE++, next); # verbose michael@0: /^-h/ && (&printHelpMsgAndExit, next); # help michael@0: /^-o/ && (($headername = shift (@ARGV)), next); # output file michael@0: /^-n/ && (($nmopts = shift (@ARGV)), next); # nm opts michael@0: /^-p/ && (($post = shift (@ARGV)), next); # nm opts michael@0: /^-x/ && (($mode = shift (@ARGV)), next); # nm opts michael@0: /^-S/ && (($U_ICU_VERSION_SUFFIX = shift(@ARGV)), next); # pick the suffix michael@0: warn("Invalid option $_\n"); michael@0: &printHelpMsgAndExit; michael@0: } michael@0: michael@0: unless(@ARGV > 0) { michael@0: warn "No libraries, exiting...\n"; michael@0: &printHelpMsgAndExit; michael@0: } michael@0: michael@0: #$headername = "uren".substr($ARGV[0], 6, index(".", $ARGV[0])-7).".h"; michael@0: michael@0: $HEADERDEF = uc($headername); # this is building the constant for #define michael@0: $HEADERDEF =~ s/\./_/; michael@0: michael@0: michael@0: open HEADER, ">$headername"; # opening a header file michael@0: michael@0: #We will print our copyright here + warnings michael@0: michael@0: $YEAR = strftime "%Y",localtime; michael@0: michael@0: print HEADER <<"EndOfHeaderComment"; michael@0: /* michael@0: ******************************************************************************* michael@0: * Copyright (C) 2002-$YEAR, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ******************************************************************************* michael@0: * michael@0: * file name: $headername michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * Created by: Perl script tools/genren.pl written by Vladimir Weinstein michael@0: * michael@0: * Contains data for renaming ICU exports. michael@0: * Gets included by umachine.h michael@0: * michael@0: * THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT michael@0: * YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! michael@0: */ michael@0: michael@0: #ifndef $HEADERDEF michael@0: #define $HEADERDEF michael@0: michael@0: /* U_DISABLE_RENAMING can be defined in the following ways: michael@0: * - when running configure, e.g. michael@0: * runConfigureICU Linux --disable-renaming michael@0: * - by changing the default setting of U_DISABLE_RENAMING in uconfig.h michael@0: */ michael@0: michael@0: #include "unicode/uconfig.h" michael@0: michael@0: #if !U_DISABLE_RENAMING michael@0: michael@0: /* 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 michael@0: the platform a chance to define it first. michael@0: Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined. michael@0: */ michael@0: michael@0: #ifndef U_ICU_ENTRY_POINT_RENAME michael@0: #include "unicode/umachine.h" michael@0: #endif michael@0: michael@0: /* If we still don't have U_ICU_ENTRY_POINT_RENAME use the default. */ michael@0: #ifndef U_ICU_ENTRY_POINT_RENAME michael@0: #include "unicode/uvernum.h" michael@0: #endif michael@0: michael@0: /* Error out before the following defines cause very strange and unexpected code breakage */ michael@0: #ifndef U_ICU_ENTRY_POINT_RENAME michael@0: #error U_ICU_ENTRY_POINT_RENAME is not defined - cannot continue. Consider defining U_DISABLE_RENAMING if renaming should not be used. michael@0: #endif michael@0: michael@0: EndOfHeaderComment michael@0: michael@0: $fileCount = 0; michael@0: $itemCount = 0; michael@0: $symbolCount = 0; michael@0: michael@0: for(;@ARGV; shift(@ARGV)) { michael@0: $fileCount++; michael@0: @NMRESULT = `nm $nmopts $ARGV[0] $post`; michael@0: if($?) { michael@0: warn "Couldn't do 'nm' for $ARGV[0], continuing...\n"; michael@0: next; # Couldn't do nm for the file michael@0: } michael@0: if($mode =~ /POSIX/) { michael@0: splice @NMRESULT, 0, 6; michael@0: } elsif ($mode =~ /Mach-O/) { michael@0: # splice @NMRESULT, 0, 10; michael@0: } michael@0: foreach (@NMRESULT) { # Process every line of result and stuff it in $_ michael@0: $itemCount++; michael@0: if($mode =~ /POSIX/) { michael@0: &verbose(" $_"); michael@0: ($_, $address, $type) = split(/\|/); michael@0: chop $qtype; michael@0: } elsif ($mode =~ /Mach-O/) { michael@0: ($address, $type, $_) = split(/ /); michael@0: if(/^_(.*)$/) { michael@0: $_ = $1; michael@0: } else { michael@0: next; michael@0: } michael@0: } else { michael@0: die "Unknown mode $mode"; michael@0: } michael@0: &verbose( "type: \"$type\" "); michael@0: if(!($type =~ /[UAwW?]/)) { michael@0: if(/@@/) { # These would be imports michael@0: &verbose( "Import: $_ \"$type\"\n"); michael@0: &verbose( "C++ method: $_\n"); michael@0: } elsif (/^[^\(]*::/) { # C++ methods, stuff class name in associative array michael@0: ## DON'T match ... ( foo::bar ... want :: to be to the left of paren michael@0: ## icu::CharString::~CharString(void) -> CharString michael@0: @CppName = split(/::/); ## remove scope stuff michael@0: michael@0: if(@CppName>1) { michael@0: ## MessageFormat virtual table -> MessageFormat michael@0: if(! ($CppName[0] =~ /icu/ )) { michael@0: # *** WARNING Bad namespace (not 'icu') on ShoeSize::ShoeSize() michael@0: warn "*** WARNING Bad namespace (not 'icu') on $_\n"; michael@0: next; michael@0: } michael@0: &verbose ( "(Chopping scope $CppName[0] )"); michael@0: @CppName = split(/ /, $CppName[1]); ## remove debug stuff michael@0: } michael@0: ## ures_getUnicodeStringByIndex(UResourceBundle -> ures_getUnicodeStringByIndex michael@0: @CppName = split(/\(/, $CppName[0]); ## remove function args michael@0: if($CppName[0] =~ /^operator/) { michael@0: &verbose ("Skipping C++ function: $_\n"); michael@0: } elsif($CppName[0] =~ /^~/) { michael@0: &verbose ("Skipping C++ destructor: $_\n"); michael@0: } else { michael@0: &verbose( "Skipping C++ class: '$CppName[0]': $_ \n"); michael@0: # $CppClasses{$CppName[0]}++; michael@0: # $symbolCount++; michael@0: } michael@0: } elsif ( my ($cfn) = m/^([A-Za-z0-9_]*)\(.*/ ) { michael@0: &verbose ( "$ARGV[0]: got global C++ function $cfn with '$_'\n" ); michael@0: $CFuncs{$cfn}++; michael@0: $symbolCount++; michael@0: } elsif ( /\(/) { # These are strange functions michael@0: print STDERR "$ARGV[0]: Not sure what to do with '$_'\n"; michael@0: } elsif ( /^_init/ ) { michael@0: &verbose( "$ARGV[0]: Skipped initializer $_\n" ); michael@0: } elsif ( /^_fini/ ) { michael@0: &verbose( "$ARGV[0]: Skipped finilizer $_\n" ); michael@0: } elsif ( /icu_/) { michael@0: print STDERR "$ARGV[0]: Skipped strange mangled function $_\n"; michael@0: } elsif ( /^vtable for /) { michael@0: print STDERR "$ARGV[0]: Skipped vtable $_\n"; michael@0: } elsif ( /^typeinfo/) { michael@0: print STDERR "$ARGV[0]: Skipped typeinfo $_\n"; michael@0: } elsif ( /operator\+/ ) { michael@0: print STDERR "$ARGV[0]: Skipped ignored function $_\n"; michael@0: } else { # This is regular C function michael@0: &verbose( "C func: $_\n"); michael@0: @funcname = split(/[\(\s+]/); michael@0: $CFuncs{$funcname[0]}++; michael@0: $symbolCount++; michael@0: } michael@0: } else { michael@0: &verbose( "Skipped: $_ $1\n"); michael@0: } michael@0: } michael@0: } michael@0: michael@0: if( $fileCount == 0 ) { michael@0: die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n"; michael@0: } michael@0: michael@0: if( $symbolCount == 0 ) { michael@0: die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n"; michael@0: } michael@0: michael@0: print " Loaded $symbolCount symbols from $itemCount lines in $fileCount files.\n"; michael@0: michael@0: print HEADER "\n/* C exports renaming data */\n\n"; michael@0: foreach(sort keys(%CFuncs)) { michael@0: print HEADER "#define $_ U_ICU_ENTRY_POINT_RENAME($_)\n"; michael@0: # print HEADER "#define $_ $_$U_ICU_VERSION_SUFFIX\n"; michael@0: } michael@0: michael@0: print HEADER "\n#endif\n"; michael@0: print HEADER "\n#endif\n"; michael@0: michael@0: close HEADER; michael@0: michael@0: sub verbose { michael@0: if($VERBOSE) { michael@0: print STDERR @_; michael@0: } michael@0: } michael@0: michael@0: michael@0: sub printHelpMsgAndExit { michael@0: print STDERR <<"EndHelpText"; michael@0: Usage: $0 [OPTIONS] LIBRARY_FILES michael@0: Options: michael@0: -v - verbose michael@0: -h - help michael@0: -o - output file name (defaults to 'urename.h' michael@0: -S - suffix (defaults to _MAJOR_MINOR of current ICU version) michael@0: Will produce a renaming .h file michael@0: michael@0: EndHelpText michael@0: michael@0: exit 0; michael@0: michael@0: }