Add "include" option for config file reading.

Based on a recommendation from Michael Hansen, this commit adds the
ability to include other files from the rc file used for kdesrc-build.

Tilde-expansion is supported on the filename, but only of the ~/foo
variety (not ~user/foo).

It works by essentially intercepting the input stream as necessary, so
unfortunately things like a common "global" followed by different
"global" sections doesn't work (although let me know if that's needed,
it wouldn't be too hard).

On the other hand each rc-file would be able to include the global
options that are common.

To use, simply use "include /path/to/file-to-include" as a single line
in your config file. Leading spaces are supported, but the remainder of
the file after the "include" and all whitespace immediately following
"include" is assumed to be the filename, so don't leave trailing spaces.

BUG:223331
FIXED-IN:1.14
wilder
Michael Pyne 15 years ago
parent c6e6829406
commit 594f40b413
  1. 110
      kdesrc-build

@ -867,6 +867,93 @@ my @screen_log;
}
# }}}
# package RecursiveFH {{{
{
package RecursiveFH;
# Alias the global make_exception into this package.
*make_exception = *main::make_exception;
sub new
{
my ($class) = @_;
my $data = {
'filehandles' => [], # Stack of filehandles to read
'current' => undef, # Current filehandle to read
};
return bless $data, $class;
}
sub addFilehandle
{
my ($self, $fh) = @_;
push @{$self->{filehandles}}, $fh;
$self->{current} = $fh;
}
# Reads the next line of input and returns it.
# If a line of the form "include foo" is read, this function automatically
# opens the given file and starts reading from it instead. The original
# file is not read again until the entire included file has been read. This
# works recursively as necessary.
#
# No further modification is performed to returned lines.
#
# undef is returned on end-of-file (but only of the initial filehandle, not
# included files from there)
sub readLine
{
my $self = shift;
my $fh = $self->{current};
# Sanity check since different methods might try to read same file reader
return undef unless defined $fh;
my $line = readline($fh);
if (not defined $line) {
my $oldFh = pop @{$self->{filehandles}};
close $oldFh;
# If last file, return undef
$self->{current} = undef;
return undef if scalar @{$self->{filehandles}} == 0;
# Else, use last filehandle (top of the stack)
$self->{current} = ${$self->{filehandles}}[-1];
return $self->readLine();
}
elsif ($line =~ /^\s*include\s+\S/) {
# Include found, extract file name and open file.
chomp $line;
my ($filename) = ($line =~ /^\s*include\s+(.+)$/);
if (not defined $filename || !$filename) {
die make_exception('Config',
"Unable to handle file include on line $., '$line'");
}
my $newFh;
$filename =~ s/^~\//$ENV{HOME}\//; # Tilde-expand
open ($newFh, '<', $filename) or
die make_exception('Config',
"Unable to open file $filename which was included from line $.");
push @{$self->{filehandles}}, $newFh;
$self->{current} = $newFh;
return $self->readLine();
}
else {
return $line;
}
}
1;
}
# }}}
# Debugging routines {{{
# Colors
my ($RED, $GREEN, $YELLOW, $NORMAL, $BOLD) = ("") x 5;
@ -3353,7 +3440,7 @@ sub split_option_value
# 'module' if we should expect an end module statement.
sub parse_module
{
my ($fh, $module) = @_;
my ($fileReader, $module) = @_;
$module = 'global' unless $module;
# Setup default options in case user specifies only module name to get it
@ -3364,7 +3451,7 @@ sub parse_module
}
# Read in each option
while (read_line($fh))
while (read_line($fileReader->readLine()))
{
if($module eq 'global')
{
@ -3477,14 +3564,14 @@ sub ensure_projects_xml_present
sub parse_moduleset
{
my $ctx = shift;
my $fh = shift;
my $fileReader = shift;
my $moduleSetName = shift || '';
my $repoSet = get_option('global', 'git-repository-base');
my @modules;
my %optionSet; # We read all options, and apply them to all modules
my $startLine = $.; # For later error messages
while(read_line($fh)) {
while(read_line($fileReader->readLine())) {
last if /^end\s+module(-?set)?$/;
my ($option, $value) = split_option_value($_);
@ -3741,8 +3828,11 @@ sub read_options
my @module_list;
my ($option, $modulename, %readModules);
my $fileReader = RecursiveFH->new();
$fileReader->addFilehandle($fh);
# Read in global settings
while (<$fh>)
while ($fileReader->readLine())
{
s/#.*$//; # Remove comments
s/^\s*//; # Remove leading whitespace
@ -3758,7 +3848,7 @@ sub read_options
}
# Now read in each global option
parse_module($fh, 'global');
parse_module($fileReader, 'global');
last;
}
@ -3775,7 +3865,7 @@ sub read_options
}
# Now read in module settings
while (<$fh>)
while ($fileReader->readLine())
{
s/#.*$//; # Remove comments
s/^\s*//; # Remove leading whitespace
@ -3797,10 +3887,10 @@ sub read_options
}
# A moduleset can give us more than one module to add.
push @module_list, parse_moduleset($ctx, $fh, $modulename);
push @module_list, parse_moduleset($ctx, $fileReader, $modulename);
}
else {
parse_module($fh, $modulename);
parse_module($fileReader, $modulename);
push @module_list, Module->new($ctx, $modulename);
}
@ -3808,8 +3898,6 @@ sub read_options
$using_default = 0;
}
close $fh;
# All modules and their options have been read, filter out modules not
# to update or build, based on the --ignore-modules option already present
# on the command line. manual-update and manual-build are also relevant,

Loading…
Cancel
Save