home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / sgml / unix / sgmlc / modsgml1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-03  |  20.9 KB  |  439 lines

  1. /******************************************************************************/
  2. /* Deleted idcan, entref, and entdef services (prohibited by standard).       */
  3. /* Removed obsolete declarations of iolpu and ielpu.                          */
  4. /******************************************************************************/
  5. #include "sgmlincl.h"         /* #INCLUDE statements for SGML parser. */
  6. /******************************************************************************/
  7. #define ETDCON (tags[ts].tetd->etdmod->ttype)     /* ETD content flags. */
  8. #define PUTRCB(ptr) *tprcbp = (UNIV)ptr           /* Set RCB pointer. */
  9. #define PUTRC *tprc = rc                          /* Set return code. */
  10. /******************************************************************************/
  11. /* SGML: Main SGML driver routine.
  12. */
  13. /* global */ VOID sgml(
  14. struct ipbt *ipbl)            /* IPB: SGML services (or NULL). */
  15. {
  16.      unsigned swact;          /* Switch action: saved conact, new, or sgmlact.*/
  17.  
  18.      if (ipbl) {
  19.           sgmlserv(ipbl);     /* If non-NULL ptr, go do services. */
  20.           return;
  21.      }
  22.      if (prologsw) {
  23.           conact = parsepro(tbuf);
  24.           conactsw = 0;       /* Assume SGMLACT will not be skipped. */
  25.           switch(conact) {
  26.  
  27.           case PIS_:
  28.           case EOD_:
  29.                conactsw = 1;   /* We can skip sgmlact in opening state. */
  30.                break;
  31.  
  32.           case DAF_:
  33.                newetd = stagreal = ETDCDATA;
  34.                conact = stag(datarc = DAF_);
  35.                conactsw = 1;   /* We can skip sgmlact in opening state. */
  36.                prologsw = 0;   /* End the prolog. */
  37.                break;
  38.  
  39.           default:             /* DCE_ PEP_: not defined in SGMLACT.H. */
  40.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  41.           case MSS_:
  42.                prologsw = 0;   /* End the prolog. */
  43.           case DTD_:
  44.                break;
  45.           }
  46.           if (!prologsw || newdtdsw) {  /* Prolog start or end; return DTD. */
  47.                newdtdsw = 0;            /* No longer the prolog start. */
  48.                rcbdaf.rcbtype = prologsw ? SGMLSDTD : SGMLEDTD;
  49.                rcbdaf.contersw = ds.srcnt; /* >0=SHORTREF maps in use. */
  50.                rcbdaf.datalen = *dtype;
  51.                rcbdaf.data = dtype;
  52.                rcbdaf.sgmles = es;      /* Current level in scb stack. */
  53.                scbset();                /* Update location in current scb. */
  54.                PUTRCB(&rcbdaf); return;
  55.           }
  56.      }
  57. /*lint -e716*/
  58.      while (1) {
  59. /*lint +e716*/
  60.           if (conactsw) {conactsw = 0; swact = conact; contersw = contersv;}
  61.           else swact =
  62.                sgmlact((UNCH)((conact = parsecon(tbuf, lbuf, conpcb))!=EOD_
  63.                                  ? conact : LOP_));
  64.  
  65.           switch (swact) {
  66.  
  67.           case MD_:           /* Process markup declaration. */
  68.                parsenm(tbuf, NAMECASE); /* Get declaration name. */
  69.                if (!strcmp(tbuf+1, syn.k.usemap)) {
  70.                     mdsrmuse(tbuf);
  71. #ifndef NOTVM
  72.                     rcbdaf.rcbtype = SGMLMV;
  73.                     rcbdaf.data = tags[ts].tsrm!=SRMNULL
  74.                                   ? tags[ts].tsrm[0]->ename : 0;
  75.                     rcbdaf.datalen = *rcbdaf.data;
  76.                     rcbdaf.sgmles = es;    /* Current level in scb stack. */
  77.                     scbset();              /* Update location in current scb. */
  78.                     PUTRCB(&rcbdaf); return;
  79. #endif
  80.                }
  81.                else sgmlerr(_MDNAME, conpcb, tbuf+1, NULL);
  82.                continue;
  83.           case MDC_:           /* Process markup declaration comment. */
  84.                if (*FPOS!=lex.d.mdc)
  85.                     parsemd(tbuf, NAMECASE, (struct parse *)0, NAMELEN);
  86.                continue;
  87.  
  88.           case MSS_:           /* Process marked section start. */
  89.                conpcb = mdms(tbuf, conpcb);
  90.                continue;
  91.           case MSE_:           /* Process marked section end (drop to LOP_). */
  92.                if (mdmse()) conpcb = getpcb((int)ETDCON);
  93.                continue;
  94.  
  95.           case PIS_:           /* Return processing instruction (string). */
  96.                rcbdaf.rcbtype = SGMLPIS;
  97.                if (entpisw) rcbdaf.data = data;
  98.                else {
  99.                     parselit(tbuf, &pcblitc, PILEN, lex.d.pic);
  100.                     rcbdaf.data = tbuf+1;
  101.                }
  102.                rcbdaf.datalen = datalen;
  103.                rcbdaf.contersw = entpisw;
  104.                                  entpisw = 0;        /* Reset for next time.*/
  105.                rcbdaf.sgmles = es;      /* Current level in scb stack. */
  106.                scbset();                /* Update location in current scb. */
  107.                PUTRCB(&rcbdaf); return;
  108.  
  109.           case ETG_:               /* Return end-tag. */
  110.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  111.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  112.                if (!tags[ts+1].tetd->etdetag && sw.swetdtag) continue;
  113.                rcbetag.contersw = tags[ts+1].tflags;
  114.                rcbetag.tagmin = etagimsw ? MINETAG : etagmin;
  115.                memcpy(rcbetag.curgi, tags[ts+1].tetd->etdgi, NAMELEN+2);
  116.                rcbetag.gidata = tags[ts+1].tetd->etdetag;
  117.                rcbetag.ru.oldgi = tags[ts].tetd->etdgi;
  118.                if (etagmin==MINSTAG) rcbetag.tagreal =
  119.                      stagreal<MINPTR ? stagreal : (PETD)stagreal->etdgi;
  120.                else rcbetag.tagreal =
  121.                      etagreal<MINPTR ? etagreal : (PETD)etagreal->etdgi;
  122. #ifdef V2
  123.                rcbetag.format = chainsaw(tags[ts+1].tetd->etdmod->ttype);
  124. #endif
  125.                rcbetag.etictr = etictr;
  126.                rcbetag.srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  127.                                                       : 0;
  128.                rcbetag.sgmles = es;     /* Current level in scb stack. */
  129.                scbset();                /* Update location in current scb. */
  130.                PUTRCB(&rcbetag); return;
  131.  
  132.           case STG_:               /* Return start-tag. */
  133.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  134.                if (!conrefsw && msplevel==0) conpcb = getpcb((int)ETDCON);
  135.                if (!tags[ts].tetd->etdstag && sw.swetdtag) continue;
  136.                rcbstag.contersw = tags[ts].tflags;
  137.                rcbstag.tagmin = dostag ? MINSTAG : stagmin;
  138.                memcpy(rcbstag.curgi, tags[ts].tetd->etdgi, NAMELEN+2);
  139.                rcbstag.gidata = tags[ts].tetd->etdstag;
  140.                /* Get attribute list if one was defined for this element. */
  141.                rcbstag.ru.al = !tags[ts].tetd->adl ? 0 :
  142.                     rcbstag.tagmin==MINNONE  ? al : tags[ts].tetd->adl;
  143.                rcbstag.idrefl = idrefl;
  144.                rcbstag.aentl = aentl;
  145.                rcbstag.tagreal = stagreal<MINPTR?stagreal:(PETD)stagreal->etdgi;
  146. #ifdef V2
  147.                rcbstag.format = chainsaw(tags[ts].tetd->etdmod->ttype);
  148. #endif
  149.                rcbstag.etictr = etictr;
  150.                rcbstag.srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  151.                                                       : 0;
  152.                rcbstag.sgmles = es;     /* Current level in scb stack. */
  153.                scbset();                /* Update location in current scb. */
  154.                PUTRCB(&rcbstag); return;
  155.  
  156.           case DAF_:               /* Return data in source entity buffer. */
  157.                charmode = 1;
  158.                rcbdaf.rcbtype = SGMLDAF;
  159.                rcbdaf.datalen = datalen;
  160.                rcbdaf.data = data;
  161.                rcbdaf.contersw = contersw | entdatsw;
  162.                                contersw = entdatsw = 0;/* Reset for next time.*/
  163.                rcbdaf.sgmles = es;      /* Current level in scb stack. */
  164.                scbset();                /* Update location in current scb. */
  165.                PUTRCB(&rcbdaf); return;
  166.  
  167.           case CON_:               /* Process conact after returning REF_. */
  168.                conactsw = 1;
  169.                contersv = contersw;
  170.           case REF_:               /* Return RE found. */
  171.                if (badresw) {
  172.                     badresw = 0;
  173.                     sgmlerr(_CHARS, &pcbconm, tags[ts].tetd->etdgi+1, NULL);
  174.                     continue;
  175.                }
  176.                charmode = 1;
  177.                rcbdaf.rcbtype = SGMLREF;
  178.                rcbdaf.contersw = contersw;
  179.                                  contersw = 0;        /* Reset for next time.*/
  180.                rcbdaf.sgmles = es;      /* Current level in scb stack. */
  181.                scbset();                /* Update location in current scb. */
  182.                PUTRCB(&rcbdaf); return;
  183.  
  184.           case EOD_:               /* End of source document entity. */
  185.                if (mslevel != 0) sgmlerr(139, conpcb, NULL, NULL);
  186.                rcbdaf.rcbtype = SGMLEOD;
  187.                rcbdaf.sgmles = es;      /* Current level in scb stack. */
  188.                scbset();                /* Update location in current scb. */
  189.                PUTRCB(&rcbdaf); return;
  190.  
  191.           default:             /* LOP_: Loop again with no action. */
  192.                continue;
  193.           }
  194.      }
  195. }
  196. /******************************************************************************/
  197. /* PCBSGML: State and action table for action codes returned to text processor
  198.             by SGML.C.  It causes a REF_ to be handled as follows:
  199.             ST1: Ignore first REF_ of content if no DAF, ETG, or RS intervenes.
  200.             NR1: Process REF_ if it is a REF-only record (null record).
  201.             DA1: Save REF_ if record contains data.
  202.             NR2: (REF_ pending) Process REF_ if it is a null record.
  203.             ST2: (REF_ pending) Ignore REF_ if no MD_, PIS_, or DAF_ intervenes.
  204.             Columns are based on SGMLACT.H values minus DAF_, except that end
  205.             of document has input code LOP_, regardless of its action code.
  206. */
  207. /* Symbols for state names (end with a number). */
  208. #define ST1     0   /* Trailing STG_ or markup record: ignore REF_. */
  209. #define NR1     2   /* New record: return immediate REF_. */
  210. #define DA1     4   /* Data or element found: save REF_. */
  211. #define NR2     6   /* New record with REF_ pending: return immediate REF_. */
  212. #define ST2     8   /* REF_ pending; return it and conact except ETG EOD. */
  213.  
  214. static UNCH sgmltab[10][12] = {
  215. /*daf_ etg_ md_  mdc_ mss_ mse_ pis_ ref_ stg_ etgp_rsr_ eod  */
  216.   DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,ST1 ,NR1 ,ST1 ,/*st1*/
  217.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
  218.  
  219.   DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,DA1 ,NR1 ,ST1 ,/*nr1*/
  220.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,STG_,ETG_,LOP_,EOD_,
  221.  
  222.   DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,NR2 ,ST1 ,DA1 ,NR1 ,ST1 ,/*da1*/
  223.   DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
  224.  
  225.   DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*nr2*/
  226.   CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,CON_,ETG_,LOP_,EOD_,
  227.  
  228.   DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*st2*/
  229.   CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,CON_,ETG_,LOP_,EOD_
  230. };
  231. int scbsgmst = ST1;           /* SCBSGML: trailing stag or markup; ignore RE. */
  232. int scbsgmnr = NR1;           /* SCBSGML: new record; do not ignore RE. */
  233. /******************************************************************************/
  234. /* SGMLACT: Determine action to be taken by SGML.C based on current state and
  235.             specified input.
  236.             For start or end of a plus exception element, push or pop the
  237.             pcbsgml stack.
  238.             Return to caller with action code.
  239. */
  240. int sgmlact(
  241. UNCH conret)                  /* Action returned to SGML.C by content parse. */
  242. {
  243.  
  244.      if (conret==STG_ && GET(tags[ts].tflags, TAGPEX))
  245.           {++pss; scbsgml[pss].snext = ST1;}
  246.      scbsgml[pss].sstate = scbsgml[pss].snext;
  247.      scbsgml[pss].snext = sgmltab[scbsgml[pss].sstate]
  248.                                     [scbsgml[pss].sinput = conret-DAF_];
  249.      scbsgml[pss].saction = sgmltab[scbsgml[pss].sstate+1][scbsgml[pss].sinput];
  250. #ifndef FINAL
  251.      if (trace) tracegml(scbsgml, pss, conactsw, conact);
  252. #endif
  253.      return (int)scbsgml[(conret==ETG_ && GET(tags[ts+1].tflags, TAGPEX)) ?
  254.                          pss-- : pss].saction;
  255. }
  256. /******************************************************************************/
  257. #undef ST1
  258. #undef NR1
  259. #undef DA1
  260. #undef NR2
  261. #undef ST2
  262. /******************************************************************************/
  263. /* GETPCB: Choose pcb for new or resumed element.
  264. */
  265. struct parse *getpcb(
  266. int etdcon)                   /* Content type of new or resumed element. */
  267. {
  268.      if (BITON(etdcon, MGI)) {
  269.           return(BITON(etdcon, MCHARS) ? &pcbconm : &pcbcone);
  270.      }
  271.      if (BITON(etdcon, MCDATA) || BITON(etdcon, MRCDATA)) {
  272.          charmode = 1;
  273.          return(BITON(etdcon, MCDATA) ? &pcbconc : (rcessv = es, &pcbconr));
  274.      }
  275.      return(&pcbconm);
  276. }
  277. /******************************************************************************/
  278. #ifdef V2
  279. /* CHAINSAW: Set format class based on Goldfarb convention.
  280. */
  281. int chainsaw(
  282. int mtype)                    /* Model type byte. */
  283. {
  284.      if (GET(mtype, MPHRASE)) return FORMATP;
  285.      if (GET(mtype, MGI) && !GET(mtype, MCHARS)) return FORMATS;
  286.      if (mtype==MNDATA) return FORMATN;
  287.      return FORMATB;
  288. }
  289. #endif
  290. /******************************************************************************/
  291. /* SGMLSERV: Main interface to SGML services.
  292. */
  293. VOID sgmlserv(
  294. struct ipbt *ipb)             /* Caller's IPB: SGML services. */
  295. {
  296.      struct ipbt it;          /* Our copy of caller's IPB. */
  297.      struct etd *p;           /* Pointer to an etd. */
  298.      UNCH iname[NAMELEN+2];   /* Buffer for names moved from IPB. */
  299.      int rc;                  /* Save area for return codes. */
  300.      PECB ep;                 /* Pointer to an entity control block. */
  301.  
  302.      memcpy((UNIV)&it, (UNIV)ipb, sizeof(it));
  303.      memcpy(iname, it.itnm, sizeof(iname));
  304.      switch (it.ipbtype) {
  305.  
  306.      case SGMLSET:            /* SGML: set up run (returns delims, DS).*/
  307.           /* Initialize variables based on switches structure members. */
  308.           memcpy((UNIV)&sw, (UNIV)it.itp1, sizeof(struct switches));
  309.           tprc = sw.src;                /* Save addr to return rc. */
  310.           tprcbp = sw.srcbp;            /* Save addr to return rcb ptr. */
  311.           nonchbuf[0] = sw.delnonch;    /* Prefix delimiter for non-SGML char.*/
  312.           rbuf = rmalloc((UNS)RCCBUFSZ+sw.swbufsz); /* DOS file read area. */
  313.           rbufs = rbuf+RCCBUFSZ;        /* DOS read area: start read position.*/
  314.           /* Initialize lexical tables for non-SGML char prefix delimiter. */
  315.           lexcnm[sw.delnonch] =
  316.                lexcon[sw.delnonch] = lexlms[sw.delnonch] = lex.l.lmnsc;
  317.           /* Initialize IPBERR and RCBs with SGML entity stack address. */
  318.           ie.sgmlscbs = rcbdaf.sgmlscbs = rcbetag.sgmlscbs =
  319.                rcbstag.sgmlscbs = scbs;
  320. #ifndef FINAL
  321.           tracepro();         /* Set trace switches for prolog. */
  322. #endif
  323.           PUTRCB(&lex.m);
  324.           return;
  325.      case SGMLRSET:           /* SGML: set up for each pass. */
  326.           /* Parser pass number has origin of 0; no setup for 1st (0) pass. */
  327.           if ((pass = (int)it.itl1-1)>0) sgmlrset();
  328.           return;
  329.      case SGMLEND:            /* SGML: clean up after entire run. */
  330.           for (; es>=0; --es) if (FILESW) fileclos();
  331.           rcbdaf.data = (STRING)&ds;
  332.           ds.capused = (long)((ds.dcncnt+ds.pmexgcnt+ds.etdcnt+ds.etdercnt+
  333.                         ds.pmexcnt+ds.modcnt+ds.attcnt+ds.attgcnt+
  334.                         ds.idcnt+ds.idrcnt+ds.ecbcnt)*NAMELEN +
  335.                         ds.attdef+ds.ecbtext+ds.dcntext +
  336.                         ds.srcnt*NAMELEN*(lex.s.dtb[0].mapdata+1));
  337.           ds.capacity = CAPACITY;
  338.           PUTRCB(&ds); return;
  339.      case ENTGET:             /* Entity: get text if data entity. */
  340.           if ((ep = entfind(iname))!=0) {
  341.                rc = -2;       /* Assume not a data entity. */
  342.                if (ep->estore==ESN) {
  343.                     rc = 1;   /* NDATA entity. */
  344.                     it.itp1 = (UNIV)ep->etx.n;
  345.                }
  346.                else if (ep->estore==ESC)
  347.                     rc = 2;   /* CDATA entity. */
  348.                else if (ep->estore==ESX)
  349.                     rc = 3;   /* SDATA entity. */
  350.                if (rc>1) it.itp1 = ep->etx.c;
  351.                if (rc>0)      /* Copy control block for a data entity. */
  352.                     memcpy((UNIV)ipb, (UNIV)&it, sizeof(it));
  353.           }
  354.           else rc = -1;
  355.           PUTRC; return;
  356.      case ENTPRIME:           /* Entity: define and reference primary entity. */
  357.           rc = entopen(xentdef(indocent, it.itl1, it.itp1));
  358.           PUTRC; return;
  359.      case GISET:              /* GI: associate start- & end-tag ptrs with GI.*/
  360.           if ((p = etdref(iname))!=0) {
  361.             p->etdstag = it.itp1;
  362.             p->etdetag = it.itp2;
  363.           }
  364.           rc = !p;
  365.           PUTRC; return;
  366.      case GIGET:              /* GI: retrieve start- and end-tag ptrs for GI. */
  367.           if ((p = etdref(iname))!=0) {
  368.                it.itp1 = p->etdstag;
  369.                it.itp2 = p->etdetag;
  370.                memcpy((UNIV)ipb, (UNIV)&it, sizeof(it));
  371.           }
  372.           rc = !p;
  373.           PUTRC; return;
  374.      }
  375. }
  376. /******************************************************************************/
  377. /* XENTDEF: Define an entity for a system identifier.
  378. */
  379. struct entity *xentdef(
  380. UNCH *ename,                  /* Entity name. */
  381. UNS len,                      /* Length of system identifier. */
  382. UNCH *etext)                  /* System identifier. */
  383. {
  384.      struct fpi f;            /* Formal public identifier structure. */
  385.      union etext etx;         /* Ptr to entity text. */
  386.  
  387.      memset((UNIV)&f, 0, (UNS)FPISZ);                       /* Initialize fpi.*/
  388.      memcpy(f.fpinm, ename, (f.fpinml = (char)*ename));     /* Store name. */
  389.      memcpy(f.fpisysis, etext, (f.fpisysl = (char)len));    /* Store sys ID. */
  390.      f.fpistore = 2;                                        /* Type: general. */
  391.      etx.x = entgen(&f);                                    /* Get SGMLIO nm. */
  392.      return(entdef(indocent, ESF, &etx));                   /* Store it. */
  393. }
  394. /******************************************************************************/
  395. /* SGMLRSET: Initialization for start of pass.
  396. */
  397. VOID sgmlrset(void)
  398. {
  399.      for (; es>=0; --es) if (FILESW) fileclos();
  400.      badresw = 0;             /* 1=REF_ out of context; 0=valid. */
  401.      charmode = 0;            /* >0=in #CHARS; 0=not. */
  402.      conactsw = 0;            /* No saved content parse action. */
  403.      conrefsw = 0;            /* 1=content reference att or empty; 0=no. */
  404.      contersv = 0;            /* Save contersw if next action is in hand. */
  405.      contersw = 0;            /* 1=element or #CHARS out of context; 0=valid. */
  406.      datarc = 0;              /* Return code for data: DAF_ or REF_. */
  407.      delmscsw = 0;            /* 1=DELMSC must be inserted in read buffer. */
  408.      didreq = 0;              /* 1=required implied tag processed; 0=no. */
  409.      dostag = 0;              /* 1=retry newetd instead of parsing; 0=parse. */
  410.      dtdsw = 0;               /* DOCTYPE declaration found: 1=yes; 0=no. */
  411.      entdatsw = 0;            /* 2=CDATA entity; 4=SDATA; 8=NDATA; 0=none. */
  412.      entpisw = 0;             /* 4=PI entity occurred; 0=not. */
  413.      eodsw = 0;               /* 1=eod found in error; 0=not yet. */
  414.      eofsw = 0;               /* EOF not yet found in document body. */
  415.      etagimct = 0;            /* Implicitly ended elements left on stack. */
  416.      etagimsw = 0;            /* 1=end-tag implied by other end-tag; 0=not. */
  417.      etagmin = MINNONE;       /* Minim: NONE NULL NET DATA; implied by S/ETAG*/
  418.      etictr = 0;              /* Number of "NET enabled" tags on stack. */
  419.      etisw = 0;               /* 1=tag ended with eti; 0=did not. */
  420.      indtdsw = 0;             /* Are we in the DTD? 1=yes; 0=no. */
  421.      mslevel = 0;             /* Nesting level of marked sections. */
  422.      msplevel = 0;            /* Nested MS levels subject to special parse. */
  423.      newdtdsw = 0;            /* 1=DTD just started; 0=DTD returned to TP. */
  424.      prologsw = 1;            /* Start parsing with prolog. */
  425.      propcb = &pcbpro;        /* Start with normal prolog PCB. */
  426.      pss = 0;                 /* SGMLACT pcb stack level. */
  427.      sgmlsw = 0;              /* SGML declaration found: 1=yes; 0=no. */
  428.      stagmin = MINNONE;       /* Minimization: NONE, NULL tag, implied by STAG*/
  429.      tagctr = 0;              /* No start-tag chars counted yet. */
  430.      ts = -1;                 /* Index of current tag in stack. */
  431.      nextetd = 0;             /* ETD that must come next (only one choice). */
  432.      return;
  433. }
  434. /******************************************************************************/
  435. #undef ETDCON
  436. #undef PUTRCB
  437. #undef PUTRC
  438. /******************************************************************************/
  439.