/*******************************************************************************
* 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 / SGML Library                                       *
* STATUS           = Version 0, Release 1, Level 33 and up                     *
* COMPONENT NAME   = loadodt.c                                                 *
* DESCRIPTIVE NAME = Load the .ODT file in memory  (<!DOCTYPE declaration>)    *
* DATE_WR          = 07/04/1987                                                *
* AUTHOR           = Pierre G. Richard - PETRUS at YKTVMX                      *
*                                                                              *
* FUNCTIONAL DESCRIPTION =                                                     *
*                                                                              *
* CHANGE HISTORY =                                                             *
* Number Date     Inits    Change & Reason (brief)                             *
*      1 02/23/90 PGR      RANK Feature                                        *
*      2 12/09/90 PGR      Load the descriptor structure                       *
*      3 12/07/91 PGR      DocType signature                                   *
*******************************************************************************/

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

/*--------------------------------------------------------------------load_odt-+
| Load the OCS in memory.                                                      |
| Return a pointer to the base document type ELT                               |
+-----------------------------------------------------------------------------*/
void P_FCT load_odt(GA_P gbla_p, DTSG *dtsg_p)
{
   int    base_elt_ix;           /* index in ELT array */
   uint   mdltab_size;
   uint   elttab_size;
   uint   extab_size;
   uint   atdtab_size;
   uint   getytab_size, petytab_size;
   uint   srmtab_size;
   uint   dtptab_size;
   uint   nadtab_size;
   uint   ncbtab_size;
   uint   exidtab_size;
   uint   ststab_size;
   uint   rkltab_size;
   MDL   *mdltab;
   ELT   *elttab;
   EX    *extab;
   ATD   *atdtab;
   ADLEN *desctab;
   ETY   *getytab, *petytab;
   SRM   *srmtab;
   DTP   *dtptab;
   NAD   *nadtab;
   NCB   *ncbtab;
   EXID  *exidtab;
   STS   *ststab;
   RKL   *rkltab;
   uchar *strbuf;
   ulong  cap_count[CAP_MAX_SIZE];
   uchar  const * const odt_banner = bnr_odt();

   /*----------------+
   |Read the ODT file|
   +----------------*/
   {
      AHL ahl;
      uchar  banner[81];
      uint i;

      if ((i=1, !ut_open(
            gbla_p, UTODTR_XFC, FALSE, dtsg_p->base_elt_name, (EXID *)0, &ahl
         )) ||
         (ut_read(gbla_p,ahl,banner,1 + *odt_banner) != 1 + *odt_banner) ||
         (i=2, strlen(banner) != *odt_banner) ||
         (i=3, strcmp(banner, odt_banner+1))) {
         errorh(gbla_p,BADOPDRD,ERH_T_SEV,i);
      }
      ut_read(gbla_p,ahl,&base_elt_ix,sizeof(int));
      ut_read(gbla_p,ahl,&(GA(dtd_sr_max)),sizeof(int));           /* OCS dep.*/
      ut_read(gbla_p,ahl,dtsg_p->qntytab,sizeof(dtsg_p->qntytab)); /* OCS dep.*/
      ut_read(gbla_p,ahl,dtsg_p->dsettab,sizeof(dtsg_p->dsettab)); /* OCS dep.*/
      ut_read(gbla_p,ahl,cap_count,sizeof(cap_count));
      mdltab_size  = ut_vget(gbla_p,ahl,(void **)&mdltab);
      elttab_size  = ut_vget(gbla_p,ahl,(void **)&elttab);
      extab_size   = ut_vget(gbla_p,ahl,(void **)&extab);
                     ut_vget(gbla_p,ahl,(void **)&GA(elt_htab));
      atdtab_size  = ut_vget(gbla_p,ahl,(void **)&atdtab);
                     ut_vget(gbla_p,ahl,(void **)&desctab);
      getytab_size = ut_vget(gbla_p,ahl,(void **)&getytab);
                     ut_vget(gbla_p,ahl,(void **)&GA(gety_htab));
      petytab_size = ut_vget(gbla_p,ahl,(void **)&petytab);
                     ut_vget(gbla_p,ahl,(void **)&GA(pety_htab));
      srmtab_size  = ut_vget(gbla_p,ahl,(void **)&srmtab);
                     ut_vget(gbla_p,ahl,(void **)&GA(srm_htab));
      dtptab_size  = ut_vget(gbla_p,ahl,(void **)&dtptab);
      nadtab_size  = ut_vget(gbla_p,ahl,(void **)&nadtab);
      ncbtab_size  = ut_vget(gbla_p,ahl,(void **)&ncbtab);
                     ut_vget(gbla_p,ahl,(void **)&GA(ncb_htab));
      exidtab_size = ut_vget(gbla_p,ahl,(void **)&exidtab);
      ststab_size  = ut_vget(gbla_p,ahl,(void **)&ststab);
                     ut_vget(gbla_p,ahl,(void **)&GA(sts_htab));
      rkltab_size  = ut_vget(gbla_p,ahl,(void **)&rkltab);
      ut_vget(gbla_p,ahl,(void **)&strbuf);
      ut_close(gbla_p,ahl);
   }
   /*----------------------+
   |Format the hash tables |
   +----------------------*/
   GA(elt_htab)  = shsh_lod(GA(elt_htab),elttab);
   GA(gety_htab) = shsh_lod(GA(gety_htab),getytab);
   GA(pety_htab) = shsh_lod(GA(pety_htab),petytab);
   GA(srm_htab)  = shsh_lod(GA(srm_htab),srmtab);
   GA(ncb_htab)  = shsh_lod(GA(ncb_htab),ncbtab);
   GA(sts_htab)  = shsh_lod(GA(sts_htab),ststab);

   {
      register MDL *mdl_p;
      uint i;

      for (mdl_p=mdltab, i=mdltab_size/sizeof(MDL); i--; ++mdl_p) {
         if (!mdl_p->connector) {
            if (mdl_p->is_pcdata) {           /* PCDATA */
               mdl_p->l.elt.p = (ELT *)0;
            }else if (mdl_p->is_datatag) {    /* DATATAG */
               mdl_p->l.dtp.p = dtptab + mdl_p->l.dtp.ix;
            }else {                           /* TARGET or REGULAR */
               mdl_p->l.elt.p = elttab + mdl_p->l.elt.ix;
            }
         }
      }
   }
   {
      register ELT *elt_p;
      uint i;

      for (
         GA(elt_tab)=elt_p=elttab, GA(elt_count)=i=elttab_size/sizeof(ELT);
         i--; ++elt_p
      ) {
         elt_p->name.p = strbuf + elt_p->name.ofs;
         elt_p->mdl.p = (elt_p->mdl.ix==-1) ? (MDL *)0 : mdltab + elt_p->mdl.ix;
         elt_p->mex.p = (elt_p->mex.ix==-1) ? (EX *)0  : extab  + elt_p->mex.ix;
         elt_p->pex.p = (elt_p->pex.ix==-1) ? (EX *)0  : extab  + elt_p->pex.ix;
         elt_p->atd.p = (elt_p->atd.ix==-1) ? (ATD *)0 : atdtab + elt_p->atd.ix;
         elt_p->srm.p = (elt_p->srm.ix==-1) ? (SRM *)0 : srmtab + elt_p->srm.ix;
         elt_p->rkl.p = (elt_p->rkl.ix==-1) ? (RKL *)0 : rkltab + elt_p->rkl.ix;
      }
   }
   {
      register EX *ex_p;
      uint i;

      for (ex_p=extab, i=extab_size/sizeof(EX); i--; ++ex_p) {
         ex_p->p = (ex_p->ix == -1) ? (ELT *)0 : elttab + ex_p->ix;
      }
   }
   {
      register ATD *atd_p;
      uint i, count;
      ADLEN *desc_p;

      for (atd_p=atdtab, i=atdtab_size/sizeof(ATD); i--; ++atd_p) {
         atd_p->name.p = strbuf + atd_p->name.ofs;
         if IS_BITON(atd_p->is,DESC_AF) {
            desc_p = atd_p->val.desc._.p = desctab + atd_p->val.desc._.ix;
            count = atd_p->val.desc.len;
            desc_p->_.p = strbuf + desc_p->_.ofs;
            while (--count) {
               ++desc_p;
               desc_p->_.p = (desc_p->_.ix==-1)?(ETY *)0 : getytab+desc_p->_.ix;
            }
         }else {
            atd_p->val.lit._.p = strbuf + atd_p->val.lit._.ofs;
         }
      }
   }
   {
      register DTP *dtp_p;
      uint i;

      for (dtp_p=dtptab, i=dtptab_size/sizeof(DTP); i--; ++dtp_p) {
         dtp_p->c_p = strbuf + dtp_p->ofs;
      }
   }
   {
      register NAD *nad_p;
      uint i;

      for (nad_p=nadtab, i=nadtab_size/sizeof(NAD); i--; ++nad_p) {
         nad_p->atd.p = (nad_p->atd.ix==-1) ? (ATD *)0 : atdtab + nad_p->atd.ix;
         nad_p->ncb.p = (nad_p->ncb.ix==-1) ? (NCB *)0 : ncbtab + nad_p->ncb.ix;
      }
   }
   {
      register NCB *ncb_p;
      uint i;

      for (
         GA(ncb_tab)=ncb_p=ncbtab, GA(ncb_count)=i=ncbtab_size/sizeof(NCB);
         i--; ++ncb_p
      ) {
         ncb_p->exid.name._.p = strbuf + ncb_p->exid.name._.ofs; /* not. name */
         ncb_p->exid.val._.p = strbuf + ncb_p->exid.val._.ofs;
         /* This is the deflt ATL associated: maybe we'll need it some day ? */
         ncb_p->atd.p = (ncb_p->atd.ix==-1) ? (ATD *)0 : atdtab + ncb_p->atd.ix;
      }
   }
   {
      register STS *sts_p;
      uint i;

      for (sts_p=ststab, i=ststab_size/sizeof(STS); i--; ++sts_p) {
         sts_p->name.p = strbuf + sts_p->name.ofs;
      }
   }
   {
      register RKL *rkl_p;
      uint i;

      for (rkl_p=rkltab, i=rkltab_size/sizeof(RKL); i--; ++rkl_p) {
         rkl_p->sts.p = ststab + rkl_p->sts.ix;
         rkl_p->grp.p = rkltab + rkl_p->grp.ix;
      }
   }
   {
      register EXID *exid_p;
      uint i;

      for (exid_p=exidtab, i=exidtab_size/sizeof(EXID); i--; ++exid_p) {
         exid_p->name._.p = strbuf + exid_p->name._.ofs;
         exid_p->val._.p = strbuf + exid_p->val._.ofs;
      }
   }
   {
      register ETY *ety_p;
      uint i, j;

      j = 0;
      for (
         GA(gety_tab) = ety_p = getytab,                   /* gety first, */
         GA(gety_count) = i = getytab_size/sizeof(ETY);
         ++j <= 2;                                         /* then.. */
         GA(pety_tab) = ety_p = petytab,                   /* pety */
         GA(pety_count) = i = petytab_size/sizeof(ETY)
      ) {
         for ( ; i--; ++ety_p) {
            ety_p->name._.p = strbuf + ety_p->name._.ofs;
            if IS_BITON(ety_p->is,EXTERNAL_EF) {
               ety_p->val.ext._.exid.p = exidtab + ety_p->val.ext._.exid.ix;
               ety_p->val.ext.nad.p = (ety_p->val.ext.nad.ix == -1) ?
               (NAD *)0 : nadtab + ety_p->val.ext.nad.ix;
            }else {
               ety_p->val.lit._.p = strbuf + ety_p->val.lit._.ofs;
            }
         }
      }
   }
   {
      register SRM *srm_p;
      uint i, j;

      for (srm_p=srmtab,i=(srmtab_size/sizeof(SRM))/(1+GA(dtd_sr_max)); i--; ) {
         srm_p->mapname.p = strbuf + srm_p->mapname.ofs;
         for (++srm_p, j=1+GA(dtd_sr_max); --j; ++srm_p) {
            srm_p->ety_p = (srm_p->ix == -1) ? (ETY *)0 : getytab + srm_p->ix;
         }
      }
   }
   {
      register ulong *i_p;
      register ulong *j_p;
      uint i;

      for (j_p=GA(capcnt)-1, i_p=cap_count-1, i=CAP_MAX_SIZE+1; --i; ) {
         *(++j_p) += *(++i_p);
      }
   }
   GA(is_odt_done) = TRUE;                  /* Turn on odt_done switch */
   dtsg_p->base_elt_p = (base_elt_ix == -1) ? (ELT *)0 : elttab + base_elt_ix;
}
/******************************************************************************/
