Fix handling of collating symbols in regexps
[glibc.git] / libio / wgenops.c
blobb39b6912c63e3d7b7b1e07087aa5bf26440eaab4
1 /* Copyright (C) 1993-2013 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, see
18 <http://www.gnu.org/licenses/>.
20 As a special exception, if you link the code in this file with
21 files compiled with a GNU compiler to produce an executable,
22 that does not cause the resulting executable to be covered by
23 the GNU Lesser General Public License. This exception does not
24 however invalidate any other reasons why the executable file
25 might be covered by the GNU Lesser General Public License.
26 This exception applies to code released by its copyright holders
27 in files containing the exception. */
29 /* Generic or default I/O operations. */
31 #include "libioP.h"
32 #include <stdlib.h>
33 #include <string.h>
34 #include <wchar.h>
37 #ifndef _LIBC
38 # define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
39 #endif
42 static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW
43 #ifdef _LIBC
44 internal_function
45 #endif
48 /* Return minimum _pos markers
49 Assumes the current get area is the main get area. */
50 _IO_ssize_t
51 _IO_least_wmarker (fp, end_p)
52 _IO_FILE *fp;
53 wchar_t *end_p;
55 _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
56 struct _IO_marker *mark;
57 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
58 if (mark->_pos < least_so_far)
59 least_so_far = mark->_pos;
60 return least_so_far;
62 libc_hidden_def (_IO_least_wmarker)
64 /* Switch current get area from backup buffer to (start of) main get area. */
65 void
66 _IO_switch_to_main_wget_area (fp)
67 _IO_FILE *fp;
69 wchar_t *tmp;
70 fp->_flags &= ~_IO_IN_BACKUP;
71 /* Swap _IO_read_end and _IO_save_end. */
72 tmp = fp->_wide_data->_IO_read_end;
73 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
74 fp->_wide_data->_IO_save_end= tmp;
75 /* Swap _IO_read_base and _IO_save_base. */
76 tmp = fp->_wide_data->_IO_read_base;
77 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
78 fp->_wide_data->_IO_save_base = tmp;
79 /* Set _IO_read_ptr. */
80 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
82 libc_hidden_def (_IO_switch_to_main_wget_area)
85 /* Switch current get area from main get area to (end of) backup area. */
86 void
87 _IO_switch_to_wbackup_area (fp)
88 _IO_FILE *fp;
90 wchar_t *tmp;
91 fp->_flags |= _IO_IN_BACKUP;
92 /* Swap _IO_read_end and _IO_save_end. */
93 tmp = fp->_wide_data->_IO_read_end;
94 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
95 fp->_wide_data->_IO_save_end = tmp;
96 /* Swap _IO_read_base and _IO_save_base. */
97 tmp = fp->_wide_data->_IO_read_base;
98 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
99 fp->_wide_data->_IO_save_base = tmp;
100 /* Set _IO_read_ptr. */
101 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
103 libc_hidden_def (_IO_switch_to_wbackup_area)
106 void
107 _IO_wsetb (f, b, eb, a)
108 _IO_FILE *f;
109 wchar_t *b;
110 wchar_t *eb;
111 int a;
113 if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF))
114 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
115 f->_wide_data->_IO_buf_base = b;
116 f->_wide_data->_IO_buf_end = eb;
117 if (a)
118 f->_flags2 &= ~_IO_FLAGS2_USER_WBUF;
119 else
120 f->_flags2 |= _IO_FLAGS2_USER_WBUF;
122 libc_hidden_def (_IO_wsetb)
125 wint_t
126 _IO_wdefault_pbackfail (fp, c)
127 _IO_FILE *fp;
128 wint_t c;
130 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
131 && !_IO_in_backup (fp)
132 && (wint_t) fp->_IO_read_ptr[-1] == c)
133 --fp->_IO_read_ptr;
134 else
136 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
137 if (!_IO_in_backup (fp))
139 /* We need to keep the invariant that the main get area
140 logically follows the backup area. */
141 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
142 && _IO_have_wbackup (fp))
144 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
145 return WEOF;
147 else if (!_IO_have_wbackup (fp))
149 /* No backup buffer: allocate one. */
150 /* Use nshort buffer, if unused? (probably not) FIXME */
151 int backup_size = 128;
152 wchar_t *bbuf = (wchar_t *) malloc (backup_size
153 * sizeof (wchar_t));
154 if (bbuf == NULL)
155 return WEOF;
156 fp->_wide_data->_IO_save_base = bbuf;
157 fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
158 + backup_size);
159 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
161 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
162 _IO_switch_to_wbackup_area (fp);
164 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
166 /* Increase size of existing backup buffer. */
167 _IO_size_t new_size;
168 _IO_size_t old_size = (fp->_wide_data->_IO_read_end
169 - fp->_wide_data->_IO_read_base);
170 wchar_t *new_buf;
171 new_size = 2 * old_size;
172 new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
173 if (new_buf == NULL)
174 return WEOF;
175 __wmemcpy (new_buf + (new_size - old_size),
176 fp->_wide_data->_IO_read_base, old_size);
177 free (fp->_wide_data->_IO_read_base);
178 _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
179 new_buf + new_size);
180 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
183 *--fp->_wide_data->_IO_read_ptr = c;
185 return c;
187 libc_hidden_def (_IO_wdefault_pbackfail)
190 void
191 _IO_wdefault_finish (fp, dummy)
192 _IO_FILE *fp;
193 int dummy;
195 struct _IO_marker *mark;
196 if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
198 FREE_BUF (fp->_wide_data->_IO_buf_base,
199 _IO_wblen (fp) * sizeof (wchar_t));
200 fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
203 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
204 mark->_sbuf = NULL;
206 if (fp->_IO_save_base)
208 free (fp->_wide_data->_IO_save_base);
209 fp->_IO_save_base = NULL;
212 #ifdef _IO_MTSAFE_IO
213 if (fp->_lock != NULL)
214 _IO_lock_fini (*fp->_lock);
215 #endif
217 _IO_un_link ((struct _IO_FILE_plus *) fp);
219 libc_hidden_def (_IO_wdefault_finish)
222 wint_t
223 _IO_wdefault_uflow (fp)
224 _IO_FILE *fp;
226 wint_t wch;
227 wch = _IO_UNDERFLOW (fp);
228 if (wch == WEOF)
229 return WEOF;
230 return *fp->_wide_data->_IO_read_ptr++;
232 libc_hidden_def (_IO_wdefault_uflow)
235 wint_t
236 __woverflow (f, wch)
237 _IO_FILE *f;
238 wint_t wch;
240 if (f->_mode == 0)
241 _IO_fwide (f, 1);
242 return _IO_OVERFLOW (f, wch);
244 libc_hidden_def (__woverflow)
247 wint_t
248 __wuflow (fp)
249 _IO_FILE *fp;
251 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
252 return WEOF;
254 if (fp->_mode == 0)
255 _IO_fwide (fp, 1);
256 if (_IO_in_put_mode (fp))
257 if (_IO_switch_to_wget_mode (fp) == EOF)
258 return WEOF;
259 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
260 return *fp->_wide_data->_IO_read_ptr++;
261 if (_IO_in_backup (fp))
263 _IO_switch_to_main_wget_area (fp);
264 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
265 return *fp->_wide_data->_IO_read_ptr++;
267 if (_IO_have_markers (fp))
269 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
270 return WEOF;
272 else if (_IO_have_wbackup (fp))
273 _IO_free_wbackup_area (fp);
274 return _IO_UFLOW (fp);
276 libc_hidden_def (__wuflow)
278 wint_t
279 __wunderflow (fp)
280 _IO_FILE *fp;
282 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
283 return WEOF;
285 if (fp->_mode == 0)
286 _IO_fwide (fp, 1);
287 if (_IO_in_put_mode (fp))
288 if (_IO_switch_to_wget_mode (fp) == EOF)
289 return WEOF;
290 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
291 return *fp->_wide_data->_IO_read_ptr;
292 if (_IO_in_backup (fp))
294 _IO_switch_to_main_wget_area (fp);
295 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
296 return *fp->_wide_data->_IO_read_ptr;
298 if (_IO_have_markers (fp))
300 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
301 return WEOF;
303 else if (_IO_have_backup (fp))
304 _IO_free_wbackup_area (fp);
305 return _IO_UNDERFLOW (fp);
307 libc_hidden_def (__wunderflow)
310 _IO_size_t
311 _IO_wdefault_xsputn (f, data, n)
312 _IO_FILE *f;
313 const void *data;
314 _IO_size_t n;
316 const wchar_t *s = (const wchar_t *) data;
317 _IO_size_t more = n;
318 if (more <= 0)
319 return 0;
320 for (;;)
322 /* Space available. */
323 _IO_ssize_t count = (f->_wide_data->_IO_write_end
324 - f->_wide_data->_IO_write_ptr);
325 if (count > 0)
327 if ((_IO_size_t) count > more)
328 count = more;
329 if (count > 20)
331 #ifdef _LIBC
332 f->_wide_data->_IO_write_ptr =
333 __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
334 #else
335 memcpy (f->_wide_data->_IO_write_ptr, s, count);
336 f->_wide_data->_IO_write_ptr += count;
337 #endif
338 s += count;
340 else if (count <= 0)
341 count = 0;
342 else
344 wchar_t *p = f->_wide_data->_IO_write_ptr;
345 _IO_ssize_t i;
346 for (i = count; --i >= 0; )
347 *p++ = *s++;
348 f->_wide_data->_IO_write_ptr = p;
350 more -= count;
352 if (more == 0 || __woverflow (f, *s++) == WEOF)
353 break;
354 more--;
356 return n - more;
358 libc_hidden_def (_IO_wdefault_xsputn)
361 _IO_size_t
362 _IO_wdefault_xsgetn (fp, data, n)
363 _IO_FILE *fp;
364 void *data;
365 _IO_size_t n;
367 _IO_size_t more = n;
368 wchar_t *s = (wchar_t*) data;
369 for (;;)
371 /* Data available. */
372 _IO_ssize_t count = (fp->_wide_data->_IO_read_end
373 - fp->_wide_data->_IO_read_ptr);
374 if (count > 0)
376 if ((_IO_size_t) count > more)
377 count = more;
378 if (count > 20)
380 #ifdef _LIBC
381 s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
382 #else
383 memcpy (s, fp->_wide_data->_IO_read_ptr, count);
384 s += count;
385 #endif
386 fp->_wide_data->_IO_read_ptr += count;
388 else if (count <= 0)
389 count = 0;
390 else
392 wchar_t *p = fp->_wide_data->_IO_read_ptr;
393 int i = (int) count;
394 while (--i >= 0)
395 *s++ = *p++;
396 fp->_wide_data->_IO_read_ptr = p;
398 more -= count;
400 if (more == 0 || __wunderflow (fp) == WEOF)
401 break;
403 return n - more;
405 libc_hidden_def (_IO_wdefault_xsgetn)
408 void
409 _IO_wdoallocbuf (fp)
410 _IO_FILE *fp;
412 if (fp->_wide_data->_IO_buf_base)
413 return;
414 if (!(fp->_flags & _IO_UNBUFFERED))
415 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
416 return;
417 _IO_wsetb (fp, fp->_wide_data->_shortbuf,
418 fp->_wide_data->_shortbuf + 1, 0);
420 libc_hidden_def (_IO_wdoallocbuf)
424 _IO_wdefault_doallocate (fp)
425 _IO_FILE *fp;
427 wchar_t *buf;
429 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
430 _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1);
431 return 1;
433 libc_hidden_def (_IO_wdefault_doallocate)
437 _IO_switch_to_wget_mode (fp)
438 _IO_FILE *fp;
440 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
441 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
442 return EOF;
443 if (_IO_in_backup (fp))
444 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
445 else
447 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
448 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
449 fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
451 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
453 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
454 = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
456 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
457 return 0;
459 libc_hidden_def (_IO_switch_to_wget_mode)
461 void
462 _IO_free_wbackup_area (fp)
463 _IO_FILE *fp;
465 if (_IO_in_backup (fp))
466 _IO_switch_to_main_wget_area (fp); /* Just in case. */
467 free (fp->_wide_data->_IO_save_base);
468 fp->_wide_data->_IO_save_base = NULL;
469 fp->_wide_data->_IO_save_end = NULL;
470 fp->_wide_data->_IO_backup_base = NULL;
472 libc_hidden_def (_IO_free_wbackup_area)
474 #if 0
476 _IO_switch_to_wput_mode (fp)
477 _IO_FILE *fp;
479 fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
480 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
481 /* Following is wrong if line- or un-buffered? */
482 fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
483 ? fp->_wide_data->_IO_read_end
484 : fp->_wide_data->_IO_buf_end);
486 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
487 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
489 fp->_flags |= _IO_CURRENTLY_PUTTING;
490 return 0;
492 #endif
495 static int
496 #ifdef _LIBC
497 internal_function
498 #endif
499 save_for_wbackup (fp, end_p)
500 _IO_FILE *fp;
501 wchar_t *end_p;
503 /* Append [_IO_read_base..end_p] to backup area. */
504 _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p);
505 /* needed_size is how much space we need in the backup area. */
506 _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
507 - least_mark);
508 /* FIXME: Dubious arithmetic if pointers are NULL */
509 _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
510 - fp->_wide_data->_IO_save_base);
511 _IO_size_t avail; /* Extra space available for future expansion. */
512 _IO_ssize_t delta;
513 struct _IO_marker *mark;
514 if (needed_size > current_Bsize)
516 wchar_t *new_buffer;
517 avail = 100;
518 new_buffer = (wchar_t *) malloc ((avail + needed_size)
519 * sizeof (wchar_t));
520 if (new_buffer == NULL)
521 return EOF; /* FIXME */
522 if (least_mark < 0)
524 #ifdef _LIBC
525 __wmempcpy (__wmempcpy (new_buffer + avail,
526 fp->_wide_data->_IO_save_end + least_mark,
527 -least_mark),
528 fp->_wide_data->_IO_read_base,
529 end_p - fp->_wide_data->_IO_read_base);
530 #else
531 memcpy (new_buffer + avail,
532 fp->_wide_data->_IO_save_end + least_mark,
533 -least_mark * sizeof (wchar_t));
534 memcpy (new_buffer + avail - least_mark,
535 fp->_wide_data->_IO_read_base,
536 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
537 #endif
539 else
541 #ifdef _LIBC
542 __wmemcpy (new_buffer + avail,
543 fp->_wide_data->_IO_read_base + least_mark,
544 needed_size);
545 #else
546 memcpy (new_buffer + avail,
547 fp->_wide_data->_IO_read_base + least_mark,
548 needed_size * sizeof (wchar_t));
549 #endif
551 free (fp->_wide_data->_IO_save_base);
552 fp->_wide_data->_IO_save_base = new_buffer;
553 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
555 else
557 avail = current_Bsize - needed_size;
558 if (least_mark < 0)
560 #ifdef _LIBC
561 __wmemmove (fp->_wide_data->_IO_save_base + avail,
562 fp->_wide_data->_IO_save_end + least_mark,
563 -least_mark);
564 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
565 fp->_wide_data->_IO_read_base,
566 end_p - fp->_wide_data->_IO_read_base);
567 #else
568 memmove (fp->_wide_data->_IO_save_base + avail,
569 fp->_wide_data->_IO_save_end + least_mark,
570 -least_mark * sizeof (wchar_t));
571 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
572 fp->_wide_data->_IO_read_base,
573 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
574 #endif
576 else if (needed_size > 0)
577 #ifdef _LIBC
578 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
579 fp->_wide_data->_IO_read_base + least_mark,
580 needed_size);
581 #else
582 memcpy (fp->_wide_data->_IO_save_base + avail,
583 fp->_wide_data->_IO_read_base + least_mark,
584 needed_size * sizeof (wchar_t));
585 #endif
587 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
588 /* Adjust all the streammarkers. */
589 delta = end_p - fp->_wide_data->_IO_read_base;
590 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
591 mark->_pos -= delta;
592 return 0;
595 wint_t
596 _IO_sputbackwc (fp, c)
597 _IO_FILE *fp;
598 wint_t c;
600 wint_t result;
602 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
603 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
605 fp->_wide_data->_IO_read_ptr--;
606 result = c;
608 else
609 result = _IO_PBACKFAIL (fp, c);
611 if (result != WEOF)
612 fp->_flags &= ~_IO_EOF_SEEN;
614 return result;
616 libc_hidden_def (_IO_sputbackwc)
618 wint_t
619 _IO_sungetwc (fp)
620 _IO_FILE *fp;
622 wint_t result;
624 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
626 fp->_wide_data->_IO_read_ptr--;
627 result = *fp->_wide_data->_IO_read_ptr;
629 else
630 result = _IO_PBACKFAIL (fp, EOF);
632 if (result != WEOF)
633 fp->_flags &= ~_IO_EOF_SEEN;
635 return result;
639 unsigned
640 _IO_adjust_wcolumn (start, line, count)
641 unsigned start;
642 const wchar_t *line;
643 int count;
645 const wchar_t *ptr = line + count;
646 while (ptr > line)
647 if (*--ptr == L'\n')
648 return line + count - ptr - 1;
649 return start + count;
652 void
653 _IO_init_wmarker (marker, fp)
654 struct _IO_marker *marker;
655 _IO_FILE *fp;
657 marker->_sbuf = fp;
658 if (_IO_in_put_mode (fp))
659 _IO_switch_to_wget_mode (fp);
660 if (_IO_in_backup (fp))
661 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
662 else
663 marker->_pos = (fp->_wide_data->_IO_read_ptr
664 - fp->_wide_data->_IO_read_base);
666 /* Should perhaps sort the chain? */
667 marker->_next = fp->_markers;
668 fp->_markers = marker;
671 #define BAD_DELTA EOF
673 /* Return difference between MARK and current position of MARK's stream. */
675 _IO_wmarker_delta (mark)
676 struct _IO_marker *mark;
678 int cur_pos;
679 if (mark->_sbuf == NULL)
680 return BAD_DELTA;
681 if (_IO_in_backup (mark->_sbuf))
682 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
683 - mark->_sbuf->_wide_data->_IO_read_end);
684 else
685 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
686 - mark->_sbuf->_wide_data->_IO_read_base);
687 return mark->_pos - cur_pos;
691 _IO_seekwmark (fp, mark, delta)
692 _IO_FILE *fp;
693 struct _IO_marker *mark;
694 int delta;
696 if (mark->_sbuf != fp)
697 return EOF;
698 if (mark->_pos >= 0)
700 if (_IO_in_backup (fp))
701 _IO_switch_to_main_wget_area (fp);
702 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
703 + mark->_pos);
705 else
707 if (!_IO_in_backup (fp))
708 _IO_switch_to_wbackup_area (fp);
709 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
711 return 0;
714 void
715 _IO_unsave_wmarkers (fp)
716 _IO_FILE *fp;
718 struct _IO_marker *mark = fp->_markers;
719 if (mark)
721 #ifdef TODO
722 streampos offset = seekoff (0, ios::cur, ios::in);
723 if (offset != EOF)
725 offset += eGptr () - Gbase ();
726 for ( ; mark != NULL; mark = mark->_next)
727 mark->set_streampos (mark->_pos + offset);
729 else
731 for ( ; mark != NULL; mark = mark->_next)
732 mark->set_streampos (EOF);
734 #endif
735 fp->_markers = 0;
738 if (_IO_have_backup (fp))
739 _IO_free_wbackup_area (fp);