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