| #!/usr/bin/perl | |
| # | |
| # Copyright Statement: | |
| # -------------------- | |
| # This software is protected by Copyright and the information contained | |
| # herein is confidential. The software may not be copied and the information | |
| # contained herein may not be used or disclosed except with the written | |
| # permission of MediaTek Inc. (C) 2005 | |
| # | |
| # BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES | |
| # THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") | |
| # RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON | |
| # AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, | |
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF | |
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. | |
| # NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE | |
| # SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR | |
| # SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH | |
| # THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO | |
| # NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S | |
| # SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. | |
| # | |
| # BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE | |
| # LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, | |
| # AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, | |
| # OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO | |
| # MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. | |
| # | |
| # THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE | |
| # WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF | |
| # LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND | |
| # RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER | |
| # THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). | |
| # | |
| # | |
| #!/usr/bin/perl | |
| # filter out the lines having no define options | |
| # | |
| # parsing command arguments | |
| # | |
| my $line_no; | |
| my $debug_print = 0; # 1 for debug; 0 for non-debug | |
| if (!($ARGV[0] =~ /\.(h|c|hpp|cpp|s|java|inc)$/i)) | |
| { | |
| &usage; | |
| } | |
| if (!(($ARGV[1] =~ /info\.log$/i) || ($ARGV[1] =~ /\.def$/i)) || !($ARGV[2] =~ /\.def$/i)) | |
| { | |
| &usage; | |
| } | |
| if (!($ARGV[3] =~ /\.(h|c|hpp|cpp|s|java|inc)$/i)) | |
| { | |
| &usage; | |
| } | |
| # | |
| #get %opt_list | |
| # | |
| my %opt_list; | |
| my $ENOPT_FILE = $ARGV[1]; | |
| open ENOPT_FILE, "<$ENOPT_FILE" or die "cannot open $ENOPT_FILE\n"; | |
| my $is_option_area = -1; # -1: not in a option area | |
| # 1: in a option area | |
| my $log_turnon = "[ COMMON OPTION ]"; | |
| my $log_turnoff = "[ COMMON INCLUDE PATH ]"; | |
| my $opt_no = 0; | |
| while (<ENOPT_FILE>) | |
| { | |
| $read_line = $_; | |
| if ((index($read_line, $log_turnon) >=0) && ($is_option_area == -1)) | |
| { | |
| $is_option_area = 1; | |
| } | |
| elsif ((index($read_line, $log_turnoff) >=0) && ($is_option_area == 1)) | |
| { | |
| $is_option_area = -1; | |
| } | |
| else | |
| { | |
| if ($is_option_area == 1) | |
| { | |
| $read_line =~ s/\s*(\w+)\s*(\n)+/$1/; | |
| $opt_list{$read_line} = 1; | |
| $opt_no ++; | |
| } | |
| } | |
| } | |
| close ENOPT_FILE; | |
| #print $opt_no; | |
| #exit(0); | |
| my $DISOPT_FILE = $ARGV[2]; | |
| open DISOPT_FILE, "<$DISOPT_FILE" or die "cannot open $DISOPT_FILE\n"; | |
| while (<DISOPT_FILE>) | |
| { | |
| s/\s*(\w+)\s*(\n)+/$1/; | |
| $opt_list{$_} = 0; | |
| } | |
| close DISOPT_FILE; | |
| # | |
| # open source file & result file | |
| # | |
| my $SRC_FILE = $ARGV[0]; | |
| my $is_exist = 0; | |
| $is_exist = 1 if -e $SRC_FILE; | |
| if ($is_exist == 1) | |
| { | |
| open SRC_FILE, "<$SRC_FILE" or die "cannot open $SRC_FILE\n"; | |
| } | |
| else | |
| { | |
| print "$SRC_FILE is not existed!!!\n"; | |
| exit(1); | |
| } | |
| my $RSLT_FILE = $ARGV[3]; | |
| open RSLT_FILE, ">$RSLT_FILE" or die "cannot open $RSLT_FILE\n"; | |
| # | |
| # record lines in multi-line comments in %in_mline_cmt_list | |
| # !!!nested comments are not applicable | |
| # | |
| # %in_mline_cmt_list is used to record the line which is in a multi-line comment | |
| # $key : line number in a multi-line comment | |
| # $value 0: the beginning line of the multi-line comment | |
| # 1: the line between the beginning and the end lines of the multi-line comment | |
| # 2: the end line of the multi-line comment | |
| # 3: the end line of one multi-line comment & the beginning line of another multi-line comment | |
| my $is_in_mline_cmt = 0; | |
| $line_no = 1; | |
| #print "scanning comment\n"; | |
| while (<SRC_FILE>) | |
| { | |
| my $line = $_; | |
| my $cmt_ptn; | |
| if ($is_in_mline_cmt == 1) | |
| { | |
| if ($line =~ /\*\//) | |
| { | |
| $in_mline_cmt_list{$line_no} = 2; | |
| $is_in_mline_cmt = 0; | |
| $line =~ s{.*?\*/}{}; | |
| } | |
| else | |
| { | |
| $in_mline_cmt_list{$line_no} = 1; | |
| } | |
| # print $in_mline_cmt_list{$line_no}; | |
| } | |
| else | |
| { | |
| # print "-"; | |
| } | |
| while ( $line =~ /\/\/|\/\*/ ) | |
| { | |
| $cmt_ptn = $&; | |
| if ( $line =~ /\".*?(\/\/|\/\*).*?\"/ ) | |
| { | |
| last; | |
| } | |
| # print "$line \t $cmt_ptn \n"; | |
| if ($cmt_ptn =~ /\/\//) | |
| { | |
| $line =~ s{//.*}{\n}; | |
| } | |
| elsif ($cmt_ptn =~ /\/\*/) | |
| { | |
| $line =~ /\/\*/; | |
| if ($' =~ /\*\//)#' | |
| { | |
| $line =~ s{/\*.*?\*/}{}; | |
| } | |
| else | |
| { | |
| $in_mline_cmt_list{$line_no} = ( exists $in_mline_cmt_list{$line_no} )? 3 : 0; | |
| $is_in_mline_cmt = 1; | |
| # print $in_mline_cmt_list{$line_no}; | |
| last; | |
| } | |
| } | |
| } | |
| $line_no ++; | |
| if (($line =~ /\\$/) || ($line =~ /\\\r/)) | |
| { | |
| $in_mline_cmt_list{$line_no} = 4; | |
| } | |
| # print "$line_no \n"; | |
| } # foreach (<SRC_FILE>) of record lines in multi-line comments in %in_mline_cmt_list | |
| seek(SRC_FILE, 0, 0); | |
| #print "start parsing...\n"; | |
| # | |
| # parsing directives: #if, #ifdef, #ifndef, #endif, #else, #elif | |
| # | |
| $line_no = 1; | |
| while (<SRC_FILE>) | |
| { | |
| $read_line = $_; | |
| print "$line_no\t" if ($debug_print == 1); | |
| if (((/^\s*\#\s*if/) || (/^\s*\/\*.*\*\/\s*\#\s*if/) || (/^\s*\#\s*if/)) && !($in_mline_cmt_list{$line_no} > 0)) | |
| { | |
| print RSLT_FILE $read_line; | |
| # remove the comment in expression first | |
| $uncommented_line = &rm_cmt($read_line); | |
| while ($uncommented_line eq 'A non-ended multiple-line comment!!!') | |
| { | |
| chomp($read_line); | |
| print "$uncommented_line\n" if ($debug_print == 1); | |
| $read_line =~ s/\\$//; | |
| $read_line =~ s/\\\r//; | |
| $extra_line = <SRC_FILE>; | |
| $line_no ++; | |
| print "$line_no\t" if ($debug_print == 1); | |
| print RSLT_FILE $extra_line; | |
| $read_line .= $extra_line; | |
| $uncommented_line = &rm_cmt($read_line); | |
| } | |
| &do_ifxxx($uncommented_line); | |
| } | |
| elsif (((/^\s*\#\s*endif/) || (/^\s*\/\*.*\*\/\s*\#\s*endif/)) && !($in_mline_cmt_list{$line_no} > 0)) | |
| { | |
| print RSLT_FILE $read_line; | |
| &do_endif; | |
| } | |
| elsif (((/^\s*\#\s*else/) || (/^\s*\/\*.*\*\/\s*\#\s*else/)) && !($in_mline_cmt_list{$line_no} > 0)) | |
| { | |
| print RSLT_FILE $read_line; | |
| &do_else; | |
| } | |
| elsif (((/^\s*\#\s*elif/) || (/^\s*\/\*.*\*\/\s*\#\s*elif/)) && !($in_mline_cmt_list{$line_no} > 0)) | |
| { | |
| print RSLT_FILE $read_line; | |
| # remove the comment in expression first | |
| $uncommented_line = &rm_cmt($read_line); | |
| while ($uncommented_line eq 'A non-ended multiple-line comment!!!') | |
| { | |
| chomp($read_line); | |
| print "$uncommented_line\n" if ($debug_print == 1); | |
| $read_line =~ s/\\$//; | |
| $read_line =~ s/\\\r//; | |
| $extra_line = <SRC_FILE>; | |
| $line_no ++; | |
| print "$line_no\t" if ($debug_print == 1); | |
| print RSLT_FILE $extra_line; | |
| $read_line .= $extra_line; | |
| $uncommented_line = &rm_cmt($read_line); | |
| } | |
| &do_elif($uncommented_line); | |
| } | |
| else | |
| { | |
| if (@if_stack != ()) | |
| { | |
| my $need_prn; | |
| my $need_removal = 0; | |
| for ($i=$#if_stack; $i>=0; $i--) | |
| { | |
| $if_truth_value_list = $if_stack[$i]; | |
| $if_truth_value_list =~ m/(\w)\s*$/; | |
| $need_prn = $1; | |
| print "<$need_prn>" if ($debug_print == 1); | |
| if ($need_prn =~ /0/) | |
| { | |
| $need_removal = 1; | |
| last; | |
| } | |
| } | |
| print "\n" if ($debug_print == 1); | |
| ($need_removal == 1) ? | |
| print RSLT_FILE "/* under construction !*/\n" : | |
| print RSLT_FILE $read_line; | |
| } | |
| else | |
| { | |
| print RSLT_FILE $read_line; | |
| print "1\n" if ($debug_print == 1); | |
| } | |
| } | |
| $line_no ++; | |
| } # foreach (<SRC_FILE>) of parsing directives: #if, #ifdef, #ifndef, #endif, #else, #elif | |
| close SRC_FILE; | |
| close RSLT_FILE; | |
| exit 0; | |
| # show usage | |
| sub usage | |
| { | |
| print "USAGE: perl if_fil.pl <source file> <enabled define options> <disabled define options> <destination file>\n"; | |
| exit(0); | |
| } | |
| # remove comment in line | |
| sub rm_cmt | |
| { | |
| my $line; | |
| my $cmt_ptn; | |
| $_ = $_[0]; | |
| while (/\/\/|\/\*/) | |
| { | |
| $line = $_; | |
| $cmt_ptn = $&; | |
| if ($cmt_ptn =~ /\/\//) | |
| { | |
| $line =~ s{//.*\n}{\n}; | |
| } | |
| elsif ($cmt_ptn =~ /\/\*/) | |
| { # nested comments are not applicable!!! | |
| if ($line =~ /\*\//) | |
| { | |
| $line =~ s{/\*.*?\*/}{}; | |
| } | |
| else | |
| { | |
| return "A non-ended multiple-line comment!!!"; | |
| } | |
| } | |
| $_ = $line; | |
| } | |
| if ((/\\$/) || (/\\\r/)) | |
| { | |
| return "A non-ended multiple-line comment!!!"; | |
| } | |
| return $_; | |
| } | |
| # determine the truth value of a conditional expression | |
| sub truth_exp | |
| { | |
| my $line; | |
| my $opt; | |
| my $opt_value; | |
| my $exp_rslt; | |
| my $undetermin_cnt = 0; | |
| my $determin_cnt = 0; | |
| $_ = $_[0]; | |
| s/defined//g; | |
| if (/'\\?(.|\w+)'/) | |
| { | |
| # workaround for #if 'A' == '\301' in applib\sqlite3\inc\sqliteInt.h | |
| return "_ "; | |
| } | |
| s/\b[A-Za-z_]\w*\s*(<=|==|>=|!=|<|>)\s*\d+\b/_/g; | |
| if ((/\b0\s*\&\&/) || (/\&\&\s*0\b/) || (/\b1\s*\|\|/) || (/\|\|\s*1\b/)) | |
| { | |
| $determin_cnt = 1; | |
| } | |
| while (/\b([A-Za-z_]\w*)\b/) | |
| { | |
| $line = $_; | |
| $opt = $1; | |
| if ( exists $opt_list{$opt}) | |
| { | |
| $determin_cnt++; | |
| $opt_value = $opt_list{$opt}; | |
| $line =~ s/$opt/$opt_value/; | |
| } | |
| else | |
| { | |
| $undetermin_cnt ++; | |
| $line =~ s/$opt/\#/; | |
| #print "[$line]"; | |
| } | |
| $_ = $line; | |
| } | |
| s/!/int!/g; | |
| #print "[$undetermin_cnt]"; | |
| $line = $_; | |
| if ($undetermin_cnt == 0) | |
| { | |
| $exp_rslt = eval($line); | |
| } | |
| elsif ($determin_cnt == 0) | |
| { | |
| return "_ "; | |
| } | |
| elsif (($undetermin_cnt > 22) && ($line =~ /\b(0|1)\b/)) | |
| { | |
| return "_ "; | |
| } | |
| else # if ($undetermin_cnt > 0) | |
| { | |
| my $pre_exp_rslt = -1; | |
| my $index; | |
| for ($index=0; $index<2**$undetermin_cnt; $index++) | |
| { | |
| #print "\n$_ = "; | |
| my $i = $index; | |
| my $ln = $line; | |
| foreach (1..$undetermin_cnt) | |
| { | |
| my $mod = $i % 2; | |
| $ln =~ s/\#/$mod/; | |
| $i -= $mod; | |
| $i /= 2; | |
| } | |
| $exp_rslt = eval($ln); | |
| #print "[$exp_rslt]"; | |
| if ($pre_exp_rslt == -1) | |
| { | |
| $pre_exp_rslt = $exp_rslt; | |
| } | |
| else | |
| { | |
| if ($pre_exp_rslt != $exp_rslt) | |
| { | |
| $exp_rslt = ""; | |
| last; | |
| } | |
| } | |
| } # foreach (0..2**$undetermin_cnt-1) | |
| } | |
| if ($exp_rslt =~ /1/) | |
| { | |
| # print "$line ==> $exp_rslt"; | |
| return "1 "; | |
| } | |
| elsif ($exp_rslt =~ /0/) | |
| { | |
| # print "$line ==> $exp_rslt"; | |
| return "0 "; | |
| } | |
| else | |
| { | |
| return "_ "; | |
| } | |
| } | |
| # do for #ifndef, #ifdef, #if | |
| sub do_ifxxx | |
| { | |
| my $truth_value; | |
| # determine current expression truth value | |
| $_ = $_[0]; | |
| if ( (s/^\s*\#\s*ifndef\s+(.+)\n$/$1/) || (s/^\s*\/\*.*\*\/\s*\#\s*ifndef\s+(.+)\n$/$1/)) | |
| { | |
| s/\s+/ /g; | |
| s/\s+$//; | |
| $opt = $_; | |
| if ( exists $opt_list{$opt} ) | |
| { | |
| if ($opt_list{$opt} == 0) # is in the $dis_opt_list | |
| { | |
| $truth_value = "1 "; | |
| } | |
| elsif ($opt_list{$opt} == 1) # is in the $en_opt_list | |
| { | |
| $truth_value = "0 "; | |
| } | |
| } | |
| else # $opt is in neither $en_opt_list nor $dis_opt_list | |
| { | |
| $truth_value = "_ "; | |
| } | |
| print "#ifndef $opt ==> $truth_value\n" if ($debug_print == 1); | |
| } | |
| elsif ( (s/^\s*\#\s*ifdef\s+(.+)\n$/$1/) || (s/^\s*\/\*.*\*\/\s*\#\s*ifdef\s+(.+)\n$/$1/)) | |
| { | |
| s/\s+/ /g; | |
| s/\s+$//; | |
| $opt = $_; | |
| if ( exists $opt_list{$opt} ) | |
| { | |
| if ($opt_list{$opt} == 0) # is in the $dis_opt_list | |
| { | |
| $truth_value = "0 "; | |
| } | |
| elsif ($opt_list{$opt} == 1) # is in the $en_opt_list | |
| { | |
| $truth_value = "1 "; | |
| } | |
| } | |
| else # $opt is in neither $en_opt_list nor $dis_opt_list | |
| { | |
| $truth_value = "_ "; | |
| } | |
| print "#ifdef $opt ==> $truth_value\n" if ($debug_print == 1); | |
| } | |
| elsif ( (s/^\s*\#\s*if\s+(.+)\n$/$1/) || (s/^\s*\/\*.*\*\/\s*\#\s*if\s+(.+)\n$/$1/)) | |
| { | |
| $truth_value = &truth_exp($_); | |
| print "#if $_ ==> $truth_value\n" if ($debug_print == 1); | |
| } | |
| # push an entry into @if_stack | |
| push @if_stack, $truth_value; | |
| } | |
| # do for #endif | |
| sub do_endif | |
| { | |
| pop @if_stack; | |
| print "#endif\n" if ($debug_print == 1); | |
| } | |
| # do for #else | |
| sub do_else | |
| { | |
| $if_stack[-1] .= ($if_stack[-1] =~ /1/) ? "0 " : "1 "; | |
| # Just fur debug | |
| $_ = $if_stack[-1]; | |
| m/(\d)\s*$/; | |
| print "#else ==> $1\n" if ($debug_print == 1); | |
| } | |
| # do for #elif | |
| sub do_elif | |
| { | |
| my $truth_value; | |
| $_ = $_[0]; | |
| s/^\s*\#\s*elif\s+(.+)\n$/$1/; | |
| $truth_value = &truth_exp($_); | |
| $if_stack[-1] .= $truth_value; | |
| print "#elif $if_stack[-1]\n" if ($debug_print == 1); | |
| } |