Macromania User Documentation

Doug Neuhauser, UC Berkeley Seismological Laboratory
Last revised: 1999.162

Tables of Contents

Overview

The purpose of macromania is to create a series of files that are dependent on input template files, key files, and keymacro files. The goal is to be able to dynamically configure the startup of the MSHEAR software and the aqcfg file for multiple stations in a network with the smallest amount of site-dependent information isolated in a site-specific key file.

Macromania is used to dynamically construct:

Syntax

macromania filelist keyfile [-u] [-d] [-r] [-p] [-f] [-k=keysize [-x-expansize]
where: The first directive in the keyfile should be a keyword directive:
	grp	N
which is used by macromania to determine which set of input files to process. For each output file listed in the filelist, the input file is determined to be filename_%grp%, where %grp% is replaced by the value of the grp keyword. For example, If the filelist contains the filename
	aqcfg
and the keyfile contains the line
	grp	1
the file aqcfg will be created from them template file aqcfg_1. This allows the key file to select which group of input template files should be used to create the requested output file.

Operation

Macromania performs two distinct operations.
  1. Keyword table construction:
    Macromania first creates a keyword table consisting of keywords and keyword values which is constructed by processing the keyfile and the default keyword macro definition file keymacro. Keywords are single token unquoted strings, and are case insensitive. Keyword values may be either blank (empty) or non-blank strings. Keywords are case insensitive: the keywords joe, Joe, and JOE are all the same keyword.

    Only the FIRST definition of the keyword is used -- subsequent definitions of the same keyword are ignored. This means that system-specific values can be defined early in the key file, and later definitions (often defined in an include file or defined in keymacros) can supply "default" values for keywords that have not been previously defined.

    Macromania stores the keyword table in a memory module which can be used by subsequent infocations of macromania in order to save the time needed to re-create the keyword table. If the keymacro file is not specified, macromania will use a previously constructed keyword table in the memory module to process the template files.

  2. Template file expansion:
    Macromania reads the templatelist file which contains a list of files to be created by macromania. For each file in the list, it determines the name of the input template file and processes that input template file to create the specified output file. Processing a template file consists of processing template macro definitions and template macro calls, performing keyword replacement, processing conditional directives, and writing the resulting lines to the output file.

Details

Macromania constructs a keyword and keyvalue list by reading the key file, optional user-specified key include files, optional user-specified keymacro files, and the default keymacro file. It then processes a template file with this keyword and keyvalue table in order to create the specified output file.

Keyword table construction:

Macromania processes the key file and default keymacro file keymacro in the following manner to create the keyword table.

Template file processing:

Macromania reads each target filename from the templatelist file, determines the name of the input filename by appending the string _%grp% to the filename (where %grp% is replaced by the value of the GRP keyword. The input file is then processed in the following manner in order to create the specified output file. The file may contain template macro directives (which begin with a $. All template macro directives are case insensitive, eg $MDEFINE, $Mdefine, and $mdefine are all equivalent. Since the template file contains directives for conditional processing, macromania maintain a stack of conditional processing states as well as the current conditional processing state. At startup, the initial processing state is TRUE, and the previous processing state on the stack is initialized to TRUE.

Macromania reads each line from the template file, and processes it in the following manner:

  1. It processes the following template directive lines:
    • $MEND
      If the line is a $MEND line and a template macro is currently being defined, it terminates the definition of the $MDEFINE template macro, and adds the template macro name and macro body to the template macro table. The line is then discarded.
    • $ENDIF
      If the line is a $ENDIF line, it pops the conditional processing stack, setting the current processing state to the most recent processing state on the stack. The line is then discarded.
    • $ELSE
      If the line is a $ELSE, it computes a new processing state whose value is computed by the expression:
      ((!current process state) && previous processing state on stack)
      The line is then discarded.

  2. It substitutes keyword references in the line with the corresponding keyword value in a left to right order. A keyword reference is denoted by a keyword bracketed with the keyword escape character "%", e.g. the substring %comlink% is replaced by the value of the keyword comlink. Since the value of a keyword may contain additional keywords, the string must be reexamined after each keywork replacement. It is an error if a keyword is encountered that is not defined in the keywork table. Before each keyword is replaced, and after all keywords have been replaces, the line is examined to see if begins with the characters *#. Any line found that begins with this character sequence is discarded.

  3. It evaluates all arithmetic expressions in the line of the form {@arithmetic_expression}@, and replaces the expression with the value of the expression. The following operators may be used within the expression:
    • + (addition)
    • - (subtraction)
    • * (multiplication)
    • / (division)
    • & (logical AND)
    • | (logical OR)
    • ^ (exponentiation)
    • ( ) (parenthetical expressions for explicit grouping)
    Contants may be specified in either fixed point notation (eg 5 or 5.23) or exponential notation (eg 1.23E2, 1.23e2, 1.23D2, or 1.23d2).

  4. It processes all other template directives lines of the format:
    • $MDEFINE $template_macro
      This lines starts the definition of the specified template macro. The $MDEFINE directive may also contain additional comment tokens which may document the possible parameters that may be passed to the macro. The body of the macro consists of all following lines up to a $MEND line. The body of the macro (including conditional directives and keyword substitution) is NOT evaluated during macro definition. The macro body may contain formal arguments $1$ through $Z$ which will be replaced with the corresponding actual arguments when macro is called.
    • $IF arith_expression
      The arithmetic expression is evaluated, and if the resulting value (rounded to an integer?) is non-zero, the condition is TRUE; otherwise the condition is FALSE. Since conditionals may appear within other conditional blocks, the new processing state is set to (conditional && current_state). The current state is pushed on to the processing stack, and the current processing state is set to the new processing state. If the new processing state is TRUE, all lines up to the matching $ELSE or $ENDIF will be processed (or ignored if the condition is FALSE).
    • $IFEQ arith_expression
      The arithmetic expression is evaluated, and if the resulting value (rounded to an integer?) is zero, the condition is TRUE; otherwise the condition is FALSE. Since conditionals may appear within other conditional blocks, the new processing state is set to (conditional && current_state). The current state is pushed on to the processing stack, and the current processing state is set to the new processing state. If the new processing state is TRUE, all lines up to the matching $ELSE or $ENDIF will be processed (or ignored if the condition is FALSE).
    • $IFDEF %keyword%
      By this time, the keyword has already been evaluated and replaced by its value. If the value is blank (or the empty string), the condition is FALSE; otherwise the condition is TRUE. Since conditionals may appear within other conditional blocks, the new processing state is set to (conditional && current_state). The current state is pushed on to the processing stack, and the current processing state is set to the new processing state. If the new processing state is TRUE, all lines up to the matching $ELSE or $ENDIF will be processed (or ignored if the condition is FALSE). Note that this directive would be more correctly name $IFNBLANK.
    • $IFNDEF %keyword%
      By this time, the keyword has already been evaluated and replaced by its value. If the value is blank (or the empty string), the condition is TRUE; otherwise the condition is FALSE. Since conditionals may appear within other conditional blocks, the new processing state is set to (conditional && current_state). The current state is pushed on to the processing stack, and the current processing state is set to the new processing state. If the new processing state is TRUE, all lines up to the matching $ELSE or $ENDIF will be processed (or ignored if the condition is FALSE). Note that this directive would be more correctly name $IFBLANK. This line is then disarded.
    • $ESCAPE new_escape_char
    • $ESCAPE
      This directive defines a new escape character to be used for delimiting keywords. If no character is specified, the default keyword delimeter will be used.
    • $INCLUDE filename If filename is not blank or the empty string, process the contents of the specified file at this point. If the filename is blank, ignore the directive.
    • $macro argument_list
      If the line begins with a $ and, it is assumed to be a call to a previously defined template. When a template macro is called, the formal arguments $1$ through $Z$ in the body of the template macro are replaced by the actual arguments in the macro call. The value of any formal argument not specifed in the keymacro call is set to the empty string. If an actual argument is a quoted string, the quotes are removed from the string when it is assigned to the corresponding formal argument. The body of the macro is processed at this time.

  5. If the line is not template macro call or directive and was not previously discarded, the resulting line is written to the output file.

File Formats

Perl version of macromania

As an aid to developing and debugging key files, keymacro files, and template files in a Unix environment, UC Berkeley developed a
perl version of macromania. The perl version should conform to Quanterra's macromania version 23 with the following exceptions:
  1. The perl version of macromania does not save key macros in a memory module between invocations. Therefore, a key file must be provided to macromania every time it is run.
  2. The perl version of macromania uses dynamic arrays and hash tables, and does not require the user to define the size of the key and expansion tables.
  3. The perl verions has different debugging outputs, and therefore supports different command line options. Type macromania -h for details.