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