diff options
Diffstat (limited to 'lib/Automake/File.pm')
-rw-r--r-- | lib/Automake/File.pm | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/lib/Automake/File.pm b/lib/Automake/File.pm index b82e65fed..99d3038db 100644 --- a/lib/Automake/File.pm +++ b/lib/Automake/File.pm @@ -25,16 +25,148 @@ use Automake::CondStack; use Automake::Config; use Automake::Global; use Automake::Location; +use Automake::Options; use Automake::Rule; use Automake::RuleDef; use Automake::Utils; use Automake::VarDef; use Automake::Variable; +use Automake::XFile; use Exporter 'import'; use vars qw (@EXPORT); -@EXPORT = qw (file_contents_internal file_contents); +@EXPORT = qw (%am_file_cache %transformed_files $seen_canonical + $seen_maint_mode preprocess_file make_paragraphs + file_contents_internal file_contents); + +# Cache each file processed by make_paragraphs. +# (This is different from %transformed_files because +# %transformed_files is reset for each file while %am_file_cache +# it global to the run.) +our %am_file_cache; + +# Record each file processed by make_paragraphs. +our %transformed_files; + +# Most important AC_CANONICAL_* macro seen so far. +our $seen_canonical = 0; + +# Where AM_MAINTAINER_MODE appears. +our $seen_maint_mode; + +# $TEXT +# preprocess_file ($MAKEFILE, [%TRANSFORM]) +# ----------------------------------------- +# Load a $MAKEFILE, apply the %TRANSFORM, and return the result. +# No extra parsing or post-processing is done (i.e., recognition of +# rules declaration or of make variables definitions). +sub preprocess_file +{ + my ($file, %transform) = @_; + + # Complete %transform with global options. + # Note that %transform goes last, so it overrides global options. + %transform = ( 'MAINTAINER-MODE' + => $seen_maint_mode ? subst ('MAINTAINER_MODE_TRUE') : '', + + 'XZ' => !! option 'dist-xz', + 'LZIP' => !! option 'dist-lzip', + 'BZIP2' => !! option 'dist-bzip2', + 'COMPRESS' => !! option 'dist-tarZ', + 'GZIP' => ! option 'no-dist-gzip', + 'SHAR' => !! option 'dist-shar', + 'ZIP' => !! option 'dist-zip', + + 'INSTALL-INFO' => ! option 'no-installinfo', + 'INSTALL-MAN' => ! option 'no-installman', + 'CK-NEWS' => !! option 'check-news', + + 'SUBDIRS' => !! Automake::Variable::var ('SUBDIRS'), + 'TOPDIR_P' => $relative_dir eq '.', + + 'BUILD' => ($seen_canonical >= AC_CANONICAL_BUILD), + 'HOST' => ($seen_canonical >= AC_CANONICAL_HOST), + 'TARGET' => ($seen_canonical >= AC_CANONICAL_TARGET), + + 'LIBTOOL' => !! Automake::Variable::var ('LIBTOOL'), + 'NONLIBTOOL' => 1, + %transform); + + if (! defined ($_ = $am_file_cache{$file})) + { + verb "reading $file"; + # Swallow the whole file. + my $fc_file = new Automake::XFile "< $file"; + my $saved_dollar_slash = $/; + undef $/; + $_ = $fc_file->getline; + $/ = $saved_dollar_slash; + $fc_file->close; + # Remove ##-comments. + # Besides we don't need more than two consecutive new-lines. + s/(?:$IGNORE_PATTERN|(?<=\n\n)\n+)//gom; + # Remember the contents of the just-read file. + $am_file_cache{$file} = $_; + } + + # Substitute Automake template tokens. + s/(?: % \?? [\w\-]+ % + | \? !? [\w\-]+ \? + )/transform($&, %transform)/gex; + # transform() may have added some ##%-comments to strip. + # (we use '##%' instead of '##' so we can distinguish ##%##%##% from + # ####### and do not remove the latter.) + s/^[ \t]*(?:##%)+.*\n//gm; + + return $_; +} + + +# @PARAGRAPHS +# make_paragraphs ($MAKEFILE, [%TRANSFORM]) +# ----------------------------------------- +# Load a $MAKEFILE, apply the %TRANSFORM, and return it as a list of +# paragraphs. +sub make_paragraphs +{ + my ($file, %transform) = @_; + $transform{FIRST} = !$transformed_files{$file}; + $transformed_files{$file} = 1; + + my @lines = split /(?<!\\)\n/, preprocess_file ($file, %transform); + my @res; + + while (defined ($_ = shift @lines)) + { + my $paragraph = $_; + # If we are a rule, eat as long as we start with a tab. + if (/$RULE_PATTERN/smo) + { + while (defined ($_ = shift @lines) && $_ =~ /^\t/) + { + $paragraph .= "\n$_"; + } + unshift (@lines, $_); + } + + # If we are a comments, eat as much comments as you can. + elsif (/$COMMENT_PATTERN/smo) + { + while (defined ($_ = shift @lines) + && $_ =~ /$COMMENT_PATTERN/smo) + { + $paragraph .= "\n$_"; + } + unshift (@lines, $_); + } + + push @res, $paragraph; + } + + return @res; +} + # ($COMMENT, $VARIABLES, $RULES) # file_contents_internal ($IS_AM, $FILENAME, $WHERE, \@PARAGRAPHS, [%TRANSFORM]) |