home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* MDENTITY: Fixed bug -- pne was not being stored in ecb->etx.n. */
- /* MDEXTID: Fixed bug -- specified att list was not stored permanently. */
- /* MDEXTID: Fixed bug -- default att list was not stored with entity. */
- /******************************************************************************/
- /* MDENTITY & MDEXTID: Support N/C/SDATA entities with attributes. */
- /* Changed free() to frem() to move memory allocation to TP environment. */
- /* Some minor LINT fixes. */
- /******************************************************************************/
- #include "sgmlincl.h" /* #INCLUDE statements for SGML parser. */
- /******************************************************************************/
- /* MDENTITY: Process ENTITY declaration.
- */
- void mdentity(
- UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */
- {
- struct fpi fpicb; /* Formal public identifier structure. */
- struct fpi *fpis = &fpicb; /* Ptr to current or #DEFAULT fpi. */
- UNCH ename[NAMELEN+3]; /* Entity name (+1 for RNI). */
- UNCH pname[NAMELEN+2]; /* Parameter entity name (no PERO). */
- UNCH *xnmpt = ename; /* Ptr to name to use for MDEXTID. */
- union etext etx; /* Ptr to entity text. */
- UNCH estore = ESM; /* Entity storage class. */
- struct entity *ecb; /* Ptr to entity control block. */
- int parmsw = 0; /* 1=parameter entity declaration; 0 = not. */
- int defltsw = 0; /* 1=#DEFAULT declaration; 0=not. */
- int dupsw = 0; /* 1=duplicate entity (ignore); 0=not. */
- PNE pne; /* Ptr to N/C/SDATA entity control block. */
-
- mdname = syn.k.entitee; /* Declaration name for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
- /* PARAMETER 1: Entity name.
- */
- pcbmd.newstate = 0;
- parsemd(ename, ENTCASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: entity nm");
- #endif
- switch (pcbmd.action) {
- case PEN:
- parsemd(pname, ENTCASE, &pcblitp, NAMELEN-1);
- if (pcbmd.action!=NAS) {mderr(120, NULL, NULL); return;}
- *ename = *pname+1; /* Increment length for PERO. */
- ename[1] = lex.d.pero; /* Prefix PERO to name. */
- memcpy(&ename[2] , &pname[1],*pname-1 ); /* Copy to name buffer. */
- parmsw = 1; /* Indicate parameter entity. */
- case NAS:
- break;
- case RNS: /* Reserved name started. */
- if (strcmp(ename+1, syn.k.kdefault)) {
- mderr(118, ename+1, syn.k.kdefault);
- return;
- }
- memcpy(ename, indefent, *indefent);/* Copy #DEFAULT to name buffer. */
- fpis = &fpidf; /* Use #DEFAULT fpi if external. */
- defltsw = 1; /* Indicate #DEFAULT is being defined.*/
- break;
- default:
- mderr(122, NULL, NULL);
- return;
- }
- subdcl = ename+1; /* Subject name for error messages. */
- if ((ecb = entfind(ename))!=0 && ecb->estore) {
- if (sw.swdupent) mderr(68, ename+1, NULL);
- dupsw = 1; /* Not an error: finish parsing dcl. */
- }
- /* PARAMETER 2: Entity text keyword (optional).
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: keyword");
- #endif
- switch (pcbmd.action) {
- case NAS:
- if ((estore = (char)mapsrch(enttab, tbuf+1))==0) {
- if (parmsw) {estore = ESP; xnmpt = pname;}
- else estore = ESF; /* Assume general entity. */
- pne = (PNE)rmalloc(NESZ);
- if (mdextid(tbuf, fpis, xnmpt, &estore, pne)==0) return;
- if (defltsw) etx.x = NULL;
- else if ((etx.x = entgen(&fpicb))==0) return;
- goto parm4;
- }
- if (parmsw && (estore==ESX || estore==ESC)) {
- mderr(38, tbuf+1, NULL);
- estore = ESM;
- }
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
- break;
- default:
- estore = ESM;
- break;
- }
- /* PARAMETER 3: Parameter literal.
- */
- #ifndef FINAL
- if (dtrace) tracemd("3: literal");
- #endif
- switch (pcbmd.action) {
- case LITE:
- case LIT:
- switch (estore) {
- case ESM: /* LITERAL: parameter literal required. */
- case ESC: /* CDATA: parameter literal required. */
- case ESX: /* SDATA: parameter literal required. */
- case ESI: /* PI: parameter literal required. */
- etx.c = strlsave(tbuf);
- break;
- case ESMD: /* MD: parameter literal required. */
- etx.c = sandwich(tbuf, lex.m.mdo, lex.m.mdc);
- break;
- case ESMS: /* MS: parameter literal required. */
- etx.c = sandwich(tbuf, lex.m.mss, lex.m.mse);
- break;
- case ESS: /* STARTTAG: parameter literal required. */
- tagtext(tbuf, &estore, lex.m.lennst, lex.m.stag, &etx);
- break;
- case ESE: /* ENDTAG: parameter literal required. */
- tagtext(tbuf, &estore, lex.m.lennet, lex.m.etag, &etx);
- break;
- }
- break;
- default:
- mderr(123, NULL, NULL);
- return;
- }
- /* PARAMETER 4: End of declaration.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
- parm4:
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- if (es!=mdessv) synerr(37, &pcbmd);
-
- /* EXECUTE: If the entity already exists, ignore the new definition.
- If it is a new entity, store the definition.
- */
- if (dupsw) {
- if (estore<ESFM && estore!=ESS && estore!=ESE) frem(etx.c);
- return;
- }
- ++ds.ecbcnt; /* Do capacity before NOTATION. */
- ds.ecbtext +=
- (estore<ESFM && estore!=ESS && estore!=ESE) ? (int)*etx.c-2 : entlen;
- ecb = entdef(ename, estore, &etx); /* Define the entity. */
- if (estore==ESN) { /* If entity is external: */
- NEENAME(pne) = ecb->ename; /* Store entity name in ne. */
- NEID(pne) = etx.x; /* Store system fileid in ne. */
- ecb->etx.n = pne; /* Store ne control block in etx. */
- #ifndef FINAL
- if (etrace || atrace || ntrace) traceesn(pne);
- #endif
- }
- if (defltsw) ecbdeflt = ecb; /* If #DEFAULT save ecb. */
- }
- /******************************************************************************/
- /* TAGTEXT: Generate entity text for STARTTAG or ENDTAG.
- */
- VOID tagtext(
- UNCH *tbuf, /* Entity text as specified in declaration. */
- UNCH *pestore, /* Point to caller's estore value. */
- int lennt, /* Length of a null tag (start- or end-). */
- UNCH *marktag, /* Tag open delimiter (stago or etago). */
- union etext *petext) /* Pointer to etext union. */
- {
- if ((entlen = *tbuf-2 + lennt)==lennt) /* Null tag: no etd. */
- {petext->e = ETDNULL; return;}
- if (!parseval(tbuf, ANAME, lbuf)) /* GI with no atts: use etd. */
- {petext->e = etddef(pvalptr); return;}
- *pestore = EST; /* GI with atts: use tag. */
- petext->c = sandwich(tbuf, marktag, lex.m.tagc);
- }
- /******************************************************************************/
- /* ENTFIX: Change a type ESS or ESE entity to the corresponding tag form.
- The entity is assumed to exist.
- */
- VOID entfix(
- UNCH *ename) /* Entity name (with length and EOS). */
- {
- struct entity *ecb; /* Entity control block. */
-
- /* Get the entity control block, as the entity has been defined. */
- ecb = entfind(ename);
- ecb->etx.c = sandwich(ecb->etx.e->etdgi,
- ecb->estore==ESS ? lex.m.stag : lex.m.etag, lex.m.tagc);
- ecb->estore = EST;
- #ifndef FINAL
- if (etrace) traceecb("ENTFIX", ecb);
- #endif
- }
- /******************************************************************************/
- /* MDEXTID: Process external identifier parameter of a markup declaration.
- On entry, tbuf contains SYSTEM or PUBLIC if all is well.
- NULL is returned if an error, otherwise fpis. If it is a
- valid external data entity, the caller's estore is set to ESN
- and its nxetype is set to the code for the external entity type.
- The event that terminated the parse is preserved in pcb.action,
- so the caller should process it before further parsing.
- */
- struct fpi *mdextid(
- UNCH *tbuf, /* Work area for tokenization[2*(LITLEN+2)]. */
- struct fpi *fpis, /* FPI structure. */
- UNCH *ename, /* Entity or notation name, with length and EOS.*/
- /* NOTE: No PERO on parameter entity name. */
- UNCH *estore, /* DTD, general or parameter entity, DCN. */
- PNE pne) /* Caller's external entity ptr. */
- {
- PDCB dcb; /* Ptr to DCN control block. */
- int exidtype; /* External ID type: 0=none 1=system 2=public. */
- int exetype; /* External entity type. */
-
- memset((UNIV)fpis, 0, (UNS)FPISZ); /* Initialize fpi structure. */
- /* Move entity name into fpi (any PERO was stripped by caller). */
- memcpy(fpis->fpinm, ename, (UNS)(fpis->fpinml = *ename));
- entlen = 0; /* Initialize external ID length. */
-
- /* PARAMETER 1: External identifier keyword or error.
- */
- #ifndef FINAL
- if (dtrace) tracemd("1: extid keyword");
- #endif
- if ((exidtype = mapsrch(exttab, tbuf+1))==0) {
- mderr(29, NULL, NULL);
- return (struct fpi *)0;
- }
- if (exidtype==EDSYSTEM) goto parm3;
-
- /* PARAMETER 2: Public ID literal.
- */
- pcbmd.newstate = 0;
- parsemd(fpis->fpipubis, NAMECASE, &pcblitv, LITLEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: pub ID literal");
- #endif
- switch (pcbmd.action) {
- case LITE: /* Use alternative literal delimiter. */
- case LIT: /* Save literal as public ID string. */
- entlen = (fpis->fpipubl = *fpis->fpipubis) - 2;
- break;
- default:
- mderr(117, NULL, NULL);
- return (struct fpi *)0; /* Signal error to caller. */
- }
- /* PARAMETER 3: System ID literal.
- */
- parm3:
- pcbmd.newstate = 0;
- parsemd(fpis->fpisysis, NAMECASE, &pcblitc, LITLEN);
- #ifndef FINAL
- if (dtrace) tracemd("3: sys ID literal");
- #endif
- if (pcbmd.action==LIT || pcbmd.action==LITE) {
- entlen += (fpis->fpisysl = *fpis->fpisysis) - 2;
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
- }
- else memcpy(tbuf , fpis->fpisysis, *fpis->fpisysis );
- if (*estore!=ESF || pcbmd.action!=NAS) goto genfpi;
-
- /* PARAMETER 4: Entity type keyword.
- */
- #ifndef FINAL
- if (dtrace) tracemd("4: Entity type");
- #endif
- if ((exetype = mapsrch(extettab, tbuf+1))==0) {
- mderr(24, tbuf+1, NULL);
- return (struct fpi *)0;
- }
- if (exetype==ESNSUB) {
- mderr(90, tbuf+1, NULL);
- return (struct fpi *)0;
- }
- NEXTYPE(pne) = (char)exetype; /* Save entity type in caller's ne. */
- *estore = ESN; /* Signal that entity is a data entity. */
-
- /* PARAMETER 5: Notation name.
- */
- pcbmd.newstate = 0;
- parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("5: notation");
- #endif
- if (pcbmd.action!=NAS) {mderr(119, tbuf+1, NULL); return (struct fpi *)0;}
- /* Locate the data content notation. */
- pne->nedcn = dcb = dcndef(lbuf);
-
- /* PARAMETER 6: Data attribute specification.
- */
- pcbmd.newstate = 0;
- parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("6: [att list]");
- #endif
- if (pcbmd.action!=MDS) { /* No attributes specified. */
- NEAL(pne) = dcb->adl; /* Copy default atts (if any). */
- goto genfpi;
- }
- if (dcb->adl==0) { /* Atts specified, but none defined. */
- mderr(22, NULL, NULL);
- return (struct fpi *)0;
- }
- pcbstag.newstate = pcbstan; /* First separator is optional. */
- if ((parseatt(dcb->adl, tbuf, lbuf))==0)/* Empty list. */
- mderr(91, NULL, NULL);
- else {
- adlval((int)ADN, (struct etd *)0);
- NEAL(pne) = (struct ad *)rmalloc((1+ADN)*ADSZ);
- memcpy((UNIV)NEAL(pne), (UNIV)al, (1+ADN)*ADSZ );
- ds.attcnt += AN; /* Number of attributes defined. */
- ds.attgcnt += ADN - AN; /* Number of att grp members. */
- }
- parse(&pcbmds); /* Parse the list ending. */
- pcbmd.newstate = 0; /* Parse next token for caller. */
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
-
- /* GENFPI: Builds a formal public identifier structure, including the
- entity name, offsets of the components of the public ID, and
- other data a system might use to identify the actual file.
- */
- genfpi:
- #ifndef FINAL
- if (dtrace) tracemd("7: generate fpi");
- #endif
- fpis->fpistore = *estore - ESFM + 1; /* External entity type: 1-6. */
- /* Analyze public ID and make structure entries. */
- if (exidtype==EDPUBLIC && parsefpi(fpis)>0) {
- mderr(88, fpis->fpipubis+1, NULL);
- fpis->fpiversw = -1; /* Signal bad formal public ID. */
- }
- return (fpis);
- }
- /******************************************************************************/
- /* PARSEFPI: Parses a formal public identifier and builds a control block.
- PARSEFPI returns a positive error code (1-9), or 0 if no errors.
- It set fpiversw if no version was specified in the ID and the
- public text is in a class that permits display versions.
- Note: An empty version ("//") can be specified (usually it is
- the non-device-specific form, such as a definitional entity set).
- */
- int parsefpi(
- PFPI f) /* Ptr to formal public identifier structure. */
- {
- UNCH *l; /* Pointer to EOS of public identifier. */
- UNCH *p, *q; /* Ptrs to current field in public identifier. */
-
- p = f->fpipubis; /* Point to start of identifier. */
- l = *p + p++ -1; /* Point to EOS of identifier. */
- if (*p=='+' || *p=='-') { /* If owner registered, unregistered. */
- f->fpiot = *p; /* Save owner type. */
- if ((p += 3)>=l) return 1; /* Get to owner ID field. */
- }
- else f->fpiot = '!'; /* Indicate ISO owner identifier. */
- if ((q = pubfield(p, l, '/'))==0) /* Find end of owner ID field. */
- return 2;
- f->fpiol = (char)pifldlen; /* Save owner ID length. */
- f->fpio = (int)(p - f->fpipubis); /* Save offset in pubis to owner ID. */
-
- if ((p = pubfield(q, l, ' '))==0) /* Find end of text class field. */
- return 3;
- *(--p) = EOS; /* Temporarily make class a string. */
- f->fpic = mapsrch(pubcltab, q); /* Check for valid uc class name.*/
- *p++ = ' '; /* Restore the SPACE delimiter. */
- if (f->fpic==0) return 4; /* Error if not valid uc class name.*/
-
- if (*p=='-') { /* If text is unavailable public text.*/
- f->fpitt = *p; /* Save text type. */
- if ((p += 3)>=l) return 5; /* Get to text description field. */
- }
- else f->fpitt = '+'; /* Indicate available public text. */
- if ((q = pubfield(p, l, '/'))==0) /* Find end of text description. */
- return 6;
- f->fpitl = (char)pifldlen; /* Save text description length. */
- f->fpit = (int)(p - f->fpipubis); /* Save ptr (in pubis) to description.*/
-
- p = pubfield(q, l, '/'); /* Bound language field. */
- if (pifldlen!=2) return 7; /* Language must be 2 characters. */
- f->fpil[0] = *q; /* Save 1st language character. */
- f->fpil[1] = *(q+1); /* Save 2nd language character. */
-
- if (p!=0) { /* If there is a version field: */
- if (f->fpic<FPICMINV) /* Error if class prohibits versions. */
- return 8;
- if ((pubfield(p, l, '/'))!=0) /* Bound version field. */
- return 9; /* Error if yet another field. */
- f->fpivl = (char)pifldlen; /* Save version length. */
- f->fpiv = (int)(p-f->fpipubis); /* Save ptr (in pubis) to version. */
- }
- else if (f->fpic>=FPICMINV) f->fpiversw = 1;/* No version: get the best. */
- return(0);
- }
- /******************************************************************************/
- /* PUBFIELD: Returns ptr to next field, or NULL if ID has ended.
- */
- UNCH *pubfield(
- UNCH *p, /* Public identifier field (no length or EOS). */
- UNCH *l, /* Pointer to EOS of public identifier. */
- UNCH d) /* Field delimiter: ' ' or '/'. */
- {
- UNCH *psv = p+1; /* Save starting value of p. */
-
- while (p<l) {
- if (*p++==d) { /* Test for delimiter character. */
- pifldlen =(UNS)(p-psv);/* Save field length (no len or EOS). */
- if (d=='/' && *p++!=d) /* Solidus requires a second one. */
- continue;
- return(p); /* Return ptr to next field. */
- }
- }
- pifldlen =(UNS)(p - --psv); /* Save field length (no len or EOS). */
- return NULL;
- }
- /******************************************************************************/
- /* MDMS: Process marked section start.
- If already in special parse, bump the level counters and return
- without parsing the declaration.
- */
- struct parse *mdms(
- UNCH *tbuf, /* Work area for tokenization [NAMELEN+2]. */
- struct parse *pcb) /* Parse control block for this parse. */
- {
- int key; /* Index of keyword in mslist. */
- int ptype; /* Parameter token type. */
- int pcbcode = 0; /* Parse code: 0=same; 2-4 per defines. */
-
- if (++mslevel>TAGLVL) {
- --mslevel;
- sgmlerr(27, (struct parse *)0, ntoa(TAGLVL), NULL);
- }
-
- /* If already in IGNORE mode, return without parsing parameters. */
- if (msplevel) {++msplevel; return(pcb);}
-
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
- pcbmd.newstate = pcbmdtk; /* First separator is optional. */
-
- /* PARAMETERS: TEMP, RCDATA, CDATA, IGNORE, INCLUDE, or MDS. */
- while ((ptype = parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN))==NAS){
- if ((key = mapsrch(mstab, tbuf+1))==0) {
- sgmlerr(64, (struct parse *)0, ntoa(parmno), tbuf+1);
- continue;
- }
- if (key==MSTEMP) continue; /* TEMP: for documentation. */
- msplevel = 1; /* Special parse required. */
- if (key>pcbcode) pcbcode = key; /* Update if higher priority. */
- }
- if (ptype!=MDS) {
- NEWCC; /* Syntax error did REPEATCC. */
- sgmlerr(97, (struct parse *)0, lex.m.dso, NULL);
- REPEATCC; /* 1st char of marked section. */
- }
- if (es!=mdessv) synerr(37, pcb);
- #ifndef FINAL
- if (mtrace) tracems(1, pcbcode, mslevel, msplevel);
- #endif
- if (pcbcode==MSIGNORE) pcb = &pcbmsi;
- else if (pcbcode) {
- pcb = pcbcode==MSCDATA ? &pcbmsc : (rcessv = es, &pcbmsrc);
- }
- return(pcb); /* Tell caller whether to change the parse. */
- }
- /******************************************************************************/
- /* MDMSE: Process marked section end.
- Issue an error if no marked section had started.
- */
- int mdmse(void)
- {
- int retcode = 0; /* Return code: 0=same parse; 1=cancel special. */
-
- if (mslevel) --mslevel;
- else sgmlerr(26, (struct parse *)0, NULL, NULL);
-
- if (msplevel) if (--msplevel==0) retcode = 1;
- #ifndef FINAL
- if (mtrace) tracems(0, retcode, mslevel, msplevel);
- #endif
- return retcode;
- }
- /******************************************************************************/
- /* MDNOT: Process NOTATION declaration.
- */
- VOID mdnot(
- UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */
- {
- struct fpi fpicb; /* Formal public identifier structure. */
- PDCB dcb; /* Ptr to notation entity in dcntab. */
- UNIV ntx; /* Ptr to notation text (DOS identifier). */
- UNCH estore = ESK; /* Entity storage class. */
-
- mdname = syn.k.notation; /* Identify declaration for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
-
- /* PARAMETER 1: Notation name.
- */
- pcbmd.newstate = 0;
- parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: name");
- #endif
- if (pcbmd.action!=NAS) {mderr(120, NULL, NULL); return;}
- subdcl = lbuf+1; /* Save notation name for error msgs. */
-
- /* PARAMETER 2: External identifier keyword.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: extid");
- #endif
- if (pcbmd.action!=NAS) {mderr(29, NULL, NULL); return;}
- if (mdextid(tbuf, &fpicb, lbuf, &estore, (PNE)0)==0) return;
- if ((ntx = entgen(&fpicb))==0) return;
-
- /* PARAMETER 3: End of declaration.
- Token was parsed by MDEXTID.
- */
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- if (es!=mdessv) synerr(37, &pcbmd);
-
- /* EXECUTE: Store notation name.
- If defined with dcnid!=0, ignore this duplicate assignment.
- Else if dcnid==0, assign ntx to dcnid.
- If not defined at all, do a complete definition.
- */
- if ( (dcb = dcnfind(lbuf))!=0 && dcb->dcnid!=0 )
- {mderr(56, lbuf+1, NULL); return;}
- /* else */
- (dcb = dcndef(lbuf))->dcnid = ntx;
- ++ds.dcncnt; ds.dcntext += entlen;
- #ifndef FINAL
- if (ntrace) tracedcn(dcb);
- #endif
- return;
- }
- /******************************************************************************/
- /* DCNDEF: Define a notation and return its DCNCB.
- If caller does not care if it already exists,
- he should specify NULL for the notation text
- so we don't clobber the existing text (if any).
- */
- struct dcncb *dcndef(
- UNCH *nname) /* Notation name (with length and EOS). */
- {
- return((PDCB)hin((THASH)dcntab, nname, 0, DCBSZ));
- }
- /******************************************************************************/
- /* DCNFIND: If a notation was declared, return its DCNCB.
- Return NULL if it is not defined.
- */
- struct dcncb *dcnfind(
- UNCH *nname) /* Notation name (with length and EOS). */
- {
- return((PDCB)hfind((THASH)dcntab, nname, 0));
- }
- /******************************************************************************/
- #define SRM(i) (srhptr->srhsrm[i]) /* Current entry in SHORTREF map. */
- /******************************************************************************/
- /* MDSRMDEF: Process short reference mapping declaration.
- */
- VOID mdsrmdef(
- UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */
- {
- UNCH sname[NAMELEN+2]; /* Name of short reference map being defined. */
- struct entity *entcb; /* Ptr to defined entity. */
- PSRH srhptr; /* Ptr to short reference map hdr (in srhtab).*/
- int srn; /* Short reference delimiter number in srdeltab.*/
-
- mdname = syn.k.shortref; /* Identify declaration for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
- /* PARAMETER 1: SHORTREF map name.
- */
- pcbmd.newstate = 0;
- parsemd(sname, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: map nm");
- #endif
- if (pcbmd.action!=NAS) {mderr(120, NULL, NULL); return;}
- if ((srhptr = srhfind(sname))!=0) {
- /* Error if map was declared (not just used). */
- if (SRM(0)) {mderr(56, sname+1, NULL); return;}
- }
- else srhptr = srhdef(sname); /* Create map with SRs mapped to NULL.*/
- SRM(0) = (PECB)srhptr; /* Indicate map was actually declared.*/
- subdcl = sname+1; /* Save map name for error msgs. */
-
- while ( pcbmd.newstate = 0,
- parsemd(tbuf, NAMECASE, &pcblitp, SRMAXLEN)==LIT
- || pcbmd.action==LITE ) {
- /* PARAMETER 2: Delimiter string.
- */
- #ifndef FINAL
- if (dtrace) tracemd("2: SR string");
- #endif
- if ((srn = mapsrch(lex.s.dtb, tbuf+1))==0) {
- mderr(124, tbuf+1, NULL);
- goto cleanup;
- }
- /* PARAMETER 3: Entity name.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, ENTCASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("3: entity");
- #endif
- if (pcbmd.action!=NAS) {mderr(120, NULL, NULL); goto cleanup;}
- if ((entcb = entfind(tbuf))==0)
- entcb = entdef(tbuf, '\0', (union etext *)NULL);
- if (SRM(srn)) {
- mderr(56, (srn<lex.s.prtmin ? lex.s.pdtb[srn]
- : lex.s.dtb[srn].mapnm), NULL);
- continue;
- }
- SRM(srn) = entcb;
- if (srn>=lex.s.fce && srn!=lex.s.hyp && srn!=lex.s.hyp2)
- lexcnm[*lex.s.dtb[srn].mapnm] = lex.l.fce;
- else if (srn==lex.s.spc) lexcnm[' '] = lex.l.spcr;
- }
- /* PARAMETER 4: End of declaration.
- */
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (parmno==2)
- {mderr((UNS)(pcbmd.action==EMD ? 28:123), NULL, NULL); goto cleanup;}
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- if (es!=mdessv) synerr(37, &pcbmd);
- ++ds.srcnt;
- #ifndef FINAL
- if (etrace) tracesrm("SHORTREF", srhptr->srhsrm, NULL);
- #endif
- return;
-
- /* CLEANUP: Free map storage if no valid mappings. */
- cleanup:
- frem((UNIV)srhptr->srhsrm);
- hout((THASH)srhtab, sname, 0);
- }
- /******************************************************************************/
- /* MDSRMUSE: Activate a short reference map.
- */
- VOID mdsrmuse(
- UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */
- {
- PSRH srhptr; /* Ptr to short reference map hdr (in srhtab).*/
- TECB srmptr; /* Ptr to short reference map (in header). */
- PETD nmgrp[GRPCNT+1]; /* Array of etds being defined. */
- int i; /* Loop counter; temporary variable. */
- UNCH sname[NAMELEN+2]; /* Save area for name of undefined map. */
-
- mdname = syn.k.usemap; /* Identify declaration for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
- /* PARAMETER 1: SHORTREF map name or "#EMPTY".
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: map nm");
- #endif
- switch (pcbmd.action) {
- case RNS: /* Empty SHORTREF map requested. */
- if (strcmp(tbuf+1, syn.k.empty)) {
- mderr(118, tbuf+1, syn.k.empty);
- return;
- }
- srmptr = SRMNULL;
- subdcl = syn.k.empty; /* Subject name for error messages. */
- break;
- case NAS: /* Map name specified; save if undefined. */
- subdcl = tbuf+1; /* Subject name for error messages. */
- if ((srhptr = srhfind(tbuf))==0) {
- if (!indtdsw) {mderr(125, NULL, NULL); return;}
- /* else */ memcpy(sname , tbuf, (UNS)sizeof(sname));
- }
- else srmptr = srhptr->srhsrm;
- break;
- default:
- mderr(120, NULL, NULL);
- return;
- }
- /* PARAMETER 2: Element name or a group of them. (In DTD only.)
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: GI or grp");
- #endif
- if (pcbmd.action!=EMD && !indtdsw) {mderr(28, NULL, NULL); return;}
- switch (pcbmd.action) {
- case NAS:
- nmgrp[0] = etddef(tbuf);
- nmgrp[1] = (PETD)NULL;
- break;
- case GRPS:
- parsegrp(nmgrp, &pcbgrnm);
- break;
- case EMD:
- tags[ts].tsrm = srmptr;
- #ifndef FINAL
- if (etrace) tracesrm("USEMAP", tags[ts].tsrm, tags[ts].tetd->etdgi+1);
- #endif
- goto realemd;
- default:
- mderr(121, NULL, NULL);
- return;
- }
- /* PARAMETER 3: End of declaration.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- /* If map has not yet been defined, do it and get map pointer. */
- if (!srhptr) srmptr = (srhdef(sname))->srhsrm;
-
- /* Store the map pointer for each element name specified.
- */
- #ifndef FINAL
- if (gtrace) tracegrp(nmgrp);
- #endif
- for (i = -1; nmgrp[++i];) {
- if (!nmgrp[i]->etdsrm) nmgrp[i]->etdsrm = srmptr;
- else if (sw.swdupent) mderr(68, nmgrp[i]->etdgi+1, NULL);
- }
- realemd:
- if (es!=mdessv) synerr(37, &pcbmd);
- }
- /******************************************************************************/
- /* SRHDEF: Define a SHORTREF map and return ptr to its header.
- All entries in map are mapped to NULL.
- Caller must determine whether it already exists.
- */
- PSRH srhdef(
- UNCH *sname) /* SHORTREF map name (with length and EOS). */
- {
- PSRH srh; /* Ptr to SHORTREF map hdr in srhtab. */
-
- (srh = (PSRH)hin((THASH)srhtab, sname, 0, SRHSZ))->srhsrm =
- (TECB)rmalloc((UNS)(lex.s.dtb[0].mapdata+1)*sizeof(PECB));
- return(srh);
- }
- /******************************************************************************/
- /* SRHFIND: If a SHORTREF map was declared, return the ptr to its header.
- Return NULL if it is not defined.
- */
- PSRH srhfind(
- UNCH *sname) /* SHORTREF map name (with length and EOS). */
- {
- return((PSRH)hfind((THASH)srhtab, sname, 0));
- }
- /******************************************************************************/
- #undef SRM
- /******************************************************************************/
-