home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / linuxdoc-sgml-1.1 / sgmls-1.1 / sgml1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  14.5 KB  |  478 lines

  1. #include "sgmlincl.h"         /* #INCLUDE statements for SGML parser. */
  2.  
  3. #define ETDCON (tags[ts].tetd->etdmod->ttype)     /* ETD content flags. */
  4.  
  5. /* SGML: Main SGML driver routine.
  6. */
  7. enum sgmlevent sgmlnext(rcbdafp, rcbtagp)
  8. struct rcbdata *rcbdafp;
  9. struct rcbtag *rcbtagp;
  10. {
  11.      while (prologsw && !conactsw) {
  12.       int oconact;
  13.           conact = parsepro();
  14.           conactsw = 0;       /* Assume sgmlact() will not be skipped. */
  15.           switch(conact) {
  16.  
  17.           case PIS_:
  18.           case EOD_:
  19.       case APP_:           /* APPINFO */
  20.                conactsw = 1;   /* We can skip sgmlact() in opening state. */
  21.                break;
  22.  
  23.           case DAF_:
  24.                newetd = stagreal = ETDCDATA;
  25.                conact = stag(datarc = DAF_);
  26.                conactsw = 1;   /* We can skip sgmlact() in opening state. */
  27.                prologsw = 0;   /* End the prolog. */
  28.                break;
  29.       case DCE_:
  30.       case MSS_:
  31.            /* prcon[2].tu.thetd holds the etd for the document element. */
  32.            newetd = stagreal = prcon[2].tu.thetd;
  33.            stagmin = MINSTAG; /* This tag was minimized. */
  34.            /* It's an error if the start tag of the document element
  35.           is not minimizable. */
  36.            if (BITOFF(newetd->etdmin, SMO))
  37.             sgmlerr(226, conpcb, (UNCH *)0, (UNCH *)0);
  38.            oconact = conact; /* Save conact. */
  39.            conact = stag(0); /* Start the document element. */
  40.            conactsw = 1;    /* conact needs processing. */
  41.            prologsw = 0;    /* The prolog is finished. */
  42.            if (oconact == MSS_) {
  43.             if (msplevel==0) conpcb = getpcb((int)ETDCON);
  44.             conpcb = mdms(tbuf, conpcb); /* Parse the marked section
  45.                             start. */
  46.            }
  47.            break;
  48.           default:             /* STE_: not defined in SGMLACT.H. */
  49.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  50.                prologsw = 0;   /* End the prolog. */
  51.                break;
  52.           }
  53.      }
  54.      for (;;) {
  55.       unsigned swact;  /* Switch action: saved conact, new, or sgmlact.*/
  56.  
  57.           if (conactsw) {
  58.            conactsw = 0;
  59.            swact = conact;
  60.            contersw = contersv;
  61.       }
  62.           else {
  63.            conact = parsecon(tbuf, conpcb);
  64.            swact = sgmlact((UNCH)(conact != EOD_ ? conact : LOP_));
  65.       }
  66.  
  67.           switch (swact) {
  68.  
  69.           case MD_:           /* Process markup declaration. */
  70.                parsenm(tbuf, NAMECASE); /* Get declaration name. */
  71.                if (!ustrcmp(tbuf+1, key[KUSEMAP])) mdsrmuse(tbuf);
  72.                else sgmlerr(E_MDNAME, conpcb, tbuf+1, (UNCH *)0);
  73.                continue;
  74.           case MDC_:           /* Process markup declaration comment. */
  75.                if (*FPOS!=lex.d.mdc)
  76.                     parsemd(tbuf, NAMECASE, (struct parse *)0, NAMELEN);
  77.                continue;
  78.  
  79.           case MSS_:           /* Process marked section start. */
  80.                conpcb = mdms(tbuf, conpcb);
  81.                continue;
  82.           case MSE_:           /* Process marked section end (drop to LOP_). */
  83.                if (mdmse()) conpcb = getpcb((int)ETDCON);
  84.                continue;
  85.  
  86.           case PIS_:           /* Return processing instruction (string). */
  87.                if (entpisw) rcbdafp->data = data;
  88.                else {
  89.                     parselit(tbuf, &pcblitc, PILEN, lex.d.pic);
  90.                     rcbdafp->data = tbuf;
  91.                }
  92.                rcbdafp->datalen = datalen;
  93.                rcbdafp->contersw = entpisw;
  94.            entpisw = 0;             /* Reset for next time.*/
  95.                scbset();                /* Update location in current scb. */
  96.                return SGMLPIS;
  97.  
  98.       case APP_:
  99.            rcbdafp->data = tbuf;
  100.            rcbdafp->datalen = ustrlen(tbuf);
  101.            rcbdafp->contersw = 0;
  102.            scbset();
  103.            return SGMLAPP;
  104.           case ETG_:               /* Return end-tag. */
  105.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  106.                if (msplevel==0) conpcb = getpcb((int)ETDCON);
  107.                rcbtagp->contersw = tags[ts+1].tflags;
  108.                rcbtagp->tagmin = etagimsw ? MINETAG : etagmin;
  109.                rcbtagp->curgi = tags[ts+1].tetd->etdgi;
  110.                rcbtagp->ru.oldgi = tags[ts].tetd->etdgi;
  111.                if (etagmin==MINSTAG) rcbtagp->tagreal =
  112.                      BADPTR(stagreal) ? stagreal : (PETD)stagreal->etdgi;
  113.                else rcbtagp->tagreal =
  114.                      BADPTR(etagreal) ? etagreal : (PETD)etagreal->etdgi;
  115.                rcbtagp->etictr = etictr;
  116.                rcbtagp->srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  117.                                                       : 0;
  118.                scbset();                /* Update location in current scb. */
  119.                return SGMLETG;
  120.  
  121.           case STG_:               /* Return start-tag. */
  122.                charmode = 0;       /* Not in char mode unless CDATA or RCDATA.*/
  123.                if (!conrefsw && msplevel==0) conpcb = getpcb((int)ETDCON);
  124.                rcbtagp->contersw = tags[ts].tflags;
  125.                rcbtagp->tagmin = dostag ? MINSTAG : stagmin;
  126.                rcbtagp->curgi = tags[ts].tetd->etdgi;
  127.                /* Get attribute list if one was defined for this element. */
  128.                rcbtagp->ru.al = !tags[ts].tetd->adl ? 0 :
  129.                     rcbtagp->tagmin==MINNONE  ? al : tags[ts].tetd->adl;
  130.                rcbtagp->tagreal = BADPTR(stagreal)?stagreal:(PETD)stagreal->etdgi;
  131.                rcbtagp->etictr = etictr;
  132.                rcbtagp->srmnm = tags[ts].tsrm!=SRMNULL ? tags[ts].tsrm[0]->ename
  133.                                                       : 0;
  134.                scbset();                /* Update location in current scb. */
  135.                return SGMLSTG;
  136.  
  137.           case DAF_:               /* Return data in source entity buffer. */
  138.                charmode = 1;
  139.                rcbdafp->datalen = datalen;
  140.                rcbdafp->data = data;
  141.                rcbdafp->contersw = contersw | entdatsw;
  142.                                contersw = entdatsw = 0;/* Reset for next time.*/
  143.                scbset();                /* Update location in current scb. */
  144.                return SGMLDAF;
  145.  
  146.           case CON_:               /* Process conact after returning REF_. */
  147.                conactsw = 1;
  148.                contersv = contersw;
  149.           case REF_:               /* Return RE found. */
  150.                if (badresw) {
  151.                     badresw = 0;
  152.                     sgmlerr(E_CHARS, &pcbconm, tags[ts].tetd->etdgi+1, (UNCH *)0);
  153.                     continue;
  154.                }
  155.                charmode = 1;
  156.                rcbdafp->contersw = contersw;
  157.                contersw = 0;        /* Reset for next time.*/
  158.                scbset();                /* Update location in current scb. */
  159.                return SGMLREF;
  160.  
  161.           case EOD_:               /* End of source document entity. */
  162.                if (mslevel != 0) sgmlerr(139, conpcb, (UNCH *)0, (UNCH *)0);
  163.            idrck();                /* Check idrefs. */
  164.                scbset();                /* Update location in current scb. */
  165.                return SGMLEOD;
  166.  
  167.           default:             /* LOP_: Loop again with no action. */
  168.                continue;
  169.           }
  170.      }
  171. }
  172. /* PCBSGML: State and action table for action codes returned to text processor
  173.             by SGML.C.
  174.             Columns are based on SGMLACT.H values minus DAF_, except that end
  175.             of document has input code LOP_, regardless of its action code.
  176. */
  177. /* Symbols for state names (end with a number). */
  178. #define ST1     0   /* Just had a start tag. */
  179. #define NR1     2   /* Just had an RS or RE. */
  180. #define DA1     4   /* Just had some data. */
  181. #define NR2     6   /* Just had an RE; RE pending. */
  182. #define ST2     8   /* Had only markup since last RE/RS; RE pending. */
  183.  
  184. static UNCH sgmltab[][11] = {
  185. /*daf_ etg_ md_  mdc_ mss_ mse_ pis_ ref_ stg_ rsr_ eod  */
  186.  {DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR1 ,ST1 ,NR1 ,ST1 },/*st1*/
  187.  {DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,LOP_,EOD_},
  188.  
  189.  {DA1 ,DA1 ,ST1 ,ST1 ,ST1 ,ST1 ,ST1 ,NR2 ,ST1 ,NR1 ,ST1 },/*nr1*/
  190.  {DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,LOP_,EOD_},
  191.  
  192.  {DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,DA1 ,NR2 ,ST1 ,NR1 ,ST1 },/*da1*/
  193.  {DAF_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,LOP_,STG_,LOP_,EOD_},
  194.  
  195.  {DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR2 ,ST1 ,NR2 ,ST1 },/*nr2*/
  196.  {CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,CON_,LOP_,EOD_},
  197.  
  198.  {DA1 ,DA1 ,ST2 ,ST2 ,ST2 ,ST2 ,ST2 ,NR1 ,ST1 ,NR2 ,ST1 },/*st2*/
  199.  {CON_,ETG_,MD_ ,MDC_,MSS_,MSE_,PIS_,REF_,CON_,LOP_,EOD_},
  200. };
  201. int scbsgmst = ST1;           /* SCBSGML: trailing stag or markup; ignore RE. */
  202. int scbsgmnr = NR1;           /* SCBSGML: new record; do not ignore RE. */
  203. /* SGMLACT: Determine action to be taken by SGML.C based on current state and
  204.             specified input.
  205.             For start or end of a plus exception element, push or pop the
  206.             pcbsgml stack.
  207.             Return to caller with action code.
  208. */
  209. #ifdef USE_PROTOTYPES
  210. int sgmlact(UNCH conret)
  211. #else
  212. int sgmlact(conret)
  213. UNCH conret;                  /* Action returned to SGML.C by content parse. */
  214. #endif
  215. {
  216.      int action;
  217.  
  218.      if (conret==STG_ && GET(tags[ts].tflags, TAGPEX))
  219.           {++pss; scbsgml[pss].snext = ST1;}
  220.      scbsgml[pss].sstate = scbsgml[pss].snext;
  221.      scbsgml[pss].snext = sgmltab[scbsgml[pss].sstate]
  222.                                     [scbsgml[pss].sinput = conret-DAF_];
  223.      scbsgml[pss].saction = sgmltab[scbsgml[pss].sstate+1][scbsgml[pss].sinput];
  224.      TRACEGML(scbsgml, pss, conactsw, conact);
  225.      action = scbsgml[pss].saction;
  226.      if (conret==ETG_ && GET(tags[ts+1].tflags, TAGPEX)) {
  227.       pss--;
  228.       /* An included subelement affects the enclosing state like a
  229.          processing instruction (or MDC_ or MD_),
  230.          that is to say NR1 is changed to ST1 and NR2 to ST2. */
  231.       scbsgml[pss].sstate = scbsgml[pss].snext;
  232.       scbsgml[pss].snext = sgmltab[scbsgml[pss].sstate][PIS_ - DAF_];
  233.      }
  234.      return action;
  235. }
  236. /* GETPCB: Choose pcb for new or resumed element.
  237. */
  238. struct parse *getpcb(etdcon)
  239. int etdcon;                   /* Content type of new or resumed element. */
  240. {
  241.      if (BITON(etdcon, MGI)) {
  242.           return(BITON(etdcon, MCHARS) ? &pcbconm : &pcbcone);
  243.      }
  244.      if (BITON(etdcon, MCDATA) || BITON(etdcon, MRCDATA)) {
  245.          charmode = 1;
  246.          return(BITON(etdcon, MCDATA) ? &pcbconc : (rcessv = es, &pcbconr));
  247.      }
  248.      return(&pcbconm);
  249. }
  250.  
  251. struct markup *sgmlset(swp)
  252. struct switches *swp;
  253. {
  254.      /* Initialize variables based on switches structure members. */
  255.      sw = *swp;
  256.      rbufs = (UNCH *)rmalloc((UNS)3+sw.swbufsz) + 3; /* DOS file read area. */
  257.      TRACEPRO();         /* Set trace switches for prolog. */
  258.      msginit(swp);
  259.      ioinit(swp);
  260.      sdinit();
  261.      return &lex.m;
  262. }
  263.  
  264. /* Points for each capacity, indexed by *CAP in sgmldecl.h.  We'll replace
  265. 2 with the real NAMELEN at run time. */
  266.  
  267. static UNCH cappoints[] = {
  268.      1,
  269.      2,
  270.      1,
  271.      2,
  272.      2,
  273.      2,
  274.      2,
  275.      2,
  276.      1,
  277.      2,
  278.      2,
  279.      1,
  280.      2,
  281.      2,
  282.      2,
  283.      2,
  284.      2
  285. };
  286.  
  287. static long capnumber[NCAPACITY];
  288. static long maxsubcap[NCAPACITY];
  289.  
  290. VOID sgmlend(p)
  291. struct sgmlcap *p;
  292. {
  293.      int i;
  294.      for (; es >= 0; --es)
  295.       if (FILESW)
  296.            fileclos();
  297.  
  298.      capnumber[NOTCAP] = ds.dcncnt;
  299.      capnumber[EXGRPCAP] = ds.pmexgcnt;
  300.      capnumber[ELEMCAP] = ds.etdcnt+ds.etdercnt;
  301.      capnumber[EXNMCAP] = ds.pmexcnt;
  302.      capnumber[GRPCAP] = ds.modcnt;
  303.      capnumber[ATTCAP] = ds.attcnt;
  304.      capnumber[ATTCHCAP] = ds.attdef;
  305.      capnumber[AVGRPCAP] = ds.attgcnt;
  306.      capnumber[IDCAP] = ds.idcnt;
  307.      capnumber[IDREFCAP] = ds.idrcnt;
  308.      capnumber[ENTCAP] = ds.ecbcnt;
  309.      capnumber[ENTCHCAP] = ds.ecbtext;
  310.      capnumber[MAPCAP] = ds.srcnt + ds.srcnt*lex.s.dtb[0].mapdata;
  311.      capnumber[NOTCHCAP] = ds.dcntext;
  312.  
  313.      capnumber[TOTALCAP] = 0;
  314.  
  315.      for (i = 1; i < NCAPACITY; i++) {
  316.       if (cappoints[i] > 1)
  317.            cappoints[i] = NAMELEN;
  318.       capnumber[i] += maxsubcap[i]/cappoints[i];
  319.       capnumber[TOTALCAP] += (long)capnumber[i] * cappoints[i];
  320.      }
  321.      p->number = capnumber;
  322.      p->points = cappoints;
  323.      p->limit = sd.capacity;
  324.      p->name = captab;
  325.  
  326.      for (i = 0; i < NCAPACITY; i++) {
  327.       long excess = capnumber[i]*cappoints[i] - sd.capacity[i];
  328.       if (excess > 0) {
  329.            char buf[sizeof(long)*3 + 1];
  330.            sprintf(buf, "%ld", excess);
  331.            sgmlerr(162, (struct parse *)0,
  332.                (UNCH *)captab[i], (UNCH *)buf);
  333.       }
  334.      }
  335. }
  336.  
  337. VOID sgmlsubcap(v)
  338. long *v;
  339. {
  340.      int i;
  341.      for (i = 0; i < NCAPACITY; i++)
  342.       if (v[i] > maxsubcap[i])
  343.            maxsubcap[i] = v[i];
  344. }
  345.  
  346. int sgmlsdoc(ptr)
  347. UNIV ptr;
  348. {
  349.      struct entity *e;
  350.      union etext etx;
  351.      etx.x = ptr;
  352.  
  353.      e = entdef(indocent, ESF, &etx);
  354.      if (!e)
  355.       return -1;
  356.      return entopen(e);
  357. }
  358.  
  359. /* SGMLGENT:  Get a data entity.
  360.               Returns:
  361.           -1 if the entity does not exist
  362.           -2 if it is not a data entity
  363.           1 if it is an external entity
  364.           2 if it is an internal cdata entity
  365.           3 if it is an internal sdata entity
  366. */
  367. int sgmlgent(iname, np, tp)
  368. UNCH *iname;
  369. PNE *np;
  370. UNCH **tp;
  371. {
  372.      PECB ep;                 /* Pointer to an entity control block. */
  373.      
  374.      ep = entfind(iname);
  375.      if (!ep)
  376.       return -1;
  377.      switch (ep->estore) {
  378.      case ESN:
  379.       if (np)
  380.            *np = ep->etx.n;
  381.       return 1;
  382.      case ESC:
  383.       if (tp)
  384.            *tp = ep->etx.c;
  385.       return 2;
  386.      case ESX:
  387.       if (tp)
  388.            *tp = ep->etx.c;
  389.       return 3;
  390.      }
  391.      return -2;
  392. }
  393.  
  394. /* Mark an entity. */
  395.  
  396. int sgmlment(iname)
  397. UNCH *iname;
  398. {
  399.      PECB ep;
  400.      int rc;
  401.  
  402.      ep = entfind(iname);
  403.      if (!ep)
  404.       return -1;
  405.      rc = ep->mark;
  406.      ep->mark = 1;
  407.      return rc;
  408. }
  409.  
  410. int sgmlgcnterr()
  411. {
  412.      return msgcnterr();
  413. }
  414.  
  415. /* This is for error handling functions that want to print a gi backtrace. */
  416.  
  417. UNCH *getgi(i)
  418. int i;
  419. {
  420.      return i >= 0 && i <= ts ? tags[i].tetd->etdgi + 1 : NULL;
  421. }
  422.  
  423. /* Returns the value of prologsw for the use by error handling functions. */
  424.  
  425. int inprolog()
  426. {
  427.      return prologsw;
  428. }
  429.  
  430. /* Used by the error handling functions to access scbs. */
  431.  
  432. int getlocation(level, locp)
  433. int level;
  434. struct location *locp;
  435. {
  436.      if (level < 0 || level > es)
  437.       return 0;
  438.      if (locp) {
  439.       int es = level;
  440.       /* source macros access a variable called `es' */
  441.  
  442.       locp->filesw = FILESW;
  443.       locp->rcnt = RCNT;
  444.       locp->ccnt = CCNT;
  445.       locp->ename = ENTITY + 1;
  446.       locp->fcb = SCBFCB;
  447.       locp->curchar = CC;
  448.       locp->nextchar = NEXTC;
  449.      }
  450.      return 1;
  451. }
  452.  
  453. int sgmlloc(linenop, filenamep)
  454. unsigned long *linenop;
  455. char **filenamep;
  456. {
  457.      int level = es;
  458.      int es;
  459.  
  460.      for (es = level; es >= 0 && !FILESW; es--)
  461.       ;
  462.      if (es < 0)
  463.       return 0;
  464.      *linenop = RCNT;
  465.      *filenamep = ioflid(SCBFCB);
  466.      return 1;
  467. }
  468.  
  469. /*
  470. Local Variables:
  471. c-indent-level: 5
  472. c-continued-statement-offset: 5
  473. c-brace-offset: -5
  474. c-argdecl-indent: 0
  475. c-label-offset: -5
  476. End:
  477. */
  478.