home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / ascf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.4 KB  |  197 lines

  1. /*++
  2. /* NAME
  3. /*    ascf 3
  4. /* SUMMARY
  5. /*    stdio-like ascii filter
  6. /* PROJECT
  7. /*    pc-mail
  8. /* PACKAGE
  9. /*    ascii filtering
  10. /* SYNOPSIS
  11. /*    #include <stdio.h>
  12. /*    #include "ascf.h"
  13. /*
  14. /*    FILE *ascopen(name,mode)
  15. /*    char *name;
  16. /*    char *mode;
  17. /*
  18. /*    int ascget(fp)
  19. /*    FILE *fp;
  20. /*
  21. /*    ascpbk(c,fp)
  22. /*    int c;
  23. /*    FILE *fp;
  24. /*
  25. /*    char *ascgets(buf,buflen,fp);
  26. /*    char *buf;
  27. /*    int buflen;
  28. /*    FILE *fp;
  29. /*
  30. /*    int ascclose(fp)
  31. /*    FILE *fp;
  32. /* DESCRIPTION
  33. /*    The functions in this module provide filtered stream i/o for
  34. /*    textfiles produced by word processors. Their calling sequence
  35. /*    has been modelled after the standard i/o library routines.
  36. /*
  37. /*    The following mappings are done: cr/lf, cr, lf, lf/cr are 
  38. /*    replaced by newline; all high bits are stripped off; wordstar
  39. /*    hyphens are converted to normal hyphens. Except for tabs and backspace,
  40. /*    control characters are filtered out. A newline
  41. /*    character is appended to the last line of a file if that file
  42. /*    does not terminate on a newline character.
  43. /*
  44. /*    ascopen() is the analogon of fopen(3), ascget() returns the next
  45. /*    character in the filtered input stream, and ascclose() closes 
  46. /*    the stream. ascget() is a macro. A "feature" of the ascopen()
  47. /*    function is that it interprets a file name "-" as standard
  48. /*    input (and ignores the mode argument in that case).
  49. /*
  50. /*    ascpbk() pushes back the last character read with ascget().
  51. /*
  52. /*    ascgets() reads one string and strips trailing newline or carriage
  53. /*    return characters. A null pointer is returned if no string could
  54. /*    be read, otherwise ascgets() returns a pointer to the buffer.
  55. /* SEE ALSO
  56. /*    stdio(3)    standard i/o library interface.
  57. /* DIAGNOSTICS
  58. /*    ascopen() returns a null pointer on failure; ascget() returns
  59. /*    the value EOF when the end of a stream is reached. ascclose()
  60. /*    returns whatever fclose() returns.
  61. /* BUGS
  62. /*    Actually works well with wordstar or clean ascii files only.
  63. /*
  64. /*    Only "r" modes are supported.
  65. /*
  66. /*    There is no way to seek() a filtered stream.
  67. /* AUTHOR(S)
  68. /*    W.Z. Venema
  69. /*    Eindhoven University of Technology
  70. /*    Department of Mathematics and Computer Science
  71. /*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  72. /* CREATION DATE
  73. /*    Mon Jul  6 16:03:41 GMT+1:00 1987
  74. /* LAST MODIFICATION
  75. /*    90/01/22 13:01:14
  76. /* VERSION/RELEASE
  77. /*    2.1
  78. /*--*/
  79.  
  80. #include <stdio.h>
  81. #include <ctype.h>
  82.  
  83. #include "defs.h"
  84. #include "ascf.h"
  85.  
  86. /* some systems do not define _NFILE in stdio.h; not that they should, but.. */
  87.  
  88. #ifndef _NFILE
  89. #  include <sys/param.h>        /* maybe we are a sun */
  90. #    ifdef NOFILE
  91. #    define _NFILE NOFILE
  92. #  else
  93. "ERROR: cannot get max nr of open stdio streams"
  94. #  endif
  95. #endif
  96.  
  97. #define CTL(x) ((x)^0100)        /* ASCII control characters */
  98.  
  99. #ifdef MSDOS
  100. #include <fcntl.h>            /* to turn cr/lf mapping off */
  101. #endif
  102.  
  103. public Asc asc[_NFILE];        /* one filter structure per file */
  104.  
  105. /* ascopen - open stream, initialize intermediate buffer */
  106.  
  107. public FILE *ascopen(file,mode)
  108. char *file,*mode;
  109. {
  110.     register FILE *fp;
  111.  
  112.     if (*mode != 'r')            /* Cannot do filtered writes */
  113.     return(0);
  114.  
  115.     if (fp = (strcmp(file, "-") ? fopen(file,mode) : stdin)) {
  116.     register Asc *ap = asc+fileno(fp);
  117.     if (ap->buf = malloc(BUFSIZ)) {    /* if buffer available */
  118.         ap->cnt = 0;        /* init buffer count */
  119.         ap->nlf = 0;        /* no newline appended yet */
  120. #ifdef O_BINARY
  121.         setmode(fileno(fp),O_BINARY);
  122. #endif
  123.     } else {
  124.         (void) fclose(fp);        /* no room for that buffer */
  125.         fp = 0;
  126.      }
  127.     }
  128.     return(fp);
  129. }
  130.  
  131. /* ascclose - release intermediate buffer and close the stream */
  132.  
  133. public int ascclose(fp)
  134. register FILE *fp;
  135. {
  136.     free(asc[fileno(fp)].buf);
  137.     return(fclose(fp));
  138. }
  139.  
  140. /* ascbuf - the actual filter, fill one new buffer of text */
  141.  
  142. public int ascbuf(fp)
  143. FILE *fp;
  144. {
  145.     register Asc *ap = asc+fileno(fp);    /* intermediate buffer access */
  146.     register char *cp = ap->buf;    /* initialize write pointer */
  147.     register int c;            /* single-character input buffer */
  148.     int d;                /* look-ahead character */
  149.  
  150.     while (cp < ap->buf+BUFSIZ && (c = getc(fp)) != EOF) {
  151.     if ((c &= 0177) == ' ' || isprint(c) || c == '\t' || c == '\b') {
  152.         *cp++ = c;            /* accept character */
  153.     } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1)))
  154.         || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) {
  155.         *cp++ = '\n';        /* terminate line */
  156.     } else if (c == CTL('_')) {
  157.         *cp++ = '-';        /* wordstar hyphen */
  158.     } else {
  159.         continue;            /* ignore other characters */
  160.     }
  161.     }
  162.     if (ap->cnt = cp-ap->buf) {        /* anything in the buffer? */
  163.     ap->ptr = ap->buf;        /* yes, set read pointer */
  164.     ap->nlf = cp[-1];        /* remember last character */
  165.     return(ascget(fp));        /* and return first character */
  166.     } else if (ap->nlf != '\n') {    /* make sure file ends with \n */
  167.         return(ap->nlf = '\n');        /* append newline */
  168.     } else {                /* now we're really done */
  169.     return(EOF);            /* that's it. */
  170.     }
  171. }
  172.  
  173. /* ascgets - read string, strip crlf */
  174.  
  175. public char *ascgets(buf, buflen, fp)
  176. char   *buf;
  177. int     buflen;
  178. FILE   *fp;
  179. {
  180.     register int c;
  181.     register char *cp = buf;
  182.     register char *ce = buf + buflen - 1;
  183.  
  184.     while ((c = ascget(fp)) != EOF) {
  185.     if (c == '\n') {            /* suppress crlf */
  186.         break;
  187.     } else if (cp < ce) {            /* will fit */
  188.         *cp++ = c;
  189.     } else {                /* push back */
  190.         ascpbk(c, fp);
  191.         break;
  192.     }
  193.     }
  194.     *cp = 0;
  195.     return ((c == EOF && cp == buf) ? 0 : buf);
  196. }
  197.