| /* 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; |
| } |