]> git.ipfire.org Git - thirdparty/glibc.git/blame - libio/wgenops.c
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / libio / wgenops.c
CommitLineData
d4697bc9 1/* Copyright (C) 1993-2014 Free Software Foundation, Inc.
41bdb6e2 2 This file is part of the GNU C Library.
d64b6ad0
UD
3 Written by Ulrich Drepper <drepper@cygnus.com>.
4 Based on the single byte version by Per Bothner <bothner@cygnus.com>.
5
41bdb6e2
AJ
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.
d64b6ad0 10
41bdb6e2
AJ
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
d64b6ad0 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2
AJ
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>.
41bdb6e2
AJ
19
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. */
d64b6ad0
UD
28
29/* Generic or default I/O operations. */
30
31#include "libioP.h"
d64b6ad0 32#include <stdlib.h>
d64b6ad0
UD
33#include <string.h>
34#include <wchar.h>
35
36
319d719d
UD
37#ifndef _LIBC
38# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
39#endif
40
d64b6ad0 41
79937577 42static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW
d64b6ad0
UD
43#ifdef _LIBC
44 internal_function
45#endif
46 ;
47
48/* Return minimum _pos markers
49 Assumes the current get area is the main get area. */
d64b6ad0
UD
50_IO_ssize_t
51_IO_least_wmarker (fp, end_p)
52 _IO_FILE *fp;
53 wchar_t *end_p;
54{
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;
61}
d18ea0c5 62libc_hidden_def (_IO_least_wmarker)
d64b6ad0
UD
63
64/* Switch current get area from backup buffer to (start of) main get area. */
65void
66_IO_switch_to_main_wget_area (fp)
67 _IO_FILE *fp;
68{
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;
81}
d18ea0c5 82libc_hidden_def (_IO_switch_to_main_wget_area)
d64b6ad0
UD
83
84
85/* Switch current get area from main get area to (end of) backup area. */
86void
87_IO_switch_to_wbackup_area (fp)
88 _IO_FILE *fp;
89{
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;
102}
d18ea0c5 103libc_hidden_def (_IO_switch_to_wbackup_area)
d64b6ad0
UD
104
105
106void
107_IO_wsetb (f, b, eb, a)
108 _IO_FILE *f;
109 wchar_t *b;
110 wchar_t *eb;
111 int a;
112{
1e88bd0f 113 if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF))
d369ad76 114 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f) * sizeof (wchar_t));
d64b6ad0
UD
115 f->_wide_data->_IO_buf_base = b;
116 f->_wide_data->_IO_buf_end = eb;
117 if (a)
1e88bd0f 118 f->_flags2 &= ~_IO_FLAGS2_USER_WBUF;
d64b6ad0 119 else
1e88bd0f 120 f->_flags2 |= _IO_FLAGS2_USER_WBUF;
d64b6ad0 121}
d18ea0c5 122libc_hidden_def (_IO_wsetb)
d64b6ad0
UD
123
124
125wint_t
126_IO_wdefault_pbackfail (fp, c)
127 _IO_FILE *fp;
128 wint_t c;
129{
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
135 {
136 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
137 if (!_IO_in_backup (fp))
138 {
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))
143 {
144 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
145 return WEOF;
146 }
147 else if (!_IO_have_wbackup (fp))
148 {
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;
160 }
161 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
d18ea0c5 162 _IO_switch_to_wbackup_area (fp);
d64b6ad0
UD
163 }
164 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
165 {
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;
181 }
182
183 *--fp->_wide_data->_IO_read_ptr = c;
184 }
185 return c;
186}
d18ea0c5 187libc_hidden_def (_IO_wdefault_pbackfail)
d64b6ad0
UD
188
189
190void
191_IO_wdefault_finish (fp, dummy)
192 _IO_FILE *fp;
193 int dummy;
194{
195 struct _IO_marker *mark;
1e88bd0f 196 if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF))
d64b6ad0
UD
197 {
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;
201 }
202
203 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
204 mark->_sbuf = NULL;
205
206 if (fp->_IO_save_base)
207 {
208 free (fp->_wide_data->_IO_save_base);
209 fp->_IO_save_base = NULL;
210 }
211
212#ifdef _IO_MTSAFE_IO
c020d48c
UD
213 if (fp->_lock != NULL)
214 _IO_lock_fini (*fp->_lock);
d64b6ad0
UD
215#endif
216
d18ea0c5 217 _IO_un_link ((struct _IO_FILE_plus *) fp);
d64b6ad0 218}
d18ea0c5 219libc_hidden_def (_IO_wdefault_finish)
d64b6ad0
UD
220
221
222wint_t
223_IO_wdefault_uflow (fp)
224 _IO_FILE *fp;
225{
226 wint_t wch;
227 wch = _IO_UNDERFLOW (fp);
228 if (wch == WEOF)
229 return WEOF;
230 return *fp->_wide_data->_IO_read_ptr++;
231}
d18ea0c5 232libc_hidden_def (_IO_wdefault_uflow)
d64b6ad0
UD
233
234
235wint_t
236__woverflow (f, wch)
237 _IO_FILE *f;
238 wint_t wch;
239{
240 if (f->_mode == 0)
241 _IO_fwide (f, 1);
242 return _IO_OVERFLOW (f, wch);
243}
37ba7d66 244libc_hidden_def (__woverflow)
d64b6ad0
UD
245
246
247wint_t
248__wuflow (fp)
249 _IO_FILE *fp;
250{
251 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 252 return WEOF;
d64b6ad0
UD
253
254 if (fp->_mode == 0)
255 _IO_fwide (fp, 1);
256 if (_IO_in_put_mode (fp))
d18ea0c5 257 if (_IO_switch_to_wget_mode (fp) == EOF)
d64b6ad0
UD
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))
262 {
d18ea0c5 263 _IO_switch_to_main_wget_area (fp);
d64b6ad0
UD
264 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
265 return *fp->_wide_data->_IO_read_ptr++;
266 }
267 if (_IO_have_markers (fp))
268 {
269 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
270 return WEOF;
271 }
272 else if (_IO_have_wbackup (fp))
d18ea0c5 273 _IO_free_wbackup_area (fp);
d64b6ad0
UD
274 return _IO_UFLOW (fp);
275}
a20d8dbe 276libc_hidden_def (__wuflow)
d64b6ad0
UD
277
278wint_t
279__wunderflow (fp)
280 _IO_FILE *fp;
281{
282 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 283 return WEOF;
d64b6ad0 284
6f98fd7e
UD
285 if (fp->_mode == 0)
286 _IO_fwide (fp, 1);
d64b6ad0 287 if (_IO_in_put_mode (fp))
d18ea0c5 288 if (_IO_switch_to_wget_mode (fp) == EOF)
d64b6ad0
UD
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))
293 {
d18ea0c5 294 _IO_switch_to_main_wget_area (fp);
d64b6ad0
UD
295 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
296 return *fp->_wide_data->_IO_read_ptr;
297 }
298 if (_IO_have_markers (fp))
299 {
300 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
655c0697 301 return WEOF;
d64b6ad0
UD
302 }
303 else if (_IO_have_backup (fp))
d18ea0c5 304 _IO_free_wbackup_area (fp);
d64b6ad0
UD
305 return _IO_UNDERFLOW (fp);
306}
a20d8dbe 307libc_hidden_def (__wunderflow)
d64b6ad0
UD
308
309
310_IO_size_t
311_IO_wdefault_xsputn (f, data, n)
312 _IO_FILE *f;
313 const void *data;
314 _IO_size_t n;
315{
316 const wchar_t *s = (const wchar_t *) data;
317 _IO_size_t more = n;
318 if (more <= 0)
319 return 0;
320 for (;;)
321 {
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)
326 {
327 if ((_IO_size_t) count > more)
328 count = more;
329 if (count > 20)
330 {
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;
339 }
340 else if (count <= 0)
341 count = 0;
342 else
343 {
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;
349 }
350 more -= count;
351 }
352 if (more == 0 || __woverflow (f, *s++) == WEOF)
353 break;
354 more--;
355 }
356 return n - more;
357}
d18ea0c5 358libc_hidden_def (_IO_wdefault_xsputn)
d64b6ad0
UD
359
360
361_IO_size_t
362_IO_wdefault_xsgetn (fp, data, n)
363 _IO_FILE *fp;
364 void *data;
365 _IO_size_t n;
366{
367 _IO_size_t more = n;
368 wchar_t *s = (wchar_t*) data;
369 for (;;)
370 {
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)
375 {
376 if ((_IO_size_t) count > more)
377 count = more;
378 if (count > 20)
379 {
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;
387 }
388 else if (count <= 0)
389 count = 0;
390 else
391 {
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;
397 }
398 more -= count;
399 }
400 if (more == 0 || __wunderflow (fp) == WEOF)
401 break;
402 }
403 return n - more;
404}
d18ea0c5 405libc_hidden_def (_IO_wdefault_xsgetn)
d64b6ad0
UD
406
407
408void
409_IO_wdoallocbuf (fp)
410 _IO_FILE *fp;
411{
412 if (fp->_wide_data->_IO_buf_base)
413 return;
414 if (!(fp->_flags & _IO_UNBUFFERED))
1dc72e4f 415 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
d64b6ad0 416 return;
d18ea0c5 417 _IO_wsetb (fp, fp->_wide_data->_shortbuf,
77fe0b9c 418 fp->_wide_data->_shortbuf + 1, 0);
d64b6ad0 419}
d18ea0c5 420libc_hidden_def (_IO_wdoallocbuf)
d64b6ad0
UD
421
422
423int
424_IO_wdefault_doallocate (fp)
425 _IO_FILE *fp;
426{
427 wchar_t *buf;
428
429 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
d18ea0c5 430 _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1);
d64b6ad0
UD
431 return 1;
432}
d18ea0c5 433libc_hidden_def (_IO_wdefault_doallocate)
d64b6ad0
UD
434
435
436int
437_IO_switch_to_wget_mode (fp)
438 _IO_FILE *fp;
439{
440 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
1dc72e4f 441 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
d64b6ad0
UD
442 return EOF;
443 if (_IO_in_backup (fp))
444 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
445 else
446 {
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;
450 }
451 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
452
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;
455
456 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
457 return 0;
458}
d18ea0c5 459libc_hidden_def (_IO_switch_to_wget_mode)
d64b6ad0
UD
460
461void
462_IO_free_wbackup_area (fp)
463 _IO_FILE *fp;
464{
465 if (_IO_in_backup (fp))
d18ea0c5 466 _IO_switch_to_main_wget_area (fp); /* Just in case. */
d64b6ad0
UD
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;
471}
d18ea0c5 472libc_hidden_def (_IO_free_wbackup_area)
d64b6ad0
UD
473
474#if 0
475int
476_IO_switch_to_wput_mode (fp)
477 _IO_FILE *fp;
478{
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);
485
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;
488
489 fp->_flags |= _IO_CURRENTLY_PUTTING;
490 return 0;
491}
492#endif
493
494
495static int
496#ifdef _LIBC
497internal_function
498#endif
499save_for_wbackup (fp, end_p)
500 _IO_FILE *fp;
501 wchar_t *end_p;
502{
503 /* Append [_IO_read_base..end_p] to backup area. */
d18ea0c5 504 _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p);
d64b6ad0
UD
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)
515 {
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)
523 {
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
538 }
539 else
540 {
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
550 }
72e6cdfa 551 free (fp->_wide_data->_IO_save_base);
d64b6ad0
UD
552 fp->_wide_data->_IO_save_base = new_buffer;
553 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
554 }
555 else
556 {
557 avail = current_Bsize - needed_size;
558 if (least_mark < 0)
559 {
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
575 }
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
586 }
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;
593}
594
595wint_t
596_IO_sputbackwc (fp, c)
597 _IO_FILE *fp;
598 wint_t c;
599{
600 wint_t result;
601
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)
604 {
605 fp->_wide_data->_IO_read_ptr--;
606 result = c;
607 }
608 else
609 result = _IO_PBACKFAIL (fp, c);
610
1dc72e4f 611 if (result != WEOF)
d64b6ad0
UD
612 fp->_flags &= ~_IO_EOF_SEEN;
613
614 return result;
615}
d18ea0c5 616libc_hidden_def (_IO_sputbackwc)
d64b6ad0
UD
617
618wint_t
619_IO_sungetwc (fp)
620 _IO_FILE *fp;
621{
1dc72e4f 622 wint_t result;
d64b6ad0
UD
623
624 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
625 {
626 fp->_wide_data->_IO_read_ptr--;
627 result = *fp->_wide_data->_IO_read_ptr;
628 }
629 else
630 result = _IO_PBACKFAIL (fp, EOF);
631
632 if (result != WEOF)
633 fp->_flags &= ~_IO_EOF_SEEN;
634
635 return result;
636}
637
638
639unsigned
640_IO_adjust_wcolumn (start, line, count)
641 unsigned start;
642 const wchar_t *line;
643 int count;
644{
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;
650}
651
652void
653_IO_init_wmarker (marker, fp)
654 struct _IO_marker *marker;
655 _IO_FILE *fp;
656{
657 marker->_sbuf = fp;
658 if (_IO_in_put_mode (fp))
d18ea0c5 659 _IO_switch_to_wget_mode (fp);
d64b6ad0
UD
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);
665
666 /* Should perhaps sort the chain? */
667 marker->_next = fp->_markers;
668 fp->_markers = marker;
669}
670
671#define BAD_DELTA EOF
672
673/* Return difference between MARK and current position of MARK's stream. */
674int
675_IO_wmarker_delta (mark)
676 struct _IO_marker *mark;
677{
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;
688}
689
690int
691_IO_seekwmark (fp, mark, delta)
692 _IO_FILE *fp;
693 struct _IO_marker *mark;
694 int delta;
695{
696 if (mark->_sbuf != fp)
697 return EOF;
698 if (mark->_pos >= 0)
699 {
700 if (_IO_in_backup (fp))
d18ea0c5 701 _IO_switch_to_main_wget_area (fp);
d64b6ad0
UD
702 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
703 + mark->_pos);
704 }
705 else
706 {
707 if (!_IO_in_backup (fp))
d18ea0c5 708 _IO_switch_to_wbackup_area (fp);
d64b6ad0
UD
709 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
710 }
711 return 0;
712}
713
714void
715_IO_unsave_wmarkers (fp)
716 _IO_FILE *fp;
717{
718 struct _IO_marker *mark = fp->_markers;
719 if (mark)
720 {
721#ifdef TODO
722 streampos offset = seekoff (0, ios::cur, ios::in);
723 if (offset != EOF)
724 {
725 offset += eGptr () - Gbase ();
726 for ( ; mark != NULL; mark = mark->_next)
727 mark->set_streampos (mark->_pos + offset);
728 }
729 else
730 {
731 for ( ; mark != NULL; mark = mark->_next)
732 mark->set_streampos (EOF);
733 }
734#endif
735 fp->_markers = 0;
736 }
737
738 if (_IO_have_backup (fp))
d18ea0c5 739 _IO_free_wbackup_area (fp);
d64b6ad0 740}