Update.
1998-04-20 18:00 Ulrich Drepper <drepper@cygnus.com> * libc.map: Add __dgettext to GLIBC_2.0 and __libc_longjmp, and __libc_siglongjmp to GLIBC_2.1. * elf/dl-minimal.c (__assert_perror_fail): Don't use strerror, use __strerror_r. * iconv/Makefile: Don't run tests now. * iconv/iconv_prog.c (process_block): If loop is repeated, call iconv with correct output buffer. Major rewrite of the low-level gconv functionality. * iconv/gconv.c: Rewritten. * iconv/gconv.h: Likewise. * iconv/gconv_builtin.c: Likewise. * iconv/gconv_builtin.h: Likewise. * iconv/gconv_conf.c: Likewise. * iconv/gconv_int.h: Likewise. * iconv/gconv_open.c: Likewise. * iconv/gconv_simple.c: Likewise. * iconv/iconv.c: Likewise. * iconvdata/8bit-gap.c: Likewise. * iconvdata/8bit-generic.c: Likewise. * iconvdata/Makefile: Likewise. * iconvdata/big5.c: Likewise. * iconvdata/cns11643.c: Likewise. * iconvdata/cns11643.h: Likewise. * iconvdata/cns11643l1.c: Likewise. * iconvdata/cns11643l1.h: Likewise. * iconvdata/ebcdic-at-de-a.c: Likewise. * iconvdata/ebcdic-at-de.c: Likewise. * iconvdata/ebcdic-ca-fr.c: Likewise. * iconvdata/euccn.c: Likewise. * iconvdata/eucjp.c: Likewise. * iconvdata/euckr.c: Likewise. * iconvdata/euctw.c: Likewise. * iconvdata/gb2312.c: Likewise. * iconvdata/gb2312.h: Likewise. * iconvdata/hp-roman8.c: Likewise. * iconvdata/iso646.c: Likewise. * iconvdata/iso6937.c: Likewise. * iconvdata/iso8859-1.c: Likewise. * iconvdata/iso8859-10.c: Likewise. * iconvdata/iso8859-2.c: Likewise. * iconvdata/iso8859-3.c: Likewise. * iconvdata/iso8859-4.c: Likewise. * iconvdata/iso8859-5.c: Likewise. * iconvdata/iso8859-6.c: Likewise. * iconvdata/iso8859-7.c: Likewise. * iconvdata/iso8859-8.c: Likewise. * iconvdata/iso8859-9.c: Likewise. * iconvdata/jis0201.c: Likewise. * iconvdata/jis0201.h: Likewise. * iconvdata/jis0208.c: Likewise. * iconvdata/jis0208.h: Likewise. * iconvdata/jis0212.c: Likewise. * iconvdata/jis0212.h: Likewise. * iconvdata/johab.c: Likewise. * iconvdata/koi-8.c: Likewise. * iconvdata/koi8-r.c: Likewise. * iconvdata/ksc5601.c: Likewise. * iconvdata/ksc5601.h: Likewise. * iconvdata/latin-greek-1.c: Likewise. * iconvdata/latin-greek.c: Likewise. * iconvdata/run-iconv-test.sh: Likewise. * iconvdata/sjis.c: Likewise. * iconvdata/t61.c: Likewise. * iconvdata/uhc.c: Likewise. * wcsmbs/btowc.c: Likewise. * wcsmbs/mbrtowc.c: Likewise. * wcsmbs/mbsnrtowcs.c: Likewise. * wcsmbs/mbsrtowcs.c: Likewise. * wcsmbs/wcrtomb.c: Likewise. * wcsmbs/wcsmbsload.c: Likewise. * wcsmbs/wcsnrtombs.c: Likewise. * wcsmbs/wcsrtombs.c: Likewise. * wcsmbs/wctob.c: Likewise. * iconv/loop.c: New file. * iconv/skeleton.c: New file. * stdlib/mblen.c: Handle empty input string correctly. * stdlib/mbtowc.c: Likewise. * posix/getopt.c: Various cleanups. * sysdeps/arm/bits/setjmp.h: Add copyright text. * sysdeps/i386/bits/setjmp.h: Likewise. * sysdeps/m68k/bits/setjmp.h: Likewise. * sysdeps/powerpc/bits/setjmp.h: Likewise. * sysdeps/sparc/sparc32/bits/setjmp.h: Likewise. * sysdeps/generic/longjmp.c: Rename function to __libc_siglongjmp and make longjmp weak alias. 1998-04-18 20:29 Philip Blundell <Philip.Blundell@pobox.com> * iconv/Makefile (routines): Only include gconv_dl if building for an ELF system - dynamic linking is not available on a.out. (CFLAGS-gconv_conf.c): Define STATIC_GCONV if omitting gconv_dl due to above check. * iconv/gconv_db.c: If STATIC_GCONV defined, don't try to call routines from gconv_dl. 1998-04-17 Gordon Matzigkeit <gord@profitpress.com> * csu/init.c (_IO_stdin_used): Protect with USE_IN_LIBIO so that we can compile without libio. 1998-04-20 16:28 Ulrich Drepper <drepper@cygnus.com> * sysdeps/mach/hurd/Subdirs: Remove login. 1998-04-11 Gordon Matzigkeit <gord@profitpress.com> * db2/compat.h: Include <errno.h>, to make sure we get the definition of EFTYPE before we define it ourselves. 1998-04-10 Gordon Matzigkeit <gord@profitpress.com> * sysdeps/generic/bits/socket.h: Protect against multiple inclusion. * sysdeps/mach/hurd/bits/ioctls.h: Likewise. Fix typo to allow inclusion from sys/ioctl.h again. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * iconvdata/*.[ch]: Clean up namespace. Optimize character lookup. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libc.map: Export __strerror_r. Remove _strerror_internal. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/generic/strcasestr.c: Undefine strcasestr, not strstr. Also undefine __strcasestr. 1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * posix/regex.c: Rename __re_max_failures back to re_max_failures, aliases do not work with global variables due to copy relocations. 1998-04-20 15:12 Ulrich Drepper <drepper@cygnus.com> * manual/creature.texi: Fix type. Patch by Andreas Schwab. 1998-04-20 13:47 Ulrich Drepper <drepper@cygnus.com> * signal/sighold.c: Include stddef.h for NULL definition. * signal/sigrelse.c: Likewise. * sysdeps/posix/sigignore.c: Likewise. * sysdeps/posix/sigset.c: Likewise. * sysdeps/posix/waitid.c: Likewise. * sysdeps/unix/sysv/linux/rt_sigsuspend.c: Likewise. * sysdeps/unix/sysv/linux/rt_sigtimedwait.c: Likewise. * sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise. * wcsmbs/mbsrtowcs.c: Include stdlib.h for MB_CUR_MAX. Patch by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>. 1998-04-13 Mark Kettenis <kettenis@phys.uva.nl> * login/Makefile (headers): Remove utmpx.h and bits/utmpx.h. * login/getutent.c (getutxent): Remove alias. * login/getutent_r.c (setutxent, pututxline, endutxent): Remove aliases. * login/getutid.c (getutxid): Remove alias. * login/getutline.c (getutxline): Remove alias. * login/utmp.h: Add prototypes for __updwtmp, __getutent, __getutid, __getutline and __pututline. * login/utmpx.h: Moved to ... * sysdeps/gnu/utmpx.h: ... here. [__USE_GNU]: Define UTMPX_FILE, UTMPX_FILENAME, WTMPX_FILE and WTMPX_FILENAME, declare utmpxname and updwtmpx. * login/updwtmp.c: Moved to ... * sysdeps/generic/updwtmp.c: ... here. (updwtmp): Generalized by allowing file name transformation. * sysdeps/gnu/updwtmp.c: New file. Use generic implementation with additional file name transformation. * sysdeps/unix/sysv/linux/updwtmp.c: Likewise. * login/utmp_file.c: Moved to ... * sysdeps/generic/utmp_file.c: ... here. (setutent_file): Generalized by allowing file name transformation. Do not print error message. Library functions should not print them. Reported by Jim Meyering. * sysdeps/gnu/utmp_file.c: New file. Use generic implementation with additional file name transformation. * sysdeps/unix/sysv/linux/utmp_file.c: Likewise. * sysdeps/gnu/Makefile [$(subdir)=login] (sysdep_routines): Add setutxent, getutxent, endutxent, getutxid, getutxid, getutxline, pututxline, utmpxname and updwtmpx. (sysdep_headers): Add utmpx.h and bits/utmpx.h. * sysdeps/gnu/bits/utmpx.h [__USE_GNU] Include paths.h. (_PATH_UTMPX): Define to _PATH_UTMP. (_PATH_WTMPX): Define to _PATH_WTMPX. (RUN_LVL): Define only if __USE_GNU. (ACCOUNTING): Define if __USE_GNU. * sysdeps/gnu/setutxent.c: New file. * sysdeps/gnu/getutxent.c: New file. * sysdeps/gnu/endutxent.c: New file. * sysdeps/gnu/getutxid.c: New file. * sysdeps/gnu/getutxline.c: New file. * sysdeps/gnu/pututxline.c: New file. * sysdeps/gnu/utmpxname.c: New file. * sysdeps/gnu/updwtmpx.c: New file. * sysdeps/unix/sysv/linux/paths.h (_PATH_UTMP_DB): Remove. * sysdeps/generic/bits/utmpx.h: Remove. 1998-04-20 Ulrich Drepper <drepper@cygnus.com> * posix/wordexp-test.c (main): Initialize ifs element of ts for ~root test. 1998-04-17 07:53 H.J. Lu <hjl@gnu.org> * sysdeps/unix/sysv/linux/i386/s_pread64.S: Fix a typo. 1998-04-17 11:32 Ulrich Drepper <drepper@cygnus.com> * libio/oldfileops.c (_IO_old_file_seekoff): Define temporary st variable using _G_stat64. * libio/fileops.c: Remove macro definition of fstat, it is in the global header. Reported by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>. 1998-04-17 Philip Blundell <pb@nexus.co.uk> * sysdeps/arm/strlen.S: New file, based on code by Matthew Wilcox <willy@odie.barnet.ac.uk>. 1998-04-16 Philip Blundell <Philip.Blundell@pobox.com> * inet/netinet/in.h (IN6_IS_ADDR_MC_NODELOCAL): New macro, required by IPv6 Basic API. (IN6_IS_ADDR_MC_LINKLOCAL): Likewise. (IN6_IS_ADDR_MC_SITELOCAL): Likewise. (IN6_IS_ADDR_MC_ORGLOCAL): Likewise. (IN6_IS_ADDR_MC_GLOBAL): Likewise.
This commit is contained in:
parent
f1fa8b68f3
commit
8619129f3f
238
ChangeLog
238
ChangeLog
@ -1,3 +1,241 @@
|
||||
1998-04-20 18:00 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* libc.map: Add __dgettext to GLIBC_2.0 and __libc_longjmp, and
|
||||
__libc_siglongjmp to GLIBC_2.1.
|
||||
|
||||
* elf/dl-minimal.c (__assert_perror_fail): Don't use strerror, use
|
||||
__strerror_r.
|
||||
|
||||
* iconv/Makefile: Don't run tests now.
|
||||
|
||||
* iconv/iconv_prog.c (process_block): If loop is repeated, call iconv
|
||||
with correct output buffer.
|
||||
|
||||
Major rewrite of the low-level gconv functionality.
|
||||
* iconv/gconv.c: Rewritten.
|
||||
* iconv/gconv.h: Likewise.
|
||||
* iconv/gconv_builtin.c: Likewise.
|
||||
* iconv/gconv_builtin.h: Likewise.
|
||||
* iconv/gconv_conf.c: Likewise.
|
||||
* iconv/gconv_int.h: Likewise.
|
||||
* iconv/gconv_open.c: Likewise.
|
||||
* iconv/gconv_simple.c: Likewise.
|
||||
* iconv/iconv.c: Likewise.
|
||||
* iconvdata/8bit-gap.c: Likewise.
|
||||
* iconvdata/8bit-generic.c: Likewise.
|
||||
* iconvdata/Makefile: Likewise.
|
||||
* iconvdata/big5.c: Likewise.
|
||||
* iconvdata/cns11643.c: Likewise.
|
||||
* iconvdata/cns11643.h: Likewise.
|
||||
* iconvdata/cns11643l1.c: Likewise.
|
||||
* iconvdata/cns11643l1.h: Likewise.
|
||||
* iconvdata/ebcdic-at-de-a.c: Likewise.
|
||||
* iconvdata/ebcdic-at-de.c: Likewise.
|
||||
* iconvdata/ebcdic-ca-fr.c: Likewise.
|
||||
* iconvdata/euccn.c: Likewise.
|
||||
* iconvdata/eucjp.c: Likewise.
|
||||
* iconvdata/euckr.c: Likewise.
|
||||
* iconvdata/euctw.c: Likewise.
|
||||
* iconvdata/gb2312.c: Likewise.
|
||||
* iconvdata/gb2312.h: Likewise.
|
||||
* iconvdata/hp-roman8.c: Likewise.
|
||||
* iconvdata/iso646.c: Likewise.
|
||||
* iconvdata/iso6937.c: Likewise.
|
||||
* iconvdata/iso8859-1.c: Likewise.
|
||||
* iconvdata/iso8859-10.c: Likewise.
|
||||
* iconvdata/iso8859-2.c: Likewise.
|
||||
* iconvdata/iso8859-3.c: Likewise.
|
||||
* iconvdata/iso8859-4.c: Likewise.
|
||||
* iconvdata/iso8859-5.c: Likewise.
|
||||
* iconvdata/iso8859-6.c: Likewise.
|
||||
* iconvdata/iso8859-7.c: Likewise.
|
||||
* iconvdata/iso8859-8.c: Likewise.
|
||||
* iconvdata/iso8859-9.c: Likewise.
|
||||
* iconvdata/jis0201.c: Likewise.
|
||||
* iconvdata/jis0201.h: Likewise.
|
||||
* iconvdata/jis0208.c: Likewise.
|
||||
* iconvdata/jis0208.h: Likewise.
|
||||
* iconvdata/jis0212.c: Likewise.
|
||||
* iconvdata/jis0212.h: Likewise.
|
||||
* iconvdata/johab.c: Likewise.
|
||||
* iconvdata/koi-8.c: Likewise.
|
||||
* iconvdata/koi8-r.c: Likewise.
|
||||
* iconvdata/ksc5601.c: Likewise.
|
||||
* iconvdata/ksc5601.h: Likewise.
|
||||
* iconvdata/latin-greek-1.c: Likewise.
|
||||
* iconvdata/latin-greek.c: Likewise.
|
||||
* iconvdata/run-iconv-test.sh: Likewise.
|
||||
* iconvdata/sjis.c: Likewise.
|
||||
* iconvdata/t61.c: Likewise.
|
||||
* iconvdata/uhc.c: Likewise.
|
||||
* wcsmbs/btowc.c: Likewise.
|
||||
* wcsmbs/mbrtowc.c: Likewise.
|
||||
* wcsmbs/mbsnrtowcs.c: Likewise.
|
||||
* wcsmbs/mbsrtowcs.c: Likewise.
|
||||
* wcsmbs/wcrtomb.c: Likewise.
|
||||
* wcsmbs/wcsmbsload.c: Likewise.
|
||||
* wcsmbs/wcsnrtombs.c: Likewise.
|
||||
* wcsmbs/wcsrtombs.c: Likewise.
|
||||
* wcsmbs/wctob.c: Likewise.
|
||||
* iconv/loop.c: New file.
|
||||
* iconv/skeleton.c: New file.
|
||||
|
||||
* stdlib/mblen.c: Handle empty input string correctly.
|
||||
* stdlib/mbtowc.c: Likewise.
|
||||
|
||||
* posix/getopt.c: Various cleanups.
|
||||
|
||||
* sysdeps/arm/bits/setjmp.h: Add copyright text.
|
||||
* sysdeps/i386/bits/setjmp.h: Likewise.
|
||||
* sysdeps/m68k/bits/setjmp.h: Likewise.
|
||||
* sysdeps/powerpc/bits/setjmp.h: Likewise.
|
||||
* sysdeps/sparc/sparc32/bits/setjmp.h: Likewise.
|
||||
|
||||
* sysdeps/generic/longjmp.c: Rename function to __libc_siglongjmp
|
||||
and make longjmp weak alias.
|
||||
|
||||
1998-04-18 20:29 Philip Blundell <Philip.Blundell@pobox.com>
|
||||
|
||||
* iconv/Makefile (routines): Only include gconv_dl if building for
|
||||
an ELF system - dynamic linking is not available on a.out.
|
||||
(CFLAGS-gconv_conf.c): Define STATIC_GCONV if omitting gconv_dl
|
||||
due to above check.
|
||||
* iconv/gconv_db.c: If STATIC_GCONV defined, don't try to call
|
||||
routines from gconv_dl.
|
||||
|
||||
1998-04-17 Gordon Matzigkeit <gord@profitpress.com>
|
||||
|
||||
* csu/init.c (_IO_stdin_used): Protect with USE_IN_LIBIO so that
|
||||
we can compile without libio.
|
||||
|
||||
1998-04-20 16:28 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sysdeps/mach/hurd/Subdirs: Remove login.
|
||||
|
||||
1998-04-11 Gordon Matzigkeit <gord@profitpress.com>
|
||||
|
||||
* db2/compat.h: Include <errno.h>, to make sure we get the
|
||||
definition of EFTYPE before we define it ourselves.
|
||||
|
||||
1998-04-10 Gordon Matzigkeit <gord@profitpress.com>
|
||||
|
||||
* sysdeps/generic/bits/socket.h: Protect against multiple inclusion.
|
||||
* sysdeps/mach/hurd/bits/ioctls.h: Likewise.
|
||||
Fix typo to allow inclusion from sys/ioctl.h again.
|
||||
|
||||
1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* iconvdata/*.[ch]: Clean up namespace. Optimize character lookup.
|
||||
|
||||
1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* libc.map: Export __strerror_r. Remove _strerror_internal.
|
||||
|
||||
1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* sysdeps/generic/strcasestr.c: Undefine strcasestr, not strstr.
|
||||
Also undefine __strcasestr.
|
||||
|
||||
1998-04-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* posix/regex.c: Rename __re_max_failures back to re_max_failures,
|
||||
aliases do not work with global variables due to copy relocations.
|
||||
|
||||
1998-04-20 15:12 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* manual/creature.texi: Fix type. Patch by Andreas Schwab.
|
||||
|
||||
1998-04-20 13:47 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* signal/sighold.c: Include stddef.h for NULL definition.
|
||||
* signal/sigrelse.c: Likewise.
|
||||
* sysdeps/posix/sigignore.c: Likewise.
|
||||
* sysdeps/posix/sigset.c: Likewise.
|
||||
* sysdeps/posix/waitid.c: Likewise.
|
||||
* sysdeps/unix/sysv/linux/rt_sigsuspend.c: Likewise.
|
||||
* sysdeps/unix/sysv/linux/rt_sigtimedwait.c: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sigwaitinfo.c: Likewise.
|
||||
* wcsmbs/mbsrtowcs.c: Include stdlib.h for MB_CUR_MAX.
|
||||
Patch by Franz Sirl <Franz.Sirl-kernel@lauterbach.com>.
|
||||
|
||||
1998-04-13 Mark Kettenis <kettenis@phys.uva.nl>
|
||||
|
||||
* login/Makefile (headers): Remove utmpx.h and bits/utmpx.h.
|
||||
* login/getutent.c (getutxent): Remove alias.
|
||||
* login/getutent_r.c (setutxent, pututxline, endutxent):
|
||||
Remove aliases.
|
||||
* login/getutid.c (getutxid): Remove alias.
|
||||
* login/getutline.c (getutxline): Remove alias.
|
||||
* login/utmp.h: Add prototypes for __updwtmp, __getutent,
|
||||
__getutid, __getutline and __pututline.
|
||||
* login/utmpx.h: Moved to ...
|
||||
* sysdeps/gnu/utmpx.h: ... here. [__USE_GNU]: Define UTMPX_FILE,
|
||||
UTMPX_FILENAME, WTMPX_FILE and WTMPX_FILENAME, declare utmpxname
|
||||
and updwtmpx.
|
||||
* login/updwtmp.c: Moved to ...
|
||||
* sysdeps/generic/updwtmp.c: ... here. (updwtmp): Generalized by
|
||||
allowing file name transformation.
|
||||
* sysdeps/gnu/updwtmp.c: New file. Use generic implementation with
|
||||
additional file name transformation.
|
||||
* sysdeps/unix/sysv/linux/updwtmp.c: Likewise.
|
||||
* login/utmp_file.c: Moved to ...
|
||||
* sysdeps/generic/utmp_file.c: ... here. (setutent_file):
|
||||
Generalized by allowing file name transformation. Do not
|
||||
print error message. Library functions should not print them.
|
||||
Reported by Jim Meyering.
|
||||
* sysdeps/gnu/utmp_file.c: New file. Use generic implementation
|
||||
with additional file name transformation.
|
||||
* sysdeps/unix/sysv/linux/utmp_file.c: Likewise.
|
||||
* sysdeps/gnu/Makefile [$(subdir)=login] (sysdep_routines): Add
|
||||
setutxent, getutxent, endutxent, getutxid, getutxid, getutxline,
|
||||
pututxline, utmpxname and updwtmpx. (sysdep_headers): Add utmpx.h
|
||||
and bits/utmpx.h.
|
||||
* sysdeps/gnu/bits/utmpx.h [__USE_GNU] Include paths.h.
|
||||
(_PATH_UTMPX): Define to _PATH_UTMP. (_PATH_WTMPX): Define to
|
||||
_PATH_WTMPX. (RUN_LVL): Define only if __USE_GNU. (ACCOUNTING):
|
||||
Define if __USE_GNU.
|
||||
* sysdeps/gnu/setutxent.c: New file.
|
||||
* sysdeps/gnu/getutxent.c: New file.
|
||||
* sysdeps/gnu/endutxent.c: New file.
|
||||
* sysdeps/gnu/getutxid.c: New file.
|
||||
* sysdeps/gnu/getutxline.c: New file.
|
||||
* sysdeps/gnu/pututxline.c: New file.
|
||||
* sysdeps/gnu/utmpxname.c: New file.
|
||||
* sysdeps/gnu/updwtmpx.c: New file.
|
||||
* sysdeps/unix/sysv/linux/paths.h (_PATH_UTMP_DB): Remove.
|
||||
* sysdeps/generic/bits/utmpx.h: Remove.
|
||||
|
||||
1998-04-20 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* posix/wordexp-test.c (main): Initialize ifs element of ts for
|
||||
~root test.
|
||||
|
||||
1998-04-17 07:53 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/s_pread64.S: Fix a typo.
|
||||
|
||||
1998-04-17 11:32 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* libio/oldfileops.c (_IO_old_file_seekoff): Define temporary st
|
||||
variable using _G_stat64.
|
||||
* libio/fileops.c: Remove macro definition of fstat, it is in the
|
||||
global header.
|
||||
Reported by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>.
|
||||
|
||||
1998-04-17 Philip Blundell <pb@nexus.co.uk>
|
||||
|
||||
* sysdeps/arm/strlen.S: New file, based on code by Matthew Wilcox
|
||||
<willy@odie.barnet.ac.uk>.
|
||||
|
||||
1998-04-16 Philip Blundell <Philip.Blundell@pobox.com>
|
||||
|
||||
* inet/netinet/in.h (IN6_IS_ADDR_MC_NODELOCAL): New macro,
|
||||
required by IPv6 Basic API.
|
||||
(IN6_IS_ADDR_MC_LINKLOCAL): Likewise.
|
||||
(IN6_IS_ADDR_MC_SITELOCAL): Likewise.
|
||||
(IN6_IS_ADDR_MC_ORGLOCAL): Likewise.
|
||||
(IN6_IS_ADDR_MC_GLOBAL): Likewise.
|
||||
|
||||
1998-04-15 16:41 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
Don't name internal representation since it might be different from
|
||||
|
34
FAQ
34
FAQ
@ -24,7 +24,7 @@ please let me know.
|
||||
1.3. When I try to compile glibc I get only error messages.
|
||||
What's wrong?
|
||||
1.4. Do I need a special linker or archiver?
|
||||
1.5. What tools do I need for powerpc?
|
||||
1.5. Which compiler should I use for powerpc?
|
||||
1.6. Do I need some more things to compile GNU C Library?
|
||||
1.7. What version of the Linux kernel headers should be used?
|
||||
1.8. When I run `nm -u libc.so' on the produced library I still
|
||||
@ -203,25 +203,19 @@ may have native linker support, but it's moot right now, because glibc
|
||||
has not been ported to them.
|
||||
|
||||
|
||||
1.5. What tools do I need for powerpc?
|
||||
1.5. Which compiler should I use for powerpc?
|
||||
|
||||
{GK} For a successful installation you definitely need the most recent
|
||||
tools. You can safely assume that anything earlier than binutils
|
||||
2.8.1.0.17 and egcs-1.0 will have problems. We'd advise at the moment
|
||||
binutils 2.8.1.0.18 and egcs-1.0.1.
|
||||
{GK} You want to use egcs 1.0.1 or later (together with the right
|
||||
versions of all the other tools, of course).
|
||||
|
||||
In fact, egcs 1.0.1 currently has two serious bugs that prevent a
|
||||
clean make; one relates to switch statement folding, for which there
|
||||
is a temporary patch at
|
||||
In fact, egcs 1.0.1 has a serious bug that prevents a clean make,
|
||||
relating to switch statement folding. It also causes the resulting
|
||||
shared libraries to use more memory than they should. There is a
|
||||
patch at:
|
||||
|
||||
<http://discus.anu.edu.au/~geoffk/egcs-1.0-geoffk.diff.gz>
|
||||
<http://discus.anu.edu.au/~geoffk/egcs-1.0.1-geoffk.diff>
|
||||
|
||||
and the other relates to 'forbidden register spilled', for which the
|
||||
workaround is to put
|
||||
|
||||
CFLAGS-condvar.c += -fno-inline
|
||||
|
||||
in configparms. Later versions of egcs may fix these problems.
|
||||
Later versions of egcs may fix these problems.
|
||||
|
||||
|
||||
1.6. Do I need some more things to compile GNU C Library?
|
||||
@ -247,7 +241,8 @@ in configparms. Later versions of egcs may fix these problems.
|
||||
* When compiling for Linux, the header files of the Linux kernel must
|
||||
be available to the compiler as <linux/*.h> and <asm/*.h>.
|
||||
|
||||
* lots of disk space (~170MB for i?86-linux; more for RISC platforms).
|
||||
* lots of disk space (~170MB for i?86-linux; more for RISC platforms,
|
||||
as much as 400MB).
|
||||
|
||||
* plenty of time. Compiling just the shared and static libraries for
|
||||
i?86-linux takes approximately 1h on an i586@133, or 2.5h on
|
||||
@ -290,9 +285,6 @@ symbols:
|
||||
|
||||
* symbols starting with _dl_* come from the dynamic linker
|
||||
|
||||
* symbols resolved by using libgcc.a
|
||||
(__udivdi3, __umoddi3, or similar)
|
||||
|
||||
* weak symbols, which need not be resolved at all (fabs for example)
|
||||
|
||||
Generally, you should make sure you find a real program which produces
|
||||
@ -1141,7 +1133,7 @@ Answers were given by:
|
||||
{MK} Mark Kettenis, <kettenis@phys.uva.nl>
|
||||
{ZW} Zack Weinberg, <zack@rabi.phys.columbia.edu>
|
||||
{TK} Thorsten Kukuk, <kukuk@vt.uni-paderborn.de>
|
||||
{GK} Geoffrey Keating, <Geoff.Keating@anu.edu.au>
|
||||
{GK} Geoffrey Keating, <geoffk@ozemail.com.au>
|
||||
{HJ} H.J. Lu, <hjl@gnu.org>
|
||||
|
||||
Local Variables:
|
||||
|
32
FAQ.in
32
FAQ.in
@ -89,25 +89,19 @@ required. For Linux, get binutils-2.8.1.0.23 or later. Other systems
|
||||
may have native linker support, but it's moot right now, because glibc
|
||||
has not been ported to them.
|
||||
|
||||
??powerpc What tools do I need for powerpc?
|
||||
??powerpc Which compiler should I use for powerpc?
|
||||
|
||||
{GK} For a successful installation you definitely need the most recent
|
||||
tools. You can safely assume that anything earlier than binutils
|
||||
2.8.1.0.17 and egcs-1.0 will have problems. We'd advise at the moment
|
||||
binutils 2.8.1.0.18 and egcs-1.0.1.
|
||||
{GK} You want to use egcs 1.0.1 or later (together with the right
|
||||
versions of all the other tools, of course).
|
||||
|
||||
In fact, egcs 1.0.1 currently has two serious bugs that prevent a
|
||||
clean make; one relates to switch statement folding, for which there
|
||||
is a temporary patch at
|
||||
In fact, egcs 1.0.1 has a serious bug that prevents a clean make,
|
||||
relating to switch statement folding. It also causes the resulting
|
||||
shared libraries to use more memory than they should. There is a
|
||||
patch at:
|
||||
|
||||
<http://discus.anu.edu.au/~geoffk/egcs-1.0-geoffk.diff.gz>
|
||||
<http://discus.anu.edu.au/~geoffk/egcs-1.0.1-geoffk.diff>
|
||||
|
||||
and the other relates to 'forbidden register spilled', for which the
|
||||
workaround is to put
|
||||
|
||||
CFLAGS-condvar.c += -fno-inline
|
||||
|
||||
in configparms. Later versions of egcs may fix these problems.
|
||||
Later versions of egcs may fix these problems.
|
||||
|
||||
|
||||
?? Do I need some more things to compile GNU C Library?
|
||||
@ -133,7 +127,8 @@ in configparms. Later versions of egcs may fix these problems.
|
||||
* When compiling for Linux, the header files of the Linux kernel must
|
||||
be available to the compiler as <linux/*.h> and <asm/*.h>.
|
||||
|
||||
* lots of disk space (~170MB for i?86-linux; more for RISC platforms).
|
||||
* lots of disk space (~170MB for i?86-linux; more for RISC platforms,
|
||||
as much as 400MB).
|
||||
|
||||
* plenty of time. Compiling just the shared and static libraries for
|
||||
i?86-linux takes approximately 1h on an i586@133, or 2.5h on
|
||||
@ -174,9 +169,6 @@ symbols:
|
||||
|
||||
* symbols starting with _dl_* come from the dynamic linker
|
||||
|
||||
* symbols resolved by using libgcc.a
|
||||
(__udivdi3, __umoddi3, or similar)
|
||||
|
||||
* weak symbols, which need not be resolved at all (fabs for example)
|
||||
|
||||
Generally, you should make sure you find a real program which produces
|
||||
@ -981,7 +973,7 @@ Answers were given by:
|
||||
{MK} Mark Kettenis, <kettenis@phys.uva.nl>
|
||||
{ZW} Zack Weinberg, <zack@rabi.phys.columbia.edu>
|
||||
{TK} Thorsten Kukuk, <kukuk@vt.uni-paderborn.de>
|
||||
{GK} Geoffrey Keating, <Geoff.Keating@anu.edu.au>
|
||||
{GK} Geoffrey Keating, <geoffk@ozemail.com.au>
|
||||
{HJ} H.J. Lu, <hjl@gnu.org>
|
||||
|
||||
Local Variables:
|
||||
|
@ -17,6 +17,9 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef __BITS_SOCKET_H
|
||||
#define __BITS_SOCKET_H 1
|
||||
|
||||
#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
|
||||
# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
|
||||
#endif
|
||||
@ -196,3 +199,5 @@ struct linger
|
||||
int l_onoff; /* Nonzero to linger on close. */
|
||||
int l_linger; /* Time to linger. */
|
||||
};
|
||||
|
||||
#endif /* bits/socket.h */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Special startup support.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it
|
||||
@ -26,7 +26,7 @@
|
||||
write to the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
#if defined USE_IN_LIBIO && defined __GNUC__ && __GNUC__ >= 2
|
||||
|
||||
#undef _LIBC
|
||||
#include <libio.h>
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Compatibility gunk for the db library. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef EFTYPE
|
||||
# define EFTYPE EINVAL
|
||||
|
@ -193,12 +193,15 @@ __assert_perror_fail (int errnum,
|
||||
const char *file, unsigned int line,
|
||||
const char *function)
|
||||
{
|
||||
char errbuf[64];
|
||||
char buf[64];
|
||||
buf[sizeof buf - 1] = '\0';
|
||||
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
|
||||
file, ": ", _itoa_word (line, buf + sizeof buf - 1, 10, 0),
|
||||
": ", function ?: "", function ? ": " : "",
|
||||
"Unexpected error: ", strerror (errnum), "\n", NULL);
|
||||
"Unexpected error: ",
|
||||
__strerror_r (errnum, errbuf, sizeof (errbuf)), "\n",
|
||||
NULL);
|
||||
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,18 @@
|
||||
#
|
||||
subdir := iconv
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
headers = iconv.h gconv.h
|
||||
routines = iconv_open iconv iconv_close \
|
||||
gconv_open gconv gconv_close gconv_db gconv_conf \
|
||||
gconv_dl gconv_builtin gconv_simple
|
||||
gconv_builtin gconv_simple
|
||||
ifeq ($(elf),yes)
|
||||
routines += gconv_dl
|
||||
else
|
||||
CFLAGS-gconv_db.c = -DSTATIC_GCONV
|
||||
endif
|
||||
|
||||
distribute = gconv_builtin.h gconv_int.h
|
||||
|
||||
others = iconv_prog
|
||||
|
@ -19,39 +19,58 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <gconv.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
||||
size_t *outbytesleft, size_t *converted)
|
||||
__gconv (gconv_t cd, const char **inbuf, const char *inbufend, char **outbuf,
|
||||
char *outbufend, size_t *converted)
|
||||
{
|
||||
size_t last_step = cd->nsteps - 1;
|
||||
size_t oldinbytes = *inbytesleft;
|
||||
int result;
|
||||
|
||||
if (cd == (gconv_t) -1L)
|
||||
return GCONV_ILLEGAL_DESCRIPTOR;
|
||||
|
||||
cd->data[last_step].outbuf = outbuf ? *outbuf : NULL;
|
||||
cd->data[last_step].outbufavail = 0;
|
||||
cd->data[last_step].outbufsize = *outbytesleft;
|
||||
assert (converted != NULL);
|
||||
*converted = 0;
|
||||
|
||||
if (converted != NULL)
|
||||
*converted = 0;
|
||||
|
||||
result = (*cd->steps->fct) (cd->steps, cd->data,
|
||||
inbuf ? *inbuf : NULL, inbytesleft,
|
||||
converted, inbuf == NULL || *inbuf == NULL);
|
||||
|
||||
if (inbuf != NULL && *inbuf != NULL)
|
||||
*inbuf += oldinbytes - *inbytesleft;
|
||||
if (outbuf != NULL && *outbuf != NULL)
|
||||
if (inbuf == NULL || *inbuf == NULL)
|
||||
/* We just flush. */
|
||||
result = (*cd->steps->fct) (cd->steps, cd->data, NULL, NULL, converted, 1);
|
||||
else
|
||||
{
|
||||
*outbuf += cd->data[last_step].outbufavail;
|
||||
*outbytesleft -= cd->data[last_step].outbufavail;
|
||||
const char *last_start;
|
||||
|
||||
assert (outbuf != NULL && *outbuf != NULL);
|
||||
cd->data[last_step].outbuf = *outbuf;
|
||||
cd->data[last_step].outbufend = outbufend;
|
||||
|
||||
do
|
||||
{
|
||||
/* See whether the input size is reasoable for the output
|
||||
size. If not adjust it. */
|
||||
size_t inlen = ((inbufend - *inbuf) / cd->steps->max_needed_from
|
||||
* cd->steps->max_needed_from);
|
||||
|
||||
if (cd->nsteps > 1)
|
||||
inlen = MIN (inlen, (((outbufend - cd->data[last_step].outbuf)
|
||||
/ cd->steps[last_step].max_needed_to)
|
||||
* cd->steps[last_step].max_needed_to));
|
||||
|
||||
last_start = *inbuf;
|
||||
result = (*cd->steps->fct) (cd->steps, cd->data, inbuf,
|
||||
*inbuf + inlen, converted, 0);
|
||||
}
|
||||
while (result == GCONV_EMPTY_INPUT && last_start != *inbuf
|
||||
&& *inbuf + cd->steps->min_needed_from <= inbufend);
|
||||
}
|
||||
|
||||
if (outbuf != NULL && *outbuf != NULL)
|
||||
*outbuf = cd->data[last_step].outbuf;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ struct gconv_loaded_object;
|
||||
|
||||
/* Type of a conversion function. */
|
||||
typedef int (*gconv_fct) __P ((struct gconv_step *,
|
||||
struct gconv_step_data *,
|
||||
__const char *, size_t *, size_t *, int));
|
||||
struct gconv_step_data *, __const char **,
|
||||
__const char *, size_t *, int));
|
||||
|
||||
/* Constructor and destructor for local data for conversion step. */
|
||||
typedef int (*gconv_init_fct) __P ((struct gconv_step *));
|
||||
@ -80,6 +80,13 @@ struct gconv_step
|
||||
gconv_init_fct init_fct;
|
||||
gconv_end_fct end_fct;
|
||||
|
||||
/* Information about the number of bytes needed or produced in this
|
||||
step. This helps optimizing the buffer sizes. */
|
||||
int min_needed_from;
|
||||
int max_needed_from;
|
||||
int min_needed_to;
|
||||
int max_needed_to;
|
||||
|
||||
void *data; /* Pointer to step-local data. */
|
||||
};
|
||||
|
||||
@ -88,8 +95,7 @@ struct gconv_step
|
||||
struct gconv_step_data
|
||||
{
|
||||
char *outbuf; /* Output buffer for this step. */
|
||||
size_t outbufavail; /* Bytes already available in output buffer. */
|
||||
size_t outbufsize; /* Size of output buffer. */
|
||||
char *outbufend; /* Address of first byte after the output buffer. */
|
||||
|
||||
int is_last;
|
||||
|
||||
|
@ -33,15 +33,25 @@ static struct builtin_map
|
||||
gconv_init_fct init;
|
||||
gconv_end_fct end;
|
||||
|
||||
int min_needed_from;
|
||||
int max_needed_from;
|
||||
int min_needed_to;
|
||||
int max_needed_to;
|
||||
|
||||
} map[] =
|
||||
{
|
||||
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
|
||||
Fct, Init, End) \
|
||||
Fct, Init, End, MinF, MaxF, MinT, MaxT) \
|
||||
{ \
|
||||
name: Name, \
|
||||
fct: Fct, \
|
||||
init: Init, \
|
||||
end: End, \
|
||||
\
|
||||
min_needed_from: MinF, \
|
||||
max_needed_from: MaxF, \
|
||||
min_needed_to: MinT, \
|
||||
max_needed_to: MaxT \
|
||||
},
|
||||
#define BUILTIN_ALIAS(From, To)
|
||||
|
||||
@ -66,4 +76,9 @@ __gconv_get_builtin_trans (const char *name, struct gconv_step *step)
|
||||
step->end_fct = map[cnt].end;
|
||||
step->counter = INT_MAX;
|
||||
step->shlib_handle = NULL;
|
||||
|
||||
step->min_needed_from = map[cnt].min_needed_from;
|
||||
step->max_needed_from = map[cnt].max_needed_from;
|
||||
step->min_needed_to = map[cnt].min_needed_to;
|
||||
step->max_needed_to = map[cnt].max_needed_to;
|
||||
}
|
||||
|
@ -26,10 +26,12 @@ BUILTIN_ALIAS ("10646-1:1993/UCS4/", "ISO-10646/UCS4/")
|
||||
|
||||
BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8,
|
||||
"ISO-10646/UCS4/", 1, "=INTERNAL->ucs4",
|
||||
__gconv_transform_internal_ucs4, NULL, NULL)
|
||||
__gconv_transform_internal_ucs4, NULL, NULL,
|
||||
4, 4, 4, 4)
|
||||
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS4/", 15,
|
||||
"INTERNAL", 1, "=ucs4->INTERNAL",
|
||||
__gconv_transform_internal_ucs4, NULL, NULL)
|
||||
__gconv_transform_internal_ucs4, NULL, NULL,
|
||||
4, 4, 4, 4)
|
||||
/* Please note that we need only one function for both direction. */
|
||||
|
||||
BUILTIN_ALIAS ("UTF8//", "ISO-10646/UTF8/")
|
||||
@ -37,22 +39,27 @@ BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/")
|
||||
|
||||
BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8,
|
||||
"ISO-10646/UTF8/", 1, "=INTERNAL->utf8",
|
||||
__gconv_transform_internal_utf8, NULL, NULL)
|
||||
__gconv_transform_internal_utf8, NULL, NULL,
|
||||
4, 4, 1, 6)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("ISO-10646/UTF-?8/", "ISO-10646/UTF", 13,
|
||||
"INTERNAL", 1, "=utf8->INTERNAL",
|
||||
__gconv_transform_utf8_internal, NULL, NULL)
|
||||
__gconv_transform_utf8_internal, NULL, NULL,
|
||||
1, 6, 4, 4)
|
||||
|
||||
BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/")
|
||||
BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/")
|
||||
|
||||
BUILTIN_TRANSFORMATION (NULL, "ISO-10646/UCS2/", 15, "INTERNAL",
|
||||
1, "=ucs2->INTERNAL",
|
||||
__gconv_transform_ucs2_internal, NULL, NULL)
|
||||
__gconv_transform_ucs2_internal, NULL, NULL,
|
||||
2, 2, 4, 4)
|
||||
|
||||
BUILTIN_TRANSFORMATION (NULL, "INTERNAL", 8, "ISO-10646/UCS2/",
|
||||
1, "=INTERNAL->ucs2",
|
||||
__gconv_transform_internal_ucs2, NULL, NULL)
|
||||
__gconv_transform_internal_ucs2, NULL, NULL,
|
||||
4, 4, 2, 2)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
|
||||
__gconv_transform_dummy, NULL, NULL)
|
||||
__gconv_transform_dummy, NULL, NULL,
|
||||
1, 1, 1, 1)
|
||||
|
@ -47,7 +47,7 @@ static const char gconv_module_ext[] = MODULE_EXT;
|
||||
static struct gconv_module builtin_modules[] =
|
||||
{
|
||||
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
|
||||
Fct, Init, End) \
|
||||
Fct, Init, End, MinF, MaxF, MinT, MaxT) \
|
||||
{ \
|
||||
from_pattern: From, \
|
||||
from_constpfx: ConstPfx, \
|
||||
@ -69,7 +69,7 @@ static const char *
|
||||
builtin_aliases[] =
|
||||
{
|
||||
#define BUILTIN_TRANSFORMATION(From, ConstPfx, ConstLen, To, Cost, Name, \
|
||||
Fct, Init, End)
|
||||
Fct, Init, End, MinF, MaxF, MinT, MaxT)
|
||||
#define BUILTIN_ALIAS(From, To) From " " To,
|
||||
|
||||
#include "gconv_builtin.h"
|
||||
|
@ -192,6 +192,7 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
? __strdup (current->result_set)
|
||||
: result[step_cnt + 1].from_name);
|
||||
|
||||
#ifndef STATIC_GCONV
|
||||
if (current->code->module_name[0] == '/')
|
||||
{
|
||||
/* Load the module, return handle for it. */
|
||||
@ -212,6 +213,7 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
result[step_cnt].end_fct = shlib_handle->end_fct;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* It's a builtin transformation. */
|
||||
__gconv_get_builtin_trans (current->code->module_name,
|
||||
&result[step_cnt]);
|
||||
@ -230,7 +232,9 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
{
|
||||
if (result[step_cnt].end_fct != NULL)
|
||||
(*result[step_cnt].end_fct) (&result[step_cnt]);
|
||||
#ifndef STATIC_GCONV
|
||||
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
||||
#endif
|
||||
}
|
||||
free (result);
|
||||
*nsteps = 0;
|
||||
@ -525,6 +529,7 @@ __gconv_find_transform (const char *toset, const char *fromset,
|
||||
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
|
||||
handle, nsteps);
|
||||
|
||||
#ifndef STATIC_GCONV
|
||||
/* Increment the user counter. */
|
||||
if (result == GCONV_OK)
|
||||
{
|
||||
@ -548,6 +553,7 @@ __gconv_find_transform (const char *toset, const char *fromset,
|
||||
}
|
||||
while (cnt > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Release the lock. */
|
||||
__libc_lock_unlock (lock);
|
||||
@ -568,6 +574,7 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
|
||||
{
|
||||
int result = GCONV_OK;
|
||||
|
||||
#ifndef STATIC_GCONV
|
||||
/* Acquire the lock. */
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
@ -583,6 +590,7 @@ __gconv_close_transform (struct gconv_step *steps, size_t nsteps)
|
||||
|
||||
/* Release the lock. */
|
||||
__libc_lock_unlock (lock);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ struct gconv_alias
|
||||
};
|
||||
|
||||
|
||||
/* Default size of intermediate buffers. */
|
||||
#define GCONV_DEFAULT_BUFSIZE 8160
|
||||
/* How many character should be conveted in one call? */
|
||||
#define GCONV_NCHAR_GOAL 8160
|
||||
|
||||
|
||||
/* Structure describing one loaded shared object. This normally are
|
||||
@ -99,9 +99,8 @@ extern int __gconv_close (gconv_t cd)
|
||||
according to rules described by CD and place up to *OUTBYTESLEFT
|
||||
bytes in buffer starting at *OUTBUF. Return number of written
|
||||
characters in *CONVERTED if this pointer is not null. */
|
||||
extern int __gconv (gconv_t __cd, const char **__inbuf, size_t *__inbytesleft,
|
||||
char **__outbuf, size_t *__outbytesleft,
|
||||
size_t *__converted)
|
||||
extern int __gconv (gconv_t __cd, const char **__inbuf, const char *inbufend,
|
||||
char **__outbuf, char *outbufend, size_t *__converted)
|
||||
internal_function;
|
||||
|
||||
/* Return in *HANDLE a pointer to an array with *NSTEPS elements describing
|
||||
@ -149,8 +148,8 @@ extern void __gconv_get_builtin_trans (const char *__name,
|
||||
#ifdef _LIBC
|
||||
# define __BUILTIN_TRANS(Name) \
|
||||
extern int Name (struct gconv_step *__step, struct gconv_step_data *__data, \
|
||||
const char *__inbuf, size_t *__inlen, size_t *__written, \
|
||||
int __do_flush)
|
||||
const char **__inbuf, const char *__inbufend, \
|
||||
size_t *__written, int __do_flush)
|
||||
|
||||
__BUILTIN_TRANS (__gconv_transform_dummy);
|
||||
__BUILTIN_TRANS (__gconv_transform_ascii_internal);
|
||||
|
@ -62,21 +62,24 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
|
||||
for (cnt = 0; cnt < nsteps; ++cnt)
|
||||
{
|
||||
/* If this is the last step we must not allocate an output
|
||||
buffer. Signal this to the initializer. */
|
||||
buffer. */
|
||||
data[cnt].is_last = cnt == nsteps - 1;
|
||||
|
||||
/* We use the `mbstate_t' member in DATA. */
|
||||
data[cnt].statep = &data[cnt].__state;
|
||||
|
||||
/* Allocate the buffer. */
|
||||
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
|
||||
data[cnt].outbuf = (char *) malloc (data[cnt].outbufsize);
|
||||
if (data[cnt].outbuf == NULL)
|
||||
if (!data[cnt].is_last)
|
||||
{
|
||||
res = GCONV_NOMEM;
|
||||
break;
|
||||
data[cnt].outbuf =
|
||||
(char *) malloc (GCONV_NCHAR_GOAL
|
||||
* steps[cnt].max_needed_to);
|
||||
if (data[cnt].outbuf == NULL)
|
||||
{
|
||||
res = GCONV_NOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data[cnt].outbufavail = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1216
iconv/gconv_simple.c
1216
iconv/gconv_simple.c
File diff suppressed because it is too large
Load Diff
@ -32,10 +32,27 @@ iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
||||
size_t *outbytesleft)
|
||||
{
|
||||
gconv_t gcd = (gconv_t) cd;
|
||||
char *outstart = outbuf ? *outbuf : NULL;
|
||||
size_t converted;
|
||||
int result;
|
||||
|
||||
result = __gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted);
|
||||
if (inbuf == NULL || *inbuf == NULL)
|
||||
{
|
||||
result = __gconv (gcd, NULL, NULL, outbuf, outstart + *outbytesleft,
|
||||
&converted);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *instart = *inbuf;
|
||||
|
||||
result = __gconv (gcd, inbuf, *inbuf + *inbytesleft, outbuf,
|
||||
*outbuf + *outbytesleft, &converted);
|
||||
|
||||
*inbytesleft -= *inbuf - instart;
|
||||
}
|
||||
if (outstart != NULL)
|
||||
*outbytesleft -= *outbuf - outstart;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case GCONV_ILLEGAL_DESCRIPTOR:
|
||||
|
@ -299,12 +299,15 @@ process_block (iconv_t cd, const char *addr, size_t len, FILE *output)
|
||||
{
|
||||
#define OUTBUF_SIZE 32768
|
||||
char outbuf[OUTBUF_SIZE];
|
||||
char *outptr = outbuf;
|
||||
size_t outlen = OUTBUF_SIZE;
|
||||
char *outptr;
|
||||
size_t outlen;
|
||||
size_t n;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
size_t n = iconv (cd, &addr, &len, &outptr, &outlen);
|
||||
outptr = outbuf;
|
||||
outlen = OUTBUF_SIZE;
|
||||
n = iconv (cd, &addr, &len, &outptr, &outlen);
|
||||
|
||||
if (outptr != outbuf)
|
||||
{
|
||||
|
226
iconv/loop.c
Normal file
226
iconv/loop.c
Normal file
@ -0,0 +1,226 @@
|
||||
/* Conversion loop frame work.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file provides a frame for the reader loop in all conversion modules.
|
||||
The actual code must (of course) be provided in the actual module source
|
||||
code but certain actions can be written down generically, with some
|
||||
customization options which are these:
|
||||
|
||||
MIN_NEEDED_INPUT minimal number of input bytes needed for the next
|
||||
conversion.
|
||||
MIN_NEEDED_OUTPUT minimal number of bytes produced by the next round
|
||||
of conversion.
|
||||
|
||||
MAX_NEEDED_INPUT you guess it, this is the maximal number of input
|
||||
bytes needed. It defaults to MIN_NEEDED_INPUT
|
||||
MAX_NEEDED_OUTPUT likewise for output bytes.
|
||||
|
||||
Both values have a default of 1.
|
||||
|
||||
LOOPFCT name of the function created. If not specified
|
||||
the name is `loop' but this prevents the use
|
||||
of multiple functions in the same file.
|
||||
|
||||
COUNT_CONVERTED optional macro which is used to count the actual
|
||||
number of characters converted. For some conversion
|
||||
it is easy to compute the value afterwards, but for
|
||||
others explicit counting is cheaper.
|
||||
|
||||
BODY this is supposed to expand to the body of the loop.
|
||||
The user must provide this.
|
||||
*/
|
||||
|
||||
#include <gconv.h>
|
||||
#include <sys/param.h> /* For MIN. */
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* We need at least one byte for the next round. */
|
||||
#ifndef MIN_NEEDED_INPUT
|
||||
# define MIN_NEEDED_INPUT 1
|
||||
#endif
|
||||
|
||||
/* Let's see how many bytes we produce. */
|
||||
#ifndef MAX_NEEDED_INPUT
|
||||
# define MAX_NEEDED_INPUT MIN_NEEDED_INPUT
|
||||
#endif
|
||||
|
||||
/* We produce at least one byte in the next round. */
|
||||
#ifndef MIN_NEEDED_OUTPUT
|
||||
# define MIN_NEEDED_OUTPUT 1
|
||||
#endif
|
||||
|
||||
/* Let's see how many bytes we produce. */
|
||||
#ifndef MAX_NEEDED_OUTPUT
|
||||
# define MAX_NEEDED_OUTPUT MIN_NEEDED_OUTPUT
|
||||
#endif
|
||||
|
||||
/* Default name for the function. */
|
||||
#ifndef LOOPFCT
|
||||
# define LOOPFCT loop
|
||||
#endif
|
||||
|
||||
/* Make sure we have a loop body. */
|
||||
#ifndef BODY
|
||||
# error "Definition of BODY missing for function" LOOPFCT
|
||||
#endif
|
||||
|
||||
/* We can calculate the number of converted characters easily if one
|
||||
of the character sets has a fixed width. */
|
||||
#ifndef COUNT_CONVERTED
|
||||
# if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT
|
||||
# if MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
|
||||
/* Decide whether one of the charsets has size 1. */
|
||||
# if MIN_NEEDED_INPUT == 1
|
||||
# define COUNT_CONVERTED (inptr - *inptrp)
|
||||
# elif MIN_NEEDED_OUTPUT == 1
|
||||
# define COUNT_CONVERTED (outptr - *outptrp)
|
||||
# else
|
||||
/* Else we should see whether one of the two numbers is a power of 2. */
|
||||
# define COUNT_CONVERTED \
|
||||
((MIN_NEEDED_INPUT & (-MIN_NEEDED_INPUT)) == MIN_NEEDED_INPUT \
|
||||
? (inptr - *inptrp) : (outptr - *outptrp))
|
||||
# endif
|
||||
# else
|
||||
# define COUNT_CONVERTED (inptr - *inptrp)
|
||||
# endif
|
||||
# elif MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
|
||||
# define COUNT_CONVERTED (outptr - *outptrp)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* The function returns the status, as defined in gconv.h. */
|
||||
static inline int
|
||||
LOOPFCT (const unsigned char **inptrp, const unsigned char *inend,
|
||||
unsigned char **outptrp, unsigned char *outend, mbstate_t *state,
|
||||
void *data, size_t *converted)
|
||||
{
|
||||
int result = GCONV_OK;
|
||||
const unsigned char *inptr = *inptrp;
|
||||
unsigned char *outptr = *outptrp;
|
||||
#ifndef COUNT_CONVERTED
|
||||
size_t done = 0;
|
||||
#endif
|
||||
|
||||
/* We run one loop where we avoid checks for underflow/overflow of the
|
||||
buffers to speed up the conversion a bit. */
|
||||
size_t min_in_rounds = (inend - inptr) / MAX_NEEDED_INPUT;
|
||||
size_t min_out_rounds = (outend - outptr) / MAX_NEEDED_OUTPUT;
|
||||
size_t min_rounds = MIN (min_in_rounds, min_out_rounds);
|
||||
|
||||
#undef NEED_LENGTH_TEST
|
||||
#define NEED_LENGTH_TEST 0
|
||||
while (min_rounds-- > 0)
|
||||
{
|
||||
/* Here comes the body the user provides. It can stop with RESULT
|
||||
set to GCONV_INCOMPLETE_INPUT (if the size of the input characters
|
||||
vary in size), GCONV_ILLEGAL_INPUT, or GCONV_FULL_OUTPUT (if the
|
||||
output characters vary in size. */
|
||||
BODY
|
||||
|
||||
/* If necessary count the successful conversion. */
|
||||
#ifndef COUNT_CONVERTED
|
||||
++done;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (result == GCONV_OK)
|
||||
{
|
||||
#if MIN_NEEDED_INPUT == MAX_NEEDED_INPUT \
|
||||
&& MIN_NEEDED_OUTPUT == MAX_NEEDED_OUTPUT
|
||||
/* We don't need to start another loop since we were able to determine
|
||||
the maximal number of characters to copy in advance. What remains
|
||||
to be determined is the status. */
|
||||
if (inptr == inend)
|
||||
/* No more input. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
else if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
|
||||
|| (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
|
||||
/* Overflow in the output buffer. */
|
||||
result = GCONV_FULL_OUTPUT;
|
||||
else
|
||||
/* We have something left in the input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
#else
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
# undef NEED_LENGTH_TEST
|
||||
# define NEED_LENGTH_TEST 1
|
||||
while (inptr != inend)
|
||||
{
|
||||
/* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the
|
||||
compiler generating better code. It will optimized away
|
||||
since MIN_NEEDED_OUTPUT is always a constant. */
|
||||
if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend)
|
||||
|| (MIN_NEEDED_OUTPUT == 1 && outptr >= outend))
|
||||
{
|
||||
/* Overflow in the output buffer. */
|
||||
result = GCONV_FULL_OUTPUT;
|
||||
break;
|
||||
}
|
||||
if (MIN_NEEDED_INPUT > 1 && inptr + MIN_NEEDED_INPUT > inend)
|
||||
{
|
||||
/* We don't have enough input for another complete input
|
||||
character. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Here comes the body the user provides. It can stop with
|
||||
RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the
|
||||
input characters vary in size), GCONV_ILLEGAL_INPUT, or
|
||||
GCONV_FULL_OUTPUT (if the output characters vary in size. */
|
||||
BODY
|
||||
|
||||
/* If necessary count the successful conversion. */
|
||||
# ifndef COUNT_CONVERTED
|
||||
++done;
|
||||
# endif
|
||||
}
|
||||
#endif /* Input and output charset are not both fixed width. */
|
||||
}
|
||||
|
||||
/* Add the number of characters we actually converted. */
|
||||
#ifdef COUNT_CONVERTED
|
||||
*converted += COUNT_CONVERTED;
|
||||
#else
|
||||
*converted += done;
|
||||
#endif
|
||||
|
||||
/* Update the pointers pointed to by the parameters. */
|
||||
*inptrp = inptr;
|
||||
*outptrp = outptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* We remove the macro definitions so that we can include this file again
|
||||
for the definition of another function. */
|
||||
#undef MIN_NEEDED_INPUT
|
||||
#undef MAX_NEEDED_INPUT
|
||||
#undef MIN_NEEDED_OUTPUT
|
||||
#undef MAX_NEEDED_OUTPUT
|
||||
#undef LOOPFCT
|
||||
#undef COUNT_CONVERTED
|
||||
#undef BODY
|
||||
#undef LOOPFCT
|
328
iconv/skeleton.c
Normal file
328
iconv/skeleton.c
Normal file
@ -0,0 +1,328 @@
|
||||
/* Skeleton for a converison module.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file can be included to provide definitions of several things
|
||||
many modules have in common. It can be customized using the following
|
||||
macros:
|
||||
|
||||
DEFINE_INIT define the default initializer. This requires the
|
||||
following symbol to be defined.
|
||||
|
||||
CHARSET_NAME string with official name of the coded character
|
||||
set (in all-caps)
|
||||
|
||||
DEFINE_FINI define the default destructor function.
|
||||
|
||||
MIN_NEEDED_FROM minimal number of bytes needed for the from-charset.
|
||||
MIN_NEEDED_TO likewise for the to-charset.
|
||||
|
||||
MAX_NEEDED_FROM maximal number of bytes needed for the from-charset.
|
||||
This macro is optional, it defaults to MIN_NEEDED_FROM.
|
||||
MAX_NEEDED_TO likewise for the to-charset.
|
||||
|
||||
DEFINE_DIRECTION_OBJECTS
|
||||
two objects will be defined to be used when the
|
||||
`gconv' function must only distinguish two
|
||||
directions. This is implied by DEFINE_INIT.
|
||||
If this macro is not defined the following
|
||||
macro must be available.
|
||||
|
||||
FROM_DIRECTION this macro is supposed to return a value != 0
|
||||
if we convert from the current character set,
|
||||
otherwise it return 0.
|
||||
|
||||
EMIT_SHIFT_TO_INIT this symbol is optional. If it is defined it
|
||||
defines some code which writes out a sequence
|
||||
of characters which bring the current state into
|
||||
the initial state.
|
||||
|
||||
FROM_LOOP name of the function implementing the conversion
|
||||
from the current characters.
|
||||
TO_LOOP likewise for the other direction
|
||||
|
||||
RESET_STATE in case of an error we must reset the state for
|
||||
the rerun so this macro must be defined for
|
||||
stateful encodings. It takes an argument which
|
||||
is nonzero when saving.
|
||||
|
||||
RESET_INPUT_BUFFER If the input character sets allow this the macro
|
||||
can be defined to reset the input buffer pointers
|
||||
to cover only those characters up to the error.
|
||||
|
||||
FUNCTION_NAME if not set the conversion function is named `gconv'.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <gconv.h>
|
||||
#include <string.h>
|
||||
#define __need_size_t
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* The direction objects. */
|
||||
#if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT
|
||||
static int from_object;
|
||||
static int to_object;
|
||||
|
||||
# ifndef FROM_DIRECTION
|
||||
# define FROM_DIRECTION step->data == &from_object
|
||||
# endif
|
||||
#else
|
||||
# ifndef FROM_DIRECTION
|
||||
# error "FROM_DIRECTION must be provided if direction objects are not used"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* How many bytes are needed at most for the from-charset. */
|
||||
#ifndef MAX_NEEDED_FROM
|
||||
# define MAX_NEEDED_FROM MIN_NEEDED_FROM
|
||||
#endif
|
||||
|
||||
/* Same for the to-charset. */
|
||||
#ifndef MAX_NEEDED_TO
|
||||
# define MAX_NEEDED_TO MIN_NEEDED_TO
|
||||
#endif
|
||||
|
||||
|
||||
/* For conversions from a fixed width character sets to another fixed width
|
||||
character set we we can define RESET_INPUT_BUFFER is necessary. */
|
||||
#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
|
||||
# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
|
||||
/* We have to used these `if's here since the compiler cannot know that
|
||||
(outbuf - outerr) is always divisible by MIN_NEEDED_TO. */
|
||||
# define RESET_INPUT_BUFFER \
|
||||
if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0) \
|
||||
*inbuf -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO); \
|
||||
else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0) \
|
||||
*inbuf -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM); \
|
||||
else \
|
||||
*inbuf -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* The default init function. It simply matches the name and initializes
|
||||
the step data to point to one of the objects above. */
|
||||
#if DEFINE_INIT
|
||||
# ifndef CHARSET_NAME
|
||||
# error "CHARSET_NAME not defined"
|
||||
# endif
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (__strcasestr (step->from_name, CHARSET_NAME) != NULL)
|
||||
step->data = &from_object;
|
||||
else if (__strcasestr (step->to_name, CHARSET_NAME) != NULL)
|
||||
step->data = &to_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
step->min_needed_from = MIN_NEEDED_FROM;
|
||||
step->max_needed_from = MAX_NEEDED_FROM;
|
||||
step->min_needed_to = MIN_NEEDED_TO;
|
||||
step->max_needed_to = MAX_NEEDED_TO;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* The default destructor function does nothing in the moment and so
|
||||
be define it at all. But we still provide the macro just in case
|
||||
we need it some day. */
|
||||
#if DEFINE_FINI
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the actual conversion function. */
|
||||
#ifndef FUNCTION_NAME
|
||||
# define FUNCTION_NAME gconv
|
||||
#endif
|
||||
|
||||
int
|
||||
FUNCTION_NAME (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char **inbuf, const char *inbufend, size_t *written,
|
||||
int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
int status;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
status = GCONV_OK;
|
||||
else
|
||||
{
|
||||
#ifdef EMIT_SHIFT_TO_INIT
|
||||
status = GCONV_OK;
|
||||
|
||||
EMIT_SHIFT_TO_INIT;
|
||||
|
||||
if (status == GCONV_OK)
|
||||
#endif
|
||||
/* Give the modules below the same chance. */
|
||||
status = (*fct) (next_step, next_data, NULL, NULL, written, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This variable is used to count the number of characters we
|
||||
actually converted. */
|
||||
size_t converted = 0;
|
||||
|
||||
/* We preserve the initial values of the pointer variables. */
|
||||
const char *inptr = *inbuf;
|
||||
char *outbuf = data->outbuf;
|
||||
char *outend = data->outbufend;
|
||||
char *outptr;
|
||||
|
||||
do
|
||||
{
|
||||
/* Remember the start value for this round. */
|
||||
inptr = *inbuf;
|
||||
/* The outbuf buffer is empty. */
|
||||
outptr = outbuf;
|
||||
|
||||
/* Save the state. */
|
||||
#ifdef SAVE_RESET_STATE
|
||||
SAVE_RESET_STATE (1);
|
||||
#endif
|
||||
|
||||
if (FROM_DIRECTION)
|
||||
/* Run the conversion loop. */
|
||||
status = FROM_LOOP ((const unsigned char **) inbuf,
|
||||
(const unsigned char *) inbufend,
|
||||
(unsigned char **) &outbuf,
|
||||
(unsigned char *) outend,
|
||||
data->statep, step->data, &converted);
|
||||
else
|
||||
/* Run the conversion loop. */
|
||||
status = TO_LOOP ((const unsigned char **) inbuf,
|
||||
(const unsigned char *) inbufend,
|
||||
(unsigned char **) &outbuf,
|
||||
(unsigned char *) outend,
|
||||
data->statep, step->data, &converted);
|
||||
|
||||
/* If this is the last step leave the loop, there is nothgin
|
||||
we can do. */
|
||||
if (data->is_last)
|
||||
{
|
||||
/* Store information about how many bytes are available. */
|
||||
data->outbuf = outbuf;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write out all output which was produced. */
|
||||
if (outbuf > outptr)
|
||||
{
|
||||
const char *outerr = outbuf;
|
||||
int result;
|
||||
|
||||
result = (*fct) (next_step, next_data, &outerr, outbuf,
|
||||
written, 0);
|
||||
|
||||
if (result != GCONV_EMPTY_INPUT)
|
||||
{
|
||||
if (outerr != outbuf)
|
||||
{
|
||||
#ifdef RESET_INPUT_BUFFER
|
||||
RESET_INPUT_BUFFER;
|
||||
#else
|
||||
/* We have a problem with the in on of the functions
|
||||
below. Undo the conversion upto the error point. */
|
||||
size_t nstatus;
|
||||
|
||||
/* Reload the pointers. */
|
||||
*inbuf = inptr;
|
||||
outbuf = outptr;
|
||||
|
||||
/* Reset the state. */
|
||||
# ifdef SAVE_RESET_STATE
|
||||
SAVE_RESET_STATE (0);
|
||||
# endif
|
||||
|
||||
if (FROM_DIRECTION)
|
||||
/* Run the conversion loop. */
|
||||
nstatus = FROM_LOOP ((const unsigned char **) inbuf,
|
||||
(const unsigned char *) inbufend,
|
||||
(unsigned char **) &outbuf,
|
||||
(unsigned char *) outerr,
|
||||
data->statep, step->data,
|
||||
&converted);
|
||||
else
|
||||
/* Run the conversion loop. */
|
||||
nstatus = TO_LOOP ((const unsigned char **) inbuf,
|
||||
(const unsigned char *) inbufend,
|
||||
(unsigned char **) &outbuf,
|
||||
(unsigned char *) outerr,
|
||||
data->statep, step->data,
|
||||
&converted);
|
||||
|
||||
/* We must run out of output buffer space in this
|
||||
rerun. */
|
||||
assert (nstatus == GCONV_FULL_OUTPUT
|
||||
&& outbuf == outerr);
|
||||
#endif /* reset input buffer */
|
||||
}
|
||||
|
||||
/* Change the status. */
|
||||
status = result;
|
||||
}
|
||||
else
|
||||
/* All the output is consumed, we can make another run
|
||||
if everything was ok. */
|
||||
if (status == GCONV_FULL_OUTPUT)
|
||||
status = GCONV_OK;
|
||||
}
|
||||
}
|
||||
while (status == GCONV_OK);
|
||||
|
||||
/* Remember how many characters we converted. */
|
||||
*written += converted;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#undef DEFINE_INIT
|
||||
#undef CHARSET_NAME
|
||||
#undef DEFINE_FINI
|
||||
#undef MIN_NEEDED_FROM
|
||||
#undef MIN_NEEDED_TO
|
||||
#undef MAX_NEEDED_FROM
|
||||
#undef MAX_NEEDED_TO
|
||||
#undef DEFINE_DIRECTION_OBJECTS
|
||||
#undef FROM_DIRECTION
|
||||
#undef EMIT_SHIFT_TO_INIT
|
||||
#undef FROM_LOOP
|
||||
#undef TO_LOOP
|
||||
#undef RESET_STATE
|
||||
#undef RESET_INPUT_BUFFER
|
||||
#undef FUNCTION_NAME
|
@ -19,10 +19,7 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
struct gap
|
||||
{
|
||||
@ -34,192 +31,68 @@ struct gap
|
||||
/* Now we can include the tables. */
|
||||
#include TABLES
|
||||
|
||||
/* We use three objects to describe the operation mode. */
|
||||
static int from_8bit_object;
|
||||
static int to_8bit_object;
|
||||
|
||||
#define FROM_LOOP from_gap
|
||||
#define TO_LOOP to_gap
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, NAME) != NULL)
|
||||
step->data = &from_8bit_object;
|
||||
else if (strcasestr (step->to_name, NAME) != NULL)
|
||||
step->data = &to_8bit_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from the 8bit charset to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = to_ucs4[*inptr]; \
|
||||
\
|
||||
if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
++inptr; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
const struct gap *rp = from_idx; \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
unsigned char res; \
|
||||
\
|
||||
while (ch > rp->end) \
|
||||
++rp; \
|
||||
if (ch < rp->start) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
res = from_ucs4[ch + rp->idx]; \
|
||||
if (ch != 0 && res == '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = res; \
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_8bit_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
wchar_t ch = to_ucs4[((unsigned char *) inbuf)[cnt]];
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
const struct gap *rp = from_idx;
|
||||
unsigned int ch = *((wchar_t *) (inbuf + cnt));
|
||||
char res;
|
||||
|
||||
while (ch > rp->end)
|
||||
++rp;
|
||||
if (ch < rp->start)
|
||||
/* No valid character. */
|
||||
break;
|
||||
|
||||
res = from_ucs4[ch + rp->idx];
|
||||
if (res == '\0' && ch != 0)
|
||||
/* No valid character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = res;
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_8bit_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -18,186 +18,56 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <string.h>
|
||||
|
||||
/* We use three objects to describe the operation mode. */
|
||||
static int from_8bit_object;
|
||||
static int to_8bit_object;
|
||||
#define FROM_LOOP from_generic
|
||||
#define TO_LOOP to_generic
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, NAME) != NULL)
|
||||
step->data = &from_8bit_object;
|
||||
else if (strcasestr (step->to_name, NAME) != NULL)
|
||||
step->data = &to_8bit_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from the 8bit charset to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = to_ucs4[*inptr]; \
|
||||
\
|
||||
if (HAS_HOLES && ch == L'\0' && *inptr != '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
++inptr; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
\
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]) \
|
||||
|| (ch != 0 && from_ucs4[ch] == '\0')) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = from_ucs4[ch]; \
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_8bit_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
wchar_t ch = to_ucs4[((unsigned char *) inbuf)[cnt]];
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
int ch = *((wchar_t *) (inbuf + cnt));
|
||||
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])
|
||||
|| ch < 0 || (from_ucs4[ch] == '\0' && ch != 0))
|
||||
break;
|
||||
|
||||
outbuf[outchars] = from_ucs4[ch];
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_8bit_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -26,8 +26,8 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
|
||||
ISO8859-6 ISO8859-7 ISO8859-8 ISO8859-9 ISO8859-10 \
|
||||
T.61 ISO_6937 SJIS KOI-8 KOI8-R LATIN-GREEK LATIN-GREEK-1 \
|
||||
HP-ROMAN8 EBCDIC-AT-DE EBCDIC-AT-DE-A EBCDIC-CA-FR \
|
||||
EUC-KR UHC JOHAB libJIS libKSC ISO646 BIG5 EUC-JP libGB \
|
||||
EUC-CN libCNS EUC-TW
|
||||
EUC-KR UHC JOHAB libJIS libKSC BIG5 EUC-JP libGB \
|
||||
EUC-CN libCNS EUC-TW # ISO646
|
||||
modules.so := $(addsuffix .so, $(modules))
|
||||
|
||||
|
||||
@ -211,7 +211,7 @@ endif
|
||||
include ../Rules
|
||||
|
||||
.PHONY: do-iconv-test
|
||||
tests: do-iconv-test
|
||||
#tests: do-iconv-test
|
||||
|
||||
do-iconv-test: run-iconv-test.sh $(objpfx)gconv-modules \
|
||||
$(addprefix $(objpfx),$(modules.so)) \
|
||||
|
451
iconvdata/big5.c
451
iconvdata/big5.c
@ -8411,289 +8411,180 @@ static const char from_ucs4_tab13[][2] =
|
||||
};
|
||||
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_big5_object;
|
||||
static int from_big5_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "BIG5"
|
||||
#define FROM_LOOP from_big5
|
||||
#define TO_LOOP to_big5
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "BIG5") != NULL)
|
||||
step->data = &from_big5_object;
|
||||
else if (strcasestr (step->to_name, "BIG5") != NULL)
|
||||
step->data = &to_big5_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from Big5 to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch >= '\xa1' && ch <= '\xff') \
|
||||
{ \
|
||||
/* Two-byte character. First test whether the next character \
|
||||
is also available. */ \
|
||||
uint32_t ch2; \
|
||||
int idx; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
idx = (ch - 0xa1) * 157; \
|
||||
ch2 = inptr[1]; \
|
||||
/* See whether the second byte is in the correct range. */ \
|
||||
if (ch2 >= '\x40' && ch2 <= '\x7e') \
|
||||
idx += ch2 - 0x40; \
|
||||
else if (ch2 >= '\xa1' && ch2 <= '\xfe') \
|
||||
idx += 0x3f + (ch2 - 0xa1); \
|
||||
else \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* Get the value from the table. */ \
|
||||
ch = big5_to_ucs[idx]; \
|
||||
\
|
||||
/* Is this character defined? */ \
|
||||
if (ch == L'\0' && *inptr != '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
else \
|
||||
++inptr; \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
char buf[2]; \
|
||||
const char *cp; \
|
||||
\
|
||||
if (ch >= sizeof (from_ucs4_tab1) / sizeof (from_ucs4_tab1[0])) \
|
||||
switch (ch) \
|
||||
{ \
|
||||
case 0x2c7 ... 0x2d9: \
|
||||
cp = from_ucs4_tab2[ch - 0x2c7]; \
|
||||
break; \
|
||||
case 0x391 ... 0x451: \
|
||||
cp = from_ucs4_tab3[ch - 0x391]; \
|
||||
break; \
|
||||
case 0x2013 ... 0x203e: \
|
||||
cp = from_ucs4_tab4[ch - 0x2013]; \
|
||||
break; \
|
||||
case 0x2103: \
|
||||
cp = "\xa2\x4a"; \
|
||||
break; \
|
||||
case 0x2105: \
|
||||
cp = "\xa1\xc1"; \
|
||||
break; \
|
||||
case 0x2109: \
|
||||
cp = "\xa2\x4b"; \
|
||||
break; \
|
||||
case 0x2160 ... 0x2169: \
|
||||
{ \
|
||||
buf[0] = '\xa2'; \
|
||||
buf[1] = '\xb9' + (ch - 0x2160); \
|
||||
cp = buf; \
|
||||
} \
|
||||
break; \
|
||||
case 0x2190 ... 0x2199: \
|
||||
cp = from_ucs4_tab5[ch - 0x2190]; \
|
||||
break; \
|
||||
case 0x221a ... 0x22bf: \
|
||||
cp = from_ucs4_tab6[ch - 0x221a]; \
|
||||
break; \
|
||||
case 0x2460 ... 0x247d: \
|
||||
cp = from_ucs4_tab7[ch - 0x2460]; \
|
||||
break; \
|
||||
case 0x2500 ... 0x2642: \
|
||||
cp = from_ucs4_tab8[ch - 0x2500]; \
|
||||
break; \
|
||||
case 0x3000 ... 0x3129: \
|
||||
cp = from_ucs4_tab9[ch - 0x3000]; \
|
||||
break; \
|
||||
case 0x32a3: \
|
||||
cp = "\xa1\xc0"; \
|
||||
break; \
|
||||
case 0x338e ... 0x33d5: \
|
||||
cp = from_ucs4_tab10[ch - 0x338e]; \
|
||||
break; \
|
||||
case 0x4e00 ... 0x9fa4: \
|
||||
cp = from_ucs4_tab11[ch - 0x4e00]; \
|
||||
break; \
|
||||
case 0xfa0c: \
|
||||
cp = "\xc9\x4a"; \
|
||||
break; \
|
||||
case 0xfa0d: \
|
||||
cp = "\xdd\xfc"; \
|
||||
break; \
|
||||
case 0xfe30 ... 0xfe6b: \
|
||||
cp = from_ucs4_tab12[ch - 0xfe30]; \
|
||||
break; \
|
||||
case 0xff01 ... 0xff64: \
|
||||
cp = from_ucs4_tab13[ch - 0xff01]; \
|
||||
break; \
|
||||
default: \
|
||||
/* Illegal character. */ \
|
||||
cp = ""; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
cp = from_ucs4_tab1[ch]; \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* See whether there is enough room for the second byte we write. */ \
|
||||
if (NEED_LENGTH_TEST && cp[1] != '\0' && outptr + 1 >= outend) \
|
||||
{ \
|
||||
/* We have not enough room. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
if (cp[1] != '\0') \
|
||||
*outptr++ = cp[1]; \
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_big5_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar < '\xa1' || inchar > '\xfe')
|
||||
ch = (wchar_t) inchar;
|
||||
else
|
||||
{
|
||||
/* Two-byte character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
int idx;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
idx = (inchar - 0xa1) * 157;
|
||||
inchar2 = inbuf[++cnt];
|
||||
/* See whether the second byte is in the correct
|
||||
range. */
|
||||
if (inchar2 >= '\x40' && inchar2 <= '\x7e')
|
||||
idx += inchar2 - 0x40;
|
||||
else if (inchar2 >= '\xa1' && inchar2 <= '\xfe')
|
||||
idx += 0x3f + (inchar2 - 0xa1);
|
||||
else
|
||||
{
|
||||
/* This is illegal. */
|
||||
--cnt;
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the value from the table. */
|
||||
ch = big5_to_ucs[idx];
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
int ch = *((wchar_t *) (inbuf + cnt));
|
||||
char buf[2];
|
||||
const char *cp;
|
||||
|
||||
if (ch >= (sizeof (from_ucs4_tab1)
|
||||
/ sizeof (from_ucs4_tab1[0])))
|
||||
{
|
||||
if (ch >= 0x2c7 && ch <= 0x2d9)
|
||||
cp = from_ucs4_tab2[ch - 0x2c7];
|
||||
else if (ch >= 0x391 && ch <= 0x451)
|
||||
cp = from_ucs4_tab3[ch - 0x391];
|
||||
else if (ch >= 0x2013 && ch <= 0x203e)
|
||||
cp = from_ucs4_tab4[ch - 0x2013];
|
||||
else if (ch == 0x2103)
|
||||
cp = "\xa2\x4a";
|
||||
else if (ch == 0x2105)
|
||||
cp = "\xa1\xc1";
|
||||
else if (ch == 0x2109)
|
||||
cp = "\xa2\x4b";
|
||||
else if (ch >= 0x2160 && ch <= 0x2169)
|
||||
{
|
||||
buf[0] = '\xa2';
|
||||
buf[1] = '\xb9' + (ch - 0x2160);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch >= 0x2190 && ch <= 0x2199)
|
||||
cp = from_ucs4_tab5[ch - 0x2190];
|
||||
else if (ch >= 0x221a && ch <= 0x22bf)
|
||||
cp = from_ucs4_tab6[ch - 0x221a];
|
||||
else if (ch >= 0x2460 && ch <= 0x247d)
|
||||
cp = from_ucs4_tab7[ch - 0x2460];
|
||||
else if (ch >= 0x2500 && ch <= 0x2642)
|
||||
cp = from_ucs4_tab8[ch - 0x2500];
|
||||
else if (ch >= 0x3000 && ch <= 0x3129)
|
||||
cp = from_ucs4_tab9[ch - 0x3000];
|
||||
else if (ch == 0x32a3)
|
||||
cp = "\xa1\xc0";
|
||||
else if (ch >= 0x338e && ch <= 0x33d5)
|
||||
cp = from_ucs4_tab10[ch - 0x338e];
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fa4)
|
||||
cp = from_ucs4_tab11[ch - 0x4e00];
|
||||
else if (ch == 0xfa0c)
|
||||
cp = "\xc9\x4a";
|
||||
else if (ch == 0xfa0d)
|
||||
cp = "\xdd\xfc";
|
||||
else if (ch >= 0xfe30 && ch <= 0xfe6b)
|
||||
cp = from_ucs4_tab12[ch - 0xfe30];
|
||||
else if (ch >= 0xff01 && ch <= 0xff64)
|
||||
cp = from_ucs4_tab13[ch - 0xff01];
|
||||
else
|
||||
/* Illegal character. */
|
||||
break;
|
||||
}
|
||||
else
|
||||
cp = from_ucs4_tab1[ch];
|
||||
|
||||
if (cp[0] == '\0' && ch != 0)
|
||||
/* Illegal character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_big5_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -44,7 +44,7 @@
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t cns11643l2_to_ucs4_tab[] =
|
||||
const uint16_t __cns11643l2_to_ucs4_tab[] =
|
||||
{
|
||||
[0x0000] = 0x4e42, [0x0001] = 0x4e5c, [0x0002] = 0x51f5, [0x0003] = 0x531a,
|
||||
[0x0004] = 0x5382, [0x0005] = 0x4e07, [0x0006] = 0x4e0c, [0x0007] = 0x4e47,
|
||||
@ -1985,7 +1985,7 @@ const uint16_t cns11643l2_to_ucs4_tab[] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t cns11643l14_to_ucs4_tab[] =
|
||||
const uint16_t __cns11643l14_to_ucs4_tab[] =
|
||||
{
|
||||
[0x0000] = 0x4e28, [0x0001] = 0x4e36, [0x0002] = 0x4e3f, [0x0003] = 0x4e85,
|
||||
[0x0004] = 0x4e05, [0x0005] = 0x4e04, [0x0006] = 0x5182, [0x0007] = 0x5196,
|
||||
@ -3064,7 +3064,7 @@ const uint16_t cns11643l14_to_ucs4_tab[] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643_from_ucs4_tab[][3] =
|
||||
const char __cns11643_from_ucs4_tab[][3] =
|
||||
{
|
||||
[0x0000] = "\x01\x44\x21", [0x0001] = "\x01\x44\x23",
|
||||
[0x0003] = "\x01\x44\x24", [0x0004] = "\x0e\x21\x26",
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* Table for CNS 11643, plane 2 to UCS4 conversion. */
|
||||
extern const uint16_t cns11643l2_to_ucs4_tab[];
|
||||
extern const uint16_t cns11643l14_to_ucs4_tab[];
|
||||
extern const uint16_t __cns11643l2_to_ucs4_tab[];
|
||||
extern const uint16_t __cns11643l14_to_ucs4_tab[];
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
@ -54,19 +54,19 @@ cns11643_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
{
|
||||
if (idx > 0x2196)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
result = cns11643l1_to_ucs4_tab[idx];
|
||||
result = __cns11643l1_to_ucs4_tab[idx];
|
||||
}
|
||||
else if ((ch - 0x21 - offset) == 2)
|
||||
{
|
||||
if (idx > 0x1de1)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
result = cns11643l2_to_ucs4_tab[idx];
|
||||
result = __cns11643l2_to_ucs4_tab[idx];
|
||||
}
|
||||
else if ((ch - 0x21 - offset) == 0xe)
|
||||
{
|
||||
if (idx > 0x19bd)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
result = cns11643l14_to_ucs4_tab[idx];
|
||||
result = __cns11643l14_to_ucs4_tab[idx];
|
||||
}
|
||||
else
|
||||
return UNKNOWN_10646_CHAR;
|
||||
@ -81,21 +81,21 @@ cns11643_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
|
||||
|
||||
/* Tables for the UCS4 -> CNS conversion. */
|
||||
extern const char cns11643l1_from_ucs4_tab1[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab2[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab3[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab4[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab5[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab6[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab7[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab8[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab9[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab10[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab11[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab12[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab13[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab14[][2];
|
||||
extern const char cns11643_from_ucs4_tab[][3];
|
||||
extern const char __cns11643l1_from_ucs4_tab1[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab2[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab3[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab4[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab5[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab6[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab7[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab8[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab9[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab10[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab11[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab12[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab13[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab14[][2];
|
||||
extern const char __cns11643_from_ucs4_tab[][3];
|
||||
|
||||
|
||||
static inline size_t
|
||||
@ -103,120 +103,104 @@ ucs4_to_cns11643 (wchar_t wch, char *s, size_t avail)
|
||||
{
|
||||
unsigned int ch = (unsigned int) wch;
|
||||
char buf[2];
|
||||
const char *cp = NULL;
|
||||
const char *cp = buf;
|
||||
int needed = 2;
|
||||
|
||||
if (ch < 0xa7)
|
||||
cp = "";
|
||||
else if (ch < 0xf7)
|
||||
cp = cns11643l1_from_ucs4_tab1[ch - 0xa7];
|
||||
else if (ch < 0x2c7)
|
||||
cp = "";
|
||||
else if (ch <= 0x2d9)
|
||||
cp = cns11643l1_from_ucs4_tab2[ch - 0x2c7];
|
||||
else if (ch < 0x391)
|
||||
cp = "";
|
||||
else if (ch <= 0x3c9)
|
||||
cp = cns11643l1_from_ucs4_tab3[ch - 0x391];
|
||||
else if (ch < 0x2013)
|
||||
cp = "";
|
||||
else if (ch <= 0x203e)
|
||||
cp = cns11643l1_from_ucs4_tab4[ch - 0x2013];
|
||||
else if (ch == 0x2103)
|
||||
cp = "\x22\x6a";
|
||||
else if (ch == 0x2105)
|
||||
cp = "\x22\x22";
|
||||
else if (ch == 0x2109)
|
||||
cp = "\x22\x6b";
|
||||
else if (ch < 0x2160)
|
||||
cp = "";
|
||||
else if (ch <= 0x2169)
|
||||
switch (ch)
|
||||
{
|
||||
case 0xa7 ... 0xf7:
|
||||
cp = __cns11643l1_from_ucs4_tab1[ch - 0xa7];
|
||||
break;
|
||||
case 0x2c7 ... 0x2d9:
|
||||
cp = __cns11643l1_from_ucs4_tab2[ch - 0x2c7];
|
||||
break;
|
||||
case 0x391 ... 0x3c9:
|
||||
cp = __cns11643l1_from_ucs4_tab3[ch - 0x391];
|
||||
break;
|
||||
case 0x2013 ... 0x203e:
|
||||
cp = __cns11643l1_from_ucs4_tab4[ch - 0x2013];
|
||||
break;
|
||||
case 0x2103:
|
||||
cp = "\x22\x6a";
|
||||
break;
|
||||
case 0x2105:
|
||||
cp = "\x22\x22";
|
||||
break;
|
||||
case 0x2109:
|
||||
cp = "\x22\x6b";
|
||||
break;
|
||||
case 0x2160 ...0x2169:
|
||||
buf[0] = '\x24';
|
||||
buf[1] = '\x2b' + (ch - 0x2160);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch < 0x2170)
|
||||
cp = "";
|
||||
else if (ch <= 0x2179)
|
||||
{
|
||||
break;
|
||||
case 0x2170 ... 0x2179:
|
||||
buf[0] = '\x26';
|
||||
buf[1] = '\x35' + (ch - 0x2170);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch < 0x2190)
|
||||
cp = "";
|
||||
else if (ch <= 0x2199)
|
||||
cp = cns11643l1_from_ucs4_tab5[ch - 0x2190];
|
||||
else if (ch < 0x2215)
|
||||
cp = "";
|
||||
else if (ch <= 0x2267)
|
||||
cp = cns11643l1_from_ucs4_tab6[ch - 0x2215];
|
||||
else if (ch == 0x22a5)
|
||||
cp = "\x22\x47";
|
||||
else if (ch == 0x22bf)
|
||||
cp = "\x22\x4a";
|
||||
else if (ch < 0x2400)
|
||||
cp = "";
|
||||
else if (ch <= 0x2421)
|
||||
cp = cns11643l1_from_ucs4_tab7[ch - 0x2400];
|
||||
else if (ch < 0x2460)
|
||||
cp = "";
|
||||
else if (ch <= 0x247d)
|
||||
cp = cns11643l1_from_ucs4_tab8[ch - 0x2460];
|
||||
else if (ch < 0x2500)
|
||||
cp = "";
|
||||
else if (ch <= 0x2642)
|
||||
cp = cns11643l1_from_ucs4_tab9[ch - 0x2500];
|
||||
else if (ch < 0x3000)
|
||||
cp = "";
|
||||
else if (ch <= 0x3029)
|
||||
cp = cns11643l1_from_ucs4_tab10[ch - 0x3000];
|
||||
else if (ch == 0x30fb)
|
||||
cp = "\x21\x26";
|
||||
else if (ch < 0x3105)
|
||||
cp = "";
|
||||
else if (ch <= 0x3129)
|
||||
{
|
||||
break;
|
||||
case 0x2190 ... 0x2199:
|
||||
cp = __cns11643l1_from_ucs4_tab5[ch - 0x2190];
|
||||
break;
|
||||
case 0x2215 ... 0x2267:
|
||||
cp = __cns11643l1_from_ucs4_tab6[ch - 0x2215];
|
||||
break;
|
||||
case 0x22a5:
|
||||
cp = "\x22\x47";
|
||||
break;
|
||||
case 0x22bf:
|
||||
cp = "\x22\x4a";
|
||||
break;
|
||||
case 0x2400 ... 0x2421:
|
||||
cp = __cns11643l1_from_ucs4_tab7[ch - 0x2400];
|
||||
break;
|
||||
case 0x2460 ... 0x247d:
|
||||
cp = __cns11643l1_from_ucs4_tab8[ch - 0x2460];
|
||||
break;
|
||||
case 0x2500 ... 0x2642:
|
||||
cp = __cns11643l1_from_ucs4_tab9[ch - 0x2500];
|
||||
case 0x3000 ... 0x3029:
|
||||
cp = __cns11643l1_from_ucs4_tab10[ch - 0x3000];
|
||||
break;
|
||||
case 0x30fb:
|
||||
cp = "\x21\x26";
|
||||
break;
|
||||
case 0x3105 ... 0x3129:
|
||||
buf[0] = '\x25';
|
||||
buf[1] = '\x26' + (ch - 0x3105);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch == 0x32a3)
|
||||
cp = "\x22\x21";
|
||||
else if (ch < 0x338e)
|
||||
cp = "";
|
||||
else if (ch <= 0x33d5)
|
||||
cp = cns11643l1_from_ucs4_tab11[ch - 0x338e];
|
||||
else if (ch < 0x4e00)
|
||||
cp = "";
|
||||
else if (ch <= 0x9f9c)
|
||||
{
|
||||
cp = cns11643l1_from_ucs4_tab12[ch - 0x4e00];
|
||||
break;
|
||||
case 0x32a3:
|
||||
cp = "\x22\x21";
|
||||
break;
|
||||
case 0x338e ... 0x33d5:
|
||||
cp = __cns11643l1_from_ucs4_tab11[ch - 0x338e];
|
||||
break;
|
||||
case 0x4e00 ... 0x9f9c:
|
||||
cp = __cns11643l1_from_ucs4_tab12[ch - 0x4e00];
|
||||
|
||||
if (cp[0] == '\0')
|
||||
{
|
||||
/* Let's try the other planes. */
|
||||
needed = 3;
|
||||
cp = cns11643_from_ucs4_tab[ch - 0x4e00];
|
||||
cp = __cns11643_from_ucs4_tab[ch - 0x4e00];
|
||||
}
|
||||
break;
|
||||
case 0xfe30 ... 0xfe6b:
|
||||
cp = __cns11643l1_from_ucs4_tab13[ch - 0xfe30];
|
||||
break;
|
||||
case 0xff01 ... 0xff5d:
|
||||
cp = __cns11643l1_from_ucs4_tab14[ch - 0xff01];
|
||||
break;
|
||||
case 0xffe0:
|
||||
cp = "\x22\x66";
|
||||
break;
|
||||
case 0xffe1:
|
||||
cp = "\x22\x67";
|
||||
break;
|
||||
case 0xffe5:
|
||||
cp = "\x22\x64";
|
||||
break;
|
||||
default:
|
||||
cp = "";
|
||||
}
|
||||
else if (ch < 0xfe30)
|
||||
cp = "";
|
||||
else if (ch <= 0xfe6b)
|
||||
cp = cns11643l1_from_ucs4_tab13[ch - 0xfe30];
|
||||
else if (ch < 0xff01)
|
||||
cp = "";
|
||||
else if (ch <= 0xff5d)
|
||||
cp = cns11643l1_from_ucs4_tab14[ch - 0xff01];
|
||||
else if (ch == 0xffe0)
|
||||
cp = "\x22\x66";
|
||||
else if (ch == 0xffe1)
|
||||
cp = "\x22\x67";
|
||||
else if (ch == 0xffe5)
|
||||
cp = "\x22\x64";
|
||||
else
|
||||
cp = "";
|
||||
|
||||
if (cp[0] == '\0')
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
@ -45,7 +45,7 @@
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t cns11643l1_to_ucs4_tab[] =
|
||||
const uint16_t __cns11643l1_to_ucs4_tab[] =
|
||||
{
|
||||
[0x0000] = 0x3000, [0x0001] = 0xff0c, [0x0002] = 0x3001, [0x0003] = 0x3002,
|
||||
[0x0004] = 0xff0e, [0x0005] = 0x30fb, [0x0006] = 0xff1b, [0x0007] = 0xff1a,
|
||||
@ -1517,7 +1517,7 @@ const uint16_t cns11643l1_to_ucs4_tab[] =
|
||||
|
||||
|
||||
/* Some Latin1 characters, starting at U+00a7. */
|
||||
const char cns11643l1_from_ucs4_tab1[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab1[][2] =
|
||||
{
|
||||
[0x00] = "\x21\x70", [0x09] = "\x22\x78", [0x0a] = "\x22\x34",
|
||||
[0x10] = "\x21\x31", [0x30] = "\x22\x32", [0x50] = "\x22\x33"
|
||||
@ -1525,7 +1525,7 @@ const char cns11643l1_from_ucs4_tab1[][2] =
|
||||
|
||||
|
||||
/* Some phonetic modifiers, starting at U+02c7. */
|
||||
const char cns11643l1_from_ucs4_tab2[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab2[][2] =
|
||||
{
|
||||
[0x00] = "\x25\x6f", [0x02] = "\x25\x6d", [0x03] = "\x25\x6e",
|
||||
[0x04] = "\x25\x70", [0x12] = "\x25\x6c"
|
||||
@ -1552,7 +1552,7 @@ const char cns11643l1_from_ucs4_tab2[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab3[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab3[][2] =
|
||||
{
|
||||
[0x0000] = "\x24\x75", [0x0001] = "\x24\x76", [0x0002] = "\x24\x77",
|
||||
[0x0003] = "\x24\x78", [0x0004] = "\x24\x79", [0x0005] = "\x24\x7a",
|
||||
@ -1593,7 +1593,7 @@ const char cns11643l1_from_ucs4_tab3[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab4[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab4[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x39", [0x0001] = "\x21\x37", [0x0003] = "\x22\x5d",
|
||||
[0x0005] = "\x21\x64", [0x0006] = "\x21\x65", [0x0009] = "\x21\x66",
|
||||
@ -1603,7 +1603,7 @@ const char cns11643l1_from_ucs4_tab4[][2] =
|
||||
};
|
||||
|
||||
|
||||
const char cns11643l1_from_ucs4_tab5[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab5[][2] =
|
||||
{
|
||||
[0x00] = "\x22\x58", [0x01] = "\x22\x55", [0x02] = "\x22\x57",
|
||||
[0x03] = "\x22\x56", [0x06] = "\x22\x59", [0x07] = "\x22\x5a",
|
||||
@ -1631,7 +1631,7 @@ const char cns11643l1_from_ucs4_tab5[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab6[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab6[][2] =
|
||||
{
|
||||
[0x0000] = "\x22\x61", [0x0005] = "\x22\x35", [0x0009] = "\x22\x3c",
|
||||
[0x000a] = "\x22\x49", [0x000b] = "\x22\x48", [0x0014] = "\x22\x45",
|
||||
@ -1661,7 +1661,7 @@ const char cns11643l1_from_ucs4_tab6[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab7[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab7[][2] =
|
||||
{
|
||||
[0x0000] = "\x42\x21", [0x0001] = "\x42\x22", [0x0002] = "\x42\x23",
|
||||
[0x0003] = "\x42\x24", [0x0004] = "\x42\x25", [0x0005] = "\x42\x26",
|
||||
@ -1697,7 +1697,7 @@ const char cns11643l1_from_ucs4_tab7[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab8[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab8[][2] =
|
||||
{
|
||||
[0x0000] = "\x26\x21", [0x0001] = "\x26\x22", [0x0002] = "\x26\x23",
|
||||
[0x0003] = "\x26\x24", [0x0004] = "\x26\x25", [0x0005] = "\x26\x26",
|
||||
@ -1729,7 +1729,7 @@ const char cns11643l1_from_ucs4_tab8[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab9[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab9[][2] =
|
||||
{
|
||||
[0x0000] = "\x23\x39", [0x0002] = "\x23\x3a", [0x000c] = "\x23\x3c",
|
||||
[0x0010] = "\x23\x3d", [0x0014] = "\x23\x3e", [0x0018] = "\x23\x3f",
|
||||
@ -1774,7 +1774,7 @@ const char cns11643l1_from_ucs4_tab9[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab10[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab10[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x21", [0x0001] = "\x21\x23", [0x0002] = "\x21\x24",
|
||||
[0x0003] = "\x21\x71", [0x0008] = "\x21\x52", [0x0009] = "\x21\x53",
|
||||
@ -1809,7 +1809,7 @@ const char cns11643l1_from_ucs4_tab10[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab11[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab11[][2] =
|
||||
{
|
||||
[0x0000] = "\x22\x75", [0x0001] = "\x22\x76", [0x000e] = "\x22\x70",
|
||||
[0x000f] = "\x22\x71", [0x0010] = "\x22\x72", [0x0013] = "\x22\x74",
|
||||
@ -1838,7 +1838,7 @@ const char cns11643l1_from_ucs4_tab11[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab12[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab12[][2] =
|
||||
{
|
||||
[0x0000] = "\x44\x21", [0x0001] = "\x44\x23", [0x0003] = "\x44\x24",
|
||||
[0x0008] = "\x44\x37", [0x0009] = "\x44\x35", [0x000a] = "\x44\x38",
|
||||
@ -3667,7 +3667,7 @@ const char cns11643l1_from_ucs4_tab12[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab13[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab13[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x2b", [0x0001] = "\x21\x36", [0x0002] = "\x21\x38",
|
||||
[0x0005] = "\x21\x40", [0x0006] = "\x21\x41", [0x0007] = "\x21\x44",
|
||||
@ -3709,7 +3709,7 @@ const char cns11643l1_from_ucs4_tab13[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char cns11643l1_from_ucs4_tab14[][2] =
|
||||
const char __cns11643l1_from_ucs4_tab14[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x2a", [0x0002] = "\x21\x6c", [0x0003] = "\x22\x63",
|
||||
[0x0004] = "\x22\x68", [0x0005] = "\x21\x6d", [0x0007] = "\x21\x3e",
|
||||
|
@ -19,9 +19,10 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <gconv.h>
|
||||
|
||||
/* Table for CNS 11643, plane 1 to UCS4 conversion. */
|
||||
extern const uint16_t cns11643l1_to_ucs4_tab[];
|
||||
extern const uint16_t __cns11643l1_to_ucs4_tab[];
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
@ -47,25 +48,25 @@ cns11643l1_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
|
||||
(*s) += 2;
|
||||
|
||||
return cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
return __cns11643l1_to_ucs4_tab[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
}
|
||||
|
||||
|
||||
/* Tables for the UCS4 -> CNS conversion. */
|
||||
extern const char cns11643l1_from_ucs4_tab1[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab2[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab3[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab4[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab5[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab6[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab7[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab8[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab9[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab10[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab11[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab12[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab13[][2];
|
||||
extern const char cns11643l1_from_ucs4_tab14[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab1[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab2[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab3[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab4[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab5[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab6[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab7[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab8[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab9[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab10[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab11[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab12[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab13[][2];
|
||||
extern const char __cns11643l1_from_ucs4_tab14[][2];
|
||||
|
||||
|
||||
static inline size_t
|
||||
@ -73,110 +74,95 @@ ucs4_to_cns11643l1 (wchar_t wch, char *s, size_t avail)
|
||||
{
|
||||
unsigned int ch = (unsigned int) wch;
|
||||
char buf[2];
|
||||
const char *cp = NULL;
|
||||
const char *cp = buf;
|
||||
|
||||
if (ch < 0xa7)
|
||||
cp = "";
|
||||
else if (ch < 0xf7)
|
||||
cp = cns11643l1_from_ucs4_tab1[ch - 0xa7];
|
||||
else if (ch < 0x2c7)
|
||||
cp = "";
|
||||
else if (ch <= 0x2d9)
|
||||
cp = cns11643l1_from_ucs4_tab2[ch - 0x2c7];
|
||||
else if (ch < 0x391)
|
||||
cp = "";
|
||||
else if (ch <= 0x3c9)
|
||||
cp = cns11643l1_from_ucs4_tab3[ch - 0x391];
|
||||
else if (ch < 0x2013)
|
||||
cp = "";
|
||||
else if (ch <= 0x203e)
|
||||
cp = cns11643l1_from_ucs4_tab4[ch - 0x2013];
|
||||
else if (ch == 0x2103)
|
||||
cp = "\x22\x6a";
|
||||
else if (ch == 0x2105)
|
||||
cp = "\x22\x22";
|
||||
else if (ch == 0x2109)
|
||||
cp = "\x22\x6b";
|
||||
else if (ch < 0x2160)
|
||||
cp = "";
|
||||
else if (ch <= 0x2169)
|
||||
switch (ch)
|
||||
{
|
||||
case 0xa7 ... 0xf7:
|
||||
cp = __cns11643l1_from_ucs4_tab1[ch - 0xa7];
|
||||
break;
|
||||
case 0x2c7 ... 0x2d9:
|
||||
cp = __cns11643l1_from_ucs4_tab2[ch - 0x2c7];
|
||||
break;
|
||||
case 0x391 ... 0x3c9:
|
||||
cp = __cns11643l1_from_ucs4_tab3[ch - 0x391];
|
||||
case 0x2013 ... 0x203e:
|
||||
cp = __cns11643l1_from_ucs4_tab4[ch - 0x2013];
|
||||
case 0x2103:
|
||||
cp = "\x22\x6a";
|
||||
break;
|
||||
case 0x2105:
|
||||
cp = "\x22\x22";
|
||||
break;
|
||||
case 0x2109:
|
||||
cp = "\x22\x6b";
|
||||
break;
|
||||
case 0x2160 ... 0x2169:
|
||||
buf[0] = '\x24';
|
||||
buf[1] = '\x2b' + (ch - 0x2160);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch < 0x2170)
|
||||
cp = "";
|
||||
else if (ch <= 0x2179)
|
||||
{
|
||||
break;
|
||||
case 0x2170 ... 0x2179:
|
||||
buf[0] = '\x26';
|
||||
buf[1] = '\x35' + (ch - 0x2170);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch < 0x2190)
|
||||
cp = "";
|
||||
else if (ch <= 0x2199)
|
||||
cp = cns11643l1_from_ucs4_tab5[ch - 0x2190];
|
||||
else if (ch < 0x2215)
|
||||
cp = "";
|
||||
else if (ch <= 0x2267)
|
||||
cp = cns11643l1_from_ucs4_tab6[ch - 0x2215];
|
||||
else if (ch == 0x22a5)
|
||||
cp = "\x22\x47";
|
||||
else if (ch == 0x22bf)
|
||||
cp = "\x22\x4a";
|
||||
else if (ch < 0x2400)
|
||||
cp = "";
|
||||
else if (ch <= 0x2421)
|
||||
cp = cns11643l1_from_ucs4_tab7[ch - 0x2400];
|
||||
else if (ch < 0x2460)
|
||||
cp = "";
|
||||
else if (ch <= 0x247d)
|
||||
cp = cns11643l1_from_ucs4_tab8[ch - 0x2460];
|
||||
else if (ch < 0x2500)
|
||||
cp = "";
|
||||
else if (ch <= 0x2642)
|
||||
cp = cns11643l1_from_ucs4_tab9[ch - 0x2500];
|
||||
else if (ch < 0x3000)
|
||||
cp = "";
|
||||
else if (ch <= 0x3029)
|
||||
cp = cns11643l1_from_ucs4_tab10[ch - 0x3000];
|
||||
else if (ch == 0x30fb)
|
||||
cp = "\x21\x26";
|
||||
else if (ch < 0x3105)
|
||||
cp = "";
|
||||
else if (ch <= 0x3129)
|
||||
{
|
||||
break;
|
||||
case 0x2190 ...0x2199:
|
||||
cp = __cns11643l1_from_ucs4_tab5[ch - 0x2190];
|
||||
break;
|
||||
case 0x2215 ... 0x2267:
|
||||
cp = __cns11643l1_from_ucs4_tab6[ch - 0x2215];
|
||||
break;
|
||||
case 0x22a5:
|
||||
cp = "\x22\x47";
|
||||
break;
|
||||
case 0x22bf:
|
||||
cp = "\x22\x4a";
|
||||
break;
|
||||
case 0x2400 ... 0x2421:
|
||||
cp = __cns11643l1_from_ucs4_tab7[ch - 0x2400];
|
||||
break;
|
||||
case 0x2460 ... 0x247d:
|
||||
cp = __cns11643l1_from_ucs4_tab8[ch - 0x2460];
|
||||
break;
|
||||
case 0x2500 ... 0x2642:
|
||||
cp = __cns11643l1_from_ucs4_tab9[ch - 0x2500];
|
||||
break;
|
||||
case 0x3000 ... 0x3029:
|
||||
cp = __cns11643l1_from_ucs4_tab10[ch - 0x3000];
|
||||
break;
|
||||
case 0x30fb:
|
||||
cp = "\x21\x26";
|
||||
break;
|
||||
case 0x3105 ... 0x3129:
|
||||
buf[0] = '\x25';
|
||||
buf[1] = '\x26' + (ch - 0x3105);
|
||||
cp = buf;
|
||||
break;
|
||||
case 0x32a3:
|
||||
cp = "\x22\x21";
|
||||
break;
|
||||
case 0x338e ... 0x33d5:
|
||||
cp = __cns11643l1_from_ucs4_tab11[ch - 0x338e];
|
||||
break;
|
||||
case 0x4e00 ... 0x9f9c:
|
||||
cp = __cns11643l1_from_ucs4_tab12[ch - 0x4e00];
|
||||
break;
|
||||
case 0xfe30 ... 0xfe6b:
|
||||
cp = __cns11643l1_from_ucs4_tab13[ch - 0xfe30];
|
||||
break;
|
||||
case 0xff01 ... 0xff5d:
|
||||
cp = __cns11643l1_from_ucs4_tab14[ch - 0xff01];
|
||||
break;
|
||||
case 0xffe0:
|
||||
cp = "\x22\x66";
|
||||
break;
|
||||
case 0xffe1:
|
||||
cp = "\x22\x67";
|
||||
break;
|
||||
case 0xffe5:
|
||||
cp = "\x22\x64";
|
||||
break;
|
||||
default:
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else if (ch == 0x32a3)
|
||||
cp = "\x22\x21";
|
||||
else if (ch < 0x338e)
|
||||
cp = "";
|
||||
else if (ch <= 0x33d5)
|
||||
cp = cns11643l1_from_ucs4_tab11[ch - 0x338e];
|
||||
else if (ch < 0x4e00)
|
||||
cp = "";
|
||||
else if (ch <= 0x9f9c)
|
||||
cp = cns11643l1_from_ucs4_tab12[ch - 0x4e00];
|
||||
else if (ch < 0xfe30)
|
||||
cp = "";
|
||||
else if (ch <= 0xfe6b)
|
||||
cp = cns11643l1_from_ucs4_tab13[ch - 0xfe30];
|
||||
else if (ch < 0xff01)
|
||||
cp = "";
|
||||
else if (ch <= 0xff5d)
|
||||
cp = cns11643l1_from_ucs4_tab14[ch - 0xff01];
|
||||
else if (ch == 0xffe0)
|
||||
cp = "\x22\x66";
|
||||
else if (ch == 0xffe1)
|
||||
cp = "\x22\x67";
|
||||
else if (ch == 0xffe5)
|
||||
cp = "\x22\x64";
|
||||
else
|
||||
cp = "";
|
||||
|
||||
if (cp[0] == '\0')
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to EBCDIC-AT-DE-A.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Get the conversion table. */
|
||||
#include <ebcdic-at-de-a.h>
|
||||
#define NAME "EBCDIC-AT-DE-A"
|
||||
|
||||
#define CHARSET_NAME "EBCDIC-AT-DE-A"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to EBCDIC-AT-DE.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Get the conversion table. */
|
||||
#include <ebcdic-at-de.h>
|
||||
#define NAME "EBCDIC-AT-DE"
|
||||
|
||||
#define CHARSET_NAME "EBCDIC-AT-DE"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to EBCDIC-CA-FR.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Get the conversion table. */
|
||||
#include <ebcdic-ca-fr.h>
|
||||
#define NAME "EBCDIC-CA-FR"
|
||||
|
||||
#define CHARSET_NAME "EBCDIC-CA-FR"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -18,262 +18,124 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <gb2312.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_euccn_object;
|
||||
static int from_euccn_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "EUC-CN"
|
||||
#define FROM_LOOP from_euc_cn
|
||||
#define TO_LOOP to_euc_cn
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "EUC-CN") != NULL)
|
||||
step->data = &from_euccn_object;
|
||||
else if (strcasestr (step->to_name, "EUC-CN") != NULL)
|
||||
step->data = &to_euccn_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from ISO 8859-1 to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
++inptr; \
|
||||
else \
|
||||
if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two or more byte character. First test whether the \
|
||||
next character is also available. */ \
|
||||
const char *endp; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store \
|
||||
the intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch = inptr[1]; \
|
||||
\
|
||||
/* All second bytes of a multibyte character must be >= 0xa1. */ \
|
||||
if (ch < 0xa1) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* This is code set 1: GB 2312-80. */ \
|
||||
endp = inptr; \
|
||||
\
|
||||
ch = gb2312_to_ucs4 (&endp, 2, 0x80); \
|
||||
if (ch == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
\
|
||||
if (ch <= L'\x7f') \
|
||||
/* It's plain ASCII. */ \
|
||||
*outptr++ = (unsigned char) ch; \
|
||||
else \
|
||||
{ \
|
||||
size_t found; \
|
||||
\
|
||||
found = ucs4_to_gb2312 (ch, outptr, \
|
||||
(NEED_LENGTH_TEST \
|
||||
? outend - outptr : MAX_NEEDED_OUTPUT)); \
|
||||
if (!NEED_LENGTH_TEST || found != 0) \
|
||||
{ \
|
||||
if (found == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* It's a GB 2312 character, adjust it for EUC-CN. */ \
|
||||
*outptr++ += 0x80; \
|
||||
*outptr++ += 0x80; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* We ran out of space. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_euccn_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
else if ((inchar <= 0xa0 || inchar > 0xfe)
|
||||
&& inchar != 0x8e && inchar != 0x8f)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two or more byte character. First test whether the
|
||||
next character is also available. */
|
||||
const char *endp;
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
|
||||
/* All second bytes of a multibyte character must be
|
||||
>= 0xa1. */
|
||||
if (inchar2 < 0xa1)
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
--cnt;
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* This is code set 1: GB 2312-80. */
|
||||
endp = &inbuf[cnt - 1];
|
||||
|
||||
ch = gb2312_to_ucs4 (&endp, 2, 0x80);
|
||||
if (ch != L'\0')
|
||||
++cnt;
|
||||
|
||||
if (ch == UNKNOWN_10646_CHAR)
|
||||
ch = L'\0';
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
|
||||
if (ch <= L'\x7f')
|
||||
/* It's plain ASCII. */
|
||||
outbuf[outchars] = ch;
|
||||
else
|
||||
{
|
||||
/* Try the JIS character sets. */
|
||||
size_t found;
|
||||
|
||||
found = ucs4_to_gb2312 (ch, &outbuf[outchars],
|
||||
(data->outbufsize
|
||||
- outchars));
|
||||
if (found > 0)
|
||||
{
|
||||
/* It's a GB 2312 character, adjust it for
|
||||
EUC-CN. */
|
||||
outbuf[outchars++] += 0x80;
|
||||
outbuf[outchars] += 0x80;
|
||||
}
|
||||
else if (found == 0)
|
||||
{
|
||||
/* We ran out of space. */
|
||||
extra = 2;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* Illegal character. */
|
||||
break;
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_euccn_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -18,306 +18,190 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <gconv.h>
|
||||
#include <jis0201.h>
|
||||
#include <jis0208.h>
|
||||
#include <jis0212.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_eucjp_object;
|
||||
static int from_eucjp_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "EUC-JP"
|
||||
#define FROM_LOOP from_euc_jp
|
||||
#define TO_LOOP to_euc_jp
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 3
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "EUC-JP") != NULL)
|
||||
step->data = &from_eucjp_object;
|
||||
else if (strcasestr (step->to_name, "EUC-JP") != NULL)
|
||||
step->data = &to_eucjp_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from EUC-JP to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
++inptr; \
|
||||
else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e && ch != 0x8f) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two or more byte character. First test whether the next \
|
||||
character is also available. */ \
|
||||
int ch2; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store the \
|
||||
intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
\
|
||||
/* All second bytes of a multibyte character must be >= 0xa1. */ \
|
||||
if (ch2 < 0xa1) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (ch == 0x8e) \
|
||||
{ \
|
||||
/* This is code set 2: half-width katakana. */ \
|
||||
ch = jisx0201_to_ucs4 (ch2); \
|
||||
inptr += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
const unsigned char *endp; \
|
||||
\
|
||||
if (ch == 0x8f) \
|
||||
{ \
|
||||
/* This is code set 3: JIS X 0212-1990. */ \
|
||||
endp = inptr + 1; \
|
||||
\
|
||||
ch = jisx0212_to_ucs4 (&endp, \
|
||||
NEED_LENGTH_TEST ? inend - endp : 2, \
|
||||
0x80); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* This is code set 1: JIS X 0208. */ \
|
||||
endp = inptr; \
|
||||
\
|
||||
ch = jisx0208_to_ucs4 (&endp, \
|
||||
NEED_LENGTH_TEST ? inend - inptr : 2, \
|
||||
0x80); \
|
||||
} \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && ch == 0) \
|
||||
{ \
|
||||
/* Not enough input available. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
if (ch == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
inptr = endp; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
/* It's plain ASCII. */ \
|
||||
*outptr++ = ch; \
|
||||
else \
|
||||
{ \
|
||||
/* Try the JIS character sets. */ \
|
||||
size_t found; \
|
||||
\
|
||||
/* See whether we have room for at least two characters. */ \
|
||||
if (NEED_LENGTH_TEST && outptr + 1 >= outend) \
|
||||
{ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
found = ucs4_to_jisx0201 (ch, outptr + 1); \
|
||||
if (found != UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Yes, it's a JIS 0201 character. Store the shift byte. */ \
|
||||
*outptr = 0x8e; \
|
||||
outptr += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* No JIS 0201 character. */ \
|
||||
found = ucs4_to_jisx0208 (ch, outptr, 2); \
|
||||
/* Please note that we always have enough room for the output. */ \
|
||||
if (found != UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* It's a JIS 0208 character, adjust it for EUC-JP. */ \
|
||||
*outptr++ += 0x80; \
|
||||
*outptr++ += 0x80; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* No JIS 0208 character. */ \
|
||||
found = ucs4_to_jisx0212 (ch, outptr + 1, \
|
||||
(NEED_LENGTH_TEST \
|
||||
? outend - outptr - 1 : 2)); \
|
||||
\
|
||||
if (found == 0) \
|
||||
{ \
|
||||
/* We ran out of space. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
else if (found != UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* It's a JIS 0212 character, adjust it for EUC-JP. */ \
|
||||
*outptr++ = 0x8f; \
|
||||
*outptr++ += 0x80; \
|
||||
*outptr++ += 0x80; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_eucjp_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
else if ((inchar <= 0xa0 || inchar > 0xfe)
|
||||
&& inchar != 0x8e && inchar != 0x8f)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two or more byte character. First test whether the
|
||||
next character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
|
||||
/* All second bytes of a multibyte character must be
|
||||
>= 0xa1. */
|
||||
if (inchar2 < 0xa1)
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
--cnt;
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inchar == '\x8e')
|
||||
/* This is code set 2: half-width katakana. */
|
||||
ch = jisx0201_to_ucs4 (inchar2);
|
||||
else if (inchar == '\x8f')
|
||||
{
|
||||
/* This is code set 3: JIS X 0212-1990. */
|
||||
const char *endp = &inbuf[cnt];
|
||||
|
||||
ch = jisx0212_to_ucs4 (&endp, 1 + inchars - cnt,
|
||||
0x80);
|
||||
cnt = endp - inbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is code set 1: JIS X 0208. */
|
||||
const char *endp = &inbuf[cnt - 1];
|
||||
|
||||
ch = jisx0208_to_ucs4 (&endp, 2 + inchars - cnt,
|
||||
0x80);
|
||||
if (ch != L'\0')
|
||||
++cnt;
|
||||
}
|
||||
|
||||
if (ch == UNKNOWN_10646_CHAR)
|
||||
ch = L'\0';
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
|
||||
if (ch <= L'\x7f')
|
||||
/* It's plain ASCII. */
|
||||
outbuf[outchars] = ch;
|
||||
else
|
||||
{
|
||||
/* Try the JIS character sets. */
|
||||
size_t found;
|
||||
|
||||
found = ucs4_to_jisx0201 (ch, &outbuf[outchars]);
|
||||
|
||||
if (found == UNKNOWN_10646_CHAR)
|
||||
{
|
||||
/* No JIS 0201 character. */
|
||||
found = ucs4_to_jisx0208 (ch, &outbuf[outchars],
|
||||
(data->outbufsize
|
||||
- outchars));
|
||||
if (found == 0)
|
||||
{
|
||||
/* We ran out of space. */
|
||||
extra = 2;
|
||||
break;
|
||||
}
|
||||
else if (found != UNKNOWN_10646_CHAR)
|
||||
{
|
||||
/* It's a JIS 0208 character, adjust it for
|
||||
EUC-JP. */
|
||||
outbuf[outchars++] += 0x80;
|
||||
outbuf[outchars] += 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No JIS 0208 character. */
|
||||
found = ucs4_to_jisx0212 (ch, &outbuf[outchars],
|
||||
(data->outbufsize
|
||||
- outchars));
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
/* We ran out of space. */
|
||||
extra = 2;
|
||||
break;
|
||||
}
|
||||
else if (found != UNKNOWN_10646_CHAR)
|
||||
{
|
||||
/* It's a JIS 0212 character, adjust it for
|
||||
EUC-JP. */
|
||||
outbuf[outchars++] += 0x80;
|
||||
outbuf[outchars] += 0x80;
|
||||
}
|
||||
else
|
||||
/* Illegal character. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_eucjp_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* Mapping tables for EUC-KR handling.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
|
||||
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
|
||||
and Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -18,276 +19,142 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <ksc5601.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_euckr_object;
|
||||
static int from_euckr_object;
|
||||
|
||||
|
||||
static inline void
|
||||
euckr_from_ucs4(wchar_t ch, unsigned char *cp)
|
||||
euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
|
||||
{
|
||||
if (ch > 0x7f)
|
||||
{
|
||||
uint16_t idx=0;
|
||||
uint16_t idx = 0;
|
||||
|
||||
if (ucs4_to_ksc5601 (ch, &idx))
|
||||
idx |= 0x8080;
|
||||
|
||||
*cp = (unsigned char) (idx/256);
|
||||
*(cp+1) = (unsigned char) (idx & 0xff) ;
|
||||
cp[0] = (unsigned char) (idx / 256);
|
||||
cp[1] = (unsigned char) (idx & 0xff);
|
||||
}
|
||||
/* think about 0x5c ; '\' */
|
||||
/* XXX Think about 0x5c ; '\'. */
|
||||
else
|
||||
{
|
||||
*cp = (unsigned char) (0x7f & ch) ;
|
||||
*(cp+1) = (unsigned char) 0;
|
||||
cp[0] = (unsigned char) ch;
|
||||
cp[1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "EUC-KR") != NULL)
|
||||
step->data = &from_euckr_object;
|
||||
else if (strcasestr (step->to_name, "EUC-KR") != NULL)
|
||||
step->data = &to_euckr_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "EUC-KR"
|
||||
#define FROM_LOOP from_euc_kr
|
||||
#define TO_LOOP to_euc_kr
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* First define the conversion function from EUC-KR to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
/* Half-width Korean Currency WON sign \
|
||||
\
|
||||
if (inchar == 0x5c) \
|
||||
ch = 0x20a9; \
|
||||
else if (inchar <= 0x7f) \
|
||||
ch = (wchar_t) inchar; \
|
||||
*/ \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
/* Plain ASCII. */ \
|
||||
++inptr; \
|
||||
/* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are \
|
||||
user-defined areas. */ \
|
||||
else if (ch <= 0xa0 || ch > 0xfe || ch == 0xc9) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two-byte character. First test whether the next character \
|
||||
is also available. */ \
|
||||
int ch2; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
\
|
||||
if (ch2 < 0xa1 || ch2 >= 0xfe \
|
||||
|| ((ch = ksc5601_to_ucs4 ((uint16_t) (ch * 256 + ch2) & 0x7f7f)) \
|
||||
== UNKNOWN_10646_CHAR)) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_euckr_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
/*
|
||||
half-width Korean Currency WON sign
|
||||
|
||||
if (inchar == 0x5c)
|
||||
ch = 0x20a9;
|
||||
else if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
*/
|
||||
|
||||
if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
unsigned char cp[2]; \
|
||||
\
|
||||
/* Decomposing Hangul syllables not available in KS C 5601 into \
|
||||
Jamos should be considered either here or in euckr_from_ucs4() */ \
|
||||
euckr_from_ucs4 (ch, cp) ; \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
--outptr; \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
/* 0xfe(->0x7e : row 94) and 0xc9(->0x59 : row 41) are user-defined areas */
|
||||
|
||||
else if ( inchar <= 0xa0 || inchar > 0xfe || inchar == 0xc9)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two-byte character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
|
||||
ch = ksc5601_to_ucs4 ((uint16_t) (inchar * 256 + inchar2)
|
||||
& 0x7f7f);
|
||||
if (ch == UNKNOWN_10646_CHAR)
|
||||
ch = L'\0';
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
unsigned char cp[2];
|
||||
|
||||
/* decomposing Hangul syllables not available in KS C 5601 into Jamos
|
||||
should be considered either here or in euckr_from_ucs4() */
|
||||
|
||||
euckr_from_ucs4(ch,cp) ;
|
||||
|
||||
if (cp[0] == '\0' && ch != 0)
|
||||
/* Illegal character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_euckr_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -18,302 +18,171 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <cns11643l1.h>
|
||||
#include <cns11643.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_euctw_object;
|
||||
static int from_euctw_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "EUC-TW"
|
||||
#define FROM_LOOP from_euc_tw
|
||||
#define TO_LOOP to_euc_tw
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 4
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "EUC-TW") != NULL)
|
||||
step->data = &from_euctw_object;
|
||||
else if (strcasestr (step->to_name, "EUC-TW") != NULL)
|
||||
step->data = &to_euctw_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from EUC-TW to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
/* Plain ASCII. */ \
|
||||
++inptr; \
|
||||
else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two or more byte character. First test whether the next \
|
||||
character is also available. */ \
|
||||
uint32_t ch2; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + (ch == 0x8e ? 3 : 1) >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store the \
|
||||
intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = *inptr; \
|
||||
\
|
||||
/* All second bytes of a multibyte character must be >= 0xa1. */ \
|
||||
if (ch2 < 0xa1 || ch2 == 0xff) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (ch == 0x8e) \
|
||||
{ \
|
||||
/* This is code set 2: CNS 11643, planes 1 to 16. */ \
|
||||
const char *endp = inptr + 1; \
|
||||
\
|
||||
ch = cns11643_to_ucs4 (&endp, \
|
||||
NEED_LENGTH_TEST ? inend - inptr - 1 : 3, \
|
||||
0x80); \
|
||||
/* Please note that we need not test for the missing input \
|
||||
characters here anymore. */ \
|
||||
if (ch == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Illegal input. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* This is code set 1: CNS 11643, plane 1. */ \
|
||||
const char *endp = inptr; \
|
||||
\
|
||||
ch = cns11643l1_to_ucs4 (&endp, \
|
||||
NEED_LENGTH_TEST ? inend - inptr : 2, \
|
||||
0x80); \
|
||||
/* Please note that we need not test for the missing input \
|
||||
characters here anymore. */ \
|
||||
if (ch == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Illegal input. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
\
|
||||
if (ch <= 0x7f) \
|
||||
/* It's plain ASCII. */ \
|
||||
*outptr++ = ch; \
|
||||
else \
|
||||
{ \
|
||||
/* Try the JIS character sets. */ \
|
||||
size_t found; \
|
||||
\
|
||||
found = ucs4_to_cns11643l1 (ch, outptr, \
|
||||
NEED_LENGTH_TEST ? outend - outptr : 2); \
|
||||
if (NEED_LENGTH_TEST && found == 0) \
|
||||
{ \
|
||||
/* We ran out of space. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
if (found != UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* It's a CNS 11643, plane 1 character, adjust it for EUC-TW. */ \
|
||||
*outptr++ += 0x80; \
|
||||
*outptr++ += 0x80; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* No CNS 11643, plane 1 character. */ \
|
||||
\
|
||||
found = ucs4_to_cns11643 (ch, outptr + 1, \
|
||||
(NEED_LENGTH_TEST \
|
||||
? outend - outptr - 1 : 3)); \
|
||||
if (NEED_LENGTH_TEST && found == 0) \
|
||||
{ \
|
||||
/* We ran out of space. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
if (found == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* No legal input. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* It's a CNS 11643 character, adjust it for EUC-TW. */ \
|
||||
*outptr++ = '\x8e'; \
|
||||
*outptr++ += 0xa0; \
|
||||
*outptr++ += 0x80; \
|
||||
*outptr++ += 0x80; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_euctw_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
else if ((inchar <= 0xa0 || inchar > 0xfe)
|
||||
&& inchar != 0x8e)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two or more byte character. First test whether the
|
||||
next character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 + (inchar == 0x8e ? 2 : 0) >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
|
||||
/* All second bytes of a multibyte character must be
|
||||
>= 0xa1. */
|
||||
if (inchar2 < 0xa1 && inchar2 == 0xff)
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
--cnt;
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inchar == '\x8e')
|
||||
{
|
||||
/* This is code set 2: CNS 11643, planes 1 to 16. */
|
||||
const char *endp = &inbuf[cnt];
|
||||
|
||||
ch = cns11643_to_ucs4 (&endp, 2 + inchars - cnt,
|
||||
0x80);
|
||||
|
||||
if (ch == UNKNOWN_10646_CHAR)
|
||||
ch = L'\0';
|
||||
if (ch != L'\0')
|
||||
cnt += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is code set 1: CNS 11643, plane 1. */
|
||||
const char *endp = &inbuf[cnt - 1];
|
||||
|
||||
ch = cns11643l1_to_ucs4 (&endp, 2 + inchars - cnt,
|
||||
0x80);
|
||||
|
||||
if (ch == UNKNOWN_10646_CHAR)
|
||||
ch = L'\0';
|
||||
if (ch != L'\0')
|
||||
++cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
|
||||
if (ch <= L'\x7f')
|
||||
/* It's plain ASCII. */
|
||||
outbuf[outchars] = ch;
|
||||
else
|
||||
{
|
||||
/* Try the JIS character sets. */
|
||||
size_t found;
|
||||
|
||||
found = ucs4_to_cns11643l1 (ch, &outbuf[outchars],
|
||||
(data->outbufsize
|
||||
- outchars));
|
||||
if (found == 0)
|
||||
{
|
||||
/* We ran out of space. */
|
||||
extra = 2;
|
||||
break;
|
||||
}
|
||||
else if (found != UNKNOWN_10646_CHAR)
|
||||
{
|
||||
/* It's a CNS 11643, plane 1 character, adjust it
|
||||
for EUC-TW. */
|
||||
outbuf[outchars++] += 0x80;
|
||||
outbuf[outchars] += 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No CNS 11643, plane 1 character. */
|
||||
outbuf[outchars] = '\x8e';
|
||||
|
||||
found = ucs4_to_cns11643 (ch, &outbuf[outchars + 1],
|
||||
(data->outbufsize
|
||||
- outchars - 1));
|
||||
if (found > 0)
|
||||
{
|
||||
/* It's a CNS 11643 character, adjust it for
|
||||
EUC-TW. */
|
||||
outbuf[++outchars] += 0xa0;
|
||||
outbuf[++outchars] += 0x80;
|
||||
outbuf[outchars] += 0x80;
|
||||
}
|
||||
else if (found == 0)
|
||||
{
|
||||
/* We ran out of space. */
|
||||
extra = 4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* Illegal character. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_euctw_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -40,7 +40,7 @@
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t gb2312_to_ucs[] =
|
||||
const uint16_t __gb2312_to_ucs[] =
|
||||
{
|
||||
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0x30fb,
|
||||
[0x0004] = 0x02c9, [0x0005] = 0x02c7, [0x0006] = 0x00a8, [0x0007] = 0x3003,
|
||||
@ -1907,7 +1907,7 @@ const uint16_t gb2312_to_ucs[] =
|
||||
};
|
||||
|
||||
|
||||
const char gb2312_from_ucs4_tab1[][2] =
|
||||
const char __gb2312_from_ucs4_tab1[][2] =
|
||||
{
|
||||
[0x00] = "\x21\x68", [0x03] = "\x21\x6c", [0x04] = "\x21\x27",
|
||||
[0x0c] = "\x21\x63", [0x0d] = "\x21\x40", [0x33] = "\x21\x41",
|
||||
@ -1939,7 +1939,7 @@ const char gb2312_from_ucs4_tab1[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab2[][2] =
|
||||
const char __gb2312_from_ucs4_tab2[][2] =
|
||||
{
|
||||
[0x0000] = "\x26\x21", [0x0001] = "\x26\x22", [0x0002] = "\x26\x23",
|
||||
[0x0003] = "\x26\x24", [0x0004] = "\x26\x25", [0x0005] = "\x26\x26",
|
||||
@ -1980,7 +1980,7 @@ const char gb2312_from_ucs4_tab2[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab3[][2] =
|
||||
const char __gb2312_from_ucs4_tab3[][2] =
|
||||
{
|
||||
[0x0000] = "\x27\x27", [0x000f] = "\x27\x21", [0x0010] = "\x27\x22",
|
||||
[0x0011] = "\x27\x23", [0x0012] = "\x27\x24", [0x0013] = "\x27\x25",
|
||||
@ -2027,7 +2027,7 @@ const char gb2312_from_ucs4_tab3[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab4[][2] =
|
||||
const char __gb2312_from_ucs4_tab4[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x2a", [0x0003] = "\x21\x2e", [0x0004] = "\x21\x2f",
|
||||
[0x0007] = "\x21\x30", [0x0008] = "\x21\x31", [0x0011] = "\x21\x2d",
|
||||
@ -2059,7 +2059,7 @@ const char gb2312_from_ucs4_tab4[][2] =
|
||||
But we have a problem here since U+2225 maps to either 0x212C or
|
||||
0x214E. We simply choose the first solution here.
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab5[][2] =
|
||||
const char __gb2312_from_ucs4_tab5[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x66", [0x0013] = "\x21\x6d", [0x005d] = "\x22\x71",
|
||||
[0x005e] = "\x22\x72", [0x005f] = "\x22\x73", [0x0060] = "\x22\x74",
|
||||
@ -2100,7 +2100,7 @@ const char gb2312_from_ucs4_tab5[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab6[][2] =
|
||||
const char __gb2312_from_ucs4_tab6[][2] =
|
||||
{
|
||||
[0x0000] = "\x22\x59", [0x0001] = "\x22\x5a", [0x0002] = "\x22\x5b",
|
||||
[0x0003] = "\x22\x5c", [0x0004] = "\x22\x5d", [0x0005] = "\x22\x5e",
|
||||
@ -2142,7 +2142,7 @@ const char gb2312_from_ucs4_tab6[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab7[][2] =
|
||||
const char __gb2312_from_ucs4_tab7[][2] =
|
||||
{
|
||||
[0x0000] = "\x21\x21", [0x0001] = "\x21\x22", [0x0002] = "\x21\x23",
|
||||
[0x0003] = "\x21\x28", [0x0005] = "\x21\x29", [0x0008] = "\x21\x34",
|
||||
@ -2243,7 +2243,7 @@ const char gb2312_from_ucs4_tab7[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab8[][2] =
|
||||
const char __gb2312_from_ucs4_tab8[][2] =
|
||||
{
|
||||
[0x0000] = "\x52\x3b", [0x0001] = "\x36\x21", [0x0003] = "\x46\x5f",
|
||||
[0x0007] = "\x4d\x72", [0x0008] = "\x55\x49", [0x0009] = "\x48\x7d",
|
||||
@ -4523,7 +4523,7 @@ const char gb2312_from_ucs4_tab8[][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char gb2312_from_ucs4_tab9[][2] =
|
||||
const char __gb2312_from_ucs4_tab9[][2] =
|
||||
{
|
||||
[0x0000] = "\x23\x21", [0x0001] = "\x23\x22", [0x0002] = "\x23\x23",
|
||||
[0x0003] = "\x21\x67", [0x0004] = "\x23\x25", [0x0005] = "\x23\x26",
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* Conversion table. */
|
||||
extern const uint16_t gb2312_to_ucs[];
|
||||
extern const uint16_t __gb2312_to_ucs[];
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
@ -51,127 +51,166 @@ gb2312_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
|
||||
(*s) += 2;
|
||||
|
||||
return gb2312_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
return __gb2312_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
}
|
||||
|
||||
|
||||
extern const char gb2312_from_ucs4_tab1[][2];
|
||||
extern const char gb2312_from_ucs4_tab2[][2];
|
||||
extern const char gb2312_from_ucs4_tab3[][2];
|
||||
extern const char gb2312_from_ucs4_tab4[][2];
|
||||
extern const char gb2312_from_ucs4_tab5[][2];
|
||||
extern const char gb2312_from_ucs4_tab6[][2];
|
||||
extern const char gb2312_from_ucs4_tab7[][2];
|
||||
extern const char gb2312_from_ucs4_tab8[][2];
|
||||
extern const char gb2312_from_ucs4_tab9[][2];
|
||||
extern const char __gb2312_from_ucs4_tab1[][2];
|
||||
extern const char __gb2312_from_ucs4_tab2[][2];
|
||||
extern const char __gb2312_from_ucs4_tab3[][2];
|
||||
extern const char __gb2312_from_ucs4_tab4[][2];
|
||||
extern const char __gb2312_from_ucs4_tab5[][2];
|
||||
extern const char __gb2312_from_ucs4_tab6[][2];
|
||||
extern const char __gb2312_from_ucs4_tab7[][2];
|
||||
extern const char __gb2312_from_ucs4_tab8[][2];
|
||||
extern const char __gb2312_from_ucs4_tab9[][2];
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_gb2312 (wchar_t wch, char *s, size_t avail)
|
||||
{
|
||||
unsigned int ch = (unsigned int) wch;
|
||||
char buf[2];
|
||||
const char *cp = NULL;
|
||||
const char *cp = buf;
|
||||
|
||||
if (ch < 0xa4)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
else if (ch < 0x101)
|
||||
cp = gb2312_from_ucs4_tab1[ch - 0xa4];
|
||||
else if (ch == 0x113)
|
||||
cp = "\x28\x25";
|
||||
else if (ch == 0x11b)
|
||||
cp = "\x28\x27";
|
||||
else if (ch == 0x12b)
|
||||
cp = "\x28\x29";
|
||||
else if (ch == 0x14d)
|
||||
cp = "\x28\x2d";
|
||||
else if (ch == 0x16b)
|
||||
cp = "\x28\x31";
|
||||
else if (ch == 0x1ce)
|
||||
cp = "\x28\x23";
|
||||
else if (ch == 0x1d0)
|
||||
cp = "\x28\x2b";
|
||||
else if (ch == 0x1d2)
|
||||
cp = "\x28\x2f";
|
||||
else if (ch == 0x1d4)
|
||||
cp = "\x28\x33";
|
||||
else if (ch == 0x1d6)
|
||||
cp = "\x28\x35";
|
||||
else if (ch == 0x1d8)
|
||||
cp = "\x28\x36";
|
||||
else if (ch == 0x1da)
|
||||
cp = "\x28\x37";
|
||||
else if (ch == 0x1dc)
|
||||
cp = "\x28\x38";
|
||||
else if (ch == 0x2c7)
|
||||
cp = "\x21\x26";
|
||||
else if (ch == 0x2c9)
|
||||
cp = "\x21\x25";
|
||||
else if (ch >= 0x391 && ch <= 0x3c9)
|
||||
cp = gb2312_from_ucs4_tab2[ch - 0x391];
|
||||
else if (ch >= 0x401 && ch <= 0x451)
|
||||
cp = gb2312_from_ucs4_tab3[ch - 0x401];
|
||||
else if (ch >= 0x2015 && ch <= 0x203b)
|
||||
cp = gb2312_from_ucs4_tab4[ch - 0x2015];
|
||||
else if (ch >= 0x2103 && ch <= 0x22a5)
|
||||
cp = gb2312_from_ucs4_tab5[ch - 0x2103];
|
||||
else if (ch == 0x2313)
|
||||
cp = "\x21\x50";
|
||||
else if (ch >= 0x2460 && ch <= 0x249b)
|
||||
cp = gb2312_from_ucs4_tab6[ch - 0x2460];
|
||||
else if (ch >= 0x2500 && ch <= 0x254b)
|
||||
switch (ch)
|
||||
{
|
||||
case 0xa4 ... 0x100:
|
||||
cp = __gb2312_from_ucs4_tab1[ch - 0xa4];
|
||||
break;
|
||||
case 0x113:
|
||||
cp = "\x28\x25";
|
||||
break;
|
||||
case 0x11b:
|
||||
cp = "\x28\x27";
|
||||
break;
|
||||
case 0x12b:
|
||||
cp = "\x28\x29";
|
||||
break;
|
||||
case 0x14d:
|
||||
cp = "\x28\x2d";
|
||||
break;
|
||||
case 0x16b:
|
||||
cp = "\x28\x31";
|
||||
break;
|
||||
case 0x1ce:
|
||||
cp = "\x28\x23";
|
||||
break;
|
||||
case 0x1d0:
|
||||
cp = "\x28\x2b";
|
||||
break;
|
||||
case 0x1d2:
|
||||
cp = "\x28\x2f";
|
||||
break;
|
||||
case 0x1d4:
|
||||
cp = "\x28\x33";
|
||||
break;
|
||||
case 0x1d6:
|
||||
cp = "\x28\x35";
|
||||
break;
|
||||
case 0x1d8:
|
||||
cp = "\x28\x36";
|
||||
break;
|
||||
case 0x1da:
|
||||
cp = "\x28\x37";
|
||||
break;
|
||||
case 0x1dc:
|
||||
cp = "\x28\x38";
|
||||
break;
|
||||
case 0x2c7:
|
||||
cp = "\x21\x26";
|
||||
break;
|
||||
case 0x2c9:
|
||||
cp = "\x21\x25";
|
||||
break;
|
||||
case 0x391 ... 0x3c9:
|
||||
cp = __gb2312_from_ucs4_tab2[ch - 0x391];
|
||||
break;
|
||||
case 0x401 ... 0x451:
|
||||
cp = __gb2312_from_ucs4_tab3[ch - 0x401];
|
||||
break;
|
||||
case 0x2015 ... 0x203b:
|
||||
cp = __gb2312_from_ucs4_tab4[ch - 0x2015];
|
||||
break;
|
||||
case 0x2103 ... 0x22a5:
|
||||
cp = __gb2312_from_ucs4_tab5[ch - 0x2103];
|
||||
break;
|
||||
case 0x2313:
|
||||
cp = "\x21\x50";
|
||||
break;
|
||||
case 0x2460 ... 0x249b:
|
||||
cp = __gb2312_from_ucs4_tab6[ch - 0x2460];
|
||||
break;
|
||||
case 0x2500 ... 0x254b:
|
||||
buf[0] = '\x29';
|
||||
buf[1] = '\x24' + (ch & 256);
|
||||
cp = buf;
|
||||
}
|
||||
else if (ch == 0x25a0)
|
||||
cp = "\x21\x76";
|
||||
else if (ch == 0x25a1)
|
||||
cp = "\x21\x75";
|
||||
else if (ch == 0x25b2)
|
||||
cp = "\x21\x78";
|
||||
else if (ch == 0x25b3)
|
||||
cp = "\x21\x77";
|
||||
else if (ch == 0x25c6)
|
||||
cp = "\x21\x74";
|
||||
else if (ch == 0x25c7)
|
||||
cp = "\x21\x73";
|
||||
else if (ch == 0x25cb)
|
||||
cp = "\x21\x70";
|
||||
else if (ch == 0x25ce)
|
||||
cp = "\x21\x72";
|
||||
else if (ch == 0x25cf)
|
||||
cp = "\x21\x71";
|
||||
else if (ch == 0x2605)
|
||||
cp = "\x21\x6f";
|
||||
else if (ch == 0x2606)
|
||||
cp = "\x21\x6e";
|
||||
else if (ch == 0x2640)
|
||||
cp = "\x21\x62";
|
||||
else if (ch == 0x2642)
|
||||
cp = "\x21\x61";
|
||||
else if (ch >= 0x3000 && ch <= 0x3129)
|
||||
cp = gb2312_from_ucs4_tab7[ch - 0x3000];
|
||||
else if (ch >= 0x3220 && ch <= 0x3229)
|
||||
{
|
||||
break;
|
||||
case 0x25a0:
|
||||
cp = "\x21\x76";
|
||||
break;
|
||||
case 0x25a1:
|
||||
cp = "\x21\x75";
|
||||
break;
|
||||
case 0x25b2:
|
||||
cp = "\x21\x78";
|
||||
break;
|
||||
case 0x25b3:
|
||||
cp = "\x21\x77";
|
||||
break;
|
||||
case 0x25c6:
|
||||
cp = "\x21\x74";
|
||||
break;
|
||||
case 0x25c7:
|
||||
cp = "\x21\x73";
|
||||
break;
|
||||
case 0x25cb:
|
||||
cp = "\x21\x70";
|
||||
break;
|
||||
case 0x25ce:
|
||||
cp = "\x21\x72";
|
||||
break;
|
||||
case 0x25cf:
|
||||
cp = "\x21\x71";
|
||||
break;
|
||||
case 0x2605:
|
||||
cp = "\x21\x6f";
|
||||
break;
|
||||
case 0x2606:
|
||||
cp = "\x21\x6e";
|
||||
break;
|
||||
case 0x2640:
|
||||
cp = "\x21\x62";
|
||||
break;
|
||||
case 0x2642:
|
||||
cp = "\x21\x61";
|
||||
break;
|
||||
case 0x3000 ... 0x3129:
|
||||
cp = __gb2312_from_ucs4_tab7[ch - 0x3000];
|
||||
break;
|
||||
case 0x3220 ... 0x3229:
|
||||
buf[0] = '\x22';
|
||||
buf[1] = '\x65' + (ch - 0x3220);
|
||||
cp = buf;
|
||||
break;
|
||||
case 0x4e00 ... 0x9fa0:
|
||||
cp = __gb2312_from_ucs4_tab8[ch - 0x4e00];
|
||||
break;
|
||||
case 0xff01 ... 0xff5e:
|
||||
cp = __gb2312_from_ucs4_tab9[ch - 0xff01];
|
||||
break;
|
||||
case 0xffe0:
|
||||
cp = "\x21\x69";
|
||||
break;
|
||||
case 0xffe1:
|
||||
cp = "\x21\x6a";
|
||||
break;
|
||||
case 0xffe3:
|
||||
cp = "\x23\x7e";
|
||||
break;
|
||||
case 0xffe5:
|
||||
cp = "\x23\x24";
|
||||
break;
|
||||
default:
|
||||
return UNKNOWN_10646_CHAR;
|
||||
}
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fa0)
|
||||
cp = gb2312_from_ucs4_tab8[ch - 0x4e00];
|
||||
else if (ch >= 0xff01 && ch <= 0xff5e)
|
||||
cp = gb2312_from_ucs4_tab9[ch - 0xff01];
|
||||
else if (ch == 0xffe0)
|
||||
cp = "\x21\x69";
|
||||
else if (ch == 0xffe1)
|
||||
cp = "\x21\x6a";
|
||||
else if (ch == 0xffe3)
|
||||
cp = "\x23\x7e";
|
||||
else if (ch == 0xffe5)
|
||||
cp = "\x23\x24";
|
||||
else
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
||||
if (cp[1] != '\0' && avail < 2)
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to HP-ROMAN8.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Get the conversion table. */
|
||||
#include <hp-roman8.h>
|
||||
#define NAME "HP-ROMAN8"
|
||||
|
||||
#define CHARSET_NAME "HP-ROMAN8"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -292,19 +292,17 @@ gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
*written += do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -18,11 +18,10 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Data taken from the WG15 tables. */
|
||||
static const wchar_t to_ucs4[256] =
|
||||
static const uint32_t to_ucs4[256] =
|
||||
{
|
||||
/* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||
/* 0x08 */ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
@ -60,7 +59,7 @@ static const wchar_t to_ucs4[256] =
|
||||
|
||||
/* The outer array range runs from 0xc1 to 0xcf, the inner range from 0x20
|
||||
to 0x7f. */
|
||||
static const wchar_t to_ucs4_comb[15][96] =
|
||||
static const uint32_t to_ucs4_comb[15][96] =
|
||||
{
|
||||
/* 0xc1 */
|
||||
{
|
||||
@ -371,290 +370,179 @@ static const char from_ucs4[][2] =
|
||||
*/
|
||||
};
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_iso6937_object;
|
||||
static int from_iso6937_object;
|
||||
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "ISO_6937"
|
||||
#define FROM_LOOP from_iso6937
|
||||
#define TO_LOOP to_iso6937
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "ISO_6937") != NULL)
|
||||
step->data = &from_iso6937_object;
|
||||
else if (strcasestr (step->to_name, "ISO_6937") != NULL)
|
||||
step->data = &to_iso6937_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from ISO 6937 to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch >= 0xc1 && ch <= 0xcf) \
|
||||
{ \
|
||||
/* Composed character. First test whether the next character \
|
||||
is also available. */ \
|
||||
int ch2; \
|
||||
\
|
||||
if (inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store the \
|
||||
intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
\
|
||||
if (ch2 < 0x20 || ch2 >= 0x80) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
|
||||
\
|
||||
if (ch == 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ch = to_ucs4[ch]; \
|
||||
\
|
||||
if (ch == 0 && *inptr != '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
++inptr; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothign to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
char tmp[2]; \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
const char *cp; \
|
||||
\
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \
|
||||
{ \
|
||||
int fail = 0; \
|
||||
switch (ch) \
|
||||
{ \
|
||||
case 0x2c7: \
|
||||
cp = "\xcf\x20"; \
|
||||
break; \
|
||||
case 0x2d8 ... 0x2dd: \
|
||||
{ \
|
||||
static const char map[5] = "\xc6\xc7\xca\xce\xcd"; \
|
||||
\
|
||||
tmp[0] = map[ch - 0x2d8]; \
|
||||
tmp[1] = ' '; \
|
||||
cp = tmp; \
|
||||
} \
|
||||
break; \
|
||||
case 0x2014: \
|
||||
cp = "\xd0"; \
|
||||
break; \
|
||||
case 0x2018: \
|
||||
cp = "\xa9"; \
|
||||
break; \
|
||||
case 0x2019: \
|
||||
cp = "\xb9"; \
|
||||
break; \
|
||||
case 0x201c: \
|
||||
cp = "\xaa"; \
|
||||
break; \
|
||||
case 0x201d: \
|
||||
cp = "\xba"; \
|
||||
break; \
|
||||
case 0x2122: \
|
||||
cp = "\xd4"; \
|
||||
break; \
|
||||
case 0x2126: \
|
||||
cp = "\xe0"; \
|
||||
break; \
|
||||
case 0x215b ... 0x215e: \
|
||||
tmp[0] = 0xdc + (ch - 0x215b); \
|
||||
tmp[1] = '\0'; \
|
||||
cp = tmp; \
|
||||
break; \
|
||||
case 0x2190 ... 0x2193: \
|
||||
tmp[0] = 0xac + (ch - 0x2190); \
|
||||
tmp[1] = '\0'; \
|
||||
cp = tmp; \
|
||||
break; \
|
||||
case 0x266a: \
|
||||
cp = "\xd5"; \
|
||||
break; \
|
||||
default: \
|
||||
cp = NULL; \
|
||||
fail = 1; \
|
||||
} \
|
||||
\
|
||||
if (fail) \
|
||||
{ \
|
||||
/* Illegal characters. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
else if (from_ucs4[ch][0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal characters. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
cp = from_ucs4[ch]; \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_iso6937_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar >= '\xc1' && inchar <= '\xcf')
|
||||
{
|
||||
/* Composed character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = inbuf[++cnt];
|
||||
|
||||
if (inchar2 < '\x20' || inchar2 >= '\x80')
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
ch = to_ucs4_comb[inchar - 0xc1][inchar2 - 0x20];
|
||||
|
||||
if (ch == L'\0')
|
||||
/* Undo the increment for illegal characters. */
|
||||
--cnt;
|
||||
}
|
||||
else
|
||||
ch = to_ucs4[inchar];
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
char tmp[2];
|
||||
int ch = *((wchar_t *) (inbuf + cnt));
|
||||
const char *cp;
|
||||
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))
|
||||
{
|
||||
int fail = 0;
|
||||
switch (ch)
|
||||
{
|
||||
case 0x2c7:
|
||||
cp = "\xcf\x20";
|
||||
break;
|
||||
case 0x2d8 ... 0x2dd:
|
||||
{
|
||||
static const char map[5] = "\xc6\xc7\xca\xce\xcd";
|
||||
|
||||
tmp[0] = map[ch - 0x2d8];
|
||||
tmp[1] = ' ';
|
||||
cp = tmp;
|
||||
}
|
||||
break;
|
||||
case 0x2014:
|
||||
cp = "\xd0";
|
||||
break;
|
||||
case 0x2018:
|
||||
cp = "\xa9";
|
||||
break;
|
||||
case 0x2019:
|
||||
cp = "\xb9";
|
||||
break;
|
||||
case 0x201c:
|
||||
cp = "\xaa";
|
||||
break;
|
||||
case 0x201d:
|
||||
cp = "\xba";
|
||||
break;
|
||||
case 0x2122:
|
||||
cp = "\xd4";
|
||||
break;
|
||||
case 0x2126:
|
||||
cp = "\xe0";
|
||||
break;
|
||||
case 0x215b ... 0x215e:
|
||||
tmp[0] = 0xdc + (ch - 0x215b);
|
||||
tmp[1] = '\0';
|
||||
cp = tmp;
|
||||
break;
|
||||
case 0x2190 ... 0x2193:
|
||||
tmp[0] = 0xac + (ch - 0x2190);
|
||||
tmp[1] = '\0';
|
||||
cp = tmp;
|
||||
break;
|
||||
case 0x266a:
|
||||
cp = "\xd5";
|
||||
break;
|
||||
default:
|
||||
cp = NULL;
|
||||
fail = 1;
|
||||
}
|
||||
|
||||
if (fail)
|
||||
/* Illegal characters. */
|
||||
break;
|
||||
}
|
||||
else if (ch < 0 || (from_ucs4[ch][0] == '\0' && ch != 0))
|
||||
break;
|
||||
else
|
||||
cp = from_ucs4[ch];
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_iso6937_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -18,179 +18,44 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_iso88591_object;
|
||||
static int from_iso88591_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "ISO-8859-1"
|
||||
#define FROM_LOOP from_iso8859_1
|
||||
#define TO_LOOP to_iso8859_1
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
/* First define the conversion function from ISO 8859-1 to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
*((uint32_t *) outptr)++ = *inptr++;
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "ISO-8859-1") != NULL)
|
||||
step->data = &from_iso88591_object;
|
||||
else if (strcasestr (step->to_name, "ISO-8859-1") != NULL)
|
||||
step->data = &to_iso88591_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
if (ch > 0xff) \
|
||||
{ \
|
||||
/* We have an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
*outptr++ = (unsigned char) ch; \
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_iso88591_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
*((wchar_t *) (outbuf + outwchars)) =
|
||||
(unsigned char) inbuf[cnt];
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
if (*((wchar_t *) (inbuf + cnt)) >= L'\0'
|
||||
&& *((wchar_t *) (inbuf + cnt)) <= L'\377')
|
||||
outbuf[outchars] = *((wchar_t *) (inbuf + cnt));
|
||||
else
|
||||
/* Here is where the transliteration would enter the
|
||||
scene. */
|
||||
break;
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_iso88591_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-10.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-10.h>
|
||||
#define NAME "ISO-8859-10"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-10"
|
||||
#define HAS_HOLES 0 /* All 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-2.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-2.h>
|
||||
#define NAME "ISO-8859-2"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-2"
|
||||
#define HAS_HOLES 0 /* All 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-3.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-3.h>
|
||||
#define NAME "ISO-8859-3"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-3"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-4.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-4.h>
|
||||
#define NAME "ISO-8859-4"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-4"
|
||||
#define HAS_HOLES 0 /* All 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-5.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-5.h>
|
||||
#define NAME "ISO-8859-5"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-5"
|
||||
#define HAS_HOLES 0 /* All 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-6.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-6.h>
|
||||
#define NAME "ISO-8859-6"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-6"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-7.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-7.h>
|
||||
#define NAME "ISO-8859-7"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-7"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-8.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-8.h>
|
||||
#define NAME "ISO-8859-8"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-8"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to ISO 8859-9.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <iso8859-9.h>
|
||||
#define NAME "ISO-8859-9"
|
||||
|
||||
#define CHARSET_NAME "ISO-8859-9"
|
||||
#define HAS_HOLES 0 /* All 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Mapping tables for JIS0201 handling.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,10 +18,10 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
const wchar_t jisx0201_to_ucs4[256] =
|
||||
const uint32_t __jisx0201_to_ucs4[256] =
|
||||
{
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
|
||||
|
@ -22,13 +22,13 @@
|
||||
#define _JIS0201_H 1
|
||||
|
||||
/* Conversion table. */
|
||||
extern const wchar_t jis0201_to_ucs4[];
|
||||
extern const uint32_t __jis0201_to_ucs4[];
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
static inline uint32_t
|
||||
jisx0201_to_ucs4 (char ch)
|
||||
{
|
||||
wchar_t val = jis0201_to_ucs4[(unsigned char) ch];
|
||||
uint32_t val = __jis0201_to_ucs4[(unsigned char) ch];
|
||||
|
||||
if (val == 0 && ch != '\0')
|
||||
val = UNKNOWN_10646_CHAR;
|
||||
@ -38,7 +38,7 @@ jisx0201_to_ucs4 (char ch)
|
||||
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_jisx0201 (wchar_t wch, char *s)
|
||||
ucs4_to_jisx0201 (uint32_t wch, char *s)
|
||||
{
|
||||
char ch;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Mapping tables for JIS0208 handling.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "jis0208.h"
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t jis0208_to_ucs[0x1e80] =
|
||||
const uint16_t __jis0208_to_ucs[0x1e80] =
|
||||
{
|
||||
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0xff0c,
|
||||
[0x0004] = 0xff0e, [0x0005] = 0x30fb, [0x0006] = 0xff1a, [0x0007] = 0xff1b,
|
||||
@ -1783,7 +1783,7 @@ const uint16_t jis0208_to_ucs[0x1e80] =
|
||||
};
|
||||
|
||||
|
||||
const char jisx0208_from_ucs4_lat1[256][2] =
|
||||
const char __jisx0208_from_ucs4_lat1[256][2] =
|
||||
{
|
||||
[0x005C] = "\x21\x40", [0x00A2] = "\x21\x71", [0x00A3] = "\x21\x72",
|
||||
[0x00A7] = "\x21\x78", [0x00A8] = "\x21\x2f", [0x00AC] = "\x22\x4c",
|
||||
@ -1814,7 +1814,7 @@ const char jisx0208_from_ucs4_lat1[256][2] =
|
||||
printf ("\n");
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char jisx0208_from_ucs4_greek[0xc1][2] =
|
||||
const char __jisx0208_from_ucs4_greek[0xc1][2] =
|
||||
{
|
||||
[0x00] = "\x26\x21", [0x01] = "\x26\x22", [0x02] = "\x26\x23",
|
||||
[0x03] = "\x26\x24", [0x04] = "\x26\x25", [0x05] = "\x26\x26",
|
||||
@ -1887,7 +1887,7 @@ const char jisx0208_from_ucs4_greek[0xc1][2] =
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
|
||||
const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
|
||||
const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[] =
|
||||
{
|
||||
{ start: 0x2010, end: 0x2026, idx: 0 },
|
||||
{ start: 0x2030, end: 0x2033, idx: 23 },
|
||||
@ -2596,7 +2596,7 @@ const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
|
||||
{ start: 0x9f9c, end: 0x9fa0, idx: 14109 },
|
||||
{ start: 0xff01, end: 0xff5d, idx: 14114 },
|
||||
{ start: 0xffe3, end: 0xffe5, idx: 14207 },
|
||||
{ start: 0 }
|
||||
{ start: 0xffff, end: 0xffff, idx: 0 }
|
||||
};
|
||||
|
||||
|
||||
@ -2637,7 +2637,7 @@ const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[] =
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char jisx0208_from_ucs_tab[14210][2] =
|
||||
const char __jisx0208_from_ucs_tab[14210][2] =
|
||||
{
|
||||
"\x20\x10", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x20\x15",
|
||||
"\x20\x16", "\x00\x00", "\x20\x18", "\x20\x19", "\x00\x00", "\x00\x00",
|
||||
|
@ -25,12 +25,12 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* Conversion table. */
|
||||
extern const uint16_t jis0208_to_ucs[];
|
||||
extern const uint16_t __jis0208_to_ucs[];
|
||||
|
||||
extern const char jisx0208_from_ucs4_lat1[256][2];
|
||||
extern const char jisx0208_from_ucs4_greek[0xc1][2];
|
||||
extern const struct jisx0208_ucs_idx jisx0208_from_ucs_idx[];
|
||||
extern const char jisx0208_from_ucs_tab[][2];
|
||||
extern const char __jisx0208_from_ucs4_lat1[256][2];
|
||||
extern const char __jisx0208_from_ucs4_greek[0xc1][2];
|
||||
extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[];
|
||||
extern const char __jisx0208_from_ucs_tab[][2];
|
||||
|
||||
|
||||
/* Struct for table with indeces in UCS mapping table. */
|
||||
@ -42,8 +42,8 @@ struct jisx0208_ucs_idx
|
||||
};
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
jisx0208_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
static inline uint32_t
|
||||
jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
|
||||
{
|
||||
unsigned char ch = *(*s);
|
||||
unsigned char ch2;
|
||||
@ -65,34 +65,38 @@ jisx0208_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
|
||||
(*s) += 2;
|
||||
|
||||
return jis0208_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
return __jis0208_to_ucs[idx] ?: ((*s) -= 2, UNKNOWN_10646_CHAR);
|
||||
}
|
||||
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_jisx0208 (wchar_t wch, char *s, size_t avail)
|
||||
ucs4_to_jisx0208 (uint32_t wch, char *s, size_t avail)
|
||||
{
|
||||
unsigned int ch = (unsigned int) wch;
|
||||
const char *cp = NULL;
|
||||
const char *cp;
|
||||
|
||||
if (avail < 2)
|
||||
return 0;
|
||||
|
||||
if (ch < 0x100)
|
||||
cp = jisx0208_from_ucs4_lat1[ch];
|
||||
cp = __jisx0208_from_ucs4_lat1[ch];
|
||||
else if (ch >= 0x391 && ch <= 0x451)
|
||||
cp = jisx0208_from_ucs4_greek[ch];
|
||||
cp = __jisx0208_from_ucs4_greek[ch];
|
||||
else
|
||||
{
|
||||
const struct jisx0208_ucs_idx *rp = jisx0208_from_ucs_idx;
|
||||
const struct jisx0208_ucs_idx *rp = __jisx0208_from_ucs_idx;
|
||||
|
||||
if (ch >= 0xffff)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
while (ch > rp->end)
|
||||
++rp;
|
||||
if (ch >= rp->start)
|
||||
cp = jisx0208_from_ucs_tab[rp->idx + ch - rp->start];
|
||||
cp = __jisx0208_from_ucs_tab[rp->idx + ch - rp->start];
|
||||
else
|
||||
return UNKNOWN_10646_CHAR;
|
||||
}
|
||||
|
||||
if (cp == NULL || cp[0] == '\0')
|
||||
if (cp[0] == '\0')
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
||||
s[0] = cp[0];
|
||||
|
@ -19,7 +19,6 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <jis0212.h>
|
||||
|
||||
@ -54,7 +53,7 @@
|
||||
$first, $last, $idx);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const struct jisx0212_idx jisx0212_to_ucs_idx[] =
|
||||
const struct jisx0212_idx __jisx0212_to_ucs_idx[] =
|
||||
{
|
||||
{ start: 0x006c, end: 0x0076, idx: 0 },
|
||||
{ start: 0x007f, end: 0x0081, idx: 11 },
|
||||
@ -67,7 +66,7 @@ const struct jisx0212_idx jisx0212_to_ucs_idx[] =
|
||||
{ start: 0x034e, end: 0x03a4, idx: 107 },
|
||||
{ start: 0x03ac, end: 0x0402, idx: 194 },
|
||||
{ start: 0x0582, end: 0x1c2a, idx: 281 },
|
||||
{ start: 0 },
|
||||
{ start: 0xffff, end: 0xffff, idx: 0 },
|
||||
};
|
||||
|
||||
|
||||
@ -109,7 +108,7 @@ const struct jisx0212_idx jisx0212_to_ucs_idx[] =
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const uint16_t jisx0212_to_ucs[] =
|
||||
const uint16_t __jisx0212_to_ucs[] =
|
||||
{
|
||||
0x02d8, 0x02c7, 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da,
|
||||
0x007e, 0x0384, 0x0385, 0x00a1, 0x00a6, 0x00bf, 0x00ba, 0x00aa,
|
||||
@ -905,7 +904,7 @@ const uint16_t jisx0212_to_ucs[] =
|
||||
$first, $last, $idx);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const struct jisx0212_idx jisx0212_from_ucs_idx[] =
|
||||
const struct jisx0212_idx __jisx0212_from_ucs_idx[] =
|
||||
{
|
||||
{ start: 0x007e, end: 0x007e, idx: 0 },
|
||||
{ start: 0x00a1, end: 0x00af, idx: 1 },
|
||||
@ -1654,7 +1653,7 @@ const struct jisx0212_idx jisx0212_from_ucs_idx[] =
|
||||
{ start: 0x9f68, end: 0x9f7d, idx: 13393 },
|
||||
{ start: 0x9f8f, end: 0x9f97, idx: 13415 },
|
||||
{ start: 0x9f9e, end: 0x9fa5, idx: 13424 },
|
||||
{ start: 0 }
|
||||
{ start: 0xffff, end: 0xffff, idx: 0 }
|
||||
};
|
||||
|
||||
|
||||
@ -1697,7 +1696,7 @@ const struct jisx0212_idx jisx0212_from_ucs_idx[] =
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
const char jisx0212_from_ucs[][2] =
|
||||
const char __jisx0212_from_ucs[][2] =
|
||||
{
|
||||
"\x7e\x00", "\xa1\x00", "\x00\x00", "\x00\x00", "\xa4\x00", "\x00\x00",
|
||||
"\xa6\x00", "\x00\x00", "\x00\x00", "\xa9\x00", "\xaa\x00", "\x00\x00",
|
||||
|
@ -34,20 +34,20 @@ struct jisx0212_idx
|
||||
};
|
||||
|
||||
/* Conversion table. */
|
||||
extern const struct jisx0212_idx jisx0212_to_ucs_idx[];
|
||||
extern const uint16_t jisx0212_to_ucs[];
|
||||
extern const struct jisx0212_idx __jisx0212_to_ucs_idx[];
|
||||
extern const uint16_t __jisx0212_to_ucs[];
|
||||
|
||||
extern const struct jisx0212_idx jisx0212_from_ucs_idx[];
|
||||
extern const char jisx0212_from_ucs[][2];
|
||||
extern const struct jisx0212_idx __jisx0212_from_ucs_idx[];
|
||||
extern const char __jisx0212_from_ucs[][2];
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
jisx0212_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset)
|
||||
{
|
||||
const struct jisx0212_idx *rp = jisx0212_to_ucs_idx;
|
||||
const struct jisx0212_idx *rp = __jisx0212_to_ucs_idx;
|
||||
unsigned char ch = *(*s);
|
||||
unsigned char ch2;
|
||||
wchar_t wch = L'\0';
|
||||
uint32_t wch = 0;
|
||||
int idx;
|
||||
|
||||
if (ch < offset || (ch - offset) <= 0x6d || (ch - offset) > 0xea)
|
||||
@ -62,10 +62,10 @@ jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
|
||||
idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset);
|
||||
|
||||
while (idx < rp->start)
|
||||
while (idx > rp->end)
|
||||
++rp;
|
||||
if (idx <= rp->end)
|
||||
wch = jisx0212_to_ucs[rp->idx + idx - rp->start];
|
||||
if (idx >= rp->start)
|
||||
wch = __jisx0212_to_ucs[rp->idx + idx - rp->start];
|
||||
|
||||
if (wch != L'\0')
|
||||
(*s) += 2;
|
||||
@ -79,16 +79,20 @@ jisx0212_to_ucs4 (const char **s, size_t avail, unsigned char offset)
|
||||
static inline size_t
|
||||
ucs4_to_jisx0212 (wchar_t wch, char *s, size_t avail)
|
||||
{
|
||||
const struct jisx0212_idx *rp = jisx0212_from_ucs_idx;
|
||||
const struct jisx0212_idx *rp = __jisx0212_from_ucs_idx;
|
||||
unsigned int ch = (unsigned int) wch;
|
||||
const char *cp = NULL;
|
||||
const char *cp;
|
||||
|
||||
if (ch >= 0xffff)
|
||||
return UNKNOWN_10646_CHAR;
|
||||
while (ch > rp->end)
|
||||
++rp;
|
||||
if (ch >= rp->start)
|
||||
cp = jisx0212_from_ucs[rp->idx + ch - rp->start];
|
||||
cp = __jisx0212_from_ucs[rp->idx + ch - rp->start];
|
||||
else
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
||||
if (cp == NULL || cp[0] == '\0')
|
||||
if (cp[0] == '\0')
|
||||
return UNKNOWN_10646_CHAR;
|
||||
|
||||
s[0] = cp[0];
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* Mapping tables for JOHAB handling.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
|
||||
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
|
||||
and Ulrich Drepper <drepper@cygnus.com>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -18,16 +19,9 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <ksc5601.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_johab_object;
|
||||
static int from_johab_object;
|
||||
|
||||
/* The table for Bit pattern to Hangul Jamo
|
||||
5 bits each are used to encode
|
||||
leading consonants(19 + 1 filler), medial vowels(21 + 1 filler)
|
||||
@ -37,19 +31,19 @@ static int from_johab_object;
|
||||
0 : Filler, -1: invalid, >= 1 : valid
|
||||
|
||||
*/
|
||||
const int init[32] =
|
||||
static const int init[32] =
|
||||
{
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
const int mid[32] =
|
||||
static const int mid[32] =
|
||||
{
|
||||
-1, -1, 0, 1, 2, 3, 4, 5,
|
||||
-1, -1, 6, 7, 8, 9, 10, 11,
|
||||
-1, -1, 12, 13, 14, 15, 16, 17,
|
||||
-1, -1, 18, 19, 20, 21, -1, -1
|
||||
};
|
||||
const int final[32] =
|
||||
static const int final[32] =
|
||||
{
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
-1, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1
|
||||
@ -63,14 +57,14 @@ const int final[32] =
|
||||
block [0x3131,0x314e] or Hangul Conjoining Jamo block, [0x1100,0x11ff]
|
||||
|
||||
*/
|
||||
const wchar_t init_to_ucs[19] =
|
||||
static const uint32_t init_to_ucs[19] =
|
||||
{
|
||||
0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141, 0x3142,
|
||||
0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b,
|
||||
0x314c, 0x314d, 0x314e
|
||||
};
|
||||
|
||||
const wchar_t final_to_ucs[27] =
|
||||
static const uint32_t final_to_ucs[27] =
|
||||
{
|
||||
L'\0', L'\0', 0x3133, L'\0', 0x3135, 0x3136, L'\0', L'\0',
|
||||
0x313a, 0x313b, 0x314c, 0x313d, 0x313e, 0x313f,
|
||||
@ -88,7 +82,7 @@ const wchar_t final_to_ucs[27] =
|
||||
to get the same result arithmetically.
|
||||
|
||||
*/
|
||||
const int init_to_bit[19] =
|
||||
static const int init_to_bit[19] =
|
||||
{
|
||||
0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00,
|
||||
0xa000, 0xa400, 0xa800, 0xac00, 0xb000, 0xb400,
|
||||
@ -96,7 +90,7 @@ const int init_to_bit[19] =
|
||||
0xd000
|
||||
};
|
||||
|
||||
const int mid_to_bit[21] =
|
||||
static const int mid_to_bit[21] =
|
||||
{
|
||||
0x0060, 0x0080, 0x00a0, 0x00c0, 0x00e0,
|
||||
0x0140, 0x0160, 0x0180, 0x01a0, 0x01c0, 0x1e0,
|
||||
@ -104,7 +98,7 @@ const int mid_to_bit[21] =
|
||||
0x0340, 0x0360, 0x0380, 0x03a0
|
||||
};
|
||||
|
||||
const int final_to_bit[28] =
|
||||
static const int final_to_bit[28] =
|
||||
{
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
|
||||
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d
|
||||
@ -118,7 +112,7 @@ const int final_to_bit[28] =
|
||||
2. Unicode 2.0 manual
|
||||
|
||||
*/
|
||||
const uint16_t jamo_from_ucs_table[51] =
|
||||
static const uint16_t jamo_from_ucs_table[51] =
|
||||
{
|
||||
0x8841, 0x8c41,
|
||||
0x8444,
|
||||
@ -137,21 +131,20 @@ const uint16_t jamo_from_ucs_table[51] =
|
||||
};
|
||||
|
||||
|
||||
static inline wchar_t
|
||||
johab_sym_hanja_to_ucs (int idx, int c1, int c2)
|
||||
static inline uint32_t
|
||||
johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
|
||||
{
|
||||
if (idx <= 0xdefe)
|
||||
return (wchar_t) ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
|
||||
- (c2 > 0x90 ? 0x43 : 0x31)];
|
||||
return (uint32_t) __ksc5601_sym_to_ucs[(c1 - 0xd9) * 188 + c2
|
||||
- (c2 > 0x90 ? 0x43 : 0x31)];
|
||||
else
|
||||
return (wchar_t) ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
|
||||
- (c2 > 0x90 ? 0x43 : 0x31)];
|
||||
return (uint32_t) __ksc5601_hanja_to_ucs[(c1 - 0xe0) * 188 + c2
|
||||
- (c2 > 0x90 ? 0x43 : 0x31)];
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
johab_hanja_from_ucs (wchar_t ch)
|
||||
johab_hanja_from_ucs (uint32_t ch)
|
||||
{
|
||||
|
||||
uint16_t idx;
|
||||
if (ucs4_to_ksc5601_hanja (ch, &idx))
|
||||
{
|
||||
@ -168,7 +161,7 @@ johab_hanja_from_ucs (wchar_t ch)
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
johab_sym_from_ucs (wchar_t ch)
|
||||
johab_sym_from_ucs (uint32_t ch)
|
||||
{
|
||||
uint16_t idx;
|
||||
if (ucs4_to_ksc5601_sym (ch, &idx))
|
||||
@ -186,9 +179,8 @@ johab_sym_from_ucs (wchar_t ch)
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
johab_from_ucs4 (wchar_t ch, unsigned char *cp)
|
||||
johab_from_ucs4 (uint32_t ch, unsigned char *cp)
|
||||
{
|
||||
if (ch >= 0x7f)
|
||||
{
|
||||
@ -215,315 +207,205 @@ johab_from_ucs4 (wchar_t ch, unsigned char *cp)
|
||||
else
|
||||
idx = johab_sym_from_ucs (ch);
|
||||
|
||||
*cp = (char) (idx / 256);
|
||||
*(cp + 1) = (char) (idx & 0xff);
|
||||
cp[0] = (unsigned char) (idx / 256);
|
||||
cp[1] = (unsigned char) (idx & 0xff);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
*cp = (char) (0x7f & ch);
|
||||
*(cp + 1) = (char) 0;
|
||||
cp[0] = (unsigned char) ch;
|
||||
cp[1] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "JOHAB") != NULL)
|
||||
step->data = &from_johab_object;
|
||||
else if (strcasestr (step->to_name, "JOHAB") != NULL)
|
||||
step->data = &to_johab_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "JOHAB"
|
||||
#define FROM_LOOP from_johab
|
||||
#define TO_LOOP to_johab
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* First define the conversion function from JOHAB to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
/* half-width Korean Currency WON sign \
|
||||
if (ch == 0x5c) \
|
||||
ch = 0x20a9; \
|
||||
else if (ch < 0x7f) \
|
||||
ch = (wchar_t) ch; \
|
||||
*/ \
|
||||
if (ch < 0x7f) \
|
||||
/* Plain ASCII. */ \
|
||||
++inptr; \
|
||||
/* Johab : 1. Hangul \
|
||||
1st byte : 0x84-0xd3 \
|
||||
2nd byte : 0x41-0x7e, 0x81-0xfe \
|
||||
2. Hanja & Symbol : \
|
||||
1st byte : 0xd8-0xde, 0xe0-0xf9 \
|
||||
2nd byte : 0x31-0x7e, 0x91-0xfe \
|
||||
0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */ \
|
||||
else \
|
||||
{ \
|
||||
if (ch > 0xf9 || ch == 0xdf || (ch > 0x7e && ch < 0x84) \
|
||||
|| (ch > 0xd3 && ch < 0xd9)) \
|
||||
{ \
|
||||
/* These are illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two-byte character. First test whether the next \
|
||||
character is also available. */ \
|
||||
uint32_t ch2; \
|
||||
uint_fast32_t idx; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store the \
|
||||
intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
idx = ch * 256 + ch2; \
|
||||
if (ch <= 0xd3) \
|
||||
{ \
|
||||
/* Hangul */ \
|
||||
uint_fast32_t i, m, f; \
|
||||
\
|
||||
i = init[(idx & 0x7c00) >> 10]; \
|
||||
m = mid[(idx & 0x03e0) >> 5]; \
|
||||
f = final[idx & 0x001f]; \
|
||||
\
|
||||
if (i == -1 || m == -1 || f == -1) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else if (i > 0 && m > 0) \
|
||||
ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00; \
|
||||
else if (i > 0 && m == 0 & f == 0) \
|
||||
ch = init_to_ucs[i - 1]; \
|
||||
else if (i == 0 && m > 0 & f == 0) \
|
||||
ch = 0x314e + m; /* 0x314f + m - 1 */ \
|
||||
else if (i == 0 && m == 0 & f > 0) \
|
||||
ch = final_to_ucs[f - 1]; /* round trip?? */ \
|
||||
else \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (ch2 < 0x31 || (ch2 > 0x7e && ch2 < 0x91) || ch2 == 0xff) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else if (ch == 0xda && ch2 > 0xa0 && ch2 < 0xd4) \
|
||||
{ \
|
||||
/* This is illegal. Modern Hangul Jaso is defined \
|
||||
elsewhere in Johab */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ch = johab_sym_hanja_to_ucs (idx, ch, ch2); \
|
||||
/* if (idx <= 0xdefe) \
|
||||
ch = __ksc5601_sym_to_ucs[(ch - 0xd9) * 192 \
|
||||
+ ch2 - (ch2 > 0x90 \
|
||||
? 0x43 : 0x31)]; \
|
||||
else \
|
||||
ch = __ksc5601_hanja_to_ucs[(ch - 0xe0) *192 \
|
||||
+ ch2 - (ch2 > 0x90 \
|
||||
?0x43 : 0x31)];\
|
||||
*/ \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (ch == 0) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t * written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
unsigned char cp[2]; \
|
||||
/* \
|
||||
if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0]))) \
|
||||
{ \
|
||||
if (ch >= 0x0391 && ch <= 0x0451) \
|
||||
cp = from_ucs4_greek[ch - 0x391]; \
|
||||
else if (ch >= 0x2010 && ch <= 0x9fa0) \
|
||||
cp = from_ucs4_cjk[ch - 0x02010]; \
|
||||
else \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
cp = from_ucs4_lat1[ch]; \
|
||||
*/ \
|
||||
johab_from_ucs4 (ch, cp); \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
--outptr; \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_johab_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
/* half-width Korean Currency WON sign
|
||||
if (inchar == 0x5c)
|
||||
ch = 0x20a9;
|
||||
else if (inchar < 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
*/
|
||||
if (inchar < 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
|
||||
/* Johab : 1. Hangul
|
||||
1st byte : 0x84-0xd3
|
||||
2nd byte : 0x41-0x7e, 0x81-0xfe
|
||||
2. Hanja & Symbol :
|
||||
1st byte : 0xd8-0xde, 0xe0-0xf9
|
||||
2nd byte : 0x31-0x7e, 0x91-0xfe
|
||||
0xd831-0xd87e and 0xd891-0xd8fe are user-defined area */
|
||||
|
||||
else if (inchar > 0xf9 || inchar == 0xdf
|
||||
|| (inchar > 0x7e && inchar < 0x84)
|
||||
|| (inchar > 0xd3 && inchar < 0xd9))
|
||||
/* These are illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two-byte character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
int idx;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
idx = inchar * 256 + inchar2;
|
||||
if (inchar <= 0xd3)
|
||||
{ /* Hangul */
|
||||
int i, m, f;
|
||||
i = init[(idx & 0x7c00) >> 10];
|
||||
m = mid[(idx & 0x03e0) >> 5];
|
||||
f = final[idx & 0x001f];
|
||||
if (i == -1 || m == -1 || f == -1)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else if (i > 0 && m > 0)
|
||||
ch = ((i - 1) * 21 + (m - 1)) * 28 + f + 0xac00;
|
||||
else if (i > 0 && m == 0 & f == 0)
|
||||
ch = init_to_ucs[i - 1];
|
||||
else if (i == 0 && m > 0 & f == 0)
|
||||
ch = 0x314e + m; /* 0x314f + m - 1 */
|
||||
else if (i == 0 && m == 0 & f > 0)
|
||||
ch = final_to_ucs[f - 1]; /* round trip?? */
|
||||
else
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inchar2 < 0x31
|
||||
|| (inchar2 > 0x7e && inchar2 < 0x91)
|
||||
|| inchar2 == 0xff)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else if (inchar == 0xda
|
||||
&& inchar2 > 0xa0 && inchar2 < 0xd4)
|
||||
/* This is illegal. */
|
||||
/* Modern Hangul Jaso is defined elsewhere
|
||||
in Johab */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
ch = johab_sym_hanja_to_ucs (idx, inchar,
|
||||
inchar2);
|
||||
/* if (idx <= 0xdefe)
|
||||
ch = ksc5601_sym_to_ucs[(inchar - 0xd9) * 192
|
||||
+ inchar2
|
||||
- (inchar2>0x90 ? 0x43 : 0x31)];
|
||||
|
||||
else
|
||||
ch = ksc5601_hanja_to_ucs[(inchar - 0xe0) *192
|
||||
+ inchar2
|
||||
- (inchar2>0x90 ? 0x43 : 0x31)];
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
unsigned char cp[2];
|
||||
/*
|
||||
if (ch >= (sizeof (from_ucs4_lat1)
|
||||
/ sizeof (from_ucs4_lat1[0])))
|
||||
{
|
||||
if (ch >= 0x0391 && ch <= 0x0451)
|
||||
cp = from_ucs4_greek[ch - 0x391];
|
||||
else if (ch >= 0x2010 && ch <= 0x9fa0)
|
||||
cp = from_ucs4_cjk[ch - 0x02010];
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
cp = from_ucs4_lat1[ch];
|
||||
*/
|
||||
johab_from_ucs4 (ch, cp);
|
||||
|
||||
if (cp[0] == '\0' && ch != 0)
|
||||
/* Illegal character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_johab_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to KOI-8.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Get the conversion table. */
|
||||
#include <stdint.h>
|
||||
#include <koi-8.h>
|
||||
#define NAME "KOI-8"
|
||||
|
||||
#define CHARSET_NAME "KOI-8"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-generic.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to KOI8-R.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Specify the conversion table. */
|
||||
#define TABLES <koi8-r.h>
|
||||
#define NAME "KOI8-R"
|
||||
|
||||
#define CHARSET_NAME "KOI8-R"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-gap.c>
|
||||
|
@ -18,7 +18,7 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdint.h>
|
||||
#include "ksc5601.h"
|
||||
|
||||
/*
|
||||
@ -50,7 +50,7 @@ perl tab21.pl > ksc_hangul1.tb
|
||||
*/
|
||||
|
||||
|
||||
const uint16_t ksc5601_hangul_to_ucs[KSC5601_HANGUL]=
|
||||
const uint16_t __ksc5601_hangul_to_ucs[KSC5601_HANGUL]=
|
||||
{
|
||||
0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10,
|
||||
0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19,
|
||||
@ -369,7 +369,7 @@ grep -v '# HANGUL SYLLABLE' | perl tab11.pl > ksc_sym1.tb
|
||||
|
||||
*/
|
||||
|
||||
const uint16_t ksc5601_sym_to_ucs[] =
|
||||
const uint16_t __ksc5601_sym_to_ucs[] =
|
||||
{
|
||||
[0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0x00b7,
|
||||
[0x0004] = 0x2025, [0x0005] = 0x2026, [0x0006] = 0x00a8, [0x0007] = 0x3003,
|
||||
@ -646,7 +646,7 @@ perl tab12.pl > ksc_sym2.tb
|
||||
|
||||
*/
|
||||
|
||||
const uint16_t ksc5601_sym_from_ucs[KSC5601_SYMBOL][2] =
|
||||
const uint16_t __ksc5601_sym_from_ucs[KSC5601_SYMBOL][2] =
|
||||
{
|
||||
{0x00a1, 0x222e}, {0x00a4, 0x2234}, {0x00a7, 0x2157}, {0x00a8, 0x2127},
|
||||
{0x00aa, 0x2823}, {0x00ad, 0x2129}, {0x00b0, 0x2146}, {0x00b1, 0x213e},
|
||||
@ -914,7 +914,7 @@ perl tab21.pl > ksc_hanja1.tb
|
||||
printf ("\n");
|
||||
*/
|
||||
|
||||
const uint16_t ksc5601_hanja_to_ucs[KSC5601_HANJA]=
|
||||
const uint16_t __ksc5601_hanja_to_ucs[KSC5601_HANJA]=
|
||||
{
|
||||
0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5,
|
||||
0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c,
|
||||
@ -1550,7 +1550,7 @@ awk '{print $2,$1}' | sort -u | perl tab12.pl > ksc_hanja2.tb
|
||||
|
||||
*/
|
||||
|
||||
const uint16_t ksc5601_hanja_from_ucs[KSC5601_HANJA][2]=
|
||||
const uint16_t __ksc5601_hanja_from_ucs[KSC5601_HANJA][2]=
|
||||
{
|
||||
{0x4e00, 0x6c69}, {0x4e01, 0x6f4b}, {0x4e03, 0x7652}, {0x4e07, 0x5832},
|
||||
{0x4e08, 0x6d5b}, {0x4e09, 0x5f32}, {0x4e0a, 0x5f3e}, {0x4e0b, 0x793b},
|
||||
|
@ -28,18 +28,18 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* Conversion table. */
|
||||
extern const uint16_t ksc5601_hangul_to_ucs[KSC5601_HANGUL];
|
||||
extern const uint16_t ksc5601_sym_to_ucs[];
|
||||
extern const uint16_t ksc5601_sym_from_ucs[KSC5601_SYMBOL][2];
|
||||
extern const uint16_t ksc5601_hanja_to_ucs[KSC5601_HANJA];
|
||||
extern const uint16_t ksc5601_hanja_from_ucs[KSC5601_HANJA][2];
|
||||
extern const uint16_t __ksc5601_hangul_to_ucs[KSC5601_HANGUL];
|
||||
extern const uint16_t __ksc5601_sym_to_ucs[];
|
||||
extern const uint16_t __ksc5601_sym_from_ucs[KSC5601_SYMBOL][2];
|
||||
extern const uint16_t __ksc5601_hanja_to_ucs[KSC5601_HANJA];
|
||||
extern const uint16_t __ksc5601_hanja_from_ucs[KSC5601_HANJA][2];
|
||||
|
||||
|
||||
/*
|
||||
static inline wchar_t
|
||||
ksc5601_to_ucs4 (char **s, size_t avail)
|
||||
*/
|
||||
static inline wchar_t
|
||||
static inline uint32_t
|
||||
ksc5601_to_ucs4 (uint16_t s)
|
||||
{
|
||||
unsigned char ch = s / 256;
|
||||
@ -61,23 +61,25 @@ ksc5601_to_ucs4 (uint16_t s)
|
||||
Hangul in KS C 5601 : row 16 - row 40 */
|
||||
|
||||
if (idx >= 1410 && idx < 3760)
|
||||
return ksc5601_hangul_to_ucs[idx-1410];
|
||||
return __ksc5601_hangul_to_ucs[idx-1410];
|
||||
else if (idx > 3854)
|
||||
/* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */
|
||||
return ksc5601_hanja_to_ucs[idx-3854];
|
||||
return __ksc5601_hanja_to_ucs[idx-3854];
|
||||
else
|
||||
return ksc5601_sym_to_ucs[idx] ?: UNKNOWN_10646_CHAR;
|
||||
return __ksc5601_sym_to_ucs[idx] ?: UNKNOWN_10646_CHAR;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_ksc5601_hangul (wchar_t wch, uint16_t *s)
|
||||
ucs4_to_ksc5601_hangul (uint32_t wch, uint16_t *s)
|
||||
{
|
||||
int l=0,m,u=KSC5601_HANGUL-1;
|
||||
wchar_t try;
|
||||
int l = 0;
|
||||
int m;
|
||||
int u = KSC5601_HANGUL - 1;
|
||||
uint32_t try;
|
||||
|
||||
while (l <= u)
|
||||
{
|
||||
try = (wchar_t) ksc5601_hangul_to_ucs[m=(l+u)/2];
|
||||
try = (uint32_t) __ksc5601_hangul_to_ucs[m=(l+u)/2];
|
||||
if (try > wch)
|
||||
u = m - 1;
|
||||
else if (try < wch)
|
||||
@ -93,21 +95,24 @@ ucs4_to_ksc5601_hangul (wchar_t wch, uint16_t *s)
|
||||
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_ksc5601_hanja (wchar_t wch, uint16_t *s)
|
||||
ucs4_to_ksc5601_hanja (uint32_t wch, uint16_t *s)
|
||||
{
|
||||
int l=0,m,u=KSC5601_HANJA-1;
|
||||
wchar_t try;
|
||||
int l = 0;
|
||||
int m;
|
||||
int u = KSC5601_HANJA - 1;
|
||||
uint32_t try;
|
||||
|
||||
while (l <= u)
|
||||
{
|
||||
try = (wchar_t) ksc5601_hanja_from_ucs[m=(l+u)/2][0];
|
||||
m = (l + u) / 2;
|
||||
try = (uint32_t) __ksc5601_hanja_from_ucs[m][0];
|
||||
if (try > wch)
|
||||
u=m-1;
|
||||
else if (try < wch)
|
||||
l = m + 1;
|
||||
else
|
||||
{
|
||||
*s = ksc5601_hanja_from_ucs[m][1];
|
||||
*s = __ksc5601_hanja_from_ucs[m][1];
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@ -115,24 +120,24 @@ ucs4_to_ksc5601_hanja (wchar_t wch, uint16_t *s)
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_ksc5601_sym (wchar_t wch, uint16_t *s)
|
||||
ucs4_to_ksc5601_sym (uint32_t wch, uint16_t *s)
|
||||
{
|
||||
int l = 0;
|
||||
int m;
|
||||
int u = KSC5601_SYMBOL - 1;
|
||||
wchar_t try;
|
||||
uint32_t try;
|
||||
|
||||
while (l <= u)
|
||||
{
|
||||
m = (l + u) / 2;
|
||||
try = ksc5601_sym_from_ucs[m][0];
|
||||
try = __ksc5601_sym_from_ucs[m][0];
|
||||
if (try > wch)
|
||||
u = m - 1;
|
||||
else if (try < wch)
|
||||
l = m + 1;
|
||||
else
|
||||
{
|
||||
*s = ksc5601_sym_from_ucs[m][1];
|
||||
*s = __ksc5601_sym_from_ucs[m][1];
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@ -146,13 +151,13 @@ ucs4_to_ksc5601 (wchar_t wch, char **s, size_t avail)
|
||||
*/
|
||||
|
||||
static inline size_t
|
||||
ucs4_to_ksc5601 (wchar_t ch, uint16_t *s)
|
||||
ucs4_to_ksc5601 (uint32_t ch, uint16_t *s)
|
||||
{
|
||||
*s = (uint16_t) UNKNOWN_10646_CHAR; /* FIXIT */
|
||||
|
||||
if (ch >= 0xac00 && ch <= 0xd7a3)
|
||||
return ucs4_to_ksc5601_hangul (ch, s);
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fff || ch >= 0xf900 && ch <= 0xfa0b)
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fff || ch >= 0xf900 && ch <= 0xfa0b)
|
||||
return ucs4_to_ksc5601_hanja (ch, s);
|
||||
else
|
||||
return ucs4_to_ksc5601_sym (ch, s);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to LATIN-GREEK-1.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,10 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Specify the conversion table. */
|
||||
#define TABLES <latin-greek-1.h>
|
||||
#define NAME "LATIN-GREEK-1"
|
||||
|
||||
#define CHARSET_NAME "LATIN-GREEK-1"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-gap.c>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Conversion from and to LATIN-GREEK.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -18,7 +18,10 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <wchar.h>
|
||||
/* Specify the conversion table. */
|
||||
#define TABLES <latin-greek.h>
|
||||
#define NAME "LATIN-GREEK"
|
||||
|
||||
#define CHARSET_NAME "LATIN-GREEK"
|
||||
#define HAS_HOLES 1 /* Not all 256 character are defined. */
|
||||
|
||||
#include <8bit-gap.c>
|
||||
|
@ -52,10 +52,18 @@ while read from to targets; do
|
||||
{ echo "*** conversion from $t to $to failed"; exit 1; }
|
||||
test -s $temp1 && cmp testdata/$from $temp2 >& /dev/null ||
|
||||
{ echo "*** $from -> t -> $to conversion failed"; exit 1; }
|
||||
rm -f $temp1 $temp2
|
||||
|
||||
# Now test some bigger text, entirely in ASCII.
|
||||
$ICONV -f $from -t $t testdata/suntzus |
|
||||
$ICONV -f $t -t $to > $temp1 ||
|
||||
{ echo "*** conversion $from->$t->$to of suntzus failed"; exit 1; }
|
||||
cmp testdata/suntzus.txt $temp1 ||
|
||||
{ echo "*** conversion $from->$t->$to of suntzus incorrect"; exit 1; }
|
||||
rm -f $temp1
|
||||
|
||||
# All tests ok.
|
||||
echo "$from -> $t -> $to ok"
|
||||
rm -f $temp1 $temp2
|
||||
done
|
||||
done < TESTS
|
||||
|
||||
|
409
iconvdata/sjis.c
409
iconvdata/sjis.c
@ -18,12 +18,10 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
static const wchar_t halfkana_to_ucs4[] =
|
||||
static const uint32_t halfkana_to_ucs4[] =
|
||||
{
|
||||
0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, 0xff68,
|
||||
0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, 0xff70,
|
||||
@ -3981,268 +3979,151 @@ static const char from_ucs4_cjk[32657][2] =
|
||||
};
|
||||
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_sjis_object;
|
||||
static int from_sjis_object;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "SJIS"
|
||||
#define FROM_LOOP from_sjis
|
||||
#define TO_LOOP to_sjis
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
/* First define the conversion function from SJIS to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch == 0x5c) \
|
||||
{ \
|
||||
ch = 0xa5; \
|
||||
++inptr; \
|
||||
} \
|
||||
else if (ch == 0x7e) \
|
||||
{ \
|
||||
ch = 0x203e; \
|
||||
++inptr; \
|
||||
} \
|
||||
else if (ch < 0x7e) \
|
||||
++inptr; \
|
||||
else if (ch >= 0xa1 && ch <= 0xdf) \
|
||||
{ \
|
||||
ch = halfkana_to_ucs4[ch - 0xa1]; \
|
||||
++inptr; \
|
||||
} \
|
||||
else if (ch > 0xea || ch == 0xa0 || ch == 0x7f || ch == 0x80) \
|
||||
{ \
|
||||
/* These are illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two-byte character. First test whether the next character \
|
||||
is also available. */ \
|
||||
uint32_t ch2; \
|
||||
uint_fast32_t idx; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store \
|
||||
the intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
idx = ch * 256 + ch2; \
|
||||
if (idx < 0x8140 || (idx > 0x84be && idx < 0x889f) \
|
||||
|| (idx > 0x89fc && idx < 0x9040) \
|
||||
|| (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* We could pack the data a bit more dense. The second \
|
||||
byte will never be 0x7f and it will also be never \
|
||||
>0xfc. But this would mean yet more `if's. */ \
|
||||
if (idx <= 0x84be) \
|
||||
ch = cjk_block1[(ch - 0x81) * 192 + ch2 - 0x40]; \
|
||||
else if (idx <= 0x89fc) \
|
||||
ch = cjk_block2[(ch - 0x88) * 192 + ch2 - 0x9f]; \
|
||||
else if (idx <= 0x9ffc) \
|
||||
ch = cjk_block3[(ch - 0x90) * 192 + ch2 - 0x40]; \
|
||||
else \
|
||||
ch = cjk_block4[(ch - 0xe0) * 192 + ch2 - 0x40]; \
|
||||
} \
|
||||
\
|
||||
if (ch == 0) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "SJIS") != NULL)
|
||||
step->data = &from_sjis_object;
|
||||
else if (strcasestr (step->to_name, "SJIS") != NULL)
|
||||
step->data = &to_sjis_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
const char *cp; \
|
||||
\
|
||||
if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0]))) \
|
||||
{ \
|
||||
if (ch >= 0x0391 && ch <= 0x0451) \
|
||||
cp = from_ucs4_greek[ch - 0x391]; \
|
||||
else if (ch >= 0x2010 && ch <= 0x9fa0) \
|
||||
cp = from_ucs4_cjk[ch - 0x02010]; \
|
||||
else \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
cp = from_ucs4_lat1[ch]; \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_sjis_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar == 0x5c)
|
||||
ch = L'\xa5';
|
||||
else if (inchar == 0x7e)
|
||||
ch = 0x203e;
|
||||
else if (inchar < 0x7e)
|
||||
ch = (wchar_t) inchar;
|
||||
else if (inchar >= 0xa1 && inchar <= 0xdf)
|
||||
ch = halfkana_to_ucs4[inchar - 0xa1];
|
||||
else if (inchar > 0xea || inchar == 0xa0 || inchar == 0x7f
|
||||
|| inchar == 0x80)
|
||||
/* These are illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two-byte character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
int idx;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = inbuf[++cnt];
|
||||
idx = inchar * 256 + inchar2;
|
||||
if (idx < 0x8140 || (idx > 0x84be && idx < 0x889f)
|
||||
|| (idx > 0x89fc && idx < 0x9040)
|
||||
|| (idx > 0x9ffc && idx < 0xe040) || idx > 0xeaa4)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* We could pack the data a bit more dense.
|
||||
The second byte will never be 0x7f and it
|
||||
will also be never >0xfc. But this would
|
||||
mean yet more `if's. */
|
||||
if (idx <= 0x84be)
|
||||
ch = cjk_block1[(inchar - 0x81) * 192
|
||||
+ inchar2 - 0x40];
|
||||
else if (idx <= 0x89fc)
|
||||
ch = cjk_block2[(inchar - 0x88) * 192
|
||||
+ inchar2 - 0x9f];
|
||||
else if (idx <= 0x9ffc)
|
||||
ch = cjk_block3[(inchar - 0x90) * 192
|
||||
+ inchar2 - 0x40];
|
||||
else
|
||||
ch = cjk_block4[(inchar - 0xe0) * 192
|
||||
+ inchar2 - 0x40];
|
||||
}
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
int ch = *((wchar_t *) (inbuf + cnt));
|
||||
const char *cp;
|
||||
|
||||
if (ch >= (sizeof (from_ucs4_lat1)
|
||||
/ sizeof (from_ucs4_lat1[0])))
|
||||
{
|
||||
if (ch >= 0x0391 && ch <= 0x0451)
|
||||
cp = from_ucs4_greek[ch - 0x391];
|
||||
else if (ch >= 0x2010 && ch <= 0x9fa0)
|
||||
cp = from_ucs4_cjk[ch - 0x02010];
|
||||
else
|
||||
/* Illegal character. */
|
||||
break;
|
||||
}
|
||||
else
|
||||
cp = from_ucs4_lat1[ch];
|
||||
|
||||
if (cp[0] == '\0' && ch != 0)
|
||||
/* Illegal character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_sjis_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
368
iconvdata/t61.c
368
iconvdata/t61.c
@ -19,6 +19,7 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Data taken from the WG15 tables. */
|
||||
@ -362,248 +363,133 @@ static const char from_ucs4[][2] =
|
||||
*/
|
||||
};
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_t61_object;
|
||||
static int from_t61_object;
|
||||
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "T.61"
|
||||
#define FROM_LOOP from_t_61
|
||||
#define TO_LOOP to_t_61
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
/* First define the conversion function from T.61 to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *inptr; \
|
||||
\
|
||||
if (ch >= 0xc1 && ch <= 0xcf) \
|
||||
{ \
|
||||
/* Composed character. First test whether the next character \
|
||||
is also available. */ \
|
||||
uint32_t ch2; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
\
|
||||
if (ch2 < 0x20 || ch2 >= 0x80) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch = to_ucs4_comb[ch - 0xc1][ch2 - 0x20]; \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ch = to_ucs4[ch]; \
|
||||
++inptr; \
|
||||
} \
|
||||
\
|
||||
if (ch == 0 && *inptr != '\0') \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "T.61") != NULL)
|
||||
step->data = &from_t61_object;
|
||||
else if (strcasestr (step->to_name, "T.61") != NULL)
|
||||
step->data = &to_t61_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
char tmp[2]; \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
const char *cp; \
|
||||
\
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])) \
|
||||
{ \
|
||||
if (ch == 0x2126) \
|
||||
cp = "\xe0"; \
|
||||
else if (ch == 0x2c7) \
|
||||
cp = "\xcf\x20"; \
|
||||
else if (ch < 0x2d8 || ch > 0x2dd) \
|
||||
{ \
|
||||
/* Illegal characters. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
static const char map[5] = "\xc6\xc7\xca\xce\xcd"; \
|
||||
\
|
||||
tmp[0] = map[ch - 0x2d8]; \
|
||||
tmp[1] = ' '; \
|
||||
cp = tmp; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
cp = from_ucs4[ch]; \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
--outptr; \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_t61_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = inbuf[cnt];
|
||||
wchar_t ch;
|
||||
|
||||
if (inchar >= '\xc1' && inchar <= '\xcf')
|
||||
{
|
||||
/* Composed character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = inbuf[++cnt];
|
||||
|
||||
if (inchar2 < '\x20' || inchar2 >= '\x80')
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
ch = to_ucs4_comb[inchar - 0xc1][inchar2 - 0x20];
|
||||
|
||||
if (ch == L'\0')
|
||||
/* Undo the increment for illegal characters. */
|
||||
--cnt;
|
||||
}
|
||||
else
|
||||
ch = to_ucs4[inchar];
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
char tmp[2];
|
||||
int ch = *((wchar_t *) (inbuf + cnt));
|
||||
const char *cp;
|
||||
|
||||
if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))
|
||||
{
|
||||
if (ch == 0x2126)
|
||||
cp = "\xe0";
|
||||
else if (ch == 0x2c7)
|
||||
cp = "\xcf\x20";
|
||||
else if (ch < 0x2d8 || ch > 0x2dd)
|
||||
/* Illegal characters. */
|
||||
break;
|
||||
else
|
||||
{
|
||||
static const char map[5] = "\xc6\xc7\xca\xce\xcd";
|
||||
|
||||
tmp[0] = map[ch - 0x2d8];
|
||||
tmp[1] = ' ';
|
||||
cp = tmp;
|
||||
}
|
||||
}
|
||||
else if (ch < 0 || (from_ucs4[ch][0] == '\0' && ch != 0))
|
||||
break;
|
||||
else
|
||||
cp = from_ucs4[ch];
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_t61_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
438
iconvdata/uhc.c
438
iconvdata/uhc.c
@ -18,16 +18,9 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <gconv.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <ksc5601.h>
|
||||
|
||||
/* Direction of the transformation. */
|
||||
static int to_uhc_object;
|
||||
static int from_uhc_object;
|
||||
|
||||
|
||||
/*
|
||||
egrep \
|
||||
@ -2576,20 +2569,20 @@ static const uint16_t uhc_hangul_from_ucs[11172]=
|
||||
0xc64f, 0xc650, 0xc651, 0xc652
|
||||
};
|
||||
|
||||
|
||||
static inline void
|
||||
uhc_from_ucs4(wchar_t ch, unsigned char *cp)
|
||||
uhc_from_ucs4 (uint32_t ch, unsigned char *cp)
|
||||
{
|
||||
if (ch >= 0x7f)
|
||||
{
|
||||
uint16_t idx=0;
|
||||
|
||||
if (ch >= 0xac00 && ch <= 0xd7a3)
|
||||
idx = uhc_hangul_from_ucs[(int) ch - 0xac00];
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fa5
|
||||
|| ch >= 0xf900 && ch <= 0xfa0b)
|
||||
idx = uhc_hangul_from_ucs[ch - 0xac00];
|
||||
else if (ch >= 0x4e00 && ch <= 0x9fa5 || ch >= 0xf900 && ch <= 0xfa0b)
|
||||
{
|
||||
ucs4_to_ksc5601_hanja (ch,&idx);
|
||||
idx |= (idx ? 0x8080 : 0);
|
||||
idx |= (idx ? 0x8080 : 0);
|
||||
}
|
||||
/* Half-width Korean Currency Won Sign
|
||||
else if (ch == 0x20a9)
|
||||
@ -2598,286 +2591,169 @@ uhc_from_ucs4(wchar_t ch, unsigned char *cp)
|
||||
else
|
||||
{
|
||||
ucs4_to_ksc5601_sym (ch, &idx);
|
||||
idx |= (idx ? 0x8080 : 0);
|
||||
idx |= (idx ? 0x8080 : 0);
|
||||
}
|
||||
|
||||
*cp = (char) (idx / 256);
|
||||
*(cp + 1) = (char) (idx & 0xff) ;
|
||||
cp[0] = (unsigned char) (idx / 256);
|
||||
cp[1] = (unsigned char) (idx & 0xff);
|
||||
}
|
||||
/* think about 0x5c ; '\' */
|
||||
/* XXX Think about 0x5c ; '\'. */
|
||||
else
|
||||
{
|
||||
*cp = (char) (0x7f & ch) ;
|
||||
*(cp + 1) = (char) 0;
|
||||
cp[0] = (unsigned char) ch;
|
||||
cp[1] = (unsigned char) 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gconv_init (struct gconv_step *step)
|
||||
{
|
||||
/* Determine which direction. */
|
||||
if (strcasestr (step->from_name, "UHC") != NULL)
|
||||
step->data = &from_uhc_object;
|
||||
else if (strcasestr (step->to_name, "UHC") != NULL)
|
||||
step->data = &to_uhc_object;
|
||||
else
|
||||
return GCONV_NOCONV;
|
||||
/* Definitions used in the body of the `gconv' function. */
|
||||
#define CHARSET_NAME "UHC"
|
||||
#define FROM_LOOP from_uhc
|
||||
#define TO_LOOP to_uhc
|
||||
#define DEFINE_INIT 1
|
||||
#define DEFINE_FINI 1
|
||||
#define MIN_NEEDED_FROM 1
|
||||
#define MAX_NEEDED_FROM 2
|
||||
#define MIN_NEEDED_TO 4
|
||||
|
||||
return GCONV_OK;
|
||||
}
|
||||
/* First define the conversion function from UHC to UCS4. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||
#define LOOPFCT FROM_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = (uint32_t) *inptr; \
|
||||
\
|
||||
/* half-width Korean Currency WON sign \
|
||||
\
|
||||
if (ch == 0x5c) \
|
||||
ch = 0x20a9; \
|
||||
else if (ch <= 0x7f) \
|
||||
ch = (wchar_t) ch; \
|
||||
*/ \
|
||||
if (ch <= 0x7f) \
|
||||
++inptr; \
|
||||
else if (ch <= 0x80 || ch >= 0xfe || ch == 0xc9) \
|
||||
{ \
|
||||
/* This is illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Two-byte character. First test whether the next character \
|
||||
is also available. */ \
|
||||
uint32_t ch2; \
|
||||
\
|
||||
if (NEED_LENGTH_TEST && inptr + 1 >= inend) \
|
||||
{ \
|
||||
/* The second character is not available. Store \
|
||||
the intermediate result. */ \
|
||||
result = GCONV_INCOMPLETE_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch2 = inptr[1]; \
|
||||
\
|
||||
/* \
|
||||
Additional code points not present in EUC-KR \
|
||||
\
|
||||
1st byte 2nd byte \
|
||||
0x81-0xa0 0x41-0x5a, 0x61-0x7a, 0x81-0xfe total \
|
||||
(32) (26) + (26) + (126) = 178 5696 \
|
||||
\
|
||||
0xa1-0xc5 0x41-0x5a 0x61-0x7a 0x81-0xa0 \
|
||||
(37) (26) + (26) + (32) = 84 3108 \
|
||||
\
|
||||
0xc6 0x41-0x52 \
|
||||
(1) (18) 18 \
|
||||
\
|
||||
8822 \
|
||||
\
|
||||
8822(only in UHC) + 2350(both in EUC-KR and UHC) = 11,172 \
|
||||
*/ \
|
||||
\
|
||||
if (ch < 0xa1 || ch2 < 0xa1) \
|
||||
{ \
|
||||
if (ch > 0xc6 || ch2 <0x41 || (ch2 > 0x5a && ch2 < 0x61) \
|
||||
|| (ch2 > 0x7a && ch2 < 0x81) || (ch == 0xc6 && ch2 > 0x52)) \
|
||||
{ \
|
||||
/* This is not legal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
ch = uhc_extra_to_ucs[ch2 - 0x41 \
|
||||
- (ch2 > 0x80 ? 12 : (ch2 > 0x60 ? 6 : 0)) \
|
||||
+ (ch < 0xa1 \
|
||||
? (ch - 0x81) * 178 \
|
||||
: 5696 + (ch - 0xa1) * 84)]; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ch = ksc5601_to_ucs4 ((ch * 256 + ch2) & 0x7f7f); \
|
||||
\
|
||||
if (ch == UNKNOWN_10646_CHAR) \
|
||||
{ \
|
||||
/* Illegal. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if (ch == 0) \
|
||||
{ \
|
||||
/* This is an illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
inptr += 2; \
|
||||
} \
|
||||
\
|
||||
*((uint32_t *) outptr)++ = ch; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
void
|
||||
gconv_end (struct gconv_step *data)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
/* Next, define the other direction. */
|
||||
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||
#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
|
||||
#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
|
||||
#define LOOPFCT TO_LOOP
|
||||
#define BODY \
|
||||
{ \
|
||||
uint32_t ch = *((uint32_t *) inptr); \
|
||||
unsigned char cp[2]; \
|
||||
\
|
||||
uhc_from_ucs4 (ch, cp); \
|
||||
\
|
||||
if (cp[0] == '\0' && ch != 0) \
|
||||
{ \
|
||||
/* Illegal character. */ \
|
||||
result = GCONV_ILLEGAL_INPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[0]; \
|
||||
/* Now test for a possible second byte and write this if possible. */ \
|
||||
if (cp[1] != '\0') \
|
||||
{ \
|
||||
if (NEED_LENGTH_TEST && outptr >= outend) \
|
||||
{ \
|
||||
/* The result does not fit into the buffer. */ \
|
||||
result = GCONV_FULL_OUTPUT; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
*outptr++ = cp[1]; \
|
||||
} \
|
||||
\
|
||||
inptr += 4; \
|
||||
}
|
||||
#include <iconv/loop.c>
|
||||
|
||||
|
||||
int
|
||||
gconv (struct gconv_step *step, struct gconv_step_data *data,
|
||||
const char *inbuf, size_t *inbufsize, size_t *written, int do_flush)
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
gconv_fct fct = next_step->fct;
|
||||
size_t do_write;
|
||||
int result;
|
||||
|
||||
/* If the function is called with no input this means we have to reset
|
||||
to the initial state. The possibly partly converted input is
|
||||
dropped. */
|
||||
if (do_flush)
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
/* Call the steps down the chain if there are any. */
|
||||
if (data->is_last)
|
||||
result = GCONV_OK;
|
||||
else
|
||||
{
|
||||
struct gconv_step *next_step = step + 1;
|
||||
struct gconv_step_data *next_data = data + 1;
|
||||
|
||||
result = (*fct) (next_step, next_data, NULL, 0, written, 1);
|
||||
|
||||
/* Clear output buffer. */
|
||||
data->outbufavail = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do_write = 0;
|
||||
|
||||
do
|
||||
{
|
||||
result = GCONV_OK;
|
||||
|
||||
if (step->data == &from_uhc_object)
|
||||
{
|
||||
size_t inchars = *inbufsize;
|
||||
size_t outwchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
|
||||
while (cnt < inchars
|
||||
&& (outwchars + sizeof (wchar_t) <= data->outbufsize))
|
||||
{
|
||||
int inchar = (unsigned char) inbuf[cnt];
|
||||
wchar_t ch;
|
||||
/* half-width Korean Currency WON sign
|
||||
|
||||
if (inchar == 0x5c)
|
||||
ch = 0x20a9;
|
||||
else if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
*/
|
||||
if (inchar <= 0x7f)
|
||||
ch = (wchar_t) inchar;
|
||||
|
||||
|
||||
else if ( inchar <= 0x80 || inchar >= 0xfe || inchar == 0xc9)
|
||||
/* This is illegal. */
|
||||
ch = L'\0';
|
||||
else
|
||||
{
|
||||
/* Two-byte character. First test whether the next
|
||||
character is also available. */
|
||||
int inchar2;
|
||||
|
||||
if (cnt + 1 >= inchars)
|
||||
{
|
||||
/* The second character is not available. Store
|
||||
the intermediate result. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
inchar2 = (unsigned char) inbuf[++cnt];
|
||||
|
||||
/*
|
||||
Additional code points not present in EUC-KR
|
||||
|
||||
1st byte 2nd byte
|
||||
0x81-0xa0 0x41-0x5a, 0x61-0x7a, 0x81-0xfe total
|
||||
(32) (26) + (26) + (126) = 178 5696
|
||||
|
||||
0xa1-0xc5 0x41-0x5a 0x61-0x7a 0x81-0xa0
|
||||
(37) (26) + (26) + (32) = 84 3108
|
||||
|
||||
0xc6 0x41-0x52
|
||||
(1) (18) 18
|
||||
|
||||
8822
|
||||
|
||||
|
||||
8822(only in UHC) + 2350(both in EUC-KR and UHC) = 11,172
|
||||
*/
|
||||
|
||||
if ( inchar < 0xa1 || inchar2 < 0xa1)
|
||||
if ( inchar > 0xc6 || inchar2 <0x41 ||
|
||||
inchar2 > 0x5a && inchar2 < 0x61 ||
|
||||
inchar2 > 0x7a && inchar2 < 0x81 ||
|
||||
inchar == 0xc6 && inchar2 > 0x52 )
|
||||
ch = L'0';
|
||||
else
|
||||
{
|
||||
ch = uhc_extra_to_ucs[ inchar2 - 0x41
|
||||
- ( inchar2 > 0x80 ? 12 :
|
||||
( inchar2 > 0x60 ? 6 : 0 ) )
|
||||
+ ( inchar < 0xa1 ?
|
||||
(inchar - 0x81) * 178 :
|
||||
5696 + (inchar - 0xa1) * 84 ) ] ;
|
||||
}
|
||||
|
||||
else
|
||||
if ( ( ch = ksc5601_to_ucs4(
|
||||
(uint16_t) (inchar * 256 + inchar2) & 0x7f7f) )
|
||||
== UNKNOWN_10646_CHAR )
|
||||
|
||||
ch = L'\0';
|
||||
|
||||
if (ch == L'\0')
|
||||
--cnt;
|
||||
}
|
||||
|
||||
if (ch == L'\0' && inbuf[cnt] != '\0')
|
||||
{
|
||||
/* This is an illegal character. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
|
||||
*((wchar_t *) (outbuf + outwchars)) = ch;
|
||||
++do_write;
|
||||
outwchars += sizeof (wchar_t);
|
||||
++cnt;
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outwchars;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t inwchars = *inbufsize;
|
||||
size_t outchars = data->outbufavail;
|
||||
char *outbuf = data->outbuf;
|
||||
size_t cnt = 0;
|
||||
int extra = 0;
|
||||
|
||||
while (inwchars >= cnt + sizeof (wchar_t)
|
||||
&& outchars < data->outbufsize)
|
||||
{
|
||||
wchar_t ch = *((wchar_t *) (inbuf + cnt));
|
||||
unsigned char cp[2];
|
||||
|
||||
uhc_from_ucs4(ch,cp) ;
|
||||
|
||||
if (cp[0] == '\0' && ch != 0)
|
||||
/* Illegal character. */
|
||||
break;
|
||||
|
||||
outbuf[outchars] = cp[0];
|
||||
/* Now test for a possible second byte and write this
|
||||
if possible. */
|
||||
if (cp[1] != '\0')
|
||||
{
|
||||
if (outchars + 1 >= data->outbufsize)
|
||||
{
|
||||
/* The result does not fit into the buffer. */
|
||||
extra = 1;
|
||||
break;
|
||||
}
|
||||
outbuf[++outchars] = cp[1];
|
||||
}
|
||||
|
||||
++do_write;
|
||||
++outchars;
|
||||
cnt += sizeof (wchar_t);
|
||||
}
|
||||
*inbufsize -= cnt;
|
||||
inbuf += cnt;
|
||||
data->outbufavail = outchars;
|
||||
|
||||
if (outchars + extra < data->outbufsize)
|
||||
{
|
||||
/* If there is still room in the output buffer something
|
||||
is wrong with the input. */
|
||||
if (inwchars >= cnt + sizeof (wchar_t))
|
||||
{
|
||||
/* An error occurred. */
|
||||
result = GCONV_ILLEGAL_INPUT;
|
||||
break;
|
||||
}
|
||||
if (inwchars != cnt)
|
||||
{
|
||||
/* There are some unprocessed bytes at the end of the
|
||||
input buffer. */
|
||||
result = GCONV_INCOMPLETE_INPUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result != GCONV_OK)
|
||||
break;
|
||||
|
||||
if (data->is_last)
|
||||
{
|
||||
/* This is the last step. */
|
||||
result = (*inbufsize > (step->data == &from_uhc_object
|
||||
? 0 : sizeof (wchar_t) - 1)
|
||||
? GCONV_FULL_OUTPUT : GCONV_EMPTY_INPUT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Status so far. */
|
||||
result = GCONV_EMPTY_INPUT;
|
||||
|
||||
if (data->outbufavail > 0)
|
||||
{
|
||||
/* Call the functions below in the chain. */
|
||||
size_t newavail = data->outbufavail;
|
||||
|
||||
result = (*fct) (next_step, next_data, data->outbuf, &newavail,
|
||||
written, 0);
|
||||
|
||||
/* Correct the output buffer. */
|
||||
if (newavail != data->outbufavail && newavail > 0)
|
||||
{
|
||||
memmove (data->outbuf,
|
||||
&data->outbuf[data->outbufavail - newavail],
|
||||
newavail);
|
||||
data->outbufavail = newavail;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*inbufsize > 0 && result == GCONV_EMPTY_INPUT);
|
||||
}
|
||||
|
||||
if (written != NULL && data->is_last)
|
||||
*written = do_write;
|
||||
|
||||
return result;
|
||||
}
|
||||
/* Now define the toplevel functions. */
|
||||
#include <iconv/skeleton.c>
|
||||
|
@ -277,6 +277,22 @@ extern uint16_t htons __P ((uint16_t __hostshort));
|
||||
extern int bindresvport __P ((int __sockfd, struct sockaddr_in *__sock_in));
|
||||
|
||||
|
||||
|
||||
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x1))
|
||||
|
||||
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x2))
|
||||
|
||||
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x5))
|
||||
|
||||
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0x8))
|
||||
|
||||
#define IN6_IS_ADDR_MC_GLOBAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((u_int8_t *) (a))[1] & 0xf) == 0xe))
|
||||
|
||||
/* IPv6 packet information. */
|
||||
struct in6_pktinfo
|
||||
{
|
||||
|
6
libc.map
6
libc.map
@ -100,11 +100,12 @@ GLIBC_2.0 {
|
||||
__vsscanf; __vfscanf; __vsnprintf;
|
||||
_rpc_dtablesize; _null_auth; _seterr_reply;
|
||||
__res_randomid; __getpid;
|
||||
__strcasecmp; __write; _strerror_internal; _dl_sysdep_output;
|
||||
__strcasecmp; __strerror_r; __write; _dl_sysdep_output;
|
||||
_dl_debug_message;
|
||||
__ffs;
|
||||
__close; __connect; __fcntl; __lseek; __open; __read; __send; __wait;
|
||||
__ieee_get_fp_control; __ieee_set_fp_control;
|
||||
__dgettext;
|
||||
|
||||
# Exception handling support functions from libgcc
|
||||
__register_frame; __register_frame_table; __deregister_frame;
|
||||
@ -440,13 +441,14 @@ GLIBC_2.1 {
|
||||
__signbit; __signbitf; __signbitl; __libc_sa_len;
|
||||
|
||||
# functions used in other libraries
|
||||
_IO_fclose; _IO_fopen; _IO_fdopen; __asprintf;
|
||||
_IO_fclose; _IO_fopen; _IO_fdopen; __asprintf; __strcasestr;
|
||||
__syscall_rt_sigqueueinfo;
|
||||
__xstat64; __fxstat64; __lxstat64;
|
||||
__pread64; __pwrite64;
|
||||
|
||||
# helper functions
|
||||
__libc_current_sigrtmin; __libc_current_sigrtmax; __libc_allocate_rtsig;
|
||||
__libc_longjmp; __libc_siglongjmp;
|
||||
|
||||
# Since we have new signals this structure changed.
|
||||
_sys_siglist; sys_siglist; sys_sigabbrev;
|
||||
|
@ -48,7 +48,6 @@ extern int errno;
|
||||
# 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)
|
||||
# define fstat(FD, Buf) __fxstat (_STAT_VER, FD, Buf)
|
||||
#endif
|
||||
|
||||
/* An fstream can be in at most one of put mode, get mode, or putback mode.
|
||||
|
@ -483,7 +483,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode)
|
||||
break;
|
||||
case _IO_seek_end:
|
||||
{
|
||||
struct stat st;
|
||||
struct _G_stat64 st;
|
||||
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
|
||||
{
|
||||
offset += st.st_size;
|
||||
|
@ -1,3 +1,14 @@
|
||||
1998-04-20 14:55 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* Makefile (libpthread-routines): Add ptlongjmp and spinlock.
|
||||
* internals.h: Add definitions for new spinlock implementation.
|
||||
* ptlongjmp.c: New file.
|
||||
* spinlock.c: New file.
|
||||
* spinlock.h (acquire): Don't reschedule using __sched_yield, use
|
||||
new function __pthread_acquire to prevent deadlocks with thread
|
||||
with different priorities.
|
||||
Patches by Xavier Leroy <Xavier.Leroy@inria.fr>.
|
||||
|
||||
1998-03-16 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
* manager.c (__pthread_manager): Reduce first argument to select
|
||||
|
@ -32,8 +32,8 @@ extra-libs := libpthread
|
||||
extra-libs-others := $(extra-libs)
|
||||
|
||||
libpthread-routines := attr cancel condvar join manager mutex ptfork \
|
||||
pthread signals specific errno lockfile \
|
||||
semaphore wrapsyscall rwlock
|
||||
ptlongjmp pthread signals specific errno lockfile \
|
||||
semaphore spinlock wrapsyscall rwlock
|
||||
libpthread-map := libpthread.map
|
||||
|
||||
include ../Rules
|
||||
|
@ -250,6 +250,23 @@ static inline pthread_descr thread_self (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Max number of times we must spin on a spinlock calling sched_yield().
|
||||
After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */
|
||||
|
||||
#ifndef MAX_SPIN_COUNT
|
||||
#define MAX_SPIN_COUNT 50
|
||||
#endif
|
||||
|
||||
/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock
|
||||
after MAX_SPIN_COUNT iterations of sched_yield().
|
||||
With the 2.0 and 2.1 kernels, this MUST BE > 2ms.
|
||||
(Otherwise the kernel does busy-waiting for realtime threads,
|
||||
giving other threads no chance to run.) */
|
||||
|
||||
#ifndef SPIN_SLEEP_DURATION
|
||||
#define SPIN_SLEEP_DURATION 2000001
|
||||
#endif
|
||||
|
||||
/* Debugging */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
44
linuxthreads/ptlongjmp.c
Normal file
44
linuxthreads/ptlongjmp.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* Linuxthreads - a simple clone()-based implementation of Posix */
|
||||
/* threads for Linux. */
|
||||
/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public License */
|
||||
/* as published by the Free Software Foundation; either version 2 */
|
||||
/* of the License, 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 Library General Public License for more details. */
|
||||
|
||||
/* Redefine siglongjmp and longjmp so that they interact correctly
|
||||
with cleanup handlers */
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "pthread.h"
|
||||
#include "internals.h"
|
||||
|
||||
static void pthread_cleanup_upto(__jmp_buf target)
|
||||
{
|
||||
pthread_descr self = thread_self();
|
||||
struct _pthread_cleanup_buffer * c;
|
||||
|
||||
for (c = self->p_cleanup;
|
||||
c != NULL && _JMPBUF_UNWINDS(target, c);
|
||||
c = c->prev)
|
||||
c->routine(c->arg);
|
||||
self->p_cleanup = c;
|
||||
}
|
||||
|
||||
void siglongjmp(sigjmp_buf env, int val)
|
||||
{
|
||||
pthread_cleanup_upto(env->__jmpbuf);
|
||||
__libc_siglongjmp(env, val);
|
||||
}
|
||||
|
||||
void longjmp(jmp_buf env, int val)
|
||||
{
|
||||
pthread_cleanup_upto(env->__jmpbuf);
|
||||
__libc_longjmp(env, val);
|
||||
}
|
59
linuxthreads/spinlock.c
Normal file
59
linuxthreads/spinlock.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* Linuxthreads - a simple clone()-based implementation of Posix */
|
||||
/* threads for Linux. */
|
||||
/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or */
|
||||
/* modify it under the terms of the GNU Library General Public License */
|
||||
/* as published by the Free Software Foundation; either version 2 */
|
||||
/* of the License, 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 Library General Public License for more details. */
|
||||
|
||||
/* Spin locks */
|
||||
|
||||
#include <sched.h>
|
||||
#include <time.h>
|
||||
#include "pthread.h"
|
||||
#include "internals.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
/* This function is called if the inlined test-and-set in acquire() failed */
|
||||
|
||||
/* The retry strategy is as follows:
|
||||
- We test and set the spinlock MAX_SPIN_COUNT times, calling
|
||||
sched_yield() each time. This gives ample opportunity for other
|
||||
threads with priority >= our priority to make progress and
|
||||
release the spinlock.
|
||||
- If a thread with priority < our priority owns the spinlock,
|
||||
calling sched_yield() repeatedly is useless, since we're preventing
|
||||
the owning thread from making progress and releasing the spinlock.
|
||||
So, after MAX_SPIN_LOCK attemps, we suspend the calling thread
|
||||
using nanosleep(). This again should give time to the owning thread
|
||||
for releasing the spinlock.
|
||||
Notice that the nanosleep() interval must not be too small,
|
||||
since the kernel does busy-waiting for short intervals in a realtime
|
||||
process (!). The smallest duration that guarantees thread
|
||||
suspension is currently 2ms.
|
||||
- When nanosleep() returns, we try again, doing MAX_SPIN_COUNT
|
||||
sched_yield(), then sleeping again if needed. */
|
||||
|
||||
void __pthread_acquire(int * spinlock)
|
||||
{
|
||||
int cnt = 0;
|
||||
struct timespec tm;
|
||||
|
||||
while (testandset(spinlock)) {
|
||||
if (cnt < MAX_SPIN_COUNT) {
|
||||
sched_yield();
|
||||
cnt++;
|
||||
} else {
|
||||
tm.tv_sec = 0;
|
||||
tm.tv_nsec = SPIN_SLEEP_DURATION;
|
||||
nanosleep(&tm, NULL);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,9 +15,11 @@
|
||||
|
||||
/* Spin locks */
|
||||
|
||||
extern void __pthread_acquire(int * spinlock);
|
||||
|
||||
static inline void acquire(int * spinlock)
|
||||
{
|
||||
while (testandset(spinlock)) __sched_yield();
|
||||
if (testandset(spinlock)) __pthread_acquire(spinlock);
|
||||
}
|
||||
|
||||
static inline void release(int * spinlock)
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
subdir := login
|
||||
|
||||
headers := utmp.h bits/utmp.h utmpx.h bits/utmpx.h lastlog.h pty.h
|
||||
headers := utmp.h bits/utmp.h lastlog.h pty.h
|
||||
|
||||
routines := getutent getutent_r getutid getutline getutid_r getutline_r \
|
||||
utmp_file utmp_daemon utmpname updwtmp \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -35,4 +35,3 @@ __getutent (void)
|
||||
return result;
|
||||
}
|
||||
weak_alias (__getutent, getutent)
|
||||
weak_alias (__getutent, getutxent)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>
|
||||
and Paul Janzen <pcj@primenet.com>, 1996.
|
||||
@ -143,7 +143,6 @@ __setutent (void)
|
||||
__libc_lock_unlock (__libc_utmp_lock);
|
||||
}
|
||||
weak_alias (__setutent, setutent)
|
||||
weak_alias (__setutent, setutxent)
|
||||
|
||||
|
||||
int
|
||||
@ -176,7 +175,6 @@ __pututline (const struct utmp *data)
|
||||
return buffer;
|
||||
}
|
||||
weak_alias (__pututline, pututline)
|
||||
weak_alias (__pututline, pututxline)
|
||||
|
||||
|
||||
void
|
||||
@ -190,4 +188,3 @@ __endutent (void)
|
||||
__libc_lock_unlock (__libc_utmp_lock);
|
||||
}
|
||||
weak_alias (__endutent, endutent)
|
||||
weak_alias (__endutent, endutxent)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -35,4 +35,3 @@ __getutid (const struct utmp *id)
|
||||
return result;
|
||||
}
|
||||
weak_alias (__getutid, getutid)
|
||||
weak_alias (__getutid, getutxid)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -35,4 +35,3 @@ __getutline (const struct utmp *line)
|
||||
return result;
|
||||
}
|
||||
weak_alias (__getutline, getutline)
|
||||
weak_alias (__getutline, getutxline)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993, 1996, 1997, 1998 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
|
||||
@ -53,6 +53,8 @@ extern void logwtmp __P ((__const char *__ut_line, __const char *__ut_name,
|
||||
__const char *__ut_host));
|
||||
|
||||
/* Append entry UTMP to the wtmp-like file WTMP_FILE. */
|
||||
extern void __updwtmp __P ((__const char *__wtmp_file,
|
||||
__const struct utmp *__utmp));
|
||||
extern void updwtmp __P ((__const char *__wtmp_file,
|
||||
__const struct utmp *__utmp));
|
||||
|
||||
@ -61,6 +63,7 @@ extern int __utmpname __P ((__const char *__file));
|
||||
extern int utmpname __P ((__const char *__file));
|
||||
|
||||
/* Read next entry from a utmp-like file. */
|
||||
extern struct utmp *__getutent __P ((void));
|
||||
extern struct utmp *getutent __P ((void));
|
||||
|
||||
/* Reset the input stream to the beginning of the file. */
|
||||
@ -73,13 +76,16 @@ extern void endutent __P ((void));
|
||||
|
||||
/* Search forward from the current point in the utmp file until the
|
||||
next entry with a ut_type matching ID->ut_type. */
|
||||
extern struct utmp *__getutid __P ((__const struct utmp *__id));
|
||||
extern struct utmp *getutid __P ((__const struct utmp *__id));
|
||||
|
||||
/* Search forward from the current point in the utmp file until the
|
||||
next entry with a ut_line matching LINE->ut_line. */
|
||||
extern struct utmp *__getutline __P ((__const struct utmp *__line));
|
||||
extern struct utmp *getutline __P ((__const struct utmp *__line));
|
||||
|
||||
/* Write out entry pointed to by UTMP_PTR into the utmp file. */
|
||||
extern struct utmp *__pututline __P ((__const struct utmp *__utmp_ptr));
|
||||
extern struct utmp *pututline __P ((__const struct utmp *__utmp_ptr));
|
||||
|
||||
|
||||
|
@ -151,7 +151,7 @@ not generally used (see @code{_FILE_OFFSET_BITS}.
|
||||
|
||||
@comment (NONE)
|
||||
@comment X/Open
|
||||
@defvr _FILE_OFFSET_BITS
|
||||
@defvr Macro _FILE_OFFSET_BITS
|
||||
This macro lets decide which file system interface shall be used, one
|
||||
replacing the other. While @code{_LARGEFILE64_SOURCE} makes the @w{64
|
||||
bit} interface available as an additional interface
|
||||
|
@ -24,19 +24,19 @@
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
# define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
# ifndef const
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -51,10 +51,10 @@
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
# define ELIDE_CODE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
@ -65,26 +65,26 @@
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
#ifdef VMS
|
||||
#include <unixlib.h>
|
||||
#if HAVE_STRING_H - 0
|
||||
#include <string.h>
|
||||
#endif
|
||||
# include <unixlib.h>
|
||||
# if HAVE_STRING_H - 0
|
||||
# include <string.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef _
|
||||
/* This is for other GNU distributions with internationalized messages.
|
||||
When compiling libc, the _ macro is predefined. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
#else
|
||||
# define _(msgid) (msgid)
|
||||
#endif
|
||||
# ifdef HAVE_LIBINTL_H
|
||||
# include <libintl.h>
|
||||
# define _(msgid) gettext (msgid)
|
||||
# else
|
||||
# define _(msgid) (msgid)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
@ -194,14 +194,19 @@ static char *posixly_correct;
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
# include <string.h>
|
||||
# define my_index strchr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
#ifndef getenv
|
||||
extern char *getenv ();
|
||||
#endif
|
||||
#ifndef strncmp
|
||||
extern int strncmp ();
|
||||
#endif
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
@ -222,11 +227,11 @@ my_index (str, chr)
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
# if (!defined __STDC__ || !__STDC__) && !defined strlen
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
# endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
@ -524,11 +529,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
from the shell indicating it is not an option. The later information
|
||||
is only used when the used in the GNU libc. */
|
||||
#ifdef _LIBC
|
||||
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|
||||
|| (optind < nonoption_flags_len \
|
||||
&& __getopt_nonoption_flags[optind] == '1'))
|
||||
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|
||||
|| (optind < nonoption_flags_len \
|
||||
&& __getopt_nonoption_flags[optind] == '1'))
|
||||
#else
|
||||
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#endif
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
|
@ -1083,17 +1083,9 @@ static const char *re_error_msgid[] =
|
||||
# if defined MATCH_MAY_ALLOCATE
|
||||
/* 4400 was enough to cause a crash on Alpha OSF/1,
|
||||
whose default stack limit is 2mb. */
|
||||
# ifdef _LIBC
|
||||
long int __re_max_failures = 4000;
|
||||
# else
|
||||
long int re_max_failures = 4000;
|
||||
# endif
|
||||
# else
|
||||
# ifdef _LIBC
|
||||
long int __re_max_failures = 2000;
|
||||
# else
|
||||
long int re_max_failures = 2000;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
union fail_stack_elt
|
||||
@ -1116,24 +1108,11 @@ typedef struct
|
||||
# if defined MATCH_MAY_ALLOCATE
|
||||
/* 4400 was enough to cause a crash on Alpha OSF/1,
|
||||
whose default stack limit is 2mb. */
|
||||
# ifdef _LIBC
|
||||
int __re_max_failures = 20000;
|
||||
# else
|
||||
int re_max_failures = 20000;
|
||||
# endif
|
||||
# else
|
||||
# ifdef _LIBC
|
||||
int __re_max_failures = 2000;
|
||||
# else
|
||||
int re_max_failures = 2000;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#ifdef _LIBC
|
||||
weak_alias (__re_max_failures, re_max_failures)
|
||||
# define re_max_failures __re_max_failures
|
||||
#endif
|
||||
|
||||
union fail_stack_elt
|
||||
{
|
||||
unsigned char *pointer;
|
||||
|
@ -150,6 +150,7 @@ struct test_case_struct
|
||||
};
|
||||
|
||||
static int testit (struct test_case_struct *tc);
|
||||
static int tests;
|
||||
|
||||
void
|
||||
command_line_test (const char *words)
|
||||
@ -204,17 +205,28 @@ main (int argc, char *argv[])
|
||||
{
|
||||
struct test_case_struct ts;
|
||||
|
||||
printf ("Test %d (~root): ", ++tests);
|
||||
fflush (stdout);
|
||||
|
||||
ts.retval = 0;
|
||||
ts.env = NULL;
|
||||
ts.words = "~root";
|
||||
ts.flags = 0;
|
||||
ts.wordc = 1;
|
||||
ts.wordv[0] = pw->pw_dir;
|
||||
ts.ifs = IFS;
|
||||
|
||||
if (testit (&ts))
|
||||
++fail;
|
||||
{
|
||||
printf ("FAILED\n");
|
||||
++fail;
|
||||
}
|
||||
else
|
||||
printf ("OK\n");
|
||||
}
|
||||
|
||||
puts ("tests completed, now cleaning up");
|
||||
|
||||
/* Clean up */
|
||||
for (i = 0; globfile[i]; ++i)
|
||||
remove (globfile[i]);
|
||||
@ -225,6 +237,8 @@ main (int argc, char *argv[])
|
||||
chdir (cwd);
|
||||
rmdir (tmpdir);
|
||||
|
||||
printf ("tests failed: %d\n", fail);
|
||||
|
||||
return fail != 0;
|
||||
}
|
||||
|
||||
@ -232,7 +246,6 @@ main (int argc, char *argv[])
|
||||
static int
|
||||
testit (struct test_case_struct *tc)
|
||||
{
|
||||
static int test;
|
||||
int retval;
|
||||
wordexp_t we;
|
||||
int bzzzt = 0;
|
||||
@ -248,7 +261,7 @@ testit (struct test_case_struct *tc)
|
||||
else
|
||||
unsetenv ("IFS");
|
||||
|
||||
printf ("Test %d: ", ++test);
|
||||
printf ("Test %d (%s): ", ++tests, tc->words);
|
||||
retval = wordexp (tc->words, &we, tc->flags);
|
||||
|
||||
if (retval != tc->retval || (retval == 0 && we.we_wordc != tc->wordc))
|
||||
|
@ -18,6 +18,8 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
|
||||
int
|
||||
|
@ -18,6 +18,8 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
|
||||
int
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 1997, 1998 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
|
||||
@ -37,17 +37,23 @@ mblen (const char *s, size_t n)
|
||||
restartable functions. We simply say here all encodings have a
|
||||
state. */
|
||||
if (s == NULL)
|
||||
return 1;
|
||||
result = 1;
|
||||
else if (*s == '\0')
|
||||
/* According to the ISO C 89 standard this is the expected behaviour.
|
||||
Idiotic, but true. */
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
state.count = 0;
|
||||
state.value = 0;
|
||||
|
||||
state.count = 0;
|
||||
state.value = 0;
|
||||
result = __mbrtowc (NULL, s, n, &state);
|
||||
|
||||
result = __mbrtowc (NULL, s, n, &state);
|
||||
|
||||
/* The `mbrtowc' functions tell us more than we need. Fold the -1
|
||||
and -2 result into -1. */
|
||||
if (result < 0)
|
||||
result = -1;
|
||||
/* The `mbrtowc' functions tell us more than we need. Fold the -1
|
||||
and -2 result into -1. */
|
||||
if (result < 0)
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 92, 95, 96, 97, 98 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
|
||||
@ -43,14 +43,22 @@ mbtowc (wchar_t *pwc, const char *s, size_t n)
|
||||
restartable functions. We simply say here all encodings have a
|
||||
state. */
|
||||
if (s == NULL)
|
||||
return 1;
|
||||
result = 1;
|
||||
else if (*s == '\0')
|
||||
{
|
||||
if (pwc != NULL)
|
||||
*pwc = L'\0';
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = __mbrtowc (pwc, s, n, &__no_r_state);
|
||||
|
||||
result = __mbrtowc (pwc, s, n, &__no_r_state);
|
||||
|
||||
/* The `mbrtowc' functions tell us more than we need. Fold the -1
|
||||
and -2 result into -1. */
|
||||
if (result < 0)
|
||||
result = -1;
|
||||
/* The `mbrtowc' functions tell us more than we need. Fold the -1
|
||||
and -2 result into -1. */
|
||||
if (result < 0)
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1,3 +1,21 @@
|
||||
/* Copyright (C) 1997, 1998 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 Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Define the machine-dependent type `jmp_buf'. ARM version. */
|
||||
|
||||
#ifndef _SETJMP_H
|
||||
|
55
sysdeps/arm/strlen.S
Normal file
55
sysdeps/arm/strlen.S
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Code contributed by Matthew Wilcox <willy@odie.barnet.ac.uk>
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
/* size_t strlen(const char *S)
|
||||
* entry: r0 -> string
|
||||
* exit: r0 = len
|
||||
*/
|
||||
|
||||
ENTRY(strlen)
|
||||
bic r1, r0, $3 @ addr of word containing first byte
|
||||
ldr r2, [r1], $4 @ get the first word
|
||||
ands r3, r0, $3 @ how many bytes are duff?
|
||||
rsb r0, r3, $0 @ get - that number into counter.
|
||||
beq Laligned @ skip into main check routine if no
|
||||
@ more
|
||||
orr r2, r2, $0xff000000 @ set this byte to non-zero
|
||||
subs r3, r3, $1 @ any more to do?
|
||||
orrgt r2, r2, $0x00ff0000 @ if so, set this byte
|
||||
subs r3, r3, $1 @ more?
|
||||
orrgt r2, r2, $0x0000ff00 @ then set.
|
||||
Laligned: @ here, we have a word in r2. Does it
|
||||
tst r2, $0x000000ff @ contain any zeroes?
|
||||
tstne r2, $0x0000ff00 @
|
||||
tstne r2, $0x00ff0000 @
|
||||
tstne r2, $0xff000000 @
|
||||
addne r0, r0, $4 @ if not, the string is 4 bytes longer
|
||||
ldrne r2, [r1], $4 @ and we continue to the next word
|
||||
bne Laligned @
|
||||
Llastword: @ drop through to here once we find a
|
||||
tst r2, $0x000000ff @ word that has a zero byte in it
|
||||
addne r0, r0, $1 @
|
||||
tstne r2, $0x0000ff00 @ and add up to 3 bytes on to it
|
||||
addne r0, r0, $1 @
|
||||
tstne r2, $0x00ff0000 @ (if first three all non-zero, 4th
|
||||
addne r0, r0, $1 @ must be zero)
|
||||
RETINSTR(mov,pc,lr)
|
||||
END(strlen)
|
@ -17,6 +17,9 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef __BITS_SOCKET_H
|
||||
#define __BITS_SOCKET_H 1
|
||||
|
||||
#if !defined _SYS_SOCKET_H && !defined _NETINET_IN_H
|
||||
# error "Never include <bits/socket.h> directly; use <sys/socket.h> instead."
|
||||
#endif
|
||||
@ -196,3 +199,5 @@ struct linger
|
||||
int l_onoff; /* Nonzero to linger on close. */
|
||||
int l_linger; /* Time to linger. */
|
||||
};
|
||||
|
||||
#endif /* bits/socket.h */
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Structures and definitions for the user accounting database. Generic/BSDish
|
||||
Copyright (C) 1993, 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
@ -16,19 +17,11 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _UTMPX_H
|
||||
# error "Never include <bits/utmpx.h> directly; use <utmpx.h> instead."
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#include <utmpx.h>
|
||||
|
||||
|
||||
#define __UT_NAMESIZE 8
|
||||
#define __UT_LINESIZE 8
|
||||
#define __UT_HOSTSIZE 16
|
||||
|
||||
struct utmpx
|
||||
{
|
||||
char ut_line[__UT_LINESIZE];
|
||||
char ut_name[__UT_NAMESIZE];
|
||||
char ut_host[__UT_HOSTSIZE];
|
||||
long int ut_time;
|
||||
};
|
||||
void
|
||||
endutxent (void)
|
||||
{
|
||||
__endutent ();
|
||||
}
|
27
sysdeps/generic/getutxent.c
Normal file
27
sysdeps/generic/getutxent.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <utmp.h>
|
||||
#include <utmpx.h>
|
||||
|
||||
struct utmpx *
|
||||
getutxent (void)
|
||||
{
|
||||
return (struct utmpx *) __getutent ();
|
||||
}
|
27
sysdeps/generic/getutxid.c
Normal file
27
sysdeps/generic/getutxid.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <utmp.h>
|
||||
#include <utmpx.h>
|
||||
|
||||
struct utmpx *
|
||||
getutxid (const struct utmpx *id)
|
||||
{
|
||||
return (struct utmpx *) __getutid ((const struct utmp *) id);
|
||||
}
|
27
sysdeps/generic/getutxline.c
Normal file
27
sysdeps/generic/getutxline.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <utmp.h>
|
||||
#include <utmpx.h>
|
||||
|
||||
struct utmpx *
|
||||
getutxline (const struct utmpx *line)
|
||||
{
|
||||
return (struct utmpx *) __getutline ((const struct utmp *) line);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991, 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991, 92, 94, 95, 97, 98 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
|
||||
@ -27,7 +27,7 @@ extern void _longjmp_unwind (jmp_buf env, int val);
|
||||
to the position specified in ENV, causing the setjmp
|
||||
call there to return VAL, or 1 if VAL is 0. */
|
||||
void
|
||||
longjmp (sigjmp_buf env, int val)
|
||||
__libc_siglongjmp (sigjmp_buf env, int val)
|
||||
{
|
||||
/* Perform any cleanups needed by the frames being unwound. */
|
||||
_longjmp_unwind (env, val);
|
||||
@ -41,5 +41,7 @@ longjmp (sigjmp_buf env, int val)
|
||||
__longjmp (env[0].__jmpbuf, val ?: 1);
|
||||
}
|
||||
|
||||
weak_alias (longjmp, _longjmp)
|
||||
weak_alias (longjmp, siglongjmp)
|
||||
strong_alias (__libc_siglongjmp, __libc_longjmp)
|
||||
weak_alias (__libc_siglongjmp, _longjmp)
|
||||
weak_alias (__libc_siglongjmp, longjmp)
|
||||
weak_alias (__libc_siglongjmp, siglongjmp)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user