genren.pl (9688B)
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 21 use 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 34 open(UVERSION, $path); 35 36 while(<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 45 while($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 58 unless(@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 73 print 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 and for LLVM's Clang-Tidy tool, so that 110 // 'Go-to-Definition' (F12) and 'include-cleaner' respectively will work. 111 #if !(defined(_MSC_VER) && defined(__INTELLISENSE__)) && !defined(__clang_analyzer__) 112 113 /* 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 114 the platform a chance to define it first. 115 Normally (if utypes.h or umachine.h was included first) this will not be necessary as it will already be defined. 116 */ 117 118 #ifndef U_ICU_ENTRY_POINT_RENAME 119 #include "unicode/umachine.h" 120 #endif 121 122 /* If we still don't have U_ICU_ENTRY_POINT_RENAME use the default. */ 123 #ifndef U_ICU_ENTRY_POINT_RENAME 124 #include "unicode/uvernum.h" 125 #endif 126 127 /* Error out before the following defines cause very strange and unexpected code breakage */ 128 #ifndef U_ICU_ENTRY_POINT_RENAME 129 #error U_ICU_ENTRY_POINT_RENAME is not defined - cannot continue. Consider defining U_DISABLE_RENAMING if renaming should not be used. 130 #endif 131 132 EndOfHeaderComment 133 134 $fileCount = 0; 135 $itemCount = 0; 136 $symbolCount = 0; 137 138 for(;@ARGV; shift(@ARGV)) { 139 $fileCount++; 140 @NMRESULT = `nm $nmopts $ARGV[0] $post`; 141 if($?) { 142 warn "Couldn't do 'nm' for $ARGV[0], continuing...\n"; 143 next; # Couldn't do nm for the file 144 } 145 if($mode =~ /POSIX/) { 146 splice @NMRESULT, 0, 6; 147 } elsif ($mode =~ /Mach-O/) { 148 # splice @NMRESULT, 0, 10; 149 } 150 foreach (@NMRESULT) { # Process every line of result and stuff it in $_ 151 $itemCount++; 152 if($mode =~ /POSIX/) { 153 &verbose(" $_"); 154 ($_, $address, $type) = split(/\|/); 155 chop $qtype; 156 } elsif ($mode =~ /Mach-O/) { 157 ($address, $type, $_) = split(/ /); 158 if (/^(.*)\(/) { 159 # on Mac, C++ functions and methods are NOT prefixed with an underscore, 160 # but do contain their parameter lists (in patentheses)-- remove 161 # the parameter list 162 $_ = $1; 163 } elsif(/^_(.*)$/) { 164 # C function names (and maybe also C++ functions on Linux?) are all 165 # prefixed with an underscore-- remove it 166 $_ = $1; 167 } else { 168 # skip symbols in any other format 169 next; 170 } 171 } else { 172 die "Unknown mode $mode"; 173 } 174 &verbose( "type: \"$type\" "); 175 if(!($type =~ /[UAwW?]/)) { 176 if(/@@/) { # These would be imports 177 &verbose( "Import: $_ \"$type\"\n"); 178 &verbose( "C++ method: $_\n"); 179 } elsif (/^[^\(]*::/) { # C++ methods, stuff class name in associative array 180 ## DON'T match ... ( foo::bar ... want :: to be to the left of paren 181 ## icu::CharString::~CharString(void) -> CharString 182 @CppName = split(/::/); ## remove scope stuff 183 184 if(@CppName>1) { 185 ## MessageFormat virtual table -> MessageFormat 186 if(! ($CppName[0] =~ /icu/ )) { 187 # *** WARNING Bad namespace (not 'icu') on ShoeSize::ShoeSize() 188 warn "*** WARNING Bad namespace (not 'icu') on $_\n"; 189 next; 190 } 191 &verbose ( "(Chopping scope $CppName[0] )"); 192 @CppName = split(/ /, $CppName[1]); ## remove debug stuff 193 } 194 ## ures_getUnicodeStringByIndex(UResourceBundle -> ures_getUnicodeStringByIndex 195 @CppName = split(/\(/, $CppName[0]); ## remove function args 196 if($CppName[0] =~ /^operator/) { 197 &verbose ("Skipping C++ function: $_\n"); 198 } elsif($CppName[0] =~ /^~/) { 199 &verbose ("Skipping C++ destructor: $_\n"); 200 } else { 201 &verbose( "Skipping C++ class: '$CppName[0]': $_ \n"); 202 # $CppClasses{$CppName[0]}++; 203 # $symbolCount++; 204 } 205 } elsif ( my ($cfn) = m/^([A-Za-z0-9_]*)\(.*/ ) { 206 &verbose ( "$ARGV[0]: got global C++ function $cfn with '$_'\n" ); 207 $CFuncs{$cfn}++; 208 $symbolCount++; 209 } elsif ( /\(/) { # These are strange functions 210 print STDERR "$ARGV[0]: Not sure what to do with '$_'\n"; 211 } elsif ( /^_init/ ) { 212 &verbose( "$ARGV[0]: Skipped initializer $_\n" ); 213 } elsif ( /^_fini/ ) { 214 &verbose( "$ARGV[0]: Skipped finilizer $_\n" ); 215 } elsif ( /icu_/) { 216 print STDERR "$ARGV[0]: Skipped strange mangled function $_\n"; 217 } elsif ( /^vtable for /) { 218 print STDERR "$ARGV[0]: Skipped vtable $_\n"; 219 } elsif ( /^typeinfo/) { 220 print STDERR "$ARGV[0]: Skipped typeinfo $_\n"; 221 } elsif ( /operator\+/ ) { 222 print STDERR "$ARGV[0]: Skipped ignored function $_\n"; 223 } else { # This is regular C function 224 &verbose( "C func: $_\n"); 225 @funcname = split(/[\(\s+]/); 226 $CFuncs{$funcname[0]}++; 227 $symbolCount++; 228 } 229 } else { 230 &verbose( "Skipped: $_ $1\n"); 231 } 232 } 233 } 234 235 if( $fileCount == 0 ) { 236 die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n"; 237 } 238 239 if( $symbolCount == 0 ) { 240 die "Error: $itemCount lines from $fileCount files processed, but $symbolCount symbols were found.\n"; 241 } 242 243 print " Loaded $symbolCount symbols from $itemCount lines in $fileCount files.\n"; 244 245 print HEADER "\n/* C exports renaming data */\n\n"; 246 foreach(sort keys(%CFuncs)) { 247 print HEADER "#define $_ U_ICU_ENTRY_POINT_RENAME($_)\n"; 248 # print HEADER "#define $_ $_$U_ICU_VERSION_SUFFIX\n"; 249 } 250 251 252 print HEADER <<"EndOfHeaderFooter"; 253 254 #endif /* !(defined(_MSC_VER) && defined(__INTELLISENSE__)) && !defined(__clang_analyzer__) */ 255 #endif /* U_DISABLE_RENAMING */ 256 #endif /* URENAME_H */ 257 258 EndOfHeaderFooter 259 260 261 close HEADER; 262 263 sub verbose { 264 if($VERBOSE) { 265 print STDERR @_; 266 } 267 } 268 269 270 sub printHelpMsgAndExit { 271 print STDERR <<"EndHelpText"; 272 Usage: $0 [OPTIONS] LIBRARY_FILES 273 Options: 274 -v - verbose 275 -h - help 276 -o - output file name (defaults to 'urename.h' 277 -S - suffix (defaults to _MAJOR_MINOR of current ICU version) 278 Will produce a renaming .h file 279 280 EndHelpText 281 282 exit 0; 283 284 }