#ifndef lint static char *rcs = "$Header: getc.c,v 1.1 88/01/15 13:04:03 simpson Rel $"; #endif /* $Log: getc.c,v $ * Revision 1.1 88/01/15 13:04:03 simpson * initial release * * Revision 0.1 87/12/11 18:30:55 simpson * beta test * */ /* Secure getc(3) routines. These routines provide a set of standard I/O * functions for reading data from files. The routines are essentially * identical to their standard I/O equivalents except that these routines * check for EOF. If EOF is encountered, a function determined by the user is * called. This is useful if you are reading from a file, such as a TeX DVI * file or troff file, and you want to check to see if the file ends * prematurely without putting checks in every time you call getc(), gets(), * etc. When reading a DVI file for example, you know when a file should end * by the context, so if it does end prematurely, you can call an error * routine. The following functions are provided: * * void seteoffunction(f) * void (*f)(); * * Sets the function to call if EOF is reached when reading with any of the * routines. The function is assumed not to return although returning is * allowed. * * int cgetc(f) * FILE *f; * * Just like getc(3) but it checks for EOF. If EOF is encountered, the * function set in seteoffunction() is called. (It is really more like * fgetc(3) since it is not a macro). * * int cgetchar() * * Equivalent to cgetc(stdin). It's not a macro since we would need an * include file. * * int cgetw(f) * FILE *f; * * Just like getw(3) but is checks for EOF. If EOF is encountered, the * function set in seteoffunction() is called. * * char *cgets(s) * char *s; * * Just like gets(3) except it checks for EOF. This is a little lie. * Actually it only calls the function set in seteoffunction if it * encounters EOF on the first character read. The rationale behind this is * that you probably want the last line of a file even if it doesn't end with * a newline. * * char *cfgets(s, n, stream) * char *s; * int n; * FILE *stream; * * Just like fgets(3) except it checks for EOF. Again, it only calls the * eof function if the first character read returns EOF. * * int cfread(ptr, size, nitems, stream) * char *ptr; * int size; * int nitems; * FILE *stream; * * Just like fread(3) except it checks for EOF. The size read must be the * size expected. */ #include #include static void (*EOFFunction)(); void seteoffunction(f) void (*f)(); { EOFFunction = f; } int cgetc(f) FILE *f; { int c; if ((c = getc(f)) == EOF) { if (EOFFunction) (*EOFFunction)(); } else return c; return EOF; /* Only if EOFFunction returns or is NULL */ } int cgetchar() { return cgetc(stdin); } int cgetw(f) FILE *f; { int w; w = getw(f); if (feof(f)) { if (EOFFunction) (*EOFFunction)(); } else return w; return EOF; /* Only if EOFFunction returns or is NULL */ } char *cgets(s) char *s; { int c; char *p = s; for (c = getchar(); c != '\n' && c != EOF; c = getchar()) *p++ = c; if (c == EOF && p == s) { if (EOFFunction) (*EOFFunction)(); } else { *p = '\0'; return s; } return NULL; /* Only if EOFFunction returns or is NULL */ } char *cfgets(s, n, stream) char *s; int n; FILE *stream; { int c = '\0'; char *p = s, *strcat(); while (p - s < n - 1 && (c = getc(stream)) != '\n' && c != EOF) *p++ = c; if (c == EOF && p == s) { if (EOFFunction) (*EOFFunction)(); } else { *p = '\0'; if (c == '\n') (void)strcat(s, "\n"); return s; } return NULL; /* Only if EOFFunction returns or is NULL */ } int cfread(ptr, size, nitems, stream) char *ptr; int size; int nitems; FILE *stream; { if (fread(ptr, size, nitems, stream) != nitems) if (EOFFunction) (*EOFFunction)(); return nitems; }