home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume3
/
pcmail
/
part05
/
ascf.c
next >
Wrap
C/C++ Source or Header
|
1989-02-03
|
4KB
|
147 lines
/*++
/* 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. */
}
}