#!/usr/bin/perl
use strict;
use warnings;
use utf8;

my $in_file = "UnicodeData.txt";
my $out_file = "unicode_combine.tbl";
my $IN;
my $OUT;
open($IN, $in_file) || die "Cannot open $in_file.";
open($OUT, ">:crlf:encoding(utf8)", $out_file) || die "Cannot open $out_file.";
print $OUT "// this file was generated by get_combine_table.pl\n";
my $ostart = 0;
my $oend = 0;
my $ogeneral_category = "";
my $combine = 0;
my $comment;
while($a = <$IN>) {
	if ($a =~ /^([0-9A-F]+);([^;]*);([^;]*);/) {
		my $code_point = hex $1;
		my $name = $2;
		my $general_category = $3;

		#printf("%06x| %s| \"%s\"\n", $code_point, $general_category, $name);

		$combine = 0;
		if ($code_point < 0x300) {
			# U+0300未満は処理しない, combineしないと思われるため
		}
		elsif ($general_category eq "Mn" ||
			   $general_category eq "Mc" ||
			   $general_category eq "Me") {
			$combine = 1;
		}
		elsif ($general_category eq "Sk") {
			# Sk = Modifier_Symbol
			# 例外処理
			if ($name =~ /FULLWIDTH/ || $name =~ /KATAKANA-HIRAGANA/) {
				# 次の5文字を例外として扱う
				# 309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;
				# 309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;
				# FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;
				# FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;
				# FFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;;;;
				$combine = 0;
			}
			else {
				$combine = 1;
			}
		}

		my $output = 0;
		if ($combine == 1) {
			if ($ostart == 0) {
				$output = 0;
			} else {
				if ($ogeneral_category ne $general_category) {
					$output = 1;
				}
			}
		} else {
			if ($ostart != 0) {
				$output = 1;
			}
		}

		if ($output != 0) {
			printf $OUT "{ 0x%06x, 0x%06x, %s },		// '%s'\n", $ostart, $oend, $ogeneral_category, $comment;
			$ostart = 0;
		}

		if ($combine == 1) {
			if ($ostart == 0) {
				$ostart = $code_point;
				$ogeneral_category = $general_category;
				$comment = $name;
			}
			$oend = $code_point;
		}
	}
}
if ($ostart != 0) {
	printf $OUT "{ 0x%06x, 0x%06x },\n", $ostart, $oend;
}
