/*
Copyright (c) 2000-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 
  opyright 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.
*/

/**	@file	genau.h	Include file for genau modules.
*/

#ifndef GENAU_INC
#define GENAU_INC 1

#include <dk.h>
#include <dktypes.h>


#if defined(LINELENGTH)
#if (LINELENGTH < 512)
#undef LINELENGTH
/**	Input line buffer length. */
#define LINELENGTH 512
#endif
#else
/**	Input line buffer length. */
#define LINELENGTH 1024
#endif

/**	State machine input.
*/
typedef struct {
  char *name;		/**< Input name. */
  int   number;		/**< Numeric value. */
  int   number_defined;	/**< Flag: Numeric value defined. */
  unsigned long lineno;	/**< Line number in input file. */
  unsigned rednum;	/**< Numeric value after reduction. */
} au_input_t ;

/**	State machine output.
*/
typedef struct {
  char *name;		/**< Output name. */
  int   number;		/**< Numeric value. */
  int   number_defined;	/**< Flag: Numeric value defined. */
  unsigned long lineno;	/**< Line number in input file. */
  unsigned rednum;	/**< Numeric value after reduction. */
} au_output_t ;

/**	State.
*/
typedef struct {
  char                  *name;			/**< Name. */
  int                    number;		/**< Numeric value. */
  int                    number_defined;	/**< Flag: Value defined. */
  /* transitions sorted by name */
  dk_storage_t          *trans;		/**< Transition table containter. */
  dk_storage_iterator_t *trit;		/**< Transition table iterator. */
  unsigned long lineno;			/**< Line number in input file. */
  void                  *compat;	/**< Compatible state. */
  unsigned rednum;			/**< Numeric value after reduction. */
} au_state_t ;

/**	Transition.
*/
typedef struct {
  char        *current_name;	/**< Name of current state. */
  au_state_t  *current_data;	/**< Pointer to current state. */
  char        *input_name;	/**< Name of input. */
  au_input_t  *input_data;	/**< Pointer to input. */
  char        *next_name;	/**< Name of new state. */
  au_state_t  *next_data;	/**< Pointer to new state. */
  char        *output_name;	/**< Name of output. */
  au_output_t *output_data;	/**< Pointer to output. */
  unsigned long lineno;		/**< Line number in source file. */
} au_state_transition_t ;

/**	One option line.
*/
typedef struct {
  char		*line;		/**< Text line. */
  unsigned long lineno;		/**< Line number. */
} au_option_line_t ;

/**	State machine.
*/
typedef struct {
  /*
    options sorted by line number
  */
  dk_storage_t          *opt;	/**< Options container, by line number. */
  dk_storage_iterator_t *optit;	/**< Options iterator, by line number. */
  /*
    states sorted by name
  */
  dk_storage_t          *st;	/**< States container, by name. */
  dk_storage_iterator_t *stit;	/**< States iterator, by name. */
  /*
    initial state
  */
  au_state_t *initial_state;	/**< Intial state. */
  /*
    inputs sorted by name
  */
  dk_storage_t          *in;	/**< Inputs container, by name. */
  dk_storage_iterator_t *init;	/**< Input iterator, by name. */
  /*
    outputs sorted by name
  */
  dk_storage_t          *out;	/**< Outputs container, by name. */
  dk_storage_iterator_t *outit;	/**< Outputs iterator, by name. */
  /*
    all transitions
  */
  dk_storage_t          *alltr;		/**< Transitions container. */
  dk_storage_iterator_t *alltrit;	/**< Transitions iterator. */
  /*
    all-state-transitions sorted by input name
  */
  dk_storage_t          *asttr;		/**< All-state transitions, name. */
  dk_storage_iterator_t *asttrit;	/**< All-state transitions it, name. */
  /*
    all-state-transitions sorted by line number
  */
  dk_storage_t          *asttrl;	/**< All-state transitions, line no. */
  dk_storage_iterator_t *asttrlit;	/**< All-state tr. it., line no. */
  /*
    general rule, i.e. * * ST_START NOP
  */
  au_state_transition_t *general_rule;	/**< General rule. */
  au_output_t *def_output;		/**< Default output. */
  /* did there occur errors ? */
  int error_code;			/**< Last error occured. */
  /*
    used by readau, do not modify
  */
  dk_app_t *app;			/**< Application. */
  dk_stream_t *is;			/**< Input stream. */
  unsigned long lineno;			/**< Current line number. */
  int prototypes;			/**< Prototypes. */
  char *name_trans;			/**< Name of transition function. */
  char *name_res;			/**< Name of reset function. */
  char *i_prot;				/**< Name of include protection. */
  char *c_def;				/**< C file definition. */
  char *h_file_name;			/**< Output header file name. */
  char *t_file_name;			/**< Output file name. */
  char *input_file_name;		/**< Input file name. */
  int   squeezed_output;		/**< Output file for reduced automata. */
  int	doxy_output;			/**< Generate output for doxygen. */
} automata_t ;

#if defined(EXTERN)
#undef EXTERN
#endif
#ifndef GENAU_C
#if !DK_HAVE_PROTOTYPES
#define EXTERN extern
#else
#define EXTERN /* nix */
#endif
#else
#define EXTERN /* nix */
#endif

#if defined(__cplusplus)
extern "C" {
#endif

/**	Retrieve texts for messages.
 * 	@return	Pointer to messages array.
 */
EXTERN
char **genau_strings DK_PR((void));

/**	Retrieve texts for progress messages.
 * 	@return Pointer to messages array.
 */
EXTERN
char **genau_progress DK_PR((void));

#if defined(__cplusplus)
}
#endif

#endif

