home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************/
- /* Added PRNTSTAT routine for (verbose) printing of statistics structure. */
- /* Moved location processing here from SGMLIO. */
- /* New exiterr function for terminal errors. (CODED 10/16/87) */
- /******************************************************************************/
- #include "vmincl.h" /* Include files for VM. */
- #include "vmxtrn.h" /* Declarations for VM public variables. */
- /******************************************************************************/
- #define REALEOF '\032' /* Ctl-Z is read as part of file in binary mode.*/
- #define FOPENRD "rb" /* Binary not default: specify it. */
- #define MTRUNC 2 /* Truncate trailing CR/LF from msgs and parms. */
- /******************************************************************************/
- #define MAXARGLN FILESPEC /* Maximum length of an argument in a msg. */
- #define MAXMSGLN 84 /* Max len of record in msgfile (with CR,LF). */
- /******************************************************************************/
- FILE *msgfp; /* "Handle" of msgfile (STREAM I/O). */
- long msgindx[MAXMSGS+1] ={0}; /* Offsets of messages in msgfile. */
- long spindex[MAXPCBS+MAXDCLS]={0};/* Offsets of special parameters in msgfile.*/
- UNCH locpref[] = "\n "; /* Location prefix (indent) for messages. */
- UNCH margpos[MAXARGS+1] = {0};/* Argument positions of current msg. */
- UNCH msgid[5] = {0}; /* Message class and 3 digit ID of msg. */
- UNCH msgpref[] = "\n ";/* General prefix (indent) for messages. */
- UNCH outchar[2] = " "; /* Current character, censored for printing. */
- UNCH sevcode[2] = {0}; /* Severity code of current msg. */
- UNCH *margv[MAXARGS+2] = { /* Ptrs to argument strings (in pd). */
- pd, /* Full message file record. */
- pd+MAXMSGLN+1, /* 1st parameter. */
- pd+MAXMSGLN+1+ MAXARGLN+1, /* 2nd parameter. */
- pd+MAXMSGLN+1+2*(MAXARGLN+1) /* Special parameter text (errsp). */
- };
- UNCH *hdrall = 0; /* Initial header for all error messages. */
- UNCH *hdrdoc = 0; /* Header for document markup error messages. */
- UNCH *hdrfil = 0; /* Header for file access error messages. */
- UNCH *hdrloc = 0; /* Header for entity location stack in messages.*/
- UNCH *hdrmd2 = 0; /* Header for markup declaration messages. */
- UNCH *hdrmd3 = 0; /* Header for markup dcl msg with subdcl. */
- UNCH *hdrtag = 0; /* Header for tag stack list in messages. */
- UNCH **hdrs[MAXHDRS] = { /* Headers of error messages. */
- &hdrall, &hdrdoc, &hdrfil,
- &hdrloc, &hdrmd2, &hdrmd3, &hdrtag
- };
- /******************************************************************************/
- /* SGMLMSG: Text processor message services for SGML.
- Do not return to SGML if the error type is EXITERR.
- */
- VOID sgmlmsg(ie)
- struct ipberr *ie; /* Ptr to error message control block. */
- {
- UNCH *pt; /* Error handling: ptr to message text. */
- int margc; /* Error handling: number of msg arguments. */
- int i; /* Loop counter; work variable. */
-
- getscbs((struct source *)ie->sgmlscbs, /* Get SCBs from SGML. */
- ie->sgmles);
- ++cnterr; /* Increment msg counter. */
- pt = getmsg(msgindx[ie->errnum]); /* Get msg text and data. */
- margc = *margpos=='0' ? 0 : (int)strlen(margpos); /* Get argument count. */
- for (i = 0; ++i<=margc;) { /* Get args from SGML. */
- margpos[i-1] -= '0'; /* Convert to number. */
- memcpy( margv[i] , ie->eparm[i-1], (UNS)MAXARGLN );
- margv[i][MAXARGLN] = '\0'; /* Truncate for safety. */
- }
- printf("\n"); printf(hdrall, msgid, sevcode);
- switch (ie->errtype) {
- case MDERR: /* Error in markup declaration. */
- printf(" ");
- printf(hdrmd3, getparm(ie->errsp), ie->subdcl, ie->parmno);
- break;
- case MDERR2: /* Error in markup declaration: no subdcl. */
- printf(" "); printf(hdrmd2, getparm(ie->errsp), ie->parmno);
- break;
- case DOCERR: /* Error in document markup. */
- case EXITERR: /* Terminal error in document markup. */
- outchar[0] = ZAPEOL(CC); /* Censor CC for printing. */
- printf(" "); printf(hdrdoc, getparm(ie->errsp), outchar, CC);
- break;
- case FILERR: /* Error in file access. */
- printf(" "); printf(hdrfil, curfile);
- break;
- }
- if (tpsw.swenttr) {
- i = tpes;
- for (tpes = -1; ++tpes<i;) errloc(locpref, hdrloc);
- }
- errloc(locpref, hdrloc); printf(":");
- if (eltrsw) {
- printf(msgpref); printf(hdrtag);
- for (i = -1; ++i<=tpts;) printf(" %s", &tptags[i][0]);
- }
- printf(msgpref); prtmsg(pt, margc);
- if (ie->errtype==EXITERR) exit((int)ie->errnum);
- else return;
- }
- /******************************************************************************/
- /* MSGINIT: Read msgfile and build index to error messages.
- Errors of class "W" are clearly markup errors,
- but the parser was able to continue normal processing.
- All other errors require the parser to depart from normal
- processing in the manner indicated in the error message.
- */
- VOID msginit()
- {
- UNCH leadchar[2]; /* First nonblank character in msg record. */
- long offset; /* Offset of msg in file. */
- int msgno; /* Number of current msg. */
-
- if (!filefind(msgfptr, pd)) { /* Search dir and path. */
- printf(
- "\nVM007-> Unable to open %s message file; processing ended.",
- msgfptr);
- exit(007);
- }
- msgfp = fopen(pd, FOPENRD);
-
- /* Place offsets in message number array. */
- for (offset = 0; fgets(pd, MAXMSGLN+1, msgfp) && *pd!=REALEOF;
- offset = ftell(msgfp)) {
- /* Skip blank lines and those with * as first nonblank. */
- sscanf(pd, "%1s", leadchar);
- if (*leadchar!='*' && *leadchar!='\0') {
- /* Not a comment: save the offset in the msg number array. */
- sscanf(pd, "%3d", &msgno); /* Get message number. */
- if (msgno<1) {
- if (umsginit(-msgno, offset)==0) continue;
- }
- else if (msgno<=MAXMSGS) {
- msgindx[msgno] = offset;/* Save offset of this message. */
- continue;
- }
- printf(
- "\nVM008-> Bad item %d in SGML.MSG at offset %ld; processing ended.",
- msgno, offset);
- exit(8);
- }
- }
- fseek(msgfp, 0L, SEEK_SET); /* I think this avoids a bug. */
- }
- /******************************************************************************/
- /* UMSGINIT: User exit from message file initialization to get
- message header text strings, parameter strings, and
- national-language-specific text strings from the msgfile.
- */
- int umsginit(msgno, offset)
- int msgno; /* Number of special msg as positive number. */
- long offset; /* Offset of special msg in file. */
- {
- if (msgno<MAXHDRS) { /* Special text is a message header. */
- *hdrs[msgno] = savestr(getmsg(offset));
- return 0;
- }
- if (msgno<MAXHDRS+MAXPCBS+MAXDCLS) {
- spindex[msgno-MAXHDRS] = offset;
- return 0;
- }
- return(-1);
- }
- /******************************************************************************/
- /* GETMSG: Find a specified msg record, parse it, and return ptr to text.
- */
- UNCH *getmsg(msgoff)
- long msgoff; /* Offset of message to be found and parsed. */
- {
- UNCH *pt; /* Ptr to current msg text. */
-
- fseek(msgfp, msgoff, SEEK_SET);
- fgets(pd, MAXMSGLN+1, msgfp);
- sscanf(pd, "%*d %1s %4s %3s", sevcode, msgid, margpos);
- pt = strchr(pd, '%'); /* Find trigger at start of text. */
- while (*++pt==' ') ; /* Strip leading blanks from text. */
- pt[strlen(pt)-MTRUNC] = '\0'; /* Strip trailing newline from text. */
- return(pt);
- }
- /******************************************************************************/
- /* GETPARM: Find a specified parameter record, parse it, and return ptr to text.
- */
- UNCH *getparm(msgind)
- UNS msgind; /* Index of special parameter to be found. */
- {
- UNCH *pt = margv[MAXARGS+1]; /* Ptr to special parameter text. */
-
- fseek(msgfp, spindex[msgind], SEEK_SET); /* Position file ptr to record. */
- fgets(pt, MAXARGLN+1, msgfp); /* Copy record to special arg buffer. */
- pt += 4; /* Find start of text. */
- pt[strlen(pt)-MTRUNC] = '\0'; /* Strip trailing newline from text. */
- return(pt);
- }
- /******************************************************************************/
- /* PRTMSG: Print the message with substituted arguments.
- */
- VOID prtmsg(pt, argc)
- UNCH *pt; /* Ptr to current msg text. */
- int argc; /* Number of arguments for this msg. */
- {
- switch (argc) {
- case 0:
- printf(pt);
- return;
- case 1:
- printf(pt, margv[margpos[0]]);
- return;
- case 2:
- printf(pt, margv[margpos[0]], margv[margpos[1]]);
- return;
- case 3:
- printf(pt, margv[margpos[0]], margv[margpos[1]],
- margv[margpos[2]]);
- return;
- }
- }
- /******************************************************************************/
- /* GETSCBS: Update the source control block stack by copying entries from SGML.
- If there are new entries (i.e., entities have opened), copy all
- entries from the previous current entry to the new current entry
- and change the current level.
- If there are fewer entries (i.e., entities have closed), change
- the current level and copy its entry.
- If the level has not changed (i.e., no entity activity, or an
- equal number of opens and closes), just copy the current entry.
- */
- VOID getscbs(sgmlscbs, sgmles)
- PSCB sgmlscbs; /* Ptr to SGML scb stack. */
- int sgmles; /* SGML scb stack level. */
- {
- register int i; /* Signed work variable. */
- register UNS u; /* Unsigned work variable. */
-
- if ((i = sgmles-tpes)>0) /* Entities have opened: copy all new entries. */
- u = (i+1)*SCBSZ; /* Size of scbs to copy (include last current). */
- else {
- if (i<0) tpes = sgmles; /* Entities have closed: new current level. */
- u = SCBSZ; /* Copy current level only. */
- }
- memcpy((UNIV)&tpscbs[tpes], (UNIV)&sgmlscbs[tpes], u);
- if (i>0) tpes = sgmles; /* New current level if entities opened. */
- curfile = FLID+1; /* Current file for use by SGMLMSG. */
- }
- /******************************************************************************/
- /* ERRLOC: Read tpscbs and print location information.
- */
- VOID errloc(pref, hdr)
- UNCH *pref, *hdr;
- {
- printf(pref);
- printf(hdr, RCNT, CCNT, ENTITY+1, (FILESW) ? FLID+1 : "*INTERNAL");
- }
- /******************************************************************************/
- /* LOCATION: Print location prefix for VM messages.
- If the entity has changed since last time (possible even if
- the stack level is the same), print the new entity information.
- */
- VOID location(num)
- int num;
- {
- if (oldent!=ECBPTR) { /* Print message if entity has changed. */
- oldent = ECBPTR;
- printf(
- "\nVM100-> Entity is %s in %s.",
- ENTITY+1, (FILESW) ? FLID+1 : "*INTERNAL");
- }
- printf(
- "\nVM1%02d-> %03u %03d: ",
- num, RCNT, CCNT);
- }
- /******************************************************************************/
-