home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / tools / pep / plain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-29  |  12.6 KB  |  417 lines

  1. /* plain.c  1989 december 10 [gh]
  2. +-----------------------------------------------------------------------------
  3. | Abstract:
  4. |    Plain filter module
  5. |
  6. | Authorship:
  7. |    Copyright (c) 1988, 1989 Gisle Hannemyr.
  8. |    Permission is granted to hack, make and distribute copies of this module
  9. |    as long as this notice and the copyright notices are not removed.
  10. |    If you intend to distribute changed versions of this module, please make
  11. |    an entry in the "history" log (below) and mark the hacked lines with your
  12. |    initials. I maintain the module, and shall appreiciate copies of bug
  13. |    fixes and new versions.
  14. |    Flames, bug reports, comments and improvements to:
  15. |       snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway
  16. |       email: X400: gisle@nr.uninett
  17. |              RFC:  gisle@ifi.uio.no
  18. |              (and several BBS mailboxes in the Oslo area).
  19. |
  20. | Access programs:
  21. |    void inittable() : Initialize default transformation table.
  22. |    void readtable() : Initialize transformation table from file.
  23. |    void doplain()   : Interprete one file.
  24. |
  25. | History:
  26. |    11 dec 89 [gh] Latest update.
  27. |
  28. | See main module for more comments.
  29. +---------------------------------------------------------------------------*/
  30.  
  31. #include <stdio.h>
  32. #include "pep.h"
  33. #include <ctype.h>
  34. #include <string.h>
  35.  
  36. /*---( defines )------------------------------------------------------------*/
  37.  
  38. #define WSHH        0x1e                /* WordStar invisible soft hyphen.  */
  39. #define WSSH        0x1f                /* WordStar visible   soft hyphen.  */
  40. #define WSSC        0x8d                /* WordStar soft carrige return.    */
  41. #define WSSS        0xa0                /* WordStar soft space.             */
  42.  
  43. #ifndef    BUFSIZE
  44. #define BUFSIZE    8192
  45. #endif    /* BUFSIZE */
  46.  
  47.  
  48. /*---( types )--------------------------------------------------------------*/
  49.  
  50. typedef int FOLDMATRIX[11][2];
  51.  
  52.  
  53. /*---( constants )----------------------------------------------------------*/
  54.  
  55. /* Test for Swedish characters too, but after the Norwegian ones. */
  56. static FOLDMATRIX decfold = {
  57.    { 198,  91 },    /* AE [ (N) */
  58.    { 216,  92 },    /* OE \ (N) */
  59.    { 197,  93 },    /* AA ] (-) */
  60.    { 230, 123 },    /* ae { (N) */
  61.    { 248, 124 },    /* oe | (N) */
  62.    { 229, 125 },    /* aa } (-) */
  63.    { 196,  91 },    /* AE [ (S) */
  64.    { 214,  92 },    /* OE \ (S) */
  65.    { 228, 123 },    /* ae { (S) */
  66.    { 246, 124 },    /* oe | (S) */
  67.    {   0,   0 }
  68. };
  69.  
  70.  
  71. static FOLDMATRIX ibmfold = {
  72.    { 146,  91 },    /* AE [ (N) */
  73.    { 157,  92 },    /* OE \ (N) */
  74.    { 143,  93 },    /* AA ] (-) */
  75.    { 145, 123 },    /* ae { (N) */
  76.    { 155, 124 },    /* oe | (N) */
  77.    { 134, 125 },    /* aa } (-) */
  78.    { 142,  91 },    /* AE [ (S) */
  79.    { 153,  92 },    /* OE \ (S) */
  80.    { 132, 123 },    /* ae { (S) */
  81.    { 148, 124 },    /* oe | (S) */
  82.    {   0,   0 }
  83. };
  84.  
  85.  
  86. static FOLDMATRIX macfold = {
  87.    { 174,  91 },    /* AE [ (N) */
  88.    { 175,  92 },    /* OE \ (N) */
  89.    { 129,  93 },    /* AA ] (-) */
  90.    { 190, 123 },    /* ae { (N) */
  91.    { 191, 124 },    /* oe | (N) */
  92.    { 140, 125 },    /* aa } (-) */
  93.    { 128,  91 },    /* AE [ (S) */
  94.    { 133,  92 },    /* OE \ (S) */
  95.    { 138, 123 },    /* ae { (S) */
  96.    { 154, 124 },    /* oe | (S) */
  97.    {   0,   0 }
  98. };
  99.  
  100.  
  101. /*---( variables )----------------------------------------------------------*/
  102.  
  103. static unsigned char Buffer[BUFSIZE];       /* Output buffer                */
  104. static unsigned char CTable[256];           /* General fold matrix          */
  105.  
  106. static int  BuffSs = 0;                     /* Bona-fide chars. in string.  */
  107. static int  BuffXx = 0;                     /* Horisontal pos. in buffer.   */
  108. static int  NSpace = 0;                /* No. of spaces not flushed.   */
  109.  
  110.  
  111. /*---( forward )------------------------------------------------------------*/
  112.  
  113. char *getenv();
  114.  
  115.  
  116. /*---( housekeeping )-------------------------------------------------------*/
  117.  
  118. /*
  119. | Abs: Is it a control character?  (According to pep's rather complicated
  120. |      concept of such.)
  121. | Ret: TRUE if it is, else FALSE (pep hacks ctrl. chars, leave others alone).
  122. */
  123. static BOOL ctrlp(cc)
  124. int cc;
  125. {
  126.    if (isascii(cc)) {
  127.       if (wflag1 && (cc == WSSH)) return(FALSE);
  128.       if (iscntrl(cc)) return(TRUE); else return(FALSE);
  129.    } else if (!bflagb) return(FALSE);
  130.    /* Assert: if it was 7 bit ASCII, or if the upper 128 set shall be       */
  131.    /* considered legal character, then we have returned by now.             */
  132.  
  133.    if (wflag1 && (cc == WSSC)) return(FALSE);
  134.    /* Assert: if it was WordStar soft CR, then we have returned by now.     */
  135.  
  136.    if (iflagi && IFrst) {             /* We are folding to IBM charset,     */
  137.       int jj = 0;
  138.       while (ibmfold[jj][0] && (ibmfold[jj][0] != cc)) jj++;
  139.       return(!ibmfold[jj][0]);        /*    so those are not control chars. */
  140.    }
  141.    return(TRUE);
  142.    /* If all else fails, it must be a control character.                    */
  143. } /* ctrlp */
  144.  
  145.  
  146. /*---( transformation table )-----------------------------------------------*/
  147.  
  148. /*
  149. | Abs: Catenate tabledir and cname to create a full searchpath.
  150. | Ret: Pointer to the full, catenated path.
  151. */
  152. static char *findpath(tabledir,cname)
  153. char *tabledir, *cname;
  154. {
  155.    char fullpath[1024], *ss;
  156.  
  157.    if (!tabledir) return(cname); /* Bail out under VMS, etc.   */
  158.    ss = fullpath;
  159.    while (*ss++ = *tabledir++) ; /* strcpy(fullpath,tabledir); */
  160.    ss--;                         /* ss points to terminator    */
  161.    if (ss[-1] != DIRCHAR) { *ss = DIRCHAR; *++ss = '\0'; }
  162.    while (*ss++ = *cname++) ;    /* strcat(fullpath,cname); */
  163.    return(fullpath);
  164. } /* findpath */
  165.  
  166. /*
  167. | Abs: Initialize default transformation table.
  168. */
  169. void inittable()
  170. {
  171.    int cc;
  172.  
  173.    for (cc = 0; cc < 256; cc++) CTable[cc] = cc;
  174. } /* inittable */
  175.  
  176.  
  177. /*
  178. | Abs: Initialize transformation table from file.
  179. | Par: tabledir = pointer to table to initialize
  180. |      cname    = file to read table from
  181. |      echo     = TRUE to echo comments to stderr, else quiet.
  182. */
  183. void readtable(tabledir,cname,echo)
  184. char *tabledir, *cname;
  185. BOOL  echo;
  186. {
  187.    FILE *fdt;
  188.    char *ss;
  189.  
  190.    if ((fdt = fopen(cname,"r")) == NULL) {
  191.       if (tabledir) {
  192.          if (ss = strrchr(tabledir,DIRCHAR)) {
  193.             *++ss = '\0';
  194.             fdt = fopen(findpath(tabledir,cname),"r");
  195.          } /* if tabledir made sense */
  196.       } /* if tabledir defined */
  197.       if (fdt == NULL) {
  198. #ifndef __CPM86__
  199.          if (tabledir = getenv("PEP"))
  200.             fdt = fopen(findpath(tabledir,cname),"r");
  201. #endif
  202.          if (fdt == NULL) {
  203.             fprintf(stderr,"can't open translation table \"%s\"\n", cname);
  204.             exit(ERROR_EXIT);
  205.          } /* if file not found in environment directory */
  206.       } /* if file not found in startup directory */
  207.    } /* if file not found in local directory */
  208.  
  209.    while (fgets(Buffer,BUFSIZE-1,fdt)) {
  210.       char *ss;
  211.       int ii;
  212.       if (ss = strchr(Buffer,'#')) {
  213.       if (echo && (ss[1] != '#')) {
  214.              fputs("   ",stderr);
  215.              fputs(ss,stderr);
  216.           }
  217.           *ss = '\0';
  218.       } /* if comment */
  219.       for (ii = strlen(Buffer) - 1; isspace(Buffer[ii]) && (ii >= 0); ii--);
  220.       Buffer[++ii] = 0;
  221.       if (*Buffer) {
  222.          int tt, ff;
  223.          if (sscanf(Buffer,"%d %d",&ff,&tt) != 2) mess(6);
  224.          if ((tt < 0) || (tt > 255) || (ff < 0) || (ff > 255)) mess(6);
  225.          /* fprintf(stderr,"[%s] %d <== %d\n",Buffer,tt,ff); */
  226.          CTable[ff] = tt;
  227.       }
  228.    } /* while */
  229.    fclose(fdt);
  230. } /* readtable */
  231.  
  232.  
  233. /*---( foldings )-----------------------------------------------------------*/
  234.  
  235. /*
  236. | Abs:
  237. */
  238. static unsigned char fold8(cc,fold)
  239. int cc;
  240. FOLDMATRIX fold;
  241. {
  242.    if (cc >= ILimit) {
  243.       int jj = 0;
  244.       while (fold[jj][IFrst] && (fold[jj][IFrst] != cc)) jj++;
  245.       if (fold[jj][IFrst]) cc = fold[jj][ILast];
  246.    }
  247.    return(cc);
  248. } /* fold8 */
  249.  
  250.  
  251. /*
  252. | Abs: Flush accumulated whitespace, compressing spaces into tabs.
  253. */
  254. static void flushspace()
  255. {
  256.    int ii;
  257.  
  258.    if (cflagc && OTabSz) {
  259.       while (NSpace > 1 && NSpace >= (ii = OTabSz - (LineXx % OTabSz))) {
  260.            Buffer[BuffXx++] = '\t';
  261.          NSpace -= ii;
  262.          LineXx += ii;
  263.       } /* while */
  264.    } /* if compressing tabs */
  265.    LineXx += NSpace;
  266.    while (NSpace--) Buffer[BuffXx++] = ' ';
  267.    NSpace = 0;
  268. } /* flushspace */
  269.  
  270.  
  271. /*
  272. | Abs: Flush line in buffer to the output file.
  273. | Des: Turbo-C return bogus values if isspace is called with arg > 128.
  274. | Sef: Zero NSpace, BuffXx and LineXx counts.
  275. */
  276. static void flushline()
  277. {
  278.    if (!sflags || (BuffSs >= StrSiz)) {
  279.       while (!(Buffer[BuffXx-1] & 0x80) && isspace(Buffer[BuffXx-1]) && BuffXx)
  280.          BuffXx--;
  281.       Buffer[BuffXx] = '\0';
  282.       if (wflag1) {
  283.          int xx;
  284.          if (BuffXx && (Buffer[BuffXx-1] == '-')) Buffer[BuffXx-1] = WSSH;
  285.          xx = 0;
  286.          while (Buffer[xx]) {
  287.             if (Buffer[xx] == ' ') Buffer[xx] = WSSS;
  288.             xx++;
  289.          }
  290.       }
  291.       fputs(Buffer,Fdo);
  292.  
  293.       if      (vflagv) /* Paragraph only */ ;
  294.  
  295.       /* Terminate the line we have just flushed */
  296.       if (wflag1) {
  297.      if (BuffXx) putc(WSSC,Fdo); else putc('\r',Fdo);
  298.      putc('\n',Fdo);
  299.       } else {
  300.      if ((vflagv && BuffXx) || (EndOLn == -2)) putc(' ',Fdo);
  301.      else {
  302.         if (EndOLn == -1) { putc('\r',Fdo); putc('\n',Fdo); }
  303.         else putc(EndOLn,Fdo);
  304.      } /* if */
  305.       } /* if */
  306.       showprogress();
  307.    } /* if enough of a string to print it */
  308.    NSpace = BuffXx = LineXx = 0;
  309. } /* flushline */
  310.  
  311.  
  312. /*
  313. | Abs: Put character into line buffer.
  314. | Des: First, make some simple character foldings.  Then, put the character
  315. |      into a line buffer.  A control character may be converted to hex,
  316. |      surrounded by angle brackets.
  317. */
  318. static void putline(cc)
  319. int  cc;
  320. {
  321.    static BOOL wasbs = FALSE;
  322.    static BOOL wascr = FALSE;
  323.    static BOOL wasoe = FALSE;
  324.    BOOL        isaoe = FALSE;
  325.  
  326.    if (BuffXx >= (BUFSIZE-5)) flushline();          /* Panic!                    */
  327.    if (zflagz) cc = cc & 0x7f;                      /* Fold to 7 bit.            */
  328.    if (mflagm && !IFrst && (cc == '\r')) cc = '\n'; /* Mac uses CR as terminator */
  329.    /* This is a hack to fool the stuff below who removes redundant CR's.         */
  330.    /* When we are converting from Mac format, we want to keep them all.          */
  331.  
  332.    if (wasoe) {
  333.       wasoe = FALSE;
  334.       if (cc !=  92) {
  335.      Buffer[BuffXx] = '\\';
  336.      LineXx++;
  337.      BuffXx++;
  338.       } /* if */
  339.    } else if ((cc ==  92) && kflagk && IFrst) { wasoe++; return; }
  340.  
  341.    if (dflagd) { if (!IFrst && (cc == 216)) isaoe++; cc = fold8(cc,decfold); }
  342.    if (iflagi) { if (!IFrst && (cc == 157)) isaoe++; cc = fold8(cc,ibmfold); }
  343.    if (mflagm) { if (!IFrst && (cc == 175)) isaoe++; cc = fold8(cc,macfold); }
  344.    if (gflagg) cc = CTable[cc];               /* Fold from table.           */
  345.    if (wflag0) {
  346.       if (cc == WSHH) return;                 /* WS invisible soft hyphen.  */
  347.       if (cc == WSSH) cc = '-';               /* WS   visible soft hyphen.  */
  348.    }
  349.  
  350.    if (wascr) {
  351.       wascr = FALSE;
  352.       if (BuffXx) {
  353.          flushline();
  354.          if (cc == '\n') return;
  355.       } /* if anything in buffer */
  356.    } /* if wascr */
  357.  
  358.    if     ((cc == '\b') && BuffXx) { BuffXx--; wasbs++; }
  359.    else if (cc == '\f') {
  360.       if (BuffXx) flushline();
  361.       if (wflag1) fputs(".PA\n",Fdo);
  362.       else if (!(bflagb + sflags)) putc('\f',Fdo);
  363.       wasbs = FALSE;
  364.    }
  365.    else if (cc == '\n') { flushline(); BuffSs++; }
  366.    else if (cc == '\r') { wascr++; }
  367.    else if (cc == '\t') {
  368.       if (tflagt || cflagc) NSpace += ITabSz - ((LineXx + NSpace) % ITabSz);
  369.       else { Buffer[BuffXx++] = cc; LineXx++; }
  370.       BuffSs++;
  371.       wasbs = FALSE;
  372.    }
  373.    else if (ctrlp(cc)) {
  374.       if (xflagx) {                       /* Expanding control chars. */
  375.          char *ss;
  376.          if (NSpace) flushspace();
  377.          ss = (char *)&Buffer[BuffXx];
  378.          sprintf(ss,"<%02xh>",cc);
  379.          BuffXx += 5;
  380.          LineXx += 5;
  381.       }
  382.       else if (BuffXx) flushline(); /* Removing  control chars. */
  383.       BuffSs = 0;
  384.       wasbs  = FALSE;
  385.    }
  386.    else if (cflagc && cc == ' ') NSpace++;
  387.    else {
  388.       if (NSpace) flushspace();
  389.       if (!wasbs || (cc != '_')) Buffer[BuffXx] = cc;
  390.       LineXx++;
  391.       BuffXx++;
  392.       if (kflagk && isaoe) {
  393.      Buffer[BuffXx] = cc;
  394.      LineXx++;
  395.      BuffXx++;
  396.       }
  397.       BuffSs++;
  398.       wasbs = FALSE;
  399.    }
  400. } /* putline */
  401.  
  402.  
  403. /*---( file loop )----------------------------------------------------------*/
  404.  
  405. /*
  406. | Abs: Read (and write) one complete plain file.
  407. */
  408. void doplain()
  409. {
  410.    int cc;
  411.  
  412.    while ((cc = getc(Fdi)) != EOF) putline(cc);
  413.    if (BuffXx) flushline();
  414. } /* doplain */
  415.  
  416. /* EOF */
  417.