home *** CD-ROM | disk | FTP | other *** search
- /* plain.c 1989 december 10 [gh]
- +-----------------------------------------------------------------------------
- | Abstract:
- | Plain filter module
- |
- | Authorship:
- | Copyright (c) 1988, 1989 Gisle Hannemyr.
- | Permission is granted to hack, make and distribute copies of this module
- | as long as this notice and the copyright notices are not removed.
- | If you intend to distribute changed versions of this module, please make
- | an entry in the "history" log (below) and mark the hacked lines with your
- | initials. I maintain the module, and shall appreiciate copies of bug
- | fixes and new versions.
- | Flames, bug reports, comments and improvements to:
- | snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
- | email: X400: gisle@nr.uninett
- | RFC: gisle@ifi.uio.no
- | (and several BBS mailboxes in the Oslo area).
- |
- | Access programs:
- | void inittable() : Initialize default transformation table.
- | void readtable() : Initialize transformation table from file.
- | void doplain() : Interprete one file.
- |
- | History:
- | 11 dec 89 [gh] Latest update.
- |
- | See main module for more comments.
- +---------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include "pep.h"
- #include <ctype.h>
- #include <string.h>
-
- /*---( defines )------------------------------------------------------------*/
-
- #define WSHH 0x1e /* WordStar invisible soft hyphen. */
- #define WSSH 0x1f /* WordStar visible soft hyphen. */
- #define WSSC 0x8d /* WordStar soft carrige return. */
- #define WSSS 0xa0 /* WordStar soft space. */
-
- #ifndef BUFSIZE
- #define BUFSIZE 8192
- #endif /* BUFSIZE */
-
-
- /*---( types )--------------------------------------------------------------*/
-
- typedef int FOLDMATRIX[11][2];
-
-
- /*---( constants )----------------------------------------------------------*/
-
- /* Test for Swedish characters too, but after the Norwegian ones. */
- static FOLDMATRIX decfold = {
- { 198, 91 }, /* AE [ (N) */
- { 216, 92 }, /* OE \ (N) */
- { 197, 93 }, /* AA ] (-) */
- { 230, 123 }, /* ae { (N) */
- { 248, 124 }, /* oe | (N) */
- { 229, 125 }, /* aa } (-) */
- { 196, 91 }, /* AE [ (S) */
- { 214, 92 }, /* OE \ (S) */
- { 228, 123 }, /* ae { (S) */
- { 246, 124 }, /* oe | (S) */
- { 0, 0 }
- };
-
-
- static FOLDMATRIX ibmfold = {
- { 146, 91 }, /* AE [ (N) */
- { 157, 92 }, /* OE \ (N) */
- { 143, 93 }, /* AA ] (-) */
- { 145, 123 }, /* ae { (N) */
- { 155, 124 }, /* oe | (N) */
- { 134, 125 }, /* aa } (-) */
- { 142, 91 }, /* AE [ (S) */
- { 153, 92 }, /* OE \ (S) */
- { 132, 123 }, /* ae { (S) */
- { 148, 124 }, /* oe | (S) */
- { 0, 0 }
- };
-
-
- static FOLDMATRIX macfold = {
- { 174, 91 }, /* AE [ (N) */
- { 175, 92 }, /* OE \ (N) */
- { 129, 93 }, /* AA ] (-) */
- { 190, 123 }, /* ae { (N) */
- { 191, 124 }, /* oe | (N) */
- { 140, 125 }, /* aa } (-) */
- { 128, 91 }, /* AE [ (S) */
- { 133, 92 }, /* OE \ (S) */
- { 138, 123 }, /* ae { (S) */
- { 154, 124 }, /* oe | (S) */
- { 0, 0 }
- };
-
-
- /*---( variables )----------------------------------------------------------*/
-
- static unsigned char Buffer[BUFSIZE]; /* Output buffer */
- static unsigned char CTable[256]; /* General fold matrix */
-
- static int BuffSs = 0; /* Bona-fide chars. in string. */
- static int BuffXx = 0; /* Horisontal pos. in buffer. */
- static int NSpace = 0; /* No. of spaces not flushed. */
-
-
- /*---( forward )------------------------------------------------------------*/
-
- char *getenv();
-
-
- /*---( housekeeping )-------------------------------------------------------*/
-
- /*
- | Abs: Is it a control character? (According to pep's rather complicated
- | concept of such.)
- | Ret: TRUE if it is, else FALSE (pep hacks ctrl. chars, leave others alone).
- */
- static BOOL ctrlp(cc)
- int cc;
- {
- if (isascii(cc)) {
- if (wflag1 && (cc == WSSH)) return(FALSE);
- if (iscntrl(cc)) return(TRUE); else return(FALSE);
- } else if (!bflagb) return(FALSE);
- /* Assert: if it was 7 bit ASCII, or if the upper 128 set shall be */
- /* considered legal character, then we have returned by now. */
-
- if (wflag1 && (cc == WSSC)) return(FALSE);
- /* Assert: if it was WordStar soft CR, then we have returned by now. */
-
- if (iflagi && IFrst) { /* We are folding to IBM charset, */
- int jj = 0;
- while (ibmfold[jj][0] && (ibmfold[jj][0] != cc)) jj++;
- return(!ibmfold[jj][0]); /* so those are not control chars. */
- }
- return(TRUE);
- /* If all else fails, it must be a control character. */
- } /* ctrlp */
-
-
- /*---( transformation table )-----------------------------------------------*/
-
- /*
- | Abs: Catenate tabledir and cname to create a full searchpath.
- | Ret: Pointer to the full, catenated path.
- */
- static char *findpath(tabledir,cname)
- char *tabledir, *cname;
- {
- char fullpath[1024], *ss;
-
- if (!tabledir) return(cname); /* Bail out under VMS, etc. */
- ss = fullpath;
- while (*ss++ = *tabledir++) ; /* strcpy(fullpath,tabledir); */
- ss--; /* ss points to terminator */
- if (ss[-1] != DIRCHAR) { *ss = DIRCHAR; *++ss = '\0'; }
- while (*ss++ = *cname++) ; /* strcat(fullpath,cname); */
- return(fullpath);
- } /* findpath */
-
- /*
- | Abs: Initialize default transformation table.
- */
- void inittable()
- {
- int cc;
-
- for (cc = 0; cc < 256; cc++) CTable[cc] = cc;
- } /* inittable */
-
-
- /*
- | Abs: Initialize transformation table from file.
- | Par: tabledir = pointer to table to initialize
- | cname = file to read table from
- | echo = TRUE to echo comments to stderr, else quiet.
- */
- void readtable(tabledir,cname,echo)
- char *tabledir, *cname;
- BOOL echo;
- {
- FILE *fdt;
- char *ss;
-
- if ((fdt = fopen(cname,"r")) == NULL) {
- if (tabledir) {
- if (ss = strrchr(tabledir,DIRCHAR)) {
- *++ss = '\0';
- fdt = fopen(findpath(tabledir,cname),"r");
- } /* if tabledir made sense */
- } /* if tabledir defined */
- if (fdt == NULL) {
- #ifndef __CPM86__
- if (tabledir = getenv("PEP"))
- fdt = fopen(findpath(tabledir,cname),"r");
- #endif
- if (fdt == NULL) {
- fprintf(stderr,"can't open translation table \"%s\"\n", cname);
- exit(ERROR_EXIT);
- } /* if file not found in environment directory */
- } /* if file not found in startup directory */
- } /* if file not found in local directory */
-
- while (fgets(Buffer,BUFSIZE-1,fdt)) {
- char *ss;
- int ii;
- if (ss = strchr(Buffer,'#')) {
- if (echo && (ss[1] != '#')) {
- fputs(" ",stderr);
- fputs(ss,stderr);
- }
- *ss = '\0';
- } /* if comment */
- for (ii = strlen(Buffer) - 1; isspace(Buffer[ii]) && (ii >= 0); ii--);
- Buffer[++ii] = 0;
- if (*Buffer) {
- int tt, ff;
- if (sscanf(Buffer,"%d %d",&ff,&tt) != 2) mess(6);
- if ((tt < 0) || (tt > 255) || (ff < 0) || (ff > 255)) mess(6);
- /* fprintf(stderr,"[%s] %d <== %d\n",Buffer,tt,ff); */
- CTable[ff] = tt;
- }
- } /* while */
- fclose(fdt);
- } /* readtable */
-
-
- /*---( foldings )-----------------------------------------------------------*/
-
- /*
- | Abs:
- */
- static unsigned char fold8(cc,fold)
- int cc;
- FOLDMATRIX fold;
- {
- if (cc >= ILimit) {
- int jj = 0;
- while (fold[jj][IFrst] && (fold[jj][IFrst] != cc)) jj++;
- if (fold[jj][IFrst]) cc = fold[jj][ILast];
- }
- return(cc);
- } /* fold8 */
-
-
- /*
- | Abs: Flush accumulated whitespace, compressing spaces into tabs.
- */
- static void flushspace()
- {
- int ii;
-
- if (cflagc && OTabSz) {
- while (NSpace > 1 && NSpace >= (ii = OTabSz - (LineXx % OTabSz))) {
- Buffer[BuffXx++] = '\t';
- NSpace -= ii;
- LineXx += ii;
- } /* while */
- } /* if compressing tabs */
- LineXx += NSpace;
- while (NSpace--) Buffer[BuffXx++] = ' ';
- NSpace = 0;
- } /* flushspace */
-
-
- /*
- | Abs: Flush line in buffer to the output file.
- | Des: Turbo-C return bogus values if isspace is called with arg > 128.
- | Sef: Zero NSpace, BuffXx and LineXx counts.
- */
- static void flushline()
- {
- if (!sflags || (BuffSs >= StrSiz)) {
- while (!(Buffer[BuffXx-1] & 0x80) && isspace(Buffer[BuffXx-1]) && BuffXx)
- BuffXx--;
- Buffer[BuffXx] = '\0';
- if (wflag1) {
- int xx;
- if (BuffXx && (Buffer[BuffXx-1] == '-')) Buffer[BuffXx-1] = WSSH;
- xx = 0;
- while (Buffer[xx]) {
- if (Buffer[xx] == ' ') Buffer[xx] = WSSS;
- xx++;
- }
- }
- fputs(Buffer,Fdo);
-
- if (vflagv) /* Paragraph only */ ;
-
- /* Terminate the line we have just flushed */
- if (wflag1) {
- if (BuffXx) putc(WSSC,Fdo); else putc('\r',Fdo);
- putc('\n',Fdo);
- } else {
- if ((vflagv && BuffXx) || (EndOLn == -2)) putc(' ',Fdo);
- else {
- if (EndOLn == -1) { putc('\r',Fdo); putc('\n',Fdo); }
- else putc(EndOLn,Fdo);
- } /* if */
- } /* if */
- showprogress();
- } /* if enough of a string to print it */
- NSpace = BuffXx = LineXx = 0;
- } /* flushline */
-
-
- /*
- | Abs: Put character into line buffer.
- | Des: First, make some simple character foldings. Then, put the character
- | into a line buffer. A control character may be converted to hex,
- | surrounded by angle brackets.
- */
- static void putline(cc)
- int cc;
- {
- static BOOL wasbs = FALSE;
- static BOOL wascr = FALSE;
- static BOOL wasoe = FALSE;
- BOOL isaoe = FALSE;
-
- if (BuffXx >= (BUFSIZE-5)) flushline(); /* Panic! */
- if (zflagz) cc = cc & 0x7f; /* Fold to 7 bit. */
- if (mflagm && !IFrst && (cc == '\r')) cc = '\n'; /* Mac uses CR as terminator */
- /* This is a hack to fool the stuff below who removes redundant CR's. */
- /* When we are converting from Mac format, we want to keep them all. */
-
- if (wasoe) {
- wasoe = FALSE;
- if (cc != 92) {
- Buffer[BuffXx] = '\\';
- LineXx++;
- BuffXx++;
- } /* if */
- } else if ((cc == 92) && kflagk && IFrst) { wasoe++; return; }
-
- if (dflagd) { if (!IFrst && (cc == 216)) isaoe++; cc = fold8(cc,decfold); }
- if (iflagi) { if (!IFrst && (cc == 157)) isaoe++; cc = fold8(cc,ibmfold); }
- if (mflagm) { if (!IFrst && (cc == 175)) isaoe++; cc = fold8(cc,macfold); }
- if (gflagg) cc = CTable[cc]; /* Fold from table. */
- if (wflag0) {
- if (cc == WSHH) return; /* WS invisible soft hyphen. */
- if (cc == WSSH) cc = '-'; /* WS visible soft hyphen. */
- }
-
- if (wascr) {
- wascr = FALSE;
- if (BuffXx) {
- flushline();
- if (cc == '\n') return;
- } /* if anything in buffer */
- } /* if wascr */
-
- if ((cc == '\b') && BuffXx) { BuffXx--; wasbs++; }
- else if (cc == '\f') {
- if (BuffXx) flushline();
- if (wflag1) fputs(".PA\n",Fdo);
- else if (!(bflagb + sflags)) putc('\f',Fdo);
- wasbs = FALSE;
- }
- else if (cc == '\n') { flushline(); BuffSs++; }
- else if (cc == '\r') { wascr++; }
- else if (cc == '\t') {
- if (tflagt || cflagc) NSpace += ITabSz - ((LineXx + NSpace) % ITabSz);
- else { Buffer[BuffXx++] = cc; LineXx++; }
- BuffSs++;
- wasbs = FALSE;
- }
- else if (ctrlp(cc)) {
- if (xflagx) { /* Expanding control chars. */
- char *ss;
- if (NSpace) flushspace();
- ss = (char *)&Buffer[BuffXx];
- sprintf(ss,"<%02xh>",cc);
- BuffXx += 5;
- LineXx += 5;
- }
- else if (BuffXx) flushline(); /* Removing control chars. */
- BuffSs = 0;
- wasbs = FALSE;
- }
- else if (cflagc && cc == ' ') NSpace++;
- else {
- if (NSpace) flushspace();
- if (!wasbs || (cc != '_')) Buffer[BuffXx] = cc;
- LineXx++;
- BuffXx++;
- if (kflagk && isaoe) {
- Buffer[BuffXx] = cc;
- LineXx++;
- BuffXx++;
- }
- BuffSs++;
- wasbs = FALSE;
- }
- } /* putline */
-
-
- /*---( file loop )----------------------------------------------------------*/
-
- /*
- | Abs: Read (and write) one complete plain file.
- */
- void doplain()
- {
- int cc;
-
- while ((cc = getc(Fdi)) != EOF) putline(cc);
- if (BuffXx) flushline();
- } /* doplain */
-
- /* EOF */
-