#ifndef lint
char ut_sccsid[] = "@(#)yaccpar	1.4 (Berkeley) 02/25/90";
#endif
#line 2 "parseComplex.y"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Syslog.h"
#include "Attributes.h"
#include "Item.h"
#include "ItemList.h"  

Boolean debug;

/* Function prototypes*/
int ut_error(char *errorBuf);
int ut_lex();
int ut_parse();
int fileLineNo();

const int eofReturn = -1;
const int errorReturn = 1;
const int okReturn = 0;

Attributes *_attributes;

Item *_curItem;
ItemList *_itemList;

char _errorBuf[512];

void restartLexer();
Boolean isIdentifier( const char *testMe );

#line 35 "parseComplex.y"
typedef union 
{
  int integer;
  char *string;
} YYSTYPE;
#line 43 "parseComplex.tab.c"
#define Word 257
#define Identifier 258
#define YYERRCODE 256
short ut_lhs[] = {                                        -1,
    0,    1,    1,    2,    2,    3,    5,    6,    6,    4,
};
short ut_len[] = {                                         2,
    1,    1,    2,    1,    1,    3,    3,    1,    2,    4,
};
short ut_defred[] = {                                      0,
    0,    0,    0,    0,    2,    4,    5,    0,    0,    0,
    3,    8,    0,    0,    7,    6,    9,   10,
};
short ut_dgoto[] = {                                       3,
    4,    5,    6,    7,    8,   13,
};
short ut_sindex[] = {                                   -255,
  -57, -252,    0, -255,    0,    0,    0, -250, -249, -114,
    0,    0, -125,  -49,    0,    0,    0,    0,
};
short ut_rindex[] = {                                      0,
    0,    0,    0,   11,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,
};
short ut_gindex[] = {                                      0,
    0,    8,    0,   -7,    0,    0,
};
#define YYTABLESIZE 132
short ut_table[] = {                                      16,
   12,    1,    2,    9,   10,   17,    1,   14,   15,   18,
    1,   11,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    1,
};
short ut_check[] = {                                     125,
    8,  257,  258,   61,  257,   13,  257,  257,  123,   59,
    0,    4,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  257,
};
#define YYFINAL 3
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 258
#if YYDEBUG
char *yyname[] = {
"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0,"'='",0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"Word",
"Identifier",
};
char *yyrule[] = {
"$accept : ConfigFile",
"ConfigFile : Units",
"Units : Unit",
"Units : Units Unit",
"Unit : Item",
"Unit : Attribute",
"Item : StartItem Attributes '}'",
"StartItem : Identifier Word '{'",
"Attributes : Attribute",
"Attributes : Attributes Attribute",
"Attribute : Word '=' Word ';'",
};
#endif
#define yyclearin (ut_char=(-1))
#define yyerrok (ut_errflag=0)
#ifndef YYSTACKSIZE
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 300
#endif
#endif
int ut_debug;
int ut_nerrs;
int ut_errflag;
int ut_char;
short *ut_ssp;
YYSTYPE *ut_vsp;
YYSTYPE ut_val;
YYSTYPE ut_lval;
#define yystacksize YYSTACKSIZE
short ut_ss[YYSTACKSIZE];
YYSTYPE ut_vs[YYSTACKSIZE];
#line 153 "parseComplex.y"

extern char *ut_text;

int ut_error(char *errorMsg)
{
  sprintf(_errorBuf, 
	  "Line %d: %s\noffending text: \"%s\"", 
	  fileLineNo(), errorMsg, ut_text);
  
  return 0;
}

void resetComplex()
{
     _curItem = NULL;
     _attributes = NULL;
     _itemList = NULL;
}

// Used in the Lexer
Boolean isIdentifier( const char *testMe )
{
//     Boolean debug = False;

     dprintf("isIdentifier -- I've been asked to test the word %s",
	     testMe );
   
     if( _itemList != NULL )
     {
//	  return  _itemList->isIdentifier( testMe );
	  if( _itemList->isIdentifier( testMe ) )
	  {
	       dprintf("isidentifier -- %s matches",
		       _itemList->identifier() );
	       return True;
	  }
	  else
	  {
	       dprintf("isIdentifier -- %s doesn't match",
		       _itemList->identifier() );
	       return False;
	  }
	       
     }

     return False;
}

void parseComplex(FILE *fp, 
		  Attributes *attributes,
		  ItemList *itemList,
		  Boolean *error, char *errorMsg,
		  Boolean debugIn)
{
  int ret;
  extern FILE *ut_in;
  
  restartLexer();

  _attributes = attributes;
  _itemList = itemList;

  *error = False;
  ut_in = fp;

  debug = debugIn;

  if ((ret = ut_parse()) != okReturn)
  {
    /* Error or end-of-file */
    if (ret == errorReturn)
    {
      *error = True;
      strcpy(errorMsg, _errorBuf);
    }
    return;
  }

  return;
}

#line 236 "parseComplex.tab.c"
#define YYABORT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR goto yyerrlab
int
ut_parse()
{
    register int yym, yyn, yystate;
#if YYDEBUG
    register char *yys;
    extern char *getenv();

    if (yys = getenv("YYDEBUG"))
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            ut_debug = yyn - '0';
    }
#endif

    ut_nerrs = 0;
    ut_errflag = 0;
    ut_char = (-1);

    ut_ssp = ut_ss;
    ut_vsp = ut_vs;
    *ut_ssp = yystate = 0;

yyloop:
    if (yyn = ut_defred[yystate]) goto yyreduce;
    if (ut_char < 0)
    {
        if ((ut_char = ut_lex()) < 0) ut_char = 0;
#if YYDEBUG
        if (ut_debug)
        {
            yys = 0;
            if (ut_char <= YYMAXTOKEN) yys = yyname[ut_char];
            if (!yys) yys = "illegal-symbol";
            printf("ut_debug: state %d, reading %d (%s)\n", yystate,
                    ut_char, yys);
        }
#endif
    }
    if ((yyn = ut_sindex[yystate]) && (yyn += ut_char) >= 0 &&
            yyn <= YYTABLESIZE && ut_check[yyn] == ut_char)
    {
#if YYDEBUG
        if (ut_debug)
            printf("ut_debug: state %d, shifting to state %d\n",
                    yystate, ut_table[yyn]);
#endif
        if (ut_ssp >= ut_ss + yystacksize - 1)
        {
            goto yyoverflow;
        }
        *++ut_ssp = yystate = ut_table[yyn];
        *++ut_vsp = ut_lval;
        ut_char = (-1);
        if (ut_errflag > 0)  --ut_errflag;
        goto yyloop;
    }
    if ((yyn = ut_rindex[yystate]) && (yyn += ut_char) >= 0 &&
            yyn <= YYTABLESIZE && ut_check[yyn] == ut_char)
    {
        yyn = ut_table[yyn];
        goto yyreduce;
    }
    if (ut_errflag) goto ut_inrecovery;
#ifdef lint
    goto yynewerror;
#endif
yynewerror:
    ut_error("syntax error");
#ifdef lint
    goto yyerrlab;
#endif
yyerrlab:
    ++ut_nerrs;
ut_inrecovery:
    if (ut_errflag < 3)
    {
        ut_errflag = 3;
        for (;;)
        {
            if ((yyn = ut_sindex[*ut_ssp]) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && ut_check[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (ut_debug)
                    printf("ut_debug: state %d, error recovery shifting\
 to state %d\n", *ut_ssp, ut_table[yyn]);
#endif
                if (ut_ssp >= ut_ss + yystacksize - 1)
                {
                    goto yyoverflow;
                }
                *++ut_ssp = yystate = ut_table[yyn];
                *++ut_vsp = ut_lval;
                goto yyloop;
            }
            else
            {
#if YYDEBUG
                if (ut_debug)
                    printf("ut_debug: error recovery discarding state %d\n",
                            *ut_ssp);
#endif
                if (ut_ssp <= ut_ss) goto yyabort;
                --ut_ssp;
                --ut_vsp;
            }
        }
    }
    else
    {
        if (ut_char == 0) goto yyabort;
#if YYDEBUG
        if (ut_debug)
        {
            yys = 0;
            if (ut_char <= YYMAXTOKEN) yys = yyname[ut_char];
            if (!yys) yys = "illegal-symbol";
            printf("ut_debug: state %d, error recovery discards token %d (%s)\n",
                    yystate, ut_char, yys);
        }
#endif
        ut_char = (-1);
        goto yyloop;
    }
yyreduce:
#if YYDEBUG
    if (ut_debug)
        printf("ut_debug: state %d, reducing by rule %d (%s)\n",
                yystate, yyn, yyrule[yyn]);
#endif
    yym = ut_len[yyn];
    ut_val = ut_vsp[1-yym];
    switch (yyn)
    {
case 1:
#line 47 "parseComplex.y"
{
}
break;
case 2:
#line 51 "parseComplex.y"
{
}
break;
case 3:
#line 55 "parseComplex.y"
{
}
break;
case 4:
#line 60 "parseComplex.y"
{
}
break;
case 5:
#line 64 "parseComplex.y"
{
}
break;
case 6:
#line 68 "parseComplex.y"
{
     dprintf("Finished parsing item %s", _curItem->name());
     _curItem = NULL;
}
break;
case 7:
#line 74 "parseComplex.y"
{
     if( _itemList == NULL )
     {
	  Syslog::write("Parser has found inappropriate identifier");
	  return errorReturn;
     }

     dprintf("Parsing new item of type: %s named %s\n",
	     _itemList->identifier(), ut_vsp[-1].string  );
     
     if( (_curItem = _itemList->addItem( ut_vsp[-1].string  )) == NULL ) 
     {
	  dprintf("Something went wrong adding a new item called %s",
		  ut_vsp[-1].string  );
     }

}
break;
case 8:
#line 93 "parseComplex.y"
{
}
break;
case 9:
#line 98 "parseComplex.y"
{
}
break;
case 10:
#line 103 "parseComplex.y"
{
  dprintf("Parsing attribute %s = %s", ut_vsp[-3].string , ut_vsp[-1].string  );

  Attributes *curAttributes = NULL;

  Attribute::Input *input = new Attribute::Input(ut_vsp[-3].string , ut_vsp[-1].string );

  Boolean error = False;

/*  dprintf("Parsing attribute %s = %s", $1, $3 );*/

  if( _curItem != NULL ) {
       dprintf("Using the current item %s",
	       _curItem->name() );
       curAttributes = _curItem->attributes();

       dprintf("Using the attribute set %s from item  %s\n",
	       curAttributes->objectName(),
	       _curItem->name() );
  }
  else if( _attributes != NULL ) {
       dprintf("No current item .. using the provided attributes %s",
	       _attributes->objectName() );
       curAttributes = _attributes;
  }
  else
  {
       Syslog::write("complexParser -- Found ungrouped attributes in the "
		     "wrong place.");
       return errorReturn;
  }

  if (curAttributes->parse(input) == -1) {

      /* Invalid worksite attribute*/
/*      sprintf(_errorBuf, "Invalid attribute: %s = %s",*/
/*	      $1, $3);*/

      error = True;
  }

  delete input;

  if (error)
    return errorReturn;
}
break;
#line 487 "parseComplex.tab.c"
    }
    ut_ssp -= yym;
    yystate = *ut_ssp;
    ut_vsp -= yym;
    yym = ut_lhs[yyn];
    if (yystate == 0 && yym == 0)
    {
#ifdef YYDEBUG
        if (ut_debug)
            printf("ut_debug: after reduction, shifting from state 0 to\
 state %d\n", YYFINAL);
#endif
        yystate = YYFINAL;
        *++ut_ssp = YYFINAL;
        *++ut_vsp = ut_val;
        if (ut_char < 0)
        {
            if ((ut_char = ut_lex()) < 0) ut_char = 0;
#if YYDEBUG
            if (ut_debug)
            {
                yys = 0;
                if (ut_char <= YYMAXTOKEN) yys = yyname[ut_char];
                if (!yys) yys = "illegal-symbol";
                printf("ut_debug: state %d, reading %d (%s)\n",
                        YYFINAL, ut_char, yys);
            }
#endif
        }
        if (ut_char == 0) goto yyaccept;
        goto yyloop;
    }
    if ((yyn = ut_gindex[yym]) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && ut_check[yyn] == yystate)
        yystate = ut_table[yyn];
    else
        yystate = ut_dgoto[yym];
#ifdef YYDEBUG
    if (ut_debug)
        printf("ut_debug: after reduction, shifting from state %d \
to state %d\n", *ut_ssp, yystate);
#endif
    if (ut_ssp >= ut_ss + yystacksize - 1)
    {
        goto yyoverflow;
    }
    *++ut_ssp = yystate;
    *++ut_vsp = ut_val;
    goto yyloop;
yyoverflow:
    ut_error("yacc stack overflow");
yyabort:
    return (1);
yyaccept:
    return (0);
}
