]> gcc.gnu.org Git - gcc.git/blame - libstdc++-v3/libio/genops.c
* gcc.c (.h spec): Fix typo.
[gcc.git] / libstdc++-v3 / libio / genops.c
CommitLineData
20427c6b 1/* Copyright (C) 1993, 1995, 1997-1999, 2000 Free Software Foundation, Inc.
b2dad0e3
BK
2 This file is part of the GNU IO Library.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this library; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17 MA 02111-1307, USA.
18
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does
21 not cause the resulting executable to be covered by the GNU General
22 Public License. This exception does not however invalidate any
23 other reasons why the executable file might be covered by the GNU
24 General Public License. */
25
26/* Generic or default I/O operations. */
27
28#include "libioP.h"
29#ifdef __STDC__
30#include <stdlib.h>
31#endif
32#include <string.h>
33
20427c6b
BK
34#ifdef _IO_MTSAFE_IO
35static _IO_lock_t list_all_lock = _IO_lock_initializer;
36#endif
37
b2dad0e3
BK
38void
39_IO_un_link (fp)
20427c6b 40 struct _IO_FILE_plus *fp;
b2dad0e3 41{
20427c6b 42 if (fp->file._flags & _IO_LINKED)
b2dad0e3 43 {
20427c6b
BK
44 struct _IO_FILE_plus **f;
45#ifdef _IO_MTSAFE_IO
46 _IO_lock_lock (list_all_lock);
47#endif
48 for (f = &_IO_list_all; *f != NULL; f = &(*f)->file._chain)
b2dad0e3
BK
49 {
50 if (*f == fp)
51 {
20427c6b 52 *f = fp->file._chain;
b2dad0e3
BK
53 break;
54 }
55 }
20427c6b
BK
56#ifdef _IO_MTSAFE_IO
57 _IO_lock_unlock (list_all_lock);
58#endif
59 fp->file._flags &= ~_IO_LINKED;
b2dad0e3
BK
60 }
61}
62
63void
64_IO_link_in (fp)
20427c6b 65 struct _IO_FILE_plus *fp;
b2dad0e3 66{
20427c6b 67 if ((fp->file._flags & _IO_LINKED) == 0)
b2dad0e3 68 {
20427c6b
BK
69 fp->file._flags |= _IO_LINKED;
70#ifdef _IO_MTSAFE_IO
71 _IO_lock_lock (list_all_lock);
72#endif
73 fp->file._chain = _IO_list_all;
b2dad0e3 74 _IO_list_all = fp;
20427c6b
BK
75#ifdef _IO_MTSAFE_IO
76 _IO_lock_unlock (list_all_lock);
77#endif
b2dad0e3
BK
78 }
79}
80
81/* Return minimum _pos markers
82 Assumes the current get area is the main get area. */
20427c6b 83_IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
b2dad0e3 84
20427c6b
BK
85_IO_ssize_t
86_IO_least_marker (fp, end_p)
b2dad0e3 87 _IO_FILE *fp;
20427c6b 88 char *end_p;
b2dad0e3 89{
20427c6b 90 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
b2dad0e3
BK
91 struct _IO_marker *mark;
92 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
93 if (mark->_pos < least_so_far)
94 least_so_far = mark->_pos;
95 return least_so_far;
96}
97
98/* Switch current get area from backup buffer to (start of) main get area. */
99
100void
101_IO_switch_to_main_get_area (fp)
102 _IO_FILE *fp;
103{
104 char *tmp;
105 fp->_flags &= ~_IO_IN_BACKUP;
106 /* Swap _IO_read_end and _IO_save_end. */
107 tmp = fp->_IO_read_end;
108 fp->_IO_read_end = fp->_IO_save_end;
109 fp->_IO_save_end= tmp;
110 /* Swap _IO_read_base and _IO_save_base. */
111 tmp = fp->_IO_read_base;
112 fp->_IO_read_base = fp->_IO_save_base;
113 fp->_IO_save_base = tmp;
20427c6b 114 /* Set _IO_read_ptr. */
b2dad0e3
BK
115 fp->_IO_read_ptr = fp->_IO_read_base;
116}
117
118/* Switch current get area from main get area to (end of) backup area. */
119
120void
121_IO_switch_to_backup_area (fp)
122 _IO_FILE *fp;
123{
124 char *tmp;
125 fp->_flags |= _IO_IN_BACKUP;
126 /* Swap _IO_read_end and _IO_save_end. */
127 tmp = fp->_IO_read_end;
128 fp->_IO_read_end = fp->_IO_save_end;
129 fp->_IO_save_end = tmp;
20427c6b 130 /* Swap _IO_read_base and _IO_save_base. */
b2dad0e3
BK
131 tmp = fp->_IO_read_base;
132 fp->_IO_read_base = fp->_IO_save_base;
133 fp->_IO_save_base = tmp;
20427c6b 134 /* Set _IO_read_ptr. */
b2dad0e3
BK
135 fp->_IO_read_ptr = fp->_IO_read_end;
136}
137
138int
139_IO_switch_to_get_mode (fp)
140 _IO_FILE *fp;
141{
142 if (fp->_IO_write_ptr > fp->_IO_write_base)
143 if (_IO_OVERFLOW (fp, EOF) == EOF)
144 return EOF;
145 if (_IO_in_backup (fp))
146 fp->_IO_read_base = fp->_IO_backup_base;
147 else
148 {
149 fp->_IO_read_base = fp->_IO_buf_base;
150 if (fp->_IO_write_ptr > fp->_IO_read_end)
151 fp->_IO_read_end = fp->_IO_write_ptr;
152 }
153 fp->_IO_read_ptr = fp->_IO_write_ptr;
154
155 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
156
157 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
158 return 0;
159}
160
161void
162_IO_free_backup_area (fp)
163 _IO_FILE *fp;
164{
165 if (_IO_in_backup (fp))
166 _IO_switch_to_main_get_area (fp); /* Just in case. */
167 free (fp->_IO_save_base);
168 fp->_IO_save_base = NULL;
169 fp->_IO_save_end = NULL;
170 fp->_IO_backup_base = NULL;
171}
172
173#if 0
174int
175_IO_switch_to_put_mode (fp)
176 _IO_FILE *fp;
177{
178 fp->_IO_write_base = fp->_IO_read_ptr;
179 fp->_IO_write_ptr = fp->_IO_read_ptr;
180 /* Following is wrong if line- or un-buffered? */
181 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
182 ? fp->_IO_read_end : fp->_IO_buf_end);
183
184 fp->_IO_read_ptr = fp->_IO_read_end;
185 fp->_IO_read_base = fp->_IO_read_end;
186
187 fp->_flags |= _IO_CURRENTLY_PUTTING;
188 return 0;
189}
190#endif
191
192int
193__overflow (f, ch)
194 _IO_FILE *f;
195 int ch;
196{
197 return _IO_OVERFLOW (f, ch);
198}
199
20427c6b
BK
200static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
201#ifdef _LIBC
202 internal_function
203#endif
204 ;
b2dad0e3 205
20427c6b
BK
206static int
207#ifdef _LIBC
208internal_function
209#endif
210save_for_backup (fp, end_p)
b2dad0e3 211 _IO_FILE *fp;
20427c6b 212 char *end_p;
b2dad0e3 213{
20427c6b
BK
214 /* Append [_IO_read_base..end_p] to backup area. */
215 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
b2dad0e3 216 /* needed_size is how much space we need in the backup area. */
20427c6b
BK
217 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
218 /* FIXME: Dubious arithmetic if pointers are NULL */
219 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
220 _IO_size_t avail; /* Extra space available for future expansion. */
221 _IO_ssize_t delta;
b2dad0e3
BK
222 struct _IO_marker *mark;
223 if (needed_size > current_Bsize)
224 {
225 char *new_buffer;
226 avail = 100;
227 new_buffer = (char *) malloc (avail + needed_size);
228 if (new_buffer == NULL)
229 return EOF; /* FIXME */
230 if (least_mark < 0)
231 {
20427c6b
BK
232#ifdef _LIBC
233 __mempcpy (__mempcpy (new_buffer + avail,
234 fp->_IO_save_end + least_mark,
235 -least_mark),
236 fp->_IO_read_base,
237 end_p - fp->_IO_read_base);
238#else
b2dad0e3
BK
239 memcpy (new_buffer + avail,
240 fp->_IO_save_end + least_mark,
241 -least_mark);
242 memcpy (new_buffer + avail - least_mark,
243 fp->_IO_read_base,
20427c6b
BK
244 end_p - fp->_IO_read_base);
245#endif
b2dad0e3
BK
246 }
247 else
248 memcpy (new_buffer + avail,
249 fp->_IO_read_base + least_mark,
250 needed_size);
251 if (fp->_IO_save_base)
252 free (fp->_IO_save_base);
253 fp->_IO_save_base = new_buffer;
254 fp->_IO_save_end = new_buffer + avail + needed_size;
255 }
256 else
257 {
258 avail = current_Bsize - needed_size;
259 if (least_mark < 0)
260 {
261 memmove (fp->_IO_save_base + avail,
262 fp->_IO_save_end + least_mark,
263 -least_mark);
264 memcpy (fp->_IO_save_base + avail - least_mark,
265 fp->_IO_read_base,
20427c6b 266 end_p - fp->_IO_read_base);
b2dad0e3
BK
267 }
268 else if (needed_size > 0)
269 memcpy (fp->_IO_save_base + avail,
270 fp->_IO_read_base + least_mark,
271 needed_size);
272 }
b2dad0e3
BK
273 fp->_IO_backup_base = fp->_IO_save_base + avail;
274 /* Adjust all the streammarkers. */
20427c6b 275 delta = end_p - fp->_IO_read_base;
b2dad0e3
BK
276 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
277 mark->_pos -= delta;
278 return 0;
279}
280
281int
282__underflow (fp)
283 _IO_FILE *fp;
284{
20427c6b
BK
285#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
286 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
287 return EOF;
288#endif
289
b2dad0e3
BK
290 if (_IO_in_put_mode (fp))
291 if (_IO_switch_to_get_mode (fp) == EOF)
292 return EOF;
293 if (fp->_IO_read_ptr < fp->_IO_read_end)
294 return *(unsigned char *) fp->_IO_read_ptr;
295 if (_IO_in_backup (fp))
296 {
297 _IO_switch_to_main_get_area (fp);
298 if (fp->_IO_read_ptr < fp->_IO_read_end)
299 return *(unsigned char *) fp->_IO_read_ptr;
300 }
301 if (_IO_have_markers (fp))
302 {
20427c6b 303 if (save_for_backup (fp, fp->_IO_read_end))
b2dad0e3
BK
304 return EOF;
305 }
306 else if (_IO_have_backup (fp))
307 _IO_free_backup_area (fp);
308 return _IO_UNDERFLOW (fp);
309}
310
311int
312__uflow (fp)
313 _IO_FILE *fp;
314{
20427c6b
BK
315#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
316 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
317 return EOF;
318#endif
319
b2dad0e3
BK
320 if (_IO_in_put_mode (fp))
321 if (_IO_switch_to_get_mode (fp) == EOF)
322 return EOF;
323 if (fp->_IO_read_ptr < fp->_IO_read_end)
324 return *(unsigned char *) fp->_IO_read_ptr++;
325 if (_IO_in_backup (fp))
326 {
327 _IO_switch_to_main_get_area (fp);
328 if (fp->_IO_read_ptr < fp->_IO_read_end)
329 return *(unsigned char *) fp->_IO_read_ptr++;
330 }
331 if (_IO_have_markers (fp))
332 {
20427c6b 333 if (save_for_backup (fp, fp->_IO_read_end))
b2dad0e3
BK
334 return EOF;
335 }
336 else if (_IO_have_backup (fp))
337 _IO_free_backup_area (fp);
338 return _IO_UFLOW (fp);
339}
340
341void
342_IO_setb (f, b, eb, a)
343 _IO_FILE *f;
344 char *b;
345 char *eb;
346 int a;
347{
348 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
349 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
350 f->_IO_buf_base = b;
351 f->_IO_buf_end = eb;
352 if (a)
353 f->_flags &= ~_IO_USER_BUF;
354 else
355 f->_flags |= _IO_USER_BUF;
356}
357
358void
359_IO_doallocbuf (fp)
360 _IO_FILE *fp;
361{
362 if (fp->_IO_buf_base)
363 return;
364 if (!(fp->_flags & _IO_UNBUFFERED))
365 if (_IO_DOALLOCATE (fp) != EOF)
366 return;
367 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
368}
369
370int
371_IO_default_underflow (fp)
372 _IO_FILE *fp;
373{
374 return EOF;
375}
376
377int
378_IO_default_uflow (fp)
379 _IO_FILE *fp;
380{
381 int ch = _IO_UNDERFLOW (fp);
382 if (ch == EOF)
383 return EOF;
384 return *(unsigned char *) fp->_IO_read_ptr++;
385}
386
387_IO_size_t
388_IO_default_xsputn (f, data, n)
389 _IO_FILE *f;
390 const void *data;
391 _IO_size_t n;
392{
393 const char *s = (char *) data;
394 _IO_size_t more = n;
395 if (more <= 0)
396 return 0;
397 for (;;)
398 {
399 /* Space available. */
400 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
401 if (count > 0)
402 {
403 if ((_IO_size_t) count > more)
404 count = more;
405 if (count > 20)
406 {
20427c6b
BK
407#ifdef _LIBC
408 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
409#else
b2dad0e3 410 memcpy (f->_IO_write_ptr, s, count);
b2dad0e3 411 f->_IO_write_ptr += count;
20427c6b
BK
412#endif
413 s += count;
b2dad0e3
BK
414 }
415 else if (count <= 0)
416 count = 0;
417 else
418 {
419 char *p = f->_IO_write_ptr;
420 _IO_ssize_t i;
421 for (i = count; --i >= 0; )
422 *p++ = *s++;
423 f->_IO_write_ptr = p;
424 }
425 more -= count;
426 }
20427c6b 427 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
b2dad0e3
BK
428 break;
429 more--;
430 }
431 return n - more;
432}
433
434_IO_size_t
435_IO_sgetn (fp, data, n)
436 _IO_FILE *fp;
437 void *data;
438 _IO_size_t n;
439{
440 /* FIXME handle putback buffer here! */
441 return _IO_XSGETN (fp, data, n);
442}
443
444_IO_size_t
445_IO_default_xsgetn (fp, data, n)
446 _IO_FILE *fp;
447 void *data;
448 _IO_size_t n;
449{
450 _IO_size_t more = n;
451 char *s = (char*) data;
452 for (;;)
453 {
454 /* Data available. */
455 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
456 if (count > 0)
457 {
458 if ((_IO_size_t) count > more)
459 count = more;
460 if (count > 20)
461 {
20427c6b
BK
462#ifdef _LIBC
463 s = __mempcpy (s, fp->_IO_read_ptr, count);
464#else
b2dad0e3
BK
465 memcpy (s, fp->_IO_read_ptr, count);
466 s += count;
20427c6b 467#endif
b2dad0e3
BK
468 fp->_IO_read_ptr += count;
469 }
470 else if (count <= 0)
471 count = 0;
472 else
473 {
474 char *p = fp->_IO_read_ptr;
475 int i = (int) count;
476 while (--i >= 0)
477 *s++ = *p++;
478 fp->_IO_read_ptr = p;
479 }
480 more -= count;
481 }
482 if (more == 0 || __underflow (fp) == EOF)
483 break;
484 }
485 return n - more;
486}
487
488#if 0
489/* Seems not to be needed. --drepper */
490int
491_IO_sync (fp)
492 _IO_FILE *fp;
493{
494 return 0;
495}
496#endif
497
498_IO_FILE *
499_IO_default_setbuf (fp, p, len)
500 _IO_FILE *fp;
501 char *p;
502 _IO_ssize_t len;
503{
504 if (_IO_SYNC (fp) == EOF)
505 return NULL;
506 if (p == NULL || len == 0)
507 {
508 fp->_flags |= _IO_UNBUFFERED;
509 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
510 }
511 else
512 {
513 fp->_flags &= ~_IO_UNBUFFERED;
514 _IO_setb (fp, p, p+len, 0);
515 }
516 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
517 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
518 return fp;
519}
520
f3b004d8 521_IO_off64_t
b2dad0e3
BK
522_IO_default_seekpos (fp, pos, mode)
523 _IO_FILE *fp;
f3b004d8 524 _IO_off64_t pos;
b2dad0e3
BK
525 int mode;
526{
f3b004d8 527 return _IO_SEEKOFF (fp, pos, 0, mode);
b2dad0e3
BK
528}
529
530int
531_IO_default_doallocate (fp)
532 _IO_FILE *fp;
533{
534 char *buf;
535
536 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
537 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
538 return 1;
539}
540
541void
542_IO_init (fp, flags)
543 _IO_FILE *fp;
544 int flags;
20427c6b
BK
545{
546 _IO_no_init (fp, flags, -1, NULL, NULL);
547}
548
549void
550_IO_no_init (fp, flags, orientation, wd, jmp)
551 _IO_FILE *fp;
552 int flags;
553 int orientation;
554 struct _IO_wide_data *wd;
555 struct _IO_jump_t *jmp;
b2dad0e3
BK
556{
557 fp->_flags = _IO_MAGIC|flags;
558 fp->_IO_buf_base = NULL;
559 fp->_IO_buf_end = NULL;
560 fp->_IO_read_base = NULL;
561 fp->_IO_read_ptr = NULL;
562 fp->_IO_read_end = NULL;
563 fp->_IO_write_base = NULL;
564 fp->_IO_write_ptr = NULL;
565 fp->_IO_write_end = NULL;
566 fp->_chain = NULL; /* Not necessary. */
567
568 fp->_IO_save_base = NULL;
569 fp->_IO_backup_base = NULL;
570 fp->_IO_save_end = NULL;
571 fp->_markers = NULL;
572 fp->_cur_column = 0;
20427c6b
BK
573#if _IO_JUMPS_OFFSET
574 fp->_vtable_offset = 0;
575#endif
b2dad0e3
BK
576#ifdef _IO_MTSAFE_IO
577 _IO_lock_init (*fp->_lock);
20427c6b
BK
578#endif
579 fp->_mode = orientation;
580#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
581 if (orientation >= 0)
582 {
583 fp->_wide_data = wd;
584 fp->_wide_data->_IO_buf_base = NULL;
585 fp->_wide_data->_IO_buf_end = NULL;
586 fp->_wide_data->_IO_read_base = NULL;
587 fp->_wide_data->_IO_read_ptr = NULL;
588 fp->_wide_data->_IO_read_end = NULL;
589 fp->_wide_data->_IO_write_base = NULL;
590 fp->_wide_data->_IO_write_ptr = NULL;
591 fp->_wide_data->_IO_write_end = NULL;
592 fp->_wide_data->_IO_save_base = NULL;
593 fp->_wide_data->_IO_backup_base = NULL;
594 fp->_wide_data->_IO_save_end = NULL;
595
596 fp->_wide_data->_wide_vtable = jmp;
597 }
b2dad0e3
BK
598#endif
599}
600
601int
602_IO_default_sync (fp)
603 _IO_FILE *fp;
604{
605 return 0;
606}
607
608/* The way the C++ classes are mapped into the C functions in the
609 current implementation, this function can get called twice! */
610
611void
612_IO_default_finish (fp, dummy)
613 _IO_FILE *fp;
614 int dummy;
615{
616 struct _IO_marker *mark;
617 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
618 {
619 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
620 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
621 }
622
623 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
624 mark->_sbuf = NULL;
625
626 if (fp->_IO_save_base)
627 {
628 free (fp->_IO_save_base);
629 fp->_IO_save_base = NULL;
630 }
631
632#ifdef _IO_MTSAFE_IO
633 _IO_lock_fini (*fp->_lock);
634#endif
635
20427c6b 636 _IO_un_link ((struct _IO_FILE_plus *) fp);
b2dad0e3
BK
637}
638
f3b004d8
BK
639_IO_off64_t
640_IO_default_seekoff (fp, offset, dir, mode)
641 _IO_FILE *fp;
642 _IO_off64_t offset;
643 int dir;
644 int mode;
b2dad0e3
BK
645{
646 return _IO_pos_BAD;
647}
648
649int
650_IO_sputbackc (fp, c)
651 _IO_FILE *fp;
652 int c;
653{
654 int result;
655
656 if (fp->_IO_read_ptr > fp->_IO_read_base
657 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
658 {
659 fp->_IO_read_ptr--;
660 result = (unsigned char) c;
661 }
662 else
663 result = _IO_PBACKFAIL (fp, c);
664
665 if (result != EOF)
666 fp->_flags &= ~_IO_EOF_SEEN;
667
668 return result;
669}
670
671int
672_IO_sungetc (fp)
673 _IO_FILE *fp;
674{
675 int result;
676
677 if (fp->_IO_read_ptr > fp->_IO_read_base)
678 {
679 fp->_IO_read_ptr--;
680 result = (unsigned char) *fp->_IO_read_ptr;
681 }
682 else
683 result = _IO_PBACKFAIL (fp, EOF);
684
685 if (result != EOF)
686 fp->_flags &= ~_IO_EOF_SEEN;
687
688 return result;
689}
690
691#if 0 /* Work in progress */
692/* Seems not to be needed. */
693#if 0
694void
695_IO_set_column (fp, c)
696 _IO_FILE *fp;
697 int c;
698{
699 if (c == -1)
700 fp->_column = -1;
701 else
702 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
703}
704#else
705int
706_IO_set_column (fp, i)
707 _IO_FILE *fp;
708 int i;
709{
710 fp->_cur_column = i + 1;
711 return 0;
712}
713#endif
714#endif
715
716
717unsigned
718_IO_adjust_column (start, line, count)
719 unsigned start;
720 const char *line;
721 int count;
722{
723 const char *ptr = line + count;
724 while (ptr > line)
725 if (*--ptr == '\n')
726 return line + count - ptr - 1;
727 return start + count;
728}
729
730#if 0
731/* Seems not to be needed. --drepper */
732int
733_IO_get_column (fp)
734 _IO_FILE *fp;
735{
736 if (fp->_cur_column)
737 return _IO_adjust_column (fp->_cur_column - 1,
738 fp->_IO_write_base,
739 fp->_IO_write_ptr - fp->_IO_write_base);
740 return -1;
741}
742#endif
743
744int
745_IO_flush_all ()
746{
747 int result = 0;
20427c6b
BK
748 struct _IO_FILE_plus *fp;
749 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
750 if (((fp->file._mode < 0 && fp->file._IO_write_ptr > fp->file._IO_write_base)
751#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
752
753 || (fp->file._vtable_offset == 0
754 && fp->file._mode > 0 && (fp->file._wide_data->_IO_write_ptr
755 > fp->file._wide_data->_IO_write_base))
756#endif
757 )
758 && _IO_OVERFLOW (&fp->file, EOF) == EOF)
b2dad0e3
BK
759 result = EOF;
760 return result;
761}
762
763void
764_IO_flush_all_linebuffered ()
765{
20427c6b
BK
766 struct _IO_FILE_plus *fp;
767 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
768 if ((fp->file._flags & _IO_NO_WRITES) == 0 && fp->file._flags & _IO_LINE_BUF)
769 _IO_OVERFLOW (&fp->file, EOF);
b2dad0e3
BK
770}
771
20427c6b 772static void _IO_unbuffer_write __P ((void));
b2dad0e3
BK
773
774static void
20427c6b 775_IO_unbuffer_write ()
b2dad0e3 776{
20427c6b
BK
777 struct _IO_FILE_plus *fp;
778 for (fp = _IO_list_all; fp != NULL; fp = fp->file._chain)
779 if (! (fp->file._flags & _IO_UNBUFFERED)
780 && (! (fp->file._flags & _IO_NO_WRITES)
781 || (fp->file._flags & _IO_IS_APPENDING)))
782 _IO_SETBUF (&fp->file, NULL, 0);
b2dad0e3
BK
783}
784
20427c6b 785int
b2dad0e3
BK
786_IO_cleanup ()
787{
20427c6b 788 int result = _IO_flush_all ();
b2dad0e3
BK
789
790 /* We currently don't have a reliable mechanism for making sure that
791 C++ static destructors are executed in the correct order.
792 So it is possible that other static destructors might want to
793 write to cout - and they're supposed to be able to do so.
794
795 The following will make the standard streambufs be unbuffered,
796 which forces any output from late destructors to be written out. */
20427c6b
BK
797 _IO_unbuffer_write ();
798
799 return result;
b2dad0e3
BK
800}
801
20427c6b 802
b2dad0e3
BK
803void
804_IO_init_marker (marker, fp)
805 struct _IO_marker *marker;
806 _IO_FILE *fp;
807{
808 marker->_sbuf = fp;
809 if (_IO_in_put_mode (fp))
810 _IO_switch_to_get_mode (fp);
811 if (_IO_in_backup (fp))
812 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
813 else
814 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
815
816 /* Should perhaps sort the chain? */
817 marker->_next = fp->_markers;
818 fp->_markers = marker;
819}
820
821void
822_IO_remove_marker (marker)
823 struct _IO_marker *marker;
824{
825 /* Unlink from sb's chain. */
826 struct _IO_marker **ptr = &marker->_sbuf->_markers;
827 for (; ; ptr = &(*ptr)->_next)
828 {
829 if (*ptr == NULL)
830 break;
831 else if (*ptr == marker)
832 {
833 *ptr = marker->_next;
834 return;
835 }
836 }
837#if 0
838 if _sbuf has a backup area that is no longer needed, should we delete
839 it now, or wait until the next underflow?
840#endif
841}
842
843#define BAD_DELTA EOF
844
845int
846_IO_marker_difference (mark1, mark2)
847 struct _IO_marker *mark1;
848 struct _IO_marker *mark2;
849{
850 return mark1->_pos - mark2->_pos;
851}
852
853/* Return difference between MARK and current position of MARK's stream. */
854int
855_IO_marker_delta (mark)
856 struct _IO_marker *mark;
857{
858 int cur_pos;
859 if (mark->_sbuf == NULL)
860 return BAD_DELTA;
861 if (_IO_in_backup (mark->_sbuf))
862 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
863 else
864 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
865 return mark->_pos - cur_pos;
866}
867
868int
869_IO_seekmark (fp, mark, delta)
870 _IO_FILE *fp;
871 struct _IO_marker *mark;
872 int delta;
873{
874 if (mark->_sbuf != fp)
875 return EOF;
876 if (mark->_pos >= 0)
877 {
878 if (_IO_in_backup (fp))
879 _IO_switch_to_main_get_area (fp);
880 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
881 }
882 else
883 {
884 if (!_IO_in_backup (fp))
885 _IO_switch_to_backup_area (fp);
886 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
887 }
888 return 0;
889}
890
891void
892_IO_unsave_markers (fp)
893 _IO_FILE *fp;
894{
895 struct _IO_marker *mark = fp->_markers;
896 if (mark)
897 {
898#ifdef TODO
899 streampos offset = seekoff (0, ios::cur, ios::in);
900 if (offset != EOF)
901 {
902 offset += eGptr () - Gbase ();
903 for ( ; mark != NULL; mark = mark->_next)
904 mark->set_streampos (mark->_pos + offset);
905 }
906 else
907 {
908 for ( ; mark != NULL; mark = mark->_next)
909 mark->set_streampos (EOF);
910 }
911#endif
912 fp->_markers = 0;
913 }
914
915 if (_IO_have_backup (fp))
916 _IO_free_backup_area (fp);
917}
918
919#if 0
920/* Seems not to be needed. --drepper */
921int
922_IO_nobackup_pbackfail (fp, c)
923 _IO_FILE *fp;
924 int c;
925{
926 if (fp->_IO_read_ptr > fp->_IO_read_base)
927 fp->_IO_read_ptr--;
928 if (c != EOF && *fp->_IO_read_ptr != c)
929 *fp->_IO_read_ptr = c;
930 return (unsigned char) c;
931}
932#endif
933
934int
935_IO_default_pbackfail (fp, c)
936 _IO_FILE *fp;
937 int c;
938{
20427c6b
BK
939 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
940 && (unsigned char) fp->_IO_read_ptr[-1] == c)
941 --fp->_IO_read_ptr;
942 else
b2dad0e3
BK
943 {
944 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
20427c6b 945 if (!_IO_in_backup (fp))
b2dad0e3 946 {
20427c6b
BK
947 /* We need to keep the invariant that the main get area
948 logically follows the backup area. */
949 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
950 {
951 if (save_for_backup (fp, fp->_IO_read_ptr))
952 return EOF;
953 }
954 else if (!_IO_have_backup (fp))
955 {
956 /* No backup buffer: allocate one. */
957 /* Use nshort buffer, if unused? (probably not) FIXME */
958 int backup_size = 128;
959 char *bbuf = (char *) malloc (backup_size);
960 if (bbuf == NULL)
961 return EOF;
962 fp->_IO_save_base = bbuf;
963 fp->_IO_save_end = fp->_IO_save_base + backup_size;
964 fp->_IO_backup_base = fp->_IO_save_end;
965 }
966 fp->_IO_read_base = fp->_IO_read_ptr;
b2dad0e3
BK
967 _IO_switch_to_backup_area (fp);
968 }
969 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
970 {
971 /* Increase size of existing backup buffer. */
972 _IO_size_t new_size;
973 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
974 char *new_buf;
975 new_size = 2 * old_size;
976 new_buf = (char *) malloc (new_size);
977 if (new_buf == NULL)
978 return EOF;
979 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
980 old_size);
981 free (fp->_IO_read_base);
982 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
983 new_buf + new_size);
984 fp->_IO_backup_base = fp->_IO_read_ptr;
985 }
20427c6b
BK
986
987 *--fp->_IO_read_ptr = c;
b2dad0e3 988 }
20427c6b 989 return (unsigned char) c;
b2dad0e3
BK
990}
991
f3b004d8
BK
992_IO_off64_t
993_IO_default_seek (fp, offset, dir)
994 _IO_FILE *fp;
995 _IO_off64_t offset;
996 int dir;
b2dad0e3
BK
997{
998 return _IO_pos_BAD;
999}
1000
1001int
1002_IO_default_stat (fp, st)
1003 _IO_FILE *fp;
1004 void* st;
1005{
1006 return EOF;
1007}
1008
1009_IO_ssize_t
1010_IO_default_read (fp, data, n)
1011 _IO_FILE* fp;
1012 void *data;
1013 _IO_ssize_t n;
1014{
1015 return -1;
1016}
1017
1018_IO_ssize_t
1019_IO_default_write (fp, data, n)
1020 _IO_FILE *fp;
1021 const void *data;
1022 _IO_ssize_t n;
1023{
1024 return 0;
1025}
1026
20427c6b
BK
1027int
1028_IO_default_showmanyc (fp)
1029 _IO_FILE *fp;
1030{
1031 return -1;
1032}
1033
1034void
1035_IO_default_imbue (fp, locale)
1036 _IO_FILE *fp;
1037 void *locale;
1038{
1039}
1040
1041_IO_ITER
1042_IO_iter_begin()
1043{
1044 return _IO_list_all;
1045}
1046
1047_IO_ITER
1048_IO_iter_end()
1049{
1050 return NULL;
1051}
1052
1053_IO_ITER
1054_IO_iter_next(iter)
1055 _IO_ITER iter;
1056{
1057 return iter->file._chain;
1058}
1059
1060_IO_FILE *
1061_IO_iter_file(iter)
1062 _IO_ITER iter;
1063{
1064 return (_IO_FILE *) iter;
1065}
1066
1067void
1068_IO_list_lock()
1069{
1070#ifdef _IO_MTSAFE_IO
1071 _IO_lock_lock (list_all_lock);
1072#endif
1073}
1074
1075void
1076_IO_list_unlock()
1077{
1078#ifdef _IO_MTSAFE_IO
1079 _IO_lock_unlock (list_all_lock);
1080#endif
1081}
1082
1083void
1084_IO_list_resetlock()
1085{
1086#ifdef _IO_MTSAFE_IO
1087 _IO_lock_init (list_all_lock);
1088#endif
1089}
1090
b2dad0e3
BK
1091
1092#ifdef TODO
1093#if defined(linux)
1094#define IO_CLEANUP ;
1095#endif
1096
1097#ifdef IO_CLEANUP
1098 IO_CLEANUP
1099#else
1100struct __io_defs {
1101 __io_defs() { }
1102 ~__io_defs() { _IO_cleanup (); }
1103};
1104__io_defs io_defs__;
1105#endif
1106
1107#endif /* TODO */
1108
1109#ifdef weak_alias
1110weak_alias (_IO_cleanup, _cleanup)
b2dad0e3
BK
1111#endif
1112
1113#ifdef text_set_element
1114text_set_element(__libc_atexit, _cleanup);
1115#endif
This page took 0.16743 seconds and 5 git commands to generate.