home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* 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. */
- /******************************************************************************/
- /* MDADL: Process ATTLIST declaration.
- */
- VOID mdadl(
- UNCH *tbuf) /* Work area for tokenization (tbuf). */
- {
- struct etd *nmgrp[GRPCNT+1]; /* Array of etds being defined. */
- int i; /* Loop counter; temporary variable. */
- int adlim; /* Number of unused ad slots in al. */
- struct ad *alperm = 0; /* Attribute definition list. */
-
- mdname = syn.k.attlist; /* Identify declaration for messages. */
- subdcl = 0; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es level for entity nesting check. */
- reqadn = noteadn = 0; /* No required attributes yet. */
- idadn = conradn = 0; /* No special atts yet.*/
- AN = 0; /* Number of attributes defined. */
- ADN = 0; /* Number of ad's in al (atts + name vals).*/
- /* PARAMETER 1: Element name or a group of them.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: element name or group");
- #endif
- switch (pcbmd.action) {
- case NAS:
- nmgrp[0] = etddef(tbuf);
- nmgrp[1] = 0;
- break;
- case GRPS:
- parsegrp(nmgrp, &pcbgrnm);
- break;
- case RNS: /* Reserved name started. */
- if (strcmp(tbuf+1, syn.k.notation)) {
- mderr(118, tbuf+1, syn.k.notation);
- return;
- }
- mdnadl(tbuf);
- return;
- default:
- mderr(121, NULL, NULL);
- return;
- }
- subdcl = nmgrp[0]->etdgi+1; /* Save first GI for error msgs. */
- /* PARAMETER 2: Attribute definition list.
- */
- parsemd((STRING)al[ADN+1].adname, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: attribute list");
- #endif
- if (pcbmd.action!=NAS) {
- mderr(120, NULL, NULL);
- return;
- }
- while (pcbmd.action==NAS) {
- if ((adlim = ATTCNT-((int)ADN++))<0) {mderr(111, NULL, NULL); return;}
- ++AN;
- if (mdattdef(adlim)) return;
- parsemd((STRING)al[ADN+1].adname, NAMECASE, &pcblitp, NAMELEN);
- }
- if (AN>0) { /* Save list only if 1 or more good atts. */
- if (reqadn) SET(ADLF, ADLREQ); /* Element must have start-tag. */
- if (noteadn) SET(ADLF, ADLNOTE); /* Element cannot be EMPTY. */
- if (conradn) SET(ADLF, ADLCONR); /* Element cannot be EMPTY. */
- alperm = (struct ad *)rmalloc((1+ADN)*ADSZ);
- memcpy((UNIV)alperm, (UNIV)al, (1+ADN)*ADSZ );
- ds.attcnt += AN; /* Number of attributes defined. */
- ds.attgcnt += ADN - AN; /* Number of att grp members. */
- #ifndef FINAL
- if (atrace) traceadl(alperm);
- #endif
- }
- /* Clear attribute list for next declaration. */
- memset((UNIV)al, '\0', (1+ADN)*ADSZ);
-
- /* PARAMETER 3: End of declaration.
- */
- /* Next pcb.action was set during attribute definition loop. */
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) {mderr(126, NULL, NULL); return;}
- if (es!=mdessv) synerr(37, &pcbmd);
-
- /* EXECUTE: Store the definition for each element name specified.
- */
- #ifndef FINAL
- if (gtrace) tracegrp(nmgrp);
- #endif
- for (i = -1; nmgrp[++i];) {
- if (nmgrp[i]->adl) { /* Error if an ADL exists. */
- mderr(112, NULL, NULL);
- continue;
- }
- nmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */
- etdadl(nmgrp[i]); /* Check for conflicts with ETD. */
- }
- }
- /******************************************************************************/
- /* ETDADL: Check compatibility between ETD and ADL.
- */
- void etdadl(
- struct etd *p) /* Pointer to element type definition. */
- {
- parmno = 0;
- /* Minimizable element cannot have required attribute. */
- if (GET(p->etdmin, SMO) && GET(p->adl[0].adflags, ADLREQ)) {
- mderr(40, NULL, NULL);
- RESET(p->etdmin, SMO);
- }
- /* Empty element cannot have NOTATION attribute.
- Attribute is not removed (too much trouble), but we trap
- attempts to specify it on the start-tag in PARSEATT.C.
- */
- if (p->etdmod && GET(p->etdmod->ttype, MNONE)) {
- if (GET(p->adl[0].adflags, ADLNOTE))
- mderr(83, NULL, NULL);
-
- /* Empty element cannot have CONREF attribute.
- Attribute is not removed because it just acts
- like IMPLIED anyway.
- */
- if (GET(p->adl[0].adflags, ADLCONR))
- mderr(85, NULL, NULL);
- }
- }
- /******************************************************************************/
- /* MDNADL: Process ATTLIST declaration for notation.
- TO DO: Pass deftab and dvtab as parameters so
- that prohibited types can be handled by leaving
- them out of the tables.
- */
- VOID mdnadl(
- UNCH *tbuf) /* Work area for tokenization (tbuf). */
- {
- PDCB nmgrp[GRPCNT+1]; /* Array of dcncb's being defined. */
- int i; /* Loop counter; temporary variable. */
- int adlim; /* Number of unused ad slots in al. */
- struct ad *alperm = 0; /* Attribute definition list. */
-
- /* PARAMETER 1: Notation name or a group of them.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: notation name or group");
- #endif
- switch (pcbmd.action) {
- case NAS:
- nmgrp[0] = dcndef(tbuf);
- nmgrp[1] = 0;
- break;
- case GRPS:
- parsngrp(nmgrp, &pcbgrnm);
- break;
- default:
- mderr(121, NULL, NULL);
- return;
- }
- subdcl = nmgrp[0]->ename+1; /* Save first name for error msgs. */
- /* PARAMETER 2: Attribute definition list.
- */
- parsemd((STRING)al[ADN+1].adname, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: attribute list");
- #endif
- if (pcbmd.action!=NAS) {
- mderr(120, NULL, NULL);
- return;
- }
- while (pcbmd.action==NAS) {
- if ((adlim = ATTCNT-((int)ADN++))<0) {mderr(111, NULL, NULL); return;}
- ++AN;
- if (mdattdef(adlim)) return;
- parsemd((STRING)al[ADN+1].adname, NAMECASE, &pcblitp, NAMELEN);
- }
- if (AN>0) { /* Save list only if 1 or more good atts. */
- alperm = (struct ad *)rmalloc((1+ADN)*ADSZ);
- memcpy((UNIV)alperm, (UNIV)al, (1+ADN)*ADSZ );
- ds.attcnt += AN; /* Number of attributes defined. */
- ds.attgcnt += ADN - AN; /* Number of att grp members. */
- #ifndef FINAL
- if (atrace) traceadl(alperm);
- #endif
- }
- /* Clear attribute list for next declaration. */
- memset((UNIV)al, '\0', (1+ADN)*ADSZ);
-
- /* PARAMETER 3: End of declaration.
- */
- /* Next pcb.action was set during attribute definition loop. */
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) {mderr(126, NULL, NULL); return;}
- if (es!=mdessv) synerr(37, &pcbmd);
-
- /* EXECUTE: Store the definition for each notation name specified.
- */
- #ifndef FINAL
- if (gtrace) tracengr(nmgrp);
- #endif
- for (i = -1; nmgrp[++i];) {
- if (nmgrp[i]->adl) { /* Error if an ADL exists. */
- mderr(112, NULL, NULL);
- continue;
- }
- nmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */
- #ifndef FINAL
- if (ntrace) tracedcn(nmgrp[i]);
- #endif
- }
- }
- /******************************************************************************/
- /* MDATTDEF: Process an individual attribute definition.
- The attribute name is parsed by the caller.
- Duplicate attributes are parsed, but removed from list.
- Returns 0 if successful, otherwise returns 1.
- */
- int mdattdef(
- int adlim) /* Remaining capacity of al (in tokens).*/
- {
- int deftype; /* Default value type: 0=not keyword. */
- int errsw = 0; /* 1=semantic error; ignore att. */
- int novalsw = 0; /* 1=semantic error; treat as IMPLIED. */
- int attadn = (int)ADN; /* Save ad number of this attribute. */
- struct parse *grppcb; /* PCB for name/token grp parse. */
- int errcode; /* Error type returned by PARSEVAL, ANMTGRP. */
- UNCH *advalsv; /* Save area for permanent value ptr. */
-
- /* PARAMETER 1: Attribute name (parsed by caller).
- */
- #ifndef FINAL
- if (dtrace) tracemd("1: attribute name");
- #endif
- if (anmget((int)ADN-1, al[attadn].adname)) {
- errsw = 1;
- mderr(99, ADNAME(attadn), NULL);
- }
- ADNUM(attadn) = ADFLAGS(attadn) = ADLEN(attadn) = 0;
- ADVAL(attadn) = 0; ADDATA(attadn).x = 0; ADTYPE(attadn) = ANMTGRP;
- /* PARAMETER 2: Declared value.
- */
- parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: declared value");
- #endif
- switch (pcbmd.action) {
- case NAS: /* Keyword for value type. */
- switch (ADTYPE(attadn) = (char)mapsrch(dvtab, lbuf+1)) {
- case 0:
- mderr(100, ADNAME(attadn), lbuf+1);
- return 1;
- case ANOTEGRP:
- if (!noteadn) noteadn = ADN;
- else {
- errsw = 1;
- mderr(101, ADNAME(attadn), NULL);
- }
- grppcb = &pcbgrnm; /* NOTATION requires name grp. */
- parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);/* Get GRPO*/
- break;
- case AID:
- if (!idadn) idadn = attadn;
- else {
- errsw = 1;
- mderr(102, ADNAME(attadn), NULL);
- }
- break;
- }
- break;
- case GRPS:
- grppcb = &pcbgrnt; /* Normal grp is name token grp. */
- break;
- case EMD:
- mderr(103, ADNAME(attadn), NULL);
- return 1;
- default:
- mderr(104, ADNAME(attadn), NULL);
- return 1;
- }
- /* PARAMETER 2A: Name token group.
- */
- if (pcbmd.action==GRPS || ADTYPE(attadn)==ANOTEGRP) {
- #ifndef FINAL
- if (dtrace) tracemd("2A: name group");
- #endif
- switch (pcbmd.action) {
- case GRPS: /* Name token list. */
- SET(ADFLAGS(attadn), AGROUP);
- /* Call routine to parse group, create ad entries in adl. */
- errcode = anmtgrp(grppcb, al+attadn,
- (GRPCNT<adlim ? GRPCNT+1 : adlim+1),
- &al[attadn].adnum, (int)ADN);
- if (errcode<=0) {
- mderr(105, ADNAME(attadn), NULL);
- return 1;
- }
- ADN += ADNUM(attadn); /* Add grp size to total ad cnt.*/
- break;
- default:
- mderr(106, ADNAME(attadn), NULL);
- return 1;
- }
- }
- /* PARAMETER 3: Default value keyword.
- */
- parsemd(lbuf, AVALCASE, &pcblitr, LITLEN);
- #ifndef FINAL
- if (dtrace) tracemd("3: default keyword");
- #endif
- switch (pcbmd.action) {
- case RNS: /* Keyword. */
- deftype = mapsrch(deftab, lbuf+1);
- switch (deftype) {
- case DFIXED: /* FIXED */
- SET(ADFLAGS(attadn), AFIXED);
- parsemd(lbuf, AVALCASE, &pcblitr, LITLEN); /* Real default. */
- goto parm3x; /* Go process specified value. */
- case DCURR: /* CURRENT: If ID, treat as IMPLIED. */
- if (ADTYPE(attadn)==AID) {
- mderr(80, ADNAME(attadn), NULL);
- break;
- }
- SET(ADFLAGS(attadn), ACURRENT);
- break;
- case DREQ: /* REQUIRED */
- SET(ADFLAGS(attadn), AREQ); ++reqadn;
- break;
- case DCONR: /* CONREF */
- if (ADTYPE(attadn)==AID) {
- mderr(107, ADNAME(attadn), NULL);
- break;
- }
- SET(ADFLAGS(attadn), ACONREF); conradn = 1;
- case DNULL: /* IMPLIED */
- break;
- default: /* Unknown keyword is an error. */
- mderr(108, ADNAME(attadn), lbuf+1);
- errsw = 1;
- }
- if (errsw) {--AN; ADN = (char)attadn-1;} /* Ignore erroneous att. */
- return(0);
- default:
- break;
- }
- /* PARAMETER 3x: Default value (non-keyword).
- */
- parm3x:
- #ifndef FINAL
- if (dtrace) tracemd("3x: default (non-keyword)");
- #endif
- /* if (ADTYPE(attadn)==AID) { ** If ID, treat as IMPLIED. **
- mderr(81, ADNAME(attadn), NULL);
- novalsw = 1; ** Keep parsing to keep things straight. **
- } */
- switch (pcbmd.action) {
- case LIT: /* Literal. */
- case LITE: /* Literal. */
- /* Null string (except CDATA) is error: msg and treat as IMPLIED. */
- if (*lbuf<=2 && ADTYPE(attadn)!=ACHARS) {
- mderr(82, ADNAME(attadn), NULL);
- novalsw = 1;
- }
- case NAS: /* Name character string. */
- case NMT: /* Name character string. */
- case NUM: /* Number or number token string. */
- break;
- case EMD:
- mderr(109, ADNAME(attadn), NULL);
- return 1;
- default:
- mderr(110, ADNAME(attadn), NULL);
- return 1;
- }
- if (errsw) {
- --AN; ADN = (char)attadn-1; /* Ignore erroneous att. */
- return(0);
- }
- if (novalsw) return(0);
-
- /* PARAMETER 3y: Validate and store default value.
- */
- if (ADTYPE(attadn)==ACHARS) {
- /* No more checking for CDATA value. */
- ADNUM(attadn) = 0; /* CDATA is 0 tokens. */
- ADVAL(attadn) = strlsave(lbuf);/* Store default; save ptr. */
- ds.attdef += (ADLEN(attadn) = *lbuf);/* Length for capacity count.*/
- return 0;
- }
- /* Parse value and save token count (GROUP implies 1 token). */
- advalsv = rmalloc(*lbuf+1); /* Storage for tokenized value. */
- errcode = parseval(lbuf, (UNS)ADTYPE(attadn), advalsv);
- if (BITOFF(ADFLAGS(attadn), AGROUP)) ADNUM(attadn) = (char)tokencnt;
-
- /* If value was invalid, or was a group member that was not in the group,
- issue an appropriate message and set the error switch. */
- if (errcode)
- {sgmlerr((UNS)errcode, &pcbmd, ADNAME(attadn), lbuf+1); errsw = 1;}
- else if ( BITON(ADFLAGS(attadn), AGROUP)
- && !amemget(&al[attadn], (int)ADNUM(attadn), pvalptr) ) {
- sgmlerr(79, &pcbmd, ADNAME(attadn), pvalptr+1);
- errsw = 1;
- }
- /* For valid tokenized value, save it and update statistics. */
- if (!errsw) {
- ds.attdef += (ADLEN(attadn) = (char)vallen(ADTYPE(attadn)>=ATKNLIST,
- (int)ADNUM(attadn), (ADVAL(attadn) = pvalptr)));
- return 0;
- }
- /* If value was bad, free the value's storage and treat as
- IMPLIED or REQUIRED. */
- frem((UNIV)advalsv); /* Release storage for value. */
- ADVAL(attadn) = NULL; /* And make value NULL. */
- return 0;
- }
- /******************************************************************************/
- /* ANMTGRP: Parse a name or name token group, create attribute descriptors
- for its members, and add them to the attribute descriptor list.
- The parse either terminates or returns a good token, so no
- switch is needed.
- */
- int anmtgrp(
- struct parse *pcb, /* PCB for name or name token grp. */
- struct ad nt[], /* Buffer for creating name token list. */
- int grplim, /* Maximum size of list (plus 1). */
- UNCH *adn, /* Ptr to number of names or tokens in grp. */
- int adsz) /* Size of att def list. */
- {
- UNCH adtype = (char)(pcb==&pcbgrnt ? ANMTGRP:ANOTEGRP);/*Attribute type.*/
- int essv = es; /* Entity stack level when grp started. */
-
- *adn = 0; /* Group is empty to start. */
- while (parse(pcb)!=GRPE && (int)*adn<grplim) {
- switch (pcb->action) {
- case NAS_: /* Name or name token (depending on pcb). */
- case NMT_:
- parsenm(nt[*adn+1].adname, NAMECASE);
- if (antvget((int)(adsz+*adn), nt[*adn+1].adname))
- mderr(98, ntoa((int)*adn+1), nt[*adn+1].adname+1);
- nt[++*adn].adtype = adtype;
- nt[*adn].addef = NULL;
- continue;
-
- case EE_: /* Entity ended (correctly or incorrectly). */
- if (es<essv) {synerr(37, pcb); essv = es;}
- continue;
-
- case PIE_: /* PI entity reference (invalid). */
- entpisw = 0; /* Reset PI entity indicator. */
- synerr(59, pcb);
- continue;
-
- default:
- break;
- }
- break;
- }
- if (es!=essv) synerr(37, pcb);
- if ((int)*adn==grplim) return -1;
- else return (int)*adn; /* Return number of tokens. */
- }
- /******************************************************************************/
- /* MDDTDS: Process start of DOCTYPE declaration (through MSO).
- */
- VOID mddtds(
- UNCH *tbuf) /* Work area for tokenization[LITLEN+2]. */
- {
- struct fpi fpicb; /* Formal public identifier structure. */
- union etext etx; /* Ptr to entity text. */
- UNCH estore = ESD; /* Entity storage class. */
- int emdsw = 0; /* 1=end of declaration found; 0=not yet. */
-
- mdname = syn.k.doctype; /* Identify declaration for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es for checking entity nesting. */
- dtdrefsw = 0; /* No external DTD entity as yet. */
- /* PARAMETER 1: Document type name.
- */
- pcbmd.newstate = 0;
- parsemd(dtype, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: doc type name");
- #endif
- if (pcbmd.action!=NAS) {mderr(120, NULL, NULL); return;}
- subdcl = dtype+1; /* Subject of declaration for error msgs. */
-
- /* PARAMETER 2: External identifier keyword or MDS.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("2: extid or MDS");
- #endif
- switch (pcbmd.action) {
- case NAS:
- if (mdextid(tbuf, &fpicb, dtype, &estore, (PNE)0)==0) return;
- if ((etx.x = entgen(&fpicb))==0) return;
- dtdrefsw = 1; /* Signal external DTD entity. */
- break;
- case MDS:
- goto execute;
- default:
- mderr(128, NULL, NULL);
- return;
- }
- /* PARAMETER 3: MDS or end of declaration.
- */
- #ifndef FINAL
- if (dtrace) tracemd("3: MDS or EMD");
- #endif
- switch (pcbmd.action) {
- default: /* Treat as end of declaration. */
- mderr(126, NULL, NULL);
- case EMD:
- emdsw = 1;
- case MDS:
- break;
- }
- /* EXECUTE: Store entity definition if an external ID was specified.
- */
- execute:
- if (es!=mdessv) synerr(37, &pcbmd);
- propcb = &pcbmds; /* Prepare to parse doc type definition (MDS). */
- if (dtdrefsw) {
- if (!pass) { /* Store entity on first pass only. */
- /* TO DO: If concurrent DTD's supported, free existing
- etext for all but first DTD (or reuse it). */
- entdef(indtdent, estore, &etx);
- ++ds.ecbcnt; ds.ecbtext += entlen;
- }
- if (emdsw) {
- REPEATCC; /* Push back the MDC. */
- *FPOS = lex.d.msc; /* Simulate end of DTD subset. */
- REPEATCC; /* Back up to read MSC next. */
- delmscsw = 1; /* Insert MSC after referenced DTD. */
- }
- }
- indtdsw = 1; /* Allow "DTD only" parameters. */
- return;
- }
- /******************************************************************************/
- /* MDDTDE: Process DOCTYPE declaration end.
- */
- VOID mddtde(
- UNCH *tbuf) /* Work area for tokenization. */
- {
- mdessv = es; /* Save es for checking entity nesting. */
- propcb = &pcbpro; /* Restore normal prolog parse. */
- indtdsw = 0; /* Prohibit "DTD only" parameters. */
-
- mdname = syn.k.doctype; /* Identify declaration for messages. */
- subdcl = dtype+1; /* Subject of declaration for error msgs. */
- parmno = 0; /* No parameters as yet. */
- /* PARAMETER 4: End of declaration.
- */
- pcbmd.newstate = 0;
- parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- if (es!=mdessv) synerr(37, &pcbmd);
- }
- /******************************************************************************/
- /* MDELEM: Process ELEMENT declaration.
- */
- VOID mdelem(
- UNCH *tbuf) /* Work area for tokenization (tbuf). */
- {
- UNCH ranksuff[NAMELEN+2];/* Rank suffix. */
- UNCH comgibuf[NAMELEN+2];/* Buffer for complete GI (stem + rank suffix). */
- struct etd *nmgrp[GRPCNT+1]; /* Array of etds being defined. */
- UNS dctype = 0; /* Declared content type (from dctab). */
- UNCH fmin = 0; /* Minimization bit flags. */
- int i; /* Loop counter. */
- UNS u; /* Temporary variable. */
- struct etd **mexgrp, **pexgrp; /* Ptr to model exceptions array. */
- struct thdr *cmod, *cmodsv; /* Ptr to content model. */
- UNCH *etdgi; /* GI of current etd (when going through group).*/
-
- mdname = syn.k.element; /* Identify declaration for messages. */
- subdcl = NULL; /* No subject as yet. */
- parmno = 0; /* No parameters as yet. */
- mdessv = es; /* Save es level for entity nesting check. */
- ranksuff[0] = 0;
- mexgrp = pexgrp = 0;
- /* PARAMETER 1: Element name or a group of them.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1: element name or grp");
- #endif
- switch (pcbmd.action) {
- case NAS:
- nmgrp[0] = etddef(tbuf);
- nmgrp[1] = 0;
- break;
- case GRPS:
- parsegrp(nmgrp, &pcbgrnm);
- break;
- default:
- mderr(121, NULL, NULL);
- return;
- }
- /* Save first GI for trace and error messages. */
- subdcl = nmgrp[0]->etdgi+1;
-
- /* PARAMETER 1A: Rank suffix (optional).
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("1A: rank suffix");
- #endif
- switch (pcbmd.action) {
- case NUM:
- memcpy(ranksuff , tbuf, *tbuf );
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- default:
- break;
- }
- /* PARAMETER 2A: Start-tag minimization.
- */
- #ifndef FINAL
- if (dtrace) tracemd("2A: start min");
- #endif
- switch (pcbmd.action) {
- case NAS:
- if (*tbuf!=3 || *(tbuf+1)!='O') {mderr(129, tbuf+1, NULL); return;}
- SET(fmin, SMO);
- case CDR:
- break;
- default:
- mderr(129, tbuf+1, NULL);
- return;
- }
- /* PARAMETER 2B: End-tag minimization.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, 1);
- #ifndef FINAL
- if (dtrace) tracemd("2B: end min");
- #endif
- switch (pcbmd.action) {
- case NAS:
- if (*(tbuf+1)!='O') {mderr(129, tbuf+1, NULL); return;}
- SET(fmin, EMO);
- case CDR:
- break;
- default:
- mderr(129, tbuf+1, NULL);
- return;
- }
- /* PARAMETER 3: Declared content.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- #ifndef FINAL
- if (dtrace) tracemd("3: declared content");
- #endif
- switch (pcbmd.action) {
- case NAS:
- dctype = mapsrch(dctab, tbuf+1);
- if (!dctype) {mderr(24, tbuf+1, NULL); return;}
- /* Eliminate incompatibilities among parameters. */
- if (GET(fmin, SMO) && GET(dctype, MNONE+MCDATA+MRCDATA)) {
- mderr(58, NULL, NULL);
- RESET(fmin, SMO);
- }
- if (GET(dctype, MNONE) && BITOFF(fmin, EMO)) {
- mderr(87, NULL, NULL);
- SET(fmin, EMO);
- }
- /* If valid, process like a content model. */
- case GRPS:
- cmodsv = parsemod((int)(pcbmd.action==GRPS ? 0 : dctype));
- if (cmodsv==0) return;
- cmod = (struct thdr *)rmalloc(u = (cmodsv->tu.tnum+1) * THSZ);
- memcpy((UNIV)cmod , (UNIV)cmodsv, u );
- ds.modcnt += cmod->tu.tnum;
- #ifndef FINAL
- if (gtrace) tracemod(cmod);
- #endif
- break;
- default:
- mderr(130, NULL, NULL);
- return;
- }
- /* PARAMETERS 3A, 3B: Exceptions or end.
- */
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- if (BITOFF(cmod->ttype, MCDATA+MRCDATA+MNONE)) {
- /* PARAMETER 3A: Minus exceptions.
- */
- #ifndef FINAL
- if (dtrace) tracemd("3A: -grp");
- #endif
- switch (pcbmd.action) {
- case MGRP:
- mexgrp = copygrp((PETD *)tbuf,
- u = parsegrp((PETD *)tbuf, &pcbgrnm));
- ++ds.pmexgcnt; ds.pmexcnt += u-1;
- #ifndef FINAL
- if (gtrace) tracegrp(mexgrp);
- #endif
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- default:
- break;
- }
- /* PARAMETER 3B: Plus exceptions.
- */
- #ifndef FINAL
- if (dtrace) tracemd("3B: +grp");
- #endif
- switch (pcbmd.action) {
- case PGRP:
- pexgrp = copygrp((PETD *)tbuf,
- u = parsegrp((PETD *)tbuf, &pcbgrnm));
- ++ds.pmexgcnt; ds.pmexcnt += u-1;
- #ifndef FINAL
- if (gtrace) tracegrp(pexgrp);
- #endif
- parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
- default:
- break;
- }
- }
- /* PARAMETER 4: End of declaration.
- */
- #ifndef FINAL
- if (dtrace) tracemd(emd);
- #endif
- if (pcbmd.action!=EMD) mderr(126, NULL, NULL);
- if (es!=mdessv) synerr(37, &pcbmd);
-
- /* EXECUTE: Store the definition for each element name specified.
- */
- #ifndef FINAL
- if (gtrace) tracegrp(nmgrp);
- #endif
- for (i = -1; nmgrp[++i];) {
- etdgi = nmgrp[i]->etdgi;
- if (*ranksuff) {
- if ((comgibuf[0] = *etdgi + ranksuff[0]-2)>NAMELEN) {
- mderr(131, etdgi+1, ranksuff+1);
- continue;
- }
- memcpy(comgibuf+1, etdgi+1, *etdgi-1);
- memcpy(comgibuf+*etdgi-1 , ranksuff+1, *ranksuff-1 );
- etdcan(etdgi);
- nmgrp[i] = etddef(comgibuf);
- }
- if (nmgrp[i]->etdmod) {mderr(56, etdgi+1, NULL); continue;}
- etdset(nmgrp[i], fmin+ETDDCL, cmod, mexgrp, pexgrp, nmgrp[i]->etdsrm);
- ++ds.etdcnt;
- if (nmgrp[i]->adl) etdadl(nmgrp[i]); /* Check ETD conflicts. */
- #ifndef FINAL
- if (gtrace) traceetd(nmgrp[i]);
- #endif
- }
- }
- /******************************************************************************/