// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/*
 * make is(upper|lower|title|space|alpha)rune and
 * to(upper|lower|title)rune from a UnicodeData.txt file.
 * these can be found at unicode.org
 *
 * with -c, runs a check of the existing runetype functions vs.
 * those extracted from UnicodeData.
 *
 * with -p, generates tables for pairs of chars, as well as for ranges
 * and singletons.
 *
 * UnicodeData defines 4 fields of interest:
 * 1) a category
 * 2) an upper case mapping
 * 3) a lower case mapping
 * 4) a title case mapping
 *
 * toupper, tolower, and totitle are defined directly from the mapping.
 *
 * isalpharune(c) is true iff c is a "letter" category
 * isupperrune(c) is true iff c is the target of toupperrune,
 *	or is in the uppercase letter category
 * similarly for islowerrune and istitlerune.
 * isspacerune is true for space category chars, "C" locale white space chars,
 *	and two additions:
 *	0085	"next line" control char
 *	feff]	"zero-width non-break space"
 * isdigitrune is true iff c is a numeric-digit category.
 */

#include <u.h>
#include <libc.h>
#include <stdio.h>
#include "utf.h"
#include "utfdef.h"

enum {
	/*
	 * fields in the unicode data file
	 */
	FIELD_CODE,
	FIELD_NAME,
	FIELD_CATEGORY,
	FIELD_COMBINING,
	FIELD_BIDIR,
	FIELD_DECOMP,
	FIELD_DECIMAL_DIG,
	FIELD_DIG,
	FIELD_NUMERIC_VAL,
	FIELD_MIRRORED,
	FIELD_UNICODE_1_NAME,
	FIELD_COMMENT,
	FIELD_UPPER,
	FIELD_LOWER,
	FIELD_TITLE,
	NFIELDS,

	MAX_LINE	= 1024,

	TO_OFFSET	= 1 << 20,

	NRUNES		= 1 << 21,
};

#define TO_DELTA(xmapped,x)	(TO_OFFSET + (xmapped) - (x))

static char	myisspace[NRUNES];
static char	myisalpha[NRUNES];
static char	myisdigit[NRUNES];
static char	myisupper[NRUNES];
static char	myislower[NRUNES];
static char	myistitle[NRUNES];

static int	mytoupper[NRUNES];
static int	mytolower[NRUNES];
static int	mytotitle[NRUNES];

static void	check(void);
static void	mktables(char *src, int usepairs);
static void	fatal(const char *fmt, ...);
static int	mygetfields(char **fields, int nfields, char *str, const char *delim);
static int	getunicodeline(FILE *in, char **fields, char *buf);
static int	getcode(char *s);

static void
usage(void)
{
	fprintf(stderr, "usage: mktables [-cp] <UnicodeData.txt>\n");
	exit(1);
}

int
main(int argc, char *argv[]){
	FILE *in;
	char buf[MAX_LINE], buf2[MAX_LINE];
	char *fields[NFIELDS + 1], *fields2[NFIELDS + 1];
	char *p;
	int i, code, last, docheck, usepairs;

	docheck = 0;
	usepairs = 0;
	ARGBEGIN{
	case 'c':
		docheck = 1;
		break;
	case 'p':
		usepairs = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc != 1){
		usage();
	}

	in = fopen(argv[0], "r");
	if(in == NULL){
		fatal("can't open %s", argv[0]);
	}

	for(i = 0; i < NRUNES; i++){
		mytoupper[i] = i;
		mytolower[i] = i;
		mytotitle[i] = i;
	}

	/*
	 * make sure isspace has all of the "C" locale whitespace chars
	 */
	myisspace['\t'] = 1;
	myisspace['\n'] = 1;
	myisspace['\r'] = 1;
	myisspace['\f'] = 1;
	myisspace['\v'] = 1;

	/*
	 * a couple of other exceptions
	 */
	myisspace[0x85] = 1;	/* control char, "next line" */
	myisspace[0xfeff] = 1;	/* zero-width non-break space */

	last = -1;
	while(getunicodeline(in, fields, buf)){
		code = getcode(fields[FIELD_CODE]);
		if (code >= NRUNES)
			fatal("code-point value too big: %x", code);
		if(code <= last)
			fatal("bad code sequence: %x then %x", last, code);
		last = code;

		/*
		 * check for ranges
		 */
		p = fields[FIELD_CATEGORY];
		if(strstr(fields[FIELD_NAME], ", First>") != NULL){
			if(!getunicodeline(in, fields2, buf2))
				fatal("range start at eof");
			if (strstr(fields2[FIELD_NAME], ", Last>") == NULL)
				fatal("range start not followed by range end");
			last = getcode(fields2[FIELD_CODE]);
			if(last <= code)
				fatal("range out of sequence: %x then %x", code, last);
			if(strcmp(p, fields2[FIELD_CATEGORY]) != 0)
				fatal("range with mismatched category");
		}

		/*
		 * set properties and conversions
		 */
		for (; code <= last; code++){
			if(p[0] == 'L')
				myisalpha[code] = 1;
			if(p[0] == 'Z')
				myisspace[code] = 1;

			if(strcmp(p, "Lu") == 0)
				myisupper[code] = 1;
			if(strcmp(p, "Ll") == 0)
				myislower[code] = 1;

			if(strcmp(p, "Lt") == 0)
				myistitle[code] = 1;

			if(strcmp(p, "Nd") == 0)
				myisdigit[code] = 1;

			/*
			 * when finding conversions, also need to mark
			 * upper/lower case, since some chars, like
			 * "III" (0x2162), aren't defined as letters but have a
			 * lower case mapping ("iii" (0x2172)).
			 */
			if(fields[FIELD_UPPER][0] != '\0'){
				mytoupper[code] = getcode(fields[FIELD_UPPER]);
			}
			if(fields[FIELD_LOWER][0] != '\0'){
				mytolower[code] = getcode(fields[FIELD_LOWER]);
			}
			if(fields[FIELD_TITLE][0] != '\0'){
				mytotitle[code] = getcode(fields[FIELD_TITLE]);
			}
		}
	}

	fclose(in);

	/*
	 * check for codes with no totitle mapping but a toupper mapping.
	 * these appear in UnicodeData-2.0.14.txt, but are almost certainly
	 * erroneous.
	 */
	for(i = 0; i < NRUNES; i++){
		if(mytotitle[i] == i
		&& mytoupper[i] != i
		&& !myistitle[i])
			fprintf(stderr, "warning: code=%.4x not istitle, totitle is same, toupper=%.4x\n", i, mytoupper[i]);
	}

	/*
	 * make sure isupper[c] is true if for some x toupper[x]  == c
	 * ditto for islower and istitle
	 */
	for(i = 0; i < NRUNES; i++) {
		if(mytoupper[i] != i)
			myisupper[mytoupper[i]] = 1;
		if(mytolower[i] != i)
			myislower[mytolower[i]] = 1;
		if(mytotitle[i] != i)
			myistitle[mytotitle[i]] = 1;
	}

	if(docheck){
		check();
	}else{
		mktables(argv[0], usepairs);
	}
	return 0;
}

/*
 * generate a properties array for ranges, clearing those cases covered.
 * if force, generate one-entry ranges for singletons.
 */
static int
mkisrange(const char* label, char* prop, int force)
{
	int start, stop, some;

	/*
	 * first, the ranges
	 */
	some = 0;
	for(start = 0; start < NRUNES; ) {
		if(!prop[start]){
			start++;
			continue;
		}

		for(stop = start + 1; stop < NRUNES; stop++){
			if(!prop[stop]){
				break;
			}
			prop[stop] = 0;
		}
		if(force || stop != start + 1){
			if(!some){
				printf("static Rune __is%sr[] = {\n", label);
				some = 1;
			}
			prop[start] = 0;
			printf("\t0x%.4x, 0x%.4x,\n", start, stop - 1);
		}

		start = stop;
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate a mapping array for pairs with a skip between,
 * clearing those entries covered.
 */
static int
mkispair(const char *label, char *prop)
{
	int start, stop, some;

	some = 0;
	for(start = 0; start + 2 < NRUNES; ) {
		if(!prop[start]){
			start++;
			continue;
		}

		for(stop = start + 2; stop < NRUNES; stop += 2){
			if(!prop[stop]){
				break;
			}
			prop[stop] = 0;
		}
		if(stop != start + 2){
			if(!some){
				printf("static Rune __is%sp[] = {\n", label);
				some = 1;
			}
			prop[start] = 0;
			printf("\t0x%.4x, 0x%.4x,\n", start, stop - 2);
		}

		start = stop;
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate a properties array for singletons, clearing those cases covered.
 */
static int
mkissingle(const char *label, char *prop)
{
	int start, some;

	some = 0;
	for(start = 0; start < NRUNES; start++) {
		if(!prop[start]){
			continue;
		}

		if(!some){
			printf("static Rune __is%ss[] = {\n", label);
			some = 1;
		}
		prop[start] = 0;
		printf("\t0x%.4x,\n", start);
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate tables and a function for is<label>rune
 */
static void
mkis(const char* label, char* prop, int usepairs)
{
	int isr, isp, iss;

	isr = mkisrange(label, prop, 0);
	isp = 0;
	if(usepairs)
		isp = mkispair(label, prop);
	iss = mkissingle(label, prop);

	printf(
		"int\n"
		"is%srune(Rune c)\n"
		"{\n"
		"	Rune *p;\n"
		"\n",
		label);

	if(isr)
		printf(
			"	p = rbsearch(c, __is%sr, nelem(__is%sr)/2, 2);\n"
			"	if(p && c >= p[0] && c <= p[1])\n"
			"		return 1;\n",
			label, label);

	if(isp)
		printf(
			"	p = rbsearch(c, __is%sp, nelem(__is%sp)/2, 2);\n"
			"	if(p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
			"		return 1;\n",
			label, label);

	if(iss)
		printf(
			"	p = rbsearch(c, __is%ss, nelem(__is%ss), 1);\n"
			"	if(p && c == p[0])\n"
			"		return 1;\n",
			label, label);


	printf(
		"	return 0;\n"
		"}\n"
		"\n"
	);
}

/*
 * generate a mapping array for ranges, clearing those entries covered.
 * if force, generate one-entry ranges for singletons.
 */
static int
mktorange(const char* label, int* map, int force)
{
	int start, stop, delta, some;

	some = 0;
	for(start = 0; start < NRUNES; ) {
		if(map[start] == start){
			start++;
			continue;
		}

		delta = TO_DELTA(map[start], start);
		if(delta != (Rune)delta)
			fatal("bad map delta %d", delta);
		for(stop = start + 1; stop < NRUNES; stop++){
			if(TO_DELTA(map[stop], stop) != delta){
				break;
			}
			map[stop] = stop;
		}
		if(stop != start + 1){
			if(!some){
				printf("static Rune __to%sr[] = {\n", label);
				some = 1;
			}
			map[start] = start;
			printf("\t0x%.4x, 0x%.4x, %d,\n", start, stop - 1, delta);
		}

		start = stop;
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate a mapping array for pairs with a skip between,
 * clearing those entries covered.
 */
static int
mktopair(const char* label, int* map)
{
	int start, stop, delta, some;

	some = 0;
	for(start = 0; start + 2 < NRUNES; ) {
		if(map[start] == start){
			start++;
			continue;
		}

		delta = TO_DELTA(map[start], start);
		if(delta != (Rune)delta)
			fatal("bad map delta %d", delta);
		for(stop = start + 2; stop < NRUNES; stop += 2){
			if(TO_DELTA(map[stop], stop) != delta){
				break;
			}
			map[stop] = stop;
		}
		if(stop != start + 2){
			if(!some){
				printf("static Rune __to%sp[] = {\n", label);
				some = 1;
			}
			map[start] = start;
			printf("\t0x%.4x, 0x%.4x, %d,\n", start, stop - 2, delta);
		}

		start = stop;
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate a mapping array for singletons, clearing those entries covered.
 */
static int
mktosingle(const char* label, int* map)
{
	int start, delta, some;

	some = 0;
	for(start = 0; start < NRUNES; start++) {
		if(map[start] == start){
			continue;
		}

		delta = TO_DELTA(map[start], start);
		if(delta != (Rune)delta)
			fatal("bad map delta %d", delta);
		if(!some){
			printf("static Rune __to%ss[] = {\n", label);
			some = 1;
		}
		map[start] = start;
		printf("\t0x%.4x, %d,\n", start, delta);
	}
	if(some)
		printf("};\n\n");
	return some;
}

/*
 * generate tables and a function for to<label>rune
 */
static void
mkto(const char* label, int* map, int usepairs)
{
	int tor, top, tos;

	tor = mktorange(label, map, 0);
	top = 0;
	if(usepairs)
		top = mktopair(label, map);
	tos = mktosingle(label, map);

	printf(
		"Rune\n"
		"to%srune(Rune c)\n"
		"{\n"
		"	Rune *p;\n"
		"\n",
		label);

	if(tor)
		printf(
			"	p = rbsearch(c, __to%sr, nelem(__to%sr)/3, 3);\n"
			"	if(p && c >= p[0] && c <= p[1])\n"
			"		return c + p[2] - %d;\n",
			label, label, TO_OFFSET);

	if(top)
		printf(
			"	p = rbsearch(c, __to%sp, nelem(__to%sp)/3, 3);\n"
			"	if(p && c >= p[0] && c <= p[1] && !((c - p[0]) & 1))\n"
			"		return c + p[2] - %d;\n",
			label, label, TO_OFFSET);

	if(tos)
		printf(
			"	p = rbsearch(c, __to%ss, nelem(__to%ss)/2, 2);\n"
			"	if(p && c == p[0])\n"
			"		return c + p[1] - %d;\n",
			label, label, TO_OFFSET);


	printf(
		"	return c;\n"
		"}\n"
		"\n"
	);
}

// Make only range tables and a function for is<label>rune.
static void
mkisronly(const char* label, char* prop) {
	mkisrange(label, prop, 1);
	printf(
		"int\n"
		"is%srune(Rune c)\n"
		"{\n"
		"	Rune *p;\n"
		"\n"
		"	p = rbsearch(c, __is%sr, nelem(__is%sr)/2, 2);\n"
		"	if(p && c >= p[0] && c <= p[1])\n"
		"		return 1;\n"
		"	return 0;\n"
		"}\n"
		"\n",
	        label, label, label);
}

/*
 * generate the body of runetype.
 * assumes there is a function Rune* rbsearch(Rune c, Rune *t, int n, int ne);
 */
static void
mktables(char *src, int usepairs)
{
	printf("/* generated automatically by mkrunetype.c from %s */\n\n", src);

	/*
	 * we special case the space and digit tables, since they are assumed
	 * to be small with several ranges.
	 */
	mkisronly("space", myisspace);
	mkisronly("digit", myisdigit);

	mkis("alpha", myisalpha, 0);
	mkis("upper", myisupper, usepairs);
	mkis("lower", myislower, usepairs);
	mkis("title", myistitle, usepairs);

	mkto("upper", mytoupper, usepairs);
	mkto("lower", mytolower, usepairs);
	mkto("title", mytotitle, usepairs);
}

/*
 * find differences between the newly generated tables and current runetypes.
 */
static void
check(void)
{
	int i;

	for(i = 0; i < NRUNES; i++){
		if(isdigitrune(i) != myisdigit[i])
			fprintf(stderr, "isdigit diff at %x: runetype=%x, unicode=%x\n",
				i, isdigitrune(i), myisdigit[i]);

		if(isspacerune(i) != myisspace[i])
			fprintf(stderr, "isspace diff at %x: runetype=%x, unicode=%x\n",
				i, isspacerune(i), myisspace[i]);

		if(isupperrune(i) != myisupper[i])
			fprintf(stderr, "isupper diff at %x: runetype=%x, unicode=%x\n",
				i, isupperrune(i), myisupper[i]);

		if(islowerrune(i) != myislower[i])
			fprintf(stderr, "islower diff at %x: runetype=%x, unicode=%x\n",
				i, islowerrune(i), myislower[i]);

		if(isalpharune(i) != myisalpha[i])
			fprintf(stderr, "isalpha diff at %x: runetype=%x, unicode=%x\n",
				i, isalpharune(i), myisalpha[i]);

		if(toupperrune(i) != mytoupper[i])
			fprintf(stderr, "toupper diff at %x: runetype=%x, unicode=%x\n",
				i, toupperrune(i), mytoupper[i]);

		if(tolowerrune(i) != mytolower[i])
			fprintf(stderr, "tolower diff at %x: runetype=%x, unicode=%x\n",
				i, tolowerrune(i), mytolower[i]);

		if(istitlerune(i) != myistitle[i])
			fprintf(stderr, "istitle diff at %x: runetype=%x, unicode=%x\n",
				i, istitlerune(i), myistitle[i]);

		if(totitlerune(i) != mytotitle[i])
			fprintf(stderr, "totitle diff at %x: runetype=%x, unicode=%x\n",
				i, totitlerune(i), mytotitle[i]);


	}
}

static int
mygetfields(char **fields, int nfields, char *str, const char *delim)
{
	int nf;

	fields[0] = str;
	nf = 1;
	if(nf >= nfields)
		return nf;

	for(; *str; str++){
		if(strchr(delim, *str) != NULL){
			*str = '\0';
			fields[nf++] = str + 1;
			if(nf >= nfields)
				break;
		}
	}
	return nf;
}

static int
getunicodeline(FILE *in, char **fields, char *buf)
{
	char *p;

	if(fgets(buf, MAX_LINE, in) == NULL)
		return 0;

	p = strchr(buf, '\n');
	if (p == NULL)
		fatal("line too long");
	*p = '\0';

	if (mygetfields(fields, NFIELDS + 1, buf, ";") != NFIELDS)
		fatal("bad number of fields");

	return 1;
}

static int
getcode(char *s)
{
	int i, code;

	code = 0;
	i = 0;
	/* Parse a hex number */
	while(s[i]) {
		code <<= 4;
		if(s[i] >= '0' && s[i] <= '9')
			code += s[i] - '0';
		else if(s[i] >= 'A' && s[i] <= 'F')
			code += s[i] - 'A' + 10;
		else
			fatal("bad code char '%c'", s[i]);
		i++;
	}
	return code;
}

static void
fatal(const char *fmt, ...)
{
	va_list arg;

	fprintf(stderr, "%s: fatal error: ", argv0);
	va_start(arg, fmt);
	vfprintf(stderr, fmt, arg);
	va_end(arg);
	fprintf(stderr, "\n");

	exit(1);
}
