]> Git Repo - uclibc-ng.git/blame - libc/stdio/ungetc.c
make sure TARGET_ARCH is set ... thought i committed this already?
[uclibc-ng.git] / libc / stdio / ungetc.c
CommitLineData
082e680b
MNI
1/* Copyright (C) 2004 Manuel Novoa III <[email protected]>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8#include "_stdio.h"
9
10/* Having ungotten characters implies the stream is reading.
11 * The scheme used here treats the least significant 2 bits of
12 * the stream's modeflags member as follows:
13 * 0 0 Not currently reading.
14 * 0 1 Reading, but no ungetc() or scanf() push back chars.
15 * 1 0 Reading with one ungetc() char (ungot[1] is 1)
16 * or one scanf() pushed back char (ungot[1] is 0).
17 * 1 1 Reading with both an ungetc() char and a scanf()
18 * pushed back char. Note that this must be the result
19 * of a scanf() push back (in ungot[0]) _followed_ by
20 * an ungetc() call (in ungot[1]).
21 *
22 * Notes:
23 * scanf() can NOT use ungetc() to push back characters.
24 * (See section 7.19.6.2 of the C9X rationale -- WG14/N897.)
25 */
26
27int ungetc(int c, register FILE *stream)
28{
29 __STDIO_AUTO_THREADLOCK_VAR;
30
31 __STDIO_AUTO_THREADLOCK(stream);
32 __STDIO_STREAM_VALIDATE(stream);
33
34#ifdef __UCLIBC_MJN3_ONLY__
35#warning CONSIDER: Make fast ungetc an option?
36#endif
37#ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__
38 /* If buffered narrow reading with no ungot slots filled, and if not
39 * ungetting a different char than the one last read from the buffer,
40 * we can simply decrement the position and not worry about disabling
41 * the getc macros. This will cut down on overhead in applications
42 * that use getc/ungetc extensively (like gcc). */
43 /* NOTE: If we can use getc, then we are buffered narrow reading with
44 * no ungot slots filled. */
45 if (__STDIO_STREAM_CAN_USE_BUFFER_GET(stream)
46 && (c != EOF)
47 && (stream->__bufpos > stream->__bufstart)
48 && (stream->__bufpos[-1] == ((unsigned char)c))
49 ) {
50 --stream->__bufpos;
51 __STDIO_STREAM_CLEAR_EOF(stream); /* Must clear end-of-file flag. */
52 } else
53#endif
54 /* Note: Even if c == EOF, we need to initialize/verify the
55 * stream's orientation and ensure the stream is in reading
56 * mode (if readable and properly oriented). */
57 if ((!__STDIO_STREAM_IS_NARROW_READING(stream)
58 && __STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_NARROW))
59 || ((stream->__modeflags & __FLAG_UNGOT)
60 && ((stream->__modeflags & 1) || stream->__ungot[1]))
61 ) {
62 c = EOF;
63 } else if (c != EOF) {
64 __STDIO_STREAM_DISABLE_GETC(stream);
65
66 /* Flag this as a user ungot, as scanf does the necessary fixup. */
67 stream->__ungot[1] = 1;
68 stream->__ungot[(++stream->__modeflags) & 1] = c;
69
70 __STDIO_STREAM_CLEAR_EOF(stream); /* Must clear end-of-file flag. */
71 }
72
73 __STDIO_STREAM_VALIDATE(stream);
74 __STDIO_AUTO_THREADUNLOCK(stream);
75
76 return c;
77}
This page took 0.074258 seconds and 4 git commands to generate.