]> sourceware.org Git - glibc.git/blame - libio/wgenops.c
Update.
[glibc.git] / libio / wgenops.c
CommitLineData
79937577 1/* Copyright (C) 1993,1995,1997-2001,2002,2004 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
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.
20
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. */
d64b6ad0
UD
29
30/* Generic or default I/O operations. */
31
32#include "libioP.h"
33#ifdef __STDC__
34#include <stdlib.h>
35#endif
36#include <string.h>
37#include <wchar.h>
38
39
319d719d
UD
40#ifndef _LIBC
41# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n)
42#endif
43
d64b6ad0 44
79937577 45static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW
d64b6ad0
UD
46#ifdef _LIBC
47 internal_function
48#endif
49 ;
50
51/* Return minimum _pos markers
52 Assumes the current get area is the main get area. */
79937577 53_IO_ssize_t _IO_least_wmarker (_IO_FILE *fp, wchar_t *end_p) __THROW;
d64b6ad0
UD
54
55_IO_ssize_t
56_IO_least_wmarker (fp, end_p)
57 _IO_FILE *fp;
58 wchar_t *end_p;
59{
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;
66}
77fe0b9c 67INTDEF(_IO_least_wmarker)
d64b6ad0
UD
68
69/* Switch current get area from backup buffer to (start of) main get area. */
70void
71_IO_switch_to_main_wget_area (fp)
72 _IO_FILE *fp;
73{
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;
86}
77fe0b9c 87INTDEF(_IO_switch_to_main_wget_area)
d64b6ad0
UD
88
89
90/* Switch current get area from main get area to (end of) backup area. */
91void
92_IO_switch_to_wbackup_area (fp)
93 _IO_FILE *fp;
94{
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;
107}
77fe0b9c 108INTDEF(_IO_switch_to_wbackup_area)
d64b6ad0
UD
109
110
111void
112_IO_wsetb (f, b, eb, a)
113 _IO_FILE *f;
114 wchar_t *b;
115 wchar_t *eb;
116 int a;
117{
118 if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
119 FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
120 f->_wide_data->_IO_buf_base = b;
121 f->_wide_data->_IO_buf_end = eb;
122 if (a)
123 f->_flags &= ~_IO_USER_BUF;
124 else
125 f->_flags |= _IO_USER_BUF;
126}
77fe0b9c 127INTDEF(_IO_wsetb)
d64b6ad0
UD
128
129
130wint_t
131_IO_wdefault_pbackfail (fp, c)
132 _IO_FILE *fp;
133 wint_t c;
134{
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
140 {
141 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
142 if (!_IO_in_backup (fp))
143 {
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))
148 {
149 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
150 return WEOF;
151 }
152 else if (!_IO_have_wbackup (fp))
153 {
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;
165 }
166 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
77fe0b9c 167 INTUSE(_IO_switch_to_wbackup_area) (fp);
d64b6ad0
UD
168 }
169 else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
170 {
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;
186 }
187
188 *--fp->_wide_data->_IO_read_ptr = c;
189 }
190 return c;
191}
77fe0b9c 192INTDEF(_IO_wdefault_pbackfail)
d64b6ad0
UD
193
194
195void
196_IO_wdefault_finish (fp, dummy)
197 _IO_FILE *fp;
198 int dummy;
199{
200 struct _IO_marker *mark;
201 if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
202 {
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;
206 }
207
208 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
209 mark->_sbuf = NULL;
210
211 if (fp->_IO_save_base)
212 {
213 free (fp->_wide_data->_IO_save_base);
214 fp->_IO_save_base = NULL;
215 }
216
217#ifdef _IO_MTSAFE_IO
c020d48c
UD
218 if (fp->_lock != NULL)
219 _IO_lock_fini (*fp->_lock);
d64b6ad0
UD
220#endif
221
77fe0b9c 222 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
d64b6ad0 223}
77fe0b9c 224INTDEF(_IO_wdefault_finish)
d64b6ad0
UD
225
226
227wint_t
228_IO_wdefault_uflow (fp)
229 _IO_FILE *fp;
230{
231 wint_t wch;
232 wch = _IO_UNDERFLOW (fp);
233 if (wch == WEOF)
234 return WEOF;
235 return *fp->_wide_data->_IO_read_ptr++;
236}
77fe0b9c 237INTDEF(_IO_wdefault_uflow)
d64b6ad0
UD
238
239
240wint_t
241__woverflow (f, wch)
242 _IO_FILE *f;
243 wint_t wch;
244{
245 if (f->_mode == 0)
246 _IO_fwide (f, 1);
247 return _IO_OVERFLOW (f, wch);
248}
37ba7d66 249libc_hidden_def (__woverflow)
d64b6ad0
UD
250
251
252wint_t
253__wuflow (fp)
254 _IO_FILE *fp;
255{
256 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 257 return WEOF;
d64b6ad0
UD
258
259 if (fp->_mode == 0)
260 _IO_fwide (fp, 1);
261 if (_IO_in_put_mode (fp))
77fe0b9c 262 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
d64b6ad0
UD
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))
267 {
77fe0b9c 268 INTUSE(_IO_switch_to_main_wget_area) (fp);
d64b6ad0
UD
269 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
270 return *fp->_wide_data->_IO_read_ptr++;
271 }
272 if (_IO_have_markers (fp))
273 {
274 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
275 return WEOF;
276 }
277 else if (_IO_have_wbackup (fp))
77fe0b9c 278 INTUSE(_IO_free_wbackup_area) (fp);
d64b6ad0
UD
279 return _IO_UFLOW (fp);
280}
a20d8dbe 281libc_hidden_def (__wuflow)
d64b6ad0
UD
282
283wint_t
284__wunderflow (fp)
285 _IO_FILE *fp;
286{
287 if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
655c0697 288 return WEOF;
d64b6ad0 289
6f98fd7e
UD
290 if (fp->_mode == 0)
291 _IO_fwide (fp, 1);
d64b6ad0 292 if (_IO_in_put_mode (fp))
77fe0b9c 293 if (INTUSE(_IO_switch_to_wget_mode) (fp) == EOF)
d64b6ad0
UD
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))
298 {
77fe0b9c 299 INTUSE(_IO_switch_to_main_wget_area) (fp);
d64b6ad0
UD
300 if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
301 return *fp->_wide_data->_IO_read_ptr;
302 }
303 if (_IO_have_markers (fp))
304 {
305 if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
655c0697 306 return WEOF;
d64b6ad0
UD
307 }
308 else if (_IO_have_backup (fp))
77fe0b9c 309 INTUSE(_IO_free_wbackup_area) (fp);
d64b6ad0
UD
310 return _IO_UNDERFLOW (fp);
311}
a20d8dbe 312libc_hidden_def (__wunderflow)
d64b6ad0
UD
313
314
315_IO_size_t
316_IO_wdefault_xsputn (f, data, n)
317 _IO_FILE *f;
318 const void *data;
319 _IO_size_t n;
320{
321 const wchar_t *s = (const wchar_t *) data;
322 _IO_size_t more = n;
323 if (more <= 0)
324 return 0;
325 for (;;)
326 {
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)
331 {
332 if ((_IO_size_t) count > more)
333 count = more;
334 if (count > 20)
335 {
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;
344 }
345 else if (count <= 0)
346 count = 0;
347 else
348 {
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;
354 }
355 more -= count;
356 }
357 if (more == 0 || __woverflow (f, *s++) == WEOF)
358 break;
359 more--;
360 }
361 return n - more;
362}
77fe0b9c 363INTDEF(_IO_wdefault_xsputn)
d64b6ad0
UD
364
365
366_IO_size_t
367_IO_wdefault_xsgetn (fp, data, n)
368 _IO_FILE *fp;
369 void *data;
370 _IO_size_t n;
371{
372 _IO_size_t more = n;
373 wchar_t *s = (wchar_t*) data;
374 for (;;)
375 {
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)
380 {
381 if ((_IO_size_t) count > more)
382 count = more;
383 if (count > 20)
384 {
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;
392 }
393 else if (count <= 0)
394 count = 0;
395 else
396 {
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;
402 }
403 more -= count;
404 }
405 if (more == 0 || __wunderflow (fp) == WEOF)
406 break;
407 }
408 return n - more;
409}
77fe0b9c 410INTDEF(_IO_wdefault_xsgetn)
d64b6ad0
UD
411
412
413void
414_IO_wdoallocbuf (fp)
415 _IO_FILE *fp;
416{
417 if (fp->_wide_data->_IO_buf_base)
418 return;
419 if (!(fp->_flags & _IO_UNBUFFERED))
1dc72e4f 420 if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF)
d64b6ad0 421 return;
77fe0b9c
UD
422 INTUSE(_IO_wsetb) (fp, fp->_wide_data->_shortbuf,
423 fp->_wide_data->_shortbuf + 1, 0);
d64b6ad0 424}
77fe0b9c 425INTDEF(_IO_wdoallocbuf)
d64b6ad0
UD
426
427
428int
429_IO_wdefault_doallocate (fp)
430 _IO_FILE *fp;
431{
432 wchar_t *buf;
433
434 ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
77fe0b9c 435 INTUSE(_IO_wsetb) (fp, buf, buf + _IO_BUFSIZ, 1);
d64b6ad0
UD
436 return 1;
437}
77fe0b9c 438INTDEF(_IO_wdefault_doallocate)
d64b6ad0
UD
439
440
441int
442_IO_switch_to_wget_mode (fp)
443 _IO_FILE *fp;
444{
445 if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
1dc72e4f 446 if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF)
d64b6ad0
UD
447 return EOF;
448 if (_IO_in_backup (fp))
449 fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
450 else
451 {
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;
455 }
456 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
457
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;
460
461 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
462 return 0;
463}
77fe0b9c 464INTDEF(_IO_switch_to_wget_mode)
d64b6ad0
UD
465
466void
467_IO_free_wbackup_area (fp)
468 _IO_FILE *fp;
469{
470 if (_IO_in_backup (fp))
77fe0b9c 471 INTUSE(_IO_switch_to_main_wget_area) (fp); /* Just in case. */
d64b6ad0
UD
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;
476}
77fe0b9c 477INTDEF(_IO_free_wbackup_area)
d64b6ad0
UD
478
479#if 0
480int
481_IO_switch_to_wput_mode (fp)
482 _IO_FILE *fp;
483{
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);
490
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;
493
494 fp->_flags |= _IO_CURRENTLY_PUTTING;
495 return 0;
496}
497#endif
498
499
500static int
501#ifdef _LIBC
502internal_function
503#endif
504save_for_wbackup (fp, end_p)
505 _IO_FILE *fp;
506 wchar_t *end_p;
507{
508 /* Append [_IO_read_base..end_p] to backup area. */
77fe0b9c 509 _IO_ssize_t least_mark = INTUSE(_IO_least_wmarker) (fp, end_p);
d64b6ad0
UD
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)
520 {
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)
528 {
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
543 }
544 else
545 {
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
555 }
556 if (fp->_wide_data->_IO_save_base)
557 free (fp->_wide_data->_IO_save_base);
558 fp->_wide_data->_IO_save_base = new_buffer;
559 fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
560 }
561 else
562 {
563 avail = current_Bsize - needed_size;
564 if (least_mark < 0)
565 {
566#ifdef _LIBC
567 __wmemmove (fp->_wide_data->_IO_save_base + avail,
568 fp->_wide_data->_IO_save_end + least_mark,
569 -least_mark);
570 __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
571 fp->_wide_data->_IO_read_base,
572 end_p - fp->_wide_data->_IO_read_base);
573#else
574 memmove (fp->_wide_data->_IO_save_base + avail,
575 fp->_wide_data->_IO_save_end + least_mark,
576 -least_mark * sizeof (wchar_t));
577 memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
578 fp->_wide_data->_IO_read_base,
579 (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
580#endif
581 }
582 else if (needed_size > 0)
583#ifdef _LIBC
584 __wmemcpy (fp->_wide_data->_IO_save_base + avail,
585 fp->_wide_data->_IO_read_base + least_mark,
586 needed_size);
587#else
588 memcpy (fp->_wide_data->_IO_save_base + avail,
589 fp->_wide_data->_IO_read_base + least_mark,
590 needed_size * sizeof (wchar_t));
591#endif
592 }
593 fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
594 /* Adjust all the streammarkers. */
595 delta = end_p - fp->_wide_data->_IO_read_base;
596 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
597 mark->_pos -= delta;
598 return 0;
599}
600
601wint_t
602_IO_sputbackwc (fp, c)
603 _IO_FILE *fp;
604 wint_t c;
605{
606 wint_t result;
607
608 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
609 && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
610 {
611 fp->_wide_data->_IO_read_ptr--;
612 result = c;
613 }
614 else
615 result = _IO_PBACKFAIL (fp, c);
616
1dc72e4f 617 if (result != WEOF)
d64b6ad0
UD
618 fp->_flags &= ~_IO_EOF_SEEN;
619
620 return result;
621}
77fe0b9c 622INTDEF(_IO_sputbackwc)
d64b6ad0
UD
623
624wint_t
625_IO_sungetwc (fp)
626 _IO_FILE *fp;
627{
1dc72e4f 628 wint_t result;
d64b6ad0
UD
629
630 if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
631 {
632 fp->_wide_data->_IO_read_ptr--;
633 result = *fp->_wide_data->_IO_read_ptr;
634 }
635 else
636 result = _IO_PBACKFAIL (fp, EOF);
637
638 if (result != WEOF)
639 fp->_flags &= ~_IO_EOF_SEEN;
640
641 return result;
642}
643
644
645unsigned
646_IO_adjust_wcolumn (start, line, count)
647 unsigned start;
648 const wchar_t *line;
649 int count;
650{
651 const wchar_t *ptr = line + count;
652 while (ptr > line)
653 if (*--ptr == L'\n')
654 return line + count - ptr - 1;
655 return start + count;
656}
657
658void
659_IO_init_wmarker (marker, fp)
660 struct _IO_marker *marker;
661 _IO_FILE *fp;
662{
663 marker->_sbuf = fp;
664 if (_IO_in_put_mode (fp))
77fe0b9c 665 INTUSE(_IO_switch_to_wget_mode) (fp);
d64b6ad0
UD
666 if (_IO_in_backup (fp))
667 marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
668 else
669 marker->_pos = (fp->_wide_data->_IO_read_ptr
670 - fp->_wide_data->_IO_read_base);
671
672 /* Should perhaps sort the chain? */
673 marker->_next = fp->_markers;
674 fp->_markers = marker;
675}
676
677#define BAD_DELTA EOF
678
679/* Return difference between MARK and current position of MARK's stream. */
680int
681_IO_wmarker_delta (mark)
682 struct _IO_marker *mark;
683{
684 int cur_pos;
685 if (mark->_sbuf == NULL)
686 return BAD_DELTA;
687 if (_IO_in_backup (mark->_sbuf))
688 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
689 - mark->_sbuf->_wide_data->_IO_read_end);
690 else
691 cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
692 - mark->_sbuf->_wide_data->_IO_read_base);
693 return mark->_pos - cur_pos;
694}
695
696int
697_IO_seekwmark (fp, mark, delta)
698 _IO_FILE *fp;
699 struct _IO_marker *mark;
700 int delta;
701{
702 if (mark->_sbuf != fp)
703 return EOF;
704 if (mark->_pos >= 0)
705 {
706 if (_IO_in_backup (fp))
77fe0b9c 707 INTUSE(_IO_switch_to_main_wget_area) (fp);
d64b6ad0
UD
708 fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
709 + mark->_pos);
710 }
711 else
712 {
713 if (!_IO_in_backup (fp))
77fe0b9c 714 INTUSE(_IO_switch_to_wbackup_area) (fp);
d64b6ad0
UD
715 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
716 }
717 return 0;
718}
719
720void
721_IO_unsave_wmarkers (fp)
722 _IO_FILE *fp;
723{
724 struct _IO_marker *mark = fp->_markers;
725 if (mark)
726 {
727#ifdef TODO
728 streampos offset = seekoff (0, ios::cur, ios::in);
729 if (offset != EOF)
730 {
731 offset += eGptr () - Gbase ();
732 for ( ; mark != NULL; mark = mark->_next)
733 mark->set_streampos (mark->_pos + offset);
734 }
735 else
736 {
737 for ( ; mark != NULL; mark = mark->_next)
738 mark->set_streampos (EOF);
739 }
740#endif
741 fp->_markers = 0;
742 }
743
744 if (_IO_have_backup (fp))
77fe0b9c 745 INTUSE(_IO_free_wbackup_area) (fp);
d64b6ad0 746}
This page took 0.267451 seconds and 5 git commands to generate.