2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: fileGetc.c,v 1.6 2000/01/18 12:41:03 simonmar Exp $
6 * hGetChar Runtime Support
14 /* Pre-condition: only ever called on a readable fileObject */
16 fileGetc(StgForeignPtr ptr)
18 IOFileObject* fo = (IOFileObject*)ptr;
23 fprintf(stderr, "fgc: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->flags);
26 fileGetc does the following:
27 - if the input is buffered, try fetch the char from buffer.
30 - if the input stream is 'connected' to an output stream,
31 flush it before requesting any input.
32 - if unbuffered, read in one character.
33 - if line-buffered, read in one line, returning the first.
34 - if block-buffered, fill up block, returning the first.
37 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
38 rc = flushBuffer(ptr);
39 if (rc < 0) return rc;
42 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
44 if ( FILEOBJ_IS_EOF(fo) ) {
45 ghc_errtype = ERR_EOF;
50 if ( FILEOBJ_BUFFER_EMPTY(fo) ) {
52 } else if ( FILEOBJ_UNBUFFERED(fo) && !FILEOBJ_HAS_PUSHBACKS(fo) ) {
54 } else if ( FILEOBJ_UNBUFFERED(fo) ) { /* Unbuffered stream has pushbacks, retrieve them */
55 c=((unsigned char*)(fo->buf))[fo->bufRPtr++];
58 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
63 /* Nothing in the buffer, go out and fetch a byte for our customer,
64 filling up the buffer if needs be.
66 if ( FILEOBJ_UNBUFFERED(fo) ) {
67 return (readChar(ptr));
68 } else if ( FILEOBJ_LINEBUFFERED(fo) ) {
70 /* if input stream is connect to an output stream, flush it first */
71 if ( fo->connectedTo != NULL &&
72 fo->connectedTo->fd != -1 &&
73 (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
74 rc = flushFile((StgForeignPtr)fo->connectedTo);
76 if (rc < 0) return rc;
78 rc = fill_up_line_buffer(fo);
79 if (rc < 0) return rc;
81 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
85 } else { /* Fully-buffered */
87 if (rc < 0) return rc;
89 c=((unsigned char*)(fo->buf))[fo->bufRPtr];