/* vi:ts=4:sw=4

	jptab.h generator (SJIS or EUC file)

*/

#ifndef KANJI
#define KANJI
#endif

#include <stdio.h>
#include "vim.h"
#include "kanji.h"

char_u *										/* 戝暥帤埖偄偺婰崋 */
Upsyms = "乛丳亯亸仜仚丷丼乂丄丅亱丒乧丩乪乬亖亙亜亄仏亾乥乕乮乯乷乸乽乿";

char_u *										/* 彫暥帤埖偄偺婰崋 */
Losyms = "乢丵亰亹仠仛乀乁乆丆丏亷乚乨丮乫乭亗亝亞亇亊亐乤亅乹乺乲乴亀亁";

char_u *										/* 嬛懃張棟傪峴偆婰崋 */
Pcsyms = "乕亅丄丅丆丏丗丟丠両丣並亱亴亶亷丩丷丼乀乁乄乆乊乂乧乨乫乭乯乴乶乸乺乼乿亁亃";
char_u * Pckana = "偀偂偅偉偋傖傘傚傡偭";		/* 嬛懃張棟傪峴偆壖柤 */
char_u * PCASCI = ".,:;!?>)}]-";				/* 嬛懃張棟傪峴偆ASCII暥帤*/
char_u * Posyms = "丮乪乬乮乲乵乷乹乻乽亀亂亸亹亼亽仒";/* 嬛懃張棟(close)偺婰崋 */
char_u * POASCI = "<({[@`";						/* 嬛懃張棟(close) */

char_u *Spsyms = "丂丵";						/* 嬻敀埖偄偺婰崋 */
char_u *Kjsyms = "乄乆乊乂";					/* 娍帤埖偄偺婰崋 */
char_u *Ktsyms = "乕亅";						/* 僇僞僇僫埖偄偺婰崋 */
char_u *Hrsyms = "丷丼乀乁";					/* 傂傜偑側埖偄偺婰崋 */
char_u *Sesyms = "丅丏丠両";					/* 暥枛偺婰崋 */


/*	JIS X 0201 敿妏僇僫 偲 JIS X0208 慡妏娍帤偺僇僞僇僫晹暘偲偺懳墳  */
char_u *JISX0201 = 
"  丅乽乿丄丒儝傽傿僁僃僅儍儏儑僢亅傾僀僂僄僆僇僉僋働僐僒僔僗僙僜僞僠僣僥僩僫僯僰僱僲僴僸僼僿儂儅儈儉儊儌儎儐儓儔儕儖儗儘儚儞丣並";

/*  偁偄傑偄専嶕  */
char_u *Ksyms[] = {
	"!両",	"\"乭",	"#仈",	"$亹",	"%亾",	"&仌",	"'乫",	"(乮", ")乯",
	"-亅",	"=亖",	"^丱",	"~丳",	"\\亸",	"|乥",	"@仐",	"`乪", "[乵",
	"{乷",	";丟",	"+亄",	":丗",	"*仏",	"]乶",	"}乸",	",丆", "<亙",
	".丏",	">亜",	"/乛",	"?丠",	" 丂",	"\t丂",	"\0\0\0",
	NULL};

/* tracktab偺擔杮岅暥帤僙僢僩 */
char_u *trackset[] =
{
	"tracktab_jp",
		"  ", "伀", "仾", "劆", "仺", "劊", "劉", "劎",
		"仼", "劋", "劇", "劌", "劅", "劏", "劍", "劑", "",
	"tracktab_bj",
		"  ", "伀", "仾", "劔", "仺", "劗", "劖", "劜",
		"仼", "劘", "劕", "劙", "劒", "劤", "劚", "劥", "",
	"tracktab_hj",
		"  ", "伀", "仾", "劆", "仺", "劊", "劉", "劶",
		"仼", "劘", "劕", "労", "劒", "劯", "劧", "劰", "",
	NULL
};

char_u *UPSYMS;
char_u *LOSYMS;
char_u *PCSYMS;
char_u *PCKANA;
char_u *POSYMS;
char_u *SPSYMS;
char_u *KJSYMS;
char_u *KTSYMS;
char_u *HRSYMS;
char_u *SESYMS;

#define JPC_NG ((char)-1)
#define JUPS 1
#define JLOS 2

struct _jptab
{
	char cls1, cls2;
#if 0
	/* Turbo C++ doesn't handle bitfields correctly... */
	unsigned int punccsym, puncckana, punccasc;
	unsigned int puncosym, puncoasc, stcend;
	unsigned int scase;
#else
	unsigned int punccsym:1, puncckana:1, punccasc:1;
	unsigned int puncosym:1, puncoasc:1, stcend:1;
	unsigned int scase:2;
#endif
	char swap;
} jptab[128];

char *macroJPC[128];

static void		sjistoeuc __ARGS((char_u *, char_u *));
static void		euctosjis __ARGS((char_u *, char_u *));

	static void
sjistoeuc(high, low)
char_u	*	high;
char_u	*	low;
{
	if (*high <= 0x9f)
		*high -= 0x71;
	else
		*high -= 0xb1;
	*high = *high * 2 + 1;
	if (*low > 0x7f)
		(*low)--;
	if (*low >= 0x9e)
	{
		*low -= 0x7d;
		(*high)++;
	}
	else
	{
		*low -= 0x1f;
	}
}

	static void
euctosjis(high, low)
char_u	*	high;
char_u	*	low;
{
	*low  &= 0x7f;
	*high &= 0x7f;
	if (*high & 1)
		*low += 0x1f;
	else
		*low += 0x7d;
	if (*low >= 0x7f)
		(*low)++;
	*high = (*high - 0x21 >> 1) + 0x81;
	if (*high > 0x9f)
		*high += 0x40;
}


#if defined(UTS4)
    int
#else
	void
#endif
main()
{
	int i;
	char_u *cp, *dp;

	UPSYMS = strdup(Upsyms);
	LOSYMS = strdup(Losyms);
	PCSYMS = strdup(Pcsyms);
	PCKANA = strdup(Pckana);
	POSYMS = strdup(Posyms);
	SPSYMS = strdup(Spsyms);
	KJSYMS = strdup(Kjsyms);
	KTSYMS = strdup(Ktsyms);
	HRSYMS = strdup(Hrsyms);
	SESYMS = strdup(Sesyms);

	/* convert kanji code start */
	if ((char_u)UPSYMS[0] == 0x81 && (char_u)UPSYMS[1] == 0x5e)
	{
		fprintf(stderr, "\tSJIS -> EUC convert\n");
		for(cp = UPSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = LOSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = PCSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = PCKANA; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = POSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = SPSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = KJSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = KTSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = HRSYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
		for(cp = SESYMS; *cp; cp+=2) sjistoeuc(cp, cp+1);
	}
	else
	{
		char_u **tp;

		fprintf(stderr, "\tEUC -> SJIS convert\n");
		for (tp = trackset; *tp; tp++)
		{
			tp++;
			for(; **tp; tp++)
				if (**tp >= 0x80) euctosjis(*tp, (*tp)+1);
		}
		for (cp = JISX0201; *cp; cp+=2)
			if (*cp >= 0x80) euctosjis(cp, cp+1);
	}
	/* convert kanji code end */


	printf("/*\n");
	printf("   This table is generated by jptab.c. \n");
	printf("*/\n\n");
	printf("#ifndef JP_TRACKTAB\n");
	printf("#define JUPS 1\n");
	printf("#define JLOS 2\n\n");
	printf("#define JPCS TRUE\n");
	printf("#define JPOS TRUE\n");
	printf("#define JPCK TRUE\n");
	printf("#define JPCA TRUE\n\n");
	printf("#define JPOA TRUE\n\n");
	printf("static struct _jptab\n");
	printf("{\n");
	printf("\tchar\tcls1, cls2;\n");
#if 0
	printf("\tunsigned int\tpunccsym, puncckana, punccasc;\n");
	printf("\tunsigned int\tpuncosym, puncoasc, stcend;\n");
	printf("\tunsigned int\tscase;\n");
#else
	printf("\tunsigned int\tpunccsym:1, puncckana:1, punccasc:1;\n");
	printf("\tunsigned int\tpuncosym:1, puncoasc:1, stcend:1;\n");
	printf("\tunsigned int\tscase:2;\n");
#endif
	printf("\tchar\tswap;\n");
	printf("}\t");

	for(i = 0; i < 128; i++)
	{
		jptab[i].cls1 = jptab[i].cls2 = JPC_NG;
		jptab[i].scase = 0;
		jptab[i].punccsym = jptab[i].puncckana = jptab[i].punccasc = 0;
		jptab[i].puncosym = jptab[i].puncoasc  = jptab[i].stcend   = 0;
		jptab[i].swap = i;
	}

	/* init cls1 */
	for(i = ' ' + 1; i < '\177'; i++)
		jptab[i].cls1 = JPC_KANJI;
	jptab[JP1_ALNUM & 0x7f].cls1 = JPC_ALNUM;
	jptab[JP1_HIRA  & 0x7f].cls1 = JPC_HIRA;
	jptab[JP1_KATA  & 0x7f].cls1 = JPC_KATA;
	jptab[JP1_KIGOU & 0x7f].cls1 = JPC_KIGOU;
	jptab[JP1_KIGOU2& 0x7f].cls1 = JPC_KIGOU2;

	for(i = 0; i < 128; i++)
		macroJPC[i] = "JPTAB macro JPC_XXX ERROR";
	macroJPC[0] =         "/*Spc*/ 0";
	macroJPC[JPC_ALNUM] = "JPC_ALNUM";
	macroJPC[JPC_HIRA ] = "JPC_HIRA ";
	macroJPC[JPC_KATA ] = "JPC_KATA ";
	macroJPC[JPC_KIGOU] = "JPC_KIGOU";
	macroJPC[JPC_KIGOU2]= "JPC_KIGOU2";
	macroJPC[JPC_KANJI] = "JPC_KANJI";

	/* init cls2 */
	for(i = ' ' + 1; i < '\177'; i++)
		jptab[i].cls2 = JPC_KIGOU;
	for(cp = SPSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].cls2 = 0;
	for(cp = KJSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].cls2 = JPC_KANJI;
	for(cp = KTSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].cls2 = JPC_KATA;
	for(cp = HRSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].cls2 = JPC_HIRA;

	/* init puncsym, punckana */
	for(cp = PCSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].punccsym  = 1;
	for(cp = PCKANA; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].puncckana = 1;
	for(cp = PCASCI; *cp; cp++)  jptab[ *cp & 0x7f ].punccasc = 1;

	for(cp = POSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].puncosym  = 1;
	for(cp = POASCI; *cp; cp++)  jptab[ *cp & 0x7f ].puncoasc = 1;

	/* init stcend */
	for(cp = SESYMS; *cp; cp++)  jptab[ *cp & 0x7f ].stcend = 1;

	/* init scase */
	for(cp = UPSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].scase = JUPS;
	for(cp = LOSYMS; *cp; cp+=2) jptab[ *(cp + 1) & 0x7f ].scase = JLOS;

	/* init swap */
	for(cp = UPSYMS, dp = LOSYMS; *cp; cp+=2, dp+=2)
		jptab[ *(cp + 1) & 0x7f ].swap = *(dp + 1);
	for(cp = LOSYMS, dp = UPSYMS; *cp; cp+=2, dp+=2)
		jptab[ *(cp + 1) & 0x7f ].swap = *(dp + 1);

	printf("\tjptab[128] = {\n");

	for(i = 0; i < 128; i++)
    {
		printf("{");

		/* cls1 */
		printf("%9s,", jptab[i].cls1==JPC_NG ? "-1": macroJPC[jptab[i].cls1]);
		/* cls2 */
		printf("%9s,", jptab[i].cls2==JPC_NG ? "-1": macroJPC[jptab[i].cls2]);

		/* punccsym  */
		printf("%s,", jptab[i].punccsym  ? "JPCS": "   0");
		/* puncckana  */
		printf("%s,", jptab[i].puncckana ? "JPCK": "   0");
		/* punccasc  */
		printf("%s,", jptab[i].punccasc  ? "JPCA": "   0");

		/* puncosym  */
		printf("%s,", jptab[i].puncosym  ? "JPOS": "   0");
		/* puncoasc  */
		printf("%s,", jptab[i].puncoasc  ? "JPOA": "   0");

		/* stcend  */
		printf("%s,", jptab[i].stcend  ? "1": "0");

		/* scase */
		switch(jptab[i].scase)
		{
			case JUPS: printf("JUPS,");break;
			case JLOS: printf("JLOS,");break;
			default:   printf("   0,");
		}

		/* swap */
#ifdef comment
		if ((jptab[i].swap & 0x7f) > ' '&& (jptab[i].swap & 0x7f) < '\177')
			printf("/*%c%c*/", JP1_KIGOU | 0x80, jptab[i].swap);
		else
			printf("/*%2x*/", jptab[i].swap & 0x7f);
			/*printf("      ");*/
#endif
		printf("'\\%03o' ", jptab[i].swap & 0xff);

		/* */
		printf("}");

#ifdef comment
		if ( i > ' ' && i < '\177')
			printf("/*%c %c%c%c%c */ ",
							i, JP1_HIRA|0x80, i|0x80,
							   JP1_KIGOU|0x80,i|0x80);
		else
			printf("/* 0x%02x  */ ", i);
#endif

		printf(i != '\177' ? ",\n": "\n");
	}
	printf("};\n\n");
	/*
	 *  JIS X 0201R <-> JIS X 0208 conversion table
	 */
	printf("char jisx0201r[] =");
	printf("{\n");
	for(cp = JISX0201; *cp; cp+=2)
#ifdef comment
		printf("\t '\\%03o', '\\%03o', /* %c%c */\n",
				*cp & 0xff , *(cp + 1) & 0xff, *cp, *(cp + 1));
#else
		printf("\t '\\%03o', '\\%03o',\n", *cp & 0xff , *(cp + 1) & 0xff);
#endif
	printf("};\n\n");
 	{
		char_u **	tp;
		int			i;

		printf("char *Asconv[] =\n");
		printf("{\n");
		for(tp = Ksyms, i = 1; *tp; tp++, i++)
		{
			unsigned char *cp = *tp;

			printf(" \"");
			printf("\\%03o", *(cp + 0));
			printf("\\%03o", *(cp + 1));
			printf("\\%03o", *(cp + 2));
			printf("\"/* %c */,", *cp == '\0' ? '@' : *cp);
			if (*(tp + 1) == NULL)
				break;
			if (i % 3 == 0)
				printf("\n");
			else
				printf(" ");
		}
		printf("\n};\n\n");
	}

/*
 *
 * JP_TRACKTAB
 *
 */
	printf("#else /* JP_TRACKTAB */\n");
 	{
		char_u **tp;
		for(tp = trackset; *tp; tp++)
		{
			int i;
			printf("char *%s[] =\n", *tp++);
			printf("{\n");
			for(i = 1; **tp; tp++, i++)
			{
				unsigned char *cp;
				int n;

				printf(" \"");
				for(n = 0, cp = (unsigned char *)*tp; *cp; cp++)
				{
					printf("\\%03o", *cp);
					n += 4;
				}
				printf("\"");
				for(; n < 8; n++)
					printf(" ");
#ifdef comment
				printf("/*%s*/", *tp);
#endif
				if (**(tp + 1))
					printf(",");
				if (i % 4 == 0)
					printf("\n");
			}
			printf("};\n");
		}
	}
	printf("#endif /* JP_TRACKTAB */\n");
	exit(0);
}
