/* l2xusrlb.c           user-defined support functions for l2x actions */
/*                  Written by Peter Wilson (Catholic University and NIST) */

/* Development of this software was funded by the United States Government,
 * and is not subject to copyright.
 */


#include <stdio.h>
#ifndef STRTYPES_H
#include "strtypes.h"
#endif
#ifndef L2XCOM_H
#include "l2xcom.h"
#endif
#include "l2xytab.h"               /* parser communication */
#include "l2xlib.h"                /* l2x system library functions */
#include "l2xacts.h"               /* l2x standard actions */

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

/* In general, actions are specified via case statements
 * in the special_ functions at the end of this file. The
 * special actions must be provided by the extender.
 */

/* The system special_ functions */
void special_start_with_req();
void special_action_p_p1();
void special_action_last_p();
void special_start_with_opt();
void special_action_opt_first();
void special_action_p_opt();
void special_action_last_opt();
void special_action_no_param();

/* extender-provided functions */
void prwboiler1();
void prwboiler2();
void prwboiler3();
void codespecial_start();
void codespecial_p1();
void codespecial_end();



          /* FUNCTIONS, ETC. TO BE PROVIDED BY THE EXTENDER */

             /* demonstration string definition */
STRING boiler_string_3 = "\nin the middle of it.\n\n";

                   /* demonstration functions */

char codebuf[80];                  /* a string buffer */

/* PRWBOILER1 print some demonstration boilerplate */
void prwboiler1()
{
  myprint("\nSome boilerplate text with ");
}                                 /* end PRWBOILER1 */

/* PRWBOILER2 print some demonstration boilerplate */
void prwboiler2()                 
{
  myprint("\nin the middle. Now there is\n");
  myprint("some more boilerplate with ");
}                                 /* end PRWBOILER2 */

/* PRWBOILER3 yet more demonstration boilerplate */
void prwboiler3()                 
{
  myprint(boiler_string_3);
}                                 /* end PRWBOILER1 */

/* CODESPECIAL_START actions for start of CODEspecial command */
void codespecial_start(pos)
PSENTRY pos;                           /* symbol entry */
{
  start_section(pos);              /* do start of sectioning */
  tag_print(get_t(pos));             /* print start tag */
}                              /* end CODESPECIAL_START */


/* CODESPECIAL_P1 actions at stast of CODEspecial param 1 */
void codespecial_p1(pos)
PSENTRY pos;                           /* symbol entry */
{
  tag_print(get_tag_t(pos,1));       /* print 1st param start tag */
  initialise_sysbuf();             /* clear system string buffer */
  set_print(p_print_to_sysbuf);    /* put param text into system buffer */
}                             /* end CODESPECIAL_P1 */

/* CODESPECIAL_END actions at end of CODEspecial command */
void codespecial_end(pos)
PSENTRY pos;                           /* symbol entry */
{
  initialise_string(codebuf);      /* clear this string buffer */
  copy_sysbuf(codebuf);            /* copy system buffer into this buffer */
  reset_print();                   /* normal printing */
  prwboiler1();                    /* print some boilerplate */
  print_sysbuf();                  /* print system buffer */
  prwboiler2();                    /* print more boilerplate */
  myprint(codebuf);                /* print this buffer */
  prwboiler3();                    /* print yet more boilerplate */
  start_list(pos);                 /* start a list environment */
}                             /* end CODESPECIAL_END */



/*==================================================================*/
    /* SYSTEM SPECIAL_ FUNCTIONS FOR INCORPORATING EXTENDER */
    /* SPECIFIED CASE STATEMENTS FOR USER-DEFINED SPECIAL COMMANDS */


/* SPECIAL_START_WITH_REQ special action at start of command with req param */
void special_start_with_req(pos)
PSENTRY pos;                           /* symbol entry  */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_start_with_req) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_START_WITH_REQ */


/* SPECIAL_ACTION_P_P1 special action between p'th and (p+1)'th req params */
void special_action_p_p1(pos,p)
PSENTRY pos;                           /* symbol entry */
int p;                             /* number of p'th req param */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_p_p1) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_P_P1 */


/* SPECIAL_ACTION_LAST_P special action after last req param */
void special_action_last_p(pos,p)
PSENTRY pos;                           /* symbol entry */
int p;                             /* number of last req param */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */
  case 59999:                       /* example coded special */
    if (p == 1) {                   /* has only 1 req param */
      codespecial_end(pos);
    }
    break;

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_last_p) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_LAST_P */


/* SPECIAL_START_WITH_OPT special start for command with opt param */
void special_start_with_opt(pos)
PSENTRY pos;                           /* symbol entry */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */
  case 59999:                       /* example coded special */
    codespecial_start(pos);
    default_start_with_opt(pos);
    break;

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_start_with_opt) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_START_WITH_OPT */


/* SPECIAL_ACTION_OPT_FIRST special action between opt and 1st param */
void special_action_opt_first(pos)
PSENTRY pos;                           /* symbol entry */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */
  case 59999:                       /* example coded special */
    default_end_start_opt(pos);
    codespecial_p1(pos);
    break;

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_opt_first) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_OPT_FIRST */


/* SPECIAL_ACTION_P_OPT special action between param p and opt */
void special_action_p_opt(pos,p)
PSENTRY pos;                           /* symbol entry */
int p;                             /* number of p'th req param */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_p_opt) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_P_OPT */


/* SPECIAL_ACTION_LAST_OPT special action after last opt param */
void special_action_last_opt(pos)
PSENTRY pos;                           /* symbol entry */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_last_opt) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_LAST_OPT */


/* SPECIAL_ACTION_NO_PARAM special action for command with no params */
void special_action_no_param(pos)
PSENTRY pos;                           /* symbol entry */
{
  int special_kind;                /* user-specified special token */

  special_kind = get_special_token(pos);

  switch(special_kind) {
    /* additional cases for specials added here */

    /* end of cases for specials */
  default:                        /* should not be here! */
    warning("(special_action_no_param) Unrecognized SPECIAL");
    tdebug_str_int("SPECIAL_TOKEN =",special_kind);
    break;
  }  /* end of switch on user_kind */
}                            /* end SPECIAL_ACTION_NO_PARAM */