Blame sgmls-1.1/md1.c

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
*/