mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
Update.
2000-09-10 Bruno Haible <haible@clisp.cons.org> * locale/programs/ld-collate.c (collate_read): Fix typo in handling of decimal ellipsis. 2000-09-11 Bruno Haible <haible@clisp.cons.org> * locale/programs/ld-collate.c (collate_read): Always initialize error_section.next. 2000-09-10 Bruno Haible <haible@clisp.cons.org> * locale/programs/ld-collate.c (collate_finish): Upper bound for ruleidx is 128, not 256. 2000-09-11 Ulrich Drepper <drepper@redhat.com> * locale/programs/ld-collate.c (collate_read): Correct check for already inserted entries. 2000-09-10 Bruno Haible <haible@clisp.cons.org> * iconv/skeleton.c (FUNCTION_NAME): Handle unaligned access in second try as well. 2000-09-10 Bruno Haible <haible@clisp.cons.org> * iconv/skeleton.c (FUNCTION_NAME): Optimize an `if' if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1. 2000-09-10 Bruno Haible <haible@clisp.cons.org> * iconv/skeleton.c (gconv_init): Replace all uses of RESET_STATE with SAVE_RESET_STATE. 2000-09-10 Bruno Haible <haible@clisp.cons.org> * iconvdata/utf-7.c: New file. * iconvdata/gconv-modules (UTF-7): New module entries. * iconvdata/Makefile (modules): Add UTF-7. (distribute): Add utf-7.c. * iconvdata/testdata/UTF-7: New file. * iconvdata/testdata/UTF-7..UTF8: New file. * iconvdata/TESTS (UTF-7): New entry. * iconvdata/run-iconv-test.sh: Fix confusing output.
This commit is contained in:
46
ChangeLog
46
ChangeLog
@@ -1,3 +1,49 @@
|
|||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* locale/programs/ld-collate.c (collate_read): Fix typo in handling
|
||||||
|
of decimal ellipsis.
|
||||||
|
|
||||||
|
2000-09-11 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* locale/programs/ld-collate.c (collate_read): Always initialize
|
||||||
|
error_section.next.
|
||||||
|
|
||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* locale/programs/ld-collate.c (collate_finish): Upper bound for
|
||||||
|
ruleidx is 128, not 256.
|
||||||
|
|
||||||
|
2000-09-11 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* locale/programs/ld-collate.c (collate_read): Correct check for
|
||||||
|
already inserted entries.
|
||||||
|
|
||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* iconv/skeleton.c (FUNCTION_NAME): Handle unaligned access in
|
||||||
|
second try as well.
|
||||||
|
|
||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* iconv/skeleton.c (FUNCTION_NAME): Optimize an `if' if
|
||||||
|
MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1.
|
||||||
|
|
||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* iconv/skeleton.c (gconv_init): Replace all uses of RESET_STATE with
|
||||||
|
SAVE_RESET_STATE.
|
||||||
|
|
||||||
|
2000-09-10 Bruno Haible <haible@clisp.cons.org>
|
||||||
|
|
||||||
|
* iconvdata/utf-7.c: New file.
|
||||||
|
* iconvdata/gconv-modules (UTF-7): New module entries.
|
||||||
|
* iconvdata/Makefile (modules): Add UTF-7.
|
||||||
|
(distribute): Add utf-7.c.
|
||||||
|
* iconvdata/testdata/UTF-7: New file.
|
||||||
|
* iconvdata/testdata/UTF-7..UTF8: New file.
|
||||||
|
* iconvdata/TESTS (UTF-7): New entry.
|
||||||
|
* iconvdata/run-iconv-test.sh: Fix confusing output.
|
||||||
|
|
||||||
2000-09-11 Ulrich Drepper <drepper@redhat.com>
|
2000-09-11 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* sysdeps/posix/tempname.c (__gen_tempname): Use __lxstat and __xstat.
|
* sysdeps/posix/tempname.c (__gen_tempname): Use __lxstat and __xstat.
|
||||||
|
@@ -57,7 +57,12 @@
|
|||||||
from the current characters.
|
from the current characters.
|
||||||
TO_LOOP likewise for the other direction
|
TO_LOOP likewise for the other direction
|
||||||
|
|
||||||
RESET_STATE in case of an error we must reset the state for
|
ONE_DIRECTION optional. If defined to 1, only one conversion
|
||||||
|
direction is defined instead of two. In this
|
||||||
|
case, FROM_DIRECTION should be defined to 1, and
|
||||||
|
FROM_LOOP and TO_LOOP should have the same value.
|
||||||
|
|
||||||
|
SAVE_RESET_STATE in case of an error we must reset the state for
|
||||||
the rerun so this macro must be defined for
|
the rerun so this macro must be defined for
|
||||||
stateful encodings. It takes an argument which
|
stateful encodings. It takes an argument which
|
||||||
is nonzero when saving.
|
is nonzero when saving.
|
||||||
@@ -184,8 +189,8 @@ static int to_object;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* For conversions from a fixed width character sets to another fixed width
|
/* For conversions from a fixed width character set to another fixed width
|
||||||
character set we we can define RESET_INPUT_BUFFER is necessary. */
|
character set we can define RESET_INPUT_BUFFER in a very fast way. */
|
||||||
#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
|
#if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
|
||||||
# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
|
# if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO
|
||||||
/* We have to use these `if's here since the compiler cannot know that
|
/* We have to use these `if's here since the compiler cannot know that
|
||||||
@@ -233,7 +238,7 @@ gconv_init (struct __gconv_step *step)
|
|||||||
else
|
else
|
||||||
return __GCONV_NOCONV;
|
return __GCONV_NOCONV;
|
||||||
|
|
||||||
#ifdef RESET_STATE
|
#ifdef SAVE_RESET_STATE
|
||||||
step->__stateful = 1;
|
step->__stateful = 1;
|
||||||
#else
|
#else
|
||||||
step->__stateful = 0;
|
step->__stateful = 0;
|
||||||
@@ -245,8 +250,8 @@ gconv_init (struct __gconv_step *step)
|
|||||||
|
|
||||||
|
|
||||||
/* The default destructor function does nothing in the moment and so
|
/* 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 don't define it at all. But we still provide the macro just in
|
||||||
we need it some day. */
|
case we need it some day. */
|
||||||
#if DEFINE_FINI
|
#if DEFINE_FINI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -339,7 +344,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
|
|||||||
/* If the function is used to implement the mb*towc*() or wc*tomb*()
|
/* If the function is used to implement the mb*towc*() or wc*tomb*()
|
||||||
functions we must test whether any bytes from the last call are
|
functions we must test whether any bytes from the last call are
|
||||||
stored in the `state' object. */
|
stored in the `state' object. */
|
||||||
if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
|
if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1)
|
||||||
|
|| (MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
|
||||||
|| (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
|
|| (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
|
||||||
&& consume_incomplete && (data->__statep->__count & 7) != 0)
|
&& consume_incomplete && (data->__statep->__count & 7) != 0)
|
||||||
{
|
{
|
||||||
@@ -491,23 +497,44 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
|
|||||||
SAVE_RESET_STATE (0);
|
SAVE_RESET_STATE (0);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* XXX Handle unaligned access here as well. */
|
if (__builtin_expect (!unaligned, 1))
|
||||||
|
{
|
||||||
if (FROM_DIRECTION)
|
if (FROM_DIRECTION)
|
||||||
/* Run the conversion loop. */
|
/* Run the conversion loop. */
|
||||||
nstatus = FROM_LOOP (step, data,
|
nstatus = FROM_LOOP (step, data, inptrp, inend,
|
||||||
(const unsigned char **) inptrp,
|
&outbuf,
|
||||||
(const unsigned char *) inend,
|
|
||||||
(unsigned char **) &outbuf,
|
|
||||||
(unsigned char *) outerr,
|
(unsigned char *) outerr,
|
||||||
lirreversiblep EXTRA_LOOP_ARGS);
|
lirreversiblep
|
||||||
|
EXTRA_LOOP_ARGS);
|
||||||
else
|
else
|
||||||
/* Run the conversion loop. */
|
/* Run the conversion loop. */
|
||||||
nstatus = TO_LOOP (step, data,
|
nstatus = TO_LOOP (step, data, inptrp, inend,
|
||||||
(const unsigned char **) inptrp,
|
&outbuf,
|
||||||
(const unsigned char *) inend,
|
|
||||||
(unsigned char **) &outbuf,
|
|
||||||
(unsigned char *) outerr,
|
(unsigned char *) outerr,
|
||||||
lirreversiblep EXTRA_LOOP_ARGS);
|
lirreversiblep
|
||||||
|
EXTRA_LOOP_ARGS);
|
||||||
|
}
|
||||||
|
# if !defined _STRING_ARCH_unaligned \
|
||||||
|
&& MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \
|
||||||
|
&& MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FROM_DIRECTION)
|
||||||
|
/* Run the conversion loop. */
|
||||||
|
nstatus = GEN_unaligned (FROM_LOOP) (step, data,
|
||||||
|
inptrp, inend,
|
||||||
|
(unsigned char *) outerr,
|
||||||
|
lirreversiblep
|
||||||
|
EXTRA_LOOP_ARGS);
|
||||||
|
else
|
||||||
|
/* Run the conversion loop. */
|
||||||
|
nstatus = GEN_unaligned (TO_LOOP) (step, data,
|
||||||
|
inptrp, inend,
|
||||||
|
(unsigned char *) outerr,
|
||||||
|
lirreversiblep
|
||||||
|
EXTRA_LOOP_ARGS);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
/* We must run out of output buffer space in this
|
/* We must run out of output buffer space in this
|
||||||
rerun. */
|
rerun. */
|
||||||
@@ -540,7 +567,8 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
|
|||||||
/* If we are supposed to consume all character store now all of the
|
/* If we are supposed to consume all character store now all of the
|
||||||
remaining characters in the `state' object. */
|
remaining characters in the `state' object. */
|
||||||
#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
|
#if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1
|
||||||
if (((MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
|
if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1)
|
||||||
|
|| (MAX_NEEDED_FROM > 1 && FROM_DIRECTION)
|
||||||
|| (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
|
|| (MAX_NEEDED_TO > 1 && !FROM_DIRECTION))
|
||||||
&& __builtin_expect (consume_incomplete, 0)
|
&& __builtin_expect (consume_incomplete, 0)
|
||||||
&& status == __GCONV_INCOMPLETE_INPUT)
|
&& status == __GCONV_INCOMPLETE_INPUT)
|
||||||
@@ -580,7 +608,7 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
|
|||||||
#undef EMIT_SHIFT_TO_INIT
|
#undef EMIT_SHIFT_TO_INIT
|
||||||
#undef FROM_LOOP
|
#undef FROM_LOOP
|
||||||
#undef TO_LOOP
|
#undef TO_LOOP
|
||||||
#undef RESET_STATE
|
#undef SAVE_RESET_STATE
|
||||||
#undef RESET_INPUT_BUFFER
|
#undef RESET_INPUT_BUFFER
|
||||||
#undef FUNCTION_NAME
|
#undef FUNCTION_NAME
|
||||||
#undef PREPARE_LOOP
|
#undef PREPARE_LOOP
|
||||||
|
@@ -45,7 +45,8 @@ modules := ISO8859-1 ISO8859-2 ISO8859-3 ISO8859-4 ISO8859-5 \
|
|||||||
INIS-CYRILLIC ISO_6937-2 ISO_2033 ISO_5427 ISO_5427-EXT \
|
INIS-CYRILLIC ISO_6937-2 ISO_2033 ISO_5427 ISO_5427-EXT \
|
||||||
ISO_5428 ISO_10367-BOX MAC-IS MAC-UK NATS-DANO NATS-SEFI \
|
ISO_5428 ISO_10367-BOX MAC-IS MAC-UK NATS-DANO NATS-SEFI \
|
||||||
SAMI-WS2 ISO-IR-197 TIS-620 KOI8-U GBK ISIRI-3342 GBGBK \
|
SAMI-WS2 ISO-IR-197 TIS-620 KOI8-U GBK ISIRI-3342 GBGBK \
|
||||||
ISO-2022-CN libISOIR165 UTF-16 UNICODE BIG5HKSCS GB18030
|
ISO-2022-CN libISOIR165 UTF-16 UNICODE UTF-7 BIG5HKSCS \
|
||||||
|
GB18030
|
||||||
|
|
||||||
modules.so := $(addsuffix .so, $(modules))
|
modules.so := $(addsuffix .so, $(modules))
|
||||||
|
|
||||||
@@ -125,8 +126,8 @@ distribute := gconv-modules extra-module.mk gap.awk gaptab.awk \
|
|||||||
macintosh.c mac-is.c mac-uk.c nats-dano.c nats-sefi.c sjis.c \
|
macintosh.c mac-is.c mac-uk.c nats-dano.c nats-sefi.c sjis.c \
|
||||||
t.61.c uhc.c sami-ws2.c iso-ir-197.c tis-620.c koi8-u.c \
|
t.61.c uhc.c sami-ws2.c iso-ir-197.c tis-620.c koi8-u.c \
|
||||||
isiri-3342.c isiri-3342.h gbgbk.c iso-2022-cn.c cns11643l2.h \
|
isiri-3342.c isiri-3342.h gbgbk.c iso-2022-cn.c cns11643l2.h \
|
||||||
iso8859-16.c utf-16.c unicode.c big5hkscs.c iso-ir-165.c \
|
iso8859-16.c utf-16.c unicode.c utf-7.c big5hkscs.c \
|
||||||
iso-ir-165.h gb18030.c
|
iso-ir-165.c iso-ir-165.h gb18030.c
|
||||||
|
|
||||||
# We build the transformation modules only when we build shared libs.
|
# We build the transformation modules only when we build shared libs.
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
|
@@ -81,3 +81,4 @@ EUC-KR EUC-KR Y UTF8
|
|||||||
EUC-CN EUC-CN Y UTF8
|
EUC-CN EUC-CN Y UTF8
|
||||||
GBK GBK Y UTF8
|
GBK GBK Y UTF8
|
||||||
BIG5HKSCS BIG5HKSCS Y UTF8
|
BIG5HKSCS BIG5HKSCS Y UTF8
|
||||||
|
UTF-7 UTF-7 N UTF8
|
||||||
|
@@ -1194,6 +1194,10 @@ alias CSUNICODE// UNICODE//
|
|||||||
module UNICODE// INTERNAL UNICODE 1
|
module UNICODE// INTERNAL UNICODE 1
|
||||||
module INTERNAL UNICODE// UNICODE 1
|
module INTERNAL UNICODE// UNICODE 1
|
||||||
|
|
||||||
|
# from to module cost
|
||||||
|
module UTF-7// INTERNAL UTF-7 1
|
||||||
|
module INTERNAL UTF-7// UTF-7 1
|
||||||
|
|
||||||
# from to module cost
|
# from to module cost
|
||||||
module GB18030// INTERNAL GB18030 1
|
module GB18030// INTERNAL GB18030 1
|
||||||
module INTERNAL GB18030// GB18030 1
|
module INTERNAL GB18030// GB18030 1
|
||||||
|
@@ -100,7 +100,7 @@ while read from to subset targets; do
|
|||||||
{ echo "/FAILED";
|
{ echo "/FAILED";
|
||||||
failed=1; continue; }
|
failed=1; continue; }
|
||||||
else
|
else
|
||||||
echo $ac_n " suntzu: $from -> ASCII -> $to $ac_c"
|
echo $ac_n " suntzu: ASCII -> $to -> ASCII $ac_c"
|
||||||
$PROG -f ASCII -t $to testdata/suntzus |
|
$PROG -f ASCII -t $to testdata/suntzus |
|
||||||
$PROG -f $to -t ASCII > $temp1 ||
|
$PROG -f $to -t ASCII > $temp1 ||
|
||||||
{ if test $? -gt 128; then exit 1; fi
|
{ if test $? -gt 128; then exit 1; fi
|
||||||
|
25
iconvdata/testdata/UTF-7
vendored
Normal file
25
iconvdata/testdata/UTF-7
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
+EqASGxItEps Amharic
|
||||||
|
+AQ0-esky Czech
|
||||||
|
Dansk Danish
|
||||||
|
English English
|
||||||
|
Suomi Finnish
|
||||||
|
Fran+AOc-ais French
|
||||||
|
Deutsch German
|
||||||
|
+A5UDuwO7A7cDvQO5A7oDrA Greek
|
||||||
|
+BeIF0QXoBdkF6g Hebrew
|
||||||
|
Italiano Italian
|
||||||
|
Norsk Norwegian
|
||||||
|
+BCAEQwRBBEEEOgQ4BDk Russian
|
||||||
|
Espa+APE-ol Spanish
|
||||||
|
Svenska Swedish
|
||||||
|
+DiAOMg4pDjIORA4XDiI Thai
|
||||||
|
T+APw-rk+AOc-e Turkish
|
||||||
|
Ti+Hr8-ng Vi+Hsc-t Vietnamese
|
||||||
|
+ZeVnLIqe Japanese
|
||||||
|
+Ti1lhw Chinese
|
||||||
|
+1VyuAA Korean
|
||||||
|
|
||||||
|
// The last line of this file is missing the end-of-line terminator
|
||||||
|
// on purpose, in order to test that the conversion empties the bit buffer
|
||||||
|
// and shifts back to the initial state at the end of the conversion.
|
||||||
|
A+ImIDkQ-
|
25
iconvdata/testdata/UTF-7..UTF8
vendored
Normal file
25
iconvdata/testdata/UTF-7..UTF8
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
አማርኛ Amharic
|
||||||
|
česky Czech
|
||||||
|
Dansk Danish
|
||||||
|
English English
|
||||||
|
Suomi Finnish
|
||||||
|
Français French
|
||||||
|
Deutsch German
|
||||||
|
Ελληνικά Greek
|
||||||
|
עברית Hebrew
|
||||||
|
Italiano Italian
|
||||||
|
Norsk Norwegian
|
||||||
|
Русский Russian
|
||||||
|
Español Spanish
|
||||||
|
Svenska Swedish
|
||||||
|
ภาษาไทย Thai
|
||||||
|
Türkçe Turkish
|
||||||
|
Tiếng Việt Vietnamese
|
||||||
|
日本語 Japanese
|
||||||
|
中文 Chinese
|
||||||
|
한글 Korean
|
||||||
|
|
||||||
|
// The last line of this file is missing the end-of-line terminator
|
||||||
|
// on purpose, in order to test that the conversion empties the bit buffer
|
||||||
|
// and shifts back to the initial state at the end of the conversion.
|
||||||
|
A≢Α
|
559
iconvdata/utf-7.c
Normal file
559
iconvdata/utf-7.c
Normal file
@@ -0,0 +1,559 @@
|
|||||||
|
/* Conversion module for UTF-7.
|
||||||
|
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Bruno Haible <haible@clisp.cons.org>, 2000.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* UTF-7 is a legacy encoding used for transmitting Unicode within the
|
||||||
|
ASCII character set, used primarily by mail agents. New programs
|
||||||
|
are encouraged to use UTF-8 instead.
|
||||||
|
|
||||||
|
UTF-7 is specified in RFC 2152 (and old RFC 1641, RFC 1642). The
|
||||||
|
original Base64 encoding is defined in RFC 2045. */
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <gconv.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Define this to 1 if you want the so-called "optional direct" characters
|
||||||
|
! " # $ % & * ; < = > @ [ ] ^ _ ` { | }
|
||||||
|
to be encoded. Define to 0 if you want them to be passed straight
|
||||||
|
through, like the so-called "direct" characters.
|
||||||
|
We set this to 1 because it's safer.
|
||||||
|
*/
|
||||||
|
#define UTF7_ENCODE_OPTIONAL_CHARS 1
|
||||||
|
|
||||||
|
|
||||||
|
/* The set of "direct characters":
|
||||||
|
A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const unsigned char direct_tab[128/8] =
|
||||||
|
{
|
||||||
|
0x00, 0x26, 0x00, 0x00, 0x81, 0xf3, 0xff, 0x87,
|
||||||
|
0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
isdirect (uint32_t ch)
|
||||||
|
{
|
||||||
|
return (ch < 128 && ((direct_tab[ch >> 3] >> (ch & 7)) & 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The set of "direct and optional direct characters":
|
||||||
|
A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr
|
||||||
|
! " # $ % & * ; < = > @ [ ] ^ _ ` { | }
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const unsigned char xdirect_tab[128/8] =
|
||||||
|
{
|
||||||
|
0x00, 0x26, 0x00, 0x00, 0xff, 0xf7, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x3f
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
isxdirect (uint32_t ch)
|
||||||
|
{
|
||||||
|
return (ch < 128 && ((xdirect_tab[ch >> 3] >> (ch & 7)) & 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The set of "extended base64 characters":
|
||||||
|
A-Z a-z 0-9 + / -
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const unsigned char xbase64_tab[128/8] =
|
||||||
|
{
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xff, 0x03,
|
||||||
|
0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
isxbase64 (uint32_t ch)
|
||||||
|
{
|
||||||
|
return (ch < 128 && ((xbase64_tab[ch >> 3] >> (ch & 7)) & 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Converts a value in the range 0..63 to a base64 encoded char. */
|
||||||
|
static inline unsigned char
|
||||||
|
base64 (unsigned int i)
|
||||||
|
{
|
||||||
|
if (i < 26)
|
||||||
|
return i + 'A';
|
||||||
|
else if (i < 52)
|
||||||
|
return i - 26 + 'a';
|
||||||
|
else if (i < 62)
|
||||||
|
return i - 52 + '0';
|
||||||
|
else if (i == 62)
|
||||||
|
return '+';
|
||||||
|
else if (i == 63)
|
||||||
|
return '/';
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions used in the body of the `gconv' function. */
|
||||||
|
#define CHARSET_NAME "UTF-7//"
|
||||||
|
#define DEFINE_INIT 1
|
||||||
|
#define DEFINE_FINI 1
|
||||||
|
#define FROM_LOOP from_utf7_loop
|
||||||
|
#define TO_LOOP to_utf7_loop
|
||||||
|
#define MIN_NEEDED_FROM 1
|
||||||
|
#define MAX_NEEDED_FROM 6
|
||||||
|
#define MIN_NEEDED_TO 4
|
||||||
|
#define MAX_NEEDED_TO 4
|
||||||
|
#define PREPARE_LOOP \
|
||||||
|
mbstate_t saved_state; \
|
||||||
|
mbstate_t *statep = data->__statep;
|
||||||
|
#define EXTRA_LOOP_ARGS , statep
|
||||||
|
|
||||||
|
|
||||||
|
/* Since we might have to reset input pointer we must be able to save
|
||||||
|
and restore the state. */
|
||||||
|
#define SAVE_RESET_STATE(Save) \
|
||||||
|
if (Save) \
|
||||||
|
saved_state = *statep; \
|
||||||
|
else \
|
||||||
|
*statep = saved_state
|
||||||
|
|
||||||
|
|
||||||
|
/* First define the conversion function from UTF-7 to UCS4.
|
||||||
|
The state is structured as follows:
|
||||||
|
__count bit 2..0: zero
|
||||||
|
__count bit 8..3: shift
|
||||||
|
__wch: data
|
||||||
|
Precise meaning:
|
||||||
|
shift data
|
||||||
|
0 -- not inside base64 encoding
|
||||||
|
1..32 XX..XX00..00 inside base64, (32 - shift) bits pending
|
||||||
|
This state layout is simpler than relying on STORE_REST/UNPACK_BYTES.
|
||||||
|
|
||||||
|
When shift = 0, __wch needs to store at most one lookahead byte (see
|
||||||
|
__GCONV_INCOMPLETE_INPUT below).
|
||||||
|
*/
|
||||||
|
#define MIN_NEEDED_INPUT MIN_NEEDED_FROM
|
||||||
|
#define MAX_NEEDED_INPUT MAX_NEEDED_FROM
|
||||||
|
#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
|
||||||
|
#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO
|
||||||
|
#define LOOPFCT FROM_LOOP
|
||||||
|
#define BODY \
|
||||||
|
{ \
|
||||||
|
uint_fast8_t ch = *inptr; \
|
||||||
|
\
|
||||||
|
if ((statep->__count >> 3) == 0) \
|
||||||
|
{ \
|
||||||
|
/* base64 encoding inactive. */ \
|
||||||
|
if (isxdirect (ch)) \
|
||||||
|
{ \
|
||||||
|
inptr++; \
|
||||||
|
put32 (outptr, ch); \
|
||||||
|
outptr += 4; \
|
||||||
|
} \
|
||||||
|
else if (__builtin_expect (ch == '+', 1)) \
|
||||||
|
{ \
|
||||||
|
if (__builtin_expect (inptr + 2 >= inend, 0)) \
|
||||||
|
{ \
|
||||||
|
/* Not enough input available. */ \
|
||||||
|
result = __GCONV_INCOMPLETE_INPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
if (inptr[1] == '-') \
|
||||||
|
{ \
|
||||||
|
inptr += 2; \
|
||||||
|
put32 (outptr, ch); \
|
||||||
|
outptr += 4; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* Switch into base64 mode. */ \
|
||||||
|
inptr++; \
|
||||||
|
statep->__count = (32 << 3); \
|
||||||
|
statep->__value.__wch = 0; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* The input is invalid. */ \
|
||||||
|
if (! ignore_errors_p ()) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_ILLEGAL_INPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
++inptr; \
|
||||||
|
++*irreversible; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* base64 encoding active. */ \
|
||||||
|
uint32_t i; \
|
||||||
|
int shift; \
|
||||||
|
\
|
||||||
|
if (ch >= 'A' && ch <= 'Z') \
|
||||||
|
i = ch - 'A'; \
|
||||||
|
else if (ch >= 'a' && ch <= 'z') \
|
||||||
|
i = ch - 'a' + 26; \
|
||||||
|
else if (ch >= '0' && ch <= '9') \
|
||||||
|
i = ch - '0' + 52; \
|
||||||
|
else if (ch == '+') \
|
||||||
|
i = 62; \
|
||||||
|
else if (ch == '/') \
|
||||||
|
i = 63; \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* Terminate base64 encoding. */ \
|
||||||
|
\
|
||||||
|
/* If accumulated data is nonzero, the input is invalid. */ \
|
||||||
|
/* Also, partial UTF-16 characters are invalid. */ \
|
||||||
|
if (__builtin_expect (statep->__value.__wch != 0, 0) \
|
||||||
|
|| __builtin_expect ((statep->__count >> 3) <= 26, 0)) \
|
||||||
|
{ \
|
||||||
|
if (! ignore_errors_p ()) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_ILLEGAL_INPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
++inptr; \
|
||||||
|
++*irreversible; \
|
||||||
|
statep->__count = 0; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (ch == '-') \
|
||||||
|
inptr++; \
|
||||||
|
\
|
||||||
|
statep->__count = 0; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Concatenate the base64 integer i to the accumulator. */ \
|
||||||
|
shift = (statep->__count >> 3); \
|
||||||
|
if (shift > 6) \
|
||||||
|
{ \
|
||||||
|
uint32_t wch; \
|
||||||
|
\
|
||||||
|
shift -= 6; \
|
||||||
|
wch = statep->__value.__wch | (i << shift); \
|
||||||
|
\
|
||||||
|
if (shift <= 16 && shift > 10) \
|
||||||
|
{ \
|
||||||
|
/* An UTF-16 character has just been completed. */ \
|
||||||
|
uint32_t wc1 = wch >> 16; \
|
||||||
|
\
|
||||||
|
/* UTF-16: When we see a High Surrogate, we must also decode \
|
||||||
|
the following Low Surrogate. */ \
|
||||||
|
if (!(wc1 >= 0xd800 && wc1 < 0xdc00)) \
|
||||||
|
{ \
|
||||||
|
wch = wch << 16; \
|
||||||
|
shift += 16; \
|
||||||
|
put32 (outptr, wc1); \
|
||||||
|
outptr += 4; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (shift <= 10 && shift > 4) \
|
||||||
|
{ \
|
||||||
|
/* After a High Surrogate, verify that the next 16 bit \
|
||||||
|
indeed form a Low Surrogate. */ \
|
||||||
|
uint32_t wc2 = wch & 0xffff; \
|
||||||
|
\
|
||||||
|
if (! __builtin_expect (wc2 >= 0xdc00 && wc2 < 0xe000, 1)) \
|
||||||
|
{ \
|
||||||
|
if (! ignore_errors_p ()) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_ILLEGAL_INPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
++inptr; \
|
||||||
|
++*irreversible; \
|
||||||
|
statep->__count = 0; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
statep->__value.__wch = wch; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* An UTF-16 surrogate pair has just been completed. */ \
|
||||||
|
uint32_t wc1 = (uint32_t) statep->__value.__wch >> 16; \
|
||||||
|
uint32_t wc2 = ((uint32_t) statep->__value.__wch & 0xffff) \
|
||||||
|
| (i >> (6 - shift)); \
|
||||||
|
\
|
||||||
|
statep->__value.__wch = (i << shift) << 26; \
|
||||||
|
shift += 26; \
|
||||||
|
\
|
||||||
|
assert (wc1 >= 0xd800 && wc1 < 0xdc00); \
|
||||||
|
assert (wc2 >= 0xdc00 && wc2 < 0xe000); \
|
||||||
|
put32 (outptr, \
|
||||||
|
0x10000 + ((wc1 - 0xd800) << 10) + (wc2 - 0xdc00)); \
|
||||||
|
outptr += 4; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
statep->__count = shift << 3; \
|
||||||
|
\
|
||||||
|
/* Now that we digested the input increment the input pointer. */ \
|
||||||
|
inptr++; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#define LOOP_NEED_FLAGS
|
||||||
|
#define EXTRA_LOOP_DECLS , mbstate_t *statep
|
||||||
|
#include <iconv/loop.c>
|
||||||
|
|
||||||
|
|
||||||
|
/* Next, define the conversion from UCS4 to UTF-7.
|
||||||
|
The state is structured as follows:
|
||||||
|
__count bit 2..0: zero
|
||||||
|
__count bit 4..3: shift
|
||||||
|
__count bit 8..5: data
|
||||||
|
Precise meaning:
|
||||||
|
shift data
|
||||||
|
0 0 not inside base64 encoding
|
||||||
|
1 0 inside base64, no pending bits
|
||||||
|
2 XX00 inside base64, 2 bits known for next byte
|
||||||
|
3 XXXX inside base64, 4 bits known for next byte
|
||||||
|
|
||||||
|
__count bit 2..0 and __wch are always zero, because this direction
|
||||||
|
never returns __GCONV_INCOMPLETE_INPUT.
|
||||||
|
*/
|
||||||
|
#define MIN_NEEDED_INPUT MIN_NEEDED_TO
|
||||||
|
#define MAX_NEEDED_INPUT MAX_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 = get32 (inptr); \
|
||||||
|
\
|
||||||
|
if ((statep->__count & 0x18) == 0) \
|
||||||
|
{ \
|
||||||
|
/* base64 encoding inactive */ \
|
||||||
|
if (UTF7_ENCODE_OPTIONAL_CHARS ? isdirect (ch) : isxdirect (ch)) \
|
||||||
|
{ \
|
||||||
|
*outptr++ = (unsigned char) ch; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
size_t count; \
|
||||||
|
\
|
||||||
|
if (ch == '+') \
|
||||||
|
count = 2; \
|
||||||
|
else if (ch < 0x10000) \
|
||||||
|
count = 3; \
|
||||||
|
else if (ch < 0x110000) \
|
||||||
|
count = 6; \
|
||||||
|
else \
|
||||||
|
STANDARD_ERR_HANDLER (4); \
|
||||||
|
\
|
||||||
|
if (__builtin_expect (outptr + count > outend, 0)) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_FULL_OUTPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
*outptr++ = '+'; \
|
||||||
|
if (ch == '+') \
|
||||||
|
*outptr++ = '-'; \
|
||||||
|
else if (ch < 0x10000) \
|
||||||
|
{ \
|
||||||
|
*outptr++ = base64 (ch >> 10); \
|
||||||
|
*outptr++ = base64 ((ch >> 4) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 15) << 5) | (3 << 3); \
|
||||||
|
} \
|
||||||
|
else if (ch < 0x110000) \
|
||||||
|
{ \
|
||||||
|
uint32_t ch1 = 0xd800 + ((ch - 0x10000) >> 10); \
|
||||||
|
uint32_t ch2 = 0xdc00 + ((ch - 0x10000) & 0x3ff); \
|
||||||
|
\
|
||||||
|
ch = (ch1 << 16) | ch2; \
|
||||||
|
*outptr++ = base64 (ch >> 26); \
|
||||||
|
*outptr++ = base64 ((ch >> 20) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 14) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 8) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 2) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 3) << 7) | (2 << 3); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
abort (); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* base64 encoding active */ \
|
||||||
|
if (UTF7_ENCODE_OPTIONAL_CHARS ? isdirect (ch) : isxdirect (ch)) \
|
||||||
|
{ \
|
||||||
|
/* deactivate base64 encoding */ \
|
||||||
|
size_t count; \
|
||||||
|
\
|
||||||
|
count = ((statep->__count & 0x18) >= 0x10) + isxbase64 (ch) + 1; \
|
||||||
|
if (__builtin_expect (outptr + count > outend, 0)) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_FULL_OUTPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if ((statep->__count & 0x18) >= 0x10) \
|
||||||
|
*outptr++ = base64 ((statep->__count >> 3) & ~3); \
|
||||||
|
if (isxbase64 (ch)) \
|
||||||
|
*outptr++ = '-'; \
|
||||||
|
*outptr++ = (unsigned char) ch; \
|
||||||
|
statep->__count = 0; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
size_t count; \
|
||||||
|
\
|
||||||
|
if (ch < 0x10000) \
|
||||||
|
count = ((statep->__count & 0x18) >= 0x10 ? 3 : 2); \
|
||||||
|
else if (ch < 0x110000) \
|
||||||
|
count = ((statep->__count & 0x18) >= 0x18 ? 6 : 5); \
|
||||||
|
else \
|
||||||
|
STANDARD_ERR_HANDLER (4); \
|
||||||
|
\
|
||||||
|
if (__builtin_expect (outptr + count > outend, 0)) \
|
||||||
|
{ \
|
||||||
|
result = __GCONV_FULL_OUTPUT; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (ch < 0x10000) \
|
||||||
|
{ \
|
||||||
|
switch ((statep->__count >> 3) & 3) \
|
||||||
|
{ \
|
||||||
|
case 1: \
|
||||||
|
*outptr++ = base64 (ch >> 10); \
|
||||||
|
*outptr++ = base64 ((ch >> 4) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 15) << 5) | (3 << 3); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*outptr++ = \
|
||||||
|
base64 (((statep->__count >> 3) & ~3) | (ch >> 12)); \
|
||||||
|
*outptr++ = base64 ((ch >> 6) & 0x3f); \
|
||||||
|
*outptr++ = base64 (ch & 0x3f); \
|
||||||
|
statep->__count = (1 << 3); \
|
||||||
|
break; \
|
||||||
|
case 3: \
|
||||||
|
*outptr++ = \
|
||||||
|
base64 (((statep->__count >> 3) & ~3) | (ch >> 14)); \
|
||||||
|
*outptr++ = base64 ((ch >> 8) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 2) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 3) << 7) | (2 << 3); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
abort (); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (ch < 0x110000) \
|
||||||
|
{ \
|
||||||
|
uint32_t ch1 = 0xd800 + ((ch - 0x10000) >> 10); \
|
||||||
|
uint32_t ch2 = 0xdc00 + ((ch - 0x10000) & 0x3ff); \
|
||||||
|
\
|
||||||
|
ch = (ch1 << 16) | ch2; \
|
||||||
|
switch ((statep->__count >> 3) & 3) \
|
||||||
|
{ \
|
||||||
|
case 1: \
|
||||||
|
*outptr++ = base64 (ch >> 26); \
|
||||||
|
*outptr++ = base64 ((ch >> 20) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 14) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 8) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 2) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 3) << 7) | (2 << 3); \
|
||||||
|
break; \
|
||||||
|
case 2: \
|
||||||
|
*outptr++ = \
|
||||||
|
base64 (((statep->__count >> 3) & ~3) | (ch >> 28)); \
|
||||||
|
*outptr++ = base64 ((ch >> 22) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 16) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 10) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 4) & 0x3f); \
|
||||||
|
statep->__count = ((ch & 15) << 5) | (3 << 3); \
|
||||||
|
break; \
|
||||||
|
case 3: \
|
||||||
|
*outptr++ = \
|
||||||
|
base64 (((statep->__count >> 3) & ~3) | (ch >> 30)); \
|
||||||
|
*outptr++ = base64 ((ch >> 24) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 18) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 12) & 0x3f); \
|
||||||
|
*outptr++ = base64 ((ch >> 6) & 0x3f); \
|
||||||
|
*outptr++ = base64 (ch & 0x3f); \
|
||||||
|
statep->__count = (1 << 3); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
abort (); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
abort (); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Now that we wrote the output increment the input pointer. */ \
|
||||||
|
inptr += 4; \
|
||||||
|
}
|
||||||
|
#define LOOP_NEED_FLAGS
|
||||||
|
#define EXTRA_LOOP_DECLS , mbstate_t *statep
|
||||||
|
#include <iconv/loop.c>
|
||||||
|
|
||||||
|
|
||||||
|
/* Since this is a stateful encoding we have to provide code which resets
|
||||||
|
the output state to the initial state. This has to be done during the
|
||||||
|
flushing. */
|
||||||
|
#define EMIT_SHIFT_TO_INIT \
|
||||||
|
if (FROM_DIRECTION) \
|
||||||
|
/* Nothing to emit. */ \
|
||||||
|
memset (data->__statep, '\0', sizeof (mbstate_t)); \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* The "to UTF-7" direction. Flush the remaining bits and terminate \
|
||||||
|
with a '-' byte. This will guarantee correct decoding if more \
|
||||||
|
UTF-7 encoded text is added afterwards. */ \
|
||||||
|
int state = data->__statep->__count; \
|
||||||
|
\
|
||||||
|
if (state & 0x18) \
|
||||||
|
{ \
|
||||||
|
/* Deactivate base64 encoding. */ \
|
||||||
|
unsigned char *outbuf = data->__outbuf; \
|
||||||
|
size_t count = ((state & 0x18) >= 0x10) + 1; \
|
||||||
|
\
|
||||||
|
if (__builtin_expect (outbuf + count > data->__outbufend, 0)) \
|
||||||
|
/* We don't have enough room in the output buffer. */ \
|
||||||
|
status = __GCONV_FULL_OUTPUT; \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
/* Write out the shift sequence. */ \
|
||||||
|
if ((state & 0x18) >= 0x10) \
|
||||||
|
*outbuf++ = base64 ((state >> 3) & ~3); \
|
||||||
|
*outbuf++ = '-'; \
|
||||||
|
\
|
||||||
|
data->__outbuf = outbuf; \
|
||||||
|
data->__statep->__count = 0; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
data->__statep->__count = 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now define the toplevel functions. */
|
||||||
|
#include <iconv/skeleton.c>
|
@@ -65,7 +65,9 @@ struct element_t;
|
|||||||
/* Data type for list of strings. */
|
/* Data type for list of strings. */
|
||||||
struct section_list
|
struct section_list
|
||||||
{
|
{
|
||||||
|
/* Successor in the known_sections list. */
|
||||||
struct section_list *def_next;
|
struct section_list *def_next;
|
||||||
|
/* Successor in the sections list. */
|
||||||
struct section_list *next;
|
struct section_list *next;
|
||||||
/* Name of the section. */
|
/* Name of the section. */
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -291,6 +293,7 @@ make_seclist_elem (struct locale_collate_t *collate, const char *string,
|
|||||||
newp->next = next;
|
newp->next = next;
|
||||||
newp->name = string;
|
newp->name = string;
|
||||||
newp->first = NULL;
|
newp->first = NULL;
|
||||||
|
newp->last = NULL;
|
||||||
|
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
@@ -336,6 +339,10 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
|
|||||||
newp->used_in_level = 0;
|
newp->used_in_level = 0;
|
||||||
newp->is_character = is_character;
|
newp->is_character = is_character;
|
||||||
|
|
||||||
|
/* Will be assigned later. XXX */
|
||||||
|
newp->mbseqorder = 0;
|
||||||
|
newp->wcseqorder = 0;
|
||||||
|
|
||||||
/* Will be allocated later. */
|
/* Will be allocated later. */
|
||||||
newp->weights = NULL;
|
newp->weights = NULL;
|
||||||
|
|
||||||
@@ -350,6 +357,9 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
|
|||||||
newp->mbnext = NULL;
|
newp->mbnext = NULL;
|
||||||
newp->mblast = NULL;
|
newp->mblast = NULL;
|
||||||
|
|
||||||
|
newp->wcnext = NULL;
|
||||||
|
newp->wclast = NULL;
|
||||||
|
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +629,6 @@ find_element (struct linereader *ldfile, struct locale_collate_t *collate,
|
|||||||
/* It's also no collation element. So it is a character
|
/* It's also no collation element. So it is a character
|
||||||
element defined later. */
|
element defined later. */
|
||||||
result = new_element (collate, NULL, 0, NULL, str, len, 1);
|
result = new_element (collate, NULL, 0, NULL, str, len, 1);
|
||||||
if (result != NULL)
|
|
||||||
/* Insert it into the sequence table. */
|
/* Insert it into the sequence table. */
|
||||||
insert_entry (&collate->seq_table, str, len, result);
|
insert_entry (&collate->seq_table, str, len, result);
|
||||||
}
|
}
|
||||||
@@ -660,11 +669,11 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
|
|||||||
/* Initialize all the fields. */
|
/* Initialize all the fields. */
|
||||||
elem->file = ldfile->fname;
|
elem->file = ldfile->fname;
|
||||||
elem->line = ldfile->lineno;
|
elem->line = ldfile->lineno;
|
||||||
|
|
||||||
elem->last = collate->cursor;
|
elem->last = collate->cursor;
|
||||||
elem->next = collate->cursor ? collate->cursor->next : NULL;
|
elem->next = collate->cursor ? collate->cursor->next : NULL;
|
||||||
if (collate->cursor != NULL && collate->cursor->next != NULL)
|
if (collate->cursor != NULL && collate->cursor->next != NULL)
|
||||||
collate->cursor->next->last = elem;
|
collate->cursor->next->last = elem;
|
||||||
elem->section = collate->current_section;
|
|
||||||
if (collate->cursor != NULL)
|
if (collate->cursor != NULL)
|
||||||
collate->cursor->next = elem;
|
collate->cursor->next = elem;
|
||||||
if (collate->start == NULL)
|
if (collate->start == NULL)
|
||||||
@@ -672,9 +681,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
|
|||||||
assert (collate->cursor == NULL);
|
assert (collate->cursor == NULL);
|
||||||
collate->start = elem;
|
collate->start = elem;
|
||||||
}
|
}
|
||||||
elem->weights = (struct element_list_t *)
|
|
||||||
obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
|
elem->section = collate->current_section;
|
||||||
memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
|
|
||||||
|
|
||||||
if (collate->current_section->first == NULL)
|
if (collate->current_section->first == NULL)
|
||||||
collate->current_section->first = elem;
|
collate->current_section->first = elem;
|
||||||
@@ -683,6 +691,10 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
|
|||||||
|
|
||||||
collate->cursor = elem;
|
collate->cursor = elem;
|
||||||
|
|
||||||
|
elem->weights = (struct element_list_t *)
|
||||||
|
obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
|
||||||
|
memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
|
||||||
|
|
||||||
weight_cnt = 0;
|
weight_cnt = 0;
|
||||||
|
|
||||||
arg = lr_token (ldfile, charmap, repertoire);
|
arg = lr_token (ldfile, charmap, repertoire);
|
||||||
@@ -839,8 +851,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
|
|||||||
%s: weights must use the same ellipsis symbol as the name"),
|
%s: weights must use the same ellipsis symbol as the name"),
|
||||||
"LC_COLLATE");
|
"LC_COLLATE");
|
||||||
|
|
||||||
/* The weight for this level has to be ignored. We use the
|
/* The weight for this level will depend on the element
|
||||||
null pointer to indicate this. */
|
iterating over the range. Put a placeholder. */
|
||||||
elem->weights[weight_cnt].w = (struct element_t **)
|
elem->weights[weight_cnt].w = (struct element_t **)
|
||||||
obstack_alloc (&collate->mempool, sizeof (struct element_t *));
|
obstack_alloc (&collate->mempool, sizeof (struct element_t *));
|
||||||
elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
|
elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
|
||||||
@@ -988,8 +1000,7 @@ insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Test whether this element is not already in the list. */
|
/* Test whether this element is not already in the list. */
|
||||||
if (elem->next != NULL || (collate->cursor != NULL
|
if (elem->next != NULL || elem == collate->cursor)
|
||||||
&& elem->next == collate->cursor))
|
|
||||||
{
|
{
|
||||||
lr_error (ldfile, _("order for `%.*s' already defined at %s:%Zu"),
|
lr_error (ldfile, _("order for `%.*s' already defined at %s:%Zu"),
|
||||||
(int) symlen, symstr, elem->file, elem->line);
|
(int) symlen, symstr, elem->file, elem->line);
|
||||||
@@ -1434,6 +1445,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
|
|||||||
collate->col_weight_max = -1;
|
collate->col_weight_max = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
/* Reuse the copy_locale's data structures. */
|
||||||
collate = locale->categories[LC_COLLATE].collate =
|
collate = locale->categories[LC_COLLATE].collate =
|
||||||
copy_locale->categories[LC_COLLATE].collate;
|
copy_locale->categories[LC_COLLATE].collate;
|
||||||
}
|
}
|
||||||
@@ -1788,9 +1800,9 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
|
|||||||
while (sect != NULL && sect->rules == NULL);
|
while (sect != NULL && sect->rules == NULL);
|
||||||
}
|
}
|
||||||
while (sect != NULL);
|
while (sect != NULL);
|
||||||
/* We are currently not prepared for more than 256 rulesets. But this
|
/* We are currently not prepared for more than 128 rulesets. But this
|
||||||
should never really be a problem. */
|
should never really be a problem. */
|
||||||
assert (ruleidx <= 256);
|
assert (ruleidx <= 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2529,9 +2541,18 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
|
|||||||
struct token *now;
|
struct token *now;
|
||||||
struct token *arg = NULL;
|
struct token *arg = NULL;
|
||||||
enum token_t nowtok;
|
enum token_t nowtok;
|
||||||
int state = 0;
|
|
||||||
enum token_t was_ellipsis = tok_none;
|
enum token_t was_ellipsis = tok_none;
|
||||||
struct localedef_t *copy_locale = NULL;
|
struct localedef_t *copy_locale = NULL;
|
||||||
|
/* Parsing state:
|
||||||
|
0 - start
|
||||||
|
1 - between `order-start' and `order-end'
|
||||||
|
2 - after `order-end'
|
||||||
|
3 - after `reorder-after', waiting for `reorder-end'
|
||||||
|
4 - after `reorder-end'
|
||||||
|
5 - after `reorder-sections-after', waiting for `reorder-sections-end'
|
||||||
|
6 - after `reorder-sections-end'
|
||||||
|
*/
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
/* Get the repertoire we have to use. */
|
/* Get the repertoire we have to use. */
|
||||||
if (repertoire_name != NULL)
|
if (repertoire_name != NULL)
|
||||||
@@ -2828,9 +2849,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
|
|||||||
}
|
}
|
||||||
else if (ellipsis == tok_none)
|
else if (ellipsis == tok_none)
|
||||||
{
|
{
|
||||||
/* The name is already defined. */
|
/* A single symbol, no ellipsis. */
|
||||||
if (check_duplicate (ldfile, collate, charmap,
|
if (check_duplicate (ldfile, collate, charmap,
|
||||||
repertoire, symbol, symbol_len))
|
repertoire, symbol, symbol_len))
|
||||||
|
/* The name is already defined. */
|
||||||
goto col_sym_free;
|
goto col_sym_free;
|
||||||
|
|
||||||
insert_entry (&collate->sym_table, symbol, symbol_len,
|
insert_entry (&collate->sym_table, symbol, symbol_len,
|
||||||
@@ -2884,13 +2906,13 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
|
|||||||
/* Create the name. */
|
/* Create the name. */
|
||||||
sprintf (symbuf,
|
sprintf (symbuf,
|
||||||
ellipsis == tok_ellipsis2
|
ellipsis == tok_ellipsis2
|
||||||
? "%.*s%.*lX" : "%.*s%.*lX",
|
? "%.*s%.*lX" : "%.*s%.*lu",
|
||||||
(int) prefixlen, symbol,
|
(int) prefixlen, symbol,
|
||||||
(int) (symbol_len - prefixlen), from);
|
(int) (symbol_len - prefixlen), from);
|
||||||
|
|
||||||
/* The name is already defined. */
|
|
||||||
if (check_duplicate (ldfile, collate, charmap,
|
if (check_duplicate (ldfile, collate, charmap,
|
||||||
repertoire, symbuf, symbol_len))
|
repertoire, symbuf, symbol_len))
|
||||||
|
/* The name is already defined. */
|
||||||
goto col_sym_free;
|
goto col_sym_free;
|
||||||
|
|
||||||
insert_entry (&collate->sym_table, symbuf,
|
insert_entry (&collate->sym_table, symbuf,
|
||||||
@@ -3021,8 +3043,8 @@ error while adding equivalent collating symbol"));
|
|||||||
}
|
}
|
||||||
|
|
||||||
runp = (struct section_list *) xcalloc (1, sizeof (*runp));
|
runp = (struct section_list *) xcalloc (1, sizeof (*runp));
|
||||||
name = strncpy (xmalloc (arg->val.str.lenmb + 1),
|
name = (char *) xmalloc (arg->val.str.lenmb + 1);
|
||||||
arg->val.str.startmb, arg->val.str.lenmb);
|
memcpy (name, arg->val.str.startmb, arg->val.str.lenmb);
|
||||||
name[arg->val.str.lenmb] = '\0';
|
name[arg->val.str.lenmb] = '\0';
|
||||||
runp->name = name;
|
runp->name = name;
|
||||||
|
|
||||||
@@ -3070,6 +3092,8 @@ error while adding equivalent collating symbol"));
|
|||||||
|
|
||||||
if (collate->error_section.first == NULL)
|
if (collate->error_section.first == NULL)
|
||||||
{
|
{
|
||||||
|
/* Insert &collate->error_section at the end of
|
||||||
|
the collate->sections list. */
|
||||||
if (collate->sections == NULL)
|
if (collate->sections == NULL)
|
||||||
collate->sections = &collate->error_section;
|
collate->sections = &collate->error_section;
|
||||||
else
|
else
|
||||||
@@ -3078,9 +3102,9 @@ error while adding equivalent collating symbol"));
|
|||||||
while (sp->next != NULL)
|
while (sp->next != NULL)
|
||||||
sp = sp->next;
|
sp = sp->next;
|
||||||
|
|
||||||
collate->error_section.next = NULL;
|
|
||||||
sp->next = &collate->error_section;
|
sp->next = &collate->error_section;
|
||||||
}
|
}
|
||||||
|
collate->error_section.next = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3093,6 +3117,8 @@ error while adding equivalent collating symbol"));
|
|||||||
"LC_COLLATE", sp->name);
|
"LC_COLLATE", sp->name);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Insert sp in the collate->sections list,
|
||||||
|
right after collate->current_section. */
|
||||||
if (collate->current_section == NULL)
|
if (collate->current_section == NULL)
|
||||||
collate->current_section = sp;
|
collate->current_section = sp;
|
||||||
else
|
else
|
||||||
@@ -3141,6 +3167,8 @@ error while adding equivalent collating symbol"));
|
|||||||
"LC_COLLATE");
|
"LC_COLLATE");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Insert &collate->unnamed_section at the beginning of
|
||||||
|
the collate->sections list. */
|
||||||
collate->unnamed_section.next = collate->sections;
|
collate->unnamed_section.next = collate->sections;
|
||||||
collate->sections = &collate->unnamed_section;
|
collate->sections = &collate->unnamed_section;
|
||||||
}
|
}
|
||||||
@@ -3149,7 +3177,7 @@ error while adding equivalent collating symbol"));
|
|||||||
/* Now read the direction names. */
|
/* Now read the direction names. */
|
||||||
read_directions (ldfile, arg, charmap, repertoire, collate);
|
read_directions (ldfile, arg, charmap, repertoire, collate);
|
||||||
|
|
||||||
/* From now be need the strings untranslated. */
|
/* From now we need the strings untranslated. */
|
||||||
ldfile->translate_strings = 0;
|
ldfile->translate_strings = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -3428,7 +3456,7 @@ error while adding equivalent collating symbol"));
|
|||||||
/* We are outside an `order_start' region. This means
|
/* We are outside an `order_start' region. This means
|
||||||
we must only accept definitions of values for
|
we must only accept definitions of values for
|
||||||
collation symbols since these are purely abstract
|
collation symbols since these are purely abstract
|
||||||
values and don't need dorections associated. */
|
values and don't need directions associated. */
|
||||||
struct element_t *seqp;
|
struct element_t *seqp;
|
||||||
|
|
||||||
if (find_entry (&collate->seq_table, symstr, symlen,
|
if (find_entry (&collate->seq_table, symstr, symlen,
|
||||||
@@ -3510,7 +3538,7 @@ error while adding equivalent collating symbol"));
|
|||||||
if (seqp->section->first == seqp)
|
if (seqp->section->first == seqp)
|
||||||
{
|
{
|
||||||
if (seqp->section->first == seqp->section->last)
|
if (seqp->section->first == seqp->section->last)
|
||||||
/* This setion has no content anymore. */
|
/* This section has no content anymore. */
|
||||||
seqp->section->first = seqp->section->last = NULL;
|
seqp->section->first = seqp->section->last = NULL;
|
||||||
else
|
else
|
||||||
seqp->section->first = seqp->next;
|
seqp->section->first = seqp->next;
|
||||||
@@ -3616,8 +3644,7 @@ error while adding equivalent collating symbol"));
|
|||||||
|
|
||||||
/* See whether UNDEFINED already appeared somewhere. */
|
/* See whether UNDEFINED already appeared somewhere. */
|
||||||
if (collate->undefined.next != NULL
|
if (collate->undefined.next != NULL
|
||||||
|| (collate->cursor != NULL
|
|| &collate->undefined == collate->cursor)
|
||||||
&& collate->undefined.next == collate->cursor))
|
|
||||||
{
|
{
|
||||||
lr_error (ldfile,
|
lr_error (ldfile,
|
||||||
_("%s: order for `%.*s' already defined at %s:%Zu"),
|
_("%s: order for `%.*s' already defined at %s:%Zu"),
|
||||||
@@ -3632,9 +3659,9 @@ error while adding equivalent collating symbol"));
|
|||||||
repertoire, collate, tok_none);
|
repertoire, collate, tok_none);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tok_ellipsis2:
|
case tok_ellipsis2: /* symbolic hexadecimal ellipsis */
|
||||||
case tok_ellipsis3:
|
case tok_ellipsis3: /* absolute ellipsis */
|
||||||
case tok_ellipsis4:
|
case tok_ellipsis4: /* symbolic decimal ellipsis */
|
||||||
/* This is the symbolic (decimal or hexadecimal) or absolute
|
/* This is the symbolic (decimal or hexadecimal) or absolute
|
||||||
ellipsis. */
|
ellipsis. */
|
||||||
if (was_ellipsis != tok_none)
|
if (was_ellipsis != tok_none)
|
||||||
|
Reference in New Issue
Block a user