/* vi: set sw=4 ts=4: */
/*
* CCE - Console Chinese Environment -
* Copyright (C) 1998-2003 Rui He (rhe@3eti.com)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Name: cceconv
* Documentation:
* Universal file encoding convertor (GB/GBK/Big5/JIS/ShiftJIS/KSC)
*
* This program is based on the following programs:
* dos2unix/unix2dos Benjamin Lin(blin@socs.uts.edu.au)
* hc 3.0 Ricky Yeung(Ricky.Yeung@eng.sun.com) and
* Fung F. Leeconvert.c(lee@umunhum.stanford.edu)
* (The GBToBig5Tbl & Big5ToGBTbl is generated from hc 3.0's hc.tab)
*
* Other gb<->jis gbk<->big5 gb<->ksc conversion table is generated from NJStar
*/
#define VER_AUTHOR "Rui He"
#define VER_DATE "2003.08.09"
#define VER_REVISION "1.0"
#ifdef __MSDOS__
# include
#endif /* __MSDOS__ */
#include
#include
#include
#include
#include
#include
#include
#include "defs.h"
#include "convert.h"
#define LOBYTE(n) ((n) & 0xFF)
#define HIBYTE(n) ((n) / 256 )
#define DOS_MODE (CODE_NUM) /* 0x0D 0A */
#define UNIX_MODE (CODE_NUM+1) /* 0x */
char *codingName[] = { "2022JP", "JIS", "Shift-JIS", "Big5", "GB", "GBK", "KSC", "UHC", "Unicode",
"DOS", "Unix" };
typedef struct
{
int OldCoding; /* old coding */
int NewCoding; /* new coding */
int ConvMode; /* for DOS/Unix */
int NewFile; /* is in new file mode? */
int Quiet; /* is in quiet mode? */
int KeepDate; /* should keep date stamp? */
int KeepPerm; /* should keep permision stamp? */
} CFlag;
#if 0
static int D2UAsciiTable[256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
'\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
'\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
'\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
'\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
'\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
'\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
'\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
'\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7',
'\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf' ,
'\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7',
'\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf',
'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
'\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff',
};
static int D2U7BitTable[256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
};
static int D2UIsoTable[256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\xb6', '\xa7', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x81',
'\xc7', '\xfc', '\xe9', '\xe2', '\xe4', '\xe0', '\xe5', '\xe7',
'\xea', '\xeb', '\xe8', '\xef', '\xee', '\xec', '\xc4', '\xc5',
'\xc9', '\xe6', '\xc6', '\xf4', '\xf6', '\xf2', '\xfb', '\xf9',
'\xff', '\xd6', '\xdc', '\xa2', '\xa3', '\xa5', '\xa4', '\x96',
'\xe1', '\xed', '\xf3', '\xfa', '\xf1', '\xd1', '\xaa', '\xba',
'\xbf', '\xa8', '\xac', '\xbd', '\xbc', '\xa1', '\xab', '\xaf',
'\x97', '\x98', '\x99', '\xfe', '\xb3', '\xb4', '\xb5', '\xb8',
'\xb9', '\xa0', '\xa6', '\xa9', '\xad', '\xbb', '\xbe', '\xc0',
'\xc1', '\xc2', '\xc3', '\xc8', '\xfd', '\xca', '\xcb', '\xcc',
'\xae', '\xd0', '\xd7', '\xdd', '\xde', '\xcd', '\xf0', '\xce' ,
'\xcf', '\xd2', '\xd3', '\xd4', '\xd5', '\xd8', '\xd9', '\xda',
'\xdb', '\xe3', '\xf5', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e',
'\x80', '\xdf', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
'\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
'\x14', '\xb1', '\xf8', '\x7f', '\x9f', '\x15', '\xf7', '\x95',
'\xb0', '\xb7', '\x94', '\x93', '\x92', '\xb2', '\x91', '\x90',
};
#endif
int ConvertDosToUnix(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag)
{
int RetVal = 0;
int TempChar;
switch (ipFlag->ConvMode)
{
case 0: /* ASCII */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar != '\x0d') &&
(putc(/* D2UAsciiTable[TempChar] */ TempChar, ipOutF) == EOF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "cceconv: can not write to out file\n");
break;
}
break;
#if 0
case 1: /* 7Bit */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar != '\x0d') &&
(putc(D2U7BitTable[TempChar], ipOutF) == EOF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "dos2unix: can not write to out file\n");
break;
}
break;
case 2: /* ISO */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar != '\x0d') &&
(putc(D2UIsoTable[TempChar], ipOutF) == EOF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "dos2unix: can not write to out file\n");
break;
}
break;
case 3: /* Mac */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar != '\x0d'))
{
if(putc(D2UAsciiTable[TempChar], ipOutF) == EOF)
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "dos2unix: can not write to out file\n");
break;
}
}
else
{
if (putc('\x0a', ipOutF) == EOF)
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "dos2unix: can not write to out file\n");
break;
}
}
break;
#endif
default: /* unknown convmode */
;
#ifdef DEBUG
fprintf(stderr, "cceconv: program error, invalid conversion mode %d\n",ipFlag->ConvMode);
exit(1);
#endif /* DEBUG */
}
return RetVal;
}
#if 0
static int U2DAsciiTable[256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
'\x80', '\x81', '\x82', '\x83', '\x84', '\x85', '\x86', '\x87',
'\x88', '\x89', '\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f',
'\x90', '\x91', '\x92', '\x93', '\x94', '\x95', '\x96', '\x97',
'\x98', '\x99', '\x9a', '\x9b', '\x9c', '\x9d', '\x9e', '\x9f',
'\xa0', '\xa1', '\xa2', '\xa3', '\xa4', '\xa5', '\xa6', '\xa7',
'\xa8', '\xa9', '\xaa', '\xab', '\xac', '\xad', '\xae', '\xaf',
'\xb0', '\xb1', '\xb2', '\xb3', '\xb4', '\xb5', '\xb6', '\xb7',
'\xb8', '\xb9', '\xba', '\xbb', '\xbc', '\xbd', '\xbe', '\xbf',
'\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7',
'\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce', '\xcf' ,
'\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd7',
'\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde', '\xdf',
'\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
'\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf7',
'\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff',
};
static int U2D7BitTable [256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\x7f',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
'\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20', '\x20',
};
static int U2DIsoTable[256] =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
'\x10', '\x11', '\x12', '\x13', '\xf0', '\xf5', '\x16', '\x17',
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27',
'\x28', '\x29', '\x2a', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37',
'\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47',
'\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f' ,
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57',
'\x58', '\x59', '\x5a', '\x5b', '\x5c', '\x5d', '\x5e', '\x5f',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67',
'\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77',
'\x78', '\x79', '\x7a', '\x7b', '\x7c', '\x7d', '\x7e', '\xf3',
'\xe0', '\x7f', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7',
'\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee', '\xef',
'\xff', '\xfe', '\xfc', '\xfb', '\xfa', '\xf7', '\x9f', '\xb0',
'\xb1', '\xb2', '\xdb', '\xdc', '\xdd', '\xde', '\xdf', '\xf4',
'\xb9', '\xad', '\x9b', '\x9c', '\x9e', '\x9d', '\xba', '\x15',
'\xa9', '\xbb', '\xa6', '\xae', '\xaa', '\xbc', '\xc8', '\xaf',
'\xf8', '\xf1', '\xfd', '\xb4', '\xb5', '\xb6', '\x14', '\xf9',
'\xb7', '\xb8', '\xa7', '\xbd', '\xac', '\xab', '\xbe', '\xa8',
'\xbf', '\xc0', '\xc1', '\xc2', '\x8e', '\x8f', '\x92', '\x80',
'\xc3', '\x90', '\xc5', '\xc6', '\xc7', '\xcd', '\xcf', '\xd0' ,
'\xc9', '\xa5', '\xd1', '\xd2', '\xd3', '\xd4', '\x99', '\xca',
'\xd5', '\xd6', '\xd7', '\xd8', '\x9a', '\xcb', '\xcc', '\xe1',
'\x85', '\xa0', '\x83', '\xd9', '\x84', '\x86', '\x91', '\x87',
'\x8a', '\x82', '\x88', '\x89', '\x8d', '\xa1', '\x8c', '\x8b',
'\xce', '\xa4', '\x95', '\xa2', '\x93', '\xda', '\x94', '\xf6',
'\xf2', '\x97', '\xa3', '\x96', '\x81', '\xc4', '\xb3', '\x98',
};
#endif
int ConvertUnixToDos(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag)
{
int RetVal = 0;
int TempChar;
switch (ipFlag->ConvMode)
{
case 0: /* ASCII */
while ( (TempChar = getc(ipInF)) != EOF )
if (((TempChar == '\x0a') && ( putc('\x0d', ipOutF) == EOF)) ||
((TempChar == '\x0d') && ( ((TempChar = getc(ipInF)) == EOF) || (putc('\x0d', ipOutF) == EOF))) ||
(putc(TempChar /* U2DAsciiTable[TempChar] */, ipOutF) == EOF) )
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "cceconv: can not write to output file\n");
break;
}
break;
#if 0
case 1: /* 7Bit */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar == '\x0a') && (putc('\x0d', ipOutF) == EOF) ||
(TempChar == '\x0d') && (((TempChar = getc(ipInF)) == EOF) || (putc('\x0d', ipOutF) == EOF)) ||
(putc(U2D7BitTable[TempChar], ipOutF) == EOF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "unix2dos: can not write to output file\n");
break;
}
break;
case 2: /* ISO */
while ((TempChar = getc(ipInF)) != EOF)
if ((TempChar == '\x0a') && (putc('\x0d', ipOutF) == EOF) ||
(TempChar == '\x0d') && (((TempChar = getc(ipInF)) == EOF) || (putc('\x0d', ipOutF) == EOF)) ||
(putc(U2DIsoTable[TempChar], ipOutF) == EOF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "unix2dos: can not write to output file\n");
break;
}
break;
#endif
default: /*unknown convmode */
;
#ifdef DEBUG
fprintf(stderr, "cceconv: program error, invalid conversion mode %d\n",ipFlag->ConvMode);
exit(1);
#endif /* DEBUG */
}
return RetVal;
}
#define EUCbox 0xA1A1 /* JIS empty box symbol */
#define SJISbox 0x8140 /* Shift JIS code for the empty box symbol */
#define GBbox 0xA1F5 /* GB code for the empty box symbol */
#define GBKbox 0xA1F5 /* GBK code for the empty box symbol */
#define BIGbox 0xA1BC /* BIG code for the empty box symbol */
#define KSCbox 0xA1E0 /* KSC code for the empty box symbol */
unsigned short EmptyBoxSymbols[CODE_NUM] = {
0x0000, EUCbox, SJISbox, BIGbox, GBbox, GBKbox, KSCbox, KSCbox, 0x00000, /* last two: UHC, Unicode */
};
void CCEConvertChar(int High, int Low, FILE *ipOutF, int OldCoding, int NewCoding)
{
int OutChar = ConvertEncoding_Char(OldCoding, NewCoding, High, Low, NULL, NULL);
if (OutChar == 0 || OutChar == -1) /* -1 is the error flag */
OutChar = EmptyBoxSymbols[NewCoding];
putc(HIBYTE(OutChar), ipOutF);
putc(LOBYTE(OutChar), ipOutF);
}
static unsigned short zenmap[] = {
0x2121,0x2123,0x2156,0x2157,0x2122,0x2126,0x2572,0x2521,
0x2523,0x2525,0x2527,0x2529,0x2563,0x2565,0x2567,0x2543,
0x213c,0x2522,0x2524,0x2526,0x2528,0x252a,0x252b,0x252d,
0x252f,0x2531,0x2533,0x2535,0x2537,0x2539,0x253b,0x253d,
0x253f,0x2541,0x2544,0x2546,0x2548,0x254a,0x254b,0x254c,
0x254d,0x254e,0x254f,0x2552,0x2555,0x2558,0x255b,0x255e,
0x255f,0x2560,0x2561,0x2562,0x2564,0x2566,0x2568,0x2569,
0x256a,0x256b,0x256c,0x256d,0x256f,0x2573,0x212b,0x212c, /* 64 points 0xA0-DF, in JIS */
#if 0 /* in GB coding */
0x2121,0x2123, 0x2138/*0x2156*/, 0x2139/*0x2157*/, 0x2122, 0x2124/* 0x2126*/, 0x2572,0x2521,
0x2523,0x2525,0x2527,0x2529,0x2563,0x2565,0x2567,0x2543,
0x212A/*0x213c*/, 0x2522,0x2524,0x2526,0x2528,0x252a,0x252b,0x252d,
0x252f,0x2531,0x2533,0x2535,0x2537,0x2539,0x253b,0x253d,
0x253f,0x2541,0x2544,0x2546,0x2548,0x254a,0x254b,0x254c,
0x254d,0x254e,0x254f,0x2552,0x2555,0x2558,0x255b,0x255e,
0x255f,0x2560,0x2561,0x2562,0x2564,0x2566,0x2568,0x2569,
0x256a,0x256b,0x256c,0x256d,0x256f,0x2573, 0x2165/* 0x212b */ , 0x2163/*0x212c */,
#endif
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x252c,0x252e,
0x2530,0x2532,0x2534,0x2536,0x2538,0x253a,0x253c,0x253e,
0x2540,0x2542,0x2545,0x2547,0x2549,0x0000,0x0000,0x0000,
0x0000,0x0000,0x2550,0x2553,0x2556,0x2559,0x255c,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, /* [A0-DD] DE */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, /* 64 chars, same in GB&JIS */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
0x0000,0x0000,0x2551,0x2554,0x2557,0x255a,0x255d,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, /* [A0-DD] DF */
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, /* 64 chars, same in GB&JIS */
};
static void CCEKanaConvert(int inChar1, int inChar2, FILE* ipOutF, CFlag *ipFlag)
{
int OutChar;
inChar1 &= 0xFF;
inChar2 &= 0xFF;
if (inChar1 >= 0xA0 && inChar1 <= 0xDF)
{
if (inChar2 == 0xDE && zenmap[inChar1 - 0xA0 + 0x40] != 0)
OutChar = zenmap[inChar1 - 0xA0 + 0x40] | 0x8080;
else if (inChar2 == 0xDF && zenmap[inChar1 - 0xA0 + 0x80] != 0)
OutChar = zenmap[inChar1 - 0xA0 + 0x80] | 0x8080;
else OutChar = zenmap[inChar1 - 0xA0] | 0x8080;
CCEConvertChar(OutChar >> 8, OutChar & 0xFF, ipOutF, CODE_EUC, ipFlag->NewCoding);
}
else
{
putc(inChar1, ipOutF); /* inChar2 should be -1 now */
}
}
int CCEConvertFile_FromEUCJP(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag)
{
int RetVal = 0;
int TempChar,LastChar = 0;
while ((TempChar = getc(ipInF)) != EOF)
{
if (TempChar == 0x0A || TempChar == 0x0D) /* new line */
{
if ((LastChar & 0xFF) == 0x8E) LastChar >>= 8;
if (LastChar != 0)
CCEKanaConvert(LastChar & 0xFF, -1, ipOutF, ipFlag);
LastChar = 0;
putc(TempChar, ipOutF);
}
else if (LastChar != 0) /* a Chinese/Japanese/Korean char second byte? */
{
if (LastChar == 0x8E) /* CHAR_SS2 */
{
if (ipFlag->NewCoding == CODE_SJIS || TempChar < 0xA0 || TempChar > 0xDF)
{
putc(TempChar, ipOutF);
LastChar = 0;
continue;
}
else /* now TempChar is in A0-DF range -> 0x8EA0-8EDF */
{
LastChar = 0x8E00 | TempChar;
continue;
}
}
else if ((LastChar & 0xFFFF00) == 0x8E00) /* 0x8EA0-0x8EDF */
{
if (TempChar == 0x8E)
{
LastChar = LastChar << 8 || TempChar; /* 0x8E[A0-DF]8E */
continue;
}
else /* not 8E for this one */
{
CCEKanaConvert(LastChar & 0xFF, -1, ipOutF, ipFlag);
LastChar = 0;
ungetc(TempChar, ipInF); /* put back */
continue;
}
}
else if ((LastChar & 0xFF00FF) == 0x8E008E) /* 8E[A0-DF]8E */
{
if (TempChar == 0xDE || TempChar == 0xDF)
{
CCEKanaConvert((LastChar >> 8) & 0xFF, TempChar, ipOutF, ipFlag);
LastChar = 0;
continue;
}
else if (TempChar >= 0xA0 && TempChar <= 0xDF)
{
CCEKanaConvert((LastChar >> 8) & 0xFF, -1, ipOutF, ipFlag); /* output */
LastChar = 0x8E00 || TempChar;
continue;
}
else
{
CCEKanaConvert((LastChar >> 8) & 0xFF, -1, ipOutF, ipFlag); /* output */
LastChar = 0;
putc(TempChar, ipOutF); /* 8E [A0-DF] 8E ![A0-DF] */
continue;
}
}
CCEConvertChar(LastChar, TempChar,ipOutF,ipFlag->OldCoding,ipFlag->NewCoding );
LastChar = 0;
}
else /* now single byte output */
{
if (TempChar == 0x8E || iskanji_byte1(ipFlag->OldCoding, TempChar))
LastChar=TempChar;
else putc(TempChar,ipOutF);
}
}
if (ferror(ipInF) || ferror(ipOutF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "big2gb: Error while converting file!\n");
}
else
{
if ((LastChar & 0xFF) == 0x8E) LastChar >>= 8;
if (LastChar != 0)
CCEKanaConvert(LastChar & 0xFF, -1, ipOutF, ipFlag);
}
return RetVal;
}
int CCEConvertFile_FromShiftJIS(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag)
{
int RetVal = 0;
int TempChar,LastChar = 0;
while ((TempChar = getc(ipInF)) != EOF)
{
if (TempChar == 0x0A || TempChar == 0x0D) /* new line */
{
if (LastChar != 0)
{
CCEKanaConvert(LastChar, -1, ipOutF, ipFlag);
LastChar = 0;
}
putc(TempChar, ipOutF);
}
else if (LastChar != 0) /* a Japanese char second byte? */
{
if (LastChar >= 0xA0 && LastChar <= 0xDF) /* saved kana */
{
if (TempChar == 0xDE || TempChar == 0xDF)
{
CCEKanaConvert(LastChar, TempChar, ipOutF, ipFlag);
LastChar = 0;
continue;
}
CCEKanaConvert(LastChar, -1, ipOutF, ipFlag);
LastChar = 0;
ungetc(TempChar, ipInF); /* push back */
continue;
}
if (!iskanji_byte2(ipFlag->OldCoding, TempChar))
{
putc(LastChar, ipOutF); /* send it out */
LastChar = 0;
ungetc(TempChar, ipInF); /* push back */
continue;
}
CCEConvertChar(LastChar, TempChar,ipOutF,ipFlag->OldCoding,ipFlag->NewCoding);
LastChar = 0;
}
else /* now single byte output */
{
if (TempChar >= 0xA0 && TempChar <= 0xDF) /* not a valid SJIS first byte */
{
if (ipFlag->NewCoding == CODE_EUC)
{
putc(0x8E, ipOutF); /* EUC-JP 0x8E 0xA0-DF */
putc(TempChar, ipOutF); /* keep the half symbol */
continue;
}
else LastChar = TempChar; /* save it, try to do 0xA0-DF 0xDE/DF */
}
else if (iskanji_byte1(ipFlag->OldCoding, TempChar))
LastChar=TempChar;
else putc(TempChar,ipOutF);
}
}
if (ferror(ipInF) || ferror(ipOutF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "cceconv: Error while converting file!\n");
}
else if (LastChar != 0) CCEKanaConvert(LastChar, -1, ipOutF, ipFlag);
return RetVal;
}
int CCEConvertFile(FILE* ipInF, FILE* ipOutF, CFlag *ipFlag)
{
int RetVal = 0;
int TempChar,LastChar = 0;
if (ipFlag->OldCoding == DOS_MODE)
return ConvertDosToUnix(ipInF, ipOutF, ipFlag);
if (ipFlag->OldCoding == UNIX_MODE)
return ConvertUnixToDos(ipInF, ipOutF, ipFlag);
if (ipFlag->OldCoding == CODE_EUC)
return CCEConvertFile_FromEUCJP(ipInF, ipOutF, ipFlag);
if (ipFlag->OldCoding == CODE_SJIS)
return CCEConvertFile_FromShiftJIS(ipInF, ipOutF, ipFlag);
while ((TempChar = getc(ipInF)) != EOF)
{
if (TempChar == 0x0A || TempChar == 0x0D) /* new line */
{
if (LastChar != 0)
{
putc(LastChar, ipOutF);
LastChar = 0;
}
putc(TempChar, ipOutF);
}
else if (LastChar != 0) /* a Chinese/Japanese/Korean char second byte? */
{
if (!iskanji_byte2(ipFlag->OldCoding, TempChar))
{
putc(LastChar, ipOutF);
LastChar = 0; /* now send out the LastChar */
if (iskanji_byte1(ipFlag->OldCoding, TempChar))
LastChar=TempChar;
else putc(TempChar,ipOutF);
continue;
}
CCEConvertChar(LastChar, TempChar,ipOutF,ipFlag->OldCoding,ipFlag->NewCoding);
LastChar = 0;
}
else /* now single byte output */
{
if (iskanji_byte1(ipFlag->OldCoding, TempChar))
LastChar=TempChar;
else putc(TempChar,ipOutF);
}
}
if (ferror(ipInF) || ferror(ipOutF))
{
RetVal = -1;
if (!ipFlag->Quiet)
fprintf(stderr, "cceconv: Error while converting file!\n");
}
else if (LastChar != 0) putc(LastChar, ipOutF);
return RetVal;
}
void PrintUsage(char *argv[])
{
fprintf(stderr, " %s %s Copyright (c) 1998-2003 %s. (%s)\n",
argv[0], VER_REVISION, VER_AUTHOR, VER_DATE);
fprintf(stderr, " Usage: %s [-hkqV] [-o file ...] [-n infile outfile ...]\n", argv[0]);
fprintf(stderr, " -h --help give this help\n");
fprintf(stderr, " -k --keepdate keep output file date\n");
fprintf(stderr, " -p --keepperm keep output file permision\n");
fprintf(stderr, " -q --quiet quiet mode, suppress all warnings\n");
fprintf(stderr, " always on in stdin->stdout mode\n");
fprintf(stderr, " -V --version display version number\n");
fprintf(stderr, " -o --oldfile write to old file\n");
fprintf(stderr, " file ... files to convert in old file mode\n");
fprintf(stderr, " -n --newfile write to new file(filename specified in pairs)\n");
fprintf(stderr, " infile original file in new file mode\n");
fprintf(stderr, " outfile output file in new file mode\n");
fprintf(stderr, " -gb2big|-big2gb|-gbk2big|-big2gbk|-gb2sjis|-sjis2gb\n");
fprintf(stderr, " -sjis2euc|-euc2sjis|-gb2ksc|-ksc2gb|...\n");
fprintf(stderr, " -dos2unix|-unix2dos|-d2u|-u2d\n");
fprintf(stderr, " you can use any combination from gb/gbk/big/sjis/jis(euc)/ksc/uhc\n");
fprintf(stderr, " With only a CONVOPTION option, %s will operate in stdin/stdout mode.\n", argv[0]);
}
void PrintVersion(char *argv[])
{
fprintf(stderr, "%s %s (%s)\n", VER_REVISION, VER_DATE, argv[0]);
}
FILE* OpenInFile(char *ipFN)
{
return (fopen(ipFN, R_CNTRL));
}
FILE* OpenOutFile(char *ipFN)
{
return (fopen(ipFN, W_CNTRL));
}
int CCEConvertNewFile(char *ipInFN, char *ipOutFN, CFlag *ipFlag)
{
int RetVal = 0;
FILE *InF = NULL;
FILE *TempF = NULL;
char TempPath[16];
struct stat StatBuf;
struct utimbuf UTimeBuf;
if ((ipFlag->KeepDate || ipFlag->KeepPerm) && stat(ipInFN, &StatBuf))
RetVal = -1;
strcpy(TempPath, "./ccetmpXXXXXX");
#ifndef __MINGW32__
mkstemp (TempPath); /* FIXME: a hack for MinGW32, no mkstemp, dangerous! */
#endif
#ifdef DEBUG
fprintf(stderr, "cceconv: using %s as temp file\n", TempPath);
#endif /* DEBUG */
if ((!RetVal) && ((InF=OpenInFile(ipInFN)) == NULL))
RetVal = -1;
if ((!RetVal) && (InF) && ((TempF=OpenOutFile(TempPath)) == NULL))
{
fclose (InF);
RetVal = -1;
}
if ((!RetVal) && (CCEConvertFile(InF, TempF, ipFlag)))
RetVal = -1;
if ((InF) && (fclose(InF) == EOF))
RetVal = -1;
if ((TempF) && (fclose(TempF) == EOF))
RetVal = -1;
if ((!RetVal) && (ipFlag->KeepDate))
{
UTimeBuf.actime = StatBuf.st_atime;
UTimeBuf.modtime = StatBuf.st_mtime;
if (utime(TempPath, &UTimeBuf) == -1)
RetVal = -1;
}
if ((!RetVal) && (ipFlag->KeepPerm))
{
if (chmod(TempPath,StatBuf.st_mode) == -1)
RetVal = -1;
}
if ((RetVal) && (unlink(TempPath)))
RetVal = -1;
if (!RetVal)
{
if (stat(ipOutFN, &StatBuf) == 0)
unlink(ipOutFN);
if ((rename(TempPath, ipOutFN) == -1) && (!ipFlag->Quiet))
{
fprintf(stderr, "cceconv: problems renaming '%s' to '%s'\n", TempPath, ipOutFN);
fprintf(stderr, " output file remains in '%s'\n", TempPath);
RetVal = -1;
}
}
return RetVal;
}
int CCEConvertOldFile(char* ipInFN, CFlag *ipFlag)
{
int RetVal = 0;
FILE *InF = NULL;
FILE *TempF = NULL;
char TempPath[16];
struct stat StatBuf;
struct utimbuf UTimeBuf;
if ((ipFlag->KeepDate || ipFlag->KeepPerm) && stat(ipInFN, &StatBuf))
RetVal = -1;
strcpy(TempPath, "./ccetmpXXXXXX");
#ifndef __MINGW32__
mkstemp (TempPath); /* FIXME: a hack for MinGW32, no mkstemp */
#endif
#ifdef DEBUG
fprintf(stderr, "cceconv: using %s as temp file\n", TempPath);
#endif /* DEBUG */
if ((!RetVal) && ((InF=OpenInFile(ipInFN)) == NULL))
RetVal = -1;
if ((!RetVal) && (InF) && ((TempF=OpenOutFile(TempPath)) == NULL))
{
fclose (InF);
RetVal = -1;
}
if ((!RetVal) && (CCEConvertFile(InF, TempF, ipFlag)))
RetVal = -1;
if ((InF) && (fclose(InF) == EOF))
RetVal = -1;
if ((TempF) && (fclose(TempF) == EOF))
RetVal = -1;
if ((!RetVal) && (ipFlag->KeepDate))
{
UTimeBuf.actime = StatBuf.st_atime;
UTimeBuf.modtime = StatBuf.st_mtime;
if (utime(TempPath, &UTimeBuf) == -1)
RetVal = -1;
}
if ((!RetVal) && (ipFlag->KeepPerm))
{
if (chmod(TempPath,StatBuf.st_mode) == -1)
RetVal = -1;
}
if ((!RetVal) && (unlink(ipInFN) == -1))
RetVal = -1;
if ((RetVal) && (unlink(TempPath)))
RetVal = -1;
if ((!RetVal) && (rename(TempPath, ipInFN) == -1))
{
if (!ipFlag->Quiet)
{
fprintf(stderr, "cceconv: problems renaming '%s' to '%s'\n", TempPath, ipInFN);
fprintf(stderr, " output file remains in '%s'\n", TempPath);
}
RetVal = -1;
}
return RetVal;
}
int CCEConvertStdio(CFlag *ipFlag)
{
ipFlag->NewFile = 1;
ipFlag->Quiet = 1;
ipFlag->KeepDate = 0;
ipFlag->KeepPerm = 0;
return (CCEConvertFile(stdin, stdout, ipFlag));
}
static int GetCoding(char *p)
{
if (!p || !*p) return -1;
if (strncasecmp(p, "gbk", 3) == 0) return CODE_GBK;
if (strncasecmp(p, "big", 3) == 0 || strncasecmp(p, "b5", 2) == 0) return CODE_BIG5;
if (strncasecmp(p, "ks", 2) == 0) return CODE_KSC;
if (strncasecmp(p, "gb", 2) == 0 )return CODE_GB;
if (strncasecmp(p, "euc", 3) == 0 || strncasecmp(p, "jis", 3) == 0) return CODE_EUC;
if (strncasecmp(p, "sjis", 4) == 0 || strncasecmp(p, "shiftjis", 8) == 0) return CODE_SJIS;
if (strncasecmp(p, "uhc", 3) == 0) return CODE_UHC;
if (strncasecmp(p, "unicode", 7) == 0) return CODE_UNICODE;
if (strncasecmp(p, "dos", 3) == 0 || strcasecmp(p, "d") == 0 ) return DOS_MODE;
if (strncasecmp(p, "unix", 4) == 0 || strcasecmp(p, "u") == 0) return UNIX_MODE;
return -1;
}
int cceconvert_main (int argc, char *argv[])
{
int ArgIdx;
int CanSwitchFileMode;
int ShouldExit;
CFlag *pFlag;
char *p;
ArgIdx = 0;
CanSwitchFileMode = 1;
ShouldExit = 0;
pFlag = (CFlag*)malloc(sizeof(CFlag));
pFlag->NewFile = 0;
pFlag->Quiet = 0;
pFlag->KeepDate = 0;
pFlag->KeepPerm = 0;
pFlag->OldCoding = -1;
pFlag->NewCoding = -1;
if (argc == 1) /* no option specified */
{
PrintUsage(argv);
exit(0);
}
while ((++ArgIdx < argc) && (!ShouldExit))
{
if (argv[ArgIdx][0] == '-')
{
p = index(argv[ArgIdx], '2');
if (p) /* conversion option */
{
*p++ = '\0';
pFlag->OldCoding = GetCoding(argv[ArgIdx]+1);
pFlag->NewCoding = GetCoding(p);
if (pFlag->OldCoding < 0 || pFlag->NewCoding < 0 ||
(pFlag->OldCoding < CODE_NUM && pFlag->NewCoding >= CODE_NUM) ||
(pFlag->OldCoding >= CODE_NUM && pFlag->NewCoding < CODE_NUM) )
{
fprintf(stderr, "%s: Unrecognized conversion request (%s to %s)\n",
argv[0], argv[ArgIdx]+1, p);
ShouldExit = 1;
}
else if (pFlag->OldCoding == pFlag->NewCoding)
{
fprintf(stderr, "%s: No conversion necessary (%s to %s)\n",
argv[0], argv[ArgIdx]+1, p);
ShouldExit = 1;
}
if (!ShouldExit)
{
#ifdef CONVTABLE_USE_MMAP
if (pFlag->OldCoding < CODE_NUM) MmapConvertTable(CCELIB "/" CONV_TABLE_FILE);
#endif
if (ArgIdx == 1 && argc == 2)
exit(CCEConvertStdio(pFlag));
}
}
if ((strcmp(argv[ArgIdx],"-h") == 0) || (strcmp(argv[ArgIdx],"--help") == 0))
PrintUsage(argv);
if ((strcmp(argv[ArgIdx],"-k") == 0) || (strcmp(argv[ArgIdx],"--keepdate") == 0))
pFlag->KeepDate = 1;
if ((strcmp(argv[ArgIdx],"-p") == 0) || (strcmp(argv[ArgIdx],"--keepperm") == 0))
pFlag->KeepPerm = 1;
if ((strcmp(argv[ArgIdx],"-q") == 0) || (strcmp(argv[ArgIdx],"--quiet") == 0))
pFlag->Quiet = 1;
if ((strcmp(argv[ArgIdx],"-V") == 0) || (strcmp(argv[ArgIdx],"--version") == 0))
PrintVersion(argv);
if ((strcmp(argv[ArgIdx],"-o") == 0) || (strcmp(argv[ArgIdx],"--oldfile") == 0))
{
if (!CanSwitchFileMode)
{
if (!pFlag->Quiet)
fprintf(stderr, "%s: target of file %s not specified in new file mode\n",
argv[0], argv[ArgIdx-1]);
ShouldExit = 1;
}
pFlag->NewFile = 0;
}
if ((strcmp(argv[ArgIdx],"-n") == 0) || (strcmp(argv[ArgIdx],"--newfile") == 0))
{
if (!CanSwitchFileMode)
{
if (!pFlag->Quiet)
fprintf(stderr, "%s: target of file %s not specified in new file mode\n",
argv[0], argv[ArgIdx-1]);
ShouldExit = 1;
}
pFlag->NewFile = 1;
}
}
else
{
if (pFlag->NewFile) /* if NewFile mode, filename in pairs */
{
if (CanSwitchFileMode)
CanSwitchFileMode = 0; /* wait until the next filename */
else
{
if (pFlag->OldCoding < 0 || pFlag->NewCoding < 0)
{
fprintf(stderr, "%s: no conversion option specified.\n", argv[0]);
ShouldExit = 1;
continue;
}
if (!pFlag->Quiet)
fprintf(stderr, "%s: converting file %s to file %s in %s format ...\n",
argv[0], argv[ArgIdx-1], argv[ArgIdx], codingName[pFlag->NewCoding]);
if (CCEConvertNewFile(argv[ArgIdx-1], argv[ArgIdx], pFlag))
{
if (!pFlag->Quiet)
fprintf(stderr, "%s: problems converting file %s to file %s\n",
argv[0], argv[ArgIdx-1], argv[ArgIdx]);
ShouldExit = 1;
}
CanSwitchFileMode = 1;
}
}
else /*OldFile mode, filename not in pairs */
{
if (pFlag->OldCoding < 0 || pFlag->NewCoding < 0)
{
fprintf(stderr, "%s: no conversion option specified.\n", argv[0]);
ShouldExit = 1;
continue;
}
if (!pFlag->Quiet)
fprintf(stderr, "%s: converting file %s to %s format ...\n",
argv[0], argv[ArgIdx], codingName[pFlag->NewCoding] );
if (CCEConvertOldFile(argv[ArgIdx], pFlag))
{
if (!pFlag->Quiet)
fprintf(stderr, "%s: problems converting file %s\n", argv[0], argv[ArgIdx]);
ShouldExit = 1;
}
}
}
}
if ((!pFlag->Quiet) && (!CanSwitchFileMode) && (pFlag->OldCoding >=0 && pFlag->NewCoding >= 0))
{
fprintf(stderr, "%s: target of file %s not specified in new file mode\n",
argv[0], argv[ArgIdx-1]);
ShouldExit = 1;
}
free(pFlag);
#ifdef CONVTABLE_USE_MMAP
MunmapConvertTable(); /* unmap the conversion table */
#endif
return (ShouldExit);
}