2 * Copyright (c) 1990 The Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static char sccsid
[] = "%W% (Berkeley) %G%";
20 #endif /* LIBC_SCCS and not lint */
28 * Expand the ungetc buffer `in place'. That is, adjust fp->_p when
29 * the buffer moves, so that it points the same distance from the end,
30 * and move the bytes in the buffer around as necessary so that they
31 * are all at the end (stack-style).
40 register unsigned char *p
;
42 if (fp
->_ub
._base
== fp
->_ubuf
)
45 * Get a new buffer (rather than expanding the old one).
47 if ((p
= (unsigned char *) _malloc_r (_REENT
, (size_t) BUFSIZ
)) == NULL
)
50 fp
->_ub
._size
= BUFSIZ
;
51 p
+= BUFSIZ
- sizeof (fp
->_ubuf
);
52 for (i
= sizeof (fp
->_ubuf
); --i
>= 0;)
58 p
= (unsigned char *) _realloc_r (_REENT
, (_PTR
) (fp
->_ub
._base
), i
<< 1);
61 (void) memcpy ((void *) (p
+ i
), (void *) p
, (size_t) i
);
64 fp
->_ub
._size
= i
<< 1;
78 /* Ensure stdio has been initialized.
79 ??? Might be able to remove this as some other stdio routine should
80 have already been called to get the char we are un-getting. */
84 /* After ungetc, we won't be at eof anymore */
85 fp
->_flags
&= ~__SEOF
;
87 if ((fp
->_flags
& __SRD
) == 0)
90 * Not already reading: no good unless reading-and-writing.
91 * Otherwise, flush any current write stuff.
93 if ((fp
->_flags
& __SRW
) == 0)
98 if (fp
->_flags
& __SWR
)
105 fp
->_flags
&= ~__SWR
;
111 c
= (unsigned char) c
;
114 * If we are in the middle of ungetc'ing, just continue.
115 * This may require expanding the current ungetc buffer.
120 if (fp
->_r
>= fp
->_ub
._size
&& __submore (fp
))
132 * If we can handle this by simply backing up, do so,
133 * but never replace the original character.
134 * (This makes sscanf() work when scanning `const' data.)
137 if (fp
->_bf
._base
!= NULL
&& fp
->_p
> fp
->_bf
._base
&& fp
->_p
[-1] == c
)
146 * Create an ungetc buffer.
147 * Initially, we will use the `reserve' buffer.
152 fp
->_ub
._base
= fp
->_ubuf
;
153 fp
->_ub
._size
= sizeof (fp
->_ubuf
);
154 fp
->_ubuf
[sizeof (fp
->_ubuf
) - 1] = c
;
155 fp
->_p
= &fp
->_ubuf
[sizeof (fp
->_ubuf
) - 1];