2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
4 \subsection[fileGetc.lc]{hGetChar Runtime Support}
14 /* Pre-condition: only ever called on a readable fileObject */
19 IOFileObject* fo = (IOFileObject*)ptr;
24 fprintf(stderr, "fgc: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->flags);
27 fileGetc does the following:
28 - if the input is buffered, try fetch the char from buffer.
31 - if the input stream is 'connected' to an output stream,
32 flush it before requesting any input.
33 - if unbuffered, read in one character.
34 - if line-buffered, read in one line, returning the first.
35 - if block-buffered, fill up block, returning the first.
38 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
39 rc = flushBuffer(ptr);
40 if (rc < 0) return rc;
43 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
45 if ( FILEOBJ_IS_EOF(fo) ) {
46 ghc_errtype = ERR_EOF;
51 if ( FILEOBJ_BUFFER_EMPTY(fo) ) {
53 } else if ( FILEOBJ_UNBUFFERED(fo) && !FILEOBJ_HAS_PUSHBACKS(fo) ) {
55 } else if ( FILEOBJ_UNBUFFERED(fo) ) { /* Unbuffered stream has pushbacks, retrieve them */
56 c=((unsigned char*)(fo->buf))[fo->bufRPtr++];
59 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
64 /* Nothing in the buffer, go out and fetch a byte for our customer,
65 filling up the buffer if needs be.
67 if ( FILEOBJ_UNBUFFERED(fo) ) {
68 return (readChar(ptr));
69 } else if ( FILEOBJ_LINEBUFFERED(fo) ) {
71 /* if input stream is connect to an output stream, flush it first */
72 if ( fo->connectedTo != NULL &&
73 fo->connectedTo->fd != -1 &&
74 (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
75 rc = flushFile((StgForeignObj)fo->connectedTo);
77 if (rc < 0) return rc;
79 rc = fill_up_line_buffer(fo);
80 if (rc < 0) return rc;
82 c=((unsigned char*)(fo->buf))[fo->bufRPtr];
86 } else { /* Fully-buffered */
88 if (rc < 0) return rc;
90 c=((unsigned char*)(fo->buf))[fo->bufRPtr];