Blame nkf.c

Packit 5b6b86
/*
Packit 5b6b86
 * Copyright (c) 1987, Fujitsu LTD. (Itaru ICHIKAWA).
Packit 5b6b86
 * Copyright (c) 1996-2013, The nkf Project.
Packit 5b6b86
 *
Packit 5b6b86
 * This software is provided 'as-is', without any express or implied
Packit 5b6b86
 * warranty. In no event will the authors be held liable for any damages
Packit 5b6b86
 * arising from the use of this software.
Packit 5b6b86
 *
Packit 5b6b86
 * Permission is granted to anyone to use this software for any purpose,
Packit 5b6b86
 * including commercial applications, and to alter it and redistribute it
Packit 5b6b86
 * freely, subject to the following restrictions:
Packit 5b6b86
 *
Packit 5b6b86
 * 1. The origin of this software must not be misrepresented; you must not
Packit 5b6b86
 * claim that you wrote the original software. If you use this software
Packit 5b6b86
 * in a product, an acknowledgment in the product documentation would be
Packit 5b6b86
 * appreciated but is not required.
Packit 5b6b86
 *
Packit 5b6b86
 * 2. Altered source versions must be plainly marked as such, and must not be
Packit 5b6b86
 * misrepresented as being the original software.
Packit 5b6b86
 *
Packit 5b6b86
 * 3. This notice may not be removed or altered from any source distribution.
Packit 5b6b86
 */
Packit 5b6b86
#define NKF_VERSION "2.1.4"
Packit 5b6b86
#define NKF_RELEASE_DATE "2015-12-12"
Packit 5b6b86
#define COPY_RIGHT \
Packit 5b6b86
    "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).\n" \
Packit 5b6b86
    "Copyright (C) 1996-2015, The nkf Project."
Packit 5b6b86
Packit 5b6b86
#include "config.h"
Packit 5b6b86
#include "nkf.h"
Packit 5b6b86
#include "utf8tbl.h"
Packit 5b6b86
#ifdef __WIN32__
Packit 5b6b86
#include <windows.h>
Packit 5b6b86
#include <locale.h>
Packit 5b6b86
#endif
Packit 5b6b86
#if defined(__OS2__)
Packit 5b6b86
# define INCL_DOS
Packit 5b6b86
# define INCL_DOSERRORS
Packit 5b6b86
# include <os2.h>
Packit 5b6b86
#endif
Packit 5b6b86
#include <assert.h>
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
/* state of output_mode and input_mode
Packit 5b6b86
Packit 5b6b86
   c2           0 means ASCII
Packit 5b6b86
   JIS_X_0201_1976_K
Packit 5b6b86
   ISO_8859_1
Packit 5b6b86
   JIS_X_0208
Packit 5b6b86
   EOF      all termination
Packit 5b6b86
   c1           32bit data
Packit 5b6b86
Packit 5b6b86
 */
Packit 5b6b86
Packit 5b6b86
/* MIME ENCODE */
Packit 5b6b86
Packit 5b6b86
#define         FIXED_MIME      7
Packit 5b6b86
#define         STRICT_MIME     8
Packit 5b6b86
Packit 5b6b86
/* byte order */
Packit 5b6b86
enum byte_order {
Packit 5b6b86
    ENDIAN_BIG    = 1,
Packit 5b6b86
    ENDIAN_LITTLE = 2,
Packit 5b6b86
    ENDIAN_2143   = 3,
Packit 5b6b86
    ENDIAN_3412   = 4
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
/* ASCII CODE */
Packit 5b6b86
Packit 5b6b86
#define         BS      0x08
Packit 5b6b86
#define         TAB     0x09
Packit 5b6b86
#define         LF      0x0a
Packit 5b6b86
#define         CR      0x0d
Packit 5b6b86
#define         ESC     0x1b
Packit 5b6b86
#define         SP      0x20
Packit 5b6b86
#define         DEL     0x7f
Packit 5b6b86
#define         SI      0x0f
Packit 5b6b86
#define         SO      0x0e
Packit 5b6b86
#define         SS2     0x8e
Packit 5b6b86
#define         SS3     0x8f
Packit 5b6b86
#define         CRLF    0x0D0A
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
/* encodings */
Packit 5b6b86
Packit 5b6b86
enum nkf_encodings {
Packit 5b6b86
    ASCII,
Packit 5b6b86
    ISO_8859_1,
Packit 5b6b86
    ISO_2022_JP,
Packit 5b6b86
    CP50220,
Packit 5b6b86
    CP50221,
Packit 5b6b86
    CP50222,
Packit 5b6b86
    ISO_2022_JP_1,
Packit 5b6b86
    ISO_2022_JP_3,
Packit 5b6b86
    ISO_2022_JP_2004,
Packit 5b6b86
    SHIFT_JIS,
Packit 5b6b86
    WINDOWS_31J,
Packit 5b6b86
    CP10001,
Packit 5b6b86
    EUC_JP,
Packit 5b6b86
    EUCJP_NKF,
Packit 5b6b86
    CP51932,
Packit 5b6b86
    EUCJP_MS,
Packit 5b6b86
    EUCJP_ASCII,
Packit 5b6b86
    SHIFT_JISX0213,
Packit 5b6b86
    SHIFT_JIS_2004,
Packit 5b6b86
    EUC_JISX0213,
Packit 5b6b86
    EUC_JIS_2004,
Packit 5b6b86
    UTF_8,
Packit 5b6b86
    UTF_8N,
Packit 5b6b86
    UTF_8_BOM,
Packit 5b6b86
    UTF8_MAC,
Packit 5b6b86
    UTF_16,
Packit 5b6b86
    UTF_16BE,
Packit 5b6b86
    UTF_16BE_BOM,
Packit 5b6b86
    UTF_16LE,
Packit 5b6b86
    UTF_16LE_BOM,
Packit 5b6b86
    UTF_32,
Packit 5b6b86
    UTF_32BE,
Packit 5b6b86
    UTF_32BE_BOM,
Packit 5b6b86
    UTF_32LE,
Packit 5b6b86
    UTF_32LE_BOM,
Packit 5b6b86
    BINARY,
Packit 5b6b86
    NKF_ENCODING_TABLE_SIZE,
Packit 5b6b86
    JIS_X_0201_1976_K = 0x1013, /* I */ /* JIS C 6220-1969 */
Packit 5b6b86
    /* JIS_X_0201_1976_R = 0x1014, */ /* J */ /* JIS C 6220-1969 */
Packit 5b6b86
    /* JIS_X_0208_1978   = 0x1040, */ /* @ */ /* JIS C 6226-1978 */
Packit 5b6b86
    /* JIS_X_0208_1983   = 0x1087, */ /* B */ /* JIS C 6226-1983 */
Packit 5b6b86
    JIS_X_0208        = 0x1168, /* @B */
Packit 5b6b86
    JIS_X_0212        = 0x1159, /* D */
Packit 5b6b86
    /* JIS_X_0213_2000_1 = 0x1228, */ /* O */
Packit 5b6b86
    JIS_X_0213_2 = 0x1229, /* P */
Packit 5b6b86
    JIS_X_0213_1 = 0x1233 /* Q */
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static nkf_char s_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
static nkf_char e_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
static nkf_char w_iconv(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
static nkf_char w_iconv16(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
static nkf_char w_iconv32(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
static void j_oconv(nkf_char c2, nkf_char c1);
Packit 5b6b86
static void s_oconv(nkf_char c2, nkf_char c1);
Packit 5b6b86
static void e_oconv(nkf_char c2, nkf_char c1);
Packit 5b6b86
static void w_oconv(nkf_char c2, nkf_char c1);
Packit 5b6b86
static void w_oconv16(nkf_char c2, nkf_char c1);
Packit 5b6b86
static void w_oconv32(nkf_char c2, nkf_char c1);
Packit 5b6b86
Packit 5b6b86
typedef struct {
Packit 5b6b86
    const char *name;
Packit 5b6b86
    nkf_char (*iconv)(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
    void (*oconv)(nkf_char c2, nkf_char c1);
Packit 5b6b86
} nkf_native_encoding;
Packit 5b6b86
Packit 5b6b86
nkf_native_encoding NkfEncodingASCII =		{ "ASCII", e_iconv, e_oconv };
Packit 5b6b86
nkf_native_encoding NkfEncodingISO_2022_JP =	{ "ISO-2022-JP", e_iconv, j_oconv };
Packit 5b6b86
nkf_native_encoding NkfEncodingShift_JIS =	{ "Shift_JIS", s_iconv, s_oconv };
Packit 5b6b86
nkf_native_encoding NkfEncodingEUC_JP =		{ "EUC-JP", e_iconv, e_oconv };
Packit 5b6b86
nkf_native_encoding NkfEncodingUTF_8 =		{ "UTF-8", w_iconv, w_oconv };
Packit 5b6b86
nkf_native_encoding NkfEncodingUTF_16 =		{ "UTF-16", w_iconv16, w_oconv16 };
Packit 5b6b86
nkf_native_encoding NkfEncodingUTF_32 =		{ "UTF-32", w_iconv32, w_oconv32 };
Packit 5b6b86
Packit 5b6b86
typedef struct {
Packit 5b6b86
    const int id;
Packit 5b6b86
    const char *name;
Packit 5b6b86
    const nkf_native_encoding *base_encoding;
Packit 5b6b86
} nkf_encoding;
Packit 5b6b86
Packit 5b6b86
nkf_encoding nkf_encoding_table[] = {
Packit 5b6b86
    {ASCII,		"US-ASCII",		&NkfEncodingASCII},
Packit 5b6b86
    {ISO_8859_1,	"ISO-8859-1",		&NkfEncodingASCII},
Packit 5b6b86
    {ISO_2022_JP,	"ISO-2022-JP",		&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {CP50220,		"CP50220",		&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {CP50221,		"CP50221",		&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {CP50222,		"CP50222",		&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {ISO_2022_JP_1,	"ISO-2022-JP-1",	&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {ISO_2022_JP_3,	"ISO-2022-JP-3",	&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {ISO_2022_JP_2004,	"ISO-2022-JP-2004",	&NkfEncodingISO_2022_JP},
Packit 5b6b86
    {SHIFT_JIS,		"Shift_JIS",		&NkfEncodingShift_JIS},
Packit 5b6b86
    {WINDOWS_31J,	"Windows-31J",		&NkfEncodingShift_JIS},
Packit 5b6b86
    {CP10001,		"CP10001",		&NkfEncodingShift_JIS},
Packit 5b6b86
    {EUC_JP,		"EUC-JP",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {EUCJP_NKF,		"eucJP-nkf",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {CP51932,		"CP51932",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {EUCJP_MS,		"eucJP-MS",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {EUCJP_ASCII,	"eucJP-ASCII",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {SHIFT_JISX0213,	"Shift_JISX0213",	&NkfEncodingShift_JIS},
Packit 5b6b86
    {SHIFT_JIS_2004,	"Shift_JIS-2004",	&NkfEncodingShift_JIS},
Packit 5b6b86
    {EUC_JISX0213,	"EUC-JISX0213",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {EUC_JIS_2004,	"EUC-JIS-2004",		&NkfEncodingEUC_JP},
Packit 5b6b86
    {UTF_8,		"UTF-8",		&NkfEncodingUTF_8},
Packit 5b6b86
    {UTF_8N,		"UTF-8N",		&NkfEncodingUTF_8},
Packit 5b6b86
    {UTF_8_BOM,		"UTF-8-BOM",		&NkfEncodingUTF_8},
Packit 5b6b86
    {UTF8_MAC,		"UTF8-MAC",		&NkfEncodingUTF_8},
Packit 5b6b86
    {UTF_16,		"UTF-16",		&NkfEncodingUTF_16},
Packit 5b6b86
    {UTF_16BE,		"UTF-16BE",		&NkfEncodingUTF_16},
Packit 5b6b86
    {UTF_16BE_BOM,	"UTF-16BE-BOM",		&NkfEncodingUTF_16},
Packit 5b6b86
    {UTF_16LE,		"UTF-16LE",		&NkfEncodingUTF_16},
Packit 5b6b86
    {UTF_16LE_BOM,	"UTF-16LE-BOM",		&NkfEncodingUTF_16},
Packit 5b6b86
    {UTF_32,		"UTF-32",		&NkfEncodingUTF_32},
Packit 5b6b86
    {UTF_32BE,		"UTF-32BE",		&NkfEncodingUTF_32},
Packit 5b6b86
    {UTF_32BE_BOM,	"UTF-32BE-BOM",		&NkfEncodingUTF_32},
Packit 5b6b86
    {UTF_32LE,		"UTF-32LE",		&NkfEncodingUTF_32},
Packit 5b6b86
    {UTF_32LE_BOM,	"UTF-32LE-BOM",		&NkfEncodingUTF_32},
Packit 5b6b86
    {BINARY,		"BINARY",		&NkfEncodingASCII},
Packit 5b6b86
    {-1,		NULL,			NULL}
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
struct {
Packit 5b6b86
    const char *name;
Packit 5b6b86
    const int id;
Packit 5b6b86
} encoding_name_to_id_table[] = {
Packit 5b6b86
    {"US-ASCII",		ASCII},
Packit 5b6b86
    {"ASCII",			ASCII},
Packit 5b6b86
    {"646",			ASCII},
Packit 5b6b86
    {"ROMAN8",			ASCII},
Packit 5b6b86
    {"ISO-2022-JP",		ISO_2022_JP},
Packit 5b6b86
    {"ISO2022JP-CP932",		CP50220},
Packit 5b6b86
    {"CP50220",			CP50220},
Packit 5b6b86
    {"CP50221",			CP50221},
Packit 5b6b86
    {"CSISO2022JP",		CP50221},
Packit 5b6b86
    {"CP50222",			CP50222},
Packit 5b6b86
    {"ISO-2022-JP-1",		ISO_2022_JP_1},
Packit 5b6b86
    {"ISO-2022-JP-3",		ISO_2022_JP_3},
Packit 5b6b86
    {"ISO-2022-JP-2004",	ISO_2022_JP_2004},
Packit 5b6b86
    {"SHIFT_JIS",		SHIFT_JIS},
Packit 5b6b86
    {"SJIS",			SHIFT_JIS},
Packit 5b6b86
    {"MS_Kanji",		SHIFT_JIS},
Packit 5b6b86
    {"PCK",			SHIFT_JIS},
Packit 5b6b86
    {"WINDOWS-31J",		WINDOWS_31J},
Packit 5b6b86
    {"CSWINDOWS31J",		WINDOWS_31J},
Packit 5b6b86
    {"CP932",			WINDOWS_31J},
Packit 5b6b86
    {"MS932",			WINDOWS_31J},
Packit 5b6b86
    {"CP10001",			CP10001},
Packit 5b6b86
    {"EUCJP",			EUC_JP},
Packit 5b6b86
    {"EUC-JP",			EUC_JP},
Packit 5b6b86
    {"EUCJP-NKF",		EUCJP_NKF},
Packit 5b6b86
    {"CP51932",			CP51932},
Packit 5b6b86
    {"EUC-JP-MS",		EUCJP_MS},
Packit 5b6b86
    {"EUCJP-MS",		EUCJP_MS},
Packit 5b6b86
    {"EUCJPMS",			EUCJP_MS},
Packit 5b6b86
    {"EUC-JP-ASCII",		EUCJP_ASCII},
Packit 5b6b86
    {"EUCJP-ASCII",		EUCJP_ASCII},
Packit 5b6b86
    {"SHIFT_JISX0213",		SHIFT_JISX0213},
Packit 5b6b86
    {"SHIFT_JIS-2004",		SHIFT_JIS_2004},
Packit 5b6b86
    {"EUC-JISX0213",		EUC_JISX0213},
Packit 5b6b86
    {"EUC-JIS-2004",		EUC_JIS_2004},
Packit 5b6b86
    {"UTF-8",			UTF_8},
Packit 5b6b86
    {"UTF-8N",			UTF_8N},
Packit 5b6b86
    {"UTF-8-BOM",		UTF_8_BOM},
Packit 5b6b86
    {"UTF8-MAC",		UTF8_MAC},
Packit 5b6b86
    {"UTF-8-MAC",		UTF8_MAC},
Packit 5b6b86
    {"UTF-16",			UTF_16},
Packit 5b6b86
    {"UTF-16BE",		UTF_16BE},
Packit 5b6b86
    {"UTF-16BE-BOM",		UTF_16BE_BOM},
Packit 5b6b86
    {"UTF-16LE",		UTF_16LE},
Packit 5b6b86
    {"UTF-16LE-BOM",		UTF_16LE_BOM},
Packit 5b6b86
    {"UTF-32",			UTF_32},
Packit 5b6b86
    {"UTF-32BE",		UTF_32BE},
Packit 5b6b86
    {"UTF-32BE-BOM",		UTF_32BE_BOM},
Packit 5b6b86
    {"UTF-32LE",		UTF_32LE},
Packit 5b6b86
    {"UTF-32LE-BOM",		UTF_32LE_BOM},
Packit 5b6b86
    {"BINARY",			BINARY},
Packit 5b6b86
    {NULL,			-1}
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
#if defined(DEFAULT_CODE_JIS)
Packit 5b6b86
#define	    DEFAULT_ENCIDX ISO_2022_JP
Packit 5b6b86
#elif defined(DEFAULT_CODE_SJIS)
Packit 5b6b86
#define	    DEFAULT_ENCIDX SHIFT_JIS
Packit 5b6b86
#elif defined(DEFAULT_CODE_WINDOWS_31J)
Packit 5b6b86
#define	    DEFAULT_ENCIDX WINDOWS_31J
Packit 5b6b86
#elif defined(DEFAULT_CODE_EUC)
Packit 5b6b86
#define	    DEFAULT_ENCIDX EUC_JP
Packit 5b6b86
#elif defined(DEFAULT_CODE_UTF8)
Packit 5b6b86
#define	    DEFAULT_ENCIDX UTF_8
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
#define		is_alnum(c)  \
Packit 5b6b86
    (('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))
Packit 5b6b86
Packit 5b6b86
/* I don't trust portablity of toupper */
Packit 5b6b86
#define nkf_toupper(c)  (('a'<=c && c<='z')?(c-('a'-'A')):c)
Packit 5b6b86
#define nkf_isoctal(c)  ('0'<=c && c<='7')
Packit 5b6b86
#define nkf_isdigit(c)  ('0'<=c && c<='9')
Packit 5b6b86
#define nkf_isxdigit(c)  (nkf_isdigit(c) || ('a'<=c && c<='f') || ('A'<=c && c <= 'F'))
Packit 5b6b86
#define nkf_isblank(c) (c == SP || c == TAB)
Packit 5b6b86
#define nkf_isspace(c) (nkf_isblank(c) || c == CR || c == LF)
Packit 5b6b86
#define nkf_isalpha(c) (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
Packit 5b6b86
#define nkf_isalnum(c) (nkf_isdigit(c) || nkf_isalpha(c))
Packit 5b6b86
#define nkf_isprint(c) (SP<=c && c<='~')
Packit 5b6b86
#define nkf_isgraph(c) ('!'<=c && c<='~')
Packit 5b6b86
#define hex2bin(c) (('0'<=c&&c<='9') ? (c-'0') : \
Packit 5b6b86
		    ('A'<=c&&c<='F') ? (c-'A'+10) : \
Packit 5b6b86
		    ('a'<=c&&c<='f') ? (c-'a'+10) : 0)
Packit 5b6b86
#define bin2hex(c) ("0123456789ABCDEF"[c&15])
Packit 5b6b86
#define is_eucg3(c2) (((unsigned short)c2 >> 8) == SS3)
Packit 5b6b86
#define nkf_noescape_mime(c) ((c == CR) || (c == LF) || \
Packit 5b6b86
			      ((c > SP) && (c < DEL) && (c != '?') && (c != '=') && (c != '_') \
Packit 5b6b86
			       && (c != '(') && (c != ')') && (c != '.') && (c != 0x22)))
Packit 5b6b86
Packit 5b6b86
#define is_ibmext_in_sjis(c2) (CP932_TABLE_BEGIN <= c2 && c2 <= CP932_TABLE_END)
Packit 5b6b86
#define nkf_byte_jisx0201_katakana_p(c) (SP <= c && c <= 0x5F)
Packit 5b6b86
Packit 5b6b86
#define         HOLD_SIZE       1024
Packit 5b6b86
#if defined(INT_IS_SHORT)
Packit 5b6b86
#define         IOBUF_SIZE      2048
Packit 5b6b86
#else
Packit 5b6b86
#define         IOBUF_SIZE      16384
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define         DEFAULT_J       'B'
Packit 5b6b86
#define         DEFAULT_R       'B'
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
#define         GETA1   0x22
Packit 5b6b86
#define         GETA2   0x2e
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
/* MIME preprocessor */
Packit 5b6b86
Packit 5b6b86
#ifdef EASYWIN /*Easy Win */
Packit 5b6b86
extern POINT _BufferSize;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
struct input_code{
Packit 5b6b86
    const char *name;
Packit 5b6b86
    nkf_char stat;
Packit 5b6b86
    nkf_char score;
Packit 5b6b86
    nkf_char index;
Packit 5b6b86
    nkf_char buf[3];
Packit 5b6b86
    void (*status_func)(struct input_code *, nkf_char);
Packit 5b6b86
    nkf_char (*iconv_func)(nkf_char c2, nkf_char c1, nkf_char c0);
Packit 5b6b86
    int _file_stat;
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static const char *input_codename = NULL; /* NULL: unestablished, "": BINARY */
Packit 5b6b86
static nkf_encoding *input_encoding = NULL;
Packit 5b6b86
static nkf_encoding *output_encoding = NULL;
Packit 5b6b86
Packit 5b6b86
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
Packit 5b6b86
/* UCS Mapping
Packit 5b6b86
 * 0: Shift_JIS, eucJP-ascii
Packit 5b6b86
 * 1: eucJP-ms
Packit 5b6b86
 * 2: CP932, CP51932
Packit 5b6b86
 * 3: CP10001
Packit 5b6b86
 */
Packit 5b6b86
#define UCS_MAP_ASCII   0
Packit 5b6b86
#define UCS_MAP_MS      1
Packit 5b6b86
#define UCS_MAP_CP932   2
Packit 5b6b86
#define UCS_MAP_CP10001 3
Packit 5b6b86
static int ms_ucs_map_f = UCS_MAP_ASCII;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
/* no NEC special, NEC-selected IBM extended and IBM extended characters */
Packit 5b6b86
static  int     no_cp932ext_f = FALSE;
Packit 5b6b86
/* ignore ZERO WIDTH NO-BREAK SPACE */
Packit 5b6b86
static  int     no_best_fit_chars_f = FALSE;
Packit 5b6b86
static  int     input_endian = ENDIAN_BIG;
Packit 5b6b86
static  int     input_bom_f = FALSE;
Packit 5b6b86
static  nkf_char     unicode_subchar = '?'; /* the regular substitution character */
Packit 5b6b86
static  void    (*encode_fallback)(nkf_char c) = NULL;
Packit 5b6b86
static  void    w_status(struct input_code *, nkf_char);
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
static  int     output_bom_f = FALSE;
Packit 5b6b86
static  int     output_endian = ENDIAN_BIG;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static  void    std_putc(nkf_char c);
Packit 5b6b86
static  nkf_char     std_getc(FILE *f);
Packit 5b6b86
static  nkf_char     std_ungetc(nkf_char c,FILE *f);
Packit 5b6b86
Packit 5b6b86
static  nkf_char     broken_getc(FILE *f);
Packit 5b6b86
static  nkf_char     broken_ungetc(nkf_char c,FILE *f);
Packit 5b6b86
Packit 5b6b86
static  nkf_char     mime_getc(FILE *f);
Packit 5b6b86
Packit 5b6b86
static void mime_putc(nkf_char c);
Packit 5b6b86
Packit 5b6b86
/* buffers */
Packit 5b6b86
Packit 5b6b86
#if !defined(PERL_XS) && !defined(WIN32DLL)
Packit 5b6b86
static unsigned char   stdibuf[IOBUF_SIZE];
Packit 5b6b86
static unsigned char   stdobuf[IOBUF_SIZE];
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define NKF_UNSPECIFIED (-TRUE)
Packit 5b6b86
Packit 5b6b86
/* flags */
Packit 5b6b86
static int             unbuf_f = FALSE;
Packit 5b6b86
static int             estab_f = FALSE;
Packit 5b6b86
static int             nop_f = FALSE;
Packit 5b6b86
static int             binmode_f = TRUE;       /* binary mode */
Packit 5b6b86
static int             rot_f = FALSE;          /* rot14/43 mode */
Packit 5b6b86
static int             hira_f = FALSE;          /* hira/kata henkan */
Packit 5b6b86
static int             alpha_f = FALSE;        /* convert JIx0208 alphbet to ASCII */
Packit 5b6b86
static int             mime_f = MIME_DECODE_DEFAULT;   /* convert MIME B base64 or Q */
Packit 5b6b86
static int             mime_decode_f = FALSE;  /* mime decode is explicitly on */
Packit 5b6b86
static int             mimebuf_f = FALSE;      /* MIME buffered input */
Packit 5b6b86
static int             broken_f = FALSE;       /* convert ESC-less broken JIS */
Packit 5b6b86
static int             iso8859_f = FALSE;      /* ISO8859 through */
Packit 5b6b86
static int             mimeout_f = FALSE;       /* base64 mode */
Packit 5b6b86
static int             x0201_f = NKF_UNSPECIFIED;   /* convert JIS X 0201 */
Packit 5b6b86
static int             iso2022jp_f = FALSE;    /* replace non ISO-2022-JP with GETA */
Packit 5b6b86
Packit 5b6b86
#ifdef UNICODE_NORMALIZATION
Packit 5b6b86
static int nfc_f = FALSE;
Packit 5b6b86
static nkf_char (*i_nfc_getc)(FILE *) = std_getc; /* input of ugetc */
Packit 5b6b86
static nkf_char (*i_nfc_ungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#ifdef INPUT_OPTION
Packit 5b6b86
static int cap_f = FALSE;
Packit 5b6b86
static nkf_char (*i_cgetc)(FILE *) = std_getc; /* input of cgetc */
Packit 5b6b86
static nkf_char (*i_cungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
Packit 5b6b86
static int url_f = FALSE;
Packit 5b6b86
static nkf_char (*i_ugetc)(FILE *) = std_getc; /* input of ugetc */
Packit 5b6b86
static nkf_char (*i_uungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define PREFIX_EUCG3    NKF_INT32_C(0x8F00)
Packit 5b6b86
#define CLASS_MASK      NKF_INT32_C(0xFF000000)
Packit 5b6b86
#define CLASS_UNICODE   NKF_INT32_C(0x01000000)
Packit 5b6b86
#define VALUE_MASK      NKF_INT32_C(0x00FFFFFF)
Packit 5b6b86
#define UNICODE_BMP_MAX NKF_INT32_C(0x0000FFFF)
Packit 5b6b86
#define UNICODE_MAX     NKF_INT32_C(0x0010FFFF)
Packit 5b6b86
#define nkf_char_euc3_new(c) ((c) | PREFIX_EUCG3)
Packit 5b6b86
#define nkf_char_unicode_new(c) ((c) | CLASS_UNICODE)
Packit 5b6b86
#define nkf_char_unicode_p(c) ((c & CLASS_MASK) == CLASS_UNICODE)
Packit 5b6b86
#define nkf_char_unicode_bmp_p(c) ((c & VALUE_MASK) <= UNICODE_BMP_MAX)
Packit 5b6b86
#define nkf_char_unicode_value_p(c) ((c & VALUE_MASK) <= UNICODE_MAX)
Packit 5b6b86
Packit 5b6b86
#define UTF16_TO_UTF32(lead, trail) (((lead) << 10) + (trail) - NKF_INT32_C(0x35FDC00))
Packit 5b6b86
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
static int numchar_f = FALSE;
Packit 5b6b86
static nkf_char (*i_ngetc)(FILE *) = std_getc; /* input of ugetc */
Packit 5b6b86
static nkf_char (*i_nungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#ifdef CHECK_OPTION
Packit 5b6b86
static int noout_f = FALSE;
Packit 5b6b86
static void no_putc(nkf_char c);
Packit 5b6b86
static int debug_f = FALSE;
Packit 5b6b86
static void debug(const char *str);
Packit 5b6b86
static nkf_char (*iconv_for_check)(nkf_char c2,nkf_char c1,nkf_char c0) = 0;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static int guess_f = 0; /* 0: OFF, 1: ON, 2: VERBOSE */
Packit 5b6b86
static  void    set_input_codename(const char *codename);
Packit 5b6b86
Packit 5b6b86
#ifdef EXEC_IO
Packit 5b6b86
static int exec_f = 0;
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
/* invert IBM extended characters to others */
Packit 5b6b86
static int cp51932_f = FALSE;
Packit 5b6b86
Packit 5b6b86
/* invert NEC-selected IBM extended characters to IBM extended characters */
Packit 5b6b86
static int cp932inv_f = TRUE;
Packit 5b6b86
Packit 5b6b86
/* static nkf_char cp932_conv(nkf_char c2, nkf_char c1); */
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
Packit 5b6b86
static int x0212_f = FALSE;
Packit 5b6b86
static int x0213_f = FALSE;
Packit 5b6b86
Packit 5b6b86
static unsigned char prefix_table[256];
Packit 5b6b86
Packit 5b6b86
static void e_status(struct input_code *, nkf_char);
Packit 5b6b86
static void s_status(struct input_code *, nkf_char);
Packit 5b6b86
Packit 5b6b86
struct input_code input_code_list[] = {
Packit 5b6b86
    {"EUC-JP",    0, 0, 0, {0, 0, 0}, e_status, e_iconv, 0},
Packit 5b6b86
    {"Shift_JIS", 0, 0, 0, {0, 0, 0}, s_status, s_iconv, 0},
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
    {"UTF-8",     0, 0, 0, {0, 0, 0}, w_status, w_iconv, 0},
Packit 5b6b86
    {"UTF-16",     0, 0, 0, {0, 0, 0}, NULL, w_iconv16, 0},
Packit 5b6b86
    {"UTF-32",     0, 0, 0, {0, 0, 0}, NULL, w_iconv32, 0},
Packit 5b6b86
#endif
Packit 5b6b86
    {NULL,        0, 0, 0, {0, 0, 0}, NULL, NULL, 0}
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static int              mimeout_mode = 0; /* 0, -1, 'Q', 'B', 1, 2 */
Packit 5b6b86
static int              base64_count = 0;
Packit 5b6b86
Packit 5b6b86
/* X0208 -> ASCII converter */
Packit 5b6b86
Packit 5b6b86
/* fold parameter */
Packit 5b6b86
static int             f_line = 0;    /* chars in line */
Packit 5b6b86
static int             f_prev = 0;
Packit 5b6b86
static int             fold_preserve_f = FALSE; /* preserve new lines */
Packit 5b6b86
static int             fold_f  = FALSE;
Packit 5b6b86
static int             fold_len  = 0;
Packit 5b6b86
Packit 5b6b86
/* options */
Packit 5b6b86
static unsigned char   kanji_intro = DEFAULT_J;
Packit 5b6b86
static unsigned char   ascii_intro = DEFAULT_R;
Packit 5b6b86
Packit 5b6b86
/* Folding */
Packit 5b6b86
Packit 5b6b86
#define FOLD_MARGIN  10
Packit 5b6b86
#define DEFAULT_FOLD 60
Packit 5b6b86
Packit 5b6b86
static int             fold_margin  = FOLD_MARGIN;
Packit 5b6b86
Packit 5b6b86
/* process default */
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
no_connection2(ARG_UNUSED nkf_char c2, ARG_UNUSED nkf_char c1, ARG_UNUSED nkf_char c0)
Packit 5b6b86
{
Packit 5b6b86
    fprintf(stderr,"nkf internal module connection failure.\n");
Packit 5b6b86
    exit(EXIT_FAILURE);
Packit 5b6b86
    return 0; /* LINT */
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
no_connection(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    no_connection2(c2,c1,0);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char (*iconv)(nkf_char c2,nkf_char c1,nkf_char c0) = no_connection2;
Packit 5b6b86
static void (*oconv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
Packit 5b6b86
static void (*o_zconv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_fconv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_eol_conv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_rot_conv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_hira_conv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_base64conv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
static void (*o_iso2022jp_check_conv)(nkf_char c2,nkf_char c1) = no_connection;
Packit 5b6b86
Packit 5b6b86
/* static redirections */
Packit 5b6b86
Packit 5b6b86
static  void   (*o_putc)(nkf_char c) = std_putc;
Packit 5b6b86
Packit 5b6b86
static  nkf_char    (*i_getc)(FILE *f) = std_getc; /* general input */
Packit 5b6b86
static  nkf_char    (*i_ungetc)(nkf_char c,FILE *f) =std_ungetc;
Packit 5b6b86
Packit 5b6b86
static  nkf_char    (*i_bgetc)(FILE *) = std_getc; /* input of mgetc */
Packit 5b6b86
static  nkf_char    (*i_bungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
Packit 5b6b86
static  void   (*o_mputc)(nkf_char c) = std_putc ; /* output of mputc */
Packit 5b6b86
Packit 5b6b86
static  nkf_char    (*i_mgetc)(FILE *) = std_getc; /* input of mgetc */
Packit 5b6b86
static  nkf_char    (*i_mungetc)(nkf_char c ,FILE *f) = std_ungetc;
Packit 5b6b86
Packit 5b6b86
/* for strict mime */
Packit 5b6b86
static  nkf_char    (*i_mgetc_buf)(FILE *) = std_getc; /* input of mgetc_buf */
Packit 5b6b86
static  nkf_char    (*i_mungetc_buf)(nkf_char c,FILE *f) = std_ungetc;
Packit 5b6b86
Packit 5b6b86
/* Global states */
Packit 5b6b86
static int output_mode = ASCII;    /* output kanji mode */
Packit 5b6b86
static int input_mode =  ASCII;    /* input kanji mode */
Packit 5b6b86
static int mime_decode_mode =   FALSE;    /* MIME mode B base64, Q hex */
Packit 5b6b86
Packit 5b6b86
/* X0201 / X0208 conversion tables */
Packit 5b6b86
Packit 5b6b86
/* X0201 kana conversion table */
Packit 5b6b86
/* 90-9F A0-DF */
Packit 5b6b86
static const unsigned char cv[]= {
Packit 5b6b86
    0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,
Packit 5b6b86
    0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,
Packit 5b6b86
    0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29,
Packit 5b6b86
    0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43,
Packit 5b6b86
    0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26,
Packit 5b6b86
    0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d,
Packit 5b6b86
    0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35,
Packit 5b6b86
    0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d,
Packit 5b6b86
    0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46,
Packit 5b6b86
    0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c,
Packit 5b6b86
    0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52,
Packit 5b6b86
    0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e,
Packit 5b6b86
    0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62,
Packit 5b6b86
    0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69,
Packit 5b6b86
    0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d,
Packit 5b6b86
    0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c,
Packit 5b6b86
    0x00,0x00};
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
/* X0201 kana conversion table for daguten */
Packit 5b6b86
/* 90-9F A0-DF */
Packit 5b6b86
static const unsigned char dv[]= {
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x74,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e,
Packit 5b6b86
    0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36,
Packit 5b6b86
    0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e,
Packit 5b6b86
    0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47,
Packit 5b6b86
    0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53,
Packit 5b6b86
    0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00};
Packit 5b6b86
Packit 5b6b86
/* X0201 kana conversion table for han-daguten */
Packit 5b6b86
/* 90-9F A0-DF */
Packit 5b6b86
static const unsigned char ev[]= {
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54,
Packit 5b6b86
    0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00};
Packit 5b6b86
Packit 5b6b86
/* X0201 kana to X0213 conversion table for han-daguten */
Packit 5b6b86
/* 90-9F A0-DF */
Packit 5b6b86
static const unsigned char ev_x0213[]= {
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x77,0x25,0x78,
Packit 5b6b86
    0x25,0x79,0x25,0x7a,0x25,0x7b,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x7c,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x25,0x7d,0x00,0x00,
Packit 5b6b86
    0x25,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00};
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
/* X0208 kigou conversion table */
Packit 5b6b86
/* 0x8140 - 0x819e */
Packit 5b6b86
static const unsigned char fv[] = {
Packit 5b6b86
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,
Packit 5b6b86
    0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00,
Packit 5b6b86
    0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f,
Packit 5b6b86
    0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27,
Packit 5b6b86
    0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d,
Packit 5b6b86
    0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00,
Packit 5b6b86
    0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
Packit 5b6b86
    0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40,
Packit 5b6b86
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
Packit 5b6b86
} ;
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
static int option_mode = 0;
Packit 5b6b86
static int             file_out_f = FALSE;
Packit 5b6b86
#ifdef OVERWRITE
Packit 5b6b86
static int             overwrite_f = FALSE;
Packit 5b6b86
static int             preserve_time_f = FALSE;
Packit 5b6b86
static int             backup_f = FALSE;
Packit 5b6b86
static char            *backup_suffix = "";
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static int eolmode_f = 0;   /* CR, LF, CRLF */
Packit 5b6b86
static int input_eol = 0; /* 0: unestablished, EOF: MIXED */
Packit 5b6b86
static nkf_char prev_cr = 0; /* CR or 0 */
Packit 5b6b86
#ifdef EASYWIN /*Easy Win */
Packit 5b6b86
static int             end_check;
Packit 5b6b86
#endif /*Easy Win */
Packit 5b6b86
Packit 5b6b86
static void *
Packit 5b6b86
nkf_xmalloc(size_t size)
Packit 5b6b86
{
Packit 5b6b86
    void *ptr;
Packit 5b6b86
Packit 5b6b86
    if (size == 0) size = 1;
Packit 5b6b86
Packit 5b6b86
    ptr = malloc(size);
Packit 5b6b86
    if (ptr == NULL) {
Packit 5b6b86
	perror("can't malloc");
Packit 5b6b86
	exit(EXIT_FAILURE);
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    return ptr;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void *
Packit 5b6b86
nkf_xrealloc(void *ptr, size_t size)
Packit 5b6b86
{
Packit 5b6b86
    if (size == 0) size = 1;
Packit 5b6b86
Packit 5b6b86
    ptr = realloc(ptr, size);
Packit 5b6b86
    if (ptr == NULL) {
Packit 5b6b86
	perror("can't realloc");
Packit 5b6b86
	exit(EXIT_FAILURE);
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    return ptr;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define nkf_xfree(ptr) free(ptr)
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
nkf_str_caseeql(const char *src, const char *target)
Packit 5b6b86
{
Packit 5b6b86
    int i;
Packit 5b6b86
    for (i = 0; src[i] && target[i]; i++) {
Packit 5b6b86
	if (nkf_toupper(src[i]) != nkf_toupper(target[i])) return FALSE;
Packit 5b6b86
    }
Packit 5b6b86
    if (src[i] || target[i]) return FALSE;
Packit 5b6b86
    else return TRUE;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_encoding*
Packit 5b6b86
nkf_enc_from_index(int idx)
Packit 5b6b86
{
Packit 5b6b86
    if (idx < 0 || NKF_ENCODING_TABLE_SIZE <= idx) {
Packit 5b6b86
	return 0;
Packit 5b6b86
    }
Packit 5b6b86
    return &nkf_encoding_table[idx];
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
nkf_enc_find_index(const char *name)
Packit 5b6b86
{
Packit 5b6b86
    int i;
Packit 5b6b86
    if (name[0] == 'X' && *(name+1) == '-') name += 2;
Packit 5b6b86
    for (i = 0; encoding_name_to_id_table[i].id >= 0; i++) {
Packit 5b6b86
	if (nkf_str_caseeql(encoding_name_to_id_table[i].name, name)) {
Packit 5b6b86
	    return encoding_name_to_id_table[i].id;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return -1;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_encoding*
Packit 5b6b86
nkf_enc_find(const char *name)
Packit 5b6b86
{
Packit 5b6b86
    int idx = -1;
Packit 5b6b86
    idx = nkf_enc_find_index(name);
Packit 5b6b86
    if (idx < 0) return 0;
Packit 5b6b86
    return nkf_enc_from_index(idx);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define nkf_enc_name(enc) (enc)->name
Packit 5b6b86
#define nkf_enc_to_index(enc) (enc)->id
Packit 5b6b86
#define nkf_enc_to_base_encoding(enc) (enc)->base_encoding
Packit 5b6b86
#define nkf_enc_to_iconv(enc) nkf_enc_to_base_encoding(enc)->iconv
Packit 5b6b86
#define nkf_enc_to_oconv(enc) nkf_enc_to_base_encoding(enc)->oconv
Packit 5b6b86
#define nkf_enc_asciicompat(enc) (\
Packit 5b6b86
				  nkf_enc_to_base_encoding(enc) == &NkfEncodingASCII ||\
Packit 5b6b86
				  nkf_enc_to_base_encoding(enc) == &NkfEncodingISO_2022_JP)
Packit 5b6b86
#define nkf_enc_unicode_p(enc) (\
Packit 5b6b86
				nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_8 ||\
Packit 5b6b86
				nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_16 ||\
Packit 5b6b86
				nkf_enc_to_base_encoding(enc) == &NkfEncodingUTF_32)
Packit 5b6b86
#define nkf_enc_cp5022x_p(enc) (\
Packit 5b6b86
				nkf_enc_to_index(enc) == CP50220 ||\
Packit 5b6b86
				nkf_enc_to_index(enc) == CP50221 ||\
Packit 5b6b86
				nkf_enc_to_index(enc) == CP50222)
Packit 5b6b86
Packit 5b6b86
#ifdef DEFAULT_CODE_LOCALE
Packit 5b6b86
static const char*
Packit 5b6b86
nkf_locale_charmap()
Packit 5b6b86
{
Packit 5b6b86
#ifdef HAVE_LANGINFO_H
Packit 5b6b86
    return nl_langinfo(CODESET);
Packit 5b6b86
#elif defined(__WIN32__)
Packit 5b6b86
    static char buf[16];
Packit 5b6b86
    sprintf(buf, "CP%d", GetACP());
Packit 5b6b86
    return buf;
Packit 5b6b86
#elif defined(__OS2__)
Packit 5b6b86
# if defined(INT_IS_SHORT)
Packit 5b6b86
    /* OS/2 1.x */
Packit 5b6b86
    return NULL;
Packit 5b6b86
# else
Packit 5b6b86
    /* OS/2 32bit */
Packit 5b6b86
    static char buf[16];
Packit 5b6b86
    ULONG ulCP[1], ulncp;
Packit 5b6b86
    DosQueryCp(sizeof(ulCP), ulCP, &ulncp);
Packit 5b6b86
    if (ulCP[0] == 932 || ulCP[0] == 943)
Packit 5b6b86
        strcpy(buf, "Shift_JIS");
Packit 5b6b86
    else
Packit 5b6b86
        sprintf(buf, "CP%lu", ulCP[0]);
Packit 5b6b86
    return buf;
Packit 5b6b86
# endif
Packit 5b6b86
#endif
Packit 5b6b86
    return NULL;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_encoding*
Packit 5b6b86
nkf_locale_encoding()
Packit 5b6b86
{
Packit 5b6b86
    nkf_encoding *enc = 0;
Packit 5b6b86
    const char *encname = nkf_locale_charmap();
Packit 5b6b86
    if (encname)
Packit 5b6b86
	enc = nkf_enc_find(encname);
Packit 5b6b86
    return enc;
Packit 5b6b86
}
Packit 5b6b86
#endif /* DEFAULT_CODE_LOCALE */
Packit 5b6b86
Packit 5b6b86
static nkf_encoding*
Packit 5b6b86
nkf_utf8_encoding()
Packit 5b6b86
{
Packit 5b6b86
    return &nkf_encoding_table[UTF_8];
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_encoding*
Packit 5b6b86
nkf_default_encoding()
Packit 5b6b86
{
Packit 5b6b86
    nkf_encoding *enc = 0;
Packit 5b6b86
#ifdef DEFAULT_CODE_LOCALE
Packit 5b6b86
    enc = nkf_locale_encoding();
Packit 5b6b86
#elif defined(DEFAULT_ENCIDX)
Packit 5b6b86
    enc = nkf_enc_from_index(DEFAULT_ENCIDX);
Packit 5b6b86
#endif
Packit 5b6b86
    if (!enc) enc = nkf_utf8_encoding();
Packit 5b6b86
    return enc;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
typedef struct {
Packit 5b6b86
    long capa;
Packit 5b6b86
    long len;
Packit 5b6b86
    nkf_char *ptr;
Packit 5b6b86
} nkf_buf_t;
Packit 5b6b86
Packit 5b6b86
static nkf_buf_t *
Packit 5b6b86
nkf_buf_new(int length)
Packit 5b6b86
{
Packit 5b6b86
    nkf_buf_t *buf = nkf_xmalloc(sizeof(nkf_buf_t));
Packit 5b6b86
    buf->ptr = nkf_xmalloc(sizeof(nkf_char) * length);
Packit 5b6b86
    buf->capa = length;
Packit 5b6b86
    buf->len = 0;
Packit 5b6b86
    return buf;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#if 0
Packit 5b6b86
static void
Packit 5b6b86
nkf_buf_dispose(nkf_buf_t *buf)
Packit 5b6b86
{
Packit 5b6b86
    nkf_xfree(buf->ptr);
Packit 5b6b86
    nkf_xfree(buf);
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define nkf_buf_length(buf) ((buf)->len)
Packit 5b6b86
#define nkf_buf_empty_p(buf) ((buf)->len == 0)
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
nkf_buf_at(nkf_buf_t *buf, int index)
Packit 5b6b86
{
Packit 5b6b86
    assert(index <= buf->len);
Packit 5b6b86
    return buf->ptr[index];
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
nkf_buf_clear(nkf_buf_t *buf)
Packit 5b6b86
{
Packit 5b6b86
    buf->len = 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
nkf_buf_push(nkf_buf_t *buf, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    if (buf->capa <= buf->len) {
Packit 5b6b86
	exit(EXIT_FAILURE);
Packit 5b6b86
    }
Packit 5b6b86
    buf->ptr[buf->len++] = c;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
nkf_buf_pop(nkf_buf_t *buf)
Packit 5b6b86
{
Packit 5b6b86
    assert(!nkf_buf_empty_p(buf));
Packit 5b6b86
    return buf->ptr[--buf->len];
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
/* Normalization Form C */
Packit 5b6b86
#ifndef PERL_XS
Packit 5b6b86
#ifdef WIN32DLL
Packit 5b6b86
#define fprintf dllprintf
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
version(void)
Packit 5b6b86
{
Packit 5b6b86
    fprintf(HELP_OUTPUT,"Network Kanji Filter Version " NKF_VERSION " (" NKF_RELEASE_DATE ") \n" COPY_RIGHT "\n");
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
usage(void)
Packit 5b6b86
{
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    "Usage:  nkf -[flags] [--] [in file] .. [out file for -O flag]\n"
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	    " j/s/e/w  Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
Packit 5b6b86
	    "          UTF options is -w[8[0],{16,32}[{B,L}[0]]]\n"
Packit 5b6b86
#else
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
	    " J/S/E/W  Specify input encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
Packit 5b6b86
	    "          UTF option is -W[8,[16,32][B,L]]\n"
Packit 5b6b86
#else
Packit 5b6b86
	    " J/S/E    Specify output encoding ISO-2022-JP, Shift_JIS, EUC-JP\n"
Packit 5b6b86
#endif
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    " m[BQSN0] MIME decode [B:base64,Q:quoted,S:strict,N:nonstrict,0:no decode]\n"
Packit 5b6b86
	    " M[BQ]    MIME encode [B:base64 Q:quoted]\n"
Packit 5b6b86
	    " f/F      Folding: -f60 or -f or -f60-10 (fold margin 10) F preserve nl\n"
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    " Z[0-4]   Default/0: Convert JISX0208 Alphabet to ASCII\n"
Packit 5b6b86
	    "          1: Kankaku to one space  2: to two spaces  3: HTML Entity\n"
Packit 5b6b86
	    "          4: JISX0208 Katakana to JISX0201 Katakana\n"
Packit 5b6b86
	    " X,x      Convert Halfwidth Katakana to Fullwidth or preserve it\n"
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    " O        Output to File (DEFAULT 'nkf.out')\n"
Packit 5b6b86
	    " L[uwm]   Line mode u:LF w:CRLF m:CR (DEFAULT noconversion)\n"
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    " --ic=<encoding>        Specify the input encoding\n"
Packit 5b6b86
	    " --oc=<encoding>        Specify the output encoding\n"
Packit 5b6b86
	    " --hiragana --katakana  Hiragana/Katakana Conversion\n"
Packit 5b6b86
	    " --katakana-hiragana    Converts each other\n"
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
#ifdef INPUT_OPTION
Packit 5b6b86
	    " --{cap, url}-input     Convert hex after ':' or '%%'\n"
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
	    " --numchar-input        Convert Unicode Character Reference\n"
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
	    " --fb-{skip, html, xml, perl, java, subchar}\n"
Packit 5b6b86
	    "                        Specify unassigned character's replacement\n"
Packit 5b6b86
#endif
Packit 5b6b86
	    );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
#ifdef OVERWRITE
Packit 5b6b86
	    " --in-place[=SUF]       Overwrite original files\n"
Packit 5b6b86
	    " --overwrite[=SUF]      Preserve timestamp of original files\n"
Packit 5b6b86
#endif
Packit 5b6b86
	    " -g --guess             Guess the input code\n"
Packit 5b6b86
	    " -v --version           Print the version\n"
Packit 5b6b86
	    " --help/-V              Print this help / configuration\n"
Packit 5b6b86
	    );
Packit 5b6b86
    version();
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
show_configuration(void)
Packit 5b6b86
{
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    "Summary of my nkf " NKF_VERSION " (" NKF_RELEASE_DATE ") configuration:\n"
Packit 5b6b86
	    "  Compile-time options:\n"
Packit 5b6b86
	    "    Compiled at:                 " __DATE__ " " __TIME__ "\n"
Packit 5b6b86
	   );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    "    Default output encoding:     "
Packit 5b6b86
#ifdef DEFAULT_CODE_LOCALE
Packit 5b6b86
	    "LOCALE (%s)\n", nkf_enc_name(nkf_default_encoding())
Packit 5b6b86
#elif defined(DEFAULT_ENCIDX)
Packit 5b6b86
	    "CONFIG (%s)\n", nkf_enc_name(nkf_default_encoding())
Packit 5b6b86
#else
Packit 5b6b86
	    "NONE\n"
Packit 5b6b86
#endif
Packit 5b6b86
	   );
Packit 5b6b86
    fprintf(HELP_OUTPUT,
Packit 5b6b86
	    "    Default output end of line:  "
Packit 5b6b86
#if DEFAULT_NEWLINE == CR
Packit 5b6b86
	    "CR"
Packit 5b6b86
#elif DEFAULT_NEWLINE == CRLF
Packit 5b6b86
	    "CRLF"
Packit 5b6b86
#else
Packit 5b6b86
	    "LF"
Packit 5b6b86
#endif
Packit 5b6b86
	    "\n"
Packit 5b6b86
	    "    Decode MIME encoded string:  "
Packit 5b6b86
#if MIME_DECODE_DEFAULT
Packit 5b6b86
	    "ON"
Packit 5b6b86
#else
Packit 5b6b86
	    "OFF"
Packit 5b6b86
#endif
Packit 5b6b86
	    "\n"
Packit 5b6b86
	    "    Convert JIS X 0201 Katakana: "
Packit 5b6b86
#if X0201_DEFAULT
Packit 5b6b86
	    "ON"
Packit 5b6b86
#else
Packit 5b6b86
	    "OFF"
Packit 5b6b86
#endif
Packit 5b6b86
	    "\n"
Packit 5b6b86
	    "    --help, --version output:    "
Packit 5b6b86
#if HELP_OUTPUT_HELP_OUTPUT
Packit 5b6b86
	    "HELP_OUTPUT"
Packit 5b6b86
#else
Packit 5b6b86
	    "STDOUT"
Packit 5b6b86
#endif
Packit 5b6b86
	    "\n");
Packit 5b6b86
}
Packit 5b6b86
#endif /*PERL_XS*/
Packit 5b6b86
Packit 5b6b86
#ifdef OVERWRITE
Packit 5b6b86
static char*
Packit 5b6b86
get_backup_filename(const char *suffix, const char *filename)
Packit 5b6b86
{
Packit 5b6b86
    char *backup_filename;
Packit 5b6b86
    int asterisk_count = 0;
Packit 5b6b86
    int i, j;
Packit 5b6b86
    int filename_length = strlen(filename);
Packit 5b6b86
Packit 5b6b86
    for(i = 0; suffix[i]; i++){
Packit 5b6b86
	if(suffix[i] == '*') asterisk_count++;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if(asterisk_count){
Packit 5b6b86
	backup_filename = nkf_xmalloc(strlen(suffix) + (asterisk_count * (filename_length - 1)) + 1);
Packit 5b6b86
	for(i = 0, j = 0; suffix[i];){
Packit 5b6b86
	    if(suffix[i] == '*'){
Packit 5b6b86
		backup_filename[j] = '\0';
Packit 5b6b86
		strncat(backup_filename, filename, filename_length);
Packit 5b6b86
		i++;
Packit 5b6b86
		j += filename_length;
Packit 5b6b86
	    }else{
Packit 5b6b86
		backup_filename[j++] = suffix[i++];
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
	backup_filename[j] = '\0';
Packit 5b6b86
    }else{
Packit 5b6b86
	j = filename_length + strlen(suffix);
Packit 5b6b86
	backup_filename = nkf_xmalloc(j + 1);
Packit 5b6b86
	strcpy(backup_filename, filename);
Packit 5b6b86
	strcat(backup_filename, suffix);
Packit 5b6b86
	backup_filename[j] = '\0';
Packit 5b6b86
    }
Packit 5b6b86
    return backup_filename;
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
static void
Packit 5b6b86
nkf_each_char_to_hex(void (*f)(nkf_char c2,nkf_char c1), nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    int shift = 20;
Packit 5b6b86
    c &= VALUE_MASK;
Packit 5b6b86
    while(shift >= 0){
Packit 5b6b86
	if(c >= NKF_INT32_C(1)<
Packit 5b6b86
	    while(shift >= 0){
Packit 5b6b86
		(*f)(0, bin2hex(c>>shift));
Packit 5b6b86
		shift -= 4;
Packit 5b6b86
	    }
Packit 5b6b86
	}else{
Packit 5b6b86
	    shift -= 4;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
encode_fallback_html(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(0, '&';;
Packit 5b6b86
    (*oconv)(0, '#');
Packit 5b6b86
    c &= VALUE_MASK;
Packit 5b6b86
    if(c >= NKF_INT32_C(1000000))
Packit 5b6b86
	(*oconv)(0, 0x30+(c/NKF_INT32_C(1000000))%10);
Packit 5b6b86
    if(c >= NKF_INT32_C(100000))
Packit 5b6b86
	(*oconv)(0, 0x30+(c/NKF_INT32_C(100000) )%10);
Packit 5b6b86
    if(c >= 10000)
Packit 5b6b86
	(*oconv)(0, 0x30+(c/10000  )%10);
Packit 5b6b86
    if(c >= 1000)
Packit 5b6b86
	(*oconv)(0, 0x30+(c/1000   )%10);
Packit 5b6b86
    if(c >= 100)
Packit 5b6b86
	(*oconv)(0, 0x30+(c/100    )%10);
Packit 5b6b86
    if(c >= 10)
Packit 5b6b86
	(*oconv)(0, 0x30+(c/10     )%10);
Packit 5b6b86
    if(c >= 0)
Packit 5b6b86
	(*oconv)(0, 0x30+ c         %10);
Packit 5b6b86
    (*oconv)(0, ';');
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
encode_fallback_xml(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(0, '&';;
Packit 5b6b86
    (*oconv)(0, '#');
Packit 5b6b86
    (*oconv)(0, 'x');
Packit 5b6b86
    nkf_each_char_to_hex(oconv, c);
Packit 5b6b86
    (*oconv)(0, ';');
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
encode_fallback_java(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(0, '\\');
Packit 5b6b86
    c &= VALUE_MASK;
Packit 5b6b86
    if(!nkf_char_unicode_bmp_p(c)){
Packit 5b6b86
	(*oconv)(0, 'U');
Packit 5b6b86
	(*oconv)(0, '0');
Packit 5b6b86
	(*oconv)(0, '0');
Packit 5b6b86
	(*oconv)(0, bin2hex(c>>20));
Packit 5b6b86
	(*oconv)(0, bin2hex(c>>16));
Packit 5b6b86
    }else{
Packit 5b6b86
	(*oconv)(0, 'u');
Packit 5b6b86
    }
Packit 5b6b86
    (*oconv)(0, bin2hex(c>>12));
Packit 5b6b86
    (*oconv)(0, bin2hex(c>> 8));
Packit 5b6b86
    (*oconv)(0, bin2hex(c>> 4));
Packit 5b6b86
    (*oconv)(0, bin2hex(c    ));
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
encode_fallback_perl(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(0, '\\');
Packit 5b6b86
    (*oconv)(0, 'x');
Packit 5b6b86
    (*oconv)(0, '{');
Packit 5b6b86
    nkf_each_char_to_hex(oconv, c);
Packit 5b6b86
    (*oconv)(0, '}');
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
encode_fallback_subchar(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    c = unicode_subchar;
Packit 5b6b86
    (*oconv)((c>>8)&0xFF, c&0xFF);
Packit 5b6b86
    return;
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static const struct {
Packit 5b6b86
    const char *name;
Packit 5b6b86
    const char *alias;
Packit 5b6b86
} long_option[] = {
Packit 5b6b86
    {"ic=", ""},
Packit 5b6b86
    {"oc=", ""},
Packit 5b6b86
    {"base64","jMB"},
Packit 5b6b86
    {"euc","e"},
Packit 5b6b86
    {"euc-input","E"},
Packit 5b6b86
    {"fj","jm"},
Packit 5b6b86
    {"help",""},
Packit 5b6b86
    {"jis","j"},
Packit 5b6b86
    {"jis-input","J"},
Packit 5b6b86
    {"mac","sLm"},
Packit 5b6b86
    {"mime","jM"},
Packit 5b6b86
    {"mime-input","m"},
Packit 5b6b86
    {"msdos","sLw"},
Packit 5b6b86
    {"sjis","s"},
Packit 5b6b86
    {"sjis-input","S"},
Packit 5b6b86
    {"unix","eLu"},
Packit 5b6b86
    {"version","v"},
Packit 5b6b86
    {"windows","sLw"},
Packit 5b6b86
    {"hiragana","h1"},
Packit 5b6b86
    {"katakana","h2"},
Packit 5b6b86
    {"katakana-hiragana","h3"},
Packit 5b6b86
    {"guess=", ""},
Packit 5b6b86
    {"guess", "g2"},
Packit 5b6b86
    {"cp932", ""},
Packit 5b6b86
    {"no-cp932", ""},
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    {"x0212", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
    {"utf8", "w"},
Packit 5b6b86
    {"utf16", "w16"},
Packit 5b6b86
    {"ms-ucs-map", ""},
Packit 5b6b86
    {"fb-skip", ""},
Packit 5b6b86
    {"fb-html", ""},
Packit 5b6b86
    {"fb-xml", ""},
Packit 5b6b86
    {"fb-perl", ""},
Packit 5b6b86
    {"fb-java", ""},
Packit 5b6b86
    {"fb-subchar", ""},
Packit 5b6b86
    {"fb-subchar=", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
    {"utf8-input", "W"},
Packit 5b6b86
    {"utf16-input", "W16"},
Packit 5b6b86
    {"no-cp932ext", ""},
Packit 5b6b86
    {"no-best-fit-chars",""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UNICODE_NORMALIZATION
Packit 5b6b86
    {"utf8mac-input", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef OVERWRITE
Packit 5b6b86
    {"overwrite", ""},
Packit 5b6b86
    {"overwrite=", ""},
Packit 5b6b86
    {"in-place", ""},
Packit 5b6b86
    {"in-place=", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef INPUT_OPTION
Packit 5b6b86
    {"cap-input", ""},
Packit 5b6b86
    {"url-input", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
    {"numchar-input", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef CHECK_OPTION
Packit 5b6b86
    {"no-output", ""},
Packit 5b6b86
    {"debug", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
    {"cp932inv", ""},
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef EXEC_IO
Packit 5b6b86
    {"exec-in", ""},
Packit 5b6b86
    {"exec-out", ""},
Packit 5b6b86
#endif
Packit 5b6b86
    {"prefix=", ""},
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
set_input_encoding(nkf_encoding *enc)
Packit 5b6b86
{
Packit 5b6b86
    switch (nkf_enc_to_index(enc)) {
Packit 5b6b86
    case ISO_8859_1:
Packit 5b6b86
	iso8859_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case CP50221:
Packit 5b6b86
    case CP50222:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
    case CP50220:
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = TRUE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP_1:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP_3:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP_2004:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case SHIFT_JIS:
Packit 5b6b86
	break;
Packit 5b6b86
    case WINDOWS_31J:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = TRUE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
	break;
Packit 5b6b86
    case CP10001:
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = TRUE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP10001;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUC_JP:
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_NKF:
Packit 5b6b86
	break;
Packit 5b6b86
    case CP51932:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = TRUE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_MS:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_MS;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_ASCII:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_ASCII;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case SHIFT_JISX0213:
Packit 5b6b86
    case SHIFT_JIS_2004:
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = FALSE;
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUC_JISX0213:
Packit 5b6b86
    case EUC_JIS_2004:
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	cp51932_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
#ifdef UNICODE_NORMALIZATION
Packit 5b6b86
    case UTF8_MAC:
Packit 5b6b86
	nfc_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
#endif
Packit 5b6b86
    case UTF_16:
Packit 5b6b86
    case UTF_16BE:
Packit 5b6b86
    case UTF_16BE_BOM:
Packit 5b6b86
	input_endian = ENDIAN_BIG;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_16LE:
Packit 5b6b86
    case UTF_16LE_BOM:
Packit 5b6b86
	input_endian = ENDIAN_LITTLE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_32:
Packit 5b6b86
    case UTF_32BE:
Packit 5b6b86
    case UTF_32BE_BOM:
Packit 5b6b86
	input_endian = ENDIAN_BIG;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_32LE:
Packit 5b6b86
    case UTF_32LE_BOM:
Packit 5b6b86
	input_endian = ENDIAN_LITTLE;
Packit 5b6b86
	break;
Packit 5b6b86
#endif
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
set_output_encoding(nkf_encoding *enc)
Packit 5b6b86
{
Packit 5b6b86
    switch (nkf_enc_to_index(enc)) {
Packit 5b6b86
    case CP50220:
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case CP50221:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP:
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP_1:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case ISO_2022_JP_3:
Packit 5b6b86
    case ISO_2022_JP_2004:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case SHIFT_JIS:
Packit 5b6b86
	break;
Packit 5b6b86
    case WINDOWS_31J:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case CP10001:
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP10001;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUC_JP:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_ASCII;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_NKF:
Packit 5b6b86
	x0212_f = FALSE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_ASCII;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case CP51932:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_CP932;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_MS:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_MS;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUCJP_ASCII:
Packit 5b6b86
	if (x0201_f == NKF_UNSPECIFIED) x0201_f = FALSE;	/* -x specified implicitly */
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
	ms_ucs_map_f = UCS_MAP_ASCII;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case SHIFT_JISX0213:
Packit 5b6b86
    case SHIFT_JIS_2004:
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
    case EUC_JISX0213:
Packit 5b6b86
    case EUC_JIS_2004:
Packit 5b6b86
	x0212_f = TRUE;
Packit 5b6b86
	x0213_f = TRUE;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f == TRUE) cp932inv_f = FALSE;
Packit 5b6b86
#endif
Packit 5b6b86
	break;
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
    case UTF_8_BOM:
Packit 5b6b86
	output_bom_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_16:
Packit 5b6b86
    case UTF_16BE_BOM:
Packit 5b6b86
	output_bom_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_16LE:
Packit 5b6b86
	output_endian = ENDIAN_LITTLE;
Packit 5b6b86
	output_bom_f = FALSE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_16LE_BOM:
Packit 5b6b86
	output_endian = ENDIAN_LITTLE;
Packit 5b6b86
	output_bom_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_32:
Packit 5b6b86
    case UTF_32BE_BOM:
Packit 5b6b86
	output_bom_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_32LE:
Packit 5b6b86
	output_endian = ENDIAN_LITTLE;
Packit 5b6b86
	output_bom_f = FALSE;
Packit 5b6b86
	break;
Packit 5b6b86
    case UTF_32LE_BOM:
Packit 5b6b86
	output_endian = ENDIAN_LITTLE;
Packit 5b6b86
	output_bom_f = TRUE;
Packit 5b6b86
	break;
Packit 5b6b86
#endif
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static struct input_code*
Packit 5b6b86
find_inputcode_byfunc(nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
Packit 5b6b86
{
Packit 5b6b86
    if (iconv_func){
Packit 5b6b86
	struct input_code *p = input_code_list;
Packit 5b6b86
	while (p->name){
Packit 5b6b86
	    if (iconv_func == p->iconv_func){
Packit 5b6b86
		return p;
Packit 5b6b86
	    }
Packit 5b6b86
	    p++;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
set_iconv(nkf_char f, nkf_char (*iconv_func)(nkf_char c2,nkf_char c1,nkf_char c0))
Packit 5b6b86
{
Packit 5b6b86
#ifdef INPUT_CODE_FIX
Packit 5b6b86
    if (f || !input_encoding)
Packit 5b6b86
#endif
Packit 5b6b86
	if (estab_f != f){
Packit 5b6b86
	    estab_f = f;
Packit 5b6b86
	}
Packit 5b6b86
Packit 5b6b86
    if (iconv_func
Packit 5b6b86
#ifdef INPUT_CODE_FIX
Packit 5b6b86
	&& (f == -TRUE || !input_encoding) /* -TRUE means "FORCE" */
Packit 5b6b86
#endif
Packit 5b6b86
       ){
Packit 5b6b86
	iconv = iconv_func;
Packit 5b6b86
    }
Packit 5b6b86
#ifdef CHECK_OPTION
Packit 5b6b86
    if (estab_f && iconv_for_check != iconv){
Packit 5b6b86
	struct input_code *p = find_inputcode_byfunc(iconv);
Packit 5b6b86
	if (p){
Packit 5b6b86
	    set_input_codename(p->name);
Packit 5b6b86
	    debug(p->name);
Packit 5b6b86
	}
Packit 5b6b86
	iconv_for_check = iconv;
Packit 5b6b86
    }
Packit 5b6b86
#endif
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
static nkf_char
Packit 5b6b86
x0212_shift(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char ret = c;
Packit 5b6b86
    c &= 0x7f;
Packit 5b6b86
    if (is_eucg3(ret)){
Packit 5b6b86
	if (0x75 <= c && c <= 0x7f){
Packit 5b6b86
	    ret = c + (0x109 - 0x75);
Packit 5b6b86
	}
Packit 5b6b86
    }else{
Packit 5b6b86
	if (0x75 <= c && c <= 0x7f){
Packit 5b6b86
	    ret = c + (0x113 - 0x75);
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
x0212_unshift(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char ret = c;
Packit 5b6b86
    if (0x7f <= c && c <= 0x88){
Packit 5b6b86
	ret = c + (0x75 - 0x7f);
Packit 5b6b86
    }else if (0x89 <= c && c <= 0x92){
Packit 5b6b86
	ret = PREFIX_EUCG3 | 0x80 | (c + (0x75 - 0x89));
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
is_x0213_2_in_x0212(nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    static const char x0213_2_table[] =
Packit 5b6b86
	{0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1};
Packit 5b6b86
    int ku = c1 - 0x20;
Packit 5b6b86
    if (ku <= 15)
Packit 5b6b86
	return x0213_2_table[ku]; /* 1, 3-5, 8, 12-15 */
Packit 5b6b86
    if (78 <= ku && ku <= 94)
Packit 5b6b86
	return 1;
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
e2s_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char ndx;
Packit 5b6b86
    if (is_eucg3(c2)){
Packit 5b6b86
	ndx = c2 & 0x7f;
Packit 5b6b86
	if (x0213_f && is_x0213_2_in_x0212(ndx)){
Packit 5b6b86
	    if((0x21 <= ndx && ndx <= 0x2F)){
Packit 5b6b86
		if (p2) *p2 = ((ndx - 1) >> 1) + 0xec - ndx / 8 * 3;
Packit 5b6b86
		if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
Packit 5b6b86
		return 0;
Packit 5b6b86
	    }else if(0x6E <= ndx && ndx <= 0x7E){
Packit 5b6b86
		if (p2) *p2 = ((ndx - 1) >> 1) + 0xbe;
Packit 5b6b86
		if (p1) *p1 = c1 + ((ndx & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
Packit 5b6b86
		return 0;
Packit 5b6b86
	    }
Packit 5b6b86
	    return 1;
Packit 5b6b86
	}
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
	else if(nkf_isgraph(ndx)){
Packit 5b6b86
	    nkf_char val = 0;
Packit 5b6b86
	    const unsigned short *ptr;
Packit 5b6b86
	    ptr = x0212_shiftjis[ndx - 0x21];
Packit 5b6b86
	    if (ptr){
Packit 5b6b86
		val = ptr[(c1 & 0x7f) - 0x21];
Packit 5b6b86
	    }
Packit 5b6b86
	    if (val){
Packit 5b6b86
		c2 = val >> 8;
Packit 5b6b86
		c1 = val & 0xff;
Packit 5b6b86
		if (p2) *p2 = c2;
Packit 5b6b86
		if (p1) *p1 = c1;
Packit 5b6b86
		return 0;
Packit 5b6b86
	    }
Packit 5b6b86
	    c2 = x0212_shift(c2);
Packit 5b6b86
	}
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
    }
Packit 5b6b86
    if(0x7F < c2) return 1;
Packit 5b6b86
    if (p2) *p2 = ((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1);
Packit 5b6b86
    if (p1) *p1 = c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e);
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
s2e_conv(nkf_char c2, nkf_char c1, nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
#if defined(SHIFTJIS_CP932) || defined(X0212_ENABLE)
Packit 5b6b86
    nkf_char val;
Packit 5b6b86
#endif
Packit 5b6b86
    static const char shift_jisx0213_s1a3_table[5][2] ={ { 1, 8}, { 3, 4}, { 5,12}, {13,14}, {15, 0} };
Packit 5b6b86
    if (0xFC < c1) return 1;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
    if (!cp932inv_f && !x0213_f && is_ibmext_in_sjis(c2)){
Packit 5b6b86
	val = shiftjis_cp932[c2 - CP932_TABLE_BEGIN][c1 - 0x40];
Packit 5b6b86
	if (val){
Packit 5b6b86
	    c2 = val >> 8;
Packit 5b6b86
	    c1 = val & 0xff;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    if (cp932inv_f
Packit 5b6b86
	&& CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
Packit 5b6b86
	val = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
Packit 5b6b86
	if (val){
Packit 5b6b86
	    c2 = val >> 8;
Packit 5b6b86
	    c1 = val & 0xff;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    if (!x0213_f && is_ibmext_in_sjis(c2)){
Packit 5b6b86
	val = shiftjis_x0212[c2 - 0xfa][c1 - 0x40];
Packit 5b6b86
	if (val){
Packit 5b6b86
	    if (val > 0x7FFF){
Packit 5b6b86
		c2 = PREFIX_EUCG3 | ((val >> 8) & 0x7f);
Packit 5b6b86
		c1 = val & 0xff;
Packit 5b6b86
	    }else{
Packit 5b6b86
		c2 = val >> 8;
Packit 5b6b86
		c1 = val & 0xff;
Packit 5b6b86
	    }
Packit 5b6b86
	    if (p2) *p2 = c2;
Packit 5b6b86
	    if (p1) *p1 = c1;
Packit 5b6b86
	    return 0;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
#endif
Packit 5b6b86
    if(c2 >= 0x80){
Packit 5b6b86
	if(x0213_f && c2 >= 0xF0){
Packit 5b6b86
	    if(c2 <= 0xF3 || (c2 == 0xF4 && c1 < 0x9F)){ /* k=1, 3<=k<=5, k=8, 12<=k<=15 */
Packit 5b6b86
		c2 = PREFIX_EUCG3 | 0x20 | shift_jisx0213_s1a3_table[c2 - 0xF0][0x9E < c1];
Packit 5b6b86
	    }else{ /* 78<=k<=94 */
Packit 5b6b86
		c2 = PREFIX_EUCG3 | (c2 * 2 - 0x17B);
Packit 5b6b86
		if (0x9E < c1) c2++;
Packit 5b6b86
	    }
Packit 5b6b86
	}else{
Packit 5b6b86
#define         SJ0162  0x00e1          /* 01 - 62 ku offset */
Packit 5b6b86
#define         SJ6394  0x0161          /* 63 - 94 ku offset */
Packit 5b6b86
	    c2 = c2 + c2 - ((c2 <= 0x9F) ? SJ0162 : SJ6394);
Packit 5b6b86
	    if (0x9E < c1) c2++;
Packit 5b6b86
	}
Packit 5b6b86
	if (c1 < 0x9F)
Packit 5b6b86
	    c1 = c1 - ((c1 > DEL) ? SP : 0x1F);
Packit 5b6b86
	else {
Packit 5b6b86
	    c1 = c1 - 0x7E;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    c2 = x0212_unshift(c2);
Packit 5b6b86
#endif
Packit 5b6b86
    if (p2) *p2 = c2;
Packit 5b6b86
    if (p1) *p1 = c1;
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#if defined(UTF8_INPUT_ENABLE) || defined(UTF8_OUTPUT_ENABLE)
Packit 5b6b86
static void
Packit 5b6b86
nkf_unicode_to_utf8(nkf_char val, nkf_char *p1, nkf_char *p2, nkf_char *p3, nkf_char *p4)
Packit 5b6b86
{
Packit 5b6b86
    val &= VALUE_MASK;
Packit 5b6b86
    if (val < 0x80){
Packit 5b6b86
	*p1 = val;
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p3 = 0;
Packit 5b6b86
	*p4 = 0;
Packit 5b6b86
    }else if (val < 0x800){
Packit 5b6b86
	*p1 = 0xc0 | (val >> 6);
Packit 5b6b86
	*p2 = 0x80 | (val & 0x3f);
Packit 5b6b86
	*p3 = 0;
Packit 5b6b86
	*p4 = 0;
Packit 5b6b86
    } else if (nkf_char_unicode_bmp_p(val)) {
Packit 5b6b86
	*p1 = 0xe0 |  (val >> 12);
Packit 5b6b86
	*p2 = 0x80 | ((val >>  6) & 0x3f);
Packit 5b6b86
	*p3 = 0x80 | ( val        & 0x3f);
Packit 5b6b86
	*p4 = 0;
Packit 5b6b86
    } else if (nkf_char_unicode_value_p(val)) {
Packit 5b6b86
	*p1 = 0xf0 |  (val >> 18);
Packit 5b6b86
	*p2 = 0x80 | ((val >> 12) & 0x3f);
Packit 5b6b86
	*p3 = 0x80 | ((val >>  6) & 0x3f);
Packit 5b6b86
	*p4 = 0x80 | ( val        & 0x3f);
Packit 5b6b86
    } else {
Packit 5b6b86
	*p1 = 0;
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p3 = 0;
Packit 5b6b86
	*p4 = 0;
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
nkf_utf8_to_unicode(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
    if (c1 <= 0x7F) {
Packit 5b6b86
	/* single byte */
Packit 5b6b86
	wc = c1;
Packit 5b6b86
    }
Packit 5b6b86
    else if (c1 <= 0xC1) {
Packit 5b6b86
	/* trail byte or invalid */
Packit 5b6b86
	return -1;
Packit 5b6b86
    }
Packit 5b6b86
    else if (c1 <= 0xDF) {
Packit 5b6b86
	/* 2 bytes */
Packit 5b6b86
	wc  = (c1 & 0x1F) << 6;
Packit 5b6b86
	wc |= (c2 & 0x3F);
Packit 5b6b86
    }
Packit 5b6b86
    else if (c1 <= 0xEF) {
Packit 5b6b86
	/* 3 bytes */
Packit 5b6b86
	wc  = (c1 & 0x0F) << 12;
Packit 5b6b86
	wc |= (c2 & 0x3F) << 6;
Packit 5b6b86
	wc |= (c3 & 0x3F);
Packit 5b6b86
    }
Packit 5b6b86
    else if (c2 <= 0xF4) {
Packit 5b6b86
	/* 4 bytes */
Packit 5b6b86
	wc  = (c1 & 0x0F) << 18;
Packit 5b6b86
	wc |= (c2 & 0x3F) << 12;
Packit 5b6b86
	wc |= (c3 & 0x3F) << 6;
Packit 5b6b86
	wc |= (c4 & 0x3F);
Packit 5b6b86
    }
Packit 5b6b86
    else {
Packit 5b6b86
	return -1;
Packit 5b6b86
    }
Packit 5b6b86
    return wc;
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
static int
Packit 5b6b86
unicode_to_jis_common2(nkf_char c1, nkf_char c0,
Packit 5b6b86
		       const unsigned short *const *pp, nkf_char psize,
Packit 5b6b86
		       nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c2;
Packit 5b6b86
    const unsigned short *p;
Packit 5b6b86
    unsigned short val;
Packit 5b6b86
Packit 5b6b86
    if (pp == 0) return 1;
Packit 5b6b86
Packit 5b6b86
    c1 -= 0x80;
Packit 5b6b86
    if (c1 < 0 || psize <= c1) return 1;
Packit 5b6b86
    p = pp[c1];
Packit 5b6b86
    if (p == 0)  return 1;
Packit 5b6b86
Packit 5b6b86
    c0 -= 0x80;
Packit 5b6b86
    if (c0 < 0 || sizeof_utf8_to_euc_C2 <= c0) return 1;
Packit 5b6b86
    val = p[c0];
Packit 5b6b86
    if (val == 0) return 1;
Packit 5b6b86
    if (no_cp932ext_f && (
Packit 5b6b86
			  (val>>8) == 0x2D || /* NEC special characters */
Packit 5b6b86
			  val > NKF_INT32_C(0xF300) /* IBM extended characters */
Packit 5b6b86
			 )) return 1;
Packit 5b6b86
Packit 5b6b86
    c2 = val >> 8;
Packit 5b6b86
    if (val > 0x7FFF){
Packit 5b6b86
	c2 &= 0x7f;
Packit 5b6b86
	c2 |= PREFIX_EUCG3;
Packit 5b6b86
    }
Packit 5b6b86
    if (c2 == SO) c2 = JIS_X_0201_1976_K;
Packit 5b6b86
    c1 = val & 0xFF;
Packit 5b6b86
    if (p2) *p2 = c2;
Packit 5b6b86
    if (p1) *p1 = c1;
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
unicode_to_jis_common(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
    const unsigned short *const *pp;
Packit 5b6b86
    const unsigned short *const *const *ppp;
Packit 5b6b86
    static const char no_best_fit_chars_table_C2[] =
Packit 5b6b86
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 1, 2,
Packit 5b6b86
	0, 0, 1, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1};
Packit 5b6b86
    static const char no_best_fit_chars_table_C2_ms[] =
Packit 5b6b86
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0,
Packit 5b6b86
	0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0};
Packit 5b6b86
    static const char no_best_fit_chars_table_932_C2[] =
Packit 5b6b86
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0};
Packit 5b6b86
    static const char no_best_fit_chars_table_932_C3[] =
Packit 5b6b86
    {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Packit 5b6b86
	1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1};
Packit 5b6b86
    nkf_char ret = 0;
Packit 5b6b86
Packit 5b6b86
    if(c2 < 0x80){
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p1 = c2;
Packit 5b6b86
    }else if(c2 < 0xe0){
Packit 5b6b86
	if(no_best_fit_chars_f){
Packit 5b6b86
	    if(ms_ucs_map_f == UCS_MAP_CP932){
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xC2:
Packit 5b6b86
		    if(no_best_fit_chars_table_932_C2[c1&0x3F]) return 1;
Packit 5b6b86
		    break;
Packit 5b6b86
		case 0xC3:
Packit 5b6b86
		    if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }else if(!cp932inv_f){
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xC2:
Packit 5b6b86
		    if(no_best_fit_chars_table_C2[c1&0x3F]) return 1;
Packit 5b6b86
		    break;
Packit 5b6b86
		case 0xC3:
Packit 5b6b86
		    if(no_best_fit_chars_table_932_C3[c1&0x3F]) return 1;
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }else if(ms_ucs_map_f == UCS_MAP_MS){
Packit 5b6b86
		if(c2 == 0xC2 && no_best_fit_chars_table_C2_ms[c1&0x3F]) return 1;
Packit 5b6b86
	    }else if(ms_ucs_map_f == UCS_MAP_CP10001){
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xC2:
Packit 5b6b86
		    switch(c1){
Packit 5b6b86
		    case 0xA2:
Packit 5b6b86
		    case 0xA3:
Packit 5b6b86
		    case 0xA5:
Packit 5b6b86
		    case 0xA6:
Packit 5b6b86
		    case 0xAC:
Packit 5b6b86
		    case 0xAF:
Packit 5b6b86
		    case 0xB8:
Packit 5b6b86
			return 1;
Packit 5b6b86
		    }
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
	pp =
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_2bytes_932 :
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_2bytes_ms :
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_2bytes_mac :
Packit 5b6b86
	    x0213_f ? utf8_to_euc_2bytes_x0213 :
Packit 5b6b86
	    utf8_to_euc_2bytes;
Packit 5b6b86
	ret =  unicode_to_jis_common2(c2, c1, pp, sizeof_utf8_to_euc_2bytes, p2, p1);
Packit 5b6b86
    }else if(c0 < 0xF0){
Packit 5b6b86
	if(no_best_fit_chars_f){
Packit 5b6b86
	    if(ms_ucs_map_f == UCS_MAP_CP932){
Packit 5b6b86
		if(c2 == 0xE3 && c1 == 0x82 && c0 == 0x94) return 1;
Packit 5b6b86
	    }else if(ms_ucs_map_f == UCS_MAP_MS){
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xE2:
Packit 5b6b86
		    switch(c1){
Packit 5b6b86
		    case 0x80:
Packit 5b6b86
			if(c0 == 0x94 || c0 == 0x96 || c0 == 0xBE) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    case 0x88:
Packit 5b6b86
			if(c0 == 0x92) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    }
Packit 5b6b86
		    break;
Packit 5b6b86
		case 0xE3:
Packit 5b6b86
		    if(c1 == 0x80 || c0 == 0x9C) return 1;
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }else if(ms_ucs_map_f == UCS_MAP_CP10001){
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xE3:
Packit 5b6b86
		    switch(c1){
Packit 5b6b86
		    case 0x82:
Packit 5b6b86
			if(c0 == 0x94) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    case 0x83:
Packit 5b6b86
			if(c0 == 0xBB) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    }
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }else{
Packit 5b6b86
		switch(c2){
Packit 5b6b86
		case 0xE2:
Packit 5b6b86
		    switch(c1){
Packit 5b6b86
		    case 0x80:
Packit 5b6b86
			if(c0 == 0x95) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    case 0x88:
Packit 5b6b86
			if(c0 == 0xA5) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    }
Packit 5b6b86
		    break;
Packit 5b6b86
		case 0xEF:
Packit 5b6b86
		    switch(c1){
Packit 5b6b86
		    case 0xBC:
Packit 5b6b86
			if(c0 == 0x8D) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    case 0xBD:
Packit 5b6b86
			if(c0 == 0x9E && !cp932inv_f) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    case 0xBF:
Packit 5b6b86
			if(0xA0 <= c0 && c0 <= 0xA5) return 1;
Packit 5b6b86
			break;
Packit 5b6b86
		    }
Packit 5b6b86
		    break;
Packit 5b6b86
		}
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
	ppp =
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_CP932 ? utf8_to_euc_3bytes_932 :
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_MS ? utf8_to_euc_3bytes_ms :
Packit 5b6b86
	    ms_ucs_map_f == UCS_MAP_CP10001 ? utf8_to_euc_3bytes_mac :
Packit 5b6b86
	    x0213_f ? utf8_to_euc_3bytes_x0213 :
Packit 5b6b86
	    utf8_to_euc_3bytes;
Packit 5b6b86
	ret = unicode_to_jis_common2(c1, c0, ppp[c2 - 0xE0], sizeof_utf8_to_euc_C2, p2, p1);
Packit 5b6b86
    }else return -1;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
    if (!ret && !cp932inv_f && is_eucg3(*p2)) {
Packit 5b6b86
	nkf_char s2, s1;
Packit 5b6b86
	if (e2s_conv(*p2, *p1, &s2, &s1) == 0) {
Packit 5b6b86
	    s2e_conv(s2, s1, p2, p1);
Packit 5b6b86
	}else{
Packit 5b6b86
	    ret = 1;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
#endif
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
#define X0213_SURROGATE_FIND(tbl, size, euc) do { \
Packit 5b6b86
	int i; \
Packit 5b6b86
	for (i = 0; i < size; i++) \
Packit 5b6b86
	    if (tbl[i][0] == euc) { \
Packit 5b6b86
		low = tbl[i][2]; \
Packit 5b6b86
		break; \
Packit 5b6b86
	    } \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
e2w_conv(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    const unsigned short *p;
Packit 5b6b86
Packit 5b6b86
    if (c2 == JIS_X_0201_1976_K) {
Packit 5b6b86
	if (ms_ucs_map_f == UCS_MAP_CP10001) {
Packit 5b6b86
	    switch (c1) {
Packit 5b6b86
	    case 0x20:
Packit 5b6b86
		return 0xA0;
Packit 5b6b86
	    case 0x7D:
Packit 5b6b86
		return 0xA9;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
	p = euc_to_utf8_1byte;
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    } else if (is_eucg3(c2)){
Packit 5b6b86
	if(ms_ucs_map_f == UCS_MAP_ASCII&& c2 == NKF_INT32_C(0x8F22) && c1 == 0x43){
Packit 5b6b86
	    return 0xA6;
Packit 5b6b86
	}
Packit 5b6b86
	c2 = (c2&0x7f) - 0x21;
Packit 5b6b86
	if (0<=c2 && c2
Packit 5b6b86
	    p =
Packit 5b6b86
		x0213_f ? x0212_to_utf8_2bytes_x0213[c2] :
Packit 5b6b86
		x0212_to_utf8_2bytes[c2];
Packit 5b6b86
	else
Packit 5b6b86
	    return 0;
Packit 5b6b86
#endif
Packit 5b6b86
    } else {
Packit 5b6b86
	c2 &= 0x7f;
Packit 5b6b86
	c2 = (c2&0x7f) - 0x21;
Packit 5b6b86
	if (0<=c2 && c2
Packit 5b6b86
	    p =
Packit 5b6b86
		x0213_f ? euc_to_utf8_2bytes_x0213[c2] :
Packit 5b6b86
		ms_ucs_map_f == UCS_MAP_ASCII ? euc_to_utf8_2bytes[c2] :
Packit 5b6b86
		ms_ucs_map_f == UCS_MAP_CP10001 ? euc_to_utf8_2bytes_mac[c2] :
Packit 5b6b86
		euc_to_utf8_2bytes_ms[c2];
Packit 5b6b86
	else
Packit 5b6b86
	    return 0;
Packit 5b6b86
    }
Packit 5b6b86
    if (!p) return 0;
Packit 5b6b86
    c1 = (c1 & 0x7f) - 0x21;
Packit 5b6b86
    if (0<=c1 && c1
Packit 5b6b86
	nkf_char val = p[c1];
Packit 5b6b86
	if (x0213_f && 0xD800<=val && val<=0xDBFF) {
Packit 5b6b86
	    nkf_char euc = (c2+0x21)<<8 | (c1+0x21);
Packit 5b6b86
	    nkf_char low = 0;
Packit 5b6b86
	    if (p==x0212_to_utf8_2bytes_x0213[c2]) {
Packit 5b6b86
		X0213_SURROGATE_FIND(x0213_2_surrogate_table, sizeof_x0213_2_surrogate_table, euc);
Packit 5b6b86
	    } else {
Packit 5b6b86
		X0213_SURROGATE_FIND(x0213_1_surrogate_table, sizeof_x0213_1_surrogate_table, euc);
Packit 5b6b86
	    }
Packit 5b6b86
	    if (!low) return 0;
Packit 5b6b86
	    return UTF16_TO_UTF32(val, low);
Packit 5b6b86
	} else {
Packit 5b6b86
	    return val;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
e2w_combining(nkf_char comb, nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char euc;
Packit 5b6b86
    int i;
Packit 5b6b86
    for (i = 0; i < sizeof_x0213_combining_chars; i++)
Packit 5b6b86
	if (x0213_combining_chars[i] == comb)
Packit 5b6b86
	    break;
Packit 5b6b86
    if (i >= sizeof_x0213_combining_chars)
Packit 5b6b86
	return 0;
Packit 5b6b86
    euc = (c2&0x7f)<<8 | (c1&0x7f);
Packit 5b6b86
    for (i = 0; i < sizeof_x0213_combining_table; i++)
Packit 5b6b86
	if (x0213_combining_table[i][0] == euc)
Packit 5b6b86
	    return x0213_combining_table[i][1];
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w2e_conv(nkf_char c2, nkf_char c1, nkf_char c0, nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char ret = 0;
Packit 5b6b86
Packit 5b6b86
    if (!c1){
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p1 = c2;
Packit 5b6b86
    }else if (0xc0 <= c2 && c2 <= 0xef) {
Packit 5b6b86
	ret =  unicode_to_jis_common(c2, c1, c0, p2, p1);
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
	if (ret > 0){
Packit 5b6b86
	    if (p2) *p2 = 0;
Packit 5b6b86
	    if (p1) *p1 = nkf_char_unicode_new(nkf_utf8_to_unicode(c2, c1, c0, 0));
Packit 5b6b86
	    ret = 0;
Packit 5b6b86
	}
Packit 5b6b86
#endif
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
static nkf_char
Packit 5b6b86
w16e_conv(nkf_char val, nkf_char *p2, nkf_char *p1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c1, c2, c3, c4;
Packit 5b6b86
    nkf_char ret = 0;
Packit 5b6b86
    val &= VALUE_MASK;
Packit 5b6b86
    if (val < 0x80) {
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p1 = val;
Packit 5b6b86
    }
Packit 5b6b86
    else if (nkf_char_unicode_bmp_p(val)){
Packit 5b6b86
	nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4;;
Packit 5b6b86
	ret =  unicode_to_jis_common(c1, c2, c3, p2, p1);
Packit 5b6b86
	if (ret > 0){
Packit 5b6b86
	    *p2 = 0;
Packit 5b6b86
	    *p1 = nkf_char_unicode_new(val);
Packit 5b6b86
	    ret = 0;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    else {
Packit 5b6b86
	int i;
Packit 5b6b86
	if (x0213_f) {
Packit 5b6b86
	    c1 = (val >> 10) + NKF_INT32_C(0xD7C0);   /* high surrogate */
Packit 5b6b86
	    c2 = (val & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */
Packit 5b6b86
	    for (i = 0; i < sizeof_x0213_1_surrogate_table; i++)
Packit 5b6b86
		if (x0213_1_surrogate_table[i][1] == c1 && x0213_1_surrogate_table[i][2] == c2) {
Packit 5b6b86
		    val = x0213_1_surrogate_table[i][0];
Packit 5b6b86
		    *p2 = val >> 8;
Packit 5b6b86
		    *p1 = val & 0xFF;
Packit 5b6b86
		    return 0;
Packit 5b6b86
		}
Packit 5b6b86
	    for (i = 0; i < sizeof_x0213_2_surrogate_table; i++)
Packit 5b6b86
		if (x0213_2_surrogate_table[i][1] == c1 && x0213_2_surrogate_table[i][2] == c2) {
Packit 5b6b86
		    val = x0213_2_surrogate_table[i][0];
Packit 5b6b86
		    *p2 = PREFIX_EUCG3 | (val >> 8);
Packit 5b6b86
		    *p1 = val & 0xFF;
Packit 5b6b86
		    return 0;
Packit 5b6b86
		}
Packit 5b6b86
	}
Packit 5b6b86
	*p2 = 0;
Packit 5b6b86
	*p1 = nkf_char_unicode_new(val);
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
e_iconv(nkf_char c2, nkf_char c1, nkf_char c0)
Packit 5b6b86
{
Packit 5b6b86
    if (c2 == JIS_X_0201_1976_K || c2 == SS2){
Packit 5b6b86
	if (iso2022jp_f && !x0201_f) {
Packit 5b6b86
	    c2 = GETA1; c1 = GETA2;
Packit 5b6b86
	} else {
Packit 5b6b86
	    c2 = JIS_X_0201_1976_K;
Packit 5b6b86
	    c1 &= 0x7f;
Packit 5b6b86
	}
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    }else if (c2 == 0x8f){
Packit 5b6b86
	if (c0 == 0){
Packit 5b6b86
	    return -1;
Packit 5b6b86
	}
Packit 5b6b86
	if (!cp51932_f && !x0213_f && 0xF5 <= c1 && c1 <= 0xFE && 0xA1 <= c0 && c0 <= 0xFE) {
Packit 5b6b86
	    /* encoding is eucJP-ms, so invert to Unicode Private User Area */
Packit 5b6b86
	    c1 = nkf_char_unicode_new((c1 - 0xF5) * 94 + c0 - 0xA1 + 0xE3AC);
Packit 5b6b86
	    c2 = 0;
Packit 5b6b86
	} else {
Packit 5b6b86
	    c2 = (c2 << 8) | (c1 & 0x7f);
Packit 5b6b86
	    c1 = c0 & 0x7f;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	    if (cp51932_f){
Packit 5b6b86
		nkf_char s2, s1;
Packit 5b6b86
		if (e2s_conv(c2, c1, &s2, &s1) == 0){
Packit 5b6b86
		    s2e_conv(s2, s1, &c2, &c1;;
Packit 5b6b86
		    if (c2 < 0x100){
Packit 5b6b86
			c1 &= 0x7f;
Packit 5b6b86
			c2 &= 0x7f;
Packit 5b6b86
		    }
Packit 5b6b86
		}
Packit 5b6b86
	    }
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
	}
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
    } else if ((c2 == EOF) || (c2 == 0) || c2 < SP || c2 == ISO_8859_1) {
Packit 5b6b86
	/* NOP */
Packit 5b6b86
    } else {
Packit 5b6b86
	if (!cp51932_f && ms_ucs_map_f && 0xF5 <= c2 && c2 <= 0xFE && 0xA1 <= c1 && c1 <= 0xFE) {
Packit 5b6b86
	    /* encoding is eucJP-ms, so invert to Unicode Private User Area */
Packit 5b6b86
	    c1 = nkf_char_unicode_new((c2 - 0xF5) * 94 + c1 - 0xA1 + 0xE000);
Packit 5b6b86
	    c2 = 0;
Packit 5b6b86
	} else {
Packit 5b6b86
	    c1 &= 0x7f;
Packit 5b6b86
	    c2 &= 0x7f;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	    if (cp51932_f && 0x79 <= c2 && c2 <= 0x7c){
Packit 5b6b86
		nkf_char s2, s1;
Packit 5b6b86
		if (e2s_conv(c2, c1, &s2, &s1) == 0){
Packit 5b6b86
		    s2e_conv(s2, s1, &c2, &c1;;
Packit 5b6b86
		    if (c2 < 0x100){
Packit 5b6b86
			c1 &= 0x7f;
Packit 5b6b86
			c2 &= 0x7f;
Packit 5b6b86
		    }
Packit 5b6b86
		}
Packit 5b6b86
	    }
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    (*oconv)(c2, c1);
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
s_iconv(ARG_UNUSED nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0)
Packit 5b6b86
{
Packit 5b6b86
    if (c2 == JIS_X_0201_1976_K || (0xA1 <= c2 && c2 <= 0xDF)) {
Packit 5b6b86
	if (iso2022jp_f && !x0201_f) {
Packit 5b6b86
	    c2 = GETA1; c1 = GETA2;
Packit 5b6b86
	} else {
Packit 5b6b86
	    c1 &= 0x7f;
Packit 5b6b86
	}
Packit 5b6b86
    } else if ((c2 == EOF) || (c2 == 0) || c2 < SP) {
Packit 5b6b86
	/* NOP */
Packit 5b6b86
    } else if (!x0213_f && 0xF0 <= c2 && c2 <= 0xF9 && 0x40 <= c1 && c1 <= 0xFC) {
Packit 5b6b86
	/* CP932 UDC */
Packit 5b6b86
	if(c1 == 0x7F) return 0;
Packit 5b6b86
	c1 = nkf_char_unicode_new((c2 - 0xF0) * 188 + (c1 - 0x40 - (0x7E < c1)) + 0xE000);
Packit 5b6b86
	c2 = 0;
Packit 5b6b86
    } else {
Packit 5b6b86
	nkf_char ret = s2e_conv(c2, c1, &c2, &c1;;
Packit 5b6b86
	if (ret) return ret;
Packit 5b6b86
    }
Packit 5b6b86
    (*oconv)(c2, c1);
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
x0213_wait_combining_p(nkf_char wc)
Packit 5b6b86
{
Packit 5b6b86
    int i;
Packit 5b6b86
    for (i = 0; i < sizeof_x0213_combining_table; i++) {
Packit 5b6b86
	if (x0213_combining_table[i][1] == wc) {
Packit 5b6b86
	    return TRUE;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return FALSE;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
x0213_combining_p(nkf_char wc)
Packit 5b6b86
{
Packit 5b6b86
    int i;
Packit 5b6b86
    for (i = 0; i < sizeof_x0213_combining_chars; i++) {
Packit 5b6b86
	if (x0213_combining_chars[i] == wc) {
Packit 5b6b86
	    return TRUE;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    return FALSE;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w_iconv(nkf_char c1, nkf_char c2, nkf_char c3)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char ret = 0, c4 = 0;
Packit 5b6b86
    static const char w_iconv_utf8_1st_byte[] =
Packit 5b6b86
    { /* 0xC0 - 0xFF */
Packit 5b6b86
	20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
Packit 5b6b86
	21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
Packit 5b6b86
	30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 33, 33,
Packit 5b6b86
	40, 41, 41, 41, 42, 43, 43, 43, 50, 50, 50, 50, 60, 60, 70, 70};
Packit 5b6b86
Packit 5b6b86
    if (c3 > 0xFF) {
Packit 5b6b86
	c4 = c3 & 0xFF;
Packit 5b6b86
	c3 >>= 8;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c1 < 0 || 0xff < c1) {
Packit 5b6b86
    }else if (c1 == 0) { /* 0 : 1 byte*/
Packit 5b6b86
	c3 = 0;
Packit 5b6b86
    } else if ((c1 & 0xC0) == 0x80) { /* 0x80-0xbf : trail byte */
Packit 5b6b86
	return 0;
Packit 5b6b86
    } else{
Packit 5b6b86
	switch (w_iconv_utf8_1st_byte[c1 - 0xC0]) {
Packit 5b6b86
	case 21:
Packit 5b6b86
	    if (c2 < 0x80 || 0xBF < c2) return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 30:
Packit 5b6b86
	    if (c3 == 0) return -1;
Packit 5b6b86
	    if (c2 < 0xA0 || 0xBF < c2 || (c3 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 31:
Packit 5b6b86
	case 33:
Packit 5b6b86
	    if (c3 == 0) return -1;
Packit 5b6b86
	    if ((c2 & 0xC0) != 0x80 || (c3 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 32:
Packit 5b6b86
	    if (c3 == 0) return -1;
Packit 5b6b86
	    if (c2 < 0x80 || 0x9F < c2 || (c3 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 40:
Packit 5b6b86
	    if (c3 == 0) return -2;
Packit 5b6b86
	    if (c2 < 0x90 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 41:
Packit 5b6b86
	    if (c3 == 0) return -2;
Packit 5b6b86
	    if (c2 < 0x80 || 0xBF < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	case 42:
Packit 5b6b86
	    if (c3 == 0) return -2;
Packit 5b6b86
	    if (c2 < 0x80 || 0x8F < c2 || (c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
Packit 5b6b86
		return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	default:
Packit 5b6b86
	    return 0;
Packit 5b6b86
	    break;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
    if (c1 == 0 || c1 == EOF){
Packit 5b6b86
    } else if ((c1 & 0xf8) == 0xf0) { /* 4 bytes */
Packit 5b6b86
	c2 = nkf_char_unicode_new(nkf_utf8_to_unicode(c1, c2, c3, c4));
Packit 5b6b86
	c1 = 0;
Packit 5b6b86
    } else {
Packit 5b6b86
	if (x0213_f && x0213_wait_combining_p(nkf_utf8_to_unicode(c1, c2, c3, c4)))
Packit 5b6b86
	    return -3;
Packit 5b6b86
	ret = w2e_conv(c1, c2, c3, &c1, &c2;;
Packit 5b6b86
    }
Packit 5b6b86
    if (ret == 0){
Packit 5b6b86
	(*oconv)(c1, c2);
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w_iconv_nocombine(nkf_char c1, nkf_char c2, nkf_char c3)
Packit 5b6b86
{
Packit 5b6b86
    /* continue from the line below 'return -3;' in w_iconv() */
Packit 5b6b86
    nkf_char ret = w2e_conv(c1, c2, c3, &c1, &c2;;
Packit 5b6b86
    if (ret == 0){
Packit 5b6b86
	(*oconv)(c1, c2);
Packit 5b6b86
    }
Packit 5b6b86
    return ret;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define NKF_ICONV_INVALID_CODE_RANGE -13
Packit 5b6b86
#define NKF_ICONV_WAIT_COMBINING_CHAR -14
Packit 5b6b86
#define NKF_ICONV_NOT_COMBINED -15
Packit 5b6b86
static size_t
Packit 5b6b86
unicode_iconv(nkf_char wc, int nocombine)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c1, c2;
Packit 5b6b86
    int ret = 0;
Packit 5b6b86
Packit 5b6b86
    if (wc < 0x80) {
Packit 5b6b86
	c2 = 0;
Packit 5b6b86
	c1 = wc;
Packit 5b6b86
    }else if ((wc>>11) == 27) {
Packit 5b6b86
	/* unpaired surrogate */
Packit 5b6b86
	return NKF_ICONV_INVALID_CODE_RANGE;
Packit 5b6b86
    }else if (wc < 0xFFFF) {
Packit 5b6b86
	if (!nocombine && x0213_f && x0213_wait_combining_p(wc))
Packit 5b6b86
	    return NKF_ICONV_WAIT_COMBINING_CHAR;
Packit 5b6b86
	ret = w16e_conv(wc, &c2, &c1;;
Packit 5b6b86
	if (ret) return ret;
Packit 5b6b86
    }else if (wc < 0x10FFFF) {
Packit 5b6b86
	c2 = 0;
Packit 5b6b86
	c1 = nkf_char_unicode_new(wc);
Packit 5b6b86
    } else {
Packit 5b6b86
	return NKF_ICONV_INVALID_CODE_RANGE;
Packit 5b6b86
    }
Packit 5b6b86
    (*oconv)(c2, c1);
Packit 5b6b86
    return 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
unicode_iconv_combine(nkf_char wc, nkf_char wc2)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c1, c2;
Packit 5b6b86
    int i;
Packit 5b6b86
Packit 5b6b86
    if (wc2 < 0x80) {
Packit 5b6b86
	return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
    }else if ((wc2>>11) == 27) {
Packit 5b6b86
	/* unpaired surrogate */
Packit 5b6b86
	return NKF_ICONV_INVALID_CODE_RANGE;
Packit 5b6b86
    }else if (wc2 < 0xFFFF) {
Packit 5b6b86
	if (!x0213_combining_p(wc2))
Packit 5b6b86
	    return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
	for (i = 0; i < sizeof_x0213_combining_table; i++) {
Packit 5b6b86
	    if (x0213_combining_table[i][1] == wc &&
Packit 5b6b86
		x0213_combining_table[i][2] == wc2) {
Packit 5b6b86
		c2 = x0213_combining_table[i][0] >> 8;
Packit 5b6b86
		c1 = x0213_combining_table[i][0] & 0x7f;
Packit 5b6b86
		(*oconv)(c2, c1);
Packit 5b6b86
		return 0;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
    }else if (wc2 < 0x10FFFF) {
Packit 5b6b86
	return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
    } else {
Packit 5b6b86
	return NKF_ICONV_INVALID_CODE_RANGE;
Packit 5b6b86
    }
Packit 5b6b86
    return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w_iconv_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4, nkf_char c5, nkf_char c6)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc, wc2;
Packit 5b6b86
    wc = nkf_utf8_to_unicode(c1, c2, c3, 0);
Packit 5b6b86
    wc2 = nkf_utf8_to_unicode(c4, c5, c6, 0);
Packit 5b6b86
    if (wc2 < 0)
Packit 5b6b86
	return wc2;
Packit 5b6b86
    return unicode_iconv_combine(wc, wc2);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define NKF_ICONV_NEED_ONE_MORE_BYTE (size_t)-1
Packit 5b6b86
#define NKF_ICONV_NEED_TWO_MORE_BYTES (size_t)-2
Packit 5b6b86
static size_t
Packit 5b6b86
nkf_iconv_utf_16(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
Packit 5b6b86
    if (c1 == EOF) {
Packit 5b6b86
	(*oconv)(EOF, 0);
Packit 5b6b86
	return 0;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (input_endian == ENDIAN_BIG) {
Packit 5b6b86
	if (0xD8 <= c1 && c1 <= 0xDB) {
Packit 5b6b86
	    if (0xDC <= c3 && c3 <= 0xDF) {
Packit 5b6b86
		wc = UTF16_TO_UTF32(c1 << 8 | c2, c3 << 8 | c4);
Packit 5b6b86
	    } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
Packit 5b6b86
	} else {
Packit 5b6b86
	    wc = c1 << 8 | c2;
Packit 5b6b86
	}
Packit 5b6b86
    } else {
Packit 5b6b86
	if (0xD8 <= c2 && c2 <= 0xDB) {
Packit 5b6b86
	    if (0xDC <= c4 && c4 <= 0xDF) {
Packit 5b6b86
		wc = UTF16_TO_UTF32(c2 << 8 | c1, c4 << 8 | c3);
Packit 5b6b86
	    } else return NKF_ICONV_NEED_TWO_MORE_BYTES;
Packit 5b6b86
	} else {
Packit 5b6b86
	    wc = c2 << 8 | c1;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    return (*unicode_iconv)(wc, FALSE);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static size_t
Packit 5b6b86
nkf_iconv_utf_16_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc, wc2;
Packit 5b6b86
Packit 5b6b86
    if (input_endian == ENDIAN_BIG) {
Packit 5b6b86
	if (0xD8 <= c3 && c3 <= 0xDB) {
Packit 5b6b86
	    return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
	} else {
Packit 5b6b86
	    wc = c1 << 8 | c2;
Packit 5b6b86
	    wc2 = c3 << 8 | c4;
Packit 5b6b86
	}
Packit 5b6b86
    } else {
Packit 5b6b86
	if (0xD8 <= c2 && c2 <= 0xDB) {
Packit 5b6b86
	    return NKF_ICONV_NOT_COMBINED;
Packit 5b6b86
	} else {
Packit 5b6b86
	    wc = c2 << 8 | c1;
Packit 5b6b86
	    wc2 = c4 << 8 | c3;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    return unicode_iconv_combine(wc, wc2);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static size_t
Packit 5b6b86
nkf_iconv_utf_16_nocombine(nkf_char c1, nkf_char c2)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
    if (input_endian == ENDIAN_BIG)
Packit 5b6b86
	wc = c1 << 8 | c2;
Packit 5b6b86
    else
Packit 5b6b86
	wc = c2 << 8 | c1;
Packit 5b6b86
    return (*unicode_iconv)(wc, TRUE);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w_iconv16(nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(c2, c1);
Packit 5b6b86
    return 16; /* different from w_iconv32 */
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
w_iconv32(nkf_char c2, nkf_char c1, ARG_UNUSED nkf_char c0)
Packit 5b6b86
{
Packit 5b6b86
    (*oconv)(c2, c1);
Packit 5b6b86
    return 32; /* different from w_iconv16 */
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
utf32_to_nkf_char(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
Packit 5b6b86
    switch(input_endian){
Packit 5b6b86
    case ENDIAN_BIG:
Packit 5b6b86
	wc = c2 << 16 | c3 << 8 | c4;
Packit 5b6b86
	break;
Packit 5b6b86
    case ENDIAN_LITTLE:
Packit 5b6b86
	wc = c3 << 16 | c2 << 8 | c1;
Packit 5b6b86
	break;
Packit 5b6b86
    case ENDIAN_2143:
Packit 5b6b86
	wc = c1 << 16 | c4 << 8 | c3;
Packit 5b6b86
	break;
Packit 5b6b86
    case ENDIAN_3412:
Packit 5b6b86
	wc = c4 << 16 | c1 << 8 | c2;
Packit 5b6b86
	break;
Packit 5b6b86
    default:
Packit 5b6b86
	return NKF_ICONV_INVALID_CODE_RANGE;
Packit 5b6b86
    }
Packit 5b6b86
    return wc;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static size_t
Packit 5b6b86
nkf_iconv_utf_32(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
Packit 5b6b86
    if (c1 == EOF) {
Packit 5b6b86
	(*oconv)(EOF, 0);
Packit 5b6b86
	return 0;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    wc = utf32_to_nkf_char(c1, c2, c3, c4);
Packit 5b6b86
    if (wc < 0)
Packit 5b6b86
	return wc;
Packit 5b6b86
Packit 5b6b86
    return (*unicode_iconv)(wc, FALSE);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
nkf_iconv_utf_32_combine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4, nkf_char c5, nkf_char c6, nkf_char c7, nkf_char c8)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc, wc2;
Packit 5b6b86
Packit 5b6b86
    wc = utf32_to_nkf_char(c1, c2, c3, c4);
Packit 5b6b86
    if (wc < 0)
Packit 5b6b86
	return wc;
Packit 5b6b86
    wc2 = utf32_to_nkf_char(c5, c6, c7, c8);
Packit 5b6b86
    if (wc2 < 0)
Packit 5b6b86
	return wc2;
Packit 5b6b86
Packit 5b6b86
    return unicode_iconv_combine(wc, wc2);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static size_t
Packit 5b6b86
nkf_iconv_utf_32_nocombine(nkf_char c1, nkf_char c2, nkf_char c3, nkf_char c4)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char wc;
Packit 5b6b86
Packit 5b6b86
    wc = utf32_to_nkf_char(c1, c2, c3, c4);
Packit 5b6b86
    return (*unicode_iconv)(wc, TRUE);
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define output_ascii_escape_sequence(mode) do { \
Packit 5b6b86
	    if (output_mode != ASCII && output_mode != ISO_8859_1) { \
Packit 5b6b86
		    (*o_putc)(ESC); \
Packit 5b6b86
		    (*o_putc)('('); \
Packit 5b6b86
		    (*o_putc)(ascii_intro); \
Packit 5b6b86
		    output_mode = mode; \
Packit 5b6b86
	    } \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
output_escape_sequence(int mode)
Packit 5b6b86
{
Packit 5b6b86
    if (output_mode == mode)
Packit 5b6b86
	return;
Packit 5b6b86
    switch(mode) {
Packit 5b6b86
    case ISO_8859_1:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('.');
Packit 5b6b86
	(*o_putc)('A');
Packit 5b6b86
	break;
Packit 5b6b86
    case JIS_X_0201_1976_K:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('(');
Packit 5b6b86
	(*o_putc)('I');
Packit 5b6b86
	break;
Packit 5b6b86
    case JIS_X_0208:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('$');
Packit 5b6b86
	(*o_putc)(kanji_intro);
Packit 5b6b86
	break;
Packit 5b6b86
    case JIS_X_0212:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('$');
Packit 5b6b86
	(*o_putc)('(');
Packit 5b6b86
	(*o_putc)('D');
Packit 5b6b86
	break;
Packit 5b6b86
    case JIS_X_0213_1:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('$');
Packit 5b6b86
	(*o_putc)('(');
Packit 5b6b86
	(*o_putc)('Q');
Packit 5b6b86
	break;
Packit 5b6b86
    case JIS_X_0213_2:
Packit 5b6b86
	(*o_putc)(ESC);
Packit 5b6b86
	(*o_putc)('$');
Packit 5b6b86
	(*o_putc)('(');
Packit 5b6b86
	(*o_putc)('P');
Packit 5b6b86
	break;
Packit 5b6b86
    }
Packit 5b6b86
    output_mode = mode;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
j_oconv(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
    if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	w16e_conv(c1, &c2, &c1;;
Packit 5b6b86
	if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	    c2 = c1 & VALUE_MASK;
Packit 5b6b86
	    if (ms_ucs_map_f && 0xE000 <= c2 && c2 <= 0xE757) {
Packit 5b6b86
		/* CP5022x UDC */
Packit 5b6b86
		c1 &= 0xFFF;
Packit 5b6b86
		c2 = 0x7F + c1 / 94;
Packit 5b6b86
		c1 = 0x21 + c1 % 94;
Packit 5b6b86
	    } else {
Packit 5b6b86
		if (encode_fallback) (*encode_fallback)(c1);
Packit 5b6b86
		return;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
#endif
Packit 5b6b86
    if (c2 == 0) {
Packit 5b6b86
	output_ascii_escape_sequence(ASCII);
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    }
Packit 5b6b86
    else if (c2 == EOF) {
Packit 5b6b86
	output_ascii_escape_sequence(ASCII);
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
    }
Packit 5b6b86
    else if (c2 == ISO_8859_1) {
Packit 5b6b86
	output_ascii_escape_sequence(ISO_8859_1);
Packit 5b6b86
	(*o_putc)(c1|0x80);
Packit 5b6b86
    }
Packit 5b6b86
    else if (c2 == JIS_X_0201_1976_K) {
Packit 5b6b86
	output_escape_sequence(JIS_X_0201_1976_K);
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    } else if (is_eucg3(c2)){
Packit 5b6b86
	output_escape_sequence(x0213_f ? JIS_X_0213_2 : JIS_X_0212);
Packit 5b6b86
	(*o_putc)(c2 & 0x7f);
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
#endif
Packit 5b6b86
    } else {
Packit 5b6b86
	if(ms_ucs_map_f
Packit 5b6b86
	   ? c2<0x20 || 0x92
Packit 5b6b86
	   : c2<0x20 || 0x7e
Packit 5b6b86
	output_escape_sequence(x0213_f ? JIS_X_0213_1 : JIS_X_0208);
Packit 5b6b86
	(*o_putc)(c2);
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
e_oconv(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	w16e_conv(c1, &c2, &c1;;
Packit 5b6b86
	if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	    c2 = c1 & VALUE_MASK;
Packit 5b6b86
	    if (x0212_f && 0xE000 <= c2 && c2 <= 0xE757) {
Packit 5b6b86
		/* eucJP-ms UDC */
Packit 5b6b86
		c1 &= 0xFFF;
Packit 5b6b86
		c2 = c1 / 94;
Packit 5b6b86
		c2 += c2 < 10 ? 0x75 : 0x8FEB;
Packit 5b6b86
		c1 = 0x21 + c1 % 94;
Packit 5b6b86
		if (is_eucg3(c2)){
Packit 5b6b86
		    (*o_putc)(0x8f);
Packit 5b6b86
		    (*o_putc)((c2 & 0x7f) | 0x080);
Packit 5b6b86
		    (*o_putc)(c1 | 0x080);
Packit 5b6b86
		}else{
Packit 5b6b86
		    (*o_putc)((c2 & 0x7f) | 0x080);
Packit 5b6b86
		    (*o_putc)(c1 | 0x080);
Packit 5b6b86
		}
Packit 5b6b86
		return;
Packit 5b6b86
	    } else {
Packit 5b6b86
		if (encode_fallback) (*encode_fallback)(c1);
Packit 5b6b86
		return;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == EOF) {
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
    } else if (c2 == 0) {
Packit 5b6b86
	output_mode = ASCII;
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    } else if (c2 == JIS_X_0201_1976_K) {
Packit 5b6b86
	output_mode = EUC_JP;
Packit 5b6b86
	(*o_putc)(SS2); (*o_putc)(c1|0x80);
Packit 5b6b86
    } else if (c2 == ISO_8859_1) {
Packit 5b6b86
	output_mode = ISO_8859_1;
Packit 5b6b86
	(*o_putc)(c1 | 0x080);
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    } else if (is_eucg3(c2)){
Packit 5b6b86
	output_mode = EUC_JP;
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (!cp932inv_f){
Packit 5b6b86
	    nkf_char s2, s1;
Packit 5b6b86
	    if (e2s_conv(c2, c1, &s2, &s1) == 0){
Packit 5b6b86
		s2e_conv(s2, s1, &c2, &c1;;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
#endif
Packit 5b6b86
	if (c2 == 0) {
Packit 5b6b86
	    output_mode = ASCII;
Packit 5b6b86
	    (*o_putc)(c1);
Packit 5b6b86
	}else if (is_eucg3(c2)){
Packit 5b6b86
	    if (x0212_f){
Packit 5b6b86
		(*o_putc)(0x8f);
Packit 5b6b86
		(*o_putc)((c2 & 0x7f) | 0x080);
Packit 5b6b86
		(*o_putc)(c1 | 0x080);
Packit 5b6b86
	    }
Packit 5b6b86
	}else{
Packit 5b6b86
	    (*o_putc)((c2 & 0x7f) | 0x080);
Packit 5b6b86
	    (*o_putc)(c1 | 0x080);
Packit 5b6b86
	}
Packit 5b6b86
#endif
Packit 5b6b86
    } else {
Packit 5b6b86
	if (!nkf_isgraph(c1) || !nkf_isgraph(c2)) {
Packit 5b6b86
	    set_iconv(FALSE, 0);
Packit 5b6b86
	    return; /* too late to rescue this char */
Packit 5b6b86
	}
Packit 5b6b86
	output_mode = EUC_JP;
Packit 5b6b86
	(*o_putc)(c2 | 0x080);
Packit 5b6b86
	(*o_putc)(c1 | 0x080);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
s_oconv(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
#ifdef NUMCHAR_OPTION
Packit 5b6b86
    if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	w16e_conv(c1, &c2, &c1;;
Packit 5b6b86
	if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	    c2 = c1 & VALUE_MASK;
Packit 5b6b86
	    if (!x0213_f && 0xE000 <= c2 && c2 <= 0xE757) {
Packit 5b6b86
		/* CP932 UDC */
Packit 5b6b86
		c1 &= 0xFFF;
Packit 5b6b86
		c2 = c1 / 188 + (cp932inv_f ? 0xF0 : 0xEB);
Packit 5b6b86
		c1 = c1 % 188;
Packit 5b6b86
		c1 += 0x40 + (c1 > 0x3e);
Packit 5b6b86
		(*o_putc)(c2);
Packit 5b6b86
		(*o_putc)(c1);
Packit 5b6b86
		return;
Packit 5b6b86
	    } else {
Packit 5b6b86
		if(encode_fallback)(*encode_fallback)(c1);
Packit 5b6b86
		return;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
#endif
Packit 5b6b86
    if (c2 == EOF) {
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
	return;
Packit 5b6b86
    } else if (c2 == 0) {
Packit 5b6b86
	output_mode = ASCII;
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    } else if (c2 == JIS_X_0201_1976_K) {
Packit 5b6b86
	output_mode = SHIFT_JIS;
Packit 5b6b86
	(*o_putc)(c1|0x80);
Packit 5b6b86
    } else if (c2 == ISO_8859_1) {
Packit 5b6b86
	output_mode = ISO_8859_1;
Packit 5b6b86
	(*o_putc)(c1 | 0x080);
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    } else if (is_eucg3(c2)){
Packit 5b6b86
	output_mode = SHIFT_JIS;
Packit 5b6b86
	if (e2s_conv(c2, c1, &c2, &c1) == 0){
Packit 5b6b86
	    (*o_putc)(c2);
Packit 5b6b86
	    (*o_putc)(c1);
Packit 5b6b86
	}
Packit 5b6b86
#endif
Packit 5b6b86
    } else {
Packit 5b6b86
	if (!nkf_isprint(c1) || !nkf_isprint(c2)) {
Packit 5b6b86
	    set_iconv(FALSE, 0);
Packit 5b6b86
	    return; /* too late to rescue this char */
Packit 5b6b86
	}
Packit 5b6b86
	output_mode = SHIFT_JIS;
Packit 5b6b86
	e2s_conv(c2, c1, &c2, &c1;;
Packit 5b6b86
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if (cp932inv_f
Packit 5b6b86
	    && CP932INV_TABLE_BEGIN <= c2 && c2 <= CP932INV_TABLE_END){
Packit 5b6b86
	    nkf_char c = cp932inv[c2 - CP932INV_TABLE_BEGIN][c1 - 0x40];
Packit 5b6b86
	    if (c){
Packit 5b6b86
		c2 = c >> 8;
Packit 5b6b86
		c1 = c & 0xff;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
Packit 5b6b86
	(*o_putc)(c2);
Packit 5b6b86
	if (prefix_table[(unsigned char)c1]){
Packit 5b6b86
	    (*o_putc)(prefix_table[(unsigned char)c1]);
Packit 5b6b86
	}
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
#define OUTPUT_UTF8(val) do { \
Packit 5b6b86
	nkf_unicode_to_utf8(val, &c1, &c2, &c3, &c4;; \
Packit 5b6b86
	(*o_putc)(c1); \
Packit 5b6b86
	if (c2) (*o_putc)(c2); \
Packit 5b6b86
	if (c3) (*o_putc)(c3); \
Packit 5b6b86
	if (c4) (*o_putc)(c4); \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
w_oconv(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c3, c4;
Packit 5b6b86
    nkf_char val, val2;
Packit 5b6b86
Packit 5b6b86
    if (output_bom_f) {
Packit 5b6b86
	output_bom_f = FALSE;
Packit 5b6b86
	(*o_putc)('\357');
Packit 5b6b86
	(*o_putc)('\273');
Packit 5b6b86
	(*o_putc)('\277');
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == EOF) {
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
	return;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == 0 && nkf_char_unicode_p(c1)){
Packit 5b6b86
	val = c1 & VALUE_MASK;
Packit 5b6b86
	OUTPUT_UTF8(val);
Packit 5b6b86
	return;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == 0) {
Packit 5b6b86
	(*o_putc)(c1);
Packit 5b6b86
    } else {
Packit 5b6b86
	val = e2w_conv(c2, c1);
Packit 5b6b86
	if (val){
Packit 5b6b86
	    val2 = e2w_combining(val, c2, c1);
Packit 5b6b86
	    if (val2)
Packit 5b6b86
		OUTPUT_UTF8(val2);
Packit 5b6b86
	    OUTPUT_UTF8(val);
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define OUTPUT_UTF16_BYTES(c1, c2) do { \
Packit 5b6b86
	if (output_endian == ENDIAN_LITTLE){ \
Packit 5b6b86
	    (*o_putc)(c1); \
Packit 5b6b86
	    (*o_putc)(c2); \
Packit 5b6b86
	}else{ \
Packit 5b6b86
	    (*o_putc)(c2); \
Packit 5b6b86
	    (*o_putc)(c1); \
Packit 5b6b86
	} \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
#define OUTPUT_UTF16(val) do { \
Packit 5b6b86
	if (nkf_char_unicode_bmp_p(val)) { \
Packit 5b6b86
	    c2 = (val >> 8) & 0xff; \
Packit 5b6b86
	    c1 = val & 0xff; \
Packit 5b6b86
	    OUTPUT_UTF16_BYTES(c1, c2); \
Packit 5b6b86
	} else { \
Packit 5b6b86
	    val &= VALUE_MASK; \
Packit 5b6b86
	    if (val <= UNICODE_MAX) { \
Packit 5b6b86
		c2 = (val >> 10) + NKF_INT32_C(0xD7C0);   /* high surrogate */ \
Packit 5b6b86
		c1 = (val & 0x3FF) + NKF_INT32_C(0xDC00); /* low surrogate */ \
Packit 5b6b86
		OUTPUT_UTF16_BYTES(c2 & 0xff, (c2 >> 8) & 0xff); \
Packit 5b6b86
		OUTPUT_UTF16_BYTES(c1 & 0xff, (c1 >> 8) & 0xff); \
Packit 5b6b86
	    } \
Packit 5b6b86
	} \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
w_oconv16(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    if (output_bom_f) {
Packit 5b6b86
	output_bom_f = FALSE;
Packit 5b6b86
	OUTPUT_UTF16_BYTES(0xFF, 0xFE);
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == EOF) {
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
	return;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == 0 && nkf_char_unicode_p(c1)) {
Packit 5b6b86
	OUTPUT_UTF16(c1);
Packit 5b6b86
    } else if (c2) {
Packit 5b6b86
	nkf_char val, val2;
Packit 5b6b86
	val = e2w_conv(c2, c1);
Packit 5b6b86
	if (!val) return;
Packit 5b6b86
	val2 = e2w_combining(val, c2, c1);
Packit 5b6b86
	if (val2)
Packit 5b6b86
	    OUTPUT_UTF16(val2);
Packit 5b6b86
	OUTPUT_UTF16(val);
Packit 5b6b86
    } else {
Packit 5b6b86
	OUTPUT_UTF16_BYTES(c1, c2);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#define OUTPUT_UTF32(c) do { \
Packit 5b6b86
	if (output_endian == ENDIAN_LITTLE){ \
Packit 5b6b86
	    (*o_putc)( (c)        & 0xFF); \
Packit 5b6b86
	    (*o_putc)(((c) >>  8) & 0xFF); \
Packit 5b6b86
	    (*o_putc)(((c) >> 16) & 0xFF); \
Packit 5b6b86
	    (*o_putc)(0); \
Packit 5b6b86
	}else{ \
Packit 5b6b86
	    (*o_putc)(0); \
Packit 5b6b86
	    (*o_putc)(((c) >> 16) & 0xFF); \
Packit 5b6b86
	    (*o_putc)(((c) >>  8) & 0xFF); \
Packit 5b6b86
	    (*o_putc)( (c)        & 0xFF); \
Packit 5b6b86
	} \
Packit 5b6b86
    } while (0)
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
w_oconv32(nkf_char c2, nkf_char c1)
Packit 5b6b86
{
Packit 5b6b86
    if (output_bom_f) {
Packit 5b6b86
	output_bom_f = FALSE;
Packit 5b6b86
	if (output_endian == ENDIAN_LITTLE){
Packit 5b6b86
	    (*o_putc)(0xFF);
Packit 5b6b86
	    (*o_putc)(0xFE);
Packit 5b6b86
	    (*o_putc)(0);
Packit 5b6b86
	    (*o_putc)(0);
Packit 5b6b86
	}else{
Packit 5b6b86
	    (*o_putc)(0);
Packit 5b6b86
	    (*o_putc)(0);
Packit 5b6b86
	    (*o_putc)(0xFE);
Packit 5b6b86
	    (*o_putc)(0xFF);
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == EOF) {
Packit 5b6b86
	(*o_putc)(EOF);
Packit 5b6b86
	return;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (c2 == ISO_8859_1) {
Packit 5b6b86
	c1 |= 0x80;
Packit 5b6b86
    } else if (c2 == 0 && nkf_char_unicode_p(c1)) {
Packit 5b6b86
	c1 &= VALUE_MASK;
Packit 5b6b86
    } else if (c2) {
Packit 5b6b86
	nkf_char val, val2;
Packit 5b6b86
	val = e2w_conv(c2, c1);
Packit 5b6b86
	if (!val) return;
Packit 5b6b86
	val2 = e2w_combining(val, c2, c1);
Packit 5b6b86
	if (val2)
Packit 5b6b86
	    OUTPUT_UTF32(val2);
Packit 5b6b86
	c1 = val;
Packit 5b6b86
    }
Packit 5b6b86
    OUTPUT_UTF32(c1);
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
#define SCORE_L2       (1)                   /* Kanji Level 2 */
Packit 5b6b86
#define SCORE_KANA     (SCORE_L2 << 1)       /* Halfwidth Katakana */
Packit 5b6b86
#define SCORE_DEPEND   (SCORE_KANA << 1)     /* MD Characters */
Packit 5b6b86
#define SCORE_CP932    (SCORE_DEPEND << 1)   /* IBM extended characters */
Packit 5b6b86
#define SCORE_X0212    (SCORE_CP932 << 1)    /* JIS X 0212 */
Packit 5b6b86
#define SCORE_X0213    (SCORE_X0212 << 1)    /* JIS X 0213 */
Packit 5b6b86
#define SCORE_NO_EXIST (SCORE_X0213 << 1)    /* Undefined Characters */
Packit 5b6b86
#define SCORE_iMIME    (SCORE_NO_EXIST << 1) /* MIME selected */
Packit 5b6b86
#define SCORE_ERROR    (SCORE_iMIME << 1) /* Error */
Packit 5b6b86
Packit 5b6b86
#define SCORE_INIT (SCORE_iMIME)
Packit 5b6b86
Packit 5b6b86
static const nkf_char score_table_A0[] = {
Packit 5b6b86
    0, 0, 0, 0,
Packit 5b6b86
    0, 0, 0, 0,
Packit 5b6b86
    0, SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND,
Packit 5b6b86
    SCORE_DEPEND, SCORE_DEPEND, SCORE_DEPEND, SCORE_X0213,
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static const nkf_char score_table_F0[] = {
Packit 5b6b86
    SCORE_L2, SCORE_L2, SCORE_L2, SCORE_L2,
Packit 5b6b86
    SCORE_L2, SCORE_DEPEND, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
    SCORE_DEPEND, SCORE_DEPEND, SCORE_CP932, SCORE_CP932,
Packit 5b6b86
    SCORE_CP932, SCORE_X0213, SCORE_X0213, SCORE_ERROR,
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static const nkf_char score_table_8FA0[] = {
Packit 5b6b86
    0, SCORE_X0213, SCORE_X0212, SCORE_X0213,
Packit 5b6b86
    SCORE_X0213, SCORE_X0213, SCORE_X0212, SCORE_X0212,
Packit 5b6b86
    SCORE_X0213, SCORE_X0212, SCORE_X0212, SCORE_X0212,
Packit 5b6b86
    SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static const nkf_char score_table_8FE0[] = {
Packit 5b6b86
    SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212,
Packit 5b6b86
    SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212,
Packit 5b6b86
    SCORE_X0212, SCORE_X0212, SCORE_X0212, SCORE_X0212,
Packit 5b6b86
    SCORE_X0212, SCORE_X0212, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static const nkf_char score_table_8FF0[] = {
Packit 5b6b86
    SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0212,
Packit 5b6b86
    SCORE_X0212, SCORE_X0213, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
    SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
    SCORE_X0213, SCORE_X0213, SCORE_X0213, SCORE_X0213,
Packit 5b6b86
};
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
set_code_score(struct input_code *ptr, nkf_char score)
Packit 5b6b86
{
Packit 5b6b86
    if (ptr){
Packit 5b6b86
	ptr->score |= score;
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
clr_code_score(struct input_code *ptr, nkf_char score)
Packit 5b6b86
{
Packit 5b6b86
    if (ptr){
Packit 5b6b86
	ptr->score &= ~score;
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
code_score(struct input_code *ptr)
Packit 5b6b86
{
Packit 5b6b86
    nkf_char c2 = ptr->buf[0];
Packit 5b6b86
    nkf_char c1 = ptr->buf[1];
Packit 5b6b86
    if (c2 < 0){
Packit 5b6b86
	set_code_score(ptr, SCORE_ERROR);
Packit 5b6b86
    }else if (c2 == SS2){
Packit 5b6b86
	set_code_score(ptr, SCORE_KANA);
Packit 5b6b86
    }else if (c2 == 0x8f){
Packit 5b6b86
	if ((c1 & 0x70) == 0x20){
Packit 5b6b86
	    set_code_score(ptr, score_table_8FA0[c1 & 0x0f]);
Packit 5b6b86
	}else if ((c1 & 0x70) == 0x60){
Packit 5b6b86
	    set_code_score(ptr, score_table_8FE0[c1 & 0x0f]);
Packit 5b6b86
	}else if ((c1 & 0x70) == 0x70){
Packit 5b6b86
	    set_code_score(ptr, score_table_8FF0[c1 & 0x0f]);
Packit 5b6b86
	}else{
Packit 5b6b86
	    set_code_score(ptr, SCORE_X0212);
Packit 5b6b86
	}
Packit 5b6b86
#ifdef UTF8_OUTPUT_ENABLE
Packit 5b6b86
    }else if (!e2w_conv(c2, c1)){
Packit 5b6b86
	set_code_score(ptr, SCORE_NO_EXIST);
Packit 5b6b86
#endif
Packit 5b6b86
    }else if ((c2 & 0x70) == 0x20){
Packit 5b6b86
	set_code_score(ptr, score_table_A0[c2 & 0x0f]);
Packit 5b6b86
    }else if ((c2 & 0x70) == 0x70){
Packit 5b6b86
	set_code_score(ptr, score_table_F0[c2 & 0x0f]);
Packit 5b6b86
    }else if ((c2 & 0x70) >= 0x50){
Packit 5b6b86
	set_code_score(ptr, SCORE_L2);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_disable(struct input_code *ptr)
Packit 5b6b86
{
Packit 5b6b86
    ptr->stat = -1;
Packit 5b6b86
    ptr->buf[0] = -1;
Packit 5b6b86
    code_score(ptr);
Packit 5b6b86
    if (iconv == ptr->iconv_func) set_iconv(FALSE, 0);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_push_ch(struct input_code *ptr, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    ptr->buf[ptr->index++] = c;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_clear(struct input_code *ptr)
Packit 5b6b86
{
Packit 5b6b86
    ptr->stat = 0;
Packit 5b6b86
    ptr->index = 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_reset(struct input_code *ptr)
Packit 5b6b86
{
Packit 5b6b86
    status_clear(ptr);
Packit 5b6b86
    ptr->score = SCORE_INIT;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_reinit(struct input_code *ptr)
Packit 5b6b86
{
Packit 5b6b86
    status_reset(ptr);
Packit 5b6b86
    ptr->_file_stat = 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
status_check(struct input_code *ptr, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    if (c <= DEL && estab_f){
Packit 5b6b86
	status_reset(ptr);
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
s_status(struct input_code *ptr, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    switch(ptr->stat){
Packit 5b6b86
    case -1:
Packit 5b6b86
	status_check(ptr, c);
Packit 5b6b86
	break;
Packit 5b6b86
    case 0:
Packit 5b6b86
	if (c <= DEL){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (nkf_char_unicode_p(c)){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (0xa1 <= c && c <= 0xdf){
Packit 5b6b86
	    status_push_ch(ptr, SS2);
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    code_score(ptr);
Packit 5b6b86
	    status_clear(ptr);
Packit 5b6b86
	}else if ((0x81 <= c && c < 0xa0) || (0xe0 <= c && c <= 0xea)){
Packit 5b6b86
	    ptr->stat = 1;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	}else if (0xed <= c && c <= 0xee){
Packit 5b6b86
	    ptr->stat = 3;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	}else if (is_ibmext_in_sjis(c)){
Packit 5b6b86
	    ptr->stat = 2;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
	}else if (0xf0 <= c && c <= 0xfc){
Packit 5b6b86
	    ptr->stat = 1;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    case 1:
Packit 5b6b86
	if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
Packit 5b6b86
	    code_score(ptr);
Packit 5b6b86
	    status_clear(ptr);
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    case 2:
Packit 5b6b86
#ifdef SHIFTJIS_CP932
Packit 5b6b86
	if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)) {
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    if (s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]) == 0) {
Packit 5b6b86
		set_code_score(ptr, SCORE_CP932);
Packit 5b6b86
		status_clear(ptr);
Packit 5b6b86
		break;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
#endif /* SHIFTJIS_CP932 */
Packit 5b6b86
	status_disable(ptr);
Packit 5b6b86
	break;
Packit 5b6b86
    case 3:
Packit 5b6b86
	if ((0x40 <= c && c <= 0x7e) || (0x80 <= c && c <= 0xfc)){
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    s2e_conv(ptr->buf[0], ptr->buf[1], &ptr->buf[0], &ptr->buf[1]);
Packit 5b6b86
	    set_code_score(ptr, SCORE_CP932);
Packit 5b6b86
	    status_clear(ptr);
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
e_status(struct input_code *ptr, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    switch (ptr->stat){
Packit 5b6b86
    case -1:
Packit 5b6b86
	status_check(ptr, c);
Packit 5b6b86
	break;
Packit 5b6b86
    case 0:
Packit 5b6b86
	if (c <= DEL){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (nkf_char_unicode_p(c)){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (SS2 == c || (0xa1 <= c && c <= 0xfe)){
Packit 5b6b86
	    ptr->stat = 1;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
	}else if (0x8f == c){
Packit 5b6b86
	    ptr->stat = 2;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    case 1:
Packit 5b6b86
	if (0xa1 <= c && c <= 0xfe){
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    code_score(ptr);
Packit 5b6b86
	    status_clear(ptr);
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
#ifdef X0212_ENABLE
Packit 5b6b86
    case 2:
Packit 5b6b86
	if (0xa1 <= c && c <= 0xfe){
Packit 5b6b86
	    ptr->stat = 1;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
#endif /* X0212_ENABLE */
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifdef UTF8_INPUT_ENABLE
Packit 5b6b86
static void
Packit 5b6b86
w_status(struct input_code *ptr, nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    switch (ptr->stat){
Packit 5b6b86
    case -1:
Packit 5b6b86
	status_check(ptr, c);
Packit 5b6b86
	break;
Packit 5b6b86
    case 0:
Packit 5b6b86
	if (c <= DEL){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (nkf_char_unicode_p(c)){
Packit 5b6b86
	    break;
Packit 5b6b86
	}else if (0xc0 <= c && c <= 0xdf){
Packit 5b6b86
	    ptr->stat = 1;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	}else if (0xe0 <= c && c <= 0xef){
Packit 5b6b86
	    ptr->stat = 2;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	}else if (0xf0 <= c && c <= 0xf4){
Packit 5b6b86
	    ptr->stat = 3;
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    case 1:
Packit 5b6b86
    case 2:
Packit 5b6b86
	if (0x80 <= c && c <= 0xbf){
Packit 5b6b86
	    status_push_ch(ptr, c);
Packit 5b6b86
	    if (ptr->index > ptr->stat){
Packit 5b6b86
		int bom = (ptr->buf[0] == 0xef && ptr->buf[1] == 0xbb
Packit 5b6b86
			   && ptr->buf[2] == 0xbf);
Packit 5b6b86
		w2e_conv(ptr->buf[0], ptr->buf[1], ptr->buf[2],
Packit 5b6b86
			 &ptr->buf[0], &ptr->buf[1]);
Packit 5b6b86
		if (!bom){
Packit 5b6b86
		    code_score(ptr);
Packit 5b6b86
		}
Packit 5b6b86
		status_clear(ptr);
Packit 5b6b86
	    }
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    case 3:
Packit 5b6b86
	if (0x80 <= c && c <= 0xbf){
Packit 5b6b86
	    if (ptr->index < ptr->stat){
Packit 5b6b86
		status_push_ch(ptr, c);
Packit 5b6b86
	    } else {
Packit 5b6b86
		status_clear(ptr);
Packit 5b6b86
	    }
Packit 5b6b86
	}else{
Packit 5b6b86
	    status_disable(ptr);
Packit 5b6b86
	}
Packit 5b6b86
	break;
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
#endif
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
code_status(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    int action_flag = 1;
Packit 5b6b86
    struct input_code *result = 0;
Packit 5b6b86
    struct input_code *p = input_code_list;
Packit 5b6b86
    while (p->name){
Packit 5b6b86
	if (!p->status_func) {
Packit 5b6b86
	    ++p;
Packit 5b6b86
	    continue;
Packit 5b6b86
	}
Packit 5b6b86
	if (!p->status_func)
Packit 5b6b86
	    continue;
Packit 5b6b86
	(p->status_func)(p, c);
Packit 5b6b86
	if (p->stat > 0){
Packit 5b6b86
	    action_flag = 0;
Packit 5b6b86
	}else if(p->stat == 0){
Packit 5b6b86
	    if (result){
Packit 5b6b86
		action_flag = 0;
Packit 5b6b86
	    }else{
Packit 5b6b86
		result = p;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
	++p;
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (action_flag){
Packit 5b6b86
	if (result && !estab_f){
Packit 5b6b86
	    set_iconv(TRUE, result->iconv_func);
Packit 5b6b86
	}else if (c <= DEL){
Packit 5b6b86
	    struct input_code *ptr = input_code_list;
Packit 5b6b86
	    while (ptr->name){
Packit 5b6b86
		status_reset(ptr);
Packit 5b6b86
		++ptr;
Packit 5b6b86
	    }
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
typedef struct {
Packit 5b6b86
    nkf_buf_t *std_gc_buf;
Packit 5b6b86
    nkf_char broken_state;
Packit 5b6b86
    nkf_buf_t *broken_buf;
Packit 5b6b86
    nkf_char mimeout_state;
Packit 5b6b86
    nkf_buf_t *nfc_buf;
Packit 5b6b86
} nkf_state_t;
Packit 5b6b86
Packit 5b6b86
static nkf_state_t *nkf_state = NULL;
Packit 5b6b86
Packit 5b6b86
#define STD_GC_BUFSIZE (256)
Packit 5b6b86
Packit 5b6b86
static void
Packit 5b6b86
nkf_state_init(void)
Packit 5b6b86
{
Packit 5b6b86
    if (nkf_state) {
Packit 5b6b86
	nkf_buf_clear(nkf_state->std_gc_buf);
Packit 5b6b86
	nkf_buf_clear(nkf_state->broken_buf);
Packit 5b6b86
	nkf_buf_clear(nkf_state->nfc_buf);
Packit 5b6b86
    }
Packit 5b6b86
    else {
Packit 5b6b86
	nkf_state = nkf_xmalloc(sizeof(nkf_state_t));
Packit 5b6b86
	nkf_state->std_gc_buf = nkf_buf_new(STD_GC_BUFSIZE);
Packit 5b6b86
	nkf_state->broken_buf = nkf_buf_new(3);
Packit 5b6b86
	nkf_state->nfc_buf = nkf_buf_new(9);
Packit 5b6b86
    }
Packit 5b6b86
    nkf_state->broken_state = 0;
Packit 5b6b86
    nkf_state->mimeout_state = 0;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifndef WIN32DLL
Packit 5b6b86
static nkf_char
Packit 5b6b86
std_getc(FILE *f)
Packit 5b6b86
{
Packit 5b6b86
    if (!nkf_buf_empty_p(nkf_state->std_gc_buf)){
Packit 5b6b86
	return nkf_buf_pop(nkf_state->std_gc_buf);
Packit 5b6b86
    }
Packit 5b6b86
    return getc(f);
Packit 5b6b86
}
Packit 5b6b86
#endif /*WIN32DLL*/
Packit 5b6b86
Packit 5b6b86
static nkf_char
Packit 5b6b86
std_ungetc(nkf_char c, ARG_UNUSED FILE *f)
Packit 5b6b86
{
Packit 5b6b86
    nkf_buf_push(nkf_state->std_gc_buf, c);
Packit 5b6b86
    return c;
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
#ifndef WIN32DLL
Packit 5b6b86
static void
Packit 5b6b86
std_putc(nkf_char c)
Packit 5b6b86
{
Packit 5b6b86
    if(c!=EOF)
Packit 5b6b86
	putchar(c);
Packit 5b6b86
}
Packit 5b6b86
#endif /*WIN32DLL*/
Packit 5b6b86
Packit 5b6b86
static nkf_char   hold_buf[HOLD_SIZE*2];
Packit 5b6b86
static int             hold_count = 0;
Packit 5b6b86
static nkf_char
Packit 5b6b86
push_hold_buf(nkf_char c2)
Packit 5b6b86
{
Packit 5b6b86
    if (hold_count >= HOLD_SIZE*2)
Packit 5b6b86
	return (EOF);
Packit 5b6b86
    hold_buf[hold_count++] = c2;
Packit 5b6b86
    return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
Packit 5b6b86
}
Packit 5b6b86
Packit 5b6b86
static int
Packit 5b6b86
h_conv(FILE *f, nkf_char c1, nkf_char c2)
Packit 5b6b86
{
Packit 5b6b86
    int ret;
Packit 5b6b86
    int hold_index;
Packit 5b6b86
    int fromhold_count;
Packit 5b6b86
    nkf_char c3, c4;
Packit 5b6b86
Packit 5b6b86
    /** it must NOT be in the kanji shifte sequence      */
Packit 5b6b86
    /** it must NOT be written in JIS7                   */
Packit 5b6b86
    /** and it must be after 2 byte 8bit code            */
Packit 5b6b86
Packit 5b6b86
    hold_count = 0;
Packit 5b6b86
    push_hold_buf(c1);
Packit 5b6b86
    push_hold_buf(c2);
Packit 5b6b86
Packit 5b6b86
    while ((c2 = (*i_getc)(f)) != EOF) {
Packit 5b6b86
	if (c2 == ESC){
Packit 5b6b86
	    (*i_ungetc)(c2,f);
Packit 5b6b86
	    break;
Packit 5b6b86
	}
Packit 5b6b86
	code_status(c2);
Packit 5b6b86
	if (push_hold_buf(c2) == EOF || estab_f) {
Packit 5b6b86
	    break;
Packit 5b6b86
	}
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
    if (!estab_f) {
Packit 5b6b86
	struct input_code *p = input_code_list;
Packit 5b6b86
	struct input_code *result = p;
Packit 5b6b86
	if (c2 == EOF) {
Packit 5b6b86
	    code_status(c2);
Packit 5b6b86
	}
Packit 5b6b86
	while (p->name) {
Packit 5b6b86
	    if (p->status_func && p->score < result->score) {
Packit 5b6b86
		result = p;
Packit 5b6b86
	    }
Packit 5b6b86
	    p++;
Packit 5b6b86
	}
Packit 5b6b86
	set_iconv(TRUE, result->iconv_func);
Packit 5b6b86
    }
Packit 5b6b86
Packit 5b6b86
Packit 5b6b86
    /** now,
Packit 5b6b86
     ** 1) EOF is detected, or
Packit 5b6b86
     ** 2) Code is established, or
Packit 5b6b86
     ** 3) Buffer is FULL (but last word is pushed)
Packit 5b6b86
     **
Packit 5b6b86
     ** in 1) and 3) cases, we continue to use
Packit 5b6b86
     ** Kanji codes by oconv and leave estab_f unchanged.
Packit 5b6b86
     **/
Packit 5b6b86
Packit 5b6b86
    ret = c2;
Packit 5b6b86
    hold_index = 0;
Packit 5b6b86
    while (hold_index < hold_count){
Packit 5b6b86
	c1 = hold_buf[hold_index++];
Packit 5b6b86
	if (nkf_char_unicode_p(c1)) {
Packit 5b6b86
	    (*oconv)(0, c1);
Packit 5b6b86
	    continue;
Packit 5b6b86
	}
Packit 5b6b86
	else if (c1 <= DEL){
Packit 5b6b86
	    (*iconv)(0, c1, 0);
Packit 5b6b86
	    continue;
Packit 5b6b86
	}else if (iconv == s_iconv && 0xa1 <= c1 && c1 <= 0xdf){
Packit 5b6b86
	    (*iconv)(JIS_X_0201_1976_K, c1, 0);
Packit 5b6b86
	    continue;
Packit 5b6b86
	}
Packit 5b6b86
	fromhold_count = 1;
Packit 5b6b86
	if (hold_index < hold_count){
Packit 5b6b86
	    c2 = hold_buf[hold_index++];
Packit 5b6b86
	    fromhold_count++;
Packit 5b6b86
	}else{
Packit 5b6b86
	    c2 = (*i_getc)(f);
Packit 5b6b86
	    if (c2 == EOF){
Packit 5b6b86
		c4 = EOF;
Packit 5b6b86
		break;
Packit 5b6b86
	    }
Packit 5b6b86
	    code_status(c2);
Packit 5b6b86
	}