1#!/usr/bin/perl
2#*
3#*******************************************************************************
4#*   Copyright (C) 2001-2009, 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
19use 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 = 'LINUX';
29
30(-e $path) || die "Cannot find uversion.h";
31
32open(UVERSION, $path);
33
34while(<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
43while($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
56unless(@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
72$YEAR = strftime "%Y",localtime;
73
74print HEADER <<"EndOfHeaderComment";
75/*
76*******************************************************************************
77*   Copyright (C) 2002-$YEAR, International Business Machines
78*   Corporation and others.  All Rights Reserved.
79*******************************************************************************
80*
81*   file name:  $headername
82*   encoding:   US-ASCII
83*   tab size:   8 (not used)
84*   indentation:4
85*
86*   Created by: Perl script written by Vladimir Weinstein
87*
88*  Contains data for renaming ICU exports.
89*  Gets included by umachine.h
90*
91*  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
92*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
93*/
94
95#ifndef $HEADERDEF
96#define $HEADERDEF
97
98/* Uncomment the following line to disable renaming on platforms
99   that do not use Autoconf. */
100/* #define U_DISABLE_RENAMING 1 */
101
102#if !U_DISABLE_RENAMING
103EndOfHeaderComment
104
105for(;@ARGV; shift(@ARGV)) {
106    @NMRESULT = `nm $nmopts $ARGV[0] $post`;
107    if($?) {
108        warn "Couldn't do 'nm' for $ARGV[0], continuing...\n";
109        next; # Couldn't do nm for the file
110    }
111    if($mode =~ /POSIX/) {
112        splice @NMRESULT, 0, 6;
113    } elsif ($mode =~ /Mach-O/) {
114#        splice @NMRESULT, 0, 10;
115    }
116    foreach (@NMRESULT) { # Process every line of result and stuff it in $_
117        if($mode =~ /POSIX/) {
118            ($_, $address, $type) = split(/\|/);
119        } elsif ($mode =~ /Mach-O/) {
120            if(/^(?:[0-9a-fA-F]){8} ([A-Z]) (?:_)?(.*)$/) {
121                ($_, $type) = ($2, $1);
122            } else {
123                next;
124            }
125        } else {
126            die "Unknown mode $mode";
127        }
128        &verbose( "type: \"$type\" ");
129        if(!($type =~ /[UAwW?]/)) {
130            if(/@@/) { # These would be imports
131                &verbose( "Import: $_ \"$type\"\n");
132            } elsif (/::/) { # C++ methods, stuff class name in associative array
133                &verbose( "C++ method: $_\n");
134                ## icu_2_0::CharString::~CharString(void) -> CharString
135                @CppName = split(/::/); ## remove scope stuff
136                if(@CppName>1) {
137                    ## MessageFormat virtual table -> MessageFormat
138                    @CppName = split(/ /, $CppName[1]); ## remove debug stuff
139                }
140                ## ures_getUnicodeStringByIndex(UResourceBundle -> ures_getUnicodeStringByIndex
141                @CppName = split(/\(/, $CppName[0]); ## remove function args
142                if($CppName[0] =~ /^operator/) {
143                    &verbose ("Skipping C++ function: $_\n");
144                } elsif($CppName[0] =~ /^~/) {
145                    &verbose ("Skipping C++ destructor: $_\n");
146                } else {
147                    $CppClasses{$CppName[0]}++;
148                }
149            } elsif ( /\(/) { # These are strange functions
150                print STDERR "$_\n";
151            } elsif ( /icu_/) {
152                print STDERR "Skipped strange mangled function $_\n";
153            } elsif ( /^vtable for /) {
154                print STDERR "Skipped vtable $_\n";
155            } elsif ( /^typeinfo for /) {
156                print STDERR "Skipped typeinfo $_\n";
157            } elsif ( /operator\+/ ) {
158                print STDERR "Skipped ignored function $_\n";
159            } else { # This is regular C function
160                &verbose( "C func: $_\n");
161                @funcname = split(/[\(\s+]/);
162                $CFuncs{$funcname[0]}++;
163            }
164        } else {
165            &verbose( "Skipped: $_ $1\n");
166        }
167    }
168}
169
170print HEADER "\n/* C exports renaming data */\n\n";
171foreach(sort keys(%CFuncs)) {
172    print HEADER "#define $_ $_$U_ICU_VERSION_SUFFIX\n";
173}
174
175print HEADER "/* C++ class names renaming defines */\n\n";
176print HEADER "#ifdef XP_CPLUSPLUS\n";
177print HEADER "#if !U_HAVE_NAMESPACE\n\n";
178foreach(sort keys(%CppClasses)) {
179    print HEADER "#define $_ $_$U_ICU_VERSION_SUFFIX\n";
180}
181print HEADER "\n#endif\n";
182print HEADER "#endif\n";
183print HEADER "\n#endif\n";
184print HEADER "\n#endif\n";
185
186close HEADER;
187
188sub verbose {
189    if($VERBOSE) {
190        print STDERR @_;
191    }
192}
193
194
195sub printHelpMsgAndExit {
196    print STDERR <<"EndHelpText";
197Usage: $0 [OPTIONS] LIBRARY_FILES
198  Options:
199    -v - verbose
200    -h - help
201    -o - output file name (defaults to 'urename.h'
202    -S - suffix (defaults to _MAJOR_MINOR of current ICU version)
203Will produce a renaming .h file
204
205EndHelpText
206
207    exit 0;
208
209}
210
211