=head1	NAME

genau - Generate automata function.

=head1	SYNOPSIS

  genau [<filename>]

=head1	DESCRIPTION

The program reads a lookup-table-based automata description and creates a
C function to simulate the automata.

=head1	RETURN VALUE

The program returns exit status code 0 on success, any other value indicates
an error.

=head1	EXAMPLE

In the example we want to write a function to check whether a string is a
valid identifier in the C programming language. Identifiers are started
by a character or underscore and followed by an optional sequence of
characters, underscores and digits.

The function check_string() processes the string character by character.
Each character is classified by the classify_char() function,
the classification result is the input to the state machine. After processing
all characters we tell the state machine about the end of input data,
output in this step shows whether the string is acceptable or not.

The check_string() function looks like this:

  #include "testid.h"

  int check_string(char *str)
  {
    int state_machine;
    int input;
    int output;
    char *ptr;

    ptr = str;
    reset_decide(&state_machine);
    while(*ptr) {
      input = classify_char(*ptr);
      (void)decide(&state_machine, input);
      ptr++;
    }
    output = decide(&state_machine, I_FINISHED);
    return output;
  }

The classify_char() function looks like this:

  int classify_char(char c)
  {
    int back = I_ANY;
    if((c >= 'a') && (c <= 'z')) {
      back = I_CHARACTER;
    } else {
      if((c >= 'A') && (c <= 'Z')) {
        back = I_CHARACTER;
      } else {
        if((c >= '1') && (c <= '9')) {
	  back = I_DIGIT;
	} else {
	  if(c == '0') {
	    back = I_DIGIT;
	  } else {
	    if(c == '_') {
	      back = I_UNDERSCORE;
	    }
	  }
	}
      }
    }
  }

We provide an input file for genau:

  [options]
    c file              = testid.c
    h file              = testid.h
    reduced file        = testid2.au
    transition function = decide
    reset function      = reset_decide
  [states]
    S_START
    S_OK
    S_ERROR
  [inputs]
    I_ANY          # Any character not mentioned below
    I_UNDERSCORE   # Input byte is '_'
    I_CHARACTER    # Input byte is a character
    I_DIGIT        # Input byte is a digit
    I_FINISHED     # Notification about the end of string
  [outputs]
    O_OK           # The string is acceptable
    O_ERROR        # The string is not an identifier
  [rules]
    *       *            S_ERROR O_ERROR
    *       I_FINISHED   S_START O_ERROR
    S_START I_UNDERSCORE S_OK    O_OK
    S_START I_CHARACTER  S_OK    O_OK
    S_OK    I_UNDERSCORE S_OK    O_OK
    S_OK    I_CHARACTER  S_OK    O_OK
    S_OK    I_DIGIT      S_OK    O_OK
    S_OK    I_FINISHED   S_START O_OK

Processing this file with genau generates testid.c and testid.h
containing the decide() and reset_decide() function.

=head1	INPUT FILE STRUCTURE

=head2	OVERVIEW

Comments in the file are started by ``#''.

The input file consists of the following sections:
``options'', ``states'', ``inputs'', ``outputs'', and ``rules''.

=head2	OPTIONS SECTION

The options section is started by ``[options]'' standing alone in
the line. In the section there are key/value pairs, key and value 
are separated by ``=''.

The following keys can be used:

=over	6

=item	B<c file>

Name of the *.c file to produce.

=item	B<h file>

Name of the *.h file to produce.

=item	B<prototypes>

Specify whether to use prototypes in the *.h file (``yes''),
K&R function declarations (``no'') or the DK_PR() notation used
by DK libs (``dk'').

=item	B<transition function>

Name of the function doing the transitions, must be a C identifier.

=item	B<reset function>

Name of the function to reset the state machine, must be a C identifier.

=item	B<reduced file>

Write reduced state machine file to this file name.

=item	B<reduce>

Allow (``yes'') or deny (``no'') a state machine reduction.

=item	B<include protect>

Specify a C identifier used to prevent multiple inclusion of the
header file.

=item	B<c define>

Specify a C identifier used to separate between the .c module generated
by genau and other C modules.

=item	B<test file>

Name of a C file to generate. This C file will test all possible
state/input combinations.

=item	B<doxygen comments>

Boolean to control whether or not to write comments for doxygen to output.

=item	B<squeezed>

Boolean to control whether output is squeezed (less spaces and empty lines)
or normal.

=back

=head2	States section

The states section is started by ``[states]'' standing alone in a line.
The following lines contain a state name each, optionally followed by
an integer number. The state names must be C identifiers.

=head2	Inputs section

The inputs section is started by ``[inputs]'' standing alone in a line.
The following lines contain input value names, optionally followed
by an integer number. The input names must be C identifiers

=head2	Outputs section

The outputs section is started by ``[outputs]'' standing alone in a line.
The following lines contain output value names, optionally followed
by an integer number. The output names must be C identifiers.

=head2	Rules section

The rules section is started by ``[rules]'' standing alone in a line.
Each line in the section contains one transition rule consisting of
four items: current state, input to process, new state, output.

Each of the items must be a name as defined in the sections above.

The wildcard symbol ``*'' can be used for current state and input.

When using wildcards, priority for the rules is as follows:

=over	6

=item	Exact rule

An exact rule (not containing wildcards) has highest priority.

=item	One wildcard

If no exact rule matches current state and input, rules containing
one wildcard are considered next. The B<first> rule found in the
file is used.

=item	Two wildcards

The general rule (two wildcards) is used only if there was no matching
exact rule and no matching rule containing one wildcard found.

=item	Implicit rule

If no matching rule was found in the tests above the state machine remains
in the current state and issues the default output (the first output
name declared in the outputs section).

=back

=head1	SEE ALSO

http://dktools.sourceforge.net/genau.html

=head1	AUTHOR

Dirk Krause

=head1	COPYRIGHT AND LICENSE

Copyright (c) 2010, Dirk Krause
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above
   copyright notice, this list of conditions and the
   following disclaimer.

 * Redistributions in binary form must reproduce the above
   copyright notice, this list of conditions and the following
   disclaimer in the documentation and/or other materials
   provided with the distribution.

 * Neither the name of the Dirk Krause nor the names of
   contributors may be used to endorse or promote products
   derived from this software without specific prior written
   permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

