/* gen-mirroring-tab.c - generate gmirroringtable.h for glib
 * copied from FriBidi.
 *
 * $Id$
 * $Author$
 * $Date$
 * $Revision$
 * $Source$
 *
 * Author:
 *   Behdad Esfahbod, 2001, 2002, 2004
 *
 * Copyright (C) 2004 Sharif FarsiWeb, Inc
 * Copyright (C) 2001,2002,2004 Behdad Esfahbod
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 * 
 * For licensing issues, contact <license@farsiweb.info>.
 */

#include <glib.h>

#include <stdlib.h>
#include <stdio.h>

#include "packtab.h"

#define appname "gen-mirroring-tab"
#define outputname "gmirroringtable.h"

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

static void
die2 (
  const char *fmt,
  const char *p
)
{
  fprintf (stderr, appname ": ");
  fprintf (stderr, fmt, p);
  fprintf (stderr, "\n");
  exit (1);
}

static void
die4 (
  const char *fmt,
  unsigned long l,
  unsigned long p,
  unsigned long q
)
{
  fprintf (stderr, appname ": ");
  fprintf (stderr, fmt, l, p, q);
  fprintf (stderr, "\n");
  exit (1);
}

#define table_name "Mir"
#define macro_name "GLIB_GET_MIRRORING"

#define UNICODE_CHARS 0x110000

static signed int table[UNICODE_CHARS];
static char buf[4000];
static signed long max_dist;

static void
init (
  void
)
{
  max_dist = 0;
}

static void
clear_tab (
  void
)
{
  register gunichar c;

  for (c = 0; c < UNICODE_CHARS; c++)
    table[c] = 0;
}

static void
init_tab_mirroring_txt (
  void
)
{
  clear_tab ();
}

static void
read_bidi_mirroring_txt (
  FILE *f
)
{
  unsigned long l;

  init_tab_mirroring_txt ();

  l = 0;
  while (fgets (buf, sizeof buf, f))
    {
      unsigned long i, j;
      signed long dist;
      int k;
      const char *s = buf;

      l++;

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

      if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
	continue;

      k = sscanf (s, "%lx; %lx", &i, &j);
      if (k != 2 || i >= UNICODE_CHARS || j >= UNICODE_CHARS)
	die4 ("invalid pair in input at line %lu: %04lX, %04lX", l, i, j);
      dist = ((signed long) j - (signed long) i);
      table[i] = dist;
      if (dist > max_dist)
	max_dist = dist;
      else if (-dist > max_dist)
	max_dist = -dist;
    }
}

static void
read_data (
  const char *data_file_type,
  const char *data_file_name
)
{
  FILE *f;

  fprintf (stderr, "Reading '%s'\n", data_file_name);
  if (!(f = fopen (data_file_name, "rt")))
    die2 ("error: cannot open '%s' for reading", data_file_name);

  if (!strcmp (data_file_type, "BidiMirroring.txt"))
    read_bidi_mirroring_txt (f);
  else
    die2 ("error: unknown data-file-type %s", data_file_type);

  fclose (f);
}

static void
gen_mirroring_tab (
  int max_depth,
  const char *data_file_type
)
{
  int key_bytes;
  const char *key_type;

  fprintf (stderr,
	   "Generating '" outputname "', it may take up to a few minutes\n");
  printf ("/* " outputname "\n * generated by " appname " "
	  "\n" " * from the file %s of */\n\n", data_file_type);

  printf ("#define PACKTAB_UINT8 guint8\n"
	  "#define PACKTAB_UINT16 guint16\n"
	  "#define PACKTAB_UINT32 guint32\n\n");

  key_bytes = max_dist <= 0x7f ? 1 : max_dist < 0x7fff ? 2 : 4;
  key_type = key_bytes == 1 ? "gint8" : key_bytes == 2 ?
    "gint16" : "gint32";

  if (!pack_table
      (table, UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL,
       key_type, table_name, macro_name "_DELTA", stdout))
    die ("error: insufficient memory, decrease max_depth");

  printf ("#undef PACKTAB_UINT8\n"
	  "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n");

  printf ("#define " macro_name "(x) ((x) + " macro_name "_DELTA(x))\n\n");

  printf ("/* End of generated " outputname " */\n");
}

int
main (
  int argc,
  const char **argv
)
{
  const char *data_file_type = "BidiMirroring.txt";

  if (argc < 3)
    die2 ("usage:\n  " appname " max-lookups /path/to/%s [junk...]",
	  data_file_type);

  {
    int max_depth = atoi (argv[1]);
    const char *data_file_name = argv[2];

    if (max_depth < 2)
      die ("invalid depth");

    init ();
    read_data (data_file_type, data_file_name);
    gen_mirroring_tab (max_depth, data_file_type);
  }

  return 0;
}
