📄 md2.c
字号:
/* The public text class in a notation identifier must be NOTATION. */ if (f->fpistore == ESK - ESFM + 1 && f->fpic != FPINOT) return 10; if (*p=='-' && p[1] == '/' && p[2] == '/') { /* If text is unavailable public text.*/ f->fpitt = *p; /* Save text type. */ p += 3; } else f->fpitt = '+'; /* Indicate available public text. */ if ((q = pubfield(p, l, '/', &len))==0) /* Find end of text description. */ return 6; f->fpitl = len; /* Save text description length. */ f->fpit = p - f->fpipubis; /* Save ptr to description.*/ p = pubfield(q, l, '/', &len); /* Bound language field. */ if (f->fpic != FPICHARS) { int i; /* Language must be all upper-case letters. */ /* The standard only says that it *should* be two letters, so don't enforce that. */ /* Language must be a name, which means it can't be empty. */ if (len == 0) return 7; for (i = 0; i < len; i++) { /* Don't assume ASCII. */ if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", q[i])) return 7; } } f->fpill = len; f->fpil = q - f->fpipubis; if (p!=0) { /* If there is a version field: */ if (f->fpic<FPICMINV) /* Error if class prohibits versions. */ return 8; if ((pubfield(p, l, '/', &len))!=0) /* Bound version field. */ return 9; /* Error if yet another field. */ f->fpivl = len; /* Save version length. */ f->fpiv = p - f->fpipubis; /* Save ptr (in pubis) to version. */ } else if (f->fpic>=FPICMINV) f->fpiversw = 1;/* No version: get the best. */ return(0);}/* PUBFIELD: Returns ptr to next field, or NULL if ID has ended.*/#ifdef USE_PROTOTYPESUNCH *pubfield(UNCH *p, UNCH *l, UNCH d, UNS *lenp)#elseUNCH *pubfield(p, l, d, lenp)UNCH *p; /* Public identifier field (no length or EOS). */UNCH *l; /* Pointer to EOS of public identifier. */UNCH d; /* Field delimiter: ' ' or '/'. */UNS *lenp; /* Gets field length */#endif{ UNCH *psv = p+1; /* Save starting value of p. */ while (p<l) { if (*p++==d) { /* Test for delimiter character. */ *lenp = p - psv; /* Save field length (no len or EOS). */ if (d=='/' && *p++!=d) /* Solidus requires a second one. */ continue; return(p); /* Return ptr to next field. */ } } *lenp = p - --psv; /* Save field length (no len or EOS). */ return NULL;}/* MDMS: Process marked section start. If already in special parse, bump the level counters and return without parsing the declaration.*/struct parse *mdms(tbuf, pcb)UNCH *tbuf; /* Work area for tokenization [NAMELEN+2]. */struct parse *pcb; /* Parse control block for this parse. */{ int key; /* Index of keyword in mslist. */ int ptype; /* Parameter token type. */ int pcbcode = 0; /* Parse code: 0=same; 2-4 per defines. */ if (++mslevel>TAGLVL) { --mslevel; sgmlerr(27, (struct parse *)0, ntoa(TAGLVL), (UNCH *)0); } /* If already in IGNORE mode, return without parsing parameters. */ if (msplevel) {++msplevel; return(pcb);} parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ pcbmd.newstate = pcbmdtk; /* First separator is optional. */ /* PARAMETERS: TEMP, RCDATA, CDATA, IGNORE, INCLUDE, or MDS. */ while ((ptype = parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN))==NAS){ if ((key = mapsrch(mstab, tbuf+1))==0) { sgmlerr(64, (struct parse *)0, ntoa(parmno), tbuf+1); continue; } if (key==MSTEMP) continue; /* TEMP: for documentation. */ msplevel = 1; /* Special parse required. */ if (key>pcbcode) pcbcode = key; /* Update if higher priority. */ } if (ptype!=MDS) { NEWCC; /* Syntax error did REPEATCC. */ sgmlerr(97, (struct parse *)0, lex.m.dso, (UNCH *)0); REPEATCC; /* 1st char of marked section. */ } if (es!=mdessv) synerr(37, pcb); TRACEMS(1, pcbcode, mslevel, msplevel); if (pcbcode==MSIGNORE) pcb = &pcbmsi; else if (pcbcode) { pcb = pcbcode==MSCDATA ? &pcbmsc : (rcessv = es, &pcbmsrc); } return(pcb); /* Tell caller whether to change the parse. */}/* MDMSE: Process marked section end. Issue an error if no marked section had started.*/int mdmse(){ int retcode = 0; /* Return code: 0=same parse; 1=cancel special. */ if (mslevel) --mslevel; else sgmlerr(26, (struct parse *)0, (UNCH *)0, (UNCH *)0); if (msplevel) if (--msplevel==0) retcode = 1; TRACEMS(0, retcode, mslevel, msplevel); return retcode;}/* MDNOT: Process NOTATION declaration.*/VOID mdnot(tbuf)UNCH *tbuf; /* Work area for tokenization[LITLEN+2]. */{ struct fpi fpicb; /* Formal public identifier structure. */ PDCB dcb; /* Ptr to notation entity in dcntab. */ UNCH estore = ESK; /* Entity storage class. */ mdname = key[KNOTATION]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ /* PARAMETER 1: Notation name. */ pcbmd.newstate = 0; parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: name"); if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); return;} subdcl = lbuf+1; /* Save notation name for error msgs. */ /* PARAMETER 2: External identifier keyword. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: extid"); if (pcbmd.action!=NAS) {mderr(29, (UNCH *)0, (UNCH *)0); return;} if (mdextid(tbuf, &fpicb, lbuf+1, &estore, (PNE)0)==0) return; /* PARAMETER 3: End of declaration. Token was parsed by MDEXTID. */ TRACEMD(emd); if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); if (es!=mdessv) synerr(37, &pcbmd); /* EXECUTE: Store notation name. */ if ((dcb = dcnfind(lbuf)) != 0 && dcb->defined) { mderr(56, lbuf+1, (UNCH *)0); return; } /* else */ dcb = dcndef(lbuf); dcb->defined = 1; dcb->sysid = fpicb.fpisysis ? savestr(fpicb.fpisysis) : 0; dcb->pubid = fpicb.fpipubis ? savestr(fpicb.fpipubis) : 0; ++ds.dcncnt; ds.dcntext += entlen; TRACEDCN(dcb); return;}/* DCNDEF: Define a notation and return its DCNCB. If caller does not care if it already exists, he should specify NULL for the notation text so we don't clobber the existing text (if any).*/struct dcncb *dcndef(nname)UNCH *nname; /* Notation name (with length and EOS). */{ return((PDCB)hin((THASH)dcntab, nname, 0, DCBSZ));}/* DCNFIND: If a notation was declared, return its DCNCB. Return NULL if it is not defined.*/struct dcncb *dcnfind(nname)UNCH *nname; /* Notation name (with length and EOS). */{ return((PDCB)hfind((THASH)dcntab, nname, 0));}#define SRM(i) (srhptr->srhsrm[i]) /* Current entry in SHORTREF map. *//* MDSRMDEF: Process short reference mapping declaration.*/VOID mdsrmdef(tbuf)UNCH *tbuf; /* Work area for tokenization[LITLEN+2]. */{ struct entity *entcb; /* Ptr to defined entity. */ PSRH srhptr; /* Ptr to short reference map hdr (in srhtab).*/ int srn; /* Short reference delimiter number in srdeltab.*/ int mapused = 0; /* Has map already been used? */ mdname = key[KSHORTREF]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ if (!sd.shortref) {mderr(198, (UNCH *)0, (UNCH *)0); return;} mdessv = es; /* Save es for checking entity nesting. */ /* PARAMETER 1: SHORTREF map name. */ pcbmd.newstate = 0; parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: map nm"); if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); return;} if ((srhptr = srhfind(tbuf))!=0) { mapused = 1; /* Error if map was declared (not just used). */ if (SRM(0)) {mderr(56, tbuf+1, (UNCH *)0); return;} } else srhptr = srhdef(tbuf); /* Create map with SRs mapped to NULL.*/ SRM(0) = (PECB)srhptr; /* Indicate map was actually declared.*/ subdcl = srhptr->ename+1; /* Save map name for error msgs. */ while (parsemd(tbuf, NAMECASE, &pcblitp, SRMAXLEN) == LIT || pcbmd.action==LITE ) { /* PARAMETER 2: Delimiter string. */ TRACEMD("2: SR string"); if ((srn = mapsrch(lex.s.dtb, tbuf))==0) { mderr(124, tbuf, (UNCH *)0); goto cleanup; } /* PARAMETER 3: Entity name. */ parsemd(tbuf, ENTCASE, &pcblitp, NAMELEN); TRACEMD("3: entity"); if (pcbmd.action!=NAS) {mderr(120, (UNCH *)0, (UNCH *)0); goto cleanup;} if ((entcb = entfind(tbuf))==0) { union etext etx; etx.x = 0; entcb = entdef(tbuf, '\0', &etx); } if (SRM(srn)) { mderr(56, (srn<lex.s.prtmin ? (UNCH *)lex.s.pdtb[srn] : lex.s.dtb[srn].mapnm), (UNCH *)0); continue; } SRM(srn) = entcb; if (srn>=lex.s.fce && srn!=lex.s.hyp && srn!=lex.s.hyp2 && srn!=lex.s.lbr && srn!=lex.s.rbr) lexcnm[*lex.s.dtb[srn].mapnm] = lex.l.fce; else if (srn==lex.s.spc) lexcnm[' '] = lex.l.spcr; } /* PARAMETER 4: End of declaration. */ TRACEMD(emd); if (parmno==2) {mderr((UNS)(pcbmd.action==EMD ? 28:123), (UNCH *)0, (UNCH *)0); goto cleanup;} if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); if (es!=mdessv) synerr(37, &pcbmd); ++ds.srcnt; TRACESRM("SHORTREF", srhptr->srhsrm, (UNCH *)0); return; cleanup: /* Don't free the map if the map was in use (because of a USEMAP declaration) before this declaration. */ if (mapused) MEMZERO((UNIV)srhptr->srhsrm, sizeof(PECB)*(lex.s.dtb[0].mapdata+1)); else { frem((UNIV)srhptr->srhsrm); hout((THASH)srhtab, srhptr->ename, 0); frem((UNIV)srhptr); }}/* MDSRMUSE: Activate a short reference map.*/VOID mdsrmuse(tbuf)UNCH *tbuf; /* Work area for tokenization[LITLEN+2]. */{ PSRH srhptr; /* Ptr to short reference map hdr (in srhtab).*/ TECB srmptr; /* Ptr to short reference map (in header). */ int i; /* Loop counter; temporary variable. */ mdname = key[KUSEMAP]; /* Identify declaration for messages. */ subdcl = NULL; /* No subject as yet. */ parmno = 0; /* No parameters as yet. */ mdessv = es; /* Save es for checking entity nesting. */ /* PARAMETER 1: SHORTREF map name or "#EMPTY". */ pcbmd.newstate = 0; parsemd(lbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("1: map nm"); subdcl = lbuf+1; /* Subject name for error messages. */ switch (pcbmd.action) { case RNS: /* Empty SHORTREF map requested. */ if (ustrcmp(lbuf+1, key[KEMPTY])) { mderr(118, lbuf+1, key[KEMPTY]); return; } srmptr = SRMNULL; break; case NAS: /* Map name specified; save if undefined. */ if ((srhptr = srhfind(lbuf))==0) { if (!indtdsw) {mderr(125, (UNCH *)0, (UNCH *)0); return;} srmptr = NULL; } else srmptr = srhptr->srhsrm; break; default: mderr(120, (UNCH *)0, (UNCH *)0); return; } /* PARAMETER 2: Element name or a group of them. (In DTD only.) */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD("2: GI or grp"); switch (pcbmd.action) { case NAS: if (!indtdsw) {mderr(142, (UNCH *)0, (UNCH *)0); return;} nmgrp[0] = etddef(tbuf); nmgrp[1] = (PETD)NULL; break; case GRPS: if (!indtdsw) {mderr(142, (UNCH *)0, (UNCH *)0); return;} parsegrp(nmgrp, &pcbgrnm, tbuf); break; case EMD: if (indtdsw) {mderr(28, (UNCH *)0, (UNCH *)0); return;} if (docelsw) {mderr(233, (UNCH *)0, (UNCH *)0); return;} tags[ts].tsrm = srmptr; TRACESRM("USEMAP", tags[ts].tsrm, tags[ts].tetd->etdgi+1); goto realemd; default: mderr(indtdsw ? 121 : 126, (UNCH *)0, (UNCH *)0); return; } /* PARAMETER 3: End of declaration. */ parsemd(tbuf, NAMECASE, &pcblitp, NAMELEN); TRACEMD(emd); if (pcbmd.action!=EMD) mderr(126, (UNCH *)0, (UNCH *)0); /* If map has not yet been defined, do it and get map pointer. */ if (!srmptr) srmptr = (srhdef(lbuf))->srhsrm; /* Store the map pointer for each element name specified. */ TRACEGRP(nmgrp); for (i = -1; nmgrp[++i];) { if (!nmgrp[i]->etdsrm) nmgrp[i]->etdsrm = srmptr; else if (sw.swdupent) mderr(68, nmgrp[i]->etdgi+1, (UNCH *)0); } realemd: if (es!=mdessv) synerr(37, &pcbmd);}/* SRHDEF: Define a SHORTREF map and return ptr to its header. All entries in map are mapped to NULL. Caller must determine whether it already exists.*/PSRH srhdef(sname)UNCH *sname; /* SHORTREF map name (with length and EOS). */{ PSRH srh; /* Ptr to SHORTREF map hdr in srhtab. */ (srh = (PSRH)hin((THASH)srhtab, sname, 0, SRHSZ))->srhsrm = (TECB)rmalloc((UNS)(lex.s.dtb[0].mapdata+1)*sizeof(PECB)); return(srh);}/* SRHFIND: If a SHORTREF map was declared, return the ptr to its header. Return NULL if it is not defined.*/PSRH srhfind(sname)UNCH *sname; /* SHORTREF map name (with length and EOS). */{ return((PSRH)hfind((THASH)srhtab, sname, 0));}#undef SRM/*Local Variables:c-indent-level: 5c-continued-statement-offset: 5c-brace-offset: -5c-argdecl-indent: 0c-label-offset: -5comment-column: 30End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -