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:
Ulrich Drepper 1998-04-20 18:41:05 +00:00
parent f1fa8b68f3
commit 8619129f3f
141 changed files with 4466 additions and 5559 deletions

238
ChangeLog
View File

@ -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
View File

@ -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
View File

@ -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:

View File

@ -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 */

View File

@ -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>

View File

@ -1,6 +1,7 @@
/* Compatibility gunk for the db library. */
#include <sys/types.h>
#include <errno.h>
#ifndef EFTYPE
# define EFTYPE EINVAL

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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"

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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:

View File

@ -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
View 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
View 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

View File

@ -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>

View File

@ -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>

View File

@ -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)) \

View File

@ -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>

View File

@ -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",

View File

@ -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;

View File

@ -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",

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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",

View File

@ -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;

View File

@ -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>

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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,

View File

@ -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;

View File

@ -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",

View File

@ -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];

View File

@ -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",

View File

@ -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];

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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},

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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
{

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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;
}
}
}

View File

@ -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)

View File

@ -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 \

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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));

View File

@ -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

View File

@ -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')

View File

@ -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;

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View 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)

View File

@ -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 */

View File

@ -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 ();
}

View 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 ();
}

View 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);
}

View 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);
}

View File

@ -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