blob: 627fb4c542441d96a80ce33d0285e0f9741c77b3 [file] [log] [blame]
Eitan Isaacson109996e2008-12-20 14:52:53 +00001/* liblouis Braille Translation and Back-Translation Library
2
3 Based on BRLTTY, copyright (C) 1999-2006 by
4 The BRLTTY Team
5
Christian Egli08d96a72009-10-08 08:49:13 +00006 Copyright (C) 2004, 2005, 2006, 2009
7 ViewPlus Technologies, Inc. www.viewplus.com and
Eitan Isaacson109996e2008-12-20 14:52:53 +00008 JJB Software, Inc. www.jjb-software.com
9
Christian Egli08d96a72009-10-08 08:49:13 +000010 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
Eitan Isaacson109996e2008-12-20 14:52:53 +000020 You should have received a copy of the GNU General Public License
Christian Egli08d96a72009-10-08 08:49:13 +000021 along with this program. If not, see <http://www.gnu.org/licenses/>.
Bert Frees312affd2017-09-30 19:49:15 +020022*/
Eitan Isaacson109996e2008-12-20 14:52:53 +000023
Christian Egli31ef6ff2015-06-05 11:22:36 +020024# include <config.h>
Eitan Isaacson109996e2008-12-20 14:52:53 +000025#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
Davy Kagerff52a4f2017-04-26 22:01:10 +020028#include "internal.h"
Christian Eglibe149002009-10-09 09:09:07 +000029#include <getopt.h>
30#include "progname.h"
Christian Egli4b193942016-06-21 17:57:26 +020031#include "unistr.h"
Christian Eglibe149002009-10-09 09:09:07 +000032#include "version-etc.h"
33
34static const struct option longopts[] =
35{
36 { "help", no_argument, NULL, 'h' },
37 { "version", no_argument, NULL, 'v' },
Bert Freesbe3466f2017-09-30 22:26:57 +020038 { NULL, 0, NULL, 0 },
Christian Eglibe149002009-10-09 09:09:07 +000039};
40
41const char version_etc_copyright[] =
42 "Copyright %s %d ViewPlus Technologies, Inc. and JJB Software, Inc.";
43
44#define AUTHORS "John J. Boyer"
45
46static void
47print_help (void)
48{
49 printf ("\
Christian Eglibaefdb22012-12-19 09:48:54 +000050Usage: %s [OPTIONS] TABLE[,TABLE,...]\n", program_name);
Christian Eglibe149002009-10-09 09:09:07 +000051
52 fputs ("\
53Examine and debug Braille translation tables. This program allows you\n\
54to inspect liblouis translation tables and gather information about\n\
55them, such as forward and backward rules, characters and dot patterns,\n\
56specific opcodes, the size of a table, whether a hyphenation\n\
57table is used, how many passes the translation takes and much\n\
58more.\n\n", stdout);
59
60 fputs ("\
61 -h, --help display this help and exit\n\
62 -v, --version display version information and exit\n", stdout);
63
64 printf ("\n");
Christian Eglidc50af92012-09-27 13:10:51 +000065 printf ("Report bugs to %s.\n", PACKAGE_BUGREPORT);
66
67#ifdef PACKAGE_PACKAGER_BUG_REPORTS
68 printf ("Report %s bugs to: %s\n", PACKAGE_PACKAGER, PACKAGE_PACKAGER_BUG_REPORTS);
69#endif
70#ifdef PACKAGE_URL
71 printf ("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
72#endif
Christian Eglibe149002009-10-09 09:09:07 +000073}
74
Eitan Isaacson109996e2008-12-20 14:52:53 +000075#define BUFSIZE 256
76
John Boyer16689ac2009-01-12 15:11:39 +000077static const TranslationTableHeader *table;
Eitan Isaacson109996e2008-12-20 14:52:53 +000078static char inputBuffer[BUFSIZE];
79
80static int
Eitan Isaacson109996e2008-12-20 14:52:53 +000081getInput (void)
82{
John Boyer16689ac2009-01-12 15:11:39 +000083 int inputLength;
84 inputBuffer[0] = 0;
Christian Egli3741c622016-06-10 15:04:44 +020085 if (!fgets (inputBuffer, sizeof (inputBuffer), stdin))
86 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +000087 inputLength = strlen (inputBuffer) - 1;
Bert Frees6f731002017-09-30 19:59:17 +020088 if (inputLength < 0) /* EOF on script */
Christian Egli3741c622016-06-10 15:04:44 +020089 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +000090 inputBuffer[inputLength] = 0;
91 return inputLength;
Eitan Isaacson109996e2008-12-20 14:52:53 +000092}
93
Christian Egli4b193942016-06-21 17:57:26 +020094static char*
95print_chars(const widechar *buffer, int length) {
96 static uint8_t result_buf[BUFSIZE];
97 size_t result_len = BUFSIZE - 1;
98#ifdef WIDECHARS_ARE_UCS4
Dave Mielke4ebfc2c2017-01-16 06:01:52 -050099 u32_to_u8(buffer, length, result_buf, &result_len);
Christian Egli4b193942016-06-21 17:57:26 +0200100#else
Dave Mielke4ebfc2c2017-01-16 06:01:52 -0500101 u16_to_u8(buffer, length, result_buf, &result_len);
Christian Egli4b193942016-06-21 17:57:26 +0200102#endif
103 result_buf[result_len] = 0;
104 return result_buf;
105}
106
Eitan Isaacson109996e2008-12-20 14:52:53 +0000107static int
John Boyer16689ac2009-01-12 15:11:39 +0000108printRule (TranslationTableRule * thisRule, int mode)
109{
110 printf ("Rule: ");
Davy Kager9bdc9c22017-04-26 22:54:41 +0200111 printf ("opcode=%s, ", _lou_findOpcodeName (thisRule->opcode));
John Boyer16689ac2009-01-12 15:11:39 +0000112 if (thisRule->before)
113 printf ("before=%x, ", thisRule->before);
114 if (thisRule->after)
115 printf ("after=%x, ", thisRule->after);
116 switch (thisRule->opcode)
117 {
118 case CTO_Context:
119 case CTO_Correct:
120 case CTO_SwapCd:
121 case CTO_SwapDd:
122 case CTO_Pass2:
123 case CTO_Pass3:
124 case CTO_Pass4:
Christian Egli4b193942016-06-21 17:57:26 +0200125 printf ("code=%s ", print_chars(thisRule->charsdots, thisRule->charslen
John Boyer16689ac2009-01-12 15:11:39 +0000126 + thisRule->dotslen));
127 break;
128 default:
129 if (mode == 0)
130 {
Christian Egli4b193942016-06-21 17:57:26 +0200131 printf ("chars=%s, ", print_chars(thisRule->charsdots,
John Boyer16689ac2009-01-12 15:11:39 +0000132 thisRule->charslen));
133 printf ("dots=%s, ",
Davy Kager9bdc9c22017-04-26 22:54:41 +0200134 _lou_showDots (&thisRule->charsdots[thisRule->charslen],
John Boyer16689ac2009-01-12 15:11:39 +0000135 thisRule->dotslen));
136 }
137 else
138 {
139 printf ("dots=%s, ",
Davy Kager9bdc9c22017-04-26 22:54:41 +0200140 _lou_showDots (&thisRule->charsdots[thisRule->charslen],
John Boyer16689ac2009-01-12 15:11:39 +0000141 thisRule->dotslen));
Christian Egli4b193942016-06-21 17:57:26 +0200142 printf ("chars=%s, ", print_chars(thisRule->charsdots,
John Boyer16689ac2009-01-12 15:11:39 +0000143 thisRule->charslen));
144 }
145 break;
146 }
147 return 1;
148}
149
150static int
151printCharacter (TranslationTableCharacter * thisChar, int mode)
152{
153 TranslationTableRule *thisRule;
154 TranslationTableOffset nextRule;
155 if (mode == 0)
156 {
157 printf ("Char: ");
Christian Egli4b193942016-06-21 17:57:26 +0200158 printf ("real=%s, ", print_chars(&thisChar->realchar, 1));
159 printf ("upper=%s, ", print_chars(&thisChar->uppercase, 1));
160 printf ("lower=%s, ", print_chars(&thisChar->lowercase, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000161 }
162 else
Davy Kager9bdc9c22017-04-26 22:54:41 +0200163 printf ("Dots: real=%s, ", _lou_showDots (&thisChar->realchar, 1));
164 printf ("attr=%s, ", _lou_showAttributes (thisChar->attributes));
John Boyer16689ac2009-01-12 15:11:39 +0000165 nextRule = thisChar->otherRules;
166 while (nextRule)
167 {
168 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
John Boyerc675d7a2009-01-15 14:32:20 +0000169 if (nextRule == thisChar->definitionRule)
John Boyer16689ac2009-01-12 15:11:39 +0000170 printf ("definition ");
171 printRule (thisRule, mode);
172 printf ("\n");
173 if (mode == 0)
174 nextRule = thisRule->charsnext;
175 else
176 nextRule = thisRule->dotsnext;
177 }
178 return 1;
179}
180
181static int
182show_characters (int startHash)
183{
184 int k;
185 TranslationTableCharacter *thisChar;
186 TranslationTableOffset nextChar;
187 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
188 if (startHash < 0)
189 k = 0;
190 else
191 k = startHash;
192 for (; k < HASHNUM; k++)
193 if (table->characters[k])
194 {
195 printf ("Hash=%d\n", k);
196 nextChar = table->characters[k];
197 while (nextChar)
198 {
199 thisChar =
200 (TranslationTableCharacter *) & table->ruleArea[nextChar];
201 printCharacter (thisChar, 0);
202 printf ("=> ");
203 getInput ();
204 if (*inputBuffer == 'h')
205 break;
206 if (*inputBuffer == 'e')
207 return 1;
208 nextChar = thisChar->next;
209 }
210 }
211 return 1;
212}
213
214static int
215show_dots (int startHash)
216{
217 int k;
218 TranslationTableCharacter *thisDots;
219 TranslationTableOffset nextDots;
220 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
221 if (startHash < 0)
222 k = 0;
223 else
224 k = startHash;
225 for (; k < HASHNUM; k++)
226 if (table->dots[k])
227 {
228 printf ("Hash=%d\n", k);
229 nextDots = table->dots[k];
230 while (nextDots)
231 {
232 thisDots =
233 (TranslationTableCharacter *) & table->ruleArea[nextDots];
234 printCharacter (thisDots, 1);
235 printf ("=> ");
236 getInput ();
237 if (*inputBuffer == 'h')
238 break;
239 if (*inputBuffer == 'e')
240 return 1;
241 nextDots = thisDots->next;
242 }
243 }
244 return 1;
245}
246
247static int
248show_forRules (int startHash)
249{
250 int k;
251 TranslationTableRule *thisRule;
252 TranslationTableOffset nextRule;
253 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
254 if (startHash < 0)
255 k = 0;
256 else
257 k = startHash;
258 for (; k < HASHNUM; k++)
259 if (table->forRules[k])
260 {
261 printf ("Hash=%d\n", k);
262 nextRule = table->forRules[k];
263 while (nextRule)
264 {
265 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
266 printRule (thisRule, 0);
267 printf ("=> ");
268 getInput ();
269 if (*inputBuffer == 'h')
270 break;
271 if (*inputBuffer == 'e')
272 return 1;
273 nextRule = thisRule->charsnext;
274 }
275 }
276 return 1;
277}
278
279static int
280show_backRules (int startHash)
281{
282 int k;
283 TranslationTableRule *thisRule;
284 TranslationTableOffset nextRule;
285 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
286 if (startHash < 0)
287 k = 0;
288 else
289 k = startHash;
290 for (; k < HASHNUM; k++)
291 if (table->backRules[k])
292 {
293 printf ("Hash=%d\n", k);
294 nextRule = table->backRules[k];
295 while (nextRule)
296 {
297 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
298 printRule (thisRule, 1);
299 printf ("=> ");
300 getInput ();
301 if (*inputBuffer == 'h')
302 break;
303 if (*inputBuffer == 'e')
304 return 1;
305 nextRule = thisRule->dotsnext;
306 }
307 }
308 return 1;
309}
310
311static int
312print_brailleIndicator (TranslationTableOffset offset, char *opcode)
313{
314 TranslationTableRule *thisRule;
315 if (!offset)
316 return 0;
317 thisRule = (TranslationTableRule *) & table->ruleArea[offset];
318 printf ("%s %s\n", opcode,
Davy Kager9bdc9c22017-04-26 22:54:41 +0200319 _lou_showDots (&thisRule->charsdots[0], thisRule->dotslen));
John Boyer16689ac2009-01-12 15:11:39 +0000320 return 1;
321}
322
323static int
324print_phraseLength (TranslationTableOffset offset, char *opcode)
325{
326 if (!offset)
327 return 0;
328 printf ("%s %d\n", opcode, offset);
Christian Eglifbfea8b2009-08-11 11:24:40 +0000329 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000330}
331
332static int
333show_brailleIndicators (void)
334{
Christian Eglif1da9822016-06-10 15:03:34 +0200335 char name[BUFSIZE];
336 char *emphNames[] = {"begemphphrase %s",
337 "endemphphrase %s before",
338 "endemphphrase %s after",
339 "begemphword %s",
340 "endemphword %s",
341 "emphletter %s",
342 "begemph %s",
343 "endemph %s",
344 NULL};
345 char *capsNames[] = {"firstwordcaps",
346 "lastwordcapsbefore",
347 "lastwordcapsafter",
348 "begcaps",
349 "endcaps",
350 "capsletter",
351 "capsword",
352 "capswordstop",
353 NULL};
354
Davy Kager68004042016-01-26 12:50:22 +0100355 // FIXME: update to include all UEB opcodes.
Christian Eglif1da9822016-06-10 15:03:34 +0200356
357 for (EmphCodeOffset offset = 0; capsNames[offset]; offset++) {
358 print_brailleIndicator (table->emphRules[capsRule][offset],capsNames[offset]);
359 }
Davy Kagerb3ff4542016-02-15 11:03:02 +0100360 print_phraseLength (table->emphRules[capsRule][lenPhraseOffset], "lencapsphrase");
John Boyer16689ac2009-01-12 15:11:39 +0000361 print_brailleIndicator (table->letterSign, "letsign");
362 print_brailleIndicator (table->numberSign, "numsign");
Christian Eglif1da9822016-06-10 15:03:34 +0200363
364 for (int i = 0; table->emphClasses[i]; i++) {
365 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
366 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
367 print_brailleIndicator (table->emphRules[emph1Rule][offset], name);
368 }
369 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
370 print_phraseLength (table->emphRules[emph1Rule][lenPhraseOffset], name);
371 }
John Boyer16689ac2009-01-12 15:11:39 +0000372 print_brailleIndicator (table->begComp, "begcomp");
373 print_brailleIndicator (table->compBegEmph1, "compbegemph1");
374 print_brailleIndicator (table->compEndEmph1, "compendemph1");
375 print_brailleIndicator (table->compBegEmph2, "compbegemph2");
376 print_brailleIndicator (table->compEndEmph2, "compendemph2");
377 print_brailleIndicator (table->compBegEmph3, "compbegemph3");
378 print_brailleIndicator (table->compEndEmph3, "compendemph3");
379 print_brailleIndicator (table->compCapSign, "compcapsign");
380 print_brailleIndicator (table->compBegCaps, "compbegcaps");
381 print_brailleIndicator (table->compEndCaps, "compendcaps");
382 print_brailleIndicator (table->endComp, "endcomp");
383 return 1;
384}
385
386static char *
387pickYN (int a)
388{
389 if (!a)
390 return "no";
391 return "yes";
392}
393
394static int
395show_misc (void)
396{
397 printf ("Table size: %d\n", table->tableSize);
398 printf ("Bytes used: %d\n", table->bytesUsed);
399 printf ("Number of passes: %d\n", table->numPasses);
Christian Egli5e8c3892009-01-15 16:30:59 +0000400 printf ("'correct' opcodes: %s\n", pickYN (table->corrections));
John Boyer16689ac2009-01-12 15:11:39 +0000401 printf ("'syllable' opcodes: %s\n", pickYN (table->syllables));
402 printf ("'capsnocont' opcode: %s\n", pickYN (table->capsNoCont));
403 printf ("Hyphenation table: %s\n", pickYN (table->hyphenStatesArray));
Christian Egli4b193942016-06-21 17:57:26 +0200404 printf ("noletsignbefore %s\n", print_chars(&table->noLetsignBefore[0],
John Boyer16689ac2009-01-12 15:11:39 +0000405 table->noLetsignBeforeCount));
Christian Egli4b193942016-06-21 17:57:26 +0200406 printf ("noletsign %s\n", print_chars(&table->noLetsign[0],
John Boyer16689ac2009-01-12 15:11:39 +0000407 table->noLetsignCount));
Christian Egli4b193942016-06-21 17:57:26 +0200408 printf ("noletsignafter %s\n", print_chars(&table->noLetsignAfter[0],
John Boyer16689ac2009-01-12 15:11:39 +0000409 table->noLetsignAfterCount));
Christian Eglifbfea8b2009-08-11 11:24:40 +0000410 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000411}
412
413static int
414show_charMap (int startHash)
415{
416 int k;
417 CharOrDots *thisChar;
418 TranslationTableOffset nextChar;
419 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
420 if (startHash < 0)
421 k = 0;
422 else
423 k = startHash;
424 for (; k < HASHNUM; k++)
425 if (table->charToDots[k])
426 {
427 printf ("Hash=%d\n", k);
428 nextChar = table->charToDots[k];
429 while (nextChar)
430 {
431 thisChar = (CharOrDots *) & table->ruleArea[nextChar];
Christian Egli4b193942016-06-21 17:57:26 +0200432 printf ("Char: %s ", print_chars(&thisChar->lookFor, 1));
Davy Kager9bdc9c22017-04-26 22:54:41 +0200433 printf ("dots=%s\n", _lou_showDots (&thisChar->found, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000434 printf ("=> ");
435 getInput ();
436 if (*inputBuffer == 'h')
437 break;
438 if (*inputBuffer == 'e')
439 return 1;
440 nextChar = thisChar->next;
441 }
442 }
443 return 1;
444}
445
446static int
447show_dotsMap (int startHash)
448{
449 int k;
450 CharOrDots *thisDots;
451 TranslationTableOffset nextDots;
452 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
453 if (startHash < 0)
454 k = 0;
455 else
456 k = startHash;
457 for (; k < HASHNUM; k++)
458 if (table->dotsToChar[k])
459 {
460 printf ("Hash=%d\n", k);
461 nextDots = table->dotsToChar[k];
462 while (nextDots)
463 {
464 thisDots = (CharOrDots *) & table->ruleArea[nextDots];
Davy Kager9bdc9c22017-04-26 22:54:41 +0200465 printf ("Dots: %s ", _lou_showDots (&thisDots->lookFor, 1));
Christian Egli4b193942016-06-21 17:57:26 +0200466 printf ("char=%s\n", print_chars(&thisDots->found, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000467 printf ("=> ");
468 getInput ();
469 if (*inputBuffer == 'h')
470 break;
471 if (*inputBuffer == 'e')
472 return 1;
473 nextDots = thisDots->next;
474 }
475 }
476 return 1;
477}
478
479static int
480show_compDots (int startChar)
481{
482 widechar k;
483 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
484 if (startChar < 0)
485 k = 0;
486 else
487 k = startChar;
488 for (; k < 256; k++)
489 if (table->compdotsPattern[k])
490 {
491 TranslationTableRule *thisRule = (TranslationTableRule *)
492 & table->ruleArea[table->compdotsPattern[k]];
Christian Egli4b193942016-06-21 17:57:26 +0200493 printf ("Char: %s ", print_chars(&k, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000494 printf ("dots=%s\n",
Davy Kager9bdc9c22017-04-26 22:54:41 +0200495 _lou_showDots (&thisRule->charsdots[1], thisRule->dotslen));
John Boyer16689ac2009-01-12 15:11:39 +0000496 printf ("=> ");
497 getInput ();
498 if (*inputBuffer == 'e')
499 return 1;
500 }
501 return 1;
502}
503
504static void
Davy Kagere5f98122017-04-26 15:20:15 +0200505part_paramLetters (void)
John Boyer16689ac2009-01-12 15:11:39 +0000506{
507 printf ("show particular hash chains.\n");
508 printf
509 ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
510 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
511 printf ("(z)-compdots, (h)elp, e(x)it\n");
512}
513
514static void
515particularHelp (void)
516{
517 part_paramLetters ();
518}
519
520static int
521particular (void)
522{
523 int startHash;
524 widechar parsed[BUFSIZE];
525 part_paramLetters ();
526 do
527 {
528 printf ("particular: ");
529 getInput ();
530 switch (inputBuffer[0])
531 {
532 case 0:
533 break;
534 case 'h':
535 particularHelp ();
536 break;
537 case 'c':
538 printf ("-> ");
539 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200540 if (!_lou_extParseChars (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000541 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200542 startHash = _lou_charHash (*parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000543 if (table->characters[startHash] == 0)
544 {
545 printf ("Character not in table.\n");
546 break;
547 }
548 show_characters (startHash);
549 break;
550 case 'd':
551 printf ("-> ");
552 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200553 if (!_lou_extParseDots (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000554 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200555 startHash = _lou_charHash (*parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000556 if (table->dots[startHash] == 0)
557 {
558 printf ("Dot pattern not in table.\n");
559 break;
560 }
561 show_dots (startHash);
562 break;
563 case 'C':
564 printf ("-> ");
565 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200566 if (!_lou_extParseChars (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000567 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200568 startHash = _lou_charHash (*parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000569 if (table->charToDots[startHash] == 0)
570 {
571 printf ("Character not in table.\n");
572 break;
573 }
574 show_charMap (startHash);
575 break;
576 case 'D':
577 printf ("-> ");
578 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200579 if (!_lou_extParseDots (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000580 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200581 startHash = _lou_charHash (*parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000582 if (table->dotsToChar[startHash] == 0)
583 {
584 printf ("Dot pattern not in table.\n");
585 break;
586 }
587 show_dotsMap (startHash);
588 break;
589 case 'f':
590 printf ("-> ");
591 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200592 if (!_lou_extParseChars (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000593 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200594 startHash = _lou_stringHash (parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000595 if (table->forRules[startHash] == 0)
596 {
597 printf ("Character string not in table.\n");
598 break;
599 }
600 show_forRules (startHash);
601 break;
602 case 'b':
603 printf ("-> ");
604 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200605 if (!_lou_extParseDots (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000606 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200607 startHash = _lou_stringHash (parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000608 if (table->backRules[startHash] == 0)
609 {
610 printf ("Dot pattern not in table.\n");
611 break;
612 }
613 show_backRules (startHash);
614 break;
615 case 'z':
616 printf ("-> ");
617 getInput ();
Davy Kager9bdc9c22017-04-26 22:54:41 +0200618 if (!_lou_extParseChars (inputBuffer, parsed))
John Boyer16689ac2009-01-12 15:11:39 +0000619 break;
Davy Kager9bdc9c22017-04-26 22:54:41 +0200620 startHash = _lou_charHash (*parsed);
John Boyer16689ac2009-01-12 15:11:39 +0000621 if (*parsed > 255 || table->compdotsPattern[startHash] == 0)
622 {
623 printf ("Character not in table.\n");
624 break;
625 }
626 show_compDots (startHash);
627 break;
628 case 'x':
629 return 1;
630 default:
631 printf ("Bad choice.\n");
632 break;
633 }
634 }
635 while (inputBuffer[0] != 'x');
636 return 1;
637}
638
Eitan Isaacson109996e2008-12-20 14:52:53 +0000639static void
640paramLetters (void)
641{
John Boyer16689ac2009-01-12 15:11:39 +0000642 printf ("Press one of the letters in parentheses, then enter.\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200643 printf ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
John Boyer16689ac2009-01-12 15:11:39 +0000644 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
645 printf ("show-(m)isc, show-(z)-compdots\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200646 printf ("show-braille(i)ndicators, show-(p)articulars\n");
647 printf ("(h)elp, (q)uit\n");
John Boyer16689ac2009-01-12 15:11:39 +0000648}
649
650static void
651commandHelp (void)
652{
653 paramLetters ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000654}
655
656static int
657getCommands (void)
658{
659 paramLetters ();
660 do
661 {
662 printf ("Command: ");
663 getInput ();
664 switch (inputBuffer[0])
665 {
666 case 0:
667 break;
John Boyer16689ac2009-01-12 15:11:39 +0000668 case 'h':
669 commandHelp ();
670 break;
671 case 'C':
672 show_charMap (-1);
673 break;
674 case 'D':
675 show_dotsMap (-1);
676 break;
677 case 'z':
678 show_compDots (-1);
679 break;
680 case 'c':
681 show_characters (-1);
682 break;
683 case 'd':
684 show_dots (-1);
685 break;
686 case 'f':
687 show_forRules (-1);
688 break;
689 case 'b':
690 show_backRules (-1);
691 break;
692 case 'i':
693 show_brailleIndicators ();
694 break;
695 case 'm':
696 show_misc ();
697 break;
698 case 'p':
699 particular ();
700 break;
701 case 'q':
702 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000703 default:
704 printf ("Bad choice.\n");
705 break;
706 }
707 }
John Boyer16689ac2009-01-12 15:11:39 +0000708 while (inputBuffer[0] != 'q');
Eitan Isaacson109996e2008-12-20 14:52:53 +0000709 return 1;
710}
711
712int
713main (int argc, char **argv)
714{
Christian Eglibe149002009-10-09 09:09:07 +0000715 int optc;
716
717 set_program_name (argv[0]);
718
719 while ((optc = getopt_long (argc, argv, "hv", longopts, NULL)) != -1)
720 switch (optc)
721 {
Bert Frees6f731002017-09-30 19:59:17 +0200722 /* --help and --version exit immediately, per GNU coding standards. */
Christian Eglibe149002009-10-09 09:09:07 +0000723 case 'v':
724 version_etc (stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *) NULL);
725 exit (EXIT_SUCCESS);
726 break;
727 case 'h':
728 print_help ();
729 exit (EXIT_SUCCESS);
730 break;
731 default:
732 fprintf (stderr, "Try `%s --help' for more information.\n",
733 program_name);
734 exit (EXIT_FAILURE);
735 break;
736 }
737
738 if (optind != argc - 1)
Eitan Isaacson109996e2008-12-20 14:52:53 +0000739 {
Bert Frees6f731002017-09-30 19:59:17 +0200740 /* Print error message and exit. */
Christian Eglibe149002009-10-09 09:09:07 +0000741 if (optind < argc - 1)
742 fprintf (stderr, "%s: extra operand: %s\n",
743 program_name, argv[optind + 1]);
744 else
745 fprintf (stderr, "%s: no table specified\n",
746 program_name);
747 fprintf (stderr, "Try `%s --help' for more information.\n",
748 program_name);
749 exit (EXIT_FAILURE);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000750 }
Christian Eglibe149002009-10-09 09:09:07 +0000751
752 if (!(table = lou_getTable (argv[optind])))
John Boyer16689ac2009-01-12 15:11:39 +0000753 {
754 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000755 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +0000756 }
757 getCommands ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000758 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000759 exit (EXIT_SUCCESS);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000760}