home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* ascf 3
- /* SUMMARY
- /* stdio-like ascii filter
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* ascii filtering
- /* SYNOPSIS
- /* FILE *ascopen(name,mode)
- /* char *name;
- /* char *mode;
- /*
- /* int ascget(fp)
- /* FILE *fp;
- /*
- /* int ascclose(fp)
- /* FILE *fp;
- /* DESCRIPTION
- /* The functions in this module provide filtered stream i/o for
- /* textfiles produced by word processors. Their calling sequence
- /* has been modelled after the standard i/o library routines.
- /*
- /* ascopen() is the analogon of fopen(3), ascget() returns the next
- /* character in the filtered input stream, and ascclose() closes
- /* the stream. ascget() is a macro.
- /*
- /* The following mappings are done: cr/lf, cr, lf, lf/cr are
- /* replaced by newline; all high bits are stripped off; wordstar
- /* hyphens are converted to normal hyphens. Except for tabs,
- /* all control characters are suppressed in the output.
- /* In order to avoid problems in mailers, a newline
- /* character is appended to the last line of each file.
- /* SEE ALSO
- /* stdio(3) standard i/o library interface.
- /* DIAGNOSTICS
- /* ascopen() returns a null pointer on failure; ascget() returns
- /* the value EOF when the end of a stream is reached. ascclose()
- /* returns whatever fclose() returns.
- /* BUGS
- /* Actually works with wordstar or clean ascii files only.
- /* No character pushback.
- /* Although allowed by ascopen(), the "w" file open mode is
- /* of no use.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Jul 6 16:03:41 GMT+1:00 1987
- /* LAST MODIFICATION
- /* Mon Apr 4 23:34:46 MET 1988
- /* VERSION/RELEASE
- /* 1.4
- /*--*/
-
- #include <ctype.h>
-
- #include "defs.h"
- #include "ascf.h"
-
- /* some systems do not define _NFILE in stdio.h */
-
- #ifndef _NFILE
- # include <sys/param.h> /* maybe we are a sun */
- # ifdef NOFILE
- # define _NFILE NOFILE
- # else
- "ERROR: cannot get max nr of open files"
- # endif
- #endif
-
- #define CTRL(x) ((x)^0100) /* ASCII control characters */
-
- #ifdef MSDOS
- #include <fcntl.h> /* to turn cr/lf mapping off */
- #endif
-
- public Asc asc[_NFILE]; /* one filter structure per file */
-
- /* ascopen - open stream, initialize intermediate buffer */
-
- public FILE *ascopen(file,mode)
- char *file,*mode;
- {
- register FILE *fp;
-
- if (fp = fopen(file,mode)) { /* if file is accessable */
- register Asc *ap = asc+fileno(fp);
- if (ap->buf = malloc(BUFSIZ)) { /* if buffer available */
- ap->cnt = 0; /* init buffer count */
- ap->nlf = 0; /* no newline appended yet */
- #ifdef O_BINARY
- setmode(fileno(fp),O_BINARY);
- #endif
- } else {
- fclose(fp); /* no room for that buffer */
- fp = 0;
- }
- }
- return(fp);
- }
-
- /* ascclose - release intermediate buffer and close the stream */
-
- public int ascclose(fp)
- register FILE *fp;
- {
- free(asc[fileno(fp)].buf);
- return(fclose(fp));
- }
-
- /* ascbuf - ascii filter, make new buffer of text */
-
- public int ascbuf(fp)
- FILE *fp;
- {
- register Asc *ap = asc+fileno(fp); /* intermediate buffer access */
- register char *cp = ap->buf; /* init write pointer */
- register int c; /* single-character input buffer */
- int d; /* look-ahead character */
-
- while (cp < ap->buf+BUFSIZ &&
- (c = getc(fp)) != EOF && (c &= 0177) != CTRL('Z')) {
- if (c == ' ' || isprint(c) || c == '\t') {
- *cp++ = c; /* accept character */
- } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1)))
- || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) {
- *cp++ = '\n'; /* terminate line */
- } else if (c == CTRL('_')) {
- *cp++ = '-'; /* wordstar hyphen */
- } else {
- continue; /* ignore other characters */
- }
- }
- if (ap->cnt = cp-ap->buf) { /* anything in the buffer? */
- ap->ptr = ap->buf; /* yes, set read pointer */
- return(ascget(fp)); /* and return first character */
- } else if (ap->nlf == 0) { /* make sure file ends with \n */
- return(ap->nlf = '\n'); /* append newline first */
- } else { /* now we're really done */
- return(EOF); /* that's it. */
- }
- }
-