/*******************************************************************************
* YORKTOWN ADVANCED SGML PARSER (YASP)                                         *
*         An SGML Parser conforming to International Standard ISO 8879 --      *
*         Standard Generalized Markup Language                                 *
*------------------------------------------------------------------------------*
* Written 1987 - 1993 by                                                       *
*         Pierre G. Richard                                                    *
*         IBM T.J. Watson Research Center                                      *
*         Yorktown Heights, New York                                           *
*         petrus@watson.ibm.com                                                *
*------------------------------------------------------------------------------*
* FUNCTION NAME    = YASP / Header File                                        *
* STATUS           = Version 0, Release 1, Level 34 and up                     *
* COMPONENT NAME   = global.h                                                  *
* DESCRIPTIVE NAME = Global Variables Definition and General Tables            *
* DATE_WR          = 03/20/1987                                                *
* AUTHOR           = Pierre G. Richard - PETRUS at YKTVMX                      *
*                                                                              *
* FUNCTIONAL DESCRIPTION =                                                     *
*                                                                              *
* Define in GLOBAL AREA *all* non-constant data that are:                      *
*   - shared between separate functions                                        *
*     (external --at the program scope, static or not)                         *
*   OR                                                                         *
*   - kept permanently for the use of a specific function                      *
*     (internal static, within the scope of a function)                        *
*                                                                              *
* Use GA(member) when a variable belonging to the GLOBAL_AREA needs to be      *
* accessed.                                                                    *
*                                                                              *
* IMPLEMENTATION NOTES =                                                       *
*                                                                              *
* 1) This area is on the stack, zeroed at initialization.                      *
*                                                                              *
* 2) To insure REENTRANCY all other internal static / external data must       *
*    be qualified with the CONST modifier !  (some compilers are smart)        *
*                                                                              *
* 3) There is no more way to keep the "privacy" of "extern static" variables.  *
*    However enough safety is provided:                                        *
*    - no GLOBAL DATA must be "inadvertently" accessed:                        *
*      GA(member) must be used.                                                *
*    - explicit names avoid erroneous usages (member names can be any size)    *
*                                                                              *
* CHANGE HISTORY =                                                             *
* Number Date     Inits    Change & Reason (brief)                             *
*      1 01/28/89 PETRUS   REENTRANCY.                                         *
*      2 03/01/91 DUROT    Added pos. in ODBF, RE_position, ooc_position in GA *
*******************************************************************************/
#include <setjmp.h>

/*-----------------------------------------------------------------------------+
| Token numbers are associated to SGML keywords and grouped in an enum type.   |
| This permits a strongest type checking (for compilers that allow it).        |
+-----------------------------------------------------------------------------*/
typedef enum t_TK {    /* TK */
   NOT_FOUND_TK,       /* This one reserved */
   AND_TK,        ANY_TK,        ATTLIST_TK,    CDATA_TK,      COM_TK,
   CONTROLS_TK,   CRO_TK,        DOCTYPE_TK,    DOCUMENT_TK,   DSC_TK,
   DSO_TK,        DTGC_TK,       DTGO_TK,       ELEMENT_TK,    EMPTY_TK,
   ENTITY_TK,     ERO_GRPO_TK,   ERO_TK,        ETAGO_TK,      ETAGO_GRPO_TK,
   ETAGO_TAGC_TK, GRPC_TK,       GRPO_TK,       IDLINK_TK,     INSTANCE_TK,
   LINK_TK,       LINKTYPE_TK,   LIT_TK,        LITA_TK,       MDC_TK,
   MDO_TK,        MDO_COM_TK,    MDO_DSO_TK,    MDO_MDC_TK,    MINUS_TK,
   MINUS_GRPO_TK, MSC_MDC_TK,    MSC_TK,        NET_TK,        NO_TK,
   NONE_TK,       NOTATION_TK,   OPT_TK,        OR_TK,         PERO_GRPO_TK,
   PERO_TK,       PIC_TK,        PIO_TK,        PLUS_TK,       PLUS_GRPO_TK,
   PUBLIC_TK,     RCDATA_TK,     REFC_TK,       REGION_TK,     REP_TK,
   RNI_TK,        SEQ_TK,        SHORTREF_TK,   STAGO_GRPO_TK, STAGO_TAGC_TK,
   STAGO_TK,      SYSTEM_TK,     TAGC_TK,       USEMAP_TK,     VI_TK,
   YES_TK,
   SR_first
/* SR_last = SR_first + 5000 */
}TK;

/*-----------------------------------------------------------------------------+
| GEN.H and PSE.H: Tables associated to SGML Keywords, generated by GNNAME     |
+-----------------------------------------------------------------------------*/
#include "pse.h"
#include "gen.h"

#if (defined(DOS_SYS) || defined(OS2V1_SYS))    /* 16-bit systems */
#define MAX_DTD 3               /* will limit CONCUR or SUBDOC */
#else
#define MAX_DTD 10              /* will limit CONCUR or SUBDOC */
#endif

/*-----------------------------------------------------------------------------+
| SKMGR: Local structures and #defined Values                                  |
+-----------------------------------------------------------------------------*/
#define PARKING_LOT_SIZE LITLEN_MAX+1  /* No string greater than this value ! */

typedef struct t_PARKING {
   OFS    ofs_start;
   struct t_PARKING *prev;      /* previous parking */
   uint   room_size;            /* room_left until the parking is full */
   uchar  lot[PARKING_LOT_SIZE];
}PARKING;

/*-----------------------------------------------------------------------------+
| PLMGR: Local structures and #defined Values                                  |
+-----------------------------------------------------------------------------*/
#define POOLID_MAX 7  /* 8 pools numbered from 0 to 7 */
#define ITFCE_POOL 5  /* Pool id of all malloc/free for the Interface */

typedef struct t_POOL {
   void *sp_p;                  /* current sub-pool for this pool */
   uint  idmax;                 /* number of subpool(s) in this pool */
}POOL;

/*-----------------------------------------------------------------------------+
| UTMGR: Local structures                                                      |
+-----------------------------------------------------------------------------*/
typedef struct t_UTID {         /* to associate an Id-AHL to an utility file */
   uchar name[NAMELEN_MAX+1];   /* ODT: doctype name */
   AHL   id_ahl;                /* identifier */
}UTID;

/*-----------------------------------------------------------------------------+
| EM (Entity Manager): Local structures and #defined Values                    |
+-----------------------------------------------------------------------------*/
#define OFRW_MAX  10          /* Max number of offset/rows to remember */
#define BUFSIZE 0x1000        /* must be a power of 2 (4096 defined here) */
                              /* LITLEN and BSEQLEN must be less or equal */
typedef struct t_YB {         /* entitY Block */
   OEB oeb;                   /* Open Entity Block */
   struct t_YB *prev_p;       /* Previous opened entity */
   long  vdiff;               /* offset - virtual offset (after replacements) */
   int fore_bufsize;          /* unread buffer size */
   union {
      uint  curr_char;        /* just one char */
      uchar *fore_buf;        /* or a true buffer is waiting */
   }v;
   /* the following is irrelevant for a memory entity */
   int buf_pos;               /* Current active position in buffer */
   int buf_max;               /* Last valid position in buffer */
   long  ofrw[OFRW_MAX];      /* Offsets of the OFRW_MAX last rows */
   uchar *buffer;             /* Data transfer buffer */
}YB;

/*-----------------------------------------------------------------------------+
| DELIMITER Tables: (OCSDLIM, DLFIND)                                          |
| The Delimiter Vector Table maps a tree for a fast delimiter recognition.     |
+-----------------------------------------------------------------------------*/
#define MAX_MODE_LVL  16      /* modes: maximum level of nesting */
#define MAX_CHARSET  256      /* Maximum CHARSET size */

typedef struct t_DV {         /* Delimiter Vector */
   union {                    /* either: */
      struct {                /* for a primary node: */
         boolean is_bseq;     /* B sequence indicator */
         uchar count;         /* and count of consequent vectors */
      }h;                     /* for a secondary node, and bseq-node */
      uint dvix;              /* index to the next prim node, or previous ... */
      struct t_DV *next;      /* ...then relocated */
      struct t_DV *previous;  /* ...then relocated */
   }i;
   union {
      uint bseqlen;           /* bseq_node: count of minimum B-seq follows */
      TK tk;                  /* token associated */
   }t;
   union {                    /* either */
      OFS stix;               /* Prep Char List / Continuation String.. */
      uchar *str;             /* ...then relocated */
      boolean must_recur;     /* bseq_node: fast recognition of a recurrence */
   }s;
}DV;

typedef union {               /* Entry in the DVTAB for a given mode */
   uint rel;                  /* relative to the DVTAB */
   DV *dv_p;                  /* ... then relocated */
}DVTBENT;

typedef struct {
   uchar  *named;
   TK      token;
   ALLMO   allmode;
   uchar  *assigned;
   int     dstab_ix;
}DLMV;

typedef struct {
   TK    tk1;
   TK    tk2;
   TK    token;
   ALLMO allmode;
}DDLMV;

/*-----------------------------------------------------------------------------+
| STOWER: double-buffer                                                        |
| The ODBF_SIZE cannot be more than 256, as the length of a string is saved in |
| one byte.                                                                    |
+-----------------------------------------------------------------------------*/
#define ODBF_SIZE 128                 /* Cannot not be more than 256 */

/* If the following error arises:                            */
/* - Increase the ODBF_SIZE until 256                        */
/* - If still troubles, recode ODBF for a triple-buffering   */
/*   or find a trick... (256 records == continuation ?)      */

#if (DTAGLEN > ODBF_SIZE)
#error DTAGLEN too big, redo data buffering code
#endif

typedef struct t_ODBF {          /* Output Buffer -- Double buffering */
   struct t_ODBF STACK_BASED *next_p; /* Pointer to the alternate ODBF */
   uchar  STACK_BASED *c_p0;     /* Start substrings in buf since last flush */
   uchar  STACK_BASED *cnt_p;    /* Current substring starts with its length */
   uchar  STACK_BASED *c_p;      /* Current character in current substring */
   uchar  buf[ODBF_SIZE];        /* First entry is always a substring length */
   POS    STACK_BASED *pos_p0;   /* Start positions in pos */
   POS    STACK_BASED *pos_p;    /* Current position pointer */
   POS    pos[ODBF_SIZE];        /* Buffer for positions */
}ODBF;

/*-----------------------------------------------------------------------------+
| DSET: BASESET's + DESCSET's                                                  |
| Used only (really) by OCSCHAR.C.                                             |
| Saved in the OCS and ODT only to be able to check Syntax Charsets versus     |
| the Reference one, if SCOPE INSTANCE.                                        |
+-----------------------------------------------------------------------------*/
typedef struct t_DSET {           /* indexed by the code # (d_chnb) */
   uint  is_described   : 1;      /* described */
   uint  is_based       : 1;      /* described thru a based chnb */
   uint  is_parm_lit    : 1;      /* described thru a parameter literal */
   uint  is_unused      : 1;      /* described as UNUSED */
   uint  s_chnb         : 8;      /* s_chnb value (b_chnb -> system charset) */
}DSET;                            /* or pseudo s_chnb if parmlit */

/*-----------------------------------------------------------------------------+
|                        ---  GLOBAL AREA ---                                  |
+-----------------------------------------------------------------------------*/
typedef struct t_GLOBAL_AREA {
   /*------------------------------------ Recovery ------*/
   jmp_buf   to_main;                /* to long-jump to main if in troubles */
   boolean   recovering;             /* Recovering currently in process */
   boolean   ut_opened;              /* An utility file is currently opened */
   AHL       ut_ahl;                 /* AHL of this file */
   /*--------------------------------------- SKMGR ------*/
   PARKING  *this_park;
   OFS       parks_ofs;
   /*--------------------------------------- PLMGR ------*/
   POOL      pool[POOLID_MAX+1];
   uint      poolid_C;               /* current pool number */
   POOL      pool_C;                 /* == pool[poolid_C], faster */
   /*--------------------------------------- DLFIND -----*/
   DV       *dv_mo_p;                /* current dv table in use */
   ALLMO     rcgn_mo;                /* current mode code */
   uint      mode_stack[MAX_MODE_LVL];
   int       max_mode_ix;
   TK        curr_token;             /* current token found */
   uint      curr_count;             /* char count for current token */
   uint      curr_mode;              /* current recognition mode */
   ulong     curr_elt_id;            /* Used for ID and IDREF.  Temporary ? */

   /*-------------------------------------- PARSEDOC ----*/
   void     *dtm_base_p;             /* for data tags */

   /*---------------------------------------------+
   |Some values need to be kept when a PSF after  |
   |DOCND is processed.                           |
   |Those values are grouped from here to the end |
   |of the GLOBAL_AREA structure.                 |
   +---------------------------------------------*/
#define DOCND_GLOBAL_AREA_SIZE offsetof(struct t_GLOBAL_AREA,nbr_of_g_entities)

   /*-------------------------------------- ODT ---------*/
   uint      nbr_of_g_entities;      /* nbr of general entities created */
   uint      nbr_of_exid;            /* nbr of external identifiers */
   void     *pety_scope;             /* parameter entity reference scope */
   void     *gety_scope;             /* general entity reference scope */
   void     *id_scope;               /* ID attributes scope */
   void     *gety_htab;              /* hash table for general entities */
   void     *pety_htab;              /* hash table for parameter entities */
   void     *elt_htab;               /* hash table for ELEMENT GI */
   void     *srm_htab;               /* hash table for SR MAPS */
   void     *ncb_htab;               /* hash table for NOTATION */
   void     *sts_htab;               /* hash table for RANK */
   /*--- Added for the AutoTagger and the DCF Translator --*/
   void     *ncb_tab;
   uint      ncb_count;
   void     *elt_tab;
   uint      elt_count;
   void     *gety_tab;
   uint      gety_count;
   void     *pety_tab;
   uint      pety_count;

   boolean   is_odt_done;            /* ODT compiled and loaded in memory */
   int       dtd_sr_max;             /* number of entries in SRMAP (ODT) */
   uchar     active_type[NAMELEN_MAX+1]; /* active document/link type */

   /*----------------------------------------+
   |Some values need to be kept when a new   |
   |SUBDOC is entered.  They are grouped at  |
   |the end of the GLOBAL_AREA structure.    |
   +----------------------------------------*/
#define VARIABLE_GLOBAL_AREA_SIZE offsetof(struct t_GLOBAL_AREA,RE_char)

   /*-------------------------------------- OCS ---------*/
   uchar    RE_char;                 /* Record End Character */
   uchar    RS_char;                 /* Record Start Character */
   uchar    SPACE_char;              /* Space Character */
   uchar    BSEQ_char;               /* BSEQ_char (for OCS only) */
   ushort   gtype[MAX_CHARSET];      /* classification of the character set */
   uchar    uctab[MAX_CHARSET];      /* upper case table */
   ALLMO    dltab[MAX_CHARSET];      /* "could be a delimiter"=f(char,mode) */
   DSET     dsettab[MAX_CHARSET];    /* Syntax Character Set */
   DVTBENT  dvtbent[NBR_OF_MODES];   /* Entries in DVTAB for a given mode */
   DSTAB    dstab;                   /* delimiter string table */
   GNWDTAB  gnwdtab;                 /* changeable keywords table */
   OPT      opt;                     /* Options */
   ulong    capmax[CAP_MAX_SIZE];    /* Capacity: max values */
   QNTYTAB  qntytab;                 /* Quantity table */
   uint     fncr_max;                /* count of entries in fncr table */
   FNCR    *fncrtab;                 /* Function Character <-> Character Nbr */
   uint     sr_max;                  /* number of entries in srtab */
   EQTK    *srtab;                   /* (shortref <-> token) table */
   ALWDTAB  const * alwdtab_p;       /* fixed SGML keywords */
   DLMV     const * dlmv_tab;        /* coded table to build the delimiters */
   DDLMV    const * ddlmv_tab;       /* coded table for combined delimiters */
   uchar    const **cap_names;       /* capacity names */
   uchar    const **qnty_names;      /* quantity names */
   uchar    const * ISO_banner;      /* "ISO 8879:1986" */
   ushort   subdoc_count;            /* count of SUBDOC's */
   boolean  is_ocs_done;             /* OCS compiled and loaded in memory */
   boolean  is_doc_ended;            /* Document instance properly ended */

   /*--------------------------------------- EM ---------*/
   int       head;
   int       max;
   uchar     ebuf[BUFSIZE];
   YB       *yb_pC;                  /* C is for current */
   uint      curr_char;              /* current character read */
   int       enty_level;             /* entity level (1==PRIMARY) */
   int       floor_level;            /* can't close past this (SKIP.C) */
   boolean   quiet_at_floor;         /* at floor, don't issue error message */

   /*--------------------------------------- UTMGR ------*/
   UTID      utid_tbl[MAX_DTD+2];    /* 1st members: OCS Local, OCS User */

   /*-------------------------------------- STOWER ------*/
   ODBF odbf_base[2], STACK_BASED *odbf_pC;
   POS       RE_position;            /* Position of last RE */
   POS       ooc_position;           /* Position for Out Of Context Data */

   /*-------------------------------------- PARSEDOC ----*/
   void STACK_BASED *M_p;            /* Common Area (on the stack) */
   void        *N_p;                 /* Common Area save (mallocated) */

   /*-------------------------------------- OTHER -------*/
   ulong     capcnt[CAP_MAX_SIZE];   /* Capacity: count of objects */
   uint      cappoint[CAP_MAX_SIZE]; /* Capacity: point per object */
   int       ms_level;               /* Marked section depth, signed ! */
   int       ms_enty_level;          /* For an RCDATA marked section */
   int       cn_enty_level;          /* For RCDATA in content */

   uchar    *pi_lit;                 /* PI buffer */
   uchar    *lit_p;                  /* size is 2*(LITLEN+1) */
   void     *pac_p;                  /* Points the PAC */

}GLOBAL_AREA;

/* Global area is on the stack (in the nearby) */
typedef GLOBAL_AREA STACK_BASED * GA_P;

#define GA(member) (gbla_p->member)
#define GLOBAL_INCLUDED
/******************************************************************************/
