diff options
author | Richard Levitte <levitte@openssl.org> | 2015-05-18 22:35:23 +0200 |
---|---|---|
committer | Richard Levitte <richard@levitte.org> | 2016-01-22 23:12:22 +0100 |
commit | 291e94df90aa085ae53b43e52e1cef02efc0ff10 (patch) | |
tree | 0611f97c5443ae3efc73bf5835648ce20ff2b726 /util | |
parent | 00ae96caf74658be3c687de38255b344d767387a (diff) |
Refactor file writing - introduce template driven file writing
apps/CA.pl and tools/c_rehash are built from template files. So far,
this was done by Configure, which created its own problems as it
forced everyone to reconfigure just because one of the template files
had changed.
Instead, have those files created as part of the normal build in apps/
and in tools/.
Furthermore, this prepares for a future where Configure may produce
entirely other build files than Makefile, and the latter can't be
guaranteed to be the holder of all information for other scripts.
Instead, configdata.pm (described below) becomes the center of
configuration information.
This introduces a few new things:
%config a hash table to hold all kinds of configuration data
that can be used by any other script.
configdata.pm a perl module that Configure writes. It currently
holds the hash tables %config and %target.
util/dofile.pl a script that takes a template on STDIN and outputs
the result after applying configuration data on it.
It's supposed to be called like this:
perl -I$(TOP) -Mconfigdata < template > result
or
perl -I$(TOP) -Mconfigdata templ1 templ2 ... > result
Note: util/dofile.pl requires Text::Template.
As part of this changed, remove a number of variables that are really
just copies of entries in %target, and use %target directly. The
exceptions are $target{cflags} and $target{lflags}, they do get copied
to $cflags and $lflags. The reason for this is that those variable
potentially go through a lot of changes and would rather deserve a
place in %config. That, however, is for another commit.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/dofile.pl | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/util/dofile.pl b/util/dofile.pl new file mode 100644 index 0000000000..4bf90babbf --- /dev/null +++ b/util/dofile.pl @@ -0,0 +1,99 @@ +#! /usr/bin/perl +# +# Reads one or more template files and runs it through Text::Template +# +# It is assumed that this scripts is called with -Mconfigdata, a module +# that holds configuration data in %config + +use strict; +use warnings; +use Text::Template; + +# We actually expect to get the following hash tables from configdata: +# +# %config +# %target +# %withargs +# +# We just do a minimal test to see that we got what we expected. +# $config{target} must exist as an absolute minimum. +die "You must run this script with -Mconfigdata\n" if !exists($config{target}); + +# Helper functions for the templates ################################# + +# It might be practical to quotify some strings and have them protected +# from possible harm. These functions primarly quote things that might +# be interpreted wrongly by a perl eval. + +# quotify1 STRING +# This adds quotes (") around the given string, and escapes any $, @, \, +# " and ' by prepending a \ to them. +sub quotify1 { + my $s = shift @_; + $s =~ s/([\$\@\\"'])/\\$1/g; + '"'.$s.'"'; +} + +# quotify_l LIST +# For each defined element in LIST (i.e. elements that aren't undef), have +# it quotified with 'quotofy1' +sub quotify_l { + map { + if (!defined($_)) { + (); + } else { + quotify1($_); + } + } @_; +} + +# Error reporter ##################################################### + +# The error reporter uses %lines to figure out exactly which file the +# error happened and at what line. Not that the line number may be +# the start of a perl snippet rather than the exact line where it +# happened. Nothing we can do about that here. + +my %lines = (); +sub broken { + my %args = @_; + my $filename = "<STDIN>"; + my $deducelines = 0; + foreach (sort keys %lines) { + $filename = $lines{$_}; + last if ($_ > $args{lineno}); + $deducelines += $_; + } + print STDERR $args{error}," in $filename, fragment starting at line ",$args{lineno}-$deducelines; + undef; +} + +# Template reading ################################################### + +# Read in all the templates into $text, while keeping track of each +# file and its size in lines, to try to help report errors with the +# correct file name and line number. + +my $prev_linecount = 0; +my $text = + @ARGV + ? join("", map { my $x = my $y = Text::Template::_load_text($_); + my $linecount = $x =~ tr/\n//; + $prev_linecount = ($linecount += $prev_linecount); + $lines{$linecount} = $_; + $x } @ARGV) + : join("", <STDIN>); + +# Engage! ############################################################ + +# Load the full template (combination of files) into Text::Template +# and fill it up with our data. Output goes directly to STDOUT + +my $template = Text::Template->new(TYPE => 'STRING', SOURCE => $text ); +$template->fill_in(OUTPUT => \*STDOUT, + HASH => { config => \%config, + target => \%target, + quotify1 => \"ify1, + quotify_l => \"ify_l }, + DELIMITERS => [ "{-", "-}" ], + BROKEN => \&broken); |