|  |  9.3.2 `sic_syntax.c' 
The syntax of the commands in the shell I am writing is defined by a set
of syntax handlers which are loaded into `libsic' at startup.  I
can get the C preprocessor to do most of the repetitive code for me, and
just fill in the function bodies:
 
 |  | 
 #if HAVE_CONFIG_H
#  include <config.h>
#endif
#include "sic.h"
/* List of builtin syntax. */
#define syntax_functions                \
        SYNTAX(escape,  "\\")           \
        SYNTAX(space,   " \f\n\r\t\v")  \
        SYNTAX(comment, "#")            \
        SYNTAX(string,  "\"")           \
        SYNTAX(endcmd,  ";")            \
        SYNTAX(endstr,  "")
/* Prototype Generator. */
#define SIC_SYNTAX(name)                \
        int name (Sic *sic, BufferIn *in, BufferOut *out)
#define SYNTAX(name, string)            \
        extern SIC_SYNTAX (CONC (syntax_, name));
syntax_functions
#undef SYNTAX
/* Syntax handler mappings. */
Syntax syntax_table[] = {
#define SYNTAX(name, string)            \
        { CONC (syntax_, name), string },
  syntax_functions
#undef SYNTAX
  
  { NULL, NULL }
};
 | 
 
This code writes the prototypes for the syntax handler functions, and
creates a table which associates each with one or more characters that
might occur in the input stream.  The advantage of writing the code this
way is that when I want to add a new syntax handler later, it is a simple
matter of adding a new row to the syntax_functionsmacro, and
writing the function itself. 
 |