home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* Deleted idcan, entref, and entdef services (prohibited by standard). */
- /* Removed obsolete declarations of iolpu and ielpu. */
- /******************************************************************************/
- #include "sgmlincl.h" /* #INCLUDE statements for SGML parser. */
- /******************************************************************************/
- #define ETDCON (tags[ts].tetd->etdmod->ttype) /* ETD content flags. */
- #define PUTRCB(ptr) *tprcbp = (UNIV)ptr /* Set RCB pointer. */
- #define PUTRC *tprc = rc /* Set return code. */
- /******************************************************************************/
- /* SGML: Main SGML driver routine.
- */
- /* global */ VOID sgml(
- struct ipbt *ipbl) /* IPB: SGML services (or NULL). */
- {
- unsigned swact; /* Switch action: saved conact, new, or sgmlact.*/
-
- if (ipbl) {
- sgmlserv(ipbl); /* If non-NULL ptr, go do services. */
- return;
- }
- if (prologsw) {
- conact = parsepro(tbuf);
- conactsw = 0; /* Assume SGMLACT will not be skipped. */
- switch(conact) {
-
- case PIS_:
- case EOD_:
- conactsw = 1; /* We can skip sgmlact in opening state. */
- break;
-
- case DAF_:
- newetd = stagreal = ETDCDATA;
- conact = stag(datarc = DAF_);
- conactsw = 1; /* We can skip sgmlact in opening state. */
- prologsw = 0; /* End the prolog. */
- break;
-
- default: /* DCE_ PEP_: not defined in SGMLACT.H. */
- if (msplevel==0) conpcb = getpcb((int)ETDCON);
- case MSS_:
- prologsw = 0; /* End the prolog. */
- case DTD_:
- break;
- }
- if (!prologsw || newdtdsw) { /* Prolog start or end; return DTD. */
- newdtdsw = 0; /* No longer the prolog start. */
- rcbdaf.rcbtype = prologsw ? SGMLSDTD : SGMLEDTD;
- rcbdaf.contersw = ds.srcnt; /* >0=SHORTREF maps in use. */
- rcbdaf.datalen = *dtype;
- rcbdaf.data = dtype;
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
- }
- }
- /*lint -e716*/
- while (1) {
- /*lint +e716*/
- if (conactsw) {conactsw = 0; swact = conact; contersw = contersv;}
- else swact =
- sgmlact((UNCH)((conact = parsecon(tbuf, lbuf, conpcb))!=EOD_
- ? conact : LOP_));
-
- switch (swact) {
-
- case MD_: /* Process markup declaration. */
- parsenm(tbuf, NAMECASE); /* Get declaration name. */
- if (!strcmp(tbuf+1, syn.k.usemap)) {
- mdsrmuse(tbuf);
- #ifndef NOTVM
- rcbdaf.rcbtype = SGMLMV;
- rcbdaf.data = tags[ts].tsrm!=SRMNULL
- ? tags[ts].tsrm[0]->ename : 0;
- rcbdaf.datalen = *rcbdaf.data;
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
- #endif
- }
- else sgmlerr(_MDNAME, conpcb, tbuf+1, NULL);
- continue;
- case MDC_: /* Process markup declaration comment. */
- if (*FPOS!=lex.d.mdc)
- parsemd(tbuf, NAMECASE, (struct parse *)0, NAMELEN);
- continue;
-
- case MSS_: /* Process marked section start. */
- conpcb = mdms(tbuf, conpcb);
- continue;
- case MSE_: /* Process marked section end (drop to LOP_). */
- if (mdmse()) conpcb = getpcb((int)ETDCON);
- continue;
-
- case PIS_: /* Return processing instruction (string). */
- rcbdaf.rcbtype = SGMLPIS;
- if (entpisw) rcbdaf.data = data;
- else {
- parselit(tbuf, &pcblitc, PILEN, lex.d.pic);
- rcbdaf.data = tbuf+1;
- }
- rcbdaf.datalen = datalen;
- rcbdaf.contersw = entpisw;
- entpisw = 0; /* Reset for next time.*/
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
-
- case ETG_: /* Return end-tag. */
- charmode = 0; /* Not in char mode unless CDATA or RCDATA.*/
- if (msplevel==0) conpcb = getpcb((int)ETDCON);
- if (!tags[ts+1].tetd->etdetag && sw.swetdtag) continue;
- rcbetag.contersw = tags[ts+1].tflags;
- rcbetag.tagmin = etagimsw ? MINETAG : etagmin;
- memcpy(rcbetag.curgi, tags[ts+1].tetd->etdgi, NAMELEN+2);
- rcbetag.gidata = tags[ts+1].tetd->etdetag;
- rcbetag.ru.oldgi = tags[ts].tetd->etdgi;
- if (etagmin==MINSTAG) rcbetag.tagreal =
- stagreal<MINPTR ? stagreal : (PETD)stagreal->etdgi;
- else rcbetag.tagreal =
- etagreal<MINPTR ? etagreal : (PETD)etagreal->etdgi;
- #ifdef V2
- rcbetag.format = chainsaw(tags[ts+1].tetd->etdmod->ttype);
- #endif
- rcbetag.etictr = etictr;
- rcbetag.srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
- : 0;
- rcbetag.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbetag); return;
-
- case STG_: /* Return start-tag. */
- charmode = 0; /* Not in char mode unless CDATA or RCDATA.*/
- if (!conrefsw && msplevel==0) conpcb = getpcb((int)ETDCON);
- if (!tags[ts].tetd->etdstag && sw.swetdtag) continue;
- rcbstag.contersw = tags[ts].tflags;
- rcbstag.tagmin = dostag ? MINSTAG : stagmin;
- memcpy(rcbstag.curgi, tags[ts].tetd->etdgi, NAMELEN+2);
- rcbstag.gidata = tags[ts].tetd->etdstag;
- /* Get attribute list if one was defined for this element. */
- rcbstag.ru.al = !tags[ts].tetd->adl ? 0 :
- rcbstag.tagmin==MINNONE ? al : tags[ts].tetd->adl;
- rcbstag.idrefl = idrefl;
- rcbstag.aentl = aentl;
- rcbstag.tagreal = stagreal<MINPTR?stagreal:(PETD)stagreal->etdgi;
- #ifdef V2
- rcbstag.format = chainsaw(tags[ts].tetd->etdmod->ttype);
- #endif
- rcbstag.etictr = etictr;
- rcbstag.srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
- : 0;
- rcbstag.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbstag); return;
-
- case DAF_: /* Return data in source entity buffer. */
- charmode = 1;
- rcbdaf.rcbtype = SGMLDAF;
- rcbdaf.datalen = datalen;
- rcbdaf.data = data;
- rcbdaf.contersw = contersw | entdatsw;
- contersw = entdatsw = 0;/* Reset for next time.*/
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
-
- case CON_: /* Process conact after returning REF_. */
- conactsw = 1;
- contersv = contersw;
- case REF_: /* Return RE found. */
- if (badresw) {
- badresw = 0;
- sgmlerr(_CHARS, &pcbconm, tags[ts].tetd->etdgi+1, NULL);
- continue;
- }
- charmode = 1;
- rcbdaf.rcbtype = SGMLREF;
- rcbdaf.contersw = contersw;
- contersw = 0; /* Reset for next time.*/
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
-
- case EOD_: /* End of source document entity. */
- if (mslevel != 0) sgmlerr(139, conpcb, NULL, NULL);
- rcbdaf.rcbtype = SGMLEOD;
- rcbdaf.sgmles = es; /* Current level in scb stack. */
- scbset(); /* Update location in current scb. */
- PUTRCB(&rcbdaf); return;
-
- default: /* LOP_: Loop again with no action. */
- continue;
- }
- }
- }
- /******************************************************************************/
- /* PCBSGML: State and action table for action codes returned to text processor
- by SGML.C. It causes a REF_ to be handled as follows:
- ST1: Ignore first REF_ of content if no DAF, ETG, or RS intervenes.
- NR1: Process REF_ if it is a REF-only record (null record).
- DA1: Save REF_ if record contains data.
- NR2: (REF_ pending) Process REF_ if it is a null record.
- ST2: (REF_ pending) Ignore REF_ if no MD_, PIS_, or DAF_ intervenes.
- Columns are based on SGMLACT.H values minus DAF_, except that end
- of document has input code LOP_, regardless of its action code.
- */
- /* Symbols for state names (end with a number). */
- #define ST1 0 /* Trailing STG_ or markup record: ignore REF_. */
- #define NR1 2 /* New record: return immediate REF_. */
- #define DA1 4 /* Data or element found: save REF_. */
- #define NR2 6 /* New record with REF_ pending: return immediate REF_. */
- #define ST2 8 /* REF_ pending; return it and conact except ETG EOD. */
-
- static UNCH sgmltab[10][12] = {
- /*daf_ etg_ md_ mdc_ mss_ mse_ pis_ ref_ stg_ etgp_rsr_ eod */
- DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,ST1 ,NR1 ,ST1 ,/*st1*/
- DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
-
- DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,DA1 ,NR1 ,ST1 ,/*nr1*/
- DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,STG_,ETG_,LOP_,EOD_,
-
- DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,NR2 ,ST1 ,DA1 ,NR1 ,ST1 ,/*da1*/
- DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,ETG_,LOP_,EOD_,
-
- DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*nr2*/
- CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,CON_,ETG_,LOP_,EOD_,
-
- DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,ST2 ,NR2 ,ST1 ,/*st2*/
- CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,CON_,ETG_,LOP_,EOD_
- };
- int scbsgmst = ST1; /* SCBSGML: trailing stag or markup; ignore RE. */
- int scbsgmnr = NR1; /* SCBSGML: new record; do not ignore RE. */
- /******************************************************************************/
- /* SGMLACT: Determine action to be taken by SGML.C based on current state and
- specified input.
- For start or end of a plus exception element, push or pop the
- pcbsgml stack.
- Return to caller with action code.
- */
- int sgmlact(
- UNCH conret) /* Action returned to SGML.C by content parse. */
- {
-
- if (conret==STG_ && GET(tags[ts].tflags, TAGPEX))
- {++pss; scbsgml[pss].snext = ST1;}
- scbsgml[pss].sstate = scbsgml[pss].snext;
- scbsgml[pss].snext = sgmltab[scbsgml[pss].sstate]
- [scbsgml[pss].sinput = conret-DAF_];
- scbsgml[pss].saction = sgmltab[scbsgml[pss].sstate+1][scbsgml[pss].sinput];
- #ifndef FINAL
- if (trace) tracegml(scbsgml, pss, conactsw, conact);
- #endif
- return (int)scbsgml[(conret==ETG_ && GET(tags[ts+1].tflags, TAGPEX)) ?
- pss-- : pss].saction;
- }
- /******************************************************************************/
- #undef ST1
- #undef NR1
- #undef DA1
- #undef NR2
- #undef ST2
- /******************************************************************************/
- /* GETPCB: Choose pcb for new or resumed element.
- */
- struct parse *getpcb(
- int etdcon) /* Content type of new or resumed element. */
- {
- if (BITON(etdcon, MGI)) {
- return(BITON(etdcon, MCHARS) ? &pcbconm : &pcbcone);
- }
- if (BITON(etdcon, MCDATA) || BITON(etdcon, MRCDATA)) {
- charmode = 1;
- return(BITON(etdcon, MCDATA) ? &pcbconc : (rcessv = es, &pcbconr));
- }
- return(&pcbconm);
- }
- /******************************************************************************/
- #ifdef V2
- /* CHAINSAW: Set format class based on Goldfarb convention.
- */
- int chainsaw(
- int mtype) /* Model type byte. */
- {
- if (GET(mtype, MPHRASE)) return FORMATP;
- if (GET(mtype, MGI) && !GET(mtype, MCHARS)) return FORMATS;
- if (mtype==MNDATA) return FORMATN;
- return FORMATB;
- }
- #endif
- /******************************************************************************/
- /* SGMLSERV: Main interface to SGML services.
- */
- VOID sgmlserv(
- struct ipbt *ipb) /* Caller's IPB: SGML services. */
- {
- struct ipbt it; /* Our copy of caller's IPB. */
- struct etd *p; /* Pointer to an etd. */
- UNCH iname[NAMELEN+2]; /* Buffer for names moved from IPB. */
- int rc; /* Save area for return codes. */
- PECB ep; /* Pointer to an entity control block. */
-
- memcpy((UNIV)&it, (UNIV)ipb, sizeof(it));
- memcpy(iname, it.itnm, sizeof(iname));
- switch (it.ipbtype) {
-
- case SGMLSET: /* SGML: set up run (returns delims, DS).*/
- /* Initialize variables based on switches structure members. */
- memcpy((UNIV)&sw, (UNIV)it.itp1, sizeof(struct switches));
- tprc = sw.src; /* Save addr to return rc. */
- tprcbp = sw.srcbp; /* Save addr to return rcb ptr. */
- nonchbuf[0] = sw.delnonch; /* Prefix delimiter for non-SGML char.*/
- rbuf = rmalloc((UNS)RCCBUFSZ+sw.swbufsz); /* DOS file read area. */
- rbufs = rbuf+RCCBUFSZ; /* DOS read area: start read position.*/
- /* Initialize lexical tables for non-SGML char prefix delimiter. */
- lexcnm[sw.delnonch] =
- lexcon[sw.delnonch] = lexlms[sw.delnonch] = lex.l.lmnsc;
- /* Initialize IPBERR and RCBs with SGML entity stack address. */
- ie.sgmlscbs = rcbdaf.sgmlscbs = rcbetag.sgmlscbs =
- rcbstag.sgmlscbs = scbs;
- #ifndef FINAL
- tracepro(); /* Set trace switches for prolog. */
- #endif
- PUTRCB(&lex.m);
- return;
- case SGMLRSET: /* SGML: set up for each pass. */
- /* Parser pass number has origin of 0; no setup for 1st (0) pass. */
- if ((pass = (int)it.itl1-1)>0) sgmlrset();
- return;
- case SGMLEND: /* SGML: clean up after entire run. */
- for (; es>=0; --es) if (FILESW) fileclos();
- rcbdaf.data = (STRING)&ds;
- ds.capused = (long)((ds.dcncnt+ds.pmexgcnt+ds.etdcnt+ds.etdercnt+
- ds.pmexcnt+ds.modcnt+ds.attcnt+ds.attgcnt+
- ds.idcnt+ds.idrcnt+ds.ecbcnt)*NAMELEN +
- ds.attdef+ds.ecbtext+ds.dcntext +
- ds.srcnt*NAMELEN*(lex.s.dtb[0].mapdata+1));
- ds.capacity = CAPACITY;
- PUTRCB(&ds); return;
- case ENTGET: /* Entity: get text if data entity. */
- if ((ep = entfind(iname))!=0) {
- rc = -2; /* Assume not a data entity. */
- if (ep->estore==ESN) {
- rc = 1; /* NDATA entity. */
- it.itp1 = (UNIV)ep->etx.n;
- }
- else if (ep->estore==ESC)
- rc = 2; /* CDATA entity. */
- else if (ep->estore==ESX)
- rc = 3; /* SDATA entity. */
- if (rc>1) it.itp1 = ep->etx.c;
- if (rc>0) /* Copy control block for a data entity. */
- memcpy((UNIV)ipb, (UNIV)&it, sizeof(it));
- }
- else rc = -1;
- PUTRC; return;
- case ENTPRIME: /* Entity: define and reference primary entity. */
- rc = entopen(xentdef(indocent, it.itl1, it.itp1));
- PUTRC; return;
- case GISET: /* GI: associate start- & end-tag ptrs with GI.*/
- if ((p = etdref(iname))!=0) {
- p->etdstag = it.itp1;
- p->etdetag = it.itp2;
- }
- rc = !p;
- PUTRC; return;
- case GIGET: /* GI: retrieve start- and end-tag ptrs for GI. */
- if ((p = etdref(iname))!=0) {
- it.itp1 = p->etdstag;
- it.itp2 = p->etdetag;
- memcpy((UNIV)ipb, (UNIV)&it, sizeof(it));
- }
- rc = !p;
- PUTRC; return;
- }
- }
- /******************************************************************************/
- /* XENTDEF: Define an entity for a system identifier.
- */
- struct entity *xentdef(
- UNCH *ename, /* Entity name. */
- UNS len, /* Length of system identifier. */
- UNCH *etext) /* System identifier. */
- {
- struct fpi f; /* Formal public identifier structure. */
- union etext etx; /* Ptr to entity text. */
-
- memset((UNIV)&f, 0, (UNS)FPISZ); /* Initialize fpi.*/
- memcpy(f.fpinm, ename, (f.fpinml = (char)*ename)); /* Store name. */
- memcpy(f.fpisysis, etext, (f.fpisysl = (char)len)); /* Store sys ID. */
- f.fpistore = 2; /* Type: general. */
- etx.x = entgen(&f); /* Get SGMLIO nm. */
- return(entdef(indocent, ESF, &etx)); /* Store it. */
- }
- /******************************************************************************/
- /* SGMLRSET: Initialization for start of pass.
- */
- VOID sgmlrset(void)
- {
- for (; es>=0; --es) if (FILESW) fileclos();
- badresw = 0; /* 1=REF_ out of context; 0=valid. */
- charmode = 0; /* >0=in #CHARS; 0=not. */
- conactsw = 0; /* No saved content parse action. */
- conrefsw = 0; /* 1=content reference att or empty; 0=no. */
- contersv = 0; /* Save contersw if next action is in hand. */
- contersw = 0; /* 1=element or #CHARS out of context; 0=valid. */
- datarc = 0; /* Return code for data: DAF_ or REF_. */
- delmscsw = 0; /* 1=DELMSC must be inserted in read buffer. */
- didreq = 0; /* 1=required implied tag processed; 0=no. */
- dostag = 0; /* 1=retry newetd instead of parsing; 0=parse. */
- dtdsw = 0; /* DOCTYPE declaration found: 1=yes; 0=no. */
- entdatsw = 0; /* 2=CDATA entity; 4=SDATA; 8=NDATA; 0=none. */
- entpisw = 0; /* 4=PI entity occurred; 0=not. */
- eodsw = 0; /* 1=eod found in error; 0=not yet. */
- eofsw = 0; /* EOF not yet found in document body. */
- etagimct = 0; /* Implicitly ended elements left on stack. */
- etagimsw = 0; /* 1=end-tag implied by other end-tag; 0=not. */
- etagmin = MINNONE; /* Minim: NONE NULL NET DATA; implied by S/ETAG*/
- etictr = 0; /* Number of "NET enabled" tags on stack. */
- etisw = 0; /* 1=tag ended with eti; 0=did not. */
- indtdsw = 0; /* Are we in the DTD? 1=yes; 0=no. */
- mslevel = 0; /* Nesting level of marked sections. */
- msplevel = 0; /* Nested MS levels subject to special parse. */
- newdtdsw = 0; /* 1=DTD just started; 0=DTD returned to TP. */
- prologsw = 1; /* Start parsing with prolog. */
- propcb = &pcbpro; /* Start with normal prolog PCB. */
- pss = 0; /* SGMLACT pcb stack level. */
- sgmlsw = 0; /* SGML declaration found: 1=yes; 0=no. */
- stagmin = MINNONE; /* Minimization: NONE, NULL tag, implied by STAG*/
- tagctr = 0; /* No start-tag chars counted yet. */
- ts = -1; /* Index of current tag in stack. */
- nextetd = 0; /* ETD that must come next (only one choice). */
- return;
- }
- /******************************************************************************/
- #undef ETDCON
- #undef PUTRCB
- #undef PUTRC
- /******************************************************************************/