/*******************************************************************************
* 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 / DTD compiler                                       *
* STATUS           = Version 0, Release 1, Level 36 and up                     *
* COMPONENT NAME   = odtnota.c                                                 *
* DESCRIPTIVE NAME = NOTATION declaration                                      *
* DATE_WR          = 12/25/1988                                                *
* AUTHOR           = Pierre G. Richard - PETRUS at YKTVMX                      *
*                                                                              *
* FUNCTIONAL DESCRIPTION =                                                     *
*                                                                              *
* IMPLEMENTATION NOTE =                                                        *
*                                                                              *
* DEPENDENCIES =  (see Include list)                                           *
*                                                                              *
* IMPORT=                                                                      *
*                                                                              *
* EXPORT=                                                                      *
*                                                                              *
* CHANGE HISTORY =                                                             *
* Number Date     Inits    Change & Reason (brief)                             *
*      1 04/01/97 ESPERT   Added NOTATION declaration reporting                *
*******************************************************************************/

/*-------------+
|Include Files |
+-------------*/
#include "machine.h"
#include "portable.h"
#include "yaspapi.h"
#include "global.h"
#include "usrlib.h"
#include "sgml.h"
#include "hash.h"
#include "odt.h"
#include "teller.h"

/*--------------------------------------------------------------------nta_deco-+
|Process NOTATION MD (Notation Markup Declaration)                             |
|                                                                              |
|Enter here when NOTATION has been decoded,                                    |
|Returns with curr_char (supposed to ) == MDC                                  |
|                                                                              |
| [148] notation declaration = mdo, "NOTATION", ps+, notation name, ps+,       |
|                              notation identifier, ps*, mdc)                  |
|                                                                              |
| [149] notation identifier = external identifier                              |
+-----------------------------------------------------------------------------*/
void P_FCT nta_deco(COMMON_P M_p)
{
   GA_P gbla_p = M_p->gbla_p;
   uchar  name[NAMELEN_MAX+1];
   NB    *nb_p;
   EXID  *exid_p;
   NCB   *ncb_p;
   uchar *c_p0;

   /* Tell NOTATION declaration start */
   tll_NTDCST(gbla_p);

   /*-------------------+
   |Decode notation name|
   +-------------------*/
   skip_Wps(gbla_p);
   get_name(gbla_p,name);

   /*-----------------------+
   |get external identifier |
   +-----------------------*/
   skip_ps(gbla_p);
   xid_fill(gbla_p, exid_p=(EXID *)malloc(sizeof(EXID)), NOTATION_XFC);
   c_p0 = exid_p->val._.p;              /* save pointer to the exid buffer */

   /* Tell the NOTATION declaration end before installing */
   ncb_p = (NCB *)malloc(sizeof(NCB));
   ncb_p->exid = *exid_p;
   ncb_p->exid.name._.p = name;
   tll_NTDCND(gbla_p, ncb_p);
   /*--------------------------------------+
   |Install the notation in the hash tables|
   +--------------------------------------*/
   nb_p = (NB *)ehsh_lnk(M_p->nota_scope,name,sizeof(NB));
   if (nb_p->v.exid_p) {                /* if duplicate */
      errorh(gbla_p,DUPNAMNOT,ERH_W_SEV+ERH_LOCATE); /* tell user error */
      free(exid_p);                     /* release exid */
   }else {
      ++M_p->nbr_of_ncb;                /* only counted for <!NOTATION */
      M_p->nbr_of_nxid_text += (exid_p->sid.len + exid_p->pid.len);
      exid_p->val._.ofs = sk_park(M_p->gbla_p,c_p0,exid_p->val.len);
      nb_p->v.exid_p = exid_p;          /* tell nb_p about our new xid */
   }
   free(c_p0);                          /* free the exid buffer */
   free(ncb_p);
}

/*------------------------------------------------------------------nota_build-+
|Build NCB tables (notation tables)                                            |
|                                                                              |
|NCBs are built from the information found in the NB, a block used to gather   |
|the information at compile time.                                              |
|An NCB must be seen as an EXID for a notation, followed by an ATD to point    |
|the default AVS.  It's also an entry in the hash table for notations.         |
|It is filled by the <!NOTATION MD and the <!ATTLIST #NOTATION MD.             |
|No NCB is really taken into account until the <!NOTATION is encountered.      |
|The <!ATTLIST related to NOTATIONS that haven't been defined are thrown away. |
|                                                                              |
|The NAD is a block that is associated to external data entities: it defines   |
|what NOTATION, and what DATA attributes are associated.  It is pointed        |
|from the ETY block of external entities.                                      |
|                                                                              |
|The notation name of an NAD stays unsolved until the end of the compilation.  |
|Also, if no attributes were defined, the ATD pointer of the NAD is not        |
|pointing the default attributes until the end of the compilation.             |
|Now is the end of the compilation !  We need to allow ETY_BUILD to point      |
|the right NCB and possibily the DEFAULT attributes.                           |
+-----------------------------------------------------------------------------*/
#define M_p ((COMMON_P)XM_p)
void P_FCT nta_bld(void STACK_BASED * XM_p, EHSH *ehsh_p)
{
   GA_P gbla_p = M_p->gbla_p;
   NCB   *ncb_p;
   NB    *nb_p;
   ANHDR *anhdr_p;

   anhdr_p = (nb_p = (NB *)(ehsh_p->var_p))->u.anhdr_p;
   if (!nb_p->v.exid_p) {                       /* ATTLIST w/o NOTATION */
      errorh(gbla_p,NONOTA,ERH_W_SEV,ehsh_p->name_p);  /* tell user  */
      ehsh_p->var_p = (void *)0;                /* remove from shsh table */
      free(nb_p);
      if (--anhdr_p->ref_cnt == 0) free(anhdr_p);
   }else {
      ncb_p = (M_p->ncb_p)++;
      ncb_p->exid = *(nb_p->v.exid_p);          /* copy the exid */
      ncb_p->exid.name._.ofs =                  /* fill the name field */
         sk_park(M_p->gbla_p,ehsh_p->name_p,1+ (
         ncb_p->exid.name.len = strlen(ehsh_p->name_p)) );
      free(nb_p->v.exid_p);                     /* and free */
      if (anhdr_p) {                            /* NOTATION and ATTLIST */
         ncb_p->atd.ix = adl_ulad(M_p,anhdr_p); /* unload and free ? anhdr */
      }else {
         ncb_p->atd.ix = -1;                    /* NOTATION w/o ATTLIST */
      }
      /*-------------------------------------------------+
      |As the NB structures in core are still valid,     |
      |use the room left by:                             |
      |- nb_p->exid_p to store the value of              |
      |  the NCB index of this notation in the NCB table,|
      |- nb_p->anhdr_p to store the value of             |
      |  its matching index in the ATD table.            |
      |                                                  |
      |This is a trick to later update the NAD           |
      |associated to external entities: NAD_FILL called  |
      |by ETY_BUILD.                                     |
      +-------------------------------------------------*/
      nb_p->v.ncb_ix = diffptr(M_p->ncb_p, M_p->ncb_orig) - 1;
                                                /* to set NCB ptr in NAD */
      nb_p->u.atd_ix = ncb_p->atd.ix;           /* to solve def data att */
   }
}
#undef M_p
/******************************************************************************/
