|
Packit |
9741aa |
#include "sgmlincl.h" /* #INCLUDE statements for SGML parser. */
|
|
Packit |
9741aa |
/* MDADL: Process ATTLIST declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID mdadl(tbuf)
|
|
Packit |
9741aa |
UNCH *tbuf; /* Work area for tokenization (tbuf). */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
int i; /* Loop counter; temporary variable. */
|
|
Packit |
9741aa |
int adlim; /* Number of unused ad slots in al. */
|
|
Packit |
9741aa |
struct ad *alperm = 0; /* Attribute definition list. */
|
|
Packit |
9741aa |
int stored = 0;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
mdname = key[KATTLIST]; /* Identify declaration for messages. */
|
|
Packit |
9741aa |
subdcl = 0; /* No subject as yet. */
|
|
Packit |
9741aa |
parmno = 0; /* No parameters as yet. */
|
|
Packit |
9741aa |
mdessv = es; /* Save es level for entity nesting check. */
|
|
Packit |
9741aa |
reqadn = noteadn = 0; /* No required attributes yet. */
|
|
Packit |
9741aa |
idadn = conradn = 0; /* No special atts yet.*/
|
|
Packit |
9741aa |
AN(al) = 0; /* Number of attributes defined. */
|
|
Packit |
9741aa |
ADN(al) = 0; /* Number of ad's in al (atts + name vals).*/
|
|
Packit |
9741aa |
/* PARAMETER 1: Element name or a group of them.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("1: element name or group");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
nmgrp[0] = etddef(tbuf);
|
|
Packit |
9741aa |
nmgrp[1] = 0;
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case GRPS:
|
|
Packit |
9741aa |
parsegrp(nmgrp, &pcbgrnm, tbuf);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case RNS: /* Reserved name started. */
|
|
Packit |
9741aa |
if (ustrcmp(tbuf+1, key[KNOTATION])) {
|
|
Packit |
9741aa |
mderr(118, tbuf+1, key[KNOTATION]);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
mdnadl(tbuf);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(121, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Save first GI for error msgs. */
|
|
Packit |
9741aa |
if (nmgrp[0])
|
|
Packit |
9741aa |
subdcl = nmgrp[0]->etdgi+1;
|
|
Packit |
9741aa |
/* PARAMETER 2: Attribute definition list.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("2: attribute list");
|
|
Packit |
9741aa |
if (pcbmd.action!=NAS) {
|
|
Packit |
9741aa |
mderr(120, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
while (pcbmd.action==NAS) {
|
|
Packit |
9741aa |
al[ADN(al)+1].adname = savenm(tbuf);
|
|
Packit |
9741aa |
if ((adlim = ATTCNT-((int)++ADN(al)))<0) {
|
|
Packit |
9741aa |
mderr(111, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
adlfree(al, 1);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
++AN(al);
|
|
Packit |
9741aa |
if (mdattdef(adlim, 0)) {
|
|
Packit |
9741aa |
adlfree(al, 1);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (AN(al)>0) { /* Save list only if 1 or more good atts. */
|
|
Packit |
9741aa |
if (reqadn) SET(ADLF(al), ADLREQ); /* Element must have start-tag. */
|
|
Packit |
9741aa |
if (noteadn) SET(ADLF(al), ADLNOTE); /* Element cannot be EMPTY. */
|
|
Packit |
9741aa |
if (conradn) SET(ADLF(al), ADLCONR); /* Element cannot be EMPTY. */
|
|
Packit |
9741aa |
alperm = (struct ad *)rmalloc((1+ADN(al))*ADSZ);
|
|
Packit |
9741aa |
memcpy((UNIV)alperm, (UNIV)al, (1+ADN(al))*ADSZ );
|
|
Packit |
9741aa |
ds.attcnt += AN(al); /* Number of attributes defined. */
|
|
Packit |
9741aa |
ds.attgcnt += ADN(al) - AN(al); /* Number of att grp members. */
|
|
Packit |
9741aa |
TRACEADL(alperm);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Clear attribute list for next declaration. */
|
|
Packit |
9741aa |
MEMZERO((UNIV)al, (1+ADN(al))*ADSZ);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 3: End of declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
/* Next pcb.action was set during attribute definition loop. */
|
|
Packit |
9741aa |
TRACEMD(emd);
|
|
Packit |
9741aa |
if (pcbmd.action!=EMD) {mderr(126, (UNCH *)0, (UNCH *)0); return;}
|
|
Packit |
9741aa |
if (es!=mdessv) synerr(37, &pcbmd);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* EXECUTE: Store the definition for each element name specified.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEGRP(nmgrp);
|
|
Packit |
9741aa |
for (i = 0; nmgrp[i]; i++) {
|
|
Packit |
9741aa |
if (nmgrp[i]->adl) { /* Error if an ADL exists. */
|
|
Packit |
9741aa |
mderr(112, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
nmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */
|
|
Packit |
9741aa |
stored = 1;
|
|
Packit |
9741aa |
if (alperm && nmgrp[i]->etdmod)
|
|
Packit |
9741aa |
etdadl(nmgrp[i]); /* Check for conflicts with ETD. */
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (!stored && alperm) {
|
|
Packit |
9741aa |
adlfree(alperm, 1);
|
|
Packit |
9741aa |
frem((UNIV)alperm);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* ETDADL: Check compatibility between ETD and ADL.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID etdadl(p)
|
|
Packit |
9741aa |
struct etd *p; /* Pointer to element type definition. */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
parmno = 0;
|
|
Packit |
9741aa |
/* Minimizable element cannot have required attribute. */
|
|
Packit |
9741aa |
if (GET(p->etdmin, SMO) && GET(p->adl[0].adflags, ADLREQ)) {
|
|
Packit |
9741aa |
mderr(40, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
RESET(p->etdmin, SMO);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Empty element cannot have NOTATION attribute.
|
|
Packit |
9741aa |
Attribute is not removed (too much trouble), but we trap
|
|
Packit |
9741aa |
attempts to specify it on the start-tag in adlval().
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
if (GET(p->etdmod->ttype, MNONE)) {
|
|
Packit |
9741aa |
if (GET(p->adl[0].adflags, ADLNOTE))
|
|
Packit |
9741aa |
mderr(83, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* Empty element cannot have CONREF attribute.
|
|
Packit |
9741aa |
Attribute is not removed because it just acts
|
|
Packit |
9741aa |
like IMPLIED anyway.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
if (GET(p->adl[0].adflags, ADLCONR))
|
|
Packit |
9741aa |
mderr(85, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* "-" should not be specified for the end-tag minimization if
|
|
Packit |
9741aa |
the element has a content reference attribute. */
|
|
Packit |
9741aa |
if (GET(p->adl[0].adflags, ADLCONR) && BITON(p->etdmin, EMM))
|
|
Packit |
9741aa |
mderr(153, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* MDNADL: Process ATTLIST declaration for notation.
|
|
Packit |
9741aa |
TO DO: Pass deftab and dvtab as parameters so
|
|
Packit |
9741aa |
that prohibited types can be handled by leaving
|
|
Packit |
9741aa |
them out of the tables.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID mdnadl(tbuf)
|
|
Packit |
9741aa |
UNCH *tbuf; /* Work area for tokenization (tbuf). */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
int i; /* Loop counter; temporary variable. */
|
|
Packit |
9741aa |
int adlim; /* Number of unused ad slots in al. */
|
|
Packit |
9741aa |
struct ad *alperm = 0; /* Attribute definition list. */
|
|
Packit |
9741aa |
int stored = 0;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 1: Notation name or a group of them.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("1: notation name or group");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
nnmgrp[0] = dcndef(tbuf);
|
|
Packit |
9741aa |
nnmgrp[1] = 0;
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case GRPS:
|
|
Packit |
9741aa |
parsngrp(nnmgrp, &pcbgrnm, tbuf);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(121, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
subdcl = nnmgrp[0]->ename+1; /* Save first name for error msgs. */
|
|
Packit |
9741aa |
/* PARAMETER 2: Attribute definition list.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("2: attribute list");
|
|
Packit |
9741aa |
if (pcbmd.action!=NAS) {
|
|
Packit |
9741aa |
mderr(120, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
while (pcbmd.action==NAS) {
|
|
Packit |
9741aa |
al[ADN(al)+1].adname = savenm(tbuf);
|
|
Packit |
9741aa |
if ((adlim = ATTCNT-((int)ADN(al)++))<0) {
|
|
Packit |
9741aa |
mderr(111, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
adlfree(al, 1);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
++AN(al);
|
|
Packit |
9741aa |
if (mdattdef(adlim, 1)) {
|
|
Packit |
9741aa |
adlfree(al, 1);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (AN(al)>0) { /* Save list only if 1 or more good atts. */
|
|
Packit |
9741aa |
alperm = (struct ad *)rmalloc((1+ADN(al))*ADSZ);
|
|
Packit |
9741aa |
memcpy((UNIV)alperm, (UNIV)al, (1+ADN(al))*ADSZ );
|
|
Packit |
9741aa |
ds.attcnt += AN(al); /* Number of attributes defined. */
|
|
Packit |
9741aa |
ds.attgcnt += ADN(al) - AN(al); /* Number of att grp members. */
|
|
Packit |
9741aa |
TRACEADL(alperm);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Clear attribute list for next declaration. */
|
|
Packit |
9741aa |
MEMZERO((UNIV)al, (1+ADN(al))*ADSZ);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 3: End of declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
/* Next pcb.action was set during attribute definition loop. */
|
|
Packit |
9741aa |
TRACEMD(emd);
|
|
Packit |
9741aa |
if (pcbmd.action!=EMD) {mderr(126, (UNCH *)0, (UNCH *)0); return;}
|
|
Packit |
9741aa |
if (es!=mdessv) synerr(37, &pcbmd);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* EXECUTE: Store the definition for each notation name specified.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACENGR(nnmgrp);
|
|
Packit |
9741aa |
for (i = 0; nnmgrp[i]; i++) {
|
|
Packit |
9741aa |
if (nnmgrp[i]->adl) { /* Error if an ADL exists. */
|
|
Packit |
9741aa |
mderr(112, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
nnmgrp[i]->adl = alperm; /* If virgin, store the adl ptr. */
|
|
Packit |
9741aa |
if (nnmgrp[i]->entsw)
|
|
Packit |
9741aa |
fixdatt(nnmgrp[i]);
|
|
Packit |
9741aa |
stored = 1;
|
|
Packit |
9741aa |
TRACEDCN(nnmgrp[i]);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (!stored && alperm) {
|
|
Packit |
9741aa |
adlfree(alperm, 1);
|
|
Packit |
9741aa |
frem((UNIV)alperm);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* Data attributes have been specified for notation p, but entities
|
|
Packit |
9741aa |
have already been declared with notation p. Fix up the definitions of
|
|
Packit |
9741aa |
all entities with notation p. Generate an error for any data
|
|
Packit |
9741aa |
attribute that was required. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
VOID fixdatt(p)
|
|
Packit |
9741aa |
struct dcncb *p;
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
int i;
|
|
Packit |
9741aa |
for (i = 0; i < ENTHASH; i++) {
|
|
Packit |
9741aa |
struct entity *ep;
|
|
Packit |
9741aa |
for (ep = etab[i]; ep; ep = ep->enext)
|
|
Packit |
9741aa |
if (ep->estore == ESN && ep->etx.n && ep->etx.n->nedcn == p) {
|
|
Packit |
9741aa |
int adn;
|
|
Packit |
9741aa |
initatt(p->adl);
|
|
Packit |
9741aa |
/* Don't use adlval because if there were required
|
|
Packit |
9741aa |
attributes the error message wouldn't say what
|
|
Packit |
9741aa |
entity was involved. */
|
|
Packit |
9741aa |
for (adn = 1; adn <= ADN(al); adn++) {
|
|
Packit |
9741aa |
if (GET(ADFLAGS(al,adn), AREQ)) {
|
|
Packit |
9741aa |
sgmlerr(218, &pcbstag, ADNAME(al,adn),
|
|
Packit |
9741aa |
ep->ename + 1);
|
|
Packit |
9741aa |
SET(ADFLAGS(al,adn), AINVALID);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (BITON(ADFLAGS(al, adn), AGROUP))
|
|
Packit |
9741aa |
adn += ADNUM(al, adn);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
storedatt(ep->etx.n);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* MDATTDEF: Process an individual attribute definition.
|
|
Packit |
9741aa |
The attribute name is parsed by the caller.
|
|
Packit |
9741aa |
Duplicate attributes are parsed, but removed from list.
|
|
Packit |
9741aa |
Returns 0 if successful, otherwise returns 1.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
int mdattdef(adlim, datt)
|
|
Packit |
9741aa |
int adlim; /* Remaining capacity of al (in tokens).*/
|
|
Packit |
9741aa |
int datt; /* Non-zero if a data attribute. */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
int deftype; /* Default value type: 0=not keyword. */
|
|
Packit |
9741aa |
int errsw = 0; /* 1=semantic error; ignore att. */
|
|
Packit |
9741aa |
int novalsw = 0; /* 1=semantic error; treat as IMPLIED. */
|
|
Packit |
9741aa |
int attadn = (int)ADN(al); /* Save ad number of this attribute. */
|
|
Packit |
9741aa |
struct parse *grppcb = NULL; /* PCB for name/token grp parse. */
|
|
Packit |
9741aa |
int errcode; /* Error type returned by PARSEVAL, ANMTGRP. */
|
|
Packit |
9741aa |
UNCH *advalsv; /* Save area for permanent value ptr. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 1: Attribute name (parsed by caller).
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD("1: attribute name");
|
|
Packit |
9741aa |
if (anmget((int)ADN(al)-1, al[attadn].adname)) {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(99, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
ADNUM(al,attadn) = ADFLAGS(al,attadn) = ADLEN(al,attadn) = 0;
|
|
Packit |
9741aa |
ADVAL(al,attadn) = 0; ADDATA(al,attadn).x = 0; ADTYPE(al,attadn) = ANMTGRP;
|
|
Packit |
9741aa |
/* PARAMETER 2: Declared value.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("2: declared value");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS: /* Keyword for value type. */
|
|
Packit |
9741aa |
switch (ADTYPE(al,attadn) = (UNCH)mapsrch(dvtab, lbuf+1)) {
|
|
Packit |
9741aa |
case 0:
|
|
Packit |
9741aa |
mderr(100, ADNAME(al,attadn), lbuf+1);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
case ANOTEGRP:
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(156, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
else if (!noteadn) noteadn = ADN(al);
|
|
Packit |
9741aa |
else {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(101, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
grppcb = &pcbgrnm; /* NOTATION requires name grp. */
|
|
Packit |
9741aa |
parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN);/* Get GRPO*/
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case AID:
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(144, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
else if (!idadn)
|
|
Packit |
9741aa |
idadn = attadn;
|
|
Packit |
9741aa |
else {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(102, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case AIDREF:
|
|
Packit |
9741aa |
case AIDREFS:
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(155, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case AENTITY:
|
|
Packit |
9741aa |
case AENTITYS:
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
mderr(154, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case GRPS:
|
|
Packit |
9741aa |
grppcb = &pcbgrnt; /* Normal grp is name token grp. */
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case EMD:
|
|
Packit |
9741aa |
mderr(103, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(104, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 2A: Name token group.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
if (grppcb != NULL) {
|
|
Packit |
9741aa |
TRACEMD("2A: name group");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case GRPS: /* Name token list. */
|
|
Packit |
9741aa |
SET(ADFLAGS(al,attadn), AGROUP);
|
|
Packit |
9741aa |
/* Call routine to parse group, create ad entries in adl. */
|
|
Packit |
9741aa |
errcode = anmtgrp(grppcb, al+attadn,
|
|
Packit |
9741aa |
(GRPCNT
|
|
Packit |
9741aa |
&al[attadn].adnum, ADN(al));
|
|
Packit |
9741aa |
if (errcode<=0) {
|
|
Packit |
9741aa |
if (adlim < GRPCNT)
|
|
Packit |
9741aa |
mderr(111, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
else
|
|
Packit |
9741aa |
mderr(105, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
ADN(al) += ADNUM(al,attadn); /* Add grp size to total ad cnt.*/
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(106, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 3: Default value keyword.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(lbuf, AVALCASE,
|
|
Packit |
9741aa |
(ADTYPE(al,attadn)==ACHARS) ? &pcblitr : &pcblitt, LITLEN);
|
|
Packit |
9741aa |
TRACEMD("3: default keyword");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case RNS: /* Keyword. */
|
|
Packit |
9741aa |
deftype = mapsrch(deftab, lbuf+1);
|
|
Packit |
9741aa |
switch (deftype) {
|
|
Packit |
9741aa |
case DFIXED: /* FIXED */
|
|
Packit |
9741aa |
SET(ADFLAGS(al,attadn), AFIXED);
|
|
Packit |
9741aa |
parsemd(lbuf, AVALCASE,
|
|
Packit |
9741aa |
(ADTYPE(al,attadn)==ACHARS) ? &pcblitr : &pcblitt,
|
|
Packit |
9741aa |
LITLEN); /* Real default. */
|
|
Packit |
9741aa |
goto parm3x; /* Go process specified value. */
|
|
Packit |
9741aa |
case DCURR: /* CURRENT: If ID, treat as IMPLIED. */
|
|
Packit |
9741aa |
if (ADTYPE(al,attadn)==AID) {
|
|
Packit |
9741aa |
mderr(80, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
mderr(157, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
SET(ADFLAGS(al,attadn), ACURRENT);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case DREQ: /* REQUIRED */
|
|
Packit |
9741aa |
SET(ADFLAGS(al,attadn), AREQ); ++reqadn;
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case DCONR: /* CONREF */
|
|
Packit |
9741aa |
if (ADTYPE(al,attadn)==AID) {
|
|
Packit |
9741aa |
mderr(107, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (datt) {
|
|
Packit |
9741aa |
mderr(158, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
SET(ADFLAGS(al,attadn), ACONREF); conradn = 1;
|
|
Packit |
9741aa |
case DNULL: /* IMPLIED */
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default: /* Unknown keyword is an error. */
|
|
Packit |
9741aa |
mderr(108, ADNAME(al,attadn), lbuf+1);
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (errsw) {
|
|
Packit |
9741aa |
/* Ignore erroneous att. */
|
|
Packit |
9741aa |
adlfree(al, attadn);
|
|
Packit |
9741aa |
--AN(al);
|
|
Packit |
9741aa |
ADN(al) = (UNCH)attadn-1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
return(0);
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 3x: Default value (non-keyword).
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parm3x:
|
|
Packit |
9741aa |
TRACEMD("3x: default (non-keyword)");
|
|
Packit |
9741aa |
if (ADTYPE(al,attadn)==AID) { /* If ID, treat as IMPLIED. */
|
|
Packit |
9741aa |
mderr(81, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
novalsw = 1; /* Keep parsing to keep things straight. */
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case LIT: /* Literal. */
|
|
Packit |
9741aa |
case LITE: /* Literal. */
|
|
Packit |
9741aa |
/* Null string (except CDATA) is error: msg and treat as IMPLIED. */
|
|
Packit |
9741aa |
if (*lbuf == '\0' && ADTYPE(al,attadn)!=ACHARS) {
|
|
Packit |
9741aa |
mderr(82, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
novalsw = 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case NAS: /* Name character string. */
|
|
Packit |
9741aa |
case NMT: /* Name character string. */
|
|
Packit |
9741aa |
case NUM: /* Number or number token string. */
|
|
Packit |
9741aa |
/* The name won't have a length byte because AVALCASE was specified. */
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case CDR:
|
|
Packit |
9741aa |
parsetkn(lbuf, NMC, LITLEN);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case EMD:
|
|
Packit |
9741aa |
mderr(109, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(110, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (errsw) {
|
|
Packit |
9741aa |
/* Ignore erroneous att. */
|
|
Packit |
9741aa |
adlfree(al, attadn);
|
|
Packit |
9741aa |
--AN(al);
|
|
Packit |
9741aa |
ADN(al) = (UNCH)attadn-1;
|
|
Packit |
9741aa |
return(0);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (novalsw) return(0);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 3y: Validate and store default value.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
if (ADTYPE(al,attadn)==ACHARS) {
|
|
Packit |
9741aa |
UNS len = vallen(ACHARS, 0, lbuf);
|
|
Packit |
9741aa |
if (len > LITLEN) {
|
|
Packit |
9741aa |
/* Treat as implied. */
|
|
Packit |
9741aa |
sgmlerr(224, &pcbmd, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
return 0;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* No more checking for CDATA value. */
|
|
Packit |
9741aa |
ADNUM(al,attadn) = 0; /* CDATA is 0 tokens. */
|
|
Packit |
9741aa |
ADVAL(al,attadn) = savestr(lbuf);/* Store default; save ptr. */
|
|
Packit |
9741aa |
ADLEN(al,attadn) = len;
|
|
Packit |
9741aa |
ds.attdef += len;
|
|
Packit |
9741aa |
return 0;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Parse value and save token count (GROUP implies 1 token). */
|
|
Packit |
9741aa |
advalsv = (UNCH *)rmalloc(ustrlen(lbuf)+2); /* Storage for tokenized value. */
|
|
Packit |
9741aa |
errcode = parseval(lbuf, (UNS)ADTYPE(al,attadn), advalsv);
|
|
Packit |
9741aa |
if (BITOFF(ADFLAGS(al,attadn), AGROUP)) ADNUM(al,attadn) = (UNCH)tokencnt;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* If value was invalid, or was a group member that was not in the group,
|
|
Packit |
9741aa |
issue an appropriate message and set the error switch. */
|
|
Packit |
9741aa |
if (errcode)
|
|
Packit |
9741aa |
{sgmlerr((UNS)errcode, &pcbmd, ADNAME(al,attadn), lbuf); errsw = 1;}
|
|
Packit |
9741aa |
else if ( BITON(ADFLAGS(al,attadn), AGROUP)
|
|
Packit |
9741aa |
&& !amemget(&al[attadn], (int)ADNUM(al,attadn), advalsv) ) {
|
|
Packit |
9741aa |
sgmlerr(79, &pcbmd, ADNAME(al,attadn), advalsv+1);
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
ADLEN(al,attadn) = vallen(ADTYPE(al,attadn), ADNUM(al,attadn), advalsv);
|
|
Packit |
9741aa |
if (ADLEN(al,attadn) > LITLEN) {
|
|
Packit |
9741aa |
sgmlerr(224, &pcbmd, ADNAME(al,attadn), (UNCH *)0);
|
|
Packit |
9741aa |
ADLEN(al,attadn) = 0;
|
|
Packit |
9741aa |
errsw = 1;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* For valid tokenized value, save it and update statistics. */
|
|
Packit |
9741aa |
if (!errsw) {
|
|
Packit |
9741aa |
ADVAL(al,attadn) = advalsv;
|
|
Packit |
9741aa |
ds.attdef += ADLEN(al,attadn);
|
|
Packit |
9741aa |
return 0;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* If value was bad, free the value's storage and treat as
|
|
Packit |
9741aa |
IMPLIED or REQUIRED. */
|
|
Packit |
9741aa |
frem((UNIV)advalsv); /* Release storage for value. */
|
|
Packit |
9741aa |
ADVAL(al,attadn) = NULL; /* And make value NULL. */
|
|
Packit |
9741aa |
return 0;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* ANMTGRP: Parse a name or name token group, create attribute descriptors
|
|
Packit |
9741aa |
for its members, and add them to the attribute descriptor list.
|
|
Packit |
9741aa |
The parse either terminates or returns a good token, so no
|
|
Packit |
9741aa |
switch is needed.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
int anmtgrp(pcb, nt, grplim, adn, adsz)
|
|
Packit |
9741aa |
struct parse *pcb; /* PCB for name or name token grp. */
|
|
Packit |
9741aa |
struct ad nt[]; /* Buffer for creating name token list. */
|
|
Packit |
9741aa |
int grplim; /* Maximum size of list (plus 1). */
|
|
Packit |
9741aa |
UNS *adn; /* Ptr to number of names or tokens in grp. */
|
|
Packit |
9741aa |
int adsz; /* Size of att def list. */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
UNCH adtype = (UNCH)(pcb==&pcbgrnt ? ANMTGRP:ANOTEGRP);/*Attribute type.*/
|
|
Packit |
9741aa |
int essv = es; /* Entity stack level when grp started. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
*adn = 0; /* Group is empty to start. */
|
|
Packit |
9741aa |
while (parse(pcb)!=GRPE && *adn
|
|
Packit |
9741aa |
switch (pcb->action) {
|
|
Packit |
9741aa |
case NAS_: /* Name or name token (depending on pcb). */
|
|
Packit |
9741aa |
case NMT_:
|
|
Packit |
9741aa |
parsenm(lbuf, NAMECASE);
|
|
Packit |
9741aa |
nt[*adn+1].adname = savenm(lbuf);
|
|
Packit |
9741aa |
if (antvget((int)(adsz+*adn), nt[*adn+1].adname, (UNCH **)0))
|
|
Packit |
9741aa |
mderr(98, ntoa((int)*adn+1), nt[*adn+1].adname+1);
|
|
Packit |
9741aa |
nt[++*adn].adtype = adtype;
|
|
Packit |
9741aa |
nt[*adn].addef = NULL;
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
case EE_: /* Entity ended (correctly or incorrectly). */
|
|
Packit |
9741aa |
if (es
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
case PIE_: /* PI entity reference (invalid). */
|
|
Packit |
9741aa |
entpisw = 0; /* Reset PI entity indicator. */
|
|
Packit |
9741aa |
synerr(59, pcb);
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (es!=essv) synerr(37, pcb);
|
|
Packit |
9741aa |
if (*adn==grplim) return -1;
|
|
Packit |
9741aa |
else return *adn; /* Return number of tokens. */
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* MDDTDS: Process start of DOCTYPE declaration (through MSO).
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID mddtds(tbuf)
|
|
Packit |
9741aa |
UNCH *tbuf; /* Work area for tokenization[LITLEN+2]. */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
struct fpi fpicb; /* Formal public identifier structure. */
|
|
Packit |
9741aa |
union etext etx; /* Ptr to entity text. */
|
|
Packit |
9741aa |
UNCH estore = ESD; /* Entity storage class. */
|
|
Packit |
9741aa |
int emdsw = 0; /* 1=end of declaration found; 0=not yet. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
mdname = key[KDOCTYPE]; /* Identify declaration for messages. */
|
|
Packit |
9741aa |
subdcl = NULL; /* No subject as yet. */
|
|
Packit |
9741aa |
parmno = 0; /* No parameters as yet. */
|
|
Packit |
9741aa |
mdessv = es; /* Save es for checking entity nesting. */
|
|
Packit |
9741aa |
dtdrefsw = 0; /* No external DTD entity as yet. */
|
|
Packit |
9741aa |
/* PARAMETER 1: Document type name.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
pcbmd.newstate = 0;
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("1: doc type name");
|
|
Packit |
9741aa |
if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); return;}
|
|
Packit |
9741aa |
dtype = savenm(tbuf);
|
|
Packit |
9741aa |
subdcl = dtype+1; /* Subject of declaration for error msgs. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 2: External identifier keyword or MDS.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
pcbmd.newstate = 0;
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("2: extid or MDS");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
if (mdextid(tbuf, &fpicb, dtype+1, &estore, (PNE)0)==0) return;
|
|
Packit |
9741aa |
if ((etx.x = entgen(&fpicb))==0)
|
|
Packit |
9741aa |
mderr(146, dtype+1, (UNCH *)0);
|
|
Packit |
9741aa |
else
|
|
Packit |
9741aa |
dtdrefsw = 1; /* Signal external DTD entity. */
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case MDS:
|
|
Packit |
9741aa |
goto execute;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(128, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 3: MDS or end of declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD("3: MDS or EMD");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
default: /* Treat as end of declaration. */
|
|
Packit |
9741aa |
mderr(126, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
case EMD:
|
|
Packit |
9741aa |
emdsw = 1;
|
|
Packit |
9741aa |
case MDS:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* EXECUTE: Store entity definition if an external ID was specified.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
execute:
|
|
Packit |
9741aa |
if (es!=mdessv) synerr(37, &pcbmd);
|
|
Packit |
9741aa |
propcb = &pcbmds; /* Prepare to parse doc type definition (MDS). */
|
|
Packit |
9741aa |
if (dtdrefsw) {
|
|
Packit |
9741aa |
/* TO DO: If concurrent DTD's supported, free existing
|
|
Packit |
9741aa |
etext for all but first DTD (or reuse it). */
|
|
Packit |
9741aa |
entdef(indtdent, estore, &etx;;
|
|
Packit |
9741aa |
++ds.ecbcnt; ds.ecbtext += entlen;
|
|
Packit |
9741aa |
if (emdsw) {
|
|
Packit |
9741aa |
REPEATCC; /* Push back the MDC. */
|
|
Packit |
9741aa |
*FPOS = lex.d.msc; /* Simulate end of DTD subset. */
|
|
Packit |
9741aa |
REPEATCC; /* Back up to read MSC next. */
|
|
Packit |
9741aa |
delmscsw = 1; /* Insert MSC after referenced DTD. */
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
indtdsw = 1; /* Allow "DTD only" parameters. */
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* MDDTDE: Process DOCTYPE declaration end.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID mddtde(tbuf)
|
|
Packit |
9741aa |
UNCH *tbuf; /* Work area for tokenization. */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
mdessv = es; /* Save es for checking entity nesting. */
|
|
Packit |
9741aa |
propcb = &pcbpro; /* Restore normal prolog parse. */
|
|
Packit |
9741aa |
indtdsw = 0; /* Prohibit "DTD only" parameters. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
mdname = key[KDOCTYPE]; /* Identify declaration for messages. */
|
|
Packit |
9741aa |
subdcl = dtype+1; /* Subject of declaration for error msgs. */
|
|
Packit |
9741aa |
parmno = 0; /* No parameters as yet. */
|
|
Packit |
9741aa |
/* PARAMETER 4: End of declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
pcbmd.newstate = 0;
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, LITLEN);
|
|
Packit |
9741aa |
TRACEMD(emd);
|
|
Packit |
9741aa |
if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
if (es!=mdessv) synerr(37, &pcbmd);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* MDELEM: Process ELEMENT declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
VOID mdelem(tbuf)
|
|
Packit |
9741aa |
UNCH *tbuf; /* Work area for tokenization (tbuf). */
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
UNCH *ranksuff = lbuf; /* Rank suffix. */
|
|
Packit |
9741aa |
UNS dctype = 0; /* Declared content type (from dctab). */
|
|
Packit |
9741aa |
UNCH fmin = 0; /* Minimization bit flags. */
|
|
Packit |
9741aa |
int i; /* Loop counter. */
|
|
Packit |
9741aa |
UNS u; /* Temporary variable. */
|
|
Packit |
9741aa |
struct etd **mexgrp, **pexgrp; /* Ptr to model exceptions array. */
|
|
Packit |
9741aa |
struct thdr *cmod, *cmodsv; /* Ptr to content model. */
|
|
Packit |
9741aa |
UNCH *etdgi; /* GI of current etd (when going through group).*/
|
|
Packit |
9741aa |
int minomitted = 0; /* Tag minimization parameters omitted. */
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
mdname = key[KELEMENT]; /* Identify declaration for messages. */
|
|
Packit |
9741aa |
subdcl = NULL; /* No subject as yet. */
|
|
Packit |
9741aa |
parmno = 0; /* No parameters as yet. */
|
|
Packit |
9741aa |
mdessv = es; /* Save es level for entity nesting check. */
|
|
Packit |
9741aa |
ranksuff[0] = 0;
|
|
Packit |
9741aa |
mexgrp = pexgrp = 0;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 1: Element name or a group of them.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("1: element name or grp");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
nmgrp[0] = etddef(tbuf);
|
|
Packit |
9741aa |
nmgrp[1] = 0;
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case GRPS:
|
|
Packit |
9741aa |
parsegrp(nmgrp, &pcbgrnm, tbuf);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(121, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Save first GI for trace and error messages. */
|
|
Packit |
9741aa |
if (nmgrp[0])
|
|
Packit |
9741aa |
subdcl = nmgrp[0]->etdgi+1;
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* PARAMETER 1A: Rank suffix (optional).
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("1A: rank suffix");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NUM:
|
|
Packit |
9741aa |
ustrcpy(ranksuff, tbuf);
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 2A: Start-tag minimization.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD("2A: start min");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case CDR:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
if (!ustrcmp(tbuf+1, key[KO])) {
|
|
Packit |
9741aa |
if (OMITTAG==YES) SET(fmin, SMO);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* fall through */
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
if (OMITTAG==NO) {minomitted=1; break;}
|
|
Packit |
9741aa |
mderr(129, tbuf+1, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* Must omit omitted end-tag minimization, if omitted
|
|
Packit |
9741aa |
start-tag minimization was omitted (because OMITTAG == NO). */
|
|
Packit |
9741aa |
if (!minomitted) {
|
|
Packit |
9741aa |
/* PARAMETER 2B: End-tag minimization.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
TRACEMD("2B: end min");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
if (ustrcmp(tbuf+1, key[KO])) {mderr(129, tbuf+1, (UNCH *)0); return;}
|
|
Packit |
9741aa |
if (OMITTAG==YES) SET(fmin, EMO);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
case CDR:
|
|
Packit |
9741aa |
SET(fmin, EMM);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(129, tbuf+1, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 3: Declared content.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
TRACEMD("3: declared content");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case NAS:
|
|
Packit |
9741aa |
dctype = mapsrch(dctab, tbuf+1);
|
|
Packit |
9741aa |
if (!dctype) {mderr(24, tbuf+1, (UNCH *)0); return;}
|
|
Packit |
9741aa |
/* Eliminate incompatibilities among parameters. */
|
|
Packit |
9741aa |
if (GET(fmin, SMO) && GET(dctype, MNONE+MCDATA+MRCDATA)) {
|
|
Packit |
9741aa |
mderr(58, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
RESET(fmin, SMO);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (GET(dctype, MNONE) && BITON(fmin, EMM)) {
|
|
Packit |
9741aa |
mderr(87, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
SET(fmin, EMO);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* If valid, process like a content model. */
|
|
Packit |
9741aa |
case GRPS:
|
|
Packit |
9741aa |
cmodsv = parsemod((int)(pcbmd.action==GRPS ? 0 : dctype));
|
|
Packit |
9741aa |
if (cmodsv==0) return;
|
|
Packit |
9741aa |
u = (dctype ? 1 : cmodsv->tu.tnum+2) * THSZ;
|
|
Packit |
9741aa |
cmod = (struct thdr *)rmalloc(u);
|
|
Packit |
9741aa |
memcpy((UNIV)cmod , (UNIV)cmodsv, u );
|
|
Packit |
9741aa |
ds.modcnt += cmod->tu.tnum;
|
|
Packit |
9741aa |
TRACEMOD(cmod);
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
mderr(130, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
return;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETERS 3A, 3B: Exceptions or end.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
if (BITOFF(cmod->ttype, MCDATA+MRCDATA+MNONE)) {
|
|
Packit |
9741aa |
/* PARAMETER 3A: Minus exceptions.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD("3A: -grp");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case MGRP:
|
|
Packit |
9741aa |
/* We cheat and use nnmgrp for this. */
|
|
Packit |
9741aa |
mexgrp = copygrp((PETD *)nnmgrp,
|
|
Packit |
9741aa |
u = parsegrp((PETD *)nnmgrp, &pcbgrnm, tbuf));
|
|
Packit |
9741aa |
++ds.pmexgcnt; ds.pmexcnt += u-1;
|
|
Packit |
9741aa |
TRACEGRP(mexgrp);
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 3B: Plus exceptions.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD("3B: +grp");
|
|
Packit |
9741aa |
switch (pcbmd.action) {
|
|
Packit |
9741aa |
case PGRP:
|
|
Packit |
9741aa |
pexgrp = copygrp((PETD *)nnmgrp,
|
|
Packit |
9741aa |
u = parsegrp((PETD *)nnmgrp, &pcbgrnm, tbuf));
|
|
Packit |
9741aa |
++ds.pmexgcnt; ds.pmexcnt += u-1;
|
|
Packit |
9741aa |
TRACEGRP(pexgrp);
|
|
Packit |
9741aa |
parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN);
|
|
Packit |
9741aa |
default:
|
|
Packit |
9741aa |
break;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
/* PARAMETER 4: End of declaration.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEMD(emd);
|
|
Packit |
9741aa |
if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0);
|
|
Packit |
9741aa |
if (es!=mdessv) synerr(37, &pcbmd);
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/* EXECUTE: Store the definition for each element name specified.
|
|
Packit |
9741aa |
*/
|
|
Packit |
9741aa |
TRACEGRP(nmgrp);
|
|
Packit |
9741aa |
for (i = -1; nmgrp[++i];) {
|
|
Packit |
9741aa |
etdgi = nmgrp[i]->etdgi;
|
|
Packit |
9741aa |
if (*ranksuff) {
|
|
Packit |
9741aa |
if ((tbuf[0] = *etdgi + ustrlen(ranksuff)) - 2 > NAMELEN) {
|
|
Packit |
9741aa |
mderr(131, etdgi+1, ranksuff);
|
|
Packit |
9741aa |
continue;
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
memcpy(tbuf+1, etdgi+1, *etdgi-1);
|
|
Packit |
9741aa |
ustrcpy(tbuf+*etdgi-1, ranksuff);
|
|
Packit |
9741aa |
etdcan(etdgi);
|
|
Packit |
9741aa |
nmgrp[i] = etddef(tbuf);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
if (nmgrp[i]->etdmod) {mderr(56, etdgi+1, (UNCH *)0); continue;}
|
|
Packit |
9741aa |
etdset(nmgrp[i], fmin+ETDDCL, cmod, mexgrp, pexgrp, nmgrp[i]->etdsrm);
|
|
Packit |
9741aa |
++ds.etdcnt;
|
|
Packit |
9741aa |
if (nmgrp[i]->adl) etdadl(nmgrp[i]); /* Check ETD conflicts. */
|
|
Packit |
9741aa |
TRACEETD(nmgrp[i]);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
VOID adlfree(al, aln)
|
|
Packit |
9741aa |
struct ad *al;
|
|
Packit |
9741aa |
int aln;
|
|
Packit |
9741aa |
{
|
|
Packit |
9741aa |
for (; aln <= ADN(al); aln++) {
|
|
Packit |
9741aa |
frem((UNIV)al[aln].adname);
|
|
Packit |
9741aa |
if (ADVAL(al, aln))
|
|
Packit |
9741aa |
frem((UNIV)ADVAL(al, aln));
|
|
Packit |
9741aa |
if (BITON(ADFLAGS(al, aln), AGROUP)) {
|
|
Packit |
9741aa |
int i;
|
|
Packit |
9741aa |
for (i = 0; i < ADNUM(al, aln); i++)
|
|
Packit |
9741aa |
frem((UNIV)al[aln + i + 1].adname);
|
|
Packit |
9741aa |
aln += ADNUM(al, aln);
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
}
|
|
Packit |
9741aa |
|
|
Packit |
9741aa |
/*
|
|
Packit |
9741aa |
Local Variables:
|
|
Packit |
9741aa |
c-indent-level: 5
|
|
Packit |
9741aa |
c-continued-statement-offset: 5
|
|
Packit |
9741aa |
c-brace-offset: -5
|
|
Packit |
9741aa |
c-argdecl-indent: 0
|
|
Packit |
9741aa |
c-label-offset: -5
|
|
Packit |
9741aa |
comment-column: 30
|
|
Packit |
9741aa |
End:
|
|
Packit |
9741aa |
*/
|