/* Make ucnid.h from various sources.
   Copyright (C) 2005-2021 Free Software Foundation, Inc.

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 3, 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; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* Run this program as
   ./makeucnid ucnid.tab UnicodeData.txt DerivedNormalizationProps.txt \
      DerivedCoreProperties.txt > ucnid.h
*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>

enum {
  C99 = 1,
  CXX = 2,
  N99 = 4,
  C11 = 8,
  N11 = 16,
  CXX23 = 32,
  NXX23 = 64,
  all_languages = C99 | CXX | C11 | CXX23 | NXX23,
  not_NFC = 128,
  not_NFKC = 256,
  maybe_not_NFC = 512
};

#define NUM_CODE_POINTS 0x110000
#define MAX_CODE_POINT 0x10ffff

static unsigned flags[NUM_CODE_POINTS];
static unsigned int all_decomp[NUM_CODE_POINTS][2];
static unsigned int decomp[NUM_CODE_POINTS][2];
static unsigned char combining_value[NUM_CODE_POINTS];

/* Die!  */

static void
fail (const char *s)
{
  fprintf (stderr, "%s\n", s);
  exit (1);
}

/* Read ucnid.tab and set the flags for language versions in header[].  */

static void
read_ucnid (const char *fname)
{
  FILE *f = fopen (fname, "r");
  unsigned fl = 0;
  
  if (!f)
    fail ("opening ucnid.tab");
  for (;;)
    {
      char line[256];

      if (!fgets (line, sizeof (line), f))
	break;
      if (strcmp (line, "[C99]\n") == 0)
	fl = C99;
      else if (strcmp (line, "[C99DIG]\n") == 0)
	fl = C99|N99;
      else if (strcmp (line, "[CXX]\n") == 0)
	fl = CXX;
      else if (strcmp (line, "[C11]\n") == 0)
	fl = C11;
      else if (strcmp (line, "[C11NOSTART]\n") == 0)
	fl = C11|N11;
      else if (isxdigit (line[0]))
	{
	  char *l = line;
	  while (*l)
	    {
	      unsigned long start, end;
	      char *endptr;
	      start = strtoul (l, &endptr, 16);
	      if (endptr == l || (*endptr != '-' && ! isspace (*endptr)))
		fail ("parsing ucnid.tab [1]");
	      l = endptr;
	      if (*l != '-')
		end = start;
	      else
		{
		  end = strtoul (l + 1, &endptr, 16);
		  if (end < start)
		    fail ("parsing ucnid.tab, end before start");
		  l = endptr;
		  if (! isspace (*l))
		    fail ("parsing ucnid.tab, junk after range");
		}
	      while (isspace (*l))
		l++;
	      if (end > MAX_CODE_POINT)
		fail ("parsing ucnid.tab, end too large");
	      while (start <= end)
		flags[start++] |= fl;
	    }
	}
    }
  if (ferror (f))
    fail ("reading ucnid.tab");
  fclose (f);
}

/* Read UnicodeData.txt and fill in the 'decomp' table to be the
   decompositions of characters for which both the character
   decomposed and all the code points in the decomposition are valid
   for some supported language version, and the 'all_decomp' table to
   be the decompositions of all characters without those
   constraints.  */

static void
read_table (char *fname)
{
  FILE * f = fopen (fname, "r");
  
  if (!f)
    fail ("opening UnicodeData.txt");
  for (;;)
    {
      char line[256];
      unsigned long codepoint, this_decomp[4];
      char *l;
      int i, j;
      int decomp_useful;

      if (!fgets (line, sizeof (line), f))
	break;
      codepoint = strtoul (line, &l, 16);
      if (l == line || *l != ';')
	fail ("parsing UnicodeData.txt, reading code point");
      if (codepoint > MAX_CODE_POINT)
	fail ("parsing UnicodeData.txt, code point too large");

      do {
	l++;
      } while (*l != ';');
      /* Category value.  */
      do {
	l++;
      } while (*l != ';');
      /* Canonical combining class; in NFC/NFKC, they must be increasing
	 (or zero).  */
      if (! isdigit (*++l))
	fail ("parsing UnicodeData.txt, combining class not number");
      combining_value[codepoint] = strtoul (l, &l, 10);
      if (*l++ != ';')
	fail ("parsing UnicodeData.txt, junk after combining class");
	
      /* Skip over bidi value.  */
      do {
	l++;
      } while (*l != ';');
      
      /* Decomposition mapping.  */
      decomp_useful = flags[codepoint];
      if (*++l == '<')  /* Compatibility mapping. */
	continue;
      for (i = 0; i < 4; i++)
	{
	  if (*l == ';')
	    break;
	  if (!isxdigit (*l))
	    fail ("parsing UnicodeData.txt, decomposition format");
	  this_decomp[i] = strtoul (l, &l, 16);
	  decomp_useful &= flags[this_decomp[i]];
	  while (isspace (*l))
	    l++;
	}
      if (i > 2)  /* Decomposition too long.  */
	fail ("parsing UnicodeData.txt, decomposition too long");
      for (j = 0; j < i; j++)
	all_decomp[codepoint][j] = this_decomp[j];
      if ((flags[codepoint] & all_languages) && decomp_useful)
	while (--i >= 0)
	  decomp[codepoint][i] = this_decomp[i];
    }
  if (ferror (f))
    fail ("reading UnicodeData.txt");
  fclose (f);
}

/* Read DerivedNormalizationProps.txt and set the flags that say whether
   a character is in NFC, NFKC, or is context-dependent.  */

static void
read_derived (const char *fname)
{
  FILE * f = fopen (fname, "r");
  
  if (!f)
    fail ("opening DerivedNormalizationProps.txt");
  for (;;)
    {
      char line[256];
      unsigned long start, end;
      char *l;
      bool not_NFC_p, not_NFKC_p, maybe_not_NFC_p;

      if (!fgets (line, sizeof (line), f))
	break;
      not_NFC_p = (strstr (line, "; NFC_QC; N") != NULL);
      not_NFKC_p = (strstr (line, "; NFKC_QC; N") != NULL);
      maybe_not_NFC_p = (strstr (line, "; NFC_QC; M") != NULL);
      if (! not_NFC_p && ! not_NFKC_p && ! maybe_not_NFC_p)
	continue;
	
      start = strtoul (line, &l, 16);
      if (l == line)
	fail ("parsing DerivedNormalizationProps.txt, reading start");
      if (start > MAX_CODE_POINT)
	fail ("parsing DerivedNormalizationProps.txt, code point too large");
      if (*l == '.' && l[1] == '.')
	end = strtoul (l + 2, &l, 16);
      else
	end = start;

      while (start <= end)
	flags[start++] |= ((not_NFC_p ? not_NFC : 0) 
			   | (not_NFKC_p ? not_NFKC : 0)
			   | (maybe_not_NFC_p ? maybe_not_NFC : 0)
			   );
    }
  if (ferror (f))
    fail ("reading DerivedNormalizationProps.txt");
  fclose (f);
}

/* Read DerivedCoreProperties.txt and fill in languages version in
   flags from the XID_Start and XID_Continue properties.  */

static void
read_derivedcore (char *fname)
{
  FILE * f = fopen (fname, "r");
  
  if (!f)
    fail ("opening DerivedCoreProperties.txt");
  for (;;)
    {
      char line[256];
      unsigned long codepoint_start, codepoint_end;
      char *l;
      int i, j;

      if (!fgets (line, sizeof (line), f))
	break;
      if (line[0] == '#' || line[0] == '\n' || line[0] == '\r')
	continue;
      codepoint_start = strtoul (line, &l, 16);
      if (l == line)
	fail ("parsing DerivedCoreProperties.txt, reading code point");
      if (codepoint_start > MAX_CODE_POINT)
	fail ("parsing DerivedCoreProperties.txt, code point too large");
      
      if (*l == '.' && l[1] == '.')
	{
	  char *l2 = l + 2;
	  codepoint_end = strtoul (l + 2, &l, 16);
	  if (l == l2 || codepoint_end < codepoint_start)
	    fail ("parsing DerivedCoreProperties.txt, reading code point");
	  if (codepoint_end > MAX_CODE_POINT)
	    fail ("parsing DerivedCoreProperties.txt, code point too large");
	}
      else
	codepoint_end = codepoint_start;

      while (*l == ' ')
	l++;
      if (*l++ != ';')
	fail ("parsing DerivedCoreProperties.txt, reading code point");

      while (*l == ' ')
	l++;

      if (codepoint_end < 0x80)
        continue;

      if (strncmp (l, "XID_Start ", 10) == 0)
	{
	  for (; codepoint_start <= codepoint_end; codepoint_start++)
	    flags[codepoint_start]
	      = (flags[codepoint_start] | CXX23) & ~NXX23;
	}
      else if (strncmp (l, "XID_Continue ", 13) == 0)
	{
	  for (; codepoint_start <= codepoint_end; codepoint_start++)
	    if ((flags[codepoint_start] & CXX23) == 0)
	      flags[codepoint_start] |= CXX23 | NXX23;
	}
    }
  if (ferror (f))
    fail ("reading DerivedCoreProperties.txt");
  fclose (f);
}

/* Write out the table.
   The table consists of two words per entry.  The first word is the flags
   for the unicode code points up to and including the second word.  */

static void
write_table (void)
{
  unsigned i;
  unsigned last_flag = flags[0];
  bool really_safe = decomp[0][0] == 0;
  unsigned char last_combine = combining_value[0];

  printf ("static const struct ucnrange ucnranges[] = {\n");
  
  for (i = 1; i <= NUM_CODE_POINTS; i++)
    if (i == NUM_CODE_POINTS
	|| (flags[i] != last_flag && ((flags[i] | last_flag) & all_languages))
	|| really_safe != (decomp[i][0] == 0)
	|| combining_value[i] != last_combine)
      {
	printf ("{ %s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s, %3d, %#06x },\n",
		last_flag & C99 ? "C99" : "  0",
		last_flag & N99 ? "N99" : "  0",
		last_flag & CXX ? "CXX" : "  0",
		last_flag & C11 ? "C11" : "  0",
		last_flag & N11 ? "N11" : "  0",
		last_flag & CXX23 ? "CXX23" : "    0",
		last_flag & NXX23 ? "NXX23" : "    0",
		really_safe ? "CID" : "  0",
		last_flag & not_NFC ? "  0" : "NFC",
		last_flag & not_NFKC ? "  0" : "NKC",
		last_flag & maybe_not_NFC ? "CTX" : "  0",
		combining_value[i - 1],
		i - 1);
	last_flag = flags[i];
	last_combine = combining_value[i];
	really_safe = decomp[i][0] == 0;
      }

  printf ("};\n");
}

/* Return whether a given character is valid in an identifier for some
   supported language, either as itself or as a UCN.  */

static bool
char_id_valid (unsigned int c)
{
  return ((flags[c] & all_languages)
	  || (c == 0x24)
	  || (c >= 0x30 && c <= 0x39)
	  || (c >= 0x41 && c <= 0x5a)
	  || (c >= 0x61 && c <= 0x7a));
}

/* Write out the switch statement over characters for which it is
   context-dependent whether they are in NFC.  */

static void
write_context_switch (void)
{
  unsigned i;
  printf ("static bool\n"
	  "check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p)\n"
	  "{\n"
	  "  switch (c)\n"
	  "    {\n");
  for (i = 0; i < NUM_CODE_POINTS; i++)
    {
      bool found_case = false;
      unsigned j;
      if (!(flags[i] & all_languages) || !(flags[i] & maybe_not_NFC))
	continue;
      if ((i >= 0x1161 && i <= 0x1175) || (i >= 0x11A8 && i <= 0x11C2))
	continue; /* Hangul handled algorithmically.  */
      printf ("    case %#06x:\n"
	      "      switch (p)\n"
	      "\t{\n", i);
      /* If an NFC starter character decomposes with this character I
	 as the second character and an NFC starter character S as the
	 first character, that latter character as a previous
	 character means this character is not NFC.  Furthermore, any
	 NFC starter character K made by a series of compositions of S
	 with combining characters whose combining class is greater
	 than that of I also means this character is not NFC.  */
      for (j = 0; j < NUM_CODE_POINTS; j++)
	{
	  unsigned s, k;
	  if (all_decomp[j][1] != i)
	    continue;
	  s = all_decomp[j][0];
	  if (combining_value[s] != 0 || (flags[s] & not_NFC) != 0)
	    continue;
	  if (char_id_valid (s))
	    {
	      found_case = true;
	      printf ("\tcase %#06x:\n", s);
	    }
	  for (k = 0; k < NUM_CODE_POINTS; k++)
	    {
	      unsigned t = k;
	      if (k == s || !char_id_valid (k))
		continue;
	      while (all_decomp[t][1] != 0
		     && combining_value[all_decomp[t][1]] > combining_value[i])
		{
		  if (combining_value[t] != 0 || (flags[t] & not_NFC) != 0)
		    break;
		  t = all_decomp[t][0];
		}
	      if (t == s)
		{
		  found_case = true;
		  printf ("\tcase %#06x:\n", k);
		}
	    }
	}
      if (found_case)
	printf ("\t  return false;\n");
      else
	printf ("\t/* Non-NFC cases not applicable to C/C++.  */\n");
      printf ("\tdefault:\n"
	      "\t  return true;\n"
	      "\t}\n\n");
    }
  printf ("    default:\n"
	  "      cpp_error (pfile, CPP_DL_ICE, \"Character %%x might not be NFKC\", c);\n"
	  "      return true;\n"
	  "  }\n"
	  "}\n");
}

/* Print out the huge copyright notice.  */

static void
write_copyright (void)
{
  static const char copyright[] = "\
/* Unicode characters and various properties.\n\
   Copyright (C) 2003-2021 Free Software Foundation, Inc.\n\
\n\
   This program is free software; you can redistribute it and/or modify it\n\
   under the terms of the GNU General Public License as published by the\n\
   Free Software Foundation; either version 3, or (at your option) any\n\
   later version.\n\
\n\
   This program is distributed in the hope that it will be useful,\n\
   but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
   GNU General Public License for more details.\n\
\n\
   You should have received a copy of the GNU General Public License\n\
   along with this program; see the file COPYING3.  If not see\n\
   <http://www.gnu.org/licenses/>.\n\
\n\
\n\
   Copyright (C) 1991-2005 Unicode, Inc.  All rights reserved.\n\
   Distributed under the Terms of Use in\n\
   http://www.unicode.org/copyright.html.\n\
\n\
   Permission is hereby granted, free of charge, to any person\n\
   obtaining a copy of the Unicode data files and any associated\n\
   documentation (the \"Data Files\") or Unicode software and any\n\
   associated documentation (the \"Software\") to deal in the Data Files\n\
   or Software without restriction, including without limitation the\n\
   rights to use, copy, modify, merge, publish, distribute, and/or\n\
   sell copies of the Data Files or Software, and to permit persons to\n\
   whom the Data Files or Software are furnished to do so, provided\n\
   that (a) the above copyright notice(s) and this permission notice\n\
   appear with all copies of the Data Files or Software, (b) both the\n\
   above copyright notice(s) and this permission notice appear in\n\
   associated documentation, and (c) there is clear notice in each\n\
   modified Data File or in the Software as well as in the\n\
   documentation associated with the Data File(s) or Software that the\n\
   data or software has been modified.\n\
\n\
   THE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY\n\
   OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n\
   WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\
   NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE\n\
   COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR\n\
   ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY\n\
   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\n\
   WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\n\
   ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n\
   OF THE DATA FILES OR SOFTWARE.\n\
\n\
   Except as contained in this notice, the name of a copyright holder\n\
   shall not be used in advertising or otherwise to promote the sale,\n\
   use or other dealings in these Data Files or Software without prior\n\
   written authorization of the copyright holder.  */\n";
   
   puts (copyright);
}

/* Main program.  */

int
main(int argc, char ** argv)
{
  if (argc != 5)
    fail ("too few arguments to makeucn");
  read_ucnid (argv[1]);
  read_table (argv[2]);
  read_derived (argv[3]);
  read_derivedcore (argv[4]);

  write_copyright ();
  write_table ();
  write_context_switch ();
  return 0;
}
