home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / pcmail / part05 / ascf.c next >
C/C++ Source or Header  |  1989-02-03  |  4KB  |  147 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. /*    FILE *ascopen(name,mode)
  12. /*    char *name;
  13. /*    char *mode;
  14. /*
  15. /*    int ascget(fp)
  16. /*    FILE *fp;
  17. /*
  18. /*    int ascclose(fp)
  19. /*    FILE *fp;
  20. /* DESCRIPTION
  21. /*    The functions in this module provide filtered stream i/o for
  22. /*    textfiles produced by word processors. Their calling sequence
  23. /*    has been modelled after the standard i/o library routines.
  24. /*
  25. /*    ascopen() is the analogon of fopen(3), ascget() returns the next
  26. /*    character in the filtered input stream, and ascclose() closes 
  27. /*    the stream. ascget() is a macro.
  28. /*
  29. /*    The following mappings are done: cr/lf, cr, lf, lf/cr are 
  30. /*    replaced by newline; all high bits are stripped off; wordstar
  31. /*    hyphens are converted to normal hyphens. Except for tabs,
  32. /*    all control characters are suppressed in the output.
  33. /*    In order to avoid problems in mailers, a newline
  34. /*    character is appended to the last line of each file.
  35. /* SEE ALSO
  36. /*    stdio(3)    standard i/o library interface.
  37. /* DIAGNOSTICS
  38. /*    ascopen() returns a null pointer on failure; ascget() returns
  39. /*    the value EOF when the end of a stream is reached. ascclose()
  40. /*    returns whatever fclose() returns.
  41. /* BUGS
  42. /*    Actually works with wordstar or clean ascii files only.
  43. /*    No character pushback.
  44. /*    Although allowed by ascopen(), the "w" file open mode is 
  45. /*    of no use. 
  46. /* AUTHOR(S)
  47. /*    W.Z. Venema
  48. /*    Eindhoven University of Technology
  49. /*    Department of Mathematics and Computer Science
  50. /*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  51. /* CREATION DATE
  52. /*    Mon Jul  6 16:03:41 GMT+1:00 1987
  53. /* LAST MODIFICATION
  54. /*    Mon Apr  4 23:34:46 MET 1988
  55. /* VERSION/RELEASE
  56. /*    1.4
  57. /*--*/
  58.  
  59. #include <ctype.h>
  60.  
  61. #include "defs.h"
  62. #include "ascf.h"
  63.  
  64. /* some systems do not define _NFILE in stdio.h */
  65.  
  66. #ifndef _NFILE
  67. #  include <sys/param.h>        /* maybe we are a sun */
  68. #    ifdef NOFILE
  69. #    define _NFILE NOFILE
  70. #  else
  71. "ERROR: cannot get max nr of open files"
  72. #  endif
  73. #endif
  74.  
  75. #define CTRL(x) ((x)^0100)        /* ASCII control characters */
  76.  
  77. #ifdef MSDOS
  78. #include <fcntl.h>            /* to turn cr/lf mapping off */
  79. #endif
  80.  
  81. public Asc asc[_NFILE];            /* one filter structure per file */
  82.  
  83. /* ascopen - open stream, initialize intermediate buffer */
  84.  
  85. public FILE *ascopen(file,mode)
  86. char *file,*mode;
  87. {
  88.     register FILE *fp;
  89.  
  90.     if (fp = fopen(file,mode)) {    /* if file is accessable */
  91.     register Asc *ap = asc+fileno(fp);
  92.     if (ap->buf = malloc(BUFSIZ)) {    /* if buffer available */
  93.         ap->cnt = 0;        /* init buffer count */
  94.         ap->nlf = 0;        /* no newline appended yet */
  95. #ifdef O_BINARY
  96.         setmode(fileno(fp),O_BINARY);
  97. #endif
  98.     } else {
  99.         fclose(fp);            /* no room for that buffer */
  100.         fp = 0;
  101.      }
  102.     }
  103.     return(fp);
  104. }
  105.  
  106. /* ascclose - release intermediate buffer and close the stream */
  107.  
  108. public int ascclose(fp)
  109. register FILE *fp;
  110. {
  111.     free(asc[fileno(fp)].buf);
  112.     return(fclose(fp));
  113. }
  114.  
  115. /* ascbuf - ascii filter, make new buffer of text */
  116.  
  117. public int ascbuf(fp)
  118. FILE *fp;
  119. {
  120.     register Asc *ap = asc+fileno(fp);    /* intermediate buffer access */
  121.     register char *cp = ap->buf;    /* init write pointer */
  122.     register int c;            /* single-character input buffer */
  123.     int d;                /* look-ahead character */
  124.  
  125.     while (cp < ap->buf+BUFSIZ && 
  126.     (c = getc(fp)) != EOF && (c &= 0177) != CTRL('Z')) {
  127.     if (c == ' ' || isprint(c) || c == '\t') {
  128.         *cp++ = c;            /* accept character */
  129.     } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1)))
  130.         || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) {
  131.         *cp++ = '\n';        /* terminate line */
  132.     } else if (c == CTRL('_')) {
  133.         *cp++ = '-';        /* wordstar hyphen */
  134.     } else {
  135.         continue;            /* ignore other characters */
  136.     }
  137.     }
  138.     if (ap->cnt = cp-ap->buf) {        /* anything in the buffer? */
  139.     ap->ptr = ap->buf;        /* yes, set read pointer */
  140.     return(ascget(fp));        /* and return first character */
  141.     } else if (ap->nlf == 0) {        /* make sure file ends with \n */
  142.         return(ap->nlf = '\n');        /* append newline first */
  143.     } else {                /* now we're really done */
  144.     return(EOF);            /* that's it. */
  145.     }
  146. }
  147.