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