//
// IBIS_AMI_tree.h
//
// Header file for parsing and assembling IBIS AMI parameter trees
// 
// Copyright (c) 2007. Signal Integrity Software, Inc. (SiSoft)
// All Rights Reserved.
//
// History:
// 8 June 2007, Mike Steinberger: Added support for array-type parameters.
// 22 May 2007, Mike Steinberger: Initial file creation
//
//
// Permission to use, copy, modify, and distribute this software and 
// associated documentation for educational, research and commercial 
// purposes, without fee and without a signed licensing agreement, is hereby
// granted, provided that the above copyright notice, this paragraph and
// the following three paragraphs appear in all copies, modifications, and
// distributions. 
//
// This is part of a sample IBIS Algorithmic Modeling Interface (AMI) model. 
// This code has been provided by SiSoft to help demonstrate and drive 
// adoption of the IBIS AMI modeling standard.  For more information
// on this and other IBIS AMI models, contact Signal Integrity Software, 
// 6 Clock Tower Place, Maynard, MA 01754, (978) 461-0449 or email
// ibis-ami@sisoft.com.
// 
// THIS MATERIAL IS PROVIDED FOR THE RECIPIENT'S USE AT THE RECIPIENT's OWN RISK.
// IN NO EVENT SHALL SISOFT BE LIABLE TO ANY PARTY FOR FOR ANY DIRECT,
// INDIRECT, INCIDENTAL,SPECIAL OR CONSEQUENTIAL DAMAGES, OR ANY OTHER DAMAGES 
// WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, 
// BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) 
// ARISING OUT OF THE USE OR INABILITY TO USE THIS LICENSED MATERIAL, WHETHER 
// OR NOT THE POSSIBILITY OR CAUSE OF SUCH DAMAGES WAS KNOWN TO SISOFT.
// 
// SISOFT SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE. THIS SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
// ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". SISOFT HAS NO OBLIGATION
// TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

#ifndef AMI_TREE_INCLUDED
#define AMI_TREE_INCLUDED

#define MAX_TREE_DEPTH 16  //Maximum nesting depth for tree structure
#define MAX_LEAF_SIZE  128 //Maximum text length for a single leaf
#define MAX_VAL_SIZE   32  //Maximum text length for a single value
#define _CRT_SECURE_NO_WARNINGS //Hack for M$ non-portability

typedef enum {
   ami_double_type,
   ami_long_type,
   ami_int_type,
   ami_short_type,
   ami_char_type,
   ami_double_array_type,
   ami_long_array_type,
   ami_int_array_type,
   ami_short_array_type,
   ami_string_type,
   ami_list_type    //Intended for pointers to branches of the tree
                    //   in order to support nested branching
} ParamType;

typedef struct {
   ParamType array_type;
   int       length;
   void     *contents;
} ArrayVal;

typedef union {
   double    dbl_val;
   long      long_val;
   int       int_val;
   short     short_val;
   char      char_val;
   ArrayVal *array_val;
   char     *string_val;
   void     *ptr_val;
} ParamVal;

typedef struct ParamListItem{
   char     *name;
   ParamType p_type;
   ParamVal  p_val;
} ParamListItem;

typedef struct ParamList{
   char          *name;
   int            length;
   ParamListItem *contents;
} ParamList;

typedef enum {
   ami_open_paren,
   ami_text,
   ami_white_space,
   ami_close_paren
} LexerState;

typedef enum {
   ami_start,
   ami_branch,
   ami_leaf,
   ami_end
} ParserState;

typedef struct {
   const char *start;
   int   length;
} InLineString;

//Allocate memory for an output string and then concatenate two strings
//into the output string.
//Use with string-type parameters to avoid free() errors when using FreeTree().
char* string_cat( const char* str1, const char* str2 );

//Tree syntax lexer
//   text_ptr         Incoming character
//   lexer_state     Incoming lexer state
//   parser_state    Parser state (to support string literal values)
//   token_text      Accumulated token
//   string_literal  Flag to indicate when in the middle of a string literal.
//                   Initialize to zero.
//   process_text    Flag to indicate when the text is to be processed
//                   Initialize to zero.
//   Returns updated lexer state.
LexerState AmiLexer( const char   *text_ptr,
                     LexerState   lexer_state,
                     ParserState  parser_state,
                     InLineString *token_text,
                     int          *string_literal,
                     int          *process_text );

//Tree syntax parser
//   lexer_state     Incoming lexer state
//   parser_state    Incoming parser state
//   process_text    Flag to indicate when the text is to be processed.
//                   Also an implicit part of the lexer state.
//                   Initialize to zero.
//   stack_ptr       Branch stack index in and out.
//                   Initialize to zero.
//   Returns updated parser state.
ParserState AmiParser( LexerState  lexer_state,
                       ParserState parser_state,
                       int         *process_text,
                       int         *stack_ptr );

//Parse incoming parameter string from tree syntax to specified parameter list.
//   Return the number of items set.
int ParseTree( const char *parameters_in, ParamList param_list_in );

//Convert a parameter list to a parameter string with tree syntax.
//   This function allocates the memory for the string.
//   The caller is responsible for freeing it.
char* GrowTree( const ParamList param_list_in );

//Destroy a parameter list and free its associated memory.
//   Assume that names are static strings that should not be destroyed/freed.
//   Assume that array and string values have been allocated dynamically
//   and must therefore be freed.
void FreeTree( ParamList param_list_in );
#endif //AMI_TREE_INCLUDED
