Chapter 6. Extending the Global Configuration Script

Table of Contents

JugglerConfigure.pm
JugglerConfigure
JugglerModule
ModuleDependency
conifgure.pl
Command-Line Argument Handling
Help Output
Build Configuration
File Regeneration

Most extensions to configure.pl can be localized to the JugglerConfigure.pm module file. That module contains the configuration file parsing code and two data structures (JugglerModule and ModuleDependency) for managing the data that is parsed. In configure.pl, most of the code relates to execution of the configure scripts in the individual modules. This includes running the configuration scripts to configure a build tree and running them to collect, reformat, and output usage information (the output normally printed from passing --help). In this chapter, we examine both files separately and explain how to extend them.

JugglerConfigure.pm

This file contains three Perl packages: JugglerConfigure, JugglerModule, and ModuleDependency. The first has a single procedure, parseConfigFile(), that parses the user-specified configuration (juggler.cfg in most cases). The latter two define data structures (Perl classes) used to manage individual modules defined in the configuration file and the dependencies of each module. We will discuss each package in turn.

JugglerConfigure

As stated above, this package contains a single subroutine: parseConfigFile(). This parses a user-specified configuration file in the format described in the section called “Build Configuration File”. If the config file is parsed correctly, a hash named %MODULES is returned to the caller. This hash, indexed by module name, provides references to JugglerModule instances.

The parsing code is fairly straightforward. There are only three keywords in the configuration file format: module, depend, and Default. The basic concepts used in the format are similar to those for the C grammar. In other words, curly braces denote blocks, semi-colons denote the end of a declaration, and all code is case-sensitive. The following provides the grammar for the configuration file:

DOCUMENT   ::= COMMENT DEFAULT MODULE
DEFAULT    ::= 'Default:' NAME | ε
MODULE     ::= NAME '{' COMMENT DEPENDENCY '}' COMMENT MODULE | ε
NAME       ::= ([A-Za-z0-9_][A-Za-z0-9_]* + λ)[A-Za-z0-9_]
DEPENDENCY ::= DIR ';' DEPENDENCY | MODDEP ';' DEPENDENCY | ε
DIR        ::= <valid-path> | <valid-path> ':' ENVVAR
ENVVAR     ::= NAME '=' <text> | NAME '=' <text> ',' ENVVAR
MODDEP     ::= 'depend' NAME
COMMENT    ::= '#' <text> | '//' <text> | '/*' <text> '*/' | ε

The structure of this grammar should be reflected in the parsing code. Differences between strict regular expressions (used above, more or less) and Perl regular expressions may muddy the correlation.

JugglerModule

The JugglerModule package defines a class containing two “data members”: name and deps. These are actually keys of the blessed hash returned by the new() subroutine. The name member is just a string that contains the unique name of the module. The deps member is more interesting. Indeed, the main purpose of the JugglerModule package is to maintain the list of dependencies.

The deps member is a reference to an array of ModuleDependency objects (see the section called “ModuleDependency). An array is used to preserve the ordering read from the configuration file. All dependencies given in the configuration file appear in the array. This includes those “inherited” from another module through the use of the depend keyword.

Duplication of dependencies is avoided by performing a check whenever a new dependency is added using addDependency(). The hasDependency() method encapsulates the process of making the check. The dependencies of two modules can be merged using the addDependencies() method.

ModuleDependency

The ModuleDependency package defines a class containing two “data members”: path and env. The first is a simple string, and the second is a reference to a hash where the keys are environment variable names. The values for these are extracted from the DIR rule in the above grammar. More specifically, the terminal <valid-path> in DIR rule corresponds to the path member, and the ENVVAR rule defines the hash of environment variable mappings.

Access to a given JugglerModule object's dependencies happens entirely through the API of that class. This class is provided as a convenient abstraction around the information provided through each DIR parser rule expansion.