2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: fileGetc.c,v 1.3 1998/12/02 13:27:23 simonm Exp $
6 * hGetChar Runtime Support
15 /* Pre-condition: only ever called on a readable fileObject */
20 IOFileObject* fo = (IOFileObject*)ptr;
25 fprintf(stderr, "fgc: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->flags);
28 fileGetc does the following:
29 - if the input is buffered, try fetch the char from buffer.
32 - if the input stream is 'connected' to an output stream,
33 flush it before requesting any input.
34 - if unbuffered, read in one character.
35 - if line-buffered, read in one line, returning the first.
36 - if block-buffered, fill up block, returning the first.
39 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
40 rc = flushBuffer(ptr);
41 if (rc < 0) return rc;
44 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
46 if ( FILEOBJ_IS_EOF(fo) ) {
47 ghc_errtype = ERR_EOF;
52 if ( FILEOBJ_BUFFER_EMPTY(fo) ) {
54 } else if ( FILEOBJ_UNBUFFERED(fo) && !FILEOBJ_HAS_PUSHBACKS(fo) ) {
56 } else if ( FILEOBJ_UNBUFFERED(fo) ) { /* Unbuffered stream has pushbacks, retrieve them */
57 c=((unsigned char*)(fo->buf))[fo->bufRPtr++];
60 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
65 /* Nothing in the buffer, go out and fetch a byte for our customer,
66 filling up the buffer if needs be.
68 if ( FILEOBJ_UNBUFFERED(fo) ) {
69 return (readChar(ptr));
70 } else if ( FILEOBJ_LINEBUFFERED(fo) ) {
72 /* if input stream is connect to an output stream, flush it first */
73 if ( fo->connectedTo != NULL &&
74 fo->connectedTo->fd != -1 &&
75 (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
76 rc = flushFile((StgForeignPtr)fo->connectedTo);
78 if (rc < 0) return rc;
80 rc = fill_up_line_buffer(fo);
81 if (rc < 0) return rc;
83 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
87 } else { /* Fully-buffered */
89 if (rc < 0) return rc;
91 c=((unsigned char*)(fo->buf))[fo->bufRPtr];