#!/usr/bin/perl #************************************************************************* #* #* $RCSfile: filter.pl,v $ #* #* $Revision: 1.2 $ #* #* last change: $Author: rt $ $Date: 2003-12-01 18:18:24 $ #* #* The Contents of this file are made available subject to the terms of #* either of the following licenses #* #* - GNU Lesser General Public License Version 2.1 #* - Sun Industry Standards Source License Version 1.1 #* #* Sun Microsystems Inc., October, 2002 #* #* GNU Lesser General Public License Version 2.1 #* ============================================= #* Copyright 2002 by Sun Microsystems, Inc. #* 901 San Antonio Road, Palo Alto, CA 94303, USA #* #* This library is free software; you can redistribute it and/or #* modify it under the terms of the GNU Lesser General Public #* License version 2.1, as published by the Free Software Foundation. #* #* This library is distributed in the hope that it will be useful, #* but WITHOUT ANY WARRANTY; without even the implied warranty of #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #* Lesser General Public License for more details. #* #* You should have received a copy of the GNU Lesser General Public #* License along with this library; if not, write to the Free Software #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, #* MA 02111-1307 USA #* #* #* Sun Industry Standards Source License Version 1.1 #* ================================================= #* The contents of this file are subject to the Sun Industry Standards #* Source License Version 1.1 (the "License"); You may not use this file #* except in compliance with the License. You may obtain a copy of the #* License at http://www.openoffice.org/license.html. #* #* Software provided under this License is provided on an "AS IS" basis, #* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, #* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, #* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. #* See the License for the specific provisions governing your rights and #* obligations concerning the Software. #* #* The Initial Developer of the Original Code is: Sun Microsystems, Inc. #* #* Copyright: 2002 by Sun Microsystems, Inc. #* #* All Rights Reserved. #* #* Contributor(s): _______________________________________ #* #* #************************************************************************/ $debug = ""; $ctrue = 1; $cfalse = 0; $cskip = $ctrue; $cread = $cfalse; # keine umlaute # Berechnet den Ausdruck der durch den 1. Parameter Uebergeben wird. # Falls symbole nicht ersetzt werden koennen findet behandlung als Makro statt # Bricht im Fehlerfall das Programm ab # # computes the expression by the 1. Parameter handing over becomes. # If symbols not to be replaced can find treatment as macro instead of break off # in the event of an error the program sub calc_value { $_ = $_[0]; s/(\||\+|\-|\*|\/|\(|\)|\<=|\>=|\!=|\>{1,2}|\<{1,2}|\={1,2})/ $1 /g; # Insert blanks around operators s/^ *(.*) *$/$1/; # blanks vorn und hinten weg s/\( *[a-zA-Z]* *\)//; # Casts auf Typen raus @ops = split; print join(",",@ops),"\n" if $debug; @neuop = ""; foreach $op (@ops) { if ($op !~ /^(\||\+|\-|\*|\/|\(|\)|\>{1,2}|\<{1,2}|\<=|\>=|\!=|\={1,2}|\d+|0[xX][0-9a-fA-F]+)$/) { print "replace $op through",$symbol {$op},"\n" if $debug; # If no operand or number or clip $op = $symbol {$op}; # also accessed associative array also {} } # ersetzen des Symbols durch seinen Wert if ( defined ($op) ) { push(@neuop,$op); } else { # Symbol not found -> Als Text uebernehmen print "aborting calc_value : \"$_\"\n" if $debug; return $_; } } print @neuop,"\n" if $debug; $_ = join(" ",@neuop); print "$_\n" if $debug; eval "\$value = $_"; # Actual computation of the value if ($@) { die "$@ ($_)"; } # Error message in $ @ evaluate (abort) $value; } # reads a block # Parameter: FileHandle # Flag $$skip whether block .bersprungen to become is or interpreted # Flag $$BlindSkip whether if or else branch (then examines further if-then-else) # those expressions represent the end of block. # with # ifdef block would then be ("^#else\$", "^#endif\$") sub read_block { local($file,$skip,$BlindSkip,@patterns) = @_; print "reading block '$file' $skip $BlindSkip @patterns ",scalar(@_),"\n" if $debug; while (<$file>) { chop; s/\s*$//; # remove trailing whitespaces s/\(USHORT\)//; # remove (USHORT) s/SAL_CONST_INT64(\([^)]+\))/\1/; # remove (USHORT) print "Input : \"$_\"\n" if $debug; s/\/\/.*//; # Remove line comment # s/\/\*.*?\*\///g; # Kommentare inerhalb einer Zeile entfernen # erst ab perl 5 s/\s+/ /g; # Change all whitespace into a single blank s/ *$//; # Remove whitespace at end # Tests whether last line is reached # Liefert auch im falle der ganzen Datei, also ohne RegExp das gewuenschte # Ergebnis. foreach $patt (@patterns) { # Fuer jede der Expressions testen print "Testing against $patt\n" if $debug; print "Pattern fits: $patt\n" if $debug && /$patt/; return $& if /$patt/; # Ruecksprung wenn die Zeile auf das Muster passt. } if ( $skip eq $cread || !$BlindSkip ) { if ( /\/\*/ ) { # kommentarbeginn entdecken $_ = $`; # Zeile auf restzeile vor kommantar setzen $comment = $ctrue; print "Kommantar erkannt\n" if $debug; } @line = split(/ /,$_,3); # Zeile Parsen und in @line speichern $_ = $line[0]; # Default patternspace setzen if (/^#/) { # Zeile faengt mit '#' an -> Praeprozessorbefehl print "Bearbeite Zeile: @line\n" if $debug; SELECT: { # SELECT ist hier frei gewaehlt if (/#if/) { # Alle Ifbefehle (#if,#ifdef und #ifndef) if ($skip) { print "skipping nested if\n" if $debug; $ende = &read_block ($file,$cskip,$cfalse,'^#else$','^#endif$'); print "skipping nested else\n" if $debug && $ende eq "#else"; &read_block ($file,$cskip,$cfalse,'^#endif$') if $ende eq "#else"; last SELECT; } if (/#if$/) { $isif = &calc_value (join(" ",@line[1,2])); } else { $isif = defined ($symbol {$line[1]}); if (/#ifndef/) { $isif = ! $isif; } } if ( $isif ) { print "if\n" if $debug; $ende = &read_block ($file,$cread,$cfalse,'^#else$','^#endif$'); print "skipping else\n" if $debug && $ende eq "#else"; &read_block ($file,$cskip,$cfalse,'^#endif$') if $ende eq "#else"; } else { print "skipping if\n" if $debug; $ende = &read_block ($file,$cskip,$cfalse,'^#else$','^#endif$'); print "else\n" if $debug && $ende eq "#else"; &read_block ($file,$cread,$cfalse,'^#endif$') if $ende eq "#else"; } print "endif\n" if $debug; last SELECT; } last SELECT if $skip eq $cskip; #Der Rest ist egal (Skip von if und else) if (/#define/) { # print join(",",%symbol),"\n"; if (defined ($symbol {$line[1]}) ) { print "Symbol schon definiert: $line[1]\n"; } else { if (defined ($line[2])) { $symbol {$line[1]} = &calc_value ($line[2]); } else { $symbol {$line[1]} = ""; } print "setze $line[1] = ",$symbol {$line[1]},"\n" if $debug; if ( $line[1] =~ /^$namefilter/ ) { $mykey = $line[1]; $mykey =~ s/^$namefilter//; $count += 1; print OUT "$mykey ",$symbol {$line[1]},"\n"; print OUT2 "\t{ \"$mykey\", ",$symbol {$line[1]}," },\n"; } } last SELECT; } if (/#include/) { $_ = $line[1]; s/<(.*)>/$1/; # < .. > entfernen s/"(.*)"/$1/; # " .. " entfernene &read_file ($_,$file); # print "Include abgeklemmt!!!\n" if $debug; last SELECT; } if (/#pragma/) { print "Pragma Ignoriert!!!\n" if $debug; last SELECT; } if (/#error/) { die "Error: @line[1,2]\n";} # Ansonsten Fehlermeldung print "unbekannter Praeprozessorbefehl : \"$_\"\n"; } } if ($comment) { &read_block ($file,$cskip,$ctrue,'\*\/'); print "After comment $skip\n" if $debug; $comment = $cfalse; # redo main; # Schleifenrumpf mit Restzeile neu Durchlaufen # kann hier entfallen, da nur Praeprozessorbefehle vorhanden. } } } print "Leaving read_block at the end\n" if $debug; } sub convert_path { $_ = $_[0]; $GUI = $ENV {"GUI"}; $use_shell = $ENV {"USE_SHELL"}; if ( $GUI eq "WNT" ) { if ( defined( $use_shell ) && "$use_shell" eq "4nt" ) { s/\//\\/g; } } $_; } # Einlesen einer Datei. # der erste Parameter ist der Dateiname # Globale Variable %symbols enthaelt die Symboltabelle sub read_file { local ($filename,$file) = @_; $comment = $cfalse; # Am Dateianfang immer ausserhalb eines Kommentares $file++; # String increment local $TempFileName = &convert_path ($basename."/".$filename); print "reading file $TempFileName as $file\n" if $debug; if ( ! open($file, $TempFileName )) { print "Warning: Could not open file $TempFileName. "; $TempFileName = &convert_path ($basename."/../".$filename); print "Trying $TempFileName\n"; open($file, $TempFileName ) || print "Warning: Could not open file $TempFileName. Ignoring.\n" || return; #( die $basename."/../$filename $!" ) ; # Oeffnen der Datei zum lesen } &read_block($file,$cread,$cfalse); # Daten lesen close($file); print "done reading $filename\n" if $debug; } # Hauptprogramm beginnt hier print &convert_path ("//\n\n\n"); %symbol = ""; # Assotiatives Array initialisieren $basename = "."; $basename = $ARGV[0] if defined($ARGV[0]); $filename = "app.hrc"; $filename = $ARGV[1] if defined($ARGV[1]); $filebase = $filename; $filebase =~ s/\.[^.]+$//; # Schneidet den suffix ab $filebase = $ARGV[2] if defined($ARGV[2]); $namefilter = $ARGV[3] if defined($ARGV[3]); print "Generating $filebase:\n"; $count = 0; open(OUT,">$filebase"); open(OUT2,">$filebase.hxx"); print OUT2 "\{\n"; &read_file ($filename,"f00"); print OUT2 "\t{ \"\" ,0 }\n\};\n"; close(OUT); close(OUT2); if ( $count == 0 ) { die "Error: No Entries Found generating \"$filebase.hxx\". Testtool will not work!" }