diff options
author | Ulrich Drepper <drepper@redhat.com> | 1999-06-16 22:55:47 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1999-06-16 22:55:47 +0000 |
commit | d64b6ad07585b8a37e5fecc9a47fcee766d52ede (patch) | |
tree | 076b36cc9c1b82254348212e75939d842885563a /libio/wstrops.c | |
parent | bc938d3de936a8e429b16237180c046139be8247 (diff) | |
download | glibc-d64b6ad07585b8a37e5fecc9a47fcee766d52ede.tar.gz |
Update.
* Versions.def: Add GLIBC_2.2 for libc.
* iconv/gconv.h: Make header suitable for inclusion in public header
by protecting all names with __.
* iconv/gconv.c: Adapt for symbol name changes.
* iconv/gconv.h: Likewise.
* iconv/gconv_builtin.c: Likewise.
* iconv/gconv_close.c: Likewise.
* iconv/gconv_db.c: Likewise.
* iconv/gconv_dl.c: Likewise.
* iconv/gconv_int.h: Likewise.
* iconv/gconv_open.c: Likewise.
* iconv/gconv_simple.c: Likewise.
* iconv/iconv.c: Likewise.
* iconv/iconv_close.c: Likewise.
* iconv/iconv_open.c: Likewise.
* iconv/loop.c: Likewise.
* iconv/skeleton.c: Likewise.
* iconvdata/8bit-gap.c: Likewise.
* iconvdata/8bit-generic.c: Likewise.
* iconvdata/ansi_x3.110.c: Likewise.
* iconvdata/big5.c: Likewise.
* iconvdata/cns11643.h: Likewise.
* iconvdata/cns11643l1.h: Likewise.
* iconvdata/euc-cn.c: Likewise.
* iconvdata/euc-jp.c: Likewise.
* iconvdata/euc-kr.c: Likewise.
* iconvdata/euc-tw.c: Likewise.
* iconvdata/gb2312.h: Likewise.
* iconvdata/iso-2022-jp.c: Likewise.
* iconvdata/iso-2022-kr.c: Likewise.
* iconvdata/iso646.c: Likewise.
* iconvdata/iso8859-1.c: Likewise.
* iconvdata/iso_6937-2.c: Likewise.
* iconvdata/iso_6937.c: Likewise.
* iconvdata/jis0201.h: Likewise.
* iconvdata/jis0208.h: Likewise.
* iconvdata/jis0212.h: Likewise.
* iconvdata/johab.c: Likewise.
* iconvdata/ksc5601.h: Likewise.
* iconvdata/sjis.c: Likewise.
* iconvdata/t.61.c: Likewise.
* iconvdata/uhc.c: Likewise.
* stdlib/mblen.c: Likewise.
* stdlib/mbtowc.c: Likewise.
* stdlib/wctomb.c: Likewise.
* wcsmbs/btowc.c: Likewise.
* wcsmbs/mbrtowc.c: Likewise.
* wcsmbs/mbsnrtowcs.c: Likewise.
* wcsmbs/mbsrtowcs.c: Likewise.
* wcsmbs/wchar.h: Likewise.
* wcsmbs/wcrtomb.c: Likewise.
* wcsmbs/wcsmbsload.c: Likewise.
* wcsmbs/wcsmbsload.h: Likewise.
* wcsmbs/wcsnrtombs.c: Likewise.
* wcsmbs/wcsrtombs.c: Likewise.
* wcsmbs/wctob.c: Likewise.
* include/limits.h (MB_LEN_MAX): Increase to 16.
* sysdeps/generic/_G_config.h: Define _G_fpos_t as struct. Define
_G_iconv_t.
* sysdeps/unix/sysv/linux/_G_config.h: Likewise.
* include/wchar.h: Change mbstate_t to __mbstate_t.
* libio/Makefile (routines): Add wfiledoalloc, oldiofgetpos,
oldiofgetpos64, oldiofsetpos, oldiofsetpos64, fputwc, fputwc_u,
getwc, getwc_u, getwchar, getwchar_u, iofgetws, iofgetws_u,
iofputws, iofputws_u, iogetwline, iowpadn, ioungetwc, putwc, putwc_u,
putchar, putchar_u, swprintf, vwprintf, wprintf, wscanf, fwscanf,
vwscanf, vswprintf, iovswscanf, swscanf, wgenops, wstrops, wfileops,
and iofwide.
(tests): Add tst_swprintf, tst_wprintf, tst_swscanf, and tst_wscanf.
* libio/Versions: Add _IO_fgetpos, _IO_fgetpos64, _IO_fsetpos,
_IO_fsetpos64, fgetpos, fgetpos64, fgetwc, fgetwc_unlocked, fgetws,
fgetws_unlocked, fputwc, fputwc_unlocked, fputws, fputws_unlocked,
fsetpos, fsetpos64, fwide, fwprintf, fwscanf, getwc, getwc_unlocked,
getwchar, getwchar_unlocked, putwc, putwc_unlocked, putwchar,
putwchar_unlocked, swprintf, swscanf, ungetwc, vfwprintf, vswprintf,
vwprintf, vfwscanf, vswscanf, vwscanf, wprintf, and wscanf to
GLIBC_2.2 for libc.
* libio/libio.h: Define codecvt struct. Define _IO_wide_data.
Extend _IO_file contain pointer to codecvt, widedata and mode.
(_IO_getwc_unlocked): New macro.
(_IO_putwc_unlocked): New macro.
(_IO_fwide): New macro.
* libio/libioP.h: Add new prototypes and adjust existing declarations.
* libio/fileops.c (_IO_new_file_close_it): Reset normal or widedata
buffers based on mode.
(new_do_write): Set _IO_write_end to _IO_buf_end if stream is wide
oriented.
(_IO_new_file_overflow): Don't depend only on _IO_CURRENTLY_PUTTING
flag to be enough to signal unallocated buffer. For wide oriented
stream don't make it linebuffered. Don't use _IO_do_flush, use
_IO_new_do_write directly.
(_IO_new_file_seekoff): Change return value type to _IO_off64_t.
(_IO_file_seek): Likewise.
* libio/genops.c (_IO_least_marker): Make global.
(__underflow): Orient stream if not already done.
(__uflow): Likewise.
(_IO_default_seekpos): Change to type _IO_off64_t.
(_IO_default_seekoff): Likewise.
(_IO_default_seek): Likewise.
(_IO_no_init): New function. Similar to _IO_init but allows to orient
in initialization.
* libio/iolibio.h: Add prototype for _IO_vswprintf. Change _IO_pos_BAD
to use _IO_off64_t.
* libio/ftello.c: Use _IO_off_t. For now abort when use with wide
char stream.
* libio/ftello64.c: Likewise.
* libio/ioftell.c: Likewise.
* libio/iofopncook.c: Likewise.
* libio/ioseekoff.c: Likewise.
* libio/ioseekpos.c: Likewise.
* libio/oldfileops.c: Likewise.
* libio/iofgetpos.c: Store state of conversion if necessary.
* libio/iofgetpos64.c: Likewise.
* libio/iofsetpos.c: Restore conversion state if necessary.
* libio/iofsetpos64.c: Likewise.
* libio/iofdopen.c: Initialize so that stream can be wide oriented.
* libio/iofopen.c: Likewise.
* libio/iofopen64.c: Likewise.
* libio/iopopen.c: Likewise.
* libio/iovdprintf.c: Likewise.
* libio/iovsprintf.c: Likewise.
* libio/iovsscanf.c: Likewise.
* libio/memstream.c: Likewise.
* libio/obprintf.c: Likewise.
* libio/iofputs.c: Orient stream if not already happened.
* libio/iofputs_u.c: Likewise.
* libio/iofwrite.c: Likewise.
* libio/iofwrite_u.c: Likewise.
* libio/ioputs.c: Likewise.
* libio/iosetbuffer.c: Handle not yet oriented stream.
* libio/iosetvbuf.c: Likewise.
* libio/oldstdfiles.c: Adjust FILEBUF_LITERAL call.
* libio/stdfiles.c: Likewise.
* libio/strops.c (_IO_str_overflow): Correctly free buffer after
failed allocation.
(_IO_str_seekoff): Use _IO_off64_t.
* libio/vasprintf.c: Pre-orient stream.
* libio/vsnprintf.c: Likewise.
* libio/fputwc.c: New file.
* libio/fputwc_u.c: New file.
* libio/fwprintf.c: New file.
* libio/fwscanf.c: New file.
* libio/getwc.c: New file.
* libio/getwc_u.c: New file.
* libio/getwchar.c: New file.
* libio/getwchar_u.c: New file.
* libio/iofgetws.c: New file.
* libio/iofgetws_u.c: New file.
* libio/iofputws.c: New file.
* libio/iofputws_u.c: New file.
* libio/iofwide.c: New file.
* libio/iogetwline.c: New file.
* libio/ioungetwc.c: New file.
* libio/iovswscanf.c: New file.
* libio/iowpadn.c: New file.
* libio/oldiofgetpos.c: New file.
* libio/oldiofgetpos64.c: New file.
* libio/oldiofsetpos.c: New file.
* libio/oldiofsetpos64.c: New file.
* libio/putwc.c: New file.
* libio/putwc_u.c: New file.
* libio/putwchar.c: New file.
* libio/putwchar_u.c: New file.
* libio/swprintf.c: New file.
* libio/swscanf.c: New file.
* libio/tst_swprintf.c: New file.
* libio/tst_swscanf.c: New file.
* libio/tst_wprintf.c: New file.
* libio/tst_wscanf.c: New file.
* libio/tst_wscanf.input: New file.
* libio/vswprintf.c: New file.
* libio/vwprintf.c: New file.
* libio/vwscanf.c: New file.
* libio/wfiledoalloc.c: New file.
* libio/wfileops.c: New file.
* libio/wgenops.c: New file.
* libio/wprintf.c: New file.
* libio/wscanf.c: New file.
* libio/wstrops.c: New file.
* stdio-common/Makefile (routines): Add _itowa, itowa-digits,
vfwprintf, and vfwscanf.
* stdio-common/_itoa.c (base_table): Rename to _IO_base_table and
make global.
* stdio-common/_itowa.c: New file.
* stdio-common/_itowa.h: New file.
* stdio-common/itoa-digits.c: Minimal optimization.
* stdio-common/itowa-digits.c: New file.
* stdio-common/printf-parse.h: Allow use in wide character context.
* stdio-common/printf-prs.c: Define ISASCII and MBRLEN.
* stdio-common/printf.h (printf_info): Add wide bit.
* stdio-common/printf_fp.c: Determine from wide bit whether stream
is wide oriented or not.
* stdio-common/printf_size.c: Likewise.
* sysdeps/generic/printf_fphex.c: Likewise.
* stdlib/strfmon.c: Call __printf_fp with wide bit cleared.
* stdio-common/vfprintf.c: Rewrite to allow use in wide character
context.
* stdio-common/vfscand.c: Likewise.
* stdio-common/vfwprintf.c: New file.
* stdio-common/vfwscanf.c: New file.
* time/Makefile (routines): Add wcsftime.
(tests): Add tst_wcsftime.
* time/Versions: Add wcsftime to GLIBC_2.2 for libc.
* time/strftime.c: Make usable as wcsftime.
* time/wcsftime.c: New file.
* time/tst_wcsftime.c: New file.
* wcsmbs/Makefile (routines): Add wmempcpy and wcschrnul.
* wcsmbs/Versions: Add wmempcpy and wcschrnul to GLIBC_2.2 for libc.
* wcsmbs/wcschrnul.c: New file.
* wcsmbs/wmemcpy.c: New file.
* wcsmbs/wmemcpy.c: Rename to __wmemcpy and make wmemcpy weak alias.
* wcsmbs/wmemmove.c: Likewise for wmemmove.
* manual/stdio.texi: Document is_char and wide element if printf_info.
* manual/time.texi: Document wcsftime.
* include/wchar.h: Add prototypes for __wmemcpy, __wmempcpy,
__wmemmove, __wcschrnul, and __vfwscanf.
* locale/langinfo.h: Add new LC_TIME entries for wchar_t data.
* locale/C-time.c: Adapt for above change.
* locale/categories.def: Likewise.
* locale/localeinfo.h: Likewise.
* localedata/Makefile: Don't run tests for now.
Diffstat (limited to 'libio/wstrops.c')
-rw-r--r-- | libio/wstrops.c | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/libio/wstrops.c b/libio/wstrops.c new file mode 100644 index 0000000000..af2c957b05 --- /dev/null +++ b/libio/wstrops.c @@ -0,0 +1,330 @@ +/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU IO Library. + + This library 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 2, or (at + your option) any later version. + + This 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to + the Free Software Foundation, 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, if you link this library with files + compiled with a GNU compiler to produce an executable, this does + not cause the resulting executable to be covered by the GNU General + Public License. This exception does not however invalidate any + other reasons why the executable file might be covered by the GNU + General Public License. */ + +#include "strfile.h" +#include "libioP.h" +#include <string.h> +#include <wchar.h> + +#if 0 +/* The following definitions are for exposition only. + They map the terminology used in the ANSI/ISO C++ draft standard + to the implementation. */ + +/* allocated: set when a dynamic array object has been allocated, and + hence should be freed by the destructor for the strstreambuf object. */ +#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP)) + +/* constant: set when the array object has const elements, + so the output sequence cannot be written. */ +#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES) + +/* alsize: the suggested minimum size for a dynamic array object. */ +#define ALSIZE(FP) ??? /* not stored */ + +/* palloc: points to the function to call to allocate a dynamic array object.*/ +#define PALLOC(FP) \ + ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer) + +/* pfree: points to the function to call to free a dynamic array object. */ +#define PFREE(FP) \ + ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer) + +#endif + +#ifdef TODO +/* An "unbounded buffer" is when a buffer is supplied, but with no + specified length. An example is the buffer argument to sprintf. + */ +#endif + +void +_IO_wstr_init_static (fp, ptr, size, pstart) + _IO_FILE *fp; + wchar_t *ptr; + int size; + wchar_t *pstart; +{ + if (size == 0) + size = __wcslen (ptr); + else if (size < 0) + { + /* If size is negative 'the characters are assumed to + continue indefinitely.' This is kind of messy ... */ + int s; + size = 512; + /* Try increasing powers of 2, as long as we don't wrap around. */ + for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; ) + size = s; + /* Try increasing size as much as we can without wrapping around. */ + for (s = size >> 1; s > 0; s >>= 1) + { + if (ptr + size + s > ptr) + size += s; + } + } + _IO_wsetb (fp, ptr, ptr + size, 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 = ptr + size; + 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 = ptr + size; + } + /* A null _allocate_buffer function flags the strfile as being static. */ + (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; +} + +void +_IO_wstr_init_readonly (fp, ptr, size) + _IO_FILE *fp; + const char *ptr; + int size; +{ + _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL); + fp->_IO_file_flags |= _IO_NO_WRITES; +} + +_IO_wint_t +_IO_wstr_overflow (fp, c) + _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->_flags & _IO_USER_BUF) /* not allowed to enlarge */ + return WEOF; + else + { + wchar_t *new_buf; + wchar_t *old_buf = fp->_wide_data->_IO_buf_base; + _IO_size_t new_size = 2 * _IO_wblen (fp) + 100; + 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, _IO_wblen (fp)); + (*((_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; + } + _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 (fp) + _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 (fp) + _IO_FILE *fp; +{ + return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end + ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end) + - fp->_wide_data->_IO_read_base); +} + +_IO_off64_t +_IO_wstr_seekoff (fp, offset, dir, mode) + _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); + + if (mode == 0) + { + /* Don't move any pointers. But there is no clear indication what + mode FP is in. Let's guess. */ + if (fp->_IO_file_flags & _IO_NO_WRITES) + new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; + else + 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) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + + offset); + 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) + { + switch (dir) + { + case _IO_seek_end: + offset += cur_size; + break; + case _IO_seek_cur: + offset += (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + break; + default: /* case _IO_seek_set: */ + break; + } + if (offset < 0 || (_IO_ssize_t) offset > cur_size) + return EOF; + fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base + + offset); + new_pos = offset; + } + } + return new_pos; +} + +_IO_wint_t +_IO_wstr_pbackfail (fp, c) + _IO_FILE *fp; + _IO_wint_t c; +{ + if ((fp->_flags & _IO_NO_WRITES) && c != EOF) + return WEOF; + return _IO_wdefault_pbackfail (fp, c); +} + +void +_IO_wstr_finish (fp, dummy) + _IO_FILE *fp; + int dummy; +{ + if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) + (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); + fp->_wide_data->_IO_buf_base = NULL; + + _IO_wdefault_finish (fp, 0); +} + +struct _IO_jump_t _IO_wstr_jumps = +{ + 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_setbuf_t) _IO_wdefault_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) +}; |