Merge branch 'upstream' into tizen
[platform/upstream/fribidi.git] / gen.tab / gen-brackets-type-tab.c
1 /* FriBidi
2  * gen-brackets-type-tab.c - generate brackets.tab.i
3  *
4  * Author:
5  *   Behdad Esfahbod, 2001, 2002, 2004
6  *   Dov Grobgeld 2017
7  *
8  * Copyright (C) 2004 Sharif FarsiWeb, Inc
9  * Copyright (C) 2001,2002,2004 Behdad Esfahbod
10  * Copyright (C) 2017 Dov Grobgeld
11  * 
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * 
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  * 
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this library, in a file named COPYING; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA
26  * 
27  * For licensing issues, contact <fribidi.license@gmail.com>.
28  */
29
30 #include <common.h>
31
32 #include <fribidi-unicode.h>
33
34 #include <stdio.h>
35 #ifdef STDC_HEADERS
36 # include <stdlib.h>
37 # include <stddef.h>
38 #else
39 # if HAVE_STDLIB_H
40 #  include <stdlib.h>
41 # endif
42 #endif
43 #ifdef HAVE_STRING_H
44 # if !STDC_HEADERS && HAVE_MEMORY_H
45 #  include <memory.h>
46 # endif
47 # include <string.h>
48 #endif
49 #ifdef HAVE_STRINGS_H
50 # include <strings.h>
51 #endif
52
53 #include "packtab.h"
54
55 #define appname "gen-brackets-type-tab"
56 #define outputname "brackets-type.tab.i"
57
58 static void
59 die (
60   const char *msg
61 )
62 {
63   fprintf (stderr, appname ": %s\n", msg);
64   exit (1);
65 }
66
67 static void
68 die2 (
69   const char *fmt,
70   const char *p
71 )
72 {
73   fprintf (stderr, appname ": ");
74   fprintf (stderr, fmt, p);
75   fprintf (stderr, "\n");
76   exit (1);
77 }
78
79 static void
80 die4 (
81   const char *fmt,
82   unsigned long l,
83   unsigned long p,
84   unsigned long q
85 )
86 {
87   fprintf (stderr, appname ": ");
88   fprintf (stderr, fmt, l, p, q);
89   fprintf (stderr, "\n");
90   exit (1);
91 }
92
93 #define table_name "Brt"
94 #define macro_name "FRIBIDI_GET_BRACKET_TYPE"
95
96 static signed int table[FRIBIDI_UNICODE_CHARS];
97 static char buf[4000];
98 static signed long max_dist;
99
100 static void
101 init (
102   void
103 )
104 {
105   max_dist = 0;
106 }
107
108 static void
109 clear_tab (
110   void
111 )
112 {
113   register FriBidiChar c;
114
115   for (c = 0; c < FRIBIDI_UNICODE_CHARS; c++)
116     table[c] = 0;
117 }
118
119 static void
120 init_tab_brackets_type_txt (
121   void
122 )
123 {
124   clear_tab ();
125 }
126
127 static void
128 read_bidi_brackets_type_txt (
129   FILE *f
130 )
131 {
132   unsigned long l;
133
134   init_tab_brackets_type_txt ();
135
136   l = 0;
137   while (fgets (buf, sizeof buf, f))
138     {
139       unsigned long i, j;
140       int k;
141       const char *s = buf;
142       char open_close;
143
144       l++;
145
146       while (*s == ' ')
147         s++;
148
149       if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
150         continue;
151
152       k = sscanf (s, "%lx; %lx; %c", &i, &j, &open_close);
153       if (k != 3 || i >= FRIBIDI_UNICODE_CHARS || j >= FRIBIDI_UNICODE_CHARS)
154         die4 ("invalid pair in input at line %ld: %04lX, %04lX", l, i, j);
155       table[i] = 1 + (0x2 * (open_close=='o'));
156     }
157 }
158
159 static void
160 read_data (
161   const char *data_file_type,
162   const char *data_file_name
163 )
164 {
165   FILE *f;
166
167   if (!(f = fopen (data_file_name, "rt")))
168     die2 ("error: cannot open `%s' for reading", data_file_name);
169
170   if (!strcmp (data_file_type, "BidiBrackets.txt"))
171     read_bidi_brackets_type_txt (f);
172   else
173     die2 ("error: unknown data-file-type %s", data_file_type);
174
175   fclose (f);
176 }
177
178 static void
179 gen_brackets_tab (
180   int max_depth,
181   const char *data_file_type
182 )
183 {
184   int key_bytes;
185   const char *key_type;
186
187   printf ("/* " outputname "\n * generated by " appname " (" FRIBIDI_NAME " "
188           FRIBIDI_VERSION ")\n" " * from the file %s of Unicode version "
189           FRIBIDI_UNICODE_VERSION ". */\n\n", data_file_type);
190
191   printf ("#define PACKTAB_UINT8 uint8_t\n"
192           "#define PACKTAB_UINT16 uint16_t\n"
193           "#define PACKTAB_UINT32 uint32_t\n\n");
194
195   key_bytes = 1;
196   key_type = key_bytes == 1 ? "int8_t" : key_bytes == 2 ?
197     "int16_t" : "int32_t";
198
199   if (!pack_table
200       (table, FRIBIDI_UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL,
201        key_type, table_name, macro_name, stdout))
202     die ("error: insufficient memory, decrease max_depth");
203
204   printf ("#undef PACKTAB_UINT8\n"
205           "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n");
206
207   printf ("/* End of generated " outputname " */\n");
208 }
209
210 int
211 main (
212   int argc,
213   const char **argv
214 )
215 {
216   const char *data_file_type = "BidiBrackets.txt";
217
218   if (argc < 3)
219     die2 ("usage:\n  " appname " max-depth /path/to/%s [junk...]",
220           data_file_type);
221
222   {
223     int max_depth = atoi (argv[1]);
224     const char *data_file_name = argv[2];
225
226     if (max_depth < 2)
227       die ("invalid depth");
228
229     init ();
230     read_data (data_file_type, data_file_name);
231     gen_brackets_tab (max_depth, data_file_type);
232   }
233
234   return 0;
235 }