AutoGen: 1.2 A Simple Example

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 1.2 A Simple Example

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 const char* az_name_list[ 3 ];

Then you also have ``list.c'` that defines the actual strings:

    #include "list.h"
    const char* 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 const char* az_name_list[ [+ (count "list") +] ];
    [+

       ==  c  +]
    #include "list.h"
    const char* 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] | [ ? ]

This document was generated by Bruce Korb on April, 24 2005 using texi2html 1.76.