This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Populate metaconfig branch.
[metaconfig.git] / dist-3.0at70b / jmake / jmake.SH
1 case $CONFIG in
2 '')
3         if test -f config.sh; then TOP=.;
4         elif test -f ../config.sh; then TOP=..;
5         elif test -f ../../config.sh; then TOP=../..;
6         elif test -f ../../../config.sh; then TOP=../../..;
7         elif test -f ../../../../config.sh; then TOP=../../../..;
8         else
9                 echo "Can't find config.sh."; exit 1
10         fi
11         . $TOP/config.sh
12         ;;
13 esac
14 case "$0" in
15 */*) cd `expr X$0 : 'X\(.*\)/'` ;;
16 esac
17 echo "Extracting jmake/jmake (with variable substitutions)"
18 $spitshell >jmake <<!GROK!THIS!
19 $startperl
20         eval 'exec perl -S \$0 "\$@"'
21                 if \$runnning_under_some_shell;
22
23 # $Id: jmake.SH,v 3.0.1.6 1995/09/25 09:08:01 ram Exp $
24 #
25 #  Copyright (c) 1991-1993, Raphael Manfredi
26 #  
27 #  You may redistribute only under the terms of the Artistic Licence,
28 #  as specified in the README file that comes with the distribution.
29 #  You may reuse parts of this distribution only within the terms of
30 #  that same Artistic Licence; a copy of which may be found at the root
31 #  of the source tree for dist 3.0.
32 #
33 # $Log: jmake.SH,v $
34 # Revision 3.0.1.6  1995/09/25  09:08:01  ram
35 # patch59: will now force macro definitions to the left
36 #
37 # Revision 3.0.1.5  1995/07/25  13:34:47  ram
38 # patch56: all error messages are now prefixed with the program name
39 #
40 # Revision 3.0.1.4  1995/03/21  08:45:27  ram
41 # patch52: now invokes cpp through new fixcpp script
42 # patch52: first pass now skips cpp comments alltogether
43 #
44 # Revision 3.0.1.3  1994/10/29  15:47:01  ram
45 # patch36: added various escapes in strings for perl5 support
46 #
47 # Revision 3.0.1.2  1993/08/24  12:12:50  ram
48 # patch3: privlib dir was ~name expanded in the wrong place
49 #
50 # Revision 3.0.1.1  1993/08/19  06:42:13  ram
51 # patch1: leading config.sh searching was not aborting properly
52 #
53 # Revision 3.0  1993/08/18  12:04:17  ram
54 # Baseline for dist 3.0 netwide release.
55 #
56
57 \$dir = '$privlib/files';
58 \$cpp = '$cpp';
59 \$version = '$VERSION';
60 \$patchlevel = '$PATCHLEVEL';
61 !GROK!THIS!
62 $spitshell >>jmake <<'!NO!SUBS!'
63
64 ($me = $0) =~ s|.*/(.*)|$1|;
65 $dir = &tilda_expand($dir);             # ~name expansion
66 $file = $dir . '/Jmake.tmpl';
67
68 $cpp_opt = "-I. ";                              # For Jmakefile, which is local
69 while ($ARGV[0] =~ /^-/) {
70         $_ = shift;
71         last if /--/;
72         $cpp_opt .= "$_ ";
73 }
74 $cpp_opt .= "-I$dir";
75
76 # Thank you HP-UX for having a cpp that blindly strips trailing backslashes
77 # in the text. Run through cpp by using the fixcpp script...
78
79 open(CPP, "$dir/fixcpp $cpp_opt $file |");
80 while (<CPP>) {
81         # Record defined symbols in Jmakefile. We won't catch symbols
82         # in conditional commands, but that's ok, I hope.
83         if ($in_symbol) {
84                 $val = $_;
85                 $in_symbol = 0 if !($val =~ s/\\\s*$//);        # Last line
86                 if ($val = /^\|expand/) {               # Found an expand command
87                         $in_symbol = 0;                         # Stop gathering value
88                         $val .= "void::x";                      # Stop any incomplete escape sequence
89                 }
90                 chop($val);
91                 $Makesym{$current_symbol} .= $val;
92         } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) {
93                 # Found a makefile's macro declaration
94                 $val = $2;
95                 $current_symbol = $1;
96                 if ($val =~ s/\\\s*$//) {       # Remove final '\'
97                         $in_symbol = 1;                 # This is a continuation line
98                 }
99                 $Makesym{$current_symbol} = $val;
100                 push(@Order, $current_symbol);  # Keep track of order
101         }
102         # Protect RCS keyword Id or Header from normal substitution
103         s/\$(Id|Header|Log)/\$X-$1/;
104         # Restore possibly escaped C comments
105         s|/#\*|/*|g;
106         s|\*#/|*/|g;
107         # Remove all ^^ (null space character)
108         s|\^\^||g;
109         # Restore escaped ^^ sequence
110         s|\^\\\^|^^|g;
111         next if /^#\s+\d+/;             # Skip cpp commments
112
113         s/^;#/#/;
114         s/@#\s?/\n/g;           # Kept for backward compatibility
115         s/@!\s?/\n/g;
116         s/@@\s?/\n\t/g;
117
118         $* = 1;
119         # A '\r' is added to all lines, in order to let 'split' keep them
120         # As lines ending with '\' won't fit in the next regular
121         # expression (why ?), we have to treat that special case separately
122         s/\n$/\r\n/g;
123         s/\\\s*$/\\\r/g;        # Remove spaces after final '\' and add '\r'
124         $* = 0;
125         @macro = split(/\n/);
126         for ($i = 0; $i <= $#macro; $i++) {
127                 chop($_ = $macro[$i]);                          # Remove final '\r'
128                 s/\s+$//g;                                                      # Remove possible useless spaces
129                 if (/^TOP\s*=\s*(\S+)/) {                       # Get the top from generated file
130                         $top = $1;
131                 }
132                 if (s/^\s*>//) {                                        # '>' means "symbol wanted"
133                         $symbol{$_} = 1;
134                 } elsif (s/^\s*\+//) {                          # '+' means "initialization section"
135                         if (s/^\+(\w+)//) {                             # '++' means add to variable list
136                                 $added{$1} .= $_;
137                         } else {                                                # A single '+' means "add as is".
138                                 push(@init, $_);
139                         }
140                 } elsif (s/^\|//) {                                     # Command for us
141                         if (/suffix\s+(\S+)/) {                 # Add suffix
142                                 push(@suffix, $1) unless $seen{$1};
143                                 $seen{$1} = 1;
144                         } elsif (s/^rule://) {                  # Add building rule
145                                 s/^\s(\s*\S+)/\t$1/;            # Make sure leading tab is there
146                                 push(@rule, $_);
147                         } elsif (/^skip/) {                             # Unconditional skip... funny!
148                                 push(@makefile, "|$_");         # Skip handled in pass 2
149                         } elsif (/^expand/) {
150                                 push(@makefile, "|$_");         # Expand handled in pass 2
151                         } elsif (/^once\s+(\S+)/) {             # Once handled in pass 1
152                                 if ($Once{$1}++) {                      # Symbol already seen -- skip
153                                         for (; $i <= $#macro; $i++) {
154                                                 last if $macro[$i] =~/^-once/;
155                                         }
156                                         warn("$me: -once not found for $1")
157                                                 unless $macro[$i] =~/^-once/;
158                                 }
159                         } else {
160                                 print "$me: Warning: unknown command $_\n";
161                         }
162                 } else {
163                         next if /^-once/;                       # Control statement removed
164                         push(@makefile, $_);
165                 }
166         }
167 }
168 close CPP;
169
170 @key = keys(%added);
171 $last_was_blank = 1;    # To avoid blank line at the top of the file
172 $symbol{'INIT'} = 1 if ($#init >= 0 || $#key >=0);              # Initializations
173 $symbol{'SUFFIX'} = 1 if ($#suffix >= 0 || $#rule >=0); # Rules or suffixes
174 $symbol{'TOP'} = 1 if $top eq '.';              # If imake invoked for the top
175
176 open(MAKEFILE, ">Makefile.SH");
177 # We have to use for instead of foreach to handle 'skip' easily
178 line: for ($i = 0; $i <= $#makefile; $i++) {
179         $_ = $makefile[$i];
180         next if /^-skip|-expand/;               # They might have made a mistake
181
182         s/<TAG>/[jmake $version PL$patchlevel]/;
183         if (/^\s*$/) {
184                 next if ($last_was_blank);
185                 $last_was_blank = 1;
186         } else {
187                 $last_was_blank = 0;
188         }
189
190         # Lines starting with ?SYMBOL: (resp. %SYMBOL:) are to be processed
191         # only if SYMBOL is defined (resp. undefined).
192
193         # Apply in sequence
194         while (/^\s*\?|\s*%/) {
195                 if (s/^\s*\?(\w+)://) {                                 # Wanted symbol ?
196                         next line unless $symbol{$1};
197                 } elsif (s/^\s*%(\w+)://) {                             # Unwanted symbol ?
198                         next line if $symbol{$1};
199                 } else {
200                         print "$me: Warning: missing ':' in $_\n";
201                         last;
202                 }
203         }
204
205         # We wish to make sure there is a leading tab if the line starts with
206         # a space to prevent problems later on. However, variable definitions
207         # might want to be aligned on the '=' (imake style). Not all make
208         # may be able to cope with those though, so they are left justified
209         # again.
210
211         s/^\s/\t/ unless /^\s+\w+\s+=/;         # Make sure leading tab is there
212         s/^\s+(\w+\s+=)/$1/;                            # Left justify variable definition
213         s/^;#/#/;                                                       # Comments in Jmakefile
214
215         if (s/^\|//) {                                                  # Command for us
216                 if (/^skip/) {                                          # Skip until -skip
217                         for (; $i <= $#makefile; $i++) {
218                                 last if $makefile[$i] =~ /^-skip/;
219                         }
220                 } elsif (s/^expand//) {
221                         do init_expand($_);                     # Initializes data structures
222                         $i++;                                           # Skip expand line
223                         undef @Expand;                          # Storage for expanded lines
224                         $pattern = '';                          # Assume no pattern
225                         for (; $i <= $#makefile; $i++) {
226                                 $_ = $makefile[$i];
227                                 if (s/^-expand//) {                     # Reached end of expansion
228                                         if (s/^\s*(.*)/$1/) {   # Expand followed by a pattern
229                                                 $pattern = $_;          # Get pattern to be removed
230                                         }
231                                         last;
232                                 }
233                                 s/^\s/\t/;                              # Make sure leading tab is there
234                                 push(@Expand, $_);              # Line to be expanded
235                         }
236                         do expand($pattern);            # Expand all lines in buffer
237                 } else {
238                         print "$me: Warning: unknown command $_\n";
239                 }
240         } elsif (/^INIT/) {                                             # Initialization section
241                 # All the initializations are put in the variable substitution
242                 # section of the Makefile.SH. Therefore, we have to protect all
243                 # the '$' signs that are not followed by an alphanumeric character.
244                 foreach (@init) {
245                         # Dumps core sometimes with perl 4.0 PL10
246                         # do protect_dollars(*_);
247                         $_ = do protect_dollars($_);
248                         do print_makefile($_);
249                 }
250                 foreach (@key) {        # @key set earlier to keys(%added)
251                         $_ .= " = " . $added{$_};
252                         # Dumps core sometimes with perl 4.0 PL10
253                         # do protect_dollars(*_);
254                         $_ = do protect_dollars($_);
255                         do print_makefile($_);
256                 }
257         } elsif (/^SUFFIX/) {                                   # Suffixes/Rules section
258                 # Rules and suffixes are put in the variable substitution
259                 # section of the Makefile.SH. Therefore, we have to protect all
260                 # the '$' signs that are not followed by an alphanumeric character.
261                 if ($#suffix >= 0) {
262                         print MAKEFILE ".SUFFIXES:";
263                         foreach (@suffix) {
264                                 # Dumps core sometimes with perl 4.0 PL10
265                                 # do protect_dollars(*_);
266                                 $_ = do protect_dollars($_);
267                                 print MAKEFILE " $_";
268                         }
269                         print MAKEFILE "\n\n";
270                 }
271                 foreach (@rule) {
272                         # Dumps core sometimes with perl 4.0 PL10
273                         # do protect_dollars(*_);
274                         $_ = do protect_dollars($_);
275                         print MAKEFILE "$_\n";
276                 }
277         } else {
278                 do print_makefile($_);
279         }
280 }
281 close MAKEFILE;
282
283 sub protect_dollars {
284         # Dumps core sometimes with perl 4.0 PL10
285         # local(*_) = shift(@_);
286         s/\\\$/\\=/g;           # Protect already escaped '$'
287         s/(\$\W)/\\$1/g;        # Escape unprotected '$'
288         s/\\=/\\\$/g;           # Restore escaped '$'
289         $_;                                     # Because perl dumps core... :-(
290 }
291
292 # Initializes data structures for expansion. If we detect Makefile
293 # macro in the 'expand' line (the argument), then we write a small
294 # makefile that will do the substitution for us -- I'm lazy today :-)
295 sub init_expand {
296         local($_) = shift(@_);
297         undef %Vars;            # Reset array of variables
298         $Vars_len = 0;          # Number of "symbols" in first expanded
299         if (/\$\(\w+\)/) {      # If at least one macro
300                 local($make) = "/tmp/mkjm$$";
301                 open(MAKE, ">$make") || die "$me: can't create $make: $!\n";
302                 do gen_variables();                     # Generates already computed variables
303                 foreach $var (@Order) {         # Print each in order we found them
304                         print MAKE "$var = $Makesym{$var}\n" if !$Gvars{$var};
305                 }
306                 print MAKE "all:\n\t\@echo '$_'\n";
307                 close MAKE;
308                 chop($_ = `make -f $make all`);
309                 unlink($make);
310         }
311         while (s/^\s*(\w+)!([^!]*)!//) {
312                 $Vars{$1} = $2;
313                 # Record only length for _first_ expanded symbol
314                 $Vars_len = split(/\s\s*/, $2) unless $Vars_len;
315         }
316 }
317
318 # Expand lines in the @Expand array. The argument is a pattern which is to
319 # be removed from the last chunk of expanded lines.
320 # For each symbol s, !s is replaced by the next item, and !s:p=q does the
321 # same after having replaced the pattern 'p' by pattern 'q' in the item.
322 # Spaces are NOT allowed in 'p' or 'q'. Substitution is done once (no /g).
323 sub expand {
324         local($pattern) = shift;                # To-be-removed pattern for last chunk
325         local($_);
326         local($sub);
327         local($i);
328         local(@expands);
329         for ($i = 0; $i < $Vars_len; $i++) {
330                 foreach $line (@Expand) {
331                         $_ = $line;             # Don't modify elements in array
332                         foreach $sym (keys %Vars) {
333                                 @expands = split(/\s\s*/, $Vars{$sym});
334                                 $sub = $expands[$i];
335                                 $sub =~ s/\/\///g;              # // is a void value
336                                 while (s/!${sym}:([^\s]*)=([^\s]*)/,x##x,/) {
337                                         # Replacing item is altered by some pattern
338                                         local($p) = $1;
339                                         local($q) = $2;
340                                         local($subq) = $sub;
341                                         eval "\$subq =~ s=${p}=${q}=";
342                                         s/,x##x,/${subq}/;
343                                 }
344                                 s/!${sym}/${sub}/g;
345                         }
346                         # Protect substitution in an 'eval' in case of error
347                         eval "s/${pattern}\$//" if $pattern && $i == ($Vars_len - 1);
348                         do print_makefile($_);
349                 }
350         }
351 }
352
353 # Prints its argument in MAKEFILE and records it also in Generated
354 sub print_makefile {
355         local($_) = shift(@_);          # Line to be printed
356         print MAKEFILE "$_\n";
357         push(@Generated, "$_\n");
358 }
359
360 # Generates in MAKE file all the generated variable we have so far for
361 # final Makefile. This is mainly intended to allow expansion of variables
362 # which are already defined with an expand.
363 sub gen_variables {
364         undef %Gvars;                           # Reset already generated variables
365         local ($in_symbol) = 0;         # True when in variable (Makefile's macro)
366         foreach (@Generated) {
367                 if ($in_symbol) {
368                         if (/^\s*(\w+)\s*=(.*)/) {              # Missed the end of previous macro
369                                 $in_symbol = 0;
370                                 $Gvars{$1} = 1;                                 # Definition of variable seen
371                                 $in_symbol = 1 if (/\\\s*$/);   # There is a final '\'
372                                 print MAKE "void::\n";                  # Cut incomplete esc sequence
373                         } else  {
374                                 $in_symbol = 0 if !(/\\\s*$/);  # Last line
375                         }
376                         print MAKE;
377                 } elsif (/^\s*(\w+)\s*=(.*)/ && !$in_symbol) {
378                         # Found a makefile's macro declaration
379                         $Gvars{$1} = 1;                                 # Definition of variable seen
380                         $in_symbol = 1 if (/\\\s*$/);   # There is a final '\'
381                         print MAKE;
382                 }
383         }
384         print MAKE "void::\n";          # Cut incomplete escape sequence
385 }
386
387 !NO!SUBS!
388 $grep -v '^;#' ../pl/tilde.pl >>jmake 
389 chmod 755 jmake
390 $eunicefix jmake