diff options
Diffstat (limited to 'REORG.TODO/libio')
211 files changed, 26772 insertions, 0 deletions
diff --git a/REORG.TODO/libio/Depend b/REORG.TODO/libio/Depend new file mode 100644 index 0000000000..f3e1156a4e --- /dev/null +++ b/REORG.TODO/libio/Depend @@ -0,0 +1 @@ +localedata diff --git a/REORG.TODO/libio/Makefile b/REORG.TODO/libio/Makefile new file mode 100644 index 0000000000..a002a3365c --- /dev/null +++ b/REORG.TODO/libio/Makefile @@ -0,0 +1,220 @@ +# Copyright (C) 1995-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +# +# Specific makefile for libio. +# +subdir := libio + +include ../Makeconfig + +headers := stdio.h libio.h _G_config.h bits/stdio.h \ + bits/sys_errlist.h bits/stdio2.h bits/stdio-ldbl.h bits/libio-ldbl.h \ + bits/types/FILE.h bits/types/__FILE.h + +routines := \ + filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \ + iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \ + iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \ + ioseekoff ioseekpos iosetbuffer iosetvbuf ioungetc \ + iovsprintf iovsscanf \ + iofgetpos64 iofopen64 iofsetpos64 \ + fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \ + iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \ + putwchar putwchar_u putchar putchar_u fwprintf swprintf vwprintf \ + wprintf wscanf fwscanf vwscanf vswprintf iovswscanf swscanf wgenops \ + wstrops wfileops iofwide fwide wmemstream \ + \ + clearerr feof ferror fileno fputc freopen fseek getc getchar \ + memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ + iovdprintf vscanf vsnprintf obprintf fcloseall fseeko ftello \ + freopen64 fseeko64 ftello64 \ + \ + __fbufsize __freading __fwriting __freadable __fwritable __flbf \ + __fpurge __fpending __fsetlocking \ + \ + libc_fatal fmemopen oldfmemopen vtables + +tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \ + tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \ + tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \ + tst-freopen bug-rewind bug-rewind2 bug-ungetc bug-fseek \ + tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \ + tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \ + bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \ + tst-memstream1 tst-memstream2 tst-memstream3 \ + tst-wmemstream1 tst-wmemstream2 tst-wmemstream3 \ + bug-memstream1 bug-wmemstream1 \ + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ + tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ + tst-ftell-append tst-fputws +ifeq (yes,$(build-shared)) +# Add test-fopenloc only if shared library is enabled since it depends on +# shared localedata objects. +tests += tst-fopenloc +endif +test-srcs = test-freopen + +ifeq ($(build-shared),yes) +routines += oldiofopen oldiofdopen oldiofclose oldiopopen oldpclose \ + oldtmpfile oldiofgetpos oldiofgetpos64 oldiofsetpos \ + oldiofsetpos64 +endif + +ifeq (yes,$(libc-reentrant)) +routines += clearerr_u feof_u ferror_u fputc_u getc_u getchar_u \ + iofflush_u putc_u putchar_u peekc iofread_u iofwrite_u iofgets_u \ + iofputs_u +endif + +CPPFLAGS += $(libio-mtsafe) + +# Support for exception handling. +CFLAGS-fileops.c = -fexceptions +CFLAGS-fputc.c = -fexceptions +CFLAGS-fputwc.c = -fexceptions +CFLAGS-freopen64.c = -fexceptions +CFLAGS-freopen.c = -fexceptions +CFLAGS-fseek.c = -fexceptions +CFLAGS-fseeko64.c = -fexceptions +CFLAGS-fseeko.c = -fexceptions +CFLAGS-ftello64.c = -fexceptions +CFLAGS-ftello.c = -fexceptions +CFLAGS-fwide.c = -fexceptions +CFLAGS-genops.c = -fexceptions +CFLAGS-getc.c = -fexceptions +CFLAGS-getchar.c = -fexceptions +CFLAGS-getwc.c = -fexceptions +CFLAGS-getwchar.c = -fexceptions +CFLAGS-iofclose.c = -fexceptions +CFLAGS-iofflush.c = -fexceptions +CFLAGS-iofgetpos64.c = -fexceptions +CFLAGS-iofgetpos.c = -fexceptions +CFLAGS-iofgets.c = -fexceptions +CFLAGS-iofgetws.c = -fexceptions +CFLAGS-iofputs.c = -fexceptions +CFLAGS-iofputws.c = -fexceptions +CFLAGS-iofread.c = -fexceptions +CFLAGS-iofsetpos64.c = -fexceptions +CFLAGS-iofsetpos.c = -fexceptions +CFLAGS-ioftell.c = -fexceptions +CFLAGS-iofwrite.c = -fexceptions +CFLAGS-iogetdelim.c = -fexceptions +CFLAGS-iogetline.c = -fexceptions +CFLAGS-iogets.c = -fexceptions +CFLAGS-iogetwline.c = -fexceptions +CFLAGS-ioputs.c = -fexceptions +CFLAGS-ioseekoff.c = -fexceptions +CFLAGS-ioseekpos.c = -fexceptions +CFLAGS-iosetbuffer.c = -fexceptions +CFLAGS-iosetvbuf.c = -fexceptions +CFLAGS-ioungetc.c = -fexceptions +CFLAGS-ioungetwc.c = -fexceptions +CFLAGS-oldfileops.c = -fexceptions +CFLAGS-oldiofclose.c = -fexceptions +CFLAGS-oldiofgetpos64.c = -fexceptions +CFLAGS-oldiofgetpos.c = -fexceptions +CFLAGS-oldiofsetpos64.c = -fexceptions +CFLAGS-oldiofsetpos.c = -fexceptions +CFLAGS-peekc.c = -fexceptions +CFLAGS-putc.c = -fexceptions +CFLAGS-putchar.c = -fexceptions +CFLAGS-putwc.c = -fexceptions +CFLAGS-putwchar.c = -fexceptions +CFLAGS-rewind.c = -fexceptions +CFLAGS-wfileops.c = -fexceptions +CFLAGS-wgenops.c = -fexceptions +CFLAGS-oldiofopen.c = -fexceptions +CFLAGS-iofopen.c = -fexceptions +CFLAGS-iofopen64.c = -fexceptions +CFLAGS-oldtmpfile.c = -fexceptions +# XXX Do we need filedoalloc and wfiledoalloc? Others? + +CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\" + +tst_wprintf2-ARGS = "Some Text" + +test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace +tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace + +generated += test-fmemopen.mtrace test-fmemopen.check +generated += tst-fopenloc.mtrace tst-fopenloc.check + +aux := fileops genops stdfiles stdio strops + +ifeq ($(build-shared),yes) +aux += oldfileops oldstdfiles +endif + +shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \ + oldstdfiles oldiopopen oldpclose oldtmpfile \ + oldiofgetpos oldiofgetpos64 oldiofsetpos \ + oldiofsetpos64 + +ifeq ($(run-built-tests),yes) +tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out +ifeq (yes,$(build-shared)) +# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared +# library is enabled since they depend on tst-fopenloc.out. +tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out +endif +endif + +include ../Rules + +ifeq ($(run-built-tests),yes) +LOCALES := de_DE.ISO-8859-1 de_DE.UTF-8 en_US.ISO-8859-1 en_US.UTF-8 \ + ja_JP.EUC-JP ja_JP.UTF-8 +include ../gen-locales.mk + +$(objpfx)bug-ftell.out: $(gen-locales) +$(objpfx)bug-ungetwc1.out: $(gen-locales) +$(objpfx)bug-ungetwc2.out: $(gen-locales) +$(objpfx)tst-fgetwc.out: $(gen-locales) +$(objpfx)tst-fgetws.out: $(gen-locales) +$(objpfx)tst-fopenloc.out: $(gen-locales) +$(objpfx)tst-fputws.out: $(gen-locales) +$(objpfx)tst-fseek.out: $(gen-locales) +$(objpfx)tst-ftell-active-handler.out: $(gen-locales) +$(objpfx)tst-ftell-append.out: $(gen-locales) +$(objpfx)tst-ftell-partial-wide.out: $(gen-locales) +$(objpfx)tst-setvbuf1.out: $(gen-locales) +$(objpfx)tst-swscanf.out: $(gen-locales) +$(objpfx)tst-ungetwc1.out: $(gen-locales) +$(objpfx)tst-ungetwc2.out: $(gen-locales) +$(objpfx)tst-widetext.out: $(gen-locales) +$(objpfx)tst_wprintf2.out: $(gen-locales) +endif + +$(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen + $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' \ + $(common-objpfx)libio/; \ + $(evaluate-test) + +$(objpfx)tst-fopenloc-cmp.out: ../iconvdata/testdata/ISO-8859-1..UTF8 \ + $(objpfx)tst-fopenloc.out + cmp $^ > $@; \ + $(evaluate-test) + +$(objpfx)test-fmemopen-mem.out: $(objpfx)test-fmemopen.out + $(common-objpfx)malloc/mtrace $(objpfx)test-fmemopen.mtrace > $@; \ + $(evaluate-test) + +$(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-fopenloc.mtrace > $@; \ + $(evaluate-test) diff --git a/REORG.TODO/libio/Versions b/REORG.TODO/libio/Versions new file mode 100644 index 0000000000..2a1d6e6c85 --- /dev/null +++ b/REORG.TODO/libio/Versions @@ -0,0 +1,159 @@ +libc { + GLIBC_2.0 { + # global variables + _IO_list_all; _IO_stderr_; _IO_stdin_; _IO_stdout_; + + # functions used in inline functions or macros + __getdelim; + + # functions used in inline functions or macros + _IO_getc; _IO_peekc_unlocked; _IO_putc; _IO_feof; _IO_ferror; + __uflow; __underflow; __overflow; + + # functions used in other libraries + __vsscanf; __vsnprintf; + + # libio + _IO_adjust_column; _IO_clearerr; _IO_default_doallocate; + _IO_default_finish; _IO_default_pbackfail; _IO_default_uflow; + _IO_default_xsgetn; _IO_default_xsputn; _IO_do_write; + _IO_doallocbuf; _IO_fclose; _IO_fdopen; _IO_feof; _IO_ferror; + _IO_fflush; _IO_fgetc; _IO_fgetpos; _IO_fgets; _IO_file_attach; + _IO_file_close; _IO_file_close_it; _IO_file_doallocate; + _IO_file_fopen; _IO_file_init; _IO_file_jumps; _IO_file_open; + _IO_file_overflow; _IO_file_read; _IO_file_seek; _IO_file_seekoff; + _IO_file_setbuf; _IO_file_stat; _IO_file_sync; _IO_file_underflow; + _IO_file_write; _IO_file_xsputn; _IO_fileno; _IO_flockfile; + _IO_flush_all; _IO_flush_all_linebuffered; _IO_fopen; _IO_fprintf; + _IO_fputs; _IO_fread; _IO_free_backup_area; _IO_freopen; + _IO_fscanf; _IO_fseek; _IO_fsetpos; _IO_ftell; _IO_ftrylockfile; + _IO_funlockfile; _IO_fwrite; _IO_getc; _IO_getline; _IO_gets; + _IO_init; _IO_init_marker; _IO_link_in; _IO_marker_delta; + _IO_marker_difference; _IO_padn; _IO_pclose; _IO_peekc_locked; + _IO_perror; _IO_popen; _IO_printf; _IO_proc_close; _IO_proc_open; + _IO_putc; _IO_puts; _IO_remove_marker; _IO_rewind; _IO_scanf; + _IO_seekmark; _IO_seekoff; _IO_seekpos; _IO_setb; _IO_setbuf; + _IO_setbuffer; _IO_setlinebuf; _IO_setvbuf; _IO_sgetn; + _IO_sprintf; _IO_sputbackc; _IO_sscanf; _IO_str_init_readonly; + _IO_str_init_static; _IO_str_overflow; _IO_str_pbackfail; + _IO_str_seekoff; _IO_str_underflow; _IO_sungetc; + _IO_switch_to_get_mode; _IO_un_link; _IO_ungetc; + _IO_unsave_markers; _IO_vfprintf; _IO_vfscanf; _IO_vsprintf; + + # variables in normal name space + stderr; stdin; stdout; + + # c* + clearerr; clearerr_unlocked; + + # f* + fclose; fcloseall; fdopen; feof; feof_locked; feof_unlocked; ferror; + ferror_locked; ferror_unlocked; fflush; fflush_locked; fflush_unlocked; + fgetc; fgetpos; fgets; fileno; fileno_locked; fileno_unlocked; + fopen; fopencookie; fputc; fputc_locked; fputc_unlocked; fputs; + fread; freopen; fseek; fsetpos; ftell; fwrite; + + # g* + getc; getc_locked; getc_unlocked; getchar; getchar_unlocked; getdelim; + gets; + + # o* + open_memstream; obstack_printf; obstack_vprintf; + + # p* + pclose; popen; putc; putc_locked; putc_unlocked; putchar; + putchar_unlocked; puts; + + # r* + rewind; + + # s* + setbuf; setbuffer; setlinebuf; setvbuf; + + # u* + ungetc; + + # v* + vasprintf; vdprintf; vscanf; vsnprintf; vsprintf; vsscanf; + } + GLIBC_2.1 { + # global variables + _IO_2_1_stdin_; _IO_2_1_stdout_; _IO_2_1_stderr_; + + # functions used in other libraries + _IO_fclose; _IO_fopen; _IO_fdopen; _IO_popen; __asprintf; + + # functions used in libstdc++ + _IO_do_write; _IO_file_attach; _IO_file_close_it; _IO_file_finish; + _IO_file_fopen; _IO_file_init; _IO_file_overflow; _IO_file_seekoff; + _IO_file_setbuf; _IO_file_sync; _IO_file_underflow; + _IO_file_write; _IO_file_xsputn; _IO_proc_open; _IO_proc_close; + + # Changed getline function in libio. + _IO_getline_info; + + # f* + fgetpos64; fopen64; freopen64; fseeko; fseeko64; fsetpos64; ftello; + ftello64; fopen; fclose; fdopen; fread_unlocked; fwrite_unlocked; + fgets_unlocked; fputs_unlocked; fgetc_unlocked; + + # p* + pclose; popen; + } + GLIBC_2.2 { + # functions used in libstdc++ + _IO_fgetpos; _IO_fgetpos64; _IO_fsetpos; _IO_fsetpos64; + _IO_wdo_write; _IO_wfile_jumps; _IO_wfile_overflow; _IO_wfile_seekoff; + _IO_wfile_setbuf; _IO_wfile_sync; _IO_wfile_underflow; _IO_wfile_xsputn; + _IO_adjust_wcolumn; _IO_free_wbackup_area; _IO_init_wmarker; + _IO_least_wmarker; _IO_seekwmark; _IO_sputbackwc; _IO_sungetwc; + _IO_switch_to_main_wget_area; _IO_switch_to_wbackup_area; + _IO_switch_to_wget_mode; _IO_unsave_wmarkers; _IO_wdefault_doallocate; + _IO_wdefault_finish; _IO_wdefault_pbackfail; _IO_wdefault_setbuf; + _IO_wdefault_uflow; _IO_wdefault_xsgetn; _IO_wdefault_xsputn; + _IO_wdoallocbuf; _IO_wmarker_delta; _IO_wsetb; __woverflow; __wuflow; + __wunderflow; + + # LinuxThreads uses this protected interface + _IO_iter_begin; _IO_iter_end; _IO_iter_next; _IO_iter_file; + _IO_list_lock; _IO_list_unlock; _IO_list_resetlock; + + # Functions to access FILE internals. + __fbufsize; __freading; __fwriting; __freadable; __fwritable; __flbf; + __fpurge; __fpending; __fsetlocking; _flushlbf; + + # f* + fgetpos; fgetpos64; fgetwc; fgetwc_unlocked; fgetws; fgetws_unlocked; + fputwc; fputwc_unlocked; fputws; fputws_unlocked; fsetpos; fsetpos64; + fwide; fwprintf; fwscanf; fopencookie; fmemopen; + + # g* + getwc; getwc_unlocked; getwchar; getwchar_unlocked; + + # p* + putwc; putwc_unlocked; putwchar; putwchar_unlocked; + + # s* + swprintf; swscanf; + + # u* + ungetwc; + + # v* + vfwprintf; vswprintf; vwprintf; vfwscanf; vswscanf; vwscanf; + + # w* + wprintf; wscanf; + } + GLIBC_2.4 { + open_wmemstream; + } + GLIBC_2.22 { + # f* + fmemopen; + } + GLIBC_PRIVATE { + # Used by NPTL and librt + __libc_fatal; + } +} diff --git a/REORG.TODO/libio/__fbufsize.c b/REORG.TODO/libio/__fbufsize.c new file mode 100644 index 0000000000..74d2ebbe81 --- /dev/null +++ b/REORG.TODO/libio/__fbufsize.c @@ -0,0 +1,27 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +size_t +__fbufsize (FILE *fp) +{ + if (fp->_mode > 0) + return fp->_wide_data->_IO_buf_end - fp->_wide_data->_IO_buf_base; + else + return fp->_IO_buf_end - fp->_IO_buf_base; +} diff --git a/REORG.TODO/libio/__flbf.c b/REORG.TODO/libio/__flbf.c new file mode 100644 index 0000000000..929175df70 --- /dev/null +++ b/REORG.TODO/libio/__flbf.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +int +__flbf (FILE *fp) +{ + return fp->_flags & _IO_LINE_BUF; +} diff --git a/REORG.TODO/libio/__fpending.c b/REORG.TODO/libio/__fpending.c new file mode 100644 index 0000000000..e957839985 --- /dev/null +++ b/REORG.TODO/libio/__fpending.c @@ -0,0 +1,27 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +size_t +__fpending (FILE *fp) +{ + if (fp->_mode > 0) + return fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; + else + return fp->_IO_write_ptr - fp->_IO_write_base; +} diff --git a/REORG.TODO/libio/__fpurge.c b/REORG.TODO/libio/__fpurge.c new file mode 100644 index 0000000000..925701a711 --- /dev/null +++ b/REORG.TODO/libio/__fpurge.c @@ -0,0 +1,42 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> +#include "libioP.h" + +void +__fpurge (FILE *fp) +{ + if (fp->_mode > 0) + { + /* Wide-char stream. */ + if (_IO_in_backup (fp)) + _IO_free_wbackup_area (fp); + + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + } + else + { + /* Byte stream. */ + if (_IO_in_backup (fp)) + _IO_free_backup_area (fp); + + fp->_IO_read_end = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_write_base; + } +} diff --git a/REORG.TODO/libio/__freadable.c b/REORG.TODO/libio/__freadable.c new file mode 100644 index 0000000000..3bde42a729 --- /dev/null +++ b/REORG.TODO/libio/__freadable.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +int +__freadable (FILE *fp) +{ + return (fp->_flags & _IO_NO_READS) == 0; +} diff --git a/REORG.TODO/libio/__freading.c b/REORG.TODO/libio/__freading.c new file mode 100644 index 0000000000..f16f42679f --- /dev/null +++ b/REORG.TODO/libio/__freading.c @@ -0,0 +1,26 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +int +__freading (FILE *fp) +{ + return ((fp->_flags & _IO_NO_WRITES) + || ((fp->_flags & (_IO_CURRENTLY_PUTTING | _IO_NO_READS)) == 0 + && fp->_IO_read_base != NULL)); +} diff --git a/REORG.TODO/libio/__fsetlocking.c b/REORG.TODO/libio/__fsetlocking.c new file mode 100644 index 0000000000..5fcf75b0e4 --- /dev/null +++ b/REORG.TODO/libio/__fsetlocking.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +#undef __fsetlocking + +int +__fsetlocking (FILE *fp, int type) +{ + int result = ((fp->_flags & _IO_USER_LOCK) + ? FSETLOCKING_BYCALLER : FSETLOCKING_INTERNAL); + + if (type != FSETLOCKING_QUERY) + { + fp->_flags &= ~_IO_USER_LOCK; + if (type == FSETLOCKING_BYCALLER) + fp->_flags |= _IO_USER_LOCK; + } + + return result; +} +libc_hidden_def (__fsetlocking) diff --git a/REORG.TODO/libio/__fwritable.c b/REORG.TODO/libio/__fwritable.c new file mode 100644 index 0000000000..1584aec68f --- /dev/null +++ b/REORG.TODO/libio/__fwritable.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +int +__fwritable (FILE *fp) +{ + return (fp->_flags & _IO_NO_WRITES) == 0; +} diff --git a/REORG.TODO/libio/__fwriting.c b/REORG.TODO/libio/__fwriting.c new file mode 100644 index 0000000000..1769d2107e --- /dev/null +++ b/REORG.TODO/libio/__fwriting.c @@ -0,0 +1,24 @@ +/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio_ext.h> + +int +__fwriting (FILE *fp) +{ + return fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING); +} diff --git a/REORG.TODO/libio/bits/libio-ldbl.h b/REORG.TODO/libio/bits/libio-ldbl.h new file mode 100644 index 0000000000..f238550e4b --- /dev/null +++ b/REORG.TODO/libio/bits/libio-ldbl.h @@ -0,0 +1,24 @@ +/* -mlong-double-64 compatibility mode for libio functions. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _IO_STDIO_H +# error "Never include <bits/libio-ldbl.h> directly; use <libio.h> instead." +#endif + +__LDBL_REDIR_DECL (_IO_vfscanf) +__LDBL_REDIR_DECL (_IO_vfprintf) diff --git a/REORG.TODO/libio/bits/stdio-ldbl.h b/REORG.TODO/libio/bits/stdio-ldbl.h new file mode 100644 index 0000000000..caa1e538c3 --- /dev/null +++ b/REORG.TODO/libio/bits/stdio-ldbl.h @@ -0,0 +1,95 @@ +/* -mlong-double-64 compatibility mode for stdio functions. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _STDIO_H +# error "Never include <bits/stdio-ldbl.h> directly; use <stdio.h> instead." +#endif + +__LDBL_REDIR_DECL (fprintf) +__LDBL_REDIR_DECL (printf) +__LDBL_REDIR_DECL (sprintf) +__LDBL_REDIR_DECL (vfprintf) +__LDBL_REDIR_DECL (vprintf) +__LDBL_REDIR_DECL (vsprintf) +#if defined __USE_ISOC99 && !defined __USE_GNU \ + && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (fscanf, __nldbl___isoc99_fscanf) +__LDBL_REDIR1_DECL (scanf, __nldbl___isoc99_scanf) +__LDBL_REDIR1_DECL (sscanf, __nldbl___isoc99_sscanf) +#else +__LDBL_REDIR_DECL (fscanf) +__LDBL_REDIR_DECL (scanf) +__LDBL_REDIR_DECL (sscanf) +#endif + +#if defined __USE_ISOC99 || defined __USE_UNIX98 +__LDBL_REDIR_DECL (snprintf) +__LDBL_REDIR_DECL (vsnprintf) +#endif + +#ifdef __USE_ISOC99 +# if !defined __USE_GNU && !defined __REDIRECT \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +__LDBL_REDIR1_DECL (vfscanf, __nldbl___isoc99_vfscanf) +__LDBL_REDIR1_DECL (vscanf, __nldbl___isoc99_vscanf) +__LDBL_REDIR1_DECL (vsscanf, __nldbl___isoc99_vsscanf) +# else +__LDBL_REDIR_DECL (vfscanf) +__LDBL_REDIR_DECL (vsscanf) +__LDBL_REDIR_DECL (vscanf) +# endif +#endif + +#ifdef __USE_XOPEN2K8 +__LDBL_REDIR_DECL (vdprintf) +__LDBL_REDIR_DECL (dprintf) +#endif + +#ifdef __USE_GNU +__LDBL_REDIR_DECL (vasprintf) +__LDBL_REDIR_DECL (__asprintf) +__LDBL_REDIR_DECL (asprintf) +__LDBL_REDIR_DECL (obstack_printf) +__LDBL_REDIR_DECL (obstack_vprintf) +#endif + +#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function +__LDBL_REDIR_DECL (__sprintf_chk) +__LDBL_REDIR_DECL (__vsprintf_chk) +# if defined __USE_ISOC99 || defined __USE_UNIX98 +__LDBL_REDIR_DECL (__snprintf_chk) +__LDBL_REDIR_DECL (__vsnprintf_chk) +# endif +# if __USE_FORTIFY_LEVEL > 1 +__LDBL_REDIR_DECL (__fprintf_chk) +__LDBL_REDIR_DECL (__printf_chk) +__LDBL_REDIR_DECL (__vfprintf_chk) +__LDBL_REDIR_DECL (__vprintf_chk) +# ifdef __USE_XOPEN2K8 +__LDBL_REDIR_DECL (__dprintf_chk) +__LDBL_REDIR_DECL (__vdprintf_chk) +# endif +# ifdef __USE_GNU +__LDBL_REDIR_DECL (__asprintf_chk) +__LDBL_REDIR_DECL (__vasprintf_chk) +__LDBL_REDIR_DECL (__obstack_printf_chk) +__LDBL_REDIR_DECL (__obstack_vprintf_chk) +# endif +# endif +#endif diff --git a/REORG.TODO/libio/bits/stdio.h b/REORG.TODO/libio/bits/stdio.h new file mode 100644 index 0000000000..21ad2fb20c --- /dev/null +++ b/REORG.TODO/libio/bits/stdio.h @@ -0,0 +1,190 @@ +/* Optimizing macros and inline functions for stdio functions. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _STDIO_H +# error "Never include <bits/stdio.h> directly; use <stdio.h> instead." +#endif + +#ifndef __extern_inline +# define __STDIO_INLINE inline +#else +# define __STDIO_INLINE __extern_inline +#endif + + +#ifdef __USE_EXTERN_INLINES +/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different + inline. */ +# if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function) +/* Write formatted output to stdout from argument list ARG. */ +__STDIO_INLINE int +vprintf (const char *__restrict __fmt, _G_va_list __arg) +{ + return vfprintf (stdout, __fmt, __arg); +} +# endif + +/* Read a character from stdin. */ +__STDIO_INLINE int +getchar (void) +{ + return _IO_getc (stdin); +} + + +# ifdef __USE_MISC +/* Faster version when locking is not necessary. */ +__STDIO_INLINE int +fgetc_unlocked (FILE *__fp) +{ + return _IO_getc_unlocked (__fp); +} +# endif /* misc */ + + +# ifdef __USE_POSIX +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +getc_unlocked (FILE *__fp) +{ + return _IO_getc_unlocked (__fp); +} + +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +getchar_unlocked (void) +{ + return _IO_getc_unlocked (stdin); +} +# endif /* POSIX */ + + +/* Write a character to stdout. */ +__STDIO_INLINE int +putchar (int __c) +{ + return _IO_putc (__c, stdout); +} + + +# ifdef __USE_MISC +/* Faster version when locking is not necessary. */ +__STDIO_INLINE int +fputc_unlocked (int __c, FILE *__stream) +{ + return _IO_putc_unlocked (__c, __stream); +} +# endif /* misc */ + + +# ifdef __USE_POSIX +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +putc_unlocked (int __c, FILE *__stream) +{ + return _IO_putc_unlocked (__c, __stream); +} + +/* This is defined in POSIX.1:1996. */ +__STDIO_INLINE int +putchar_unlocked (int __c) +{ + return _IO_putc_unlocked (__c, stdout); +} +# endif /* POSIX */ + + +# ifdef __USE_GNU +/* Like `getdelim', but reads up to a newline. */ +__STDIO_INLINE _IO_ssize_t +getline (char **__lineptr, size_t *__n, FILE *__stream) +{ + return __getdelim (__lineptr, __n, '\n', __stream); +} +# endif /* GNU */ + + +# ifdef __USE_MISC +/* Faster versions when locking is not required. */ +__STDIO_INLINE int +__NTH (feof_unlocked (FILE *__stream)) +{ + return _IO_feof_unlocked (__stream); +} + +/* Faster versions when locking is not required. */ +__STDIO_INLINE int +__NTH (ferror_unlocked (FILE *__stream)) +{ + return _IO_ferror_unlocked (__stream); +} +# endif /* misc */ + +#endif /* Use extern inlines. */ + + +#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__ \ + && !defined __cplusplus +/* Perform some simple optimizations. */ +# define fread_unlocked(ptr, size, n, stream) \ + (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && (size_t) (size) * (size_t) (n) <= 8 \ + && (size_t) (size) != 0) \ + ? ({ char *__ptr = (char *) (ptr); \ + FILE *__stream = (stream); \ + size_t __cnt; \ + for (__cnt = (size_t) (size) * (size_t) (n); \ + __cnt > 0; --__cnt) \ + { \ + int __c = _IO_getc_unlocked (__stream); \ + if (__c == EOF) \ + break; \ + *__ptr++ = __c; \ + } \ + ((size_t) (size) * (size_t) (n) - __cnt) \ + / (size_t) (size); }) \ + : (((__builtin_constant_p (size) && (size_t) (size) == 0) \ + || (__builtin_constant_p (n) && (size_t) (n) == 0)) \ + /* Evaluate all parameters once. */ \ + ? ((void) (ptr), (void) (stream), (void) (size), \ + (void) (n), (size_t) 0) \ + : fread_unlocked (ptr, size, n, stream)))) + +# define fwrite_unlocked(ptr, size, n, stream) \ + (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n) \ + && (size_t) (size) * (size_t) (n) <= 8 \ + && (size_t) (size) != 0) \ + ? ({ const char *__ptr = (const char *) (ptr); \ + FILE *__stream = (stream); \ + size_t __cnt; \ + for (__cnt = (size_t) (size) * (size_t) (n); \ + __cnt > 0; --__cnt) \ + if (_IO_putc_unlocked (*__ptr++, __stream) == EOF) \ + break; \ + ((size_t) (size) * (size_t) (n) - __cnt) \ + / (size_t) (size); }) \ + : (((__builtin_constant_p (size) && (size_t) (size) == 0) \ + || (__builtin_constant_p (n) && (size_t) (n) == 0)) \ + /* Evaluate all parameters once. */ \ + ? ((void) (ptr), (void) (stream), (void) (size), \ + (void) (n), (size_t) 0) \ + : fwrite_unlocked (ptr, size, n, stream)))) +#endif + +/* Define helper macro. */ +#undef __STDIO_INLINE diff --git a/REORG.TODO/libio/bits/stdio2.h b/REORG.TODO/libio/bits/stdio2.h new file mode 100644 index 0000000000..e9f9d6952b --- /dev/null +++ b/REORG.TODO/libio/bits/stdio2.h @@ -0,0 +1,381 @@ +/* Checking macros for stdio functions. + Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _STDIO_H +# error "Never include <bits/stdio2.h> directly; use <stdio.h> instead." +#endif + +extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, + const char *__restrict __format, ...) __THROW; +extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, + const char *__restrict __format, + _G_va_list __ap) __THROW; + +#ifdef __va_arg_pack +__fortify_function int +__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...)) +{ + return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __va_arg_pack ()); +} +#elif !defined __cplusplus +# define sprintf(str, ...) \ + __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \ + __VA_ARGS__) +#endif + +__fortify_function int +__NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt, + _G_va_list __ap)) +{ + return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __ap); +} + +#if defined __USE_ISOC99 || defined __USE_UNIX98 + +extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, + size_t __slen, const char *__restrict __format, + ...) __THROW; +extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, + size_t __slen, const char *__restrict __format, + _G_va_list __ap) __THROW; + +# ifdef __va_arg_pack +__fortify_function int +__NTH (snprintf (char *__restrict __s, size_t __n, + const char *__restrict __fmt, ...)) +{ + return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __va_arg_pack ()); +} +# elif !defined __cplusplus +# define snprintf(str, len, ...) \ + __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ + __VA_ARGS__) +# endif + +__fortify_function int +__NTH (vsnprintf (char *__restrict __s, size_t __n, + const char *__restrict __fmt, _G_va_list __ap)) +{ + return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, + __bos (__s), __fmt, __ap); +} + +#endif + +#if __USE_FORTIFY_LEVEL > 1 + +extern int __fprintf_chk (FILE *__restrict __stream, int __flag, + const char *__restrict __format, ...); +extern int __printf_chk (int __flag, const char *__restrict __format, ...); +extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, + const char *__restrict __format, _G_va_list __ap); +extern int __vprintf_chk (int __flag, const char *__restrict __format, + _G_va_list __ap); + +# ifdef __va_arg_pack +__fortify_function int +fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...) +{ + return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} + +__fortify_function int +printf (const char *__restrict __fmt, ...) +{ + return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); +} +# elif !defined __cplusplus +# define printf(...) \ + __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# define fprintf(stream, ...) \ + __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# endif + +__fortify_function int +vprintf (const char *__restrict __fmt, _G_va_list __ap) +{ +#ifdef __USE_EXTERN_INLINES + return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); +#else + return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap); +#endif +} + +__fortify_function int +vfprintf (FILE *__restrict __stream, + const char *__restrict __fmt, _G_va_list __ap) +{ + return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); +} + +# ifdef __USE_XOPEN2K8 +extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt, + ...) __attribute__ ((__format__ (__printf__, 3, 4))); +extern int __vdprintf_chk (int __fd, int __flag, + const char *__restrict __fmt, _G_va_list __arg) + __attribute__ ((__format__ (__printf__, 3, 0))); + +# ifdef __va_arg_pack +__fortify_function int +dprintf (int __fd, const char *__restrict __fmt, ...) +{ + return __dprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} +# elif !defined __cplusplus +# define dprintf(fd, ...) \ + __dprintf_chk (fd, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# endif + +__fortify_function int +vdprintf (int __fd, const char *__restrict __fmt, _G_va_list __ap) +{ + return __vdprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); +} +# endif + +# ifdef __USE_GNU + +extern int __asprintf_chk (char **__restrict __ptr, int __flag, + const char *__restrict __fmt, ...) + __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur; +extern int __vasprintf_chk (char **__restrict __ptr, int __flag, + const char *__restrict __fmt, _G_va_list __arg) + __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur; +extern int __obstack_printf_chk (struct obstack *__restrict __obstack, + int __flag, const char *__restrict __format, + ...) + __THROW __attribute__ ((__format__ (__printf__, 3, 4))); +extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack, + int __flag, + const char *__restrict __format, + _G_va_list __args) + __THROW __attribute__ ((__format__ (__printf__, 3, 0))); + +# ifdef __va_arg_pack +__fortify_function int +__NTH (asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...)) +{ + return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} + +__fortify_function int +__NTH (__asprintf (char **__restrict __ptr, const char *__restrict __fmt, + ...)) +{ + return __asprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} + +__fortify_function int +__NTH (obstack_printf (struct obstack *__restrict __obstack, + const char *__restrict __fmt, ...)) +{ + return __obstack_printf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt, + __va_arg_pack ()); +} +# elif !defined __cplusplus +# define asprintf(ptr, ...) \ + __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# define __asprintf(ptr, ...) \ + __asprintf_chk (ptr, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# define obstack_printf(obstack, ...) \ + __obstack_printf_chk (obstack, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__) +# endif + +__fortify_function int +__NTH (vasprintf (char **__restrict __ptr, const char *__restrict __fmt, + _G_va_list __ap)) +{ + return __vasprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); +} + +__fortify_function int +__NTH (obstack_vprintf (struct obstack *__restrict __obstack, + const char *__restrict __fmt, _G_va_list __ap)) +{ + return __obstack_vprintf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt, + __ap); +} + +# endif + +#endif + +#if __GLIBC_USE (DEPRECATED_GETS) +extern char *__gets_chk (char *__str, size_t) __wur; +extern char *__REDIRECT (__gets_warn, (char *__str), gets) + __wur __warnattr ("please use fgets or getline instead, gets can't " + "specify buffer size"); + +__fortify_function __wur char * +gets (char *__str) +{ + if (__bos (__str) != (size_t) -1) + return __gets_chk (__str, __bos (__str)); + return __gets_warn (__str); +} +#endif + +extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, + FILE *__restrict __stream) __wur; +extern char *__REDIRECT (__fgets_alias, + (char *__restrict __s, int __n, + FILE *__restrict __stream), fgets) __wur; +extern char *__REDIRECT (__fgets_chk_warn, + (char *__restrict __s, size_t __size, int __n, + FILE *__restrict __stream), __fgets_chk) + __wur __warnattr ("fgets called with bigger size than length " + "of destination buffer"); + +__fortify_function __wur char * +fgets (char *__restrict __s, int __n, FILE *__restrict __stream) +{ + if (__bos (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) + return __fgets_chk (__s, __bos (__s), __n, __stream); + + if ((size_t) __n > __bos (__s)) + return __fgets_chk_warn (__s, __bos (__s), __n, __stream); + } + return __fgets_alias (__s, __n, __stream); +} + +extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream) __wur; +extern size_t __REDIRECT (__fread_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), + fread) __wur; +extern size_t __REDIRECT (__fread_chk_warn, + (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream), + __fread_chk) + __wur __warnattr ("fread called with bigger size * nmemb than length " + "of destination buffer"); + +__fortify_function __wur size_t +fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) +{ + if (__bos0 (__ptr) != (size_t) -1) + { + if (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) + return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); + + if (__size * __n > __bos0 (__ptr)) + return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream); + } + return __fread_alias (__ptr, __size, __n, __stream); +} + +#ifdef __USE_GNU +extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, + int __n, FILE *__restrict __stream) __wur; +extern char *__REDIRECT (__fgets_unlocked_alias, + (char *__restrict __s, int __n, + FILE *__restrict __stream), fgets_unlocked) __wur; +extern char *__REDIRECT (__fgets_unlocked_chk_warn, + (char *__restrict __s, size_t __size, int __n, + FILE *__restrict __stream), __fgets_unlocked_chk) + __wur __warnattr ("fgets_unlocked called with bigger size than length " + "of destination buffer"); + +__fortify_function __wur char * +fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) +{ + if (__bos (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) + return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream); + + if ((size_t) __n > __bos (__s)) + return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream); + } + return __fgets_unlocked_alias (__s, __n, __stream); +} +#endif + +#ifdef __USE_MISC +# undef fread_unlocked +extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream) __wur; +extern size_t __REDIRECT (__fread_unlocked_alias, + (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream), + fread_unlocked) __wur; +extern size_t __REDIRECT (__fread_unlocked_chk_warn, + (void *__restrict __ptr, size_t __ptrlen, + size_t __size, size_t __n, + FILE *__restrict __stream), + __fread_unlocked_chk) + __wur __warnattr ("fread_unlocked called with bigger size * nmemb than " + "length of destination buffer"); + +__fortify_function __wur size_t +fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) +{ + if (__bos0 (__ptr) != (size_t) -1) + { + if (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) + return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, + __stream); + + if (__size * __n > __bos0 (__ptr)) + return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n, + __stream); + } + +# ifdef __USE_EXTERN_INLINES + if (__builtin_constant_p (__size) + && __builtin_constant_p (__n) + && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) + && __size * __n <= 8) + { + size_t __cnt = __size * __n; + char *__cptr = (char *) __ptr; + if (__cnt == 0) + return 0; + + for (; __cnt > 0; --__cnt) + { + int __c = _IO_getc_unlocked (__stream); + if (__c == EOF) + break; + *__cptr++ = __c; + } + return (__cptr - (char *) __ptr) / __size; + } +# endif + return __fread_unlocked_alias (__ptr, __size, __n, __stream); +} +#endif diff --git a/REORG.TODO/libio/bits/types/FILE.h b/REORG.TODO/libio/bits/types/FILE.h new file mode 100644 index 0000000000..f268263209 --- /dev/null +++ b/REORG.TODO/libio/bits/types/FILE.h @@ -0,0 +1,9 @@ +#ifndef __FILE_defined +#define __FILE_defined 1 + +struct _IO_FILE; + +/* The opaque type of streams. This is the definition used elsewhere. */ +typedef struct _IO_FILE FILE; + +#endif diff --git a/REORG.TODO/libio/bits/types/__FILE.h b/REORG.TODO/libio/bits/types/__FILE.h new file mode 100644 index 0000000000..06dd79bc83 --- /dev/null +++ b/REORG.TODO/libio/bits/types/__FILE.h @@ -0,0 +1,7 @@ +#ifndef ____FILE_defined +#define ____FILE_defined 1 + +struct _IO_FILE; +typedef struct _IO_FILE __FILE; + +#endif diff --git a/REORG.TODO/libio/bug-fopena+.c b/REORG.TODO/libio/bug-fopena+.c new file mode 100644 index 0000000000..5446de1592 --- /dev/null +++ b/REORG.TODO/libio/bug-fopena+.c @@ -0,0 +1,100 @@ +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +static int fd; +static char *fname; + + +static void prepare (void); +#define PREPARE(argc, argv) prepare () + + +#define TEST_FUNCTION do_test () +static int do_test (void); +#include "../test-skeleton.c" + + +static void +prepare (void) +{ + fd = create_temp_file ("wrewind.", &fname); + if (fd == -1) + exit (3); +} + + +static int +do_test (void) +{ + char buf[100]; + FILE *fp; + int result = 0; + + fp = fdopen (fd, "w"); + if (fp == NULL) + { + puts ("cannot create file"); + exit (1); + } + + if (fputs ("one\n", fp) == EOF || fputs ("two\n", fp) == EOF) + { + puts ("cannot create filec content"); + exit (1); + } + + fclose (fp); + + fp = fopen (fname, "a+"); + if (fp == NULL) + { + puts ("cannot fopen a+"); + exit (1); + } + + if (fgets (buf, sizeof (buf), fp) == NULL) + { + puts ("cannot read after fopen a+"); + exit (1); + } + + if (strcmp (buf, "one\n") != 0) + { + puts ("read after fopen a+ produced wrong result"); + result = 1; + } + + fclose (fp); + + fd = open (fname, O_RDWR); + if (fd == -1) + { + puts ("open failed"); + exit (1); + } + + fp = fdopen (fd, "a+"); + if (fp == NULL) + { + puts ("fopen after open failed"); + exit (1); + } + + if (fgets (buf, sizeof (buf), fp) == NULL) + { + puts ("cannot read after fdopen a+"); + exit (1); + } + + if (strcmp (buf, "one\n") != 0) + { + puts ("read after fdopen a+ produced wrong result"); + result = 1; + } + + fclose (fp); + + return result; +} diff --git a/REORG.TODO/libio/bug-fseek.c b/REORG.TODO/libio/bug-fseek.c new file mode 100644 index 0000000000..1b60580b53 --- /dev/null +++ b/REORG.TODO/libio/bug-fseek.c @@ -0,0 +1,123 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +static char *fname; + + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + + +static void +do_prepare (void) +{ + static const char pattern[] = "12345678901234567890"; + int fd = create_temp_file ("bug-fseek.", &fname); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + + if (write (fd, pattern, sizeof (pattern)) != sizeof (pattern)) + { + perror ("short write"); + abort (); + } + close (fd); +} + + + +static int +do_test (void) +{ + FILE *f; + int result = 0; + char buf[10]; + + + if ((f = fopen (fname, "r")) == (FILE *) NULL) + { + perror ("fopen(\"r\")"); + } + + fread (buf, 3, 1, f); + errno = 0; + if (fseek (f, -10, SEEK_CUR) == 0) + { + printf ("fseek() for r to before start of file worked!\n"); + result = 1; + } + else if (errno != EINVAL) + { + printf ("\ +fseek() for r to before start of file did not set errno to EINVAL. \ +Got %d instead\n", + errno); + result = 1; + } + + fclose (f); + + + if ((f = fopen (fname, "r+")) == (FILE *) NULL) + { + perror ("fopen(\"r+\")"); + } + + fread (buf, 3, 1, f); + errno = 0; + if (fseek (f, -10, SEEK_CUR) == 0) + { + printf ("fseek() for r+ to before start of file worked!\n"); + result = 1; + } + else if (errno != EINVAL) + { + printf ("\ +fseek() for r+ to before start of file did not set errno to EINVAL. \ +Got %d instead\n", + errno); + result = 1; + } + + fclose (f); + + + if ((f = fopen (fname, "r+")) == (FILE *) NULL) + { + perror ("fopen(\"r+\")"); + } + + fread (buf, 3, 1, f); + if (ftell (f) != 3) + { + puts ("ftell failed"); + return 1; + } + errno = 0; + if (fseek (f, -10, SEEK_CUR) == 0) + { + printf ("fseek() for r+ to before start of file worked!\n"); + result = 1; + } + else if (errno != EINVAL) + { + printf ("\ +fseek() for r+ to before start of file did not set errno to EINVAL. \ +Got %d instead\n", + errno); + result = 1; + } + + fclose (f); + + return result; +} diff --git a/REORG.TODO/libio/bug-ftell.c b/REORG.TODO/libio/bug-ftell.c new file mode 100644 index 0000000000..496c8cb75c --- /dev/null +++ b/REORG.TODO/libio/bug-ftell.c @@ -0,0 +1,58 @@ +#include <locale.h> +#include <stdio.h> +#include <wchar.h> +#include <sys/types.h> + + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + puts ("setlocale failed"); + return 1; + } + + FILE *fp = tmpfile (); + if (fp == NULL) + { + puts ("tmpfile failed"); + return 1; + } + + if (fputws (L"hello", fp) == EOF) + { + puts ("fputws failed"); + return 1; + } + + rewind (fp); + + const wchar_t *cp; + unsigned int cnt; + for (cp = L"hello", cnt = 1; *cp != L'\0'; ++cp, ++cnt) + { + wint_t wc = fgetwc (fp); + if (wc != (wint_t) *cp) + { + printf ("fgetwc failed: got L'%lc', expected L'%lc'\n", + wc, (wint_t) *cp); + return 1; + } + off_t o = ftello (fp); + if (o != cnt) + { + printf ("ftello failed: got %lu, expected %u\n", + (unsigned long int) o, cnt); + return 1; + } + printf ("round %u OK\n", cnt); + } + + fclose (fp); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/bug-memstream1.c b/REORG.TODO/libio/bug-memstream1.c new file mode 100644 index 0000000000..d1ecc79564 --- /dev/null +++ b/REORG.TODO/libio/bug-memstream1.c @@ -0,0 +1,134 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + + +static int +do_test (void) +{ + size_t size; + char *buf; + FILE *fp = open_memstream (&buf, &size); + if (fp == NULL) + { + puts ("open_memstream failed"); + return 1; + } + + off64_t off = ftello64 (fp); + if (off != 0) + { + puts ("initial position wrong"); + return 1; + } + + if (fseek (fp, 32768, SEEK_SET) != 0) + { + puts ("fseek failed"); + return 1; + } + + if (fputs ("foo", fp) == EOF) + { + puts ("fputs failed"); + return 1; + } + + if (fclose (fp) == EOF) + { + puts ("fclose failed"); + return 1; + } + + if (size != 32768 + 3) + { + printf ("expected size %d, got %zu\n", 32768 + 3, size); + return 1; + } + + for (int i = 0; i < 32768; ++i) + if (buf[i] != '\0') + { + printf ("byte at offset %d is %#hhx\n", i, buf[i]); + return 1; + } + + if (memcmp (buf + 32768, "foo", 3) != 0) + { + puts ("written string incorrect"); + return 1; + } + + /* Mark the buffer. */ + memset (buf, 'A', size); + free (buf); + + /* Try again, this time with write mode enabled before the seek. */ + fp = open_memstream (&buf, &size); + if (fp == NULL) + { + puts ("2nd open_memstream failed"); + return 1; + } + + off = ftello64 (fp); + if (off != 0) + { + puts ("2nd initial position wrong"); + return 1; + } + + if (fputs ("bar", fp) == EOF) + { + puts ("2nd fputs failed"); + return 1; + } + + if (fseek (fp, 32768, SEEK_SET) != 0) + { + puts ("2nd fseek failed"); + return 1; + } + + if (fputs ("foo", fp) == EOF) + { + puts ("3rd fputs failed"); + return 1; + } + + if (fclose (fp) == EOF) + { + puts ("2nd fclose failed"); + return 1; + } + + if (size != 32768 + 3) + { + printf ("2nd expected size %d, got %zu\n", 32768 + 3, size); + return 1; + } + + if (memcmp (buf, "bar", 3) != 0) + { + puts ("initial string incorrect in 2nd try"); + return 1; + } + + for (int i = 3; i < 32768; ++i) + if (buf[i] != '\0') + { + printf ("byte at offset %d is %#hhx in 2nd try\n", i, buf[i]); + return 1; + } + + if (memcmp (buf + 32768, "foo", 3) != 0) + { + puts ("written string incorrect in 2nd try"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/bug-mmap-fflush.c b/REORG.TODO/libio/bug-mmap-fflush.c new file mode 100644 index 0000000000..d8aa58985a --- /dev/null +++ b/REORG.TODO/libio/bug-mmap-fflush.c @@ -0,0 +1,53 @@ +/* Test for bug in fflush synchronization behavior. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +static char *fname; + +static void prepare (void); +#define PREPARE(argc, argv) prepare () + + +#define TEST_FUNCTION do_test () +static int do_test (void); +#include "../test-skeleton.c" + + +static void +prepare (void) +{ + int fd = create_temp_file ("bug-mmap-fflush.", &fname); + if (fd == -1) + exit (3); + /* We don't need the descriptor. */ + close (fd); +} + + +static int +do_test (void) +{ + FILE *f; + off_t o; + char buffer[1024]; + + snprintf (buffer, sizeof (buffer), "echo 'From foo@bar.com' > %s", fname); + system (buffer); + f = fopen (fname, "r"); + fseek (f, 0, SEEK_END); + o = ftello (f); + fseek (f, 0, SEEK_SET); + fflush (f); + snprintf (buffer, sizeof (buffer), "echo 'From bar@baz.edu' >> %s", fname); + system (buffer); + fseek (f, o, SEEK_SET); + if (fgets (buffer, 1024, f) == NULL) + exit (1); + if (strncmp (buffer, "From ", 5) != 0) + exit (1); + fclose (f); + exit (0); +} diff --git a/REORG.TODO/libio/bug-rewind.c b/REORG.TODO/libio/bug-rewind.c new file mode 100644 index 0000000000..1734de285f --- /dev/null +++ b/REORG.TODO/libio/bug-rewind.c @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <wchar.h> + +#define PASSED 0 +#define FAILED 3 + + +static int fd; + +static void prepare (void); +#define PREPARE(argc, argv) prepare () + + +#define TEST_FUNCTION do_test () +static int do_test (void); +#include "../test-skeleton.c" + + +static void +prepare (void) +{ + fd = create_temp_file ("wrewind.", NULL); + if (fd == -1) + exit (3); +} + + +static int +do_test (void) +{ + FILE *fptr; + char arg1; + char arg2; + int ret1, ret2, result, num; + + ret1 = 0; + ret2 = 0; + + fptr = fdopen (fd, "w+"); + if (fptr == NULL) + { + printf ("Unable to open file.\n"); + return 1; + } + + if (fwprintf (fptr, L"cderf") <= 0) + { + printf ("Unable to write to file with fwprintf().\n"); + fclose (fptr); + return 2; + } + + rewind (fptr); + ret1 = fwscanf (fptr, L"%c%c", &arg1, &arg2); + if (ret1 != 2) + { + printf ("first fwscanf returned %d, expected 2\n", ret1); + return 3; + } + + rewind (fptr); + ret2 = fwscanf (fptr, L"%c%n%c", &arg1, &num, &arg2); + if (ret2 != 2) + { + printf ("second fwscanf returned %d, expected 2\n", ret2); + return 4; + } + + if (arg2 != 'd') + { + result = FAILED; + printf ("rewind after first fwscanf failed\n"); + } + else + { + printf ("Passed\n"); + result = PASSED; + } + + + fclose (fptr); + return result; +} diff --git a/REORG.TODO/libio/bug-rewind2.c b/REORG.TODO/libio/bug-rewind2.c new file mode 100644 index 0000000000..496f628675 --- /dev/null +++ b/REORG.TODO/libio/bug-rewind2.c @@ -0,0 +1,67 @@ +#include <stdio.h> +#include <wchar.h> + + +static int fd; + +static void prepare (void); +#define PREPARE(argc, argv) prepare () + + +#define TEST_FUNCTION do_test () +static int do_test (void); +#include "../test-skeleton.c" + + +static void +prepare (void) +{ + fd = create_temp_file ("wrewind2.", NULL); + if (fd == -1) + exit (3); +} + + +static int +do_test (void) +{ + wchar_t dummy[10]; + int ret = 0; + FILE *fp; + int result = 0; + + fp = fdopen (fd, "w+"); + if (fp == NULL) + { + puts ("fopen(""testfile"", ""w+"") returned NULL."); + return 1; + } + else + { + fwprintf (fp, L"abcd"); + printf ("current pos = %ld\n", ftell (fp)); + if (ftell (fp) != 4) + result = 1; + + rewind (fp); + ret = fwscanf (fp, L"%c", dummy); + if (ret != 1) + { + printf ("fwscanf returned %d, expected 1\n", ret); + result = 1; + } + + printf ("current pos = %ld\n", ftell (fp)); + if (ftell (fp) != 1) + result = 1; + + rewind (fp); + printf ("current pos = %ld\n", ftell (fp)); + if (ftell (fp) != 0) + result = 1; + + fclose (fp); + } + + return result; +} diff --git a/REORG.TODO/libio/bug-ungetc.c b/REORG.TODO/libio/bug-ungetc.c new file mode 100644 index 0000000000..51940b68f5 --- /dev/null +++ b/REORG.TODO/libio/bug-ungetc.c @@ -0,0 +1,61 @@ +/* Test program for ungetc/ftell interaction bug. */ + +#include <stdio.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static const char pattern[] = "12345"; +static char *temp_file; + +static void +do_prepare (void) +{ + int fd = create_temp_file ("bug-ungetc.", &temp_file); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + write (fd, pattern, sizeof (pattern)); + close (fd); +} + +static int +do_test (void) +{ + int i; + FILE *f; + char buf[10]; + long offset, diff; + int result = 0; + + f = fopen (temp_file, "rw"); + + rewind (f); + for (i = 0; i < 3; i++) + printf ("%c\n", getc (f)); + offset = ftell (f); + printf ("offset = %ld\n", offset); + if (ungetc ('4', f) != '4') + { + printf ("ungetc failed\n"); + abort (); + } + printf ("offset after ungetc = %ld\n", ftell (f)); + + i = fread ((void *) buf, 4, (size_t) 1, f); + printf ("read %d (%c), offset = %ld\n", i, buf[0], ftell (f)); + diff = ftell (f) - offset; + if (diff != 3) + { + printf ("ftell did not update properly. got %ld, expected 3\n", diff); + result = 1; + } + fclose (f); + + return result; +} diff --git a/REORG.TODO/libio/bug-ungetc2.c b/REORG.TODO/libio/bug-ungetc2.c new file mode 100644 index 0000000000..652f7e956c --- /dev/null +++ b/REORG.TODO/libio/bug-ungetc2.c @@ -0,0 +1,98 @@ +#include <stdio.h> +#include <sys/types.h> + + +static int +check (FILE *fp, off_t o) +{ + int result = 0; + if (feof (fp)) + { + puts ("feof !"); + result = 1; + } + if (ferror (fp)) + { + puts ("ferror !"); + result = 1; + } + if (ftello (fp) != o) + { + printf ("position = %lu, not %lu\n", (unsigned long int) ftello (fp), + (unsigned long int) o); + result = 1; + } + return result; +} + + +static int +do_test (void) +{ + FILE *fp = tmpfile (); + if (fp == NULL) + { + puts ("tmpfile failed"); + return 1; + } + if (check (fp, 0) != 0) + return 1; + + puts ("going to write"); + if (fputs ("hello", fp) == EOF) + { + puts ("fputs failed"); + return 1; + } + if (check (fp, 5) != 0) + return 1; + + puts ("going to rewind"); + rewind (fp); + if (check (fp, 0) != 0) + return 1; + + puts ("going to read char"); + int c = fgetc (fp); + if (c != 'h') + { + printf ("read %c, not %c\n", c, 'h'); + return 1; + } + if (check (fp, 1) != 0) + return 1; + + puts ("going to put back"); + if (ungetc (' ', fp) == EOF) + { + puts ("ungetc failed"); + return 1; + } + if (check (fp, 0) != 0) + return 1; + + puts ("going to write again"); + if (fputs ("world", fp) == EOF) + { + puts ("2nd fputs failed"); + return 1; + } + if (check (fp, 5) != 0) + return 1; + + puts ("going to rewind again"); + rewind (fp); + if (check (fp, 0) != 0) + return 1; + + if (fclose (fp) != 0) + { + puts ("fclose failed"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/bug-ungetc3.c b/REORG.TODO/libio/bug-ungetc3.c new file mode 100644 index 0000000000..0c83c1161e --- /dev/null +++ b/REORG.TODO/libio/bug-ungetc3.c @@ -0,0 +1,94 @@ +/* Test program for ungetc/ftell interaction bug. */ + +#include <stdio.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static const char pattern[] = "12345"; +static char *temp_file; + +static void +do_prepare (void) +{ + int fd = create_temp_file ("bug-ungetc.", &temp_file); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + write (fd, pattern, sizeof (pattern)); + close (fd); +} + +static int +do_one_test (int mode) +{ + FILE *f; + + f = fopen (temp_file, "r"); + if (f == NULL) + { + printf ("could not open temporary file: %m\n"); + return 1; + } + + if (mode == 1 && ftell (f) != 0) + { + printf ("first ftell returned wrong position %ld\n", ftell (f)); + return 1; + } + + if (fgetc (f) != '1' || fgetc (f) != '2') + { + puts ("fgetc failed"); + return 1; + } + + if (mode == 2 && ftell (f) != 2) + { + printf ("second ftell returned wrong position %ld\n", ftell (f)); + return 1; + } + + if (ungetc ('6', f) != '6') + { + puts ("ungetc failed"); + return 1; + } + + if (ftell (f) != 1) + { + printf ("third ftell returned wrong position %ld\n", ftell (f)); + return 1; + } + + if (fgetc (f) != '6') + { + puts ("fgetc failed"); + return 1; + } + + if (ftell (f) != 2) + { + printf ("fourth ftell returned wrong position %ld\n", ftell (f)); + return 1; + } + + fclose (f); + + return 0; +} + +static int +do_test (void) +{ + int mode; + for (mode = 0; mode <= 2; mode++) + if (do_one_test (mode)) + return 1; + return 0; +} diff --git a/REORG.TODO/libio/bug-ungetc4.c b/REORG.TODO/libio/bug-ungetc4.c new file mode 100644 index 0000000000..3ce20fe751 --- /dev/null +++ b/REORG.TODO/libio/bug-ungetc4.c @@ -0,0 +1,115 @@ +/* Test program for ungetc/fseekpos interaction. + Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static const char pattern[] = "abcdefghijklmnopqrstuvwxyz"; +static char *temp_file; + +static void +do_prepare (void) +{ + int fd = create_temp_file ("bug-ungetc.", &temp_file); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + write (fd, pattern, sizeof (pattern) - 1); + close (fd); +} + +#define TEST_POS 5 + +static int +do_one_test (int mode) +{ + FILE *f = fopen (temp_file, "r"); + if (f == NULL) + { + printf ("%d: could not open temporary file: %m\n", mode); + return 1; + } + + int i; + for (i = 0; i < TEST_POS; ++i) + getc (f); + + fpos_t p; + if (fgetpos (f, &p) != 0) + { + printf ("%d: fgetpos failed: %m\n", mode); + return 1; + } + + if (mode) + { + if (fseek (f, 0, SEEK_SET) != 0) + { + printf ("%d: fseek failed: %m\n", mode); + return 1; + } + + for (i = 0; i < TEST_POS - (mode >= 2); ++i) + getc (f); + } + + if (mode != 2 && ungetc ('X', f) != 'X') + { + printf ("%d: ungetc failed\n", mode); + return 1; + } + + if (mode == 3 && getc (f) != 'X') + { + printf ("%d: getc after ungetc did not return X\n", mode); + return 1; + } + + if (fsetpos (f, &p) != 0) + { + printf ("%d: fsetpos failed: %m\n", mode); + return 1; + } + + if (getc (f) != pattern[TEST_POS]) + { + printf ("%d: getc did not return %c\n", mode, pattern[TEST_POS]); + return 1; + } + + fclose (f); + + return 0; +} + +static int +do_test (void) +{ + int mode, ret = 0; + for (mode = 0; mode <= 4; mode++) + ret |= do_one_test (mode); + return ret; +} diff --git a/REORG.TODO/libio/bug-ungetwc1.c b/REORG.TODO/libio/bug-ungetwc1.c new file mode 100644 index 0000000000..56a3d336ae --- /dev/null +++ b/REORG.TODO/libio/bug-ungetwc1.c @@ -0,0 +1,91 @@ +#define _XOPEN_SOURCE 500 +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <wchar.h> + +const char write_chars[] = "ABC"; /* Characters on testfile. */ +const wint_t unget_wchar = L'A'; /* Ungotten wide character. */ + +char *fname; + + +static int do_test (void); +#define TEST_FUNCTION do_test () + +#include "../test-skeleton.c" + + +static int +do_test (void) +{ + wint_t wc; + FILE *fp; + int fd; + + fname = (char *) malloc (strlen (test_dir) + sizeof "/bug-ungetwc1.XXXXXX"); + if (fname == NULL) + { + puts ("no memory"); + return 1; + } + strcpy (stpcpy (fname, test_dir), "/bug-ungetwc1.XXXXXX"); + fd = mkstemp (fname); + if (fd == -1) + { + printf ("cannot open temporary file: %m\n"); + return 1; + } + add_temp_file (fname); + + setlocale(LC_ALL, ""); + + /* Output to the file. */ + if ((fp = fdopen (fd, "w")) == NULL) + { + fprintf (stderr, "Cannot make `%s' file\n", fname); + exit (EXIT_FAILURE); + } + + fprintf (fp, "%s", write_chars); + fclose (fp); + + /* Read from the file. */ + fp = fopen (fname, "r"); + + size_t i = 0; + while (!feof (fp)) + { + wc = getwc (fp); + if (i >= sizeof (write_chars)) + { + printf ("Did not get end-of-file when expected.\n"); + return 1; + } + else if (wc != (write_chars[i] ? write_chars[i] : WEOF)) + { + printf ("Unexpected %lu from getwc.\n", (unsigned long int) wc); + return 1; + } + i++; + } + printf ("\nThe end-of-file indicator is set.\n"); + + /* Unget a wide character. */ + ungetwc (unget_wchar, fp); + printf ("< `%lc' is ungotten.\n", unget_wchar); + + /* Check the end-of-file indicator. */ + if (feof (fp)) + { + printf ("The end-of-file indicator is still set.\n"); + return 1; + } + else + printf ("The end-of-file flag is cleared.\n"); + + fflush (stdout); + fclose (fp); + + return 0; +} diff --git a/REORG.TODO/libio/bug-ungetwc2.c b/REORG.TODO/libio/bug-ungetwc2.c new file mode 100644 index 0000000000..b901fc01e3 --- /dev/null +++ b/REORG.TODO/libio/bug-ungetwc2.c @@ -0,0 +1,93 @@ +#define _XOPEN_SOURCE 500 +#include <errno.h> +#include <error.h> +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <wchar.h> + +const char test_locale[] = "de_DE.UTF-8"; +const wchar_t write_wchars[] = {L'A', 0x00C4, L'B', L'\0'}; + /* `0x00C4' is A with diaeresis. */ +size_t last_pos = 2; /* Which character is last one to read. */ +wint_t unget_wchar = L'C'; /* Ungotten ide characters. */ + +char *fname; + + +static int do_test (void); +#define TEST_FUNCTION do_test () + +#include "../test-skeleton.c" + + +static int +do_test (void) +{ + size_t i; + wint_t wc; + FILE *fp; + int fd; + + fname = (char *) malloc (strlen (test_dir) + sizeof "/bug-ungetwc2.XXXXXX"); + if (fname == NULL) + { + puts ("no memory"); + return 1; + } + strcpy (stpcpy (fname, test_dir), "/bug-ungetwc2.XXXXXX"); + fd = mkstemp (fname); + if (fd == -1) + { + printf ("cannot open temporary file: %m\n"); + return 1; + } + add_temp_file (fname); + + printf ("\nNote: This program runs on %s locale.\n\n", test_locale); + + if (setlocale (LC_ALL, test_locale) == NULL) + { + fprintf (stderr, "Cannot use `%s' locale.\n", test_locale); + exit (EXIT_FAILURE); + } + + /* Output to the file. */ + if ((fp = fdopen (fd, "w")) == NULL) + { + setlocale (LC_ALL, "C"); + fprintf (stderr, "Cannot make `%s' file.\n", fname); + exit (EXIT_FAILURE); + } + fprintf (fp, "%ls", write_wchars); + fclose (fp); + + /* Read from the file. */ + fp = fopen (fname, "r"); + if (fp == NULL) + { + setlocale (LC_ALL, "C"); + error (EXIT_FAILURE, errno, "cannot open %s", fname); + } + + printf ("%s is opened.\n", fname); + + for (i = 0; i < last_pos; i++) + { + wc = getwc (fp); + printf ("> `%lc' is gotten.\n", wc); + } + + /* Unget a wide character. */ + ungetwc (unget_wchar, fp); + printf ("< `%lc' is ungotten.\n", unget_wchar); + + /* Reget the wide character. */ + wc = getwc (fp); + printf ("> `%lc' is regotten.\n", wc); + + fflush (stdout); + fclose (fp); + + return 0; +} diff --git a/REORG.TODO/libio/bug-wfflush.c b/REORG.TODO/libio/bug-wfflush.c new file mode 100644 index 0000000000..a8fd61e997 --- /dev/null +++ b/REORG.TODO/libio/bug-wfflush.c @@ -0,0 +1,76 @@ +/* Test program for bug in wide streams. */ + +#include <stdio.h> +#include <wchar.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static char *temp_file; + +static void +do_prepare (void) +{ + int fd = create_temp_file ("bug-ungetc.", &temp_file); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + write (fd, "1!", 2); + close (fd); +} + +static int +do_test (void) +{ + FILE *f = fopen (temp_file, "r+"); + + if (f == NULL) + { + printf ("fopen: %m\n"); + return 1; + } + +#define L_(s) L##s + //#define fwscanf fscanf + //#define fwprintf fprintf + + int i; + if (fwscanf (f, L_("%d!"), &i) != 1) + { + printf ("fwscanf failed\n"); + return 1; + } + + rewind (f); + if (ferror (f)) + { + printf ("rewind: %m\n"); + return 1; + } + + if (fputws (L_("1!"), f) == EOF) + { + printf ("fputws: %m\n"); + return 1; + } + + if (fflush (f) != 0) + { + printf ("fflush: %m\n"); + return 1; + } + + if (fclose (f) != 0) + { + printf ("fclose: %m\n"); + return 1; + } + + puts ("Test succeeded."); + return 0; +} diff --git a/REORG.TODO/libio/bug-wmemstream1.c b/REORG.TODO/libio/bug-wmemstream1.c new file mode 100644 index 0000000000..709a3c6d66 --- /dev/null +++ b/REORG.TODO/libio/bug-wmemstream1.c @@ -0,0 +1,137 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + + +static int +do_test (void) +{ + size_t size; + wchar_t *buf; + FILE *fp = open_wmemstream (&buf, &size); + if (fp == NULL) + { + puts ("open_wmemstream failed"); + return 1; + } + + off64_t off = ftello64 (fp); + if (off != 0) + { + puts ("initial position wrong"); + return 1; + } + + if (fseek (fp, 32768, SEEK_SET) != 0) + { + puts ("fseek failed"); + return 1; + } + + if (fputws (L"foo", fp) == EOF) + { + puts ("fputws failed"); + return 1; + } + + if (fclose (fp) == EOF) + { + puts ("fclose failed"); + return 1; + } + + if (size != 32768 + 3) + { + printf ("expected size %d, got %zu\n", 32768 + 3, size); + return 1; + } + + for (int i = 0; i < 32768; ++i) + if (buf[i] != L'\0') + { + printf ("wide character at offset %d is %#x\n", + i, (unsigned int) buf[i]); + return 1; + } + + if (wmemcmp (buf + 32768, L"foo", 3) != 0) + { + puts ("written string incorrect"); + return 1; + } + + /* Mark the buffer. */ + wmemset (buf, L'A', size); + free (buf); + + /* Try again, this time with write mode enabled before the seek. */ + fp = open_wmemstream (&buf, &size); + if (fp == NULL) + { + puts ("2nd open_wmemstream failed"); + return 1; + } + + off = ftello64 (fp); + if (off != 0) + { + puts ("2nd initial position wrong"); + return 1; + } + + if (fputws (L"bar", fp) == EOF) + { + puts ("2nd fputws failed"); + return 1; + } + + if (fseek (fp, 32768, SEEK_SET) != 0) + { + puts ("2nd fseek failed"); + return 1; + } + + if (fputws (L"foo", fp) == EOF) + { + puts ("3rd fputws failed"); + return 1; + } + + if (fclose (fp) == EOF) + { + puts ("2nd fclose failed"); + return 1; + } + + if (size != 32768 + 3) + { + printf ("2nd expected size %d, got %zu\n", 32768 + 3, size); + return 1; + } + + if (wmemcmp (buf, L"bar", 3) != 0) + { + puts ("initial string incorrect in 2nd try"); + return 1; + } + + for (int i = 3; i < 32768; ++i) + if (buf[i] != L'\0') + { + printf ("wide character at offset %d is %#x in 2nd try\n", + i, (unsigned int) buf[i]); + return 1; + } + + if (wmemcmp (buf + 32768, L"foo", 3) != 0) + { + puts ("written string incorrect in 2nd try"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/bug-wsetpos.c b/REORG.TODO/libio/bug-wsetpos.c new file mode 100644 index 0000000000..ccb22a4b62 --- /dev/null +++ b/REORG.TODO/libio/bug-wsetpos.c @@ -0,0 +1,75 @@ +/* Test program for fsetpos on a wide character stream. */ + +#include <assert.h> +#include <stdio.h> +#include <wchar.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static const char pattern[] = "12345"; +static char *temp_file; + +static void +do_prepare (void) +{ + int fd = create_temp_file ("bug-wsetpos.", &temp_file); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } + write (fd, pattern, sizeof (pattern)); + close (fd); +} + +static int +do_test (void) +{ + FILE *fp = fopen (temp_file, "r"); + fpos_t pos; + wchar_t c; + + if (fp == NULL) + { + printf ("fdopen: %m\n"); + return 1; + } + + c = fgetwc (fp); assert (c == L'1'); + c = fgetwc (fp); assert (c == L'2'); + + if (fgetpos (fp, &pos) == EOF) + { + printf ("fgetpos: %m\n"); + return 1; + } + + rewind (fp); + if (ferror (fp)) + { + printf ("rewind: %m\n"); + return 1; + } + + c = fgetwc (fp); assert (c == L'1'); + + if (fsetpos (fp, &pos) == EOF) + { + printf ("fsetpos: %m\n"); + return 1; + } + + c = fgetwc (fp); + if (c != L'3') + { + puts ("fsetpos failed"); + return 1; + } + + puts ("Test succeeded."); + return 0; +} diff --git a/REORG.TODO/libio/clearerr.c b/REORG.TODO/libio/clearerr.c new file mode 100644 index 0000000000..3c30bfd11f --- /dev/null +++ b/REORG.TODO/libio/clearerr.c @@ -0,0 +1,32 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +void +clearerr (FILE *fp) +{ + CHECK_FILE (fp, /*nothing*/); + _IO_flockfile (fp); + _IO_clearerr (fp); + _IO_funlockfile (fp); +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +weak_alias (clearerr, clearerr_unlocked) +#endif diff --git a/REORG.TODO/libio/clearerr_u.c b/REORG.TODO/libio/clearerr_u.c new file mode 100644 index 0000000000..b692ce0394 --- /dev/null +++ b/REORG.TODO/libio/clearerr_u.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +void +clearerr_unlocked (FILE *fp) +{ + CHECK_FILE (fp, /*nothing*/); + _IO_clearerr (fp); +} diff --git a/REORG.TODO/libio/fcloseall.c b/REORG.TODO/libio/fcloseall.c new file mode 100644 index 0000000000..59c33ccf48 --- /dev/null +++ b/REORG.TODO/libio/fcloseall.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +int +__fcloseall (void) +{ + /* Close all streams. */ + return _IO_cleanup (); +} + +#ifdef weak_alias +weak_alias (__fcloseall, fcloseall) +#endif diff --git a/REORG.TODO/libio/feof.c b/REORG.TODO/libio/feof.c new file mode 100644 index 0000000000..9712a81e78 --- /dev/null +++ b/REORG.TODO/libio/feof.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +_IO_feof (_IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_feof_unlocked (fp); + _IO_funlockfile (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_feof, feof) + +#ifndef _IO_MTSAFE_IO +#undef feof_unlocked +weak_alias (_IO_feof, feof_unlocked) +#endif +#endif diff --git a/REORG.TODO/libio/feof_u.c b/REORG.TODO/libio/feof_u.c new file mode 100644 index 0000000000..616eadbccd --- /dev/null +++ b/REORG.TODO/libio/feof_u.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef feof_unlocked + +int +feof_unlocked (_IO_FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_feof_unlocked (fp); +} diff --git a/REORG.TODO/libio/ferror.c b/REORG.TODO/libio/ferror.c new file mode 100644 index 0000000000..01e3bd8e2b --- /dev/null +++ b/REORG.TODO/libio/ferror.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +_IO_ferror (_IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_flockfile (fp); + result = _IO_ferror_unlocked (fp); + _IO_funlockfile (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_ferror, ferror) + +#ifndef _IO_MTSAFE_IO +#undef ferror_unlocked +weak_alias (_IO_ferror, ferror_unlocked) +#endif +#endif diff --git a/REORG.TODO/libio/ferror_u.c b/REORG.TODO/libio/ferror_u.c new file mode 100644 index 0000000000..0b4c2a86f1 --- /dev/null +++ b/REORG.TODO/libio/ferror_u.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef ferror_unlocked + +int +ferror_unlocked (_IO_FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_ferror_unlocked (fp); +} diff --git a/REORG.TODO/libio/filedoalloc.c b/REORG.TODO/libio/filedoalloc.c new file mode 100644 index 0000000000..50919c9b5f --- /dev/null +++ b/REORG.TODO/libio/filedoalloc.c @@ -0,0 +1,107 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* + Copyright (C) 1990 The Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE.*/ + +/* Modified for GNU iostream by Per Bothner 1991, 1992. */ + +#include "libioP.h" +#include <device-nrs.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <unistd.h> + +/* Return the result of isatty, without changing errno. */ +static int +local_isatty (int fd) +{ + int save_errno = errno; + int res = __isatty (fd); + __set_errno (save_errno); + return res; +} + +/* Allocate a file buffer, or switch to unbuffered I/O. Streams for + TTY devices default to line buffered. */ +int +_IO_file_doallocate (_IO_FILE *fp) +{ + _IO_size_t size; + char *p; + struct stat64 st; + + size = _IO_BUFSIZ; + if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st), 0) >= 0) + { + if (S_ISCHR (st.st_mode)) + { + /* Possibly a tty. */ + if ( +#ifdef DEV_TTY_P + DEV_TTY_P (&st) || +#endif + local_isatty (fp->_fileno)) + fp->_flags |= _IO_LINE_BUF; + } +#if _IO_HAVE_ST_BLKSIZE + if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ) + size = st.st_blksize; +#endif + } + p = malloc (size); + if (__glibc_unlikely (p == NULL)) + return EOF; + _IO_setb (fp, p, p + size, 1); + return 1; +} +libc_hidden_def (_IO_file_doallocate) diff --git a/REORG.TODO/libio/fileno.c b/REORG.TODO/libio/fileno.c new file mode 100644 index 0000000000..b78d4a1461 --- /dev/null +++ b/REORG.TODO/libio/fileno.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +int +__fileno (_IO_FILE *fp) +{ + CHECK_FILE (fp, EOF); + + if (!(fp->_flags & _IO_IS_FILEBUF) || _IO_fileno (fp) < 0) + { + __set_errno (EBADF); + return -1; + } + + return _IO_fileno (fp); +} +libc_hidden_def (__fileno) +weak_alias (__fileno, fileno) +libc_hidden_weak (fileno) + +#ifdef weak_alias +/* The fileno implementation for libio does not require locking because + it only accesses once a single variable and this is already atomic + (at least at thread level). Therefore we don't test _IO_MTSAFE_IO here. */ + +weak_alias (__fileno, fileno_unlocked) +#endif diff --git a/REORG.TODO/libio/fileops.c b/REORG.TODO/libio/fileops.c new file mode 100644 index 0000000000..c55e196dd8 --- /dev/null +++ b/REORG.TODO/libio/fileops.c @@ -0,0 +1,1600 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include <assert.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#if _LIBC +# include "../wcsmbs/wcsmbsload.h" +# include "../iconv/gconv_charset.h" +# include "../iconv/gconv_int.h" +# include <shlib-compat.h> +# include <not-cancel.h> +# include <kernel-features.h> +#endif +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + + +#ifdef _LIBC +# define open(Name, Flags, Prot) __open (Name, Flags, Prot) +# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) +# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) +# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) +#else +# define _IO_new_do_write _IO_do_write +# define _IO_new_file_attach _IO_file_attach +# define _IO_new_file_close_it _IO_file_close_it +# define _IO_new_file_finish _IO_file_finish +# define _IO_new_file_fopen _IO_file_fopen +# define _IO_new_file_init _IO_file_init +# define _IO_new_file_setbuf _IO_file_setbuf +# define _IO_new_file_sync _IO_file_sync +# define _IO_new_file_overflow _IO_file_overflow +# define _IO_new_file_seekoff _IO_file_seekoff +# define _IO_new_file_underflow _IO_file_underflow +# define _IO_new_file_write _IO_file_write +# define _IO_new_file_xsputn _IO_file_xsputn +#endif + + +#ifdef _LIBC +extern struct __gconv_trans_data __libio_translit attribute_hidden; +#endif + + +/* An fstream can be in at most one of put mode, get mode, or putback mode. + Putback mode is a variant of get mode. + + In a filebuf, there is only one current position, instead of two + separate get and put pointers. In get mode, the current position + is that of gptr(); in put mode that of pptr(). + + The position in the buffer that corresponds to the position + in external file system is normally _IO_read_end, except in putback + mode, when it is _IO_save_end and also when the file is in append mode, + since switching from read to write mode automatically sends the position in + the external file system to the end of file. + If the field _fb._offset is >= 0, it gives the offset in + the file as a whole corresponding to eGptr(). (?) + + PUT MODE: + If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end, + and _IO_read_base are equal to each other. These are usually equal + to _IO_buf_base, though not necessarily if we have switched from + get mode to put mode. (The reason is to maintain the invariant + that _IO_read_end corresponds to the external file position.) + _IO_write_base is non-NULL and usually equal to _IO_buf_base. + We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode. + The un-flushed character are those between _IO_write_base and _IO_write_ptr. + + GET MODE: + If a filebuf is in get or putback mode, eback() != egptr(). + In get mode, the unread characters are between gptr() and egptr(). + The OS file position corresponds to that of egptr(). + + PUTBACK MODE: + Putback mode is used to remember "excess" characters that have + been sputbackc'd in a separate putback buffer. + In putback mode, the get buffer points to the special putback buffer. + The unread characters are the characters between gptr() and egptr() + in the putback buffer, as well as the area between save_gptr() + and save_egptr(), which point into the original reserve buffer. + (The pointers save_gptr() and save_egptr() are the values + of gptr() and egptr() at the time putback mode was entered.) + The OS position corresponds to that of save_egptr(). + + LINE BUFFERED OUTPUT: + During line buffered output, _IO_write_base==base() && epptr()==base(). + However, ptr() may be anywhere between base() and ebuf(). + This forces a call to filebuf::overflow(int C) on every put. + If there is more space in the buffer, and C is not a '\n', + then C is inserted, and pptr() incremented. + + UNBUFFERED STREAMS: + If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer. +*/ + +#define CLOSED_FILEBUF_FLAGS \ + (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET) + + +void +_IO_new_file_init_internal (struct _IO_FILE_plus *fp) +{ + /* POSIX.1 allows another file handle to be used to change the position + of our file descriptor. Hence we actually don't know the actual + position before we do the first fseek (and until a following fflush). */ + fp->file._offset = _IO_pos_BAD; + fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + + _IO_link_in (fp); + fp->file._fileno = -1; +} + +/* External version of _IO_new_file_init_internal which switches off + vtable validation. */ +void +_IO_new_file_init (struct _IO_FILE_plus *fp) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_new_file_init_internal (fp); +} + +int +_IO_new_file_close_it (_IO_FILE *fp) +{ + int write_status; + if (!_IO_file_is_open (fp)) + return EOF; + + if ((fp->_flags & _IO_NO_WRITES) == 0 + && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) + write_status = _IO_do_flush (fp); + else + write_status = 0; + + _IO_unsave_markers (fp); + + int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 + ? _IO_SYSCLOSE (fp) : 0); + + /* Free buffer. */ +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (fp->_mode > 0) + { + if (_IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + _IO_wsetb (fp, NULL, NULL, 0); + _IO_wsetg (fp, NULL, NULL, NULL); + _IO_wsetp (fp, NULL, NULL); + } +#endif + _IO_setb (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); + + _IO_un_link ((struct _IO_FILE_plus *) fp); + fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; + fp->_fileno = -1; + fp->_offset = _IO_pos_BAD; + + return close_status ? close_status : write_status; +} +libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it) + +void +_IO_new_file_finish (_IO_FILE *fp, int dummy) +{ + if (_IO_file_is_open (fp)) + { + _IO_do_flush (fp); + if (!(fp->_flags & _IO_DELETE_DONT_CLOSE)) + _IO_SYSCLOSE (fp); + } + _IO_default_finish (fp, 0); +} +libc_hidden_ver (_IO_new_file_finish, _IO_file_finish) + +_IO_FILE * +_IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot, + int read_write, int is32not64) +{ + int fdesc; +#ifdef _LIBC + if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL)) + fdesc = open_not_cancel (filename, + posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot); + else + fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot); +#else + fdesc = open (filename, posix_mode, prot); +#endif + if (fdesc < 0) + return NULL; + fp->_fileno = fdesc; + _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + /* For append mode, send the file offset to the end of the file. Don't + update the offset cache though, since the file handle is not active. */ + if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) + == (_IO_IS_APPENDING | _IO_NO_READS)) + { + _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end); + if (new_pos == _IO_pos_BAD && errno != ESPIPE) + { + close_not_cancel (fdesc); + return NULL; + } + } + _IO_link_in ((struct _IO_FILE_plus *) fp); + return fp; +} +libc_hidden_def (_IO_file_open) + +_IO_FILE * +_IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, + int is32not64) +{ + int oflags = 0, omode; + int read_write; + int oprot = 0666; + int i; + _IO_FILE *result; +#ifdef _LIBC + const char *cs; + const char *last_recognized; +#endif + + if (_IO_file_is_open (fp)) + return 0; + switch (*mode) + { + case 'r': + omode = O_RDONLY; + read_write = _IO_NO_WRITES; + break; + case 'w': + omode = O_WRONLY; + oflags = O_CREAT|O_TRUNC; + read_write = _IO_NO_READS; + break; + case 'a': + omode = O_WRONLY; + oflags = O_CREAT|O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + __set_errno (EINVAL); + return NULL; + } +#ifdef _LIBC + last_recognized = mode; +#endif + for (i = 1; i < 7; ++i) + { + switch (*++mode) + { + case '\0': + break; + case '+': + omode = O_RDWR; + read_write &= _IO_IS_APPENDING; +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'x': + oflags |= O_EXCL; +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'b': +#ifdef _LIBC + last_recognized = mode; +#endif + continue; + case 'm': + fp->_flags2 |= _IO_FLAGS2_MMAP; + continue; + case 'c': + fp->_flags2 |= _IO_FLAGS2_NOTCANCEL; + continue; + case 'e': + oflags |= O_CLOEXEC; + fp->_flags2 |= _IO_FLAGS2_CLOEXEC; + continue; + default: + /* Ignore. */ + continue; + } + break; + } + + result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, + is32not64); + + if (result != NULL) + { + /* Test whether the mode string specifies the conversion. */ + cs = strstr (last_recognized + 1, ",ccs="); + if (cs != NULL) + { + /* Yep. Load the appropriate conversions and set the orientation + to wide. */ + struct gconv_fcts fcts; + struct _IO_codecvt *cc; + char *endp = __strchrnul (cs + 5, ','); + char *ccs = malloc (endp - (cs + 5) + 3); + + if (ccs == NULL) + { + int malloc_err = errno; /* Whatever malloc failed with. */ + (void) _IO_file_close_it (fp); + __set_errno (malloc_err); + return NULL; + } + + *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0'; + strip (ccs, ccs); + + if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0' + ? upstr (ccs, cs + 5) : ccs) != 0) + { + /* Something went wrong, we cannot load the conversion modules. + This means we cannot proceed since the user explicitly asked + for these. */ + (void) _IO_file_close_it (fp); + free (ccs); + __set_errno (EINVAL); + return NULL; + } + + free (ccs); + + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + + /* Clear the state. We start all over again. */ + memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); + memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); + + cc = fp->_codecvt = &fp->_wide_data->_codecvt; + + /* The functions are always the same. */ + *cc = __libio_codecvt; + + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + + cc->__cd_in.__cd.__data[0].__invocation_counter = 0; + cc->__cd_in.__cd.__data[0].__internal_use = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; + + cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; + cc->__cd_out.__cd.__steps = fcts.tomb; + + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__flags + = __GCONV_IS_LAST | __GCONV_TRANSLIT; + cc->__cd_out.__cd.__data[0].__statep = + &result->_wide_data->_IO_state; + + /* From now on use the wide character callback functions. */ + _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable; + + /* Set the mode now. */ + result->_mode = 1; + } + } + + return result; +} +libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen) + +_IO_FILE * +_IO_new_file_attach (_IO_FILE *fp, int fd) +{ + if (_IO_file_is_open (fp)) + return NULL; + fp->_fileno = fd; + fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES); + fp->_flags |= _IO_DELETE_DONT_CLOSE; + /* Get the current position of the file. */ + /* We have to do that since that may be junk. */ + fp->_offset = _IO_pos_BAD; + int save_errno = errno; + if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + __set_errno (save_errno); + return fp; +} +libc_hidden_ver (_IO_new_file_attach, _IO_file_attach) + +_IO_FILE * +_IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +{ + if (_IO_default_setbuf (fp, p, len) == NULL) + return NULL; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + + return fp; +} +libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf) + + +_IO_FILE * +_IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len) +{ + _IO_FILE *result; + + /* Change the function table. */ + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + + /* And perform the normal operation. */ + result = _IO_new_file_setbuf (fp, p, len); + + /* If the call failed, restore to using mmap. */ + if (result == NULL) + { + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; + } + + return result; +} + +static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t); + +/* Write TO_DO bytes from DATA to FP. + Then mark FP as having empty buffers. */ + +int +_IO_new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +{ + return (to_do == 0 + || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF; +} +libc_hidden_ver (_IO_new_do_write, _IO_do_write) + +static +_IO_size_t +new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +{ + _IO_size_t count; + if (fp->_flags & _IO_IS_APPENDING) + /* On a system without a proper O_APPEND implementation, + you would need to sys_seek(0, SEEK_END) here, but is + not needed nor desirable for Unix- or Posix-like systems. + Instead, just indicate that offset (before and after) is + unpredictable. */ + fp->_offset = _IO_pos_BAD; + else if (fp->_IO_read_end != fp->_IO_write_base) + { + _IO_off64_t new_pos + = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); + if (new_pos == _IO_pos_BAD) + return 0; + fp->_offset = new_pos; + } + count = _IO_SYSWRITE (fp, data, to_do); + if (fp->_cur_column && count) + fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; + fp->_IO_write_end = (fp->_mode <= 0 + && (fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + ? fp->_IO_buf_base : fp->_IO_buf_end); + return count; +} + +int +_IO_new_file_underflow (_IO_FILE *fp) +{ + _IO_ssize_t count; +#if 0 + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & _IO_EOF_SEEN) + return (EOF); +#endif + + if (fp->_flags & _IO_NO_READS) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + { +#if 0 + _IO_flush_all_linebuffered (); +#else + /* We used to flush all line-buffered stream. This really isn't + required by any standard. My recollection is that + traditional Unix systems did this for stdout. stderr better + not be line buffered. So we do just that here + explicitly. --drepper */ + _IO_acquire_lock (_IO_stdout); + + if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + == (_IO_LINKED | _IO_LINE_BUF)) + _IO_OVERFLOW (_IO_stdout, EOF); + + _IO_release_lock (_IO_stdout); +#endif + } + + _IO_switch_to_get_mode (fp); + + /* This is very tricky. We have to adjust those + pointers before we call _IO_SYSREAD () since + we may longjump () out while waiting for + input. Those pointers may be screwed up. H.J. */ + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_buf_base; + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + { + /* If a stream is read to EOF, the calling application may switch active + handles. As a result, our offset cache would no longer be valid, so + unset it. */ + fp->_offset = _IO_pos_BAD; + return EOF; + } + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + return *(unsigned char *) fp->_IO_read_ptr; +} +libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow) + +/* Guts of underflow callback if we mmap the file. This stats the file and + updates the stream state to match. In the normal case we return zero. + If the file is no longer eligible for mmap, its jump tables are reset to + the vanilla ones and we return nonzero. */ +static int +mmap_remap_check (_IO_FILE *fp) +{ + struct stat64 st; + + if (_IO_SYSSTAT (fp, &st) == 0 + && S_ISREG (st.st_mode) && st.st_size != 0 + /* Limit the file size to 1MB for 32-bit machines. */ + && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)) + { + const size_t pagesize = __getpagesize (); +# define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1)) + if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base)) + { + /* We can trim off some pages past the end of the file. */ + (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size), + ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base) + - ROUNDED (st.st_size)); + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } + else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base)) + { + /* The file added some pages. We need to remap it. */ + void *p; +#ifdef _G_HAVE_MREMAP + p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end + - fp->_IO_buf_base), + ROUNDED (st.st_size), MREMAP_MAYMOVE); + if (p == MAP_FAILED) + { + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + goto punt; + } +#else + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, + fp->_fileno, 0); + if (p == MAP_FAILED) + goto punt; +#endif + fp->_IO_buf_base = p; + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } + else + { + /* The number of pages didn't change. */ + fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; + } +# undef ROUNDED + + fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr; + _IO_setg (fp, fp->_IO_buf_base, + fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base + ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end, + fp->_IO_buf_end); + + /* If we are already positioned at or past the end of the file, don't + change the current offset. If not, seek past what we have mapped, + mimicking the position left by a normal underflow reading into its + buffer until EOF. */ + + if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base) + { + if (__lseek64 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, + SEEK_SET) + != fp->_IO_buf_end - fp->_IO_buf_base) + fp->_flags |= _IO_ERR_SEEN; + else + fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base; + } + + return 0; + } + else + { + /* Life is no longer good for mmap. Punt it. */ + (void) __munmap (fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + punt: + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + _IO_setg (fp, NULL, NULL, NULL); + if (fp->_mode <= 0) + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; + else + _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + + return 1; + } +} + +/* Special callback replacing the underflow callbacks if we mmap the file. */ +int +_IO_file_underflow_mmap (_IO_FILE *fp) +{ + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (__glibc_unlikely (mmap_remap_check (fp))) + /* We punted to the regular file functions. */ + return _IO_UNDERFLOW (fp); + + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + fp->_flags |= _IO_EOF_SEEN; + return EOF; +} + +static void +decide_maybe_mmap (_IO_FILE *fp) +{ + /* We use the file in read-only mode. This could mean we can + mmap the file and use it without any copying. But not all + file descriptors are for mmap-able objects and on 32-bit + machines we don't want to map files which are too large since + this would require too much virtual memory. */ + struct stat64 st; + + if (_IO_SYSSTAT (fp, &st) == 0 + && S_ISREG (st.st_mode) && st.st_size != 0 + /* Limit the file size to 1MB for 32-bit machines. */ + && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024) + /* Sanity check. */ + && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) + { + /* Try to map the file. */ + void *p; + + p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); + if (p != MAP_FAILED) + { + /* OK, we managed to map the file. Set the buffer up and use a + special jump table with simplified underflow functions which + never tries to read anything from the file. */ + + if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size) + { + (void) __munmap (p, st.st_size); + fp->_offset = _IO_pos_BAD; + } + else + { + _IO_setb (fp, p, (char *) p + st.st_size, 0); + + if (fp->_offset == _IO_pos_BAD) + fp->_offset = 0; + + _IO_setg (fp, p, p + fp->_offset, p + st.st_size); + fp->_offset = st.st_size; + + if (fp->_mode <= 0) + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap; + else + _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; + + return; + } + } + } + + /* We couldn't use mmap, so revert to the vanilla file operations. */ + + if (fp->_mode <= 0) + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; + else + _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; +} + +int +_IO_file_underflow_maybe_mmap (_IO_FILE *fp) +{ + /* This is the first read attempt. Choose mmap or vanilla operations + and then punt to the chosen underflow routine. */ + decide_maybe_mmap (fp); + return _IO_UNDERFLOW (fp); +} + + +int +_IO_new_file_overflow (_IO_FILE *f, int ch) +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL) + { + /* Allocate a buffer if needed. */ + if (f->_IO_write_base == NULL) + { + _IO_doallocbuf (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + /* Otherwise must be currently reading. + If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting the + read pointers to all point at the beginning of the block). This + makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving that + alone, so it can continue to correspond to the external position). */ + if (__glibc_unlikely (_IO_in_backup (f))) + { + size_t nbackup = f->_IO_read_end - f->_IO_read_ptr; + _IO_free_backup_area (f); + f->_IO_read_base -= MIN (nbackup, + f->_IO_read_base - f->_IO_buf_base); + f->_IO_read_ptr = f->_IO_read_base; + } + + if (f->_IO_read_ptr == f->_IO_buf_end) + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + f->_flags |= _IO_CURRENTLY_PUTTING; + if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + f->_IO_write_end = f->_IO_write_ptr; + } + if (ch == EOF) + return _IO_do_write (f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base); + if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ + if (_IO_do_flush (f) == EOF) + return EOF; + *f->_IO_write_ptr++ = ch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) + if (_IO_do_write (f, f->_IO_write_base, + f->_IO_write_ptr - f->_IO_write_base) == EOF) + return EOF; + return (unsigned char) ch; +} +libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow) + +int +_IO_new_file_sync (_IO_FILE *fp) +{ + _IO_ssize_t delta; + int retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_do_flush(fp)) return EOF; + delta = fp->_IO_read_ptr - fp->_IO_read_end; + if (delta != 0) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off64_t) EOF) + fp->_IO_read_end = fp->_IO_read_ptr; +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = EOF; + } + if (retval != EOF) + fp->_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} +libc_hidden_ver (_IO_new_file_sync, _IO_file_sync) + +static int +_IO_file_sync_mmap (_IO_FILE *fp) +{ + if (fp->_IO_read_ptr != fp->_IO_read_end) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, + SEEK_SET) + != fp->_IO_read_ptr - fp->_IO_buf_base) + { + fp->_flags |= _IO_ERR_SEEN; + return EOF; + } + } + fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base; + return 0; +} + +/* ftell{,o} implementation. The only time we modify the state of the stream + is when we have unflushed writes. In that case we seek to the end and + record that offset in the stream object. */ +static _IO_off64_t +do_ftell (_IO_FILE *fp) +{ + _IO_off64_t result, offset = 0; + + /* No point looking at unflushed data if we haven't allocated buffers + yet. */ + if (fp->_IO_buf_base != NULL) + { + bool unflushed_writes = fp->_IO_write_ptr > fp->_IO_write_base; + + bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; + + /* When we have unflushed writes in append mode, seek to the end of the + file and record that offset. This is the only time we change the file + stream state and it is safe since the file handle is active. */ + if (unflushed_writes && append_mode) + { + result = _IO_SYSSEEK (fp, 0, _IO_seek_end); + if (result == _IO_pos_BAD) + return EOF; + else + fp->_offset = result; + } + + /* Adjust for unflushed data. */ + if (!unflushed_writes) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + /* We don't trust _IO_read_end to represent the current file offset when + writing in append mode because the value would have to be shifted to + the end of the file during a flush. Use the write base instead, along + with the new offset we got above when we did a seek to the end of the + file. */ + else if (append_mode) + offset += fp->_IO_write_ptr - fp->_IO_write_base; + /* For all other modes, _IO_read_end represents the file offset. */ + else + offset += fp->_IO_write_ptr - fp->_IO_read_end; + } + + if (fp->_offset != _IO_pos_BAD) + result = fp->_offset; + else + result = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + + if (result == EOF) + return result; + + result += offset; + + if (result < 0) + { + __set_errno (EINVAL); + return EOF; + } + + return result; +} + +_IO_off64_t +_IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long count; + + /* Short-circuit into a separate function. We don't want to mix any + functionality and we don't want to touch anything inside the FILE + object. */ + if (mode == 0) + return do_ftell (fp); + + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end + && fp->_IO_write_base == fp->_IO_write_ptr); + + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to pptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ + if (was_writing && _IO_switch_to_get_mode (fp)) + return EOF; + + if (fp->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_IO_read_base != NULL) + { + free (fp->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + } + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + + if (fp->_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + if (offset < 0) + { + __set_errno (EINVAL); + return EOF; + } + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + _IO_off64_t start_offset = (fp->_offset + - (fp->_IO_read_end - fp->_IO_buf_base)); + if (offset >= start_offset && offset < fp->_offset) + { + _IO_setg (fp, fp->_IO_buf_base, + fp->_IO_buf_base + (offset - start_offset), + fp->_IO_read_end); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } + } + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + _IO_unsave_markers (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; +} +libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff) + +_IO_off64_t +_IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t result; + + /* If we are only interested in the current position, calculate it and + return right now. This calculation does the right thing when we are + using a pushback buffer, but in the usual case has the same value as + (fp->_IO_read_ptr - fp->_IO_buf_base). */ + if (mode == 0) + return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset += fp->_IO_read_ptr - fp->_IO_read_base; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + offset += fp->_IO_buf_end - fp->_IO_buf_base; + break; + } + /* At this point, dir==_IO_seek_set. */ + + if (offset < 0) + { + /* No negative offsets are valid. */ + __set_errno (EINVAL); + return EOF; + } + + result = _IO_SYSSEEK (fp, offset, 0); + if (result < 0) + return EOF; + + if (offset > fp->_IO_buf_end - fp->_IO_buf_base) + /* One can fseek arbitrarily past the end of the file + and it is meaningless until one attempts to read. + Leave the buffer pointers in EOF state until underflow. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end); + else + /* Adjust the read pointers to match the file position, + but so the next read attempt will call underflow. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset, + fp->_IO_buf_base + offset); + + fp->_offset = result; + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + + return offset; +} + +static _IO_off64_t +_IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, + int mode) +{ + /* We only get here when we haven't tried to read anything yet. + So there is nothing more useful for us to do here than just + the underlying lseek call. */ + + _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir); + if (result < 0) + return EOF; + + fp->_offset = result; + return result; +} + +_IO_ssize_t +_IO_file_read (_IO_FILE *fp, void *buf, _IO_ssize_t size) +{ + return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0) + ? read_not_cancel (fp->_fileno, buf, size) + : read (fp->_fileno, buf, size)); +} +libc_hidden_def (_IO_file_read) + +_IO_off64_t +_IO_file_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +{ + return __lseek64 (fp->_fileno, offset, dir); +} +libc_hidden_def (_IO_file_seek) + +int +_IO_file_stat (_IO_FILE *fp, void *st) +{ + return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st); +} +libc_hidden_def (_IO_file_stat) + +int +_IO_file_close_mmap (_IO_FILE *fp) +{ + /* In addition to closing the file descriptor we have to unmap the file. */ + (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base); + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + /* Cancelling close should be avoided if possible since it leaves an + unrecoverable state behind. */ + return close_not_cancel (fp->_fileno); +} + +int +_IO_file_close (_IO_FILE *fp) +{ + /* Cancelling close should be avoided if possible since it leaves an + unrecoverable state behind. */ + return close_not_cancel (fp->_fileno); +} +libc_hidden_def (_IO_file_close) + +_IO_ssize_t +_IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) +{ + _IO_ssize_t to_do = n; + while (to_do > 0) + { + _IO_ssize_t count = (__builtin_expect (f->_flags2 + & _IO_FLAGS2_NOTCANCEL, 0) + ? write_not_cancel (f->_fileno, data, to_do) + : write (f->_fileno, data, to_do)); + if (count < 0) + { + f->_flags |= _IO_ERR_SEEN; + break; + } + to_do -= count; + data = (void *) ((char *) data + count); + } + n -= to_do; + if (f->_offset >= 0) + f->_offset += n; + return n; +} + +_IO_size_t +_IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +{ + const char *s = (const char *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count = 0; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_IO_buf_end - f->_IO_write_ptr; + if (count >= n) + { + const char *p; + for (p = s + n; p > s; ) + { + if (*--p == '\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + else if (f->_IO_write_end > f->_IO_write_ptr) + count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */ + + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + to_do -= count; + } + if (to_do + must_flush > 0) + { + _IO_size_t block_size, do_write; + /* Next flush the (full) buffer. */ + if (_IO_OVERFLOW (f, EOF) == EOF) + /* If nothing else has to be written we must not signal the + caller that everything has been written. */ + return to_do == 0 ? EOF : n - to_do; + + /* Try to maintain alignment: write a whole number of blocks. */ + block_size = f->_IO_buf_end - f->_IO_buf_base; + do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); + + if (do_write) + { + count = new_do_write (f, s, do_write); + to_do -= count; + if (count < do_write) + return n - to_do; + } + + /* Now write out the remainder. Normally, this will fit in the + buffer, but it's somewhat messier for line-buffered files, + so we let _IO_default_xsputn handle the general case. */ + if (to_do) + to_do -= _IO_default_xsputn (f, s+do_write, to_do); + } + return n - to_do; +} +libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn) + +_IO_size_t +_IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +{ + _IO_size_t want, have; + _IO_ssize_t count; + char *s = data; + + want = n; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + } + + while (want > 0) + { + have = fp->_IO_read_end - fp->_IO_read_ptr; + if (want <= have) + { + memcpy (s, fp->_IO_read_ptr, want); + fp->_IO_read_ptr += want; + want = 0; + } + else + { + if (have > 0) + { +#ifdef _LIBC + s = __mempcpy (s, fp->_IO_read_ptr, have); +#else + memcpy (s, fp->_IO_read_ptr, have); + s += have; +#endif + want -= have; + fp->_IO_read_ptr += have; + } + + /* Check for backup and repeat */ + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + continue; + } + + /* If we now want less than a buffer, underflow and repeat + the copy. Otherwise, _IO_SYSREAD directly to + the user buffer. */ + if (fp->_IO_buf_base + && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base)) + { + if (__underflow (fp) == EOF) + break; + + continue; + } + + /* These must be set before the sysread as we might longjmp out + waiting for input. */ + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + + /* Try to maintain alignment: read a whole number of blocks. */ + count = want; + if (fp->_IO_buf_base) + { + _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; + if (block_size >= 128) + count -= want % block_size; + } + + count = _IO_SYSREAD (fp, s, count); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN; + + break; + } + + s += count; + want -= count; + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + } + } + + return n - want; +} +libc_hidden_def (_IO_file_xsgetn) + +static _IO_size_t +_IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n) +{ + _IO_size_t have; + char *read_ptr = fp->_IO_read_ptr; + char *s = (char *) data; + + have = fp->_IO_read_end - fp->_IO_read_ptr; + + if (have < n) + { + if (__glibc_unlikely (_IO_in_backup (fp))) + { +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif + n -= have; + _IO_switch_to_main_get_area (fp); + read_ptr = fp->_IO_read_ptr; + have = fp->_IO_read_end - fp->_IO_read_ptr; + } + + if (have < n) + { + /* Check that we are mapping all of the file, in case it grew. */ + if (__glibc_unlikely (mmap_remap_check (fp))) + /* We punted mmap, so complete with the vanilla code. */ + return s - (char *) data + _IO_XSGETN (fp, data, n); + + read_ptr = fp->_IO_read_ptr; + have = fp->_IO_read_end - read_ptr; + } + } + + if (have < n) + fp->_flags |= _IO_EOF_SEEN; + + if (have != 0) + { + have = MIN (have, n); +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif + fp->_IO_read_ptr = read_ptr + have; + } + + return s - (char *) data; +} + +static _IO_size_t +_IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n) +{ + /* We only get here if this is the first attempt to read something. + Decide which operations to use and then punt to the chosen one. */ + + decide_maybe_mmap (fp); + return _IO_XSGETN (fp, data, n); +} + +#ifdef _LIBC +versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1); +versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1); +#endif + +const struct _IO_jump_t _IO_file_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), + JUMP_INIT(underflow, _IO_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_file_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; +libc_hidden_data_def (_IO_file_jumps) + +const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), + JUMP_INIT(underflow, _IO_file_underflow_mmap), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap), + JUMP_INIT(seekoff, _IO_file_seekoff_mmap), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), + JUMP_INIT(sync, _IO_file_sync_mmap), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close_mmap), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), + JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap), + JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/REORG.TODO/libio/fmemopen.c b/REORG.TODO/libio/fmemopen.c new file mode 100644 index 0000000000..0b45f9c323 --- /dev/null +++ b/REORG.TODO/libio/fmemopen.c @@ -0,0 +1,227 @@ +/* fmemopen implementation. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* fmemopen() from 2.22 and forward works as defined by POSIX. It also + provides an older symbol, version 2.2.5, that behaves different regarding + SEEK_END (libio/oldfmemopen.c). */ + + +#include <errno.h> +#include <libio.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/types.h> +#include "libioP.h" + + +typedef struct fmemopen_cookie_struct fmemopen_cookie_t; +struct fmemopen_cookie_struct +{ + char *buffer; /* memory buffer. */ + int mybuffer; /* allocated my buffer? */ + int append; /* buffer open for append? */ + size_t size; /* buffer length in bytes. */ + _IO_off64_t pos; /* current position at the buffer. */ + size_t maxpos; /* max position in buffer. */ +}; + + +static ssize_t +fmemopen_read (void *cookie, char *b, size_t s) +{ + fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie; + + if (c->pos + s > c->maxpos) + { + s = c->maxpos - c->pos; + if ((size_t) c->pos > c->maxpos) + s = 0; + } + + memcpy (b, &(c->buffer[c->pos]), s); + + c->pos += s; + + return s; +} + + +static ssize_t +fmemopen_write (void *cookie, const char *b, size_t s) +{ + fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie;; + _IO_off64_t pos = c->append ? c->maxpos : c->pos; + int addnullc = (s == 0 || b[s - 1] != '\0'); + + if (pos + s > c->size) + { + if ((size_t) (c->pos + addnullc) >= c->size) + { + __set_errno (ENOSPC); + return 0; + } + s = c->size - pos; + } + + memcpy (&(c->buffer[pos]), b, s); + + c->pos = pos + s; + if ((size_t) c->pos > c->maxpos) + { + c->maxpos = c->pos; + if (c->maxpos < c->size && addnullc) + c->buffer[c->maxpos] = '\0'; + /* A null byte is written in a stream open for update iff it fits. */ + else if (c->append == 0 && addnullc != 0) + c->buffer[c->size-1] = '\0'; + } + + return s; +} + + +static int +fmemopen_seek (void *cookie, _IO_off64_t *p, int w) +{ + _IO_off64_t np; + fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie; + + switch (w) + { + case SEEK_SET: + np = *p; + break; + + case SEEK_CUR: + np = c->pos + *p; + break; + + case SEEK_END: + np = c->maxpos + *p; + break; + + default: + return -1; + } + + if (np < 0 || (size_t) np > c->size) + { + __set_errno (EINVAL); + return -1; + } + + *p = c->pos = np; + + return 0; +} + + +static int +fmemopen_close (void *cookie) +{ + fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie; + + if (c->mybuffer) + free (c->buffer); + free (c); + + return 0; +} + + +FILE * +__fmemopen (void *buf, size_t len, const char *mode) +{ + cookie_io_functions_t iof; + fmemopen_cookie_t *c; + FILE *result; + + c = (fmemopen_cookie_t *) calloc (sizeof (fmemopen_cookie_t), 1); + if (c == NULL) + return NULL; + + c->mybuffer = (buf == NULL); + + if (c->mybuffer) + { + c->buffer = (char *) malloc (len); + if (c->buffer == NULL) + { + free (c); + return NULL; + } + c->buffer[0] = '\0'; + } + else + { + if (__glibc_unlikely ((uintptr_t) len > -(uintptr_t) buf)) + { + free (c); + __set_errno (EINVAL); + return NULL; + } + + c->buffer = buf; + + /* POSIX states that w+ mode should truncate the buffer. */ + if (mode[0] == 'w' && mode[1] == '+') + c->buffer[0] = '\0'; + + if (mode[0] == 'a') + c->maxpos = strnlen (c->buffer, len); + } + + + /* Mode | starting position (cookie::pos) | size (cookie::size) + ------ |----------------------------------|----------------------------- + read | beginning of the buffer | size argument + write | beginning of the buffer | zero + append | first null or size buffer + 1 | first null or size argument + */ + + c->size = len; + + if (mode[0] == 'r') + c->maxpos = len; + + c->append = mode[0] == 'a'; + if (c->append) + c->pos = c->maxpos; + else + c->pos = 0; + + iof.read = fmemopen_read; + iof.write = fmemopen_write; + iof.seek = fmemopen_seek; + iof.close = fmemopen_close; + + result = _IO_fopencookie (c, mode, iof); + if (__glibc_unlikely (result == NULL)) + { + if (c->mybuffer) + free (c->buffer); + + free (c); + } + + return result; +} +libc_hidden_def (__fmemopen) +versioned_symbol (libc, __fmemopen, fmemopen, GLIBC_2_22); diff --git a/REORG.TODO/libio/fputc.c b/REORG.TODO/libio/fputc.c new file mode 100644 index 0000000000..a7cd682fe2 --- /dev/null +++ b/REORG.TODO/libio/fputc.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +fputc (int c, _IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + result = _IO_putc_unlocked (c, fp); + _IO_release_lock (fp); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef fputc_unlocked +weak_alias (fputc, fputc_unlocked) +#endif diff --git a/REORG.TODO/libio/fputc_u.c b/REORG.TODO/libio/fputc_u.c new file mode 100644 index 0000000000..c07321da3d --- /dev/null +++ b/REORG.TODO/libio/fputc_u.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef fputc_unlocked + +int +fputc_unlocked (int c, _IO_FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/REORG.TODO/libio/fputwc.c b/REORG.TODO/libio/fputwc.c new file mode 100644 index 0000000000..b84b51d9ef --- /dev/null +++ b/REORG.TODO/libio/fputwc.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +fputwc (wchar_t wc, _IO_FILE *fp) +{ + wint_t result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_fwide (fp, 1) < 0) + result = WEOF; + else + result = _IO_putwc_unlocked (wc, fp); + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/fputwc_u.c b/REORG.TODO/libio/fputwc_u.c new file mode 100644 index 0000000000..b5b159357c --- /dev/null +++ b/REORG.TODO/libio/fputwc_u.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +#undef fputwc_unlocked + +wint_t +fputwc_unlocked (wchar_t wc, _IO_FILE *fp) +{ + CHECK_FILE (fp, WEOF); + if (_IO_fwide (fp, 1) < 0) + return WEOF; + return _IO_putwc_unlocked (wc, fp); +} diff --git a/REORG.TODO/libio/freopen.c b/REORG.TODO/libio/freopen.c new file mode 100644 index 0000000000..980523af48 --- /dev/null +++ b/REORG.TODO/libio/freopen.c @@ -0,0 +1,109 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#include <shlib-compat.h> +#include <fd_to_filename.h> + +#include <kernel-features.h> + +FILE * +freopen (const char *filename, const char *mode, FILE *fp) +{ + FILE *result; + CHECK_FILE (fp, NULL); + if (!(fp->_flags & _IO_IS_FILEBUF)) + return NULL; + _IO_acquire_lock (fp); + int fd = _IO_fileno (fp); + const char *gfilename = (filename == NULL && fd >= 0 + ? fd_to_filename (fd) : filename); + fp->_flags2 |= _IO_FLAGS2_NOCLOSE; +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + if (&_IO_stdin_used == NULL) + { + /* If the shared C library is used by the application binary which + was linked against the older version of libio, we just use the + older one even for internal use to avoid trouble since a pointer + to the old libio may be passed into shared C library and wind + up here. */ + _IO_old_file_close_it (fp); + _IO_JUMPS_FILE_plus (fp) = &_IO_old_file_jumps; + result = _IO_old_file_fopen (fp, gfilename, mode); + } + else +#endif + { + _IO_file_close_it (fp); + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; + if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL) + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + result = _IO_file_fopen (fp, gfilename, mode, 1); + if (result != NULL) + result = __fopen_maybe_mmap (result); + } + fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE; + if (result != NULL) + { + /* unbound stream orientation */ + result->_mode = 0; + + if (fd != -1 && _IO_fileno (result) != fd) + { + /* At this point we have both file descriptors already allocated, + so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But + we still need to check for EINVAL and, due Linux internal + implementation, EBUSY. It is because on how it internally opens + the file by splitting the buffer allocation operation and VFS + opening (a dup operation may run when a file is still pending + 'install' on VFS). */ + if (__dup3 (_IO_fileno (result), fd, + (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 + ? O_CLOEXEC : 0) == -1) + { + _IO_file_close_it (result); + result = NULL; + goto end; + } + __close (_IO_fileno (result)); + _IO_fileno (result) = fd; + } + } + else if (fd != -1) + __close (fd); + +end: + if (filename == NULL) + free ((char *) gfilename); + + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/freopen64.c b/REORG.TODO/libio/freopen64.c new file mode 100644 index 0000000000..1e56de616c --- /dev/null +++ b/REORG.TODO/libio/freopen64.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#include <fd_to_filename.h> + +#include <kernel-features.h> + +FILE * +freopen64 (const char *filename, const char *mode, FILE *fp) +{ + FILE *result; + CHECK_FILE (fp, NULL); + if (!(fp->_flags & _IO_IS_FILEBUF)) + return NULL; + _IO_acquire_lock (fp); + int fd = _IO_fileno (fp); + const char *gfilename = (filename == NULL && fd >= 0 + ? fd_to_filename (fd) : filename); + fp->_flags2 |= _IO_FLAGS2_NOCLOSE; + _IO_file_close_it (fp); + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; + if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL) + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; + result = _IO_file_fopen (fp, gfilename, mode, 0); + fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE; + if (result != NULL) + result = __fopen_maybe_mmap (result); + if (result != NULL) + { + /* unbound stream orientation */ + result->_mode = 0; + + if (fd != -1 && _IO_fileno (result) != fd) + { + /* At this point we have both file descriptors already allocated, + so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But + we still need to check for EINVAL and, due Linux internal + implementation, EBUSY. It is because on how it internally opens + the file by splitting the buffer allocation operation and VFS + opening (a dup operation may run when a file is still pending + 'install' on VFS). */ + if (__dup3 (_IO_fileno (result), fd, + (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 + ? O_CLOEXEC : 0) == -1) + { + _IO_file_close_it (result); + result = NULL; + goto end; + } + __close (_IO_fileno (result)); + _IO_fileno (result) = fd; + } + } + else if (fd != -1) + __close (fd); + +end: + if (filename == NULL) + free ((char *) gfilename); + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/fseek.c b/REORG.TODO/libio/fseek.c new file mode 100644 index 0000000000..399eb2a07c --- /dev/null +++ b/REORG.TODO/libio/fseek.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +int +fseek (_IO_FILE *fp, long int offset, int whence) +{ + int result; + CHECK_FILE (fp, -1); + _IO_acquire_lock (fp); + result = _IO_fseek (fp, offset, whence); + _IO_release_lock (fp); + return result; +} +libc_hidden_def (fseek) diff --git a/REORG.TODO/libio/fseeko.c b/REORG.TODO/libio/fseeko.c new file mode 100644 index 0000000000..b77d4be18f --- /dev/null +++ b/REORG.TODO/libio/fseeko.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +int +fseeko (_IO_FILE *fp, off_t offset, int whence) +{ + int result; + CHECK_FILE (fp, -1); + _IO_acquire_lock (fp); + result = _IO_fseek (fp, offset, whence); + _IO_release_lock (fp); + return result; +} + +#ifdef __OFF_T_MATCHES_OFF64_T +weak_alias (fseeko, fseeko64) +#endif diff --git a/REORG.TODO/libio/fseeko64.c b/REORG.TODO/libio/fseeko64.c new file mode 100644 index 0000000000..12221d585e --- /dev/null +++ b/REORG.TODO/libio/fseeko64.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <errno.h> +#include "libioP.h" +#include "stdio.h" + +/* fseeko.c defines this as an alias if __OFF_T_MATCHES_OFF64_T. */ +#ifndef __OFF_T_MATCHES_OFF64_T + +int +fseeko64 (_IO_FILE *fp, __off64_t offset, int whence) +{ + int result; + CHECK_FILE (fp, -1); + _IO_acquire_lock (fp); + result = _IO_fseek (fp, offset, whence); + _IO_release_lock (fp); + return result; +} + +#endif diff --git a/REORG.TODO/libio/ftello.c b/REORG.TODO/libio/ftello.c new file mode 100644 index 0000000000..38863e16c3 --- /dev/null +++ b/REORG.TODO/libio/ftello.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <stdio.h> +#include <stdlib.h> +#include <libioP.h> +#include <errno.h> + + +off_t +__ftello (_IO_FILE *fp) +{ + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_release_lock (fp); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + if ((_IO_off64_t) (off_t) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + return -1L; + } + return pos; +} +libc_hidden_def (__ftello) +weak_alias (__ftello, ftello) + +#ifdef __OFF_T_MATCHES_OFF64_T +weak_alias (__ftello, ftello64) +#endif diff --git a/REORG.TODO/libio/ftello64.c b/REORG.TODO/libio/ftello64.c new file mode 100644 index 0000000000..edb10e0880 --- /dev/null +++ b/REORG.TODO/libio/ftello64.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <stdio.h> +#include <stdlib.h> +#include <libioP.h> +#include <errno.h> + +#ifndef __OFF_T_MATCHES_OFF64_T + +off64_t +ftello64 (_IO_FILE *fp) +{ + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_release_lock (fp); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + return pos; +} + +#endif diff --git a/REORG.TODO/libio/fwide.c b/REORG.TODO/libio/fwide.c new file mode 100644 index 0000000000..d725d43fe1 --- /dev/null +++ b/REORG.TODO/libio/fwide.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <stdio.h> +#include <wchar.h> + +int +fwide (_IO_FILE *fp, int mode) +{ + int result; + + /* Normalize the value. */ + mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); + + if (mode == 0 || fp->_mode != 0) + /* The caller simply wants to know about the current orientation + or the orientation already has been determined. */ + return fp->_mode; + + _IO_acquire_lock (fp); + result = _IO_fwide (fp, mode); + _IO_release_lock (fp); + + return result; +} diff --git a/REORG.TODO/libio/fwprintf.c b/REORG.TODO/libio/fwprintf.c new file mode 100644 index 0000000000..cc1b1b1984 --- /dev/null +++ b/REORG.TODO/libio/fwprintf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + + +/* Write formatted output to STREAM from the format string FORMAT. */ +/* VARARGS2 */ +int +__fwprintf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwprintf (stream, format, arg); + va_end (arg); + + return done; +} +ldbl_weak_alias (__fwprintf, fwprintf) diff --git a/REORG.TODO/libio/fwscanf.c b/REORG.TODO/libio/fwscanf.c new file mode 100644 index 0000000000..be84bf88f5 --- /dev/null +++ b/REORG.TODO/libio/fwscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + +/* Read formatted input from STREAM according to the format string FORMAT. */ +/* VARARGS2 */ +int +__fwscanf (FILE *stream, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwscanf (stream, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (__fwscanf, fwscanf) diff --git a/REORG.TODO/libio/genops.c b/REORG.TODO/libio/genops.c new file mode 100644 index 0000000000..a466cfa337 --- /dev/null +++ b/REORG.TODO/libio/genops.c @@ -0,0 +1,1259 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* Generic or default I/O operations. */ + +#include "libioP.h" +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> +#ifdef _LIBC +#include <sched.h> +#endif + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t list_all_lock = _IO_lock_initializer; +#endif + +/* Used to signal modifications to the list of FILE decriptors. */ +static int _IO_list_all_stamp; + + +static _IO_FILE *run_fp; + +#ifdef _IO_MTSAFE_IO +static void +flush_cleanup (void *not_used) +{ + if (run_fp != NULL) + _IO_funlockfile (run_fp); + _IO_lock_unlock (list_all_lock); +} +#endif + +void +_IO_un_link (struct _IO_FILE_plus *fp) +{ + if (fp->file._flags & _IO_LINKED) + { + struct _IO_FILE **f; +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); + run_fp = (_IO_FILE *) fp; + _IO_flockfile ((_IO_FILE *) fp); +#endif + if (_IO_list_all == NULL) + ; + else if (fp == _IO_list_all) + { + _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain; + ++_IO_list_all_stamp; + } + else + for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain) + if (*f == (_IO_FILE *) fp) + { + *f = fp->file._chain; + ++_IO_list_all_stamp; + break; + } + fp->file._flags &= ~_IO_LINKED; +#ifdef _IO_MTSAFE_IO + _IO_funlockfile ((_IO_FILE *) fp); + run_fp = NULL; + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif + } +} +libc_hidden_def (_IO_un_link) + +void +_IO_link_in (struct _IO_FILE_plus *fp) +{ + if ((fp->file._flags & _IO_LINKED) == 0) + { + fp->file._flags |= _IO_LINKED; +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); + run_fp = (_IO_FILE *) fp; + _IO_flockfile ((_IO_FILE *) fp); +#endif + fp->file._chain = (_IO_FILE *) _IO_list_all; + _IO_list_all = fp; + ++_IO_list_all_stamp; +#ifdef _IO_MTSAFE_IO + _IO_funlockfile ((_IO_FILE *) fp); + run_fp = NULL; + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif + } +} +libc_hidden_def (_IO_link_in) + +/* Return minimum _pos markers + Assumes the current get area is the main get area. */ +_IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p); + +_IO_ssize_t +_IO_least_marker (_IO_FILE *fp, char *end_p) +{ + _IO_ssize_t least_so_far = end_p - fp->_IO_read_base; + struct _IO_marker *mark; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + if (mark->_pos < least_so_far) + least_so_far = mark->_pos; + return least_so_far; +} + +/* Switch current get area from backup buffer to (start of) main get area. */ + +void +_IO_switch_to_main_get_area (_IO_FILE *fp) +{ + char *tmp; + fp->_flags &= ~_IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_IO_read_end; + fp->_IO_read_end = fp->_IO_save_end; + fp->_IO_save_end= tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_IO_read_base; + fp->_IO_read_base = fp->_IO_save_base; + fp->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_IO_read_ptr = fp->_IO_read_base; +} + +/* Switch current get area from main get area to (end of) backup area. */ + +void +_IO_switch_to_backup_area (_IO_FILE *fp) +{ + char *tmp; + fp->_flags |= _IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_IO_read_end; + fp->_IO_read_end = fp->_IO_save_end; + fp->_IO_save_end = tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_IO_read_base; + fp->_IO_read_base = fp->_IO_save_base; + fp->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_IO_read_ptr = fp->_IO_read_end; +} + +int +_IO_switch_to_get_mode (_IO_FILE *fp) +{ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_OVERFLOW (fp, EOF) == EOF) + return EOF; + if (_IO_in_backup (fp)) + fp->_IO_read_base = fp->_IO_backup_base; + else + { + fp->_IO_read_base = fp->_IO_buf_base; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + } + fp->_IO_read_ptr = fp->_IO_write_ptr; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + return 0; +} +libc_hidden_def (_IO_switch_to_get_mode) + +void +_IO_free_backup_area (_IO_FILE *fp) +{ + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); /* Just in case. */ + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + fp->_IO_save_end = NULL; + fp->_IO_backup_base = NULL; +} +libc_hidden_def (_IO_free_backup_area) + +#if 0 +int +_IO_switch_to_put_mode (_IO_FILE *fp) +{ + fp->_IO_write_base = fp->_IO_read_ptr; + fp->_IO_write_ptr = fp->_IO_read_ptr; + /* Following is wrong if line- or un-buffered? */ + fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP + ? fp->_IO_read_end : fp->_IO_buf_end); + + fp->_IO_read_ptr = fp->_IO_read_end; + fp->_IO_read_base = fp->_IO_read_end; + + fp->_flags |= _IO_CURRENTLY_PUTTING; + return 0; +} +#endif + +int +__overflow (_IO_FILE *f, int ch) +{ + /* This is a single-byte stream. */ + if (f->_mode == 0) + _IO_fwide (f, -1); + return _IO_OVERFLOW (f, ch); +} +libc_hidden_def (__overflow) + +static int save_for_backup (_IO_FILE *fp, char *end_p) +#ifdef _LIBC + internal_function +#endif + ; + +static int +#ifdef _LIBC +internal_function +#endif +save_for_backup (_IO_FILE *fp, char *end_p) +{ + /* Append [_IO_read_base..end_p] to backup area. */ + _IO_ssize_t least_mark = _IO_least_marker (fp, end_p); + /* needed_size is how much space we need in the backup area. */ + _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; + /* FIXME: Dubious arithmetic if pointers are NULL */ + _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; + _IO_size_t avail; /* Extra space available for future expansion. */ + _IO_ssize_t delta; + struct _IO_marker *mark; + if (needed_size > current_Bsize) + { + char *new_buffer; + avail = 100; + new_buffer = (char *) malloc (avail + needed_size); + if (new_buffer == NULL) + return EOF; /* FIXME */ + if (least_mark < 0) + { +#ifdef _LIBC + __mempcpy (__mempcpy (new_buffer + avail, + fp->_IO_save_end + least_mark, + -least_mark), + fp->_IO_read_base, + end_p - fp->_IO_read_base); +#else + memcpy (new_buffer + avail, + fp->_IO_save_end + least_mark, + -least_mark); + memcpy (new_buffer + avail - least_mark, + fp->_IO_read_base, + end_p - fp->_IO_read_base); +#endif + } + else + memcpy (new_buffer + avail, + fp->_IO_read_base + least_mark, + needed_size); + free (fp->_IO_save_base); + fp->_IO_save_base = new_buffer; + fp->_IO_save_end = new_buffer + avail + needed_size; + } + else + { + avail = current_Bsize - needed_size; + if (least_mark < 0) + { + memmove (fp->_IO_save_base + avail, + fp->_IO_save_end + least_mark, + -least_mark); + memcpy (fp->_IO_save_base + avail - least_mark, + fp->_IO_read_base, + end_p - fp->_IO_read_base); + } + else if (needed_size > 0) + memcpy (fp->_IO_save_base + avail, + fp->_IO_read_base + least_mark, + needed_size); + } + fp->_IO_backup_base = fp->_IO_save_base + avail; + /* Adjust all the streammarkers. */ + delta = end_p - fp->_IO_read_base; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_pos -= delta; + return 0; +} + +int +__underflow (_IO_FILE *fp) +{ +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1) + return EOF; +#endif + + if (fp->_mode == 0) + _IO_fwide (fp, -1); + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_get_mode (fp) == EOF) + return EOF; + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + } + if (_IO_have_markers (fp)) + { + if (save_for_backup (fp, fp->_IO_read_end)) + return EOF; + } + else if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + return _IO_UNDERFLOW (fp); +} +libc_hidden_def (__underflow) + +int +__uflow (_IO_FILE *fp) +{ +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1) + return EOF; +#endif + + if (fp->_mode == 0) + _IO_fwide (fp, -1); + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_get_mode (fp) == EOF) + return EOF; + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr++; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_get_area (fp); + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr++; + } + if (_IO_have_markers (fp)) + { + if (save_for_backup (fp, fp->_IO_read_end)) + return EOF; + } + else if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + return _IO_UFLOW (fp); +} +libc_hidden_def (__uflow) + +void +_IO_setb (_IO_FILE *f, char *b, char *eb, int a) +{ + if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) + free (f->_IO_buf_base); + f->_IO_buf_base = b; + f->_IO_buf_end = eb; + if (a) + f->_flags &= ~_IO_USER_BUF; + else + f->_flags |= _IO_USER_BUF; +} +libc_hidden_def (_IO_setb) + +void +_IO_doallocbuf (_IO_FILE *fp) +{ + if (fp->_IO_buf_base) + return; + if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) + if (_IO_DOALLOCATE (fp) != EOF) + return; + _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0); +} +libc_hidden_def (_IO_doallocbuf) + +int +_IO_default_underflow (_IO_FILE *fp) +{ + return EOF; +} + +int +_IO_default_uflow (_IO_FILE *fp) +{ + int ch = _IO_UNDERFLOW (fp); + if (ch == EOF) + return EOF; + return *(unsigned char *) fp->_IO_read_ptr++; +} +libc_hidden_def (_IO_default_uflow) + +_IO_size_t +_IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +{ + const char *s = (char *) data; + _IO_size_t more = n; + if (more <= 0) + return 0; + for (;;) + { + /* Space available. */ + if (f->_IO_write_ptr < f->_IO_write_end) + { + _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr; + if (count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + } + else if (count) + { + char *p = f->_IO_write_ptr; + _IO_ssize_t i; + for (i = count; --i >= 0; ) + *p++ = *s++; + f->_IO_write_ptr = p; + } + more -= count; + } + if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF) + break; + more--; + } + return n - more; +} +libc_hidden_def (_IO_default_xsputn) + +_IO_size_t +_IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n) +{ + /* FIXME handle putback buffer here! */ + return _IO_XSGETN (fp, data, n); +} +libc_hidden_def (_IO_sgetn) + +_IO_size_t +_IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +{ + _IO_size_t more = n; + char *s = (char*) data; + for (;;) + { + /* Data available. */ + if (fp->_IO_read_ptr < fp->_IO_read_end) + { + _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr; + if (count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + s = __mempcpy (s, fp->_IO_read_ptr, count); +#else + memcpy (s, fp->_IO_read_ptr, count); + s += count; +#endif + fp->_IO_read_ptr += count; + } + else if (count) + { + char *p = fp->_IO_read_ptr; + int i = (int) count; + while (--i >= 0) + *s++ = *p++; + fp->_IO_read_ptr = p; + } + more -= count; + } + if (more == 0 || __underflow (fp) == EOF) + break; + } + return n - more; +} +libc_hidden_def (_IO_default_xsgetn) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_sync (_IO_FILE *fp) +{ + return 0; +} +#endif + +_IO_FILE * +_IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +{ + if (_IO_SYNC (fp) == EOF) + return NULL; + if (p == NULL || len == 0) + { + fp->_flags |= _IO_UNBUFFERED; + _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0); + } + else + { + fp->_flags &= ~_IO_UNBUFFERED; + _IO_setb (fp, p, p+len, 0); + } + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0; + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0; + return fp; +} + +_IO_off64_t +_IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode) +{ + return _IO_SEEKOFF (fp, pos, 0, mode); +} + +int +_IO_default_doallocate (_IO_FILE *fp) +{ + char *buf; + + buf = malloc(_IO_BUFSIZ); + if (__glibc_unlikely (buf == NULL)) + return EOF; + + _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1); + return 1; +} +libc_hidden_def (_IO_default_doallocate) + +void +_IO_init_internal (_IO_FILE *fp, int flags) +{ + _IO_no_init (fp, flags, -1, NULL, NULL); +} + +void +_IO_init (_IO_FILE *fp, int flags) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_init_internal (fp, flags); +} + +void +_IO_old_init (_IO_FILE *fp, int flags) +{ + fp->_flags = _IO_MAGIC|flags; + fp->_flags2 = 0; + fp->_IO_buf_base = NULL; + fp->_IO_buf_end = NULL; + fp->_IO_read_base = NULL; + fp->_IO_read_ptr = NULL; + fp->_IO_read_end = NULL; + fp->_IO_write_base = NULL; + fp->_IO_write_ptr = NULL; + fp->_IO_write_end = NULL; + fp->_chain = NULL; /* Not necessary. */ + + fp->_IO_save_base = NULL; + fp->_IO_backup_base = NULL; + fp->_IO_save_end = NULL; + fp->_markers = NULL; + fp->_cur_column = 0; +#if _IO_JUMPS_OFFSET + fp->_vtable_offset = 0; +#endif +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_init (*fp->_lock); +#endif +} + +void +_IO_no_init (_IO_FILE *fp, int flags, int orientation, + struct _IO_wide_data *wd, const struct _IO_jump_t *jmp) +{ + _IO_old_init (fp, flags); + fp->_mode = orientation; +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + if (orientation >= 0) + { + fp->_wide_data = wd; + fp->_wide_data->_IO_buf_base = NULL; + fp->_wide_data->_IO_buf_end = NULL; + fp->_wide_data->_IO_read_base = NULL; + fp->_wide_data->_IO_read_ptr = NULL; + fp->_wide_data->_IO_read_end = NULL; + fp->_wide_data->_IO_write_base = NULL; + fp->_wide_data->_IO_write_ptr = NULL; + fp->_wide_data->_IO_write_end = NULL; + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_backup_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + + fp->_wide_data->_wide_vtable = jmp; + } + else + /* Cause predictable crash when a wide function is called on a byte + stream. */ + fp->_wide_data = (struct _IO_wide_data *) -1L; +#endif + fp->_freeres_list = NULL; +} + +int +_IO_default_sync (_IO_FILE *fp) +{ + return 0; +} + +/* The way the C++ classes are mapped into the C functions in the + current implementation, this function can get called twice! */ + +void +_IO_default_finish (_IO_FILE *fp, int dummy) +{ + struct _IO_marker *mark; + if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + { + free (fp->_IO_buf_base); + fp->_IO_buf_base = fp->_IO_buf_end = NULL; + } + + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_sbuf = NULL; + + if (fp->_IO_save_base) + { + free (fp->_IO_save_base); + fp->_IO_save_base = NULL; + } + + _IO_un_link ((struct _IO_FILE_plus *) fp); + +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_fini (*fp->_lock); +#endif +} +libc_hidden_def (_IO_default_finish) + +_IO_off64_t +_IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + return _IO_pos_BAD; +} + +int +_IO_sputbackc (_IO_FILE *fp, int c) +{ + int result; + + if (fp->_IO_read_ptr > fp->_IO_read_base + && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) + { + fp->_IO_read_ptr--; + result = (unsigned char) c; + } + else + result = _IO_PBACKFAIL (fp, c); + + if (result != EOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} +libc_hidden_def (_IO_sputbackc) + +int +_IO_sungetc (_IO_FILE *fp) +{ + int result; + + if (fp->_IO_read_ptr > fp->_IO_read_base) + { + fp->_IO_read_ptr--; + result = (unsigned char) *fp->_IO_read_ptr; + } + else + result = _IO_PBACKFAIL (fp, EOF); + + if (result != EOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + +#if 0 /* Work in progress */ +/* Seems not to be needed. */ +#if 0 +void +_IO_set_column (_IO_FILE *fp, int c) +{ + if (c == -1) + fp->_column = -1; + else + fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base); +} +#else +int +_IO_set_column (_IO_FILE *fp, int i) +{ + fp->_cur_column = i + 1; + return 0; +} +#endif +#endif + + +unsigned +_IO_adjust_column (unsigned start, const char *line, int count) +{ + const char *ptr = line + count; + while (ptr > line) + if (*--ptr == '\n') + return line + count - ptr - 1; + return start + count; +} +libc_hidden_def (_IO_adjust_column) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_get_column (_IO_FILE *fp) +{ + if (fp->_cur_column) + return _IO_adjust_column (fp->_cur_column - 1, + fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base); + return -1; +} +#endif + + +int +_IO_flush_all_lockp (int do_lock) +{ + int result = 0; + struct _IO_FILE *fp; + int last_stamp; + +#ifdef _IO_MTSAFE_IO + __libc_cleanup_region_start (do_lock, flush_cleanup, NULL); + if (do_lock) + _IO_lock_lock (list_all_lock); +#endif + + last_stamp = _IO_list_all_stamp; + fp = (_IO_FILE *) _IO_list_all; + while (fp != NULL) + { + run_fp = fp; + if (do_lock) + _IO_flockfile (fp); + + if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base) +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + || (_IO_vtable_offset (fp) == 0 + && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base)) +#endif + ) + && _IO_OVERFLOW (fp, EOF) == EOF) + result = EOF; + + if (do_lock) + _IO_funlockfile (fp); + run_fp = NULL; + + if (last_stamp != _IO_list_all_stamp) + { + /* Something was added to the list. Start all over again. */ + fp = (_IO_FILE *) _IO_list_all; + last_stamp = _IO_list_all_stamp; + } + else + fp = fp->_chain; + } + +#ifdef _IO_MTSAFE_IO + if (do_lock) + _IO_lock_unlock (list_all_lock); + __libc_cleanup_region_end (0); +#endif + + return result; +} + + +int +_IO_flush_all (void) +{ + /* We want locking. */ + return _IO_flush_all_lockp (1); +} +libc_hidden_def (_IO_flush_all) + +void +_IO_flush_all_linebuffered (void) +{ + struct _IO_FILE *fp; + int last_stamp; + +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); +#endif + + last_stamp = _IO_list_all_stamp; + fp = (_IO_FILE *) _IO_list_all; + while (fp != NULL) + { + run_fp = fp; + _IO_flockfile (fp); + + if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF) + _IO_OVERFLOW (fp, EOF); + + _IO_funlockfile (fp); + run_fp = NULL; + + if (last_stamp != _IO_list_all_stamp) + { + /* Something was added to the list. Start all over again. */ + fp = (_IO_FILE *) _IO_list_all; + last_stamp = _IO_list_all_stamp; + } + else + fp = fp->_chain; + } + +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif +} +libc_hidden_def (_IO_flush_all_linebuffered) +#ifdef _LIBC +weak_alias (_IO_flush_all_linebuffered, _flushlbf) +#endif + + +/* The following is a bit tricky. In general, we want to unbuffer the + streams so that all output which follows is seen. If we are not + looking for memory leaks it does not make much sense to free the + actual buffer because this will happen anyway once the program + terminated. If we do want to look for memory leaks we have to free + the buffers. Whether something is freed is determined by the + function sin the libc_freeres section. Those are called as part of + the atexit routine, just like _IO_cleanup. The problem is we do + not know whether the freeres code is called first or _IO_cleanup. + if the former is the case, we set the DEALLOC_BUFFER variable to + true and _IO_unbuffer_all will take care of the rest. If + _IO_unbuffer_all is called first we add the streams to a list + which the freeres function later can walk through. */ +static void _IO_unbuffer_all (void); + +static bool dealloc_buffers; +static _IO_FILE *freeres_list; + +static void +_IO_unbuffer_all (void) +{ + struct _IO_FILE *fp; + for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain) + { + if (! (fp->_flags & _IO_UNBUFFERED) + /* Iff stream is un-orientated, it wasn't used. */ + && fp->_mode != 0) + { +#ifdef _IO_MTSAFE_IO + int cnt; +#define MAXTRIES 2 + for (cnt = 0; cnt < MAXTRIES; ++cnt) + if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0) + break; + else + /* Give the other thread time to finish up its use of the + stream. */ + __sched_yield (); +#endif + + if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) + { + fp->_flags |= _IO_USER_BUF; + + fp->_freeres_list = freeres_list; + freeres_list = fp; + fp->_freeres_buf = fp->_IO_buf_base; + } + + _IO_SETBUF (fp, NULL, 0); + + if (fp->_mode > 0) + _IO_wsetb (fp, NULL, NULL, 0); + +#ifdef _IO_MTSAFE_IO + if (cnt < MAXTRIES && fp->_lock != NULL) + _IO_lock_unlock (*fp->_lock); +#endif + } + + /* Make sure that never again the wide char functions can be + used. */ + fp->_mode = -1; + } +} + + +libc_freeres_fn (buffer_free) +{ + dealloc_buffers = true; + + while (freeres_list != NULL) + { + free (freeres_list->_freeres_buf); + + freeres_list = freeres_list->_freeres_list; + } +} + + +int +_IO_cleanup (void) +{ + /* We do *not* want locking. Some threads might use streams but + that is their problem, we flush them underneath them. */ + int result = _IO_flush_all_lockp (0); + + /* We currently don't have a reliable mechanism for making sure that + C++ static destructors are executed in the correct order. + So it is possible that other static destructors might want to + write to cout - and they're supposed to be able to do so. + + The following will make the standard streambufs be unbuffered, + which forces any output from late destructors to be written out. */ + _IO_unbuffer_all (); + + return result; +} + + +void +_IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp) +{ + marker->_sbuf = fp; + if (_IO_in_put_mode (fp)) + _IO_switch_to_get_mode (fp); + if (_IO_in_backup (fp)) + marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end; + else + marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base; + + /* Should perhaps sort the chain? */ + marker->_next = fp->_markers; + fp->_markers = marker; +} + +void +_IO_remove_marker (struct _IO_marker *marker) +{ + /* Unlink from sb's chain. */ + struct _IO_marker **ptr = &marker->_sbuf->_markers; + for (; ; ptr = &(*ptr)->_next) + { + if (*ptr == NULL) + break; + else if (*ptr == marker) + { + *ptr = marker->_next; + return; + } + } +#if 0 + if _sbuf has a backup area that is no longer needed, should we delete + it now, or wait until the next underflow? +#endif +} + +#define BAD_DELTA EOF + +int +_IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2) +{ + return mark1->_pos - mark2->_pos; +} + +/* Return difference between MARK and current position of MARK's stream. */ +int +_IO_marker_delta (struct _IO_marker *mark) +{ + int cur_pos; + if (mark->_sbuf == NULL) + return BAD_DELTA; + if (_IO_in_backup (mark->_sbuf)) + cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end; + else + cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base; + return mark->_pos - cur_pos; +} + +int +_IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) +{ + if (mark->_sbuf != fp) + return EOF; + if (mark->_pos >= 0) + { + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); + fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos; + } + else + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos; + } + return 0; +} + +void +_IO_unsave_markers (_IO_FILE *fp) +{ + struct _IO_marker *mark = fp->_markers; + if (mark) + { +#ifdef TODO + streampos offset = seekoff (0, ios::cur, ios::in); + if (offset != EOF) + { + offset += eGptr () - Gbase (); + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (mark->_pos + offset); + } + else + { + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (EOF); + } +#endif + fp->_markers = 0; + } + + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); +} +libc_hidden_def (_IO_unsave_markers) + +#if 0 +/* Seems not to be needed. --drepper */ +int +_IO_nobackup_pbackfail (_IO_FILE *fp, int c) +{ + if (fp->_IO_read_ptr > fp->_IO_read_base) + fp->_IO_read_ptr--; + if (c != EOF && *fp->_IO_read_ptr != c) + *fp->_IO_read_ptr = c; + return (unsigned char) c; +} +#endif + +int +_IO_default_pbackfail (_IO_FILE *fp, int c) +{ + if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) + && (unsigned char) fp->_IO_read_ptr[-1] == c) + --fp->_IO_read_ptr; + else + { + /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ + if (!_IO_in_backup (fp)) + { + /* We need to keep the invariant that the main get area + logically follows the backup area. */ + if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp)) + { + if (save_for_backup (fp, fp->_IO_read_ptr)) + return EOF; + } + else if (!_IO_have_backup (fp)) + { + /* No backup buffer: allocate one. */ + /* Use nshort buffer, if unused? (probably not) FIXME */ + int backup_size = 128; + char *bbuf = (char *) malloc (backup_size); + if (bbuf == NULL) + return EOF; + fp->_IO_save_base = bbuf; + fp->_IO_save_end = fp->_IO_save_base + backup_size; + fp->_IO_backup_base = fp->_IO_save_end; + } + fp->_IO_read_base = fp->_IO_read_ptr; + _IO_switch_to_backup_area (fp); + } + else if (fp->_IO_read_ptr <= fp->_IO_read_base) + { + /* Increase size of existing backup buffer. */ + _IO_size_t new_size; + _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; + char *new_buf; + new_size = 2 * old_size; + new_buf = (char *) malloc (new_size); + if (new_buf == NULL) + return EOF; + memcpy (new_buf + (new_size - old_size), fp->_IO_read_base, + old_size); + free (fp->_IO_read_base); + _IO_setg (fp, new_buf, new_buf + (new_size - old_size), + new_buf + new_size); + fp->_IO_backup_base = fp->_IO_read_ptr; + } + + *--fp->_IO_read_ptr = c; + } + return (unsigned char) c; +} +libc_hidden_def (_IO_default_pbackfail) + +_IO_off64_t +_IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +{ + return _IO_pos_BAD; +} + +int +_IO_default_stat (_IO_FILE *fp, void *st) +{ + return EOF; +} + +_IO_ssize_t +_IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n) +{ + return -1; +} + +_IO_ssize_t +_IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n) +{ + return 0; +} + +int +_IO_default_showmanyc (_IO_FILE *fp) +{ + return -1; +} + +void +_IO_default_imbue (_IO_FILE *fp, void *locale) +{ +} + +_IO_ITER +_IO_iter_begin (void) +{ + return (_IO_ITER) _IO_list_all; +} +libc_hidden_def (_IO_iter_begin) + +_IO_ITER +_IO_iter_end (void) +{ + return NULL; +} +libc_hidden_def (_IO_iter_end) + +_IO_ITER +_IO_iter_next (_IO_ITER iter) +{ + return iter->_chain; +} +libc_hidden_def (_IO_iter_next) + +_IO_FILE * +_IO_iter_file (_IO_ITER iter) +{ + return iter; +} +libc_hidden_def (_IO_iter_file) + +void +_IO_list_lock (void) +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_lock (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_lock) + +void +_IO_list_unlock (void) +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_unlock) + +void +_IO_list_resetlock (void) +{ +#ifdef _IO_MTSAFE_IO + _IO_lock_init (list_all_lock); +#endif +} +libc_hidden_def (_IO_list_resetlock) + + +#ifdef TODO +#if defined(linux) +#define IO_CLEANUP ; +#endif + +#ifdef IO_CLEANUP + IO_CLEANUP +#else +struct __io_defs { + __io_defs() { } + ~__io_defs() { _IO_cleanup (); } +}; +__io_defs io_defs__; +#endif + +#endif /* TODO */ + +#ifdef text_set_element +text_set_element(__libc_atexit, _IO_cleanup); +#endif diff --git a/REORG.TODO/libio/getc.c b/REORG.TODO/libio/getc.c new file mode 100644 index 0000000000..b58fd62308 --- /dev/null +++ b/REORG.TODO/libio/getc.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_getc + +int +_IO_getc (FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + result = _IO_getc_unlocked (fp); + _IO_release_lock (fp); + return result; +} + +#undef getc + +#ifdef weak_alias +weak_alias (_IO_getc, getc) +weak_alias (_IO_getc, fgetc) + +#ifndef _IO_MTSAFE_IO +#undef getc_unlocked +weak_alias (_IO_getc, getc_unlocked) +weak_alias (_IO_getc, fgetc_unlocked) +#endif +#endif diff --git a/REORG.TODO/libio/getc_u.c b/REORG.TODO/libio/getc_u.c new file mode 100644 index 0000000000..b1a2861e42 --- /dev/null +++ b/REORG.TODO/libio/getc_u.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +#undef getc_unlocked + +int +__getc_unlocked (FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_getc_unlocked (fp); +} + +weak_alias (__getc_unlocked, getc_unlocked) +weak_alias (__getc_unlocked, fgetc_unlocked) diff --git a/REORG.TODO/libio/getchar.c b/REORG.TODO/libio/getchar.c new file mode 100644 index 0000000000..5b41595d17 --- /dev/null +++ b/REORG.TODO/libio/getchar.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getchar + +int +getchar (void) +{ + int result; + _IO_acquire_lock (_IO_stdin); + result = _IO_getc_unlocked (_IO_stdin); + _IO_release_lock (_IO_stdin); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef getchar_unlocked +weak_alias (getchar, getchar_unlocked) +#endif diff --git a/REORG.TODO/libio/getchar_u.c b/REORG.TODO/libio/getchar_u.c new file mode 100644 index 0000000000..5ac5bfc097 --- /dev/null +++ b/REORG.TODO/libio/getchar_u.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef getchar_unlocked + +int +getchar_unlocked (void) +{ + return _IO_getc_unlocked (_IO_stdin); +} diff --git a/REORG.TODO/libio/getwc.c b/REORG.TODO/libio/getwc.c new file mode 100644 index 0000000000..9959aab2f0 --- /dev/null +++ b/REORG.TODO/libio/getwc.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> +#include <wchar.h> + +#undef _IO_getwc + +wint_t +_IO_getwc (FILE *fp) +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_acquire_lock (fp); + result = _IO_getwc_unlocked (fp); + _IO_release_lock (fp); + return result; +} + +#undef getwc + +#ifdef weak_alias +weak_alias (_IO_getwc, getwc) +weak_alias (_IO_getwc, fgetwc) +#endif diff --git a/REORG.TODO/libio/getwc_u.c b/REORG.TODO/libio/getwc_u.c new file mode 100644 index 0000000000..44d8a5e8fa --- /dev/null +++ b/REORG.TODO/libio/getwc_u.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +#undef getwc_unlocked + +wint_t +__getwc_unlocked (FILE *fp) +{ + CHECK_FILE (fp, WEOF); + return _IO_getwc_unlocked (fp); +} + +weak_alias (__getwc_unlocked, getwc_unlocked) +weak_alias (__getwc_unlocked, fgetwc_unlocked) diff --git a/REORG.TODO/libio/getwchar.c b/REORG.TODO/libio/getwchar.c new file mode 100644 index 0000000000..8de4609350 --- /dev/null +++ b/REORG.TODO/libio/getwchar.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +#undef getwchar + +wint_t +getwchar (void) +{ + wint_t result; + _IO_acquire_lock (_IO_stdin); + result = _IO_getwc_unlocked (_IO_stdin); + _IO_release_lock (_IO_stdin); + return result; +} diff --git a/REORG.TODO/libio/getwchar_u.c b/REORG.TODO/libio/getwchar_u.c new file mode 100644 index 0000000000..7859cd3be0 --- /dev/null +++ b/REORG.TODO/libio/getwchar_u.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +#undef getwchar_unlocked + +wint_t +getwchar_unlocked (void) +{ + return _IO_getwc_unlocked (_IO_stdin); +} diff --git a/REORG.TODO/libio/iofclose.c b/REORG.TODO/libio/iofclose.c new file mode 100644 index 0000000000..9c51c4efd2 --- /dev/null +++ b/REORG.TODO/libio/iofclose.c @@ -0,0 +1,94 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdlib.h> +#if _LIBC +# include "../iconv/gconv_int.h" +# include <shlib-compat.h> +#else +# define SHLIB_COMPAT(a, b, c) 0 +# define _IO_new_fclose fclose +#endif + +int +_IO_new_fclose (_IO_FILE *fp) +{ + int status; + + CHECK_FILE(fp, EOF); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + /* We desperately try to help programs which are using streams in a + strange way and mix old and new functions. Detect old streams + here. */ + if (_IO_vtable_offset (fp) != 0) + return _IO_old_fclose (fp); +#endif + + /* First unlink the stream. */ + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + _IO_un_link ((struct _IO_FILE_plus *) fp); + + _IO_acquire_lock (fp); + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + status = _IO_file_close_it (fp); + else + status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; + _IO_release_lock (fp); + _IO_FINISH (fp); + if (fp->_mode > 0) + { +#if _LIBC + /* This stream has a wide orientation. This means we have to free + the conversion functions. */ + struct _IO_codecvt *cc = fp->_codecvt; + + __libc_lock_lock (__gconv_lock); + __gconv_release_step (cc->__cd_in.__cd.__steps); + __gconv_release_step (cc->__cd_out.__cd.__steps); + __libc_lock_unlock (__gconv_lock); +#endif + } + else + { + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + } + if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) + { + fp->_IO_file_flags = 0; + free(fp); + } + + return status; +} + +#ifdef _LIBC +versioned_symbol (libc, _IO_new_fclose, _IO_fclose, GLIBC_2_1); +strong_alias (_IO_new_fclose, __new_fclose) +versioned_symbol (libc, __new_fclose, fclose, GLIBC_2_1); +#endif diff --git a/REORG.TODO/libio/iofdopen.c b/REORG.TODO/libio/iofdopen.c new file mode 100644 index 0000000000..2a1df4680a --- /dev/null +++ b/REORG.TODO/libio/iofdopen.c @@ -0,0 +1,187 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <stdlib.h> +#include "libioP.h" +#include <fcntl.h> + +#ifdef _LIBC +# include <shlib-compat.h> +#endif + +#ifndef _IO_fcntl +#ifdef _LIBC +#define _IO_fcntl __fcntl +#else +#define _IO_fcntl fcntl +#endif +#endif + +_IO_FILE * +_IO_new_fdopen (int fd, const char *mode) +{ + int read_write; + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + int i; + int use_mmap = 0; + + /* Decide whether we modify the offset of the file we attach to and seek to + the end of file. We only do this if the mode is 'a' and if the file + descriptor did not have O_APPEND in its flags already. */ + bool do_seek = false; + + switch (*mode) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + MAYBE_SET_EINVAL; + return NULL; + } + for (i = 1; i < 5; ++i) + { + switch (*++mode) + { + case '\0': + break; + case '+': + read_write &= _IO_IS_APPENDING; + break; + case 'm': + use_mmap = 1; + continue; + case 'x': + case 'b': + default: + /* Ignore */ + continue; + } + break; + } +#ifdef F_GETFL + int fd_flags = _IO_fcntl (fd, F_GETFL); +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + if (fd_flags == -1) + return NULL; + + if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) + || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) + { + MAYBE_SET_EINVAL; + return NULL; + } + + /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b) + [System Application Program Interface (API) Amendment 1: + Realtime Extensions], Rationale B.8.3.3 + Open a Stream on a File Descriptor says: + + Although not explicitly required by POSIX.1, a good + implementation of append ("a") mode would cause the + O_APPEND flag to be set. + + (Historical implementations [such as Solaris2] do a one-time + seek in fdopen.) + + However, we do not turn O_APPEND off if the mode is "w" (even + though that would seem consistent) because that would be more + likely to break historical programs. + */ + if ((read_write & _IO_IS_APPENDING) && !(fd_flags & O_APPEND)) + { + do_seek = true; +#ifdef F_SETFL + if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) +#endif + return NULL; + } +#endif + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, +#ifdef _G_HAVE_MMAP + (use_mmap && (read_write & _IO_NO_WRITES)) + ? &_IO_wfile_jumps_maybe_mmap : +#endif + &_IO_wfile_jumps); + _IO_JUMPS (&new_f->fp) = +#ifdef _G_HAVE_MMAP + (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap : +#endif + &_IO_file_jumps; + _IO_new_file_init_internal (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + /* We only need to record the fd because _IO_file_init_internal will + have unset the offset. It is important to unset the cached + offset because the real offset in the file could change between + now and when the handle is activated and we would then mislead + ftell into believing that we have a valid offset. */ + new_f->fp.file._fileno = fd; + new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; + + _IO_mask_flags (&new_f->fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + /* For append mode, set the file offset to the end of the file if we added + O_APPEND to the file descriptor flags. Don't update the offset cache + though, since the file handle is not active. */ + if (do_seek && ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) + == (_IO_IS_APPENDING | _IO_NO_READS))) + { + _IO_off64_t new_pos = _IO_SYSSEEK (&new_f->fp.file, 0, _IO_seek_end); + if (new_pos == _IO_pos_BAD && errno != ESPIPE) + return NULL; + } + return &new_f->fp.file; +} +libc_hidden_ver (_IO_new_fdopen, _IO_fdopen) + +strong_alias (_IO_new_fdopen, __new_fdopen) +versioned_symbol (libc, _IO_new_fdopen, _IO_fdopen, GLIBC_2_1); +versioned_symbol (libc, __new_fdopen, fdopen, GLIBC_2_1); diff --git a/REORG.TODO/libio/iofflush.c b/REORG.TODO/libio/iofflush.c new file mode 100644 index 0000000000..c6b1f15946 --- /dev/null +++ b/REORG.TODO/libio/iofflush.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +int +_IO_fflush (_IO_FILE *fp) +{ + if (fp == NULL) + return _IO_flush_all (); + else + { + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + result = _IO_SYNC (fp) ? EOF : 0; + _IO_release_lock (fp); + return result; + } +} +libc_hidden_def (_IO_fflush) + +#ifdef weak_alias +weak_alias (_IO_fflush, fflush) +libc_hidden_weak (fflush) + +#ifndef _IO_MTSAFE_IO +strong_alias (_IO_fflush, __fflush_unlocked) +libc_hidden_def (__fflush_unlocked) +weak_alias (_IO_fflush, fflush_unlocked) +libc_hidden_weak (fflush_unlocked) +#endif +#endif diff --git a/REORG.TODO/libio/iofflush_u.c b/REORG.TODO/libio/iofflush_u.c new file mode 100644 index 0000000000..a4a3441df0 --- /dev/null +++ b/REORG.TODO/libio/iofflush_u.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +int +__fflush_unlocked (_IO_FILE *fp) +{ + if (fp == NULL) + return _IO_flush_all (); + else + { + CHECK_FILE (fp, EOF); + return _IO_SYNC (fp) ? EOF : 0; + } +} +libc_hidden_def (__fflush_unlocked) +weak_alias (__fflush_unlocked, fflush_unlocked) +libc_hidden_weak (fflush_unlocked) diff --git a/REORG.TODO/libio/iofgetpos.c b/REORG.TODO/libio/iofgetpos.c new file mode 100644 index 0000000000..c1330dee29 --- /dev/null +++ b/REORG.TODO/libio/iofgetpos.c @@ -0,0 +1,94 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* We need to avoid the header declarations of these, because + the types don't match _IO_fgetpos and then the compiler will + complain about the mismatch when we do the alias below. */ +#define _IO_new_fgetpos64 __renamed__IO_new_fgetpos64 +#define _IO_fgetpos64 __renamed__IO_fgetpos64 + +#include "libioP.h" + +#undef _IO_new_fgetpos64 +#undef _IO_fgetpos64 + +#include <errno.h> +#include <stdlib.h> +#include <shlib-compat.h> + +int +_IO_new_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) +{ + _IO_off64_t pos; + int result = 0; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else if ((_IO_off64_t) (__typeof (posp->__pos)) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + result = EOF; + } + else + { + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + } + + _IO_release_lock (fp); + return result; +} + +strong_alias (_IO_new_fgetpos, __new_fgetpos) +versioned_symbol (libc, _IO_new_fgetpos, _IO_fgetpos, GLIBC_2_2); +versioned_symbol (libc, __new_fgetpos, fgetpos, GLIBC_2_2); + +#ifdef __OFF_T_MATCHES_OFF64_T +strong_alias (_IO_new_fgetpos, _IO_new_fgetpos64) +strong_alias (_IO_new_fgetpos64, __new_fgetpos64) +versioned_symbol (libc, _IO_new_fgetpos64, _IO_fgetpos64, GLIBC_2_2); +versioned_symbol (libc, __new_fgetpos64, fgetpos64, GLIBC_2_2); +#endif diff --git a/REORG.TODO/libio/iofgetpos64.c b/REORG.TODO/libio/iofgetpos64.c new file mode 100644 index 0000000000..340dded802 --- /dev/null +++ b/REORG.TODO/libio/iofgetpos64.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <errno.h> +#include <shlib-compat.h> + +#ifndef __OFF_T_MATCHES_OFF64_T + +int +_IO_new_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) +{ + _IO_off64_t pos; + int result = 0; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + { + if (fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +# ifdef EIO + if (errno == 0) + __set_errno (EIO); +# endif + result = EOF; + } + else + { + posp->__pos = pos; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + posp->__state = fp->_wide_data->_IO_state; + } + _IO_release_lock (fp); + return result; +} + +strong_alias (_IO_new_fgetpos64, __new_fgetpos64) +versioned_symbol (libc, _IO_new_fgetpos64, _IO_fgetpos64, GLIBC_2_2); +versioned_symbol (libc, __new_fgetpos64, fgetpos64, GLIBC_2_2); + +#endif diff --git a/REORG.TODO/libio/iofgets.c b/REORG.TODO/libio/iofgets.c new file mode 100644 index 0000000000..8643e7c6cc --- /dev/null +++ b/REORG.TODO/libio/iofgets.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +char * +_IO_fgets (char *buf, int n, _IO_FILE *fp) +{ + _IO_size_t count; + char *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + if (__glibc_unlikely (n == 1)) + { + /* Another irregular case: since we have to store a NUL byte and + there is only room for exactly one byte, we don't have to + read anything. */ + buf[0] = '\0'; + return buf; + } + _IO_acquire_lock (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getline (fp, buf, n - 1, '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_release_lock (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_fgets, fgets) + +# ifndef _IO_MTSAFE_IO +strong_alias (_IO_fgets, __fgets_unlocked) +libc_hidden_def (__fgets_unlocked) +weak_alias (_IO_fgets, fgets_unlocked) +libc_hidden_weak (fgets_unlocked) +# endif +#endif diff --git a/REORG.TODO/libio/iofgets_u.c b/REORG.TODO/libio/iofgets_u.c new file mode 100644 index 0000000000..0aed515ddc --- /dev/null +++ b/REORG.TODO/libio/iofgets_u.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +char * +__fgets_unlocked (char *buf, int n, _IO_FILE *fp) +{ + _IO_size_t count; + char *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + if (__glibc_unlikely (n == 1)) + { + /* Another irregular case: since we have to store a NUL byte and + there is only room for exactly one byte, we don't have to + read anything. */ + buf[0] = '\0'; + return buf; + } + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getline (fp, buf, n - 1, '\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} +libc_hidden_def (__fgets_unlocked) +weak_alias (__fgets_unlocked, fgets_unlocked) +libc_hidden_weak (fgets_unlocked) diff --git a/REORG.TODO/libio/iofgetws.c b/REORG.TODO/libio/iofgetws.c new file mode 100644 index 0000000000..10bd075ffb --- /dev/null +++ b/REORG.TODO/libio/iofgetws.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +wchar_t * +fgetws (wchar_t *buf, int n, _IO_FILE *fp) +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + if (__glibc_unlikely (n == 1)) + { + /* Another irregular case: since we have to store a NUL byte and + there is only room for exactly one byte, we don't have to + read anything. */ + buf[0] = L'\0'; + return buf; + } + _IO_acquire_lock (fp); + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || (_IO_ferror_unlocked (fp) && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/iofgetws_u.c b/REORG.TODO/libio/iofgetws_u.c new file mode 100644 index 0000000000..1b915b7f37 --- /dev/null +++ b/REORG.TODO/libio/iofgetws_u.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +wchar_t * +fgetws_unlocked (wchar_t *buf, int n, _IO_FILE *fp) +{ + _IO_size_t count; + wchar_t *result; + int old_error; + CHECK_FILE (fp, NULL); + if (n <= 0) + return NULL; + if (__glibc_unlikely (n == 1)) + { + /* Another irregular case: since we have to store a NUL byte and + there is only room for exactly one byte, we don't have to + read anything. */ + buf[0] = L'\0'; + return buf; + } + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + old_error = fp->_IO_file_flags & _IO_ERR_SEEN; + fp->_IO_file_flags &= ~_IO_ERR_SEEN; + count = _IO_getwline (fp, buf, n - 1, L'\n', 1); + /* If we read in some bytes and errno is EAGAIN, that error will + be reported for next read. */ + if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) + && errno != EAGAIN)) + result = NULL; + else + { + buf[count] = '\0'; + result = buf; + } + fp->_IO_file_flags |= old_error; + return result; +} diff --git a/REORG.TODO/libio/iofopen.c b/REORG.TODO/libio/iofopen.c new file mode 100644 index 0000000000..3d30dfd94a --- /dev/null +++ b/REORG.TODO/libio/iofopen.c @@ -0,0 +1,109 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <fcntl.h> +#include <stdlib.h> +#include <stddef.h> +#ifdef _LIBC +# include <shlib-compat.h> +#else +# define _IO_new_fopen fopen +#endif + +_IO_FILE * +__fopen_maybe_mmap (_IO_FILE *fp) +{ +#ifdef _G_HAVE_MMAP + if ((fp->_flags2 & _IO_FLAGS2_MMAP) && (fp->_flags & _IO_NO_WRITES)) + { + /* Since this is read-only, we might be able to mmap the contents + directly. We delay the decision until the first read attempt by + giving it a jump table containing functions that choose mmap or + vanilla file operations and reset the jump table accordingly. */ + + if (fp->_mode <= 0) + _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_maybe_mmap; + else + _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_maybe_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap; + } +#endif + return fp; +} + + +_IO_FILE * +__fopen_internal (const char *filename, const char *mode, int is32) +{ + struct locked_FILE + { + struct _IO_FILE_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; +#endif +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); +#else + _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL); +#endif + _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; + _IO_new_file_init_internal (&new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (_IO_file_fopen ((_IO_FILE *) new_f, filename, mode, is32) != NULL) + return __fopen_maybe_mmap (&new_f->fp.file); + + _IO_un_link (&new_f->fp); + free (new_f); + return NULL; +} + +_IO_FILE * +_IO_new_fopen (const char *filename, const char *mode) +{ + return __fopen_internal (filename, mode, 1); +} + +#ifdef _LIBC +strong_alias (_IO_new_fopen, __new_fopen) +versioned_symbol (libc, _IO_new_fopen, _IO_fopen, GLIBC_2_1); +versioned_symbol (libc, __new_fopen, fopen, GLIBC_2_1); + +# if !defined O_LARGEFILE || O_LARGEFILE == 0 +weak_alias (_IO_new_fopen, _IO_fopen64) +weak_alias (_IO_new_fopen, fopen64) +# endif +#endif diff --git a/REORG.TODO/libio/iofopen64.c b/REORG.TODO/libio/iofopen64.c new file mode 100644 index 0000000000..1ec2375990 --- /dev/null +++ b/REORG.TODO/libio/iofopen64.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <fcntl.h> +#include <stdlib.h> + +/* iofopen.c defines _IO_fopen64/fopen64 as aliases if O_LARGEFILE==0. */ +#if !defined _LIBC || (defined O_LARGEFILE && O_LARGEFILE != 0) + +_IO_FILE * +_IO_fopen64 (const char *filename, const char *mode) +{ + return __fopen_internal (filename, mode, 0); +} + +#ifdef weak_alias +weak_alias (_IO_fopen64, fopen64) +#endif + +#endif diff --git a/REORG.TODO/libio/iofopncook.c b/REORG.TODO/libio/iofopncook.c new file mode 100644 index 0000000000..a08dfdaa42 --- /dev/null +++ b/REORG.TODO/libio/iofopncook.c @@ -0,0 +1,292 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <stdio.h> +#include <stdlib.h> +#include <shlib-compat.h> + +/* Prototyped for local functions. */ +static _IO_ssize_t _IO_cookie_read (_IO_FILE* fp, void* buf, + _IO_ssize_t size); +static _IO_ssize_t _IO_cookie_write (_IO_FILE* fp, + const void* buf, _IO_ssize_t size); +static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir); +static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, + int dir, int mode); +static int _IO_cookie_close (_IO_FILE* fp); + +static _IO_ssize_t +_IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size) +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_read_function_t *read_cb = cfile->__io_functions.read; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (read_cb); +#endif + + if (read_cb == NULL) + return -1; + + return read_cb (cfile->__cookie, buf, size); +} + +static _IO_ssize_t +_IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size) +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_write_function_t *write_cb = cfile->__io_functions.write; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (write_cb); +#endif + + if (write_cb == NULL) + { + fp->_flags |= _IO_ERR_SEEN; + return 0; + } + + _IO_ssize_t n = write_cb (cfile->__cookie, buf, size); + if (n < size) + fp->_flags |= _IO_ERR_SEEN; + + return n; +} + +static _IO_off64_t +_IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_seek_function_t *seek_cb = cfile->__io_functions.seek; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (seek_cb); +#endif + + return ((seek_cb == NULL + || (seek_cb (cfile->__cookie, &offset, dir) + == -1) + || offset == (_IO_off64_t) -1) + ? _IO_pos_BAD : offset); +} + +static int +_IO_cookie_close (_IO_FILE *fp) +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_close_function_t *close_cb = cfile->__io_functions.close; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (close_cb); +#endif + + if (close_cb == NULL) + return 0; + + return close_cb (cfile->__cookie); +} + + +static _IO_off64_t +_IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + /* We must force the fileops code to always use seek to determine + the position. */ + fp->_offset = _IO_pos_BAD; + return _IO_file_seekoff (fp, offset, dir, mode); +} + + +static const struct _IO_jump_t _IO_cookie_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), + JUMP_INIT(underflow, _IO_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_cookie_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf), + JUMP_INIT(sync, _IO_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_cookie_read), + JUMP_INIT(write, _IO_cookie_write), + JUMP_INIT(seek, _IO_cookie_seek), + JUMP_INIT(close, _IO_cookie_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue), +}; + + +/* Copy the callbacks from SOURCE to *TARGET, with pointer + mangling. */ +static void +set_callbacks (_IO_cookie_io_functions_t *target, + _IO_cookie_io_functions_t source) +{ +#ifdef PTR_MANGLE + PTR_MANGLE (source.read); + PTR_MANGLE (source.write); + PTR_MANGLE (source.seek); + PTR_MANGLE (source.close); +#endif + *target = source; +} + +void +_IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, + void *cookie, _IO_cookie_io_functions_t io_functions) +{ + _IO_init_internal (&cfile->__fp.file, 0); + _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps; + + cfile->__cookie = cookie; + set_callbacks (&cfile->__io_functions, io_functions); + + _IO_new_file_init_internal (&cfile->__fp); + + _IO_mask_flags (&cfile->__fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + /* We use a negative number different from -1 for _fileno to mark that + this special stream is not associated with a real file, but still has + to be treated as such. */ + cfile->__fp.file._fileno = -2; +} + + +_IO_FILE * +_IO_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions) +{ + int read_write; + struct locked_FILE + { + struct _IO_cookie_file cfile; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + + switch (*mode++) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + __set_errno (EINVAL); + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + read_write &= _IO_IS_APPENDING; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->cfile.__fp.file._lock = &new_f->lock; +#endif + + _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions); + + return (_IO_FILE *) &new_f->cfile.__fp; +} + +versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2); + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) + +static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, + int dir); +_IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions); + +static _IO_off64_t +attribute_compat_text_section +_IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +{ + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + int (*seek_cb) (_IO_FILE *, _IO_off_t, int) + = (int (*) (_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (seek_cb); +#endif + + if (seek_cb == NULL) + return _IO_pos_BAD; + + int ret = seek_cb (cfile->__cookie, offset, dir); + + return (ret == -1) ? _IO_pos_BAD : ret; +} + +static const struct _IO_jump_t _IO_old_cookie_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), + JUMP_INIT(underflow, _IO_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_cookie_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf), + JUMP_INIT(sync, _IO_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_cookie_read), + JUMP_INIT(write, _IO_cookie_write), + JUMP_INIT(seek, _IO_old_cookie_seek), + JUMP_INIT(close, _IO_cookie_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue), +}; + +_IO_FILE * +attribute_compat_text_section +_IO_old_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions) +{ + _IO_FILE *ret; + + ret = _IO_fopencookie (cookie, mode, io_functions); + if (ret != NULL) + _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps; + + return ret; +} + +compat_symbol (libc, _IO_old_fopencookie, fopencookie, GLIBC_2_0); + +#endif diff --git a/REORG.TODO/libio/iofputs.c b/REORG.TODO/libio/iofputs.c new file mode 100644 index 0000000000..379f9b0695 --- /dev/null +++ b/REORG.TODO/libio/iofputs.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <string.h> + +int +_IO_fputs (const char *str, _IO_FILE *fp) +{ + _IO_size_t len = strlen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if ((_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) + && _IO_sputn (fp, str, len) == len) + result = 1; + _IO_release_lock (fp); + return result; +} +libc_hidden_def (_IO_fputs) + +#ifdef weak_alias +weak_alias (_IO_fputs, fputs) + +# ifndef _IO_MTSAFE_IO +strong_alias (_IO_fputs, __fputs_unlocked) +libc_hidden_def (__fputs_unlocked) +weak_alias (_IO_fputs, fputs_unlocked) +libc_hidden_ver (_IO_fputs, fputs_unlocked) +# endif +#endif diff --git a/REORG.TODO/libio/iofputs_u.c b/REORG.TODO/libio/iofputs_u.c new file mode 100644 index 0000000000..dd6dd82a00 --- /dev/null +++ b/REORG.TODO/libio/iofputs_u.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> +#include <string.h> + +int +__fputs_unlocked (const char *str, _IO_FILE *fp) +{ + _IO_size_t len = strlen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, -1) == -1 && _IO_sputn (fp, str, len) == len) + result = 1; + return result; +} +libc_hidden_def (__fputs_unlocked) +weak_alias (__fputs_unlocked, fputs_unlocked) +libc_hidden_weak (fputs_unlocked) diff --git a/REORG.TODO/libio/iofputws.c b/REORG.TODO/libio/iofputws.c new file mode 100644 index 0000000000..848f9c4fd0 --- /dev/null +++ b/REORG.TODO/libio/iofputws.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +int +fputws (const wchar_t *str, _IO_FILE *fp) +{ + _IO_size_t len = __wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/iofputws_u.c b/REORG.TODO/libio/iofputws_u.c new file mode 100644 index 0000000000..e614265141 --- /dev/null +++ b/REORG.TODO/libio/iofputws_u.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> +#include <wchar.h> + +int +fputws_unlocked (const wchar_t *str, _IO_FILE *fp) +{ + _IO_size_t len = __wcslen (str); + int result = EOF; + CHECK_FILE (fp, EOF); + if (_IO_fwide (fp, 1) == 1 + && _IO_sputn (fp, (char *) str, len) == len) + result = 1; + return result; +} +libc_hidden_def (fputws_unlocked) diff --git a/REORG.TODO/libio/iofread.c b/REORG.TODO/libio/iofread.c new file mode 100644 index 0000000000..c6922d3dbf --- /dev/null +++ b/REORG.TODO/libio/iofread.c @@ -0,0 +1,52 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +_IO_size_t +_IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +{ + _IO_size_t bytes_requested = size * count; + _IO_size_t bytes_read; + CHECK_FILE (fp, 0); + if (bytes_requested == 0) + return 0; + _IO_acquire_lock (fp); + bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested); + _IO_release_lock (fp); + return bytes_requested == bytes_read ? count : bytes_read / size; +} +libc_hidden_def (_IO_fread) + +#ifdef weak_alias +weak_alias (_IO_fread, fread) + +# ifndef _IO_MTSAFE_IO +strong_alias (_IO_fread, __fread_unlocked) +libc_hidden_def (__fread_unlocked) +weak_alias (_IO_fread, fread_unlocked) +# endif +#endif diff --git a/REORG.TODO/libio/iofread_u.c b/REORG.TODO/libio/iofread_u.c new file mode 100644 index 0000000000..68d0a0cb7c --- /dev/null +++ b/REORG.TODO/libio/iofread_u.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +#undef fread_unlocked + +_IO_size_t +__fread_unlocked (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +{ + _IO_size_t bytes_requested = size * count; + _IO_size_t bytes_read; + CHECK_FILE (fp, 0); + if (bytes_requested == 0) + return 0; + bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested); + return bytes_requested == bytes_read ? count : bytes_read / size; +} +libc_hidden_def (__fread_unlocked) +weak_alias (__fread_unlocked, fread_unlocked) diff --git a/REORG.TODO/libio/iofsetpos.c b/REORG.TODO/libio/iofsetpos.c new file mode 100644 index 0000000000..3809b6a0b0 --- /dev/null +++ b/REORG.TODO/libio/iofsetpos.c @@ -0,0 +1,79 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* We need to avoid the header declarations of these, because + the types don't match _IO_fsetpos and then the compiler will + complain about the mismatch when we do the alias below. */ +#define _IO_new_fsetpos64 __renamed__IO_new_fsetpos64 +#define _IO_fsetpos64 __renamed__IO_fsetpos64 + +#include <libioP.h> + +#undef _IO_new_fsetpos64 +#undef _IO_fsetpos64 + +#include <errno.h> +#include <shlib-compat.h> + +int +_IO_new_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, restore the state. */ + fp->_wide_data->_IO_state = posp->__state; + } + _IO_release_lock (fp); + return result; +} + +strong_alias (_IO_new_fsetpos, __new_fsetpos) +versioned_symbol (libc, _IO_new_fsetpos, _IO_fsetpos, GLIBC_2_2); +versioned_symbol (libc, __new_fsetpos, fsetpos, GLIBC_2_2); + +#ifdef __OFF_T_MATCHES_OFF64_T +strong_alias (_IO_new_fsetpos, _IO_new_fsetpos64) +strong_alias (_IO_new_fsetpos64, __new_fsetpos64) +versioned_symbol (libc, __new_fsetpos64, fsetpos64, GLIBC_2_2); +versioned_symbol (libc, _IO_new_fsetpos64, _IO_fsetpos64, GLIBC_2_2); +#endif diff --git a/REORG.TODO/libio/iofsetpos64.c b/REORG.TODO/libio/iofsetpos64.c new file mode 100644 index 0000000000..04b4ddf29f --- /dev/null +++ b/REORG.TODO/libio/iofsetpos64.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <errno.h> +#include <shlib-compat.h> + +#ifndef __OFF_T_MATCHES_OFF64_T + +int +_IO_new_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + { + result = 0; + if (fp->_mode > 0 + && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) + /* This is a stateful encoding, safe the state. */ + fp->_wide_data->_IO_state = posp->__state; + } + _IO_release_lock (fp); + return result; +} + +strong_alias (_IO_new_fsetpos64, __new_fsetpos64) +versioned_symbol (libc, __new_fsetpos64, fsetpos64, GLIBC_2_2); +versioned_symbol (libc, _IO_new_fsetpos64, _IO_fsetpos64, GLIBC_2_2); + +#endif diff --git a/REORG.TODO/libio/ioftell.c b/REORG.TODO/libio/ioftell.c new file mode 100644 index 0000000000..21ba5fc6e3 --- /dev/null +++ b/REORG.TODO/libio/ioftell.c @@ -0,0 +1,66 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdlib.h> +#include <errno.h> +/* ANSI explicily requires setting errno to a positive value on failure. */ + +long int +_IO_ftell (_IO_FILE *fp) +{ + _IO_off64_t pos; + CHECK_FILE (fp, -1L); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + { + if (_IO_vtable_offset (fp) != 0 || fp->_mode <= 0) + pos -= fp->_IO_save_end - fp->_IO_save_base; + } + _IO_release_lock (fp); + if (pos == _IO_pos_BAD) + { +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return -1L; + } + if ((_IO_off64_t) (long int) pos != pos) + { +#ifdef EOVERFLOW + __set_errno (EOVERFLOW); +#endif + return -1L; + } + return pos; +} +libc_hidden_def (_IO_ftell) + +#ifdef weak_alias +weak_alias (_IO_ftell, ftell) +#endif diff --git a/REORG.TODO/libio/iofwide.c b/REORG.TODO/libio/iofwide.c new file mode 100644 index 0000000000..76efb32f5d --- /dev/null +++ b/REORG.TODO/libio/iofwide.c @@ -0,0 +1,499 @@ +/* Copyright (C) 1999-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#ifdef _LIBC +# include <dlfcn.h> +# include <wchar.h> +#endif +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#ifdef _LIBC +# include <langinfo.h> +# include <locale/localeinfo.h> +# include <wcsmbs/wcsmbsload.h> +# include <iconv/gconv_int.h> +# include <shlib-compat.h> +# include <sysdep.h> +#endif + + +/* Prototypes of libio's codecvt functions. */ +static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const wchar_t *from_start, + const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, + __mbstate_t *statep, char *to_start, + char *to_end, char **to_stop); +static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, + __mbstate_t *statep, + const char *from_start, + const char *from_end, + const char **from_stop, wchar_t *to_start, + wchar_t *to_end, wchar_t **to_stop); +static int do_encoding (struct _IO_codecvt *codecvt); +static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, + const char *from_end, _IO_size_t max); +static int do_max_length (struct _IO_codecvt *codecvt); +static int do_always_noconv (struct _IO_codecvt *codecvt); + + +/* The functions used in `codecvt' for libio are always the same. */ +const struct _IO_codecvt __libio_codecvt = +{ + .__codecvt_destr = NULL, /* Destructor, never used. */ + .__codecvt_do_out = do_out, + .__codecvt_do_unshift = do_unshift, + .__codecvt_do_in = do_in, + .__codecvt_do_encoding = do_encoding, + .__codecvt_do_always_noconv = do_always_noconv, + .__codecvt_do_length = do_length, + .__codecvt_do_max_length = do_max_length +}; + + +/* Return orientation of stream. If mode is nonzero try to change + the orientation first. */ +#undef _IO_fwide +int +_IO_fwide (_IO_FILE *fp, int mode) +{ + /* Normalize the value. */ + mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); + +#if defined SHARED && defined _LIBC \ + && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + if (__builtin_expect (&_IO_stdin_used == NULL, 0) + && (fp == _IO_stdin || fp == _IO_stdout || fp == _IO_stderr)) + /* This is for a stream in the glibc 2.0 format. */ + return -1; +#endif + + /* The orientation already has been determined. */ + if (fp->_mode != 0 + /* Or the caller simply wants to know about the current orientation. */ + || mode == 0) + return fp->_mode; + + /* Set the orientation appropriately. */ + if (mode > 0) + { + struct _IO_codecvt *cc = fp->_codecvt = &fp->_wide_data->_codecvt; + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; + + /* Get the character conversion functions based on the currently + selected locale for LC_CTYPE. */ +#ifdef _LIBC + { + /* Clear the state. We start all over again. */ + memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); + memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); + + struct gconv_fcts fcts; + __wcsmbs_clone_conv (&fcts); + assert (fcts.towc_nsteps == 1); + assert (fcts.tomb_nsteps == 1); + + /* The functions are always the same. */ + *cc = __libio_codecvt; + + cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; + cc->__cd_in.__cd.__steps = fcts.towc; + + cc->__cd_in.__cd.__data[0].__invocation_counter = 0; + cc->__cd_in.__cd.__data[0].__internal_use = 1; + cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; + cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + + cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; + cc->__cd_out.__cd.__steps = fcts.tomb; + + cc->__cd_out.__cd.__data[0].__invocation_counter = 0; + cc->__cd_out.__cd.__data[0].__internal_use = 1; + cc->__cd_out.__cd.__data[0].__flags + = __GCONV_IS_LAST | __GCONV_TRANSLIT; + cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + { + /* Determine internal and external character sets. + + XXX For now we make our life easy: we assume a fixed internal + encoding (as most sane systems have; hi HP/UX!). If somebody + cares about systems which changing internal charsets they + should come up with a solution for the determination of the + currently used internal character set. */ + const char *internal_ccs = _G_INTERNAL_CCS; + const char *external_ccs = NULL; + +# ifdef HAVE_NL_LANGINFO + external_ccs = nl_langinfo (CODESET); +# endif + if (external_ccs == NULL) + external_ccs = "ISO-8859-1"; + + cc->__cd_in = iconv_open (internal_ccs, external_ccs); + if (cc->__cd_in != (iconv_t) -1) + cc->__cd_out = iconv_open (external_ccs, internal_ccs); + + if (cc->__cd_in == (iconv_t) -1 || cc->__cd_out == (iconv_t) -1) + { + if (cc->__cd_in != (iconv_t) -1) + iconv_close (cc->__cd_in); + /* XXX */ + abort (); + } + } +# else +# error "somehow determine this from LC_CTYPE" +# endif +#endif + + /* From now on use the wide character callback functions. */ + _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable; + } + + /* Set the mode now. */ + fp->_mode = mode; + + return mode; +} + + +static enum __codecvt_result +do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const wchar_t *from_start, const wchar_t *from_end, + const wchar_t **from_stop, char *to_start, char *to_end, + char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t dummy; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + __gconv_fct fct = gs->__fct; +#ifdef PTR_DEMANGLE + if (gs->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + + status = DL_CALL_FCT (fct, + (gs, codecvt->__cd_out.__cd.__data, &from_start_copy, + (const unsigned char *) from_end, NULL, + &dummy, 0, 0)); + + *from_stop = (wchar_t *) from_start_copy; + *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + char *to_start_copy = to_start; + size_t to_len = to_end - to_start; + res = iconv (codecvt->__cd_out, &from_start_copy, &from_len, + &to_start_copy, &to_len); + + if (res == 0 || from_len == 0) + result = __codecvt_ok; + else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; + +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static enum __codecvt_result +do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, + char *to_start, char *to_end, char **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; + int status; + size_t dummy; + + codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start; + codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end; + codecvt->__cd_out.__cd.__data[0].__statep = statep; + + __gconv_fct fct = gs->__fct; +#ifdef PTR_DEMANGLE + if (gs->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + + status = DL_CALL_FCT (fct, + (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, + NULL, &dummy, 1, 0)); + + *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + char *to_start_copy = (char *) to_start; + size_t to_len = to_end - to_start; + + res = iconv (codecvt->__cd_out, NULL, NULL, &to_start_copy, &to_len); + + if (res == 0) + result = __codecvt_ok; + else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static enum __codecvt_result +do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, const char **from_stop, + wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) +{ + enum __codecvt_result result; + +#ifdef _LIBC + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + int status; + size_t dummy; + const unsigned char *from_start_copy = (unsigned char *) from_start; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_start; + codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) to_end; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + __gconv_fct fct = gs->__fct; +#ifdef PTR_DEMANGLE + if (gs->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + + status = DL_CALL_FCT (fct, + (gs, codecvt->__cd_in.__cd.__data, &from_start_copy, + (const unsigned char *) from_end, NULL, + &dummy, 0, 0)); + + *from_stop = (const char *) from_start_copy; + *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf; + + switch (status) + { + case __GCONV_OK: + case __GCONV_EMPTY_INPUT: + result = __codecvt_ok; + break; + + case __GCONV_FULL_OUTPUT: + case __GCONV_INCOMPLETE_INPUT: + result = __codecvt_partial; + break; + + default: + result = __codecvt_error; + break; + } +#else +# ifdef _GLIBCPP_USE_WCHAR_T + size_t res; + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + char *to_start_copy = (char *) from_start; + size_t to_len = to_end - to_start; + + res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, + &to_start_copy, &to_len); + + if (res == 0) + result = __codecvt_ok; + else if (to_len == 0) + result = __codecvt_partial; + else if (from_len < codecvt->__codecvt_do_max_length (codecvt)) + result = __codecvt_partial; + else + result = __codecvt_error; +# else + /* Decide what to do. */ + result = __codecvt_error; +# endif +#endif + + return result; +} + + +static int +do_encoding (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + /* See whether the encoding is stateful. */ + if (codecvt->__cd_in.__cd.__steps[0].__stateful) + return -1; + /* Fortunately not. Now determine the input bytes for the conversion + necessary for each wide character. */ + if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from + != codecvt->__cd_in.__cd.__steps[0].__max_needed_from) + /* Not a constant value. */ + return 0; + + return codecvt->__cd_in.__cd.__steps[0].__min_needed_from; +#else + /* Worst case scenario. */ + return -1; +#endif +} + + +static int +do_always_noconv (struct _IO_codecvt *codecvt) +{ + return 0; +} + + +static int +do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, + const char *from_start, const char *from_end, _IO_size_t max) +{ + int result; +#ifdef _LIBC + const unsigned char *cp = (const unsigned char *) from_start; + wchar_t to_buf[max]; + struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; + size_t dummy; + + codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_buf; + codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) &to_buf[max]; + codecvt->__cd_in.__cd.__data[0].__statep = statep; + + __gconv_fct fct = gs->__fct; +#ifdef PTR_DEMANGLE + if (gs->__shlib_handle != NULL) + PTR_DEMANGLE (fct); +#endif + + DL_CALL_FCT (fct, + (gs, codecvt->__cd_in.__cd.__data, &cp, + (const unsigned char *) from_end, NULL, + &dummy, 0, 0)); + + result = cp - (const unsigned char *) from_start; +#else +# ifdef _GLIBCPP_USE_WCHAR_T + const char *from_start_copy = (const char *) from_start; + size_t from_len = from_end - from_start; + wchar_t to_buf[max]; + size_t res; + char *to_start = (char *) to_buf; + + res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, + &to_start, &max); + + result = from_start_copy - (char *) from_start; +# else + /* Decide what to do. */ + result = 0; +# endif +#endif + + return result; +} + + +static int +do_max_length (struct _IO_codecvt *codecvt) +{ +#ifdef _LIBC + return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; +#else + return MB_CUR_MAX; +#endif +} diff --git a/REORG.TODO/libio/iofwrite.c b/REORG.TODO/libio/iofwrite.c new file mode 100644 index 0000000000..c89dd9091f --- /dev/null +++ b/REORG.TODO/libio/iofwrite.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +_IO_size_t +_IO_fwrite (const void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +{ + _IO_size_t request = size * count; + _IO_size_t written = 0; + CHECK_FILE (fp, 0); + if (request == 0) + return 0; + _IO_acquire_lock (fp); + if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) + written = _IO_sputn (fp, (const char *) buf, request); + _IO_release_lock (fp); + /* We have written all of the input in case the return value indicates + this or EOF is returned. The latter is a special case where we + simply did not manage to flush the buffer. But the data is in the + buffer and therefore written as far as fwrite is concerned. */ + if (written == request || written == EOF) + return count; + else + return written / size; +} +libc_hidden_def (_IO_fwrite) + +#ifdef weak_alias +# include <stdio.h> +weak_alias (_IO_fwrite, fwrite) +libc_hidden_weak (fwrite) +# ifndef _IO_MTSAFE_IO +weak_alias (_IO_fwrite, fwrite_unlocked) +libc_hidden_weak (fwrite_unlocked) +# endif +#endif diff --git a/REORG.TODO/libio/iofwrite_u.c b/REORG.TODO/libio/iofwrite_u.c new file mode 100644 index 0000000000..3cc53ccad5 --- /dev/null +++ b/REORG.TODO/libio/iofwrite_u.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +#undef fwrite_unlocked + +_IO_size_t +fwrite_unlocked (const void *buf, _IO_size_t size, _IO_size_t count, + _IO_FILE *fp) +{ + _IO_size_t request = size * count; + _IO_size_t written = 0; + CHECK_FILE (fp, 0); + if (request == 0) + return 0; + if (_IO_fwide (fp, -1) == -1) + { + written = _IO_sputn (fp, (const char *) buf, request); + /* We have written all of the input in case the return value indicates + this or EOF is returned. The latter is a special case where we + simply did not manage to flush the buffer. But the data is in the + buffer and therefore written as far as fwrite is concerned. */ + if (written == request || written == EOF) + return count; + } + + return written / size; +} +libc_hidden_def (fwrite_unlocked) diff --git a/REORG.TODO/libio/iogetdelim.c b/REORG.TODO/libio/iogetdelim.c new file mode 100644 index 0000000000..59138881b8 --- /dev/null +++ b/REORG.TODO/libio/iogetdelim.c @@ -0,0 +1,129 @@ +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <stdlib.h> +#include "libioP.h" +#include <string.h> +#include <errno.h> +#include <limits.h> + +/* Read up to (and including) a TERMINATOR from FP into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'ed as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. */ + +_IO_ssize_t +_IO_getdelim (char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp) +{ + _IO_ssize_t result; + _IO_ssize_t cur_len = 0; + _IO_ssize_t len; + + if (lineptr == NULL || n == NULL) + { + MAYBE_SET_EINVAL; + return -1; + } + CHECK_FILE (fp, -1); + _IO_acquire_lock (fp); + if (_IO_ferror_unlocked (fp)) + { + result = -1; + goto unlock_return; + } + + if (*lineptr == NULL || *n == 0) + { + *n = 120; + *lineptr = (char *) malloc (*n); + if (*lineptr == NULL) + { + result = -1; + goto unlock_return; + } + } + + len = fp->_IO_read_end - fp->_IO_read_ptr; + if (len <= 0) + { + if (__underflow (fp) == EOF) + { + result = -1; + goto unlock_return; + } + len = fp->_IO_read_end - fp->_IO_read_ptr; + } + + for (;;) + { + _IO_size_t needed; + char *t; + t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len); + if (t != NULL) + len = (t - fp->_IO_read_ptr) + 1; + if (__glibc_unlikely (len >= SSIZE_MAX - cur_len)) + { + __set_errno (EOVERFLOW); + result = -1; + goto unlock_return; + } + /* Make enough space for len+1 (for final NUL) bytes. */ + needed = cur_len + len + 1; + if (needed > *n) + { + char *new_lineptr; + + if (needed < 2 * *n) + needed = 2 * *n; /* Be generous. */ + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = -1; + goto unlock_return; + } + *lineptr = new_lineptr; + *n = needed; + } + memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr += len; + cur_len += len; + if (t != NULL || __underflow (fp) == EOF) + break; + len = fp->_IO_read_end - fp->_IO_read_ptr; + } + (*lineptr)[cur_len] = '\0'; + result = cur_len; + +unlock_return: + _IO_release_lock (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_getdelim, __getdelim) +weak_alias (_IO_getdelim, getdelim) +#endif diff --git a/REORG.TODO/libio/iogetline.c b/REORG.TODO/libio/iogetline.c new file mode 100644 index 0000000000..2a713c6d0c --- /dev/null +++ b/REORG.TODO/libio/iogetline.c @@ -0,0 +1,108 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <string.h> + +_IO_size_t +_IO_getline (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, + int extract_delim) +{ + return _IO_getline_info (fp, buf, n, delim, extract_delim, (int *) 0); +} +libc_hidden_def (_IO_getline) + +/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation. + + Read chars into buf (of size n), until delim is seen. + Return number of chars read (at most n). + Does not put a terminating '\0' in buf. + If extract_delim < 0, leave delimiter unread. + If extract_delim > 0, insert delim in output. */ + +_IO_size_t +_IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, + int extract_delim, int *eof) +{ + char *ptr = buf; + if (eof != NULL) + *eof = 0; + if (__builtin_expect (fp->_mode, -1) == 0) + _IO_fwide (fp, -1); + while (n != 0) + { + _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr; + if (len <= 0) + { + int c = __uflow (fp); + if (c == EOF) + { + if (eof) + *eof = c; + break; + } + if (c == delim) + { + if (extract_delim > 0) + *ptr++ = c; + else if (extract_delim < 0) + _IO_sputbackc (fp, c); + if (extract_delim > 0) + ++len; + return ptr - buf; + } + *ptr++ = c; + n--; + } + else + { + char *t; + if ((_IO_size_t) len >= n) + len = n; + t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len); + if (t != NULL) + { + _IO_size_t old_len = ptr-buf; + len = t - fp->_IO_read_ptr; + if (extract_delim >= 0) + { + ++t; + if (extract_delim > 0) + ++len; + } + memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr = t; + return old_len + len; + } + memcpy ((void *) ptr, (void *) fp->_IO_read_ptr, len); + fp->_IO_read_ptr += len; + ptr += len; + n -= len; + } + } + return ptr - buf; +} +libc_hidden_def (_IO_getline_info) diff --git a/REORG.TODO/libio/iogets.c b/REORG.TODO/libio/iogets.c new file mode 100644 index 0000000000..432cecb75c --- /dev/null +++ b/REORG.TODO/libio/iogets.c @@ -0,0 +1,76 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <limits.h> + +char * +_IO_gets (char *buf) +{ + _IO_size_t count; + int ch; + char *retval; + + _IO_acquire_lock (_IO_stdin); + ch = _IO_getc_unlocked (_IO_stdin); + if (ch == EOF) + { + retval = NULL; + goto unlock_return; + } + if (ch == '\n') + count = 0; + else + { + /* This is very tricky since a file descriptor may be in the + non-blocking mode. The error flag doesn't mean much in this + case. We return an error only when there is a new error. */ + int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN; + _IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN; + buf[0] = (char) ch; + count = _IO_getline (_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1; + if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN) + { + retval = NULL; + goto unlock_return; + } + else + _IO_stdin->_IO_file_flags |= old_error; + } + buf[count] = 0; + retval = buf; +unlock_return: + _IO_release_lock (_IO_stdin); + return retval; +} + +#ifdef weak_alias +weak_alias (_IO_gets, gets) +#endif + +#ifdef _LIBC +link_warning (gets, "the `gets' function is dangerous and should not be used.") +#endif diff --git a/REORG.TODO/libio/iogetwline.c b/REORG.TODO/libio/iogetwline.c new file mode 100644 index 0000000000..e60a590cc4 --- /dev/null +++ b/REORG.TODO/libio/iogetwline.c @@ -0,0 +1,113 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <string.h> +#include <wchar.h> + +#ifdef _LIBC +# define wmemcpy __wmemcpy +#endif + +_IO_size_t +_IO_getwline (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, + int extract_delim) +{ + return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0); +} + +/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation. + + Read chars into buf (of size n), until delim is seen. + Return number of chars read (at most n). + Does not put a terminating '\0' in buf. + If extract_delim < 0, leave delimiter unread. + If extract_delim > 0, insert delim in output. */ + +_IO_size_t +_IO_getwline_info (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, + int extract_delim, wint_t *eof) +{ + wchar_t *ptr = buf; + if (eof != NULL) + *eof = 0; + if (__builtin_expect (fp->_mode, 1) == 0) + _IO_fwide (fp, 1); + while (n != 0) + { + _IO_ssize_t len = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (len <= 0) + { + wint_t wc = __wuflow (fp); + if (wc == WEOF) + { + if (eof) + *eof = wc; + break; + } + if (wc == delim) + { + if (extract_delim > 0) + *ptr++ = wc; + else if (extract_delim < 0) + _IO_sputbackc (fp, wc); + if (extract_delim > 0) + ++len; + return ptr - buf; + } + *ptr++ = wc; + n--; + } + else + { + wchar_t *t; + if ((_IO_size_t) len >= n) + len = n; + t = wmemchr ((void *) fp->_wide_data->_IO_read_ptr, delim, len); + if (t != NULL) + { + _IO_size_t old_len = ptr - buf; + len = t - fp->_wide_data->_IO_read_ptr; + if (extract_delim >= 0) + { + ++t; + if (extract_delim > 0) + ++len; + } + wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, + len); + fp->_wide_data->_IO_read_ptr = t; + return old_len + len; + } + wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len); + fp->_wide_data->_IO_read_ptr += len; + ptr += len; + n -= len; + } + } + return ptr - buf; +} diff --git a/REORG.TODO/libio/iolibio.h b/REORG.TODO/libio/iolibio.h new file mode 100644 index 0000000000..f215fcef01 --- /dev/null +++ b/REORG.TODO/libio/iolibio.h @@ -0,0 +1,95 @@ +#include <libio.h> + +/* These emulate stdio functionality, but with a different name + (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int _IO_fclose (_IO_FILE*); +extern int _IO_new_fclose (_IO_FILE*); +extern int _IO_old_fclose (_IO_FILE*); +extern _IO_FILE *_IO_fdopen (int, const char*) __THROW; +libc_hidden_proto (_IO_fdopen) +extern _IO_FILE *_IO_old_fdopen (int, const char*) __THROW; +extern _IO_FILE *_IO_new_fdopen (int, const char*) __THROW; +extern int _IO_fflush (_IO_FILE*); +libc_hidden_proto (_IO_fflush) +extern int _IO_fgetpos (_IO_FILE*, _IO_fpos_t*); +extern int _IO_fgetpos64 (_IO_FILE*, _IO_fpos64_t*); +extern char* _IO_fgets (char*, int, _IO_FILE*); +extern _IO_FILE *_IO_fopen (const char*, const char*); +extern _IO_FILE *_IO_old_fopen (const char*, const char*); +extern _IO_FILE *_IO_new_fopen (const char*, const char*); +extern _IO_FILE *_IO_fopen64 (const char*, const char*); +extern _IO_FILE *__fopen_internal (const char*, const char*, int); +extern _IO_FILE *__fopen_maybe_mmap (_IO_FILE *) __THROW; +extern int _IO_fprintf (_IO_FILE*, const char*, ...); +extern int _IO_fputs (const char*, _IO_FILE*); +libc_hidden_proto (_IO_fputs) +extern int _IO_fsetpos (_IO_FILE*, const _IO_fpos_t *); +extern int _IO_fsetpos64 (_IO_FILE*, const _IO_fpos64_t *); +extern long int _IO_ftell (_IO_FILE*); +libc_hidden_proto (_IO_ftell) +extern _IO_size_t _IO_fread (void*, _IO_size_t, _IO_size_t, _IO_FILE*); +libc_hidden_proto (_IO_fread) +extern _IO_size_t _IO_fwrite (const void*, _IO_size_t, _IO_size_t, _IO_FILE*); +libc_hidden_proto (_IO_fwrite) +extern char* _IO_gets (char*); +extern void _IO_perror (const char*) __THROW; +extern int _IO_printf (const char*, ...); +extern int _IO_puts (const char*); +extern int _IO_scanf (const char*, ...); +extern void _IO_setbuffer (_IO_FILE *, char*, _IO_size_t) __THROW; +libc_hidden_proto (_IO_setbuffer) +extern int _IO_setvbuf (_IO_FILE*, char*, int, _IO_size_t) __THROW; +libc_hidden_proto (_IO_setvbuf) +extern int _IO_sscanf (const char*, const char*, ...) __THROW; +extern int _IO_sprintf (char *, const char*, ...) __THROW; +extern int _IO_ungetc (int, _IO_FILE*) __THROW; +extern int _IO_vsscanf (const char *, const char *, _IO_va_list) __THROW; +extern int _IO_vsprintf (char*, const char*, _IO_va_list) __THROW; +libc_hidden_proto (_IO_vsprintf) +extern int _IO_vswprintf (wchar_t*, _IO_size_t, const wchar_t*, _IO_va_list) + __THROW; + +struct obstack; +extern int _IO_obstack_vprintf (struct obstack *, const char *, _IO_va_list) + __THROW; +extern int _IO_obstack_printf (struct obstack *, const char *, ...) __THROW; +#ifndef _IO_pos_BAD +#define _IO_pos_BAD ((_IO_off64_t)(-1)) +#endif +#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) +#define _IO_fseek(__fp, __offset, __whence) \ + (_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \ + == _IO_pos_BAD ? EOF : 0) +#define _IO_rewind(FILE) \ + (void) _IO_seekoff_unlocked (FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT) +#define _IO_vprintf(FORMAT, ARGS) \ + _IO_vfprintf (_IO_stdout, FORMAT, ARGS) +#define _IO_freopen(FILENAME, MODE, FP) \ + (_IO_file_close_it (FP), \ + _IO_file_fopen (FP, FILENAME, MODE, 1)) +#define _IO_old_freopen(FILENAME, MODE, FP) \ + (_IO_old_file_close_it (FP), _IO_old_file_fopen(FP, FILENAME, MODE)) +#define _IO_freopen64(FILENAME, MODE, FP) \ + (_IO_file_close_it (FP), \ + _IO_file_fopen (FP, FILENAME, MODE, 0)) +#define _IO_fileno(FP) ((FP)->_fileno) +extern _IO_FILE* _IO_popen (const char*, const char*) __THROW; +extern _IO_FILE* _IO_new_popen (const char*, const char*) __THROW; +extern _IO_FILE* _IO_old_popen (const char*, const char*) __THROW; +extern int __new_pclose (_IO_FILE *) __THROW; +extern int __old_pclose (_IO_FILE *) __THROW; +#define _IO_pclose _IO_fclose +#define _IO_setbuf(_FP, _BUF) _IO_setbuffer (_FP, _BUF, _IO_BUFSIZ) +#define _IO_setlinebuf(_FP) _IO_setvbuf (_FP, NULL, 1, 0) + +_IO_FILE *__new_freopen (const char *, const char *, _IO_FILE *) __THROW; +_IO_FILE *__old_freopen (const char *, const char *, _IO_FILE *) __THROW; + +#ifdef __cplusplus +} +#endif diff --git a/REORG.TODO/libio/iopadn.c b/REORG.TODO/libio/iopadn.c new file mode 100644 index 0000000000..0abe92e20d --- /dev/null +++ b/REORG.TODO/libio/iopadn.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define PADSIZE 16 +static char const blanks[PADSIZE] = +{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; +static char const zeroes[PADSIZE] = +{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + +_IO_ssize_t +_IO_padn (_IO_FILE *fp, int pad, _IO_ssize_t count) +{ + char padbuf[PADSIZE]; + const char *padptr; + int i; + _IO_size_t written = 0; + _IO_size_t w; + + if (pad == ' ') + padptr = blanks; + else if (pad == '0') + padptr = zeroes; + else + { + for (i = PADSIZE; --i >= 0; ) + padbuf[i] = pad; + padptr = padbuf; + } + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = _IO_sputn (fp, padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + + if (i > 0) + { + w = _IO_sputn (fp, padptr, i); + written += w; + } + return written; +} +libc_hidden_def (_IO_padn) diff --git a/REORG.TODO/libio/iopopen.c b/REORG.TODO/libio/iopopen.c new file mode 100644 index 0000000000..b78e7e5ef2 --- /dev/null +++ b/REORG.TODO/libio/iopopen.c @@ -0,0 +1,330 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include <fcntl.h> +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#ifdef _LIBC +# include <shlib-compat.h> +# include <not-cancel.h> +#endif +#include <sys/types.h> +#include <sys/wait.h> +#include <kernel-features.h> + +#ifndef _IO_fork +#ifdef _LIBC +#define _IO_fork __fork +#else +#define _IO_fork fork /* defined in libiberty, if needed */ +#endif +extern _IO_pid_t _IO_fork (void) __THROW; +#endif + +#ifndef _IO_dup2 +#ifdef _LIBC +#define _IO_dup2 __dup2 +#else +#define _IO_dup2 dup2 +#endif +extern int _IO_dup2 (int fd, int fd2) __THROW; +#endif + +#ifndef _IO_waitpid +#ifdef _LIBC +#define _IO_waitpid waitpid_not_cancel +#else +#define _IO_waitpid waitpid +#endif +#endif + +#ifndef _IO_execl +#define _IO_execl execl +#endif +#ifndef _IO__exit +#define _IO__exit _exit +#endif + +#ifndef _IO_close +#ifdef _LIBC +#define _IO_close close_not_cancel +#else +#define _IO_close close +#endif +#endif + +struct _IO_proc_file +{ + struct _IO_FILE_plus file; + /* Following fields must match those in class procbuf (procbuf.h) */ + _IO_pid_t pid; + struct _IO_proc_file *next; +}; +typedef struct _IO_proc_file _IO_proc_file; + +static const struct _IO_jump_t _IO_proc_jumps; + +static struct _IO_proc_file *proc_file_chain; + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer; + +static void +unlock (void *not_used) +{ + _IO_lock_unlock (proc_file_chain_lock); +} +#endif + +_IO_FILE * +_IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) +{ + int read_or_write; + int parent_end, child_end; + int pipe_fds[2]; + _IO_pid_t child_pid; + + int do_read = 0; + int do_write = 0; + int do_cloexec = 0; + while (*mode != '\0') + switch (*mode++) + { + case 'r': + do_read = 1; + break; + case 'w': + do_write = 1; + break; + case 'e': + do_cloexec = 1; + break; + default: + errout: + __set_errno (EINVAL); + return NULL; + } + + if ((do_read ^ do_write) == 0) + goto errout; + + if (_IO_file_is_open (fp)) + return NULL; + + /* Atomically set the O_CLOEXEC flag for the pipe end used by the + child process (to avoid leaking the file descriptor in case of a + concurrent fork). This is later reverted in the child process. + When popen returns, the parent pipe end can be O_CLOEXEC or not, + depending on the 'e' open mode, but there is only one flag which + controls both descriptors. The parent end is adjusted below, + after creating the child process. (In the child process, the + parent end should be closed on execve, so O_CLOEXEC remains set + there.) */ + if (__pipe2 (pipe_fds, O_CLOEXEC) < 0) + return NULL; + + if (do_read) + { + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; + read_or_write = _IO_NO_WRITES; + } + else + { + parent_end = pipe_fds[1]; + child_end = pipe_fds[0]; + read_or_write = _IO_NO_READS; + } + + ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + if (child_pid == 0) + { + int child_std_end = do_read ? 1 : 0; + struct _IO_proc_file *p; + + if (child_end != child_std_end) + _IO_dup2 (child_end, child_std_end); + else + /* The descriptor is already the one we will use. But it must + not be marked close-on-exec. Undo the effects. */ + __fcntl (child_end, F_SETFD, 0); + /* POSIX.2: "popen() shall ensure that any streams from previous + popen() calls that remain open in the parent process are closed + in the new child process." */ + for (p = proc_file_chain; p; p = p->next) + { + int fd = _IO_fileno ((_IO_FILE *) p); + + /* If any stream from previous popen() calls has fileno + child_std_end, it has been already closed by the dup2 syscall + above. */ + if (fd != child_std_end) + _IO_close (fd); + } + + _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _IO__exit (127); + } + _IO_close (child_end); + if (child_pid < 0) + { + _IO_close (parent_end); + return NULL; + } + + if (!do_cloexec) + /* Undo the effects of the pipe2 call which set the + close-on-exec flag. */ + __fcntl (parent_end, F_SETFD, 0); + + _IO_fileno (fp) = parent_end; + + /* Link into proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + ((_IO_proc_file *) fp)->next = proc_file_chain; + proc_file_chain = (_IO_proc_file *) fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES); + return fp; +} + +_IO_FILE * +_IO_new_popen (const char *command, const char *mode) +{ + struct locked_FILE + { + struct _IO_proc_file fpx; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + _IO_FILE *fp; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fpx.file.file._lock = &new_f->lock; +#endif + fp = &new_f->fpx.file.file; + _IO_init_internal (fp, 0); + _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps; + _IO_new_file_init_internal (&new_f->fpx.file); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; +#endif + if (_IO_new_proc_open (fp, command, mode) != NULL) + return (_IO_FILE *) &new_f->fpx.file; + _IO_un_link (&new_f->fpx.file); + free (new_f); + return NULL; +} + +int +_IO_new_proc_close (_IO_FILE *fp) +{ + /* This is not name-space clean. FIXME! */ + int wstatus; + _IO_proc_file **ptr = &proc_file_chain; + _IO_pid_t wait_pid; + int status = -1; + + /* Unlink from proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + for ( ; *ptr != NULL; ptr = &(*ptr)->next) + { + if (*ptr == (_IO_proc_file *) fp) + { + *ptr = (*ptr)->next; + status = 0; + break; + } + } +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + return -1; + /* POSIX.2 Rationale: "Some historical implementations either block + or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting + for the child process to terminate. Since this behavior is not + described in POSIX.2, such implementations are not conforming." */ + do + { + wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + } + while (wait_pid == -1 && errno == EINTR); + if (wait_pid == -1) + return -1; + return wstatus; +} + +static const struct _IO_jump_t _IO_proc_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, _IO_new_file_overflow), + JUMP_INIT(underflow, _IO_new_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_new_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_new_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, _IO_new_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_new_proc_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +strong_alias (_IO_new_popen, __new_popen) +versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1); +versioned_symbol (libc, __new_popen, popen, GLIBC_2_1); +versioned_symbol (libc, _IO_new_proc_open, _IO_proc_open, GLIBC_2_1); +versioned_symbol (libc, _IO_new_proc_close, _IO_proc_close, GLIBC_2_1); diff --git a/REORG.TODO/libio/ioputs.c b/REORG.TODO/libio/ioputs.c new file mode 100644 index 0000000000..bf3224e9ab --- /dev/null +++ b/REORG.TODO/libio/ioputs.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <string.h> +#include <limits.h> + +int +_IO_puts (const char *str) +{ + int result = EOF; + _IO_size_t len = strlen (str); + _IO_acquire_lock (_IO_stdout); + + if ((_IO_vtable_offset (_IO_stdout) != 0 + || _IO_fwide (_IO_stdout, -1) == -1) + && _IO_sputn (_IO_stdout, str, len) == len + && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) + result = MIN (INT_MAX, len + 1); + + _IO_release_lock (_IO_stdout); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_puts, puts) +#endif diff --git a/REORG.TODO/libio/ioseekoff.c b/REORG.TODO/libio/ioseekoff.c new file mode 100644 index 0000000000..425c020c51 --- /dev/null +++ b/REORG.TODO/libio/ioseekoff.c @@ -0,0 +1,78 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <stdlib.h> +#include <libioP.h> +#include <errno.h> +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +_IO_off64_t +_IO_seekoff_unlocked (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) + { + __set_errno (EINVAL); + return EOF; + } + + /* If we have a backup buffer, get rid of it, since the __seekoff + callback may not know to do the right thing about it. + This may be over-kill, but it'll do for now. TODO */ + if (mode != 0 && ((_IO_fwide (fp, 0) < 0 && _IO_have_backup (fp)) + || (_IO_fwide (fp, 0) > 0 && _IO_have_wbackup (fp)))) + { + if (dir == _IO_seek_cur && _IO_in_backup (fp)) + { + if (_IO_vtable_offset (fp) != 0 || fp->_mode <= 0) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + else + abort (); + } + if (_IO_fwide (fp, 0) < 0) + _IO_free_backup_area (fp); + else + _IO_free_wbackup_area (fp); + } + + return _IO_SEEKOFF (fp, offset, dir, mode); +} + + +_IO_off64_t +_IO_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t retval; + + _IO_acquire_lock (fp); + retval = _IO_seekoff_unlocked (fp, offset, dir, mode); + _IO_release_lock (fp); + return retval; +} diff --git a/REORG.TODO/libio/ioseekpos.c b/REORG.TODO/libio/ioseekpos.c new file mode 100644 index 0000000000..27e0a8bba2 --- /dev/null +++ b/REORG.TODO/libio/ioseekpos.c @@ -0,0 +1,59 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> + +_IO_off64_t +_IO_seekpos_unlocked (_IO_FILE *fp, _IO_off64_t pos, int mode) +{ + /* If we have a backup buffer, get rid of it, since the __seekoff + callback may not know to do the right thing about it. + This may be over-kill, but it'll do for now. TODO */ + if (_IO_fwide (fp, 0) <= 0) + { + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + } + else + { + if (_IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + } + + return _IO_SEEKOFF (fp, pos, 0, mode); +} + + +_IO_off64_t +_IO_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode) +{ + _IO_off64_t retval; + + _IO_acquire_lock (fp); + retval = _IO_seekpos_unlocked (fp, pos, mode); + _IO_release_lock (fp); + return retval; +} diff --git a/REORG.TODO/libio/iosetbuffer.c b/REORG.TODO/libio/iosetbuffer.c new file mode 100644 index 0000000000..c5df900fd9 --- /dev/null +++ b/REORG.TODO/libio/iosetbuffer.c @@ -0,0 +1,47 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +void +_IO_setbuffer (_IO_FILE *fp, char *buf, _IO_size_t size) +{ + CHECK_FILE (fp, ); + _IO_acquire_lock (fp); + fp->_flags &= ~_IO_LINE_BUF; + if (!buf) + size = 0; + (void) _IO_SETBUF (fp, buf, size); + if (_IO_vtable_offset (fp) == 0 && fp->_mode == 0 && _IO_CHECK_WIDE (fp)) + /* We also have to set the buffer using the wide char function. */ + (void) _IO_WSETBUF (fp, buf, size); + _IO_release_lock (fp); +} +libc_hidden_def (_IO_setbuffer) + +#ifdef weak_alias +weak_alias (_IO_setbuffer, setbuffer) +#endif diff --git a/REORG.TODO/libio/iosetvbuf.c b/REORG.TODO/libio/iosetvbuf.c new file mode 100644 index 0000000000..b242018c0b --- /dev/null +++ b/REORG.TODO/libio/iosetvbuf.c @@ -0,0 +1,100 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define _IOFBF 0 /* Fully buffered. */ +#define _IOLBF 1 /* Line buffered. */ +#define _IONBF 2 /* No buffering. */ + +int +_IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + switch (mode) + { + case _IOFBF: + fp->_IO_file_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); + if (buf == NULL) + { + if (fp->_IO_buf_base == NULL) + { + /* There is no flag to distinguish between "fully buffered + mode has been explicitly set" as opposed to "line + buffering has not been explicitly set". In both + cases, _IO_LINE_BUF is off. If this is a tty, and + _IO_filedoalloc later gets called, it cannot know if + it should set the _IO_LINE_BUF flag (because that is + the default), or not (because we have explicitly asked + for fully buffered mode). So we make sure a buffer + gets allocated now, and explicitly turn off line + buffering. + + A possibly cleaner alternative would be to add an + extra flag, but then flags are a finite resource. */ + if (_IO_DOALLOCATE (fp) < 0) + { + result = EOF; + goto unlock_return; + } + fp->_IO_file_flags &= ~_IO_LINE_BUF; + } + result = 0; + goto unlock_return; + } + break; + case _IOLBF: + fp->_IO_file_flags &= ~_IO_UNBUFFERED; + fp->_IO_file_flags |= _IO_LINE_BUF; + if (buf == NULL) + { + result = 0; + goto unlock_return; + } + break; + case _IONBF: + fp->_IO_file_flags &= ~_IO_LINE_BUF; + fp->_IO_file_flags |= _IO_UNBUFFERED; + buf = NULL; + size = 0; + break; + default: + result = EOF; + goto unlock_return; + } + result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0; + +unlock_return: + _IO_release_lock (fp); + return result; +} +libc_hidden_def (_IO_setvbuf) + +#ifdef weak_alias +weak_alias (_IO_setvbuf, setvbuf) +#endif diff --git a/REORG.TODO/libio/ioungetc.c b/REORG.TODO/libio/ioungetc.c new file mode 100644 index 0000000000..951064fa12 --- /dev/null +++ b/REORG.TODO/libio/ioungetc.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +int +_IO_ungetc (int c, _IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + if (c == EOF) + return EOF; + _IO_acquire_lock (fp); + result = _IO_sputbackc (fp, (unsigned char) c); + _IO_release_lock (fp); + return result; +} + +#ifdef weak_alias +weak_alias (_IO_ungetc, ungetc) +#endif diff --git a/REORG.TODO/libio/ioungetwc.c b/REORG.TODO/libio/ioungetwc.c new file mode 100644 index 0000000000..866a5b332f --- /dev/null +++ b/REORG.TODO/libio/ioungetwc.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +ungetwc (wint_t c, _IO_FILE *fp) +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_acquire_lock (fp); + _IO_fwide (fp, 1); + if (c == WEOF) + result = WEOF; + else + result = _IO_sputbackwc (fp, c); + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/iovdprintf.c b/REORG.TODO/libio/iovdprintf.c new file mode 100644 index 0000000000..aa79f74274 --- /dev/null +++ b/REORG.TODO/libio/iovdprintf.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <stdio_ext.h> + +int +_IO_vdprintf (int d, const char *format, _IO_va_list arg) +{ + struct _IO_FILE_plus tmpfil; + struct _IO_wide_data wd; + int done; + +#ifdef _IO_MTSAFE_IO + tmpfil.file._lock = NULL; +#endif + _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); + _IO_JUMPS (&tmpfil) = &_IO_file_jumps; + _IO_new_file_init_internal (&tmpfil); +#if !_IO_UNIFIED_JUMPTABLES + tmpfil.vtable = NULL; +#endif + if (_IO_file_attach (&tmpfil.file, d) == NULL) + { + _IO_un_link (&tmpfil); + return EOF; + } + tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; + + _IO_mask_flags (&tmpfil.file, _IO_NO_READS, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + done = _IO_vfprintf (&tmpfil.file, format, arg); + + if (done != EOF && _IO_do_flush (&tmpfil.file) == EOF) + done = EOF; + + _IO_FINISH (&tmpfil.file); + + return done; +} +ldbl_weak_alias (_IO_vdprintf, vdprintf) diff --git a/REORG.TODO/libio/iovsprintf.c b/REORG.TODO/libio/iovsprintf.c new file mode 100644 index 0000000000..80a2aee1cb --- /dev/null +++ b/REORG.TODO/libio/iovsprintf.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + +int +__IO_vsprintf (char *string, const char *format, _IO_va_list args) +{ + _IO_strfile sf; + int ret; + +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&sf, string, -1, string); + ret = _IO_vfprintf (&sf._sbf._f, format, args); + _IO_putc_unlocked ('\0', &sf._sbf._f); + return ret; +} +ldbl_hidden_def (__IO_vsprintf, _IO_vsprintf) + +ldbl_strong_alias (__IO_vsprintf, _IO_vsprintf) +ldbl_weak_alias (__IO_vsprintf, vsprintf) diff --git a/REORG.TODO/libio/iovsscanf.c b/REORG.TODO/libio/iovsscanf.c new file mode 100644 index 0000000000..ae87a1f3a3 --- /dev/null +++ b/REORG.TODO/libio/iovsscanf.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + +int +_IO_vsscanf (const char *string, const char *format, _IO_va_list args) +{ + int ret; + _IO_strfile sf; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&sf, (char*)string, 0, NULL); + ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL); + return ret; +} +ldbl_weak_alias (_IO_vsscanf, __vsscanf) +ldbl_weak_alias (_IO_vsscanf, vsscanf) diff --git a/REORG.TODO/libio/iovswscanf.c b/REORG.TODO/libio/iovswscanf.c new file mode 100644 index 0000000000..16568fea3d --- /dev/null +++ b/REORG.TODO/libio/iovswscanf.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" +#include <wchar.h> + +int +__vswscanf (const wchar_t *string, const wchar_t *format, _IO_va_list args) +{ + int ret; + _IO_strfile sf; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); + _IO_fwide (&sf._sbf._f, 1); + _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); + ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL); + return ret; +} +libc_hidden_def (__vswscanf) +ldbl_hidden_def (__vswscanf, vswscanf) +ldbl_weak_alias (__vswscanf, vswscanf) diff --git a/REORG.TODO/libio/iowpadn.c b/REORG.TODO/libio/iowpadn.c new file mode 100644 index 0000000000..761b5af965 --- /dev/null +++ b/REORG.TODO/libio/iowpadn.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" + +#define PADSIZE 16 +static wchar_t const blanks[PADSIZE] = +{ + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ', + L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ' +}; +static wchar_t const zeroes[PADSIZE] = +{ + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0', + L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0' +}; + +_IO_ssize_t +_IO_wpadn (_IO_FILE *fp, wint_t pad, _IO_ssize_t count) +{ + wchar_t padbuf[PADSIZE]; + const wchar_t *padptr; + int i; + _IO_size_t written = 0; + _IO_size_t w; + + if (pad == L' ') + padptr = blanks; + else if (pad == L'0') + padptr = zeroes; + else + { + for (i = PADSIZE; --i >= 0; ) + padbuf[i] = pad; + padptr = padbuf; + } + for (i = count; i >= PADSIZE; i -= PADSIZE) + { + w = _IO_sputn (fp, (char *) padptr, PADSIZE); + written += w; + if (w != PADSIZE) + return written; + } + + if (i > 0) + { + w = _IO_sputn (fp, (char *) padptr, i); + written += w; + } + return written; +} diff --git a/REORG.TODO/libio/libc_fatal.c b/REORG.TODO/libio/libc_fatal.c new file mode 100644 index 0000000000..0e31e07a39 --- /dev/null +++ b/REORG.TODO/libio/libc_fatal.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> + +/* Abort with an error message. */ +void +__libc_fatal (const char *message) +{ + /* This function should write MESSAGE out in the most reliable way. + It is called in situations like internal stdio lossage. */ + + abort (); +} +libc_hidden_def (__libc_fatal) diff --git a/REORG.TODO/libio/libio.h b/REORG.TODO/libio/libio.h new file mode 100644 index 0000000000..518ffd8e44 --- /dev/null +++ b/REORG.TODO/libio/libio.h @@ -0,0 +1,519 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#ifndef _IO_STDIO_H +#define _IO_STDIO_H + +#include <_G_config.h> +/* ALL of these should be defined in _G_config.h */ +#define _IO_fpos_t _G_fpos_t +#define _IO_fpos64_t _G_fpos64_t +#define _IO_size_t size_t +#define _IO_ssize_t __ssize_t +#define _IO_off_t __off_t +#define _IO_off64_t __off64_t +#define _IO_pid_t __pid_t +#define _IO_uid_t __uid_t +#define _IO_iconv_t _G_iconv_t +#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE +#define _IO_BUFSIZ _G_BUFSIZ +#define _IO_va_list _G_va_list +#define _IO_wint_t wint_t + +/* This define avoids name pollution if we're using GNU stdarg.h */ +#define __need___va_list +#include <stdarg.h> +#ifdef __GNUC_VA_LIST +# undef _IO_va_list +# define _IO_va_list __gnuc_va_list +#endif /* __GNUC_VA_LIST */ + +#ifndef __P +# include <sys/cdefs.h> +#endif /*!__P*/ + +#define _IO_UNIFIED_JUMPTABLES 1 + +#ifndef EOF +# define EOF (-1) +#endif +#ifndef NULL +# if defined __GNUG__ && \ + (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define NULL (__null) +# else +# if !defined(__cplusplus) +# define NULL ((void*)0) +# else +# define NULL (0) +# endif +# endif +#endif + +#define _IOS_INPUT 1 +#define _IOS_OUTPUT 2 +#define _IOS_ATEND 4 +#define _IOS_APPEND 8 +#define _IOS_TRUNC 16 +#define _IOS_NOCREATE 32 +#define _IOS_NOREPLACE 64 +#define _IOS_BIN 128 + +/* Magic numbers and bits for the _flags field. + The magic numbers use the high-order bits of _flags; + the remaining bits are available for variable flags. + Note: The magic numbers must all be negative if stdio + emulation is desired. */ + +#define _IO_MAGIC 0xFBAD0000 /* Magic number */ +#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */ +#define _IO_MAGIC_MASK 0xFFFF0000 +#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */ +#define _IO_UNBUFFERED 2 +#define _IO_NO_READS 4 /* Reading not allowed */ +#define _IO_NO_WRITES 8 /* Writing not allowd */ +#define _IO_EOF_SEEN 0x10 +#define _IO_ERR_SEEN 0x20 +#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */ +#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/ +#define _IO_IN_BACKUP 0x100 +#define _IO_LINE_BUF 0x200 +#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */ +#define _IO_CURRENTLY_PUTTING 0x800 +#define _IO_IS_APPENDING 0x1000 +#define _IO_IS_FILEBUF 0x2000 +#define _IO_BAD_SEEN 0x4000 +#define _IO_USER_LOCK 0x8000 + +#define _IO_FLAGS2_MMAP 1 +#define _IO_FLAGS2_NOTCANCEL 2 +#ifdef _LIBC +# define _IO_FLAGS2_FORTIFY 4 +#endif +#define _IO_FLAGS2_USER_WBUF 8 +#ifdef _LIBC +# define _IO_FLAGS2_SCANF_STD 16 +# define _IO_FLAGS2_NOCLOSE 32 +# define _IO_FLAGS2_CLOEXEC 64 +#endif + +/* These are "formatting flags" matching the iostream fmtflags enum values. */ +#define _IO_SKIPWS 01 +#define _IO_LEFT 02 +#define _IO_RIGHT 04 +#define _IO_INTERNAL 010 +#define _IO_DEC 020 +#define _IO_OCT 040 +#define _IO_HEX 0100 +#define _IO_SHOWBASE 0200 +#define _IO_SHOWPOINT 0400 +#define _IO_UPPERCASE 01000 +#define _IO_SHOWPOS 02000 +#define _IO_SCIENTIFIC 04000 +#define _IO_FIXED 010000 +#define _IO_UNITBUF 020000 +#define _IO_STDIO 040000 +#define _IO_DONT_CLOSE 0100000 +#define _IO_BOOLALPHA 0200000 + + +struct _IO_jump_t; struct _IO_FILE; + +/* During the build of glibc itself, _IO_lock_t will already have been + defined by internal headers. */ +#ifndef _IO_lock_t_defined +typedef void _IO_lock_t; +#endif + + +/* A streammarker remembers a position in a buffer. */ + +struct _IO_marker { + struct _IO_marker *_next; + struct _IO_FILE *_sbuf; + /* If _pos >= 0 + it points to _buf->Gbase()+_pos. FIXME comment */ + /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */ + int _pos; +#if 0 + void set_streampos(streampos sp) { _spos = sp; } + void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); } + public: + streammarker(streambuf *sb); + ~streammarker(); + int saving() { return _spos == -2; } + int delta(streammarker&); + int delta(); +#endif +}; + +/* This is the structure from the libstdc++ codecvt class. */ +enum __codecvt_result +{ + __codecvt_ok, + __codecvt_partial, + __codecvt_error, + __codecvt_noconv +}; + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +/* The order of the elements in the following struct must match the order + of the virtual functions in the libstdc++ codecvt class. */ +struct _IO_codecvt +{ + void (*__codecvt_destr) (struct _IO_codecvt *); + enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *, + __mbstate_t *, + const wchar_t *, + const wchar_t *, + const wchar_t **, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *, + __mbstate_t *, char *, + char *, char **); + enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *, + __mbstate_t *, + const char *, const char *, + const char **, wchar_t *, + wchar_t *, wchar_t **); + int (*__codecvt_do_encoding) (struct _IO_codecvt *); + int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); + int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, + const char *, const char *, _IO_size_t); + int (*__codecvt_do_max_length) (struct _IO_codecvt *); + + _IO_iconv_t __cd_in; + _IO_iconv_t __cd_out; +}; + +/* Extra data for wide character streams. */ +struct _IO_wide_data +{ + wchar_t *_IO_read_ptr; /* Current read pointer */ + wchar_t *_IO_read_end; /* End of get area. */ + wchar_t *_IO_read_base; /* Start of putback+get area. */ + wchar_t *_IO_write_base; /* Start of put area. */ + wchar_t *_IO_write_ptr; /* Current put pointer. */ + wchar_t *_IO_write_end; /* End of put area. */ + wchar_t *_IO_buf_base; /* Start of reserve area. */ + wchar_t *_IO_buf_end; /* End of reserve area. */ + /* The following fields are used to support backing up and undo. */ + wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */ + wchar_t *_IO_backup_base; /* Pointer to first valid character of + backup area */ + wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */ + + __mbstate_t _IO_state; + __mbstate_t _IO_last_state; + struct _IO_codecvt _codecvt; + + wchar_t _shortbuf[1]; + + const struct _IO_jump_t *_wide_vtable; +}; +#endif + +struct _IO_FILE { + int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ +#define _IO_file_flags _flags + + /* The following pointers correspond to the C++ streambuf protocol. */ + /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ + char* _IO_read_ptr; /* Current read pointer */ + char* _IO_read_end; /* End of get area. */ + char* _IO_read_base; /* Start of putback+get area. */ + char* _IO_write_base; /* Start of put area. */ + char* _IO_write_ptr; /* Current put pointer. */ + char* _IO_write_end; /* End of put area. */ + char* _IO_buf_base; /* Start of reserve area. */ + char* _IO_buf_end; /* End of reserve area. */ + /* The following fields are used to support backing up and undo. */ + char *_IO_save_base; /* Pointer to start of non-current get area. */ + char *_IO_backup_base; /* Pointer to first valid character of backup area */ + char *_IO_save_end; /* Pointer to end of non-current get area. */ + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; +#if 0 + int _blksize; +#else + int _flags2; +#endif + _IO_off_t _old_offset; /* This used to be _offset but it's too small. */ + +#define __HAVE_COLUMN /* temporary */ + /* 1+column number of pbase(); 0 is unknown. */ + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + /* char* _save_gptr; char* _save_egptr; */ + + _IO_lock_t *_lock; +#ifdef _IO_USE_OLD_IO_FILE +}; + +struct _IO_FILE_complete +{ + struct _IO_FILE _file; +#endif +#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001 + _IO_off64_t _offset; +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T + /* Wide character stream stuff. */ + struct _IO_codecvt *_codecvt; + struct _IO_wide_data *_wide_data; + struct _IO_FILE *_freeres_list; + void *_freeres_buf; +# else + void *__pad1; + void *__pad2; + void *__pad3; + void *__pad4; +# endif + size_t __pad5; + int _mode; + /* Make sure we don't get into trouble again. */ + char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; +#endif +}; + +#ifndef __cplusplus +typedef struct _IO_FILE _IO_FILE; +#endif + +struct _IO_FILE_plus; + +extern struct _IO_FILE_plus _IO_2_1_stdin_; +extern struct _IO_FILE_plus _IO_2_1_stdout_; +extern struct _IO_FILE_plus _IO_2_1_stderr_; +#ifndef _LIBC +#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_)) +#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_)) +#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_)) +#else +extern _IO_FILE *_IO_stdin attribute_hidden; +extern _IO_FILE *_IO_stdout attribute_hidden; +extern _IO_FILE *_IO_stderr attribute_hidden; +#endif + + +/* Functions to do I/O and file management for a stream. */ + +/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. + Return number of bytes read. */ +typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); + +/* Write N bytes pointed to by BUF to COOKIE. Write all N bytes + unless there is an error. Return number of bytes written. If + there is an error, return 0 and do not write anything. If the file + has been opened for append (__mode.__append set), then set the file + pointer to the end of the file and then do the write; if not, just + write at the current file pointer. */ +typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf, + size_t __n); + +/* Move COOKIE's file position to *POS bytes from the + beginning of the file (if W is SEEK_SET), + the current position (if W is SEEK_CUR), + or the end of the file (if W is SEEK_END). + Set *POS to the new file position. + Returns zero if successful, nonzero if not. */ +typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w); + +/* Close COOKIE. */ +typedef int __io_close_fn (void *__cookie); + + +#ifdef __USE_GNU +/* User-visible names for the above. */ +typedef __io_read_fn cookie_read_function_t; +typedef __io_write_fn cookie_write_function_t; +typedef __io_seek_fn cookie_seek_function_t; +typedef __io_close_fn cookie_close_function_t; + +/* The structure with the cookie function pointers. */ +typedef struct +{ + __io_read_fn *read; /* Read bytes. */ + __io_write_fn *write; /* Write bytes. */ + __io_seek_fn *seek; /* Seek/tell file position. */ + __io_close_fn *close; /* Close file. */ +} _IO_cookie_io_functions_t; +typedef _IO_cookie_io_functions_t cookie_io_functions_t; + +struct _IO_cookie_file; + +/* Initialize one of those. */ +extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, + void *__cookie, _IO_cookie_io_functions_t __fns); +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +extern int __underflow (_IO_FILE *); +extern int __uflow (_IO_FILE *); +extern int __overflow (_IO_FILE *, int); +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +extern _IO_wint_t __wunderflow (_IO_FILE *); +extern _IO_wint_t __wuflow (_IO_FILE *); +extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t); +#endif + +#if __GNUC__ >= 3 +# define _IO_BE(expr, res) __builtin_expect ((expr), res) +#else +# define _IO_BE(expr, res) (expr) +#endif + +#define _IO_getc_unlocked(_fp) \ + (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \ + ? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++) +#define _IO_peekc_unlocked(_fp) \ + (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \ + && __underflow (_fp) == EOF ? EOF \ + : *(unsigned char *) (_fp)->_IO_read_ptr) +#define _IO_putc_unlocked(_ch, _fp) \ + (_IO_BE ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end, 0) \ + ? __overflow (_fp, (unsigned char) (_ch)) \ + : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define _IO_getwc_unlocked(_fp) \ + (_IO_BE ((_fp)->_wide_data == NULL \ + || ((_fp)->_wide_data->_IO_read_ptr \ + >= (_fp)->_wide_data->_IO_read_end), 0) \ + ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++) +# define _IO_putwc_unlocked(_wch, _fp) \ + (_IO_BE ((_fp)->_wide_data == NULL \ + || ((_fp)->_wide_data->_IO_write_ptr \ + >= (_fp)->_wide_data->_IO_write_end), 0) \ + ? __woverflow (_fp, _wch) \ + : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch))) +#endif + +#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) +#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) + +extern int _IO_getc (_IO_FILE *__fp); +extern int _IO_putc (int __c, _IO_FILE *__fp); +extern int _IO_feof (_IO_FILE *__fp) __THROW; +extern int _IO_ferror (_IO_FILE *__fp) __THROW; + +extern int _IO_peekc_locked (_IO_FILE *__fp); + +/* This one is for Emacs. */ +#define _IO_PENDING_OUTPUT_COUNT(_fp) \ + ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) + +extern void _IO_flockfile (_IO_FILE *) __THROW; +extern void _IO_funlockfile (_IO_FILE *) __THROW; +extern int _IO_ftrylockfile (_IO_FILE *) __THROW; + +#define _IO_peekc(_fp) _IO_peekc_unlocked (_fp) +#define _IO_flockfile(_fp) /**/ +#define _IO_funlockfile(_fp) /**/ +#define _IO_ftrylockfile(_fp) /**/ +#ifndef _IO_cleanup_region_start +#define _IO_cleanup_region_start(_fct, _fp) /**/ +#endif +#ifndef _IO_cleanup_region_end +#define _IO_cleanup_region_end(_Doit) /**/ +#endif + +extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, + _IO_va_list, int *__restrict); +extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, + _IO_va_list); +extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t); +extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t); + +extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int); +extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int); + +extern void _IO_free_backup_area (_IO_FILE *) __THROW; + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +extern _IO_wint_t _IO_getwc (_IO_FILE *__fp); +extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp); +extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW; +# if __GNUC__ >= 2 +/* While compiling glibc we have to handle compatibility with very old + versions. */ +# if defined _LIBC && defined SHARED +# include <shlib-compat.h> +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) +# define _IO_fwide_maybe_incompatible \ + (__builtin_expect (&_IO_stdin_used == NULL, 0)) +extern const int _IO_stdin_used; +weak_extern (_IO_stdin_used); +# endif +# endif +# ifndef _IO_fwide_maybe_incompatible +# define _IO_fwide_maybe_incompatible (0) +# endif +/* A special optimized version of the function above. It optimizes the + case of initializing an unoriented byte stream. */ +# define _IO_fwide(__fp, __mode) \ + ({ int __result = (__mode); \ + if (__result < 0 && ! _IO_fwide_maybe_incompatible) \ + { \ + if ((__fp)->_mode == 0) \ + /* We know that all we have to do is to set the flag. */ \ + (__fp)->_mode = -1; \ + __result = (__fp)->_mode; \ + } \ + else if (__builtin_constant_p (__mode) && (__mode) == 0) \ + __result = _IO_fwide_maybe_incompatible ? -1 : (__fp)->_mode; \ + else \ + __result = _IO_fwide (__fp, __result); \ + __result; }) +# endif + +extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict, + _IO_va_list, int *__restrict); +extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict, + _IO_va_list); +extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t); +extern void _IO_free_wbackup_area (_IO_FILE *) __THROW; +#endif + +#ifdef __LDBL_COMPAT +# include <bits/libio-ldbl.h> +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _IO_STDIO_H */ diff --git a/REORG.TODO/libio/libioP.h b/REORG.TODO/libio/libioP.h new file mode 100644 index 0000000000..eb93418c8d --- /dev/null +++ b/REORG.TODO/libio/libioP.h @@ -0,0 +1,944 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* NOTE: libio is now exclusively used only by glibc since libstdc++ has its + own implementation. As a result, functions that were implemented for C++ + (like *sputn) may no longer have C++ semantics. This is of course only + relevant for internal callers of these functions since these functions are + not intended for external use otherwise. + + FIXME: All of the C++ cruft eventually needs to go away. */ + +#include <stddef.h> + +#include <errno.h> +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif +#if defined __GLIBC__ && __GLIBC__ >= 2 +# include <libc-lock.h> +#else +/*# include <comthread.h>*/ +#endif + +#include <math_ldbl_opt.h> + +#include "iolibio.h" + +/* Control of exported symbols. Used in glibc. By default we don't + do anything. */ +#ifndef libc_hidden_proto +# define libc_hidden_proto(name) +#endif +#ifndef libc_hidden_def +# define libc_hidden_def(name) +#endif +#ifndef libc_hidden_weak +# define libc_hidden_weak(name) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define _IO_seek_set 0 +#define _IO_seek_cur 1 +#define _IO_seek_end 2 + +/* THE JUMPTABLE FUNCTIONS. + + * The _IO_FILE type is used to implement the FILE type in GNU libc, + * as well as the streambuf class in GNU iostreams for C++. + * These are all the same, just used differently. + * An _IO_FILE (or FILE) object is allows followed by a pointer to + * a jump table (of pointers to functions). The pointer is accessed + * with the _IO_JUMPS macro. The jump table has an eccentric format, + * so as to be compatible with the layout of a C++ virtual function table. + * (as implemented by g++). When a pointer to a streambuf object is + * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just + * happens to point to the virtual function table of the streambuf. + * Thus the _IO_JUMPS function table used for C stdio/libio does + * double duty as the virtual function table for C++ streambuf. + * + * The entries in the _IO_JUMPS function table (and hence also the + * virtual functions of a streambuf) are described below. + * The first parameter of each function entry is the _IO_FILE/streambuf + * object being acted on (i.e. the 'this' parameter). + */ + +#ifdef _LIBC +# include <shlib-compat.h> +# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + /* Setting this macro disables the use of the _vtable_offset + bias in _IO_JUMPS_FUNCS, below. That is only needed if we + want to support old binaries (see oldfileops.c). */ +# define _G_IO_NO_BACKWARD_COMPAT 1 +# endif +#endif + +#if (!defined _IO_USE_OLD_IO_FILE \ + && (!defined _G_IO_NO_BACKWARD_COMPAT || _G_IO_NO_BACKWARD_COMPAT == 0)) +# define _IO_JUMPS_OFFSET 1 +#else +# define _IO_JUMPS_OFFSET 0 +#endif + +/* Type of MEMBER in struct type TYPE. */ +#define _IO_MEMBER_TYPE(TYPE, MEMBER) __typeof__ (((TYPE){}).MEMBER) + +/* Essentially ((TYPE *) THIS)->MEMBER, but avoiding the aliasing + violation in case THIS has a different pointer type. */ +#define _IO_CAST_FIELD_ACCESS(THIS, TYPE, MEMBER) \ + (*(_IO_MEMBER_TYPE (TYPE, MEMBER) *)(((char *) (THIS)) \ + + offsetof(TYPE, MEMBER))) + +#define _IO_JUMPS(THIS) (THIS)->vtable +#define _IO_JUMPS_FILE_plus(THIS) \ + _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE_plus, vtable) +#define _IO_WIDE_JUMPS(THIS) \ + _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data)->_wide_vtable +#define _IO_CHECK_WIDE(THIS) \ + (_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data) != NULL) + +#if _IO_JUMPS_OFFSET +# define _IO_JUMPS_FUNC(THIS) \ + (IO_validate_vtable \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ + + (THIS)->_vtable_offset))) +# define _IO_vtable_offset(THIS) (THIS)->_vtable_offset +#else +# define _IO_JUMPS_FUNC(THIS) (IO_validate_vtable (_IO_JUMPS_FILE_plus (THIS))) +# define _IO_vtable_offset(THIS) 0 +#endif +#define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS) +#define JUMP_FIELD(TYPE, NAME) TYPE NAME +#define JUMP0(FUNC, THIS) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS) +#define JUMP1(FUNC, THIS, X1) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1) +#define JUMP2(FUNC, THIS, X1, X2) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2) +#define JUMP3(FUNC, THIS, X1,X2,X3) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1,X2, X3) +#define JUMP_INIT(NAME, VALUE) VALUE +#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0) + +#define WJUMP0(FUNC, THIS) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS) +#define WJUMP1(FUNC, THIS, X1) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1) +#define WJUMP2(FUNC, THIS, X1, X2) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2) +#define WJUMP3(FUNC, THIS, X1,X2,X3) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1,X2, X3) + +/* The 'finish' function does any final cleaning up of an _IO_FILE object. + It does not delete (free) it, but does everything else to finalize it. + It matches the streambuf::~streambuf virtual destructor. */ +typedef void (*_IO_finish_t) (_IO_FILE *, int); /* finalize */ +#define _IO_FINISH(FP) JUMP1 (__finish, FP, 0) +#define _IO_WFINISH(FP) WJUMP1 (__finish, FP, 0) + +/* The 'overflow' hook flushes the buffer. + The second argument is a character, or EOF. + It matches the streambuf::overflow virtual function. */ +typedef int (*_IO_overflow_t) (_IO_FILE *, int); +#define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH) +#define _IO_WOVERFLOW(FP, CH) WJUMP1 (__overflow, FP, CH) + +/* The 'underflow' hook tries to fills the get buffer. + It returns the next character (as an unsigned char) or EOF. The next + character remains in the get buffer, and the get position is not changed. + It matches the streambuf::underflow virtual function. */ +typedef int (*_IO_underflow_t) (_IO_FILE *); +#define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP) +#define _IO_WUNDERFLOW(FP) WJUMP0 (__underflow, FP) + +/* The 'uflow' hook returns the next character in the input stream + (cast to unsigned char), and increments the read position; + EOF is returned on failure. + It matches the streambuf::uflow virtual function, which is not in the + cfront implementation, but was added to C++ by the ANSI/ISO committee. */ +#define _IO_UFLOW(FP) JUMP0 (__uflow, FP) +#define _IO_WUFLOW(FP) WJUMP0 (__uflow, FP) + +/* The 'pbackfail' hook handles backing up. + It matches the streambuf::pbackfail virtual function. */ +typedef int (*_IO_pbackfail_t) (_IO_FILE *, int); +#define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH) +#define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH) + +/* The 'xsputn' hook writes upto N characters from buffer DATA. + Returns EOF or the number of character actually written. + It matches the streambuf::xsputn virtual function. */ +typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA, + _IO_size_t N); +#define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N) +#define _IO_WXSPUTN(FP, DATA, N) WJUMP2 (__xsputn, FP, DATA, N) + +/* The 'xsgetn' hook reads upto N characters into buffer DATA. + Returns the number of character actually read. + It matches the streambuf::xsgetn virtual function. */ +typedef _IO_size_t (*_IO_xsgetn_t) (_IO_FILE *FP, void *DATA, _IO_size_t N); +#define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N) +#define _IO_WXSGETN(FP, DATA, N) WJUMP2 (__xsgetn, FP, DATA, N) + +/* The 'seekoff' hook moves the stream position to a new position + relative to the start of the file (if DIR==0), the current position + (MODE==1), or the end of the file (MODE==2). + It matches the streambuf::seekoff virtual function. + It is also used for the ANSI fseek function. */ +typedef _IO_off64_t (*_IO_seekoff_t) (_IO_FILE *FP, _IO_off64_t OFF, int DIR, + int MODE); +#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE) +#define _IO_WSEEKOFF(FP, OFF, DIR, MODE) WJUMP3 (__seekoff, FP, OFF, DIR, MODE) + +/* The 'seekpos' hook also moves the stream position, + but to an absolute position given by a fpos64_t (seekpos). + It matches the streambuf::seekpos virtual function. + It is also used for the ANSI fgetpos and fsetpos functions. */ +/* The _IO_seek_cur and _IO_seek_end options are not allowed. */ +typedef _IO_off64_t (*_IO_seekpos_t) (_IO_FILE *, _IO_off64_t, int); +#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS) +#define _IO_WSEEKPOS(FP, POS, FLAGS) WJUMP2 (__seekpos, FP, POS, FLAGS) + +/* The 'setbuf' hook gives a buffer to the file. + It matches the streambuf::setbuf virtual function. */ +typedef _IO_FILE* (*_IO_setbuf_t) (_IO_FILE *, char *, _IO_ssize_t); +#define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH) +#define _IO_WSETBUF(FP, BUFFER, LENGTH) WJUMP2 (__setbuf, FP, BUFFER, LENGTH) + +/* The 'sync' hook attempts to synchronize the internal data structures + of the file with the external state. + It matches the streambuf::sync virtual function. */ +typedef int (*_IO_sync_t) (_IO_FILE *); +#define _IO_SYNC(FP) JUMP0 (__sync, FP) +#define _IO_WSYNC(FP) WJUMP0 (__sync, FP) + +/* The 'doallocate' hook is used to tell the file to allocate a buffer. + It matches the streambuf::doallocate virtual function, which is not + in the ANSI/ISO C++ standard, but is part traditional implementations. */ +typedef int (*_IO_doallocate_t) (_IO_FILE *); +#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP) +#define _IO_WDOALLOCATE(FP) WJUMP0 (__doallocate, FP) + +/* The following four hooks (sysread, syswrite, sysclose, sysseek, and + sysstat) are low-level hooks specific to this implementation. + There is no correspondence in the ANSI/ISO C++ standard library. + The hooks basically correspond to the Unix system functions + (read, write, close, lseek, and stat) except that a _IO_FILE* + parameter is used instead of an integer file descriptor; the default + implementation used for normal files just calls those functions. + The advantage of overriding these functions instead of the higher-level + ones (underflow, overflow etc) is that you can leave all the buffering + higher-level functions. */ + +/* The 'sysread' hook is used to read data from the external file into + an existing buffer. It generalizes the Unix read(2) function. + It matches the streambuf::sys_read virtual function, which is + specific to this implementation. */ +typedef _IO_ssize_t (*_IO_read_t) (_IO_FILE *, void *, _IO_ssize_t); +#define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN) +#define _IO_WSYSREAD(FP, DATA, LEN) WJUMP2 (__read, FP, DATA, LEN) + +/* The 'syswrite' hook is used to write data from an existing buffer + to an external file. It generalizes the Unix write(2) function. + It matches the streambuf::sys_write virtual function, which is + specific to this implementation. */ +typedef _IO_ssize_t (*_IO_write_t) (_IO_FILE *, const void *, _IO_ssize_t); +#define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN) +#define _IO_WSYSWRITE(FP, DATA, LEN) WJUMP2 (__write, FP, DATA, LEN) + +/* The 'sysseek' hook is used to re-position an external file. + It generalizes the Unix lseek(2) function. + It matches the streambuf::sys_seek virtual function, which is + specific to this implementation. */ +typedef _IO_off64_t (*_IO_seek_t) (_IO_FILE *, _IO_off64_t, int); +#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE) +#define _IO_WSYSSEEK(FP, OFFSET, MODE) WJUMP2 (__seek, FP, OFFSET, MODE) + +/* The 'sysclose' hook is used to finalize (close, finish up) an + external file. It generalizes the Unix close(2) function. + It matches the streambuf::sys_close virtual function, which is + specific to this implementation. */ +typedef int (*_IO_close_t) (_IO_FILE *); /* finalize */ +#define _IO_SYSCLOSE(FP) JUMP0 (__close, FP) +#define _IO_WSYSCLOSE(FP) WJUMP0 (__close, FP) + +/* The 'sysstat' hook is used to get information about an external file + into a struct stat buffer. It generalizes the Unix fstat(2) call. + It matches the streambuf::sys_stat virtual function, which is + specific to this implementation. */ +typedef int (*_IO_stat_t) (_IO_FILE *, void *); +#define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF) +#define _IO_WSYSSTAT(FP, BUF) WJUMP1 (__stat, FP, BUF) + +/* The 'showmany' hook can be used to get an image how much input is + available. In many cases the answer will be 0 which means unknown + but some cases one can provide real information. */ +typedef int (*_IO_showmanyc_t) (_IO_FILE *); +#define _IO_SHOWMANYC(FP) JUMP0 (__showmanyc, FP) +#define _IO_WSHOWMANYC(FP) WJUMP0 (__showmanyc, FP) + +/* The 'imbue' hook is used to get information about the currently + installed locales. */ +typedef void (*_IO_imbue_t) (_IO_FILE *, void *); +#define _IO_IMBUE(FP, LOCALE) JUMP1 (__imbue, FP, LOCALE) +#define _IO_WIMBUE(FP, LOCALE) WJUMP1 (__imbue, FP, LOCALE) + + +#define _IO_CHAR_TYPE char /* unsigned char ? */ +#define _IO_INT_TYPE int + +struct _IO_jump_t +{ + JUMP_FIELD(size_t, __dummy); + JUMP_FIELD(size_t, __dummy2); + JUMP_FIELD(_IO_finish_t, __finish); + JUMP_FIELD(_IO_overflow_t, __overflow); + JUMP_FIELD(_IO_underflow_t, __underflow); + JUMP_FIELD(_IO_underflow_t, __uflow); + JUMP_FIELD(_IO_pbackfail_t, __pbackfail); + /* showmany */ + JUMP_FIELD(_IO_xsputn_t, __xsputn); + JUMP_FIELD(_IO_xsgetn_t, __xsgetn); + JUMP_FIELD(_IO_seekoff_t, __seekoff); + JUMP_FIELD(_IO_seekpos_t, __seekpos); + JUMP_FIELD(_IO_setbuf_t, __setbuf); + JUMP_FIELD(_IO_sync_t, __sync); + JUMP_FIELD(_IO_doallocate_t, __doallocate); + JUMP_FIELD(_IO_read_t, __read); + JUMP_FIELD(_IO_write_t, __write); + JUMP_FIELD(_IO_seek_t, __seek); + JUMP_FIELD(_IO_close_t, __close); + JUMP_FIELD(_IO_stat_t, __stat); + JUMP_FIELD(_IO_showmanyc_t, __showmanyc); + JUMP_FIELD(_IO_imbue_t, __imbue); +#if 0 + get_column; + set_column; +#endif +}; + +/* We always allocate an extra word following an _IO_FILE. + This contains a pointer to the function jump table used. + This is for compatibility with C++ streambuf; the word can + be used to smash to a pointer to a virtual function table. */ + +struct _IO_FILE_plus +{ + _IO_FILE file; + const struct _IO_jump_t *vtable; +}; + +#ifdef _IO_USE_OLD_IO_FILE +/* This structure is used by the compatibility code as if it were an + _IO_FILE_plus, but has enough space to initialize the _mode argument + of an _IO_FILE_complete. */ +struct _IO_FILE_complete_plus +{ + struct _IO_FILE_complete file; + const struct _IO_jump_t *vtable; +}; +#endif + +/* Special file type for fopencookie function. */ +struct _IO_cookie_file +{ + struct _IO_FILE_plus __fp; + void *__cookie; + _IO_cookie_io_functions_t __io_functions; +}; + +_IO_FILE *_IO_fopencookie (void *cookie, const char *mode, + _IO_cookie_io_functions_t io_functions); + + +/* Iterator type for walking global linked list of _IO_FILE objects. */ + +typedef struct _IO_FILE *_IO_ITER; + +/* Generic functions */ + +extern void _IO_switch_to_main_get_area (_IO_FILE *) __THROW; +extern void _IO_switch_to_backup_area (_IO_FILE *) __THROW; +extern int _IO_switch_to_get_mode (_IO_FILE *); +libc_hidden_proto (_IO_switch_to_get_mode) +extern void _IO_init_internal (_IO_FILE *, int) attribute_hidden; +extern int _IO_sputbackc (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_sputbackc) +extern int _IO_sungetc (_IO_FILE *) __THROW; +extern void _IO_un_link (struct _IO_FILE_plus *) __THROW; +libc_hidden_proto (_IO_un_link) +extern void _IO_link_in (struct _IO_FILE_plus *) __THROW; +libc_hidden_proto (_IO_link_in) +extern void _IO_doallocbuf (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_doallocbuf) +extern void _IO_unsave_markers (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_unsave_markers) +extern void _IO_setb (_IO_FILE *, char *, char *, int) __THROW; +libc_hidden_proto (_IO_setb) +extern unsigned _IO_adjust_column (unsigned, const char *, int) __THROW; +libc_hidden_proto (_IO_adjust_column) +#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) + +_IO_ssize_t _IO_least_wmarker (_IO_FILE *, wchar_t *) __THROW; +libc_hidden_proto (_IO_least_wmarker) +extern void _IO_switch_to_main_wget_area (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_switch_to_main_wget_area) +extern void _IO_switch_to_wbackup_area (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_switch_to_wbackup_area) +extern int _IO_switch_to_wget_mode (_IO_FILE *); +libc_hidden_proto (_IO_switch_to_wget_mode) +extern void _IO_wsetb (_IO_FILE *, wchar_t *, wchar_t *, int) __THROW; +libc_hidden_proto (_IO_wsetb) +extern wint_t _IO_sputbackwc (_IO_FILE *, wint_t) __THROW; +libc_hidden_proto (_IO_sputbackwc) +extern wint_t _IO_sungetwc (_IO_FILE *) __THROW; +extern void _IO_wdoallocbuf (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_wdoallocbuf) +extern void _IO_unsave_wmarkers (_IO_FILE *) __THROW; +extern unsigned _IO_adjust_wcolumn (unsigned, const wchar_t *, int) __THROW; +extern _IO_off64_t get_file_offset (_IO_FILE *fp); + +/* Marker-related function. */ + +extern void _IO_init_marker (struct _IO_marker *, _IO_FILE *); +extern void _IO_init_wmarker (struct _IO_marker *, _IO_FILE *); +extern void _IO_remove_marker (struct _IO_marker *) __THROW; +extern int _IO_marker_difference (struct _IO_marker *, struct _IO_marker *) + __THROW; +extern int _IO_marker_delta (struct _IO_marker *) __THROW; +extern int _IO_wmarker_delta (struct _IO_marker *) __THROW; +extern int _IO_seekmark (_IO_FILE *, struct _IO_marker *, int) __THROW; +extern int _IO_seekwmark (_IO_FILE *, struct _IO_marker *, int) __THROW; + +/* Functions for iterating global list and dealing with its lock */ + +extern _IO_ITER _IO_iter_begin (void) __THROW; +libc_hidden_proto (_IO_iter_begin) +extern _IO_ITER _IO_iter_end (void) __THROW; +libc_hidden_proto (_IO_iter_end) +extern _IO_ITER _IO_iter_next (_IO_ITER) __THROW; +libc_hidden_proto (_IO_iter_next) +extern _IO_FILE *_IO_iter_file (_IO_ITER) __THROW; +libc_hidden_proto (_IO_iter_file) +extern void _IO_list_lock (void) __THROW; +libc_hidden_proto (_IO_list_lock) +extern void _IO_list_unlock (void) __THROW; +libc_hidden_proto (_IO_list_unlock) +extern void _IO_list_resetlock (void) __THROW; +libc_hidden_proto (_IO_list_resetlock) + +/* Default jumptable functions. */ + +extern int _IO_default_underflow (_IO_FILE *) __THROW; +extern int _IO_default_uflow (_IO_FILE *); +libc_hidden_proto (_IO_default_uflow) +extern wint_t _IO_wdefault_uflow (_IO_FILE *); +libc_hidden_proto (_IO_wdefault_uflow) +extern int _IO_default_doallocate (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_default_doallocate) +extern int _IO_wdefault_doallocate (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_wdefault_doallocate) +extern void _IO_default_finish (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_default_finish) +extern void _IO_wdefault_finish (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_wdefault_finish) +extern int _IO_default_pbackfail (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_default_pbackfail) +extern wint_t _IO_wdefault_pbackfail (_IO_FILE *, wint_t) __THROW; +libc_hidden_proto (_IO_wdefault_pbackfail) +extern _IO_FILE* _IO_default_setbuf (_IO_FILE *, char *, _IO_ssize_t); +extern _IO_size_t _IO_default_xsputn (_IO_FILE *, const void *, _IO_size_t); +libc_hidden_proto (_IO_default_xsputn) +extern _IO_size_t _IO_wdefault_xsputn (_IO_FILE *, const void *, _IO_size_t); +libc_hidden_proto (_IO_wdefault_xsputn) +extern _IO_size_t _IO_default_xsgetn (_IO_FILE *, void *, _IO_size_t); +libc_hidden_proto (_IO_default_xsgetn) +extern _IO_size_t _IO_wdefault_xsgetn (_IO_FILE *, void *, _IO_size_t); +libc_hidden_proto (_IO_wdefault_xsgetn) +extern _IO_off64_t _IO_default_seekoff (_IO_FILE *, _IO_off64_t, int, int) + __THROW; +extern _IO_off64_t _IO_default_seekpos (_IO_FILE *, _IO_off64_t, int); +extern _IO_ssize_t _IO_default_write (_IO_FILE *, const void *, _IO_ssize_t); +extern _IO_ssize_t _IO_default_read (_IO_FILE *, void *, _IO_ssize_t); +extern int _IO_default_stat (_IO_FILE *, void *) __THROW; +extern _IO_off64_t _IO_default_seek (_IO_FILE *, _IO_off64_t, int) __THROW; +extern int _IO_default_sync (_IO_FILE *) __THROW; +#define _IO_default_close ((_IO_close_t) _IO_default_sync) +extern int _IO_default_showmanyc (_IO_FILE *) __THROW; +extern void _IO_default_imbue (_IO_FILE *, void *) __THROW; + +extern const struct _IO_jump_t _IO_file_jumps; +libc_hidden_proto (_IO_file_jumps) +extern const struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden; +extern const struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden; +extern const struct _IO_jump_t _IO_wfile_jumps; +libc_hidden_proto (_IO_wfile_jumps) +extern const struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden; +extern const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden; +extern const struct _IO_jump_t _IO_old_file_jumps attribute_hidden; +extern const struct _IO_jump_t _IO_streambuf_jumps; +extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; +extern const struct _IO_jump_t _IO_str_jumps attribute_hidden; +extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden; +extern const struct _IO_codecvt __libio_codecvt attribute_hidden; +extern int _IO_do_write (_IO_FILE *, const char *, _IO_size_t); +libc_hidden_proto (_IO_do_write) +extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t); +extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t); +extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t); +libc_hidden_proto (_IO_wdo_write) +extern int _IO_flush_all_lockp (int); +extern int _IO_flush_all (void); +libc_hidden_proto (_IO_flush_all) +extern int _IO_cleanup (void); +extern void _IO_flush_all_linebuffered (void); +libc_hidden_proto (_IO_flush_all_linebuffered) +extern int _IO_new_fgetpos (_IO_FILE *, _IO_fpos_t *); +extern int _IO_old_fgetpos (_IO_FILE *, _IO_fpos_t *); +extern int _IO_new_fsetpos (_IO_FILE *, const _IO_fpos_t *); +extern int _IO_old_fsetpos (_IO_FILE *, const _IO_fpos_t *); +extern int _IO_new_fgetpos64 (_IO_FILE *, _IO_fpos64_t *); +extern int _IO_old_fgetpos64 (_IO_FILE *, _IO_fpos64_t *); +extern int _IO_new_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *); +extern int _IO_old_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *); +extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW; + + +#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define _IO_do_flush(_f) \ + ((_f)->_mode <= 0 \ + ? _IO_do_write(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) \ + : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \ + ((_f)->_wide_data->_IO_write_ptr \ + - (_f)->_wide_data->_IO_write_base))) +#else +# define _IO_do_flush(_f) \ + _IO_do_write(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) +#endif +#define _IO_old_do_flush(_f) \ + _IO_old_do_write(_f, (_f)->_IO_write_base, \ + (_f)->_IO_write_ptr-(_f)->_IO_write_base) +#define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING) +#define _IO_mask_flags(fp, f, mask) \ + ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask))) +#define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\ + (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg)) +#define _IO_wsetg(fp, eb, g, eg) ((fp)->_wide_data->_IO_read_base = (eb),\ + (fp)->_wide_data->_IO_read_ptr = (g), \ + (fp)->_wide_data->_IO_read_end = (eg)) +#define _IO_setp(__fp, __p, __ep) \ + ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr \ + = __p, (__fp)->_IO_write_end = (__ep)) +#define _IO_wsetp(__fp, __p, __ep) \ + ((__fp)->_wide_data->_IO_write_base \ + = (__fp)->_wide_data->_IO_write_ptr = __p, \ + (__fp)->_wide_data->_IO_write_end = (__ep)) +#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL) +#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL) +#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP) +#define _IO_have_markers(fp) ((fp)->_markers != NULL) +#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base) +#define _IO_wblen(fp) ((fp)->_wide_data->_IO_buf_end \ + - (fp)->_wide_data->_IO_buf_base) + +/* Jumptable functions for files. */ + +extern int _IO_file_doallocate (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_file_doallocate) +extern _IO_FILE* _IO_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); +libc_hidden_proto (_IO_file_setbuf) +extern _IO_off64_t _IO_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); +libc_hidden_proto (_IO_file_seekoff) +extern _IO_off64_t _IO_file_seekoff_mmap (_IO_FILE *, _IO_off64_t, int, int) + __THROW; +extern _IO_size_t _IO_file_xsputn (_IO_FILE *, const void *, _IO_size_t); +libc_hidden_proto (_IO_file_xsputn) +extern _IO_size_t _IO_file_xsgetn (_IO_FILE *, void *, _IO_size_t); +libc_hidden_proto (_IO_file_xsgetn) +extern int _IO_file_stat (_IO_FILE *, void *) __THROW; +libc_hidden_proto (_IO_file_stat) +extern int _IO_file_close (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_file_close) +extern int _IO_file_close_mmap (_IO_FILE *) __THROW; +extern int _IO_file_underflow (_IO_FILE *); +libc_hidden_proto (_IO_file_underflow) +extern int _IO_file_underflow_mmap (_IO_FILE *); +extern int _IO_file_underflow_maybe_mmap (_IO_FILE *); +extern int _IO_file_overflow (_IO_FILE *, int); +libc_hidden_proto (_IO_file_overflow) +#define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) +extern _IO_FILE* _IO_file_attach (_IO_FILE *, int); +libc_hidden_proto (_IO_file_attach) +extern _IO_FILE* _IO_file_open (_IO_FILE *, const char *, int, int, int, int); +libc_hidden_proto (_IO_file_open) +extern _IO_FILE* _IO_file_fopen (_IO_FILE *, const char *, const char *, int); +libc_hidden_proto (_IO_file_fopen) +extern _IO_ssize_t _IO_file_write (_IO_FILE *, const void *, _IO_ssize_t); +extern _IO_ssize_t _IO_file_read (_IO_FILE *, void *, _IO_ssize_t); +libc_hidden_proto (_IO_file_read) +extern int _IO_file_sync (_IO_FILE *); +libc_hidden_proto (_IO_file_sync) +extern int _IO_file_close_it (_IO_FILE *); +libc_hidden_proto (_IO_file_close_it) +extern _IO_off64_t _IO_file_seek (_IO_FILE *, _IO_off64_t, int) __THROW; +libc_hidden_proto (_IO_file_seek) +extern void _IO_file_finish (_IO_FILE *, int); +libc_hidden_proto (_IO_file_finish) + +extern _IO_FILE* _IO_new_file_attach (_IO_FILE *, int); +extern int _IO_new_file_close_it (_IO_FILE *); +extern void _IO_new_file_finish (_IO_FILE *, int); +extern _IO_FILE* _IO_new_file_fopen (_IO_FILE *, const char *, const char *, + int); +extern void _IO_no_init (_IO_FILE *, int, int, struct _IO_wide_data *, + const struct _IO_jump_t *) __THROW; +extern void _IO_new_file_init_internal (struct _IO_FILE_plus *) + __THROW attribute_hidden; +extern _IO_FILE* _IO_new_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); +extern _IO_FILE* _IO_file_setbuf_mmap (_IO_FILE *, char *, _IO_ssize_t); +extern int _IO_new_file_sync (_IO_FILE *); +extern int _IO_new_file_underflow (_IO_FILE *); +extern int _IO_new_file_overflow (_IO_FILE *, int); +extern _IO_off64_t _IO_new_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); +extern _IO_ssize_t _IO_new_file_write (_IO_FILE *, const void *, _IO_ssize_t); +extern _IO_size_t _IO_new_file_xsputn (_IO_FILE *, const void *, _IO_size_t); + +extern _IO_FILE* _IO_old_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); +extern _IO_off64_t _IO_old_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); +extern _IO_size_t _IO_old_file_xsputn (_IO_FILE *, const void *, _IO_size_t); +extern int _IO_old_file_underflow (_IO_FILE *); +extern int _IO_old_file_overflow (_IO_FILE *, int); +extern void _IO_old_file_init_internal (struct _IO_FILE_plus *) + __THROW attribute_hidden; +extern _IO_FILE* _IO_old_file_attach (_IO_FILE *, int); +extern _IO_FILE* _IO_old_file_fopen (_IO_FILE *, const char *, const char *); +extern _IO_ssize_t _IO_old_file_write (_IO_FILE *, const void *, _IO_ssize_t); +extern int _IO_old_file_sync (_IO_FILE *); +extern int _IO_old_file_close_it (_IO_FILE *); +extern void _IO_old_file_finish (_IO_FILE *, int); + +extern int _IO_wfile_doallocate (_IO_FILE *) __THROW; +extern _IO_size_t _IO_wfile_xsputn (_IO_FILE *, const void *, _IO_size_t); +libc_hidden_proto (_IO_wfile_xsputn) +extern _IO_FILE* _IO_wfile_setbuf (_IO_FILE *, wchar_t *, _IO_ssize_t); +extern wint_t _IO_wfile_sync (_IO_FILE *); +libc_hidden_proto (_IO_wfile_sync) +extern wint_t _IO_wfile_underflow (_IO_FILE *); +libc_hidden_proto (_IO_wfile_underflow) +extern wint_t _IO_wfile_overflow (_IO_FILE *, wint_t); +libc_hidden_proto (_IO_wfile_overflow) +extern _IO_off64_t _IO_wfile_seekoff (_IO_FILE *, _IO_off64_t, int, int); +libc_hidden_proto (_IO_wfile_seekoff) + +/* Jumptable functions for proc_files. */ +extern _IO_FILE* _IO_proc_open (_IO_FILE *, const char *, const char *) + __THROW; +extern _IO_FILE* _IO_new_proc_open (_IO_FILE *, const char *, const char *) + __THROW; +extern _IO_FILE* _IO_old_proc_open (_IO_FILE *, const char *, const char *); +extern int _IO_proc_close (_IO_FILE *) __THROW; +extern int _IO_new_proc_close (_IO_FILE *) __THROW; +extern int _IO_old_proc_close (_IO_FILE *); + +/* Jumptable functions for strfiles. */ +extern int _IO_str_underflow (_IO_FILE *) __THROW; +libc_hidden_proto (_IO_str_underflow) +extern int _IO_str_overflow (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_str_overflow) +extern int _IO_str_pbackfail (_IO_FILE *, int) __THROW; +libc_hidden_proto (_IO_str_pbackfail) +extern _IO_off64_t _IO_str_seekoff (_IO_FILE *, _IO_off64_t, int, int) __THROW; +libc_hidden_proto (_IO_str_seekoff) +extern void _IO_str_finish (_IO_FILE *, int) __THROW; + +/* Other strfile functions */ +struct _IO_strfile_; +extern _IO_ssize_t _IO_str_count (_IO_FILE *) __THROW; + +/* And the wide character versions. */ +extern void _IO_wstr_init_static (_IO_FILE *, wchar_t *, _IO_size_t, wchar_t *) + __THROW; +extern _IO_ssize_t _IO_wstr_count (_IO_FILE *) __THROW; +extern _IO_wint_t _IO_wstr_overflow (_IO_FILE *, _IO_wint_t) __THROW; +extern _IO_wint_t _IO_wstr_underflow (_IO_FILE *) __THROW; +extern _IO_off64_t _IO_wstr_seekoff (_IO_FILE *, _IO_off64_t, int, int) + __THROW; +extern _IO_wint_t _IO_wstr_pbackfail (_IO_FILE *, _IO_wint_t) __THROW; +extern void _IO_wstr_finish (_IO_FILE *, int) __THROW; + +extern int _IO_vasprintf (char **result_ptr, const char *format, + _IO_va_list args) __THROW; +extern int _IO_vdprintf (int d, const char *format, _IO_va_list arg); +extern int _IO_vsnprintf (char *string, _IO_size_t maxlen, + const char *format, _IO_va_list args) __THROW; + + +extern _IO_size_t _IO_getline (_IO_FILE *,char *, _IO_size_t, int, int); +libc_hidden_proto (_IO_getline) +extern _IO_size_t _IO_getline_info (_IO_FILE *,char *, _IO_size_t, + int, int, int *); +libc_hidden_proto (_IO_getline_info) +extern _IO_ssize_t _IO_getdelim (char **, _IO_size_t *, int, _IO_FILE *); +extern _IO_size_t _IO_getwline (_IO_FILE *,wchar_t *, _IO_size_t, wint_t, int); +extern _IO_size_t _IO_getwline_info (_IO_FILE *,wchar_t *, _IO_size_t, + wint_t, int, wint_t *); + +extern struct _IO_FILE_plus *_IO_list_all; +libc_hidden_proto (_IO_list_all) +extern void (*_IO_cleanup_registration_needed) (void); + +extern void _IO_str_init_static_internal (struct _IO_strfile_ *, char *, + _IO_size_t, char *) __THROW; +extern _IO_off64_t _IO_seekoff_unlocked (_IO_FILE *, _IO_off64_t, int, int) + attribute_hidden; +extern _IO_off64_t _IO_seekpos_unlocked (_IO_FILE *, _IO_off64_t, int) + attribute_hidden; + +#ifndef EOF +# define EOF (-1) +#endif +#ifndef NULL +# if defined __GNUG__ && \ + (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) +# define NULL (__null) +# else +# if !defined(__cplusplus) +# define NULL ((void*)0) +# else +# define NULL (0) +# endif +# endif +#endif + +#if _G_HAVE_MMAP + +# include <unistd.h> +# include <fcntl.h> +# include <sys/mman.h> +# include <sys/param.h> + +# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +# define MAP_ANONYMOUS MAP_ANON +# endif + +# if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE) +# undef _G_HAVE_MMAP +# define _G_HAVE_MMAP 0 +# endif + +#endif /* _G_HAVE_MMAP */ + +#if _G_HAVE_MMAP + +# ifdef _LIBC +/* When using this code in the GNU libc we must not pollute the name space. */ +# define mmap __mmap +# define munmap __munmap +# define ftruncate __ftruncate +# endif +#endif /* _G_HAVE_MMAP */ + +#ifndef OS_FSTAT +# define OS_FSTAT fstat +#endif +extern int _IO_vscanf (const char *, _IO_va_list) __THROW; + +/* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */ +#ifndef _IO_pos_BAD +# define _IO_pos_BAD ((_IO_off64_t) -1) +#endif +/* _IO_pos_adjust adjust an _IO_off64_t by some number of bytes. */ +#ifndef _IO_pos_adjust +# define _IO_pos_adjust(pos, delta) ((pos) += (delta)) +#endif +/* _IO_pos_0 is an _IO_off64_t value indicating beginning of file. */ +#ifndef _IO_pos_0 +# define _IO_pos_0 ((_IO_off64_t) 0) +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef _IO_MTSAFE_IO +/* check following! */ +# ifdef _IO_USE_OLD_IO_FILE +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock } +# else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ + NULL, WDP, 0 } +# else +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ + 0 } +# endif +# endif +#else +# ifdef _IO_USE_OLD_IO_FILE +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD } +# else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ + NULL, WDP, 0 } +# else +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ + { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ + 0 } +# endif +# endif +#endif + +#define _IO_va_start(args, last) va_start(args, last) + +extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf; + +#if 1 +# define COERCE_FILE(FILE) /* Nothing */ +#else +/* This is part of the kludge for binary compatibility with old stdio. */ +# define COERCE_FILE(FILE) \ + (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \ + && (FILE) = *(FILE**)&((int*)fp)[1]) +#endif + +#ifdef EINVAL +# define MAYBE_SET_EINVAL __set_errno (EINVAL) +#else +# define MAYBE_SET_EINVAL /* nothing */ +#endif + +#ifdef IO_DEBUG +# define CHECK_FILE(FILE, RET) \ + if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \ + else { COERCE_FILE(FILE); \ + if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \ + { MAYBE_SET_EINVAL; return RET; }} +#else +# define CHECK_FILE(FILE, RET) COERCE_FILE (FILE) +#endif + +static inline void +__attribute__ ((__always_inline__)) +_IO_acquire_lock_fct (_IO_FILE **p) +{ + _IO_FILE *fp = *p; + if ((fp->_flags & _IO_USER_LOCK) == 0) + _IO_funlockfile (fp); +} + +static inline void +__attribute__ ((__always_inline__)) +_IO_acquire_lock_clear_flags2_fct (_IO_FILE **p) +{ + _IO_FILE *fp = *p; + fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY | _IO_FLAGS2_SCANF_STD); + if ((fp->_flags & _IO_USER_LOCK) == 0) + _IO_funlockfile (fp); +} + +#if !defined _IO_MTSAFE_IO && IS_IN (libc) +# define _IO_acquire_lock(_fp) \ + do { \ + _IO_FILE *_IO_acquire_lock_file = NULL +# define _IO_acquire_lock_clear_flags2(_fp) \ + do { \ + _IO_FILE *_IO_acquire_lock_file = (_fp) +# define _IO_release_lock(_fp) \ + if (_IO_acquire_lock_file != NULL) \ + _IO_acquire_lock_file->_flags2 &= ~(_IO_FLAGS2_FORTIFY \ + | _IO_FLAGS2_SCANF_STD); \ + } while (0) +#endif + +/* Collect all vtables in a special section for vtable verification. + These symbols cover the extent of this section. */ +symbol_set_declare (__libc_IO_vtables) + +/* libio vtables need to carry this attribute so that they pass + validation. */ +#define libio_vtable __attribute__ ((section ("__libc_IO_vtables"))) + +#ifdef SHARED +/* If equal to &_IO_vtable_check (with pointer guard protection), + unknown vtable pointers are valid. This function pointer is solely + used as a flag. */ +extern void (*IO_accept_foreign_vtables) (void) attribute_hidden; + +/* Assigns the passed function pointer (either NULL or + &_IO_vtable_check) to IO_accept_foreign_vtables. */ +static inline void +IO_set_accept_foreign_vtables (void (*flag) (void)) +{ +#ifdef PTR_MANGLE + PTR_MANGLE (flag); +#endif + atomic_store_relaxed (&IO_accept_foreign_vtables, flag); +} + +#else /* !SHARED */ + +/* The statically-linked version does nothing. */ +static inline void +IO_set_accept_foreign_vtables (void (*flag) (void)) +{ +} + +#endif + +/* Check if unknown vtable pointers are permitted; otherwise, + terminate the process. */ +void _IO_vtable_check (void) attribute_hidden; + +/* Perform vtable pointer validation. If validation fails, terminate + the process. */ +static inline const struct _IO_jump_t * +IO_validate_vtable (const struct _IO_jump_t *vtable) +{ + /* Fast path: The vtable pointer is within the __libc_IO_vtables + section. */ + uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables; + const char *ptr = (const char *) vtable; + uintptr_t offset = ptr - __start___libc_IO_vtables; + if (__glibc_unlikely (offset >= section_length)) + /* The vtable pointer is not in the expected section. Use the + slow path, which will terminate the process if necessary. */ + _IO_vtable_check (); + return vtable; +} diff --git a/REORG.TODO/libio/memstream.c b/REORG.TODO/libio/memstream.c new file mode 100644 index 0000000000..f83d4a5213 --- /dev/null +++ b/REORG.TODO/libio/memstream.c @@ -0,0 +1,139 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "strfile.h" +#include <stdio.h> +#include <stdlib.h> + + +struct _IO_FILE_memstream +{ + _IO_strfile _sf; + char **bufloc; + _IO_size_t *sizeloc; +}; + + +static int _IO_mem_sync (_IO_FILE* fp) __THROW; +static void _IO_mem_finish (_IO_FILE* fp, int) __THROW; + + +static const struct _IO_jump_t _IO_mem_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_mem_finish), + JUMP_INIT (overflow, _IO_str_overflow), + JUMP_INIT (underflow, _IO_str_underflow), + JUMP_INIT (uflow, _IO_default_uflow), + JUMP_INIT (pbackfail, _IO_str_pbackfail), + JUMP_INIT (xsputn, _IO_default_xsputn), + JUMP_INIT (xsgetn, _IO_default_xsgetn), + JUMP_INIT (seekoff, _IO_str_seekoff), + JUMP_INIT (seekpos, _IO_default_seekpos), + JUMP_INIT (setbuf, _IO_default_setbuf), + JUMP_INIT (sync, _IO_mem_sync), + JUMP_INIT (doallocate, _IO_default_doallocate), + JUMP_INIT (read, _IO_default_read), + JUMP_INIT (write, _IO_default_write), + JUMP_INIT (seek, _IO_default_seek), + JUMP_INIT (close, _IO_default_close), + JUMP_INIT (stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +_IO_FILE * +__open_memstream (char **bufloc, _IO_size_t *sizeloc) +{ + struct locked_FILE + { + struct _IO_FILE_memstream fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + char *buf; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp._sf._sbf._f._lock = &new_f->lock; +#endif + + buf = calloc (1, _IO_BUFSIZ); + if (buf == NULL) + { + free (new_f); + return NULL; + } + _IO_init_internal (&new_f->fp._sf._sbf._f, 0); + _IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_mem_jumps; + _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf); + new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; + new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; + new_f->fp._sf._s._free_buffer = (_IO_free_type) free; + + new_f->fp.bufloc = bufloc; + new_f->fp.sizeloc = sizeloc; + + return (_IO_FILE *) &new_f->fp._sf._sbf; +} +libc_hidden_def (__open_memstream) +weak_alias (__open_memstream, open_memstream) + + +static int +_IO_mem_sync (_IO_FILE *fp) +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + + if (fp->_IO_write_ptr == fp->_IO_write_end) + { + _IO_str_overflow (fp, '\0'); + --fp->_IO_write_ptr; + } + + *mp->bufloc = fp->_IO_write_base; + *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base; + + return 0; +} + + +static void +_IO_mem_finish (_IO_FILE *fp, int dummy) +{ + struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; + + *mp->bufloc = (char *) realloc (fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base + 1); + if (*mp->bufloc != NULL) + { + (*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0'; + *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base; + + fp->_IO_buf_base = NULL; + } + + _IO_str_finish (fp, 0); +} diff --git a/REORG.TODO/libio/obprintf.c b/REORG.TODO/libio/obprintf.c new file mode 100644 index 0000000000..64d890a46e --- /dev/null +++ b/REORG.TODO/libio/obprintf.c @@ -0,0 +1,188 @@ +/* Print output of stream to given obstack. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include <stdlib.h> +#include "libioP.h" +#include "strfile.h" +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <obstack.h> +#include <stdarg.h> +#include <stdio_ext.h> + + +struct _IO_obstack_file +{ + struct _IO_FILE_plus file; + struct obstack *obstack; +}; + + +static int +_IO_obstack_overflow (_IO_FILE *fp, int c) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + int size; + + /* Make room for another character. This might as well allocate a + new chunk a memory and moves the old contents over. */ + assert (c != EOF); + obstack_1grow (obstack, c); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + size = obstack_room (obstack); + fp->_IO_write_end = fp->_IO_write_ptr + size; + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, size); + + return c; +} + + +static _IO_size_t +_IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) +{ + struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; + + if (fp->_IO_write_ptr + n > fp->_IO_write_end) + { + int size; + + /* We need some more memory. First shrink the buffer to the + space we really currently need. */ + obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end); + + /* Now grow for N bytes, and put the data there. */ + obstack_grow (obstack, data, n); + + /* Setup the buffer pointers again. */ + fp->_IO_write_base = obstack_base (obstack); + fp->_IO_write_ptr = obstack_next_free (obstack); + size = obstack_room (obstack); + fp->_IO_write_end = fp->_IO_write_ptr + size; + /* Now allocate the rest of the current chunk. */ + obstack_blank_fast (obstack, size); + } + else + fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n); + + return n; +} + + +/* the jump table. */ +const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, NULL), + JUMP_INIT(overflow, _IO_obstack_overflow), + JUMP_INIT(underflow, NULL), + JUMP_INIT(uflow, NULL), + JUMP_INIT(pbackfail, NULL), + JUMP_INIT(xsputn, _IO_obstack_xsputn), + JUMP_INIT(xsgetn, NULL), + JUMP_INIT(seekoff, NULL), + JUMP_INIT(seekpos, NULL), + JUMP_INIT(setbuf, NULL), + JUMP_INIT(sync, NULL), + JUMP_INIT(doallocate, NULL), + JUMP_INIT(read, NULL), + JUMP_INIT(write, NULL), + JUMP_INIT(seek, NULL), + JUMP_INIT(close, NULL), + JUMP_INIT(stat, NULL), + JUMP_INIT(showmanyc, NULL), + JUMP_INIT(imbue, NULL) +}; + + +int +_IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) +{ + struct obstack_FILE + { + struct _IO_obstack_file ofile; + } new_f; + int result; + int size; + int room; + +#ifdef _IO_MTSAFE_IO + new_f.ofile.file.file._lock = NULL; +#endif + + _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; + room = obstack_room (obstack); + size = obstack_object_size (obstack) + room; + if (size == 0) + { + /* We have to handle the allocation a bit different since the + `_IO_str_init_static' function would handle a size of zero + different from what we expect. */ + + /* Get more memory. */ + obstack_make_room (obstack, 64); + + /* Recompute how much room we have. */ + room = obstack_room (obstack); + size = room; + + assert (size != 0); + } + + _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, + obstack_base (obstack), + size, obstack_next_free (obstack)); + /* Now allocate the rest of the current chunk. */ + assert (size == (new_f.ofile.file.file._IO_write_end + - new_f.ofile.file.file._IO_write_base)); + assert (new_f.ofile.file.file._IO_write_ptr + == (new_f.ofile.file.file._IO_write_base + + obstack_object_size (obstack))); + obstack_blank_fast (obstack, room); + + new_f.ofile.obstack = obstack; + + result = _IO_vfprintf (&new_f.ofile.file.file, format, args); + + /* Shrink the buffer to the space we really currently need. */ + obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr + - new_f.ofile.file.file._IO_write_end)); + + return result; +} +ldbl_weak_alias (_IO_obstack_vprintf, obstack_vprintf) + + +int +_IO_obstack_printf (struct obstack *obstack, const char *format, ...) +{ + int result; + va_list ap; + va_start (ap, format); + result = _IO_obstack_vprintf (obstack, format, ap); + va_end (ap); + return result; +} +ldbl_weak_alias (_IO_obstack_printf, obstack_printf) diff --git a/REORG.TODO/libio/oldfileops.c b/REORG.TODO/libio/oldfileops.c new file mode 100644 index 0000000000..2eceefa68a --- /dev/null +++ b/REORG.TODO/libio/oldfileops.c @@ -0,0 +1,792 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* This is a compatibility file. If we don't build the libc with + versioning don't compile this file. */ +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + + +#ifdef _LIBC +# define open(Name, Flags, Prot) __open (Name, Flags, Prot) +# define close(FD) __close (FD) +# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) +# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) +# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) +#endif + +/* An fstream can be in at most one of put mode, get mode, or putback mode. + Putback mode is a variant of get mode. + + In a filebuf, there is only one current position, instead of two + separate get and put pointers. In get mode, the current position + is that of gptr(); in put mode that of pptr(). + + The position in the buffer that corresponds to the position + in external file system is normally _IO_read_end, except in putback + mode, when it is _IO_save_end. + If the field _fb._offset is >= 0, it gives the offset in + the file as a whole corresponding to eGptr(). (?) + + PUT MODE: + If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end, + and _IO_read_base are equal to each other. These are usually equal + to _IO_buf_base, though not necessarily if we have switched from + get mode to put mode. (The reason is to maintain the invariant + that _IO_read_end corresponds to the external file position.) + _IO_write_base is non-NULL and usually equal to _IO_buf_base. + We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode. + The un-flushed character are those between _IO_write_base and _IO_write_ptr. + + GET MODE: + If a filebuf is in get or putback mode, eback() != egptr(). + In get mode, the unread characters are between gptr() and egptr(). + The OS file position corresponds to that of egptr(). + + PUTBACK MODE: + Putback mode is used to remember "excess" characters that have + been sputbackc'd in a separate putback buffer. + In putback mode, the get buffer points to the special putback buffer. + The unread characters are the characters between gptr() and egptr() + in the putback buffer, as well as the area between save_gptr() + and save_egptr(), which point into the original reserve buffer. + (The pointers save_gptr() and save_egptr() are the values + of gptr() and egptr() at the time putback mode was entered.) + The OS position corresponds to that of save_egptr(). + + LINE BUFFERED OUTPUT: + During line buffered output, _IO_write_base==base() && epptr()==base(). + However, ptr() may be anywhere between base() and ebuf(). + This forces a call to filebuf::overflow(int C) on every put. + If there is more space in the buffer, and C is not a '\n', + then C is inserted, and pptr() incremented. + + UNBUFFERED STREAMS: + If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer. +*/ + +#define CLOSED_FILEBUF_FLAGS \ + (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET) + + +void +attribute_compat_text_section +_IO_old_file_init_internal (struct _IO_FILE_plus *fp) +{ + /* POSIX.1 allows another file handle to be used to change the position + of our file descriptor. Hence we actually don't know the actual + position before we do the first fseek (and until a following fflush). */ + fp->file._old_offset = _IO_pos_BAD; + fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + + _IO_link_in (fp); + fp->file._vtable_offset = ((int) sizeof (struct _IO_FILE) + - (int) sizeof (struct _IO_FILE_complete)); + fp->file._fileno = -1; + +#if defined SHARED && defined _LIBC + if (__builtin_expect (&_IO_stdin_used != NULL, 1) + || (fp != (struct _IO_FILE_plus *) _IO_stdin + && fp != (struct _IO_FILE_plus *) _IO_stdout + && fp != (struct _IO_FILE_plus *) _IO_stderr)) + /* The object is dynamically allocated and large enough. Initialize + the _mode element as well. */ + ((struct _IO_FILE_complete *) fp)->_mode = -1; +#endif +} + +void +attribute_compat_text_section +_IO_old_file_init (struct _IO_FILE_plus *fp) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_old_file_init_internal (fp); +} + +int +attribute_compat_text_section +_IO_old_file_close_it (_IO_FILE *fp) +{ + int write_status, close_status; + if (!_IO_file_is_open (fp)) + return EOF; + + write_status = _IO_old_do_flush (fp); + + _IO_unsave_markers (fp); + + close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 + ? _IO_SYSCLOSE (fp) : 0); + + /* Free buffer. */ + _IO_setb (fp, NULL, NULL, 0); + _IO_setg (fp, NULL, NULL, NULL); + _IO_setp (fp, NULL, NULL); + + _IO_un_link ((struct _IO_FILE_plus *) fp); + fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; + fp->_fileno = -1; + fp->_old_offset = _IO_pos_BAD; + + return close_status ? close_status : write_status; +} + +void +attribute_compat_text_section +_IO_old_file_finish (_IO_FILE *fp, int dummy) +{ + if (_IO_file_is_open (fp)) + { + _IO_old_do_flush (fp); + if (!(fp->_flags & _IO_DELETE_DONT_CLOSE)) + _IO_SYSCLOSE (fp); + } + _IO_default_finish (fp, 0); +} + +_IO_FILE * +attribute_compat_text_section +_IO_old_file_fopen (_IO_FILE *fp, const char *filename, const char *mode) +{ + int oflags = 0, omode; + int read_write, fdesc; + int oprot = 0666; + if (_IO_file_is_open (fp)) + return 0; + switch (*mode++) + { + case 'r': + omode = O_RDONLY; + read_write = _IO_NO_WRITES; + break; + case 'w': + omode = O_WRONLY; + oflags = O_CREAT|O_TRUNC; + read_write = _IO_NO_READS; + break; + case 'a': + omode = O_WRONLY; + oflags = O_CREAT|O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + __set_errno (EINVAL); + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + { + omode = O_RDWR; + read_write &= _IO_IS_APPENDING; + } + fdesc = open (filename, omode|oflags, oprot); + if (fdesc < 0) + return NULL; + fp->_fileno = fdesc; + _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + if (read_write & _IO_IS_APPENDING) + if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + _IO_link_in ((struct _IO_FILE_plus *) fp); + return fp; +} + +_IO_FILE * +attribute_compat_text_section +_IO_old_file_attach (_IO_FILE *fp, int fd) +{ + if (_IO_file_is_open (fp)) + return NULL; + fp->_fileno = fd; + fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES); + fp->_flags |= _IO_DELETE_DONT_CLOSE; + /* Get the current position of the file. */ + /* We have to do that since that may be junk. */ + fp->_old_offset = _IO_pos_BAD; + if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD && errno != ESPIPE) + return NULL; + return fp; +} + +_IO_FILE * +attribute_compat_text_section +_IO_old_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +{ + if (_IO_default_setbuf (fp, p, len) == NULL) + return NULL; + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + + return fp; +} + +static int old_do_write (_IO_FILE *, const char *, _IO_size_t); + +/* Write TO_DO bytes from DATA to FP. + Then mark FP as having empty buffers. */ + +int +attribute_compat_text_section +_IO_old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +{ + return (to_do == 0 || (_IO_size_t) old_do_write (fp, data, to_do) == to_do) + ? 0 : EOF; +} + +static int +attribute_compat_text_section +old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +{ + _IO_size_t count; + if (fp->_flags & _IO_IS_APPENDING) + /* On a system without a proper O_APPEND implementation, + you would need to sys_seek(0, SEEK_END) here, but is + not needed nor desirable for Unix- or Posix-like systems. + Instead, just indicate that offset (before and after) is + unpredictable. */ + fp->_old_offset = _IO_pos_BAD; + else if (fp->_IO_read_end != fp->_IO_write_base) + { + _IO_off_t new_pos + = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); + if (new_pos == _IO_pos_BAD) + return 0; + fp->_old_offset = new_pos; + } + count = _IO_SYSWRITE (fp, data, to_do); + if (fp->_cur_column && count) + fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; + fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + ? fp->_IO_buf_base : fp->_IO_buf_end); + return count; +} + +int +attribute_compat_text_section +_IO_old_file_underflow (_IO_FILE *fp) +{ + _IO_ssize_t count; +#if 0 + /* SysV does not make this test; take it out for compatibility */ + if (fp->_flags & _IO_EOF_SEEN) + return (EOF); +#endif + + if (fp->_flags & _IO_NO_READS) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *(unsigned char *) fp->_IO_read_ptr; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) + _IO_flush_all_linebuffered (); + + _IO_switch_to_get_mode (fp); + + /* This is very tricky. We have to adjust those + pointers before we call _IO_SYSREAD () since + we may longjump () out while waiting for + input. Those pointers may be screwed up. H.J. */ + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + fp->_IO_read_end = fp->_IO_buf_base; + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end + = fp->_IO_buf_base; + + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + fp->_IO_buf_end - fp->_IO_buf_base); + if (count <= 0) + { + if (count == 0) + fp->_flags |= _IO_EOF_SEEN; + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + return EOF; + if (fp->_old_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_old_offset, count); + return *(unsigned char *) fp->_IO_read_ptr; +} + +int +attribute_compat_text_section +_IO_old_file_overflow (_IO_FILE *f, int ch) +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return EOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + { + /* Allocate a buffer if needed. */ + if (f->_IO_write_base == 0) + { + _IO_doallocbuf (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + /* Otherwise must be currently reading. + If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting the + read pointers to all point at the beginning of the block). This + makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving that + alone, so it can continue to correspond to the external position). */ + if (f->_IO_read_ptr == f->_IO_buf_end) + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + if (f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + f->_IO_write_end = f->_IO_write_ptr; + f->_flags |= _IO_CURRENTLY_PUTTING; + } + if (ch == EOF) + return _IO_old_do_flush (f); + if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ + if (_IO_old_do_flush (f) == EOF) + return EOF; + *f->_IO_write_ptr++ = ch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) + if (_IO_old_do_flush (f) == EOF) + return EOF; + return (unsigned char) ch; +} + +int +attribute_compat_text_section +_IO_old_file_sync (_IO_FILE *fp) +{ + _IO_ssize_t delta; + int retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_IO_write_ptr > fp->_IO_write_base) + if (_IO_old_do_flush(fp)) return EOF; + delta = fp->_IO_read_ptr - fp->_IO_read_end; + if (delta != 0) + { +#ifdef TODO + if (_IO_in_backup (fp)) + delta -= eGptr () - Gbase (); +#endif + _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off_t) EOF) + fp->_IO_read_end = fp->_IO_read_ptr; +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = EOF; + } + if (retval != EOF) + fp->_old_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} + +_IO_off64_t +attribute_compat_text_section +_IO_old_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off_t result; + _IO_off64_t delta, new_offset; + long count; + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end + && fp->_IO_write_base == fp->_IO_write_ptr); + + if (mode == 0) + dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to pptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ + + if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp)) + if (_IO_switch_to_get_mode (fp)) + return EOF; + + if (fp->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_IO_read_base != NULL) + { + free (fp->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + } + + switch (dir) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + if (fp->_old_offset == _IO_pos_BAD) + goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_old_offset; + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If we are only interested in the current position we've found it now. */ + if (mode == 0) + return offset; + + /* If destination is within current buffer, optimize: */ + if (fp->_old_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + /* Offset relative to start of main get area. */ + _IO_off_t rel_offset = (offset - fp->_old_offset + + (fp->_IO_read_end - fp->_IO_read_base)); + if (rel_offset >= 0) + { +#if 0 + if (_IO_in_backup (fp)) + _IO_switch_to_main_get_area (fp); +#endif + if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) + { + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, + fp->_IO_read_end); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } + } +#ifdef TODO + /* If we have streammarkers, seek forward by reading ahead. */ + if (_IO_have_markers (fp)) + { + int to_skip = rel_offset + - (fp->_IO_read_ptr - fp->_IO_read_base); + if (ignore (to_skip) != to_skip) + goto dumb; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } +#ifdef TODO + if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) + { + if (!_IO_in_backup (fp)) + _IO_switch_to_backup_area (fp); + gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } +#endif + } + +#ifdef TODO + _IO_unsave_markers (fp); +#endif + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + fp->_old_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + _IO_unsave_markers (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_old_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + file and the kernel file offset will be changed. */ + if (fp->_old_offset >= 0) + _IO_SYSSEEK (fp, fp->_old_offset, 0); + + return offset; +} + +_IO_ssize_t +attribute_compat_text_section +_IO_old_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) +{ + _IO_ssize_t to_do = n; + while (to_do > 0) + { + _IO_ssize_t count = write (f->_fileno, data, to_do); + if (count == EOF) + { + f->_flags |= _IO_ERR_SEEN; + break; + } + to_do -= count; + data = (void *) ((char *) data + count); + } + n -= to_do; + if (f->_old_offset >= 0) + f->_old_offset += n; + return n; +} + +_IO_size_t +attribute_compat_text_section +_IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +{ + const char *s = (char *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count = 0; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_IO_buf_end - f->_IO_write_ptr; + if (count >= n) + { + const char *p; + for (p = s + n; p > s; ) + { + if (*--p == '\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + else if (f->_IO_write_end > f->_IO_write_ptr) + count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */ + + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); +#else + memcpy (f->_IO_write_ptr, s, count); + f->_IO_write_ptr += count; +#endif + s += count; + } + else + { + char *p = f->_IO_write_ptr; + int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do + must_flush > 0) + { + _IO_size_t block_size, do_write; + /* Next flush the (full) buffer. */ + if (__overflow (f, EOF) == EOF) + return to_do == 0 ? EOF : n - to_do; + + /* Try to maintain alignment: write a whole number of blocks. + dont_write is what gets left over. */ + block_size = f->_IO_buf_end - f->_IO_buf_base; + do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); + + if (do_write) + { + count = old_do_write (f, s, do_write); + to_do -= count; + if (count < do_write) + return n - to_do; + } + + /* Now write out the remainder. Normally, this will fit in the + buffer, but it's somewhat messier for line-buffered files, + so we let _IO_default_xsputn handle the general case. */ + if (to_do) + to_do -= _IO_default_xsputn (f, s+do_write, to_do); + } + return n - to_do; +} + + +const struct _IO_jump_t _IO_old_file_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), + JUMP_INIT(overflow, _IO_old_file_overflow), + JUMP_INIT(underflow, _IO_old_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_old_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_old_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_old_file_setbuf), + JUMP_INIT(sync, _IO_old_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_old_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat) +}; + +compat_symbol (libc, _IO_old_do_write, _IO_do_write, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_attach, _IO_file_attach, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_close_it, _IO_file_close_it, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_finish, _IO_file_finish, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_fopen, _IO_file_fopen, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_init, _IO_file_init, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_setbuf, _IO_file_setbuf, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_sync, _IO_file_sync, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_overflow, _IO_file_overflow, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_seekoff, _IO_file_seekoff, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_underflow, _IO_file_underflow, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_write, _IO_file_write, GLIBC_2_0); +compat_symbol (libc, _IO_old_file_xsputn, _IO_file_xsputn, GLIBC_2_0); + +#endif diff --git a/REORG.TODO/libio/oldfmemopen.c b/REORG.TODO/libio/oldfmemopen.c new file mode 100644 index 0000000000..c2fef8d942 --- /dev/null +++ b/REORG.TODO/libio/oldfmemopen.c @@ -0,0 +1,275 @@ +/* Fmemopen implementation. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hanno Mueller, kontakt@hanno.de, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * fmemopen() - "my" version of a string stream + * Hanno Mueller, kontakt@hanno.de + * + * + * I needed fmemopen() for an application that I currently work on, + * but couldn't find it in libio. The following snippet of code is an + * attempt to implement what glibc's documentation describes. + * + * + * + * I already see some potential problems: + * + * - I never used the "original" fmemopen(). I am sure that "my" + * fmemopen() behaves differently than the original version. + * + * - The documentation doesn't say wether a string stream allows + * seeks. I checked the old fmemopen implementation in glibc's stdio + * directory, wasn't quite able to see what is going on in that + * source, but as far as I understand there was no seek there. For + * my application, I needed fseek() and ftell(), so it's here. + * + * - "append" mode and fseek(p, SEEK_END) have two different ideas + * about the "end" of the stream. + * + * As described in the documentation, when opening the file in + * "append" mode, the position pointer will be set to the first null + * character of the string buffer (yet the buffer may already + * contain more data). For fseek(), the last byte of the buffer is + * used as the end of the stream. + * + * - It is unclear to me what the documentation tries to say when it + * explains what happens when you use fmemopen with a NULL + * buffer. + * + * Quote: "fmemopen [then] allocates an array SIZE bytes long. This + * is really only useful if you are going to write things to the + * buffer and then read them back in again." + * + * What does that mean if the original fmemopen() did not allow + * seeking? How do you read what you just wrote without seeking back + * to the beginning of the stream? + * + * - I think there should be a second version of fmemopen() that does + * not add null characters for each write. (At least in my + * application, I am not actually using strings but binary data and + * so I don't need the stream to add null characters on its own.) + */ + +#include "libioP.h" + +#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_22) + +#include <errno.h> +#include <libio.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/types.h> + + +typedef struct fmemopen_cookie_struct fmemopen_cookie_t; +struct fmemopen_cookie_struct +{ + char *buffer; + int mybuffer; + int binmode; + size_t size; + _IO_off64_t pos; + size_t maxpos; +}; + + +static ssize_t +fmemopen_read (void *cookie, char *b, size_t s) +{ + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + if (c->pos + s > c->size) + { + if ((size_t) c->pos == c->size) + return 0; + s = c->size - c->pos; + } + + memcpy (b, &(c->buffer[c->pos]), s); + + c->pos += s; + if ((size_t) c->pos > c->maxpos) + c->maxpos = c->pos; + + return s; +} + + +static ssize_t +fmemopen_write (void *cookie, const char *b, size_t s) +{ + fmemopen_cookie_t *c; + int addnullc; + + c = (fmemopen_cookie_t *) cookie; + + addnullc = c->binmode == 0 && (s == 0 || b[s - 1] != '\0'); + + if (c->pos + s + addnullc > c->size) + { + if ((size_t) (c->pos + addnullc) >= c->size) + { + __set_errno (ENOSPC); + return 0; + } + s = c->size - c->pos - addnullc; + } + + memcpy (&(c->buffer[c->pos]), b, s); + + c->pos += s; + if ((size_t) c->pos > c->maxpos) + { + c->maxpos = c->pos; + if (addnullc) + c->buffer[c->maxpos] = '\0'; + } + + return s; +} + + +static int +fmemopen_seek (void *cookie, _IO_off64_t *p, int w) +{ + _IO_off64_t np; + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + switch (w) + { + case SEEK_SET: + np = *p; + break; + + case SEEK_CUR: + np = c->pos + *p; + break; + + case SEEK_END: + np = (c->binmode ? c->size : c->maxpos) - *p; + break; + + default: + return -1; + } + + if (np < 0 || (size_t) np > c->size) + return -1; + + *p = c->pos = np; + + return 0; +} + + +static int +fmemopen_close (void *cookie) +{ + fmemopen_cookie_t *c; + + c = (fmemopen_cookie_t *) cookie; + + if (c->mybuffer) + free (c->buffer); + free (c); + + return 0; +} + + +FILE * +__old_fmemopen (void *buf, size_t len, const char *mode) +{ + cookie_io_functions_t iof; + fmemopen_cookie_t *c; + FILE *result; + + if (__glibc_unlikely (len == 0)) + { + einval: + __set_errno (EINVAL); + return NULL; + } + + c = (fmemopen_cookie_t *) malloc (sizeof (fmemopen_cookie_t)); + if (c == NULL) + return NULL; + + c->mybuffer = (buf == NULL); + + if (c->mybuffer) + { + c->buffer = (char *) malloc (len); + if (c->buffer == NULL) + { + free (c); + return NULL; + } + c->buffer[0] = '\0'; + c->maxpos = 0; + } + else + { + if (__glibc_unlikely ((uintptr_t) len > -(uintptr_t) buf)) + { + free (c); + goto einval; + } + + c->buffer = buf; + + if (mode[0] == 'w') + c->buffer[0] = '\0'; + + c->maxpos = strnlen (c->buffer, len); + } + + c->size = len; + + if (mode[0] == 'a') + c->pos = c->maxpos; + else + c->pos = 0; + + c->binmode = mode[0] != '\0' && mode[1] == 'b'; + + iof.read = fmemopen_read; + iof.write = fmemopen_write; + iof.seek = fmemopen_seek; + iof.close = fmemopen_close; + + result = _IO_fopencookie (c, mode, iof); + if (__glibc_unlikely (result == NULL)) + { + if (c->mybuffer) + free (c->buffer); + + free (c); + } + + return result; +} +compat_symbol (libc, __old_fmemopen, fmemopen, GLIBC_2_2); +#endif diff --git a/REORG.TODO/libio/oldiofclose.c b/REORG.TODO/libio/oldiofclose.c new file mode 100644 index 0000000000..811888c964 --- /dev/null +++ b/REORG.TODO/libio/oldiofclose.c @@ -0,0 +1,74 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include <stdlib.h> + +int +attribute_compat_text_section +_IO_old_fclose (_IO_FILE *fp) +{ + int status; + + CHECK_FILE(fp, EOF); + + /* We desperately try to help programs which are using streams in a + strange way and mix old and new functions. Detect new streams + here. */ + if (fp->_vtable_offset == 0) + return _IO_new_fclose (fp); + + /* First unlink the stream. */ + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + _IO_un_link ((struct _IO_FILE_plus *) fp); + + _IO_acquire_lock (fp); + if (fp->_IO_file_flags & _IO_IS_FILEBUF) + status = _IO_old_file_close_it (fp); + else + status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; + _IO_release_lock (fp); + _IO_FINISH (fp); + if (_IO_have_backup (fp)) + _IO_free_backup_area (fp); + if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) + { + fp->_IO_file_flags = 0; + free(fp); + } + + return status; +} + +strong_alias (_IO_old_fclose, __old_fclose) +compat_symbol (libc, _IO_old_fclose, _IO_fclose, GLIBC_2_0); +compat_symbol (libc, __old_fclose, fclose, GLIBC_2_0); + +#endif diff --git a/REORG.TODO/libio/oldiofdopen.c b/REORG.TODO/libio/oldiofdopen.c new file mode 100644 index 0000000000..7f6180767e --- /dev/null +++ b/REORG.TODO/libio/oldiofdopen.c @@ -0,0 +1,137 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include <stdlib.h> +#include "libioP.h" +#include <fcntl.h> + +#ifndef _IO_fcntl +# define _IO_fcntl __fcntl +#endif + +_IO_FILE * +attribute_compat_text_section +_IO_old_fdopen (int fd, const char *mode) +{ + int read_write; + int posix_mode = 0; + struct locked_FILE + { + struct _IO_FILE_complete_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + int fd_flags; + + switch (*mode++) + { + case 'r': + read_write = _IO_NO_WRITES; + break; + case 'w': + read_write = _IO_NO_READS; + break; + case 'a': + posix_mode = O_APPEND; + read_write = _IO_NO_READS|_IO_IS_APPENDING; + break; + default: + MAYBE_SET_EINVAL; + return NULL; + } + if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) + read_write &= _IO_IS_APPENDING; +#ifdef F_GETFL + fd_flags = _IO_fcntl (fd, F_GETFL); +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) +#endif + if (fd_flags == -1 + || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) + || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) + return NULL; + + /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b) + [System Application Program Interface (API) Amendment 1: + Realtime Extensions], Rationale B.8.3.3 + Open a Stream on a File Descriptor says: + + Although not explicitly required by POSIX.1, a good + implementation of append ("a") mode would cause the + O_APPEND flag to be set. + + (Historical implementations [such as Solaris2] do a one-time + seek in fdopen.) + + However, we do not turn O_APPEND off if the mode is "w" (even + though that would seem consistent) because that would be more + likely to break historical programs. + */ + if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) + { +#ifdef F_SETFL + if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) +#endif + return NULL; + } +#endif + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._file._lock = &new_f->lock; +#endif + _IO_old_init (&new_f->fp.file._file, 0); + _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps; + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (_IO_old_file_attach (&new_f->fp.file._file, fd) == NULL) + { + _IO_un_link ((struct _IO_FILE_plus *) &new_f->fp); + free (new_f); + return NULL; + } + new_f->fp.file._file._flags &= ~_IO_DELETE_DONT_CLOSE; + + _IO_mask_flags (&new_f->fp.file._file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + + return (_IO_FILE *) &new_f->fp; +} + +strong_alias (_IO_old_fdopen, __old_fdopen) +compat_symbol (libc, _IO_old_fdopen, _IO_fdopen, GLIBC_2_0); +compat_symbol (libc, __old_fdopen, fdopen, GLIBC_2_0); + +#endif diff --git a/REORG.TODO/libio/oldiofgetpos.c b/REORG.TODO/libio/oldiofgetpos.c new file mode 100644 index 0000000000..9781b46d73 --- /dev/null +++ b/REORG.TODO/libio/oldiofgetpos.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <errno.h> + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) + +int +attribute_compat_text_section +_IO_old_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) +{ + _IO_off_t pos; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_release_lock (fp); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fgetpos, _IO_fgetpos, GLIBC_2_0); +strong_alias (_IO_old_fgetpos, __old_fgetpos) +compat_symbol (libc, __old_fgetpos, fgetpos, GLIBC_2_0); +#endif + +#endif diff --git a/REORG.TODO/libio/oldiofgetpos64.c b/REORG.TODO/libio/oldiofgetpos64.c new file mode 100644 index 0000000000..2221f9140b --- /dev/null +++ b/REORG.TODO/libio/oldiofgetpos64.c @@ -0,0 +1,64 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <errno.h> + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) + +int +attribute_compat_text_section +_IO_old_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) +{ + _IO_off64_t pos; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); + if (_IO_in_backup (fp) && pos != _IO_pos_BAD) + pos -= fp->_IO_save_end - fp->_IO_save_base; + _IO_release_lock (fp); + if (pos == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + return EOF; + } + posp->__pos = pos; + return 0; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fgetpos64, _IO_fgetpos64, GLIBC_2_1); +strong_alias (_IO_old_fgetpos64, __old_fgetpos64) +compat_symbol (libc, __old_fgetpos64, fgetpos64, GLIBC_2_1); +#endif + +#endif diff --git a/REORG.TODO/libio/oldiofopen.c b/REORG.TODO/libio/oldiofopen.c new file mode 100644 index 0000000000..085267b1d3 --- /dev/null +++ b/REORG.TODO/libio/oldiofopen.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include <stdlib.h> + + +_IO_FILE * +attribute_compat_text_section +_IO_old_fopen (const char *filename, const char *mode) +{ + struct locked_FILE + { + struct _IO_FILE_complete_plus fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp.file._file._lock = &new_f->lock; +#endif + _IO_old_init (&new_f->fp.file._file, 0); + _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps; + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; +#endif + if (_IO_old_file_fopen ((_IO_FILE *) &new_f->fp, filename, mode) != NULL) + return (_IO_FILE *) &new_f->fp; + _IO_un_link ((struct _IO_FILE_plus *) &new_f->fp); + free (new_f); + return NULL; +} + +strong_alias (_IO_old_fopen, __old_fopen) +compat_symbol (libc, _IO_old_fopen, _IO_fopen, GLIBC_2_0); +compat_symbol (libc, __old_fopen, fopen, GLIBC_2_0); +#endif diff --git a/REORG.TODO/libio/oldiofsetpos.c b/REORG.TODO/libio/oldiofsetpos.c new file mode 100644 index 0000000000..d711937263 --- /dev/null +++ b/REORG.TODO/libio/oldiofsetpos.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <errno.h> + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) +int +attribute_compat_text_section +_IO_old_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_release_lock (fp); + return result; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fsetpos, _IO_fsetpos, GLIBC_2_0); +strong_alias (_IO_old_fsetpos, __old_fsetpos) +compat_symbol (libc, __old_fsetpos, fsetpos, GLIBC_2_0); +#endif + +#endif diff --git a/REORG.TODO/libio/oldiofsetpos64.c b/REORG.TODO/libio/oldiofsetpos64.c new file mode 100644 index 0000000000..7fad4081a1 --- /dev/null +++ b/REORG.TODO/libio/oldiofsetpos64.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libioP.h> +#include <errno.h> + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) + +int +attribute_compat_text_section +_IO_old_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + if (_IO_seekpos_unlocked (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) + == _IO_pos_BAD) + { + /* ANSI explicitly requires setting errno to a positive value on + failure. */ +#ifdef EIO + if (errno == 0) + __set_errno (EIO); +#endif + result = EOF; + } + else + result = 0; + _IO_release_lock (fp); + return result; +} + +#ifdef weak_alias +compat_symbol (libc, _IO_old_fsetpos64, _IO_fsetpos64, GLIBC_2_1); +strong_alias (_IO_old_fsetpos64, __old_fsetpos64) +compat_symbol (libc, __old_fsetpos64, fsetpos64, GLIBC_2_1); +#endif + +#endif diff --git a/REORG.TODO/libio/oldiopopen.c b/REORG.TODO/libio/oldiopopen.c new file mode 100644 index 0000000000..af7774ae90 --- /dev/null +++ b/REORG.TODO/libio/oldiopopen.c @@ -0,0 +1,299 @@ +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#define _IO_USE_OLD_IO_FILE +#ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +#endif +#include "libioP.h" +#include <signal.h> +#include <unistd.h> +#include <stdlib.h> +#ifdef _LIBC +# include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/wait.h> + +#ifndef _IO_fork +#ifdef _LIBC +#define _IO_fork __fork +#else +#define _IO_fork fork /* defined in libiberty, if needed */ +#endif +extern _IO_pid_t _IO_fork (void) __THROW; +#endif + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#ifndef _IO_pipe +#ifdef _LIBC +#define _IO_pipe __pipe +#else +#define _IO_pipe pipe +#endif +extern int _IO_pipe (int des[2]) __THROW; +#endif + +#ifndef _IO_dup2 +#ifdef _LIBC +#define _IO_dup2 __dup2 +#else +#define _IO_dup2 dup2 +#endif +extern int _IO_dup2 (int fd, int fd2) __THROW; +#endif + +#ifndef _IO_waitpid +#ifdef _LIBC +#define _IO_waitpid __waitpid +#else +#define _IO_waitpid waitpid +#endif +#endif + +#ifndef _IO_execl +#define _IO_execl execl +#endif +#ifndef _IO__exit +#define _IO__exit _exit +#endif + +#ifndef _IO_close +#ifdef _LIBC +#define _IO_close __close +#else +#define _IO_close close +#endif +#endif + +struct _IO_proc_file +{ + struct _IO_FILE_complete_plus file; + /* Following fields must match those in class procbuf (procbuf.h) */ + _IO_pid_t pid; + struct _IO_proc_file *next; +}; +typedef struct _IO_proc_file _IO_proc_file; + +static struct _IO_proc_file *old_proc_file_chain; + +#ifdef _IO_MTSAFE_IO +static _IO_lock_t proc_file_chain_lock = _IO_lock_initializer; + +static void +unlock (void *not_used) +{ + _IO_lock_unlock (proc_file_chain_lock); +} +#endif + +_IO_FILE * +attribute_compat_text_section +_IO_old_proc_open (_IO_FILE *fp, const char *command, const char *mode) +{ + volatile int read_or_write; + volatile int parent_end, child_end; + int pipe_fds[2]; + _IO_pid_t child_pid; + if (_IO_file_is_open (fp)) + return NULL; + if (_IO_pipe (pipe_fds) < 0) + return NULL; + if (mode[0] == 'r' && mode[1] == '\0') + { + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; + read_or_write = _IO_NO_WRITES; + } + else if (mode[0] == 'w' && mode[1] == '\0') + { + parent_end = pipe_fds[1]; + child_end = pipe_fds[0]; + read_or_write = _IO_NO_READS; + } + else + { + _IO_close (pipe_fds[0]); + _IO_close (pipe_fds[1]); + __set_errno (EINVAL); + return NULL; + } + ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + if (child_pid == 0) + { + int child_std_end = mode[0] == 'r' ? 1 : 0; + struct _IO_proc_file *p; + + _IO_close (parent_end); + if (child_end != child_std_end) + { + _IO_dup2 (child_end, child_std_end); + _IO_close (child_end); + } + /* POSIX.2: "popen() shall ensure that any streams from previous + popen() calls that remain open in the parent process are closed + in the new child process." */ + for (p = old_proc_file_chain; p; p = p->next) + _IO_close (_IO_fileno ((_IO_FILE *) p)); + + _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _IO__exit (127); + } + _IO_close (child_end); + if (child_pid < 0) + { + _IO_close (parent_end); + return NULL; + } + _IO_fileno (fp) = parent_end; + + /* Link into old_proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + ((_IO_proc_file *) fp)->next = old_proc_file_chain; + old_proc_file_chain = (_IO_proc_file *) fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + _IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES); + return fp; +} + +_IO_FILE * +attribute_compat_text_section +_IO_old_popen (const char *command, const char *mode) +{ + struct locked_FILE + { + struct _IO_proc_file fpx; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + } *new_f; + _IO_FILE *fp; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fpx.file.file._file._lock = &new_f->lock; +#endif + fp = &new_f->fpx.file.file._file; + _IO_old_init (fp, 0); + _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_old_proc_jumps; + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fpx.file); +#if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; +#endif + if (_IO_old_proc_open (fp, command, mode) != NULL) + return fp; + _IO_un_link ((struct _IO_FILE_plus *) &new_f->fpx.file); + free (new_f); + return NULL; +} + +int +attribute_compat_text_section +_IO_old_proc_close (_IO_FILE *fp) +{ + /* This is not name-space clean. FIXME! */ + int wstatus; + _IO_proc_file **ptr = &old_proc_file_chain; + _IO_pid_t wait_pid; + int status = -1; + + /* Unlink from old_proc_file_chain. */ +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (unlock); + _IO_lock_lock (proc_file_chain_lock); +#endif + for ( ; *ptr != NULL; ptr = &(*ptr)->next) + { + if (*ptr == (_IO_proc_file *) fp) + { + *ptr = (*ptr)->next; + status = 0; + break; + } + } +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (proc_file_chain_lock); + _IO_cleanup_region_end (0); +#endif + + if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + return -1; + /* POSIX.2 Rationale: "Some historical implementations either block + or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting + for the child process to terminate. Since this behavior is not + described in POSIX.2, such implementations are not conforming." */ + do + { + wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + } + while (wait_pid == -1 && errno == EINTR); + if (wait_pid == -1) + return -1; + return wstatus; +} + +const struct _IO_jump_t _IO_old_proc_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), + JUMP_INIT(overflow, _IO_old_file_overflow), + JUMP_INIT(underflow, _IO_old_file_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_default_pbackfail), + JUMP_INIT(xsputn, _IO_old_file_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_old_file_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_old_file_setbuf), + JUMP_INIT(sync, _IO_old_file_sync), + JUMP_INIT(doallocate, _IO_file_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_old_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_old_proc_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +strong_alias (_IO_old_popen, __old_popen) +compat_symbol (libc, _IO_old_popen, _IO_popen, GLIBC_2_0); +compat_symbol (libc, __old_popen, popen, GLIBC_2_0); +compat_symbol (libc, _IO_old_proc_open, _IO_proc_open, GLIBC_2_0); +compat_symbol (libc, _IO_old_proc_close, _IO_proc_close, GLIBC_2_0); + +#endif diff --git a/REORG.TODO/libio/oldpclose.c b/REORG.TODO/libio/oldpclose.c new file mode 100644 index 0000000000..7ce229fb5d --- /dev/null +++ b/REORG.TODO/libio/oldpclose.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1998-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" +#include "stdio.h" +#include <errno.h> + +int +attribute_compat_text_section +__old_pclose (FILE *fp) +{ +#if 0 + /* Does not actually test that stream was created by popen(). Instead, + it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ + if (fp is not a proc_file) + return -1; +#endif + return _IO_old_fclose (fp); +} + +compat_symbol (libc, __old_pclose, pclose, GLIBC_2_0); +#endif diff --git a/REORG.TODO/libio/oldstdfiles.c b/REORG.TODO/libio/oldstdfiles.c new file mode 100644 index 0000000000..bed7bceca2 --- /dev/null +++ b/REORG.TODO/libio/oldstdfiles.c @@ -0,0 +1,95 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr + for C code. Compare stdstreams.cc. + (The difference is that here the vtable field is set to 0, + so the objects defined are not valid C++ objects. On the other + hand, we don't need a C++ compiler to build this file.) */ + +#define _IO_USE_OLD_IO_FILE +#include "libioP.h" + +#ifdef _IO_MTSAFE_IO +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; +#else +#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps}; +#endif + +DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES); +DEF_STDFILE(_IO_stdout_, 1, &_IO_stdin_, _IO_NO_READS); +DEF_STDFILE(_IO_stderr_, 2, &_IO_stdout_, _IO_NO_READS+_IO_UNBUFFERED); + +#if defined __GNUC__ && __GNUC__ >= 2 + +#include <stdio.h> + +extern const int _IO_stdin_used; +weak_extern (_IO_stdin_used); + +#undef stdin +#undef stdout +#undef stderr + +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; + +static void _IO_check_libio (void) __THROW __attribute__ ((constructor)); + +/* This function determines which shared C library the application + was linked against. We then set up the stdin/stdout/stderr and + _IO_list_all accordingly. */ + +static void +_IO_check_libio (void) +{ + if (&_IO_stdin_used == NULL) + { + /* We are using the old one. */ + _IO_stdin = stdin = (_IO_FILE *) &_IO_stdin_; + _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_; + _IO_stderr = stderr = (_IO_FILE *) &_IO_stderr_; + _IO_list_all = &_IO_stderr_; + _IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset = + _IO_stderr->_vtable_offset = stdin->_vtable_offset = + stdout->_vtable_offset = stderr->_vtable_offset = + ((int) sizeof (struct _IO_FILE) + - (int) sizeof (struct _IO_FILE_complete)); + } +} + +#endif + +#endif diff --git a/REORG.TODO/libio/oldtmpfile.c b/REORG.TODO/libio/oldtmpfile.c new file mode 100644 index 0000000000..631e339472 --- /dev/null +++ b/REORG.TODO/libio/oldtmpfile.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +#define _IO_USE_OLD_IO_FILE +#include <stdio.h> +#include <unistd.h> +#include <iolibio.h> + +/* This returns a new stream opened on a temporary file (generated + by tmpnam). The file is opened with mode "w+b" (binary read/write). + If we couldn't generate a unique filename or the file couldn't + be opened, NULL is returned. */ +FILE * +attribute_compat_text_section +__old_tmpfile (void) +{ + char buf[FILENAME_MAX]; + int fd; + FILE *f; + + if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) + return NULL; + fd = __gen_tempname (buf, 0, 0, __GT_FILE); + if (fd < 0) + return NULL; + + /* Note that this relies on the Unix semantics that + a file is not really removed until it is closed. */ + (void) __unlink (buf); + + if ((f = _IO_old_fdopen (fd, "w+b")) == NULL) + __close (fd); + + return f; +} + +compat_symbol (libc, __old_tmpfile, tmpfile, GLIBC_2_0); +#endif diff --git a/REORG.TODO/libio/pclose.c b/REORG.TODO/libio/pclose.c new file mode 100644 index 0000000000..88256d2b04 --- /dev/null +++ b/REORG.TODO/libio/pclose.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" +#include <errno.h> +#include <shlib-compat.h> + +int +__new_pclose (FILE *fp) +{ +#if 0 + /* Does not actually test that stream was created by popen(). Instead, + it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ + if (fp is not a proc_file) + return -1; +#endif + return _IO_new_fclose (fp); +} + +versioned_symbol (libc, __new_pclose, pclose, GLIBC_2_1); diff --git a/REORG.TODO/libio/peekc.c b/REORG.TODO/libio/peekc.c new file mode 100644 index 0000000000..fca4a13a4b --- /dev/null +++ b/REORG.TODO/libio/peekc.c @@ -0,0 +1,41 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_peekc + +int +_IO_peekc_locked (_IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + result = _IO_peekc_unlocked (fp); + _IO_release_lock (fp); + return result; +} diff --git a/REORG.TODO/libio/putc.c b/REORG.TODO/libio/putc.c new file mode 100644 index 0000000000..b591c5538b --- /dev/null +++ b/REORG.TODO/libio/putc.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +#undef _IO_putc + +int +_IO_putc (int c, _IO_FILE *fp) +{ + int result; + CHECK_FILE (fp, EOF); + _IO_acquire_lock (fp); + result = _IO_putc_unlocked (c, fp); + _IO_release_lock (fp); + return result; +} +libc_hidden_def (_IO_putc) + +#undef putc + +#ifdef weak_alias +weak_alias (_IO_putc, putc) + +#ifndef _IO_MTSAFE_IO +#undef putc_unlocked +weak_alias (_IO_putc, putc_unlocked) +#endif +#endif diff --git a/REORG.TODO/libio/putc_u.c b/REORG.TODO/libio/putc_u.c new file mode 100644 index 0000000000..56a18691f2 --- /dev/null +++ b/REORG.TODO/libio/putc_u.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putc_unlocked + +int +putc_unlocked (int c, _IO_FILE *fp) +{ + CHECK_FILE (fp, EOF); + return _IO_putc_unlocked (c, fp); +} diff --git a/REORG.TODO/libio/putchar.c b/REORG.TODO/libio/putchar.c new file mode 100644 index 0000000000..39c580c60e --- /dev/null +++ b/REORG.TODO/libio/putchar.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putchar + +int +putchar (int c) +{ + int result; + _IO_acquire_lock (_IO_stdout); + result = _IO_putc_unlocked (c, _IO_stdout); + _IO_release_lock (_IO_stdout); + return result; +} + +#if defined weak_alias && !defined _IO_MTSAFE_IO +#undef putchar_unlocked +weak_alias (putchar, putchar_unlocked) +#endif diff --git a/REORG.TODO/libio/putchar_u.c b/REORG.TODO/libio/putchar_u.c new file mode 100644 index 0000000000..8395bbfa28 --- /dev/null +++ b/REORG.TODO/libio/putchar_u.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "stdio.h" + +#undef putchar_unlocked + +int +putchar_unlocked (int c) +{ + CHECK_FILE (_IO_stdout, EOF); + return _IO_putc_unlocked (c, _IO_stdout); +} diff --git a/REORG.TODO/libio/putwc.c b/REORG.TODO/libio/putwc.c new file mode 100644 index 0000000000..7193c2a027 --- /dev/null +++ b/REORG.TODO/libio/putwc.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwc (wchar_t wc, _IO_FILE *fp) +{ + wint_t result; + CHECK_FILE (fp, WEOF); + _IO_acquire_lock (fp); + result = _IO_putwc_unlocked (wc, fp); + _IO_release_lock (fp); + return result; +} +libc_hidden_def (putwc) diff --git a/REORG.TODO/libio/putwc_u.c b/REORG.TODO/libio/putwc_u.c new file mode 100644 index 0000000000..c0dead7be5 --- /dev/null +++ b/REORG.TODO/libio/putwc_u.c @@ -0,0 +1,27 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwc_unlocked (wchar_t wc, _IO_FILE *fp) +{ + CHECK_FILE (fp, WEOF); + return _IO_putwc_unlocked (wc, fp); +} +libc_hidden_def (putwc_unlocked) diff --git a/REORG.TODO/libio/putwchar.c b/REORG.TODO/libio/putwchar.c new file mode 100644 index 0000000000..5dd30b9e77 --- /dev/null +++ b/REORG.TODO/libio/putwchar.c @@ -0,0 +1,29 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwchar (wchar_t wc) +{ + wint_t result; + _IO_acquire_lock (_IO_stdout); + result = _IO_putwc_unlocked (wc, _IO_stdout); + _IO_release_lock (_IO_stdout); + return result; +} diff --git a/REORG.TODO/libio/putwchar_u.c b/REORG.TODO/libio/putwchar_u.c new file mode 100644 index 0000000000..382f0fa26a --- /dev/null +++ b/REORG.TODO/libio/putwchar_u.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include <wchar.h> + +wint_t +putwchar_unlocked (wchar_t wc) +{ + CHECK_FILE (_IO_stdout, WEOF); + return _IO_putwc_unlocked (wc, _IO_stdout); +} diff --git a/REORG.TODO/libio/rewind.c b/REORG.TODO/libio/rewind.c new file mode 100644 index 0000000000..5494eec64a --- /dev/null +++ b/REORG.TODO/libio/rewind.c @@ -0,0 +1,39 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <stdio.h> + +void +rewind (_IO_FILE *fp) +{ + CHECK_FILE (fp, ); + _IO_acquire_lock (fp); + _IO_rewind (fp); + _IO_clearerr (fp); + _IO_release_lock (fp); +} +libc_hidden_def (rewind) diff --git a/REORG.TODO/libio/setbuf.c b/REORG.TODO/libio/setbuf.c new file mode 100644 index 0000000000..dd0bae4ede --- /dev/null +++ b/REORG.TODO/libio/setbuf.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +void +setbuf (_IO_FILE *fp, char *buf) +{ + _IO_setbuffer (fp, buf, _IO_BUFSIZ); +} diff --git a/REORG.TODO/libio/setlinebuf.c b/REORG.TODO/libio/setlinebuf.c new file mode 100644 index 0000000000..5afb3d828a --- /dev/null +++ b/REORG.TODO/libio/setlinebuf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef setlinebuf + +void +setlinebuf (_IO_FILE *stream) +{ + _IO_setvbuf (stream, NULL, 1, 0); +} diff --git a/REORG.TODO/libio/stdfiles.c b/REORG.TODO/libio/stdfiles.c new file mode 100644 index 0000000000..218be40e60 --- /dev/null +++ b/REORG.TODO/libio/stdfiles.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + + +/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr + for C code. Compare stdstreams.cc. + (The difference is that here the vtable field is set to 0, + so the objects defined are not valid C++ objects. On the other + hand, we don't need a C++ compiler to build this file.) */ + +#include "libioP.h" + +#ifdef _IO_MTSAFE_IO +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &_IO_wfile_jumps }; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &_IO_file_jumps}; +# else +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ + &_IO_file_jumps}; +# endif +#else +# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + static struct _IO_wide_data _IO_wide_data_##FD \ + = { ._wide_vtable = &_IO_wfile_jumps }; \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ + &_IO_file_jumps}; +# else +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ + struct _IO_FILE_plus NAME \ + = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ + &_IO_file_jumps}; +# endif +#endif + +DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); +DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS); +DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED); + +struct _IO_FILE_plus *_IO_list_all = &_IO_2_1_stderr_; +libc_hidden_data_def (_IO_list_all) diff --git a/REORG.TODO/libio/stdio.c b/REORG.TODO/libio/stdio.c new file mode 100644 index 0000000000..3ff825241b --- /dev/null +++ b/REORG.TODO/libio/stdio.c @@ -0,0 +1,48 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef stdin +#undef stdout +#undef stderr +_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_; +_IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_; +_IO_FILE *stderr = (FILE *) &_IO_2_1_stderr_; + +#undef _IO_stdin +#undef _IO_stdout +#undef _IO_stderr +#ifdef _LIBC +# define AL(name) AL2 (name, _IO_##name) +# define AL2(name, al) \ + extern __typeof (name) al __attribute__ ((alias (#name), \ + visibility ("hidden"))) +AL(stdin); +AL(stdout); +AL(stderr); +#endif diff --git a/REORG.TODO/libio/stdio.h b/REORG.TODO/libio/stdio.h new file mode 100644 index 0000000000..47490c8299 --- /dev/null +++ b/REORG.TODO/libio/stdio.h @@ -0,0 +1,870 @@ +/* Define ISO C stdio on top of C++ iostreams. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + * ISO C99 Standard: 7.19 Input/output <stdio.h> + */ + +#ifndef _STDIO_H +#define _STDIO_H 1 + +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include <bits/libc-header-start.h> + +__BEGIN_DECLS + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + +#include <bits/types.h> +#include <bits/types/__FILE.h> +#include <bits/types/FILE.h> + +#define _STDIO_USES_IOSTREAM + +#include <libio.h> + +#if defined __USE_XOPEN || defined __USE_XOPEN2K8 +# ifdef __GNUC__ +# ifndef _VA_LIST_DEFINED +typedef _G_va_list va_list; +# define _VA_LIST_DEFINED +# endif +# else +# include <stdarg.h> +# endif +#endif + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K +# ifndef __off_t_defined +# ifndef __USE_FILE_OFFSET64 +typedef __off_t off_t; +# else +typedef __off64_t off_t; +# endif +# define __off_t_defined +# endif +# if defined __USE_LARGEFILE64 && !defined __off64_t_defined +typedef __off64_t off64_t; +# define __off64_t_defined +# endif +#endif + +#ifdef __USE_XOPEN2K8 +# ifndef __ssize_t_defined +typedef __ssize_t ssize_t; +# define __ssize_t_defined +# endif +#endif + +/* The type of the second argument to `fgetpos' and `fsetpos'. */ +#ifndef __USE_FILE_OFFSET64 +typedef _G_fpos_t fpos_t; +#else +typedef _G_fpos64_t fpos_t; +#endif +#ifdef __USE_LARGEFILE64 +typedef _G_fpos64_t fpos64_t; +#endif + +/* The possibilities for the third argument to `setvbuf'. */ +#define _IOFBF 0 /* Fully buffered. */ +#define _IOLBF 1 /* Line buffered. */ +#define _IONBF 2 /* No buffering. */ + + +/* Default buffer size. */ +#ifndef BUFSIZ +# define BUFSIZ _IO_BUFSIZ +#endif + + +/* End of file character. + Some things throughout the library rely on this being -1. */ +#ifndef EOF +# define EOF (-1) +#endif + + +/* The possibilities for the third argument to `fseek'. + These values should not be changed. */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Seek from end of file. */ +#ifdef __USE_GNU +# define SEEK_DATA 3 /* Seek to next data. */ +# define SEEK_HOLE 4 /* Seek to next hole. */ +#endif + + +#if defined __USE_MISC || defined __USE_XOPEN +/* Default path prefix for `tempnam' and `tmpnam'. */ +# define P_tmpdir "/tmp" +#endif + + +/* Get the values: + L_tmpnam How long an array of chars must be to be passed to `tmpnam'. + TMP_MAX The minimum number of unique filenames generated by tmpnam + (and tempnam when it uses tmpnam's name space), + or tempnam (the two are separate). + L_ctermid How long an array to pass to `ctermid'. + L_cuserid How long an array to pass to `cuserid'. + FOPEN_MAX Minimum number of files that can be open at once. + FILENAME_MAX Maximum length of a filename. */ +#include <bits/stdio_lim.h> + + +/* Standard streams. */ +extern struct _IO_FILE *stdin; /* Standard input stream. */ +extern struct _IO_FILE *stdout; /* Standard output stream. */ +extern struct _IO_FILE *stderr; /* Standard error output stream. */ +/* C89/C99 say they're macros. Make them happy. */ +#define stdin stdin +#define stdout stdout +#define stderr stderr + +/* Remove file FILENAME. */ +extern int remove (const char *__filename) __THROW; +/* Rename file OLD to NEW. */ +extern int rename (const char *__old, const char *__new) __THROW; + +#ifdef __USE_ATFILE +/* Rename file OLD relative to OLDFD to NEW relative to NEWFD. */ +extern int renameat (int __oldfd, const char *__old, int __newfd, + const char *__new) __THROW; +#endif + +/* Create a temporary file and open it read/write. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +#ifndef __USE_FILE_OFFSET64 +extern FILE *tmpfile (void) __wur; +#else +# ifdef __REDIRECT +extern FILE *__REDIRECT (tmpfile, (void), tmpfile64) __wur; +# else +# define tmpfile tmpfile64 +# endif +#endif + +#ifdef __USE_LARGEFILE64 +extern FILE *tmpfile64 (void) __wur; +#endif + +/* Generate a temporary filename. */ +extern char *tmpnam (char *__s) __THROW __wur; + +#ifdef __USE_MISC +/* This is the reentrant variant of `tmpnam'. The only difference is + that it does not allow S to be NULL. */ +extern char *tmpnam_r (char *__s) __THROW __wur; +#endif + + +#if defined __USE_MISC || defined __USE_XOPEN +/* Generate a unique temporary filename using up to five characters of PFX + if it is not NULL. The directory to put this file in is searched for + as follows: First the environment variable "TMPDIR" is checked. + If it contains the name of a writable directory, that directory is used. + If not and if DIR is not NULL, that value is checked. If that fails, + P_tmpdir is tried and finally "/tmp". The storage for the filename + is allocated by `malloc'. */ +extern char *tempnam (const char *__dir, const char *__pfx) + __THROW __attribute_malloc__ __wur; +#endif + + +/* Close STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fclose (FILE *__stream); +/* Flush STREAM, or all streams if STREAM is NULL. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fflush (FILE *__stream); + +#ifdef __USE_MISC +/* Faster versions when locking is not required. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern int fflush_unlocked (FILE *__stream); +#endif + +#ifdef __USE_GNU +/* Close all streams. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern int fcloseall (void); +#endif + + +#ifndef __USE_FILE_OFFSET64 +/* Open a file and create a new stream for it. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern FILE *fopen (const char *__restrict __filename, + const char *__restrict __modes) __wur; +/* Open a file, replacing an existing stream with it. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern FILE *freopen (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) __wur; +#else +# ifdef __REDIRECT +extern FILE *__REDIRECT (fopen, (const char *__restrict __filename, + const char *__restrict __modes), fopen64) + __wur; +extern FILE *__REDIRECT (freopen, (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream), freopen64) + __wur; +# else +# define fopen fopen64 +# define freopen freopen64 +# endif +#endif +#ifdef __USE_LARGEFILE64 +extern FILE *fopen64 (const char *__restrict __filename, + const char *__restrict __modes) __wur; +extern FILE *freopen64 (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) __wur; +#endif + +#ifdef __USE_POSIX +/* Create a new stream that refers to an existing system file descriptor. */ +extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; +#endif + +#ifdef __USE_GNU +/* Create a new stream that refers to the given magic cookie, + and uses the given functions for input and output. */ +extern FILE *fopencookie (void *__restrict __magic_cookie, + const char *__restrict __modes, + _IO_cookie_io_functions_t __io_funcs) __THROW __wur; +#endif + +#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) +/* Create a new stream that refers to a memory buffer. */ +extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) + __THROW __wur; + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW __wur; +#endif + + +/* If BUF is NULL, make STREAM unbuffered. + Else make it use buffer BUF, of size BUFSIZ. */ +extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; +/* Make STREAM use buffering mode MODE. + If BUF is not NULL, use N bytes of it for buffering; + else allocate an internal buffer N bytes long. */ +extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, + int __modes, size_t __n) __THROW; + +#ifdef __USE_MISC +/* If BUF is NULL, make STREAM unbuffered. + Else make it use SIZE bytes of BUF for buffering. */ +extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, + size_t __size) __THROW; + +/* Make STREAM line-buffered. */ +extern void setlinebuf (FILE *__stream) __THROW; +#endif + + +/* Write formatted output to STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fprintf (FILE *__restrict __stream, + const char *__restrict __format, ...); +/* Write formatted output to stdout. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int printf (const char *__restrict __format, ...); +/* Write formatted output to S. */ +extern int sprintf (char *__restrict __s, + const char *__restrict __format, ...) __THROWNL; + +/* Write formatted output to S from argument list ARG. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, + _G_va_list __arg); +/* Write formatted output to stdout from argument list ARG. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int vprintf (const char *__restrict __format, _G_va_list __arg); +/* Write formatted output to S from argument list ARG. */ +extern int vsprintf (char *__restrict __s, const char *__restrict __format, + _G_va_list __arg) __THROWNL; + +#if defined __USE_ISOC99 || defined __USE_UNIX98 +/* Maximum chars of output to write in MAXLEN. */ +extern int snprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int vsnprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, _G_va_list __arg) + __THROWNL __attribute__ ((__format__ (__printf__, 3, 0))); +#endif + +#if __GLIBC_USE (LIB_EXT2) +/* Write formatted output to a string dynamically allocated with `malloc'. + Store the address of the string in *PTR. */ +extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, + _G_va_list __arg) + __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))) __wur; +extern int __asprintf (char **__restrict __ptr, + const char *__restrict __fmt, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))) __wur; +extern int asprintf (char **__restrict __ptr, + const char *__restrict __fmt, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))) __wur; +#endif + +#ifdef __USE_XOPEN2K8 +/* Write formatted output to a file descriptor. */ +extern int vdprintf (int __fd, const char *__restrict __fmt, + _G_va_list __arg) + __attribute__ ((__format__ (__printf__, 2, 0))); +extern int dprintf (int __fd, const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +#endif + + +/* Read formatted input from STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fscanf (FILE *__restrict __stream, + const char *__restrict __format, ...) __wur; +/* Read formatted input from stdin. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int scanf (const char *__restrict __format, ...) __wur; +/* Read formatted input from S. */ +extern int sscanf (const char *__restrict __s, + const char *__restrict __format, ...) __THROW; + +#if defined __USE_ISOC99 && !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ + GNU extension which conflicts with valid %a followed by letter + s, S or [. */ +extern int __REDIRECT (fscanf, (FILE *__restrict __stream, + const char *__restrict __format, ...), + __isoc99_fscanf) __wur; +extern int __REDIRECT (scanf, (const char *__restrict __format, ...), + __isoc99_scanf) __wur; +extern int __REDIRECT_NTH (sscanf, (const char *__restrict __s, + const char *__restrict __format, ...), + __isoc99_sscanf); +# else +extern int __isoc99_fscanf (FILE *__restrict __stream, + const char *__restrict __format, ...) __wur; +extern int __isoc99_scanf (const char *__restrict __format, ...) __wur; +extern int __isoc99_sscanf (const char *__restrict __s, + const char *__restrict __format, ...) __THROW; +# define fscanf __isoc99_fscanf +# define scanf __isoc99_scanf +# define sscanf __isoc99_sscanf +# endif +#endif + +#ifdef __USE_ISOC99 +/* Read formatted input from S into argument list ARG. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, + _G_va_list __arg) + __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; + +/* Read formatted input from stdin into argument list ARG. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int vscanf (const char *__restrict __format, _G_va_list __arg) + __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; + +/* Read formatted input from S into argument list ARG. */ +extern int vsscanf (const char *__restrict __s, + const char *__restrict __format, _G_va_list __arg) + __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); + +# if !defined __USE_GNU \ + && (!defined __LDBL_COMPAT || !defined __REDIRECT) \ + && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) +# ifdef __REDIRECT +/* For strict ISO C99 or POSIX compliance disallow %as, %aS and %a[ + GNU extension which conflicts with valid %a followed by letter + s, S or [. */ +extern int __REDIRECT (vfscanf, + (FILE *__restrict __s, + const char *__restrict __format, _G_va_list __arg), + __isoc99_vfscanf) + __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; +extern int __REDIRECT (vscanf, (const char *__restrict __format, + _G_va_list __arg), __isoc99_vscanf) + __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; +extern int __REDIRECT_NTH (vsscanf, + (const char *__restrict __s, + const char *__restrict __format, + _G_va_list __arg), __isoc99_vsscanf) + __attribute__ ((__format__ (__scanf__, 2, 0))); +# else +extern int __isoc99_vfscanf (FILE *__restrict __s, + const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vscanf (const char *__restrict __format, + _G_va_list __arg) __wur; +extern int __isoc99_vsscanf (const char *__restrict __s, + const char *__restrict __format, + _G_va_list __arg) __THROW; +# define vfscanf __isoc99_vfscanf +# define vscanf __isoc99_vscanf +# define vsscanf __isoc99_vsscanf +# endif +# endif +#endif /* Use ISO C9x. */ + + +/* Read a character from STREAM. + + These functions are possible cancellation points and therefore not + marked with __THROW. */ +extern int fgetc (FILE *__stream); +extern int getc (FILE *__stream); + +/* Read a character from stdin. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int getchar (void); + +/* The C standard explicitly says this is a macro, so we always do the + optimization for it. */ +#define getc(_fp) _IO_getc (_fp) + +#ifdef __USE_POSIX199506 +/* These are defined in POSIX.1:1996. + + These functions are possible cancellation points and therefore not + marked with __THROW. */ +extern int getc_unlocked (FILE *__stream); +extern int getchar_unlocked (void); +#endif /* Use POSIX. */ + +#ifdef __USE_MISC +/* Faster version when locking is not necessary. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern int fgetc_unlocked (FILE *__stream); +#endif /* Use MISC. */ + + +/* Write a character to STREAM. + + These functions are possible cancellation points and therefore not + marked with __THROW. + + These functions is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fputc (int __c, FILE *__stream); +extern int putc (int __c, FILE *__stream); + +/* Write a character to stdout. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int putchar (int __c); + +/* The C standard explicitly says this can be a macro, + so we always do the optimization for it. */ +#define putc(_ch, _fp) _IO_putc (_ch, _fp) + +#ifdef __USE_MISC +/* Faster version when locking is not necessary. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern int fputc_unlocked (int __c, FILE *__stream); +#endif /* Use MISC. */ + +#ifdef __USE_POSIX199506 +/* These are defined in POSIX.1:1996. + + These functions are possible cancellation points and therefore not + marked with __THROW. */ +extern int putc_unlocked (int __c, FILE *__stream); +extern int putchar_unlocked (int __c); +#endif /* Use POSIX. */ + + +#if defined __USE_MISC \ + || (defined __USE_XOPEN && !defined __USE_XOPEN2K) +/* Get a word (int) from STREAM. */ +extern int getw (FILE *__stream); + +/* Write a word (int) to STREAM. */ +extern int putw (int __w, FILE *__stream); +#endif + + +/* Get a newline-terminated string of finite length from STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + __wur; + +#if __GLIBC_USE (DEPRECATED_GETS) +/* Get a newline-terminated string from stdin, removing the newline. + + This function is impossible to use safely. It has been officially + removed from ISO C11 and ISO C++14, and we have also removed it + from the _GNU_SOURCE feature list. It remains available when + explicitly using an old ISO C, Unix, or POSIX standard. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern char *gets (char *__s) __wur __attribute_deprecated__; +#endif + +#ifdef __USE_GNU +/* This function does the same as `fgets' but does not lock the stream. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern char *fgets_unlocked (char *__restrict __s, int __n, + FILE *__restrict __stream) __wur; +#endif + + +#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) +/* Read up to (and including) a DELIMITER from STREAM into *LINEPTR + (and null-terminate it). *LINEPTR is a pointer returned from malloc (or + NULL), pointing to *N characters of space. It is realloc'd as + necessary. Returns the number of characters read (not including the + null terminator), or -1 on error or EOF. + + These functions are not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation they are cancellation points and + therefore not marked with __THROW. */ +extern _IO_ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __wur; +extern _IO_ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __wur; + +/* Like `getdelim', but reads up to a newline. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern _IO_ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) __wur; +#endif + + +/* Write a string to STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fputs (const char *__restrict __s, FILE *__restrict __stream); + +/* Write a string, followed by a newline, to stdout. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int puts (const char *__s); + + +/* Push a character back onto the input buffer of STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int ungetc (int __c, FILE *__stream); + + +/* Read chunks of generic data from STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) __wur; +/* Write chunks of generic data to STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern size_t fwrite (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s); + +#ifdef __USE_GNU +/* This function does the same as `fputs' but does not lock the stream. + + This function is not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation it is a cancellation point and + therefore not marked with __THROW. */ +extern int fputs_unlocked (const char *__restrict __s, + FILE *__restrict __stream); +#endif + +#ifdef __USE_MISC +/* Faster versions when locking is not necessary. + + These functions are not part of POSIX and therefore no official + cancellation point. But due to similarity with an POSIX interface + or due to the implementation they are cancellation points and + therefore not marked with __THROW. */ +extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) __wur; +extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream); +#endif + + +/* Seek to a certain position on STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fseek (FILE *__stream, long int __off, int __whence); +/* Return the current position of STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern long int ftell (FILE *__stream) __wur; +/* Rewind to the beginning of STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern void rewind (FILE *__stream); + +/* The Single Unix Specification, Version 2, specifies an alternative, + more adequate interface for the two functions above which deal with + file offset. `long int' is not the right type. These definitions + are originally defined in the Large File Support API. */ + +#if defined __USE_LARGEFILE || defined __USE_XOPEN2K +# ifndef __USE_FILE_OFFSET64 +/* Seek to a certain position on STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fseeko (FILE *__stream, __off_t __off, int __whence); +/* Return the current position of STREAM. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern __off_t ftello (FILE *__stream) __wur; +# else +# ifdef __REDIRECT +extern int __REDIRECT (fseeko, + (FILE *__stream, __off64_t __off, int __whence), + fseeko64); +extern __off64_t __REDIRECT (ftello, (FILE *__stream), ftello64); +# else +# define fseeko fseeko64 +# define ftello ftello64 +# endif +# endif +#endif + +#ifndef __USE_FILE_OFFSET64 +/* Get STREAM's position. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); +/* Set STREAM's position. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int fsetpos (FILE *__stream, const fpos_t *__pos); +#else +# ifdef __REDIRECT +extern int __REDIRECT (fgetpos, (FILE *__restrict __stream, + fpos_t *__restrict __pos), fgetpos64); +extern int __REDIRECT (fsetpos, + (FILE *__stream, const fpos_t *__pos), fsetpos64); +# else +# define fgetpos fgetpos64 +# define fsetpos fsetpos64 +# endif +#endif + +#ifdef __USE_LARGEFILE64 +extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); +extern __off64_t ftello64 (FILE *__stream) __wur; +extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); +extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); +#endif + +/* Clear the error and EOF indicators for STREAM. */ +extern void clearerr (FILE *__stream) __THROW; +/* Return the EOF indicator for STREAM. */ +extern int feof (FILE *__stream) __THROW __wur; +/* Return the error indicator for STREAM. */ +extern int ferror (FILE *__stream) __THROW __wur; + +#ifdef __USE_MISC +/* Faster versions when locking is not required. */ +extern void clearerr_unlocked (FILE *__stream) __THROW; +extern int feof_unlocked (FILE *__stream) __THROW __wur; +extern int ferror_unlocked (FILE *__stream) __THROW __wur; +#endif + + +/* Print a message describing the meaning of the value of errno. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern void perror (const char *__s); + +/* Provide the declarations for `sys_errlist' and `sys_nerr' if they + are available on this system. Even if available, these variables + should not be used directly. The `strerror' function provides + all the necessary functionality. */ +#include <bits/sys_errlist.h> + + +#ifdef __USE_POSIX +/* Return the system file descriptor for STREAM. */ +extern int fileno (FILE *__stream) __THROW __wur; +#endif /* Use POSIX. */ + +#ifdef __USE_MISC +/* Faster version when locking is not required. */ +extern int fileno_unlocked (FILE *__stream) __THROW __wur; +#endif + + +#ifdef __USE_POSIX2 +/* Create a new stream connected to a pipe running the given command. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern FILE *popen (const char *__command, const char *__modes) __wur; + +/* Close a stream opened by popen and return the status of its child. + + This function is a possible cancellation point and therefore not + marked with __THROW. */ +extern int pclose (FILE *__stream); +#endif + + +#ifdef __USE_POSIX +/* Return the name of the controlling terminal. */ +extern char *ctermid (char *__s) __THROW; +#endif /* Use POSIX. */ + + +#if (defined __USE_XOPEN && !defined __USE_XOPEN2K) || defined __USE_GNU +/* Return the name of the current user. */ +extern char *cuserid (char *__s); +#endif /* Use X/Open, but not issue 6. */ + + +#ifdef __USE_GNU +struct obstack; /* See <obstack.h>. */ + +/* Write formatted output to an obstack. */ +extern int obstack_printf (struct obstack *__restrict __obstack, + const char *__restrict __format, ...) + __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))); +extern int obstack_vprintf (struct obstack *__restrict __obstack, + const char *__restrict __format, + _G_va_list __args) + __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))); +#endif /* Use GNU. */ + + +#ifdef __USE_POSIX199506 +/* These are defined in POSIX.1:1996. */ + +/* Acquire ownership of STREAM. */ +extern void flockfile (FILE *__stream) __THROW; + +/* Try to acquire ownership of STREAM but do not block if it is not + possible. */ +extern int ftrylockfile (FILE *__stream) __THROW __wur; + +/* Relinquish the ownership granted for STREAM. */ +extern void funlockfile (FILE *__stream) __THROW; +#endif /* POSIX */ + +#if defined __USE_XOPEN && !defined __USE_XOPEN2K && !defined __USE_GNU +/* X/Open Issues 1-5 required getopt to be declared in this + header. It was removed in Issue 6. GNU follows Issue 6. */ +# include <bits/getopt_posix.h> +#endif + +/* If we are compiling with optimizing read this file. It contains + several optimizing inline functions and macros. */ +#ifdef __USE_EXTERN_INLINES +# include <bits/stdio.h> +#endif +#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function +# include <bits/stdio2.h> +#endif +#ifdef __LDBL_COMPAT +# include <bits/stdio-ldbl.h> +#endif + +__END_DECLS + +#endif /* <stdio.h> included. */ diff --git a/REORG.TODO/libio/strfile.h b/REORG.TODO/libio/strfile.h new file mode 100644 index 0000000000..74bd4eb269 --- /dev/null +++ b/REORG.TODO/libio/strfile.h @@ -0,0 +1,85 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <libio.h> +#ifdef TODO +Merge into libio.h ? +#endif + +typedef void *(*_IO_alloc_type) (_IO_size_t); +typedef void (*_IO_free_type) (void*); + +struct _IO_str_fields +{ + _IO_alloc_type _allocate_buffer; + _IO_free_type _free_buffer; +}; + +/* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type, + but a 32 bit pointer type. In this case, we get 4 bytes of padding + after the vtable pointer. Putting them in a structure together solves + this problem. */ + +struct _IO_streambuf +{ + struct _IO_FILE _f; + const struct _IO_jump_t *vtable; +}; + +typedef struct _IO_strfile_ +{ + struct _IO_streambuf _sbf; + struct _IO_str_fields _s; +} _IO_strfile; + +/* dynamic: set when the array object is allocated (or reallocated) as + necessary to hold a character sequence that can change in length. */ +#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0) + +/* frozen: set when the program has requested that the array object not + be altered, reallocated, or freed. */ +#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF) + +typedef struct +{ + _IO_strfile f; + /* This is used for the characters which do not fit in the buffer + provided by the user. */ + char overflow_buf[64]; +} _IO_strnfile; + +extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden; + + +typedef struct +{ + _IO_strfile f; + /* This is used for the characters which do not fit in the buffer + provided by the user. */ + wchar_t overflow_buf[64]; +} _IO_wstrnfile; + +extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden; diff --git a/REORG.TODO/libio/strops.c b/REORG.TODO/libio/strops.c new file mode 100644 index 0000000000..d72a47c649 --- /dev/null +++ b/REORG.TODO/libio/strops.c @@ -0,0 +1,377 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <assert.h> +#include "strfile.h" +#include "libioP.h" +#include <string.h> +#include <stdio_ext.h> + +void +_IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size, + char *pstart) +{ + _IO_FILE *fp = &sf->_sbf._f; + char *end; + + if (size == 0) + end = __rawmemchr (ptr, '\0'); + else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr) + end = ptr + size; + else + end = (char *) -1; + _IO_setb (fp, ptr, end, 0); + + fp->_IO_write_base = ptr; + fp->_IO_read_base = ptr; + fp->_IO_read_ptr = ptr; + if (pstart) + { + fp->_IO_write_ptr = pstart; + fp->_IO_write_end = end; + fp->_IO_read_end = pstart; + } + else + { + fp->_IO_write_ptr = ptr; + fp->_IO_write_end = ptr; + fp->_IO_read_end = end; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + sf->_s._allocate_buffer = (_IO_alloc_type) 0; +} + +void +_IO_str_init_static (_IO_strfile *sf, char *ptr, int size, char *pstart) +{ + return _IO_str_init_static_internal (sf, ptr, size < 0 ? -1 : size, pstart); +} + +void +_IO_str_init_readonly (_IO_strfile *sf, const char *ptr, int size) +{ + _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL); + sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES; +} + +int +_IO_str_overflow (_IO_FILE *fp, int c) +{ + int flush_only = c == EOF; + _IO_size_t pos; + if (fp->_flags & _IO_NO_WRITES) + return flush_only ? 0 : EOF; + if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags |= _IO_CURRENTLY_PUTTING; + fp->_IO_write_ptr = fp->_IO_read_ptr; + fp->_IO_read_ptr = fp->_IO_read_end; + } + pos = fp->_IO_write_ptr - fp->_IO_write_base; + if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only)) + { + if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + return EOF; + else + { + char *new_buf; + char *old_buf = fp->_IO_buf_base; + size_t old_blen = _IO_blen (fp); + _IO_size_t new_size = 2 * old_blen + 100; + if (new_size < old_blen) + return EOF; + new_buf + = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size); + if (new_buf == NULL) + { + /* __ferror(fp) = 1; */ + return EOF; + } + if (old_buf) + { + memcpy (new_buf, old_buf, old_blen); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + /* Make sure _IO_setb won't try to delete _IO_buf_base. */ + fp->_IO_buf_base = NULL; + } + memset (new_buf + old_blen, '\0', new_size - old_blen); + + _IO_setb (fp, new_buf, new_buf + new_size, 1); + fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf); + fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf); + fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf); + fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf); + + fp->_IO_write_base = new_buf; + fp->_IO_write_end = fp->_IO_buf_end; + } + } + + if (!flush_only) + *fp->_IO_write_ptr++ = (unsigned char) c; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + return c; +} +libc_hidden_def (_IO_str_overflow) + +int +_IO_str_underflow (_IO_FILE *fp) +{ + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + fp->_IO_read_ptr = fp->_IO_write_ptr; + fp->_IO_write_ptr = fp->_IO_write_end; + } + if (fp->_IO_read_ptr < fp->_IO_read_end) + return *((unsigned char *) fp->_IO_read_ptr); + else + return EOF; +} +libc_hidden_def (_IO_str_underflow) + +/* The size of the valid part of the buffer. */ + +_IO_ssize_t +_IO_str_count (_IO_FILE *fp) +{ + return ((fp->_IO_write_ptr > fp->_IO_read_end + ? fp->_IO_write_ptr : fp->_IO_read_end) + - fp->_IO_read_base); +} + + +static int +enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) +{ + if ((_IO_ssize_t) offset <= _IO_blen (fp)) + return 0; + + _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base; + + /* Try to enlarge the buffer. */ + if (fp->_flags & _IO_USER_BUF) + /* User-provided buffer. */ + return 1; + + _IO_size_t newsize = offset + 100; + char *oldbuf = fp->_IO_buf_base; + char *newbuf + = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize); + if (newbuf == NULL) + return 1; + + if (oldbuf != NULL) + { + memcpy (newbuf, oldbuf, _IO_blen (fp)); + (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); + /* Make sure _IO_setb won't try to delete + _IO_buf_base. */ + fp->_IO_buf_base = NULL; + } + + _IO_setb (fp, newbuf, newbuf + newsize, 1); + + if (reading) + { + fp->_IO_write_base = newbuf + (fp->_IO_write_base - oldbuf); + fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf); + fp->_IO_write_end = newbuf + (fp->_IO_write_end - oldbuf); + fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf); + + fp->_IO_read_base = newbuf; + fp->_IO_read_end = fp->_IO_buf_end; + } + else + { + fp->_IO_read_base = newbuf + (fp->_IO_read_base - oldbuf); + fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf); + fp->_IO_read_end = newbuf + (fp->_IO_read_end - oldbuf); + fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf); + + fp->_IO_write_base = newbuf; + fp->_IO_write_end = fp->_IO_buf_end; + } + + /* Clear the area between the last write position and th + new position. */ + assert (offset >= oldend); + if (reading) + memset (fp->_IO_read_base + oldend, '\0', offset - oldend); + else + memset (fp->_IO_write_base + oldend, '\0', offset - oldend); + + return 0; +} + +static void +_IO_str_switch_to_get_mode (_IO_FILE *fp) +{ + if (_IO_in_backup (fp)) + fp->_IO_read_base = fp->_IO_backup_base; + else + { + fp->_IO_read_base = fp->_IO_buf_base; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + } + fp->_IO_read_ptr = fp->_IO_read_end = fp->_IO_write_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; +} + +_IO_off64_t +_IO_str_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t new_pos; + + if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) + mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + if (was_writing) + _IO_str_switch_to_get_mode (fp); + + if (mode == 0) + { + new_pos = fp->_IO_read_ptr - fp->_IO_read_base; + } + else + { + _IO_ssize_t cur_size = _IO_str_count(fp); + new_pos = EOF; + + /* Move the get pointer, if requested. */ + if (mode & _IOS_INPUT) + { + _IO_ssize_t base; + switch (dir) + { + case _IO_seek_set: + base = 0; + break; + case _IO_seek_cur: + base = fp->_IO_read_ptr - fp->_IO_read_base; + break; + default: /* case _IO_seek_end: */ + base = cur_size; + break; + } + _IO_ssize_t maxval = SSIZE_MAX - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 1) != 0) + return EOF; + fp->_IO_read_ptr = fp->_IO_read_base + base; + fp->_IO_read_end = fp->_IO_read_base + cur_size; + new_pos = base; + } + + /* Move the put pointer, if requested. */ + if (mode & _IOS_OUTPUT) + { + _IO_ssize_t base; + switch (dir) + { + case _IO_seek_set: + base = 0; + break; + case _IO_seek_cur: + base = fp->_IO_write_ptr - fp->_IO_write_base; + break; + default: /* case _IO_seek_end: */ + base = cur_size; + break; + } + _IO_ssize_t maxval = SSIZE_MAX - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 0) != 0) + return EOF; + fp->_IO_write_ptr = fp->_IO_write_base + base; + new_pos = base; + } + } + return new_pos; +} +libc_hidden_def (_IO_str_seekoff) + +int +_IO_str_pbackfail (_IO_FILE *fp, int c) +{ + if ((fp->_flags & _IO_NO_WRITES) && c != EOF) + return EOF; + return _IO_default_pbackfail (fp, c); +} +libc_hidden_def (_IO_str_pbackfail) + +void +_IO_str_finish (_IO_FILE *fp, int dummy) +{ + if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base); + fp->_IO_buf_base = NULL; + + _IO_default_finish (fp, 0); +} + +const struct _IO_jump_t _IO_str_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, _IO_str_overflow), + JUMP_INIT(underflow, _IO_str_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_str_pbackfail), + JUMP_INIT(xsputn, _IO_default_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_str_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_default_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/REORG.TODO/libio/swprintf.c b/REORG.TODO/libio/swprintf.c new file mode 100644 index 0000000000..038f67b04c --- /dev/null +++ b/REORG.TODO/libio/swprintf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <wchar.h> + +/* Write formatted output into S, according to the format string FORMAT. */ +/* VARARGS3 */ +int +__swprintf (wchar_t *s, size_t n, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vswprintf (s, n, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (__swprintf, swprintf) diff --git a/REORG.TODO/libio/swscanf.c b/REORG.TODO/libio/swscanf.c new file mode 100644 index 0000000000..f3753e5de2 --- /dev/null +++ b/REORG.TODO/libio/swscanf.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <wchar.h> + +/* Read formatted input from S, according to the format string FORMAT. */ +/* VARARGS2 */ +int +__swscanf (const wchar_t *s, const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vswscanf (s, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (__swscanf, swscanf) diff --git a/REORG.TODO/libio/test-fmemopen.c b/REORG.TODO/libio/test-fmemopen.c new file mode 100644 index 0000000000..b02637b676 --- /dev/null +++ b/REORG.TODO/libio/test-fmemopen.c @@ -0,0 +1,100 @@ +/* Test for fmemopen implementation. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Hanno Mueller, kontakt@hanno.de, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +static char buffer[] = "foobar"; + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <mcheck.h> + +static int +do_bz18820 (void) +{ + char ch; + FILE *stream; + + errno = 0; + stream = fmemopen (&ch, 1, "?"); + if (stream) + { + printf ("fmemopen: expected NULL, got %p\n", stream); + fclose (stream); + return 1; + } + if (errno != EINVAL) + { + printf ("fmemopen: got %i, expected EINVAL (%i)\n", errno, EINVAL); + return 10; + } + + stream = fmemopen (NULL, 42, "?"); + if (stream) + { + printf ("fmemopen: expected NULL, got %p\n", stream); + fclose (stream); + return 2; + } + + errno = 0; + stream = fmemopen (NULL, ~0, "w"); + if (stream) + { + printf ("fmemopen: expected NULL, got %p\n", stream); + fclose (stream); + return 3; + } + if (errno != ENOMEM) + { + printf ("fmemopen: got %i, expected ENOMEM (%i)\n", errno, ENOMEM); + return 20; + } + + return 0; +} + +static int +do_test (void) +{ + int ch; + FILE *stream; + int ret = 0; + + mtrace (); + + stream = fmemopen (buffer, strlen (buffer), "r+"); + + while ((ch = fgetc (stream)) != EOF) + printf ("Got %c\n", ch); + + fputc ('1', stream); + if (fflush (stream) != EOF || errno != ENOSPC) + { + printf ("fflush didn't fail with ENOSPC\n"); + ret = 1; + } + + fclose (stream); + + return ret + do_bz18820 (); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/test-freopen.c b/REORG.TODO/libio/test-freopen.c new file mode 100644 index 0000000000..fcf990d205 --- /dev/null +++ b/REORG.TODO/libio/test-freopen.c @@ -0,0 +1,56 @@ +/* Test for freopen implementation. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> + + +int +main (int argc, char *argv[]) +{ + FILE *fp; + + mtrace (); + + if (argc < 2) + exit (1); + + fp = fopen (argv[1], "w"); + if (fp == NULL) + { + puts ("fopen failed: %m"); + exit (1); + } + + fputs ("Hello world (mb)\n", fp); + + fp = freopen (argv[1], "a+", fp); + if (fp == NULL) + { + puts ("freopen failed: %m"); + exit (1); + } + + fputws (L"Hello world (wc)\n", fp); + + fclose (fp); + + return 0; +} diff --git a/REORG.TODO/libio/test-freopen.sh b/REORG.TODO/libio/test-freopen.sh new file mode 100755 index 0000000000..d8a838fab7 --- /dev/null +++ b/REORG.TODO/libio/test-freopen.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Test of freopen. +# Copyright (C) 2000-2017 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# <http://www.gnu.org/licenses/>. + +set -e + +common_objpfx=$1 +test_program_prefix=$2 +objpfx=$3 + +${test_program_prefix} ${objpfx}test-freopen ${objpfx}test-freopen.out && +cmp ${objpfx}test-freopen.out - <<"EOF" +Hello world (mb) +Hello world (wc) +EOF + +exit $? diff --git a/REORG.TODO/libio/tst-atime.c b/REORG.TODO/libio/tst-atime.c new file mode 100644 index 0000000000..31ca59fec5 --- /dev/null +++ b/REORG.TODO/libio/tst-atime.c @@ -0,0 +1,120 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/statvfs.h> + + +static int do_test (void); +#define TEST_FUNCTION do_test () +#define TIMEOUT 5 +#include <test-skeleton.c> + + +static int +do_test (void) +{ + char *buf; + int fd; + FILE *fp; + int ch; + struct stat st1; + struct stat st2; + + buf = (char *) malloc (strlen (test_dir) + sizeof "/tst-atime.XXXXXX"); + if (buf == NULL) + { + printf ("cannot allocate memory: %m\n"); + return 1; + } + stpcpy (stpcpy (buf, test_dir), "/tst-atime.XXXXXX"); + + fd = mkstemp (buf); + if (fd == -1) + { + printf ("cannot open temporary file: %m\n"); + return 1; + } + +#ifdef ST_NOATIME + /* Make sure the filesystem doesn't have the noatime option set. If + statvfs is not available just continue. */ + struct statvfs sv; + int e = fstatvfs (fd, &sv); + if (e != ENOSYS) + { + if (e != 0) + { + printf ("cannot statvfs '%s': %m\n", buf); + return 1; + } + + if ((sv.f_flag & ST_NOATIME) != 0) + { + puts ("Bah! The filesystem is mounted with noatime"); + return 0; + } + } +#endif + + /* Make sure it gets removed. */ + add_temp_file (buf); + + if (write (fd, "some string\n", 12) != 12) + { + printf ("cannot write temporary file: %m\n"); + return 1; + } + + if (lseek (fd, 0, SEEK_SET) == (off_t) -1) + { + printf ("cannot reposition temporary file: %m\n"); + return 1; + } + + fp = fdopen (fd, "r"); + if (fp == NULL) + { + printf ("cannot create stream: %m\n"); + return 1; + } + + if (fstat (fd, &st1) == -1) + { + printf ("first stat failed: %m\n"); + return 1; + } + + sleep (2); + + ch = fgetc (fp); + if (ch != 's') + { + printf ("did not read correct character: got '%c', expected 's'\n", ch); + return 1; + } + + if (fstat (fd, &st2) == -1) + { + printf ("second stat failed: %m\n"); + return 1; + } + + if (st1.st_atime > st2.st_atime) + { + puts ("second atime smaller"); + return 1; + } + else if (st1.st_atime == st2.st_atime) + { + puts ("atime has not changed"); + return 1; + } + + fclose (fp); + + return 0; +} diff --git a/REORG.TODO/libio/tst-eof.c b/REORG.TODO/libio/tst-eof.c new file mode 100644 index 0000000000..6baa122ce3 --- /dev/null +++ b/REORG.TODO/libio/tst-eof.c @@ -0,0 +1,75 @@ +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + + +int fd; + + +static void +do_prepare (void) +{ + fd = create_temp_file ("tst-eof.", NULL); + if (fd == -1) + { + printf ("cannot create temporary file: %m\n"); + exit (1); + } +} + + +static int +do_test (void) +{ + char buf[40]; + FILE *fp; + + if (write (fd, "some string\n", 12) != 12) + { + printf ("cannot write temporary file: %m\n"); + return 1; + } + + if (lseek (fd, 0, SEEK_SET) == (off_t) -1) + { + printf ("cannot reposition temporary file: %m\n"); + return 1; + } + + fp = fdopen (fd, "r"); + if (fp == NULL) + { + printf ("cannot create stream: %m\n"); + return 1; + } + + if (feof (fp)) + { + puts ("EOF set after fdopen"); + return 1; + } + + if (fread (buf, 1, 20, fp) != 12) + { + puts ("didn't read the correct number of bytes"); + return 1; + } + + if (! feof (fp)) + { + puts ("EOF not set after fread"); + return 1; + } + + fclose (fp); + + return 0; +} diff --git a/REORG.TODO/libio/tst-ext.c b/REORG.TODO/libio/tst-ext.c new file mode 100644 index 0000000000..f69fbe6f21 --- /dev/null +++ b/REORG.TODO/libio/tst-ext.c @@ -0,0 +1,141 @@ +#include <stdio_ext.h> +#include <stdlib.h> +#include <string.h> + + +int +main (void) +{ + FILE *fp; + const char teststring[] = "hello world"; + char buf[3072]; + int result = 0; + char readbuf[256]; + + /* Open a file. */ + fp = tmpfile (); + + /* Set a buffer. */ + if (setvbuf (fp, buf, _IOFBF, sizeof buf) == EOF) + { + printf ("setvbuf failed: %m\n"); + exit (1); + } + + /* Get the buffer size. */ + if (__fbufsize (fp) != sizeof buf) + { + printf ("__fbusize() reported a buffer size of %Zd bytes;" + " we installed a buffer with %Zd bytes\n", + __fbufsize (fp), sizeof buf); + result = 1; + } + + /* Write something and read it back. */ + if (fputs (teststring, fp) == EOF) + { + printf ("writing to new stream failed: %m\n"); + exit (1); + } + rewind (fp); + if (fgets (readbuf, sizeof readbuf, fp) == NULL) + { + printf ("reading from new stream failed: %m\n"); + exit (1); + } + if (strcmp (readbuf, teststring) != 0) + { + puts ("not the correct string read"); + exit (1); + } + + /* The file must be opened for reading and writing. */ + if (__freading (fp) == 0) + { + puts ("__freading() reported stream is not last read from"); + result = 1; + } + if (__fwriting (fp) != 0) + { + puts ("__fwriting() reported stream is write-only or last written to"); + result = 1; + } + rewind (fp); + if (fputs (teststring, fp) == EOF) + { + printf ("writing(2) to new stream failed: %m\n"); + exit (1); + } + if (__fwriting (fp) == 0) + { + puts ("__fwriting() doe snot reported stream is last written to"); + result = 1; + } + if (__freading (fp) != 0) + { + puts ("__freading() reported stream is last read from"); + result = 1; + } + + if (__freadable (fp) == 0) + { + puts ("__freading() reported stream is last readable"); + result = 1; + } + if (__fwritable (fp) == 0) + { + puts ("__freading() reported stream is last writable"); + result = 1; + } + + /* The string we wrote above should still be in the buffer. */ + if (__fpending (fp) != strlen (teststring)) + { + printf ("__fpending() returned %Zd; expected %Zd\n", + __fpending (fp), strlen (teststring)); + result = 1; + } + /* Discard all the output. */ + __fpurge (fp); + /* And check again. */ + if (__fpending (fp) != 0) + { + printf ("__fpending() returned %Zd; expected 0\n", + __fpending (fp)); + result = 1; + } + + + /* Find out whether buffer is line buffered. */ + if (__flbf (fp) != 0) + { + puts ("__flbf() reports line buffered but it is fully buffered"); + result = 1; + } + + if (setvbuf (fp, buf, _IOLBF, sizeof buf) == EOF) + { + printf ("setvbuf(2) failed: %m\n"); + exit (1); + } + if (__flbf (fp) == 0) + { + puts ("__flbf() reports file is not line buffered"); + result = 1; + } + + if (setvbuf (fp, NULL, _IONBF, 0) == EOF) + { + printf ("setvbuf(3) failed: %m\n"); + exit (1); + } + if (__flbf (fp) != 0) + { + puts ("__flbf() reports line buffered but it is not buffered"); + result = 1; + } + + fclose (fp); + + return result; +} diff --git a/REORG.TODO/libio/tst-ext2.c b/REORG.TODO/libio/tst-ext2.c new file mode 100644 index 0000000000..ed72efa0c7 --- /dev/null +++ b/REORG.TODO/libio/tst-ext2.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdio_ext.h> + + +static char *fname; + +#define PREPARE(argc, argv) \ + do { \ + int fd = create_temp_file ("tst-ext2", &fname); \ + if (fd == -1) \ + { \ + puts ("cannot create temporary file"); \ + exit (1); \ + } \ + close (fd); \ + } while (0) + + +static int +do_test (void) +{ + int res = 0; + + FILE *fp; + + fp = fopen (fname, "w"); + printf ("Initial state for write-only stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 1); + fclose (fp); + + fp = fopen (fname, "r"); + printf ("Initial state for read-only stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 1 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + fp = fopen (fname, "r+"); + printf ("Initial state for read-write stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + fp = fopen (fname, "w+"); + printf ("Initial state for read-write stream: %d %d\n", + __freading (fp) != 0, __fwriting (fp) != 0); + res |= ((__freading (fp) != 0) != 0 + || (__fwriting (fp) != 0) != 0); + fclose (fp); + + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-fgetwc.c b/REORG.TODO/libio/tst-fgetwc.c new file mode 100644 index 0000000000..06e4a424ff --- /dev/null +++ b/REORG.TODO/libio/tst-fgetwc.c @@ -0,0 +1,52 @@ +#include <locale.h> +#include <stdio.h> +#include <wchar.h> + + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + puts ("setlocale failed"); + return 1; + } + + if (setvbuf (stdin, NULL, _IONBF, 0) != 0) + { + puts ("setvbuf failed"); + return 1; + } + + wchar_t buf[100]; + size_t nbuf = 0; + wint_t c; + while ((c = fgetwc (stdin)) != WEOF) + buf[nbuf++] = c; + + if (ferror (stdin)) + { + puts ("error on stdin"); + return 1; + } + + const wchar_t expected[] = + { + 0x00000439, 0x00000446, 0x00000443, 0x0000043a, + 0x00000435, 0x0000043d, 0x0000000a, 0x00000071, + 0x00000077, 0x00000065, 0x00000072, 0x00000074, + 0x00000079, 0x0000000a + }; + + if (nbuf != sizeof (expected) / sizeof (expected[0]) + || wmemcmp (expected, buf, nbuf) != 0) + { + puts ("incorrect result"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-fgetwc.input b/REORG.TODO/libio/tst-fgetwc.input new file mode 100644 index 0000000000..b1a48dadb8 --- /dev/null +++ b/REORG.TODO/libio/tst-fgetwc.input @@ -0,0 +1,2 @@ +йцукен +qwerty diff --git a/REORG.TODO/libio/tst-fgetws.c b/REORG.TODO/libio/tst-fgetws.c new file mode 100644 index 0000000000..1e29332743 --- /dev/null +++ b/REORG.TODO/libio/tst-fgetws.c @@ -0,0 +1,185 @@ +/* Taken from the Li18nux base test suite. */ + +#define _XOPEN_SOURCE 500 +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <wchar.h> + +#define WIDE_STR_LEN 32 + +int +main (int argc, char *argv[]) +{ + size_t i; + FILE *fp; + wchar_t *ret, wcs[WIDE_STR_LEN]; + int result = 0; + const char il_str1[] = {0xe3, 0x81, '\0'}; + const char il_str2[] = {'0', '\n', 'A', 'B', 0xe3, 0x81, 'E', '\0'}; + char name1[] = "/tmp/tst-fgetws.out.XXXXXX"; + char name2[] = "/tmp/tst-fgetws.out.XXXXXX"; + int fd; + + puts ("This program runs on de_DE.UTF-8 locale."); + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + fprintf (stderr, "Err: Cannot run on the de_DE.UTF-8 locale"); + exit (EXIT_FAILURE); + } + + /* Make a file `il_str1'. */ + fd = mkstemp (name1); + if (fd == -1) + { + printf ("cannot open temp file: %m\n"); + exit (EXIT_FAILURE); + } + if ((fp = fdopen (fd, "w")) == NULL) + { + printf ("Can't open %s.\n", argv[1]); + exit (EXIT_FAILURE); + } + fwrite (il_str1, sizeof (char), sizeof (il_str1), fp); + fclose (fp); + + /* Make a file `il_str2'. */ + fd = mkstemp (name2); + if (fd == -1) + { + printf ("cannot open temp file: %m\n"); + exit (EXIT_FAILURE); + } + if ((fp = fdopen (fd, "w")) == NULL) + { + fprintf (stderr, "Can't open %s.\n", argv[1]); + exit (EXIT_FAILURE); + } + fwrite (il_str2, sizeof (char), sizeof (il_str2), fp); + fclose (fp); + + + /* Test for il_str1. */ + if ((fp = fopen (name1, "r")) == NULL) + { + fprintf (stderr, "Can't open %s.\n", argv[1]); + exit (EXIT_FAILURE); + } + + puts ("--"); + puts ("Read a byte sequence which is invalid as a wide character string."); + puts (" bytes: 0xe3, 0x81, '\\0'"); + + errno = 0; + ret = fgetws (wcs, WIDE_STR_LEN, fp); + + if (ret == NULL) + { + puts ("Return Value: NULL"); + + if (errno == EILSEQ) + puts ("errno = EILSEQ"); + else + { + printf ("errno = %d\n", errno); + result = 1; + } + } + else + { + printf ("Return Value: %p\n", ret); + for (i = 0; i < wcslen (wcs) + 1; i++) + printf (" wcs[%zd] = %04x", i, (unsigned int)wcs[i]); + printf ("\n"); + result = 1; + } + + /* Test for il_str2. */ + if ((fp = fopen (name2, "r")) == NULL) + { + fprintf (stderr, "Can't open %s.\n", argv[1]); + exit (EXIT_FAILURE); + } + + puts ("--"); + puts ("Read a byte sequence which is invalid as a wide character string."); + puts (" bytes: '0', '\\n', 'A', 'B', 0xe3, 0x81, 'c', '\\0'"); + + errno = 0; + ret = fgetws (wcs, WIDE_STR_LEN, fp); + + if (ret == NULL) + { + puts ("Return Value: NULL"); + + if (errno == EILSEQ) + puts ("errno = EILSEQ"); + else + printf ("errno = %d\n", errno); + + result = 1; + } + else + { + size_t i; + + printf ("Return Value: %p\n", ret); + for (i = 0; i < wcslen (wcs) + 1; i++) + printf (" wcs[%zd] = 0x%04x", i, (unsigned int)wcs[i]); + printf ("\n"); + + for (i = 0; il_str2[i] != '\n'; ++i) + if ((wchar_t) il_str2[i] != wcs[i]) + { + puts ("read string not correct"); + result = 1; + break; + } + if (il_str2[i] == '\n') + { + if (wcs[i] != L'\n') + { + puts ("newline missing"); + result = 1; + } + else if (wcs[i + 1] != L'\0') + { + puts ("read string not NUL-terminated"); + result = 1; + } + } + } + + puts ("\nsecond line"); + errno = 0; + ret = fgetws (wcs, WIDE_STR_LEN, fp); + + if (ret == NULL) + { + puts ("Return Value: NULL"); + + if (errno == EILSEQ) + puts ("errno = EILSEQ"); + else + { + printf ("errno = %d\n", errno); + result = 1; + } + } + else + { + printf ("Return Value: %p\n", ret); + for (i = 0; i < wcslen (wcs) + 1; i++) + printf (" wcs[%zd] = 0x%04x", i, (unsigned int)wcs[i]); + printf ("\n"); + } + + fclose (fp); + + unlink (name1); + unlink (name2); + + return result; +} diff --git a/REORG.TODO/libio/tst-fopenloc.c b/REORG.TODO/libio/tst-fopenloc.c new file mode 100644 index 0000000000..81af8716c7 --- /dev/null +++ b/REORG.TODO/libio/tst-fopenloc.c @@ -0,0 +1,91 @@ +/* Test for ,ccs= handling in fopen. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <locale.h> +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <wchar.h> +#include <sys/resource.h> + +static const char inputfile[] = "../iconvdata/testdata/ISO-8859-1"; + +static int do_test(void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static int +do_bz17916 (void) +{ + /* BZ #17916 -- check invalid large ccs= case. */ + struct rlimit rl; + getrlimit (RLIMIT_STACK, &rl); + rl.rlim_cur = 1024 * 1024; + setrlimit (RLIMIT_STACK, &rl); + + const size_t sz = 2 * 1024 * 1024; + char *ccs = xmalloc (sz); + strcpy (ccs, "r,ccs="); + memset (ccs + 6, 'A', sz - 6 - 1); + ccs[sz - 1] = '\0'; + + FILE *fp = fopen (inputfile, ccs); + if (fp != NULL) + { + printf ("unxpected success\n"); + return 1; + } + free (ccs); + + return 0; +} + +static int +do_test (void) +{ + FILE *fp; + + mtrace (); + + setlocale (LC_ALL, "de_DE.UTF-8"); + + fp = fopen (inputfile, "r,ccs=ISO-8859-1"); + if (fp == NULL) + { + printf ("cannot open \"%s\": %s\n", inputfile, strerror (errno)); + exit (1); + } + + while (! feof_unlocked (fp)) + { + wchar_t buf[200]; + + if (fgetws_unlocked (buf, sizeof (buf) / sizeof (buf[0]), fp) == NULL) + break; + + fputws (buf, stdout); + } + + fclose (fp); + + return do_bz17916 (); +} diff --git a/REORG.TODO/libio/tst-fopenloc2.c b/REORG.TODO/libio/tst-fopenloc2.c new file mode 100644 index 0000000000..5ddd63446b --- /dev/null +++ b/REORG.TODO/libio/tst-fopenloc2.c @@ -0,0 +1,116 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <wchar.h> + + +static const struct +{ + const char *enc; + const char *data; + size_t datalen; + const wchar_t *expected; + size_t expectedlen; +} tests[] = + { + { "UCS-4LE", "a\0\0\0b\0\0\0", 8, L"ab", 2 }, + { "UCS-4BE", "\0\0\0a\0\0\0b", 8, L"ab", 2 }, + }; +#define ntests (sizeof (tests) / sizeof (tests[0])) + + +static int do_test (void); +#define TEST_FUNCTION do_test () + +static void prepare (void); +#define PREPARE(argc, argv) prepare (); + +#include "../test-skeleton.c" + + +static int fd; +static char *tmpname; + + +static void +prepare (void) +{ + fd = create_temp_file ("tst-fopenloc2", &tmpname); + if (fd == -1) + { + puts ("cannot open temp file"); + exit (1); + } +} + + +static int +do_test (void) +{ + for (int i = 0; i < ntests; ++i) + { + if (ftruncate (fd, 0) != 0) + { + printf ("ftruncate in round %d failed\n", i + 1); + return 1; + } + + if (TEMP_FAILURE_RETRY (write (fd, tests[i].data, tests[i].datalen)) + != tests[i].datalen) + { + printf ("write in round %d failed\n", i + 1); + return 1; + } + + if (lseek (fd, 0, SEEK_SET) != 0) + { + printf ("lseek in round %d failed\n", i + 1); + return 1; + } + + char *ccs; + if (asprintf (&ccs, "r,ccs=%s", tests[i].enc) == -1) + { + printf ("asprintf in round %d failed\n", i + 1); + return 1; + } + + FILE *fp = fopen (tmpname, ccs); + if (fp == NULL) + { + printf ("fopen in round %d failed\n", i + 1); + return 1; + } + +#define LINELEN 100 + wchar_t line[LINELEN]; + if (fgetws (line, LINELEN, fp) != line) + { + printf ("fgetws in round %d failed\n", i + 1); + return 1; + } + + if (wcslen (line) != tests[i].expectedlen) + { + printf ("round %d: expected length %zu, got length %zu\n", + i + 1, tests[i].expectedlen, wcslen (line)); + return 1; + } + + if (wcscmp (tests[i].expected, line) != 0) + { + printf ("round %d: expected L\"%ls\", got L\"%ls\"\n", + i + 1, tests[i].expected, line); + return 1; + } + + fclose (fp); + + free (ccs); + } + + close (fd); + + return 0; +} diff --git a/REORG.TODO/libio/tst-fputws.c b/REORG.TODO/libio/tst-fputws.c new file mode 100644 index 0000000000..b5048638f8 --- /dev/null +++ b/REORG.TODO/libio/tst-fputws.c @@ -0,0 +1,39 @@ +/* Test that we can write a multibyte character to an unbuffered stream. + Copyright (C) 2014-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <locale.h> +#include <stdio.h> +#include <wchar.h> + +static int +do_test (void) +{ + const wchar_t str[] = L"\xbe\n"; + + setlocale (LC_ALL, "en_US.UTF-8"); + setvbuf (stdout, NULL, _IONBF, 0); + + if (fputws (str, stdout) < 0) + return 1; + + return 0; +} + +#define TEST_FUNCTION do_test () + +#include <test-skeleton.c> diff --git a/REORG.TODO/libio/tst-freopen.c b/REORG.TODO/libio/tst-freopen.c new file mode 100644 index 0000000000..5ad589bffa --- /dev/null +++ b/REORG.TODO/libio/tst-freopen.c @@ -0,0 +1,112 @@ +/* Test freopen with mmap stdio. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <support/check.h> +#include <support/temp_file.h> + +static int fd; +static char *name; + +static void +do_prepare (int argc, char *argv[]) +{ + fd = create_temp_file ("tst-freopen.", &name); + TEST_VERIFY_EXIT (fd != -1); +} + +#define PREPARE do_prepare + +/* Basic tests for freopen. */ +static void +do_test_basic (void) +{ + const char * const test = "Let's test freopen.\n"; + char temp[strlen (test) + 1]; + + FILE *f = fdopen (fd, "w"); + if (f == NULL) + FAIL_EXIT1 ("fdopen: %m"); + + fputs (test, f); + fclose (f); + + f = fopen (name, "r"); + if (f == NULL) + FAIL_EXIT1 ("fopen: %m"); + + if (fread (temp, 1, strlen (test), f) != strlen (test)) + FAIL_EXIT1 ("fread: %m"); + temp [strlen (test)] = '\0'; + + if (strcmp (test, temp)) + FAIL_EXIT1 ("read different string than was written: (%s, %s)", + test, temp); + + f = freopen (name, "r+", f); + if (f == NULL) + FAIL_EXIT1 ("freopen: %m"); + + if (fseek (f, 0, SEEK_SET) != 0) + FAIL_EXIT1 ("fseek: %m"); + + if (fread (temp, 1, strlen (test), f) != strlen (test)) + FAIL_EXIT1 ("fread: %m"); + temp [strlen (test)] = '\0'; + + if (strcmp (test, temp)) + FAIL_EXIT1 ("read different string than was written: (%s, %s)", + test, temp); + + fclose (f); +} + +/* Test for BZ#21398, where it tries to freopen stdio after the close + of its file descriptor. */ +static void +do_test_bz21398 (void) +{ + (void) close (STDIN_FILENO); + + FILE *f = freopen (name, "r", stdin); + if (f == NULL) + FAIL_EXIT1 ("freopen: %m"); + + TEST_VERIFY_EXIT (ferror (f) == 0); + + char buf[128]; + char *ret = fgets (buf, sizeof (buf), stdin); + TEST_VERIFY_EXIT (ret != NULL); + TEST_VERIFY_EXIT (ferror (f) == 0); +} + +static int +do_test (void) +{ + do_test_basic (); + do_test_bz21398 (); + + return 0; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/libio/tst-fseek.c b/REORG.TODO/libio/tst-fseek.c new file mode 100644 index 0000000000..e0d06e1337 --- /dev/null +++ b/REORG.TODO/libio/tst-fseek.c @@ -0,0 +1,169 @@ +/* Verify that fseek/ftell combination works for wide chars. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <locale.h> +#include <errno.h> +#include <wchar.h> +#include <unistd.h> +#include <string.h> + +#include <support/temp_file.h> + +static int +do_seek_end (FILE *fp) +{ + long save; + + if (fputws (L"abc\n", fp) == -1) + { + printf ("do_seek_end: fputws: %s\n", strerror (errno)); + return 1; + } + + save = ftell (fp); + rewind (fp); + + if (fseek (fp, 0, SEEK_END) == -1) + { + printf ("do_seek_end: fseek: %s\n", strerror (errno)); + return 1; + } + + if (save != ftell (fp)) + { + printf ("save = %ld, ftell = %ld\n", save, ftell (fp)); + return 1; + } + + return 0; +} + +int +do_seek_set (FILE *fp) +{ + long save1, save2; + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(1): %s\n", strerror (errno)); + return 1; + } + + save1 = ftell (fp); + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(2): %s\n", strerror (errno)); + return 1; + } + + save2 = ftell (fp); + + if (fputws (L"ゅう\n", fp) == -1) + { + printf ("seek_set: fputws(3): %s\n", strerror (errno)); + return 1; + } + + if (fseek (fp, save1, SEEK_SET) == -1) + { + printf ("seek_set: fseek(1): %s\n", strerror (errno)); + return 1; + } + + if (save1 != ftell (fp)) + { + printf ("save1 = %ld, ftell = %ld\n", save1, ftell (fp)); + return 1; + } + + if (fseek (fp, save2, SEEK_SET) == -1) + { + printf ("seek_set: fseek(2): %s\n", strerror (errno)); + return 1; + } + + if (save2 != ftell (fp)) + { + printf ("save2 = %ld, ftell = %ld\n", save2, ftell (fp)); + return 1; + } + + return 0; +} + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "ja_JP.UTF-8") == NULL) + { + printf ("Cannot set ja_JP.UTF-8 locale.\n"); + exit (1); + } + + /* Retain messages in English. */ + if (setlocale (LC_MESSAGES, "en_US.ISO-8859-1") == NULL) + { + printf ("Cannot set LC_MESSAGES to en_US.ISO-8859-1 locale.\n"); + exit (1); + } + + int ret = 0; + char *filename; + int fd = create_temp_file ("tst-fseek.out", &filename); + + if (fd == -1) + return 1; + + FILE *fp = fdopen (fd, "w+"); + if (fp == NULL) + { + printf ("seek_set: fopen: %s\n", strerror (errno)); + close (fd); + return 1; + } + + if (do_seek_set (fp)) + { + printf ("SEEK_SET test failed\n"); + ret = 1; + } + + /* Reopen the file. */ + fclose (fp); + fp = fopen (filename, "w+"); + if (fp == NULL) + { + printf ("seek_end: fopen: %s\n", strerror (errno)); + return 1; + } + + if (do_seek_end (fp)) + { + printf ("SEEK_END test failed\n"); + ret = 1; + } + + fclose (fp); + + return ret; +} + +#include <support/test-driver.c> diff --git a/REORG.TODO/libio/tst-ftell-active-handler.c b/REORG.TODO/libio/tst-ftell-active-handler.c new file mode 100644 index 0000000000..5cc013da11 --- /dev/null +++ b/REORG.TODO/libio/tst-ftell-active-handler.c @@ -0,0 +1,684 @@ +/* Verify that ftell returns the correct value at various points before and + after the handler on which it is called becomes active. + Copyright (C) 2014-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <locale.h> +#include <wchar.h> + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +#define get_handles_fdopen(filename, fd, fp, fd_mode, mode) \ +({ \ + int ret = 0; \ + (fd) = open ((filename), (fd_mode), 0); \ + if ((fd) == -1) \ + { \ + printf ("open failed: %m\n"); \ + ret = 1; \ + } \ + else \ + { \ + (fp) = fdopen ((fd), (mode)); \ + if ((fp) == NULL) \ + { \ + printf ("fdopen failed: %m\n"); \ + close (fd); \ + ret = 1; \ + } \ + } \ + ret; \ +}) + +#define get_handles_fopen(filename, fd, fp, mode) \ +({ \ + int ret = 0; \ + (fp) = fopen ((filename), (mode)); \ + if ((fp) == NULL) \ + { \ + printf ("fopen failed: %m\n"); \ + ret = 1; \ + } \ + else \ + { \ + (fd) = fileno (fp); \ + if ((fd) == -1) \ + { \ + printf ("fileno failed: %m\n"); \ + ret = 1; \ + } \ + } \ + ret; \ +}) + +/* data points to either char_data or wide_data, depending on whether we're + testing regular file mode or wide mode respectively. Similarly, + fputs_func points to either fputs or fputws. data_len keeps track of the + length of the current data and file_len maintains the current file + length. */ +static const void *data; +static const char *char_data = "abcdef"; +static const wchar_t *wide_data = L"abcdef"; +static size_t data_len; +static size_t file_len; + +typedef int (*fputs_func_t) (const void *data, FILE *fp); +typedef void *(*fgets_func_t) (void *ws, int n, FILE *fp); +fputs_func_t fputs_func; +fgets_func_t fgets_func; + +/* This test verifies that the offset reported by ftell is correct after the + file is truncated using ftruncate. ftruncate does not change the file + offset on truncation and hence, SEEK_CUR should continue to point to the + old offset and not be changed to the new offset. */ +static int +do_ftruncate_test (const char *filename) +{ + FILE *fp = NULL; + int fd; + int ret = 0; + struct test + { + const char *mode; + int fd_mode; + } test_modes[] = { + {"r+", O_RDWR}, + {"w", O_WRONLY | O_TRUNC}, + {"w+", O_RDWR | O_TRUNC}, + {"a", O_WRONLY}, + {"a+", O_RDWR} + }; + + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { + int fileret; + printf ("\tftruncate: %s (file, \"%s\"): ", + j == 0 ? "fopen" : "fdopen", + test_modes[i].mode); + + if (j == 0) + fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + else + fileret = get_handles_fdopen (filename, fd, fp, + test_modes[i].fd_mode, + test_modes[i].mode); + + if (fileret != 0) + return fileret; + + /* Write some data. */ + size_t written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write data\n"); + ret |= 1; + } + + /* Record the offset. */ + long offset = ftell (fp); + + /* Flush data to allow switching active handles. */ + if (fflush (fp)) + { + printf ("Flush failed: %m\n"); + ret |= 1; + } + + /* Now truncate the file. */ + if (ftruncate (fd, 0) != 0) + { + printf ("Failed to truncate file: %m\n"); + ret |= 1; + } + + /* ftruncate does not change the offset, so there is no need to call + anything to be able to switch active handles. */ + long new_offset = ftell (fp); + + /* The offset should remain unchanged since ftruncate does not update + it. */ + if (offset != new_offset) + { + printf ("Incorrect offset. Expected %ld, but got %ld\n", + offset, new_offset); + + ret |= 1; + } + else + printf ("offset = %ld\n", offset); + + fclose (fp); + } + } + + return ret; +} +/* Test that ftell output after a rewind is correct. */ +static int +do_rewind_test (const char *filename) +{ + int ret = 0; + struct test + { + const char *mode; + int fd_mode; + size_t old_off; + size_t new_off; + } test_modes[] = { + {"w", O_WRONLY | O_TRUNC, 0, data_len}, + {"w+", O_RDWR | O_TRUNC, 0, data_len}, + {"r+", O_RDWR, 0, data_len}, + /* The new offsets for 'a' and 'a+' modes have to factor in the + previous writes since they always append to the end of the + file. */ + {"a", O_WRONLY, 0, 3 * data_len}, + {"a+", O_RDWR, 0, 4 * data_len}, + }; + + /* Empty the file before the test so that our offsets are simple to + calculate. */ + FILE *fp = fopen (filename, "w"); + if (fp == NULL) + { + printf ("Failed to open file for emptying\n"); + return 1; + } + fclose (fp); + + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { + FILE *fp; + int fd; + int fileret; + + printf ("\trewind: %s (file, \"%s\"): ", j == 0 ? "fdopen" : "fopen", + test_modes[i].mode); + + if (j == 0) + fileret = get_handles_fdopen (filename, fd, fp, + test_modes[i].fd_mode, + test_modes[i].mode); + else + fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + + if (fileret != 0) + return fileret; + + /* Write some content to the file, rewind and ensure that the ftell + output after the rewind is 0. POSIX does not specify what the + behavior is when a file is rewound in 'a' mode, so we retain + current behavior, which is to keep the 0 offset. */ + size_t written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write data\n"); + ret |= 1; + } + + rewind (fp); + long offset = ftell (fp); + + if (offset != test_modes[i].old_off) + { + printf ("Incorrect old offset. Expected %zu, but got %ld, ", + test_modes[i].old_off, offset); + ret |= 1; + } + else + printf ("old offset = %ld, ", offset); + + written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write data\n"); + ret |= 1; + } + + /* After this write, the offset in append modes should factor in the + implicit lseek to the end of file. */ + offset = ftell (fp); + if (offset != test_modes[i].new_off) + { + printf ("Incorrect new offset. Expected %zu, but got %ld\n", + test_modes[i].new_off, offset); + ret |= 1; + } + else + printf ("new offset = %ld\n", offset); + } + } + return ret; +} + +/* Test that the value of ftell is not cached when the stream handle is not + active. */ +static int +do_ftell_test (const char *filename) +{ + int ret = 0; + struct test + { + const char *mode; + int fd_mode; + size_t old_off; + size_t new_off; + size_t eof_off; + } test_modes[] = { + /* In w, w+ and r+ modes, the file position should be at the + beginning of the file. After the write, the offset should be + updated to data_len. We don't use eof_off in w and a modes since + they don't allow reading. */ + {"w", O_WRONLY | O_TRUNC, 0, data_len, 0}, + {"w+", O_RDWR | O_TRUNC, 0, data_len, 2 * data_len}, + {"r+", O_RDWR, 0, data_len, 3 * data_len}, + /* For the 'a' mode, the initial file position should be the + current end of file. After the write, the offset has data_len + added to the old value. For a+ mode however, the initial file + position is the file position of the underlying file descriptor, + since it is initially assumed to be in read mode. */ + {"a", O_WRONLY, 3 * data_len, 4 * data_len, 5 * data_len}, + {"a+", O_RDWR, 0, 5 * data_len, 6 * data_len}, + }; + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { + FILE *fp; + int fd; + int fileret; + + printf ("\tftell: %s (file, \"%s\"): ", j == 0 ? "fdopen" : "fopen", + test_modes[i].mode); + + if (j == 0) + fileret = get_handles_fdopen (filename, fd, fp, + test_modes[i].fd_mode, + test_modes[i].mode); + else + fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + + if (fileret != 0) + return fileret; + + long off = ftell (fp); + if (off != test_modes[i].old_off) + { + printf ("Incorrect old offset. Expected %zu but got %ld, ", + test_modes[i].old_off, off); + ret |= 1; + } + else + printf ("old offset = %ld, ", off); + + /* The effect of this write on the offset should be seen in the ftell + call that follows it. */ + int write_ret = write (fd, data, data_len); + if (write_ret != data_len) + { + printf ("write failed (%m)\n"); + ret |= 1; + } + off = ftell (fp); + + if (off != test_modes[i].new_off) + { + printf ("Incorrect new offset. Expected %zu but got %ld", + test_modes[i].new_off, off); + ret |= 1; + } + else + printf ("new offset = %ld", off); + + /* Read to the end, write some data to the fd and check if ftell can + see the new ofset. Do this test only for files that allow + reading. */ + if (test_modes[i].fd_mode != O_WRONLY) + { + wchar_t tmpbuf[data_len]; + + rewind (fp); + + while (fgets_func (tmpbuf, data_len, fp) && !feof (fp)); + + write_ret = write (fd, data, data_len); + if (write_ret != data_len) + { + printf ("write failed (%m)\n"); + ret |= 1; + } + off = ftell (fp); + + if (off != test_modes[i].eof_off) + { + printf (", Incorrect offset after read EOF. " + "Expected %zu but got %ld\n", + test_modes[i].eof_off, off); + ret |= 1; + } + else + printf (", offset after EOF = %ld\n", off); + } + else + putc ('\n', stdout); + + fclose (fp); + } + } + + return ret; +} + +/* This test opens the file for writing, moves the file offset of the + underlying file, writes out data and then checks if ftell trips on it. */ +static int +do_write_test (const char *filename) +{ + FILE *fp = NULL; + int fd; + int ret = 0; + struct test + { + const char *mode; + int fd_mode; + } test_modes[] = { + {"w", O_WRONLY | O_TRUNC}, + {"w+", O_RDWR | O_TRUNC}, + {"r+", O_RDWR} + }; + + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { + int fileret; + printf ("\twrite: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", + test_modes[i].mode); + + if (j == 0) + fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + else + fileret = get_handles_fdopen (filename, fd, fp, + test_modes[i].fd_mode, + test_modes[i].mode); + + if (fileret != 0) + return fileret; + + /* Move offset to just before the end of the file. */ + off_t seek_ret = lseek (fd, file_len - 1, SEEK_SET); + if (seek_ret == -1) + { + printf ("lseek failed: %m\n"); + ret |= 1; + } + + /* Write some data. */ + size_t written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write data\n"); + ret |= 1; + } + + /* Verify that the offset points to the end of the file. The length + of the file would be the original length + the length of data + written to it - the amount by which we moved the offset using + lseek. */ + long offset = ftell (fp); + file_len = file_len - 1 + data_len; + + if (offset != file_len) + { + printf ("Incorrect offset. Expected %zu, but got %ld\n", + file_len, offset); + + ret |= 1; + } + + printf ("offset = %ld\n", offset); + fclose (fp); + } + } + + return ret; +} + +/* This test opens a file in append mode, writes some data, and then verifies + that ftell does not trip over it. */ +static int +do_append_test (const char *filename) +{ + FILE *fp = NULL; + int ret = 0; + int fd; + + struct test + { + const char *mode; + int fd_mode; + } test_modes[] = { + {"a", O_WRONLY}, + {"a+", O_RDWR} + }; + + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { + int fileret; + + printf ("\tappend: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", + test_modes[i].mode); + + if (j == 0) + fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + else + fileret = get_handles_fdopen (filename, fd, fp, + test_modes[i].fd_mode, + test_modes[i].mode); + + if (fileret != 0) + return fileret; + + /* Write some data. */ + size_t written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write all data\n"); + ret |= 1; + } + + /* Verify that the offset points to the end of the file. The file + len is maintained by adding data_len each time to reflect the data + written to it. */ + long offset = ftell (fp); + file_len += data_len; + + if (offset != file_len) + { + printf ("Incorrect offset. Expected %zu, but got %ld\n", + file_len, offset); + + ret |= 1; + } + + printf ("offset = %ld\n", offset); + fclose (fp); + } + } + + /* For fdopen in 'a' mode, the file descriptor should not change if the file + is already open with the O_APPEND flag set. */ + fd = open (filename, O_WRONLY | O_APPEND, 0); + if (fd == -1) + { + printf ("open(O_APPEND) failed: %m\n"); + return 1; + } + + off_t seek_ret = lseek (fd, file_len - 1, SEEK_SET); + if (seek_ret == -1) + { + printf ("lseek[O_APPEND][0] failed: %m\n"); + ret |= 1; + } + + fp = fdopen (fd, "a"); + if (fp == NULL) + { + printf ("fdopen(O_APPEND) failed: %m\n"); + close (fd); + return 1; + } + + off_t new_seek_ret = lseek (fd, 0, SEEK_CUR); + if (seek_ret == -1) + { + printf ("lseek[O_APPEND][1] failed: %m\n"); + ret |= 1; + } + + printf ("\tappend: fdopen (file, \"a\"): O_APPEND: "); + + if (seek_ret != new_seek_ret) + { + printf ("incorrectly modified file offset to %jd, should be %jd", + (intmax_t) new_seek_ret, (intmax_t) seek_ret); + ret |= 1; + } + else + printf ("retained current file offset %jd", (intmax_t) seek_ret); + + new_seek_ret = ftello (fp); + + if (seek_ret != new_seek_ret) + { + printf (", ftello reported incorrect offset %jd, should be %jd\n", + (intmax_t) new_seek_ret, (intmax_t) seek_ret); + ret |= 1; + } + else + printf (", ftello reported correct offset %jd\n", (intmax_t) seek_ret); + + fclose (fp); + + return ret; +} + +static int +do_one_test (const char *filename) +{ + int ret = 0; + + ret |= do_ftell_test (filename); + ret |= do_write_test (filename); + ret |= do_append_test (filename); + ret |= do_rewind_test (filename); + ret |= do_ftruncate_test (filename); + + return ret; +} + +/* Run a set of tests for ftell for regular files and wide mode files. */ +static int +do_test (void) +{ + int ret = 0; + FILE *fp = NULL; + char *filename; + size_t written; + int fd = create_temp_file ("tst-active-handler-tmp.", &filename); + + if (fd == -1) + { + printf ("create_temp_file: %m\n"); + return 1; + } + + fp = fdopen (fd, "w"); + if (fp == NULL) + { + printf ("fdopen[0]: %m\n"); + close (fd); + return 1; + } + + data = char_data; + data_len = strlen (char_data); + file_len = strlen (char_data); + written = fputs (data, fp); + + if (written == EOF) + { + printf ("fputs[1] failed to write data\n"); + ret = 1; + } + + fclose (fp); + if (ret) + return ret; + + /* Tests for regular files. */ + puts ("Regular mode:"); + fputs_func = (fputs_func_t) fputs; + fgets_func = (fgets_func_t) fgets; + data = char_data; + data_len = strlen (char_data); + ret |= do_one_test (filename); + + /* Truncate the file before repeating the tests in wide mode. */ + fp = fopen (filename, "w"); + if (fp == NULL) + { + printf ("fopen failed %m\n"); + return 1; + } + fclose (fp); + + /* Tests for wide files. */ + puts ("Wide mode:"); + if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) + { + printf ("Cannot set en_US.UTF-8 locale.\n"); + return 1; + } + fputs_func = (fputs_func_t) fputws; + fgets_func = (fgets_func_t) fgetws; + data = wide_data; + data_len = wcslen (wide_data); + ret |= do_one_test (filename); + + return ret; +} diff --git a/REORG.TODO/libio/tst-ftell-append.c b/REORG.TODO/libio/tst-ftell-append.c new file mode 100644 index 0000000000..7ffdf346b3 --- /dev/null +++ b/REORG.TODO/libio/tst-ftell-append.c @@ -0,0 +1,169 @@ +/* Verify that ftell returns the correct value after a read and a write on a + file opened in a+ mode. + Copyright (C) 2014-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <locale.h> +#include <wchar.h> + +/* data points to either char_data or wide_data, depending on whether we're + testing regular file mode or wide mode respectively. Similarly, + fputs_func points to either fputs or fputws. data_len keeps track of the + length of the current data and file_len maintains the current file + length. */ +#define BUF_LEN 4 +static void *buf; +static char char_buf[BUF_LEN]; +static wchar_t wide_buf[BUF_LEN]; +static const void *data; +static const char *char_data = "abcdefghijklmnopqrstuvwxyz"; +static const wchar_t *wide_data = L"abcdefghijklmnopqrstuvwxyz"; +static size_t data_len; +static size_t file_len; + +typedef int (*fputs_func_t) (const void *data, FILE *fp); +fputs_func_t fputs_func; + +typedef void *(*fgets_func_t) (void *s, int size, FILE *stream); +fgets_func_t fgets_func; + +static int do_test (void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +static FILE * +init_file (const char *filename) +{ + FILE *fp = fopen (filename, "w"); + if (fp == NULL) + { + printf ("fopen: %m\n"); + return NULL; + } + + int written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs failed to write data\n"); + fclose (fp); + return NULL; + } + + file_len = data_len; + + fclose (fp); + + fp = fopen (filename, "a+"); + if (fp == NULL) + { + printf ("fopen(a+): %m\n"); + return NULL; + } + + return fp; +} + +static int +do_one_test (const char *filename) +{ + FILE *fp = init_file (filename); + + if (fp == NULL) + return 1; + + void *ret = fgets_func (buf, BUF_LEN, fp); + + if (ret == NULL) + { + printf ("read failed: %m\n"); + fclose (fp); + return 1; + } + + int written = fputs_func (data, fp); + + if (written == EOF) + { + printf ("fputs failed to write data\n"); + fclose (fp); + return 1; + } + + file_len += data_len; + + long off = ftell (fp); + + if (off != file_len) + { + printf ("Incorrect offset %ld, expected %zu\n", off, file_len); + fclose (fp); + return 1; + } + else + printf ("Correct offset %ld after write.\n", off); + + return 0; +} + +/* Run the tests for regular files and wide mode files. */ +static int +do_test (void) +{ + int ret = 0; + char *filename; + int fd = create_temp_file ("tst-ftell-append-tmp.", &filename); + + if (fd == -1) + { + printf ("create_temp_file: %m\n"); + return 1; + } + + close (fd); + + /* Tests for regular files. */ + puts ("Regular mode:"); + fputs_func = (fputs_func_t) fputs; + fgets_func = (fgets_func_t) fgets; + data = char_data; + buf = char_buf; + data_len = strlen (char_data); + ret |= do_one_test (filename); + + /* Tests for wide files. */ + puts ("Wide mode:"); + if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) + { + printf ("Cannot set en_US.UTF-8 locale.\n"); + return 1; + } + fputs_func = (fputs_func_t) fputws; + fgets_func = (fgets_func_t) fgetws; + data = wide_data; + buf = wide_buf; + data_len = wcslen (wide_data); + ret |= do_one_test (filename); + + return ret; +} diff --git a/REORG.TODO/libio/tst-ftell-partial-wide.c b/REORG.TODO/libio/tst-ftell-partial-wide.c new file mode 100644 index 0000000000..c5b3410084 --- /dev/null +++ b/REORG.TODO/libio/tst-ftell-partial-wide.c @@ -0,0 +1,107 @@ +/* Verify that ftell does not go into an infinite loop when a conversion fails + due to insufficient space in the buffer. + Copyright (C) 2014-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include <errno.h> +#include <unistd.h> + +static int do_test (void); +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + +/* Arbitrary number large enough so that the target buffer during conversion is + not large enough. */ +#define STRING_SIZE (1400) +#define NSTRINGS (2) + +static int +do_test (void) +{ + FILE *fp = NULL; + wchar_t *inputs[NSTRINGS] = {NULL}; + int ret = 1; + + if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) + { + printf ("Cannot set en_US.UTF-8 locale.\n"); + goto out; + } + + + /* Generate input from one character, chosen because it has an odd number of + bytes in UTF-8, making it easier to reproduce the problem: + + NAME Hiragana letter GO + CHAR ご + UTF-8 E38194 + UCS 3054 + MARC-8 692434 */ + wchar_t seed = L'ご'; + for (int i = 0; i < NSTRINGS; i++) + { + inputs[i] = malloc (STRING_SIZE * sizeof (wchar_t)); + if (inputs[i] == NULL) + { + printf ("Failed to allocate memory for inputs: %m\n"); + goto out; + } + wmemset (inputs[i], seed, STRING_SIZE - 1); + inputs[i][STRING_SIZE - 1] = L'\0'; + } + + char *filename; + int fd = create_temp_file ("tst-fseek-wide-partial.out", &filename); + + if (fd == -1) + { + printf ("create_temp_file: %m\n"); + goto out; + } + + fp = fdopen (fd, "w+"); + if (fp == NULL) + { + printf ("fopen: %m\n"); + close (fd); + goto out; + } + + for (int i = 0; i < NSTRINGS; i++) + { + printf ("offset: %ld\n", ftell (fp)); + if (fputws (inputs[i], fp) == -1) + { + perror ("fputws"); + goto out; + } + } + ret = 0; + +out: + if (fp != NULL) + fclose (fp); + for (int i = 0; i < NSTRINGS; i++) + free (inputs[i]); + + return ret; +} diff --git a/REORG.TODO/libio/tst-fwrite-error.c b/REORG.TODO/libio/tst-fwrite-error.c new file mode 100644 index 0000000000..fa64d5f0dc --- /dev/null +++ b/REORG.TODO/libio/tst-fwrite-error.c @@ -0,0 +1,67 @@ +/* Test of fwrite() function, adapted from gnulib-tests in grep. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +static int +do_test (void) +{ + char tmpl[] = "/tmp/tst-fwrite-error.XXXXXX"; + int fd = mkstemp (tmpl); + if (fd == -1) + { + printf ("mkstemp failed with errno %d\n", errno); + return 1; + } + FILE *fp = fdopen (fd, "w"); + if (fp == NULL) + { + printf ("fdopen failed with errno %d\n", errno); + return 1; + } + + char buf[] = "world"; + setvbuf (fp, NULL, _IONBF, 0); + close (fd); + unlink (tmpl); + errno = 0; + + int ret = fwrite (buf, 1, sizeof (buf), fp); + if (ret != 0) + { + printf ("fwrite returned %d\n", ret); + return 1; + } + if (errno != EBADF) + { + printf ("Errno is not EBADF: %d\n", errno); + return 1; + } + if (ferror (fp) == 0) + { + printf ("ferror not set\n"); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-memstream1.c b/REORG.TODO/libio/tst-memstream1.c new file mode 100644 index 0000000000..adc2aec257 --- /dev/null +++ b/REORG.TODO/libio/tst-memstream1.c @@ -0,0 +1,90 @@ +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> + + +#ifndef CHAR_T +# define CHAR_T char +# define W(o) o +# define OPEN_MEMSTREAM open_memstream +#endif + +#define S(s) S1 (s) +#define S1(s) #s + + +static void +mcheck_abort (enum mcheck_status ev) +{ + printf ("mecheck failed with status %d\n", (int) ev); + exit (1); +} + + +static int +do_test (void) +{ + mcheck_pedantic (mcheck_abort); + + CHAR_T *buf = (CHAR_T *) 1l; + size_t len = 12345; + FILE *fp = OPEN_MEMSTREAM (&buf, &len); + if (fp == NULL) + { + printf ("%s failed\n", S(OPEN_MEMSTREAM)); + return 1; + } + + if (fflush (fp) != 0) + { + puts ("fflush failed"); + return 1; + } + + if (len != 0) + { + puts ("string after no write not empty"); + return 1; + } + if (buf == (CHAR_T *) 1l) + { + puts ("buf not updated"); + return 1; + } + if (buf[0] != W('\0')) + { + puts ("buf[0] != 0"); + return 1; + } + + buf = (CHAR_T *) 1l; + len = 12345; + if (fclose (fp) != 0) + { + puts ("fclose failed"); + return 1; + } + + if (len != 0) + { + puts ("string after close with no write not empty"); + return 1; + } + if (buf == (CHAR_T *) 1l) + { + puts ("buf not updated"); + return 1; + } + if (buf[0] != W('\0')) + { + puts ("buf[0] != 0"); + return 1; + } + + free (buf); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-memstream2.c b/REORG.TODO/libio/tst-memstream2.c new file mode 100644 index 0000000000..d3874faaad --- /dev/null +++ b/REORG.TODO/libio/tst-memstream2.c @@ -0,0 +1,106 @@ +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> + + +#ifndef CHAR_T +# define CHAR_T char +# define W(o) o +# define OPEN_MEMSTREAM open_memstream +#endif + +#define S(s) S1 (s) +#define S1(s) #s + + +static void +mcheck_abort (enum mcheck_status ev) +{ + printf ("mecheck failed with status %d\n", (int) ev); + exit (1); +} + + +static int +do_test (void) +{ + mcheck_pedantic (mcheck_abort); + + CHAR_T *buf = (CHAR_T *) 1l; + size_t len = 12345; + FILE *fp = OPEN_MEMSTREAM (&buf, &len); + if (fp == NULL) + { + printf ("%s failed\n", S(OPEN_MEMSTREAM)); + return 1; + } + + for (int outer = 0; outer < 800; ++outer) + { + for (int inner = 0; inner < 100; ++inner) + if (fputc (W('a') + (outer * 100 + inner) % 26, fp) == EOF) + { + printf ("fputc at %d:%d failed\n", outer, inner); + return 1; + } + + if (fflush (fp) != 0) + { + puts ("fflush failed"); + return 1; + } + + if (len != (outer + 1) * 100) + { + printf ("string in round %d not %d bytest long\n", + outer + 1, (outer + 1) * 100); + return 1; + } + if (buf == (CHAR_T *) 1l) + { + printf ("round %d: buf not updated\n", outer + 1); + return 1; + } + for (int inner = 0; inner < (outer + 1) * 100; ++inner) + if (buf[inner] != W('a') + inner % 26) + { + printf ("round %d: buf[%d] != '%c'\n", outer + 1, inner, + (char) (W('a') + inner % 26)); + return 1; + } + } + + buf = (CHAR_T *) 1l; + len = 12345; + if (fclose (fp) != 0) + { + puts ("fclose failed"); + return 1; + } + + if (len != 800 * 100) + { + puts ("string after close not 80000 bytes long"); + return 1; + } + if (buf == (CHAR_T *) 1l) + { + puts ("buf not updated"); + return 1; + } + for (int inner = 0; inner < 800 * 100; ++inner) + if (buf[inner] != W('a') + inner % 26) + { + printf ("after close: buf[%d] != %c\n", inner, + (char) (W('a') + inner % 26)); + return 1; + } + + free (buf); + + return 0; +} + +#define TIMEOUT 100 +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-memstream3.c b/REORG.TODO/libio/tst-memstream3.c new file mode 100644 index 0000000000..ce201d15eb --- /dev/null +++ b/REORG.TODO/libio/tst-memstream3.c @@ -0,0 +1,167 @@ +/* Test for open_memstream implementation. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + + +#ifndef CHAR_T +# define CHAR_T char +# define W(o) o +# define OPEN_MEMSTREAM open_memstream +# define PRINTF printf +# define FWRITE fwrite +# define FPUTC fputc +# define STRCMP strcmp +#endif + +#define S(s) S1 (s) +#define S1(s) #s + +static void +mcheck_abort (enum mcheck_status ev) +{ + printf ("mecheck failed with status %d\n", (int) ev); + exit (1); +} + +static void +error_printf (int line, const char *fmt, ...) +{ + va_list ap; + + printf ("error: %s:%i: ", __FILE__, line); + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); +} + +#define ERROR_RET1(...) \ + { error_printf(__LINE__, __VA_ARGS__); return 1; } + +static int +do_test_bz18241 (void) +{ + CHAR_T *buf; + size_t size; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if (FPUTC (W('a'), fp) != W('a')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + if (fseek (fp, -2, SEEK_SET) != -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (errno != EINVAL) + ERROR_RET1 ("errno != EINVAL\n"); + if (ftell (fp) != 1) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + + if (fseek (fp, -1, SEEK_CUR) == -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (ftell (fp) != 0) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + if (FPUTC (W('b'), fp) != W('b')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (STRCMP (buf, W("b")) != 0) + ERROR_RET1 ("%s failed\n", S(STRCMP)); + + free (buf); + + return 0; +} + +static int +do_test_bz20181 (void) +{ + CHAR_T *buf; + size_t size; + size_t ret; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if ((ret = FWRITE (W("abc"), 1, 3, fp)) != 3) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE), errno); + + if (fseek (fp, 0, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (FWRITE (W("z"), 1, 1, fp) != 1) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE), errno); + + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + /* Avoid truncating the buffer on close. */ + if (fseek (fp, 3, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (size != 3) + ERROR_RET1 ("size != 3\n"); + + if (buf[0] != W('z') + || buf[1] != W('b') + || buf[2] != W('c')) + { + PRINTF (W("error: buf {%c,%c,%c} != {z,b,c}\n"), + buf[0], buf[1], buf[2]); + return 1; + } + + free (buf); + + return 0; +} + +static int +do_test (void) +{ + int ret = 0; + + mcheck_pedantic (mcheck_abort); + + ret += do_test_bz18241 (); + ret += do_test_bz20181 (); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-mmap-eofsync.c b/REORG.TODO/libio/tst-mmap-eofsync.c new file mode 100644 index 0000000000..e8ef727148 --- /dev/null +++ b/REORG.TODO/libio/tst-mmap-eofsync.c @@ -0,0 +1,106 @@ +/* Test program for synchronization of stdio state with file after EOF. */ + +#include <stdio.h> +#include <error.h> +#include <errno.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static char *temp_file; +static int temp_fd; + +static char text1[] = "Line the first\n"; +static char text2[] = "Line the second\n"; + +static void +do_prepare (void) +{ + temp_fd = create_temp_file ("tst-mmap-eofsync.", &temp_file); + if (temp_fd == -1) + error (1, errno, "cannot create temporary file"); + else + { + ssize_t cc = write (temp_fd, text1, sizeof text1 - 1); + if (cc != sizeof text1 - 1) + error (1, errno, "cannot write to temporary file"); + } +} + +static int +do_test (void) +{ + FILE *f; + char buf[128]; + int result = 0; + int c; + + f = fopen (temp_file, "rm"); + if (f == NULL) + { + perror (temp_file); + return 1; + } + + if (fgets (buf, sizeof buf, f) == NULL) + { + perror ("fgets"); + return 1; + } + + if (strcmp (buf, text1)) + { + printf ("read \"%s\", expected \"%s\"\n", buf, text1); + result = 1; + } + + printf ("feof = %d, ferror = %d immediately after fgets\n", + feof (f), ferror (f)); + +#if 1 + c = fgetc (f); + if (c == EOF) + printf ("fgetc -> EOF (feof = %d, ferror = %d)\n", + feof (f), ferror (f)); + else + { + printf ("fgetc returned %o (feof = %d, ferror = %d)\n", + c, feof (f), ferror (f)); + result = 1; + } +#endif + + c = write (temp_fd, text2, sizeof text2 - 1); + if (c == sizeof text2 - 1) + printf ("wrote more to file\n"); + else + { + printf ("wrote %d != %zd (%m)\n", c, sizeof text2 - 1); + result = 1; + } + + if (fgets (buf, sizeof buf, f) == NULL) + { + printf ("second fgets fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + clearerr (f); + if (fgets (buf, sizeof buf, f) == NULL) + { + printf ("retry fgets fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + result = 1; + } + } + if (result == 0 && strcmp (buf, text2)) + { + printf ("second time read \"%s\", expected \"%s\"\n", buf, text2); + result = 1; + } + + fclose (f); + + return result; +} diff --git a/REORG.TODO/libio/tst-mmap-fflushsync.c b/REORG.TODO/libio/tst-mmap-fflushsync.c new file mode 100644 index 0000000000..24ae33cae7 --- /dev/null +++ b/REORG.TODO/libio/tst-mmap-fflushsync.c @@ -0,0 +1,99 @@ +/* Test program for synchronization of stdio state with file after fflush. */ + +#include <stdio.h> +#include <error.h> +#include <errno.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static char *temp_file; +static int temp_fd; + +static char text1[] = "Line the first\n"; +static char text2[] = "Line the second\n"; + +static void +do_prepare (void) +{ + temp_fd = create_temp_file ("tst-mmap-eofsync.", &temp_file); + if (temp_fd == -1) + error (1, errno, "cannot create temporary file"); + else + { + ssize_t cc = write (temp_fd, text1, sizeof text1 - 1); + if (cc != sizeof text1 - 1) + error (1, errno, "cannot write to temporary file"); + } +} + +static int +do_test (void) +{ + FILE *f; + char buf[128]; + int result = 0; + int c; + + f = fopen (temp_file, "rm"); + if (f == NULL) + { + perror (temp_file); + return 1; + } + + if (fgets (buf, sizeof buf, f) == NULL) + { + perror ("fgets"); + return 1; + } + + if (strcmp (buf, text1)) + { + printf ("read \"%s\", expected \"%s\"\n", buf, text1); + result = 1; + } + + printf ("feof = %d, ferror = %d immediately after fgets\n", + feof (f), ferror (f)); + + if (fflush (f) != 0) + { + printf ("fflush failed! %m\n"); + result = 1; + } + + c = write (temp_fd, text2, sizeof text2 - 1); + if (c == sizeof text2 - 1) + printf ("wrote more to file\n"); + else + { + printf ("wrote %d != %zd (%m)\n", c, sizeof text2 - 1); + result = 1; + } + + if (fgets (buf, sizeof buf, f) == NULL) + { + printf ("second fgets fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + clearerr (f); + if (fgets (buf, sizeof buf, f) == NULL) + { + printf ("retry fgets fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + result = 1; + } + } + if (result == 0 && strcmp (buf, text2)) + { + printf ("second time read \"%s\", expected \"%s\"\n", buf, text2); + result = 1; + } + + fclose (f); + + return result; +} diff --git a/REORG.TODO/libio/tst-mmap-offend.c b/REORG.TODO/libio/tst-mmap-offend.c new file mode 100644 index 0000000000..19732e6201 --- /dev/null +++ b/REORG.TODO/libio/tst-mmap-offend.c @@ -0,0 +1,86 @@ +/* Test case for bug with mmap stdio read past end of file. */ + +#include <stdio.h> +#include <error.h> +#include <errno.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static char *temp_file; + +static const char text1[] = "hello\n"; + +static void +do_prepare (void) +{ + int temp_fd = create_temp_file ("tst-mmap-offend.", &temp_file); + if (temp_fd == -1) + error (1, errno, "cannot create temporary file"); + else + { + ssize_t cc = write (temp_fd, text1, sizeof text1 - 1); + if (cc != sizeof text1 - 1) + error (1, errno, "cannot write to temporary file"); + } + close (temp_fd); +} + +static int +do_test (void) +{ + unsigned char buffer[8192]; + int result = 0; + FILE *f = fopen (temp_file, "rm"); + size_t cc; + + if (f == NULL) + { + perror (temp_file); + return 1; + } + + cc = fread (buffer, 1, sizeof (buffer), f); + printf ("fread %zu: \"%.*s\"\n", cc, (int) cc, buffer); + if (cc != sizeof text1 - 1) + { + perror ("fread"); + result = 1; + } + + if (fseek (f, 2048, SEEK_SET) != 0) + { + perror ("fseek off end"); + result = 1; + } + + if (fread (buffer, 1, sizeof (buffer), f) != 0 + || ferror (f) || !feof (f)) + { + printf ("after fread error %d eof %d\n", + ferror (f), feof (f)); + result = 1; + } + + printf ("ftell %ld\n", ftell (f)); + + if (fseek (f, 0, SEEK_SET) != 0) + { + perror ("fseek rewind"); + result = 1; + } + + cc = fread (buffer, 1, sizeof (buffer), f); + printf ("fread after rewind %zu: \"%.*s\"\n", cc, (int) cc, buffer); + if (cc != sizeof text1 - 1) + { + perror ("fread after rewind"); + result = 1; + } + + fclose (f); + return result; +} diff --git a/REORG.TODO/libio/tst-mmap-setvbuf.c b/REORG.TODO/libio/tst-mmap-setvbuf.c new file mode 100644 index 0000000000..56844bc3df --- /dev/null +++ b/REORG.TODO/libio/tst-mmap-setvbuf.c @@ -0,0 +1,81 @@ +/* Test setvbuf on readonly fopen (using mmap stdio). + Copyright (C) 2002-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main (void) +{ + char name[] = "/tmp/tst-mmap-setvbuf.XXXXXX"; + char buf[4096]; + const char * const test = "Let's see if mmap stdio works with setvbuf.\n"; + char temp[strlen (test) + 1]; + int fd = mkstemp (name); + FILE *f; + + if (fd == -1) + { + printf ("%u: cannot open temporary file: %m\n", __LINE__); + exit (1); + } + + f = fdopen (fd, "w"); + if (f == NULL) + { + printf ("%u: cannot fdopen temporary file: %m\n", __LINE__); + exit (1); + } + + fputs (test, f); + fclose (f); + + f = fopen (name, "rm"); + if (f == NULL) + { + printf ("%u: cannot fopen temporary file: %m\n", __LINE__); + exit (1); + } + + if (setvbuf (f, buf, _IOFBF, sizeof buf)) + { + printf ("%u: setvbuf failed: %m\n", __LINE__); + exit (1); + } + + if (fread (temp, 1, strlen (test), f) != strlen (test)) + { + printf ("%u: couldn't read the file back: %m\n", __LINE__); + exit (1); + } + temp [strlen (test)] = '\0'; + + if (strcmp (test, temp)) + { + printf ("%u: read different string than was written:\n%s%s", + __LINE__, test, temp); + exit (1); + } + + fclose (f); + + unlink (name); + exit (0); +} diff --git a/REORG.TODO/libio/tst-mmap2-eofsync.c b/REORG.TODO/libio/tst-mmap2-eofsync.c new file mode 100644 index 0000000000..05dedb8c20 --- /dev/null +++ b/REORG.TODO/libio/tst-mmap2-eofsync.c @@ -0,0 +1,137 @@ +/* Test program for synchronization of stdio state with file after EOF. */ + +#include <stdio.h> +#include <error.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +static void do_prepare (void); +#define PREPARE(argc, argv) do_prepare () +static int do_test (void); +#define TEST_FUNCTION do_test () +#include <test-skeleton.c> + +static char *temp_file; +static int temp_fd; + +static char *pages; + +static void +do_prepare (void) +{ + pages = xmalloc (getpagesize () * 2); + memset (pages, 'a', getpagesize ()); + memset (pages + getpagesize (), 'b', getpagesize ()); + + temp_fd = create_temp_file ("tst-mmap2-eofsync.", &temp_file); + if (temp_fd == -1) + error (1, errno, "cannot create temporary file"); + else + { + ssize_t cc = write (temp_fd, pages, getpagesize ()); + if (cc != getpagesize ()) + error (1, errno, "cannot write to temporary file"); + } +} + +static int +do_test (void) +{ + const size_t pagesize = getpagesize (); + FILE *f; + char buf[pagesize]; + int result = 0; + int c; + + f = fopen (temp_file, "rm"); + if (f == NULL) + { + perror (temp_file); + return 1; + } + + if (fread (buf, pagesize, 1, f) != 1) + { + perror ("fread"); + return 1; + } + + if (memcmp (buf, pages, pagesize)) + { + puts ("data mismatch in page 1"); + result = 1; + } + + printf ("feof = %d, ferror = %d immediately after fread\n", + feof (f), ferror (f)); + + c = fgetc (f); + if (c == EOF) + printf ("fgetc -> EOF (feof = %d, ferror = %d)\n", + feof (f), ferror (f)); + else + { + printf ("fgetc returned %o (feof = %d, ferror = %d)\n", + c, feof (f), ferror (f)); + result = 1; + } + + c = write (temp_fd, pages + pagesize, pagesize); + if (c == (ssize_t) pagesize) + printf ("wrote more to file\n"); + else + { + printf ("wrote %d != %zd (%m)\n", c, pagesize); + result = 1; + } + + if (fread (buf, pagesize, 1, f) != 1) + { + printf ("second fread fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + clearerr (f); + if (fread (buf, pagesize, 1, f) != 1) + { + printf ("retry fread fails: feof = %d, ferror = %d (%m)\n", + feof (f), ferror (f)); + result = 1; + } + } + if (result == 0 && memcmp (buf, pages + pagesize, pagesize)) + { + puts ("data mismatch in page 2"); + result = 1; + } + + fseek (f, pagesize - 1, SEEK_SET); + c = fgetc (f); + if (c != 'a') + { + printf ("fgetc at end of page 1 read '%c' (%m)\n", c); + result = 1; + } + + if (ftruncate (temp_fd, pagesize) < 0) + { + printf ("ftruncate failed: %m\n"); + result = 1; + } + + fflush (f); + + c = fgetc (f); + if (c == EOF) + printf ("after truncate fgetc -> EOF (feof = %d, ferror = %d)\n", + feof (f), ferror (f)); + else + { + printf ("after truncate fgetc returned '%c' (feof = %d, ferror = %d)\n", + c, feof (f), ferror (f)); + result = 1; + } + + fclose (f); + + return result; +} diff --git a/REORG.TODO/libio/tst-popen1.c b/REORG.TODO/libio/tst-popen1.c new file mode 100644 index 0000000000..bae6615b9b --- /dev/null +++ b/REORG.TODO/libio/tst-popen1.c @@ -0,0 +1,49 @@ +#include <fcntl.h> +#include <stdio.h> + +static int +do_test (void) +{ + int res = 0; + + FILE *fp = popen ("echo hello", "r"); + if (fp == NULL) + { + puts ("first popen failed"); + res = 1; + } + else + { + int fd = fileno (fp); + if (fcntl (fd, F_GETFD) == FD_CLOEXEC) + { + puts ("first popen(\"r\") set FD_CLOEXEC"); + res = 1; + } + + fclose (fp); + } + + fp = popen ("echo hello", "re"); + if (fp == NULL) + { + puts ("second popen failed"); + res = 1; + } + else + { + int fd = fileno (fp); + if (fcntl (fd, F_GETFD) != FD_CLOEXEC) + { + puts ("second popen(\"r\") did not set FD_CLOEXEC"); + res = 1; + } + + fclose (fp); + } + + return res; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-setvbuf1.c b/REORG.TODO/libio/tst-setvbuf1.c new file mode 100644 index 0000000000..9222d4050d --- /dev/null +++ b/REORG.TODO/libio/tst-setvbuf1.c @@ -0,0 +1,39 @@ +/* Dereived from the test case in BZ #2337. */ +#include <errno.h> +#include <error.h> +#include <fcntl.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> + + +static char buf[512] __attribute__ ((aligned (4096))); + + +static int +do_test (void) +{ + setlocale (LC_ALL, "de_DE.UTF-8"); + + FILE *fp = fdopen (dup (STDOUT_FILENO), "a"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"a\")"); + + setvbuf (fp, buf, _IOFBF, sizeof (buf)); + + /* fwprintf to unbuffered stream. */ + fwprintf (fp, L"hello.\n"); + + fclose (fp); + + /* touch my buffer */ + buf[45] = 'a'; + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-sscanf.c b/REORG.TODO/libio/tst-sscanf.c new file mode 100644 index 0000000000..fb4be34b77 --- /dev/null +++ b/REORG.TODO/libio/tst-sscanf.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <wchar.h> + +#define WCS_LENGTH 256 + +static int +do_test (void) +{ + const char cnv[] ="%l[abc]"; + const char str[] = "abbcXab"; + wchar_t wcs[WCS_LENGTH]; + int result = 0; + + sscanf (str, cnv, wcs); + printf ("wcs = \"%ls\"\n", wcs); + fflush (stdout); + result = wcscmp (wcs, L"abbc") != 0; + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-swscanf.c b/REORG.TODO/libio/tst-swscanf.c new file mode 100644 index 0000000000..05be4e6e71 --- /dev/null +++ b/REORG.TODO/libio/tst-swscanf.c @@ -0,0 +1,101 @@ +#include <locale.h> +#include <stdio.h> +#include <string.h> +#include <wchar.h> + + +static int do_test (const char *loc); + + +int +main (void) +{ + int result; + + result = do_test ("C"); + result |= do_test ("de_DE.ISO-8859-1"); + result |= do_test ("de_DE.UTF-8"); + result |= do_test ("ja_JP.EUC-JP"); + + return result; +} + + +static const struct +{ + const wchar_t *fmt; + const wchar_t *wfmt; + const wchar_t *arg; + int retval; + const char *res; + const wchar_t *wres; + int only_C_locale; +} tests[] = + { + { L"%[abc]", L"%l[abc]", L"aabbccddaabb", 1 ,"aabbcc", L"aabbcc", 0 }, + { L"%[^def]", L"%l[^def]", L"aabbccddaabb", 1, "aabbcc", L"aabbcc", 0 }, + { L"%[^abc]", L"%l[^abc]", L"aabbccddaabb", 0, "", L"", 0 }, + { L"%[a-c]", L"%l[a-c]", L"aabbccddaabb", 1, "aabbcc", L"aabbcc", 1 }, + { L"%[^d-f]", L"%l[^d-f]", L"aabbccddaabb", 1, "aabbcc", L"aabbcc", 1 }, + { L"%[^a-c]", L"%l[^a-c]", L"aabbccddaabb", 0, "", L"", 1 }, + { L"%[^a-c]", L"%l[^a-c]", L"bbccddaabb", 0, "", L"", 1 } + }; + + +static int +do_test (const char *loc) +{ + size_t n; + int result = 0; + + if (setlocale (LC_ALL, loc) == NULL) + { + printf ("cannot set locale \"%s\": %m\n", loc); + return 1; + } + + printf ("\nnew locale: \"%s\"\n", loc); + + for (n = 0; n < sizeof (tests) / sizeof (tests[0]); ++n) + { + char buf[100]; + wchar_t wbuf[100]; + + if (tests[n].only_C_locale && strcmp (loc, "C") != 0) + continue; + + if (swscanf (tests[n].arg, tests[n].fmt, buf) != tests[n].retval) + { + printf ("swscanf (\"%S\", \"%S\", ...) failed\n", + tests[n].arg, tests[n].fmt); + result = 1; + } + else if (tests[n].retval != 0 && strcmp (buf, tests[n].res) != 0) + { + printf ("swscanf (\"%S\", \"%S\", ...) return \"%s\", expected \"%s\"\n", + tests[n].arg, tests[n].fmt, buf, tests[n].res); + result = 1; + } + else + printf ("swscanf (\"%S\", \"%S\", ...) OK\n", + tests[n].arg, tests[n].fmt); + + if (swscanf (tests[n].arg, tests[n].wfmt, wbuf) != tests[n].retval) + { + printf ("swscanf (\"%S\", \"%S\", ...) failed\n", + tests[n].arg, tests[n].wfmt); + result = 1; + } + else if (tests[n].retval != 0 && wcscmp (wbuf, tests[n].wres) != 0) + { + printf ("swscanf (\"%S\", \"%S\", ...) return \"%S\", expected \"%S\"\n", + tests[n].arg, tests[n].wfmt, wbuf, tests[n].wres); + result = 1; + } + else + printf ("swscanf (\"%S\", \"%S\", ...) OK\n", + tests[n].arg, tests[n].wfmt); + } + + return result; +} diff --git a/REORG.TODO/libio/tst-ungetwc1.c b/REORG.TODO/libio/tst-ungetwc1.c new file mode 100644 index 0000000000..f71b39059f --- /dev/null +++ b/REORG.TODO/libio/tst-ungetwc1.c @@ -0,0 +1,84 @@ +/* Taken from the Li18nux base test suite. */ + +#define _XOPEN_SOURCE 500 +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <wchar.h> + +static int +do_test (void) +{ + FILE *fp; + const char *str = "abcdef"; + wint_t ret, wc, ungetone = 0x00E4; /* 0x00E4 means `a umlaut'. */ + char fname[] = "/tmp/tst-ungetwc1.out.XXXXXX"; + int fd; + int result = 0; + + puts ("This program runs on de_DE.UTF-8 locale."); + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + fprintf (stderr, "Err: Cannot run on the de_DE.UTF-8 locale"); + exit (EXIT_FAILURE); + } + + fd = mkstemp (fname); + if (fd == -1) + { + printf ("cannot open temp file: %m\n"); + exit (EXIT_FAILURE); + } + + /* Write some characters to `testfile'. */ + if ((fp = fdopen (fd, "w")) == NULL) + { + fprintf (stderr, "Cannot open 'testfile'."); + exit (EXIT_FAILURE); + } + fputs (str, fp); + fclose (fp); + + /* Open `testfile'. */ + if ((fp = fopen (fname, "r")) == NULL) + { + fprintf (stderr, "Cannot open 'testfile'."); + exit (EXIT_FAILURE); + } + + /* Unget a character. */ + ret = ungetwc (ungetone, fp); + printf ("Unget a character (0x%04x)\n", (unsigned int) ungetone); + fflush (stdout); + if (ret == WEOF) + { + puts ("ungetwc() returns NULL."); + exit (EXIT_SUCCESS); + } + + /* Reget a character. */ + wc = getwc (fp); + printf ("Reget a character (0x%04x)\n", (unsigned int) wc); + fflush (stdout); + if (wc == ungetone) + { + puts ("The ungotten character is equal to the regotten character."); + fflush (stdout); + } + else + { + puts ("The ungotten character is not equal to the regotten character."); + printf ("ungotten one: %04x, regetone: %04x", ungetone, wc); + fflush (stdout); + result = 1; + } + fclose (fp); + + unlink (fname); + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-ungetwc2.c b/REORG.TODO/libio/tst-ungetwc2.c new file mode 100644 index 0000000000..a7c5193f5f --- /dev/null +++ b/REORG.TODO/libio/tst-ungetwc2.c @@ -0,0 +1,84 @@ +/* Taken from the Li18nux base test suite. */ + +#define _XOPEN_SOURCE 500 +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <wchar.h> + +static int +do_test (void) +{ + FILE *fp; + const char *str = "abcdef"; + wint_t ret, wc; + char fname[] = "/tmp/tst-ungetwc2.out.XXXXXX"; + int fd; + long int pos; + int result = 0; + + puts ("This program runs on de_DE.UTF-8 locale."); + if (setlocale (LC_ALL, "de_DE.UTF-8") == NULL) + { + fprintf (stderr, "Err: Cannot run on the de_DE.UTF-8 locale\n"); + exit (EXIT_FAILURE); + } + + /* Write some characters to `testfile'. */ + fd = mkstemp (fname); + if (fd == -1) + { + printf ("cannot open temp file: %m\n"); + exit (EXIT_FAILURE); + } + if ((fp = fdopen (fd, "w")) == NULL) + { + fprintf (stderr, "Cannot open 'testfile'.\n"); + exit (EXIT_FAILURE); + } + fputs (str, fp); + fclose (fp); + + /* Open `testfile'. */ + if ((fp = fopen (fname, "r")) == NULL) + { + fprintf (stderr, "Cannot open 'testfile'."); + exit (EXIT_FAILURE); + } + + /* Get a character. */ + wc = getwc (fp); + pos = ftell (fp); + printf ("After get a character: %ld\n", pos); + if (pos != 1) + result = 1; + + /* Unget a character. */ + ret = ungetwc (wc, fp); + if (ret == WEOF) + { + fprintf (stderr, "ungetwc() returns NULL."); + exit (EXIT_FAILURE); + } + pos = ftell (fp); + printf ("After unget a character: %ld\n", pos); + if (pos != 0) + result = 1; + + /* Reget a character. */ + wc = getwc (fp); + pos = ftell (fp); + printf ("After reget a character: %ld\n", pos); + if (pos != 1) + result = 1; + + fclose (fp); + + unlink (fname); + + return result; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-widetext.c b/REORG.TODO/libio/tst-widetext.c new file mode 100644 index 0000000000..6d5fa33e77 --- /dev/null +++ b/REORG.TODO/libio/tst-widetext.c @@ -0,0 +1,372 @@ +/* Test program for the wide character stream functions handling larger + amounts of text. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <iconv.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> + +/* Approximate size of the file (must be larger). */ +#define SIZE 210000 + + +static int +do_test (void) +{ + char name[] = "/tmp/widetext.out.XXXXXX"; + char mbbuf[SIZE]; + char mb2buf[SIZE]; + wchar_t wcbuf[SIZE]; + wchar_t wc2buf[SIZE]; + size_t mbsize; + size_t wcsize; + int fd; + FILE *fp; + size_t n; + int res; + int status = 0; + wchar_t *wcp; + + setlocale (LC_ALL, "de_DE.UTF-8"); + printf ("locale used: %s\n\n", setlocale (LC_ALL, NULL)); + + /* Read the file into memory. */ + mbsize = fread (mbbuf, 1, SIZE, stdin); + if (mbsize == 0) + { + printf ("%u: cannot read input file from standard input: %m\n", + __LINE__); + exit (1); + } + + printf ("INFO: input file has %Zd bytes\n", mbsize); + + /* First convert the text to wide characters. We use iconv here. */ + { + iconv_t cd; + char *inbuf = mbbuf; + size_t inleft = mbsize; + char *outbuf = (char *) wcbuf; + size_t outleft = sizeof (wcbuf); + size_t nonr; + + cd = iconv_open ("WCHAR_T", "UTF-8"); + if (cd == (iconv_t) -1) + { + printf ("%u: cannot get iconv descriptor for conversion to UCS4\n", + __LINE__); + exit (1); + } + + /* We must need only one call and there must be no losses. */ + nonr = iconv (cd, &inbuf, &inleft, &outbuf, &outleft); + if (nonr != 0 && nonr != (size_t) -1) + { + printf ("%u: iconv performed %Zd nonreversible conversions\n", + __LINE__, nonr); + exit (1); + } + + if (nonr == (size_t) -1) + { + printf ("\ +%u: iconv returned with %Zd and errno = %m (inleft: %Zd, outleft: %Zd)\n", + __LINE__, nonr, inleft, outleft); + exit (1); + } + + if (inleft != 0) + { + printf ("%u: iconv didn't convert all input\n", __LINE__); + exit (1); + } + + iconv_close (cd); + + if ((sizeof (wcbuf) - outleft) % sizeof (wchar_t) != 0) + { + printf ("%u: iconv converted not complete wchar_t\n", __LINE__); + exit (1); + } + + wcsize = (sizeof (wcbuf) - outleft) / sizeof (wchar_t); + assert (wcsize + 1 <= SIZE); + } + + /* Now that we finished the preparations, run the first test. We + are writing the wide char data out and read it back in. We write + and read single characters. */ + + fd = mkstemp (name); + if (fd == -1) + { + printf ("%u: cannot open temporary file: %m\n", __LINE__); + exit (1); + } + + unlink (name); + + fp = fdopen (dup (fd), "w"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for writing failed: %m\n", __LINE__); + exit (1); + } + + for (n = 0; n < wcsize; ++n) + { + if (fputwc (wcbuf[n], fp) == WEOF) + { + printf ("%u: fputwc failed: %m\n", __LINE__); + exit (1); + } + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after single-character writing failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + lseek (fd, SEEK_SET, 0); + fp = fdopen (dup (fd), "r"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__); + exit (1); + } + + for (n = 0; n < wcsize; ++n) + { + wint_t wch = fgetwc (fp); + if (wch == WEOF) + { + printf ("%u: fgetwc failed (idx %Zd): %m\n", __LINE__, n); + exit (1); + } + wc2buf[n] = wch; + } + + /* There should be nothing else. */ + if (fgetwc (fp) != WEOF) + { + printf ("%u: too many characters available with fgetwc\n", __LINE__); + status = 1; + } + else if (wmemcmp (wcbuf, wc2buf, wcsize) != 0) + { + printf ("%u: buffer read with fgetwc differs\n", __LINE__); + status = 1; + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after single-character reading failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + /* Just make sure there are no two errors which hide each other, read the + file using the `char' functions. */ + + lseek (fd, SEEK_SET, 0); + fp = fdopen (fd, "r"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__); + exit (1); + } + + if (fread (mb2buf, 1, mbsize, fp) != mbsize) + { + printf ("%u: cannot read all of the temp file\n", __LINE__); + status = 1; + } + else + { + /* Make sure there is nothing left. */ + if (fgetc (fp) != EOF) + { + printf ("%u: more input available\n", __LINE__); + status = 1; + } + + if (memcmp (mb2buf, mbbuf, mbsize) != 0) + { + printf ("%u: buffer written with fputwc differs\n", __LINE__); + status = 1; + } + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after single-character reading failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + /* Now to reading and writing line-wise. */ + + fd = mkstemp (strcpy (name, "/tmp/widetext.out.XXXXXX")); + if (fd == -1) + { + printf ("%u: cannot open temporary file: %m\n", __LINE__); + exit (1); + } + + unlink (name); + + fp = fdopen (dup (fd), "w"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for writing failed: %m\n", __LINE__); + exit (1); + } + + for (wcp = wcbuf; wcp < &wcbuf[wcsize]; ) + { + wchar_t *wendp = wcschr (wcp, L'\n'); + + if (wendp != NULL) + { + /* Temporarily NUL terminate the line. */ + wchar_t save = wendp[1]; + wendp[1] = L'\0'; + + fputws (wcp, fp); + + wendp[1] = save; + wcp = &wendp[1]; + } + else + { + fputws (wcp, fp); + wcp = wcschr (wcp, L'\0'); + assert (wcp == &wcbuf[wcsize]); + } + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after line-wise writing failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + lseek (fd, SEEK_SET, 0); + fp = fdopen (dup (fd), "r"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__); + exit (1); + } + + for (wcp = wc2buf; wcp < &wc2buf[wcsize]; ) + { + if (fgetws (wcp, &wc2buf[wcsize] - wcp + 1, fp) == NULL) + { + printf ("%u: short read using fgetws (only %td of %Zd)\n", + __LINE__, wcp - wc2buf, wcsize); + status = 1; + break; + } + wcp = wcschr (wcp, L'\0'); + } + + if (wcp > &wc2buf[wcsize]) + { + printf ("%u: fgetws read too much\n", __LINE__); + status = 1; + } + else if (fgetwc (fp) != WEOF) + { + /* There should be nothing else. */ + printf ("%u: too many characters available with fgetws\n", __LINE__); + status = 1; + } + + if (wcp >= &wc2buf[wcsize] && wmemcmp (wcbuf, wc2buf, wcsize) != 0) + { + printf ("%u: buffer read with fgetws differs\n", __LINE__); + status = 1; + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after single-character reading failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + /* Just make sure there are no two errors which hide each other, read the + file using the `char' functions. */ + + lseek (fd, SEEK_SET, 0); + fp = fdopen (fd, "r"); + if (fp == NULL) + { + printf ("%u: fdopen of temp file for reading failed: %m\n", __LINE__); + exit (1); + } + + if (fread (mb2buf, 1, mbsize, fp) != mbsize) + { + printf ("%u: cannot read all of the temp file\n", __LINE__); + status = 1; + } + else + { + /* Make sure there is nothing left. */ + if (fgetc (fp) != EOF) + { + printf ("%u: more input available\n", __LINE__); + status = 1; + } + + if (memcmp (mb2buf, mbbuf, mbsize) != 0) + { + printf ("%u: buffer written with fputws differs\n", __LINE__); + status = 1; + } + } + + res = fclose (fp); + if (res != 0) + { + printf ("%u: fclose after single-character reading failed (%d): %m\n", + __LINE__, res); + exit (1); + } + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/REORG.TODO/libio/tst-widetext.input b/REORG.TODO/libio/tst-widetext.input new file mode 100644 index 0000000000..b4382c0008 --- /dev/null +++ b/REORG.TODO/libio/tst-widetext.input @@ -0,0 +1,1992 @@ + +Full BMP Test File +------------------ + +Markus Kuhn <mkuhn@acm.org> -- 2000-07-25 + +This file contains the UTF-8 sequences of all code positions in the +ISO 10646-1 Basic Multilingual Plane, except for the C0 and C1 control +character areas. This corresponds to all codes in the range U+0020 - +U+007E and U+00A0 - U+FFFF. + +NOTE: The ranges U+D800 - U+DFFF (surrogates) and U+FFFE - U+FFFF are +not supposed to appear in valid UTF-8 files normally and UTF-8 +decoders are allowed to treat them like malformed sequences. + + +Basic Latin (U+0000-U+007F): + + !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +`abcdefghijklmnopqrstuvwxyz{|}~ + +Latin-1 Supplement (U+0080-U+00FF): + + ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß +àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ + +Latin Extended-A (U+0100-U+017F): + +ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿ +ŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ + +Latin Extended-B (U+0180-U+024F): + +ƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿ +ǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴǵǶǷǸǹǺǻǼǽǾǿ +ȀȁȂȃȄȅȆȇȈȉȊȋȌȍȎȏȐȑȒȓȔȕȖȗȘșȚțȜȝȞȟȠȡȢȣȤȥȦȧȨȩȪȫȬȭȮȯȰȱȲȳȴȵȶȷȸȹȺȻȼȽȾȿ +ɀɁɂɃɄɅɆɇɈɉɊɋɌɍɎɏ + +IPA Extensions (U+0250-U+02AF): + +ɐɑɒɓɔɕɖɗɘəɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏ +ʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ + +Spacing Modifier Letters (U+02B0-U+02FF): + +ʰʱʲʳʴʵʶʷʸʹʺʻʼʽʾʿˀˁ˂˃˄˅ˆˇˈˉˊˋˌˍˎˏːˑ˒˓˔˕˖˗˘˙˚˛˜˝˞˟ˠˡˢˣˤ˥˦˧˨˩˪˫ˬ˭ˮ˯ +˰˱˲˳˴˵˶˷˸˹˺˻˼˽˾˿ + +Combining Diacritical Marks (U+0300-U+036F): + +◌̀◌́◌̂◌̃◌̄◌̅◌̆◌̇◌̈◌̉◌̊◌̋◌̌◌̍◌̎◌̏◌̐◌̑◌̒◌̓◌̔◌̕◌̖◌̗◌̘◌̙◌̚◌̛◌̜◌̝◌̞◌̟◌̠◌̡◌̢◌̣◌̤◌̥◌̦◌̧◌̨◌̩◌̪◌̫◌̬◌̭◌̮◌̯◌̰◌̱◌̲◌̳◌̴◌̵◌̶◌̷◌̸◌̹◌̺◌̻◌̼◌̽◌̾◌̿ +◌̀◌́◌͂◌̓◌̈́◌ͅ◌͆◌͇◌͈◌͉◌͊◌͋◌͌◌͍◌͎͏͓͔͕͖͙͚͐͑͒͗͛͘͜͟͝͞◌͠◌͡◌ͣͤͥͦͧͨͩͪͫͬͭͮͯ͢ + +Greek (U+0370-U+03FF): + +ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;Ϳ΄΅Ά·ΈΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήί +ΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯ +ϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿ + +Cyrillic (U+0400-U+04FF): + +ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп +рстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿ +Ҁҁ҂◌҃◌҄◌҅◌҆҇ ҈ ҉ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿ +ӀӁӂӃӄӅӆӇӈӉӊӋӌӍӎӏӐӑӒӓӔӕӖӗӘәӚӛӜӝӞӟӠӡӢӣӤӥӦӧӨөӪӫӬӭӮӯӰӱӲӳӴӵӶӷӸӹӺӻӼӽӾӿ + +Free block (U+0500-U+052F): + +ԀԁԂԃԄԅԆԇԈԉԊԋԌԍԎԏԐԑԒԓԔԕԖԗԘԙԚԛԜԝԞԟԠԡԢԣԤԥԦԧԨԩԪԫԬԭԮԯ + +Armenian (U+0530-U+058F): + +ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖՙ՚՛՜՝՞՟ՠաբգդեզէըթժիլխծկ +հձղճմյնշոչպջռսվտրցւփքօֆևֈ։֊֍֎֏ + +Hebrew (U+0590-U+05FF): + +◌֑◌֒◌֓◌֔◌֕◌֖◌֗◌֘◌֙◌֚◌֛◌֜◌֝◌֞◌֟◌֠◌֢֡◌֣◌֤◌֥◌֦◌֧◌֨◌֩◌֪◌֫◌֬◌֭◌֮◌֯◌ְ◌ֱ◌ֲ◌ֳ◌ִ◌ֵ◌ֶ◌ַ◌ָ◌ֹֺ◌ֻ◌ּ◌ֽ־◌ֿ׀◌ׁ◌ׂ׃◌ׅׄ׆ׇ +אבגדהוזחטיךכלםמןנסעףפץצקרשתׯװױײ׳״ + +Arabic (U+0600-U+06FF): + +؆؇؈؉؊؋،؍؎؏ؘؙؚؐؑؒؓؔؕؖؗ؛؝؞؟ؠءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿ +ـفقكلمنهوىي◌ً◌ٌ◌ٍ◌َ◌ُ◌ِ◌ّ◌ْ◌ٓ◌ٔ◌ٕٖٜٟٗ٘ٙٚٛٝٞ٠١٢٣٤٥٦٧٨٩٪٫٬٭ٮٯ◌ٰٱٲٳٴٵٶٷٸٹٺٻټٽپٿ +ڀځڂڃڄڅچڇڈډڊڋڌڍڎڏڐڑڒړڔڕږڗژڙښڛڜڝڞڟڠڡڢڣڤڥڦڧڨکڪګڬڭڮگڰڱڲڳڴڵڶڷڸڹںڻڼڽھڿ +ۀہۂۃۄۅۆۇۈۉۊۋیۍێۏېۑےۓ۔ە◌ۖ◌ۗ◌ۘ◌ۙ◌ۚ◌ۛ◌ۜ ۞◌۟◌۠◌ۡ◌ۢ◌ۣ◌ۤۥۦ◌ۧ◌ۨ۩◌۪◌۫◌۬◌ۭۮۯ۰۱۲۳۴۵۶۷۸۹ۺۻۼ۽۾ۿ + +Syriac (U+0700-U+074F): + +܀܁܂܃܄܅܆܇܈܉܊܋܌܍ܐ◌ܑܒܓܔܕܖܗܘܙܚܛܜܝܞܟܠܡܢܣܤܥܦܧܨܩܪܫܬܭܮܯ◌ܰ◌ܱ◌ܲ◌ܳ◌ܴ◌ܵ◌ܶ◌ܷ◌ܸ◌ܹ◌ܺ◌ܻ◌ܼ◌ܽ◌ܾ◌ܿ +◌݀◌݁◌݂◌݃◌݄◌݅◌݆◌݇◌݈◌݉◌݊ݍݎݏ + +Free block (U+0750-U+077F): + +ݐݑݒݓݔݕݖݗݘݙݚݛݜݝݞݟݠݡݢݣݤݥݦݧݨݩݪݫݬݭݮݯݰݱݲݳݴݵݶݷݸݹݺݻݼݽݾݿ + +Thaana (U+0780-U+07BF): + +ހށނރބޅކއވމފދތލގޏސޑޒޓޔޕޖޗޘޙޚޛޜޝޞޟޠޡޢޣޤޥ◌ަ◌ާ◌ި◌ީ◌ު◌ޫ◌ެ◌ޭ◌ޮ◌ޯ◌ްޱ + +Free block (U+07C0-U+08FF): + +߀߁߂߃߄߅߆߇߈߉ߊߋߌߍߎߏߐߑߒߓߔߕߖߗߘߙߚߛߜߝߞߟߠߡߢߣߤߥߦߧߨߩߪ߲߫߬߭߮߯߰߱߳ߴߵ߶߷߸߹ߺ߽߾߿ +ࠀࠁࠂࠃࠄࠅࠆࠇࠈࠉࠊࠋࠌࠍࠎࠏࠐࠑࠒࠓࠔࠕࠖࠗ࠘࠙ࠚࠛࠜࠝࠞࠟࠠࠡࠢࠣࠤࠥࠦࠧࠨࠩࠪࠫࠬ࠭࠰࠱࠲࠳࠴࠵࠶࠷࠸࠹࠺࠻࠼࠽࠾ +ࡀࡁࡂࡃࡄࡅࡆࡇࡈࡉࡊࡋࡌࡍࡎࡏࡐࡑࡒࡓࡔࡕࡖࡗࡘ࡙࡚࡛࡞ࡠࡡࡢࡣࡤࡥࡦࡧࡨࡩࡪࡰࡱࡲࡳࡴࡵࡶࡷࡸࡹࡺࡻࡼࡽࡾࡿ +ࢀࢁࢂࢃࢄࢅࢆࢇ࢈ࢉࢊࢋࢌࢍࢎ࢙࢚࢛࢘࢜࢝࢞࢟ࢠࢡࢢࢣࢤࢥࢦࢧࢨࢩࢪࢫࢬࢭࢮࢯࢰࢱࢲࢳࢴࢵࢶࢷࢸࢹࢺࢻࢼࢽࢾࢿ +ࣀࣁࣂࣃࣄࣅࣆࣇࣈࣉࣰࣱࣲ࣏࣐࣑࣒࣓ࣣࣦࣩ࣭࣮࣯ࣶࣹࣺ࣊࣋࣌࣍࣎ࣔࣕࣖࣗࣘࣙࣚࣛࣜࣝࣞࣟ࣠࣡ࣤࣥࣧࣨ࣪࣫࣬ࣳࣴࣵࣷࣸࣻࣼࣽࣾࣿ + +Devanagari (U+0900-U+097F): + +ऀ◌ँ◌ंःऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढणतथदधनऩपफबभमयरऱलळऴवशषसहऺऻ◌़ऽाि +ी◌ु◌ू◌ृ◌ॄ◌ॅ◌ॆ◌े◌ैॉॊोौ◌्ॎॏॐ◌॑◌॒◌॓◌॔ॕॖॗक़ख़ग़ज़ड़ढ़फ़य़ॠॡ◌ॢ◌ॣ।॥०१२३४५६७८९॰ॱॲॳॴॵॶॷॸॹॺॻॼॽॾॿ + +Bengali (U+0980-U+09FF): + +ঀ◌ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ◌়ঽাি +ী◌ু◌ূ◌ৃ◌ৄেৈোৌ◌্ৎৗড়ঢ়য়ৠৡ◌ৢ◌ৣ০১২৩৪৫৬৭৮৯ৰৱ৲৳৴৵৶৷৸৹৺৻ৼ৽৾ + +Gurmukhi (U+0A00-U+0A7F): + +ਁ◌ਂਃਅਆਇਈਉਊਏਐਓਔਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਲ਼ਵਸ਼ਸਹ◌਼ਾਿ +ੀ◌ੁ◌ੂ◌ੇ◌ੈ◌ੋ◌ੌ◌੍ੑਖ਼ਗ਼ਜ਼ੜਫ਼੦੧੨੩੪੫੬੭੮੯◌ੰ◌ੱੲੳੴੵ੶ + +Gujarati (U+0A80-U+0AFF): + +◌ઁ◌ંઃઅઆઇઈઉઊઋઌઍએઐઑઓઔકખગઘઙચછજઝઞટઠડઢણતથદધનપફબભમયરલળવશષસહ◌઼ઽાિ +ી◌ુ◌ૂ◌ૃ◌ૄ◌ૅ◌ે◌ૈૉોૌ◌્ૐૠૡૢૣ૦૧૨૩૪૫૬૭૮૯૰૱ૹૺૻૼ૽૾૿ + +Odia (U+0B00-U+0B7F): + +◌ଁଂଃଅଆଇଈଉଊଋଌଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଳଵଶଷସହ◌଼ଽା◌ି +ୀ◌ୁ◌ୂ◌ୃୄେୈୋୌ◌୍୕◌ୖୗଡ଼ଢ଼ୟୠୡୢୣ୦୧୨୩୪୫୬୭୮୯୰ୱ୲୳୴୵୶୷ + +Tamil (U+0B80-U+0BFF): + +◌ஂஃஅஆஇஈஉஊஎஏஐஒஓஔகஙசஜஞடணதநனபமயரறலளழவஶஷஸஹாி +◌ீுூெேைொோௌ◌்ௐௗ௦௧௨௩௪௫௬௭௮௯௰௱௲௳௴௵௶௷௸௹௺ + +Telugu (U+0C00-U+0C7F): + +ఀఁంఃఄఅఆఇఈఉఊఋఌఎఏఐఒఓఔకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలళఴవశషసహ఼ఽ◌ా◌ి +◌ీుూృౄ◌ె◌ే◌ై◌ొ◌ో◌ౌ◌్◌ౕ◌ౖౘౙౚౝౠౡౢౣ౦౧౨౩౪౫౬౭౮౯౷౸౹౺౻౼౽౾౿ + +Kannada (U+0C80-U+0CFF): + +ಀಁಂಃ಄ಅಆಇಈಉಊಋಌಎಏಐಒಓಔಕಖಗಘಙಚಛಜಝಞಟಠಡಢಣತಥದಧನಪಫಬಭಮಯರಱಲಳವಶಷಸಹ಼ಽಾ◌ಿ +ೀುೂೃೄ◌ೆೇೈೊೋ◌ೌ◌್ೕೖೝೞೠೡೢೣ೦೧೨೩೪೫೬೭೮೯ೱೲೳ + +Malayalam (U+0D00-U+0D7F): + +ഀഁംഃഄഅആഇഈഉഊഋഌഎഏഐഒഓഔകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനഩപഫബഭമയരറലളഴവശഷസഹഺ഻഼ഽാി +ീ◌ു◌ൂ◌ൃൄെേൈൊോൌ◌്ൎ൏ൔൕൖൗ൘൙൚൛൜൝൞ൟൠൡൢൣ൦൧൨൩൪൫൬൭൮൯൰൱൲൳൴൵൶൷൸൹ൺൻർൽൾൿ + +Sinhala (U+0D80-U+0DFF): + +ඁංඃඅආඇඈඉඊඋඌඍඎඏඐඑඒඓඔඕඖකඛගඝඞඟචඡජඣඤඥඦටඨඩඪණඬතථදධනඳපඵබභමඹයරල +වශෂසහළෆ◌්ාැෑ◌ි◌ී◌ු◌ූෘෙේෛොෝෞෟ෦෧෨෩෪෫෬෭෮෯ෲෳ෴ + +Thai (U+0E00-U+0E7F): + +กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะ◌ัาำ◌ิ◌ี◌ึ◌ื◌ุ◌ู◌ฺ฿ +เแโใไๅๆ◌็◌่◌้◌๊◌๋◌์◌ํ◌๎๏๐๑๒๓๔๕๖๗๘๙๚๛ + +Lao (U+0E80-U+0EFF): + +ກຂຄຆງຈຉຊຌຍຎຏຐຑຒຓດຕຖທຘນບປຜຝພຟຠມຢຣລວຨຩສຫຬອຮຯະ◌ັາຳ◌ິ◌ີ◌ຶ◌ື◌ຸ◌຺ູ◌ົ◌ຼຽ +ເແໂໃໄໆ◌່◌້◌໊◌໋◌໌◌ໍ໎໐໑໒໓໔໕໖໗໘໙ໜໝໞໟ + +Tibetan (U+0F00-U+0FFF): + +ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗◌༘◌༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴◌༵༶◌༷༸◌༹༺༻༼༽༾༿ +ཀཁགགྷངཅཆཇཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ◌ཱ◌ི◌ཱི◌ུ◌ཱུ◌ྲྀ◌ཷ◌ླྀ◌ཹ◌ེ◌ཻ◌ོ◌ཽ◌ཾཿ +◌ྀ◌ཱྀ◌ྂ◌ྃ◌྄྅◌྆◌྇ྈྉྊྋྌྍྎྏ◌ྐ◌ྑ◌ྒ◌ྒྷ◌ྔ◌ྕ◌ྖ◌ྗ◌ྙ◌ྚ◌ྛ◌ྜ◌ྜྷ◌ྞ◌ྟ◌ྠ◌ྡ◌ྡྷ◌ྣ◌ྤ◌ྥ◌ྦ◌ྦྷ◌ྨ◌ྩ◌ྪ◌ྫ◌ྫྷ◌ྭ◌ྮ◌ྯ◌ྰ◌ྱ◌ྲ◌ླ◌ྴ◌ྵ◌ྶ◌ྷ◌ྸ◌ྐྵ◌ྺ◌ྻ◌ྼ྾྿ +࿀࿁࿂࿃࿄࿅◌࿆࿇࿈࿉࿊࿋࿌࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚ + +Myanmar (U+1000-U+109F): + +ကခဂဃငစဆဇဈဉညဋဌဍဎဏတထဒဓနပဖဗဘမယရလဝသဟဠအဢဣဤဥဦဧဨဩဪါာ◌ိ◌ီ◌ု◌ူေ◌ဲဳဴဵ◌ံ◌့း◌္်ျြွှဿ +၀၁၂၃၄၅၆၇၈၉၊။၌၍၎၏ၐၑၒၓၔၕၖၗ◌ၘ◌ၙၚၛၜၝၞၟၠၡၢၣၤၥၦၧၨၩၪၫၬၭၮၯၰၱၲၳၴၵၶၷၸၹၺၻၼၽၾၿ +ႀႁႂႃႄႅႆႇႈႉႊႋႌႍႎႏ႐႑႒႓႔႕႖႗႘႙ႚႛႜႝ႞႟ + +Georgian (U+10A0-U+10FF): + +ႠႡႢႣႤႥႦႧႨႩႪႫႬႭႮႯႰႱႲႳႴႵႶႷႸႹႺႻႼႽႾႿჀჁჂჃჄჅჇჍაბგდევზთიკლმნოპჟ +რსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶჷჸჹჺ჻ჼჽჾჿ + +Hangul Jamo (U+1100-U+11FF): + +ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑᄒᄓᄔᄕᄖᄗᄘᄙᄚᄛᄜᄝᄞᄟ +ᄠᄡᄢᄣᄤᄥᄦᄧᄨᄩᄪᄫᄬᄭᄮᄯᄰᄱᄲᄳᄴᄵᄶᄷᄸᄹᄺᄻᄼᄽᄾᄿ +ᅀᅁᅂᅃᅄᅅᅆᅇᅈᅉᅊᅋᅌᅍᅎᅏᅐᅑᅒᅓᅔᅕᅖᅗᅘᅙᅚᅛᅜᅝᅞᅟ +ᅠᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᅶᅷᅸᅹᅺᅻᅼᅽᅾᅿᆀᆁᆂᆃᆄᆅᆆᆇᆈᆉᆊᆋᆌᆍᆎᆏᆐᆑᆒᆓᆔᆕᆖᆗᆘᆙᆚᆛᆜᆝᆞᆟ +ᆠᆡᆢᆣᆤᆥᆦᆧᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂᇃᇄᇅᇆᇇᇈᇉᇊᇋᇌᇍᇎᇏᇐᇑᇒᇓᇔᇕᇖᇗᇘᇙᇚᇛᇜᇝᇞᇟ +ᇠᇡᇢᇣᇤᇥᇦᇧᇨᇩᇪᇫᇬᇭᇮᇯᇰᇱᇲᇳᇴᇵᇶᇷᇸᇹᇺᇻᇼᇽᇾᇿ + +Ethiopic (U+1200-U+137F): + +ሀሁሂሃሄህሆሇለሉሊላሌልሎሏሐሑሒሓሔሕሖሗመሙሚማሜምሞሟሠሡሢሣሤሥሦሧረሩሪራሬርሮሯሰሱሲሳሴስሶሷሸሹሺሻሼሽሾሿ +ቀቁቂቃቄቅቆቇቈቊቋቌቍቐቑቒቓቔቕቖቘቚቛቜቝበቡቢባቤብቦቧቨቩቪቫቬቭቮቯተቱቲታቴትቶቷቸቹቺቻቼችቾቿ +ኀኁኂኃኄኅኆኇኈኊኋኌኍነኑኒናኔንኖኗኘኙኚኛኜኝኞኟአኡኢኣኤእኦኧከኩኪካኬክኮኯኰኲኳኴኵኸኹኺኻኼኽኾ +ዀዂዃዄዅወዉዊዋዌውዎዏዐዑዒዓዔዕዖዘዙዚዛዜዝዞዟዠዡዢዣዤዥዦዧየዩዪያዬይዮዯደዱዲዳዴድዶዷዸዹዺዻዼዽዾዿ +ጀጁጂጃጄጅጆጇገጉጊጋጌግጎጏጐጒጓጔጕጘጙጚጛጜጝጞጟጠጡጢጣጤጥጦጧጨጩጪጫጬጭጮጯጰጱጲጳጴጵጶጷጸጹጺጻጼጽጾጿ +ፀፁፂፃፄፅፆፇፈፉፊፋፌፍፎፏፐፑፒፓፔፕፖፗፘፙፚ፝፞፟፠፡።፣፤፥፦፧፨፩፪፫፬፭፮፯፰፱፲፳፴፵፶፷፸፹፺፻፼ + +Free block (U+1380-U+139F): + +ᎀᎁᎂᎃᎄᎅᎆᎇᎈᎉᎊᎋᎌᎍᎎᎏ᎐᎑᎒᎓᎔᎕᎖᎗᎘᎙ + +Cherokee (U+13A0-U+13FF): + +ᎠᎡᎢᎣᎤᎥᎦᎧᎨᎩᎪᎫᎬᎭᎮᎯᎰᎱᎲᎳᎴᎵᎶᎷᎸᎹᎺᎻᎼᎽᎾᎿᏀᏁᏂᏃᏄᏅᏆᏇᏈᏉᏊᏋᏌᏍᏎᏏᏐᏑᏒᏓᏔᏕᏖᏗᏘᏙᏚᏛᏜᏝᏞᏟ +ᏠᏡᏢᏣᏤᏥᏦᏧᏨᏩᏪᏫᏬᏭᏮᏯᏰᏱᏲᏳᏴᏵᏸᏹᏺᏻᏼᏽ + +Unified Canadian Aboriginal Syllabics (U+1400-U+167F): + +᐀ᐁᐂᐃᐄᐅᐆᐇᐈᐉᐊᐋᐌᐍᐎᐏᐐᐑᐒᐓᐔᐕᐖᐗᐘᐙᐚᐛᐜᐝᐞᐟᐠᐡᐢᐣᐤᐥᐦᐧᐨᐩᐪᐫᐬᐭᐮᐯᐰᐱᐲᐳᐴᐵᐶᐷᐸᐹᐺᐻᐼᐽᐾᐿ +ᑀᑁᑂᑃᑄᑅᑆᑇᑈᑉᑊᑋᑌᑍᑎᑏᑐᑑᑒᑓᑔᑕᑖᑗᑘᑙᑚᑛᑜᑝᑞᑟᑠᑡᑢᑣᑤᑥᑦᑧᑨᑩᑪᑫᑬᑭᑮᑯᑰᑱᑲᑳᑴᑵᑶᑷᑸᑹᑺᑻᑼᑽᑾᑿ +ᒀᒁᒂᒃᒄᒅᒆᒇᒈᒉᒊᒋᒌᒍᒎᒏᒐᒑᒒᒓᒔᒕᒖᒗᒘᒙᒚᒛᒜᒝᒞᒟᒠᒡᒢᒣᒤᒥᒦᒧᒨᒩᒪᒫᒬᒭᒮᒯᒰᒱᒲᒳᒴᒵᒶᒷᒸᒹᒺᒻᒼᒽᒾᒿ +ᓀᓁᓂᓃᓄᓅᓆᓇᓈᓉᓊᓋᓌᓍᓎᓏᓐᓑᓒᓓᓔᓕᓖᓗᓘᓙᓚᓛᓜᓝᓞᓟᓠᓡᓢᓣᓤᓥᓦᓧᓨᓩᓪᓫᓬᓭᓮᓯᓰᓱᓲᓳᓴᓵᓶᓷᓸᓹᓺᓻᓼᓽᓾᓿ +ᔀᔁᔂᔃᔄᔅᔆᔇᔈᔉᔊᔋᔌᔍᔎᔏᔐᔑᔒᔓᔔᔕᔖᔗᔘᔙᔚᔛᔜᔝᔞᔟᔠᔡᔢᔣᔤᔥᔦᔧᔨᔩᔪᔫᔬᔭᔮᔯᔰᔱᔲᔳᔴᔵᔶᔷᔸᔹᔺᔻᔼᔽᔾᔿ +ᕀᕁᕂᕃᕄᕅᕆᕇᕈᕉᕊᕋᕌᕍᕎᕏᕐᕑᕒᕓᕔᕕᕖᕗᕘᕙᕚᕛᕜᕝᕞᕟᕠᕡᕢᕣᕤᕥᕦᕧᕨᕩᕪᕫᕬᕭᕮᕯᕰᕱᕲᕳᕴᕵᕶᕷᕸᕹᕺᕻᕼᕽᕾᕿ +ᖀᖁᖂᖃᖄᖅᖆᖇᖈᖉᖊᖋᖌᖍᖎᖏᖐᖑᖒᖓᖔᖕᖖᖗᖘᖙᖚᖛᖜᖝᖞᖟᖠᖡᖢᖣᖤᖥᖦᖧᖨᖩᖪᖫᖬᖭᖮᖯᖰᖱᖲᖳᖴᖵᖶᖷᖸᖹᖺᖻᖼᖽᖾᖿ +ᗀᗁᗂᗃᗄᗅᗆᗇᗈᗉᗊᗋᗌᗍᗎᗏᗐᗑᗒᗓᗔᗕᗖᗗᗘᗙᗚᗛᗜᗝᗞᗟᗠᗡᗢᗣᗤᗥᗦᗧᗨᗩᗪᗫᗬᗭᗮᗯᗰᗱᗲᗳᗴᗵᗶᗷᗸᗹᗺᗻᗼᗽᗾᗿ +ᘀᘁᘂᘃᘄᘅᘆᘇᘈᘉᘊᘋᘌᘍᘎᘏᘐᘑᘒᘓᘔᘕᘖᘗᘘᘙᘚᘛᘜᘝᘞᘟᘠᘡᘢᘣᘤᘥᘦᘧᘨᘩᘪᘫᘬᘭᘮᘯᘰᘱᘲᘳᘴᘵᘶᘷᘸᘹᘺᘻᘼᘽᘾᘿ +ᙀᙁᙂᙃᙄᙅᙆᙇᙈᙉᙊᙋᙌᙍᙎᙏᙐᙑᙒᙓᙔᙕᙖᙗᙘᙙᙚᙛᙜᙝᙞᙟᙠᙡᙢᙣᙤᙥᙦᙧᙨᙩᙪᙫᙬ᙭᙮ᙯᙰᙱᙲᙳᙴᙵᙶᙷᙸᙹᙺᙻᙼᙽᙾᙿ + +Ogham (U+1680-U+169F): + + ᚁᚂᚃᚄᚅᚆᚇᚈᚉᚊᚋᚌᚍᚎᚏᚐᚑᚒᚓᚔᚕᚖᚗᚘᚙᚚ᚛᚜ + +Runic (U+16A0-U+16FF): + +ᚠᚡᚢᚣᚤᚥᚦᚧᚨᚩᚪᚫᚬᚭᚮᚯᚰᚱᚲᚳᚴᚵᚶᚷᚸᚹᚺᚻᚼᚽᚾᚿᛀᛁᛂᛃᛄᛅᛆᛇᛈᛉᛊᛋᛌᛍᛎᛏᛐᛑᛒᛓᛔᛕᛖᛗᛘᛙᛚᛛᛜᛝᛞᛟ +ᛠᛡᛢᛣᛤᛥᛦᛧᛨᛩᛪ᛫᛬᛭ᛮᛯᛰᛱᛲᛳᛴᛵᛶᛷᛸ + +Free block (U+1700-U+177F): + +ᜀᜁᜂᜃᜄᜅᜆᜇᜈᜉᜊᜋᜌᜍᜎᜏᜐᜑᜒᜓ᜔᜕ᜟᜠᜡᜢᜣᜤᜥᜦᜧᜨᜩᜪᜫᜬᜭᜮᜯᜰᜱᜲᜳ᜴᜵᜶ +ᝀᝁᝂᝃᝄᝅᝆᝇᝈᝉᝊᝋᝌᝍᝎᝏᝐᝑᝒᝓᝠᝡᝢᝣᝤᝥᝦᝧᝨᝩᝪᝫᝬᝮᝯᝰᝲᝳ + +Khmer (U+1780-U+17FF): + +កខគឃងចឆជឈញដឋឌឍណតថទធនបផពភមយរលវឝឞសហឡអឣឤឥឦឧឨឩឪឫឬឭឮឯឰឱឲឳ឴឵ា◌ិ◌ី◌ឹ◌ឺ◌ុ◌ូ◌ួើឿ +ៀេែៃោៅ◌ំះៈ◌៉◌៊◌់◌៌◌៍◌៎◌៏◌័◌៑◌្◌៓។៕៖ៗ៘៙៚៛ៜ៝០១២៣៤៥៦៧៨៩៰៱៲៳៴៵៶៷៸៹ + +Mongolian (U+1800-U+18AF): + +᠀᠁᠂᠃᠄᠅᠆᠇᠈᠉᠊᠋᠌᠍᠏᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙ᠠᠡᠢᠣᠤᠥᠦᠧᠨᠩᠪᠫᠬᠭᠮᠯᠰᠱᠲᠳᠴᠵᠶᠷᠸᠹᠺᠻᠼᠽᠾᠿ +ᡀᡁᡂᡃᡄᡅᡆᡇᡈᡉᡊᡋᡌᡍᡎᡏᡐᡑᡒᡓᡔᡕᡖᡗᡘᡙᡚᡛᡜᡝᡞᡟᡠᡡᡢᡣᡤᡥᡦᡧᡨᡩᡪᡫᡬᡭᡮᡯᡰᡱᡲᡳᡴᡵᡶᡷᡸ +ᢀᢁᢂᢃᢄᢅᢆᢇᢈᢉᢊᢋᢌᢍᢎᢏᢐᢑᢒᢓᢔᢕᢖᢗᢘᢙᢚᢛᢜᢝᢞᢟᢠᢡᢢᢣᢤᢥᢦᢧᢨ◌ᢩᢪ + +Free block (U+18B0-U+1DFF): + +ᢰᢱᢲᢳᢴᢵᢶᢷᢸᢹᢺᢻᢼᢽᢾᢿᣀᣁᣂᣃᣄᣅᣆᣇᣈᣉᣊᣋᣌᣍᣎᣏᣐᣑᣒᣓᣔᣕᣖᣗᣘᣙᣚᣛᣜᣝᣞᣟᣠᣡᣢᣣᣤᣥᣦᣧᣨᣩᣪᣫᣬᣭᣮᣯ +ᣰᣱᣲᣳᣴᣵᤀᤁᤂᤃᤄᤅᤆᤇᤈᤉᤊᤋᤌᤍᤎᤏᤐᤑᤒᤓᤔᤕᤖᤗᤘᤙᤚᤛᤜᤝᤞᤠᤡᤢᤣᤤᤥᤦᤧᤨᤩᤪᤫ +ᤰᤱᤲᤳᤴᤵᤶᤷᤸ᤻᤹᤺᥀᥄᥅᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏ᥐᥑᥒᥓᥔᥕᥖᥗᥘᥙᥚᥛᥜᥝᥞᥟᥠᥡᥢᥣᥤᥥᥦᥧᥨᥩᥪᥫᥬᥭ +ᥰᥱᥲᥳᥴᦀᦁᦂᦃᦄᦅᦆᦇᦈᦉᦊᦋᦌᦍᦎᦏᦐᦑᦒᦓᦔᦕᦖᦗᦘᦙᦚᦛᦜᦝᦞᦟᦠᦡᦢᦣᦤᦥᦦᦧᦨᦩᦪᦫ +ᦰᦱᦲᦳᦴᦵᦶᦷᦸᦹᦺᦻᦼᦽᦾᦿᧀᧁᧂᧃᧄᧅᧆᧇᧈᧉ᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙᧚᧞᧟᧠᧡᧢᧣᧤᧥᧦᧧᧨᧩᧪᧫᧬᧭᧮᧯ +᧰᧱᧲᧳᧴᧵᧶᧷᧸᧹᧺᧻᧼᧽᧾᧿ᨀᨁᨂᨃᨄᨅᨆᨇᨈᨉᨊᨋᨌᨍᨎᨏᨐᨑᨒᨓᨔᨕᨖᨘᨗᨙᨚᨛ᨞᨟ᨠᨡᨢᨣᨤᨥᨦᨧᨨᨩᨪᨫᨬᨭᨮᨯ +ᨰᨱᨲᨳᨴᨵᨶᨷᨸᨹᨺᨻᨼᨽᨾᨿᩀᩁᩂᩃᩄᩅᩆᩇᩈᩉᩊᩋᩌᩍᩎᩏᩐᩑᩒᩓᩔᩕᩖᩗᩘᩙᩚᩛᩜᩝᩞ᩠ᩡᩢᩣᩤᩥᩦᩧᩨᩩᩪᩫᩬᩭᩮᩯ +ᩰᩱᩲᩳᩴ᩿᩵᩶᩷᩸᩹᩺᩻᩼᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙᪠᪡᪢᪣᪤᪥᪦ᪧ᪨᪩᪪᪫᪬᪭ +᪵᪶᪷᪸᪹᪺᪽᪰᪱᪲᪳᪴᪻᪼᪾ᪿᫀ᫃᫄᫊᫁᫂᫅᫆᫇᫈᫉᫋ᫌᫍᫎ +ᬀᬁᬂᬃᬄᬅᬆᬇᬈᬉᬊᬋᬌᬍᬎᬏᬐᬑᬒᬓᬔᬕᬖᬗᬘᬙᬚᬛᬜᬝᬞᬟᬠᬡᬢᬣᬤᬥᬦᬧᬨᬩᬪᬫᬬᬭᬮᬯ +ᬰᬱᬲᬳ᬴ᬵᬶᬷᬸᬹᬺᬻᬼᬽᬾᬿᭀᭁᭂᭃ᭄ᭅᭆᭇᭈᭉᭊᭋᭌ᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙᭚᭛᭜᭝᭞᭟᭠᭡᭢᭣᭤᭥᭦᭧᭨᭩᭪᭬᭫᭭᭮᭯ +᭰᭱᭲᭳᭴᭵᭶᭷᭸᭹᭺᭻᭼᭽᭾ᮀᮁᮂᮃᮄᮅᮆᮇᮈᮉᮊᮋᮌᮍᮎᮏᮐᮑᮒᮓᮔᮕᮖᮗᮘᮙᮚᮛᮜᮝᮞᮟᮠᮡᮢᮣᮤᮥᮦᮧᮨᮩ᮪᮫ᮬᮭᮮᮯ +᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹ᮺᮻᮼᮽᮾᮿᯀᯁᯂᯃᯄᯅᯆᯇᯈᯉᯊᯋᯌᯍᯎᯏᯐᯑᯒᯓᯔᯕᯖᯗᯘᯙᯚᯛᯜᯝᯞᯟᯠᯡᯢᯣᯤᯥ᯦ᯧᯨᯩᯪᯫᯬᯭᯮᯯ +ᯰᯱ᯲᯳᯼᯽᯾᯿ᰀᰁᰂᰃᰄᰅᰆᰇᰈᰉᰊᰋᰌᰍᰎᰏᰐᰑᰒᰓᰔᰕᰖᰗᰘᰙᰚᰛᰜᰝᰞᰟᰠᰡᰢᰣᰤᰥᰦᰧᰨᰩᰪᰫᰬᰭᰮᰯ +ᰰᰱᰲᰳᰴᰵᰶ᰷᰻᰼᰽᰾᰿᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉ᱍᱎᱏ᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙ᱚᱛᱜᱝᱞᱟᱠᱡᱢᱣᱤᱥᱦᱧᱨᱩᱪᱫᱬᱭᱮᱯ +ᱰᱱᱲᱳᱴᱵᱶᱷᱸᱹᱺᱻᱼᱽ᱾᱿ᲀᲁᲂᲃᲄᲅᲆᲇᲈᲐᲑᲒᲓᲔᲕᲖᲗᲘᲙᲚᲛᲜᲝᲞᲟᲠᲡᲢᲣᲤᲥᲦᲧᲨᲩᲪᲫᲬᲭᲮᲯ +ᲰᲱᲲᲳᲴᲵᲶᲷᲸᲹᲺᲽᲾᲿ᳀᳁᳂᳃᳄᳅᳆᳇᳐᳑᳒᳓᳔᳕᳖᳗᳘᳙᳜᳝᳞᳟᳚᳛᳠᳡᳢᳣᳤᳥᳦᳧᳨ᳩᳪᳫᳬ᳭ᳮᳯ +ᳰᳱᳲᳳ᳴ᳵᳶ᳷᳸᳹ᳺᴀᴁᴂᴃᴄᴅᴆᴇᴈᴉᴊᴋᴌᴍᴎᴏᴐᴑᴒᴓᴔᴕᴖᴗᴘᴙᴚᴛᴜᴝᴞᴟᴠᴡᴢᴣᴤᴥᴦᴧᴨᴩᴪᴫᴬᴭᴮᴯ +ᴰᴱᴲᴳᴴᴵᴶᴷᴸᴹᴺᴻᴼᴽᴾᴿᵀᵁᵂᵃᵄᵅᵆᵇᵈᵉᵊᵋᵌᵍᵎᵏᵐᵑᵒᵓᵔᵕᵖᵗᵘᵙᵚᵛᵜᵝᵞᵟᵠᵡᵢᵣᵤᵥᵦᵧᵨᵩᵪᵫᵬᵭᵮᵯ +ᵰᵱᵲᵳᵴᵵᵶᵷᵸᵹᵺᵻᵼᵽᵾᵿᶀᶁᶂᶃᶄᶅᶆᶇᶈᶉᶊᶋᶌᶍᶎᶏᶐᶑᶒᶓᶔᶕᶖᶗᶘᶙᶚᶛᶜᶝᶞᶟᶠᶡᶢᶣᶤᶥᶦᶧᶨᶩᶪᶫᶬᶭᶮᶯ +ᶰᶱᶲᶳᶴᶵᶶᶷᶸᶹᶺᶻᶼᶽᶾᶿ᷐᷎᷂᷊᷏᷀᷁᷃᷄᷅᷆᷇᷈᷉᷋᷌᷑᷒ᷓᷔᷕᷖᷗᷘᷙᷚᷛᷜᷝᷞᷟᷠᷡᷢᷣᷤᷥᷦᷧᷨᷩᷪᷫᷬᷭᷮᷯ᷍ +᷺᷹᷽᷿᷷᷸ᷰᷱᷲᷳᷴ᷵᷻᷾᷶᷼ + +Latin Extended Additional (U+1E00-U+1EFF): + +ḀḁḂḃḄḅḆḇḈḉḊḋḌḍḎḏḐḑḒḓḔḕḖḗḘḙḚḛḜḝḞḟḠḡḢḣḤḥḦḧḨḩḪḫḬḭḮḯḰḱḲḳḴḵḶḷḸḹḺḻḼḽḾḿ +ṀṁṂṃṄṅṆṇṈṉṊṋṌṍṎṏṐṑṒṓṔṕṖṗṘṙṚṛṜṝṞṟṠṡṢṣṤṥṦṧṨṩṪṫṬṭṮṯṰṱṲṳṴṵṶṷṸṹṺṻṼṽṾṿ +ẀẁẂẃẄẅẆẇẈẉẊẋẌẍẎẏẐẑẒẓẔẕẖẗẘẙẚẛẜẝẞẟẠạẢảẤấẦầẨẩẪẫẬậẮắẰằẲẳẴẵẶặẸẹẺẻẼẽẾế +ỀềỂểỄễỆệỈỉỊịỌọỎỏỐốỒồỔổỖỗỘộỚớỜờỞởỠỡỢợỤụỦủỨứỪừỬửỮữỰựỲỳỴỵỶỷỸỹỺỻỼỽỾỿ + +Greek Extended (U+1F00-U+1FFF): + +ἀἁἂἃἄἅἆἇἈἉἊἋἌἍἎἏἐἑἒἓἔἕἘἙἚἛἜἝἠἡἢἣἤἥἦἧἨἩἪἫἬἭἮἯἰἱἲἳἴἵἶἷἸἹἺἻἼἽἾἿ +ὀὁὂὃὄὅὈὉὊὋὌὍὐὑὒὓὔὕὖὗὙὛὝὟὠὡὢὣὤὥὦὧὨὩὪὫὬὭὮὯὰάὲέὴήὶίὸόὺύὼώ +ᾀᾁᾂᾃᾄᾅᾆᾇᾈᾉᾊᾋᾌᾍᾎᾏᾐᾑᾒᾓᾔᾕᾖᾗᾘᾙᾚᾛᾜᾝᾞᾟᾠᾡᾢᾣᾤᾥᾦᾧᾨᾩᾪᾫᾬᾭᾮᾯᾰᾱᾲᾳᾴᾶᾷᾸᾹᾺΆᾼ᾽ι᾿ +῀῁ῂῃῄῆῇῈΈῊΉῌ῍῎῏ῐῑῒΐῖῗῘῙῚΊ῝῞῟ῠῡῢΰῤῥῦῧῨῩῪΎῬ῭΅`ῲῳῴῶῷῸΌῺΏῼ´῾ + +General Punctuation (U+2000-U+206F): + + ‐‑‒–—―‖‗‘’‚‛“”„‟†‡•‣․‥…‧
‰‱′″‴‵‶‷‸‹›※‼‽‾‿ +⁀⁁⁂⁃⁄⁅⁆⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁒⁓⁔⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞ + +Superscripts and Subscripts (U+2070-U+209F): + +⁰ⁱ⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑₒₓₔₕₖₗₘₙₚₛₜ + +Currency Symbols (U+20A0-U+20CF): + +₠₡₢₣₤₥₦₧₨₩₪₫€₭₮₯₰₱₲₳₴₵₶₷₸₹₺₻₼₽₾₿⃀ + +Combining Marks for Symbols (U+20D0-U+20FF): + +◌⃐◌⃑◌⃒◌⃓◌⃔◌⃕◌⃖◌⃗◌⃘◌⃙◌⃚◌⃛◌⃜ ⃝ ⃞ ⃟ ⃠◌⃡ ⃢ ⃣⃤⃥⃦⃪⃫⃨⃬⃭⃮⃯⃧⃩⃰ + +Letterlike Symbols (U+2100-U+214F): + +℀℁ℂ℃℄℅℆ℇ℈℉ℊℋℌℍℎℏℐℑℒℓ℔ℕ№℗℘ℙℚℛℜℝ℞℟℠℡™℣ℤ℥Ω℧ℨ℩KÅℬℭ℮ℯℰℱℲℳℴℵℶℷℸℹ℺℻ℼℽℾℿ +⅀⅁⅂⅃⅄ⅅⅆⅇⅈⅉ⅊⅋⅌⅍ⅎ⅏ + +Number Forms (U+2150-U+218F): + +⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↀↁↂↃↄↅↆↇↈ↉↊↋ + +Arrows (U+2190-U+21FF): + +←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏ +⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪⇫⇬⇭⇮⇯⇰⇱⇲⇳⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿ + +Mathematical Operators (U+2200-U+22FF): + +∀∁∂∃∄∅∆∇∈∉∊∋∌∍∎∏∐∑−∓∔∕∖∗∘∙√∛∜∝∞∟∠∡∢∣∤∥∦∧∨∩∪∫∬∭∮∯∰∱∲∳∴∵∶∷∸∹∺∻∼∽∾∿ +≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿ +⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿ +⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿ + +Miscellaneous Technical (U+2300-U+23FF): + +⌀⌁⌂⌃⌄⌅⌆⌇⌈⌉⌊⌋⌌⌍⌎⌏⌐⌑⌒⌓⌔⌕⌖⌗⌘⌙⌚⌛⌜⌝⌞⌟⌠⌡⌢⌣⌤⌥⌦⌧⌨〈〉⌫⌬⌭⌮⌯⌰⌱⌲⌳⌴⌵⌶⌷⌸⌹⌺⌻⌼⌽⌾⌿ +⍀⍁⍂⍃⍄⍅⍆⍇⍈⍉⍊⍋⍌⍍⍎⍏⍐⍑⍒⍓⍔⍕⍖⍗⍘⍙⍚⍛⍜⍝⍞⍟⍠⍡⍢⍣⍤⍥⍦⍧⍨⍩⍪⍫⍬⍭⍮⍯⍰⍱⍲⍳⍴⍵⍶⍷⍸⍹⍺⍻⍼⍽⍾⍿ +⎀⎁⎂⎃⎄⎅⎆⎇⎈⎉⎊⎋⎌⎍⎎⎏⎐⎑⎒⎓⎔⎕⎖⎗⎘⎙⎚⎛⎜⎝⎞⎟⎠⎡⎢⎣⎤⎥⎦⎧⎨⎩⎪⎫⎬⎭⎮⎯⎰⎱⎲⎳⎴⎵⎶⎷⎸⎹⎺⎻⎼⎽⎾⎿ +⏀⏁⏂⏃⏄⏅⏆⏇⏈⏉⏊⏋⏌⏍⏎⏏⏐⏑⏒⏓⏔⏕⏖⏗⏘⏙⏚⏛⏜⏝⏞⏟⏠⏡⏢⏣⏤⏥⏦⏧⏨⏩⏪⏫⏬⏭⏮⏯⏰⏱⏲⏳⏴⏵⏶⏷⏸⏹⏺⏻⏼⏽⏾⏿ + +Control Pictures (U+2400-U+243F): + +␀␁␂␃␄␅␆␇␈␉␊␋␌␍␎␏␐␑␒␓␔␕␖␗␘␙␚␛␜␝␞␟␠␡␢␣␥␦ + +Optical Character Recognition (U+2440-U+245F): + +⑀⑁⑂⑃⑄⑅⑆⑇⑈⑉⑊ + +Enclosed Alphanumerics (U+2460-U+24FF): + +①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⒜⒝⒞⒟ +⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟ +ⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾⓿ + +Box Drawing (U+2500-U+257F): + +─━│┃┄┅┆┇┈┉┊┋┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿ +╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬╭╮╯╰╱╲╳╴╵╶╷╸╹╺╻╼╽╾╿ + +Block Elements (U+2580-U+259F): + +▀▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▐░▒▓▔▕▖▗▘▙▚▛▜▝▞▟ + +Geometric Shapes (U+25A0-U+25FF): + +■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯▰▱▲△▴▵▶▷▸▹►▻▼▽▾▿◀◁◂◃◄◅◆◇◈◉◊○◌◍◎●◐◑◒◓◔◕◖◗◘◙◚◛◜◝◞◟ +◠◡◢◣◤◥◦◧◨◩◪◫◬◭◮◯◰◱◲◳◴◵◶◷◸◹◺◻◼◽◾◿ + +Miscellaneous Symbols (U+2600-U+26FF): + +☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☔☕☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿ +♀♁♂♃♄♅♆♇♈♉♊♋♌♍♎♏♐♑♒♓♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿ +⚀⚁⚂⚃⚄⚅⚆⚇⚈⚉⚊⚋⚌⚍⚎⚏⚐⚑⚒⚓⚔⚕⚖⚗⚘⚙⚚⚛⚜⚝⚞⚟⚠⚡⚢⚣⚤⚥⚦⚧⚨⚩⚪⚫⚬⚭⚮⚯⚰⚱⚲⚳⚴⚵⚶⚷⚸⚹⚺⚻⚼⚽⚾⚿ +⛀⛁⛂⛃⛄⛅⛆⛇⛈⛉⛊⛋⛌⛍⛎⛏⛐⛑⛒⛓⛔⛕⛖⛗⛘⛙⛚⛛⛜⛝⛞⛟⛠⛡⛢⛣⛤⛥⛦⛧⛨⛩⛪⛫⛬⛭⛮⛯⛰⛱⛲⛳⛴⛵⛶⛷⛸⛹⛺⛻⛼⛽⛾⛿ + +Dingbats (U+2700-U+27BF): + +✀✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿ +❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞❟❠❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿ +➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➕➖➗➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾➿ + +Free block (U+27C0-U+27FF): + +⟀⟁⟂⟃⟄⟅⟆⟇⟈⟉⟊⟋⟌⟍⟎⟏⟐⟑⟒⟓⟔⟕⟖⟗⟘⟙⟚⟛⟜⟝⟞⟟⟠⟡⟢⟣⟤⟥⟦⟧⟨⟩⟪⟫⟬⟭⟮⟯⟰⟱⟲⟳⟴⟵⟶⟷⟸⟹⟺⟻⟼⟽⟾⟿ + +Braille Patterns (U+2800-U+28FF): + +⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿ +⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿ +⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿ +⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿ + +Free block (U+2900-U+2E7F): + +⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕⤖⤗⤘⤙⤚⤛⤜⤝⤞⤟⤠⤡⤢⤣⤤⤥⤦⤧⤨⤩⤪⤫⤬⤭⤮⤯⤰⤱⤲⤳⤴⤵⤶⤷⤸⤹⤺⤻⤼⤽⤾⤿ +⥀⥁⥂⥃⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑⥒⥓⥔⥕⥖⥗⥘⥙⥚⥛⥜⥝⥞⥟⥠⥡⥢⥣⥤⥥⥦⥧⥨⥩⥪⥫⥬⥭⥮⥯⥰⥱⥲⥳⥴⥵⥶⥷⥸⥹⥺⥻⥼⥽⥾⥿ +⦀⦁⦂⦃⦄⦅⦆⦇⦈⦉⦊⦋⦌⦍⦎⦏⦐⦑⦒⦓⦔⦕⦖⦗⦘⦙⦚⦛⦜⦝⦞⦟⦠⦡⦢⦣⦤⦥⦦⦧⦨⦩⦪⦫⦬⦭⦮⦯⦰⦱⦲⦳⦴⦵⦶⦷⦸⦹⦺⦻⦼⦽⦾⦿ +⧀⧁⧂⧃⧄⧅⧆⧇⧈⧉⧊⧋⧌⧍⧎⧏⧐⧑⧒⧓⧔⧕⧖⧗⧘⧙⧚⧛⧜⧝⧞⧟⧠⧡⧢⧣⧤⧥⧦⧧⧨⧩⧪⧫⧬⧭⧮⧯⧰⧱⧲⧳⧴⧵⧶⧷⧸⧹⧺⧻⧼⧽⧾⧿ +⨀⨁⨂⨃⨄⨅⨆⨇⨈⨉⨊⨋⨌⨍⨎⨏⨐⨑⨒⨓⨔⨕⨖⨗⨘⨙⨚⨛⨜⨝⨞⨟⨠⨡⨢⨣⨤⨥⨦⨧⨨⨩⨪⨫⨬⨭⨮⨯⨰⨱⨲⨳⨴⨵⨶⨷⨸⨹⨺⨻⨼⨽⨾⨿ +⩀⩁⩂⩃⩄⩅⩆⩇⩈⩉⩊⩋⩌⩍⩎⩏⩐⩑⩒⩓⩔⩕⩖⩗⩘⩙⩚⩛⩜⩝⩞⩟⩠⩡⩢⩣⩤⩥⩦⩧⩨⩩⩪⩫⩬⩭⩮⩯⩰⩱⩲⩳⩴⩵⩶⩷⩸⩹⩺⩻⩼⩽⩾⩿ +⪀⪁⪂⪃⪄⪅⪆⪇⪈⪉⪊⪋⪌⪍⪎⪏⪐⪑⪒⪓⪔⪕⪖⪗⪘⪙⪚⪛⪜⪝⪞⪟⪠⪡⪢⪣⪤⪥⪦⪧⪨⪩⪪⪫⪬⪭⪮⪯⪰⪱⪲⪳⪴⪵⪶⪷⪸⪹⪺⪻⪼⪽⪾⪿ +⫀⫁⫂⫃⫄⫅⫆⫇⫈⫉⫊⫋⫌⫍⫎⫏⫐⫑⫒⫓⫔⫕⫖⫗⫘⫙⫚⫛⫝̸⫝⫞⫟⫠⫡⫢⫣⫤⫥⫦⫧⫨⫩⫪⫫⫬⫭⫮⫯⫰⫱⫲⫳⫴⫵⫶⫷⫸⫹⫺⫻⫼⫽⫾⫿ +⬀⬁⬂⬃⬄⬅⬆⬇⬈⬉⬊⬋⬌⬍⬎⬏⬐⬑⬒⬓⬔⬕⬖⬗⬘⬙⬚⬛⬜⬝⬞⬟⬠⬡⬢⬣⬤⬥⬦⬧⬨⬩⬪⬫⬬⬭⬮⬯⬰⬱⬲⬳⬴⬵⬶⬷⬸⬹⬺⬻⬼⬽⬾⬿ +⭀⭁⭂⭃⭄⭅⭆⭇⭈⭉⭊⭋⭌⭍⭎⭏⭐⭑⭒⭓⭔⭕⭖⭗⭘⭙⭚⭛⭜⭝⭞⭟⭠⭡⭢⭣⭤⭥⭦⭧⭨⭩⭪⭫⭬⭭⭮⭯⭰⭱⭲⭳⭶⭷⭸⭹⭺⭻⭼⭽⭾⭿ +⮀⮁⮂⮃⮄⮅⮆⮇⮈⮉⮊⮋⮌⮍⮎⮏⮐⮑⮒⮓⮔⮕⮗⮘⮙⮚⮛⮜⮝⮞⮟⮠⮡⮢⮣⮤⮥⮦⮧⮨⮩⮪⮫⮬⮭⮮⮯⮰⮱⮲⮳⮴⮵⮶⮷⮸⮹⮺⮻⮼⮽⮾⮿ +⯀⯁⯂⯃⯄⯅⯆⯇⯈⯉⯊⯋⯌⯍⯎⯏⯐⯑⯒⯓⯔⯕⯖⯗⯘⯙⯚⯛⯜⯝⯞⯟⯠⯡⯢⯣⯤⯥⯦⯧⯨⯩⯪⯫⯬⯭⯮⯯⯰⯱⯲⯳⯴⯵⯶⯷⯸⯹⯺⯻⯼⯽⯾⯿ +ⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮⰯⰰⰱⰲⰳⰴⰵⰶⰷⰸⰹⰺⰻⰼⰽⰾⰿ +ⱀⱁⱂⱃⱄⱅⱆⱇⱈⱉⱊⱋⱌⱍⱎⱏⱐⱑⱒⱓⱔⱕⱖⱗⱘⱙⱚⱛⱜⱝⱞⱟⱠⱡⱢⱣⱤⱥⱦⱧⱨⱩⱪⱫⱬⱭⱮⱯⱰⱱⱲⱳⱴⱵⱶⱷⱸⱹⱺⱻⱼⱽⱾⱿ +ⲀⲁⲂⲃⲄⲅⲆⲇⲈⲉⲊⲋⲌⲍⲎⲏⲐⲑⲒⲓⲔⲕⲖⲗⲘⲙⲚⲛⲜⲝⲞⲟⲠⲡⲢⲣⲤⲥⲦⲧⲨⲩⲪⲫⲬⲭⲮⲯⲰⲱⲲⲳⲴⲵⲶⲷⲸⲹⲺⲻⲼⲽⲾⲿ +ⳀⳁⳂⳃⳄⳅⳆⳇⳈⳉⳊⳋⳌⳍⳎⳏⳐⳑⳒⳓⳔⳕⳖⳗⳘⳙⳚⳛⳜⳝⳞⳟⳠⳡⳢⳣⳤ⳥⳦⳧⳨⳩⳪ⳫⳬⳭⳮ⳯⳰⳱Ⳳⳳ⳹⳺⳻⳼⳽⳾⳿ +ⴀⴁⴂⴃⴄⴅⴆⴇⴈⴉⴊⴋⴌⴍⴎⴏⴐⴑⴒⴓⴔⴕⴖⴗⴘⴙⴚⴛⴜⴝⴞⴟⴠⴡⴢⴣⴤⴥⴧⴭⴰⴱⴲⴳⴴⴵⴶⴷⴸⴹⴺⴻⴼⴽⴾⴿ +ⵀⵁⵂⵃⵄⵅⵆⵇⵈⵉⵊⵋⵌⵍⵎⵏⵐⵑⵒⵓⵔⵕⵖⵗⵘⵙⵚⵛⵜⵝⵞⵟⵠⵡⵢⵣⵤⵥⵦⵧⵯ⵰⵿ +ⶀⶁⶂⶃⶄⶅⶆⶇⶈⶉⶊⶋⶌⶍⶎⶏⶐⶑⶒⶓⶔⶕⶖⶠⶡⶢⶣⶤⶥⶦⶨⶩⶪⶫⶬⶭⶮⶰⶱⶲⶳⶴⶵⶶⶸⶹⶺⶻⶼⶽⶾ +ⷀⷁⷂⷃⷄⷅⷆⷈⷉⷊⷋⷌⷍⷎⷐⷑⷒⷓⷔⷕⷖⷘⷙⷚⷛⷜⷝⷞⷠⷡⷢⷣⷤⷥⷦⷧⷨⷩⷪⷫⷬⷭⷮⷯⷰⷱⷲⷳⷴⷵⷶⷷⷸⷹⷺⷻⷼⷽⷾⷿ +⸀⸁⸂⸃⸄⸅⸆⸇⸈⸉⸊⸋⸌⸍⸎⸏⸐⸑⸒⸓⸔⸕⸖⸗⸘⸙⸚⸛⸜⸝⸞⸟⸠⸡⸢⸣⸤⸥⸦⸧⸨⸩⸪⸫⸬⸭⸮ⸯ⸰⸱⸲⸳⸴⸵⸶⸷⸸⸹⸺⸻⸼⸽⸾⸿ +⹀⹁⹂⹃⹄⹅⹆⹇⹈⹉⹊⹋⹌⹍⹎⹏⹐⹑⹒⹓⹔⹕⹖⹗⹘⹙⹚⹛⹜⹝ + +CJK Radicals Supplement (U+2E80-U+2EFF): + +⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟ +⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿ +⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟ +⻠⻡⻢⻣⻤⻥⻦⻧⻨⻩⻪⻫⻬⻭⻮⻯⻰⻱⻲⻳ + +Kangxi Radicals (U+2F00-U+2FDF): + +⼀⼁⼂⼃⼄⼅⼆⼇⼈⼉⼊⼋⼌⼍⼎⼏⼐⼑⼒⼓⼔⼕⼖⼗⼘⼙⼚⼛⼜⼝⼞⼟ +⼠⼡⼢⼣⼤⼥⼦⼧⼨⼩⼪⼫⼬⼭⼮⼯⼰⼱⼲⼳⼴⼵⼶⼷⼸⼹⼺⼻⼼⼽⼾⼿ +⽀⽁⽂⽃⽄⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟ +⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿ +⾀⾁⾂⾃⾄⾅⾆⾇⾈⾉⾊⾋⾌⾍⾎⾏⾐⾑⾒⾓⾔⾕⾖⾗⾘⾙⾚⾛⾜⾝⾞⾟ +⾠⾡⾢⾣⾤⾥⾦⾧⾨⾩⾪⾫⾬⾭⾮⾯⾰⾱⾲⾳⾴⾵⾶⾷⾸⾹⾺⾻⾼⾽⾾⾿ +⿀⿁⿂⿃⿄⿅⿆⿇⿈⿉⿊⿋⿌⿍⿎⿏⿐⿑⿒⿓⿔⿕ + +Free block (U+2FE0-U+2FEF): + + + +Ideographic Description Characters (U+2FF0-U+2FFF): + +⿰⿱⿲⿳⿴⿵⿶⿷⿸⿹⿺⿻ + +CJK Symbols and Punctuation (U+3000-U+303F): + + 、。〃〄々〆〇〈〉《》「」『』【】〒〓〔〕〖〗〘〙〚〛〜〝〞〟 +〠〡〢〣〤〥〦〧〨〩◌〪◌〫◌〬◌〭◌〮◌〯〰〱〲〳〴〵〶〷〸〹〺〻〼〽〾〿 + +Hiragana (U+3040-U+309F): + +ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞた +だちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみ +むめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ◌゙◌゚゛゜ゝゞゟ + +Katakana (U+30A0-U+30FF): + +゠ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタ +ダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミ +ムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ + +Bopomofo (U+3100-U+312F): + +ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟ +ㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩㄪㄫㄬㄭㄮㄯ + +Hangul Compatibility Jamo (U+3130-U+318F): + +ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏ +ㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯ +ㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ + +Kanbun (U+3190-U+319F): + +㆐㆑㆒㆓㆔㆕㆖㆗㆘㆙㆚㆛㆜㆝㆞㆟ + +Bopomofo Extended (U+31A0-U+31BF): + +ㆠㆡㆢㆣㆤㆥㆦㆧㆨㆩㆪㆫㆬㆭㆮㆯㆰㆱㆲㆳㆴㆵㆶㆷㆸㆹㆺㆻㆼㆽㆾㆿ + +Free block (U+31C0-U+31FF): + +㇀㇁㇂㇃㇄㇅㇆㇇㇈㇉㇊㇋㇌㇍㇎㇏㇐㇑㇒㇓㇔㇕㇖㇗㇘㇙㇚㇛㇜㇝㇞㇟ +㇠㇡㇢㇣ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ + +Enclosed CJK Letters and Months (U+3200-U+32FF): + +㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛㈜㈝㈞ +㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩㈪㈫㈬㈭㈮㈯㈰㈱㈲㈳㈴㈵㈶㈷㈸㈹㈺㈻㈼㈽㈾㈿ +㉀㉁㉂㉃㉄㉅㉆㉇㉈㉉㉊㉋㉌㉍㉎㉏㉐㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟ +㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻㉼㉽㉾㉿ +㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㊊㊋㊌㊍㊎㊏㊐㊑㊒㊓㊔㊕㊖㊗㊘㊙㊚㊛㊜㊝㊞㊟ +㊠㊡㊢㊣㊤㊥㊦㊧㊨㊩㊪㊫㊬㊭㊮㊯㊰㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿ +㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㋌㋍㋎㋏㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝㋞㋟ +㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽㋾㋿ + +CJK Compatibility (U+3300-U+33FF): + +㌀㌁㌂㌃㌄㌅㌆㌇㌈㌉㌊㌋㌌㌍㌎㌏㌐㌑㌒㌓㌔㌕㌖㌗㌘㌙㌚㌛㌜㌝㌞㌟ +㌠㌡㌢㌣㌤㌥㌦㌧㌨㌩㌪㌫㌬㌭㌮㌯㌰㌱㌲㌳㌴㌵㌶㌷㌸㌹㌺㌻㌼㌽㌾㌿ +㍀㍁㍂㍃㍄㍅㍆㍇㍈㍉㍊㍋㍌㍍㍎㍏㍐㍑㍒㍓㍔㍕㍖㍗㍘㍙㍚㍛㍜㍝㍞㍟ +㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍱㍲㍳㍴㍵㍶㍷㍸㍹㍺㍻㍼㍽㍾㍿ +㎀㎁㎂㎃㎄㎅㎆㎇㎈㎉㎊㎋㎌㎍㎎㎏㎐㎑㎒㎓㎔㎕㎖㎗㎘㎙㎚㎛㎜㎝㎞㎟ +㎠㎡㎢㎣㎤㎥㎦㎧㎨㎩㎪㎫㎬㎭㎮㎯㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹㎺㎻㎼㎽㎾㎿ +㏀㏁㏂㏃㏄㏅㏆㏇㏈㏉㏊㏋㏌㏍㏎㏏㏐㏑㏒㏓㏔㏕㏖㏗㏘㏙㏚㏛㏜㏝㏞㏟ +㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㏿ + +CJK Unified Ideographs Extension A (U+3400-U+4DB5): + +㐀㐁㐂㐃㐄㐅㐆㐇㐈㐉㐊㐋㐌㐍㐎㐏㐐㐑㐒㐓㐔㐕㐖㐗㐘㐙㐚㐛㐜㐝㐞㐟 +㐠㐡㐢㐣㐤㐥㐦㐧㐨㐩㐪㐫㐬㐭㐮㐯㐰㐱㐲㐳㐴㐵㐶㐷㐸㐹㐺㐻㐼㐽㐾㐿 +㑀㑁㑂㑃㑄㑅㑆㑇㑈㑉㑊㑋㑌㑍㑎㑏㑐㑑㑒㑓㑔㑕㑖㑗㑘㑙㑚㑛㑜㑝㑞㑟 +㑠㑡㑢㑣㑤㑥㑦㑧㑨㑩㑪㑫㑬㑭㑮㑯㑰㑱㑲㑳㑴㑵㑶㑷㑸㑹㑺㑻㑼㑽㑾㑿 +㒀㒁㒂㒃㒄㒅㒆㒇㒈㒉㒊㒋㒌㒍㒎㒏㒐㒑㒒㒓㒔㒕㒖㒗㒘㒙㒚㒛㒜㒝㒞㒟 +㒠㒡㒢㒣㒤㒥㒦㒧㒨㒩㒪㒫㒬㒭㒮㒯㒰㒱㒲㒳㒴㒵㒶㒷㒸㒹㒺㒻㒼㒽㒾㒿 +㓀㓁㓂㓃㓄㓅㓆㓇㓈㓉㓊㓋㓌㓍㓎㓏㓐㓑㓒㓓㓔㓕㓖㓗㓘㓙㓚㓛㓜㓝㓞㓟 +㓠㓡㓢㓣㓤㓥㓦㓧㓨㓩㓪㓫㓬㓭㓮㓯㓰㓱㓲㓳㓴㓵㓶㓷㓸㓹㓺㓻㓼㓽㓾㓿 +㔀㔁㔂㔃㔄㔅㔆㔇㔈㔉㔊㔋㔌㔍㔎㔏㔐㔑㔒㔓㔔㔕㔖㔗㔘㔙㔚㔛㔜㔝㔞㔟 +㔠㔡㔢㔣㔤㔥㔦㔧㔨㔩㔪㔫㔬㔭㔮㔯㔰㔱㔲㔳㔴㔵㔶㔷㔸㔹㔺㔻㔼㔽㔾㔿 +㕀㕁㕂㕃㕄㕅㕆㕇㕈㕉㕊㕋㕌㕍㕎㕏㕐㕑㕒㕓㕔㕕㕖㕗㕘㕙㕚㕛㕜㕝㕞㕟 +㕠㕡㕢㕣㕤㕥㕦㕧㕨㕩㕪㕫㕬㕭㕮㕯㕰㕱㕲㕳㕴㕵㕶㕷㕸㕹㕺㕻㕼㕽㕾㕿 +㖀㖁㖂㖃㖄㖅㖆㖇㖈㖉㖊㖋㖌㖍㖎㖏㖐㖑㖒㖓㖔㖕㖖㖗㖘㖙㖚㖛㖜㖝㖞㖟 +㖠㖡㖢㖣㖤㖥㖦㖧㖨㖩㖪㖫㖬㖭㖮㖯㖰㖱㖲㖳㖴㖵㖶㖷㖸㖹㖺㖻㖼㖽㖾㖿 +㗀㗁㗂㗃㗄㗅㗆㗇㗈㗉㗊㗋㗌㗍㗎㗏㗐㗑㗒㗓㗔㗕㗖㗗㗘㗙㗚㗛㗜㗝㗞㗟 +㗠㗡㗢㗣㗤㗥㗦㗧㗨㗩㗪㗫㗬㗭㗮㗯㗰㗱㗲㗳㗴㗵㗶㗷㗸㗹㗺㗻㗼㗽㗾㗿 +㘀㘁㘂㘃㘄㘅㘆㘇㘈㘉㘊㘋㘌㘍㘎㘏㘐㘑㘒㘓㘔㘕㘖㘗㘘㘙㘚㘛㘜㘝㘞㘟 +㘠㘡㘢㘣㘤㘥㘦㘧㘨㘩㘪㘫㘬㘭㘮㘯㘰㘱㘲㘳㘴㘵㘶㘷㘸㘹㘺㘻㘼㘽㘾㘿 +㙀㙁㙂㙃㙄㙅㙆㙇㙈㙉㙊㙋㙌㙍㙎㙏㙐㙑㙒㙓㙔㙕㙖㙗㙘㙙㙚㙛㙜㙝㙞㙟 +㙠㙡㙢㙣㙤㙥㙦㙧㙨㙩㙪㙫㙬㙭㙮㙯㙰㙱㙲㙳㙴㙵㙶㙷㙸㙹㙺㙻㙼㙽㙾㙿 +㚀㚁㚂㚃㚄㚅㚆㚇㚈㚉㚊㚋㚌㚍㚎㚏㚐㚑㚒㚓㚔㚕㚖㚗㚘㚙㚚㚛㚜㚝㚞㚟 +㚠㚡㚢㚣㚤㚥㚦㚧㚨㚩㚪㚫㚬㚭㚮㚯㚰㚱㚲㚳㚴㚵㚶㚷㚸㚹㚺㚻㚼㚽㚾㚿 +㛀㛁㛂㛃㛄㛅㛆㛇㛈㛉㛊㛋㛌㛍㛎㛏㛐㛑㛒㛓㛔㛕㛖㛗㛘㛙㛚㛛㛜㛝㛞㛟 +㛠㛡㛢㛣㛤㛥㛦㛧㛨㛩㛪㛫㛬㛭㛮㛯㛰㛱㛲㛳㛴㛵㛶㛷㛸㛹㛺㛻㛼㛽㛾㛿 +㜀㜁㜂㜃㜄㜅㜆㜇㜈㜉㜊㜋㜌㜍㜎㜏㜐㜑㜒㜓㜔㜕㜖㜗㜘㜙㜚㜛㜜㜝㜞㜟 +㜠㜡㜢㜣㜤㜥㜦㜧㜨㜩㜪㜫㜬㜭㜮㜯㜰㜱㜲㜳㜴㜵㜶㜷㜸㜹㜺㜻㜼㜽㜾㜿 +㝀㝁㝂㝃㝄㝅㝆㝇㝈㝉㝊㝋㝌㝍㝎㝏㝐㝑㝒㝓㝔㝕㝖㝗㝘㝙㝚㝛㝜㝝㝞㝟 +㝠㝡㝢㝣㝤㝥㝦㝧㝨㝩㝪㝫㝬㝭㝮㝯㝰㝱㝲㝳㝴㝵㝶㝷㝸㝹㝺㝻㝼㝽㝾㝿 +㞀㞁㞂㞃㞄㞅㞆㞇㞈㞉㞊㞋㞌㞍㞎㞏㞐㞑㞒㞓㞔㞕㞖㞗㞘㞙㞚㞛㞜㞝㞞㞟 +㞠㞡㞢㞣㞤㞥㞦㞧㞨㞩㞪㞫㞬㞭㞮㞯㞰㞱㞲㞳㞴㞵㞶㞷㞸㞹㞺㞻㞼㞽㞾㞿 +㟀㟁㟂㟃㟄㟅㟆㟇㟈㟉㟊㟋㟌㟍㟎㟏㟐㟑㟒㟓㟔㟕㟖㟗㟘㟙㟚㟛㟜㟝㟞㟟 +㟠㟡㟢㟣㟤㟥㟦㟧㟨㟩㟪㟫㟬㟭㟮㟯㟰㟱㟲㟳㟴㟵㟶㟷㟸㟹㟺㟻㟼㟽㟾㟿 +㠀㠁㠂㠃㠄㠅㠆㠇㠈㠉㠊㠋㠌㠍㠎㠏㠐㠑㠒㠓㠔㠕㠖㠗㠘㠙㠚㠛㠜㠝㠞㠟 +㠠㠡㠢㠣㠤㠥㠦㠧㠨㠩㠪㠫㠬㠭㠮㠯㠰㠱㠲㠳㠴㠵㠶㠷㠸㠹㠺㠻㠼㠽㠾㠿 +㡀㡁㡂㡃㡄㡅㡆㡇㡈㡉㡊㡋㡌㡍㡎㡏㡐㡑㡒㡓㡔㡕㡖㡗㡘㡙㡚㡛㡜㡝㡞㡟 +㡠㡡㡢㡣㡤㡥㡦㡧㡨㡩㡪㡫㡬㡭㡮㡯㡰㡱㡲㡳㡴㡵㡶㡷㡸㡹㡺㡻㡼㡽㡾㡿 +㢀㢁㢂㢃㢄㢅㢆㢇㢈㢉㢊㢋㢌㢍㢎㢏㢐㢑㢒㢓㢔㢕㢖㢗㢘㢙㢚㢛㢜㢝㢞㢟 +㢠㢡㢢㢣㢤㢥㢦㢧㢨㢩㢪㢫㢬㢭㢮㢯㢰㢱㢲㢳㢴㢵㢶㢷㢸㢹㢺㢻㢼㢽㢾㢿 +㣀㣁㣂㣃㣄㣅㣆㣇㣈㣉㣊㣋㣌㣍㣎㣏㣐㣑㣒㣓㣔㣕㣖㣗㣘㣙㣚㣛㣜㣝㣞㣟 +㣠㣡㣢㣣㣤㣥㣦㣧㣨㣩㣪㣫㣬㣭㣮㣯㣰㣱㣲㣳㣴㣵㣶㣷㣸㣹㣺㣻㣼㣽㣾㣿 +㤀㤁㤂㤃㤄㤅㤆㤇㤈㤉㤊㤋㤌㤍㤎㤏㤐㤑㤒㤓㤔㤕㤖㤗㤘㤙㤚㤛㤜㤝㤞㤟 +㤠㤡㤢㤣㤤㤥㤦㤧㤨㤩㤪㤫㤬㤭㤮㤯㤰㤱㤲㤳㤴㤵㤶㤷㤸㤹㤺㤻㤼㤽㤾㤿 +㥀㥁㥂㥃㥄㥅㥆㥇㥈㥉㥊㥋㥌㥍㥎㥏㥐㥑㥒㥓㥔㥕㥖㥗㥘㥙㥚㥛㥜㥝㥞㥟 +㥠㥡㥢㥣㥤㥥㥦㥧㥨㥩㥪㥫㥬㥭㥮㥯㥰㥱㥲㥳㥴㥵㥶㥷㥸㥹㥺㥻㥼㥽㥾㥿 +㦀㦁㦂㦃㦄㦅㦆㦇㦈㦉㦊㦋㦌㦍㦎㦏㦐㦑㦒㦓㦔㦕㦖㦗㦘㦙㦚㦛㦜㦝㦞㦟 +㦠㦡㦢㦣㦤㦥㦦㦧㦨㦩㦪㦫㦬㦭㦮㦯㦰㦱㦲㦳㦴㦵㦶㦷㦸㦹㦺㦻㦼㦽㦾㦿 +㧀㧁㧂㧃㧄㧅㧆㧇㧈㧉㧊㧋㧌㧍㧎㧏㧐㧑㧒㧓㧔㧕㧖㧗㧘㧙㧚㧛㧜㧝㧞㧟 +㧠㧡㧢㧣㧤㧥㧦㧧㧨㧩㧪㧫㧬㧭㧮㧯㧰㧱㧲㧳㧴㧵㧶㧷㧸㧹㧺㧻㧼㧽㧾㧿 +㨀㨁㨂㨃㨄㨅㨆㨇㨈㨉㨊㨋㨌㨍㨎㨏㨐㨑㨒㨓㨔㨕㨖㨗㨘㨙㨚㨛㨜㨝㨞㨟 +㨠㨡㨢㨣㨤㨥㨦㨧㨨㨩㨪㨫㨬㨭㨮㨯㨰㨱㨲㨳㨴㨵㨶㨷㨸㨹㨺㨻㨼㨽㨾㨿 +㩀㩁㩂㩃㩄㩅㩆㩇㩈㩉㩊㩋㩌㩍㩎㩏㩐㩑㩒㩓㩔㩕㩖㩗㩘㩙㩚㩛㩜㩝㩞㩟 +㩠㩡㩢㩣㩤㩥㩦㩧㩨㩩㩪㩫㩬㩭㩮㩯㩰㩱㩲㩳㩴㩵㩶㩷㩸㩹㩺㩻㩼㩽㩾㩿 +㪀㪁㪂㪃㪄㪅㪆㪇㪈㪉㪊㪋㪌㪍㪎㪏㪐㪑㪒㪓㪔㪕㪖㪗㪘㪙㪚㪛㪜㪝㪞㪟 +㪠㪡㪢㪣㪤㪥㪦㪧㪨㪩㪪㪫㪬㪭㪮㪯㪰㪱㪲㪳㪴㪵㪶㪷㪸㪹㪺㪻㪼㪽㪾㪿 +㫀㫁㫂㫃㫄㫅㫆㫇㫈㫉㫊㫋㫌㫍㫎㫏㫐㫑㫒㫓㫔㫕㫖㫗㫘㫙㫚㫛㫜㫝㫞㫟 +㫠㫡㫢㫣㫤㫥㫦㫧㫨㫩㫪㫫㫬㫭㫮㫯㫰㫱㫲㫳㫴㫵㫶㫷㫸㫹㫺㫻㫼㫽㫾㫿 +㬀㬁㬂㬃㬄㬅㬆㬇㬈㬉㬊㬋㬌㬍㬎㬏㬐㬑㬒㬓㬔㬕㬖㬗㬘㬙㬚㬛㬜㬝㬞㬟 +㬠㬡㬢㬣㬤㬥㬦㬧㬨㬩㬪㬫㬬㬭㬮㬯㬰㬱㬲㬳㬴㬵㬶㬷㬸㬹㬺㬻㬼㬽㬾㬿 +㭀㭁㭂㭃㭄㭅㭆㭇㭈㭉㭊㭋㭌㭍㭎㭏㭐㭑㭒㭓㭔㭕㭖㭗㭘㭙㭚㭛㭜㭝㭞㭟 +㭠㭡㭢㭣㭤㭥㭦㭧㭨㭩㭪㭫㭬㭭㭮㭯㭰㭱㭲㭳㭴㭵㭶㭷㭸㭹㭺㭻㭼㭽㭾㭿 +㮀㮁㮂㮃㮄㮅㮆㮇㮈㮉㮊㮋㮌㮍㮎㮏㮐㮑㮒㮓㮔㮕㮖㮗㮘㮙㮚㮛㮜㮝㮞㮟 +㮠㮡㮢㮣㮤㮥㮦㮧㮨㮩㮪㮫㮬㮭㮮㮯㮰㮱㮲㮳㮴㮵㮶㮷㮸㮹㮺㮻㮼㮽㮾㮿 +㯀㯁㯂㯃㯄㯅㯆㯇㯈㯉㯊㯋㯌㯍㯎㯏㯐㯑㯒㯓㯔㯕㯖㯗㯘㯙㯚㯛㯜㯝㯞㯟 +㯠㯡㯢㯣㯤㯥㯦㯧㯨㯩㯪㯫㯬㯭㯮㯯㯰㯱㯲㯳㯴㯵㯶㯷㯸㯹㯺㯻㯼㯽㯾㯿 +㰀㰁㰂㰃㰄㰅㰆㰇㰈㰉㰊㰋㰌㰍㰎㰏㰐㰑㰒㰓㰔㰕㰖㰗㰘㰙㰚㰛㰜㰝㰞㰟 +㰠㰡㰢㰣㰤㰥㰦㰧㰨㰩㰪㰫㰬㰭㰮㰯㰰㰱㰲㰳㰴㰵㰶㰷㰸㰹㰺㰻㰼㰽㰾㰿 +㱀㱁㱂㱃㱄㱅㱆㱇㱈㱉㱊㱋㱌㱍㱎㱏㱐㱑㱒㱓㱔㱕㱖㱗㱘㱙㱚㱛㱜㱝㱞㱟 +㱠㱡㱢㱣㱤㱥㱦㱧㱨㱩㱪㱫㱬㱭㱮㱯㱰㱱㱲㱳㱴㱵㱶㱷㱸㱹㱺㱻㱼㱽㱾㱿 +㲀㲁㲂㲃㲄㲅㲆㲇㲈㲉㲊㲋㲌㲍㲎㲏㲐㲑㲒㲓㲔㲕㲖㲗㲘㲙㲚㲛㲜㲝㲞㲟 +㲠㲡㲢㲣㲤㲥㲦㲧㲨㲩㲪㲫㲬㲭㲮㲯㲰㲱㲲㲳㲴㲵㲶㲷㲸㲹㲺㲻㲼㲽㲾㲿 +㳀㳁㳂㳃㳄㳅㳆㳇㳈㳉㳊㳋㳌㳍㳎㳏㳐㳑㳒㳓㳔㳕㳖㳗㳘㳙㳚㳛㳜㳝㳞㳟 +㳠㳡㳢㳣㳤㳥㳦㳧㳨㳩㳪㳫㳬㳭㳮㳯㳰㳱㳲㳳㳴㳵㳶㳷㳸㳹㳺㳻㳼㳽㳾㳿 +㴀㴁㴂㴃㴄㴅㴆㴇㴈㴉㴊㴋㴌㴍㴎㴏㴐㴑㴒㴓㴔㴕㴖㴗㴘㴙㴚㴛㴜㴝㴞㴟 +㴠㴡㴢㴣㴤㴥㴦㴧㴨㴩㴪㴫㴬㴭㴮㴯㴰㴱㴲㴳㴴㴵㴶㴷㴸㴹㴺㴻㴼㴽㴾㴿 +㵀㵁㵂㵃㵄㵅㵆㵇㵈㵉㵊㵋㵌㵍㵎㵏㵐㵑㵒㵓㵔㵕㵖㵗㵘㵙㵚㵛㵜㵝㵞㵟 +㵠㵡㵢㵣㵤㵥㵦㵧㵨㵩㵪㵫㵬㵭㵮㵯㵰㵱㵲㵳㵴㵵㵶㵷㵸㵹㵺㵻㵼㵽㵾㵿 +㶀㶁㶂㶃㶄㶅㶆㶇㶈㶉㶊㶋㶌㶍㶎㶏㶐㶑㶒㶓㶔㶕㶖㶗㶘㶙㶚㶛㶜㶝㶞㶟 +㶠㶡㶢㶣㶤㶥㶦㶧㶨㶩㶪㶫㶬㶭㶮㶯㶰㶱㶲㶳㶴㶵㶶㶷㶸㶹㶺㶻㶼㶽㶾㶿 +㷀㷁㷂㷃㷄㷅㷆㷇㷈㷉㷊㷋㷌㷍㷎㷏㷐㷑㷒㷓㷔㷕㷖㷗㷘㷙㷚㷛㷜㷝㷞㷟 +㷠㷡㷢㷣㷤㷥㷦㷧㷨㷩㷪㷫㷬㷭㷮㷯㷰㷱㷲㷳㷴㷵㷶㷷㷸㷹㷺㷻㷼㷽㷾㷿 +㸀㸁㸂㸃㸄㸅㸆㸇㸈㸉㸊㸋㸌㸍㸎㸏㸐㸑㸒㸓㸔㸕㸖㸗㸘㸙㸚㸛㸜㸝㸞㸟 +㸠㸡㸢㸣㸤㸥㸦㸧㸨㸩㸪㸫㸬㸭㸮㸯㸰㸱㸲㸳㸴㸵㸶㸷㸸㸹㸺㸻㸼㸽㸾㸿 +㹀㹁㹂㹃㹄㹅㹆㹇㹈㹉㹊㹋㹌㹍㹎㹏㹐㹑㹒㹓㹔㹕㹖㹗㹘㹙㹚㹛㹜㹝㹞㹟 +㹠㹡㹢㹣㹤㹥㹦㹧㹨㹩㹪㹫㹬㹭㹮㹯㹰㹱㹲㹳㹴㹵㹶㹷㹸㹹㹺㹻㹼㹽㹾㹿 +㺀㺁㺂㺃㺄㺅㺆㺇㺈㺉㺊㺋㺌㺍㺎㺏㺐㺑㺒㺓㺔㺕㺖㺗㺘㺙㺚㺛㺜㺝㺞㺟 +㺠㺡㺢㺣㺤㺥㺦㺧㺨㺩㺪㺫㺬㺭㺮㺯㺰㺱㺲㺳㺴㺵㺶㺷㺸㺹㺺㺻㺼㺽㺾㺿 +㻀㻁㻂㻃㻄㻅㻆㻇㻈㻉㻊㻋㻌㻍㻎㻏㻐㻑㻒㻓㻔㻕㻖㻗㻘㻙㻚㻛㻜㻝㻞㻟 +㻠㻡㻢㻣㻤㻥㻦㻧㻨㻩㻪㻫㻬㻭㻮㻯㻰㻱㻲㻳㻴㻵㻶㻷㻸㻹㻺㻻㻼㻽㻾㻿 +㼀㼁㼂㼃㼄㼅㼆㼇㼈㼉㼊㼋㼌㼍㼎㼏㼐㼑㼒㼓㼔㼕㼖㼗㼘㼙㼚㼛㼜㼝㼞㼟 +㼠㼡㼢㼣㼤㼥㼦㼧㼨㼩㼪㼫㼬㼭㼮㼯㼰㼱㼲㼳㼴㼵㼶㼷㼸㼹㼺㼻㼼㼽㼾㼿 +㽀㽁㽂㽃㽄㽅㽆㽇㽈㽉㽊㽋㽌㽍㽎㽏㽐㽑㽒㽓㽔㽕㽖㽗㽘㽙㽚㽛㽜㽝㽞㽟 +㽠㽡㽢㽣㽤㽥㽦㽧㽨㽩㽪㽫㽬㽭㽮㽯㽰㽱㽲㽳㽴㽵㽶㽷㽸㽹㽺㽻㽼㽽㽾㽿 +㾀㾁㾂㾃㾄㾅㾆㾇㾈㾉㾊㾋㾌㾍㾎㾏㾐㾑㾒㾓㾔㾕㾖㾗㾘㾙㾚㾛㾜㾝㾞㾟 +㾠㾡㾢㾣㾤㾥㾦㾧㾨㾩㾪㾫㾬㾭㾮㾯㾰㾱㾲㾳㾴㾵㾶㾷㾸㾹㾺㾻㾼㾽㾾㾿 +㿀㿁㿂㿃㿄㿅㿆㿇㿈㿉㿊㿋㿌㿍㿎㿏㿐㿑㿒㿓㿔㿕㿖㿗㿘㿙㿚㿛㿜㿝㿞㿟 +㿠㿡㿢㿣㿤㿥㿦㿧㿨㿩㿪㿫㿬㿭㿮㿯㿰㿱㿲㿳㿴㿵㿶㿷㿸㿹㿺㿻㿼㿽㿾㿿 +䀀䀁䀂䀃䀄䀅䀆䀇䀈䀉䀊䀋䀌䀍䀎䀏䀐䀑䀒䀓䀔䀕䀖䀗䀘䀙䀚䀛䀜䀝䀞䀟 +䀠䀡䀢䀣䀤䀥䀦䀧䀨䀩䀪䀫䀬䀭䀮䀯䀰䀱䀲䀳䀴䀵䀶䀷䀸䀹䀺䀻䀼䀽䀾䀿 +䁀䁁䁂䁃䁄䁅䁆䁇䁈䁉䁊䁋䁌䁍䁎䁏䁐䁑䁒䁓䁔䁕䁖䁗䁘䁙䁚䁛䁜䁝䁞䁟 +䁠䁡䁢䁣䁤䁥䁦䁧䁨䁩䁪䁫䁬䁭䁮䁯䁰䁱䁲䁳䁴䁵䁶䁷䁸䁹䁺䁻䁼䁽䁾䁿 +䂀䂁䂂䂃䂄䂅䂆䂇䂈䂉䂊䂋䂌䂍䂎䂏䂐䂑䂒䂓䂔䂕䂖䂗䂘䂙䂚䂛䂜䂝䂞䂟 +䂠䂡䂢䂣䂤䂥䂦䂧䂨䂩䂪䂫䂬䂭䂮䂯䂰䂱䂲䂳䂴䂵䂶䂷䂸䂹䂺䂻䂼䂽䂾䂿 +䃀䃁䃂䃃䃄䃅䃆䃇䃈䃉䃊䃋䃌䃍䃎䃏䃐䃑䃒䃓䃔䃕䃖䃗䃘䃙䃚䃛䃜䃝䃞䃟 +䃠䃡䃢䃣䃤䃥䃦䃧䃨䃩䃪䃫䃬䃭䃮䃯䃰䃱䃲䃳䃴䃵䃶䃷䃸䃹䃺䃻䃼䃽䃾䃿 +䄀䄁䄂䄃䄄䄅䄆䄇䄈䄉䄊䄋䄌䄍䄎䄏䄐䄑䄒䄓䄔䄕䄖䄗䄘䄙䄚䄛䄜䄝䄞䄟 +䄠䄡䄢䄣䄤䄥䄦䄧䄨䄩䄪䄫䄬䄭䄮䄯䄰䄱䄲䄳䄴䄵䄶䄷䄸䄹䄺䄻䄼䄽䄾䄿 +䅀䅁䅂䅃䅄䅅䅆䅇䅈䅉䅊䅋䅌䅍䅎䅏䅐䅑䅒䅓䅔䅕䅖䅗䅘䅙䅚䅛䅜䅝䅞䅟 +䅠䅡䅢䅣䅤䅥䅦䅧䅨䅩䅪䅫䅬䅭䅮䅯䅰䅱䅲䅳䅴䅵䅶䅷䅸䅹䅺䅻䅼䅽䅾䅿 +䆀䆁䆂䆃䆄䆅䆆䆇䆈䆉䆊䆋䆌䆍䆎䆏䆐䆑䆒䆓䆔䆕䆖䆗䆘䆙䆚䆛䆜䆝䆞䆟 +䆠䆡䆢䆣䆤䆥䆦䆧䆨䆩䆪䆫䆬䆭䆮䆯䆰䆱䆲䆳䆴䆵䆶䆷䆸䆹䆺䆻䆼䆽䆾䆿 +䇀䇁䇂䇃䇄䇅䇆䇇䇈䇉䇊䇋䇌䇍䇎䇏䇐䇑䇒䇓䇔䇕䇖䇗䇘䇙䇚䇛䇜䇝䇞䇟 +䇠䇡䇢䇣䇤䇥䇦䇧䇨䇩䇪䇫䇬䇭䇮䇯䇰䇱䇲䇳䇴䇵䇶䇷䇸䇹䇺䇻䇼䇽䇾䇿 +䈀䈁䈂䈃䈄䈅䈆䈇䈈䈉䈊䈋䈌䈍䈎䈏䈐䈑䈒䈓䈔䈕䈖䈗䈘䈙䈚䈛䈜䈝䈞䈟 +䈠䈡䈢䈣䈤䈥䈦䈧䈨䈩䈪䈫䈬䈭䈮䈯䈰䈱䈲䈳䈴䈵䈶䈷䈸䈹䈺䈻䈼䈽䈾䈿 +䉀䉁䉂䉃䉄䉅䉆䉇䉈䉉䉊䉋䉌䉍䉎䉏䉐䉑䉒䉓䉔䉕䉖䉗䉘䉙䉚䉛䉜䉝䉞䉟 +䉠䉡䉢䉣䉤䉥䉦䉧䉨䉩䉪䉫䉬䉭䉮䉯䉰䉱䉲䉳䉴䉵䉶䉷䉸䉹䉺䉻䉼䉽䉾䉿 +䊀䊁䊂䊃䊄䊅䊆䊇䊈䊉䊊䊋䊌䊍䊎䊏䊐䊑䊒䊓䊔䊕䊖䊗䊘䊙䊚䊛䊜䊝䊞䊟 +䊠䊡䊢䊣䊤䊥䊦䊧䊨䊩䊪䊫䊬䊭䊮䊯䊰䊱䊲䊳䊴䊵䊶䊷䊸䊹䊺䊻䊼䊽䊾䊿 +䋀䋁䋂䋃䋄䋅䋆䋇䋈䋉䋊䋋䋌䋍䋎䋏䋐䋑䋒䋓䋔䋕䋖䋗䋘䋙䋚䋛䋜䋝䋞䋟 +䋠䋡䋢䋣䋤䋥䋦䋧䋨䋩䋪䋫䋬䋭䋮䋯䋰䋱䋲䋳䋴䋵䋶䋷䋸䋹䋺䋻䋼䋽䋾䋿 +䌀䌁䌂䌃䌄䌅䌆䌇䌈䌉䌊䌋䌌䌍䌎䌏䌐䌑䌒䌓䌔䌕䌖䌗䌘䌙䌚䌛䌜䌝䌞䌟 +䌠䌡䌢䌣䌤䌥䌦䌧䌨䌩䌪䌫䌬䌭䌮䌯䌰䌱䌲䌳䌴䌵䌶䌷䌸䌹䌺䌻䌼䌽䌾䌿 +䍀䍁䍂䍃䍄䍅䍆䍇䍈䍉䍊䍋䍌䍍䍎䍏䍐䍑䍒䍓䍔䍕䍖䍗䍘䍙䍚䍛䍜䍝䍞䍟 +䍠䍡䍢䍣䍤䍥䍦䍧䍨䍩䍪䍫䍬䍭䍮䍯䍰䍱䍲䍳䍴䍵䍶䍷䍸䍹䍺䍻䍼䍽䍾䍿 +䎀䎁䎂䎃䎄䎅䎆䎇䎈䎉䎊䎋䎌䎍䎎䎏䎐䎑䎒䎓䎔䎕䎖䎗䎘䎙䎚䎛䎜䎝䎞䎟 +䎠䎡䎢䎣䎤䎥䎦䎧䎨䎩䎪䎫䎬䎭䎮䎯䎰䎱䎲䎳䎴䎵䎶䎷䎸䎹䎺䎻䎼䎽䎾䎿 +䏀䏁䏂䏃䏄䏅䏆䏇䏈䏉䏊䏋䏌䏍䏎䏏䏐䏑䏒䏓䏔䏕䏖䏗䏘䏙䏚䏛䏜䏝䏞䏟 +䏠䏡䏢䏣䏤䏥䏦䏧䏨䏩䏪䏫䏬䏭䏮䏯䏰䏱䏲䏳䏴䏵䏶䏷䏸䏹䏺䏻䏼䏽䏾䏿 +䐀䐁䐂䐃䐄䐅䐆䐇䐈䐉䐊䐋䐌䐍䐎䐏䐐䐑䐒䐓䐔䐕䐖䐗䐘䐙䐚䐛䐜䐝䐞䐟 +䐠䐡䐢䐣䐤䐥䐦䐧䐨䐩䐪䐫䐬䐭䐮䐯䐰䐱䐲䐳䐴䐵䐶䐷䐸䐹䐺䐻䐼䐽䐾䐿 +䑀䑁䑂䑃䑄䑅䑆䑇䑈䑉䑊䑋䑌䑍䑎䑏䑐䑑䑒䑓䑔䑕䑖䑗䑘䑙䑚䑛䑜䑝䑞䑟 +䑠䑡䑢䑣䑤䑥䑦䑧䑨䑩䑪䑫䑬䑭䑮䑯䑰䑱䑲䑳䑴䑵䑶䑷䑸䑹䑺䑻䑼䑽䑾䑿 +䒀䒁䒂䒃䒄䒅䒆䒇䒈䒉䒊䒋䒌䒍䒎䒏䒐䒑䒒䒓䒔䒕䒖䒗䒘䒙䒚䒛䒜䒝䒞䒟 +䒠䒡䒢䒣䒤䒥䒦䒧䒨䒩䒪䒫䒬䒭䒮䒯䒰䒱䒲䒳䒴䒵䒶䒷䒸䒹䒺䒻䒼䒽䒾䒿 +䓀䓁䓂䓃䓄䓅䓆䓇䓈䓉䓊䓋䓌䓍䓎䓏䓐䓑䓒䓓䓔䓕䓖䓗䓘䓙䓚䓛䓜䓝䓞䓟 +䓠䓡䓢䓣䓤䓥䓦䓧䓨䓩䓪䓫䓬䓭䓮䓯䓰䓱䓲䓳䓴䓵䓶䓷䓸䓹䓺䓻䓼䓽䓾䓿 +䔀䔁䔂䔃䔄䔅䔆䔇䔈䔉䔊䔋䔌䔍䔎䔏䔐䔑䔒䔓䔔䔕䔖䔗䔘䔙䔚䔛䔜䔝䔞䔟 +䔠䔡䔢䔣䔤䔥䔦䔧䔨䔩䔪䔫䔬䔭䔮䔯䔰䔱䔲䔳䔴䔵䔶䔷䔸䔹䔺䔻䔼䔽䔾䔿 +䕀䕁䕂䕃䕄䕅䕆䕇䕈䕉䕊䕋䕌䕍䕎䕏䕐䕑䕒䕓䕔䕕䕖䕗䕘䕙䕚䕛䕜䕝䕞䕟 +䕠䕡䕢䕣䕤䕥䕦䕧䕨䕩䕪䕫䕬䕭䕮䕯䕰䕱䕲䕳䕴䕵䕶䕷䕸䕹䕺䕻䕼䕽䕾䕿 +䖀䖁䖂䖃䖄䖅䖆䖇䖈䖉䖊䖋䖌䖍䖎䖏䖐䖑䖒䖓䖔䖕䖖䖗䖘䖙䖚䖛䖜䖝䖞䖟 +䖠䖡䖢䖣䖤䖥䖦䖧䖨䖩䖪䖫䖬䖭䖮䖯䖰䖱䖲䖳䖴䖵䖶䖷䖸䖹䖺䖻䖼䖽䖾䖿 +䗀䗁䗂䗃䗄䗅䗆䗇䗈䗉䗊䗋䗌䗍䗎䗏䗐䗑䗒䗓䗔䗕䗖䗗䗘䗙䗚䗛䗜䗝䗞䗟 +䗠䗡䗢䗣䗤䗥䗦䗧䗨䗩䗪䗫䗬䗭䗮䗯䗰䗱䗲䗳䗴䗵䗶䗷䗸䗹䗺䗻䗼䗽䗾䗿 +䘀䘁䘂䘃䘄䘅䘆䘇䘈䘉䘊䘋䘌䘍䘎䘏䘐䘑䘒䘓䘔䘕䘖䘗䘘䘙䘚䘛䘜䘝䘞䘟 +䘠䘡䘢䘣䘤䘥䘦䘧䘨䘩䘪䘫䘬䘭䘮䘯䘰䘱䘲䘳䘴䘵䘶䘷䘸䘹䘺䘻䘼䘽䘾䘿 +䙀䙁䙂䙃䙄䙅䙆䙇䙈䙉䙊䙋䙌䙍䙎䙏䙐䙑䙒䙓䙔䙕䙖䙗䙘䙙䙚䙛䙜䙝䙞䙟 +䙠䙡䙢䙣䙤䙥䙦䙧䙨䙩䙪䙫䙬䙭䙮䙯䙰䙱䙲䙳䙴䙵䙶䙷䙸䙹䙺䙻䙼䙽䙾䙿 +䚀䚁䚂䚃䚄䚅䚆䚇䚈䚉䚊䚋䚌䚍䚎䚏䚐䚑䚒䚓䚔䚕䚖䚗䚘䚙䚚䚛䚜䚝䚞䚟 +䚠䚡䚢䚣䚤䚥䚦䚧䚨䚩䚪䚫䚬䚭䚮䚯䚰䚱䚲䚳䚴䚵䚶䚷䚸䚹䚺䚻䚼䚽䚾䚿 +䛀䛁䛂䛃䛄䛅䛆䛇䛈䛉䛊䛋䛌䛍䛎䛏䛐䛑䛒䛓䛔䛕䛖䛗䛘䛙䛚䛛䛜䛝䛞䛟 +䛠䛡䛢䛣䛤䛥䛦䛧䛨䛩䛪䛫䛬䛭䛮䛯䛰䛱䛲䛳䛴䛵䛶䛷䛸䛹䛺䛻䛼䛽䛾䛿 +䜀䜁䜂䜃䜄䜅䜆䜇䜈䜉䜊䜋䜌䜍䜎䜏䜐䜑䜒䜓䜔䜕䜖䜗䜘䜙䜚䜛䜜䜝䜞䜟 +䜠䜡䜢䜣䜤䜥䜦䜧䜨䜩䜪䜫䜬䜭䜮䜯䜰䜱䜲䜳䜴䜵䜶䜷䜸䜹䜺䜻䜼䜽䜾䜿 +䝀䝁䝂䝃䝄䝅䝆䝇䝈䝉䝊䝋䝌䝍䝎䝏䝐䝑䝒䝓䝔䝕䝖䝗䝘䝙䝚䝛䝜䝝䝞䝟 +䝠䝡䝢䝣䝤䝥䝦䝧䝨䝩䝪䝫䝬䝭䝮䝯䝰䝱䝲䝳䝴䝵䝶䝷䝸䝹䝺䝻䝼䝽䝾䝿 +䞀䞁䞂䞃䞄䞅䞆䞇䞈䞉䞊䞋䞌䞍䞎䞏䞐䞑䞒䞓䞔䞕䞖䞗䞘䞙䞚䞛䞜䞝䞞䞟 +䞠䞡䞢䞣䞤䞥䞦䞧䞨䞩䞪䞫䞬䞭䞮䞯䞰䞱䞲䞳䞴䞵䞶䞷䞸䞹䞺䞻䞼䞽䞾䞿 +䟀䟁䟂䟃䟄䟅䟆䟇䟈䟉䟊䟋䟌䟍䟎䟏䟐䟑䟒䟓䟔䟕䟖䟗䟘䟙䟚䟛䟜䟝䟞䟟 +䟠䟡䟢䟣䟤䟥䟦䟧䟨䟩䟪䟫䟬䟭䟮䟯䟰䟱䟲䟳䟴䟵䟶䟷䟸䟹䟺䟻䟼䟽䟾䟿 +䠀䠁䠂䠃䠄䠅䠆䠇䠈䠉䠊䠋䠌䠍䠎䠏䠐䠑䠒䠓䠔䠕䠖䠗䠘䠙䠚䠛䠜䠝䠞䠟 +䠠䠡䠢䠣䠤䠥䠦䠧䠨䠩䠪䠫䠬䠭䠮䠯䠰䠱䠲䠳䠴䠵䠶䠷䠸䠹䠺䠻䠼䠽䠾䠿 +䡀䡁䡂䡃䡄䡅䡆䡇䡈䡉䡊䡋䡌䡍䡎䡏䡐䡑䡒䡓䡔䡕䡖䡗䡘䡙䡚䡛䡜䡝䡞䡟 +䡠䡡䡢䡣䡤䡥䡦䡧䡨䡩䡪䡫䡬䡭䡮䡯䡰䡱䡲䡳䡴䡵䡶䡷䡸䡹䡺䡻䡼䡽䡾䡿 +䢀䢁䢂䢃䢄䢅䢆䢇䢈䢉䢊䢋䢌䢍䢎䢏䢐䢑䢒䢓䢔䢕䢖䢗䢘䢙䢚䢛䢜䢝䢞䢟 +䢠䢡䢢䢣䢤䢥䢦䢧䢨䢩䢪䢫䢬䢭䢮䢯䢰䢱䢲䢳䢴䢵䢶䢷䢸䢹䢺䢻䢼䢽䢾䢿 +䣀䣁䣂䣃䣄䣅䣆䣇䣈䣉䣊䣋䣌䣍䣎䣏䣐䣑䣒䣓䣔䣕䣖䣗䣘䣙䣚䣛䣜䣝䣞䣟 +䣠䣡䣢䣣䣤䣥䣦䣧䣨䣩䣪䣫䣬䣭䣮䣯䣰䣱䣲䣳䣴䣵䣶䣷䣸䣹䣺䣻䣼䣽䣾䣿 +䤀䤁䤂䤃䤄䤅䤆䤇䤈䤉䤊䤋䤌䤍䤎䤏䤐䤑䤒䤓䤔䤕䤖䤗䤘䤙䤚䤛䤜䤝䤞䤟 +䤠䤡䤢䤣䤤䤥䤦䤧䤨䤩䤪䤫䤬䤭䤮䤯䤰䤱䤲䤳䤴䤵䤶䤷䤸䤹䤺䤻䤼䤽䤾䤿 +䥀䥁䥂䥃䥄䥅䥆䥇䥈䥉䥊䥋䥌䥍䥎䥏䥐䥑䥒䥓䥔䥕䥖䥗䥘䥙䥚䥛䥜䥝䥞䥟 +䥠䥡䥢䥣䥤䥥䥦䥧䥨䥩䥪䥫䥬䥭䥮䥯䥰䥱䥲䥳䥴䥵䥶䥷䥸䥹䥺䥻䥼䥽䥾䥿 +䦀䦁䦂䦃䦄䦅䦆䦇䦈䦉䦊䦋䦌䦍䦎䦏䦐䦑䦒䦓䦔䦕䦖䦗䦘䦙䦚䦛䦜䦝䦞䦟 +䦠䦡䦢䦣䦤䦥䦦䦧䦨䦩䦪䦫䦬䦭䦮䦯䦰䦱䦲䦳䦴䦵䦶䦷䦸䦹䦺䦻䦼䦽䦾䦿 +䧀䧁䧂䧃䧄䧅䧆䧇䧈䧉䧊䧋䧌䧍䧎䧏䧐䧑䧒䧓䧔䧕䧖䧗䧘䧙䧚䧛䧜䧝䧞䧟 +䧠䧡䧢䧣䧤䧥䧦䧧䧨䧩䧪䧫䧬䧭䧮䧯䧰䧱䧲䧳䧴䧵䧶䧷䧸䧹䧺䧻䧼䧽䧾䧿 +䨀䨁䨂䨃䨄䨅䨆䨇䨈䨉䨊䨋䨌䨍䨎䨏䨐䨑䨒䨓䨔䨕䨖䨗䨘䨙䨚䨛䨜䨝䨞䨟 +䨠䨡䨢䨣䨤䨥䨦䨧䨨䨩䨪䨫䨬䨭䨮䨯䨰䨱䨲䨳䨴䨵䨶䨷䨸䨹䨺䨻䨼䨽䨾䨿 +䩀䩁䩂䩃䩄䩅䩆䩇䩈䩉䩊䩋䩌䩍䩎䩏䩐䩑䩒䩓䩔䩕䩖䩗䩘䩙䩚䩛䩜䩝䩞䩟 +䩠䩡䩢䩣䩤䩥䩦䩧䩨䩩䩪䩫䩬䩭䩮䩯䩰䩱䩲䩳䩴䩵䩶䩷䩸䩹䩺䩻䩼䩽䩾䩿 +䪀䪁䪂䪃䪄䪅䪆䪇䪈䪉䪊䪋䪌䪍䪎䪏䪐䪑䪒䪓䪔䪕䪖䪗䪘䪙䪚䪛䪜䪝䪞䪟 +䪠䪡䪢䪣䪤䪥䪦䪧䪨䪩䪪䪫䪬䪭䪮䪯䪰䪱䪲䪳䪴䪵䪶䪷䪸䪹䪺䪻䪼䪽䪾䪿 +䫀䫁䫂䫃䫄䫅䫆䫇䫈䫉䫊䫋䫌䫍䫎䫏䫐䫑䫒䫓䫔䫕䫖䫗䫘䫙䫚䫛䫜䫝䫞䫟 +䫠䫡䫢䫣䫤䫥䫦䫧䫨䫩䫪䫫䫬䫭䫮䫯䫰䫱䫲䫳䫴䫵䫶䫷䫸䫹䫺䫻䫼䫽䫾䫿 +䬀䬁䬂䬃䬄䬅䬆䬇䬈䬉䬊䬋䬌䬍䬎䬏䬐䬑䬒䬓䬔䬕䬖䬗䬘䬙䬚䬛䬜䬝䬞䬟 +䬠䬡䬢䬣䬤䬥䬦䬧䬨䬩䬪䬫䬬䬭䬮䬯䬰䬱䬲䬳䬴䬵䬶䬷䬸䬹䬺䬻䬼䬽䬾䬿 +䭀䭁䭂䭃䭄䭅䭆䭇䭈䭉䭊䭋䭌䭍䭎䭏䭐䭑䭒䭓䭔䭕䭖䭗䭘䭙䭚䭛䭜䭝䭞䭟 +䭠䭡䭢䭣䭤䭥䭦䭧䭨䭩䭪䭫䭬䭭䭮䭯䭰䭱䭲䭳䭴䭵䭶䭷䭸䭹䭺䭻䭼䭽䭾䭿 +䮀䮁䮂䮃䮄䮅䮆䮇䮈䮉䮊䮋䮌䮍䮎䮏䮐䮑䮒䮓䮔䮕䮖䮗䮘䮙䮚䮛䮜䮝䮞䮟 +䮠䮡䮢䮣䮤䮥䮦䮧䮨䮩䮪䮫䮬䮭䮮䮯䮰䮱䮲䮳䮴䮵䮶䮷䮸䮹䮺䮻䮼䮽䮾䮿 +䯀䯁䯂䯃䯄䯅䯆䯇䯈䯉䯊䯋䯌䯍䯎䯏䯐䯑䯒䯓䯔䯕䯖䯗䯘䯙䯚䯛䯜䯝䯞䯟 +䯠䯡䯢䯣䯤䯥䯦䯧䯨䯩䯪䯫䯬䯭䯮䯯䯰䯱䯲䯳䯴䯵䯶䯷䯸䯹䯺䯻䯼䯽䯾䯿 +䰀䰁䰂䰃䰄䰅䰆䰇䰈䰉䰊䰋䰌䰍䰎䰏䰐䰑䰒䰓䰔䰕䰖䰗䰘䰙䰚䰛䰜䰝䰞䰟 +䰠䰡䰢䰣䰤䰥䰦䰧䰨䰩䰪䰫䰬䰭䰮䰯䰰䰱䰲䰳䰴䰵䰶䰷䰸䰹䰺䰻䰼䰽䰾䰿 +䱀䱁䱂䱃䱄䱅䱆䱇䱈䱉䱊䱋䱌䱍䱎䱏䱐䱑䱒䱓䱔䱕䱖䱗䱘䱙䱚䱛䱜䱝䱞䱟 +䱠䱡䱢䱣䱤䱥䱦䱧䱨䱩䱪䱫䱬䱭䱮䱯䱰䱱䱲䱳䱴䱵䱶䱷䱸䱹䱺䱻䱼䱽䱾䱿 +䲀䲁䲂䲃䲄䲅䲆䲇䲈䲉䲊䲋䲌䲍䲎䲏䲐䲑䲒䲓䲔䲕䲖䲗䲘䲙䲚䲛䲜䲝䲞䲟 +䲠䲡䲢䲣䲤䲥䲦䲧䲨䲩䲪䲫䲬䲭䲮䲯䲰䲱䲲䲳䲴䲵䲶䲷䲸䲹䲺䲻䲼䲽䲾䲿 +䳀䳁䳂䳃䳄䳅䳆䳇䳈䳉䳊䳋䳌䳍䳎䳏䳐䳑䳒䳓䳔䳕䳖䳗䳘䳙䳚䳛䳜䳝䳞䳟 +䳠䳡䳢䳣䳤䳥䳦䳧䳨䳩䳪䳫䳬䳭䳮䳯䳰䳱䳲䳳䳴䳵䳶䳷䳸䳹䳺䳻䳼䳽䳾䳿 +䴀䴁䴂䴃䴄䴅䴆䴇䴈䴉䴊䴋䴌䴍䴎䴏䴐䴑䴒䴓䴔䴕䴖䴗䴘䴙䴚䴛䴜䴝䴞䴟 +䴠䴡䴢䴣䴤䴥䴦䴧䴨䴩䴪䴫䴬䴭䴮䴯䴰䴱䴲䴳䴴䴵䴶䴷䴸䴹䴺䴻䴼䴽䴾䴿 +䵀䵁䵂䵃䵄䵅䵆䵇䵈䵉䵊䵋䵌䵍䵎䵏䵐䵑䵒䵓䵔䵕䵖䵗䵘䵙䵚䵛䵜䵝䵞䵟 +䵠䵡䵢䵣䵤䵥䵦䵧䵨䵩䵪䵫䵬䵭䵮䵯䵰䵱䵲䵳䵴䵵䵶䵷䵸䵹䵺䵻䵼䵽䵾䵿 +䶀䶁䶂䶃䶄䶅䶆䶇䶈䶉䶊䶋䶌䶍䶎䶏䶐䶑䶒䶓䶔䶕䶖䶗䶘䶙䶚䶛䶜䶝䶞䶟 +䶠䶡䶢䶣䶤䶥䶦䶧䶨䶩䶪䶫䶬䶭䶮䶯䶰䶱䶲䶳䶴䶵 + +Free block (U+4DB6-U+4DFF): + +䶶䶷䶸䶹䶺䶻䶼䶽䶾䶿䷀䷁䷂䷃䷄䷅䷆䷇䷈䷉䷊䷋䷌䷍䷎䷏䷐䷑䷒䷓䷔䷕ +䷖䷗䷘䷙䷚䷛䷜䷝䷞䷟䷠䷡䷢䷣䷤䷥䷦䷧䷨䷩䷪䷫䷬䷭䷮䷯䷰䷱䷲䷳䷴䷵ +䷶䷷䷸䷹䷺䷻䷼䷽䷾䷿ + +CJK Unified Ideographs (U+4E00-U+9FFF): + +一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗丘丙业丛东丝丞丟 +丠両丢丣两严並丧丨丩个丫丬中丮丯丰丱串丳临丵丶丷丸丹为主丼丽举丿 +乀乁乂乃乄久乆乇么义乊之乌乍乎乏乐乑乒乓乔乕乖乗乘乙乚乛乜九乞也 +习乡乢乣乤乥书乧乨乩乪乫乬乭乮乯买乱乲乳乴乵乶乷乸乹乺乻乼乽乾乿 +亀亁亂亃亄亅了亇予争亊事二亍于亏亐云互亓五井亖亗亘亙亚些亜亝亞亟 +亠亡亢亣交亥亦产亨亩亪享京亭亮亯亰亱亲亳亴亵亶亷亸亹人亻亼亽亾亿 +什仁仂仃仄仅仆仇仈仉今介仌仍从仏仐仑仒仓仔仕他仗付仙仚仛仜仝仞仟 +仠仡仢代令以仦仧仨仩仪仫们仭仮仯仰仱仲仳仴仵件价仸仹仺任仼份仾仿 +伀企伂伃伄伅伆伇伈伉伊伋伌伍伎伏伐休伒伓伔伕伖众优伙会伛伜伝伞伟 +传伡伢伣伤伥伦伧伨伩伪伫伬伭伮伯估伱伲伳伴伵伶伷伸伹伺伻似伽伾伿 +佀佁佂佃佄佅但佇佈佉佊佋佌位低住佐佑佒体佔何佖佗佘余佚佛作佝佞佟 +你佡佢佣佤佥佦佧佨佩佪佫佬佭佮佯佰佱佲佳佴併佶佷佸佹佺佻佼佽佾使 +侀侁侂侃侄侅來侇侈侉侊例侌侍侎侏侐侑侒侓侔侕侖侗侘侙侚供侜依侞侟 +侠価侢侣侤侥侦侧侨侩侪侫侬侭侮侯侰侱侲侳侴侵侶侷侸侹侺侻侼侽侾便 +俀俁係促俄俅俆俇俈俉俊俋俌俍俎俏俐俑俒俓俔俕俖俗俘俙俚俛俜保俞俟 +俠信俢俣俤俥俦俧俨俩俪俫俬俭修俯俰俱俲俳俴俵俶俷俸俹俺俻俼俽俾俿 +倀倁倂倃倄倅倆倇倈倉倊個倌倍倎倏倐們倒倓倔倕倖倗倘候倚倛倜倝倞借 +倠倡倢倣値倥倦倧倨倩倪倫倬倭倮倯倰倱倲倳倴倵倶倷倸倹债倻值倽倾倿 +偀偁偂偃偄偅偆假偈偉偊偋偌偍偎偏偐偑偒偓偔偕偖偗偘偙做偛停偝偞偟 +偠偡偢偣偤健偦偧偨偩偪偫偬偭偮偯偰偱偲偳側偵偶偷偸偹偺偻偼偽偾偿 +傀傁傂傃傄傅傆傇傈傉傊傋傌傍傎傏傐傑傒傓傔傕傖傗傘備傚傛傜傝傞傟 +傠傡傢傣傤傥傦傧储傩傪傫催傭傮傯傰傱傲傳傴債傶傷傸傹傺傻傼傽傾傿 +僀僁僂僃僄僅僆僇僈僉僊僋僌働僎像僐僑僒僓僔僕僖僗僘僙僚僛僜僝僞僟 +僠僡僢僣僤僥僦僧僨僩僪僫僬僭僮僯僰僱僲僳僴僵僶僷僸價僺僻僼僽僾僿 +儀儁儂儃億儅儆儇儈儉儊儋儌儍儎儏儐儑儒儓儔儕儖儗儘儙儚儛儜儝儞償 +儠儡儢儣儤儥儦儧儨儩優儫儬儭儮儯儰儱儲儳儴儵儶儷儸儹儺儻儼儽儾儿 +兀允兂元兄充兆兇先光兊克兌免兎兏児兑兒兓兔兕兖兗兘兙党兛兜兝兞兟 +兠兡兢兣兤入兦內全兩兪八公六兮兯兰共兲关兴兵其具典兹兺养兼兽兾兿 +冀冁冂冃冄内円冇冈冉冊冋册再冎冏冐冑冒冓冔冕冖冗冘写冚军农冝冞冟 +冠冡冢冣冤冥冦冧冨冩冪冫冬冭冮冯冰冱冲决冴况冶冷冸冹冺冻冼冽冾冿 +净凁凂凃凄凅准凇凈凉凊凋凌凍凎减凐凑凒凓凔凕凖凗凘凙凚凛凜凝凞凟 +几凡凢凣凤凥処凧凨凩凪凫凬凭凮凯凰凱凲凳凴凵凶凷凸凹出击凼函凾凿 +刀刁刂刃刄刅分切刈刉刊刋刌刍刎刏刐刑划刓刔刕刖列刘则刚创刜初刞刟 +删刡刢刣判別刦刧刨利刪别刬刭刮刯到刱刲刳刴刵制刷券刹刺刻刼刽刾刿 +剀剁剂剃剄剅剆則剈剉削剋剌前剎剏剐剑剒剓剔剕剖剗剘剙剚剛剜剝剞剟 +剠剡剢剣剤剥剦剧剨剩剪剫剬剭剮副剰剱割剳剴創剶剷剸剹剺剻剼剽剾剿 +劀劁劂劃劄劅劆劇劈劉劊劋劌劍劎劏劐劑劒劓劔劕劖劗劘劙劚力劜劝办功 +加务劢劣劤劥劦劧动助努劫劬劭劮劯劰励劲劳労劵劶劷劸効劺劻劼劽劾势 +勀勁勂勃勄勅勆勇勈勉勊勋勌勍勎勏勐勑勒勓勔動勖勗勘務勚勛勜勝勞募 +勠勡勢勣勤勥勦勧勨勩勪勫勬勭勮勯勰勱勲勳勴勵勶勷勸勹勺勻勼勽勾勿 +匀匁匂匃匄包匆匇匈匉匊匋匌匍匎匏匐匑匒匓匔匕化北匘匙匚匛匜匝匞匟 +匠匡匢匣匤匥匦匧匨匩匪匫匬匭匮匯匰匱匲匳匴匵匶匷匸匹区医匼匽匾匿 +區十卂千卄卅卆升午卉半卋卌卍华协卐卑卒卓協单卖南単卙博卛卜卝卞卟 +占卡卢卣卤卥卦卧卨卩卪卫卬卭卮卯印危卲即却卵卶卷卸卹卺卻卼卽卾卿 +厀厁厂厃厄厅历厇厈厉厊压厌厍厎厏厐厑厒厓厔厕厖厗厘厙厚厛厜厝厞原 +厠厡厢厣厤厥厦厧厨厩厪厫厬厭厮厯厰厱厲厳厴厵厶厷厸厹厺去厼厽厾县 +叀叁参參叄叅叆叇又叉及友双反収叏叐发叒叓叔叕取受变叙叚叛叜叝叞叟 +叠叡叢口古句另叧叨叩只叫召叭叮可台叱史右叴叵叶号司叹叺叻叼叽叾叿 +吀吁吂吃各吅吆吇合吉吊吋同名后吏吐向吒吓吔吕吖吗吘吙吚君吜吝吞吟 +吠吡吢吣吤吥否吧吨吩吪含听吭吮启吰吱吲吳吴吵吶吷吸吹吺吻吼吽吾吿 +呀呁呂呃呄呅呆呇呈呉告呋呌呍呎呏呐呑呒呓呔呕呖呗员呙呚呛呜呝呞呟 +呠呡呢呣呤呥呦呧周呩呪呫呬呭呮呯呰呱呲味呴呵呶呷呸呹呺呻呼命呾呿 +咀咁咂咃咄咅咆咇咈咉咊咋和咍咎咏咐咑咒咓咔咕咖咗咘咙咚咛咜咝咞咟 +咠咡咢咣咤咥咦咧咨咩咪咫咬咭咮咯咰咱咲咳咴咵咶咷咸咹咺咻咼咽咾咿 +哀品哂哃哄哅哆哇哈哉哊哋哌响哎哏哐哑哒哓哔哕哖哗哘哙哚哛哜哝哞哟 +哠員哢哣哤哥哦哧哨哩哪哫哬哭哮哯哰哱哲哳哴哵哶哷哸哹哺哻哼哽哾哿 +唀唁唂唃唄唅唆唇唈唉唊唋唌唍唎唏唐唑唒唓唔唕唖唗唘唙唚唛唜唝唞唟 +唠唡唢唣唤唥唦唧唨唩唪唫唬唭售唯唰唱唲唳唴唵唶唷唸唹唺唻唼唽唾唿 +啀啁啂啃啄啅商啇啈啉啊啋啌啍啎問啐啑啒啓啔啕啖啗啘啙啚啛啜啝啞啟 +啠啡啢啣啤啥啦啧啨啩啪啫啬啭啮啯啰啱啲啳啴啵啶啷啸啹啺啻啼啽啾啿 +喀喁喂喃善喅喆喇喈喉喊喋喌喍喎喏喐喑喒喓喔喕喖喗喘喙喚喛喜喝喞喟 +喠喡喢喣喤喥喦喧喨喩喪喫喬喭單喯喰喱喲喳喴喵営喷喸喹喺喻喼喽喾喿 +嗀嗁嗂嗃嗄嗅嗆嗇嗈嗉嗊嗋嗌嗍嗎嗏嗐嗑嗒嗓嗔嗕嗖嗗嗘嗙嗚嗛嗜嗝嗞嗟 +嗠嗡嗢嗣嗤嗥嗦嗧嗨嗩嗪嗫嗬嗭嗮嗯嗰嗱嗲嗳嗴嗵嗶嗷嗸嗹嗺嗻嗼嗽嗾嗿 +嘀嘁嘂嘃嘄嘅嘆嘇嘈嘉嘊嘋嘌嘍嘎嘏嘐嘑嘒嘓嘔嘕嘖嘗嘘嘙嘚嘛嘜嘝嘞嘟 +嘠嘡嘢嘣嘤嘥嘦嘧嘨嘩嘪嘫嘬嘭嘮嘯嘰嘱嘲嘳嘴嘵嘶嘷嘸嘹嘺嘻嘼嘽嘾嘿 +噀噁噂噃噄噅噆噇噈噉噊噋噌噍噎噏噐噑噒噓噔噕噖噗噘噙噚噛噜噝噞噟 +噠噡噢噣噤噥噦噧器噩噪噫噬噭噮噯噰噱噲噳噴噵噶噷噸噹噺噻噼噽噾噿 +嚀嚁嚂嚃嚄嚅嚆嚇嚈嚉嚊嚋嚌嚍嚎嚏嚐嚑嚒嚓嚔嚕嚖嚗嚘嚙嚚嚛嚜嚝嚞嚟 +嚠嚡嚢嚣嚤嚥嚦嚧嚨嚩嚪嚫嚬嚭嚮嚯嚰嚱嚲嚳嚴嚵嚶嚷嚸嚹嚺嚻嚼嚽嚾嚿 +囀囁囂囃囄囅囆囇囈囉囊囋囌囍囎囏囐囑囒囓囔囕囖囗囘囙囚四囜囝回囟 +因囡团団囤囥囦囧囨囩囪囫囬园囮囯困囱囲図围囵囶囷囸囹固囻囼国图囿 +圀圁圂圃圄圅圆圇圈圉圊國圌圍圎圏圐圑園圓圔圕圖圗團圙圚圛圜圝圞土 +圠圡圢圣圤圥圦圧在圩圪圫圬圭圮圯地圱圲圳圴圵圶圷圸圹场圻圼圽圾圿 +址坁坂坃坄坅坆均坈坉坊坋坌坍坎坏坐坑坒坓坔坕坖块坘坙坚坛坜坝坞坟 +坠坡坢坣坤坥坦坧坨坩坪坫坬坭坮坯坰坱坲坳坴坵坶坷坸坹坺坻坼坽坾坿 +垀垁垂垃垄垅垆垇垈垉垊型垌垍垎垏垐垑垒垓垔垕垖垗垘垙垚垛垜垝垞垟 +垠垡垢垣垤垥垦垧垨垩垪垫垬垭垮垯垰垱垲垳垴垵垶垷垸垹垺垻垼垽垾垿 +埀埁埂埃埄埅埆埇埈埉埊埋埌埍城埏埐埑埒埓埔埕埖埗埘埙埚埛埜埝埞域 +埠埡埢埣埤埥埦埧埨埩埪埫埬埭埮埯埰埱埲埳埴埵埶執埸培基埻埼埽埾埿 +堀堁堂堃堄堅堆堇堈堉堊堋堌堍堎堏堐堑堒堓堔堕堖堗堘堙堚堛堜堝堞堟 +堠堡堢堣堤堥堦堧堨堩堪堫堬堭堮堯堰報堲堳場堵堶堷堸堹堺堻堼堽堾堿 +塀塁塂塃塄塅塆塇塈塉塊塋塌塍塎塏塐塑塒塓塔塕塖塗塘塙塚塛塜塝塞塟 +塠塡塢塣塤塥塦塧塨塩塪填塬塭塮塯塰塱塲塳塴塵塶塷塸塹塺塻塼塽塾塿 +墀墁墂境墄墅墆墇墈墉墊墋墌墍墎墏墐墑墒墓墔墕墖増墘墙墚墛墜墝增墟 +墠墡墢墣墤墥墦墧墨墩墪墫墬墭墮墯墰墱墲墳墴墵墶墷墸墹墺墻墼墽墾墿 +壀壁壂壃壄壅壆壇壈壉壊壋壌壍壎壏壐壑壒壓壔壕壖壗壘壙壚壛壜壝壞壟 +壠壡壢壣壤壥壦壧壨壩壪士壬壭壮壯声壱売壳壴壵壶壷壸壹壺壻壼壽壾壿 +夀夁夂夃处夅夆备夈変夊夋夌复夎夏夐夑夒夓夔夕外夗夘夙多夛夜夝夞够 +夠夡夢夣夤夥夦大夨天太夫夬夭央夯夰失夲夳头夵夶夷夸夹夺夻夼夽夾夿 +奀奁奂奃奄奅奆奇奈奉奊奋奌奍奎奏奐契奒奓奔奕奖套奘奙奚奛奜奝奞奟 +奠奡奢奣奤奥奦奧奨奩奪奫奬奭奮奯奰奱奲女奴奵奶奷奸她奺奻奼好奾奿 +妀妁如妃妄妅妆妇妈妉妊妋妌妍妎妏妐妑妒妓妔妕妖妗妘妙妚妛妜妝妞妟 +妠妡妢妣妤妥妦妧妨妩妪妫妬妭妮妯妰妱妲妳妴妵妶妷妸妹妺妻妼妽妾妿 +姀姁姂姃姄姅姆姇姈姉姊始姌姍姎姏姐姑姒姓委姕姖姗姘姙姚姛姜姝姞姟 +姠姡姢姣姤姥姦姧姨姩姪姫姬姭姮姯姰姱姲姳姴姵姶姷姸姹姺姻姼姽姾姿 +娀威娂娃娄娅娆娇娈娉娊娋娌娍娎娏娐娑娒娓娔娕娖娗娘娙娚娛娜娝娞娟 +娠娡娢娣娤娥娦娧娨娩娪娫娬娭娮娯娰娱娲娳娴娵娶娷娸娹娺娻娼娽娾娿 +婀婁婂婃婄婅婆婇婈婉婊婋婌婍婎婏婐婑婒婓婔婕婖婗婘婙婚婛婜婝婞婟 +婠婡婢婣婤婥婦婧婨婩婪婫婬婭婮婯婰婱婲婳婴婵婶婷婸婹婺婻婼婽婾婿 +媀媁媂媃媄媅媆媇媈媉媊媋媌媍媎媏媐媑媒媓媔媕媖媗媘媙媚媛媜媝媞媟 +媠媡媢媣媤媥媦媧媨媩媪媫媬媭媮媯媰媱媲媳媴媵媶媷媸媹媺媻媼媽媾媿 +嫀嫁嫂嫃嫄嫅嫆嫇嫈嫉嫊嫋嫌嫍嫎嫏嫐嫑嫒嫓嫔嫕嫖嫗嫘嫙嫚嫛嫜嫝嫞嫟 +嫠嫡嫢嫣嫤嫥嫦嫧嫨嫩嫪嫫嫬嫭嫮嫯嫰嫱嫲嫳嫴嫵嫶嫷嫸嫹嫺嫻嫼嫽嫾嫿 +嬀嬁嬂嬃嬄嬅嬆嬇嬈嬉嬊嬋嬌嬍嬎嬏嬐嬑嬒嬓嬔嬕嬖嬗嬘嬙嬚嬛嬜嬝嬞嬟 +嬠嬡嬢嬣嬤嬥嬦嬧嬨嬩嬪嬫嬬嬭嬮嬯嬰嬱嬲嬳嬴嬵嬶嬷嬸嬹嬺嬻嬼嬽嬾嬿 +孀孁孂孃孄孅孆孇孈孉孊孋孌孍孎孏子孑孒孓孔孕孖字存孙孚孛孜孝孞孟 +孠孡孢季孤孥学孧孨孩孪孫孬孭孮孯孰孱孲孳孴孵孶孷學孹孺孻孼孽孾孿 +宀宁宂它宄宅宆宇守安宊宋完宍宎宏宐宑宒宓宔宕宖宗官宙定宛宜宝实実 +宠审客宣室宥宦宧宨宩宪宫宬宭宮宯宰宱宲害宴宵家宷宸容宺宻宼宽宾宿 +寀寁寂寃寄寅密寇寈寉寊寋富寍寎寏寐寑寒寓寔寕寖寗寘寙寚寛寜寝寞察 +寠寡寢寣寤寥實寧寨審寪寫寬寭寮寯寰寱寲寳寴寵寶寷寸对寺寻导寽対寿 +尀封専尃射尅将將專尉尊尋尌對導小尐少尒尓尔尕尖尗尘尙尚尛尜尝尞尟 +尠尡尢尣尤尥尦尧尨尩尪尫尬尭尮尯尰就尲尳尴尵尶尷尸尹尺尻尼尽尾尿 +局屁层屃屄居屆屇屈屉届屋屌屍屎屏屐屑屒屓屔展屖屗屘屙屚屛屜屝属屟 +屠屡屢屣層履屦屧屨屩屪屫屬屭屮屯屰山屲屳屴屵屶屷屸屹屺屻屼屽屾屿 +岀岁岂岃岄岅岆岇岈岉岊岋岌岍岎岏岐岑岒岓岔岕岖岗岘岙岚岛岜岝岞岟 +岠岡岢岣岤岥岦岧岨岩岪岫岬岭岮岯岰岱岲岳岴岵岶岷岸岹岺岻岼岽岾岿 +峀峁峂峃峄峅峆峇峈峉峊峋峌峍峎峏峐峑峒峓峔峕峖峗峘峙峚峛峜峝峞峟 +峠峡峢峣峤峥峦峧峨峩峪峫峬峭峮峯峰峱峲峳峴峵島峷峸峹峺峻峼峽峾峿 +崀崁崂崃崄崅崆崇崈崉崊崋崌崍崎崏崐崑崒崓崔崕崖崗崘崙崚崛崜崝崞崟 +崠崡崢崣崤崥崦崧崨崩崪崫崬崭崮崯崰崱崲崳崴崵崶崷崸崹崺崻崼崽崾崿 +嵀嵁嵂嵃嵄嵅嵆嵇嵈嵉嵊嵋嵌嵍嵎嵏嵐嵑嵒嵓嵔嵕嵖嵗嵘嵙嵚嵛嵜嵝嵞嵟 +嵠嵡嵢嵣嵤嵥嵦嵧嵨嵩嵪嵫嵬嵭嵮嵯嵰嵱嵲嵳嵴嵵嵶嵷嵸嵹嵺嵻嵼嵽嵾嵿 +嶀嶁嶂嶃嶄嶅嶆嶇嶈嶉嶊嶋嶌嶍嶎嶏嶐嶑嶒嶓嶔嶕嶖嶗嶘嶙嶚嶛嶜嶝嶞嶟 +嶠嶡嶢嶣嶤嶥嶦嶧嶨嶩嶪嶫嶬嶭嶮嶯嶰嶱嶲嶳嶴嶵嶶嶷嶸嶹嶺嶻嶼嶽嶾嶿 +巀巁巂巃巄巅巆巇巈巉巊巋巌巍巎巏巐巑巒巓巔巕巖巗巘巙巚巛巜川州巟 +巠巡巢巣巤工左巧巨巩巪巫巬巭差巯巰己已巳巴巵巶巷巸巹巺巻巼巽巾巿 +帀币市布帄帅帆帇师帉帊帋希帍帎帏帐帑帒帓帔帕帖帗帘帙帚帛帜帝帞帟 +帠帡帢帣帤帥带帧帨帩帪師帬席帮帯帰帱帲帳帴帵帶帷常帹帺帻帼帽帾帿 +幀幁幂幃幄幅幆幇幈幉幊幋幌幍幎幏幐幑幒幓幔幕幖幗幘幙幚幛幜幝幞幟 +幠幡幢幣幤幥幦幧幨幩幪幫幬幭幮幯幰幱干平年幵并幷幸幹幺幻幼幽幾广 +庀庁庂広庄庅庆庇庈庉床庋庌庍庎序庐庑庒库应底庖店庘庙庚庛府庝庞废 +庠庡庢庣庤庥度座庨庩庪庫庬庭庮庯庰庱庲庳庴庵庶康庸庹庺庻庼庽庾庿 +廀廁廂廃廄廅廆廇廈廉廊廋廌廍廎廏廐廑廒廓廔廕廖廗廘廙廚廛廜廝廞廟 +廠廡廢廣廤廥廦廧廨廩廪廫廬廭廮廯廰廱廲廳廴廵延廷廸廹建廻廼廽廾廿 +开弁异弃弄弅弆弇弈弉弊弋弌弍弎式弐弑弒弓弔引弖弗弘弙弚弛弜弝弞弟 +张弡弢弣弤弥弦弧弨弩弪弫弬弭弮弯弰弱弲弳弴張弶強弸弹强弻弼弽弾弿 +彀彁彂彃彄彅彆彇彈彉彊彋彌彍彎彏彐彑归当彔录彖彗彘彙彚彛彜彝彞彟 +彠彡形彣彤彥彦彧彨彩彪彫彬彭彮彯彰影彲彳彴彵彶彷彸役彺彻彼彽彾彿 +往征徂徃径待徆徇很徉徊律後徍徎徏徐徑徒従徔徕徖得徘徙徚徛徜徝從徟 +徠御徢徣徤徥徦徧徨復循徫徬徭微徯徰徱徲徳徴徵徶德徸徹徺徻徼徽徾徿 +忀忁忂心忄必忆忇忈忉忊忋忌忍忎忏忐忑忒忓忔忕忖志忘忙忚忛応忝忞忟 +忠忡忢忣忤忥忦忧忨忩忪快忬忭忮忯忰忱忲忳忴念忶忷忸忹忺忻忼忽忾忿 +怀态怂怃怄怅怆怇怈怉怊怋怌怍怎怏怐怑怒怓怔怕怖怗怘怙怚怛怜思怞怟 +怠怡怢怣怤急怦性怨怩怪怫怬怭怮怯怰怱怲怳怴怵怶怷怸怹怺总怼怽怾怿 +恀恁恂恃恄恅恆恇恈恉恊恋恌恍恎恏恐恑恒恓恔恕恖恗恘恙恚恛恜恝恞恟 +恠恡恢恣恤恥恦恧恨恩恪恫恬恭恮息恰恱恲恳恴恵恶恷恸恹恺恻恼恽恾恿 +悀悁悂悃悄悅悆悇悈悉悊悋悌悍悎悏悐悑悒悓悔悕悖悗悘悙悚悛悜悝悞悟 +悠悡悢患悤悥悦悧您悩悪悫悬悭悮悯悰悱悲悳悴悵悶悷悸悹悺悻悼悽悾悿 +惀惁惂惃惄情惆惇惈惉惊惋惌惍惎惏惐惑惒惓惔惕惖惗惘惙惚惛惜惝惞惟 +惠惡惢惣惤惥惦惧惨惩惪惫惬惭惮惯惰惱惲想惴惵惶惷惸惹惺惻惼惽惾惿 +愀愁愂愃愄愅愆愇愈愉愊愋愌愍愎意愐愑愒愓愔愕愖愗愘愙愚愛愜愝愞感 +愠愡愢愣愤愥愦愧愨愩愪愫愬愭愮愯愰愱愲愳愴愵愶愷愸愹愺愻愼愽愾愿 +慀慁慂慃慄慅慆慇慈慉慊態慌慍慎慏慐慑慒慓慔慕慖慗慘慙慚慛慜慝慞慟 +慠慡慢慣慤慥慦慧慨慩慪慫慬慭慮慯慰慱慲慳慴慵慶慷慸慹慺慻慼慽慾慿 +憀憁憂憃憄憅憆憇憈憉憊憋憌憍憎憏憐憑憒憓憔憕憖憗憘憙憚憛憜憝憞憟 +憠憡憢憣憤憥憦憧憨憩憪憫憬憭憮憯憰憱憲憳憴憵憶憷憸憹憺憻憼憽憾憿 +懀懁懂懃懄懅懆懇懈應懊懋懌懍懎懏懐懑懒懓懔懕懖懗懘懙懚懛懜懝懞懟 +懠懡懢懣懤懥懦懧懨懩懪懫懬懭懮懯懰懱懲懳懴懵懶懷懸懹懺懻懼懽懾懿 +戀戁戂戃戄戅戆戇戈戉戊戋戌戍戎戏成我戒戓戔戕或戗战戙戚戛戜戝戞戟 +戠戡戢戣戤戥戦戧戨戩截戫戬戭戮戯戰戱戲戳戴戵戶户戸戹戺戻戼戽戾房 +所扁扂扃扄扅扆扇扈扉扊手扌才扎扏扐扑扒打扔払扖扗托扙扚扛扜扝扞扟 +扠扡扢扣扤扥扦执扨扩扪扫扬扭扮扯扰扱扲扳扴扵扶扷扸批扺扻扼扽找承 +技抁抂抃抄抅抆抇抈抉把抋抌抍抎抏抐抑抒抓抔投抖抗折抙抚抛抜抝択抟 +抠抡抢抣护报抦抧抨抩抪披抬抭抮抯抰抱抲抳抴抵抶抷抸抹抺抻押抽抾抿 +拀拁拂拃拄担拆拇拈拉拊拋拌拍拎拏拐拑拒拓拔拕拖拗拘拙拚招拜拝拞拟 +拠拡拢拣拤拥拦拧拨择拪拫括拭拮拯拰拱拲拳拴拵拶拷拸拹拺拻拼拽拾拿 +挀持挂挃挄挅挆指挈按挊挋挌挍挎挏挐挑挒挓挔挕挖挗挘挙挚挛挜挝挞挟 +挠挡挢挣挤挥挦挧挨挩挪挫挬挭挮振挰挱挲挳挴挵挶挷挸挹挺挻挼挽挾挿 +捀捁捂捃捄捅捆捇捈捉捊捋捌捍捎捏捐捑捒捓捔捕捖捗捘捙捚捛捜捝捞损 +捠捡换捣捤捥捦捧捨捩捪捫捬捭据捯捰捱捲捳捴捵捶捷捸捹捺捻捼捽捾捿 +掀掁掂掃掄掅掆掇授掉掊掋掌掍掎掏掐掑排掓掔掕掖掗掘掙掚掛掜掝掞掟 +掠採探掣掤接掦控推掩措掫掬掭掮掯掰掱掲掳掴掵掶掷掸掹掺掻掼掽掾掿 +揀揁揂揃揄揅揆揇揈揉揊揋揌揍揎描提揑插揓揔揕揖揗揘揙揚換揜揝揞揟 +揠握揢揣揤揥揦揧揨揩揪揫揬揭揮揯揰揱揲揳援揵揶揷揸揹揺揻揼揽揾揿 +搀搁搂搃搄搅搆搇搈搉搊搋搌損搎搏搐搑搒搓搔搕搖搗搘搙搚搛搜搝搞搟 +搠搡搢搣搤搥搦搧搨搩搪搫搬搭搮搯搰搱搲搳搴搵搶搷搸搹携搻搼搽搾搿 +摀摁摂摃摄摅摆摇摈摉摊摋摌摍摎摏摐摑摒摓摔摕摖摗摘摙摚摛摜摝摞摟 +摠摡摢摣摤摥摦摧摨摩摪摫摬摭摮摯摰摱摲摳摴摵摶摷摸摹摺摻摼摽摾摿 +撀撁撂撃撄撅撆撇撈撉撊撋撌撍撎撏撐撑撒撓撔撕撖撗撘撙撚撛撜撝撞撟 +撠撡撢撣撤撥撦撧撨撩撪撫撬播撮撯撰撱撲撳撴撵撶撷撸撹撺撻撼撽撾撿 +擀擁擂擃擄擅擆擇擈擉擊擋擌操擎擏擐擑擒擓擔擕擖擗擘擙據擛擜擝擞擟 +擠擡擢擣擤擥擦擧擨擩擪擫擬擭擮擯擰擱擲擳擴擵擶擷擸擹擺擻擼擽擾擿 +攀攁攂攃攄攅攆攇攈攉攊攋攌攍攎攏攐攑攒攓攔攕攖攗攘攙攚攛攜攝攞攟 +攠攡攢攣攤攥攦攧攨攩攪攫攬攭攮支攰攱攲攳攴攵收攷攸改攺攻攼攽放政 +敀敁敂敃敄故敆敇效敉敊敋敌敍敎敏敐救敒敓敔敕敖敗敘教敚敛敜敝敞敟 +敠敡敢散敤敥敦敧敨敩敪敫敬敭敮敯数敱敲敳整敵敶敷數敹敺敻敼敽敾敿 +斀斁斂斃斄斅斆文斈斉斊斋斌斍斎斏斐斑斒斓斔斕斖斗斘料斚斛斜斝斞斟 +斠斡斢斣斤斥斦斧斨斩斪斫斬断斮斯新斱斲斳斴斵斶斷斸方斺斻於施斾斿 +旀旁旂旃旄旅旆旇旈旉旊旋旌旍旎族旐旑旒旓旔旕旖旗旘旙旚旛旜旝旞旟 +无旡既旣旤日旦旧旨早旪旫旬旭旮旯旰旱旲旳旴旵时旷旸旹旺旻旼旽旾旿 +昀昁昂昃昄昅昆昇昈昉昊昋昌昍明昏昐昑昒易昔昕昖昗昘昙昚昛昜昝昞星 +映昡昢昣昤春昦昧昨昩昪昫昬昭昮是昰昱昲昳昴昵昶昷昸昹昺昻昼昽显昿 +晀晁時晃晄晅晆晇晈晉晊晋晌晍晎晏晐晑晒晓晔晕晖晗晘晙晚晛晜晝晞晟 +晠晡晢晣晤晥晦晧晨晩晪晫晬晭普景晰晱晲晳晴晵晶晷晸晹智晻晼晽晾晿 +暀暁暂暃暄暅暆暇暈暉暊暋暌暍暎暏暐暑暒暓暔暕暖暗暘暙暚暛暜暝暞暟 +暠暡暢暣暤暥暦暧暨暩暪暫暬暭暮暯暰暱暲暳暴暵暶暷暸暹暺暻暼暽暾暿 +曀曁曂曃曄曅曆曇曈曉曊曋曌曍曎曏曐曑曒曓曔曕曖曗曘曙曚曛曜曝曞曟 +曠曡曢曣曤曥曦曧曨曩曪曫曬曭曮曯曰曱曲曳更曵曶曷書曹曺曻曼曽曾替 +最朁朂會朄朅朆朇月有朊朋朌服朎朏朐朑朒朓朔朕朖朗朘朙朚望朜朝朞期 +朠朡朢朣朤朥朦朧木朩未末本札朮术朰朱朲朳朴朵朶朷朸朹机朻朼朽朾朿 +杀杁杂权杄杅杆杇杈杉杊杋杌杍李杏材村杒杓杔杕杖杗杘杙杚杛杜杝杞束 +杠条杢杣杤来杦杧杨杩杪杫杬杭杮杯杰東杲杳杴杵杶杷杸杹杺杻杼杽松板 +枀极枂枃构枅枆枇枈枉枊枋枌枍枎枏析枑枒枓枔枕枖林枘枙枚枛果枝枞枟 +枠枡枢枣枤枥枦枧枨枩枪枫枬枭枮枯枰枱枲枳枴枵架枷枸枹枺枻枼枽枾枿 +柀柁柂柃柄柅柆柇柈柉柊柋柌柍柎柏某柑柒染柔柕柖柗柘柙柚柛柜柝柞柟 +柠柡柢柣柤查柦柧柨柩柪柫柬柭柮柯柰柱柲柳柴柵柶柷柸柹柺査柼柽柾柿 +栀栁栂栃栄栅栆标栈栉栊栋栌栍栎栏栐树栒栓栔栕栖栗栘栙栚栛栜栝栞栟 +栠校栢栣栤栥栦栧栨栩株栫栬栭栮栯栰栱栲栳栴栵栶样核根栺栻格栽栾栿 +桀桁桂桃桄桅框桇案桉桊桋桌桍桎桏桐桑桒桓桔桕桖桗桘桙桚桛桜桝桞桟 +桠桡桢档桤桥桦桧桨桩桪桫桬桭桮桯桰桱桲桳桴桵桶桷桸桹桺桻桼桽桾桿 +梀梁梂梃梄梅梆梇梈梉梊梋梌梍梎梏梐梑梒梓梔梕梖梗梘梙梚梛梜條梞梟 +梠梡梢梣梤梥梦梧梨梩梪梫梬梭梮梯械梱梲梳梴梵梶梷梸梹梺梻梼梽梾梿 +检棁棂棃棄棅棆棇棈棉棊棋棌棍棎棏棐棑棒棓棔棕棖棗棘棙棚棛棜棝棞棟 +棠棡棢棣棤棥棦棧棨棩棪棫棬棭森棯棰棱棲棳棴棵棶棷棸棹棺棻棼棽棾棿 +椀椁椂椃椄椅椆椇椈椉椊椋椌植椎椏椐椑椒椓椔椕椖椗椘椙椚椛検椝椞椟 +椠椡椢椣椤椥椦椧椨椩椪椫椬椭椮椯椰椱椲椳椴椵椶椷椸椹椺椻椼椽椾椿 +楀楁楂楃楄楅楆楇楈楉楊楋楌楍楎楏楐楑楒楓楔楕楖楗楘楙楚楛楜楝楞楟 +楠楡楢楣楤楥楦楧楨楩楪楫楬業楮楯楰楱楲楳楴極楶楷楸楹楺楻楼楽楾楿 +榀榁概榃榄榅榆榇榈榉榊榋榌榍榎榏榐榑榒榓榔榕榖榗榘榙榚榛榜榝榞榟 +榠榡榢榣榤榥榦榧榨榩榪榫榬榭榮榯榰榱榲榳榴榵榶榷榸榹榺榻榼榽榾榿 +槀槁槂槃槄槅槆槇槈槉槊構槌槍槎槏槐槑槒槓槔槕槖槗様槙槚槛槜槝槞槟 +槠槡槢槣槤槥槦槧槨槩槪槫槬槭槮槯槰槱槲槳槴槵槶槷槸槹槺槻槼槽槾槿 +樀樁樂樃樄樅樆樇樈樉樊樋樌樍樎樏樐樑樒樓樔樕樖樗樘標樚樛樜樝樞樟 +樠模樢樣樤樥樦樧樨権横樫樬樭樮樯樰樱樲樳樴樵樶樷樸樹樺樻樼樽樾樿 +橀橁橂橃橄橅橆橇橈橉橊橋橌橍橎橏橐橑橒橓橔橕橖橗橘橙橚橛橜橝橞機 +橠橡橢橣橤橥橦橧橨橩橪橫橬橭橮橯橰橱橲橳橴橵橶橷橸橹橺橻橼橽橾橿 +檀檁檂檃檄檅檆檇檈檉檊檋檌檍檎檏檐檑檒檓檔檕檖檗檘檙檚檛檜檝檞檟 +檠檡檢檣檤檥檦檧檨檩檪檫檬檭檮檯檰檱檲檳檴檵檶檷檸檹檺檻檼檽檾檿 +櫀櫁櫂櫃櫄櫅櫆櫇櫈櫉櫊櫋櫌櫍櫎櫏櫐櫑櫒櫓櫔櫕櫖櫗櫘櫙櫚櫛櫜櫝櫞櫟 +櫠櫡櫢櫣櫤櫥櫦櫧櫨櫩櫪櫫櫬櫭櫮櫯櫰櫱櫲櫳櫴櫵櫶櫷櫸櫹櫺櫻櫼櫽櫾櫿 +欀欁欂欃欄欅欆欇欈欉權欋欌欍欎欏欐欑欒欓欔欕欖欗欘欙欚欛欜欝欞欟 +欠次欢欣欤欥欦欧欨欩欪欫欬欭欮欯欰欱欲欳欴欵欶欷欸欹欺欻欼欽款欿 +歀歁歂歃歄歅歆歇歈歉歊歋歌歍歎歏歐歑歒歓歔歕歖歗歘歙歚歛歜歝歞歟 +歠歡止正此步武歧歨歩歪歫歬歭歮歯歰歱歲歳歴歵歶歷歸歹歺死歼歽歾歿 +殀殁殂殃殄殅殆殇殈殉殊残殌殍殎殏殐殑殒殓殔殕殖殗殘殙殚殛殜殝殞殟 +殠殡殢殣殤殥殦殧殨殩殪殫殬殭殮殯殰殱殲殳殴段殶殷殸殹殺殻殼殽殾殿 +毀毁毂毃毄毅毆毇毈毉毊毋毌母毎每毐毑毒毓比毕毖毗毘毙毚毛毜毝毞毟 +毠毡毢毣毤毥毦毧毨毩毪毫毬毭毮毯毰毱毲毳毴毵毶毷毸毹毺毻毼毽毾毿 +氀氁氂氃氄氅氆氇氈氉氊氋氌氍氎氏氐民氒氓气氕氖気氘氙氚氛氜氝氞氟 +氠氡氢氣氤氥氦氧氨氩氪氫氬氭氮氯氰氱氲氳水氵氶氷永氹氺氻氼氽氾氿 +汀汁求汃汄汅汆汇汈汉汊汋汌汍汎汏汐汑汒汓汔汕汖汗汘汙汚汛汜汝汞江 +池污汢汣汤汥汦汧汨汩汪汫汬汭汮汯汰汱汲汳汴汵汶汷汸汹決汻汼汽汾汿 +沀沁沂沃沄沅沆沇沈沉沊沋沌沍沎沏沐沑沒沓沔沕沖沗沘沙沚沛沜沝沞沟 +沠没沢沣沤沥沦沧沨沩沪沫沬沭沮沯沰沱沲河沴沵沶沷沸油沺治沼沽沾沿 +泀況泂泃泄泅泆泇泈泉泊泋泌泍泎泏泐泑泒泓泔法泖泗泘泙泚泛泜泝泞泟 +泠泡波泣泤泥泦泧注泩泪泫泬泭泮泯泰泱泲泳泴泵泶泷泸泹泺泻泼泽泾泿 +洀洁洂洃洄洅洆洇洈洉洊洋洌洍洎洏洐洑洒洓洔洕洖洗洘洙洚洛洜洝洞洟 +洠洡洢洣洤津洦洧洨洩洪洫洬洭洮洯洰洱洲洳洴洵洶洷洸洹洺活洼洽派洿 +浀流浂浃浄浅浆浇浈浉浊测浌浍济浏浐浑浒浓浔浕浖浗浘浙浚浛浜浝浞浟 +浠浡浢浣浤浥浦浧浨浩浪浫浬浭浮浯浰浱浲浳浴浵浶海浸浹浺浻浼浽浾浿 +涀涁涂涃涄涅涆涇消涉涊涋涌涍涎涏涐涑涒涓涔涕涖涗涘涙涚涛涜涝涞涟 +涠涡涢涣涤涥润涧涨涩涪涫涬涭涮涯涰涱液涳涴涵涶涷涸涹涺涻涼涽涾涿 +淀淁淂淃淄淅淆淇淈淉淊淋淌淍淎淏淐淑淒淓淔淕淖淗淘淙淚淛淜淝淞淟 +淠淡淢淣淤淥淦淧淨淩淪淫淬淭淮淯淰深淲淳淴淵淶混淸淹淺添淼淽淾淿 +渀渁渂渃渄清渆渇済渉渊渋渌渍渎渏渐渑渒渓渔渕渖渗渘渙渚減渜渝渞渟 +渠渡渢渣渤渥渦渧渨温渪渫測渭渮港渰渱渲渳渴渵渶渷游渹渺渻渼渽渾渿 +湀湁湂湃湄湅湆湇湈湉湊湋湌湍湎湏湐湑湒湓湔湕湖湗湘湙湚湛湜湝湞湟 +湠湡湢湣湤湥湦湧湨湩湪湫湬湭湮湯湰湱湲湳湴湵湶湷湸湹湺湻湼湽湾湿 +満溁溂溃溄溅溆溇溈溉溊溋溌溍溎溏源溑溒溓溔溕準溗溘溙溚溛溜溝溞溟 +溠溡溢溣溤溥溦溧溨溩溪溫溬溭溮溯溰溱溲溳溴溵溶溷溸溹溺溻溼溽溾溿 +滀滁滂滃滄滅滆滇滈滉滊滋滌滍滎滏滐滑滒滓滔滕滖滗滘滙滚滛滜滝滞滟 +滠满滢滣滤滥滦滧滨滩滪滫滬滭滮滯滰滱滲滳滴滵滶滷滸滹滺滻滼滽滾滿 +漀漁漂漃漄漅漆漇漈漉漊漋漌漍漎漏漐漑漒漓演漕漖漗漘漙漚漛漜漝漞漟 +漠漡漢漣漤漥漦漧漨漩漪漫漬漭漮漯漰漱漲漳漴漵漶漷漸漹漺漻漼漽漾漿 +潀潁潂潃潄潅潆潇潈潉潊潋潌潍潎潏潐潑潒潓潔潕潖潗潘潙潚潛潜潝潞潟 +潠潡潢潣潤潥潦潧潨潩潪潫潬潭潮潯潰潱潲潳潴潵潶潷潸潹潺潻潼潽潾潿 +澀澁澂澃澄澅澆澇澈澉澊澋澌澍澎澏澐澑澒澓澔澕澖澗澘澙澚澛澜澝澞澟 +澠澡澢澣澤澥澦澧澨澩澪澫澬澭澮澯澰澱澲澳澴澵澶澷澸澹澺澻澼澽澾澿 +激濁濂濃濄濅濆濇濈濉濊濋濌濍濎濏濐濑濒濓濔濕濖濗濘濙濚濛濜濝濞濟 +濠濡濢濣濤濥濦濧濨濩濪濫濬濭濮濯濰濱濲濳濴濵濶濷濸濹濺濻濼濽濾濿 +瀀瀁瀂瀃瀄瀅瀆瀇瀈瀉瀊瀋瀌瀍瀎瀏瀐瀑瀒瀓瀔瀕瀖瀗瀘瀙瀚瀛瀜瀝瀞瀟 +瀠瀡瀢瀣瀤瀥瀦瀧瀨瀩瀪瀫瀬瀭瀮瀯瀰瀱瀲瀳瀴瀵瀶瀷瀸瀹瀺瀻瀼瀽瀾瀿 +灀灁灂灃灄灅灆灇灈灉灊灋灌灍灎灏灐灑灒灓灔灕灖灗灘灙灚灛灜灝灞灟 +灠灡灢灣灤灥灦灧灨灩灪火灬灭灮灯灰灱灲灳灴灵灶灷灸灹灺灻灼災灾灿 +炀炁炂炃炄炅炆炇炈炉炊炋炌炍炎炏炐炑炒炓炔炕炖炗炘炙炚炛炜炝炞炟 +炠炡炢炣炤炥炦炧炨炩炪炫炬炭炮炯炰炱炲炳炴炵炶炷炸点為炻炼炽炾炿 +烀烁烂烃烄烅烆烇烈烉烊烋烌烍烎烏烐烑烒烓烔烕烖烗烘烙烚烛烜烝烞烟 +烠烡烢烣烤烥烦烧烨烩烪烫烬热烮烯烰烱烲烳烴烵烶烷烸烹烺烻烼烽烾烿 +焀焁焂焃焄焅焆焇焈焉焊焋焌焍焎焏焐焑焒焓焔焕焖焗焘焙焚焛焜焝焞焟 +焠無焢焣焤焥焦焧焨焩焪焫焬焭焮焯焰焱焲焳焴焵然焷焸焹焺焻焼焽焾焿 +煀煁煂煃煄煅煆煇煈煉煊煋煌煍煎煏煐煑煒煓煔煕煖煗煘煙煚煛煜煝煞煟 +煠煡煢煣煤煥煦照煨煩煪煫煬煭煮煯煰煱煲煳煴煵煶煷煸煹煺煻煼煽煾煿 +熀熁熂熃熄熅熆熇熈熉熊熋熌熍熎熏熐熑熒熓熔熕熖熗熘熙熚熛熜熝熞熟 +熠熡熢熣熤熥熦熧熨熩熪熫熬熭熮熯熰熱熲熳熴熵熶熷熸熹熺熻熼熽熾熿 +燀燁燂燃燄燅燆燇燈燉燊燋燌燍燎燏燐燑燒燓燔燕燖燗燘燙燚燛燜燝燞營 +燠燡燢燣燤燥燦燧燨燩燪燫燬燭燮燯燰燱燲燳燴燵燶燷燸燹燺燻燼燽燾燿 +爀爁爂爃爄爅爆爇爈爉爊爋爌爍爎爏爐爑爒爓爔爕爖爗爘爙爚爛爜爝爞爟 +爠爡爢爣爤爥爦爧爨爩爪爫爬爭爮爯爰爱爲爳爴爵父爷爸爹爺爻爼爽爾爿 +牀牁牂牃牄牅牆片版牉牊牋牌牍牎牏牐牑牒牓牔牕牖牗牘牙牚牛牜牝牞牟 +牠牡牢牣牤牥牦牧牨物牪牫牬牭牮牯牰牱牲牳牴牵牶牷牸特牺牻牼牽牾牿 +犀犁犂犃犄犅犆犇犈犉犊犋犌犍犎犏犐犑犒犓犔犕犖犗犘犙犚犛犜犝犞犟 +犠犡犢犣犤犥犦犧犨犩犪犫犬犭犮犯犰犱犲犳犴犵状犷犸犹犺犻犼犽犾犿 +狀狁狂狃狄狅狆狇狈狉狊狋狌狍狎狏狐狑狒狓狔狕狖狗狘狙狚狛狜狝狞狟 +狠狡狢狣狤狥狦狧狨狩狪狫独狭狮狯狰狱狲狳狴狵狶狷狸狹狺狻狼狽狾狿 +猀猁猂猃猄猅猆猇猈猉猊猋猌猍猎猏猐猑猒猓猔猕猖猗猘猙猚猛猜猝猞猟 +猠猡猢猣猤猥猦猧猨猩猪猫猬猭献猯猰猱猲猳猴猵猶猷猸猹猺猻猼猽猾猿 +獀獁獂獃獄獅獆獇獈獉獊獋獌獍獎獏獐獑獒獓獔獕獖獗獘獙獚獛獜獝獞獟 +獠獡獢獣獤獥獦獧獨獩獪獫獬獭獮獯獰獱獲獳獴獵獶獷獸獹獺獻獼獽獾獿 +玀玁玂玃玄玅玆率玈玉玊王玌玍玎玏玐玑玒玓玔玕玖玗玘玙玚玛玜玝玞玟 +玠玡玢玣玤玥玦玧玨玩玪玫玬玭玮环现玱玲玳玴玵玶玷玸玹玺玻玼玽玾玿 +珀珁珂珃珄珅珆珇珈珉珊珋珌珍珎珏珐珑珒珓珔珕珖珗珘珙珚珛珜珝珞珟 +珠珡珢珣珤珥珦珧珨珩珪珫珬班珮珯珰珱珲珳珴珵珶珷珸珹珺珻珼珽現珿 +琀琁琂球琄琅理琇琈琉琊琋琌琍琎琏琐琑琒琓琔琕琖琗琘琙琚琛琜琝琞琟 +琠琡琢琣琤琥琦琧琨琩琪琫琬琭琮琯琰琱琲琳琴琵琶琷琸琹琺琻琼琽琾琿 +瑀瑁瑂瑃瑄瑅瑆瑇瑈瑉瑊瑋瑌瑍瑎瑏瑐瑑瑒瑓瑔瑕瑖瑗瑘瑙瑚瑛瑜瑝瑞瑟 +瑠瑡瑢瑣瑤瑥瑦瑧瑨瑩瑪瑫瑬瑭瑮瑯瑰瑱瑲瑳瑴瑵瑶瑷瑸瑹瑺瑻瑼瑽瑾瑿 +璀璁璂璃璄璅璆璇璈璉璊璋璌璍璎璏璐璑璒璓璔璕璖璗璘璙璚璛璜璝璞璟 +璠璡璢璣璤璥璦璧璨璩璪璫璬璭璮璯環璱璲璳璴璵璶璷璸璹璺璻璼璽璾璿 +瓀瓁瓂瓃瓄瓅瓆瓇瓈瓉瓊瓋瓌瓍瓎瓏瓐瓑瓒瓓瓔瓕瓖瓗瓘瓙瓚瓛瓜瓝瓞瓟 +瓠瓡瓢瓣瓤瓥瓦瓧瓨瓩瓪瓫瓬瓭瓮瓯瓰瓱瓲瓳瓴瓵瓶瓷瓸瓹瓺瓻瓼瓽瓾瓿 +甀甁甂甃甄甅甆甇甈甉甊甋甌甍甎甏甐甑甒甓甔甕甖甗甘甙甚甛甜甝甞生 +甠甡產産甤甥甦甧用甩甪甫甬甭甮甯田由甲申甴电甶男甸甹町画甼甽甾甿 +畀畁畂畃畄畅畆畇畈畉畊畋界畍畎畏畐畑畒畓畔畕畖畗畘留畚畛畜畝畞畟 +畠畡畢畣畤略畦畧畨畩番畫畬畭畮畯異畱畲畳畴畵當畷畸畹畺畻畼畽畾畿 +疀疁疂疃疄疅疆疇疈疉疊疋疌疍疎疏疐疑疒疓疔疕疖疗疘疙疚疛疜疝疞疟 +疠疡疢疣疤疥疦疧疨疩疪疫疬疭疮疯疰疱疲疳疴疵疶疷疸疹疺疻疼疽疾疿 +痀痁痂痃痄病痆症痈痉痊痋痌痍痎痏痐痑痒痓痔痕痖痗痘痙痚痛痜痝痞痟 +痠痡痢痣痤痥痦痧痨痩痪痫痬痭痮痯痰痱痲痳痴痵痶痷痸痹痺痻痼痽痾痿 +瘀瘁瘂瘃瘄瘅瘆瘇瘈瘉瘊瘋瘌瘍瘎瘏瘐瘑瘒瘓瘔瘕瘖瘗瘘瘙瘚瘛瘜瘝瘞瘟 +瘠瘡瘢瘣瘤瘥瘦瘧瘨瘩瘪瘫瘬瘭瘮瘯瘰瘱瘲瘳瘴瘵瘶瘷瘸瘹瘺瘻瘼瘽瘾瘿 +癀癁療癃癄癅癆癇癈癉癊癋癌癍癎癏癐癑癒癓癔癕癖癗癘癙癚癛癜癝癞癟 +癠癡癢癣癤癥癦癧癨癩癪癫癬癭癮癯癰癱癲癳癴癵癶癷癸癹発登發白百癿 +皀皁皂皃的皅皆皇皈皉皊皋皌皍皎皏皐皑皒皓皔皕皖皗皘皙皚皛皜皝皞皟 +皠皡皢皣皤皥皦皧皨皩皪皫皬皭皮皯皰皱皲皳皴皵皶皷皸皹皺皻皼皽皾皿 +盀盁盂盃盄盅盆盇盈盉益盋盌盍盎盏盐监盒盓盔盕盖盗盘盙盚盛盜盝盞盟 +盠盡盢監盤盥盦盧盨盩盪盫盬盭目盯盰盱盲盳直盵盶盷相盹盺盻盼盽盾盿 +眀省眂眃眄眅眆眇眈眉眊看県眍眎眏眐眑眒眓眔眕眖眗眘眙眚眛眜眝眞真 +眠眡眢眣眤眥眦眧眨眩眪眫眬眭眮眯眰眱眲眳眴眵眶眷眸眹眺眻眼眽眾眿 +着睁睂睃睄睅睆睇睈睉睊睋睌睍睎睏睐睑睒睓睔睕睖睗睘睙睚睛睜睝睞睟 +睠睡睢督睤睥睦睧睨睩睪睫睬睭睮睯睰睱睲睳睴睵睶睷睸睹睺睻睼睽睾睿 +瞀瞁瞂瞃瞄瞅瞆瞇瞈瞉瞊瞋瞌瞍瞎瞏瞐瞑瞒瞓瞔瞕瞖瞗瞘瞙瞚瞛瞜瞝瞞瞟 +瞠瞡瞢瞣瞤瞥瞦瞧瞨瞩瞪瞫瞬瞭瞮瞯瞰瞱瞲瞳瞴瞵瞶瞷瞸瞹瞺瞻瞼瞽瞾瞿 +矀矁矂矃矄矅矆矇矈矉矊矋矌矍矎矏矐矑矒矓矔矕矖矗矘矙矚矛矜矝矞矟 +矠矡矢矣矤知矦矧矨矩矪矫矬短矮矯矰矱矲石矴矵矶矷矸矹矺矻矼矽矾矿 +砀码砂砃砄砅砆砇砈砉砊砋砌砍砎砏砐砑砒砓研砕砖砗砘砙砚砛砜砝砞砟 +砠砡砢砣砤砥砦砧砨砩砪砫砬砭砮砯砰砱砲砳破砵砶砷砸砹砺砻砼砽砾砿 +础硁硂硃硄硅硆硇硈硉硊硋硌硍硎硏硐硑硒硓硔硕硖硗硘硙硚硛硜硝硞硟 +硠硡硢硣硤硥硦硧硨硩硪硫硬硭确硯硰硱硲硳硴硵硶硷硸硹硺硻硼硽硾硿 +碀碁碂碃碄碅碆碇碈碉碊碋碌碍碎碏碐碑碒碓碔碕碖碗碘碙碚碛碜碝碞碟 +碠碡碢碣碤碥碦碧碨碩碪碫碬碭碮碯碰碱碲碳碴碵碶碷碸碹確碻碼碽碾碿 +磀磁磂磃磄磅磆磇磈磉磊磋磌磍磎磏磐磑磒磓磔磕磖磗磘磙磚磛磜磝磞磟 +磠磡磢磣磤磥磦磧磨磩磪磫磬磭磮磯磰磱磲磳磴磵磶磷磸磹磺磻磼磽磾磿 +礀礁礂礃礄礅礆礇礈礉礊礋礌礍礎礏礐礑礒礓礔礕礖礗礘礙礚礛礜礝礞礟 +礠礡礢礣礤礥礦礧礨礩礪礫礬礭礮礯礰礱礲礳礴礵礶礷礸礹示礻礼礽社礿 +祀祁祂祃祄祅祆祇祈祉祊祋祌祍祎祏祐祑祒祓祔祕祖祗祘祙祚祛祜祝神祟 +祠祡祢祣祤祥祦祧票祩祪祫祬祭祮祯祰祱祲祳祴祵祶祷祸祹祺祻祼祽祾祿 +禀禁禂禃禄禅禆禇禈禉禊禋禌禍禎福禐禑禒禓禔禕禖禗禘禙禚禛禜禝禞禟 +禠禡禢禣禤禥禦禧禨禩禪禫禬禭禮禯禰禱禲禳禴禵禶禷禸禹禺离禼禽禾禿 +秀私秂秃秄秅秆秇秈秉秊秋秌种秎秏秐科秒秓秔秕秖秗秘秙秚秛秜秝秞租 +秠秡秢秣秤秥秦秧秨秩秪秫秬秭秮积称秱秲秳秴秵秶秷秸秹秺移秼秽秾秿 +稀稁稂稃稄稅稆稇稈稉稊程稌稍税稏稐稑稒稓稔稕稖稗稘稙稚稛稜稝稞稟 +稠稡稢稣稤稥稦稧稨稩稪稫稬稭種稯稰稱稲稳稴稵稶稷稸稹稺稻稼稽稾稿 +穀穁穂穃穄穅穆穇穈穉穊穋穌積穎穏穐穑穒穓穔穕穖穗穘穙穚穛穜穝穞穟 +穠穡穢穣穤穥穦穧穨穩穪穫穬穭穮穯穰穱穲穳穴穵究穷穸穹空穻穼穽穾穿 +窀突窂窃窄窅窆窇窈窉窊窋窌窍窎窏窐窑窒窓窔窕窖窗窘窙窚窛窜窝窞窟 +窠窡窢窣窤窥窦窧窨窩窪窫窬窭窮窯窰窱窲窳窴窵窶窷窸窹窺窻窼窽窾窿 +竀竁竂竃竄竅竆竇竈竉竊立竌竍竎竏竐竑竒竓竔竕竖竗竘站竚竛竜竝竞竟 +章竡竢竣竤童竦竧竨竩竪竫竬竭竮端竰竱竲竳竴竵競竷竸竹竺竻竼竽竾竿 +笀笁笂笃笄笅笆笇笈笉笊笋笌笍笎笏笐笑笒笓笔笕笖笗笘笙笚笛笜笝笞笟 +笠笡笢笣笤笥符笧笨笩笪笫第笭笮笯笰笱笲笳笴笵笶笷笸笹笺笻笼笽笾笿 +筀筁筂筃筄筅筆筇筈等筊筋筌筍筎筏筐筑筒筓答筕策筗筘筙筚筛筜筝筞筟 +筠筡筢筣筤筥筦筧筨筩筪筫筬筭筮筯筰筱筲筳筴筵筶筷筸筹筺筻筼筽签筿 +简箁箂箃箄箅箆箇箈箉箊箋箌箍箎箏箐箑箒箓箔箕箖算箘箙箚箛箜箝箞箟 +箠管箢箣箤箥箦箧箨箩箪箫箬箭箮箯箰箱箲箳箴箵箶箷箸箹箺箻箼箽箾箿 +節篁篂篃範篅篆篇篈築篊篋篌篍篎篏篐篑篒篓篔篕篖篗篘篙篚篛篜篝篞篟 +篠篡篢篣篤篥篦篧篨篩篪篫篬篭篮篯篰篱篲篳篴篵篶篷篸篹篺篻篼篽篾篿 +簀簁簂簃簄簅簆簇簈簉簊簋簌簍簎簏簐簑簒簓簔簕簖簗簘簙簚簛簜簝簞簟 +簠簡簢簣簤簥簦簧簨簩簪簫簬簭簮簯簰簱簲簳簴簵簶簷簸簹簺簻簼簽簾簿 +籀籁籂籃籄籅籆籇籈籉籊籋籌籍籎籏籐籑籒籓籔籕籖籗籘籙籚籛籜籝籞籟 +籠籡籢籣籤籥籦籧籨籩籪籫籬籭籮籯籰籱籲米籴籵籶籷籸籹籺类籼籽籾籿 +粀粁粂粃粄粅粆粇粈粉粊粋粌粍粎粏粐粑粒粓粔粕粖粗粘粙粚粛粜粝粞粟 +粠粡粢粣粤粥粦粧粨粩粪粫粬粭粮粯粰粱粲粳粴粵粶粷粸粹粺粻粼粽精粿 +糀糁糂糃糄糅糆糇糈糉糊糋糌糍糎糏糐糑糒糓糔糕糖糗糘糙糚糛糜糝糞糟 +糠糡糢糣糤糥糦糧糨糩糪糫糬糭糮糯糰糱糲糳糴糵糶糷糸糹糺系糼糽糾糿 +紀紁紂紃約紅紆紇紈紉紊紋紌納紎紏紐紑紒紓純紕紖紗紘紙級紛紜紝紞紟 +素紡索紣紤紥紦紧紨紩紪紫紬紭紮累細紱紲紳紴紵紶紷紸紹紺紻紼紽紾紿 +絀絁終絃組絅絆絇絈絉絊絋経絍絎絏結絑絒絓絔絕絖絗絘絙絚絛絜絝絞絟 +絠絡絢絣絤絥給絧絨絩絪絫絬絭絮絯絰統絲絳絴絵絶絷絸絹絺絻絼絽絾絿 +綀綁綂綃綄綅綆綇綈綉綊綋綌綍綎綏綐綑綒經綔綕綖綗綘継続綛綜綝綞綟 +綠綡綢綣綤綥綦綧綨綩綪綫綬維綮綯綰綱網綳綴綵綶綷綸綹綺綻綼綽綾綿 +緀緁緂緃緄緅緆緇緈緉緊緋緌緍緎総緐緑緒緓緔緕緖緗緘緙線緛緜緝緞緟 +締緡緢緣緤緥緦緧編緩緪緫緬緭緮緯緰緱緲緳練緵緶緷緸緹緺緻緼緽緾緿 +縀縁縂縃縄縅縆縇縈縉縊縋縌縍縎縏縐縑縒縓縔縕縖縗縘縙縚縛縜縝縞縟 +縠縡縢縣縤縥縦縧縨縩縪縫縬縭縮縯縰縱縲縳縴縵縶縷縸縹縺縻縼總績縿 +繀繁繂繃繄繅繆繇繈繉繊繋繌繍繎繏繐繑繒繓織繕繖繗繘繙繚繛繜繝繞繟 +繠繡繢繣繤繥繦繧繨繩繪繫繬繭繮繯繰繱繲繳繴繵繶繷繸繹繺繻繼繽繾繿 +纀纁纂纃纄纅纆纇纈纉纊纋續纍纎纏纐纑纒纓纔纕纖纗纘纙纚纛纜纝纞纟 +纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线 +绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络绝绞统 +绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿 +缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缐缑缒缓缔缕编缗缘缙缚缛缜缝缞缟 +缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵缶缷缸缹缺缻缼缽缾缿 +罀罁罂罃罄罅罆罇罈罉罊罋罌罍罎罏罐网罒罓罔罕罖罗罘罙罚罛罜罝罞罟 +罠罡罢罣罤罥罦罧罨罩罪罫罬罭置罯罰罱署罳罴罵罶罷罸罹罺罻罼罽罾罿 +羀羁羂羃羄羅羆羇羈羉羊羋羌羍美羏羐羑羒羓羔羕羖羗羘羙羚羛羜羝羞羟 +羠羡羢羣群羥羦羧羨義羪羫羬羭羮羯羰羱羲羳羴羵羶羷羸羹羺羻羼羽羾羿 +翀翁翂翃翄翅翆翇翈翉翊翋翌翍翎翏翐翑習翓翔翕翖翗翘翙翚翛翜翝翞翟 +翠翡翢翣翤翥翦翧翨翩翪翫翬翭翮翯翰翱翲翳翴翵翶翷翸翹翺翻翼翽翾翿 +耀老耂考耄者耆耇耈耉耊耋而耍耎耏耐耑耒耓耔耕耖耗耘耙耚耛耜耝耞耟 +耠耡耢耣耤耥耦耧耨耩耪耫耬耭耮耯耰耱耲耳耴耵耶耷耸耹耺耻耼耽耾耿 +聀聁聂聃聄聅聆聇聈聉聊聋职聍聎聏聐聑聒聓联聕聖聗聘聙聚聛聜聝聞聟 +聠聡聢聣聤聥聦聧聨聩聪聫聬聭聮聯聰聱聲聳聴聵聶職聸聹聺聻聼聽聾聿 +肀肁肂肃肄肅肆肇肈肉肊肋肌肍肎肏肐肑肒肓肔肕肖肗肘肙肚肛肜肝肞肟 +肠股肢肣肤肥肦肧肨肩肪肫肬肭肮肯肰肱育肳肴肵肶肷肸肹肺肻肼肽肾肿 +胀胁胂胃胄胅胆胇胈胉胊胋背胍胎胏胐胑胒胓胔胕胖胗胘胙胚胛胜胝胞胟 +胠胡胢胣胤胥胦胧胨胩胪胫胬胭胮胯胰胱胲胳胴胵胶胷胸胹胺胻胼能胾胿 +脀脁脂脃脄脅脆脇脈脉脊脋脌脍脎脏脐脑脒脓脔脕脖脗脘脙脚脛脜脝脞脟 +脠脡脢脣脤脥脦脧脨脩脪脫脬脭脮脯脰脱脲脳脴脵脶脷脸脹脺脻脼脽脾脿 +腀腁腂腃腄腅腆腇腈腉腊腋腌腍腎腏腐腑腒腓腔腕腖腗腘腙腚腛腜腝腞腟 +腠腡腢腣腤腥腦腧腨腩腪腫腬腭腮腯腰腱腲腳腴腵腶腷腸腹腺腻腼腽腾腿 +膀膁膂膃膄膅膆膇膈膉膊膋膌膍膎膏膐膑膒膓膔膕膖膗膘膙膚膛膜膝膞膟 +膠膡膢膣膤膥膦膧膨膩膪膫膬膭膮膯膰膱膲膳膴膵膶膷膸膹膺膻膼膽膾膿 +臀臁臂臃臄臅臆臇臈臉臊臋臌臍臎臏臐臑臒臓臔臕臖臗臘臙臚臛臜臝臞臟 +臠臡臢臣臤臥臦臧臨臩自臫臬臭臮臯臰臱臲至致臵臶臷臸臹臺臻臼臽臾臿 +舀舁舂舃舄舅舆與興舉舊舋舌舍舎舏舐舑舒舓舔舕舖舗舘舙舚舛舜舝舞舟 +舠舡舢舣舤舥舦舧舨舩航舫般舭舮舯舰舱舲舳舴舵舶舷舸船舺舻舼舽舾舿 +艀艁艂艃艄艅艆艇艈艉艊艋艌艍艎艏艐艑艒艓艔艕艖艗艘艙艚艛艜艝艞艟 +艠艡艢艣艤艥艦艧艨艩艪艫艬艭艮良艰艱色艳艴艵艶艷艸艹艺艻艼艽艾艿 +芀芁节芃芄芅芆芇芈芉芊芋芌芍芎芏芐芑芒芓芔芕芖芗芘芙芚芛芜芝芞芟 +芠芡芢芣芤芥芦芧芨芩芪芫芬芭芮芯芰花芲芳芴芵芶芷芸芹芺芻芼芽芾芿 +苀苁苂苃苄苅苆苇苈苉苊苋苌苍苎苏苐苑苒苓苔苕苖苗苘苙苚苛苜苝苞苟 +苠苡苢苣苤若苦苧苨苩苪苫苬苭苮苯苰英苲苳苴苵苶苷苸苹苺苻苼苽苾苿 +茀茁茂范茄茅茆茇茈茉茊茋茌茍茎茏茐茑茒茓茔茕茖茗茘茙茚茛茜茝茞茟 +茠茡茢茣茤茥茦茧茨茩茪茫茬茭茮茯茰茱茲茳茴茵茶茷茸茹茺茻茼茽茾茿 +荀荁荂荃荄荅荆荇荈草荊荋荌荍荎荏荐荑荒荓荔荕荖荗荘荙荚荛荜荝荞荟 +荠荡荢荣荤荥荦荧荨荩荪荫荬荭荮药荰荱荲荳荴荵荶荷荸荹荺荻荼荽荾荿 +莀莁莂莃莄莅莆莇莈莉莊莋莌莍莎莏莐莑莒莓莔莕莖莗莘莙莚莛莜莝莞莟 +莠莡莢莣莤莥莦莧莨莩莪莫莬莭莮莯莰莱莲莳莴莵莶获莸莹莺莻莼莽莾莿 +菀菁菂菃菄菅菆菇菈菉菊菋菌菍菎菏菐菑菒菓菔菕菖菗菘菙菚菛菜菝菞菟 +菠菡菢菣菤菥菦菧菨菩菪菫菬菭菮華菰菱菲菳菴菵菶菷菸菹菺菻菼菽菾菿 +萀萁萂萃萄萅萆萇萈萉萊萋萌萍萎萏萐萑萒萓萔萕萖萗萘萙萚萛萜萝萞萟 +萠萡萢萣萤营萦萧萨萩萪萫萬萭萮萯萰萱萲萳萴萵萶萷萸萹萺萻萼落萾萿 +葀葁葂葃葄葅葆葇葈葉葊葋葌葍葎葏葐葑葒葓葔葕葖著葘葙葚葛葜葝葞葟 +葠葡葢董葤葥葦葧葨葩葪葫葬葭葮葯葰葱葲葳葴葵葶葷葸葹葺葻葼葽葾葿 +蒀蒁蒂蒃蒄蒅蒆蒇蒈蒉蒊蒋蒌蒍蒎蒏蒐蒑蒒蒓蒔蒕蒖蒗蒘蒙蒚蒛蒜蒝蒞蒟 +蒠蒡蒢蒣蒤蒥蒦蒧蒨蒩蒪蒫蒬蒭蒮蒯蒰蒱蒲蒳蒴蒵蒶蒷蒸蒹蒺蒻蒼蒽蒾蒿 +蓀蓁蓂蓃蓄蓅蓆蓇蓈蓉蓊蓋蓌蓍蓎蓏蓐蓑蓒蓓蓔蓕蓖蓗蓘蓙蓚蓛蓜蓝蓞蓟 +蓠蓡蓢蓣蓤蓥蓦蓧蓨蓩蓪蓫蓬蓭蓮蓯蓰蓱蓲蓳蓴蓵蓶蓷蓸蓹蓺蓻蓼蓽蓾蓿 +蔀蔁蔂蔃蔄蔅蔆蔇蔈蔉蔊蔋蔌蔍蔎蔏蔐蔑蔒蔓蔔蔕蔖蔗蔘蔙蔚蔛蔜蔝蔞蔟 +蔠蔡蔢蔣蔤蔥蔦蔧蔨蔩蔪蔫蔬蔭蔮蔯蔰蔱蔲蔳蔴蔵蔶蔷蔸蔹蔺蔻蔼蔽蔾蔿 +蕀蕁蕂蕃蕄蕅蕆蕇蕈蕉蕊蕋蕌蕍蕎蕏蕐蕑蕒蕓蕔蕕蕖蕗蕘蕙蕚蕛蕜蕝蕞蕟 +蕠蕡蕢蕣蕤蕥蕦蕧蕨蕩蕪蕫蕬蕭蕮蕯蕰蕱蕲蕳蕴蕵蕶蕷蕸蕹蕺蕻蕼蕽蕾蕿 +薀薁薂薃薄薅薆薇薈薉薊薋薌薍薎薏薐薑薒薓薔薕薖薗薘薙薚薛薜薝薞薟 +薠薡薢薣薤薥薦薧薨薩薪薫薬薭薮薯薰薱薲薳薴薵薶薷薸薹薺薻薼薽薾薿 +藀藁藂藃藄藅藆藇藈藉藊藋藌藍藎藏藐藑藒藓藔藕藖藗藘藙藚藛藜藝藞藟 +藠藡藢藣藤藥藦藧藨藩藪藫藬藭藮藯藰藱藲藳藴藵藶藷藸藹藺藻藼藽藾藿 +蘀蘁蘂蘃蘄蘅蘆蘇蘈蘉蘊蘋蘌蘍蘎蘏蘐蘑蘒蘓蘔蘕蘖蘗蘘蘙蘚蘛蘜蘝蘞蘟 +蘠蘡蘢蘣蘤蘥蘦蘧蘨蘩蘪蘫蘬蘭蘮蘯蘰蘱蘲蘳蘴蘵蘶蘷蘸蘹蘺蘻蘼蘽蘾蘿 +虀虁虂虃虄虅虆虇虈虉虊虋虌虍虎虏虐虑虒虓虔處虖虗虘虙虚虛虜虝虞號 +虠虡虢虣虤虥虦虧虨虩虪虫虬虭虮虯虰虱虲虳虴虵虶虷虸虹虺虻虼虽虾虿 +蚀蚁蚂蚃蚄蚅蚆蚇蚈蚉蚊蚋蚌蚍蚎蚏蚐蚑蚒蚓蚔蚕蚖蚗蚘蚙蚚蚛蚜蚝蚞蚟 +蚠蚡蚢蚣蚤蚥蚦蚧蚨蚩蚪蚫蚬蚭蚮蚯蚰蚱蚲蚳蚴蚵蚶蚷蚸蚹蚺蚻蚼蚽蚾蚿 +蛀蛁蛂蛃蛄蛅蛆蛇蛈蛉蛊蛋蛌蛍蛎蛏蛐蛑蛒蛓蛔蛕蛖蛗蛘蛙蛚蛛蛜蛝蛞蛟 +蛠蛡蛢蛣蛤蛥蛦蛧蛨蛩蛪蛫蛬蛭蛮蛯蛰蛱蛲蛳蛴蛵蛶蛷蛸蛹蛺蛻蛼蛽蛾蛿 +蜀蜁蜂蜃蜄蜅蜆蜇蜈蜉蜊蜋蜌蜍蜎蜏蜐蜑蜒蜓蜔蜕蜖蜗蜘蜙蜚蜛蜜蜝蜞蜟 +蜠蜡蜢蜣蜤蜥蜦蜧蜨蜩蜪蜫蜬蜭蜮蜯蜰蜱蜲蜳蜴蜵蜶蜷蜸蜹蜺蜻蜼蜽蜾蜿 +蝀蝁蝂蝃蝄蝅蝆蝇蝈蝉蝊蝋蝌蝍蝎蝏蝐蝑蝒蝓蝔蝕蝖蝗蝘蝙蝚蝛蝜蝝蝞蝟 +蝠蝡蝢蝣蝤蝥蝦蝧蝨蝩蝪蝫蝬蝭蝮蝯蝰蝱蝲蝳蝴蝵蝶蝷蝸蝹蝺蝻蝼蝽蝾蝿 +螀螁螂螃螄螅螆螇螈螉螊螋螌融螎螏螐螑螒螓螔螕螖螗螘螙螚螛螜螝螞螟 +螠螡螢螣螤螥螦螧螨螩螪螫螬螭螮螯螰螱螲螳螴螵螶螷螸螹螺螻螼螽螾螿 +蟀蟁蟂蟃蟄蟅蟆蟇蟈蟉蟊蟋蟌蟍蟎蟏蟐蟑蟒蟓蟔蟕蟖蟗蟘蟙蟚蟛蟜蟝蟞蟟 +蟠蟡蟢蟣蟤蟥蟦蟧蟨蟩蟪蟫蟬蟭蟮蟯蟰蟱蟲蟳蟴蟵蟶蟷蟸蟹蟺蟻蟼蟽蟾蟿 +蠀蠁蠂蠃蠄蠅蠆蠇蠈蠉蠊蠋蠌蠍蠎蠏蠐蠑蠒蠓蠔蠕蠖蠗蠘蠙蠚蠛蠜蠝蠞蠟 +蠠蠡蠢蠣蠤蠥蠦蠧蠨蠩蠪蠫蠬蠭蠮蠯蠰蠱蠲蠳蠴蠵蠶蠷蠸蠹蠺蠻蠼蠽蠾蠿 +血衁衂衃衄衅衆衇衈衉衊衋行衍衎衏衐衑衒術衔衕衖街衘衙衚衛衜衝衞衟 +衠衡衢衣衤补衦衧表衩衪衫衬衭衮衯衰衱衲衳衴衵衶衷衸衹衺衻衼衽衾衿 +袀袁袂袃袄袅袆袇袈袉袊袋袌袍袎袏袐袑袒袓袔袕袖袗袘袙袚袛袜袝袞袟 +袠袡袢袣袤袥袦袧袨袩袪被袬袭袮袯袰袱袲袳袴袵袶袷袸袹袺袻袼袽袾袿 +裀裁裂裃裄装裆裇裈裉裊裋裌裍裎裏裐裑裒裓裔裕裖裗裘裙裚裛補裝裞裟 +裠裡裢裣裤裥裦裧裨裩裪裫裬裭裮裯裰裱裲裳裴裵裶裷裸裹裺裻裼製裾裿 +褀褁褂褃褄褅褆複褈褉褊褋褌褍褎褏褐褑褒褓褔褕褖褗褘褙褚褛褜褝褞褟 +褠褡褢褣褤褥褦褧褨褩褪褫褬褭褮褯褰褱褲褳褴褵褶褷褸褹褺褻褼褽褾褿 +襀襁襂襃襄襅襆襇襈襉襊襋襌襍襎襏襐襑襒襓襔襕襖襗襘襙襚襛襜襝襞襟 +襠襡襢襣襤襥襦襧襨襩襪襫襬襭襮襯襰襱襲襳襴襵襶襷襸襹襺襻襼襽襾西 +覀要覂覃覄覅覆覇覈覉覊見覌覍覎規覐覑覒覓覔覕視覗覘覙覚覛覜覝覞覟 +覠覡覢覣覤覥覦覧覨覩親覫覬覭覮覯覰覱覲観覴覵覶覷覸覹覺覻覼覽覾覿 +觀见观觃规觅视觇览觉觊觋觌觍觎觏觐觑角觓觔觕觖觗觘觙觚觛觜觝觞觟 +觠觡觢解觤觥触觧觨觩觪觫觬觭觮觯觰觱觲觳觴觵觶觷觸觹觺觻觼觽觾觿 +言訁訂訃訄訅訆訇計訉訊訋訌訍討訏訐訑訒訓訔訕訖託記訙訚訛訜訝訞訟 +訠訡訢訣訤訥訦訧訨訩訪訫訬設訮訯訰許訲訳訴訵訶訷訸訹診註証訽訾訿 +詀詁詂詃詄詅詆詇詈詉詊詋詌詍詎詏詐詑詒詓詔評詖詗詘詙詚詛詜詝詞詟 +詠詡詢詣詤詥試詧詨詩詪詫詬詭詮詯詰話該詳詴詵詶詷詸詹詺詻詼詽詾詿 +誀誁誂誃誄誅誆誇誈誉誊誋誌認誎誏誐誑誒誓誔誕誖誗誘誙誚誛誜誝語誟 +誠誡誢誣誤誥誦誧誨誩說誫説読誮誯誰誱課誳誴誵誶誷誸誹誺誻誼誽誾調 +諀諁諂諃諄諅諆談諈諉諊請諌諍諎諏諐諑諒諓諔諕論諗諘諙諚諛諜諝諞諟 +諠諡諢諣諤諥諦諧諨諩諪諫諬諭諮諯諰諱諲諳諴諵諶諷諸諹諺諻諼諽諾諿 +謀謁謂謃謄謅謆謇謈謉謊謋謌謍謎謏謐謑謒謓謔謕謖謗謘謙謚講謜謝謞謟 +謠謡謢謣謤謥謦謧謨謩謪謫謬謭謮謯謰謱謲謳謴謵謶謷謸謹謺謻謼謽謾謿 +譀譁譂譃譄譅譆譇譈證譊譋譌譍譎譏譐譑譒譓譔譕譖譗識譙譚譛譜譝譞譟 +譠譡譢譣譤譥警譧譨譩譪譫譬譭譮譯議譱譲譳譴譵譶護譸譹譺譻譼譽譾譿 +讀讁讂讃讄讅讆讇讈讉變讋讌讍讎讏讐讑讒讓讔讕讖讗讘讙讚讛讜讝讞讟 +讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访 +诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟 +诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳说诵诶请诸诹诺读诼诽课诿 +谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟 +谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷谸谹谺谻谼谽谾谿 +豀豁豂豃豄豅豆豇豈豉豊豋豌豍豎豏豐豑豒豓豔豕豖豗豘豙豚豛豜豝豞豟 +豠象豢豣豤豥豦豧豨豩豪豫豬豭豮豯豰豱豲豳豴豵豶豷豸豹豺豻豼豽豾豿 +貀貁貂貃貄貅貆貇貈貉貊貋貌貍貎貏貐貑貒貓貔貕貖貗貘貙貚貛貜貝貞貟 +負財貢貣貤貥貦貧貨販貪貫責貭貮貯貰貱貲貳貴貵貶買貸貹貺費貼貽貾貿 +賀賁賂賃賄賅賆資賈賉賊賋賌賍賎賏賐賑賒賓賔賕賖賗賘賙賚賛賜賝賞賟 +賠賡賢賣賤賥賦賧賨賩質賫賬賭賮賯賰賱賲賳賴賵賶賷賸賹賺賻購賽賾賿 +贀贁贂贃贄贅贆贇贈贉贊贋贌贍贎贏贐贑贒贓贔贕贖贗贘贙贚贛贜贝贞负 +贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿 +赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赟 +赠赡赢赣赤赥赦赧赨赩赪赫赬赭赮赯走赱赲赳赴赵赶起赸赹赺赻赼赽赾赿 +趀趁趂趃趄超趆趇趈趉越趋趌趍趎趏趐趑趒趓趔趕趖趗趘趙趚趛趜趝趞趟 +趠趡趢趣趤趥趦趧趨趩趪趫趬趭趮趯趰趱趲足趴趵趶趷趸趹趺趻趼趽趾趿 +跀跁跂跃跄跅跆跇跈跉跊跋跌跍跎跏跐跑跒跓跔跕跖跗跘跙跚跛跜距跞跟 +跠跡跢跣跤跥跦跧跨跩跪跫跬跭跮路跰跱跲跳跴践跶跷跸跹跺跻跼跽跾跿 +踀踁踂踃踄踅踆踇踈踉踊踋踌踍踎踏踐踑踒踓踔踕踖踗踘踙踚踛踜踝踞踟 +踠踡踢踣踤踥踦踧踨踩踪踫踬踭踮踯踰踱踲踳踴踵踶踷踸踹踺踻踼踽踾踿 +蹀蹁蹂蹃蹄蹅蹆蹇蹈蹉蹊蹋蹌蹍蹎蹏蹐蹑蹒蹓蹔蹕蹖蹗蹘蹙蹚蹛蹜蹝蹞蹟 +蹠蹡蹢蹣蹤蹥蹦蹧蹨蹩蹪蹫蹬蹭蹮蹯蹰蹱蹲蹳蹴蹵蹶蹷蹸蹹蹺蹻蹼蹽蹾蹿 +躀躁躂躃躄躅躆躇躈躉躊躋躌躍躎躏躐躑躒躓躔躕躖躗躘躙躚躛躜躝躞躟 +躠躡躢躣躤躥躦躧躨躩躪身躬躭躮躯躰躱躲躳躴躵躶躷躸躹躺躻躼躽躾躿 +軀軁軂軃軄軅軆軇軈軉車軋軌軍軎軏軐軑軒軓軔軕軖軗軘軙軚軛軜軝軞軟 +軠軡転軣軤軥軦軧軨軩軪軫軬軭軮軯軰軱軲軳軴軵軶軷軸軹軺軻軼軽軾軿 +輀輁輂較輄輅輆輇輈載輊輋輌輍輎輏輐輑輒輓輔輕輖輗輘輙輚輛輜輝輞輟 +輠輡輢輣輤輥輦輧輨輩輪輫輬輭輮輯輰輱輲輳輴輵輶輷輸輹輺輻輼輽輾輿 +轀轁轂轃轄轅轆轇轈轉轊轋轌轍轎轏轐轑轒轓轔轕轖轗轘轙轚轛轜轝轞轟 +轠轡轢轣轤轥车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿 +辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辛辜辝辞辟 +辠辡辢辣辤辥辦辧辨辩辪辫辬辭辮辯辰辱農辳辴辵辶辷辸边辺辻込辽达辿 +迀迁迂迃迄迅迆过迈迉迊迋迌迍迎迏运近迒迓返迕迖迗还这迚进远违连迟 +迠迡迢迣迤迥迦迧迨迩迪迫迬迭迮迯述迱迲迳迴迵迶迷迸迹迺迻迼追迾迿 +退送适逃逄逅逆逇逈选逊逋逌逍逎透逐逑递逓途逕逖逗逘這通逛逜逝逞速 +造逡逢連逤逥逦逧逨逩逪逫逬逭逮逯逰週進逳逴逵逶逷逸逹逺逻逼逽逾逿 +遀遁遂遃遄遅遆遇遈遉遊運遌遍過遏遐遑遒道達違遖遗遘遙遚遛遜遝遞遟 +遠遡遢遣遤遥遦遧遨適遪遫遬遭遮遯遰遱遲遳遴遵遶遷選遹遺遻遼遽遾避 +邀邁邂邃還邅邆邇邈邉邊邋邌邍邎邏邐邑邒邓邔邕邖邗邘邙邚邛邜邝邞邟 +邠邡邢那邤邥邦邧邨邩邪邫邬邭邮邯邰邱邲邳邴邵邶邷邸邹邺邻邼邽邾邿 +郀郁郂郃郄郅郆郇郈郉郊郋郌郍郎郏郐郑郒郓郔郕郖郗郘郙郚郛郜郝郞郟 +郠郡郢郣郤郥郦郧部郩郪郫郬郭郮郯郰郱郲郳郴郵郶郷郸郹郺郻郼都郾郿 +鄀鄁鄂鄃鄄鄅鄆鄇鄈鄉鄊鄋鄌鄍鄎鄏鄐鄑鄒鄓鄔鄕鄖鄗鄘鄙鄚鄛鄜鄝鄞鄟 +鄠鄡鄢鄣鄤鄥鄦鄧鄨鄩鄪鄫鄬鄭鄮鄯鄰鄱鄲鄳鄴鄵鄶鄷鄸鄹鄺鄻鄼鄽鄾鄿 +酀酁酂酃酄酅酆酇酈酉酊酋酌配酎酏酐酑酒酓酔酕酖酗酘酙酚酛酜酝酞酟 +酠酡酢酣酤酥酦酧酨酩酪酫酬酭酮酯酰酱酲酳酴酵酶酷酸酹酺酻酼酽酾酿 +醀醁醂醃醄醅醆醇醈醉醊醋醌醍醎醏醐醑醒醓醔醕醖醗醘醙醚醛醜醝醞醟 +醠醡醢醣醤醥醦醧醨醩醪醫醬醭醮醯醰醱醲醳醴醵醶醷醸醹醺醻醼醽醾醿 +釀釁釂釃釄釅釆采釈釉释釋里重野量釐金釒釓釔釕釖釗釘釙釚釛釜針釞釟 +釠釡釢釣釤釥釦釧釨釩釪釫釬釭釮釯釰釱釲釳釴釵釶釷釸釹釺釻釼釽釾釿 +鈀鈁鈂鈃鈄鈅鈆鈇鈈鈉鈊鈋鈌鈍鈎鈏鈐鈑鈒鈓鈔鈕鈖鈗鈘鈙鈚鈛鈜鈝鈞鈟 +鈠鈡鈢鈣鈤鈥鈦鈧鈨鈩鈪鈫鈬鈭鈮鈯鈰鈱鈲鈳鈴鈵鈶鈷鈸鈹鈺鈻鈼鈽鈾鈿 +鉀鉁鉂鉃鉄鉅鉆鉇鉈鉉鉊鉋鉌鉍鉎鉏鉐鉑鉒鉓鉔鉕鉖鉗鉘鉙鉚鉛鉜鉝鉞鉟 +鉠鉡鉢鉣鉤鉥鉦鉧鉨鉩鉪鉫鉬鉭鉮鉯鉰鉱鉲鉳鉴鉵鉶鉷鉸鉹鉺鉻鉼鉽鉾鉿 +銀銁銂銃銄銅銆銇銈銉銊銋銌銍銎銏銐銑銒銓銔銕銖銗銘銙銚銛銜銝銞銟 +銠銡銢銣銤銥銦銧銨銩銪銫銬銭銮銯銰銱銲銳銴銵銶銷銸銹銺銻銼銽銾銿 +鋀鋁鋂鋃鋄鋅鋆鋇鋈鋉鋊鋋鋌鋍鋎鋏鋐鋑鋒鋓鋔鋕鋖鋗鋘鋙鋚鋛鋜鋝鋞鋟 +鋠鋡鋢鋣鋤鋥鋦鋧鋨鋩鋪鋫鋬鋭鋮鋯鋰鋱鋲鋳鋴鋵鋶鋷鋸鋹鋺鋻鋼鋽鋾鋿 +錀錁錂錃錄錅錆錇錈錉錊錋錌錍錎錏錐錑錒錓錔錕錖錗錘錙錚錛錜錝錞錟 +錠錡錢錣錤錥錦錧錨錩錪錫錬錭錮錯錰錱録錳錴錵錶錷錸錹錺錻錼錽錾錿 +鍀鍁鍂鍃鍄鍅鍆鍇鍈鍉鍊鍋鍌鍍鍎鍏鍐鍑鍒鍓鍔鍕鍖鍗鍘鍙鍚鍛鍜鍝鍞鍟 +鍠鍡鍢鍣鍤鍥鍦鍧鍨鍩鍪鍫鍬鍭鍮鍯鍰鍱鍲鍳鍴鍵鍶鍷鍸鍹鍺鍻鍼鍽鍾鍿 +鎀鎁鎂鎃鎄鎅鎆鎇鎈鎉鎊鎋鎌鎍鎎鎏鎐鎑鎒鎓鎔鎕鎖鎗鎘鎙鎚鎛鎜鎝鎞鎟 +鎠鎡鎢鎣鎤鎥鎦鎧鎨鎩鎪鎫鎬鎭鎮鎯鎰鎱鎲鎳鎴鎵鎶鎷鎸鎹鎺鎻鎼鎽鎾鎿 +鏀鏁鏂鏃鏄鏅鏆鏇鏈鏉鏊鏋鏌鏍鏎鏏鏐鏑鏒鏓鏔鏕鏖鏗鏘鏙鏚鏛鏜鏝鏞鏟 +鏠鏡鏢鏣鏤鏥鏦鏧鏨鏩鏪鏫鏬鏭鏮鏯鏰鏱鏲鏳鏴鏵鏶鏷鏸鏹鏺鏻鏼鏽鏾鏿 +鐀鐁鐂鐃鐄鐅鐆鐇鐈鐉鐊鐋鐌鐍鐎鐏鐐鐑鐒鐓鐔鐕鐖鐗鐘鐙鐚鐛鐜鐝鐞鐟 +鐠鐡鐢鐣鐤鐥鐦鐧鐨鐩鐪鐫鐬鐭鐮鐯鐰鐱鐲鐳鐴鐵鐶鐷鐸鐹鐺鐻鐼鐽鐾鐿 +鑀鑁鑂鑃鑄鑅鑆鑇鑈鑉鑊鑋鑌鑍鑎鑏鑐鑑鑒鑓鑔鑕鑖鑗鑘鑙鑚鑛鑜鑝鑞鑟 +鑠鑡鑢鑣鑤鑥鑦鑧鑨鑩鑪鑫鑬鑭鑮鑯鑰鑱鑲鑳鑴鑵鑶鑷鑸鑹鑺鑻鑼鑽鑾鑿 +钀钁钂钃钄钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟 +钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿 +铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟 +铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链铿 +销锁锂锃锄锅锆锇锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟 +锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿 +镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟 +镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶長镸镹镺镻镼镽镾长 +門閁閂閃閄閅閆閇閈閉閊開閌閍閎閏閐閑閒間閔閕閖閗閘閙閚閛閜閝閞閟 +閠閡関閣閤閥閦閧閨閩閪閫閬閭閮閯閰閱閲閳閴閵閶閷閸閹閺閻閼閽閾閿 +闀闁闂闃闄闅闆闇闈闉闊闋闌闍闎闏闐闑闒闓闔闕闖闗闘闙闚闛關闝闞闟 +闠闡闢闣闤闥闦闧门闩闪闫闬闭问闯闰闱闲闳间闵闶闷闸闹闺闻闼闽闾闿 +阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛阜阝阞队 +阠阡阢阣阤阥阦阧阨阩阪阫阬阭阮阯阰阱防阳阴阵阶阷阸阹阺阻阼阽阾阿 +陀陁陂陃附际陆陇陈陉陊陋陌降陎陏限陑陒陓陔陕陖陗陘陙陚陛陜陝陞陟 +陠陡院陣除陥陦陧陨险陪陫陬陭陮陯陰陱陲陳陴陵陶陷陸陹険陻陼陽陾陿 +隀隁隂隃隄隅隆隇隈隉隊隋隌隍階随隐隑隒隓隔隕隖隗隘隙隚際障隝隞隟 +隠隡隢隣隤隥隦隧隨隩險隫隬隭隮隯隰隱隲隳隴隵隶隷隸隹隺隻隼隽难隿 +雀雁雂雃雄雅集雇雈雉雊雋雌雍雎雏雐雑雒雓雔雕雖雗雘雙雚雛雜雝雞雟 +雠雡離難雤雥雦雧雨雩雪雫雬雭雮雯雰雱雲雳雴雵零雷雸雹雺電雼雽雾雿 +需霁霂霃霄霅霆震霈霉霊霋霌霍霎霏霐霑霒霓霔霕霖霗霘霙霚霛霜霝霞霟 +霠霡霢霣霤霥霦霧霨霩霪霫霬霭霮霯霰霱露霳霴霵霶霷霸霹霺霻霼霽霾霿 +靀靁靂靃靄靅靆靇靈靉靊靋靌靍靎靏靐靑青靓靔靕靖靗靘静靚靛靜靝非靟 +靠靡面靣靤靥靦靧靨革靪靫靬靭靮靯靰靱靲靳靴靵靶靷靸靹靺靻靼靽靾靿 +鞀鞁鞂鞃鞄鞅鞆鞇鞈鞉鞊鞋鞌鞍鞎鞏鞐鞑鞒鞓鞔鞕鞖鞗鞘鞙鞚鞛鞜鞝鞞鞟 +鞠鞡鞢鞣鞤鞥鞦鞧鞨鞩鞪鞫鞬鞭鞮鞯鞰鞱鞲鞳鞴鞵鞶鞷鞸鞹鞺鞻鞼鞽鞾鞿 +韀韁韂韃韄韅韆韇韈韉韊韋韌韍韎韏韐韑韒韓韔韕韖韗韘韙韚韛韜韝韞韟 +韠韡韢韣韤韥韦韧韨韩韪韫韬韭韮韯韰韱韲音韴韵韶韷韸韹韺韻韼韽韾響 +頀頁頂頃頄項順頇須頉頊頋頌頍頎頏預頑頒頓頔頕頖頗領頙頚頛頜頝頞頟 +頠頡頢頣頤頥頦頧頨頩頪頫頬頭頮頯頰頱頲頳頴頵頶頷頸頹頺頻頼頽頾頿 +顀顁顂顃顄顅顆顇顈顉顊顋題額顎顏顐顑顒顓顔顕顖顗願顙顚顛顜顝類顟 +顠顡顢顣顤顥顦顧顨顩顪顫顬顭顮顯顰顱顲顳顴页顶顷顸项顺须顼顽顾顿 +颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜额颞颟 +颠颡颢颣颤颥颦颧風颩颪颫颬颭颮颯颰颱颲颳颴颵颶颷颸颹颺颻颼颽颾颿 +飀飁飂飃飄飅飆飇飈飉飊飋飌飍风飏飐飑飒飓飔飕飖飗飘飙飚飛飜飝飞食 +飠飡飢飣飤飥飦飧飨飩飪飫飬飭飮飯飰飱飲飳飴飵飶飷飸飹飺飻飼飽飾飿 +餀餁餂餃餄餅餆餇餈餉養餋餌餍餎餏餐餑餒餓餔餕餖餗餘餙餚餛餜餝餞餟 +餠餡餢餣餤餥餦餧館餩餪餫餬餭餮餯餰餱餲餳餴餵餶餷餸餹餺餻餼餽餾餿 +饀饁饂饃饄饅饆饇饈饉饊饋饌饍饎饏饐饑饒饓饔饕饖饗饘饙饚饛饜饝饞饟 +饠饡饢饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿 +馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕首馗馘香馚馛馜馝馞馟 +馠馡馢馣馤馥馦馧馨馩馪馫馬馭馮馯馰馱馲馳馴馵馶馷馸馹馺馻馼馽馾馿 +駀駁駂駃駄駅駆駇駈駉駊駋駌駍駎駏駐駑駒駓駔駕駖駗駘駙駚駛駜駝駞駟 +駠駡駢駣駤駥駦駧駨駩駪駫駬駭駮駯駰駱駲駳駴駵駶駷駸駹駺駻駼駽駾駿 +騀騁騂騃騄騅騆騇騈騉騊騋騌騍騎騏騐騑騒験騔騕騖騗騘騙騚騛騜騝騞騟 +騠騡騢騣騤騥騦騧騨騩騪騫騬騭騮騯騰騱騲騳騴騵騶騷騸騹騺騻騼騽騾騿 +驀驁驂驃驄驅驆驇驈驉驊驋驌驍驎驏驐驑驒驓驔驕驖驗驘驙驚驛驜驝驞驟 +驠驡驢驣驤驥驦驧驨驩驪驫马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿 +骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟 +骠骡骢骣骤骥骦骧骨骩骪骫骬骭骮骯骰骱骲骳骴骵骶骷骸骹骺骻骼骽骾骿 +髀髁髂髃髄髅髆髇髈髉髊髋髌髍髎髏髐髑髒髓體髕髖髗高髙髚髛髜髝髞髟 +髠髡髢髣髤髥髦髧髨髩髪髫髬髭髮髯髰髱髲髳髴髵髶髷髸髹髺髻髼髽髾髿 +鬀鬁鬂鬃鬄鬅鬆鬇鬈鬉鬊鬋鬌鬍鬎鬏鬐鬑鬒鬓鬔鬕鬖鬗鬘鬙鬚鬛鬜鬝鬞鬟 +鬠鬡鬢鬣鬤鬥鬦鬧鬨鬩鬪鬫鬬鬭鬮鬯鬰鬱鬲鬳鬴鬵鬶鬷鬸鬹鬺鬻鬼鬽鬾鬿 +魀魁魂魃魄魅魆魇魈魉魊魋魌魍魎魏魐魑魒魓魔魕魖魗魘魙魚魛魜魝魞魟 +魠魡魢魣魤魥魦魧魨魩魪魫魬魭魮魯魰魱魲魳魴魵魶魷魸魹魺魻魼魽魾魿 +鮀鮁鮂鮃鮄鮅鮆鮇鮈鮉鮊鮋鮌鮍鮎鮏鮐鮑鮒鮓鮔鮕鮖鮗鮘鮙鮚鮛鮜鮝鮞鮟 +鮠鮡鮢鮣鮤鮥鮦鮧鮨鮩鮪鮫鮬鮭鮮鮯鮰鮱鮲鮳鮴鮵鮶鮷鮸鮹鮺鮻鮼鮽鮾鮿 +鯀鯁鯂鯃鯄鯅鯆鯇鯈鯉鯊鯋鯌鯍鯎鯏鯐鯑鯒鯓鯔鯕鯖鯗鯘鯙鯚鯛鯜鯝鯞鯟 +鯠鯡鯢鯣鯤鯥鯦鯧鯨鯩鯪鯫鯬鯭鯮鯯鯰鯱鯲鯳鯴鯵鯶鯷鯸鯹鯺鯻鯼鯽鯾鯿 +鰀鰁鰂鰃鰄鰅鰆鰇鰈鰉鰊鰋鰌鰍鰎鰏鰐鰑鰒鰓鰔鰕鰖鰗鰘鰙鰚鰛鰜鰝鰞鰟 +鰠鰡鰢鰣鰤鰥鰦鰧鰨鰩鰪鰫鰬鰭鰮鰯鰰鰱鰲鰳鰴鰵鰶鰷鰸鰹鰺鰻鰼鰽鰾鰿 +鱀鱁鱂鱃鱄鱅鱆鱇鱈鱉鱊鱋鱌鱍鱎鱏鱐鱑鱒鱓鱔鱕鱖鱗鱘鱙鱚鱛鱜鱝鱞鱟 +鱠鱡鱢鱣鱤鱥鱦鱧鱨鱩鱪鱫鱬鱭鱮鱯鱰鱱鱲鱳鱴鱵鱶鱷鱸鱹鱺鱻鱼鱽鱾鱿 +鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟 +鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿 +鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳚鳛鳜鳝鳞鳟 +鳠鳡鳢鳣鳤鳥鳦鳧鳨鳩鳪鳫鳬鳭鳮鳯鳰鳱鳲鳳鳴鳵鳶鳷鳸鳹鳺鳻鳼鳽鳾鳿 +鴀鴁鴂鴃鴄鴅鴆鴇鴈鴉鴊鴋鴌鴍鴎鴏鴐鴑鴒鴓鴔鴕鴖鴗鴘鴙鴚鴛鴜鴝鴞鴟 +鴠鴡鴢鴣鴤鴥鴦鴧鴨鴩鴪鴫鴬鴭鴮鴯鴰鴱鴲鴳鴴鴵鴶鴷鴸鴹鴺鴻鴼鴽鴾鴿 +鵀鵁鵂鵃鵄鵅鵆鵇鵈鵉鵊鵋鵌鵍鵎鵏鵐鵑鵒鵓鵔鵕鵖鵗鵘鵙鵚鵛鵜鵝鵞鵟 +鵠鵡鵢鵣鵤鵥鵦鵧鵨鵩鵪鵫鵬鵭鵮鵯鵰鵱鵲鵳鵴鵵鵶鵷鵸鵹鵺鵻鵼鵽鵾鵿 +鶀鶁鶂鶃鶄鶅鶆鶇鶈鶉鶊鶋鶌鶍鶎鶏鶐鶑鶒鶓鶔鶕鶖鶗鶘鶙鶚鶛鶜鶝鶞鶟 +鶠鶡鶢鶣鶤鶥鶦鶧鶨鶩鶪鶫鶬鶭鶮鶯鶰鶱鶲鶳鶴鶵鶶鶷鶸鶹鶺鶻鶼鶽鶾鶿 +鷀鷁鷂鷃鷄鷅鷆鷇鷈鷉鷊鷋鷌鷍鷎鷏鷐鷑鷒鷓鷔鷕鷖鷗鷘鷙鷚鷛鷜鷝鷞鷟 +鷠鷡鷢鷣鷤鷥鷦鷧鷨鷩鷪鷫鷬鷭鷮鷯鷰鷱鷲鷳鷴鷵鷶鷷鷸鷹鷺鷻鷼鷽鷾鷿 +鸀鸁鸂鸃鸄鸅鸆鸇鸈鸉鸊鸋鸌鸍鸎鸏鸐鸑鸒鸓鸔鸕鸖鸗鸘鸙鸚鸛鸜鸝鸞鸟 +鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿 +鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟 +鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹵鹶鹷鹸鹹鹺鹻鹼鹽鹾鹿 +麀麁麂麃麄麅麆麇麈麉麊麋麌麍麎麏麐麑麒麓麔麕麖麗麘麙麚麛麜麝麞麟 +麠麡麢麣麤麥麦麧麨麩麪麫麬麭麮麯麰麱麲麳麴麵麶麷麸麹麺麻麼麽麾麿 +黀黁黂黃黄黅黆黇黈黉黊黋黌黍黎黏黐黑黒黓黔黕黖黗默黙黚黛黜黝點黟 +黠黡黢黣黤黥黦黧黨黩黪黫黬黭黮黯黰黱黲黳黴黵黶黷黸黹黺黻黼黽黾黿 +鼀鼁鼂鼃鼄鼅鼆鼇鼈鼉鼊鼋鼌鼍鼎鼏鼐鼑鼒鼓鼔鼕鼖鼗鼘鼙鼚鼛鼜鼝鼞鼟 +鼠鼡鼢鼣鼤鼥鼦鼧鼨鼩鼪鼫鼬鼭鼮鼯鼰鼱鼲鼳鼴鼵鼶鼷鼸鼹鼺鼻鼼鼽鼾鼿 +齀齁齂齃齄齅齆齇齈齉齊齋齌齍齎齏齐齑齒齓齔齕齖齗齘齙齚齛齜齝齞齟 +齠齡齢齣齤齥齦齧齨齩齪齫齬齭齮齯齰齱齲齳齴齵齶齷齸齹齺齻齼齽齾齿 +龀龁龂龃龄龅龆龇龈龉龊龋龌龍龎龏龐龑龒龓龔龕龖龗龘龙龚龛龜龝龞龟 +龠龡龢龣龤龥龦龧龨龩龪龫龬龭龮龯龰龱龲龳龴龵龶龷龸龹龺龻龼龽龾龿 +鿀鿁鿂鿃鿄鿅鿆鿇鿈鿉鿊鿋鿌鿍鿎鿏鿐鿑鿒鿓鿔鿕鿖鿗鿘鿙鿚鿛鿜鿝鿞鿟 +鿠鿡鿢鿣鿤鿥鿦鿧鿨鿩鿪鿫鿬鿭鿮鿯鿰鿱鿲鿳鿴鿵鿶鿷鿸鿹鿺鿻鿼鿽鿾鿿 + +Yi Syllables (U+A000-U+A48F): + +ꀀꀁꀂꀃꀄꀅꀆꀇꀈꀉꀊꀋꀌꀍꀎꀏꀐꀑꀒꀓꀔꀕꀖꀗꀘꀙꀚꀛꀜꀝꀞꀟ +ꀠꀡꀢꀣꀤꀥꀦꀧꀨꀩꀪꀫꀬꀭꀮꀯꀰꀱꀲꀳꀴꀵꀶꀷꀸꀹꀺꀻꀼꀽꀾꀿ +ꁀꁁꁂꁃꁄꁅꁆꁇꁈꁉꁊꁋꁌꁍꁎꁏꁐꁑꁒꁓꁔꁕꁖꁗꁘꁙꁚꁛꁜꁝꁞꁟ +ꁠꁡꁢꁣꁤꁥꁦꁧꁨꁩꁪꁫꁬꁭꁮꁯꁰꁱꁲꁳꁴꁵꁶꁷꁸꁹꁺꁻꁼꁽꁾꁿ +ꂀꂁꂂꂃꂄꂅꂆꂇꂈꂉꂊꂋꂌꂍꂎꂏꂐꂑꂒꂓꂔꂕꂖꂗꂘꂙꂚꂛꂜꂝꂞꂟ +ꂠꂡꂢꂣꂤꂥꂦꂧꂨꂩꂪꂫꂬꂭꂮꂯꂰꂱꂲꂳꂴꂵꂶꂷꂸꂹꂺꂻꂼꂽꂾꂿ +ꃀꃁꃂꃃꃄꃅꃆꃇꃈꃉꃊꃋꃌꃍꃎꃏꃐꃑꃒꃓꃔꃕꃖꃗꃘꃙꃚꃛꃜꃝꃞꃟ +ꃠꃡꃢꃣꃤꃥꃦꃧꃨꃩꃪꃫꃬꃭꃮꃯꃰꃱꃲꃳꃴꃵꃶꃷꃸꃹꃺꃻꃼꃽꃾꃿ +ꄀꄁꄂꄃꄄꄅꄆꄇꄈꄉꄊꄋꄌꄍꄎꄏꄐꄑꄒꄓꄔꄕꄖꄗꄘꄙꄚꄛꄜꄝꄞꄟ +ꄠꄡꄢꄣꄤꄥꄦꄧꄨꄩꄪꄫꄬꄭꄮꄯꄰꄱꄲꄳꄴꄵꄶꄷꄸꄹꄺꄻꄼꄽꄾꄿ +ꅀꅁꅂꅃꅄꅅꅆꅇꅈꅉꅊꅋꅌꅍꅎꅏꅐꅑꅒꅓꅔꅕꅖꅗꅘꅙꅚꅛꅜꅝꅞꅟ +ꅠꅡꅢꅣꅤꅥꅦꅧꅨꅩꅪꅫꅬꅭꅮꅯꅰꅱꅲꅳꅴꅵꅶꅷꅸꅹꅺꅻꅼꅽꅾꅿ +ꆀꆁꆂꆃꆄꆅꆆꆇꆈꆉꆊꆋꆌꆍꆎꆏꆐꆑꆒꆓꆔꆕꆖꆗꆘꆙꆚꆛꆜꆝꆞꆟ +ꆠꆡꆢꆣꆤꆥꆦꆧꆨꆩꆪꆫꆬꆭꆮꆯꆰꆱꆲꆳꆴꆵꆶꆷꆸꆹꆺꆻꆼꆽꆾꆿ +ꇀꇁꇂꇃꇄꇅꇆꇇꇈꇉꇊꇋꇌꇍꇎꇏꇐꇑꇒꇓꇔꇕꇖꇗꇘꇙꇚꇛꇜꇝꇞꇟ +ꇠꇡꇢꇣꇤꇥꇦꇧꇨꇩꇪꇫꇬꇭꇮꇯꇰꇱꇲꇳꇴꇵꇶꇷꇸꇹꇺꇻꇼꇽꇾꇿ +ꈀꈁꈂꈃꈄꈅꈆꈇꈈꈉꈊꈋꈌꈍꈎꈏꈐꈑꈒꈓꈔꈕꈖꈗꈘꈙꈚꈛꈜꈝꈞꈟ +ꈠꈡꈢꈣꈤꈥꈦꈧꈨꈩꈪꈫꈬꈭꈮꈯꈰꈱꈲꈳꈴꈵꈶꈷꈸꈹꈺꈻꈼꈽꈾꈿ +ꉀꉁꉂꉃꉄꉅꉆꉇꉈꉉꉊꉋꉌꉍꉎꉏꉐꉑꉒꉓꉔꉕꉖꉗꉘꉙꉚꉛꉜꉝꉞꉟ +ꉠꉡꉢꉣꉤꉥꉦꉧꉨꉩꉪꉫꉬꉭꉮꉯꉰꉱꉲꉳꉴꉵꉶꉷꉸꉹꉺꉻꉼꉽꉾꉿ +ꊀꊁꊂꊃꊄꊅꊆꊇꊈꊉꊊꊋꊌꊍꊎꊏꊐꊑꊒꊓꊔꊕꊖꊗꊘꊙꊚꊛꊜꊝꊞꊟ +ꊠꊡꊢꊣꊤꊥꊦꊧꊨꊩꊪꊫꊬꊭꊮꊯꊰꊱꊲꊳꊴꊵꊶꊷꊸꊹꊺꊻꊼꊽꊾꊿ +ꋀꋁꋂꋃꋄꋅꋆꋇꋈꋉꋊꋋꋌꋍꋎꋏꋐꋑꋒꋓꋔꋕꋖꋗꋘꋙꋚꋛꋜꋝꋞꋟ +ꋠꋡꋢꋣꋤꋥꋦꋧꋨꋩꋪꋫꋬꋭꋮꋯꋰꋱꋲꋳꋴꋵꋶꋷꋸꋹꋺꋻꋼꋽꋾꋿ +ꌀꌁꌂꌃꌄꌅꌆꌇꌈꌉꌊꌋꌌꌍꌎꌏꌐꌑꌒꌓꌔꌕꌖꌗꌘꌙꌚꌛꌜꌝꌞꌟ +ꌠꌡꌢꌣꌤꌥꌦꌧꌨꌩꌪꌫꌬꌭꌮꌯꌰꌱꌲꌳꌴꌵꌶꌷꌸꌹꌺꌻꌼꌽꌾꌿ +ꍀꍁꍂꍃꍄꍅꍆꍇꍈꍉꍊꍋꍌꍍꍎꍏꍐꍑꍒꍓꍔꍕꍖꍗꍘꍙꍚꍛꍜꍝꍞꍟ +ꍠꍡꍢꍣꍤꍥꍦꍧꍨꍩꍪꍫꍬꍭꍮꍯꍰꍱꍲꍳꍴꍵꍶꍷꍸꍹꍺꍻꍼꍽꍾꍿ +ꎀꎁꎂꎃꎄꎅꎆꎇꎈꎉꎊꎋꎌꎍꎎꎏꎐꎑꎒꎓꎔꎕꎖꎗꎘꎙꎚꎛꎜꎝꎞꎟ +ꎠꎡꎢꎣꎤꎥꎦꎧꎨꎩꎪꎫꎬꎭꎮꎯꎰꎱꎲꎳꎴꎵꎶꎷꎸꎹꎺꎻꎼꎽꎾꎿ +ꏀꏁꏂꏃꏄꏅꏆꏇꏈꏉꏊꏋꏌꏍꏎꏏꏐꏑꏒꏓꏔꏕꏖꏗꏘꏙꏚꏛꏜꏝꏞꏟ +ꏠꏡꏢꏣꏤꏥꏦꏧꏨꏩꏪꏫꏬꏭꏮꏯꏰꏱꏲꏳꏴꏵꏶꏷꏸꏹꏺꏻꏼꏽꏾꏿ +ꐀꐁꐂꐃꐄꐅꐆꐇꐈꐉꐊꐋꐌꐍꐎꐏꐐꐑꐒꐓꐔꐕꐖꐗꐘꐙꐚꐛꐜꐝꐞꐟ +ꐠꐡꐢꐣꐤꐥꐦꐧꐨꐩꐪꐫꐬꐭꐮꐯꐰꐱꐲꐳꐴꐵꐶꐷꐸꐹꐺꐻꐼꐽꐾꐿ +ꑀꑁꑂꑃꑄꑅꑆꑇꑈꑉꑊꑋꑌꑍꑎꑏꑐꑑꑒꑓꑔꑕꑖꑗꑘꑙꑚꑛꑜꑝꑞꑟ +ꑠꑡꑢꑣꑤꑥꑦꑧꑨꑩꑪꑫꑬꑭꑮꑯꑰꑱꑲꑳꑴꑵꑶꑷꑸꑹꑺꑻꑼꑽꑾꑿ +ꒀꒁꒂꒃꒄꒅꒆꒇꒈꒉꒊꒋꒌ + +Yi Radicals (U+A490-U+A4CF): + +꒐꒑꒒꒓꒔꒕꒖꒗꒘꒙꒚꒛꒜꒝꒞꒟꒠꒡꒢꒣꒤꒥꒦꒧꒨꒩꒪꒫꒬꒭꒮꒯ +꒰꒱꒲꒳꒴꒵꒶꒷꒸꒹꒺꒻꒼꒽꒾꒿꓀꓁꓂꓃꓄꓅꓆ + +Free block (U+A4D0-U+ABFF): + +ꓐꓑꓒꓓꓔꓕꓖꓗꓘꓙꓚꓛꓜꓝꓞꓟꓠꓡꓢꓣꓤꓥꓦꓧꓨꓩꓪꓫꓬꓭꓮꓯꓰꓱꓲꓳꓴꓵꓶꓷꓸꓹꓺꓻꓼꓽ꓾꓿ꔀꔁꔂꔃꔄꔅꔆꔇꔈꔉꔊꔋꔌꔍꔎꔏ +ꔐꔑꔒꔓꔔꔕꔖꔗꔘꔙꔚꔛꔜꔝꔞꔟꔠꔡꔢꔣꔤꔥꔦꔧꔨꔩꔪꔫꔬꔭꔮꔯꔰꔱꔲꔳꔴꔵꔶꔷꔸꔹꔺꔻꔼꔽꔾꔿꕀꕁꕂꕃꕄꕅꕆꕇꕈꕉꕊꕋꕌꕍꕎꕏ +ꕐꕑꕒꕓꕔꕕꕖꕗꕘꕙꕚꕛꕜꕝꕞꕟꕠꕡꕢꕣꕤꕥꕦꕧꕨꕩꕪꕫꕬꕭꕮꕯꕰꕱꕲꕳꕴꕵꕶꕷꕸꕹꕺꕻꕼꕽꕾꕿꖀꖁꖂꖃꖄꖅꖆꖇꖈꖉꖊꖋꖌꖍꖎꖏ +ꖐꖑꖒꖓꖔꖕꖖꖗꖘꖙꖚꖛꖜꖝꖞꖟꖠꖡꖢꖣꖤꖥꖦꖧꖨꖩꖪꖫꖬꖭꖮꖯꖰꖱꖲꖳꖴꖵꖶꖷꖸꖹꖺꖻꖼꖽꖾꖿꗀꗁꗂꗃꗄꗅꗆꗇꗈꗉꗊꗋꗌꗍꗎꗏ +ꗐꗑꗒꗓꗔꗕꗖꗗꗘꗙꗚꗛꗜꗝꗞꗟꗠꗡꗢꗣꗤꗥꗦꗧꗨꗩꗪꗫꗬꗭꗮꗯꗰꗱꗲꗳꗴꗵꗶꗷꗸꗹꗺꗻꗼꗽꗾꗿꘀꘁꘂꘃꘄꘅꘆꘇꘈꘉꘊꘋꘌ꘍꘎꘏ +ꘐꘑꘒꘓꘔꘕꘖꘗꘘꘙꘚꘛꘜꘝꘞꘟ꘠꘡꘢꘣꘤꘥꘦꘧꘨꘩ꘪꘫꙀꙁꙂꙃꙄꙅꙆꙇꙈꙉꙊꙋꙌꙍꙎꙏ +ꙐꙑꙒꙓꙔꙕꙖꙗꙘꙙꙚꙛꙜꙝꙞꙟꙠꙡꙢꙣꙤꙥꙦꙧꙨꙩꙪꙫꙬꙭꙮ꙯꙰꙱꙲꙳ꙴꙵꙶꙷꙸꙹꙺꙻ꙼꙽꙾ꙿꚀꚁꚂꚃꚄꚅꚆꚇꚈꚉꚊꚋꚌꚍꚎꚏ +ꚐꚑꚒꚓꚔꚕꚖꚗꚘꚙꚚꚛꚜꚝꚞꚟꚠꚡꚢꚣꚤꚥꚦꚧꚨꚩꚪꚫꚬꚭꚮꚯꚰꚱꚲꚳꚴꚵꚶꚷꚸꚹꚺꚻꚼꚽꚾꚿꛀꛁꛂꛃꛄꛅꛆꛇꛈꛉꛊꛋꛌꛍꛎꛏ +ꛐꛑꛒꛓꛔꛕꛖꛗꛘꛙꛚꛛꛜꛝꛞꛟꛠꛡꛢꛣꛤꛥꛦꛧꛨꛩꛪꛫꛬꛭꛮꛯ꛰꛱꛲꛳꛴꛵꛶꛷꜀꜁꜂꜃꜄꜅꜆꜇꜈꜉꜊꜋꜌꜍꜎꜏ +꜐꜑꜒꜓꜔꜕꜖ꜗꜘꜙꜚꜛꜜꜝꜞꜟ꜠꜡ꜢꜣꜤꜥꜦꜧꜨꜩꜪꜫꜬꜭꜮꜯꜰꜱꜲꜳꜴꜵꜶꜷꜸꜹꜺꜻꜼꜽꜾꜿꝀꝁꝂꝃꝄꝅꝆꝇꝈꝉꝊꝋꝌꝍꝎꝏ +ꝐꝑꝒꝓꝔꝕꝖꝗꝘꝙꝚꝛꝜꝝꝞꝟꝠꝡꝢꝣꝤꝥꝦꝧꝨꝩꝪꝫꝬꝭꝮꝯꝰꝱꝲꝳꝴꝵꝶꝷꝸꝹꝺꝻꝼꝽꝾꝿꞀꞁꞂꞃꞄꞅꞆꞇꞈ꞉꞊ꞋꞌꞍꞎꞏ +ꞐꞑꞒꞓꞔꞕꞖꞗꞘꞙꞚꞛꞜꞝꞞꞟꞠꞡꞢꞣꞤꞥꞦꞧꞨꞩꞪꞫꞬꞭꞮꞯꞰꞱꞲꞳꞴꞵꞶꞷꞸꞹꞺꞻꞼꞽꞾꞿꟀꟁꟂꟃꟄꟅꟆꟇꟈꟉꟊ +ꟐꟑꟓꟕꟖꟗꟘꟙꟲꟳꟴꟵꟶꟷꟸꟹꟺꟻꟼꟽꟾꟿꠀꠁꠂꠃꠄꠅ꠆ꠇꠈꠉꠊꠋꠌꠍꠎꠏ +ꠐꠑꠒꠓꠔꠕꠖꠗꠘꠙꠚꠛꠜꠝꠞꠟꠠꠡꠢꠣꠤꠥꠦꠧ꠨꠩꠪꠫꠬꠰꠱꠲꠳꠴꠵꠶꠷꠸꠹ꡀꡁꡂꡃꡄꡅꡆꡇꡈꡉꡊꡋꡌꡍꡎꡏ +ꡐꡑꡒꡓꡔꡕꡖꡗꡘꡙꡚꡛꡜꡝꡞꡟꡠꡡꡢꡣꡤꡥꡦꡧꡨꡩꡪꡫꡬꡭꡮꡯꡰꡱꡲꡳ꡴꡵꡶꡷ꢀꢁꢂꢃꢄꢅꢆꢇꢈꢉꢊꢋꢌꢍꢎꢏ +ꢐꢑꢒꢓꢔꢕꢖꢗꢘꢙꢚꢛꢜꢝꢞꢟꢠꢡꢢꢣꢤꢥꢦꢧꢨꢩꢪꢫꢬꢭꢮꢯꢰꢱꢲꢳꢴꢵꢶꢷꢸꢹꢺꢻꢼꢽꢾꢿꣀꣁꣂꣃ꣄ꣅ꣎꣏ +꣐꣑꣒꣓꣔꣕꣖꣗꣘꣙꣠꣡꣢꣣꣤꣥꣦꣧꣨꣩꣪꣫꣬꣭꣮꣯꣰꣱ꣲꣳꣴꣵꣶꣷ꣸꣹꣺ꣻ꣼ꣽꣾꣿ꤀꤁꤂꤃꤄꤅꤆꤇꤈꤉ꤊꤋꤌꤍꤎꤏ +ꤐꤑꤒꤓꤔꤕꤖꤗꤘꤙꤚꤛꤜꤝꤞꤟꤠꤡꤢꤣꤤꤥꤦꤧꤨꤩꤪ꤫꤬꤭꤮꤯ꤰꤱꤲꤳꤴꤵꤶꤷꤸꤹꤺꤻꤼꤽꤾꤿꥀꥁꥂꥃꥄꥅꥆꥇꥈꥉꥊꥋꥌꥍꥎꥏ +ꥐꥑꥒ꥓꥟ꥠꥡꥢꥣꥤꥥꥦꥧꥨꥩꥪꥫꥬꥭꥮꥯꥰꥱꥲꥳꥴꥵꥶꥷꥸꥹꥺꥻꥼꦀꦁꦂꦃꦄꦅꦆꦇꦈꦉꦊꦋꦌꦍꦎꦏ +ꦐꦑꦒꦓꦔꦕꦖꦗꦘꦙꦚꦛꦜꦝꦞꦟꦠꦡꦢꦣꦤꦥꦦꦧꦨꦩꦪꦫꦬꦭꦮꦯꦰꦱꦲ꦳ꦴꦵꦶꦷꦸꦹꦺꦻꦼꦽꦾꦿ꧀꧁꧂꧃꧄꧅꧆꧇꧈꧉꧊꧋꧌꧍ꧏ +꧐꧑꧒꧓꧔꧕꧖꧗꧘꧙꧞꧟ꧠꧡꧢꧣꧤꧥꧦꧧꧨꧩꧪꧫꧬꧭꧮꧯ꧰꧱꧲꧳꧴꧵꧶꧷꧸꧹ꧺꧻꧼꧽꧾꨀꨁꨂꨃꨄꨅꨆꨇꨈꨉꨊꨋꨌꨍꨎꨏ +ꨐꨑꨒꨓꨔꨕꨖꨗꨘꨙꨚꨛꨜꨝꨞꨟꨠꨡꨢꨣꨤꨥꨦꨧꨨꨩꨪꨫꨬꨭꨮꨯꨰꨱꨲꨳꨴꨵꨶꩀꩁꩂꩃꩄꩅꩆꩇꩈꩉꩊꩋꩌꩍ +꩐꩑꩒꩓꩔꩕꩖꩗꩘꩙꩜꩝꩞꩟ꩠꩡꩢꩣꩤꩥꩦꩧꩨꩩꩪꩫꩬꩭꩮꩯꩰꩱꩲꩳꩴꩵꩶ꩷꩸꩹ꩺꩻꩼꩽꩾꩿꪀꪁꪂꪃꪄꪅꪆꪇꪈꪉꪊꪋꪌꪍꪎꪏ +ꪐꪑꪒꪓꪔꪕꪖꪗꪘꪙꪚꪛꪜꪝꪞꪟꪠꪡꪢꪣꪤꪥꪦꪧꪨꪩꪪꪫꪬꪭꪮꪯꪰꪱꪴꪲꪳꪵꪶꪷꪸꪹꪺꪻꪼꪽꪾ꪿ꫀ꫁ꫂ +ꫛꫜꫝ꫞꫟ꫠꫡꫢꫣꫤꫥꫦꫧꫨꫩꫪꫫꫬꫭꫮꫯ꫰꫱ꫲꫳꫴꫵ꫶ꬁꬂꬃꬄꬅꬆꬉꬊꬋꬌꬍꬎ +ꬑꬒꬓꬔꬕꬖꬠꬡꬢꬣꬤꬥꬦꬨꬩꬪꬫꬬꬭꬮꬰꬱꬲꬳꬴꬵꬶꬷꬸꬹꬺꬻꬼꬽꬾꬿꭀꭁꭂꭃꭄꭅꭆꭇꭈꭉꭊꭋꭌꭍꭎꭏ +ꭐꭑꭒꭓꭔꭕꭖꭗꭘꭙꭚ꭛ꭜꭝꭞꭟꭠꭡꭢꭣꭤꭥꭦꭧꭨꭩ꭪꭫ꭰꭱꭲꭳꭴꭵꭶꭷꭸꭹꭺꭻꭼꭽꭾꭿꮀꮁꮂꮃꮄꮅꮆꮇꮈꮉꮊꮋꮌꮍꮎꮏ +ꮐꮑꮒꮓꮔꮕꮖꮗꮘꮙꮚꮛꮜꮝꮞꮟꮠꮡꮢꮣꮤꮥꮦꮧꮨꮩꮪꮫꮬꮭꮮꮯꮰꮱꮲꮳꮴꮵꮶꮷꮸꮹꮺꮻꮼꮽꮾꮿꯀꯁꯂꯃꯄꯅꯆꯇꯈꯉꯊꯋꯌꯍꯎꯏ +ꯐꯑꯒꯓꯔꯕꯖꯗꯘꯙꯚꯛꯜꯝꯞꯟꯠꯡꯢꯣꯤꯥꯦꯧꯨꯩꯪ꯫꯬꯭꯰꯱꯲꯳꯴꯵꯶꯷꯸꯹ + +Hangul Syllables (U+AC00-U+D7A3): + +가각갂갃간갅갆갇갈갉갊갋갌갍갎갏감갑값갓갔강갖갗갘같갚갛개객갞갟 +갠갡갢갣갤갥갦갧갨갩갪갫갬갭갮갯갰갱갲갳갴갵갶갷갸갹갺갻갼갽갾갿 +걀걁걂걃걄걅걆걇걈걉걊걋걌걍걎걏걐걑걒걓걔걕걖걗걘걙걚걛걜걝걞걟 +걠걡걢걣걤걥걦걧걨걩걪걫걬걭걮걯거걱걲걳건걵걶걷걸걹걺걻걼걽걾걿 +검겁겂것겄겅겆겇겈겉겊겋게겍겎겏겐겑겒겓겔겕겖겗겘겙겚겛겜겝겞겟 +겠겡겢겣겤겥겦겧겨격겪겫견겭겮겯결겱겲겳겴겵겶겷겸겹겺겻겼경겾겿 +곀곁곂곃계곅곆곇곈곉곊곋곌곍곎곏곐곑곒곓곔곕곖곗곘곙곚곛곜곝곞곟 +고곡곢곣곤곥곦곧골곩곪곫곬곭곮곯곰곱곲곳곴공곶곷곸곹곺곻과곽곾곿 +관괁괂괃괄괅괆괇괈괉괊괋괌괍괎괏괐광괒괓괔괕괖괗괘괙괚괛괜괝괞괟 +괠괡괢괣괤괥괦괧괨괩괪괫괬괭괮괯괰괱괲괳괴괵괶괷괸괹괺괻괼괽괾괿 +굀굁굂굃굄굅굆굇굈굉굊굋굌굍굎굏교굑굒굓굔굕굖굗굘굙굚굛굜굝굞굟 +굠굡굢굣굤굥굦굧굨굩굪굫구국굮굯군굱굲굳굴굵굶굷굸굹굺굻굼굽굾굿 +궀궁궂궃궄궅궆궇궈궉궊궋권궍궎궏궐궑궒궓궔궕궖궗궘궙궚궛궜궝궞궟 +궠궡궢궣궤궥궦궧궨궩궪궫궬궭궮궯궰궱궲궳궴궵궶궷궸궹궺궻궼궽궾궿 +귀귁귂귃귄귅귆귇귈귉귊귋귌귍귎귏귐귑귒귓귔귕귖귗귘귙귚귛규귝귞귟 +균귡귢귣귤귥귦귧귨귩귪귫귬귭귮귯귰귱귲귳귴귵귶귷그극귺귻근귽귾귿 +글긁긂긃긄긅긆긇금급긊긋긌긍긎긏긐긑긒긓긔긕긖긗긘긙긚긛긜긝긞긟 +긠긡긢긣긤긥긦긧긨긩긪긫긬긭긮긯기긱긲긳긴긵긶긷길긹긺긻긼긽긾긿 +김깁깂깃깄깅깆깇깈깉깊깋까깍깎깏깐깑깒깓깔깕깖깗깘깙깚깛깜깝깞깟 +깠깡깢깣깤깥깦깧깨깩깪깫깬깭깮깯깰깱깲깳깴깵깶깷깸깹깺깻깼깽깾깿 +꺀꺁꺂꺃꺄꺅꺆꺇꺈꺉꺊꺋꺌꺍꺎꺏꺐꺑꺒꺓꺔꺕꺖꺗꺘꺙꺚꺛꺜꺝꺞꺟 +꺠꺡꺢꺣꺤꺥꺦꺧꺨꺩꺪꺫꺬꺭꺮꺯꺰꺱꺲꺳꺴꺵꺶꺷꺸꺹꺺꺻꺼꺽꺾꺿 +껀껁껂껃껄껅껆껇껈껉껊껋껌껍껎껏껐껑껒껓껔껕껖껗께껙껚껛껜껝껞껟 +껠껡껢껣껤껥껦껧껨껩껪껫껬껭껮껯껰껱껲껳껴껵껶껷껸껹껺껻껼껽껾껿 +꼀꼁꼂꼃꼄꼅꼆꼇꼈꼉꼊꼋꼌꼍꼎꼏꼐꼑꼒꼓꼔꼕꼖꼗꼘꼙꼚꼛꼜꼝꼞꼟 +꼠꼡꼢꼣꼤꼥꼦꼧꼨꼩꼪꼫꼬꼭꼮꼯꼰꼱꼲꼳꼴꼵꼶꼷꼸꼹꼺꼻꼼꼽꼾꼿 +꽀꽁꽂꽃꽄꽅꽆꽇꽈꽉꽊꽋꽌꽍꽎꽏꽐꽑꽒꽓꽔꽕꽖꽗꽘꽙꽚꽛꽜꽝꽞꽟 +꽠꽡꽢꽣꽤꽥꽦꽧꽨꽩꽪꽫꽬꽭꽮꽯꽰꽱꽲꽳꽴꽵꽶꽷꽸꽹꽺꽻꽼꽽꽾꽿 +꾀꾁꾂꾃꾄꾅꾆꾇꾈꾉꾊꾋꾌꾍꾎꾏꾐꾑꾒꾓꾔꾕꾖꾗꾘꾙꾚꾛꾜꾝꾞꾟 +꾠꾡꾢꾣꾤꾥꾦꾧꾨꾩꾪꾫꾬꾭꾮꾯꾰꾱꾲꾳꾴꾵꾶꾷꾸꾹꾺꾻꾼꾽꾾꾿 +꿀꿁꿂꿃꿄꿅꿆꿇꿈꿉꿊꿋꿌꿍꿎꿏꿐꿑꿒꿓꿔꿕꿖꿗꿘꿙꿚꿛꿜꿝꿞꿟 +꿠꿡꿢꿣꿤꿥꿦꿧꿨꿩꿪꿫꿬꿭꿮꿯꿰꿱꿲꿳꿴꿵꿶꿷꿸꿹꿺꿻꿼꿽꿾꿿 +뀀뀁뀂뀃뀄뀅뀆뀇뀈뀉뀊뀋뀌뀍뀎뀏뀐뀑뀒뀓뀔뀕뀖뀗뀘뀙뀚뀛뀜뀝뀞뀟 +뀠뀡뀢뀣뀤뀥뀦뀧뀨뀩뀪뀫뀬뀭뀮뀯뀰뀱뀲뀳뀴뀵뀶뀷뀸뀹뀺뀻뀼뀽뀾뀿 +끀끁끂끃끄끅끆끇끈끉끊끋끌끍끎끏끐끑끒끓끔끕끖끗끘끙끚끛끜끝끞끟 +끠끡끢끣끤끥끦끧끨끩끪끫끬끭끮끯끰끱끲끳끴끵끶끷끸끹끺끻끼끽끾끿 +낀낁낂낃낄낅낆낇낈낉낊낋낌낍낎낏낐낑낒낓낔낕낖낗나낙낚낛난낝낞낟 +날낡낢낣낤낥낦낧남납낪낫났낭낮낯낰낱낲낳내낵낶낷낸낹낺낻낼낽낾낿 +냀냁냂냃냄냅냆냇냈냉냊냋냌냍냎냏냐냑냒냓냔냕냖냗냘냙냚냛냜냝냞냟 +냠냡냢냣냤냥냦냧냨냩냪냫냬냭냮냯냰냱냲냳냴냵냶냷냸냹냺냻냼냽냾냿 +넀넁넂넃넄넅넆넇너넉넊넋넌넍넎넏널넑넒넓넔넕넖넗넘넙넚넛넜넝넞넟 +넠넡넢넣네넥넦넧넨넩넪넫넬넭넮넯넰넱넲넳넴넵넶넷넸넹넺넻넼넽넾넿 +녀녁녂녃년녅녆녇녈녉녊녋녌녍녎녏념녑녒녓녔녕녖녗녘녙녚녛녜녝녞녟 +녠녡녢녣녤녥녦녧녨녩녪녫녬녭녮녯녰녱녲녳녴녵녶녷노녹녺녻논녽녾녿 +놀놁놂놃놄놅놆놇놈놉놊놋놌농놎놏놐놑높놓놔놕놖놗놘놙놚놛놜놝놞놟 +놠놡놢놣놤놥놦놧놨놩놪놫놬놭놮놯놰놱놲놳놴놵놶놷놸놹놺놻놼놽놾놿 +뇀뇁뇂뇃뇄뇅뇆뇇뇈뇉뇊뇋뇌뇍뇎뇏뇐뇑뇒뇓뇔뇕뇖뇗뇘뇙뇚뇛뇜뇝뇞뇟 +뇠뇡뇢뇣뇤뇥뇦뇧뇨뇩뇪뇫뇬뇭뇮뇯뇰뇱뇲뇳뇴뇵뇶뇷뇸뇹뇺뇻뇼뇽뇾뇿 +눀눁눂눃누눅눆눇눈눉눊눋눌눍눎눏눐눑눒눓눔눕눖눗눘눙눚눛눜눝눞눟 +눠눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿 +뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟 +뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿 +늀늁늂늃늄늅늆늇늈늉늊늋늌늍늎늏느늑늒늓는늕늖늗늘늙늚늛늜늝늞늟 +늠늡늢늣늤능늦늧늨늩늪늫늬늭늮늯늰늱늲늳늴늵늶늷늸늹늺늻늼늽늾늿 +닀닁닂닃닄닅닆닇니닉닊닋닌닍닎닏닐닑닒닓닔닕닖닗님닙닚닛닜닝닞닟 +닠닡닢닣다닥닦닧단닩닪닫달닭닮닯닰닱닲닳담답닶닷닸당닺닻닼닽닾닿 +대댁댂댃댄댅댆댇댈댉댊댋댌댍댎댏댐댑댒댓댔댕댖댗댘댙댚댛댜댝댞댟 +댠댡댢댣댤댥댦댧댨댩댪댫댬댭댮댯댰댱댲댳댴댵댶댷댸댹댺댻댼댽댾댿 +덀덁덂덃덄덅덆덇덈덉덊덋덌덍덎덏덐덑덒덓더덕덖덗던덙덚덛덜덝덞덟 +덠덡덢덣덤덥덦덧덨덩덪덫덬덭덮덯데덱덲덳덴덵덶덷델덹덺덻덼덽덾덿 +뎀뎁뎂뎃뎄뎅뎆뎇뎈뎉뎊뎋뎌뎍뎎뎏뎐뎑뎒뎓뎔뎕뎖뎗뎘뎙뎚뎛뎜뎝뎞뎟 +뎠뎡뎢뎣뎤뎥뎦뎧뎨뎩뎪뎫뎬뎭뎮뎯뎰뎱뎲뎳뎴뎵뎶뎷뎸뎹뎺뎻뎼뎽뎾뎿 +돀돁돂돃도독돆돇돈돉돊돋돌돍돎돏돐돑돒돓돔돕돖돗돘동돚돛돜돝돞돟 +돠돡돢돣돤돥돦돧돨돩돪돫돬돭돮돯돰돱돲돳돴돵돶돷돸돹돺돻돼돽돾돿 +됀됁됂됃됄됅됆됇됈됉됊됋됌됍됎됏됐됑됒됓됔됕됖됗되됙됚됛된됝됞됟 +될됡됢됣됤됥됦됧됨됩됪됫됬됭됮됯됰됱됲됳됴됵됶됷됸됹됺됻됼됽됾됿 +둀둁둂둃둄둅둆둇둈둉둊둋둌둍둎둏두둑둒둓둔둕둖둗둘둙둚둛둜둝둞둟 +둠둡둢둣둤둥둦둧둨둩둪둫둬둭둮둯둰둱둲둳둴둵둶둷둸둹둺둻둼둽둾둿 +뒀뒁뒂뒃뒄뒅뒆뒇뒈뒉뒊뒋뒌뒍뒎뒏뒐뒑뒒뒓뒔뒕뒖뒗뒘뒙뒚뒛뒜뒝뒞뒟 +뒠뒡뒢뒣뒤뒥뒦뒧뒨뒩뒪뒫뒬뒭뒮뒯뒰뒱뒲뒳뒴뒵뒶뒷뒸뒹뒺뒻뒼뒽뒾뒿 +듀듁듂듃듄듅듆듇듈듉듊듋듌듍듎듏듐듑듒듓듔듕듖듗듘듙듚듛드득듞듟 +든듡듢듣들듥듦듧듨듩듪듫듬듭듮듯듰등듲듳듴듵듶듷듸듹듺듻듼듽듾듿 +딀딁딂딃딄딅딆딇딈딉딊딋딌딍딎딏딐딑딒딓디딕딖딗딘딙딚딛딜딝딞딟 +딠딡딢딣딤딥딦딧딨딩딪딫딬딭딮딯따딱딲딳딴딵딶딷딸딹딺딻딼딽딾딿 +땀땁땂땃땄땅땆땇땈땉땊땋때땍땎땏땐땑땒땓땔땕땖땗땘땙땚땛땜땝땞땟 +땠땡땢땣땤땥땦땧땨땩땪땫땬땭땮땯땰땱땲땳땴땵땶땷땸땹땺땻땼땽땾땿 +떀떁떂떃떄떅떆떇떈떉떊떋떌떍떎떏떐떑떒떓떔떕떖떗떘떙떚떛떜떝떞떟 +떠떡떢떣떤떥떦떧떨떩떪떫떬떭떮떯떰떱떲떳떴떵떶떷떸떹떺떻떼떽떾떿 +뗀뗁뗂뗃뗄뗅뗆뗇뗈뗉뗊뗋뗌뗍뗎뗏뗐뗑뗒뗓뗔뗕뗖뗗뗘뗙뗚뗛뗜뗝뗞뗟 +뗠뗡뗢뗣뗤뗥뗦뗧뗨뗩뗪뗫뗬뗭뗮뗯뗰뗱뗲뗳뗴뗵뗶뗷뗸뗹뗺뗻뗼뗽뗾뗿 +똀똁똂똃똄똅똆똇똈똉똊똋똌똍똎똏또똑똒똓똔똕똖똗똘똙똚똛똜똝똞똟 +똠똡똢똣똤똥똦똧똨똩똪똫똬똭똮똯똰똱똲똳똴똵똶똷똸똹똺똻똼똽똾똿 +뙀뙁뙂뙃뙄뙅뙆뙇뙈뙉뙊뙋뙌뙍뙎뙏뙐뙑뙒뙓뙔뙕뙖뙗뙘뙙뙚뙛뙜뙝뙞뙟 +뙠뙡뙢뙣뙤뙥뙦뙧뙨뙩뙪뙫뙬뙭뙮뙯뙰뙱뙲뙳뙴뙵뙶뙷뙸뙹뙺뙻뙼뙽뙾뙿 +뚀뚁뚂뚃뚄뚅뚆뚇뚈뚉뚊뚋뚌뚍뚎뚏뚐뚑뚒뚓뚔뚕뚖뚗뚘뚙뚚뚛뚜뚝뚞뚟 +뚠뚡뚢뚣뚤뚥뚦뚧뚨뚩뚪뚫뚬뚭뚮뚯뚰뚱뚲뚳뚴뚵뚶뚷뚸뚹뚺뚻뚼뚽뚾뚿 +뛀뛁뛂뛃뛄뛅뛆뛇뛈뛉뛊뛋뛌뛍뛎뛏뛐뛑뛒뛓뛔뛕뛖뛗뛘뛙뛚뛛뛜뛝뛞뛟 +뛠뛡뛢뛣뛤뛥뛦뛧뛨뛩뛪뛫뛬뛭뛮뛯뛰뛱뛲뛳뛴뛵뛶뛷뛸뛹뛺뛻뛼뛽뛾뛿 +뜀뜁뜂뜃뜄뜅뜆뜇뜈뜉뜊뜋뜌뜍뜎뜏뜐뜑뜒뜓뜔뜕뜖뜗뜘뜙뜚뜛뜜뜝뜞뜟 +뜠뜡뜢뜣뜤뜥뜦뜧뜨뜩뜪뜫뜬뜭뜮뜯뜰뜱뜲뜳뜴뜵뜶뜷뜸뜹뜺뜻뜼뜽뜾뜿 +띀띁띂띃띄띅띆띇띈띉띊띋띌띍띎띏띐띑띒띓띔띕띖띗띘띙띚띛띜띝띞띟 +띠띡띢띣띤띥띦띧띨띩띪띫띬띭띮띯띰띱띲띳띴띵띶띷띸띹띺띻라락띾띿 +란랁랂랃랄랅랆랇랈랉랊랋람랍랎랏랐랑랒랓랔랕랖랗래랙랚랛랜랝랞랟 +랠랡랢랣랤랥랦랧램랩랪랫랬랭랮랯랰랱랲랳랴략랶랷랸랹랺랻랼랽랾랿 +럀럁럂럃럄럅럆럇럈량럊럋럌럍럎럏럐럑럒럓럔럕럖럗럘럙럚럛럜럝럞럟 +럠럡럢럣럤럥럦럧럨럩럪럫러럭럮럯런럱럲럳럴럵럶럷럸럹럺럻럼럽럾럿 +렀렁렂렃렄렅렆렇레렉렊렋렌렍렎렏렐렑렒렓렔렕렖렗렘렙렚렛렜렝렞렟 +렠렡렢렣려력렦렧련렩렪렫렬렭렮렯렰렱렲렳렴렵렶렷렸령렺렻렼렽렾렿 +례롁롂롃롄롅롆롇롈롉롊롋롌롍롎롏롐롑롒롓롔롕롖롗롘롙롚롛로록롞롟 +론롡롢롣롤롥롦롧롨롩롪롫롬롭롮롯롰롱롲롳롴롵롶롷롸롹롺롻롼롽롾롿 +뢀뢁뢂뢃뢄뢅뢆뢇뢈뢉뢊뢋뢌뢍뢎뢏뢐뢑뢒뢓뢔뢕뢖뢗뢘뢙뢚뢛뢜뢝뢞뢟 +뢠뢡뢢뢣뢤뢥뢦뢧뢨뢩뢪뢫뢬뢭뢮뢯뢰뢱뢲뢳뢴뢵뢶뢷뢸뢹뢺뢻뢼뢽뢾뢿 +룀룁룂룃룄룅룆룇룈룉룊룋료룍룎룏룐룑룒룓룔룕룖룗룘룙룚룛룜룝룞룟 +룠룡룢룣룤룥룦룧루룩룪룫룬룭룮룯룰룱룲룳룴룵룶룷룸룹룺룻룼룽룾룿 +뤀뤁뤂뤃뤄뤅뤆뤇뤈뤉뤊뤋뤌뤍뤎뤏뤐뤑뤒뤓뤔뤕뤖뤗뤘뤙뤚뤛뤜뤝뤞뤟 +뤠뤡뤢뤣뤤뤥뤦뤧뤨뤩뤪뤫뤬뤭뤮뤯뤰뤱뤲뤳뤴뤵뤶뤷뤸뤹뤺뤻뤼뤽뤾뤿 +륀륁륂륃륄륅륆륇륈륉륊륋륌륍륎륏륐륑륒륓륔륕륖륗류륙륚륛륜륝륞륟 +률륡륢륣륤륥륦륧륨륩륪륫륬륭륮륯륰륱륲륳르륵륶륷른륹륺륻를륽륾륿 +릀릁릂릃름릅릆릇릈릉릊릋릌릍릎릏릐릑릒릓릔릕릖릗릘릙릚릛릜릝릞릟 +릠릡릢릣릤릥릦릧릨릩릪릫리릭릮릯린릱릲릳릴릵릶릷릸릹릺릻림립릾릿 +맀링맂맃맄맅맆맇마막맊맋만맍많맏말맑맒맓맔맕맖맗맘맙맚맛맜망맞맟 +맠맡맢맣매맥맦맧맨맩맪맫맬맭맮맯맰맱맲맳맴맵맶맷맸맹맺맻맼맽맾맿 +먀먁먂먃먄먅먆먇먈먉먊먋먌먍먎먏먐먑먒먓먔먕먖먗먘먙먚먛먜먝먞먟 +먠먡먢먣먤먥먦먧먨먩먪먫먬먭먮먯먰먱먲먳먴먵먶먷머먹먺먻먼먽먾먿 +멀멁멂멃멄멅멆멇멈멉멊멋멌멍멎멏멐멑멒멓메멕멖멗멘멙멚멛멜멝멞멟 +멠멡멢멣멤멥멦멧멨멩멪멫멬멭멮멯며멱멲멳면멵멶멷멸멹멺멻멼멽멾멿 +몀몁몂몃몄명몆몇몈몉몊몋몌몍몎몏몐몑몒몓몔몕몖몗몘몙몚몛몜몝몞몟 +몠몡몢몣몤몥몦몧모목몪몫몬몭몮몯몰몱몲몳몴몵몶몷몸몹몺못몼몽몾몿 +뫀뫁뫂뫃뫄뫅뫆뫇뫈뫉뫊뫋뫌뫍뫎뫏뫐뫑뫒뫓뫔뫕뫖뫗뫘뫙뫚뫛뫜뫝뫞뫟 +뫠뫡뫢뫣뫤뫥뫦뫧뫨뫩뫪뫫뫬뫭뫮뫯뫰뫱뫲뫳뫴뫵뫶뫷뫸뫹뫺뫻뫼뫽뫾뫿 +묀묁묂묃묄묅묆묇묈묉묊묋묌묍묎묏묐묑묒묓묔묕묖묗묘묙묚묛묜묝묞묟 +묠묡묢묣묤묥묦묧묨묩묪묫묬묭묮묯묰묱묲묳무묵묶묷문묹묺묻물묽묾묿 +뭀뭁뭂뭃뭄뭅뭆뭇뭈뭉뭊뭋뭌뭍뭎뭏뭐뭑뭒뭓뭔뭕뭖뭗뭘뭙뭚뭛뭜뭝뭞뭟 +뭠뭡뭢뭣뭤뭥뭦뭧뭨뭩뭪뭫뭬뭭뭮뭯뭰뭱뭲뭳뭴뭵뭶뭷뭸뭹뭺뭻뭼뭽뭾뭿 +뮀뮁뮂뮃뮄뮅뮆뮇뮈뮉뮊뮋뮌뮍뮎뮏뮐뮑뮒뮓뮔뮕뮖뮗뮘뮙뮚뮛뮜뮝뮞뮟 +뮠뮡뮢뮣뮤뮥뮦뮧뮨뮩뮪뮫뮬뮭뮮뮯뮰뮱뮲뮳뮴뮵뮶뮷뮸뮹뮺뮻뮼뮽뮾뮿 +므믁믂믃믄믅믆믇믈믉믊믋믌믍믎믏믐믑믒믓믔믕믖믗믘믙믚믛믜믝믞믟 +믠믡믢믣믤믥믦믧믨믩믪믫믬믭믮믯믰믱믲믳믴믵믶믷미믹믺믻민믽믾믿 +밀밁밂밃밄밅밆밇밈밉밊밋밌밍밎및밐밑밒밓바박밖밗반밙밚받발밝밞밟 +밠밡밢밣밤밥밦밧밨방밪밫밬밭밮밯배백밲밳밴밵밶밷밸밹밺밻밼밽밾밿 +뱀뱁뱂뱃뱄뱅뱆뱇뱈뱉뱊뱋뱌뱍뱎뱏뱐뱑뱒뱓뱔뱕뱖뱗뱘뱙뱚뱛뱜뱝뱞뱟 +뱠뱡뱢뱣뱤뱥뱦뱧뱨뱩뱪뱫뱬뱭뱮뱯뱰뱱뱲뱳뱴뱵뱶뱷뱸뱹뱺뱻뱼뱽뱾뱿 +벀벁벂벃버벅벆벇번벉벊벋벌벍벎벏벐벑벒벓범법벖벗벘벙벚벛벜벝벞벟 +베벡벢벣벤벥벦벧벨벩벪벫벬벭벮벯벰벱벲벳벴벵벶벷벸벹벺벻벼벽벾벿 +변볁볂볃별볅볆볇볈볉볊볋볌볍볎볏볐병볒볓볔볕볖볗볘볙볚볛볜볝볞볟 +볠볡볢볣볤볥볦볧볨볩볪볫볬볭볮볯볰볱볲볳보복볶볷본볹볺볻볼볽볾볿 +봀봁봂봃봄봅봆봇봈봉봊봋봌봍봎봏봐봑봒봓봔봕봖봗봘봙봚봛봜봝봞봟 +봠봡봢봣봤봥봦봧봨봩봪봫봬봭봮봯봰봱봲봳봴봵봶봷봸봹봺봻봼봽봾봿 +뵀뵁뵂뵃뵄뵅뵆뵇뵈뵉뵊뵋뵌뵍뵎뵏뵐뵑뵒뵓뵔뵕뵖뵗뵘뵙뵚뵛뵜뵝뵞뵟 +뵠뵡뵢뵣뵤뵥뵦뵧뵨뵩뵪뵫뵬뵭뵮뵯뵰뵱뵲뵳뵴뵵뵶뵷뵸뵹뵺뵻뵼뵽뵾뵿 +부북붂붃분붅붆붇불붉붊붋붌붍붎붏붐붑붒붓붔붕붖붗붘붙붚붛붜붝붞붟 +붠붡붢붣붤붥붦붧붨붩붪붫붬붭붮붯붰붱붲붳붴붵붶붷붸붹붺붻붼붽붾붿 +뷀뷁뷂뷃뷄뷅뷆뷇뷈뷉뷊뷋뷌뷍뷎뷏뷐뷑뷒뷓뷔뷕뷖뷗뷘뷙뷚뷛뷜뷝뷞뷟 +뷠뷡뷢뷣뷤뷥뷦뷧뷨뷩뷪뷫뷬뷭뷮뷯뷰뷱뷲뷳뷴뷵뷶뷷뷸뷹뷺뷻뷼뷽뷾뷿 +븀븁븂븃븄븅븆븇븈븉븊븋브븍븎븏븐븑븒븓블븕븖븗븘븙븚븛븜븝븞븟 +븠븡븢븣븤븥븦븧븨븩븪븫븬븭븮븯븰븱븲븳븴븵븶븷븸븹븺븻븼븽븾븿 +빀빁빂빃비빅빆빇빈빉빊빋빌빍빎빏빐빑빒빓빔빕빖빗빘빙빚빛빜빝빞빟 +빠빡빢빣빤빥빦빧빨빩빪빫빬빭빮빯빰빱빲빳빴빵빶빷빸빹빺빻빼빽빾빿 +뺀뺁뺂뺃뺄뺅뺆뺇뺈뺉뺊뺋뺌뺍뺎뺏뺐뺑뺒뺓뺔뺕뺖뺗뺘뺙뺚뺛뺜뺝뺞뺟 +뺠뺡뺢뺣뺤뺥뺦뺧뺨뺩뺪뺫뺬뺭뺮뺯뺰뺱뺲뺳뺴뺵뺶뺷뺸뺹뺺뺻뺼뺽뺾뺿 +뻀뻁뻂뻃뻄뻅뻆뻇뻈뻉뻊뻋뻌뻍뻎뻏뻐뻑뻒뻓뻔뻕뻖뻗뻘뻙뻚뻛뻜뻝뻞뻟 +뻠뻡뻢뻣뻤뻥뻦뻧뻨뻩뻪뻫뻬뻭뻮뻯뻰뻱뻲뻳뻴뻵뻶뻷뻸뻹뻺뻻뻼뻽뻾뻿 +뼀뼁뼂뼃뼄뼅뼆뼇뼈뼉뼊뼋뼌뼍뼎뼏뼐뼑뼒뼓뼔뼕뼖뼗뼘뼙뼚뼛뼜뼝뼞뼟 +뼠뼡뼢뼣뼤뼥뼦뼧뼨뼩뼪뼫뼬뼭뼮뼯뼰뼱뼲뼳뼴뼵뼶뼷뼸뼹뼺뼻뼼뼽뼾뼿 +뽀뽁뽂뽃뽄뽅뽆뽇뽈뽉뽊뽋뽌뽍뽎뽏뽐뽑뽒뽓뽔뽕뽖뽗뽘뽙뽚뽛뽜뽝뽞뽟 +뽠뽡뽢뽣뽤뽥뽦뽧뽨뽩뽪뽫뽬뽭뽮뽯뽰뽱뽲뽳뽴뽵뽶뽷뽸뽹뽺뽻뽼뽽뽾뽿 +뾀뾁뾂뾃뾄뾅뾆뾇뾈뾉뾊뾋뾌뾍뾎뾏뾐뾑뾒뾓뾔뾕뾖뾗뾘뾙뾚뾛뾜뾝뾞뾟 +뾠뾡뾢뾣뾤뾥뾦뾧뾨뾩뾪뾫뾬뾭뾮뾯뾰뾱뾲뾳뾴뾵뾶뾷뾸뾹뾺뾻뾼뾽뾾뾿 +뿀뿁뿂뿃뿄뿅뿆뿇뿈뿉뿊뿋뿌뿍뿎뿏뿐뿑뿒뿓뿔뿕뿖뿗뿘뿙뿚뿛뿜뿝뿞뿟 +뿠뿡뿢뿣뿤뿥뿦뿧뿨뿩뿪뿫뿬뿭뿮뿯뿰뿱뿲뿳뿴뿵뿶뿷뿸뿹뿺뿻뿼뿽뿾뿿 +쀀쀁쀂쀃쀄쀅쀆쀇쀈쀉쀊쀋쀌쀍쀎쀏쀐쀑쀒쀓쀔쀕쀖쀗쀘쀙쀚쀛쀜쀝쀞쀟 +쀠쀡쀢쀣쀤쀥쀦쀧쀨쀩쀪쀫쀬쀭쀮쀯쀰쀱쀲쀳쀴쀵쀶쀷쀸쀹쀺쀻쀼쀽쀾쀿 +쁀쁁쁂쁃쁄쁅쁆쁇쁈쁉쁊쁋쁌쁍쁎쁏쁐쁑쁒쁓쁔쁕쁖쁗쁘쁙쁚쁛쁜쁝쁞쁟 +쁠쁡쁢쁣쁤쁥쁦쁧쁨쁩쁪쁫쁬쁭쁮쁯쁰쁱쁲쁳쁴쁵쁶쁷쁸쁹쁺쁻쁼쁽쁾쁿 +삀삁삂삃삄삅삆삇삈삉삊삋삌삍삎삏삐삑삒삓삔삕삖삗삘삙삚삛삜삝삞삟 +삠삡삢삣삤삥삦삧삨삩삪삫사삭삮삯산삱삲삳살삵삶삷삸삹삺삻삼삽삾삿 +샀상샂샃샄샅샆샇새색샊샋샌샍샎샏샐샑샒샓샔샕샖샗샘샙샚샛샜생샞샟 +샠샡샢샣샤샥샦샧샨샩샪샫샬샭샮샯샰샱샲샳샴샵샶샷샸샹샺샻샼샽샾샿 +섀섁섂섃섄섅섆섇섈섉섊섋섌섍섎섏섐섑섒섓섔섕섖섗섘섙섚섛서석섞섟 +선섡섢섣설섥섦섧섨섩섪섫섬섭섮섯섰성섲섳섴섵섶섷세섹섺섻센섽섾섿 +셀셁셂셃셄셅셆셇셈셉셊셋셌셍셎셏셐셑셒셓셔셕셖셗션셙셚셛셜셝셞셟 +셠셡셢셣셤셥셦셧셨셩셪셫셬셭셮셯셰셱셲셳셴셵셶셷셸셹셺셻셼셽셾셿 +솀솁솂솃솄솅솆솇솈솉솊솋소속솎솏손솑솒솓솔솕솖솗솘솙솚솛솜솝솞솟 +솠송솢솣솤솥솦솧솨솩솪솫솬솭솮솯솰솱솲솳솴솵솶솷솸솹솺솻솼솽솾솿 +쇀쇁쇂쇃쇄쇅쇆쇇쇈쇉쇊쇋쇌쇍쇎쇏쇐쇑쇒쇓쇔쇕쇖쇗쇘쇙쇚쇛쇜쇝쇞쇟 +쇠쇡쇢쇣쇤쇥쇦쇧쇨쇩쇪쇫쇬쇭쇮쇯쇰쇱쇲쇳쇴쇵쇶쇷쇸쇹쇺쇻쇼쇽쇾쇿 +숀숁숂숃숄숅숆숇숈숉숊숋숌숍숎숏숐숑숒숓숔숕숖숗수숙숚숛순숝숞숟 +술숡숢숣숤숥숦숧숨숩숪숫숬숭숮숯숰숱숲숳숴숵숶숷숸숹숺숻숼숽숾숿 +쉀쉁쉂쉃쉄쉅쉆쉇쉈쉉쉊쉋쉌쉍쉎쉏쉐쉑쉒쉓쉔쉕쉖쉗쉘쉙쉚쉛쉜쉝쉞쉟 +쉠쉡쉢쉣쉤쉥쉦쉧쉨쉩쉪쉫쉬쉭쉮쉯쉰쉱쉲쉳쉴쉵쉶쉷쉸쉹쉺쉻쉼쉽쉾쉿 +슀슁슂슃슄슅슆슇슈슉슊슋슌슍슎슏슐슑슒슓슔슕슖슗슘슙슚슛슜슝슞슟 +슠슡슢슣스슥슦슧슨슩슪슫슬슭슮슯슰슱슲슳슴습슶슷슸승슺슻슼슽슾슿 +싀싁싂싃싄싅싆싇싈싉싊싋싌싍싎싏싐싑싒싓싔싕싖싗싘싙싚싛시식싞싟 +신싡싢싣실싥싦싧싨싩싪싫심십싮싯싰싱싲싳싴싵싶싷싸싹싺싻싼싽싾싿 +쌀쌁쌂쌃쌄쌅쌆쌇쌈쌉쌊쌋쌌쌍쌎쌏쌐쌑쌒쌓쌔쌕쌖쌗쌘쌙쌚쌛쌜쌝쌞쌟 +쌠쌡쌢쌣쌤쌥쌦쌧쌨쌩쌪쌫쌬쌭쌮쌯쌰쌱쌲쌳쌴쌵쌶쌷쌸쌹쌺쌻쌼쌽쌾쌿 +썀썁썂썃썄썅썆썇썈썉썊썋썌썍썎썏썐썑썒썓썔썕썖썗썘썙썚썛썜썝썞썟 +썠썡썢썣썤썥썦썧써썩썪썫썬썭썮썯썰썱썲썳썴썵썶썷썸썹썺썻썼썽썾썿 +쎀쎁쎂쎃쎄쎅쎆쎇쎈쎉쎊쎋쎌쎍쎎쎏쎐쎑쎒쎓쎔쎕쎖쎗쎘쎙쎚쎛쎜쎝쎞쎟 +쎠쎡쎢쎣쎤쎥쎦쎧쎨쎩쎪쎫쎬쎭쎮쎯쎰쎱쎲쎳쎴쎵쎶쎷쎸쎹쎺쎻쎼쎽쎾쎿 +쏀쏁쏂쏃쏄쏅쏆쏇쏈쏉쏊쏋쏌쏍쏎쏏쏐쏑쏒쏓쏔쏕쏖쏗쏘쏙쏚쏛쏜쏝쏞쏟 +쏠쏡쏢쏣쏤쏥쏦쏧쏨쏩쏪쏫쏬쏭쏮쏯쏰쏱쏲쏳쏴쏵쏶쏷쏸쏹쏺쏻쏼쏽쏾쏿 +쐀쐁쐂쐃쐄쐅쐆쐇쐈쐉쐊쐋쐌쐍쐎쐏쐐쐑쐒쐓쐔쐕쐖쐗쐘쐙쐚쐛쐜쐝쐞쐟 +쐠쐡쐢쐣쐤쐥쐦쐧쐨쐩쐪쐫쐬쐭쐮쐯쐰쐱쐲쐳쐴쐵쐶쐷쐸쐹쐺쐻쐼쐽쐾쐿 +쑀쑁쑂쑃쑄쑅쑆쑇쑈쑉쑊쑋쑌쑍쑎쑏쑐쑑쑒쑓쑔쑕쑖쑗쑘쑙쑚쑛쑜쑝쑞쑟 +쑠쑡쑢쑣쑤쑥쑦쑧쑨쑩쑪쑫쑬쑭쑮쑯쑰쑱쑲쑳쑴쑵쑶쑷쑸쑹쑺쑻쑼쑽쑾쑿 +쒀쒁쒂쒃쒄쒅쒆쒇쒈쒉쒊쒋쒌쒍쒎쒏쒐쒑쒒쒓쒔쒕쒖쒗쒘쒙쒚쒛쒜쒝쒞쒟 +쒠쒡쒢쒣쒤쒥쒦쒧쒨쒩쒪쒫쒬쒭쒮쒯쒰쒱쒲쒳쒴쒵쒶쒷쒸쒹쒺쒻쒼쒽쒾쒿 +쓀쓁쓂쓃쓄쓅쓆쓇쓈쓉쓊쓋쓌쓍쓎쓏쓐쓑쓒쓓쓔쓕쓖쓗쓘쓙쓚쓛쓜쓝쓞쓟 +쓠쓡쓢쓣쓤쓥쓦쓧쓨쓩쓪쓫쓬쓭쓮쓯쓰쓱쓲쓳쓴쓵쓶쓷쓸쓹쓺쓻쓼쓽쓾쓿 +씀씁씂씃씄씅씆씇씈씉씊씋씌씍씎씏씐씑씒씓씔씕씖씗씘씙씚씛씜씝씞씟 +씠씡씢씣씤씥씦씧씨씩씪씫씬씭씮씯씰씱씲씳씴씵씶씷씸씹씺씻씼씽씾씿 +앀앁앂앃아악앆앇안앉않앋알앍앎앏앐앑앒앓암압앖앗았앙앚앛앜앝앞앟 +애액앢앣앤앥앦앧앨앩앪앫앬앭앮앯앰앱앲앳앴앵앶앷앸앹앺앻야약앾앿 +얀얁얂얃얄얅얆얇얈얉얊얋얌얍얎얏얐양얒얓얔얕얖얗얘얙얚얛얜얝얞얟 +얠얡얢얣얤얥얦얧얨얩얪얫얬얭얮얯얰얱얲얳어억얶얷언얹얺얻얼얽얾얿 +엀엁엂엃엄업없엇었엉엊엋엌엍엎엏에엑엒엓엔엕엖엗엘엙엚엛엜엝엞엟 +엠엡엢엣엤엥엦엧엨엩엪엫여역엮엯연엱엲엳열엵엶엷엸엹엺엻염엽엾엿 +였영옂옃옄옅옆옇예옉옊옋옌옍옎옏옐옑옒옓옔옕옖옗옘옙옚옛옜옝옞옟 +옠옡옢옣오옥옦옧온옩옪옫올옭옮옯옰옱옲옳옴옵옶옷옸옹옺옻옼옽옾옿 +와왁왂왃완왅왆왇왈왉왊왋왌왍왎왏왐왑왒왓왔왕왖왗왘왙왚왛왜왝왞왟 +왠왡왢왣왤왥왦왧왨왩왪왫왬왭왮왯왰왱왲왳왴왵왶왷외왹왺왻왼왽왾왿 +욀욁욂욃욄욅욆욇욈욉욊욋욌욍욎욏욐욑욒욓요욕욖욗욘욙욚욛욜욝욞욟 +욠욡욢욣욤욥욦욧욨용욪욫욬욭욮욯우욱욲욳운욵욶욷울욹욺욻욼욽욾욿 +움웁웂웃웄웅웆웇웈웉웊웋워웍웎웏원웑웒웓월웕웖웗웘웙웚웛웜웝웞웟 +웠웡웢웣웤웥웦웧웨웩웪웫웬웭웮웯웰웱웲웳웴웵웶웷웸웹웺웻웼웽웾웿 +윀윁윂윃위윅윆윇윈윉윊윋윌윍윎윏윐윑윒윓윔윕윖윗윘윙윚윛윜윝윞윟 +유육윢윣윤윥윦윧율윩윪윫윬윭윮윯윰윱윲윳윴융윶윷윸윹윺윻으윽윾윿 +은읁읂읃을읅읆읇읈읉읊읋음읍읎읏읐응읒읓읔읕읖읗의읙읚읛읜읝읞읟 +읠읡읢읣읤읥읦읧읨읩읪읫읬읭읮읯읰읱읲읳이익읶읷인읹읺읻일읽읾읿 +잀잁잂잃임입잆잇있잉잊잋잌잍잎잏자작잒잓잔잕잖잗잘잙잚잛잜잝잞잟 +잠잡잢잣잤장잦잧잨잩잪잫재잭잮잯잰잱잲잳잴잵잶잷잸잹잺잻잼잽잾잿 +쟀쟁쟂쟃쟄쟅쟆쟇쟈쟉쟊쟋쟌쟍쟎쟏쟐쟑쟒쟓쟔쟕쟖쟗쟘쟙쟚쟛쟜쟝쟞쟟 +쟠쟡쟢쟣쟤쟥쟦쟧쟨쟩쟪쟫쟬쟭쟮쟯쟰쟱쟲쟳쟴쟵쟶쟷쟸쟹쟺쟻쟼쟽쟾쟿 +저적젂젃전젅젆젇절젉젊젋젌젍젎젏점접젒젓젔정젖젗젘젙젚젛제젝젞젟 +젠젡젢젣젤젥젦젧젨젩젪젫젬젭젮젯젰젱젲젳젴젵젶젷져젹젺젻젼젽젾젿 +졀졁졂졃졄졅졆졇졈졉졊졋졌졍졎졏졐졑졒졓졔졕졖졗졘졙졚졛졜졝졞졟 +졠졡졢졣졤졥졦졧졨졩졪졫졬졭졮졯조족졲졳존졵졶졷졸졹졺졻졼졽졾졿 +좀좁좂좃좄종좆좇좈좉좊좋좌좍좎좏좐좑좒좓좔좕좖좗좘좙좚좛좜좝좞좟 +좠좡좢좣좤좥좦좧좨좩좪좫좬좭좮좯좰좱좲좳좴좵좶좷좸좹좺좻좼좽좾좿 +죀죁죂죃죄죅죆죇죈죉죊죋죌죍죎죏죐죑죒죓죔죕죖죗죘죙죚죛죜죝죞죟 +죠죡죢죣죤죥죦죧죨죩죪죫죬죭죮죯죰죱죲죳죴죵죶죷죸죹죺죻주죽죾죿 +준줁줂줃줄줅줆줇줈줉줊줋줌줍줎줏줐중줒줓줔줕줖줗줘줙줚줛줜줝줞줟 +줠줡줢줣줤줥줦줧줨줩줪줫줬줭줮줯줰줱줲줳줴줵줶줷줸줹줺줻줼줽줾줿 +쥀쥁쥂쥃쥄쥅쥆쥇쥈쥉쥊쥋쥌쥍쥎쥏쥐쥑쥒쥓쥔쥕쥖쥗쥘쥙쥚쥛쥜쥝쥞쥟 +쥠쥡쥢쥣쥤쥥쥦쥧쥨쥩쥪쥫쥬쥭쥮쥯쥰쥱쥲쥳쥴쥵쥶쥷쥸쥹쥺쥻쥼쥽쥾쥿 +즀즁즂즃즄즅즆즇즈즉즊즋즌즍즎즏즐즑즒즓즔즕즖즗즘즙즚즛즜증즞즟 +즠즡즢즣즤즥즦즧즨즩즪즫즬즭즮즯즰즱즲즳즴즵즶즷즸즹즺즻즼즽즾즿 +지직짂짃진짅짆짇질짉짊짋짌짍짎짏짐집짒짓짔징짖짗짘짙짚짛짜짝짞짟 +짠짡짢짣짤짥짦짧짨짩짪짫짬짭짮짯짰짱짲짳짴짵짶짷째짹짺짻짼짽짾짿 +쨀쨁쨂쨃쨄쨅쨆쨇쨈쨉쨊쨋쨌쨍쨎쨏쨐쨑쨒쨓쨔쨕쨖쨗쨘쨙쨚쨛쨜쨝쨞쨟 +쨠쨡쨢쨣쨤쨥쨦쨧쨨쨩쨪쨫쨬쨭쨮쨯쨰쨱쨲쨳쨴쨵쨶쨷쨸쨹쨺쨻쨼쨽쨾쨿 +쩀쩁쩂쩃쩄쩅쩆쩇쩈쩉쩊쩋쩌쩍쩎쩏쩐쩑쩒쩓쩔쩕쩖쩗쩘쩙쩚쩛쩜쩝쩞쩟 +쩠쩡쩢쩣쩤쩥쩦쩧쩨쩩쩪쩫쩬쩭쩮쩯쩰쩱쩲쩳쩴쩵쩶쩷쩸쩹쩺쩻쩼쩽쩾쩿 +쪀쪁쪂쪃쪄쪅쪆쪇쪈쪉쪊쪋쪌쪍쪎쪏쪐쪑쪒쪓쪔쪕쪖쪗쪘쪙쪚쪛쪜쪝쪞쪟 +쪠쪡쪢쪣쪤쪥쪦쪧쪨쪩쪪쪫쪬쪭쪮쪯쪰쪱쪲쪳쪴쪵쪶쪷쪸쪹쪺쪻쪼쪽쪾쪿 +쫀쫁쫂쫃쫄쫅쫆쫇쫈쫉쫊쫋쫌쫍쫎쫏쫐쫑쫒쫓쫔쫕쫖쫗쫘쫙쫚쫛쫜쫝쫞쫟 +쫠쫡쫢쫣쫤쫥쫦쫧쫨쫩쫪쫫쫬쫭쫮쫯쫰쫱쫲쫳쫴쫵쫶쫷쫸쫹쫺쫻쫼쫽쫾쫿 +쬀쬁쬂쬃쬄쬅쬆쬇쬈쬉쬊쬋쬌쬍쬎쬏쬐쬑쬒쬓쬔쬕쬖쬗쬘쬙쬚쬛쬜쬝쬞쬟 +쬠쬡쬢쬣쬤쬥쬦쬧쬨쬩쬪쬫쬬쬭쬮쬯쬰쬱쬲쬳쬴쬵쬶쬷쬸쬹쬺쬻쬼쬽쬾쬿 +쭀쭁쭂쭃쭄쭅쭆쭇쭈쭉쭊쭋쭌쭍쭎쭏쭐쭑쭒쭓쭔쭕쭖쭗쭘쭙쭚쭛쭜쭝쭞쭟 +쭠쭡쭢쭣쭤쭥쭦쭧쭨쭩쭪쭫쭬쭭쭮쭯쭰쭱쭲쭳쭴쭵쭶쭷쭸쭹쭺쭻쭼쭽쭾쭿 +쮀쮁쮂쮃쮄쮅쮆쮇쮈쮉쮊쮋쮌쮍쮎쮏쮐쮑쮒쮓쮔쮕쮖쮗쮘쮙쮚쮛쮜쮝쮞쮟 +쮠쮡쮢쮣쮤쮥쮦쮧쮨쮩쮪쮫쮬쮭쮮쮯쮰쮱쮲쮳쮴쮵쮶쮷쮸쮹쮺쮻쮼쮽쮾쮿 +쯀쯁쯂쯃쯄쯅쯆쯇쯈쯉쯊쯋쯌쯍쯎쯏쯐쯑쯒쯓쯔쯕쯖쯗쯘쯙쯚쯛쯜쯝쯞쯟 +쯠쯡쯢쯣쯤쯥쯦쯧쯨쯩쯪쯫쯬쯭쯮쯯쯰쯱쯲쯳쯴쯵쯶쯷쯸쯹쯺쯻쯼쯽쯾쯿 +찀찁찂찃찄찅찆찇찈찉찊찋찌찍찎찏찐찑찒찓찔찕찖찗찘찙찚찛찜찝찞찟 +찠찡찢찣찤찥찦찧차착찪찫찬찭찮찯찰찱찲찳찴찵찶찷참찹찺찻찼창찾찿 +챀챁챂챃채책챆챇챈챉챊챋챌챍챎챏챐챑챒챓챔챕챖챗챘챙챚챛챜챝챞챟 +챠챡챢챣챤챥챦챧챨챩챪챫챬챭챮챯챰챱챲챳챴챵챶챷챸챹챺챻챼챽챾챿 +첀첁첂첃첄첅첆첇첈첉첊첋첌첍첎첏첐첑첒첓첔첕첖첗처척첚첛천첝첞첟 +철첡첢첣첤첥첦첧첨첩첪첫첬청첮첯첰첱첲첳체첵첶첷첸첹첺첻첼첽첾첿 +쳀쳁쳂쳃쳄쳅쳆쳇쳈쳉쳊쳋쳌쳍쳎쳏쳐쳑쳒쳓쳔쳕쳖쳗쳘쳙쳚쳛쳜쳝쳞쳟 +쳠쳡쳢쳣쳤쳥쳦쳧쳨쳩쳪쳫쳬쳭쳮쳯쳰쳱쳲쳳쳴쳵쳶쳷쳸쳹쳺쳻쳼쳽쳾쳿 +촀촁촂촃촄촅촆촇초촉촊촋촌촍촎촏촐촑촒촓촔촕촖촗촘촙촚촛촜총촞촟 +촠촡촢촣촤촥촦촧촨촩촪촫촬촭촮촯촰촱촲촳촴촵촶촷촸촹촺촻촼촽촾촿 +쵀쵁쵂쵃쵄쵅쵆쵇쵈쵉쵊쵋쵌쵍쵎쵏쵐쵑쵒쵓쵔쵕쵖쵗쵘쵙쵚쵛최쵝쵞쵟 +쵠쵡쵢쵣쵤쵥쵦쵧쵨쵩쵪쵫쵬쵭쵮쵯쵰쵱쵲쵳쵴쵵쵶쵷쵸쵹쵺쵻쵼쵽쵾쵿 +춀춁춂춃춄춅춆춇춈춉춊춋춌춍춎춏춐춑춒춓추축춖춗춘춙춚춛출춝춞춟 +춠춡춢춣춤춥춦춧춨충춪춫춬춭춮춯춰춱춲춳춴춵춶춷춸춹춺춻춼춽춾춿 +췀췁췂췃췄췅췆췇췈췉췊췋췌췍췎췏췐췑췒췓췔췕췖췗췘췙췚췛췜췝췞췟 +췠췡췢췣췤췥췦췧취췩췪췫췬췭췮췯췰췱췲췳췴췵췶췷췸췹췺췻췼췽췾췿 +츀츁츂츃츄츅츆츇츈츉츊츋츌츍츎츏츐츑츒츓츔츕츖츗츘츙츚츛츜츝츞츟 +츠측츢츣츤츥츦츧츨츩츪츫츬츭츮츯츰츱츲츳츴층츶츷츸츹츺츻츼츽츾츿 +칀칁칂칃칄칅칆칇칈칉칊칋칌칍칎칏칐칑칒칓칔칕칖칗치칙칚칛친칝칞칟 +칠칡칢칣칤칥칦칧침칩칪칫칬칭칮칯칰칱칲칳카칵칶칷칸칹칺칻칼칽칾칿 +캀캁캂캃캄캅캆캇캈캉캊캋캌캍캎캏캐캑캒캓캔캕캖캗캘캙캚캛캜캝캞캟 +캠캡캢캣캤캥캦캧캨캩캪캫캬캭캮캯캰캱캲캳캴캵캶캷캸캹캺캻캼캽캾캿 +컀컁컂컃컄컅컆컇컈컉컊컋컌컍컎컏컐컑컒컓컔컕컖컗컘컙컚컛컜컝컞컟 +컠컡컢컣커컥컦컧컨컩컪컫컬컭컮컯컰컱컲컳컴컵컶컷컸컹컺컻컼컽컾컿 +케켁켂켃켄켅켆켇켈켉켊켋켌켍켎켏켐켑켒켓켔켕켖켗켘켙켚켛켜켝켞켟 +켠켡켢켣켤켥켦켧켨켩켪켫켬켭켮켯켰켱켲켳켴켵켶켷켸켹켺켻켼켽켾켿 +콀콁콂콃콄콅콆콇콈콉콊콋콌콍콎콏콐콑콒콓코콕콖콗콘콙콚콛콜콝콞콟 +콠콡콢콣콤콥콦콧콨콩콪콫콬콭콮콯콰콱콲콳콴콵콶콷콸콹콺콻콼콽콾콿 +쾀쾁쾂쾃쾄쾅쾆쾇쾈쾉쾊쾋쾌쾍쾎쾏쾐쾑쾒쾓쾔쾕쾖쾗쾘쾙쾚쾛쾜쾝쾞쾟 +쾠쾡쾢쾣쾤쾥쾦쾧쾨쾩쾪쾫쾬쾭쾮쾯쾰쾱쾲쾳쾴쾵쾶쾷쾸쾹쾺쾻쾼쾽쾾쾿 +쿀쿁쿂쿃쿄쿅쿆쿇쿈쿉쿊쿋쿌쿍쿎쿏쿐쿑쿒쿓쿔쿕쿖쿗쿘쿙쿚쿛쿜쿝쿞쿟 +쿠쿡쿢쿣쿤쿥쿦쿧쿨쿩쿪쿫쿬쿭쿮쿯쿰쿱쿲쿳쿴쿵쿶쿷쿸쿹쿺쿻쿼쿽쿾쿿 +퀀퀁퀂퀃퀄퀅퀆퀇퀈퀉퀊퀋퀌퀍퀎퀏퀐퀑퀒퀓퀔퀕퀖퀗퀘퀙퀚퀛퀜퀝퀞퀟 +퀠퀡퀢퀣퀤퀥퀦퀧퀨퀩퀪퀫퀬퀭퀮퀯퀰퀱퀲퀳퀴퀵퀶퀷퀸퀹퀺퀻퀼퀽퀾퀿 +큀큁큂큃큄큅큆큇큈큉큊큋큌큍큎큏큐큑큒큓큔큕큖큗큘큙큚큛큜큝큞큟 +큠큡큢큣큤큥큦큧큨큩큪큫크큭큮큯큰큱큲큳클큵큶큷큸큹큺큻큼큽큾큿 +킀킁킂킃킄킅킆킇킈킉킊킋킌킍킎킏킐킑킒킓킔킕킖킗킘킙킚킛킜킝킞킟 +킠킡킢킣키킥킦킧킨킩킪킫킬킭킮킯킰킱킲킳킴킵킶킷킸킹킺킻킼킽킾킿 +타탁탂탃탄탅탆탇탈탉탊탋탌탍탎탏탐탑탒탓탔탕탖탗탘탙탚탛태택탞탟 +탠탡탢탣탤탥탦탧탨탩탪탫탬탭탮탯탰탱탲탳탴탵탶탷탸탹탺탻탼탽탾탿 +턀턁턂턃턄턅턆턇턈턉턊턋턌턍턎턏턐턑턒턓턔턕턖턗턘턙턚턛턜턝턞턟 +턠턡턢턣턤턥턦턧턨턩턪턫턬턭턮턯터턱턲턳턴턵턶턷털턹턺턻턼턽턾턿 +텀텁텂텃텄텅텆텇텈텉텊텋테텍텎텏텐텑텒텓텔텕텖텗텘텙텚텛템텝텞텟 +텠텡텢텣텤텥텦텧텨텩텪텫텬텭텮텯텰텱텲텳텴텵텶텷텸텹텺텻텼텽텾텿 +톀톁톂톃톄톅톆톇톈톉톊톋톌톍톎톏톐톑톒톓톔톕톖톗톘톙톚톛톜톝톞톟 +토톡톢톣톤톥톦톧톨톩톪톫톬톭톮톯톰톱톲톳톴통톶톷톸톹톺톻톼톽톾톿 +퇀퇁퇂퇃퇄퇅퇆퇇퇈퇉퇊퇋퇌퇍퇎퇏퇐퇑퇒퇓퇔퇕퇖퇗퇘퇙퇚퇛퇜퇝퇞퇟 +퇠퇡퇢퇣퇤퇥퇦퇧퇨퇩퇪퇫퇬퇭퇮퇯퇰퇱퇲퇳퇴퇵퇶퇷퇸퇹퇺퇻퇼퇽퇾퇿 +툀툁툂툃툄툅툆툇툈툉툊툋툌툍툎툏툐툑툒툓툔툕툖툗툘툙툚툛툜툝툞툟 +툠툡툢툣툤툥툦툧툨툩툪툫투툭툮툯툰툱툲툳툴툵툶툷툸툹툺툻툼툽툾툿 +퉀퉁퉂퉃퉄퉅퉆퉇퉈퉉퉊퉋퉌퉍퉎퉏퉐퉑퉒퉓퉔퉕퉖퉗퉘퉙퉚퉛퉜퉝퉞퉟 +퉠퉡퉢퉣퉤퉥퉦퉧퉨퉩퉪퉫퉬퉭퉮퉯퉰퉱퉲퉳퉴퉵퉶퉷퉸퉹퉺퉻퉼퉽퉾퉿 +튀튁튂튃튄튅튆튇튈튉튊튋튌튍튎튏튐튑튒튓튔튕튖튗튘튙튚튛튜튝튞튟 +튠튡튢튣튤튥튦튧튨튩튪튫튬튭튮튯튰튱튲튳튴튵튶튷트특튺튻튼튽튾튿 +틀틁틂틃틄틅틆틇틈틉틊틋틌틍틎틏틐틑틒틓틔틕틖틗틘틙틚틛틜틝틞틟 +틠틡틢틣틤틥틦틧틨틩틪틫틬틭틮틯티틱틲틳틴틵틶틷틸틹틺틻틼틽틾틿 +팀팁팂팃팄팅팆팇팈팉팊팋파팍팎팏판팑팒팓팔팕팖팗팘팙팚팛팜팝팞팟 +팠팡팢팣팤팥팦팧패팩팪팫팬팭팮팯팰팱팲팳팴팵팶팷팸팹팺팻팼팽팾팿 +퍀퍁퍂퍃퍄퍅퍆퍇퍈퍉퍊퍋퍌퍍퍎퍏퍐퍑퍒퍓퍔퍕퍖퍗퍘퍙퍚퍛퍜퍝퍞퍟 +퍠퍡퍢퍣퍤퍥퍦퍧퍨퍩퍪퍫퍬퍭퍮퍯퍰퍱퍲퍳퍴퍵퍶퍷퍸퍹퍺퍻퍼퍽퍾퍿 +펀펁펂펃펄펅펆펇펈펉펊펋펌펍펎펏펐펑펒펓펔펕펖펗페펙펚펛펜펝펞펟 +펠펡펢펣펤펥펦펧펨펩펪펫펬펭펮펯펰펱펲펳펴펵펶펷편펹펺펻펼펽펾펿 +폀폁폂폃폄폅폆폇폈평폊폋폌폍폎폏폐폑폒폓폔폕폖폗폘폙폚폛폜폝폞폟 +폠폡폢폣폤폥폦폧폨폩폪폫포폭폮폯폰폱폲폳폴폵폶폷폸폹폺폻폼폽폾폿 +퐀퐁퐂퐃퐄퐅퐆퐇퐈퐉퐊퐋퐌퐍퐎퐏퐐퐑퐒퐓퐔퐕퐖퐗퐘퐙퐚퐛퐜퐝퐞퐟 +퐠퐡퐢퐣퐤퐥퐦퐧퐨퐩퐪퐫퐬퐭퐮퐯퐰퐱퐲퐳퐴퐵퐶퐷퐸퐹퐺퐻퐼퐽퐾퐿 +푀푁푂푃푄푅푆푇푈푉푊푋푌푍푎푏푐푑푒푓푔푕푖푗푘푙푚푛표푝푞푟 +푠푡푢푣푤푥푦푧푨푩푪푫푬푭푮푯푰푱푲푳푴푵푶푷푸푹푺푻푼푽푾푿 +풀풁풂풃풄풅풆풇품풉풊풋풌풍풎풏풐풑풒풓풔풕풖풗풘풙풚풛풜풝풞풟 +풠풡풢풣풤풥풦풧풨풩풪풫풬풭풮풯풰풱풲풳풴풵풶풷풸풹풺풻풼풽풾풿 +퓀퓁퓂퓃퓄퓅퓆퓇퓈퓉퓊퓋퓌퓍퓎퓏퓐퓑퓒퓓퓔퓕퓖퓗퓘퓙퓚퓛퓜퓝퓞퓟 +퓠퓡퓢퓣퓤퓥퓦퓧퓨퓩퓪퓫퓬퓭퓮퓯퓰퓱퓲퓳퓴퓵퓶퓷퓸퓹퓺퓻퓼퓽퓾퓿 +픀픁픂픃프픅픆픇픈픉픊픋플픍픎픏픐픑픒픓픔픕픖픗픘픙픚픛픜픝픞픟 +픠픡픢픣픤픥픦픧픨픩픪픫픬픭픮픯픰픱픲픳픴픵픶픷픸픹픺픻피픽픾픿 +핀핁핂핃필핅핆핇핈핉핊핋핌핍핎핏핐핑핒핓핔핕핖핗하학핚핛한핝핞핟 +할핡핢핣핤핥핦핧함합핪핫핬항핮핯핰핱핲핳해핵핶핷핸핹핺핻핼핽핾핿 +햀햁햂햃햄햅햆햇했행햊햋햌햍햎햏햐햑햒햓햔햕햖햗햘햙햚햛햜햝햞햟 +햠햡햢햣햤향햦햧햨햩햪햫햬햭햮햯햰햱햲햳햴햵햶햷햸햹햺햻햼햽햾햿 +헀헁헂헃헄헅헆헇허헉헊헋헌헍헎헏헐헑헒헓헔헕헖헗험헙헚헛헜헝헞헟 +헠헡헢헣헤헥헦헧헨헩헪헫헬헭헮헯헰헱헲헳헴헵헶헷헸헹헺헻헼헽헾헿 +혀혁혂혃현혅혆혇혈혉혊혋혌혍혎혏혐협혒혓혔형혖혗혘혙혚혛혜혝혞혟 +혠혡혢혣혤혥혦혧혨혩혪혫혬혭혮혯혰혱혲혳혴혵혶혷호혹혺혻혼혽혾혿 +홀홁홂홃홄홅홆홇홈홉홊홋홌홍홎홏홐홑홒홓화확홖홗환홙홚홛활홝홞홟 +홠홡홢홣홤홥홦홧홨황홪홫홬홭홮홯홰홱홲홳홴홵홶홷홸홹홺홻홼홽홾홿 +횀횁횂횃횄횅횆횇횈횉횊횋회획횎횏횐횑횒횓횔횕횖횗횘횙횚횛횜횝횞횟 +횠횡횢횣횤횥횦횧효횩횪횫횬횭횮횯횰횱횲횳횴횵횶횷횸횹횺횻횼횽횾횿 +훀훁훂훃후훅훆훇훈훉훊훋훌훍훎훏훐훑훒훓훔훕훖훗훘훙훚훛훜훝훞훟 +훠훡훢훣훤훥훦훧훨훩훪훫훬훭훮훯훰훱훲훳훴훵훶훷훸훹훺훻훼훽훾훿 +휀휁휂휃휄휅휆휇휈휉휊휋휌휍휎휏휐휑휒휓휔휕휖휗휘휙휚휛휜휝휞휟 +휠휡휢휣휤휥휦휧휨휩휪휫휬휭휮휯휰휱휲휳휴휵휶휷휸휹휺휻휼휽휾휿 +흀흁흂흃흄흅흆흇흈흉흊흋흌흍흎흏흐흑흒흓흔흕흖흗흘흙흚흛흜흝흞흟 +흠흡흢흣흤흥흦흧흨흩흪흫희흭흮흯흰흱흲흳흴흵흶흷흸흹흺흻흼흽흾흿 +힀힁힂힃힄힅힆힇히힉힊힋힌힍힎힏힐힑힒힓힔힕힖힗힘힙힚힛힜힝힞힟 +힠힡힢힣 + +Free block (U+D7A4-U+D7FF): + +ힰힱힲힳힴힵힶힷힸힹힺힻힼힽힾힿퟀퟁퟂퟃퟄퟅퟆퟋퟌퟍퟎퟏퟐퟑퟒퟓퟔퟕퟖퟗퟘퟙퟚퟛퟜퟝퟞퟟퟠퟡퟢퟣ +ퟤퟥퟦퟧퟨퟩퟪퟫퟬퟭퟮퟯퟰퟱퟲퟳퟴퟵퟶퟷퟸퟹퟺퟻ + +Private Use (U+E000-U+F8FF): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CJK Compatibility Ideographs (U+F900-U+FAFF): + +豈更車賈滑串句龜龜契金喇奈懶癩羅蘿螺裸邏樂洛烙珞落酪駱亂卵欄爛蘭 +鸞嵐濫藍襤拉臘蠟廊朗浪狼郎來冷勞擄櫓爐盧老蘆虜路露魯鷺碌祿綠菉錄 +鹿論壟弄籠聾牢磊賂雷壘屢樓淚漏累縷陋勒肋凜凌稜綾菱陵讀拏樂諾丹寧 +怒率異北磻便復不泌數索參塞省葉說殺辰沈拾若掠略亮兩凉梁糧良諒量勵 +呂女廬旅濾礪閭驪麗黎力曆歷轢年憐戀撚漣煉璉秊練聯輦蓮連鍊列劣咽烈 +裂說廉念捻殮簾獵令囹寧嶺怜玲瑩羚聆鈴零靈領例禮醴隸惡了僚寮尿料樂 +燎療蓼遼龍暈阮劉杻柳流溜琉留硫紐類六戮陸倫崙淪輪律慄栗率隆利吏履 +易李梨泥理痢罹裏裡里離匿溺吝燐璘藺隣鱗麟林淋臨立笠粒狀炙識什茶刺 +切度拓糖宅洞暴輻行降見廓兀嗀﨎﨏塚﨑晴﨓﨔凞猪益礼神祥福靖精羽﨟 +蘒﨡諸﨣﨤逸都﨧﨨﨩飯飼館鶴郞隷侮僧免勉勤卑喝嘆器塀墨層屮悔慨憎 +懲敏既暑梅海渚漢煮爫琢碑社祉祈祐祖祝禍禎穀突節練縉繁署者臭艹艹著 +褐視謁謹賓贈辶逸難響頻恵𤋮舘並况全侀充冀勇勺喝啕喙嗢塚墳奄奔 +婢嬨廒廙彩徭惘慎愈憎慠懲戴揄搜摒敖晴朗望杖歹殺流滛滋漢瀞煮瞧爵犯 +猪瑱甆画瘝瘟益盛直睊着磌窱節类絛練缾者荒華蝹襁覆視調諸請謁諾諭謹 +變贈輸遲醙鉶陼難靖韛響頋頻鬒龜𢡊𢡄𣏕㮝䀘䀹𥉉𥳐𧻓齃龎 + + +Alphabetic Presentation Forms (U+FB00-U+FB4F): + +fffiflffifflſtstﬓﬔﬕﬖﬗיִ◌ﬞײַﬠﬡﬢﬣﬤﬥﬦﬧﬨ﬩שׁשׂשּׁשּׂאַאָאּבּגּדּהּוּזּטּיּךּכּלּמּ +נּסּףּפּצּקּרּשּתּוֹבֿכֿפֿﭏ + +Arabic Presentation Forms-A (U+FB50-U+FDFF): + +ﭐﭑﭒﭓﭔﭕﭖﭗﭘﭙﭚﭛﭜﭝﭞﭟﭠﭡﭢﭣﭤﭥﭦﭧﭨﭩﭪﭫﭬﭭﭮﭯﭰﭱﭲﭳﭴﭵﭶﭷﭸﭹﭺﭻﭼﭽﭾﭿﮀﮁﮂﮃﮄﮅﮆﮇﮈﮉﮊﮋﮌﮍﮎﮏ +ﮐﮑﮒﮓﮔﮕﮖﮗﮘﮙﮚﮛﮜﮝﮞﮟﮠﮡﮢﮣﮤﮥﮦﮧﮨﮩﮪﮫﮬﮭﮮﮯﮰﮱ﮲﮳﮴﮵﮶﮷﮸﮹﮺﮻﮼﮽﮾﮿﯀﯁﯂ +ﯓﯔﯕﯖﯗﯘﯙﯚﯛﯜﯝﯞﯟﯠﯡﯢﯣﯤﯥﯦﯧﯨﯩﯪﯫﯬﯭﯮﯯﯰﯱﯲﯳﯴﯵﯶﯷﯸﯹﯺﯻﯼﯽﯾﯿﰀﰁﰂﰃﰄﰅﰆﰇﰈﰉﰊﰋﰌﰍﰎﰏ +ﰐﰑﰒﰓﰔﰕﰖﰗﰘﰙﰚﰛﰜﰝﰞﰟﰠﰡﰢﰣﰤﰥﰦﰧﰨﰩﰪﰫﰬﰭﰮﰯﰰﰱﰲﰳﰴﰵﰶﰷﰸﰹﰺﰻﰼﰽﰾﰿﱀﱁﱂﱃﱄﱅﱆﱇﱈﱉﱊﱋﱌﱍﱎﱏ +ﱐﱑﱒﱓﱔﱕﱖﱗﱘﱙﱚﱛﱜﱝﱞﱟﱠﱡﱢﱣﱤﱥﱦﱧﱨﱩﱪﱫﱬﱭﱮﱯﱰﱱﱲﱳﱴﱵﱶﱷﱸﱹﱺﱻﱼﱽﱾﱿﲀﲁﲂﲃﲄﲅﲆﲇﲈﲉﲊﲋﲌﲍﲎﲏ +ﲐﲑﲒﲓﲔﲕﲖﲗﲘﲙﲚﲛﲜﲝﲞﲟﲠﲡﲢﲣﲤﲥﲦﲧﲨﲩﲪﲫﲬﲭﲮﲯﲰﲱﲲﲳﲴﲵﲶﲷﲸﲹﲺﲻﲼﲽﲾﲿﳀﳁﳂﳃﳄﳅﳆﳇﳈﳉﳊﳋﳌﳍﳎﳏ +ﳐﳑﳒﳓﳔﳕﳖﳗﳘﳙﳚﳛﳜﳝﳞﳟﳠﳡﳢﳣﳤﳥﳦﳧﳨﳩﳪﳫﳬﳭﳮﳯﳰﳱﳲﳳﳴﳵﳶﳷﳸﳹﳺﳻﳼﳽﳾﳿﴀﴁﴂﴃﴄﴅﴆﴇﴈﴉﴊﴋﴌﴍﴎﴏ +ﴐﴑﴒﴓﴔﴕﴖﴗﴘﴙﴚﴛﴜﴝﴞﴟﴠﴡﴢﴣﴤﴥﴦﴧﴨﴩﴪﴫﴬﴭﴮﴯﴰﴱﴲﴳﴴﴵﴶﴷﴸﴹﴺﴻﴼﴽ﴾﴿﵀﵁﵂﵃﵄﵅﵆﵇﵈﵉﵊﵋﵌﵍﵎﵏ +ﵐﵑﵒﵓﵔﵕﵖﵗﵘﵙﵚﵛﵜﵝﵞﵟﵠﵡﵢﵣﵤﵥﵦﵧﵨﵩﵪﵫﵬﵭﵮﵯﵰﵱﵲﵳﵴﵵﵶﵷﵸﵹﵺﵻﵼﵽﵾﵿﶀﶁﶂﶃﶄﶅﶆﶇﶈﶉﶊﶋﶌﶍﶎﶏ +ﶒﶓﶔﶕﶖﶗﶘﶙﶚﶛﶜﶝﶞﶟﶠﶡﶢﶣﶤﶥﶦﶧﶨﶩﶪﶫﶬﶭﶮﶯﶰﶱﶲﶳﶴﶵﶶﶷﶸﶹﶺﶻﶼﶽﶾﶿﷀﷁﷂﷃﷄﷅﷆﷇ﷏ +ﷰﷱﷲﷳﷴﷵﷶﷷﷸﷹﷺﷻ﷼﷽﷾﷿ + +Free block (U+FE00-U+FE1F): + +︀︁︂︃︄︅︆︇︈︉︊︋︌︍︎️︐︑︒︓︔︕︖︗︘︙ + +Combining Half Marks (U+FE20-U+FE2F): + +◌︠◌︡◌︢◌︧︨︩︪︫︬︭︣︤︥︦︮︯ + +CJK Compatibility Forms (U+FE30-U+FE4F): + +︰︱︲︳︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹅﹆﹇﹈﹉﹊﹋﹌﹍﹎﹏ + +Small Form Variants (U+FE50-U+FE6F): + +﹐﹑﹒﹔﹕﹖﹗﹘﹙﹚﹛﹜﹝﹞﹟﹠﹡﹢﹣﹤﹥﹦﹨﹩﹪﹫ + +Arabic Presentation Forms-B (U+FE70-U+FEFE): + +ﹰﹱﹲﹳﹴﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯ +ﺰﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯ +ﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ + +Specials (U+FEFF-U+FEFF): + + + +Halfwidth and Fullwidth Forms (U+FF00-U+FFEF): + +!"#$%&'()*+,-./0123456789:;<=>? +@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +`abcdefghijklmnopqrstuvwxyz{|}~⦅ +⦆。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚ +ᅠᄀᄁᆪᄂᆬᆭᄃᄄᄅᆰᆱᆲᆳᆴᆵᄚᄆᄇᄈᄡᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ +¢£¬ ̄¦¥₩│←↑→↓■○ + +Specials (U+FFF0-U+FFFD): + +� + +Free block (U+FFFE-U+FFFF): + + diff --git a/REORG.TODO/libio/tst-wmemstream1.c b/REORG.TODO/libio/tst-wmemstream1.c new file mode 100644 index 0000000000..f8b308bc6c --- /dev/null +++ b/REORG.TODO/libio/tst-wmemstream1.c @@ -0,0 +1,7 @@ +#include <wchar.h> + +#define CHAR_T wchar_t +#define W(o) L##o +#define OPEN_MEMSTREAM open_wmemstream + +#include "tst-memstream1.c" diff --git a/REORG.TODO/libio/tst-wmemstream2.c b/REORG.TODO/libio/tst-wmemstream2.c new file mode 100644 index 0000000000..e2442ebfac --- /dev/null +++ b/REORG.TODO/libio/tst-wmemstream2.c @@ -0,0 +1,7 @@ +#include <wchar.h> + +#define CHAR_T wchar_t +#define W(o) L##o +#define OPEN_MEMSTREAM open_wmemstream + +#include "tst-memstream2.c" diff --git a/REORG.TODO/libio/tst-wmemstream3.c b/REORG.TODO/libio/tst-wmemstream3.c new file mode 100644 index 0000000000..504c953a42 --- /dev/null +++ b/REORG.TODO/libio/tst-wmemstream3.c @@ -0,0 +1,44 @@ +/* Test for open_memstream implementation. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + +/* Straighforward implementation so tst-memstream3 could use check + fwrite on open_memstream. */ +static size_t +fwwrite (const void *ptr, size_t size, size_t nmemb, FILE *arq) +{ + const wchar_t *wcs = (const wchar_t*) (ptr); + for (size_t s = 0; s < size; s++) + { + for (size_t n = 0; n < nmemb; n++) + if (fputwc (wcs[n], arq) == WEOF) + return n; + } + return size * nmemb; +} + +#define CHAR_T wchar_t +#define W(o) L##o +#define OPEN_MEMSTREAM open_wmemstream +#define PRINTF wprintf +#define FWRITE fwwrite +#define FPUTC fputwc +#define STRCMP wcscmp + +#include "tst-memstream3.c" diff --git a/REORG.TODO/libio/tst_getwc.c b/REORG.TODO/libio/tst_getwc.c new file mode 100644 index 0000000000..c651de2869 --- /dev/null +++ b/REORG.TODO/libio/tst_getwc.c @@ -0,0 +1,41 @@ +/* Simple test of getwc in the C locale. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <wchar.h> + + +int +main (void) +{ + wchar_t buf[100]; + size_t n = 0; + + wmemset (buf, L'\0', sizeof (buf) / sizeof (buf[0])); + while (! feof (stdin) && n < sizeof (buf) - 1) + { + buf[n] = getwc (stdin); + if (buf[n] == WEOF) + break; + ++n; + } + buf[n] = L'\0'; + + return wcscmp (buf, L"This is a test of getwc\n") != 0; +} diff --git a/REORG.TODO/libio/tst_getwc.input b/REORG.TODO/libio/tst_getwc.input new file mode 100644 index 0000000000..9238d6bb97 --- /dev/null +++ b/REORG.TODO/libio/tst_getwc.input @@ -0,0 +1 @@ +This is a test of getwc diff --git a/REORG.TODO/libio/tst_putwc.c b/REORG.TODO/libio/tst_putwc.c new file mode 100644 index 0000000000..79654d91c1 --- /dev/null +++ b/REORG.TODO/libio/tst_putwc.c @@ -0,0 +1,124 @@ +/* Simple test of putwc in the C locale. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <error.h> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> + +static const char outname[] = OBJPFX "tst_putwc.temp"; + +/* Prototype for our test function. */ +int do_test (void); +#define TEST_FUNCTION do_test () + +/* This defines the `main' function and some more. */ +#include <test-skeleton.c> + +int +do_test (void) +{ + const wchar_t str[] = L"This is a test of putwc\n"; + wchar_t buf[100]; + size_t n = 0; + FILE *fp; + int res = 0; + + add_temp_file (outname); + + fp = fopen (outname, "w+"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "cannot open temporary file"); + + for (n = 0; str[n] != L'\0'; ++n) + putwc (str[n], fp); + + /* First try reading after rewinding. */ + rewind (fp); + + wmemset (buf, L'\0', sizeof (buf) / sizeof (buf[0])); + n = 0; + while (! feof (fp) && n < sizeof (buf) - 1) + { + buf[n] = getwc (fp); + if (buf[n] == WEOF) + break; + ++n; + } + buf[n] = L'\0'; + + if (wcscmp (buf, L"This is a test of putwc\n") != 0) + { + puts ("first comparison failed"); + res = 1; + } + + /* Now close the file, open it again, and read again. */ + if (fclose (fp) != 0) + { + printf ("failure during fclose: %m\n"); + res = 1; + } + + fp = fopen (outname, "r"); + if (fp == NULL) + { + printf ("cannot reopen file: %m\n"); + return 1; + } + + /* We can remove the file now. */ + remove (outname); + + wmemset (buf, L'\0', sizeof (buf) / sizeof (buf[0])); + n = 0; + while (! feof (fp) && n < sizeof (buf) - 1) + { + buf[n] = getwc (fp); + if (buf[n] == WEOF) + break; + ++n; + } + buf[n] = L'\0'; + + if (wcscmp (buf, L"This is a test of putwc\n") != 0) + { + puts ("second comparison failed"); + res = 1; + } + + if (fclose (fp) != 0) + { + printf ("failure during fclose: %m\n"); + res = 1; + } + + /* Next test: write a bit more than a few bytes. */ + fp = fopen (outname, "w"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "cannot open temporary file"); + + for (n = 0; n < 4098; ++n) + putwc (n & 255, fp); + + fclose (fp); + + return res; +} diff --git a/REORG.TODO/libio/tst_swprintf.c b/REORG.TODO/libio/tst_swprintf.c new file mode 100644 index 0000000000..e4bd7f022a --- /dev/null +++ b/REORG.TODO/libio/tst_swprintf.c @@ -0,0 +1,92 @@ +#include <stdio.h> +#include <wchar.h> +#include <sys/types.h> + + +static wchar_t buf[100]; +#define nbuf (sizeof (buf) / sizeof (buf[0])) +static const struct +{ + size_t n; + const char *str; + ssize_t exp; +} tests[] = + { + { nbuf, "hello world", 11 }, + { 0, "hello world", -1 }, + { 0, "", -1 }, + { nbuf, "", 0 } + }; + +int +main (int argc, char *argv[]) +{ + size_t n; + int result = 0; + + puts ("test 1"); + n = swprintf (buf, nbuf, L"Hello %s", "world"); + if (n != 11) + { + printf ("incorrect return value: %zd instead of 11\n", n); + result = 1; + } + else if (wcscmp (buf, L"Hello world") != 0) + { + printf ("incorrect string: L\"%ls\" instead of L\"Hello world\"\n", buf); + result = 1; + } + + puts ("test 2"); + n = swprintf (buf, nbuf, L"Is this >%g< 3.1?", 3.1); + if (n != 18) + { + printf ("incorrect return value: %zd instead of 18\n", n); + result = 1; + } + else if (wcscmp (buf, L"Is this >3.1< 3.1?") != 0) + { + printf ("incorrect string: L\"%ls\" instead of L\"Is this >3.1< 3.1?\"\n", + buf); + result = 1; + } + + for (n = 0; n < sizeof (tests) / sizeof (tests[0]); ++n) + { + ssize_t res = swprintf (buf, tests[n].n, L"%s", tests[n].str); + + if (tests[n].exp < 0 && res >= 0) + { + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") expected to fail\n", + tests[n].n, tests[n].str); + result = 1; + } + else if (tests[n].exp >= 0 && tests[n].exp != res) + { + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") expected to return %Zd, but got %Zd\n", + tests[n].n, tests[n].str, tests[n].exp, res); + result = 1; + } + else + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") OK\n", + tests[n].n, tests[n].str); + } + + if (swprintf (buf, nbuf, L"%.0s", "foo") != 0 + || wcslen (buf) != 0) + { + printf ("swprintf (buf, %Zu, L\"%%.0s\", \"foo\") create some output\n", + nbuf); + result = 1; + } + + if (swprintf (buf, nbuf, L"%.0ls", L"foo") != 0 + || wcslen (buf) != 0) + { + printf ("swprintf (buf, %Zu, L\"%%.0ls\", L\"foo\") create some output\n", + nbuf); + result = 1; + } + + return result; +} diff --git a/REORG.TODO/libio/tst_swscanf.c b/REORG.TODO/libio/tst_swscanf.c new file mode 100644 index 0000000000..372f0fc7d3 --- /dev/null +++ b/REORG.TODO/libio/tst_swscanf.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + const wchar_t in[] = L"7 + 35 is 42"; + size_t n; + int a, b, c; + int result = 0; + char buf1[20]; + wchar_t wbuf2[20]; + char buf3[20]; + char c4; + wchar_t wc5; + + puts ("Test 1"); + a = b = c = 0; + n = swscanf (in, L"%d + %d is %d", &a, &b, &c); + if (n != 3 || a + b != c || c != 42) + { + printf ("*** FAILED, n = %Zu, a = %d, b = %d, c = %d\n", n, a, b, c); + result = 1; + } + + puts ("Test 2"); + n = swscanf (L"one two three !!", L"%s %S %s %c%C", + buf1, wbuf2, buf3, &c4, &wc5); + if (n != 5 || strcmp (buf1, "one") != 0 || wcscmp (wbuf2, L"two") != 0 + || strcmp (buf3, "three") != 0 || c4 != '!' || wc5 != L'!') + { + printf ("*** FAILED, n = %Zu, buf1 = \"%s\", wbuf2 = L\"%S\", buf3 = \"%s\", c4 = '%c', wc5 = L'%C'\n", + n, buf1, wbuf2, buf3, c4, (wint_t) wc5); + result = 1; + } + + return result; +} diff --git a/REORG.TODO/libio/tst_wprintf.c b/REORG.TODO/libio/tst_wprintf.c new file mode 100644 index 0000000000..bf859f10fc --- /dev/null +++ b/REORG.TODO/libio/tst_wprintf.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + fputws (L"Hello world!\n", stdout); + wprintf (L"This %s a %ls string: %d\n", "is", L"mixed", 42); + wprintf (L"%Iu\n", 0xfeedbeef); + return 0; +} diff --git a/REORG.TODO/libio/tst_wprintf2.c b/REORG.TODO/libio/tst_wprintf2.c new file mode 100644 index 0000000000..dfff70f1f9 --- /dev/null +++ b/REORG.TODO/libio/tst_wprintf2.c @@ -0,0 +1,104 @@ +/* Test case by Yoshito Kawada <KAWADA@jp.ibm.com>. */ +#include <errno.h> +#include <error.h> +#include <fcntl.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + int a = 3; + int fd; + char name[] = "/tmp/wprintf.out.XXXXXX"; + FILE *fp; + char buf[100]; + size_t len; + int res = 0; + + fd = mkstemp (name); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open temporary file"); + + unlink (name); + + setlocale (LC_ALL, "en_US.UTF-8"); + + fp = fdopen (dup (fd), "w"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"w\")"); + + fwprintf (fp, L"test start"); + fwprintf (fp, L" int %d\n", a); + + /* String with precision. */ + fwprintf (fp, L"1[%6.3s]\n", argv[1]); + + fclose (fp); + + fp = fdopen (dup (fd), "a"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"a\")"); + + setvbuf (fp, NULL, _IONBF, 0); + + /* fwprintf to unbuffered stream. */ + fwprintf (fp, L"hello.\n"); + + fclose (fp); + + + /* Now read it back in. This time using multibyte functions. */ + lseek (fd, SEEK_SET, 0); + fp = fdopen (fd, "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"r\")"); + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "first fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after first line"); + res = 1; + } + printf ("1st line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "test start int 3", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "test start int 3", len) != 0; + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "second fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after second line"); + res = 1; + } + printf ("2nd line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "1[ Som]", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "1[ Som]", len) != 0; + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "third fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after third line"); + res = 1; + } + printf ("3rd line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "hello.", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "hello.", len) != 0; + + return res; +} diff --git a/REORG.TODO/libio/tst_wscanf.c b/REORG.TODO/libio/tst_wscanf.c new file mode 100644 index 0000000000..df209838c2 --- /dev/null +++ b/REORG.TODO/libio/tst_wscanf.c @@ -0,0 +1,29 @@ +#include <stdio.h> +#include <string.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + int n; + int result = 0; + char buf1[20]; + wchar_t wbuf2[20]; + char c3; + wchar_t wc4; + int d; + + puts ("Test 1"); + + n = wscanf (L"%s %S %c%C %d", buf1, wbuf2, &c3, &wc4, &d); + + if (n != 5 || strcmp (buf1, "Hello") != 0 || wcscmp (wbuf2, L"World") != 0 + || c3 != '!' || wc4 != L'!' || d != 42) + { + printf ("*** FAILED, n = %d, buf1 = \"%s\", wbuf2 = L\"%S\", c3 = '%c', wc4 = L'%C', d = %d\n", + n, buf1, wbuf2, c3, (wint_t) wc4, d); + result = 1; + } + + return result; +} diff --git a/REORG.TODO/libio/tst_wscanf.input b/REORG.TODO/libio/tst_wscanf.input new file mode 100644 index 0000000000..93e1eb55d4 --- /dev/null +++ b/REORG.TODO/libio/tst_wscanf.input @@ -0,0 +1 @@ +Hello World !! 42 diff --git a/REORG.TODO/libio/vasprintf.c b/REORG.TODO/libio/vasprintf.c new file mode 100644 index 0000000000..a9a21545a2 --- /dev/null +++ b/REORG.TODO/libio/vasprintf.c @@ -0,0 +1,88 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <malloc.h> +#include <string.h> +#include "libioP.h" +#include "stdio.h" +#include <stdio_ext.h> +#include "strfile.h" + +int +_IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args) +{ + /* Initial size of the buffer to be used. Will be doubled each time an + overflow occurs. */ + const _IO_size_t init_string_size = 100; + char *string; + _IO_strfile sf; + int ret; + _IO_size_t needed; + _IO_size_t allocated; + /* No need to clear the memory here (unlike for open_memstream) since + we know we will never seek on the stream. */ + string = (char *) malloc (init_string_size); + if (string == NULL) + return -1; +#ifdef _IO_MTSAFE_IO + sf._sbf._f._lock = NULL; +#endif + _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&sf, string, init_string_size, string); + sf._sbf._f._flags &= ~_IO_USER_BUF; + sf._s._allocate_buffer = (_IO_alloc_type) malloc; + sf._s._free_buffer = (_IO_free_type) free; + ret = _IO_vfprintf (&sf._sbf._f, format, args); + if (ret < 0) + { + free (sf._sbf._f._IO_buf_base); + return ret; + } + /* Only use realloc if the size we need is of the same (binary) + order of magnitude then the memory we allocated. */ + needed = sf._sbf._f._IO_write_ptr - sf._sbf._f._IO_write_base + 1; + allocated = sf._sbf._f._IO_write_end - sf._sbf._f._IO_write_base; + if ((allocated >> 1) <= needed) + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + else + { + *result_ptr = (char *) malloc (needed); + if (*result_ptr != NULL) + { + memcpy (*result_ptr, sf._sbf._f._IO_buf_base, needed - 1); + free (sf._sbf._f._IO_buf_base); + } + else + /* We have no choice, use the buffer we already have. */ + *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); + } + if (*result_ptr == NULL) + *result_ptr = sf._sbf._f._IO_buf_base; + (*result_ptr)[needed - 1] = '\0'; + return ret; +} +ldbl_weak_alias (_IO_vasprintf, vasprintf) diff --git a/REORG.TODO/libio/vscanf.c b/REORG.TODO/libio/vscanf.c new file mode 100644 index 0000000000..7e4989c9d7 --- /dev/null +++ b/REORG.TODO/libio/vscanf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "stdio.h" + +#undef vscanf + +int +_IO_vscanf (const char *format, _IO_va_list args) +{ + return _IO_vfscanf (_IO_stdin, format, args, NULL); +} +ldbl_weak_alias (_IO_vscanf, vscanf) diff --git a/REORG.TODO/libio/vsnprintf.c b/REORG.TODO/libio/vsnprintf.c new file mode 100644 index 0000000000..0e93c368bd --- /dev/null +++ b/REORG.TODO/libio/vsnprintf.c @@ -0,0 +1,121 @@ +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + +static int _IO_strn_overflow (_IO_FILE *fp, int c) __THROW; + +static int +_IO_strn_overflow (_IO_FILE *fp, int c) +{ + /* When we come to here this means the user supplied buffer is + filled. But since we must return the number of characters which + would have been written in total we must provide a buffer for + further use. We can do this by writing on and on in the overflow + buffer in the _IO_strnfile structure. */ + _IO_strnfile *snf = (_IO_strnfile *) fp; + + if (fp->_IO_buf_base != snf->overflow_buf) + { + /* Terminate the string. We know that there is room for at + least one more character since we initialized the stream with + a size to make this possible. */ + *fp->_IO_write_ptr = '\0'; + + _IO_setb (fp, snf->overflow_buf, + snf->overflow_buf + sizeof (snf->overflow_buf), 0); + + fp->_IO_write_base = snf->overflow_buf; + fp->_IO_read_base = snf->overflow_buf; + fp->_IO_read_ptr = snf->overflow_buf; + fp->_IO_read_end = snf->overflow_buf + sizeof (snf->overflow_buf); + } + + fp->_IO_write_ptr = snf->overflow_buf; + fp->_IO_write_end = snf->overflow_buf; + + /* Since we are not really interested in storing the characters + which do not fit in the buffer we simply ignore it. */ + return c; +} + + +const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, _IO_strn_overflow), + JUMP_INIT(underflow, _IO_str_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_str_pbackfail), + JUMP_INIT(xsputn, _IO_default_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_str_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_default_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +_IO_vsnprintf (char *string, _IO_size_t maxlen, const char *format, + _IO_va_list args) +{ + _IO_strnfile sf; + int ret; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + /* We need to handle the special case where MAXLEN is 0. Use the + overflow buffer right from the start. */ + if (maxlen == 0) + { + string = sf.overflow_buf; + maxlen = sizeof (sf.overflow_buf); + } + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps; + string[0] = '\0'; + _IO_str_init_static_internal (&sf.f, string, maxlen - 1, string); + ret = _IO_vfprintf (&sf.f._sbf._f, format, args); + + if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) + *sf.f._sbf._f._IO_write_ptr = '\0'; + return ret; +} +ldbl_weak_alias (_IO_vsnprintf, __vsnprintf) +ldbl_weak_alias (_IO_vsnprintf, vsnprintf) diff --git a/REORG.TODO/libio/vswprintf.c b/REORG.TODO/libio/vswprintf.c new file mode 100644 index 0000000000..fc78bc9e95 --- /dev/null +++ b/REORG.TODO/libio/vswprintf.c @@ -0,0 +1,124 @@ +/* Copyright (C) 1994-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include "strfile.h" + + +static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW; + +static wint_t +_IO_wstrn_overflow (_IO_FILE *fp, wint_t c) +{ + /* When we come to here this means the user supplied buffer is + filled. But since we must return the number of characters which + would have been written in total we must provide a buffer for + further use. We can do this by writing on and on in the overflow + buffer in the _IO_wstrnfile structure. */ + _IO_wstrnfile *snf = (_IO_wstrnfile *) fp; + + if (fp->_wide_data->_IO_buf_base != snf->overflow_buf) + { + _IO_wsetb (fp, snf->overflow_buf, + snf->overflow_buf + (sizeof (snf->overflow_buf) + / sizeof (wchar_t)), 0); + + fp->_wide_data->_IO_write_base = snf->overflow_buf; + fp->_wide_data->_IO_read_base = snf->overflow_buf; + fp->_wide_data->_IO_read_ptr = snf->overflow_buf; + fp->_wide_data->_IO_read_end = (snf->overflow_buf + + (sizeof (snf->overflow_buf) + / sizeof (wchar_t))); + } + + fp->_wide_data->_IO_write_ptr = snf->overflow_buf; + fp->_wide_data->_IO_write_end = snf->overflow_buf; + + /* Since we are not really interested in storing the characters + which do not fit in the buffer we simply ignore it. */ + return c; +} + + +const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, _IO_wdefault_xsputn), + JUMP_INIT(xsgetn, _IO_wdefault_xsgetn), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_wdefault_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + + +int +_IO_vswprintf (wchar_t *string, _IO_size_t maxlen, const wchar_t *format, + _IO_va_list args) +{ + _IO_wstrnfile sf; + int ret; + struct _IO_wide_data wd; +#ifdef _IO_MTSAFE_IO + sf.f._sbf._f._lock = NULL; +#endif + + if (maxlen == 0) + /* Since we have to write at least the terminating L'\0' a buffer + length of zero always makes the function fail. */ + return -1; + + _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps); + _IO_fwide (&sf.f._sbf._f, 1); + string[0] = L'\0'; + _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string); + ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args); + + if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) + /* ISO C99 requires swprintf/vswprintf to return an error if the + output does not fit in the provided buffer. */ + return -1; + + /* Terminate the string. */ + *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + + return ret; +} +weak_alias (_IO_vswprintf, __vswprintf) +ldbl_weak_alias (_IO_vswprintf, vswprintf) diff --git a/REORG.TODO/libio/vtables.c b/REORG.TODO/libio/vtables.c new file mode 100644 index 0000000000..41b48db98c --- /dev/null +++ b/REORG.TODO/libio/vtables.c @@ -0,0 +1,72 @@ +/* libio vtable validation. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <libioP.h> +#include <stdio.h> + +#ifdef SHARED + +void (*IO_accept_foreign_vtables) (void) attribute_hidden; + +/* Used to detected multiple libcs. */ +extern struct dl_open_hook *_dl_open_hook; +libc_hidden_proto (_dl_open_hook); + +#else /* !SHARED */ + +/* Used to check whether static dlopen support is needed. */ +# pragma weak __dlopen + +#endif + +void attribute_hidden +_IO_vtable_check (void) +{ +#ifdef SHARED + /* Honor the compatibility flag. */ + void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables); +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (flag); +#endif + if (flag == &_IO_vtable_check) + return; + + /* In case this libc copy is in a non-default namespace, we always + need to accept foreign vtables because there is always a + possibility that FILE * objects are passed across the linking + boundary. */ + { + Dl_info di; + struct link_map *l; + if (_dl_open_hook != NULL + || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0 + && l->l_ns != LM_ID_BASE)) + return; + } + +#else /* !SHARED */ + /* We cannot perform vtable validation in the static dlopen case + because FILE * handles might be passed back and forth across the + boundary. Therefore, we disable checking in this case. */ + if (__dlopen != NULL) + return; +#endif + + __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n"); +} diff --git a/REORG.TODO/libio/vwprintf.c b/REORG.TODO/libio/vwprintf.c new file mode 100644 index 0000000000..7b8dcd6703 --- /dev/null +++ b/REORG.TODO/libio/vwprintf.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + +/* Write formatted output to stdout according to the + format string FORMAT, using the argument list in ARG. */ +int +__vwprintf (const wchar_t *format, __gnuc_va_list arg) +{ + return __vfwprintf (stdout, format, arg); +} +ldbl_strong_alias (__vwprintf, vwprintf) diff --git a/REORG.TODO/libio/vwscanf.c b/REORG.TODO/libio/vwscanf.c new file mode 100644 index 0000000000..9498190639 --- /dev/null +++ b/REORG.TODO/libio/vwscanf.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include "libioP.h" +#include <wchar.h> + +int +__vwscanf (const wchar_t *format, _IO_va_list args) +{ + return _IO_vfwscanf (_IO_stdin, format, args, NULL); +} +ldbl_strong_alias (__vwscanf, vwscanf) diff --git a/REORG.TODO/libio/wfiledoalloc.c b/REORG.TODO/libio/wfiledoalloc.c new file mode 100644 index 0000000000..c3d324e546 --- /dev/null +++ b/REORG.TODO/libio/wfiledoalloc.c @@ -0,0 +1,84 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* + Copyright (C) 1990 The Regents of the University of California. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE.*/ + +/* Modified for GNU iostream by Per Bothner 1991, 1992. */ + +#include "libioP.h" +#include <stdlib.h> + +/* Allocate a file buffer, or switch to unbuffered I/O. */ +int +_IO_wfile_doallocate (_IO_FILE *fp) +{ + _IO_size_t size; + wchar_t *p; + + /* Allocate room for the external buffer. */ + if (fp->_IO_buf_base == NULL) + _IO_file_doallocate (fp); + + /* If narrow buffer is user allocated (set by setvbuf etc.), + use that size as the size of the wide buffer, when it is + allocated by _IO_file_doallocate, multiply that by size + of the wide character. */ + size = fp->_IO_buf_end - fp->_IO_buf_base; + if ((fp->_flags & _IO_USER_BUF)) + size = (size + sizeof (wchar_t) - 1) / sizeof (wchar_t); + p = malloc (size * sizeof (wchar_t)); + if (__glibc_unlikely (p == NULL)) + return EOF; + _IO_wsetb (fp, p, p + size, 1); + return 1; +} diff --git a/REORG.TODO/libio/wfileops.c b/REORG.TODO/libio/wfileops.c new file mode 100644 index 0000000000..fb94f45040 --- /dev/null +++ b/REORG.TODO/libio/wfileops.c @@ -0,0 +1,1117 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ulrich Drepper <drepper@cygnus.com>. + Based on the single byte version by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <assert.h> +#include <libioP.h> +#include <wchar.h> +#include <gconv.h> +#include <stdlib.h> +#include <string.h> + + +#ifndef _LIBC +# define _IO_new_do_write _IO_do_write +# define _IO_new_file_attach _IO_file_attach +# define _IO_new_file_close_it _IO_file_close_it +# define _IO_new_file_finish _IO_file_finish +# define _IO_new_file_fopen _IO_file_fopen +# define _IO_new_file_init _IO_file_init +# define _IO_new_file_setbuf _IO_file_setbuf +# define _IO_new_file_sync _IO_file_sync +# define _IO_new_file_overflow _IO_file_overflow +# define _IO_new_file_seekoff _IO_file_seekoff +# define _IO_new_file_underflow _IO_file_underflow +# define _IO_new_file_write _IO_file_write +# define _IO_new_file_xsputn _IO_file_xsputn +#endif + + +/* Convert TO_DO wide character from DATA to FP. + Then mark FP as having empty buffers. */ +int +_IO_wdo_write (_IO_FILE *fp, const wchar_t *data, _IO_size_t to_do) +{ + struct _IO_codecvt *cc = fp->_codecvt; + + if (to_do > 0) + { + if (fp->_IO_write_end == fp->_IO_write_ptr + && fp->_IO_write_end != fp->_IO_write_base) + { + if (_IO_new_do_write (fp, fp->_IO_write_base, + fp->_IO_write_ptr - fp->_IO_write_base) == EOF) + return WEOF; + } + + do + { + enum __codecvt_result result; + const wchar_t *new_data; + char mb_buf[MB_LEN_MAX]; + char *write_base, *write_ptr, *buf_end; + + if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf)) + { + /* Make sure we have room for at least one multibyte + character. */ + write_ptr = write_base = mb_buf; + buf_end = mb_buf + sizeof (mb_buf); + } + else + { + write_ptr = fp->_IO_write_ptr; + write_base = fp->_IO_write_base; + buf_end = fp->_IO_buf_end; + } + + /* Now convert from the internal format into the external buffer. */ + result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, + data, data + to_do, &new_data, + write_ptr, + buf_end, + &write_ptr); + + /* Write out what we produced so far. */ + if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF) + /* Something went wrong. */ + return WEOF; + + to_do -= new_data - data; + + /* Next see whether we had problems during the conversion. If yes, + we cannot go on. */ + if (result != __codecvt_ok + && (result != __codecvt_partial || new_data - data == 0)) + break; + + data = new_data; + } + while (to_do > 0); + } + + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + ? fp->_wide_data->_IO_buf_base + : fp->_wide_data->_IO_buf_end); + + return to_do == 0 ? 0 : WEOF; +} +libc_hidden_def (_IO_wdo_write) + + +wint_t +_IO_wfile_underflow (_IO_FILE *fp) +{ + struct _IO_codecvt *cd; + enum __codecvt_result status; + _IO_ssize_t count; + + if (__glibc_unlikely (fp->_flags & _IO_NO_READS)) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + cd = fp->_codecvt; + + /* Maybe there is something left in the external buffer. */ + if (fp->_IO_read_ptr < fp->_IO_read_end) + { + /* There is more in the external. Convert it. */ + const char *read_stop = (const char *) fp->_IO_read_ptr; + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_base = fp->_IO_read_ptr; + fp->_IO_read_ptr = (char *) read_stop; + + /* If we managed to generate some text return the next character. */ + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + if (status == __codecvt_error) + { + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + + /* Move the remaining content of the read buffer to the beginning. */ + memmove (fp->_IO_buf_base, fp->_IO_read_ptr, + fp->_IO_read_end - fp->_IO_read_ptr); + fp->_IO_read_end = (fp->_IO_buf_base + + (fp->_IO_read_end - fp->_IO_read_ptr)); + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; + } + else + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = + fp->_IO_buf_base; + + if (fp->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_IO_save_base != NULL) + { + free (fp->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + + fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = + fp->_IO_buf_base; + } + + fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = + fp->_IO_buf_base; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_wide_data->_IO_save_base != NULL) + { + free (fp->_wide_data->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_wdoallocbuf (fp); + } + + /* Flush all line buffered files before reading. */ + /* FIXME This can/should be moved to genops ?? */ + if (fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + { +#if 0 + _IO_flush_all_linebuffered (); +#else + /* We used to flush all line-buffered stream. This really isn't + required by any standard. My recollection is that + traditional Unix systems did this for stdout. stderr better + not be line buffered. So we do just that here + explicitly. --drepper */ + _IO_acquire_lock (_IO_stdout); + + if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + == (_IO_LINKED | _IO_LINE_BUF)) + _IO_OVERFLOW (_IO_stdout, EOF); + + _IO_release_lock (_IO_stdout); +#endif + } + + _IO_switch_to_get_mode (fp); + + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_buf_base; + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr = + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base; + + const char *read_ptr_copy; + char accbuf[MB_LEN_MAX]; + size_t naccbuf = 0; + again: + count = _IO_SYSREAD (fp, fp->_IO_read_end, + fp->_IO_buf_end - fp->_IO_read_end); + if (count <= 0) + { + if (count == 0 && naccbuf == 0) + { + fp->_flags |= _IO_EOF_SEEN; + fp->_offset = _IO_pos_BAD; + } + else + fp->_flags |= _IO_ERR_SEEN, count = 0; + } + fp->_IO_read_end += count; + if (count == 0) + { + if (naccbuf != 0) + /* There are some bytes in the external buffer but they don't + convert to anything. */ + __set_errno (EILSEQ); + return WEOF; + } + if (fp->_offset != _IO_pos_BAD) + _IO_pos_adjust (fp->_offset, count); + + /* Now convert the read input. */ + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_IO_read_base = fp->_IO_read_ptr; + const char *from = fp->_IO_read_ptr; + const char *to = fp->_IO_read_end; + size_t to_copy = count; + if (__glibc_unlikely (naccbuf != 0)) + { + to_copy = MIN (sizeof (accbuf) - naccbuf, count); + to = __mempcpy (&accbuf[naccbuf], from, to_copy); + naccbuf += to_copy; + from = accbuf; + } + status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + from, to, &read_ptr_copy, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + if (__glibc_unlikely (naccbuf != 0)) + fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]); + else + fp->_IO_read_ptr = (char *) read_ptr_copy; + if (fp->_wide_data->_IO_read_end == fp->_wide_data->_IO_buf_base) + { + if (status == __codecvt_error) + { + out_eilseq: + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; + } + + /* The read bytes make no complete character. Try reading again. */ + assert (status == __codecvt_partial); + + if (naccbuf == 0) + { + if (fp->_IO_read_base < fp->_IO_read_ptr) + { + /* Partially used the buffer for some input data that + produces no output. */ + size_t avail = fp->_IO_read_end - fp->_IO_read_ptr; + memmove (fp->_IO_read_base, fp->_IO_read_ptr, avail); + fp->_IO_read_ptr = fp->_IO_read_base; + fp->_IO_read_end -= avail; + goto again; + } + naccbuf = fp->_IO_read_end - fp->_IO_read_ptr; + if (naccbuf >= sizeof (accbuf)) + goto out_eilseq; + + memcpy (accbuf, fp->_IO_read_ptr, naccbuf); + } + else + { + size_t used = read_ptr_copy - accbuf; + if (used > 0) + { + memmove (accbuf, read_ptr_copy, naccbuf - used); + naccbuf -= used; + } + + if (naccbuf == sizeof (accbuf)) + goto out_eilseq; + } + + fp->_IO_read_ptr = fp->_IO_read_end = fp->_IO_read_base; + + goto again; + } + + return *fp->_wide_data->_IO_read_ptr; +} +libc_hidden_def (_IO_wfile_underflow) + + +static wint_t +_IO_wfile_underflow_mmap (_IO_FILE *fp) +{ + struct _IO_codecvt *cd; + const char *read_stop; + + if (__glibc_unlikely (fp->_flags & _IO_NO_READS)) + { + fp->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + cd = fp->_codecvt; + + /* Maybe there is something left in the external buffer. */ + if (fp->_IO_read_ptr >= fp->_IO_read_end + /* No. But maybe the read buffer is not fully set up. */ + && _IO_file_underflow_mmap (fp) == EOF) + /* Nothing available. _IO_file_underflow_mmap has set the EOF or error + flags as appropriate. */ + return WEOF; + + /* There is more in the external. Convert it. */ + read_stop = (const char *) fp->_IO_read_ptr; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* Maybe we already have a push back pointer. */ + if (fp->_wide_data->_IO_save_base != NULL) + { + free (fp->_wide_data->_IO_save_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_wdoallocbuf (fp); + } + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = + fp->_wide_data->_IO_buf_base; + (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + fp->_IO_read_ptr = (char *) read_stop; + + /* If we managed to generate some text return the next character. */ + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + + /* There is some garbage at the end of the file. */ + __set_errno (EILSEQ); + fp->_flags |= _IO_ERR_SEEN; + return WEOF; +} + +static wint_t +_IO_wfile_underflow_maybe_mmap (_IO_FILE *fp) +{ + /* This is the first read attempt. Doing the underflow will choose mmap + or vanilla operations and then punt to the chosen underflow routine. + Then we can punt to ours. */ + if (_IO_file_underflow_maybe_mmap (fp) == EOF) + return WEOF; + + return _IO_WUNDERFLOW (fp); +} + + +wint_t +_IO_wfile_overflow (_IO_FILE *f, wint_t wch) +{ + if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ + { + f->_flags |= _IO_ERR_SEEN; + __set_errno (EBADF); + return WEOF; + } + /* If currently reading or no buffer allocated. */ + if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0) + { + /* Allocate a buffer if needed. */ + if (f->_wide_data->_IO_write_base == 0) + { + _IO_wdoallocbuf (f); + _IO_wsetg (f, f->_wide_data->_IO_buf_base, + f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base); + + if (f->_IO_write_base == NULL) + { + _IO_doallocbuf (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } + } + else + { + /* Otherwise must be currently reading. If _IO_read_ptr + (and hence also _IO_read_end) is at the buffer end, + logically slide the buffer forwards one block (by setting + the read pointers to all point at the beginning of the + block). This makes room for subsequent output. + Otherwise, set the read pointers to _IO_read_end (leaving + that alone, so it can continue to correspond to the + external position). */ + if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end) + { + f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; + f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_buf_base; + } + } + f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr; + f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr; + f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end; + f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr = + f->_wide_data->_IO_read_end; + + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; + + f->_flags |= _IO_CURRENTLY_PUTTING; + if (f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) + f->_wide_data->_IO_write_end = f->_wide_data->_IO_write_ptr; + } + if (wch == WEOF) + return _IO_do_flush (f); + if (f->_wide_data->_IO_write_ptr == f->_wide_data->_IO_buf_end) + /* Buffer is really full */ + if (_IO_do_flush (f) == EOF) + return WEOF; + *f->_wide_data->_IO_write_ptr++ = wch; + if ((f->_flags & _IO_UNBUFFERED) + || ((f->_flags & _IO_LINE_BUF) && wch == L'\n')) + if (_IO_do_flush (f) == EOF) + return WEOF; + return wch; +} +libc_hidden_def (_IO_wfile_overflow) + +wint_t +_IO_wfile_sync (_IO_FILE *fp) +{ + _IO_ssize_t delta; + wint_t retval = 0; + + /* char* ptr = cur_ptr(); */ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if (_IO_do_flush (fp)) + return WEOF; + delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + if (delta != 0) + { + /* We have to find out how many bytes we have to go back in the + external buffer. */ + struct _IO_codecvt *cv = fp->_codecvt; + _IO_off64_t new_pos; + + int clen = (*cv->__codecvt_do_encoding) (cv); + + if (clen > 0) + /* It is easy, a fixed number of input bytes are used for each + wide character. */ + delta *= clen; + else + { + /* We have to find out the hard way how much to back off. + To do this we determine how much input we needed to + generate the wide characters up to the current reading + position. */ + int nread; + + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); + } + + new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (_IO_off64_t) EOF) + { + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + fp->_IO_read_end = fp->_IO_read_ptr; + } +#ifdef ESPIPE + else if (errno == ESPIPE) + ; /* Ignore error from unseekable devices. */ +#endif + else + retval = WEOF; + } + if (retval != WEOF) + fp->_offset = _IO_pos_BAD; + /* FIXME: Cleanup - can this be shared? */ + /* setg(base(), ptr, ptr); */ + return retval; +} +libc_hidden_def (_IO_wfile_sync) + +/* Adjust the internal buffer pointers to reflect the state in the external + buffer. The content between fp->_IO_read_base and fp->_IO_read_ptr is + assumed to be converted and available in the range + fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end. + + Returns 0 on success and -1 on error with the _IO_ERR_SEEN flag set. */ +static int +adjust_wide_data (_IO_FILE *fp, bool do_convert) +{ + struct _IO_codecvt *cv = fp->_codecvt; + + int clen = (*cv->__codecvt_do_encoding) (cv); + + /* Take the easy way out for constant length encodings if we don't need to + convert. */ + if (!do_convert && clen > 0) + { + fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base) + / clen); + goto done; + } + + enum __codecvt_result status; + const char *read_stop = (const char *) fp->_IO_read_base; + do + { + + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; + status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, fp->_IO_read_ptr, + &read_stop, + fp->_wide_data->_IO_read_base, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); + + /* Should we return EILSEQ? */ + if (__glibc_unlikely (status == __codecvt_error)) + { + fp->_flags |= _IO_ERR_SEEN; + return -1; + } + } + while (__builtin_expect (status == __codecvt_partial, 0)); + +done: + /* Now seek to _IO_read_end to behave as if we have read it all in. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + + return 0; +} + +/* ftell{,o} implementation for wide mode. Don't modify any state of the file + pointer while we try to get the current state of the stream except in one + case, which is when we have unflushed writes in append mode. */ +static _IO_off64_t +do_ftell_wide (_IO_FILE *fp) +{ + _IO_off64_t result, offset = 0; + + /* No point looking for offsets in the buffer if it hasn't even been + allocated. */ + if (fp->_wide_data->_IO_buf_base != NULL) + { + const wchar_t *wide_read_base; + const wchar_t *wide_read_ptr; + const wchar_t *wide_read_end; + bool unflushed_writes = (fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base); + + bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; + + /* When we have unflushed writes in append mode, seek to the end of the + file and record that offset. This is the only time we change the file + stream state and it is safe since the file handle is active. */ + if (unflushed_writes && append_mode) + { + result = _IO_SYSSEEK (fp, 0, _IO_seek_end); + if (result == _IO_pos_BAD) + return EOF; + else + fp->_offset = result; + } + + /* XXX For wide stream with backup store it is not very + reasonable to determine the offset. The pushed-back + character might require a state change and we need not be + able to compute the initial state by reverse transformation + since there is no guarantee of symmetry. So we don't even + try and return an error. */ + if (_IO_in_backup (fp)) + { + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + { + __set_errno (EINVAL); + return -1; + } + + /* Nothing in the backup store, so note the backed up pointers + without changing the state. */ + wide_read_base = fp->_wide_data->_IO_save_base; + wide_read_ptr = wide_read_base; + wide_read_end = fp->_wide_data->_IO_save_end; + } + else + { + wide_read_base = fp->_wide_data->_IO_read_base; + wide_read_ptr = fp->_wide_data->_IO_read_ptr; + wide_read_end = fp->_wide_data->_IO_read_end; + } + + struct _IO_codecvt *cv = fp->_codecvt; + int clen = (*cv->__codecvt_do_encoding) (cv); + + if (!unflushed_writes) + { + if (clen > 0) + { + offset -= (wide_read_end - wide_read_ptr) * clen; + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + } + else + { + int nread; + + size_t delta = wide_read_ptr - wide_read_base; + __mbstate_t state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, &state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + } + else + { + if (clen > 0) + offset += (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base) * clen; + else + { + size_t delta = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + + /* Allocate enough space for the conversion. */ + size_t outsize = delta * sizeof (wchar_t); + char *out = malloc (outsize); + char *outstop = out; + const wchar_t *in = fp->_wide_data->_IO_write_base; + + enum __codecvt_result status; + + __mbstate_t state = fp->_wide_data->_IO_last_state; + status = (*cv->__codecvt_do_out) (cv, &state, + in, in + delta, &in, + out, out + outsize, &outstop); + + /* We don't check for __codecvt_partial because it can be + returned on one of two conditions: either the output + buffer is full or the input sequence is incomplete. We + take care to allocate enough buffer and our input + sequences must be complete since they are accepted as + wchar_t; if not, then that is an error. */ + if (__glibc_unlikely (status != __codecvt_ok)) + { + free (out); + return WEOF; + } + + offset += outstop - out; + free (out); + } + + /* We don't trust _IO_read_end to represent the current file offset + when writing in append mode because the value would have to be + shifted to the end of the file during a flush. Use the write base + instead, along with the new offset we got above when we did a seek + to the end of the file. */ + if (append_mode) + offset += fp->_IO_write_ptr - fp->_IO_write_base; + /* For all other modes, _IO_read_end represents the file offset. */ + else + offset += fp->_IO_write_ptr - fp->_IO_read_end; + } + } + + if (fp->_offset != _IO_pos_BAD) + result = fp->_offset; + else + result = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + + if (result == EOF) + return result; + + result += offset; + + if (result < 0) + { + __set_errno (EINVAL); + return EOF; + } + + return result; +} + +_IO_off64_t +_IO_wfile_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long int count; + + /* Short-circuit into a separate function. We don't want to mix any + functionality and we don't want to touch anything inside the FILE + object. */ + if (mode == 0) + return do_ftell_wide (fp); + + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = ((fp->_wide_data->_IO_read_base + == fp->_wide_data->_IO_read_end) + && (fp->_wide_data->_IO_write_base + == fp->_wide_data->_IO_write_ptr)); + + bool was_writing = ((fp->_wide_data->_IO_write_ptr + > fp->_wide_data->_IO_write_base) + || _IO_in_put_mode (fp)); + + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set + egptr to pptr. That can't be done in the current design, + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ + if (was_writing && _IO_switch_to_wget_mode (fp)) + return WEOF; + + if (fp->_wide_data->_IO_buf_base == NULL) + { + /* It could be that we already have a pushback buffer. */ + if (fp->_wide_data->_IO_read_base != NULL) + { + free (fp->_wide_data->_IO_read_base); + fp->_flags &= ~_IO_IN_BACKUP; + } + _IO_doallocbuf (fp); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + } + + switch (dir) + { + struct _IO_codecvt *cv; + int clen; + + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). To do this we must + find out which position in the external buffer corresponds to + the current position in the internal buffer. */ + cv = fp->_codecvt; + clen = (*cv->__codecvt_do_encoding) (cv); + + if (mode != 0 || !was_writing) + { + if (clen > 0) + { + offset -= (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr) * clen; + /* Adjust by readahead in external buffer. */ + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + } + else + { + int nread; + + delta = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; + nread = (*cv->__codecvt_do_length) (cv, + &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); + fp->_IO_read_ptr = fp->_IO_read_base + nread; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + } + + if (fp->_offset == _IO_pos_BAD) + goto dumb; + + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + + dir = _IO_seek_set; + break; + case _IO_seek_set: + break; + case _IO_seek_end: + { + struct stat64 st; + if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) + { + offset += st.st_size; + dir = _IO_seek_set; + } + else + goto dumb; + } + } + /* At this point, dir==_IO_seek_set. */ + + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) + { + _IO_off64_t start_offset = (fp->_offset + - (fp->_IO_read_end - fp->_IO_buf_base)); + if (offset >= start_offset && offset < fp->_offset) + { + _IO_setg (fp, fp->_IO_buf_base, + fp->_IO_buf_base + (offset - start_offset), + fp->_IO_read_end); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + + if (adjust_wide_data (fp, false)) + goto dumb; + + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + goto resync; + } + } + + if (fp->_flags & _IO_NO_READS) + goto dumb; + + /* Try to seek to a block boundary, to improve kernel page management. */ + new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); + delta = offset - new_offset; + if (delta > fp->_IO_buf_end - fp->_IO_buf_base) + { + new_offset = offset; + delta = 0; + } + result = _IO_SYSSEEK (fp, new_offset, 0); + if (result < 0) + return EOF; + if (delta == 0) + count = 0; + else + { + count = _IO_SYSREAD (fp, fp->_IO_buf_base, + (must_be_exact + ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); + if (count < delta) + { + /* We weren't allowed to read, but try to seek the remainder. */ + offset = count == EOF ? delta : delta-count; + dir = _IO_seek_cur; + goto dumb; + } + } + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, + fp->_IO_buf_base + count); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + + if (adjust_wide_data (fp, true)) + goto dumb; + + fp->_offset = result + count; + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + return offset; + dumb: + + _IO_unsave_markers (fp); + result = _IO_SYSSEEK (fp, offset, dir); + if (result != EOF) + { + _IO_mask_flags (fp, 0, _IO_EOF_SEEN); + fp->_offset = result; + _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); + _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); + _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, + fp->_wide_data->_IO_buf_base); + } + return result; + +resync: + /* We need to do it since it is possible that the file offset in + the kernel may be changed behind our back. It may happen when + we fopen a file and then do a fork. One process may access the + file and the kernel file offset will be changed. */ + if (fp->_offset >= 0) + _IO_SYSSEEK (fp, fp->_offset, 0); + + return offset; +} +libc_hidden_def (_IO_wfile_seekoff) + + +_IO_size_t +_IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +{ + const wchar_t *s = (const wchar_t *) data; + _IO_size_t to_do = n; + int must_flush = 0; + _IO_size_t count; + + if (n <= 0) + return 0; + /* This is an optimized implementation. + If the amount to be written straddles a block boundary + (or the filebuf is unbuffered), use sys_write directly. */ + + /* First figure out how much space is available in the buffer. */ + count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr; + if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) + { + count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr; + if (count >= n) + { + const wchar_t *p; + for (p = s + n; p > s; ) + { + if (*--p == L'\n') + { + count = p - s + 1; + must_flush = 1; + break; + } + } + } + } + /* Then fill the buffer. */ + if (count > 0) + { + if (count > to_do) + count = to_do; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + wmemcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else + { + wchar_t *p = f->_wide_data->_IO_write_ptr; + int i = (int) count; + while (--i >= 0) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + to_do -= count; + } + if (to_do > 0) + to_do -= _IO_wdefault_xsputn (f, s, to_do); + if (must_flush + && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base) + _IO_wdo_write (f, f->_wide_data->_IO_write_base, + f->_wide_data->_IO_write_ptr + - f->_wide_data->_IO_write_base); + + return n - to_do; +} +libc_hidden_def (_IO_wfile_xsputn) + + +const struct _IO_jump_t _IO_wfile_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), + JUMP_INIT(xsputn, _IO_wfile_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn), + JUMP_INIT(seekoff, _IO_wfile_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_new_file_setbuf), + JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; +libc_hidden_data_def (_IO_wfile_jumps) + + +const struct _IO_jump_t _IO_wfile_jumps_mmap libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), + JUMP_INIT(xsputn, _IO_wfile_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn), + JUMP_INIT(seekoff, _IO_wfile_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf_mmap), + JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close_mmap), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), + JUMP_INIT(xsputn, _IO_wfile_xsputn), + JUMP_INIT(xsgetn, _IO_file_xsgetn), + JUMP_INIT(seekoff, _IO_wfile_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_file_setbuf_mmap), + JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync), + JUMP_INIT(doallocate, _IO_wfile_doallocate), + JUMP_INIT(read, _IO_file_read), + JUMP_INIT(write, _IO_new_file_write), + JUMP_INIT(seek, _IO_file_seek), + JUMP_INIT(close, _IO_file_close), + JUMP_INIT(stat, _IO_file_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; diff --git a/REORG.TODO/libio/wgenops.c b/REORG.TODO/libio/wgenops.c new file mode 100644 index 0000000000..d8072abea0 --- /dev/null +++ b/REORG.TODO/libio/wgenops.c @@ -0,0 +1,698 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Ulrich Drepper <drepper@cygnus.com>. + Based on the single byte version by Per Bothner <bothner@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +/* Generic or default I/O operations. */ + +#include "libioP.h" +#include <stdlib.h> +#include <string.h> +#include <wchar.h> + + +#ifndef _LIBC +# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n) +#endif + + +static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW +#ifdef _LIBC + internal_function +#endif + ; + +/* Return minimum _pos markers + Assumes the current get area is the main get area. */ +_IO_ssize_t +_IO_least_wmarker (_IO_FILE *fp, wchar_t *end_p) +{ + _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base; + struct _IO_marker *mark; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + if (mark->_pos < least_so_far) + least_so_far = mark->_pos; + return least_so_far; +} +libc_hidden_def (_IO_least_wmarker) + +/* Switch current get area from backup buffer to (start of) main get area. */ +void +_IO_switch_to_main_wget_area (_IO_FILE *fp) +{ + wchar_t *tmp; + fp->_flags &= ~_IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end= tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base; +} +libc_hidden_def (_IO_switch_to_main_wget_area) + + +/* Switch current get area from main get area to (end of) backup area. */ +void +_IO_switch_to_wbackup_area (_IO_FILE *fp) +{ + wchar_t *tmp; + fp->_flags |= _IO_IN_BACKUP; + /* Swap _IO_read_end and _IO_save_end. */ + tmp = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end; + fp->_wide_data->_IO_save_end = tmp; + /* Swap _IO_read_base and _IO_save_base. */ + tmp = fp->_wide_data->_IO_read_base; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base; + fp->_wide_data->_IO_save_base = tmp; + /* Set _IO_read_ptr. */ + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; +} +libc_hidden_def (_IO_switch_to_wbackup_area) + + +void +_IO_wsetb (_IO_FILE *f, wchar_t *b, wchar_t *eb, int a) +{ + if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF)) + free (f->_wide_data->_IO_buf_base); + f->_wide_data->_IO_buf_base = b; + f->_wide_data->_IO_buf_end = eb; + if (a) + f->_flags2 &= ~_IO_FLAGS2_USER_WBUF; + else + f->_flags2 |= _IO_FLAGS2_USER_WBUF; +} +libc_hidden_def (_IO_wsetb) + + +wint_t +_IO_wdefault_pbackfail (_IO_FILE *fp, wint_t c) +{ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && !_IO_in_backup (fp) + && (wint_t) fp->_IO_read_ptr[-1] == c) + --fp->_IO_read_ptr; + else + { + /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ + if (!_IO_in_backup (fp)) + { + /* We need to keep the invariant that the main get area + logically follows the backup area. */ + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && _IO_have_wbackup (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr)) + return WEOF; + } + else if (!_IO_have_wbackup (fp)) + { + /* No backup buffer: allocate one. */ + /* Use nshort buffer, if unused? (probably not) FIXME */ + int backup_size = 128; + wchar_t *bbuf = (wchar_t *) malloc (backup_size + * sizeof (wchar_t)); + if (bbuf == NULL) + return WEOF; + fp->_wide_data->_IO_save_base = bbuf; + fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base + + backup_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end; + } + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr; + _IO_switch_to_wbackup_area (fp); + } + else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base) + { + /* Increase size of existing backup buffer. */ + _IO_size_t new_size; + _IO_size_t old_size = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_base); + wchar_t *new_buf; + new_size = 2 * old_size; + new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t)); + if (new_buf == NULL) + return WEOF; + __wmemcpy (new_buf + (new_size - old_size), + fp->_wide_data->_IO_read_base, old_size); + free (fp->_wide_data->_IO_read_base); + _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size), + new_buf + new_size); + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr; + } + + *--fp->_wide_data->_IO_read_ptr = c; + } + return c; +} +libc_hidden_def (_IO_wdefault_pbackfail) + + +void +_IO_wdefault_finish (_IO_FILE *fp, int dummy) +{ + struct _IO_marker *mark; + if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) + { + free (fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL; + } + + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_sbuf = NULL; + + if (fp->_IO_save_base) + { + free (fp->_wide_data->_IO_save_base); + fp->_IO_save_base = NULL; + } + +#ifdef _IO_MTSAFE_IO + if (fp->_lock != NULL) + _IO_lock_fini (*fp->_lock); +#endif + + _IO_un_link ((struct _IO_FILE_plus *) fp); +} +libc_hidden_def (_IO_wdefault_finish) + + +wint_t +_IO_wdefault_uflow (_IO_FILE *fp) +{ + wint_t wch; + wch = _IO_UNDERFLOW (fp); + if (wch == WEOF) + return WEOF; + return *fp->_wide_data->_IO_read_ptr++; +} +libc_hidden_def (_IO_wdefault_uflow) + + +wint_t +__woverflow (_IO_FILE *f, wint_t wch) +{ + if (f->_mode == 0) + _IO_fwide (f, 1); + return _IO_OVERFLOW (f, wch); +} +libc_hidden_def (__woverflow) + + +wint_t +__wuflow (_IO_FILE *fp) +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return WEOF; + + if (fp->_mode == 0) + _IO_fwide (fp, 1); + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_wget_mode (fp) == EOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_wget_area (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr++; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return WEOF; + } + else if (_IO_have_wbackup (fp)) + _IO_free_wbackup_area (fp); + return _IO_UFLOW (fp); +} +libc_hidden_def (__wuflow) + +wint_t +__wunderflow (_IO_FILE *fp) +{ + if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) + return WEOF; + + if (fp->_mode == 0) + _IO_fwide (fp, 1); + if (_IO_in_put_mode (fp)) + if (_IO_switch_to_wget_mode (fp) == EOF) + return WEOF; + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + if (_IO_in_backup (fp)) + { + _IO_switch_to_main_wget_area (fp); + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + } + if (_IO_have_markers (fp)) + { + if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) + return WEOF; + } + else if (_IO_have_backup (fp)) + _IO_free_wbackup_area (fp); + return _IO_UNDERFLOW (fp); +} +libc_hidden_def (__wunderflow) + + +_IO_size_t +_IO_wdefault_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +{ + const wchar_t *s = (const wchar_t *) data; + _IO_size_t more = n; + if (more <= 0) + return 0; + for (;;) + { + /* Space available. */ + _IO_ssize_t count = (f->_wide_data->_IO_write_end + - f->_wide_data->_IO_write_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + f->_wide_data->_IO_write_ptr = + __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); +#else + memcpy (f->_wide_data->_IO_write_ptr, s, count); + f->_wide_data->_IO_write_ptr += count; +#endif + s += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = f->_wide_data->_IO_write_ptr; + _IO_ssize_t i; + for (i = count; --i >= 0; ) + *p++ = *s++; + f->_wide_data->_IO_write_ptr = p; + } + more -= count; + } + if (more == 0 || __woverflow (f, *s++) == WEOF) + break; + more--; + } + return n - more; +} +libc_hidden_def (_IO_wdefault_xsputn) + + +_IO_size_t +_IO_wdefault_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +{ + _IO_size_t more = n; + wchar_t *s = (wchar_t*) data; + for (;;) + { + /* Data available. */ + _IO_ssize_t count = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); + if (count > 0) + { + if ((_IO_size_t) count > more) + count = more; + if (count > 20) + { +#ifdef _LIBC + s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count); +#else + memcpy (s, fp->_wide_data->_IO_read_ptr, count); + s += count; +#endif + fp->_wide_data->_IO_read_ptr += count; + } + else if (count <= 0) + count = 0; + else + { + wchar_t *p = fp->_wide_data->_IO_read_ptr; + int i = (int) count; + while (--i >= 0) + *s++ = *p++; + fp->_wide_data->_IO_read_ptr = p; + } + more -= count; + } + if (more == 0 || __wunderflow (fp) == WEOF) + break; + } + return n - more; +} +libc_hidden_def (_IO_wdefault_xsgetn) + + +void +_IO_wdoallocbuf (_IO_FILE *fp) +{ + if (fp->_wide_data->_IO_buf_base) + return; + if (!(fp->_flags & _IO_UNBUFFERED)) + if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF) + return; + _IO_wsetb (fp, fp->_wide_data->_shortbuf, + fp->_wide_data->_shortbuf + 1, 0); +} +libc_hidden_def (_IO_wdoallocbuf) + + +int +_IO_wdefault_doallocate (_IO_FILE *fp) +{ + wchar_t *buf; + + buf = malloc (_IO_BUFSIZ); + if (__glibc_unlikely (buf == NULL)) + return EOF; + _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1); + return 1; +} +libc_hidden_def (_IO_wdefault_doallocate) + + +int +_IO_switch_to_wget_mode (_IO_FILE *fp) +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) + if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF) + return EOF; + if (_IO_in_backup (fp)) + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base; + else + { + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + } + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr + = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + return 0; +} +libc_hidden_def (_IO_switch_to_wget_mode) + +void +_IO_free_wbackup_area (_IO_FILE *fp) +{ + if (_IO_in_backup (fp)) + _IO_switch_to_main_wget_area (fp); /* Just in case. */ + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = NULL; + fp->_wide_data->_IO_save_end = NULL; + fp->_wide_data->_IO_backup_base = NULL; +} +libc_hidden_def (_IO_free_wbackup_area) + +#if 0 +int +_IO_switch_to_wput_mode (_IO_FILE *fp) +{ + fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + /* Following is wrong if line- or un-buffered? */ + fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP + ? fp->_wide_data->_IO_read_end + : fp->_wide_data->_IO_buf_end); + + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end; + + fp->_flags |= _IO_CURRENTLY_PUTTING; + return 0; +} +#endif + + +static int +#ifdef _LIBC +internal_function +#endif +save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) +{ + /* Append [_IO_read_base..end_p] to backup area. */ + _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p); + /* needed_size is how much space we need in the backup area. */ + _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) + - least_mark); + /* FIXME: Dubious arithmetic if pointers are NULL */ + _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end + - fp->_wide_data->_IO_save_base); + _IO_size_t avail; /* Extra space available for future expansion. */ + _IO_ssize_t delta; + struct _IO_marker *mark; + if (needed_size > current_Bsize) + { + wchar_t *new_buffer; + avail = 100; + new_buffer = (wchar_t *) malloc ((avail + needed_size) + * sizeof (wchar_t)); + if (new_buffer == NULL) + return EOF; /* FIXME */ + if (least_mark < 0) + { +#ifdef _LIBC + __wmempcpy (__wmempcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark), + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (new_buffer + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else + { +#ifdef _LIBC + __wmemcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (new_buffer + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + free (fp->_wide_data->_IO_save_base); + fp->_wide_data->_IO_save_base = new_buffer; + fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size; + } + else + { + avail = current_Bsize - needed_size; + if (least_mark < 0) + { +#ifdef _LIBC + __wmemmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark); + __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + end_p - fp->_wide_data->_IO_read_base); +#else + memmove (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_save_end + least_mark, + -least_mark * sizeof (wchar_t)); + memcpy (fp->_wide_data->_IO_save_base + avail - least_mark, + fp->_wide_data->_IO_read_base, + (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); +#endif + } + else if (needed_size > 0) +#ifdef _LIBC + __wmemcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size); +#else + memcpy (fp->_wide_data->_IO_save_base + avail, + fp->_wide_data->_IO_read_base + least_mark, + needed_size * sizeof (wchar_t)); +#endif + } + fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail; + /* Adjust all the streammarkers. */ + delta = end_p - fp->_wide_data->_IO_read_base; + for (mark = fp->_markers; mark != NULL; mark = mark->_next) + mark->_pos -= delta; + return 0; +} + +wint_t +_IO_sputbackwc (_IO_FILE *fp, wint_t c) +{ + wint_t result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base + && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c) + { + fp->_wide_data->_IO_read_ptr--; + result = c; + } + else + result = _IO_PBACKFAIL (fp, c); + + if (result != WEOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} +libc_hidden_def (_IO_sputbackwc) + +wint_t +_IO_sungetwc (_IO_FILE *fp) +{ + wint_t result; + + if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base) + { + fp->_wide_data->_IO_read_ptr--; + result = *fp->_wide_data->_IO_read_ptr; + } + else + result = _IO_PBACKFAIL (fp, EOF); + + if (result != WEOF) + fp->_flags &= ~_IO_EOF_SEEN; + + return result; +} + + +unsigned +_IO_adjust_wcolumn (unsigned start, const wchar_t *line, int count) +{ + const wchar_t *ptr = line + count; + while (ptr > line) + if (*--ptr == L'\n') + return line + count - ptr - 1; + return start + count; +} + +void +_IO_init_wmarker (struct _IO_marker *marker, _IO_FILE *fp) +{ + marker->_sbuf = fp; + if (_IO_in_put_mode (fp)) + _IO_switch_to_wget_mode (fp); + if (_IO_in_backup (fp)) + marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end; + else + marker->_pos = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + + /* Should perhaps sort the chain? */ + marker->_next = fp->_markers; + fp->_markers = marker; +} + +#define BAD_DELTA EOF + +/* Return difference between MARK and current position of MARK's stream. */ +int +_IO_wmarker_delta (struct _IO_marker *mark) +{ + int cur_pos; + if (mark->_sbuf == NULL) + return BAD_DELTA; + if (_IO_in_backup (mark->_sbuf)) + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_end); + else + cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr + - mark->_sbuf->_wide_data->_IO_read_base); + return mark->_pos - cur_pos; +} + +int +_IO_seekwmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) +{ + if (mark->_sbuf != fp) + return EOF; + if (mark->_pos >= 0) + { + if (_IO_in_backup (fp)) + _IO_switch_to_main_wget_area (fp); + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + mark->_pos); + } + else + { + if (!_IO_in_backup (fp)) + _IO_switch_to_wbackup_area (fp); + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos; + } + return 0; +} + +void +_IO_unsave_wmarkers (_IO_FILE *fp) +{ + struct _IO_marker *mark = fp->_markers; + if (mark) + { +#ifdef TODO + streampos offset = seekoff (0, ios::cur, ios::in); + if (offset != EOF) + { + offset += eGptr () - Gbase (); + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (mark->_pos + offset); + } + else + { + for ( ; mark != NULL; mark = mark->_next) + mark->set_streampos (EOF); + } +#endif + fp->_markers = 0; + } + + if (_IO_have_backup (fp)) + _IO_free_wbackup_area (fp); +} diff --git a/REORG.TODO/libio/wmemstream.c b/REORG.TODO/libio/wmemstream.c new file mode 100644 index 0000000000..5bc77f52ee --- /dev/null +++ b/REORG.TODO/libio/wmemstream.c @@ -0,0 +1,144 @@ +/* Copyright (C) 1995-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "libioP.h" +#include "strfile.h" +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> + + +struct _IO_FILE_wmemstream +{ + _IO_strfile _sf; + wchar_t **bufloc; + _IO_size_t *sizeloc; +}; + + +static int _IO_wmem_sync (_IO_FILE* fp) __THROW; +static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW; + + +static const struct _IO_jump_t _IO_wmem_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_wmem_finish), + JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT (xsputn, _IO_wdefault_xsputn), + JUMP_INIT (xsgetn, _IO_wdefault_xsgetn), + JUMP_INIT (seekoff, _IO_wstr_seekoff), + JUMP_INIT (seekpos, _IO_default_seekpos), + JUMP_INIT (setbuf, _IO_default_setbuf), + JUMP_INIT (sync, _IO_wmem_sync), + JUMP_INIT (doallocate, _IO_wdefault_doallocate), + JUMP_INIT (read, _IO_default_read), + JUMP_INIT (write, _IO_default_write), + JUMP_INIT (seek, _IO_default_seek), + JUMP_INIT (close, _IO_default_close), + JUMP_INIT (stat, _IO_default_stat), + JUMP_INIT (showmanyc, _IO_default_showmanyc), + JUMP_INIT (imbue, _IO_default_imbue) +}; + +/* Open a stream that writes into a malloc'd buffer that is expanded as + necessary. *BUFLOC and *SIZELOC are updated with the buffer's location + and the number of characters written on fflush or fclose. */ +_IO_FILE * +open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc) +{ + struct locked_FILE + { + struct _IO_FILE_wmemstream fp; +#ifdef _IO_MTSAFE_IO + _IO_lock_t lock; +#endif + struct _IO_wide_data wd; + } *new_f; + wchar_t *buf; + + new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); + if (new_f == NULL) + return NULL; +#ifdef _IO_MTSAFE_IO + new_f->fp._sf._sbf._f._lock = &new_f->lock; +#endif + + buf = calloc (1, _IO_BUFSIZ); + if (buf == NULL) + { + free (new_f); + return NULL; + } + _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps); + _IO_fwide (&new_f->fp._sf._sbf._f, 1); + _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf, + _IO_BUFSIZ / sizeof (wchar_t), buf); + new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF; + new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; + new_f->fp._sf._s._free_buffer = (_IO_free_type) free; + + new_f->fp.bufloc = bufloc; + new_f->fp.sizeloc = sizeloc; + + return (_IO_FILE *) &new_f->fp._sf._sbf; +} + + +static int +_IO_wmem_sync (_IO_FILE *fp) +{ + struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp; + + if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end) + { + _IO_wstr_overflow (fp, '\0'); + --fp->_wide_data->_IO_write_ptr; + } + + *mp->bufloc = fp->_wide_data->_IO_write_base; + *mp->sizeloc = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + + return 0; +} + + +static void +_IO_wmem_finish (_IO_FILE *fp, int dummy) +{ + struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp; + + *mp->bufloc = (wchar_t *) realloc (fp->_wide_data->_IO_write_base, + (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base + 1) + * sizeof (wchar_t)); + if (*mp->bufloc != NULL) + { + size_t len = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + (*mp->bufloc)[len] = '\0'; + *mp->sizeloc = len; + + fp->_wide_data->_IO_buf_base = NULL; + } + + _IO_wstr_finish (fp, 0); +} diff --git a/REORG.TODO/libio/wprintf.c b/REORG.TODO/libio/wprintf.c new file mode 100644 index 0000000000..7a26a0b826 --- /dev/null +++ b/REORG.TODO/libio/wprintf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + +/* Write formatted output to stdout from the format string FORMAT. */ +/* VARARGS1 */ +int +__wprintf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = __vfwprintf (stdout, format, arg); + va_end (arg); + + return done; +} +ldbl_strong_alias (__wprintf, wprintf) diff --git a/REORG.TODO/libio/wscanf.c b/REORG.TODO/libio/wscanf.c new file mode 100644 index 0000000000..debc24aa1c --- /dev/null +++ b/REORG.TODO/libio/wscanf.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libioP.h> +#include <stdarg.h> +#include <stdio.h> +#include <wchar.h> + + +/* Read formatted input from stdin according to the format string FORMAT. */ +/* VARARGS1 */ +int +__wscanf (const wchar_t *format, ...) +{ + va_list arg; + int done; + + va_start (arg, format); + done = _IO_vfwscanf (stdin, format, arg, NULL); + va_end (arg); + + return done; +} +ldbl_strong_alias (__wscanf, wscanf) diff --git a/REORG.TODO/libio/wstrops.c b/REORG.TODO/libio/wstrops.c new file mode 100644 index 0000000000..bb62fd6702 --- /dev/null +++ b/REORG.TODO/libio/wstrops.c @@ -0,0 +1,388 @@ +/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. + + As a special exception, if you link the code in this file with + files compiled with a GNU compiler to produce an executable, + that does not cause the resulting executable to be covered by + the GNU Lesser General Public License. This exception does not + however invalidate any other reasons why the executable file + might be covered by the GNU Lesser General Public License. + This exception applies to code released by its copyright holders + in files containing the exception. */ + +#include <assert.h> +#include "strfile.h" +#include "libioP.h" +#include <string.h> +#include <wchar.h> +#include <stdio_ext.h> + +void +_IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size, + wchar_t *pstart) +{ + wchar_t *end; + + if (size == 0) + end = ptr + __wcslen (ptr); + else if ((_IO_size_t) ptr + size * sizeof (wchar_t) > (_IO_size_t) ptr) + end = ptr + size; + else + /* Even for misaligned ptr make sure there is integral number of wide + characters. */ + end = ptr + (-1 - (_IO_size_t) ptr) / sizeof (wchar_t); + _IO_wsetb (fp, ptr, end, 0); + + fp->_wide_data->_IO_write_base = ptr; + fp->_wide_data->_IO_read_base = ptr; + fp->_wide_data->_IO_read_ptr = ptr; + if (pstart) + { + fp->_wide_data->_IO_write_ptr = pstart; + fp->_wide_data->_IO_write_end = end; + fp->_wide_data->_IO_read_end = pstart; + } + else + { + fp->_wide_data->_IO_write_ptr = ptr; + fp->_wide_data->_IO_write_end = ptr; + fp->_wide_data->_IO_read_end = end; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; +} + +_IO_wint_t +_IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) +{ + int flush_only = c == WEOF; + _IO_size_t pos; + if (fp->_flags & _IO_NO_WRITES) + return flush_only ? 0 : WEOF; + if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags |= _IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; + } + pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; + if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) + { + if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */ + return WEOF; + else + { + wchar_t *new_buf; + wchar_t *old_buf = fp->_wide_data->_IO_buf_base; + size_t old_wblen = _IO_wblen (fp); + _IO_size_t new_size = 2 * old_wblen + 100; + + if (__glibc_unlikely (new_size < old_wblen) + || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t))) + return EOF; + + new_buf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size + * sizeof (wchar_t)); + if (new_buf == NULL) + { + /* __ferror(fp) = 1; */ + return WEOF; + } + if (old_buf) + { + __wmemcpy (new_buf, old_buf, old_wblen); + (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + /* Make sure _IO_setb won't try to delete _IO_buf_base. */ + fp->_wide_data->_IO_buf_base = NULL; + } + + __wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen); + + _IO_wsetb (fp, new_buf, new_buf + new_size, 1); + fp->_wide_data->_IO_read_base = + new_buf + (fp->_wide_data->_IO_read_base - old_buf); + fp->_wide_data->_IO_read_ptr = + new_buf + (fp->_wide_data->_IO_read_ptr - old_buf); + fp->_wide_data->_IO_read_end = + new_buf + (fp->_wide_data->_IO_read_end - old_buf); + fp->_wide_data->_IO_write_ptr = + new_buf + (fp->_wide_data->_IO_write_ptr - old_buf); + + fp->_wide_data->_IO_write_base = new_buf; + fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end; + } + } + + if (!flush_only) + *fp->_wide_data->_IO_write_ptr++ = c; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + return c; +} + + +_IO_wint_t +_IO_wstr_underflow (_IO_FILE *fp) +{ + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING)) + { + fp->_flags &= ~_IO_CURRENTLY_PUTTING; + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_end; + } + if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) + return *fp->_wide_data->_IO_read_ptr; + else + return WEOF; +} + + +/* The size of the valid part of the buffer. */ +_IO_ssize_t +_IO_wstr_count (_IO_FILE *fp) +{ + struct _IO_wide_data *wd = fp->_wide_data; + + return ((wd->_IO_write_ptr > wd->_IO_read_end + ? wd->_IO_write_ptr : wd->_IO_read_end) + - wd->_IO_read_base); +} + + +static int +enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) +{ + if ((_IO_ssize_t) offset <= _IO_wblen (fp)) + return 0; + + struct _IO_wide_data *wd = fp->_wide_data; + + _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base; + + /* Try to enlarge the buffer. */ + if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) + /* User-provided buffer. */ + return 1; + + _IO_size_t newsize = offset + 100; + if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t))) + return 1; + + wchar_t *oldbuf = wd->_IO_buf_base; + wchar_t *newbuf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize + * sizeof (wchar_t)); + if (newbuf == NULL) + return 1; + + if (oldbuf != NULL) + { + __wmemcpy (newbuf, oldbuf, _IO_wblen (fp)); + (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); + /* Make sure _IO_setb won't try to delete + _IO_buf_base. */ + wd->_IO_buf_base = NULL; + } + + _IO_wsetb (fp, newbuf, newbuf + newsize, 1); + + if (reading) + { + wd->_IO_write_base = newbuf + (wd->_IO_write_base - oldbuf); + wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf); + wd->_IO_write_end = newbuf + (wd->_IO_write_end - oldbuf); + wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf); + + wd->_IO_read_base = newbuf; + wd->_IO_read_end = wd->_IO_buf_end; + } + else + { + wd->_IO_read_base = newbuf + (wd->_IO_read_base - oldbuf); + wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf); + wd->_IO_read_end = newbuf + (wd->_IO_read_end - oldbuf); + wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf); + + wd->_IO_write_base = newbuf; + wd->_IO_write_end = wd->_IO_buf_end; + } + + /* Clear the area between the last write position and th + new position. */ + assert (offset >= oldend); + if (reading) + __wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend); + else + __wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend); + + return 0; +} + +static void +_IO_wstr_switch_to_get_mode (_IO_FILE *fp) +{ + if (_IO_in_backup (fp)) + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base; + else + { + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + } + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + + fp->_flags &= ~_IO_CURRENTLY_PUTTING; +} + +_IO_off64_t +_IO_wstr_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +{ + _IO_off64_t new_pos; + + if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) + mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + + bool was_writing = (fp->_wide_data->_IO_write_ptr > + fp->_wide_data->_IO_write_base + || _IO_in_put_mode (fp)); + if (was_writing) + _IO_wstr_switch_to_get_mode (fp); + + if (mode == 0) + { + new_pos = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + } + else + { + _IO_ssize_t cur_size = _IO_wstr_count (fp); + new_pos = EOF; + + /* Move the get pointer, if requested. */ + if (mode & _IOS_INPUT) + { + _IO_ssize_t base; + switch (dir) + { + case _IO_seek_set: + base = 0; + break; + case _IO_seek_cur: + base = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + break; + default: /* case _IO_seek_end: */ + base = cur_size; + break; + } + _IO_ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 1) != 0) + return EOF; + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + base); + fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base + + cur_size); + new_pos = offset; + } + + /* Move the put pointer, if requested. */ + if (mode & _IOS_OUTPUT) + { + _IO_ssize_t base; + switch (dir) + { + case _IO_seek_set: + base = 0; + break; + case _IO_seek_cur: + base = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + break; + default: /* case _IO_seek_end: */ + base = cur_size; + break; + } + _IO_ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 0) != 0) + return EOF; + fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base + + base); + new_pos = base; + } + } + return new_pos; +} + +_IO_wint_t +_IO_wstr_pbackfail (_IO_FILE *fp, _IO_wint_t c) +{ + if ((fp->_flags & _IO_NO_WRITES) && c != WEOF) + return WEOF; + return _IO_wdefault_pbackfail (fp, c); +} + +void +_IO_wstr_finish (_IO_FILE *fp, int dummy) +{ + if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_buf_base = NULL; + + _IO_wdefault_finish (fp, 0); +} + +const struct _IO_jump_t _IO_wstr_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), + JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow), + JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow), + JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow), + JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), + JUMP_INIT(xsputn, _IO_wdefault_xsputn), + JUMP_INIT(xsgetn, _IO_wdefault_xsgetn), + JUMP_INIT(seekoff, _IO_wstr_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_wdefault_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; |