#!/usr/bin/perl # # jcpp Copyright (C) 1999 Jochen Hoenicke. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. # # $Id$ # This is a program to allow conditional compiled code in java files. # The key idea is, not to run the file always through the # preprocessor, but to modify the java files directly and make use of # comments. # # The comments all have the form /// to distinguish them from normal # comments. You should not use such comments yourself. # # Usage is simple: jcpp -Ddefine1 -Ddefine2 first.java second.java # The files should contain comments of the form # # ///#ifdef JDK12 # jdk1.2 code # ///#else # jdk1.1 code # ///#endif # # After running jcpp the false branch is commented out. If the true # branch was commented out it will get commented in. my @files; my %defs; for (@ARGV) { if ($_ =~ /^-D([^=]*)$/) { $defs{$1} = 1; } elsif ($_ =~ /^-D([^=]*)=([^=]*)$/) { $defs{$1} = $2; } else { push @files, $_; } } for (@files) { my $file = $_; my $branch = "none"; my $level = 0; rename "$file", "$file.orig" or do { print STDERR "Can't open file $file\n"; next; }; open OLD, "<$file.orig"; open NEW, ">$file"; my $linenr = 0; while () { $linenr++; if (/^\/\/\/\#/) { # This is a directive. First we print it out. print NEW $_; if (/^\/\/\/\#ifdef (\S*)$/) { my $label=$1; # An ifdef directive, look if -D is defined, but only # if we are not in a false branch. In a false branch # we simply increase level. if ($branch eq "false") { $level++; } else { if (defined $defs{$label}) { $branch = "true"; } else { $branch = "false"; $level = 0; } } } elsif (/^\/\/\/\#ifndef (\S*)$/) { my $label=$1; # An ifndef directive, look if -D is defined, but only # if we are not in a false branch. In a false branch # we simply increase level. if ($branch eq "false") { $level++; } else { if (defined $defs{$label}) { $branch = "false"; $level = 0; } else { $branch = "true"; } } } elsif (/^\/\/\/\#else/) { # An else directive. We switch from true to false and # if level is zero we switch from false to true if ($branch eq "true") { $branch = "false"; $level = 0; } elsif ($branch eq "false") { $branch = "true" if ($level == 0); } else { # An else outside of any directives; warn. print STDERR "$file: $linenr: ignoring unmatched $_"; } } elsif (/^\/\/\/\#endif/) { if ($branch eq "none") { # An endif outside of any directives; warn. print STDERR "$file: $linenr: ignoring unmatched $_"; } elsif ($branch eq "false") { $branch = "true" if ($level-- == 0); } } else { print STDERR "$file: $linenr: ignoring unknown directive $_"; } } elsif (/^\/\/\/(.*)/) { $line = $1; if ($branch eq "true") { # remove comments in true branch; print NEW "$line\n"; } else { # print out the full line with comments: print NEW $_; } } else { if ($branch eq "false") { # add comments in false branch print NEW "///$_"; } else { print NEW $_; } } } }