diff options
Diffstat (limited to 'mcon/pl/common.pl')
-rw-r--r-- | mcon/pl/common.pl | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/mcon/pl/common.pl b/mcon/pl/common.pl new file mode 100644 index 0000000..0d1ea5a --- /dev/null +++ b/mcon/pl/common.pl @@ -0,0 +1,289 @@ +;# $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: common.pl,v $ +;# Revision 3.0.1.4 1994/10/29 16:35:01 ram +;# patch36: metaconfig and metaxref ignore ?F: lines from now on +;# +;# Revision 3.0.1.3 1994/05/13 15:29:04 ram +;# patch27: now understands macro definitions in ?H: lines +;# +;# Revision 3.0.1.2 1994/01/24 14:22:54 ram +;# patch16: can now define "internal use only" variables on ?MAKE: lines +;# +;# Revision 3.0.1.1 1993/10/16 13:53:29 ram +;# patch12: added support for ?M: lines and confmagic.h production +;# +;# Revision 3.0 1993/08/18 12:10:19 ram +;# Baseline for dist 3.0 netwide release. +;# +;# The list of all available units is held in @ARGV. We shall parse them and +;# extract the dependencies. A lot of global data structures are filled in +;# during this phase. +;# +;# The following two H tables are used to record each know symbol (i.e. a +;# symbol known by at least one unit), and also how many times this symbol is +;# found in the sources. If an entry for a given key is positive, then the +;# associated symbol (i.e. the key) is wanted and it will be written in the +;# Wanted file. +;# %shmaster{'$sym'} records how many times '$sym' is found in a .SH file +;# %cmaster{'SYM'} records how many times 'SYM' is found in a .c file +;# %cwanted{'SYM'} records the set of necessary shell symbols needed for SYM +;# %mwanted{'sym'} is set of C symbols needed when sym is found in .c file +;# +;# This data structure records the initializations which are requires at the +;# beginning of a Configure script. The initialization only occurs when the +;# symbol is needed. Those symbols will appear in the produced config.sh file, +;# hence the name of "master" symbols. +;# @Master records shell configuration symbols which will appear in config.sh +;# +;# The @Cond array records the conditional shell symbols, i.e. those whose +;# value may be defaulted. They will appear in the initialization section of +;# the Configure script with the default value if they are not otherwise used +;# but Configure needs a suitable value internally. +;# @Cond records symbols which are flagged as conditional in the dependencies +;# %hasdefault{'sym'} is true when the conditional 'sym' has a default value +;# +;# The %Obsolete array records the obsolecence for units or symbols. The key +;# ends with .U for units, otherwise it is a symbol. Unit's obsolescence is +;# flagged with a ?O: line (the line being the message which will be issued +;# when the unit is used) while symbol obsolecence is indicated on the leading +;# ?C: or ?S: line, between parenthesis. In that case, the value stored is the +;# new symbol which should be used insted. +;# %Obsolete{'unit.U'} is a message to be printed when obsolete unit is used +;# %Obsolete{'sym'} is the symbol to be used in place of the obsoleted 'sym' +;# +;# The $dependencies variable is used to record the dependencies extracted +;# from the units (?MAKE: line). +;# +;# During the dependency extraction. some files are produced in the .MT dir. +;# Init.U records the initialization wanted +;# Config_h.U records the informations which could go in config.h.SH +;# Extern.U records the libraries and includes wanted by each symbol +;# +;# This file is shared by both metaconfig and metaxref +;# +# Initialize the extraction process by setting some variables. +# We return a string to be eval to do more customized initializations. +sub init_extraction { + open(INIT, ">$WD/.MT/Init.U") || + die "Can't create .MT/Init.U\n"; + open(CONF_H, ">$WD/.MT/Config_h.U") || + die "Can't create .MT/Config_h.U\n"; + open(EXTERN, ">$WD/.MT/Extern.U") || + die "Can't create .MT/Extern.U\n"; + open(MAGIC_H, ">$WD/.MT/Magic_h.U") || + die "Can't create .MT/Magic_h.U\n"; + + $c_symbol = ''; # Current symbol seen in ?C: lines + $s_symbol = ''; # Current symbol seen in ?S: lines + $m_symbol = ''; # Current symbol seen in ?M: lines + $heredoc = ''; # Last "here" document symbol seen + $heredoc_nosubst = 0; # True for <<'EOM' here docs + $condlist = ''; # List of conditional symbols + $defined = ''; # List of defined symbols in the unit + $body = ''; # No procedure to handle body + $ending = ''; # No procedure to clean-up +} + +# End the extraction process +sub end_extraction { + close EXTERN; # External dependencies (libraries, includes...) + close CONF_H; # C symbol definition template + close INIT; # Required initializations + close MAGIC; # Magic C symbol redefinition templates + + print $dependencies if $opt_v; # Print extracted dependencies +} + +# Process the ?MAKE: line +sub p_make { + local($_) = @_; + local(@ary); # Locally defined symbols + local(@dep); # Dependencies + if (/^[\w+ ]*:/) { # Main dependency rule + s|^\s*||; # Remove leading spaces + chop; + s/:(.*)//; + @dep = split(' ', $1); # Dependencies + @ary = split(' '); # Locally defined symbols + foreach $sym (@ary) { + # Symbols starting with a '+' are meant for internal use only. + next if $sym =~ s/^\+//; + # Only sumbols starting with a lowercase letter are to + # appear in config.sh, excepted the ones listed in Except. + if ($sym =~ /^[_a-z]/ || $Except{$sym}) { + $shmaster{"\$$sym"} = undef; + push(@Master,"?$unit:$sym=''\n"); # Initializations + } + } + $condlist = ''; # List of conditional symbols + local($sym); # Symbol copy, avoid @dep alteration + foreach $dep (@dep) { + if ($dep =~ /^\+[A-Za-z]/) { + ($sym = $dep) =~ s|^\+||; + $condlist .= "$sym "; + push(@Cond, $sym) unless $condseen{$sym}; + $condseen{$sym}++; # Conditionally wanted + } + } + # Append to already existing dependencies. The 'defined' variable + # is set for &write_out, used to implement ?L: and ?I: canvas. It is + # reset each time a new unit is parsed. + # NB: leading '+' for defined symbols (internal use only) have been + # removed at this point, but conditional dependencies still bear it. + $defined = join(' ', @ary); # Symbols defined by this unit + $dependencies .= $defined . ':' . join(' ', @dep) . "\n"; + $dependencies .= " -cond $condlist\n" if $condlist; + } else { + $dependencies .= $_; # Building rules + } +} + +# Process the ?O: line +sub p_obsolete { + local($_) = @_; + $Obsolete{"$unit.U"} .= $_; # Message(s) to print if unit is used +} + +# Process the ?S: lines +sub p_shell { + local($_) = @_; + unless ($s_symbol) { + if (/^(\w+).*:/) { + $s_symbol = $1; + print " ?S: $s_symbol\n" if $opt_d; + } else { + warn "\"$file\", line $.: syntax error in ?S: construct.\n"; + $s_symbol = $unit; + return; + } + # Deal with obsolete symbol list (enclosed between parenthesis) + &record_obsolete("\$$_") if /\(/; + } + m|^\.\s*$| && ($s_symbol = ''); # End of comment +} + +# Process the ?C: lines +sub p_c { + local($_) = @_; + unless ($c_symbol) { + if (s/^(\w+)\s*~\s*(\S+)\s*(.*):/$1 $3:/) { + # The ~ operator aliases the main C symbol to another symbol which + # is to be used instead for definition in config.h. That is to say, + # the line '?C:SYM ~ other:' would look for symbol 'other' instead, + # and the documentation for symbol SYM would only be included in + # config.h if 'other' were actually wanted. + $c_symbol = $2; # Alias for definition in config.h + print " ?C: $1 ~ $c_symbol\n" if $opt_d; + } elsif (/^(\w+).*:/) { + # Default behaviour. Include in config.h if symbol is needed. + $c_symbol = $1; + print " ?C: $c_symbol\n" if $opt_d; + } else { + warn "\"$file\", line $.: syntax error in ?C: construct.\n"; + $c_symbol = $unit; + return; + } + # Deal with obsolete symbol list (enclosed between parenthesis) and + # make sure that list do not appear in config.h.SH by removing it. + &record_obsolete("$_") if /\(/; + s/\s*\(.*\)//; # Get rid of obsolete symbol list + } + s|^(\w+)\s*|?$c_symbol:/* $1| || # Start of comment + (s|^\.\s*$|?$c_symbol: */\n| && ($c_symbol = '', 1)) || # End of comment + s|^(.*)|?$c_symbol: *$1|; # Middle of comment + &p_config("$_"); # Add comments to config.h.SH +} + +# Process the ?H: lines +sub p_config { + local($_) = @_; + local($constraint); # Constraint to be used for inclusion + ++$old_version if s/^\?%1://; # Old version + if (s/^\?(\w+)://) { # Remove leading '?var:' + $constraint = $1; # Constraint is leading '?var' + } else { + $constraint = ''; # No constraint + } + if (/^#.*\$/) { # Look only for cpp lines + if (m|^#\$(\w+)\s+(\w+).*\$(\w+)|) { + # Case: #$d_var VAR "$var" + $constraint = $2 unless $constraint; + print " ?H: ($constraint) #\$$1 $2 \"\$$3\"\n" if $opt_d; + $cmaster{$2} = undef; + $cwanted{$2} = "$1\n$3"; + } elsif (m|^#define\s+(\w+)\((.*)\)\s+\$(\w+)|) { + # Case: #define VAR(x) $var + $constraint = $1 unless $constraint; + print " ?H: ($constraint) #define $1($2) \$$3\n" if $opt_d; + $cmaster{$1} = undef; + $cwanted{$1} = $3; + } elsif (m|^#\$define\s+(\w+)|) { + # Case: #$define VAR + $constraint = $1 unless $constraint; + print " ?H: ($constraint) #define $1\n" if $opt_d; + $cmaster{$1} = undef; + $cwanted{$1} = "define\n$unit"; + } elsif (m|^#\$(\w+)\s+(\w+)|) { + # Case: #$d_var VAR + $constraint = $2 unless $constraint; + print " ?H: ($constraint) #\$$1 $2\n" if $opt_d; + $cmaster{$2} = undef; + $cwanted{$2} = $1; + } elsif (m|^#define\s+(\w+).*\$(\w+)|) { + # Case: #define VAR "$var" + $constraint = $1 unless $constraint; + print " ?H: ($constraint) #define $1 \"\$$2\"\n" if $opt_d; + $cmaster{$1} = undef; + $cwanted{$1} = $2; + } else { + $constraint = $unit unless $constraint; + print " ?H: ($constraint) $_" if $opt_d; + } + } else { + print " ?H: ($constraint) $_" if $opt_d; + } + # If not a single ?H:. line, add the leading constraint + s/^\.// || s/^/?$constraint:/; + print CONF_H; +} + +# Process the ?M: lines +sub p_magic { + local($_) = @_; + unless ($m_symbol) { + if (/^(\w+):\s*([\w\s]*)\n$/) { + # A '?M:sym:' line implies a '?W:%<:sym' since we'll need to know + # about the wantedness of sym later on when building confmagic.h. + # Buf is sym is wanted, then the C symbol dependencies have to + # be triggered. That is done by introducing sym in the mwanted + # array, known by the Wanted file construction process... + $m_symbol = $1; + print " ?M: $m_symbol\n" if $opt_d; + $mwanted{$m_symbol} = $2; # Record C dependencies + &p_wanted("$unit:$m_symbol"); # Build fake ?W: line + } else { + warn "\"$file\", line $.: syntax error in ?M: construct.\n"; + } + return; + } + (s/^\.\s*$/?$m_symbol:\n/ && ($m_symbol = '', 1)) || # End of block + s/^/?$m_symbol:/; + print MAGIC_H; # Definition goes to confmagic.h + print " ?M: $_" if $opt_d; +} + +sub p_ignore {} # Ignore comment line +sub p_lint {} # Ignore lint directives +sub p_visible {} # No visible checking in metaconfig +sub p_temp {} # No temporary variable control +sub p_file {} # Ignore produced file directives (for now) + |