/* l2xacts.c     Grammer actions for l2x  */
/* 6/96  replaced myprint(tag) by tag_print(tag)  */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifndef STRTYPES_H
#include "strtypes.h"
#endif
#ifndef L2XCOM_H
#include "l2xcom.h"
#endif
#include "l2xusrlb.h"  /* user defined action functions */
#include "l2xlib.h"    /* functions and global variables */
#include "l2xytab.h"   /* parser communication */


/* functions defined herein */
void default_start_with_opt();
void default_end_start_opt();
void start_it();
void end_it();
void start_section();
void start_list();
void end_list();
void start_with_req();
void action_p_p1();
void action_last_p();
void start_with_opt();
void action_opt_first();
void action_p_opt();
void action_last_opt();
void action_no_param();
void do_start_pc();
void do_end_pc();
int not_ok_sym();


   /* lexer/parser communication */
extern int opt_param;


   /* 6/96  changed int pos to PSENTRY pos */

/* DEFAULT_START_WITH_OPT default action before an initial opt param */
void default_start_with_opt(pos)
PSENTRY pos;                              /* ptr to sym entry */
{

 if (not_ok_sym(pos)) {
   return;
 }

 tag_print(get_opttag_t(pos));             /* print start tag for opt param */
 set_print(get_opt_print(pos));          /* set parameter printing */
 opt_param = TRUE;                       /* processing optional */
}                                         /* end DEFAULT_START_WITH_OPT */


/* DEFAULT_END_START_OPT defaults action after an initial opt param */
void default_end_start_opt(pos)
PSENTRY pos;                                  /* command position in table */
{

 if (not_ok_sym(pos)) {
   return;
 }

 opt_param = FALSE;                      /* not processing optional */
 reset_print();                          /* set printing on */
 tag_print(get_opttag_et(pos));            /* print opt param end tag */
}                                         /* end DEFAULT_END_START_OPT */


/* START_IT starts a grammar rule */
void start_it(pos)                        /* command position in table */
PSENTRY pos;
{
 int ut;

 if (not_ok_sym(pos)) {
   return;
 }
   do_start_pc(pos);                      /* added 6/96 */
   ut = get_user_type(pos);
   switch (ut) {                          /* switch on user type */
     case SECTIONING: {
       start_section(pos);
       break;
     }
     case BEGIN_LIST_ENV: {
       start_list(pos);
       break;
     }
     case END_LIST_ENV: {
       end_list();
       break;
     }
   }
   tag_print(get_t(pos));                  /* print command start tag */
}                                      /* end START_IT */


/* END_IT ends a grammar rule */
void end_it(pos)                       /* position in command table */
PSENTRY pos;
{
 int ut;

 if (not_ok_sym(pos)) {  /* out of range */
   return;
 }
   ut = get_user_type(pos);
   switch (ut) {                     /* switch on user type */
     case SECTIONING: {              /* end tag printed via start-section */
       break;
     }
     default: {
       tag_print(get_et(pos));         /* print command end tag */
       break;
     }
   }   /* end switch */
   do_end_pc(pos);                    /* added 6/96 */
}                                      /* end END_IT */



/* START_SECTION sets up sectioning stuff */
void start_section(pos)                /* position in command table */
PSENTRY pos;
{
 int this_level;                      /* sectioning level */

 if (not_ok_sym(pos)) {  /* out of range */
   return;
 }
   this_level = get_level(pos);
   close_doc_divs(this_level);           /* close prior levels */
   current_level = this_level;           /* set current level */
   set_clause_stack(current_level, get_et(pos) );
}                                      /* end START_SECTION */


/* START_LIST sets up item list stuff */
void start_list(pos)                   /* position in command table */
PSENTRY pos;
{
 if (not_ok_sym(pos)) {  /* out of range */
   return;
 }
                              /* push tags onto list stack */
   set_list_stack(get_item_t(pos), get_item_et(pos),
                  get_itemopt_t(pos), get_itemopt_et(pos) );
}                                      /* end START_LIST */



/* END_LIST finishes a list environment */
void end_list()
{
 if (list_level >= LIST_STACK_SIZE) {
   yyerror("Somethings wrong (end_list): overflow");
   list_level = LIST_STACK_SIZE - 1;
 }
 else if (list_level < 0) {
   yyerror("Somethings wrong (end_list): underflow");
   list_level = 0;
 }
 else if (num_items[list_level] > 0) {   /* close off last item */
   tag_print(list_str_stack[list_level]);
 }
 num_items[list_level] = 0;
 list_level--;
}                                   /* end END_LIST */



/* START_WITH_REQ action at start of command with req param */
void start_with_req(pos)
PSENTRY pos;                                  /* command position in table */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   start_it(pos);                          /* command start action */
   tag_print(get_tag_t(pos,1));              /* print start tag for 1st param */
   set_print(get_param_print(pos,1));      /* set parameter printing */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_start_with_req(pos);
   break;
 }
 default: {                               /* should not be here! */
   warning("(start_with_req) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end START_WITH_REQ */


/* ACTION_P_P1 action between p'th and p+1'th req params */
void action_p_p1(pos,p)
PSENTRY pos;                           /* position of command in table */
int p;                             /* number of p'th parameter */
{
 int p1;
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 p1 = p + 1;
 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   reset_print();                  /* set printing on */
   tag_print(get_tag_et(pos,p));     /* print end tag for parameter p */
   tag_print(get_tag_t(pos,p1));     /* print start tag for p+1 */
   set_print(get_param_print(pos,p1)); /* set parameter printing */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_p_p1(pos,p);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_p_p1) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_P_P1 */


/* ACTION_LAST_P action after last req parameter */
void action_last_p(pos,p)
PSENTRY pos;                           /* position of command in table */
int p;                             /* number of last parameter */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   reset_print();
   tag_print(get_tag_et(pos,p));      /* print end tag for parameter p */
   end_it(pos);                     /* final action for command */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_last_p(pos,p);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_last_p) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_LAST_P */


/* START_WITH_OPT start action for command with optional param */
void start_with_opt(pos)
PSENTRY pos;                                  /* position of command in table */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   start_it(pos);                          /* command start action */
   default_start_with_opt(pos);            /* start optional param */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_start_with_opt(pos);
   break;
 }
 default: {                               /* should not be here! */
   warning("(start_with_opt) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end START_WITH_OPT */


/* ACTION_OPT_FIRST action between opt and 1st param */
void action_opt_first(pos)
PSENTRY pos;                           /* position of command in table */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   default_end_start_opt(pos);        /* end opt param */
   tag_print(get_tag_t(pos,1));         /* print start tag for 1st param */
   set_print(get_param_print(pos,1)); /* set parameter printing */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_opt_first(pos);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_opt_first) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_OPT_FIRST */


/* ACTION_P_OPT action between param p and opt */
void action_p_opt(pos,p)
PSENTRY pos;                           /* position of command in table */
int p;                             /* number of p'th parameter */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   reset_print();                  /* set printing on */
   tag_print(get_tag_et(pos,p));     /* print end tag for parameter p */
   tag_print(get_opttag_t(pos));     /* print start tag for opt param */
   set_print(get_opt_print(pos));  /* set parameter printing */
   opt_param = TRUE;               /* processing optional */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_p_opt(pos,p);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_p_opt) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_P_OPT */


/* ACTION_LAST_OPT action after last opt param */
void action_last_opt(pos)
PSENTRY pos;                           /* position of command in table */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   opt_param = FALSE;               /* not processing optional */
   reset_print();
   tag_print(get_opttag_et(pos));     /* print end tag for opt parameter */
   end_it(pos);                     /* final action for command */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_last_opt(pos);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_last_opt) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_LAST_OPT */


/* ACTION_NO_PARAM command with no params */
void action_no_param(pos)
PSENTRY pos;                           /* position of command in table */
{
 int user_kind;                          /* user-specified command type */

 if (not_ok_sym(pos)) {
   return;
 }

 user_kind = get_user_type(pos);

 switch(user_kind) {
 case TEX_CHAR:                     /* the general, non-specials */
 case CHAR_COMMAND:
 case COMMAND:
 case BEGIN_ENV:
 case END_ENV:
 case BEGIN_LIST_ENV:
 case END_LIST_ENV:
 case SECTIONING:
 case BEGIN_DOCUMENT:
 case END_DOCUMENT:
 case VCOMMAND:
 case BEGIN_VENV:
 case END_VENV: {
   start_it(pos);                   /* start action for command */
   end_it(pos);                     /* final action for command */
   break;
 }
 case SPECIAL:                      /* the specials */
 case SPECIAL_BEGIN_ENV:
 case SPECIAL_END_ENV:
 case SPECIAL_BEGIN_LIST:
 case SPECIAL_END_LIST:
 case SPECIAL_COMMAND:
 case SPECIAL_SECTIONING: {
   special_action_no_param(pos);
   break;
 }
 default: {                               /* should not be here! */
   warning("(action_no_param) Unrecognized command type");
   break;
 }
 } /* end switch on user_kind */
}                                         /* end ACTION_NO_PARAM */


/* DO_START_PC sets the starting print control */
void do_start_pc(pos)
PSENTRY pos;                                 /* position in command table */
{
 int pc;

 if (not_ok_sym(pos)) {
   return;
 }

 pc = get_pc_enum(get_start_pc(pos));
 switch (pc) {
   case DEFAULT_PRINT : {               /* do nothing */
     break;
   }
   case RESET : {                       /* reset print control */
     reset_print();
     break;
   }
   default : {                         /* anything else changes the setting */
     set_print(get_start_pc(pos));
     break;
   }
 } /* end switch */
 return;
}                                       /* end DO_START_PC */


/* DO_END_PC sets the ending print control */
void do_end_pc(pos)
PSENTRY pos;                                 /* position in command table */
{
 int pc;

 if (not_ok_sym(pos)) {
   return;
 }

 pc = get_pc_enum(get_end_pc(pos));
 switch (pc) {
   case DEFAULT_PRINT : {               /* do nothing */
     break;
   }
   case RESET : {                       /* reset print control */
     reset_print();
     break;
   }
   default : {                         /* anything else changes the setting */
     set_print(get_end_pc(pos));
     break;
   }
 } /* end switch */
 return;
}                                       /* end DO_END_PC */


/* NOT_OK_SYM returns TRUE if sym entry not found */
int not_ok_sym(pos)
PSENTRY pos;
{
 if (pos == NULL) {
   yyerror("symbol table entry not found");
   return(TRUE);
 }
 return(FALSE);
}                                         /* end NOT_OK_SYM */