Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / liblouis / src / tools / lou_trace.c
1 /* liblouis Braille Translation and Back-Translation Library
2
3    Copyright (C) 2012 Swiss Library for the Blind, Visually Impaired and Print Disabled
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18    */
19
20 #include "config.h"
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include "louis.h"
25 #include <getopt.h>
26 #include "progname.h"
27 #include "version-etc.h"
28
29 static const struct option longopts[] = {
30   {"help", no_argument, NULL, 'h'},
31   {"version", no_argument, NULL, 'v'},
32   {NULL, 0, NULL, 0}
33 };
34
35 const char version_etc_copyright[] =
36   "Copyright %s %d Swiss Library for the Blind, Visually Impaired and Print Disabled.";
37
38 #define AUTHORS "Bert Frees"
39
40 static void
41 print_help(void) {
42   printf("\
43 Usage: %s [OPTIONS] TABLE[,TABLE,...]\n", program_name);
44   fputs("\
45 Examine and debug Braille translation tables. This program allows you\n\
46 to inspect liblouis translation tables by printing out the list of\n\
47 applied translation rules for a given input.\n\n", stdout);
48   fputs("\
49   -h, --help          display this help and exit\n\
50   -v, --version       display version information and exit\n\n", stdout);
51   printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);
52 #ifdef PACKAGE_PACKAGER_BUG_REPORTS
53   printf("Report %s bugs to: %s\n", PACKAGE_PACKAGER,
54          PACKAGE_PACKAGER_BUG_REPORTS);
55 #endif
56 #ifdef PACKAGE_URL
57   printf("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
58 #endif
59 }
60
61 #define BUFSIZE 512
62 #define RULESSIZE 512
63
64 static char *
65 get_input(void) {
66   static char input_buffer[BUFSIZE];
67   size_t input_length;
68   input_buffer[0] = 0;
69   fgets(input_buffer, sizeof(input_buffer), stdin);
70   input_length = strlen(input_buffer) - 1;
71   if (input_length < 0)
72     exit(0);
73   input_buffer[input_length] = 0;
74   return input_buffer;
75 }
76
77 static int
78 get_wide_input(widechar * buffer) {
79   return extParseChars(get_input(), buffer);
80 }
81
82 static char *
83 print_chars(const widechar * buffer, int length) {
84   static char chars[BUFSIZE];
85   strcpy(chars, &showString(buffer, length)[1]);
86   chars[strlen(chars) - 1] = 0;
87   return chars;
88 }
89
90 static char *
91 print_dots(const widechar * buffer, int length) {
92   static char dots[BUFSIZE];
93   strcpy(dots, showDots(buffer, length));
94   return dots;
95 }
96
97 static char *
98 print_number(widechar c) {
99   static char number[BUFSIZE];
100   sprintf(number, "%d", c);
101   return number;
102 }
103
104 static char *
105 print_attributes(unsigned int a) {
106   static char attr[BUFSIZE];
107   strcpy(attr, showAttributes(a));
108   return attr;
109 }
110
111 static void
112 append_char(char *destination, int *length, char source) {
113   destination[(*length)++] = source;
114 }
115
116 static void
117 append_string(char *destination, int *length, char *source) {
118   strcpy(&destination[(*length)], source);
119   (*length) += strlen(source);
120 }
121
122 static char *
123 print_script(const widechar * buffer, int length) {
124   static char script[BUFSIZE];
125   int i = 0;
126   int j = 0;
127   while (i < length) {
128     switch (buffer[i]) {
129     case pass_first:
130     case pass_last:
131     case pass_not:
132     case pass_startReplace:
133     case pass_endReplace:
134     case pass_search:
135     case pass_copy:
136     case pass_omit:
137       append_char(script, &j, buffer[i++]);
138       break;
139     case pass_lookback:
140       append_char(script, &j, buffer[i++]);
141       if (buffer[i] > 1)
142         append_string(script, &j, print_number(buffer[i++]));
143       break;
144     case pass_string:
145       append_char(script, &j, buffer[i]);
146       append_string(script, &j, print_chars(&buffer[i + 2], buffer[i + 1]));
147       append_char(script, &j, buffer[i]);
148       i += (2 + buffer[i + 1]);
149       break;
150     case pass_dots:
151       append_char(script, &j, buffer[i++]);
152       append_string(script, &j, print_dots(&buffer[i + 1], buffer[i]));
153       i += (1 + buffer[i]);
154       break;
155     case pass_eq:
156     case pass_lt:
157     case pass_gt:
158     case pass_lteq:
159     case pass_gteq:
160       append_char(script, &j, '#');
161       append_string(script, &j, print_number(buffer[i + 1]));
162       append_char(script, &j, buffer[i]);
163       append_string(script, &j, print_number(buffer[i + 2]));
164       i += 3;
165       break;
166     case pass_hyphen:
167     case pass_plus:
168       append_char(script, &j, '#');
169       append_string(script, &j, print_number(buffer[i + 1]));
170       append_char(script, &j, buffer[i]);
171       i += 2;
172       break;
173     case pass_attributes:
174       append_char(script, &j, buffer[i]);
175       append_string(script, &j,
176                     print_attributes(buffer[i + 1] << 16 | buffer[i + 2]));
177       i += 3;
178       if (buffer[i] == 1 && buffer[i + 1] == 1) {
179       } else if (buffer[i] == 1 && buffer[i + 1] == 0xffff)
180         append_char(script, &j, pass_until);
181       else if (buffer[i] == buffer[i + 1])
182         append_string(script, &j, print_number(buffer[i]));
183       else {
184         append_string(script, &j, print_number(buffer[i]));
185         append_char(script, &j, '-');
186         append_string(script, &j, print_number(buffer[i + 1]));
187       }
188       i += 2;
189       break;
190     case pass_endTest:
191       append_char(script, &j, '\t');
192       i++;
193       break;
194     case pass_swap:
195     case pass_groupstart:
196     case pass_groupend:
197     case pass_groupreplace:
198       /* TBD */
199     default:
200       i++;
201       break;
202     }
203   }
204   script[j] = 0;
205   return script;
206 }
207
208 static void
209 print_rule(const TranslationTableRule * rule) {
210   const char *opcode = findOpcodeName(rule->opcode);
211   char *chars;
212   char *dots;
213   char *script;
214   switch (rule->opcode) {
215   case CTO_Context:
216   case CTO_Correct:
217   case CTO_SwapCd:
218   case CTO_SwapDd:
219   case CTO_Pass2:
220   case CTO_Pass3:
221   case CTO_Pass4:
222     script = print_script(&rule->charsdots[rule->charslen], rule->dotslen);
223     printf("%s\t%s\n", opcode, script);
224     break;
225   default:
226     chars = print_chars(rule->charsdots, rule->charslen);
227     dots = print_dots(&rule->charsdots[rule->charslen], rule->dotslen);
228     printf("%s\t%s\t%s\n", opcode, chars, dots);
229     break;
230   }
231 }
232
233 static void
234 main_loop(char *table) {
235   widechar inbuf[BUFSIZE];
236   widechar outbuf[BUFSIZE];
237   int inlen;
238   int outlen;
239   const TranslationTableRule **rules =
240     malloc(512 * sizeof(TranslationTableRule));
241   int ruleslen;
242   int i;
243   while (1) {
244     inlen = get_wide_input(inbuf);
245     outlen = BUFSIZE;
246     ruleslen = RULESSIZE;
247     if (!trace_translate(table, inbuf, &inlen, outbuf, &outlen,
248                          NULL, NULL, NULL, NULL, NULL, rules, &ruleslen, 0))
249       break;
250     printf("%s\n", print_chars(outbuf, outlen));
251     for (i = 0; i < ruleslen; i++) {
252       printf("%d.\t", i + 1);
253       print_rule(rules[i]);
254     }
255   }
256 }
257
258 int
259 main(int argc, char **argv) {
260   int optc;
261   char *table;
262   set_program_name(argv[0]);
263   while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) {
264     switch (optc) {
265     case 'v':
266       version_etc(stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS,
267                   (char *) NULL);
268       exit(EXIT_SUCCESS);
269       break;
270     case 'h':
271       print_help();
272       exit(EXIT_SUCCESS);
273       break;
274     default:
275       fprintf(stderr, "Try `%s --help' for more information.\n",
276               program_name);
277       exit(EXIT_FAILURE);
278       break;
279     }
280   }
281   if (optind != argc - 1) {
282     if (optind < argc - 1)
283       fprintf(stderr, "%s: extra operand: %s\n", program_name,
284               argv[optind + 1]);
285     else
286       fprintf(stderr, "%s: no table specified\n", program_name);
287     fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
288     exit(EXIT_FAILURE);
289   }
290   table = argv[optind];
291   if (!lou_getTable(table)) {
292     lou_free();
293     exit(EXIT_FAILURE);
294   }
295   main_loop(table);
296   lou_free();
297   exit(EXIT_SUCCESS);
298 }