/* Make uname2c.h from various sources.
   Copyright (C) 2005-2026 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@redhat.com>

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
   ./makeuname2c UnicodeData.txt NameAliases.txt > uname2c.h

   This program generates 2 big arrays and 2 small ones.
   The large ones are uname2c_dict, initialized by string literal
   representing dictionary, and uname2c_tree, which is a space optimized
   radix tree.
   The format of the radix tree is:
   byte 0	either 0x80 + (key[0] - ' ')	(if key_len == 1)
		or key_len			(otherwise)
		either of them ored with 0x40 if it has a codepoint
   byte 1	LSB of offset into uname2c_dict for key	(only if key_len > 1)
   byte 2	MSB of offset into uname2c_dict for key	(only if key_len > 1)
		if key_len == 1, the above 2 bytes are omitted
   byte 3	LSB of codepoint (only if it has a codepoint)
   byte 4	middle byte of codepoint (ditto)
   byte 5	MSB of codepoint (ditto), ored with 0x80 if node has children
				   ored with 0x40 if it doesn't have siblings
		if it doesn't have a codepoint, the above 3 bytes are omitted
		and we assume that the node has children
   byte 6, 7, 8	uleb128 encoded offset to first child relative to the end
		of the uleb128 (only if node has children)
   byte 9	0xff (only if node doesn't have a codepoint and doesn't
		      have siblings)

   For prefixes of Unicode NR1 or NR2 rule generated names, on a node
   representing end of the prefix codepoint is 0xd800 + index into
   uname2c_generated array with indexes into uname2c_pairs array of
   code points (low, high) of the ranges terminated by single 0.
   0xd800 is NR1 rule (Hangul syllables), rest are NR2 rules.
*/

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>

#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))

#define NUM_CODE_POINTS 0x110000
#define MAX_CODE_POINT 0x10ffff
#define NO_VALUE 0xdc00
#define GENERATED 0xd800

struct entry { const char *name; unsigned long codepoint; };
static struct entry *entries;
static unsigned long num_allocated, num_entries;

/* Unicode 16.0 Table 4-8.  */
struct generated {
  const char *prefix;
  /* max_high is a workaround for UnicodeData.txt inconsistencies
     on a few CJK UNIFIED IDEOGRAPH- ranges where the "*, Last>"
     entry is a few code points above the end of the range.  */
  unsigned long low, high, max_high;
  int idx, ok;
};
static struct generated generated_ranges[] =
{ { "HANGUL SYLLABLE ", 0xac00, 0xd7a3, 0, 0, 0 }, /* NR1 rule */
  { "CJK UNIFIED IDEOGRAPH-", 0x3400, 0x4dbf, 0, 1, 0 }, /* NR2 rules */
  { "CJK UNIFIED IDEOGRAPH-", 0x4e00, 0x9fff, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x20000, 0x2a6df, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x2a700, 0x2b73f, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x2b740, 0x2b81d, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x2b820, 0x2cead, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x2ceb0, 0x2ebe0, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x2ebf0, 0x2ee5d, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x30000, 0x3134a, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x31350, 0x323af, 0, 1, 0 },
  { "CJK UNIFIED IDEOGRAPH-", 0x323b0, 0x33479, 0, 1, 0 },
  { "EGYPTIAN HIEROGLYPH-", 0x13460, 0x143fa, 0, 2, 0 },
  { "TANGUT IDEOGRAPH-", 0x17000, 0x187ff, 0, 3, 0 },
  { "TANGUT IDEOGRAPH-", 0x18d00, 0x18d1e, 0, 3, 0 },
  { "KHITAN SMALL SCRIPT CHARACTER-", 0x18b00, 0x18cd5, 0, 4, 0 },
  { "NUSHU CHARACTER-", 0x1b170, 0x1b2fb, 0, 5, 0 },
  { "CJK COMPATIBILITY IDEOGRAPH-", 0xf900, 0xfa6d, 0, 6, 0 },
  { "CJK COMPATIBILITY IDEOGRAPH-", 0xfa70, 0xfad9, 0, 6, 0 },
  { "CJK COMPATIBILITY IDEOGRAPH-", 0x2f800, 0x2fa1d, 0, 6, 0 }
};

struct node {
  struct node *sibling, *child;
  const char *key;
  size_t key_len, key_idx, node_size, size_sum, child_off;
  unsigned long codepoint;
  bool in_dict;
};
static struct node *root, **nodes;
static unsigned long num_nodes;
static size_t dict_size, tree_size, max_entry_len;
static char *dict;
static unsigned char *tree;

/* Die!  */

static void
fail (const char *s, ...)
{
  va_list ap;

  va_start (ap, s);
  vfprintf (stderr, s, ap);
  va_end (ap);
  fputc ('\n', stderr);
  exit (1);
}

static void *
xmalloc (size_t size)
{
  void *ret = malloc (size);

  if (ret == NULL)
    fail ("failed to allocate %ld bytes", (long) size);
  return ret;
}

static void *
xrealloc (void *p, size_t size)
{
  void *ret = p ? realloc (p, size) : malloc (size);

  if (ret == NULL)
    fail ("failed to allocate %ld bytes", (long) size);
  return ret;
}

static int
entrycmp (const void *p1, const void *p2)
{
  const struct entry *e1 = (const struct entry *) p1;
  const struct entry *e2 = (const struct entry *) p2;
  int ret = strcmp (e1->name, e2->name);

  if (ret != 0)
    return ret;
  if (e1->codepoint < e2->codepoint)
    return -1;
  if (e1->codepoint > e2->codepoint)
    return 1;
  return 0;
}

static int
nodecmp (const void *p1, const void *p2)
{
  const struct node *n1 = *(const struct node *const *) p1;
  const struct node *n2 = *(const struct node *const *) p2;
  if (n1->key_len > n2->key_len)
    return -1;
  if (n1->key_len < n2->key_len)
    return 1;
  return memcmp (n1->key, n2->key, n1->key_len);
}

/* 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, bool aliases_p)
{
  FILE *f = fopen (fname, "r");
  const char *sname = aliases_p ? "NameAliases.txt" : "UnicodeData.txt";

  if (!f)
    fail ("opening %s", sname);
  for (;;)
    {
      char line[256];
      unsigned long codepoint;
      const char *name, *aname;
      char *l;
      size_t i;

      if (!fgets (line, sizeof (line), f))
	break;
      codepoint = strtoul (line, &l, 16);
      if (l == line && aliases_p)
	{
	  /* NameAliased.txt can contain comments and empty lines.  */
	  if (*line == '#' || *line == '\n')
	    continue;
	}
      if (l == line || *l != ';')
	fail ("parsing %s, reading code point", sname);
      if (codepoint > MAX_CODE_POINT)
	fail ("parsing %s, code point too large", sname);

      name = l + 1;
      do {
	++l;
      } while (*l != ';');

      aname = NULL;
      if (aliases_p)
	i = ARRAY_SIZE (generated_ranges);
      else
	{
	  for (i = 0; i < ARRAY_SIZE (generated_ranges); ++i)
	    if (codepoint >= generated_ranges[i].low
		&& codepoint <= generated_ranges[i].max_high)
	      break;
	  if (i != ARRAY_SIZE (generated_ranges))
	    {
	      if (*name == '<' && l[-1] == '>')
		{
		  if (codepoint == generated_ranges[i].low
		      && l - name >= 9
		      && memcmp (l - 8, ", First>", 8) == 0
		      && generated_ranges[i].ok == 0)
		    {
		      generated_ranges[i].ok = INT_MAX - 1;
		      aname = generated_ranges[i].prefix;
		      codepoint = GENERATED + generated_ranges[i].idx;
		    }
		  /* Unfortunately, UnicodeData.txt isn't consistent
		     with the Table 4-8 range endpoints in 3 cases,
		     the ranges are longer there by a few codepoints.
		     So use the max_high hack to avoid verification
		     failures.  */
		  else if (codepoint == generated_ranges[i].max_high
			   && l - name >= 8
			   && memcmp (l - 7, ", Last>", 7) == 0
			   && generated_ranges[i].ok == INT_MAX - 1)
		    {
		      generated_ranges[i].ok = INT_MAX;
		      continue;
		    }
		  else
		    fail ("unexpected generated entry %lx %.*s",
			  codepoint, (int) (l - name), name);
		}
	      else if (codepoint
		       == generated_ranges[i].low + generated_ranges[i].ok
		       && l - name == (strlen (generated_ranges[i].prefix)
				       + (name - 1 - line))
		       && memcmp (name, generated_ranges[i].prefix,
				  strlen (generated_ranges[i].prefix)) == 0
		       && memcmp (name + strlen (generated_ranges[i].prefix),
				  line, name - 1 - line) == 0)
		{
		  ++generated_ranges[i].ok;
		  if (codepoint != generated_ranges[i].low)
		    continue;
		  aname = generated_ranges[i].prefix;
		  codepoint = GENERATED + generated_ranges[i].idx;
		}
	      else
		fail ("unexpected generated entry %lx %.*s",
		      codepoint, (int) (l - name), name);
	      if (aname == generated_ranges[i].prefix)
		{
		  size_t j;

		  /* Don't add an entry for a generated range where the
		     same prefix has been added already.  */
		  for (j = 0; j < i; ++j)
		    if (generated_ranges[j].idx == generated_ranges[i].idx
			&& generated_ranges[j].ok != 0)
		      break;
		  if (j < i)
		    continue;
		}
	    }
	  else if (*name == '<' && l[-1] == '>')
	    continue;
	}

      if (num_entries == num_allocated)
	{
	  num_allocated = num_allocated ? 2 * num_allocated : 65536;
	  entries = (struct entry *) xrealloc (entries, num_allocated
							* sizeof (entries[0]));
	}

      if (aname == NULL)
	{
	  char *a = (char *) xmalloc (l + 1 - name);
	  if (l - name > max_entry_len)
	    max_entry_len = l - name;
	  memcpy (a, name, l - name);
	  a[l - name] = '\0';
	  aname = a;
	}
      entries[num_entries].name = aname;
      entries[num_entries++].codepoint = codepoint;
    }
  if (ferror (f))
    fail ("reading %s", sname);
  fclose (f);
}

/* Assumes nodes are added from sorted array, so we never
   add any node before existing one, only after it.  */

static void
node_add (struct node **p, const char *key, size_t key_len,
	  unsigned long codepoint)
{
  struct node *n;
  size_t i;

  do
    {
      if (*p == NULL)
	{
	  *p = n = (struct node *) xmalloc (sizeof (struct node));
	  ++num_nodes;
	  assert (key_len);
	  n->sibling = NULL;
	  n->child = NULL;
	  n->key = key;
	  n->key_len = key_len;
	  n->codepoint = codepoint;
	  return;
	}
      n = *p;
      for (i = 0; i < n->key_len && i < key_len; ++i)
	if (n->key[i] != key[i])
	  break;
      if (i == 0)
	{
	  p = &n->sibling;
	  continue;
	}
      if (i == n->key_len)
	{
	  assert (key_len > n->key_len);
	  p = &n->child;
	  key += n->key_len;
	  key_len -= n->key_len;
	  continue;
	}
      /* Need to split the node.  */
      assert (i < key_len);
      n = (struct node *) xmalloc (sizeof (struct node));
      ++num_nodes;
      n->sibling = NULL;
      n->child = (*p)->child;
      n->key = (*p)->key + i;
      n->key_len = (*p)->key_len - i;
      n->codepoint = (*p)->codepoint;
      (*p)->child = n;
      (*p)->key_len = i;
      (*p)->codepoint = NO_VALUE;
      key += i;
      key_len -= i;
      p = &n->sibling;
    }
  while (1);
}

static void
append_nodes (struct node *n)
{
  for (; n; n = n->sibling)
    {
      nodes[num_nodes++] = n;
      append_nodes (n->child);
    }
}

static size_t
sizeof_uleb128 (size_t val)
{
  size_t sz = 0;
  do
    {
      val >>= 7;
      sz += 1;
    }
  while (val != 0);
  return sz;
}

static void
size_nodes (struct node *n)
{
  if (n->child)
    size_nodes (n->child);
  if (n->sibling)
    size_nodes (n->sibling);
  n->node_size = 1 + (n->key_len > 1) * 2;
  if (n->codepoint != NO_VALUE)
    n->node_size += 3;
  else if (n->sibling == NULL)
    ++n->node_size;
  n->size_sum = 0;
  n->child_off = 0;
  if (n->sibling)
    n->size_sum += n->sibling->size_sum;
  if (n->child)
    {
      n->child_off = n->size_sum + (n->codepoint == NO_VALUE
				    && n->sibling == NULL);
      n->node_size += sizeof_uleb128 (n->child_off);
    }
  n->size_sum += n->node_size;
  if (n->child)
    n->size_sum += n->child->size_sum;
  tree_size += n->node_size;
}

static void
write_uleb128 (unsigned char *p, size_t val)
{
  unsigned char c;
  do
    {
      c = val & 0x7f;
      val >>= 7;
      if (val)
	c |= 0x80;
      *p++ = c;
    }
  while (val);
}

static void
write_nodes (struct node *n, size_t off)
{
  for (; n; n = n->sibling)
    {
      assert (off < tree_size && tree[off] == 0);
      if (n->key_len > 1)
	{
	  assert (n->key_len < 64);
	  tree[off] = n->key_len;
	}
      else
	tree[off] = (n->key[0] - ' ') | 0x80;
      assert ((tree[off] & 0x40) == 0);
      if (n->codepoint != NO_VALUE)
	tree[off] |= 0x40;
      off++;
      if (n->key_len > 1)
	{
	  tree[off++] = n->key_idx & 0xff;
	  tree[off++] = (n->key_idx >> 8) & 0xff;
	}
      if (n->codepoint != NO_VALUE)
	{
	  assert (n->codepoint < (1L << 21));
	  tree[off++] = n->codepoint & 0xff;
	  tree[off++] = (n->codepoint >> 8) & 0xff;
	  tree[off] = (n->codepoint >> 16) & 0xff;
	  if (n->child)
	    tree[off] |= 0x80;
	  if (!n->sibling)
	    tree[off] |= 0x40;
	  off++;
	}
      if (n->child)
	{
	  write_uleb128 (&tree[off], n->child_off);
	  off += sizeof_uleb128 (n->child_off);
	  write_nodes (n->child, off + n->child_off);
	}
      if (n->codepoint == NO_VALUE
	  && n->sibling == NULL)
	tree[off++] = 0xff;
    }
  assert (off <= tree_size);
}

static void
build_radix_tree (void)
{
  size_t i, j, k, key_idx;

  for (i = 0; i < ARRAY_SIZE (generated_ranges); ++i)
    if (generated_ranges[i].ok == INT_MAX)
      {
	if (generated_ranges[i].max_high - generated_ranges[i].high > 15UL)
	  break;
      }
    else if (generated_ranges[i].ok == (generated_ranges[i].high
					- generated_ranges[i].low + 1))
      {
	if (generated_ranges[i].max_high != generated_ranges[i].high)
	  break;
      }
    else
      break;
  if (i < ARRAY_SIZE (generated_ranges))
    fail ("uncovered generated range %s %lx %lx",
	  generated_ranges[i].prefix, generated_ranges[i].low,
	  generated_ranges[i].high);
  /* Sort entries alphabetically, node_add relies on that.  */
  qsort (entries, num_entries, sizeof (struct entry), entrycmp);
  for (i = 1; i < num_entries; ++i)
    if (i && strcmp (entries[i].name, entries[i - 1].name) == 0)
      fail ("multiple entries for name %s", entries[i].name);

  for (i = 0; i < num_entries; ++i)
    node_add (&root, entries[i].name, strlen (entries[i].name),
	      entries[i].codepoint);

  nodes = (struct node **) xmalloc (num_nodes * sizeof (struct node *));
  i = num_nodes;
  num_nodes = 0;
  append_nodes (root);
  assert (num_nodes == i);
  /* Sort node pointers by decreasing string length to handle substrings
     right.  */
  qsort (nodes, num_nodes, sizeof (struct node *), nodecmp);
  if (nodes[0]->key_len >= 64)
    /* We could actually encode even 64 and 65, as key_len 0 and 1 will
       never appear in the multiple letter key encodings, so could subtract
       2.  */
    fail ("can't encode key length %d >= 64, so need to split some radix "
	  "tree nodes to ensure length fits", nodes[0]->key_len);

  /* Verify a property charset.cc UAX44-LM2 matching relies on:
     if - is at the end of key of some node, then all its siblings
     start with alphanumeric characters.
     Only 2 character names and 1 alias have - followed by space:
     U+0F0A TIBETAN MARK BKA- SHOG YIG MGO
     U+0FD0 TIBETAN MARK BKA- SHOG GI MGO RGYAN
     U+0FD0 TIBETAN MARK BSKA- SHOG GI MGO RGYAN
     so the KA- in there will always be followed at least by SHOG
     in the same node.
     If this changes, charset.cc needs to change.  */
  for (i = 0; i < num_nodes; ++i)
    if (nodes[i]->key[nodes[i]->key_len - 1] == '-'
	&& nodes[i]->child)
      {
	struct node *n;

	for (n = nodes[i]->child; n; n = n->sibling)
	  if (n->key[0] == ' ')
	    fail ("node with key %.*s followed by node with key %.*s",
		  (int) nodes[i]->key_len, nodes[i]->key,
		  (int) n->key_len, n->key);
      }

  /* This is expensive, O(num_nodes * num_nodes * nodes[0]->key_len), but
     fortunately num_nodes is < 64K and key_len < 64.  */
  key_idx = 0;
  for (i = 0; i < num_nodes; ++i)
    {
      nodes[i]->key_idx = SIZE_MAX;
      nodes[i]->in_dict = false;
      if (nodes[i]->key_len > 1)
	{
	  for (j = 0; j < i; ++j)
	    /* Can't rely on memmem unfortunately.  */
	    if (nodes[j]->in_dict)
	      {
		for (k = 0; k <= nodes[j]->key_len - nodes[i]->key_len; ++k)
		  if (nodes[j]->key[k] == nodes[i]->key[0]
		      && memcmp (nodes[j]->key + k + 1, nodes[i]->key + 1,
				 nodes[i]->key_len - 1) == 0)
		    {
		      nodes[i]->key_idx = nodes[j]->key_idx + k;
		      j = i;
		      break;
		    }
		if (j == i)
		  break;
		for (; k < nodes[j]->key_len; ++k)
		  if (nodes[j]->key[k] == nodes[i]->key[0]
		      && memcmp (nodes[j]->key + k + 1, nodes[i]->key + 1,
				 nodes[j]->key_len - 1 - k) == 0)
		    {
		      size_t l;

		      for (l = j + 1; l < i; ++l)
			if (nodes[l]->in_dict)
			  break;
		      if (l < i
			  && memcmp (nodes[l]->key,
				     nodes[i]->key + (nodes[j]->key_len - k),
				     nodes[i]->key_len
				     - (nodes[j]->key_len - k)) == 0)
			{
			  nodes[i]->key_idx = nodes[j]->key_idx + k;
			  j = i;
			}
		      else
			j = l - 1;
		      break;
		    }
	      }
	  if (nodes[i]->key_idx == SIZE_MAX)
	    {
	      nodes[i]->key_idx = key_idx;
	      nodes[i]->in_dict = true;
	      key_idx += nodes[i]->key_len;
	    }
	}
    }
  if (key_idx >= 65536)
    /* We only use 2 bytes for offsets into the dictionary.
       If it grows more, there is e.g. a possibility to replace
       most often seen words or substrings in the dictionary
       with characters other than [A-Z0-9 -] (say LETTER occurs
       in the dictionary almost 197 times and so by using a
       instead of LETTER we could save (6 - 1) * 197 bytes,
       with some on the side table mapping 'a' to "LETTER".  */
    fail ("too large dictionary %ld", (long) key_idx);
  dict_size = key_idx;

  size_nodes (root);

  dict = (char *) xmalloc (dict_size + 1);
  for (i = 0; i < num_nodes; ++i)
    if (nodes[i]->in_dict)
      memcpy (dict + nodes[i]->key_idx, nodes[i]->key, nodes[i]->key_len);
  dict[dict_size] = '\0';

  tree = (unsigned char *) xmalloc (tree_size);
  memset (tree, 0, tree_size);
  write_nodes (root, 0);
}

/* Print out the huge copyright notice.  */

static void
write_copyright (void)
{
  static const char copyright[] = "\
/* Unicode name to codepoint.\n\
   Copyright (C) 2005-2026 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-2025 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);
}

static void
write_dict (void)
{
  size_t i;

  printf ("static const char uname2c_dict[%ld] =\n", (long) (dict_size + 1));
  for (i = 0; i < dict_size; i += 77)
    printf ("\"%.77s\"%s\n", dict + i, i + 77 >= dict_size ? ";" : "");
  puts ("");
}

static void
write_tree (void)
{
  size_t i, j;

  printf ("static const unsigned char uname2c_tree[%ld] = {\n",
	  (long) tree_size);
  for (i = 0, j = 0; i < tree_size; ++i)
    {
      printf ("%s0x%02x%s", j == 0 ? "  " : "", tree[i],
	      i == tree_size - 1 ? " };\n\n" : j == 11 ? ",\n" : ", ");
      if (j == 11)
	j = 0;
      else
	++j;
    }
}

static void
write_generated (void)
{
  size_t i, j;

  puts ("static const cppchar_t uname2c_pairs[] = {");
  for (i = 0; i < ARRAY_SIZE (generated_ranges); ++i)
    {
      if (i == 0)
	;
      else if (generated_ranges[i - 1].idx != generated_ranges[i].idx)
	puts (", 0,");
      else
	puts (",");
      printf ("  0x%lx, 0x%lx /* %s */",
	      generated_ranges[i].low,
	      generated_ranges[i].high,
	      generated_ranges[i].prefix);
    }
  puts (", 0 };\n");

  puts ("static const unsigned char uname2c_generated[] = {");
  for (i = 0, j = -1; i < ARRAY_SIZE (generated_ranges); ++i)
    {
      if (i == 0 || generated_ranges[i - 1].idx != generated_ranges[i].idx)
	printf ("%s  %d /* %s */", i ? ",\n" : "",
		++j, generated_ranges[i].prefix);
      j += 2;
    }
  puts (" };\n");
}

/* Main program.  */

int
main (int argc, char **argv)
{
  size_t i;

  if (argc != 3)
    fail ("too few arguments to makeradixtree");
  for (i = 0; i < ARRAY_SIZE (generated_ranges); ++i)
    if (!generated_ranges[i].max_high)
      generated_ranges[i].max_high = generated_ranges[i].high;
  read_table (argv[1], false);
  read_table (argv[2], true);
  build_radix_tree ();

  write_copyright ();
  write_dict ();
  write_tree ();
  write_generated ();
  printf ("static const unsigned int uname2c_max_name_len = %ld;\n\n", max_entry_len);
  return 0;
}
