/* 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 */