1#!/usr/bin/perl
2#*
3#*******************************************************************************
4#*   Copyright (C) 2006-2011, International Business Machines
5#*   Corporation and others.  All Rights Reserved.
6#*******************************************************************************
7#*
8#*   file name:  genheaders.pl
9#*   encoding:   US-ASCII
10#*   tab size:   8 (not used)
11#*   indentation:4
12#*
13#*   Created by: Ram Viswanadha
14#*
15#*  This tool filters the deprecated.html and friends file generated by Doxygen and generates udarft.h
16#*  udeprctd.h and uobslete.h
17#*
18
19use File::Find;
20use File::Basename;
21use IO::File;
22use Cwd;
23use File::Copy;
24use Getopt::Long;
25use File::Path;
26use File::Copy;
27
28$draftHeaderName = "udraft.h";
29$draftAppend = "DRAFT_API_DO_NOT_USE";
30$draftDefine = "U_HIDE_DRAFT_API";
31
32$deprecatedHeaderName = "udeprctd.h";
33$deprecatedAppend = "DEPRECATED_API_DO_NOT_USE";
34$deprecatedDefine = "U_HIDE_DEPRECATED_API";
35
36$obsoleteHeaderName = "uobslete.h";
37$obsoleteAppend = "OBSOLETE_API_DO_NOT_USE";
38$obsoleteDefine = "U_HIDE_OBSOLETE_API";
39
40$systemHeaderName = "usystem.h";
41$systemAppend = "SYSTEM_API_DO_NOT_USE";
42$systemDefine = "U_HIDE_SYSTEM_API";
43
44$internalHeaderName = "uintrnal.h";
45$internalAppend = "INTERNAL_API_DO_NOT_USE";
46$internalDefine = "U_HIDE_INTERNAL_API";
47
48$versionAppend="";
49
50#run the program
51main();
52
53#---------------------------------------------------------------------
54# The main program
55
56sub main(){
57  GetOptions(
58           "--srcdir=s" => \$srcDir,
59           "--destdir=s" => \$destDir,
60           "--version=s"  => \$version,
61           "--exclusion-list=s"  => \$exclude,
62           "--include-types" => \$includeTypes,
63           "--verbose" => \$verbose
64           );
65  usage() unless defined $srcDir;
66  usage() unless defined $destDir;
67  usage() unless defined $version;
68  usage() unless defined $exclude;
69  $draftFile      = "$srcDir/draft.html";
70  $deprecatedFile = "$srcDir/deprecated.html";
71  $obsoleteFile   = "$srcDir/obsolete.html";
72  $systemFile     = "$srcDir/system.html";
73  $internalFile   = "$srcDir/internal.html";
74
75  $versionAppend = $version;
76  $versionAppend=~ s/^([0-9]+)\.([0-9]+).*/\1\2/;  # _48
77  $excludeFH = IO::File->new($exclude,"r")
78            or die  "could not open the file $exclude for reading: $! \n";
79  my %exclude;
80  while (defined ($line = <$excludeFH>)){
81    next if( $line =~ /^#/);
82    $line =~ s/^\s+//;
83    $line =~ s/\s+\n$//;
84    $exclude{$line}="EXCLUDE";
85  }
86
87  writeFile($draftFile, $draftHeaderName, $destDir, $draftAppend, $draftDefine, \%exclude);
88  writeFile($deprecatedFile, $deprecatedHeaderName, $destDir, $deprecatedAppend, $deprecatedDefine, \%exclude);
89  writeFile($obsoleteFile, $obsoleteHeaderName, $destDir, $obsoleteAppend, $obsoleteDefine, \%exclude);
90  writeFile($systemFile, $systemHeaderName, $destDir, $systemAppend, $systemDefine, \%exclude);
91  writeFile($internalFile, $internalHeaderName, $destDir, $internalAppend, $internalDefine, \%exclude);
92}
93
94#-----------------------------------------------------------------------
95sub getHeaderDef{
96    ($headerName) = @_;
97    $headerDef = uc($headerName);  # this is building the constant for #define
98    $headerDef =~ s/\./_/;
99    return $headerDef;
100}
101
102#-----------------------------------------------------------------------
103sub writeFile{
104  ($infile,$outfile,$destDir, $symbolAppend, $symbolDef, $exclude) = @_;
105
106  my $outFileName = $outfile;
107  $headerDef = getHeaderDef($outfile);
108
109  $outfile = $destDir."/".$outfile;
110
111  $inFH = IO::File->new($infile,"r")
112            or die  "could not open the file $infile for reading: $! \n";
113  $outFH = IO::File->new($outfile,"w")
114            or die  "could not open the file $outfile for writing: $! \n";
115
116  #print "$headerDef>>> $outfile\n";
117  printHeader($outFH, $outFileName, $headerDef, $symbolDef);
118  parseWriteFile($inFH, $outFH, $symbolAppend, $exclude);
119  printFooter($outFH, $headerDef, $symbolDef);
120  close($inFH);
121  close($outFH);
122}
123
124#-----------------------------------------------------------------------
125sub printHeader{
126    ($outFH, $headername, $HEADERDEF, $symbolDef) = @_;
127    ($DAY, $MONTH, $YEAR) = (localtime)[3,4,5];
128    $YEAR += 1900;
129#We will print our copyright here + warnings
130print $outFH <<END_HEADER_COMMENT;
131/*
132*******************************************************************************
133*   Copyright (C) 2004-$YEAR, International Business Machines
134*   Corporation and others.  All Rights Reserved.
135*******************************************************************************
136*
137*   file name:  $headername
138*   encoding:   US-ASCII
139*   tab size:   8 (not used)
140*   indentation:4
141*
142*   Created by: genheaders.pl, a perl script written by Ram Viswanadha
143*
144*  Contains data for commenting out APIs.
145*  Gets included by umachine.h
146*
147*  THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT
148*  YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN!
149*/
150
151#ifndef $HEADERDEF
152#define $HEADERDEF
153
154#ifdef $symbolDef
155
156END_HEADER_COMMENT
157}
158
159#-----------------------------------------------------------------------
160sub parseWriteFile{
161    ($inFH, $outFH, $symbolAppend, $exclude) = @_;
162    %disableRenaming;
163    %enableRenaning;
164    while (defined ($line = <$inFH>)){
165          #just process C APIs for now
166        if($line =~ /\<dt\>/ ){
167            #special cases
168            if( ($line =~ /LEUnicode/)|| ($line =~ /LanguageCodes/) ||
169                ($line =~ /ScriptCodes/) || ($line =~ /\:+/) ||
170                ($line =~ /Class/) ){
171                next;
172            }
173            if( $line =~ /^\<dt\>File [^\>]*\>([^\<]*)/ ) {
174                print "Skipping file-scope $symbolAppend $1\n";
175                next;
176            }
177            #<dt>Global <a class="el" href="utrans_8h.html#a21">utrans_unregister</a>  </dt>
178            #<dt>Global <a class="el" href="classUnicodeString.html#w1w0">UnicodeString::kInvariant</a>  </dt>
179            # the below regular expression works for both the above formats.
180            $line=~ m/\<dt\>.*\<a class=\".*\" href=\".*\">(.*)\<\/a\>.*\<\/dt\>/;
181            my $value = $1;
182            $value =~ s/\<\/a\>\s*//g;
183            $value =~ s/^\s+//;
184            $value =~ s/\s+$//;
185            #print "$exclude->{$value}\n";
186            if($exclude->{$value} eq "EXCLUDE"){
187                #print "$value  $exclude->{$value}\n";
188                next;
189            }
190            print  "$value $realSymbol $nonExSymbol :: $line\n" if defined $verbose;
191            next if(isStringAcceptable($value)==1);
192            if($value =~ /^operator[^a-zA-Z]/) {
193                print "Skipping operator $symbolAppend $value from $line\n";
194                next;
195            }
196            $realSymbol = $value."_".$versionAppend;
197            $nonExSymbol = $value."_".$symbolAppend;
198            $disableRenaming{$value} = $nonExSymbol;
199            $enableRenaming{$realSymbol} = $nonExSymbol;
200            print  "$value $realSymbol $nonExSymbol\n" if defined $verbose;
201
202        }
203    }
204    print "size of disableRenaming:  " . keys( %disableRenaming) . ".\n";
205    print "size of enableRenaming:  " . keys( %enableRenaming) . ".\n";
206    print $outFH "#    if U_DISABLE_RENAMING\n";
207    foreach $key (sort (keys(%disableRenaming))) {
208       print $outFH "#        define $key $disableRenaming{$key}\n";
209       delete($disableRenaming{$key});
210    }
211    print $outFH "#    else\n";
212    foreach $key (sort (keys(%enableRenaming))) {
213       print $outFH "#        define $key $enableRenaming{$key}\n";
214       delete($enableRenaming{$key});
215    }
216    print $outFH "#    endif /* U_DISABLE_RENAMING */\n";
217}
218#-----------------------------------------------------------------------
219sub isStringAcceptable{
220    ($string) = @_;
221    @str = split(//, $string);
222    $ret = 1;
223    foreach  $val (@str){
224        if(($val ne "_") && !($val =~ /[0-9A-Z]/)){
225        #print "$val\n";
226            $ret = 0;
227        }
228    }
229    #print "$string : $ret\n";
230    if(!(defined $includeTypes)){
231        if($ret==0 && $str[0] eq 'U'){
232            $ret=1;
233        }
234    }
235    return $ret;
236}
237
238#-----------------------------------------------------------------------
239sub printFooter{
240
241      ($outFH, $headerDef, $symbolDef ) = @_;
242#print the footer
243print $outFH <<END_FOOTER;
244
245#endif /* $symbolDef */
246#endif /* $headerDef */
247
248END_FOOTER
249}
250#-----------------------------------------------------------------------
251sub usage {
252    print << "END";
253Usage:
254gendraft.pl
255Options:
256        --srcdir=<directory>
257        --destdir=<directory>
258        --version=<current version of ICU>
259        --exclusion-list=<file name>
260        --include-types
261e.g.: genheaders.pl  --srcdir=<icu>/source/common/docs/html --destdir=<icu>/source/common/unicode --version=2.8 --exclusion-list=exclude.txt
262END
263  exit(0);
264}
265