diff options
author | Manoj Srivastava <srivasta@debian.org> | 2008-05-30 12:42:47 -0700 |
---|---|---|
committer | Manoj Srivastava <srivasta@debian.org> | 2008-05-30 12:42:47 -0700 |
commit | ceb3507a8fca872770b3dcd7e5c5b36179ab95b0 (patch) | |
tree | b46b4e25cfff5f4c13a330b8428ceed343e3796c /jmake/jmake.SH |
Import dist_3.5-236.orig.tar.gz
[dgit import orig dist_3.5-236.orig.tar.gz]
Diffstat (limited to 'jmake/jmake.SH')
-rwxr-xr-x | jmake/jmake.SH | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/jmake/jmake.SH b/jmake/jmake.SH new file mode 100755 index 0000000..3973185 --- /dev/null +++ b/jmake/jmake.SH @@ -0,0 +1,547 @@ +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +REVISION=`grep REVISION $TOP/revision.h | head -n1 | cut -d' ' -f4` +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac +echo "Extracting jmake/jmake (with variable substitutions)" +$spitshell >jmake <<!GROK!THIS! +$startperl + eval 'exec perl -S \$0 \${1+"\$@"}' + if \$runnning_under_some_shell; + +# $Id$ +# +# Copyright (c) 1991-1997, 2004-2006, Raphael Manfredi +# +# You may redistribute only under the terms of the Artistic Licence, +# as specified in the README file that comes with the distribution. +# You may reuse parts of this distribution only within the terms of +# that same Artistic Licence; a copy of which may be found at the root +# of the source tree for dist 4.0. +# +# $Log: jmake.SH,v $ +# Revision 3.0.1.9 2004/08/22 09:01:42 ram +# patch71: renamed |test as |case as the construct has its syntax +# patch71: added |subst section to allow variable substitutions +# +# Revision 3.0.1.8 2004/08/21 23:19:46 ram +# patch71: added '|shell' section to emit verbatim code in Makefile.SH +# patch71: new '|test' to conditionally generate Makefile sections +# +# Revision 3.0.1.7 2004/08/21 20:59:57 ram +# patch71: replaced old "do foo()" with modern "&foo()" syntax +# patch71: take care of junk emitted by GNU make when running commands +# patch71: new ^^^ escape sequence, removing extra spaces afterwards +# +# Revision 3.0.1.6 1995/09/25 09:08:01 ram +# patch59: will now force macro definitions to the left +# +# Revision 3.0.1.5 1995/07/25 13:34:47 ram +# patch56: all error messages are now prefixed with the program name +# +# Revision 3.0.1.4 1995/03/21 08:45:27 ram +# patch52: now invokes cpp through new fixcpp script +# patch52: first pass now skips cpp comments alltogether +# +# Revision 3.0.1.3 1994/10/29 15:47:01 ram +# patch36: added various escapes in strings for perl5 support +# +# Revision 3.0.1.2 1993/08/24 12:12:50 ram +# patch3: privlib dir was ~name expanded in the wrong place +# +# Revision 3.0.1.1 1993/08/19 06:42:13 ram +# patch1: leading config.sh searching was not aborting properly +# +# Revision 3.0 1993/08/18 12:04:17 ram +# Baseline for dist 3.0 netwide release. +# + +\$dir = '$privlib/files'; +\$cpp = '$cpp'; +\$version = '$VERSION'; +\$patchlevel = '$PATCHLEVEL'; +\$revision = '$REVISION'; +!GROK!THIS! +$spitshell >>jmake <<'!NO!SUBS!' + +($me = $0) =~ s|.*/(.*)|$1|; +$dir = &tilda_expand($dir); # ~name expansion +$file = $dir . '/Jmake.tmpl'; + +$cpp_opt = "-I. "; # For Jmakefile, which is local +while ($ARGV[0] =~ /^-/) { + $_ = shift; + last if /--/; + $cpp_opt .= "$_ "; +} +$cpp_opt .= "-I$dir"; + +# Pass 0 is looking at the template for "?CP:CP =" lines that are to be +# emitted if the CP variable is needed. Later on, when we see $(CP) being +# used, we'll be able to set the $symbol{CP} entry to 1 to have the CP +# variable initialized by the template. + +open(TMPL, $file) || die "$me: can't open $file: $!\n"; +while (<TMPL>) { + next unless /^\?([\w_]+):\1\s+=/; + $wanted{$1}++; +} +close TMPL; + +# Thank you HP-UX for having a cpp that blindly strips trailing backslashes +# in the text. Run through cpp by using the fixcpp script... + +open(CPP, "$dir/fixcpp $cpp_opt $file |"); +while (<CPP>) { + # Record defined symbols in Jmakefile. We won't catch symbols + # in conditional commands, but that's ok, I hope. + if ($in_symbol) { + $val = $_; + $in_symbol = 0 if !($val =~ s/\\\s*$//); # Last line + if ($val = /^\|expand/) { # Found an expand command + $in_symbol = 0; # Stop gathering value + $val .= "void::x"; # Stop any incomplete escape sequence + } + chop($val); + $Makesym{$current_symbol} .= $val; + } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) { + # Found a makefile's macro declaration + $val = $2; + $current_symbol = $1; + if ($val =~ s/\\\s*$//) { # Remove final '\' + $in_symbol = 1; # This is a continuation line + } + $Makesym{$current_symbol} = $val; + push(@Order, $current_symbol); # Keep track of order + } + # Protect RCS keyword Id or Header from normal substitution + s/\$(Id|Header|Log)/\$X-$1/; + # Restore possibly escaped C comments + s|/#\*|/*|g; + s|\*#/|*/|g; + # Remove all ^^^ (null space character) up to next non-space character + s|\^\^\^\s*||g; + # Remove all ^^ (null space character) + s|\^\^||g; + # Restore escaped ^^ and ^^^ sequences + s|\^\\\^\\\^|^^^|g; + s|\^\\\^|^^|g; + next if /^#\s+\d+/; # Skip cpp commments + + s/^;#/#/; + s/@#\s?/\n/g; # Kept for backward compatibility + s/@!\s?/\n/g; + s/@@\s?/\n\t/g; + + # A '\r' is added to all lines, in order to let 'split' keep them + # As lines ending with '\' won't fit in the next regular + # expression (why ?), we have to treat that special case separately + s/\n$/\r\n/gm; + s/\\\s*$/\\\r/gm; # Remove spaces after final '\' and add '\r' + @macro = split(/\n/); + for ($i = 0; $i <= $#macro; $i++) { + chop($_ = $macro[$i]); # Remove final '\r' + s/\s+$//g; # Remove possible useless spaces + if (/^TOP\s*=\s*(\S+)/) { # Get the top from generated file + $top = $1; + } + find_wanted($_); # Look for known $(VAR) usage + if (s/^\s*>//) { # '>' means "symbol wanted" + warn "$me: the '>$_' construct is deprecated for known symbols\n" + if $wanted{$_} && !$warned_wanted_symbol_deprecated++; + $symbol{$_} = 1; + } elsif (s/^\s*\+//) { # '+' means "initialization section" + if (s/^\+(\w+)//) { # '++' means add to variable list + $added{$1} .= $_; + } else { # A single '+' means "add as is". + push(@init, $_); + } + } elsif (s/^\|//) { # Command for us + if (/suffix\s+(\S+)/) { # Add suffix + push(@suffix, $1) unless $seen{$1}; + $seen{$1} = 1; + } elsif (s/^rule://) { # Add building rule + s/^\s(\s*\S+)/\t$1/; # Make sure leading tab is there + push(@rule, $_); + } elsif (/^skip/) { # Unconditional skip... funny! + push(@makefile, "|$_"); # Skip handled in pass 2 + } elsif (/^expand/) { + push(@makefile, "|$_"); # Expand handled in pass 2 + } elsif (/^once\s+(.*)/) { # Once handled in pass 1 + if ($Once{$1}++) { # Symbol already seen -- skip + for (; $i <= $#macro; $i++) { + last if $macro[$i] =~/^-once/; + } + warn("$me: -once not found for $1") + unless $macro[$i] =~/^-once/; + } + } elsif (/^shell/) { # Escaping to shell + push(@makefile, "|$_"); # will be handled in pass 2 + } elsif (/^case/) { # Conditional generation + push(@makefile, "|$_"); # will be handled in pass 2 + } elsif (/^subst/) { # Section with var substitution + push(@makefile, "|$_"); # will be handled in pass 2 + } else { + print "$me: Warning: unknown command $_\n"; + } + } else { + next if /^-once/; # Control statement removed + push(@makefile, $_); + } + } +} +close CPP; + +@key = keys(%added); +$last_was_blank = 1; # To avoid blank line at the top of the file +$symbol{'INIT'} = 1 if ($#init >= 0 || $#key >=0); # Initializations +$symbol{'SUFFIX'} = 1 if ($#suffix >= 0 || $#rule >=0); # Rules or suffixes +$symbol{'TOP'} = 1 if $top eq '.'; # If imake invoked for the top + +$shellmode = 0; # Set to true within "shell" section +$casemode = 0; # Counts nesting levels within "case" section +$substmode = 0; # True when within section with variable substitution + +$SPIT_START = "\$spitshell >>Makefile <<'!NO!SUBS!'\n"; +$SPIT_END = "!NO!SUBS!\n"; +$GROK_START = "\$spitshell >>Makefile <<!GROK!THIS!\n"; +$GROK_END = "!GROK!THIS!\n"; + +%target = (); # Will record seen targets (actually generated) + +open(MAKEFILE, ">Makefile.SH"); +# We have to use for instead of foreach to handle 'skip' easily +line: for ($i = 0; $i <= $#makefile; $i++) { + $_ = $makefile[$i]; + next if /^-skip|-expand/; # They might have made a mistake + + # Strip consecutive blank lines in generated file + + if (/^\s*$/) { + next if ($last_was_blank); + $last_was_blank = 1; + } else { + $last_was_blank = 0; + } + + # In shell mode, we're transparent, untill we reach a "-shell" + # We don't call print_makefile() as we don't want to record + # those non-makefile lines in the @Generated array. + + if ($shellmode) { + if (/^-shell/) { # Ending shell mode, back to Makefile + print MAKEFILE $substmode ? $GROK_START : $SPIT_START; + $shellmode = 0; + } elsif (/^\|shell/) { + die "$me: can't nest 'shell' sections.\n"; + } else { + print MAKEFILE "$_\n"; + } + next; + } elsif (/^\|shell/) { + print MAKEFILE $substmode ? $GROK_END : $SPIT_END; + $shellmode = 1; # Next lines emitted verbatim as shell + next; + } + + # In subst mode, the section until "-subst" is emitted regularily, + # excepted that it will be in a grok section, so its $var will be + # substituted by the shell. + + if ($substmode) { + if (/^-subst/) { # Ending subst mode, back to regular + print MAKEFILE $GROK_END; + print MAKEFILE $SPIT_START; + $substmode = 0; + next; + } elsif (/^\|subst/) { + die "$me: can't nest 'subst' sections.\n"; + } + # Continue with line + } elsif (/^\|subst/) { + print MAKEFILE $SPIT_END; # End spit section in Makefile.SH + print MAKEFILE $GROK_START; + $substmode = 1; # Next lines subject to $ interpretation + next; + } + + # In a "case" section, the Makefile will be conditionally generated + # based on the value of the supplied variable, as evaluated by the shell. + # We can nest "case" sections without problems. + + if (/^-case/) { # Ending current case section + if ($casemode == 0) { + warn "$me: ignoring spurious '-case'\n"; + next; + } + print MAKEFILE $substmode ? $GROK_END : $SPIT_END; + my $indent = "\t" x ($casemode - 1); + print MAKEFILE "${indent}\t;;\n"; + print MAKEFILE "${indent}esac\n"; + print MAKEFILE "${indent}", $substmode ? $GROK_START : $SPIT_START; + $casemode--; + next; + } + + if (/^\|case/) { + my ($var, $value) = /^\|case\s+(\w+)\s+in\s+(.*)/; + die "$me: unparseable directive '$_'\n" if $var eq ''; + $casemode++; + print MAKEFILE $substmode ? $GROK_END : $SPIT_END; + my $indent = "\t" x ($casemode - 1); + print MAKEFILE "${indent}case \"\$$var\" in\n"; + print MAKEFILE "${indent}$value)\n"; + print MAKEFILE "${indent}\t", $substmode ? $GROK_START : $SPIT_START; + next; + } + + # Process regular line to be generated in Makefile.SH + + s/<TAG>/[jmake $version-$revision]/; + + # Lines starting with ?target?: (resp. %target%:) are to be processd + # only when target is used (resp. unused) in the generated makefile. + + # Apply in sequence + while (/^\s*\?|\s*%/) { + if (s/^\s*\?([\w-.]+)\?://) { # Wanted target ? + next line unless $target{$1}; + } elsif (s/^\s*%([\w-.]+)%://) { # Unwanted target ? + next line if $target{$1}; + } else { + last; + } + } + + # Lines starting with ?SYMBOL: (resp. %SYMBOL:) are to be processed + # only if SYMBOL is defined (resp. undefined). + + # Apply in sequence + while (/^\s*\?|\s*%/) { + if (s/^\s*\?(\w+)://) { # Wanted symbol ? + next line unless $symbol{$1}; + } elsif (s/^\s*%(\w+)://) { # Unwanted symbol ? + next line if $symbol{$1}; + } else { + print "$me: Warning: missing ':' in $_\n"; + last; + } + } + + # We wish to make sure there is a leading tab if the line starts with + # a space to prevent problems later on. However, variable definitions + # might want to be aligned on the '=' (imake style). Not all make + # may be able to cope with those though, so they are left justified + # again. + + s/^\s/\t/ unless /^\s+\w+\s+=/; # Make sure leading tab is there + s/^\s+(\w+\s+=)/$1/; # Left justify variable definition + s/^;#/#/; # Comments in Jmakefile + + if (s/^\|//) { # Command for us + if (/^skip/) { # Skip until -skip + for (; $i <= $#makefile; $i++) { + last if $makefile[$i] =~ /^-skip/; + } + } elsif (s/^expand//) { + &init_expand($_); # Initializes data structures + $i++; # Skip expand line + undef @Expand; # Storage for expanded lines + $pattern = ''; # Assume no pattern + for (; $i <= $#makefile; $i++) { + $_ = $makefile[$i]; + if (s/^-expand//) { # Reached end of expansion + if (s/^\s*(.*)/$1/) { # Expand followed by a pattern + $pattern = $_; # Get pattern to be removed + } + last; + } + s/^\s/\t/; # Make sure leading tab is there + push(@Expand, $_); # Line to be expanded + } + &expand($pattern); # Expand all lines in buffer + } else { + die "$me: unknown command $_\n"; + } + } elsif (/^INIT/) { # Initialization section + # All the initializations are put in the variable substitution + # section of the Makefile.SH. Therefore, we have to protect all + # the '$' signs that are not followed by an alphanumeric character. + foreach (@init) { + # Dumps core sometimes with perl 4.0 PL10 + # &protect_dollars(*_); + $_ = &protect_dollars($_); + &print_makefile($_); + } + foreach (@key) { # @key set earlier to keys(%added) + $_ .= " = " . $added{$_}; + # Dumps core sometimes with perl 4.0 PL10 + # &protect_dollars(*_); + $_ = &protect_dollars($_); + &print_makefile($_); + } + } elsif (/^SUFFIX/) { # Suffixes/Rules section + # Rules and suffixes are put in the variable substitution + # section of the Makefile.SH. Therefore, we have to protect all + # the '$' signs that are not followed by an alphanumeric character. + if ($#suffix >= 0) { + print MAKEFILE ".SUFFIXES:"; + foreach (@suffix) { + # Dumps core sometimes with perl 4.0 PL10 + # &protect_dollars(*_); + $_ = &protect_dollars($_); + print MAKEFILE " $_"; + } + print MAKEFILE "\n\n"; + } + foreach (@rule) { + # Dumps core sometimes with perl 4.0 PL10 + # &protect_dollars(*_); + $_ = &protect_dollars($_); + print MAKEFILE "$_\n"; + } + } else { + # Keep track of the targets we generate for ?target? and %target% type + # of tests in the templates, which can generate specific code when + # a target is indeed present. + $target{$1}++ if /^([\w.-]+):/; + + &print_makefile($_); + } +} +close MAKEFILE; + +sub protect_dollars { + # Dumps core sometimes with perl 4.0 PL10 + # local(*_) = shift(@_); + s/\\\$/\\=/g; # Protect already escaped '$' + s/(\$\W)/\\$1/g; # Escape unprotected '$' + s/\\=/\\\$/g; # Restore escaped '$' + $_; # Because perl dumps core... :-( +} + +# Initializes data structures for expansion. If we detect Makefile +# macro in the 'expand' line (the argument), then we write a small +# makefile that will do the substitution for us -- I'm lazy today :-) +sub init_expand { + local($_) = shift(@_); + undef %Vars; # Reset array of variables + $Vars_len = 0; # Number of "symbols" in first expanded + if (/\$\(\w+\)/) { # If at least one macro + local($make) = "/tmp/mkjm$$"; + open(MAKE, ">$make") || die "$me: can't create $make: $!\n"; + &gen_variables(); # Generates already computed variables + foreach $var (@Order) { # Print each in order we found them + print MAKE "$var = $Makesym{$var}\n" if !$Gvars{$var}; + } + # We prepend OUTPUT: in front of the line that interests us, because + # some makes can print extra information, especially GNU make with + # its entering/leaving blurb when invoked from another makefile. + print MAKE "all:\n\t\@echo 'OUTPUT: $_'\n"; + close MAKE; + chop($_ = `make -f $make all | grep ^OUTPUT:`); + unlink($make); + } + s/^OUTPUT: //; + while (s/^\s*(\w+)!([^!]*)!//) { + $Vars{$1} = $2; + # Record only length for _first_ expanded symbol + $Vars_len = split(/\s\s*/, $2) unless $Vars_len; + } +} + +# Expand lines in the @Expand array. The argument is a pattern which is to +# be removed from the last chunk of expanded lines. +# For each symbol s, !s is replaced by the next item, and !s:p=q does the +# same after having replaced the pattern 'p' by pattern 'q' in the item. +# Spaces are NOT allowed in 'p' or 'q'. Substitution is done once (no /g). +sub expand { + local($pattern) = shift; # To-be-removed pattern for last chunk + local($_); + local($sub); + local($i); + local(@expands); + for ($i = 0; $i < $Vars_len; $i++) { + foreach $line (@Expand) { + $_ = $line; # Don't modify elements in array + foreach $sym (keys %Vars) { + @expands = split(/\s\s*/, $Vars{$sym}); + $sub = $expands[$i]; + $sub =~ s/\/\///g; # // is a void value + while (s/!${sym}:([^\s]*)=([^\s]*)/,x##x,/) { + # Replacing item is altered by some pattern + local($p) = $1; + local($q) = $2; + local($subq) = $sub; + eval "\$subq =~ s=${p}=${q}="; + s/,x##x,/${subq}/; + } + s/!${sym}/${sub}/g; + } + # Protect substitution in an 'eval' in case of error + eval "s/${pattern}\$//" if $pattern && $i == ($Vars_len - 1); + &print_makefile($_); + } + } +} + +# Prints its argument in MAKEFILE and records it also in Generated +sub print_makefile { + local($_) = shift(@_); # Line to be printed + print MAKEFILE "$_\n"; + push(@Generated, "$_\n"); +} + +# Generates in MAKE file all the generated variable we have so far for +# final Makefile. This is mainly intended to allow expansion of variables +# which are already defined with an expand. +sub gen_variables { + undef %Gvars; # Reset already generated variables + local ($in_symbol) = 0; # True when in variable (Makefile's macro) + foreach (@Generated) { + if ($in_symbol) { + if (/^\s*(\w+)\s*=(.*)/) { # Missed the end of previous macro + $in_symbol = 0; + $Gvars{$1} = 1; # Definition of variable seen + $in_symbol = 1 if (/\\\s*$/); # There is a final '\' + print MAKE "void::\n"; # Cut incomplete esc sequence + } else { + $in_symbol = 0 if !(/\\\s*$/); # Last line + } + print MAKE; + } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) { + # Found a makefile's macro declaration + $Gvars{$1} = 1; # Definition of variable seen + $in_symbol = 1 if (/\\\s*$/); # There is a final '\' + print MAKE; + } + } + print MAKE "void::\n"; # Cut incomplete escape sequence +} + +# Parse line to extract all $(VAR) usage and trigger the symbol if VAR +# is among the wanted set, as if they had manually said ">VAR" like in +# the old days. +sub find_wanted { + my ($l) = @_; + while ($l =~ s/\$\(([\w_]+)\)//) { + $symbol{$1}++ if $wanted{$1}; + } +} + +!NO!SUBS! +$grep -v '^;#' ../pl/tilde.pl >>jmake +chmod 755 jmake +$eunicefix jmake |