mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-26 08:28:04 +03:00
This replaces BYTE, WORD and DWORD types with uint8_t, uint16_t and uint32_t respectively.
405 lines
14 KiB
C
405 lines
14 KiB
C
/*
|
||
* hankaku.c 全角->半角変換
|
||
*
|
||
* Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
|
||
* 1998- <masaki-c@is.aist-nara.ac.jp>
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
*
|
||
*
|
||
*/
|
||
/* $Id: hankaku.c,v 1.7 2001/03/22 11:10:13 chikama Exp $ */
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
|
||
#include "portab.h"
|
||
#include "hankaku.h"
|
||
#include "system.h"
|
||
|
||
static const uint8_t hankakutable[3][192] = {{
|
||
// 0x8140 - 0x81ff
|
||
' ', 0xa4, 0xa1, ',', '.', 0xa5, ':', ';',
|
||
'?', '!', 0xde, 0xdf, 0, '`', 0, '^',
|
||
'~', '_', 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0xb0, 0, 0, '/', 0,
|
||
0, 0, '|', 0, 0, 0, '\'', 0,
|
||
'"', '(', ')', 0, 0, '[', ']', '{',
|
||
'}', 0, 0, 0, 0, 0xa2, 0xa3, 0,
|
||
0, 0, 0, '+', '-', 0, 0, 0,
|
||
0, '=', 0, '<', '>', 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, '\\',
|
||
'$', 0, 0, '%', '#', '&', '*', '@',
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
},{ // 0x8240 - 0x82ff
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, '0',
|
||
'1', '2', '3', '4', '5', '6', '7', '8',
|
||
'9', 0, 0, 0, 0, 0, 0, 0,
|
||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||
'Y', 'Z', 0, 0, 0, 0, 0, 0,
|
||
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||
'x', 'y', 'z', 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
},{ // 0x8340 - 0x83ff
|
||
0xa7, 0xb1, 0xa8, 0xb2, 0xa9, 0xb3, 0xaa, 0xb4,
|
||
0xab, 0xb5, 0xb6, 0, 0xb7, 0, 0xb8, 0,
|
||
0xb9, 0, 0xba, 0, 0xbb, 0, 0xbc, 0,
|
||
0xbd, 0, 0xbe, 0, 0xbf, 0, 0xc0, 0,
|
||
0xc1, 0, 0xaf, 0xc2, 0, 0xc3, 0, 0xc4,
|
||
0, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0,
|
||
0, 0xcb, 0, 0, 0xcc, 0, 0, 0xcd,
|
||
0, 0, 0xce, 0, 0, 0xcf, 0xd0, 0,
|
||
0xd1, 0xd2, 0xd3, 0xac, 0xd4, 0xad, 0xd5, 0xae,
|
||
0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0, 0xdc,
|
||
0, 0, 0xa6, 0xdd, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
0, 0, 0, 0, 0, 0, 0, 0,
|
||
}};
|
||
|
||
static const uint16_t kanatbl[] = {
|
||
0x8140, 0x8142, 0x8175, 0x8176, 0x8141, 0x8145, 0x82f0, 0x829f,
|
||
0x82a1, 0x82a3, 0x82a5, 0x82a7, 0x82e1, 0x82e3, 0x82e5, 0x82c1,
|
||
0x815b, 0x82a0, 0x82a2, 0x82a4, 0x82a6, 0x82a8, 0x82a9, 0x82ab,
|
||
0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5, 0x82b7, 0x82b9, 0x82bb,
|
||
0x82bd, 0x82bf, 0x82c2, 0x82c4, 0x82c6, 0x82c8, 0x82c9, 0x82ca,
|
||
0x82cb, 0x82cc, 0x82cd, 0x82d0, 0x82d3, 0x82d6, 0x82d9, 0x82dc,
|
||
0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e2, 0x82e4, 0x82e6, 0x82e7,
|
||
0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ed, 0x82f1, 0x814a, 0x814b
|
||
};
|
||
|
||
static const char zenkaku_digits[][3] = {
|
||
{0x82, 0x4f, 0x00}, /* 0 */
|
||
{0x82, 0x50, 0x00}, /* 1 */
|
||
{0x82, 0x51, 0x00}, /* 2 */
|
||
{0x82, 0x52, 0x00}, /* 3 */
|
||
{0x82, 0x53, 0x00}, /* 4 */
|
||
{0x82, 0x54, 0x00}, /* 5 */
|
||
{0x82, 0x55, 0x00}, /* 6 */
|
||
{0x82, 0x56, 0x00}, /* 7 */
|
||
{0x82, 0x57, 0x00}, /* 8 */
|
||
{0x82, 0x58, 0x00}, /* 9 */
|
||
{0x81, 0x40, 0x00}, /* space */
|
||
};
|
||
|
||
static uint8_t *zen2han_sjis(const uint8_t *src) {
|
||
uint8_t c0, c1;
|
||
char *dst, *_dst;
|
||
|
||
dst = _dst = malloc(strlen(src) + 1);
|
||
if (dst == NULL)
|
||
NOMEMERR();
|
||
|
||
while(0 != (c0 = *src++)) {
|
||
if (c0 < 0x81) {
|
||
*dst++ = c0;
|
||
} else if (c0 <= 0x83) {
|
||
c1 = *src++;
|
||
uint8_t h = hankakutable[c0 - 0x81][c1 - 0x40];
|
||
if (h) {
|
||
*dst++ = h;
|
||
} else {
|
||
*dst++ = c0; *dst++ = c1;
|
||
}
|
||
} else if (c0 < 0xa0){
|
||
*dst++ = c0; *dst++ = *src++;
|
||
} else if (c0 < 0xe0){
|
||
*dst++ = c0;
|
||
} else {
|
||
*dst++ = c0; *dst++ = *src++;
|
||
}
|
||
}
|
||
*dst = 0;
|
||
return _dst;
|
||
}
|
||
|
||
static char *zen2han_utf8(const char *src) {
|
||
char *dst, *_dst;
|
||
dst = _dst = malloc(strlen(src) + 1);
|
||
if (dst == NULL)
|
||
NOMEMERR();
|
||
|
||
const char *p = src;
|
||
while (*p) {
|
||
const char *prev = p;
|
||
switch (utf8_next_codepoint(&p)) {
|
||
case L'’': *dst++ = '\''; break;
|
||
case L'”': *dst++ = '"'; break;
|
||
case L' ': *dst++ = ' '; break;
|
||
case L'、': strcpy(dst, "、"); dst += 3; break;
|
||
case L'。': strcpy(dst, "。"); dst += 3; break;
|
||
case L'「': strcpy(dst, "「"); dst += 3; break;
|
||
case L'」': strcpy(dst, "」"); dst += 3; break;
|
||
case L'゛': strcpy(dst, "゙"); dst += 3; break;
|
||
case L'゜': strcpy(dst, "゚"); dst += 3; break;
|
||
case L'ァ': strcpy(dst, "ァ"); dst += 3; break;
|
||
case L'ア': strcpy(dst, "ア"); dst += 3; break;
|
||
case L'ィ': strcpy(dst, "ィ"); dst += 3; break;
|
||
case L'イ': strcpy(dst, "イ"); dst += 3; break;
|
||
case L'ゥ': strcpy(dst, "ゥ"); dst += 3; break;
|
||
case L'ウ': strcpy(dst, "ウ"); dst += 3; break;
|
||
case L'ェ': strcpy(dst, "ェ"); dst += 3; break;
|
||
case L'エ': strcpy(dst, "エ"); dst += 3; break;
|
||
case L'ォ': strcpy(dst, "ォ"); dst += 3; break;
|
||
case L'オ': strcpy(dst, "オ"); dst += 3; break;
|
||
case L'カ': strcpy(dst, "カ"); dst += 3; break;
|
||
case L'キ': strcpy(dst, "キ"); dst += 3; break;
|
||
case L'ク': strcpy(dst, "ク"); dst += 3; break;
|
||
case L'ケ': strcpy(dst, "ケ"); dst += 3; break;
|
||
case L'コ': strcpy(dst, "コ"); dst += 3; break;
|
||
case L'サ': strcpy(dst, "サ"); dst += 3; break;
|
||
case L'シ': strcpy(dst, "シ"); dst += 3; break;
|
||
case L'ス': strcpy(dst, "ス"); dst += 3; break;
|
||
case L'セ': strcpy(dst, "セ"); dst += 3; break;
|
||
case L'ソ': strcpy(dst, "ソ"); dst += 3; break;
|
||
case L'タ': strcpy(dst, "タ"); dst += 3; break;
|
||
case L'チ': strcpy(dst, "チ"); dst += 3; break;
|
||
case L'ッ': strcpy(dst, "ッ"); dst += 3; break;
|
||
case L'ツ': strcpy(dst, "ツ"); dst += 3; break;
|
||
case L'テ': strcpy(dst, "テ"); dst += 3; break;
|
||
case L'ト': strcpy(dst, "ト"); dst += 3; break;
|
||
case L'ナ': strcpy(dst, "ナ"); dst += 3; break;
|
||
case L'ニ': strcpy(dst, "ニ"); dst += 3; break;
|
||
case L'ヌ': strcpy(dst, "ヌ"); dst += 3; break;
|
||
case L'ネ': strcpy(dst, "ネ"); dst += 3; break;
|
||
case L'ノ': strcpy(dst, "ノ"); dst += 3; break;
|
||
case L'ハ': strcpy(dst, "ハ"); dst += 3; break;
|
||
case L'ヒ': strcpy(dst, "ヒ"); dst += 3; break;
|
||
case L'フ': strcpy(dst, "フ"); dst += 3; break;
|
||
case L'ヘ': strcpy(dst, "ヘ"); dst += 3; break;
|
||
case L'ホ': strcpy(dst, "ホ"); dst += 3; break;
|
||
case L'マ': strcpy(dst, "マ"); dst += 3; break;
|
||
case L'ミ': strcpy(dst, "ミ"); dst += 3; break;
|
||
case L'ム': strcpy(dst, "ム"); dst += 3; break;
|
||
case L'メ': strcpy(dst, "メ"); dst += 3; break;
|
||
case L'モ': strcpy(dst, "モ"); dst += 3; break;
|
||
case L'ャ': strcpy(dst, "ャ"); dst += 3; break;
|
||
case L'ヤ': strcpy(dst, "ヤ"); dst += 3; break;
|
||
case L'ュ': strcpy(dst, "ュ"); dst += 3; break;
|
||
case L'ユ': strcpy(dst, "ユ"); dst += 3; break;
|
||
case L'ョ': strcpy(dst, "ョ"); dst += 3; break;
|
||
case L'ヨ': strcpy(dst, "ヨ"); dst += 3; break;
|
||
case L'ラ': strcpy(dst, "ラ"); dst += 3; break;
|
||
case L'リ': strcpy(dst, "リ"); dst += 3; break;
|
||
case L'ル': strcpy(dst, "ル"); dst += 3; break;
|
||
case L'レ': strcpy(dst, "レ"); dst += 3; break;
|
||
case L'ロ': strcpy(dst, "ロ"); dst += 3; break;
|
||
case L'ワ': strcpy(dst, "ワ"); dst += 3; break;
|
||
case L'ヲ': strcpy(dst, "ヲ"); dst += 3; break;
|
||
case L'ン': strcpy(dst, "ン"); dst += 3; break;
|
||
case L'・': strcpy(dst, "・"); dst += 3; break;
|
||
case L'ー': strcpy(dst, "ー"); dst += 3; break;
|
||
case L'!': *dst++ = '!'; break;
|
||
case L'#': *dst++ = '#'; break;
|
||
case L'$': *dst++ = '$'; break;
|
||
case L'%': *dst++ = '%'; break;
|
||
case L'&': *dst++ = '&'; break;
|
||
case L'(': *dst++ = '('; break;
|
||
case L')': *dst++ = ')'; break;
|
||
case L'*': *dst++ = '*'; break;
|
||
case L'+': *dst++ = '+'; break;
|
||
case L',': *dst++ = ','; break;
|
||
case L'-': *dst++ = '-'; break;
|
||
case L'.': *dst++ = '.'; break;
|
||
case L'/': *dst++ = '/'; break;
|
||
case L'0': *dst++ = '0'; break;
|
||
case L'1': *dst++ = '1'; break;
|
||
case L'2': *dst++ = '2'; break;
|
||
case L'3': *dst++ = '3'; break;
|
||
case L'4': *dst++ = '4'; break;
|
||
case L'5': *dst++ = '5'; break;
|
||
case L'6': *dst++ = '6'; break;
|
||
case L'7': *dst++ = '7'; break;
|
||
case L'8': *dst++ = '8'; break;
|
||
case L'9': *dst++ = '9'; break;
|
||
case L':': *dst++ = ':'; break;
|
||
case L';': *dst++ = ';'; break;
|
||
case L'<': *dst++ = '<'; break;
|
||
case L'=': *dst++ = '='; break;
|
||
case L'>': *dst++ = '>'; break;
|
||
case L'?': *dst++ = '?'; break;
|
||
case L'@': *dst++ = '@'; break;
|
||
case L'A': *dst++ = 'A'; break;
|
||
case L'B': *dst++ = 'B'; break;
|
||
case L'C': *dst++ = 'C'; break;
|
||
case L'D': *dst++ = 'D'; break;
|
||
case L'E': *dst++ = 'E'; break;
|
||
case L'F': *dst++ = 'F'; break;
|
||
case L'G': *dst++ = 'G'; break;
|
||
case L'H': *dst++ = 'H'; break;
|
||
case L'I': *dst++ = 'I'; break;
|
||
case L'J': *dst++ = 'J'; break;
|
||
case L'K': *dst++ = 'K'; break;
|
||
case L'L': *dst++ = 'L'; break;
|
||
case L'M': *dst++ = 'M'; break;
|
||
case L'N': *dst++ = 'N'; break;
|
||
case L'O': *dst++ = 'O'; break;
|
||
case L'P': *dst++ = 'P'; break;
|
||
case L'Q': *dst++ = 'Q'; break;
|
||
case L'R': *dst++ = 'R'; break;
|
||
case L'S': *dst++ = 'S'; break;
|
||
case L'T': *dst++ = 'T'; break;
|
||
case L'U': *dst++ = 'U'; break;
|
||
case L'V': *dst++ = 'V'; break;
|
||
case L'W': *dst++ = 'W'; break;
|
||
case L'X': *dst++ = 'X'; break;
|
||
case L'Y': *dst++ = 'Y'; break;
|
||
case L'Z': *dst++ = 'Z'; break;
|
||
case L'[': *dst++ = '['; break;
|
||
case L']': *dst++ = ']'; break;
|
||
case L'^': *dst++ = '^'; break;
|
||
case L'_': *dst++ = '_'; break;
|
||
case L'`': *dst++ = '`'; break;
|
||
case L'a': *dst++ = 'a'; break;
|
||
case L'b': *dst++ = 'b'; break;
|
||
case L'c': *dst++ = 'c'; break;
|
||
case L'd': *dst++ = 'd'; break;
|
||
case L'e': *dst++ = 'e'; break;
|
||
case L'f': *dst++ = 'f'; break;
|
||
case L'g': *dst++ = 'g'; break;
|
||
case L'h': *dst++ = 'h'; break;
|
||
case L'i': *dst++ = 'i'; break;
|
||
case L'j': *dst++ = 'j'; break;
|
||
case L'k': *dst++ = 'k'; break;
|
||
case L'l': *dst++ = 'l'; break;
|
||
case L'm': *dst++ = 'm'; break;
|
||
case L'n': *dst++ = 'n'; break;
|
||
case L'o': *dst++ = 'o'; break;
|
||
case L'p': *dst++ = 'p'; break;
|
||
case L'q': *dst++ = 'q'; break;
|
||
case L'r': *dst++ = 'r'; break;
|
||
case L's': *dst++ = 's'; break;
|
||
case L't': *dst++ = 't'; break;
|
||
case L'u': *dst++ = 'u'; break;
|
||
case L'v': *dst++ = 'v'; break;
|
||
case L'w': *dst++ = 'w'; break;
|
||
case L'x': *dst++ = 'x'; break;
|
||
case L'y': *dst++ = 'y'; break;
|
||
case L'z': *dst++ = 'z'; break;
|
||
case L'{': *dst++ = '{'; break;
|
||
case L'|': *dst++ = '|'; break;
|
||
case L'}': *dst++ = '}'; break;
|
||
case L' ̄': *dst++ = '~'; break;
|
||
case L'¥': *dst++ = '\\'; break;
|
||
default:
|
||
while (prev < p)
|
||
*dst++ = *prev++;
|
||
break;
|
||
}
|
||
}
|
||
*dst = 0;
|
||
return _dst;
|
||
}
|
||
|
||
uint8_t *zen2han(const uint8_t *src, CharacterEncoding enc) {
|
||
switch (enc) {
|
||
case SHIFT_JIS:
|
||
return zen2han_sjis(src);
|
||
case UTF8:
|
||
return zen2han_utf8(src);
|
||
default:
|
||
return (uint8_t *)src;
|
||
}
|
||
}
|
||
|
||
uint8_t *han2zen(const uint8_t *src, CharacterEncoding enc) {
|
||
if (enc != SHIFT_JIS)
|
||
return (uint8_t *)src; // Not implemented
|
||
|
||
uint8_t c0;
|
||
uint8_t *dst, *_dst;
|
||
dst = _dst = malloc(strlen(src) * 2 + 1);
|
||
|
||
if (dst == NULL)
|
||
NOMEMERR();
|
||
|
||
while(0 != (c0 = *src++)) {
|
||
if (c0 == 0x20) {
|
||
*dst++ = 0x81; *dst++ = 0x40;
|
||
} else if (c0 < 0x80) {
|
||
*dst++ = c0;
|
||
} else if (c0 >= 0xe0) {
|
||
*dst++ = (char)c0; *dst++ = *src++;
|
||
} else if (c0 >= 0xa0) {
|
||
const uint16_t kana = kanatbl[c0 - 0xa0];
|
||
*dst++ = kana >> 8; *dst++ = kana & 0xff;
|
||
} else {
|
||
*dst++ = (char)c0; *dst++ = *src++;
|
||
}
|
||
}
|
||
*dst = 0;
|
||
return _dst;
|
||
}
|
||
|
||
char *format_number(int n, int width, char *buf) {
|
||
if (width) {
|
||
sprintf(buf, "%*d", width, n);
|
||
return buf + strlen(buf) - width;
|
||
}
|
||
sprintf(buf, "%d", n);
|
||
return buf;
|
||
}
|
||
|
||
char *format_number_zenkaku(int n, int width, char *buf) {
|
||
char work[256];
|
||
char *dst = buf;
|
||
for (char *s = format_number(n, width, work); *s; s++) {
|
||
const char *p = zenkaku_digits[*s == ' ' ? 10 : *s - '0'];
|
||
while (*p)
|
||
*dst++ = *p++;
|
||
}
|
||
*dst = '\0';
|
||
return buf;
|
||
}
|