1 /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
3 * GNU Library General Public License (LGPL) version 2 or later.
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
10 /* Both ftell() and fseek() (for SEEK_CUR) need to correct the stream's
11 * position to take into account buffered data and ungotten chars.
13 * If successful, store corrected position in *pos and return >= 0.
14 * Otherwise return < 0.
16 * If position is unrepresentable, set errno to EOVERFLOW.
19 int attribute_hidden
__stdio_adjust_position(register FILE * __restrict stream
,
20 register __offmax_t
*pos
)
25 if ((corr
= stream
->__modeflags
& __MASK_READING
) != 0) {
26 --corr
; /* Correct for ungots. Assume narrow, and fix below. */
29 #ifdef __UCLIBC_HAS_WCHAR__
30 if (corr
&& __STDIO_STREAM_IS_WIDE(stream
)) {
31 /* A wide stream and we have at least one ungotten wchar.
32 * If it is a user ungot, we need to fail since position
33 * is unspecified as per C99. */
34 if ((corr
> 1) || stream
->__ungot
[1]) { /* User ungetwc, */
35 return -1; /* so position is undefined. */
37 corr
-= (1 + stream
->__ungot_width
[1]);
38 if (stream
->__state
.__mask
> 0) { /* Incomplete (bad?) mb char. */
39 corr
-= stream
->__ungot_width
[0];
44 #ifdef __STDIO_BUFFERS
45 corr
+= (((__STDIO_STREAM_IS_WRITING(stream
))
46 ? stream
->__bufstart
: stream
->__bufread
)
52 /* Range checking cases:
53 * (pos - corr > pos) && (corr > 0) : underflow? return -corr < 0
54 * (pos - corr > pos) && (corr < 0) : ok .. return -corr > 0
55 * (pos - corr <= pos) && (corr >= 0) : ok .. return corr > 0
56 * (pos - corr <= pos) && (corr < 0) : overflow .. return corr < 0
59 if ((*pos
-= corr
) > oldpos
) {
64 __set_errno(EOVERFLOW
);