| [Top] | [Contents] | [Index] | [ ? ] |
This file documents AutoGen version 5.9. It is a tool designed for generating program files that contain repetitive text with varied substitutions. This document is very long because it is intended as a reference document. For a quick start example, See section A Simple Example.
The AutoGen distribution includes the basic generator engine and several add-on libraries and programs. Of the most general interest would be Automated Option processing, See section Automated Option Processing, which also includes stand-alone support for configuration file parsing, See section AutoOpts Features. Please see the “Add-on packages for AutoGen” section for additional programs and libraries associated with AutoGen.
This edition documents version 5.9, May 2008.
| 1. Introduction | AutoGen's Purpose | |
| 2. Definitions File | AutoGen Definitions File | |
| 3. Template File | AutoGen Template | |
| 4. Augmenting AutoGen Features | ||
| 5. Invoking autogen | Invoking AutoGen | |
| 6. Configuring and Installing | ||
| 7. Automated Option Processing | ||
| 8. Add-on packages for AutoGen | ||
| 9. Some ideas for the future. | ||
| A. Copying This Manual | ||
| Concept Index | General index | |
| Function Index | Function index |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoGen is a tool designed for generating program files that contain repetitive text with varied substitutions. Its goal is to simplify the maintenance of programs that contain large amounts of repetitious text. This is especially valuable if there are several blocks of such text that must be kept synchronized in parallel tables.
One common example is the problem of maintaining the code required for processing program options. Processing options requires a minimum of four different constructs be kept in proper order in different places in your program. You need at least:
You will need more things besides this if you choose to implement long option names, rc/ini/config file processing, environment variables and so on. All of this can be done mechanically; with the proper templates and this program. In fact, it has already been done and AutoGen itself uses it See section Automated Option Processing. For a simple example of Automated Option processing, See section Quick Start. For a full list of the Automated Option features, See section AutoOpts Features.
| 1.1 The Purpose of AutoGen | ||
| 1.2 A Simple Example | ||
| 1.3 csh/zsh caveat | ||
| 1.4 A User's Perspective |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The idea of this program is to have a text file, a template if you will, that contains the general text of the desired output file. That file includes substitution expressions and sections of text that are replicated under the control of separate definition files.
AutoGen was designed with the following features:
${VAR} construct in a shell here doc.
These markers are not fixed strings. They are specified at the start of
each template. Template designers know best what fits into their
syntax and can avoid marker conflicts.
We did this because it is burdensome and difficult to avoid conflicts using either M4 tokenization or C preprocessor substitution rules. It also makes it easier to specify expressions that transform the value. Of course, our expressions are less cryptic than the shell methods.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is just one simple example that shows a few basic features.
If you are interested, you also may run "make check" with the
VERBOSE environment variable set and see a number of other
examples in the ‘agen5/test/testdir’ directory.
Assume you have an enumeration of names and you wish to associate some string with each name. Assume also, for the sake of this example, that it is either too complex or too large to maintain easily by hand. We will start by writing an abbreviated version of what the result is supposed to be. We will use that to construct our output templates.
In a header file, ‘list.h’, you define the enumeration and the global array containing the associated strings:
typedef enum {
IDX_ALPHA,
IDX_BETA,
IDX_OMEGA } list_enum;
extern char const* az_name_list[ 3 ];
|
Then you also have ‘list.c’ that defines the actual strings:
#include "list.h"
char const* az_name_list[] = {
"some alpha stuff",
"more beta stuff",
"final omega stuff" };
|
First, we will define the information that is unique for each enumeration name/string pair. This would be placed in a file named, ‘list.def’, for example.
autogen definitions list;
list = { list_element = alpha;
list_info = "some alpha stuff"; };
list = { list_info = "more beta stuff";
list_element = beta; };
list = { list_element = omega;
list_info = "final omega stuff"; };
|
The autogen definitions list; entry defines the file as an AutoGen
definition file that uses a template named list. That is followed by
three list entries that define the associations between the
enumeration names and the strings. The order of the differently named
elements inside of list is unimportant. They are reversed inside of the
beta entry and the output is unaffected.
Now, to actually create the output, we need a template or two that can be expanded into the files you want. In this program, we use a single template that is capable of multiple output files. The definitions above refer to a ‘list’ template, so it would normally be named, ‘list.tpl’.
It looks something like this. (For a full description, See section Template File.)
[+ AutoGen5 template h c +]
[+ CASE (suffix) +][+
== h +]
typedef enum {[+
FOR list "," +]
IDX_[+ (string-upcase! (get "list_element")) +][+
ENDFOR list +] } list_enum;
extern char const* az_name_list[ [+ (count "list") +] ];
[+
== c +]
#include "list.h"
char const* az_name_list[] = {[+
FOR list "," +]
"[+list_info+]"[+
ENDFOR list +] };[+
ESAC +]
|
The [+ AutoGen5 template h c +] text tells AutoGen that this is
an AutoGen version 5 template file; that it is to be processed twice;
that the start macro marker is [+; and the end marker is
+]. The template will be processed first with a suffix value of
h and then with c. Normally, the suffix values are
appended to the ‘base-name’ to create the output file name.
The [+ == h +] and [+ == c +] CASE selection clauses
select different text for the two different passes. In this example,
the output is nearly disjoint and could have been put in two separate
templates. However, sometimes there are common sections and this is
just an example.
The [+FOR list "," +] and [+ ENDFOR list +] clauses delimit
a block of text that will be repeated for every definition of list.
Inside of that block, the definition name-value pairs that
are members of each list are available for substitutions.
The remainder of the macros are expressions. Some of these contain
special expression functions that are dependent on AutoGen named values;
others are simply Scheme expressions, the result of which will be
inserted into the output text. Other expressions are names of AutoGen
values. These values will be inserted into the output text. For example,
[+list_info+] will result in the value associated with
the name list_info being inserted between the double quotes and
(string-upcase! (get "list_element")) will first "get" the value
associated with the name list_element, then change the case of
all the letters to upper case. The result will be inserted into the
output document.
If you have compiled AutoGen, you can copy out the template and definitions
as described above and run autogen list.def. This will produce
exactly the hypothesized desired output.
One more point, too. Lets say you decided it was too much trouble to figure out how to use AutoGen, so you created this enumeration and string list with thousands of entries. Now, requirements have changed and it has become necessary to map a string containing the enumeration name into the enumeration number. With AutoGen, you just alter the template to emit the table of names. It will be guaranteed to be in the correct order, missing none of the entries. If you want to do that by hand, well, good luck.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoGen tries to use your normal shell so that you can supply shell code in a manner you are accustomed to using. If, however, you use csh or zsh, you cannot do this. Csh is sufficiently difficult to program that it is unsupported. Zsh, though largely programmable, also has some anomalies that make it incompatible with AutoGen usage. Therefore, when invoking AutoGen from these environments, you must be certain to set the SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or bash.
Any shell you choose for your own scripts need to follow these basic requirements:
trap $sig ":" without output to standard out.
This is done when the server shell is first started.
If your shell does not handle this, then it may be able to by
loading functions from its start up files.
\\cd $PWD
is inserted. This ensures that cd is not aliased to something
peculiar and each scriptlet starts life in the execution directory.
echo mumble is
appended. The program you use as a shell must emit the single
argument mumble on a line by itself.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Alexandre wrote: > > I'd appreciate opinions from others about advantages/disadvantages of > each of these macro packages. |
I am using AutoGen in my pet project, and find one of its best points to be that it separates the operational data from the implementation.
Indulge me for a few paragraphs, and all will be revealed: In the manual, Bruce cites the example of maintaining command line flags inside the source code; traditionally spreading usage information, flag names, letters and processing across several functions (if not files). Investing the time in writing a sort of boiler plate (a template in AutoGen terminology) pays by moving all of the option details (usage, flags names etc.) into a well structured table (a definition file if you will), so that adding a new command line option becomes a simple matter of adding a set of details to the table.
So far so good! Of course, now that there is a template, writing all of that tedious optargs processing and usage functions is no longer an issue. Creating a table of the options needed for the new project and running AutoGen generates all of the option processing code in C automatically from just the tabular data. AutoGen in fact already ships with such a template... AutoOpts.
One final consequence of the good separation in the design of AutoGen is that it is retargetable to a greater extent. The egcs/gcc/fixinc/inclhack.def can equally be used (with different templates) to create a shell script (inclhack.sh) or a c program (fixincl.c).
This is just the tip of the iceberg. AutoGen is far more powerful than these examples might indicate, and has many other varied uses. I am certain Bruce or I could supply you with many and varied examples, and I would heartily recommend that you try it for your project and see for yourself how it compares to m4.
As an aside, I would be interested to see whether someone might be persuaded to rationalise autoconf with AutoGen in place of m4... Ben, are you listening? autoconf-3.0! `kay? =)O|
Sincerely,
Gary V. Vaughan
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This chapter describes the syntax and semantics of the AutoGen definition file. In order to instantiate a template, you normally must provide a definitions file that identifies itself and contains some value definitions. Consequently, we keep it very simple. For "advanced" users, there are preprocessing directives, sparse arrays, named indexes and comments that may be used as well.
The definitions file is used to associate values with names. Every value is implicitly an array of values, even if there is only one value. Values may be either simple strings or compound collections of name-value pairs. An array may not contain both simple and compound members. Fundamentally, it is as simple as:
prog-name = "autogen";
flag = {
name = templ_dirs;
value = L;
descrip = "Template search directory list";
};
|
For purposes of commenting and controlling the processing of the
definitions, C-style comments and most C preprocessing directives are
honored. The major exception is that the #if directive is
ignored, along with all following text through the matching
#endif directive. The C preprocessor is not actually invoked, so
C macro substitution is not performed.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The first definition in this file is used to identify it as a
AutoGen file. It consists of the two keywords,
‘autogen’ and ‘definitions’ followed by the default
template name and a terminating semi-colon (;). That is:
AutoGen Definitions template-name; |
Note that, other than the name template-name, the words ‘AutoGen’ and ‘Definitions’ are searched for without case sensitivity. Most lookups in this program are case insensitive.
Also, if the input contains more identification definitions, they will be ignored. This is done so that you may include (see section Controlling What Gets Processed) other definition files without an identification conflict.
AutoGen uses the name of the template to find the corresponding template file. It searches for the file in the following way, stopping when it finds the file:
If AutoGen fails to find the template file in one of these places, it prints an error message and exits.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Any name may have multiple values associated with it in the definition file. If there is more than one instance, the only way to expand all of the copies of it is by using the FOR (see section FOR - Emit a template block multiple times) text function on it, as described in the next chapter.
There are two kinds of definitions, ‘simple’ and ‘compound’. They are defined thus (see section Finite State Machine Grammar):
compound_name '=' '{' definition-list '}' ';'
simple_name '=' string ';'
no_text_name ';'
|
No_text_name is a simple definition with a shorthand empty string
value. The string values for definitions may be specified in any of
several formation rules.
| 2.2.1 Definition List | ||
| 2.2.2 Double Quote String | ||
| 2.2.3 Single Quote String | ||
| 2.2.5 An Unquoted String | ||
| 2.2.4 Shell Output String | ||
| 2.2.6 Scheme Result String | ||
| 2.2.7 A Here String | ||
| 2.2.8 Concatenated Strings |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
definition-list is a list of definitions that may or may not
contain nested compound definitions. Any such definitions may
only be expanded within a FOR block iterating over the
containing compound definition. See section FOR - Emit a template block multiple times.
Here is, again, the example definitions from the previous chapter, with three additional name value pairs. Two with an empty value assigned (first and last), and a "global" group_name.
autogen definitions list;
group_name = example;
list = { list_element = alpha; first;
list_info = "some alpha stuff"; };
list = { list_info = "more beta stuff";
list_element = beta; };
list = { list_element = omega; last;
list_info = "final omega stuff"; };
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The string follows the C-style escaping (\, \n, \f,
\v, etc.), plus octal character numbers specified as \ooo.
The difference from "C" is that the string may span multiple lines.
Like ANSI "C", a series of these strings, possibly intermixed with
single quote strings, will be concatenated together.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is similar to the shell single-quote string. However, escapes
\ are honored before another escape, single quotes '
and hash characters #. This latter is done specifically
to disambiguate lines starting with a hash character inside
of a quoted string. In other words,
fumble = ' #endif '; |
could be misinterpreted by the definitions scanner, whereas this would not:
fumble = ' \#endif '; |
As with the double quote string, a series of these, even intermixed with double quote strings, will be concatenated together.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is assembled according to the same rules as the double quote string, except that there is no concatenation of strings and the resulting string is written to a shell server process. The definition takes on the value of the output string.
NB The text is interpreted by a server shell. There may be left over
state from previous server shell processing. This scriptlet may also leave
state for subsequent processing. However, a cd to the original
directory is always issued before the new command is issued.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A simple string that does not contain white space may be left
unquoted. The string must not contain any of the characters special to
the definition text (i.e., ", #, ', (,
), ,, ;, <, =, >, [,
], `, {, or }). This list is subject to
change, but it will never contain underscore (_), period
(.), slash (/), colon (:), hyphen (-) or
backslash (\\). Basically, if the string looks like it is a
normal DOS or UNIX file or variable name, and it is not one of two
keywords (‘autogen’ or ‘definitions’) then it is OK to not
quote it, otherwise you should.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A scheme result string must begin with an open parenthesis (.
The scheme expression will be evaluated by Guile and the
value will be the result. The AutoGen expression functions
are disabled at this stage, so do not use them.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A ‘here string’ is formed in much the same way as a shell here doc.
It is denoted with two less than characters(<<) and, optionally, a
hyphen. This is followed by optional horizontal white space and an
ending marker-identifier. This marker must follow the syntax rules
for identifiers. Unlike the shell version, however, you must not quote
this marker.
The resulting string will start with the first character on the next line and continue up to but not including the newline that precedes the line that begins with the marker token. If a hyphen follows the less than characters, then leading tabs will be stripped and the terminating marker will be recognized even if preceded by tabs. No backslash or any other kind of processing is done on this string. The characters are copied directly into the result string.
Here are two examples:
str1 = <<- STR_END
$quotes = " ' `
STR_END;
str2 = << STR_END
$quotes = " ' `
STR_END;
STR_END;
|
The first string contains no new line characters. The first character is the dollar sign, the last the back quote.
The second string contains one new line character. The first character
is the tab character preceding the dollar sign. The last character is
the semicolon after the STR_END. That STR_END does not
end the string because it is not at the beginning of the line. In the
preceding case, the leading tab was stripped.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If single or double quote characters are used, then you also have the option, a la ANSI-C syntax, of implicitly concatenating a series of them together, with intervening white space ignored.
NB You cannot use directives to alter the string content. That is,
str = "fumble"
#ifdef LATER
"stumble"
#endif
;
|
will result in a syntax error. The preprocessing directives are not carried out by the C preprocessor. However,
str = '"fumble\n" #ifdef LATER " stumble\n" #endif '; |
Will work. It will enclose the ‘#ifdef LATER’
and ‘#endif’ in the string. But it may also wreak
havoc with the definition processing directives. The hash
characters in the first column should be disambiguated with
an escape \ or join them with previous lines:
"fumble\n#ifdef LATER....
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In AutoGen, every name is implicitly an array of values. When assigning values, they are usually implicitly assigned to the next highest slot. They can also be specified explicitly:
mumble[9] = stumble; mumble[0] = grumble; |
If, subsequently, you assign a value to mumble without an
index, its index will be 10, not 1.
If indexes are specified, they must not cause conflicts.
#define-d names may also be used for index values.
This is equivalent to the above:
#define FIRST 0 #define LAST 9 mumble[LAST] = stumble; mumble[FIRST] = grumble; |
All values in a range do not have to be filled in. If you leave gaps, then you will have a sparse array. This is fine (see section FOR - Emit a template block multiple times). You have your choice of iterating over all the defined values, or iterating over a range of slots. This:
[+ FOR mumble +][+ ENDFOR +] |
iterates over all and only the defined entries, whereas this:
[+ FOR mumble (for-by 1) +][+ ENDFOR +] |
will iterate over all 10 "slots". Your template will likely have to contain something like this:
[+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] |
or else "mumble" will have to be a compound value that, say, always contains a "grumble" value:
[+ IF (exist? "grumble") +] |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are several methods for including dynamic content inside a definitions
file. Three of them are mentioned above (Shell Output String and
see section Scheme Result String) in the discussion of string formation rules.
Another method uses the #shell processing directive.
It will be discussed in the next section (see section Controlling What Gets Processed).
Guile/Scheme may also be used to yield to create definitions.
When the Scheme expression is preceded by a backslash and single quote, then the expression is expected to be an alist of names and values that will be used to create AutoGen definitions.
This method can be be used as follows:
\'( (name (value-expression))
(name2 (another-expr)) )
|
This is entirely equivalent to:
name = (value-expression); name2 = (another-expr); |
Under the covers, the expression gets handed off to a Guile function
named alist->autogen-def in an expression that looks like this:
(alist->autogen-def
( (name (value-expression)) (name2 (another-expr)) ) )
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Definition processing directives can only be processed
if the '#' character is the first character on a line. Also, if you
want a '#' as the first character of a line in one of your string
assignments, you should either escape it by preceding it with a
backslash ‘\’, or by embedding it in the string as in "\n#".
All of the normal C preprocessing directives are recognized, though
several are ignored. There is also an additional #shell -
#endshell pair. Another minor difference is that AutoGen
directives must have the hash character (#) in column 1.
The final tweak is that #! is treated as a comment line.
Using this feature, you can use: ‘#! /usr/local/bin/autogen’
as the first line of a definitions file, set the mode to executable
and "run" the definitions file as if it were a direct invocation of
AutoGen. This was done for its hack value.
The ignored directives are:
‘#ident’, ‘#let’, ‘#pragma’, and ‘#if’.
Note that when ignoring the #if directive, all intervening
text through its matching #endif is also ignored,
including the #else clause.
The AutoGen directives that affect the processing of definitions are:
#assert `shell-script` | (scheme-expr) | <anything else>If the shell-script or scheme-expr do not yield true
valued results, autogen will be aborted. If <anything else> or
nothing at all is provided, then this directive is ignored.
When writing the shell script, remember this is on a preprocessing line. Multiple lines must be backslash continued and the result is a single long line. Separate multiple commands with semi-colons.
The result is false (and fails) if the result is empty, the
number zero, or a string that starts with the letters 'n' or 'f' ("no"
or "false").
#define name [ <text> ]Will add the name to the define list as if it were a DEFINE program argument. Its value will be the first non-whitespace token following the name. Quotes are not processed.
After the definitions file has been processed, any remaining entries in the define list will be added to the environment.
#elifThis must follow an #if
otherwise it will generate an error.
It will be ignored.
#elseThis must follow an #if, #ifdef or #ifndef.
If it follows the #if, then it will be ignored. Otherwise,
it will change the processing state to the reverse of what it was.
#endifThis must follow an #if, #ifdef or #ifndef.
In all cases, this will resume normal processing of text.
#endmacThis terminates a "macdef", but must not ever be encountered directly.
#endshellEnds the text processed by a command shell into autogen definitions.
#error [ <descriptive text> ]This directive will cause AutoGen to stop processing and exit with a status of EXIT_FAILURE.
#if [ <ignored conditional expression> ]#if expressions are not analyzed. Everything from here
to the matching #endif is skipped.
#ifdef name-to-testThe definitions that follow, up to the matching #endif will be
processed only if there is a corresponding -Dname command line
option or if a #define of that name has been previously encountered.
#ifndef name-to-testThe definitions that follow, up to the matching #endif will be
processed only if there is not a corresponding -Dname
command line option or there was a canceling -Uname option.
#include unadorned-file-nameThis directive will insert definitions from another file into the current collection. If the file name is adorned with double quotes or angle brackets (as in a C program), then the include is ignored.
#lineAlters the current line number and/or file name. You may wish to
use this directive if you extract definition source from other files.
getdefs uses this mechanism so AutoGen will report the correct
file and approximate line number of any errors found in extracted
definitions.
#macdefThis is a new AT&T research preprocessing directive. Basically, it is a multi-line #define that may include other preprocessing directives.
#option opt-name [ <text> ]This directive will pass the option name and associated text to the AutoOpts optionLoadLine routine (see section optionLoadLine). The option text may span multiple lines by continuing them with a backslash. The backslash/newline pair will be replaced with two space characters. This directive may be used to set a search path for locating template files For example, this:
#option templ-dirs $ENVVAR/dirname |
will direct autogen to use the ENVVAR environment variable to find
a directory named dirname that (may) contain templates. Since these
directories are searched in most recently supplied first order, search
directories supplied in this way will be searched before any supplied on
the command line.
#shellInvokes $SHELL or ‘/bin/sh’ on a script that should
generate AutoGen definitions. It does this using the same server
process that handles the back-quoted ` text.
CAUTION let not your $SHELL be csh.
#undef name-to-undefineWill remove any entries from the define list that match the undef name pattern.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When AutoGen starts, it tries to determine several names from the
operating environment and put them into environment variables for use in
both #ifdef tests in the definitions files and in shell scripts
with environment variable tests. __autogen__ is always defined.
For other names, AutoGen will first try to use the POSIX version of the
sysinfo(2) system call. Failing that, it will try for the POSIX
uname(2) call. If neither is available, then only
"__autogen__" will be inserted into the environment.
In all cases, the associated names are converted to lower case, surrounded
by doubled underscores and non-symbol characters are replaced with
underscores.
With Solaris on a sparc platform, sysinfo(2) is available.
The following strings are used:
SI_SYSNAME (e.g., "__sunos__")
SI_HOSTNAME (e.g., "__ellen__")
SI_ARCHITECTURE (e.g., "__sparc__")
SI_HW_PROVIDER (e.g., "__sun_microsystems__")
SI_PLATFORM (e.g., "__sun_ultra_5_10__")
SI_MACHINE (e.g., "__sun4u__")
For Linux and other operating systems that only support the
uname(2) call, AutoGen will use these values:
sysname (e.g., "__linux__")
machine (e.g., "__i586__")
nodename (e.g., "__bach__")
By testing these pre-defines in my definitions, you can select
pieces of the definitions without resorting to writing shell
scripts that parse the output of uname(1). You can also
segregate real C code from autogen definitions by testing for
"__autogen__".
#ifdef __bach__ location = home; #else location = work; #endif |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The definitions file may contain C and C++ style comments.
/* * This is a comment. It continues for several lines and closes * when the characters '*' and '/' appear together. */ // this comment is a single line comment |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This is an extended example:
autogen definitions ‘template-name’;
/*
* This is a comment that describes what these
* definitions are all about.
*/
global = "value for a global text definition.";
/*
* Include a standard set of definitions
*/
#include standards.def
a_block = {
a_field;
a_subblock = {
sub_name = first;
sub_field = "sub value.";
};
#ifdef FEATURE
a_subblock = {
sub_name = second;
};
#endif
};
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The preprocessing directives and comments are not part of the grammar. They are handled by the scanner/lexer. The following was extracted directly from the generated defParse-fsm.c source file. The "EVT:" is the token seen, the "STATE:" is the current state and the entries in this table describe the next state and the action to take. Invalid transitions were removed from the table.
dp_trans_table[ DP_STATE_CT ][ DP_EVENT_CT ] = {
/* STATE 0: DP_ST_INIT */
{ { DP_ST_NEED_DEF, NULL }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 1: DP_ST_NEED_DEF */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_NEED_TPL, NULL }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 2: DP_ST_NEED_TPL */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: var_name */
{ DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: other_name */
{ DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 3: DP_ST_NEED_SEMI */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_NEED_NAME, NULL }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 4: DP_ST_NEED_NAME */
{ { DP_ST_NEED_DEF, NULL }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_DONE, dp_do_need_name_end }, /* EVT: End-Of-File */
{ DP_ST_HAVE_NAME, dp_do_need_name_var_name }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_HAVE_VALUE, dp_do_end_block }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 5: DP_ST_HAVE_NAME */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */
{ DP_ST_NEED_VALUE, dp_do_have_name_lit_eq }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_NEED_IDX, NULL }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 6: DP_ST_NEED_VALUE */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: var_name */
{ DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: other_name */
{ DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: string */
{ DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: here_string */
{ DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_NEED_NAME, dp_do_start_block }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 7: DP_ST_NEED_IDX */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 8: DP_ST_NEED_CBKT */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INDX_NAME, NULL } /* EVT: ] */
/* STATE 9: DP_ST_INDX_NAME */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */
{ DP_ST_NEED_VALUE, NULL }, /* EVT: = */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
/* STATE 10: DP_ST_HAVE_VALUE */
{ { DP_ST_INVALID, dp_do_invalid }, /* EVT: autogen */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: definitions */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: var_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: other_name */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: here_string */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: number */
{ DP_ST_NEED_NAME, NULL }, /* EVT: ; */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: = */
{ DP_ST_NEED_VALUE, dp_do_next_val }, /* EVT: , */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: { */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: } */
{ DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */
{ DP_ST_INVALID, dp_do_invalid } /* EVT: ] */
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are several methods for supplying data values for templates.
It is entirely possible to write a template that does not depend upon
external definitions. Such a template would likely have an unvarying
output, but be convenient nonetheless because of an external library
of either AutoGen or Scheme functions, or both. This can be accommodated
by providing the --override-tpl and --no-definitions
options on the command line. See section Invoking autogen.
AutoGen behaves as a CGI server if the definitions input is from stdin
and the environment variable REQUEST_METHOD is defined
and set to either "GET" or "POST", See section AutoGen as a CGI server. Obviously,
all the values are constrained to strings because there is no way
to represent nested values.
AutoGen comes with a program named, xml2ag. Its output can
either be redirected to a file for later use, or the program can
be used as an AutoGen wrapper. See section Invoking xml2ag.
The introductory template example (see section A Simple Example) can be rewritten in XML as follows:
<EXAMPLE template="list.tpl">
<LIST list_element="alpha"
list_info="some alpha stuff"/>
<LIST list_info="more beta stuff"
list_element="beta"/>
<LIST list_element="omega"
list_info="final omega stuff"/>
</EXAMPLE>
|
A more XML-normal form might look like this:
<EXAMPLE template="list.tpl"> <LIST list_element="alpha">some alpha stuff</LIST> <LIST list_element="beta" >more beta stuff</LIST> <LIST list_element="omega">final omega stuff</LIST> </EXAMPLE> |
but you would have to change the template list_info references
into text references.
Of course. :-)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The AutoGen template file defines the content of the output text. It is composed of two parts. The first part consists of a pseudo macro invocation and commentary. It is followed by the template proper.
This pseudo macro is special. It is used to identify the file as a AutoGen template file, fixing the starting and ending marks for the macro invocations in the rest of the file, specifying the list of suffixes to be generated by the template and, optionally, the shell to use for processing shell commands embedded in the template.
AutoGen-ing a file consists of copying text from the template to the output file until a start macro marker is found. The text from the start marker to the end marker constitutes the macro text. AutoGen macros may cause sections of the template to be skipped or processed several times. The process continues until the end of the template is reached. The process is repeated once for each suffix specified in the pseudo macro.
This chapter describes the format of the AutoGen template macros and the usage of the AutoGen native macros. Users may augment these by defining their own macros, See section DEFINE - Define a user AutoGen macro.
| 3.1 Format of the Pseudo Macro | ||
| 3.2 Naming a value | ||
| 3.3 Macro Expression Syntax | ||
| 3.4 AutoGen Scheme Functions | ||
| 3.5 Common Scheme Functions | ||
| 3.6 AutoGen Native Macros | ||
| 3.7 Redirecting Output |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The pseudo macro is used to tell AutoGen how to process a template. It tells autogen:
It is generally a good idea to use some sort of opening
bracket in the starting macro and closing bracket in the ending
macro (e.g. {, (, [, or even <
in the starting macro). It helps both visually and with editors
capable of finding a balancing parenthesis.
The next several components may be intermingled:
(suffix) scheme function (see section ‘suffix’ - get the current suffix).
The suffix specification consists of a sequence of POSIX compliant file name
characters and, optionally, an equal sign and a file name formatting
specification. That specification may be either an ordinary sequence of
file name characters with zero, one or two "%s" formatting sequences in it,
or else it may be a Scheme expression that, when evaluated, produces such a
string. The Scheme result may not be empty. The two string arguments
allowed for that string are the base name of the definition file, and the
current suffix (that being the text to the left of the equal sign). (Note:
"POSIX compliant file name characters" consist of alphanumerics plus the
period (.), hyphen (-) and underscore (_) characters.)
If the suffix begins with one of these three latter characters and a formatting string is not specified, then that character is presumed to be the suffix separator. Otherwise, without a specified format string, a single period will separate the suffix from the base name in constructing the output file name.
#]),
and edit mode comments (text between pairs of -*- strings).
before template
processing begins” means that there is no current output file, no current
suffix and, basically, none of the AutoGen specific functions
(see section AutoGen Scheme Functions) may be invoked.
It is used, for example, to allow the template writer to specify the shell program that must be used to interpret the shell commands in the template. It can have no effect on any shell commands in the definitions file, as that file will have been processed by the time the pseudo macro is interpreted.
(setenv "SHELL" "/bin/sh") |
This is extremely useful to ensure that the shell used is the one the template was written to use. By default, AutoGen determines the shell to use by user preferences. Sometimes, that can be the "csh", though.
The scheme expression can also be used to save a pre-existing output file for later text extraction (see section ‘extract’ - extract text from another file).
(shellf "mv -f %1$s.c %1$s.sav" (base-name)) |
After these must come the end macro marker:
The ending macro marker has a few constraints on its content. Some of them are just advisory, though. There is no special check for advisory restrictions.
-,
underscore _ or period .), the backslash (\) or
open parenthesis ((). These are used to identify a suffix
specification, indicate Scheme code and trim white space.
\) before the end macro mark, then
any white space characters after the mark and through the newline character
are trimmed.
#).
It might be seen as a comment within the pseudo macro.
As an example, assume we want to use [+ and +] as the start
and end macro markers, and we wish to produce a ‘.c’ and a ‘.h’
file, then the pseudo macro might look something like this:
[+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- h=chk-%s.h c # make sure we don't use csh: (setenv "SHELL" "/bin/sh") +] |
The template proper starts after the pseudo-macro. The starting character is either the first non-whitespace character or the first character after the newline that follows the end macro marker.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When an AutoGen value is specified in a template, it is specified by name. The name may be a simple name, or a compound name of several components. Since each named value in AutoGen is implicitly an array of one or more values, each component may have an index associated with it.
It looks like this:
comp-name-1 . comp-name-2 [ 2 ] |
Note that if there are multiple components to a name, each component
name is separated by a dot (.). Indexes follow a component name,
enclosed in square brackets ([ and ]). The index may be
either an integer or an integer-valued define name. The first component
of the name is searched for in the current definition level. If not
found, higher levels will be searched until either a value is found,
or there are no more definition levels. Subsequent components of the
name must be found within the context of the newly-current definition
level. Also, if the named value is prefixed by a dot (.), then
the value search is started in the current context only. No higher
levels are searched.
If someone rewrites this, I'll incorporate it. :-)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoGen has two types of expressions: full expressions and basic ones. A full AutoGen expression can appear by itself, or as the argument to certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, INVOKE (explicit invocation, see section INVOKE - Invoke a User Defined Macro), and WHILE. If it appears by itself, the result is inserted into the output. If it is an argument to one of these macros, the macro code will act on it sensibly.
You are constrained to basic expressions only when passing arguments to user defined macros, See section DEFINE - Define a user AutoGen macro.
The syntax of a full AutoGen expression is:
[[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] |
How the expression is evaluated depends upon the presence or absence
of the apply code and value name. The "value name" is the name of
an AutoGen defined value, or not. If it does not name such a value,
the expression result is generally the empty string. All expressions
must contain either a value-name or a basic-expr.
| 3.3.1 Apply Code | ||
| 3.3.2 Basic Expression |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The "apply code" selected determines the method of evaluating the expression. There are five apply codes, including the non-use of an apply code.
This is the most common expression type. Expressions of this sort come in three flavors:
The result is the value of value-name, if defined.
Otherwise it is the empty string.
The result of the basic expression is the result of the full expression, See section Basic Expression.
If there is a defined value for value-name, then the basic-expr
is evaluated. Otherwise, the result is the empty string.
If value-name is defined, use basic-expr as a format
string for sprintf. Then, if the basic-expr is either a back-quoted
string or a parenthesized expression, then hand the result to the
appropriate interpreter for further evaluation. Otherwise, for single
and double quote strings, the result is the result of the sprintf operation.
Naturally, if value-name is not defined, the result is the empty
string.
For example, assume that fumble had the string value, stumble:
[+ % fumble `printf '%%x\\n' $%s` +] |
This would cause the shell to evaluate "printf '%x\n' $stumble".
Assuming that the shell variable stumble had a numeric value,
the expression result would be that number, in hex. Note the need
for doubled percent characters and backslashes.
Two basic-expr-s are required. If the value-name is
defined, then the first basic-expr-1 is evaluated, otherwise
basic-expr-2 is.
Evaluate basic-expr only if value-name is not defined.
This combines the functions of ‘?’ and ‘%’. If value-name is
defined, it behaves exactly like ‘%’, above, using basic-expr-1.
If not defined, then basic-expr-2 is evaluated.
For example, assume again that fumble had the string value, stumble:
[+ ?% fumble `cat $%s` `pwd` +] |
This would cause the shell to evaluate "cat $stumble".
If fumble were not defined, then the result would be the name
of our current directory.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A basic expression can have one of the following forms:
A single quoted string. Backslashes can be used to protect single
quotes ('), hash characters (#), or backslashes (\)
in the string. All other characters of STRING are output as-is when the
single quoted string is evaluated. Backslashes are processed before the hash
character for consistency with the definition syntax. It is needed there
to avoid preprocessing conflicts.
A double quoted string. This is a cooked text string as in C,
except that they are not concatenated with adjacent strings.
Evaluating "STRING" will output STRING with all
backslash sequences interpreted.
A back quoted string. When this expression is evaluated, STRING is first interpreted as a cooked string (as in `"STRING"') and evaluated as a shell expression by the AutoGen server shell. This expression is replaced by the ‘stdout’ output of the shell.
A parenthesized expression. It will be passed to the Guile interpreter for evaluation and replaced by the resulting value. If there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 will report the template line number where the error occurs. Guile 1.7 has lost this capability.
Additionally, other than in the % and ?% expressions, the
Guile expressions may be introduced with the Guile comment character
(;) and you may put a series of Guile expressions within a single
macro. They will be implicitly evaluated as if they were arguments
to the (begin ...) expression. The result will be the
result of the last Guile expression evaluated.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AutoGen uses Guile to interpret Scheme expressions within AutoGen macros. All of the normal Guile functions are available, plus several extensions (see section Common Scheme Functions) have been added to augment the repertoire of string manipulation functions and manage the state of AutoGen processing.
This section describes those functions that are specific to AutoGen. Please take note that these AutoGen specific functions are not loaded and thus not made available until after the command line options have been processed and the AutoGen definitions have been loaded. They may, of course, be used in Scheme functions that get defined at those times, but they cannot be invoked.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Usage: (ag-function? ag-name)
return SCM_BOOL_T if a specified name is a user-defined AutoGen
macro, otherwise return SCM_BOOL_F.
Arguments:
ag-name - name of AutoGen macro
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |