Fix infloop in __pthread_disable_asynccancel on x86_64
[glibc.git] / libio / wgenops.c
blobe2adedd6d4d07c9f66b870de644d6c3d84848063
1 /* Copyright (C) 1993,1995,1997-2002,2004,2006 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Ulrich Drepper <drepper@cygnus.com>.
4 Based on the single byte version by Per Bothner <bothner@cygnus.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
30 /* Generic or default I/O operations. */
32 #include "libioP.h"
33 #ifdef __STDC__
34 #include <stdlib.h>
35 #endif
36 #include <string.h>
37 #include <wchar.h>
40 #ifndef _LIBC
41 # define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
42 #endif
45 static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW
46 #ifdef _LIBC
47 internal_function
48 #endif
51 /* Return minimum _pos markers
52 Assumes the current get area is the main get area. */
53 _IO_ssize_t _IO_least_wmarker (_IO_FILE *fp, wchar_t *end_p) __THROW;
55 _IO_ssize_t
56 _IO_least_wmarker (fp, end_p)
57 _IO_FILE *fp;
58 wchar_t *end_p;
60 _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
61 struct _IO_marker *mark;
62 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
63 if (mark->_pos < least_so_far)
64 least_so_far = mark->_pos;
65 return least_so_far;
67 INTDEF(_IO_least_wmarker)
69 /* Switch current get area from backup buffer to (start of) main get area. */
70 void
71 _IO_switch_to_main_wget_area (fp)
72 _IO_FILE *fp;
74 wchar_t *tmp;
75 fp->_flags &= ~_IO_IN_BACKUP;
76 /* Swap _IO_read_end and _IO_save_end. */
77 tmp = fp->_wide_data->_IO_read_end;
78 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
79 fp->_wide_data->_IO_save_end= tmp;
80 /* Swap _IO_read_base and _IO_save_base. */
81 tmp = fp->_wide_data->_IO_read_base;
82 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
83 fp->_wide_data->_IO_save_base = tmp;
84 /* Set _IO_read_ptr. */
85 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
87 INTDEF(_IO_switch_to_main_wget_area)
90 /* Switch current get area from main get area to (end of) backup area. */
91 void
92 _IO_switch_to_wbackup_area (fp)
93 _IO_FILE *fp;
95 wchar_t *tmp;
96 fp->_flags |= _IO_IN_BACKUP;
97 /* Swap _IO_read_end and _IO_save_end. */
98 tmp = fp->_wide_data->_IO_read_end;
99 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
100 fp->_wide_data->_IO_save_end = tmp;
101 /* Swap _IO_read_base and _IO_save_base. */
102 tmp = fp->_wide_data->_IO_read_base;
103 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
104 fp->_wide_data->_IO_save_base = tmp;
105 /* Set _IO_read_ptr. */
106 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
108 INTDEF(_IO_switch_to_wbackup_area)
111 void
112 _IO_wsetb (f, b, eb, a)
113 _IO_FILE *f;
114 wchar_t *b;
115 wchar_t *eb;
116 int a;
118 if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF))
119 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
120 f->_wide_data->_IO_buf_base = b;
121 f->_wide_data->_IO_buf_end = eb;
122 if (a)
123 f->_flags2 &= ~_IO_FLAGS2_USER_WBUF;
124 else
125 f->_flags2 |= _IO_FLAGS2_USER_WBUF;
127 INTDEF(_IO_wsetb)
130 wint_t
131 _IO_wdefault_pbackfail (fp, c)
132 _IO_FILE *fp;
133 wint_t c;
135 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
136 && !_IO_in_backup (fp)
137 && (wint_t) fp->_IO_read_ptr[-1] == c)
138 --fp->_IO_read_ptr;
139 else
141 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
142 if (!_IO_in_backup (fp))
144 /* We need to keep the invariant that the main get area
145 logically follows the backup area. */
146 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
147 && _IO_have_wbackup (fp))
149 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
150 return WEOF;
152 else if (!_IO_have_wbackup (fp))
154 /* No backup buffer: allocate one. */
155 /* Use nshort buffer, if unused? (probably not) FIXME */
156 int backup_size = 128;
157 wchar_t *bbuf = (wchar_t *) malloc (backup_size
158 * sizeof (wchar_t));
159 if (bbuf == NULL)
160 return WEOF;
161 fp->_wide_data->_IO_save_base = bbuf;
162 fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
163 + backup_size);
164 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
166 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
167 INTUSE(_IO_switch_to_wbackup_area) (fp);
169 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
171 /* Increase size of existing backup buffer. */
172 _IO_size_t new_size;
173 _IO_size_t old_size = (fp->_wide_data->_IO_read_end
174 - fp->_wide_data->_IO_read_base);
175 wchar_t *new_buf;
176 new_size = 2 * old_size;
177 new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
178 if (new_buf == NULL)
179 return WEOF;
180 __wmemcpy (new_buf + (new_size - old_size),
181 fp->_wide_data->_IO_read_base, old_size);
182 free (fp->_wide_data->_IO_read_base);
183 _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
184 new_buf + new_size);
185 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
188 *--fp->_wide_data->_IO_read_ptr = c;
190 return c;
192 INTDEF(_IO_wdefault_pbackfail)
195 void
196 _IO_wdefault_finish (fp, dummy)
197 _IO_FILE *fp;
198 int dummy;
200 struct _IO_marker *mark;
201 if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
203 FREE_BUF (fp->_wide_data->_IO_buf_base,
204 _IO_wblen (fp) * sizeof (wchar_t));
205 fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
208 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
209 mark->_sbuf = NULL;
211 if (fp->_IO_save_base)
213 free (fp->_wide_data->_IO_save_base);
214 fp->_IO_save_base = NULL;
217 #ifdef _IO_MTSAFE_IO
218 if (fp->_lock != NULL)
219 _IO_lock_fini (*fp->_lock);
220 #endif
222 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
224 INTDEF(_IO_wdefault_finish)
227 wint_t
228 _IO_wdefault_uflow (fp)
229 _IO_FILE *fp;
231 wint_t wch;
232 wch = _IO_UNDERFLOW (fp);
233 if (wch == WEOF)
234 return WEOF;
235 return *fp->_wide_data->_IO_read_ptr++;
237 INTDEF(_IO_wdefault_uflow)
240 wint_t
241 __woverflow (f, wch)
242 _IO_FILE *f;
243 wint_t wch;
245 if (f->_mode == 0)
246 _IO_fwide (f, 1);
247 return _IO_OVERFLOW (f, wch);
249 libc_hidden_def (__woverflow)
252 wint_t
253 __wuflow (fp)
254 _IO_FILE *fp;
256 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
257 return WEOF;
259 if (fp->_mode == 0)
260 _IO_fwide (fp, 1);
261 if (_IO_in_put_mode (fp))
262 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
263 return WEOF;
264 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
265 return *fp->_wide_data->_IO_read_ptr++;
266 if (_IO_in_backup (fp))
268 INTUSE(_IO_switch_to_main_wget_area) (fp);
269 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
270 return *fp->_wide_data->_IO_read_ptr++;
272 if (_IO_have_markers (fp))
274 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
275 return WEOF;
277 else if (_IO_have_wbackup (fp))
278 INTUSE(_IO_free_wbackup_area) (fp);
279 return _IO_UFLOW (fp);
281 libc_hidden_def (__wuflow)
283 wint_t
284 __wunderflow (fp)
285 _IO_FILE *fp;
287 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
288 return WEOF;
290 if (fp->_mode == 0)
291 _IO_fwide (fp, 1);
292 if (_IO_in_put_mode (fp))
293 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
294 return WEOF;
295 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
296 return *fp->_wide_data->_IO_read_ptr;
297 if (_IO_in_backup (fp))
299 INTUSE(_IO_switch_to_main_wget_area) (fp);
300 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
301 return *fp->_wide_data->_IO_read_ptr;
303 if (_IO_have_markers (fp))
305 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
306 return WEOF;
308 else if (_IO_have_backup (fp))
309 INTUSE(_IO_free_wbackup_area) (fp);
310 return _IO_UNDERFLOW (fp);
312 libc_hidden_def (__wunderflow)
315 _IO_size_t
316 _IO_wdefault_xsputn (f, data, n)
317 _IO_FILE *f;
318 const void *data;
319 _IO_size_t n;
321 const wchar_t *s = (const wchar_t *) data;
322 _IO_size_t more = n;
323 if (more <= 0)
324 return 0;
325 for (;;)
327 /* Space available. */
328 _IO_ssize_t count = (f->_wide_data->_IO_write_end
329 - f->_wide_data->_IO_write_ptr);
330 if (count > 0)
332 if ((_IO_size_t) count > more)
333 count = more;
334 if (count > 20)
336 #ifdef _LIBC
337 f->_wide_data->_IO_write_ptr =
338 __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
339 #else
340 memcpy (f->_wide_data->_IO_write_ptr, s, count);
341 f->_wide_data->_IO_write_ptr += count;
342 #endif
343 s += count;
345 else if (count <= 0)
346 count = 0;
347 else
349 wchar_t *p = f->_wide_data->_IO_write_ptr;
350 _IO_ssize_t i;
351 for (i = count; --i >= 0; )
352 *p++ = *s++;
353 f->_wide_data->_IO_write_ptr = p;
355 more -= count;
357 if (more == 0 || __woverflow (f, *s++) == WEOF)
358 break;
359 more--;
361 return n - more;
363 INTDEF(_IO_wdefault_xsputn)
366 _IO_size_t
367 _IO_wdefault_xsgetn (fp, data, n)
368 _IO_FILE *fp;
369 void *data;
370 _IO_size_t n;
372 _IO_size_t more = n;
373 wchar_t *s = (wchar_t*) data;
374 for (;;)
376 /* Data available. */
377 _IO_ssize_t count = (fp->_wide_data->_IO_read_end
378 - fp->_wide_data->_IO_read_ptr);
379 if (count > 0)
381 if ((_IO_size_t) count > more)
382 count = more;
383 if (count > 20)
385 #ifdef _LIBC
386 s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
387 #else
388 memcpy (s, fp->_wide_data->_IO_read_ptr, count);
389 s += count;
390 #endif
391 fp->_wide_data->_IO_read_ptr += count;
393 else if (count <= 0)
394 count = 0;
395 else
397 wchar_t *p = fp->_wide_data->_IO_read_ptr;
398 int i = (int) count;
399 while (--i >= 0)
400 *s++ = *p++;
401 fp->_wide_data->_IO_read_ptr = p;
403 more -= count;
405 if (more == 0 || __wunderflow (fp) == WEOF)
406 break;
408 return n - more;
410 INTDEF(_IO_wdefault_xsgetn)
413 void
414 _IO_wdoallocbuf (fp)
415 _IO_FILE *fp;
417 if (fp->_wide_data->_IO_buf_base)
418 return;
419 if (!(fp->_flags & _IO_UNBUFFERED))
420 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
421 return;
422 INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf,
423 fp->_wide_data->_shortbuf + 1, 0);
425 INTDEF(_IO_wdoallocbuf)
429 _IO_wdefault_doallocate (fp)
430 _IO_FILE *fp;
432 wchar_t *buf;
434 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
435 INTUSE(_IO_wsetb) (fp, buf, buf + _IO_BUFSIZ, 1);
436 return 1;
438 INTDEF(_IO_wdefault_doallocate)
442 _IO_switch_to_wget_mode (fp)
443 _IO_FILE *fp;
445 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
446 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
447 return EOF;
448 if (_IO_in_backup (fp))
449 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
450 else
452 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
453 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
454 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
456 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
458 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
459 = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
461 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
462 return 0;
464 INTDEF(_IO_switch_to_wget_mode)
466 void
467 _IO_free_wbackup_area (fp)
468 _IO_FILE *fp;
470 if (_IO_in_backup (fp))
471 INTUSE(_IO_switch_to_main_wget_area) (fp); /* Just in case. */
472 free (fp->_wide_data->_IO_save_base);
473 fp->_wide_data->_IO_save_base = NULL;
474 fp->_wide_data->_IO_save_end = NULL;
475 fp->_wide_data->_IO_backup_base = NULL;
477 INTDEF(_IO_free_wbackup_area)
479 #if 0
481 _IO_switch_to_wput_mode (fp)
482 _IO_FILE *fp;
484 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
485 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
486 /* Following is wrong if line- or un-buffered? */
487 fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
488 ? fp->_wide_data->_IO_read_end
489 : fp->_wide_data->_IO_buf_end);
491 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
492 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
494 fp->_flags |= _IO_CURRENTLY_PUTTING;
495 return 0;
497 #endif
500 static int
501 #ifdef _LIBC
502 internal_function
503 #endif
504 save_for_wbackup (fp, end_p)
505 _IO_FILE *fp;
506 wchar_t *end_p;
508 /* Append [_IO_read_base..end_p] to backup area. */
509 _IO_ssize_t least_mark = INTUSE(_IO_least_wmarker) (fp, end_p);
510 /* needed_size is how much space we need in the backup area. */
511 _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
512 - least_mark);
513 /* FIXME: Dubious arithmetic if pointers are NULL */
514 _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
515 - fp->_wide_data->_IO_save_base);
516 _IO_size_t avail; /* Extra space available for future expansion. */
517 _IO_ssize_t delta;
518 struct _IO_marker *mark;
519 if (needed_size > current_Bsize)
521 wchar_t *new_buffer;
522 avail = 100;
523 new_buffer = (wchar_t *) malloc ((avail + needed_size)
524 * sizeof (wchar_t));
525 if (new_buffer == NULL)
526 return EOF; /* FIXME */
527 if (least_mark < 0)
529 #ifdef _LIBC
530 __wmempcpy (__wmempcpy (new_buffer + avail,
531 fp->_wide_data->_IO_save_end + least_mark,
532 -least_mark),
533 fp->_wide_data->_IO_read_base,
534 end_p - fp->_wide_data->_IO_read_base);
535 #else
536 memcpy (new_buffer + avail,
537 fp->_wide_data->_IO_save_end + least_mark,
538 -least_mark * sizeof (wchar_t));
539 memcpy (new_buffer + avail - least_mark,
540 fp->_wide_data->_IO_read_base,
541 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
542 #endif
544 else
546 #ifdef _LIBC
547 __wmemcpy (new_buffer + avail,
548 fp->_wide_data->_IO_read_base + least_mark,
549 needed_size);
550 #else
551 memcpy (new_buffer + avail,
552 fp->_wide_data->_IO_read_base + least_mark,
553 needed_size * sizeof (wchar_t));
554 #endif
556 free (fp->_wide_data->_IO_save_base);
557 fp->_wide_data->_IO_save_base = new_buffer;
558 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
560 else
562 avail = current_Bsize - needed_size;
563 if (least_mark < 0)
565 #ifdef _LIBC
566 __wmemmove (fp->_wide_data->_IO_save_base + avail,
567 fp->_wide_data->_IO_save_end + least_mark,
568 -least_mark);
569 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
570 fp->_wide_data->_IO_read_base,
571 end_p - fp->_wide_data->_IO_read_base);
572 #else
573 memmove (fp->_wide_data->_IO_save_base + avail,
574 fp->_wide_data->_IO_save_end + least_mark,
575 -least_mark * sizeof (wchar_t));
576 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
577 fp->_wide_data->_IO_read_base,
578 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
579 #endif
581 else if (needed_size > 0)
582 #ifdef _LIBC
583 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
584 fp->_wide_data->_IO_read_base + least_mark,
585 needed_size);
586 #else
587 memcpy (fp->_wide_data->_IO_save_base + avail,
588 fp->_wide_data->_IO_read_base + least_mark,
589 needed_size * sizeof (wchar_t));
590 #endif
592 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
593 /* Adjust all the streammarkers. */
594 delta = end_p - fp->_wide_data->_IO_read_base;
595 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
596 mark->_pos -= delta;
597 return 0;
600 wint_t
601 _IO_sputbackwc (fp, c)
602 _IO_FILE *fp;
603 wint_t c;
605 wint_t result;
607 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
608 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
610 fp->_wide_data->_IO_read_ptr--;
611 result = c;
613 else
614 result = _IO_PBACKFAIL (fp, c);
616 if (result != WEOF)
617 fp->_flags &= ~_IO_EOF_SEEN;
619 return result;
621 INTDEF(_IO_sputbackwc)
623 wint_t
624 _IO_sungetwc (fp)
625 _IO_FILE *fp;
627 wint_t result;
629 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
631 fp->_wide_data->_IO_read_ptr--;
632 result = *fp->_wide_data->_IO_read_ptr;
634 else
635 result = _IO_PBACKFAIL (fp, EOF);
637 if (result != WEOF)
638 fp->_flags &= ~_IO_EOF_SEEN;
640 return result;
644 unsigned
645 _IO_adjust_wcolumn (start, line, count)
646 unsigned start;
647 const wchar_t *line;
648 int count;
650 const wchar_t *ptr = line + count;
651 while (ptr > line)
652 if (*--ptr == L'\n')
653 return line + count - ptr - 1;
654 return start + count;
657 void
658 _IO_init_wmarker (marker, fp)
659 struct _IO_marker *marker;
660 _IO_FILE *fp;
662 marker->_sbuf = fp;
663 if (_IO_in_put_mode (fp))
664 INTUSE(_IO_switch_to_wget_mode) (fp);
665 if (_IO_in_backup (fp))
666 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
667 else
668 marker->_pos = (fp->_wide_data->_IO_read_ptr
669 - fp->_wide_data->_IO_read_base);
671 /* Should perhaps sort the chain? */
672 marker->_next = fp->_markers;
673 fp->_markers = marker;
676 #define BAD_DELTA EOF
678 /* Return difference between MARK and current position of MARK's stream. */
680 _IO_wmarker_delta (mark)
681 struct _IO_marker *mark;
683 int cur_pos;
684 if (mark->_sbuf == NULL)
685 return BAD_DELTA;
686 if (_IO_in_backup (mark->_sbuf))
687 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
688 - mark->_sbuf->_wide_data->_IO_read_end);
689 else
690 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
691 - mark->_sbuf->_wide_data->_IO_read_base);
692 return mark->_pos - cur_pos;
696 _IO_seekwmark (fp, mark, delta)
697 _IO_FILE *fp;
698 struct _IO_marker *mark;
699 int delta;
701 if (mark->_sbuf != fp)
702 return EOF;
703 if (mark->_pos >= 0)
705 if (_IO_in_backup (fp))
706 INTUSE(_IO_switch_to_main_wget_area) (fp);
707 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
708 + mark->_pos);
710 else
712 if (!_IO_in_backup (fp))
713 INTUSE(_IO_switch_to_wbackup_area) (fp);
714 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
716 return 0;
719 void
720 _IO_unsave_wmarkers (fp)
721 _IO_FILE *fp;
723 struct _IO_marker *mark = fp->_markers;
724 if (mark)
726 #ifdef TODO
727 streampos offset = seekoff (0, ios::cur, ios::in);
728 if (offset != EOF)
730 offset += eGptr () - Gbase ();
731 for ( ; mark != NULL; mark = mark->_next)
732 mark->set_streampos (mark->_pos + offset);
734 else
736 for ( ; mark != NULL; mark = mark->_next)
737 mark->set_streampos (EOF);
739 #endif
740 fp->_markers = 0;
743 if (_IO_have_backup (fp))
744 INTUSE(_IO_free_wbackup_area) (fp);