blob: af8b7cb3e9f28abbb41cb2cf949c2adcff85e52d [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/>.
Eitan Isaacson109996e2008-12-20 14:52:53 +000022
Eitan Isaacson109996e2008-12-20 14:52:53 +000023 */
24
Christian Egli31ef6ff2015-06-05 11:22:36 +020025# include <config.h>
Eitan Isaacson109996e2008-12-20 14:52:53 +000026#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include "louis.h"
Christian Eglibe149002009-10-09 09:09:07 +000030#include <getopt.h>
31#include "progname.h"
Christian Egli4b193942016-06-21 17:57:26 +020032#include "unistr.h"
Christian Eglibe149002009-10-09 09:09:07 +000033#include "version-etc.h"
34
35static const struct option longopts[] =
36{
37 { "help", no_argument, NULL, 'h' },
38 { "version", no_argument, NULL, 'v' },
39 { NULL, 0, NULL, 0 }
40};
41
42const char version_etc_copyright[] =
43 "Copyright %s %d ViewPlus Technologies, Inc. and JJB Software, Inc.";
44
45#define AUTHORS "John J. Boyer"
46
47static void
48print_help (void)
49{
50 printf ("\
Christian Eglibaefdb22012-12-19 09:48:54 +000051Usage: %s [OPTIONS] TABLE[,TABLE,...]\n", program_name);
Christian Eglibe149002009-10-09 09:09:07 +000052
53 fputs ("\
54Examine and debug Braille translation tables. This program allows you\n\
55to inspect liblouis translation tables and gather information about\n\
56them, such as forward and backward rules, characters and dot patterns,\n\
57specific opcodes, the size of a table, whether a hyphenation\n\
58table is used, how many passes the translation takes and much\n\
59more.\n\n", stdout);
60
61 fputs ("\
62 -h, --help display this help and exit\n\
63 -v, --version display version information and exit\n", stdout);
64
65 printf ("\n");
Christian Eglidc50af92012-09-27 13:10:51 +000066 printf ("Report bugs to %s.\n", PACKAGE_BUGREPORT);
67
68#ifdef PACKAGE_PACKAGER_BUG_REPORTS
69 printf ("Report %s bugs to: %s\n", PACKAGE_PACKAGER, PACKAGE_PACKAGER_BUG_REPORTS);
70#endif
71#ifdef PACKAGE_URL
72 printf ("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
73#endif
Christian Eglibe149002009-10-09 09:09:07 +000074}
75
Eitan Isaacson109996e2008-12-20 14:52:53 +000076#define BUFSIZE 256
77
John Boyer16689ac2009-01-12 15:11:39 +000078static const TranslationTableHeader *table;
Eitan Isaacson109996e2008-12-20 14:52:53 +000079static char inputBuffer[BUFSIZE];
80
81static int
Eitan Isaacson109996e2008-12-20 14:52:53 +000082getInput (void)
83{
John Boyer16689ac2009-01-12 15:11:39 +000084 int inputLength;
85 inputBuffer[0] = 0;
Christian Egli3741c622016-06-10 15:04:44 +020086 if (!fgets (inputBuffer, sizeof (inputBuffer), stdin))
87 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +000088 inputLength = strlen (inputBuffer) - 1;
89 if (inputLength < 0) /*EOF on script */
Christian Egli3741c622016-06-10 15:04:44 +020090 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +000091 inputBuffer[inputLength] = 0;
92 return inputLength;
Eitan Isaacson109996e2008-12-20 14:52:53 +000093}
94
Christian Egli4b193942016-06-21 17:57:26 +020095static char*
96print_chars(const widechar *buffer, int length) {
97 static uint8_t result_buf[BUFSIZE];
98 size_t result_len = BUFSIZE - 1;
99#ifdef WIDECHARS_ARE_UCS4
Dave Mielke4ebfc2c2017-01-16 06:01:52 -0500100 u32_to_u8(buffer, length, result_buf, &result_len);
Christian Egli4b193942016-06-21 17:57:26 +0200101#else
Dave Mielke4ebfc2c2017-01-16 06:01:52 -0500102 u16_to_u8(buffer, length, result_buf, &result_len);
Christian Egli4b193942016-06-21 17:57:26 +0200103#endif
104 result_buf[result_len] = 0;
105 return result_buf;
106}
107
Eitan Isaacson109996e2008-12-20 14:52:53 +0000108static int
John Boyer16689ac2009-01-12 15:11:39 +0000109printRule (TranslationTableRule * thisRule, int mode)
110{
111 printf ("Rule: ");
112 printf ("opcode=%s, ", findOpcodeName (thisRule->opcode));
113 if (thisRule->before)
114 printf ("before=%x, ", thisRule->before);
115 if (thisRule->after)
116 printf ("after=%x, ", thisRule->after);
117 switch (thisRule->opcode)
118 {
119 case CTO_Context:
120 case CTO_Correct:
121 case CTO_SwapCd:
122 case CTO_SwapDd:
123 case CTO_Pass2:
124 case CTO_Pass3:
125 case CTO_Pass4:
Christian Egli4b193942016-06-21 17:57:26 +0200126 printf ("code=%s ", print_chars(thisRule->charsdots, thisRule->charslen
John Boyer16689ac2009-01-12 15:11:39 +0000127 + thisRule->dotslen));
128 break;
129 default:
130 if (mode == 0)
131 {
Christian Egli4b193942016-06-21 17:57:26 +0200132 printf ("chars=%s, ", print_chars(thisRule->charsdots,
John Boyer16689ac2009-01-12 15:11:39 +0000133 thisRule->charslen));
134 printf ("dots=%s, ",
135 showDots (&thisRule->charsdots[thisRule->charslen],
136 thisRule->dotslen));
137 }
138 else
139 {
140 printf ("dots=%s, ",
141 showDots (&thisRule->charsdots[thisRule->charslen],
142 thisRule->dotslen));
Christian Egli4b193942016-06-21 17:57:26 +0200143 printf ("chars=%s, ", print_chars(thisRule->charsdots,
John Boyer16689ac2009-01-12 15:11:39 +0000144 thisRule->charslen));
145 }
146 break;
147 }
148 return 1;
149}
150
151static int
152printCharacter (TranslationTableCharacter * thisChar, int mode)
153{
154 TranslationTableRule *thisRule;
155 TranslationTableOffset nextRule;
156 if (mode == 0)
157 {
158 printf ("Char: ");
Christian Egli4b193942016-06-21 17:57:26 +0200159 printf ("real=%s, ", print_chars(&thisChar->realchar, 1));
160 printf ("upper=%s, ", print_chars(&thisChar->uppercase, 1));
161 printf ("lower=%s, ", print_chars(&thisChar->lowercase, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000162 }
163 else
164 printf ("Dots: real=%s, ", showDots (&thisChar->realchar, 1));
165 printf ("attr=%s, ", showAttributes (thisChar->attributes));
166 nextRule = thisChar->otherRules;
167 while (nextRule)
168 {
169 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
John Boyerc675d7a2009-01-15 14:32:20 +0000170 if (nextRule == thisChar->definitionRule)
John Boyer16689ac2009-01-12 15:11:39 +0000171 printf ("definition ");
172 printRule (thisRule, mode);
173 printf ("\n");
174 if (mode == 0)
175 nextRule = thisRule->charsnext;
176 else
177 nextRule = thisRule->dotsnext;
178 }
179 return 1;
180}
181
182static int
183show_characters (int startHash)
184{
185 int k;
186 TranslationTableCharacter *thisChar;
187 TranslationTableOffset nextChar;
188 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
189 if (startHash < 0)
190 k = 0;
191 else
192 k = startHash;
193 for (; k < HASHNUM; k++)
194 if (table->characters[k])
195 {
196 printf ("Hash=%d\n", k);
197 nextChar = table->characters[k];
198 while (nextChar)
199 {
200 thisChar =
201 (TranslationTableCharacter *) & table->ruleArea[nextChar];
202 printCharacter (thisChar, 0);
203 printf ("=> ");
204 getInput ();
205 if (*inputBuffer == 'h')
206 break;
207 if (*inputBuffer == 'e')
208 return 1;
209 nextChar = thisChar->next;
210 }
211 }
212 return 1;
213}
214
215static int
216show_dots (int startHash)
217{
218 int k;
219 TranslationTableCharacter *thisDots;
220 TranslationTableOffset nextDots;
221 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
222 if (startHash < 0)
223 k = 0;
224 else
225 k = startHash;
226 for (; k < HASHNUM; k++)
227 if (table->dots[k])
228 {
229 printf ("Hash=%d\n", k);
230 nextDots = table->dots[k];
231 while (nextDots)
232 {
233 thisDots =
234 (TranslationTableCharacter *) & table->ruleArea[nextDots];
235 printCharacter (thisDots, 1);
236 printf ("=> ");
237 getInput ();
238 if (*inputBuffer == 'h')
239 break;
240 if (*inputBuffer == 'e')
241 return 1;
242 nextDots = thisDots->next;
243 }
244 }
245 return 1;
246}
247
248static int
249show_forRules (int startHash)
250{
251 int k;
252 TranslationTableRule *thisRule;
253 TranslationTableOffset nextRule;
254 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
255 if (startHash < 0)
256 k = 0;
257 else
258 k = startHash;
259 for (; k < HASHNUM; k++)
260 if (table->forRules[k])
261 {
262 printf ("Hash=%d\n", k);
263 nextRule = table->forRules[k];
264 while (nextRule)
265 {
266 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
267 printRule (thisRule, 0);
268 printf ("=> ");
269 getInput ();
270 if (*inputBuffer == 'h')
271 break;
272 if (*inputBuffer == 'e')
273 return 1;
274 nextRule = thisRule->charsnext;
275 }
276 }
277 return 1;
278}
279
280static int
281show_backRules (int startHash)
282{
283 int k;
284 TranslationTableRule *thisRule;
285 TranslationTableOffset nextRule;
286 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
287 if (startHash < 0)
288 k = 0;
289 else
290 k = startHash;
291 for (; k < HASHNUM; k++)
292 if (table->backRules[k])
293 {
294 printf ("Hash=%d\n", k);
295 nextRule = table->backRules[k];
296 while (nextRule)
297 {
298 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
299 printRule (thisRule, 1);
300 printf ("=> ");
301 getInput ();
302 if (*inputBuffer == 'h')
303 break;
304 if (*inputBuffer == 'e')
305 return 1;
306 nextRule = thisRule->dotsnext;
307 }
308 }
309 return 1;
310}
311
312static int
313print_brailleIndicator (TranslationTableOffset offset, char *opcode)
314{
315 TranslationTableRule *thisRule;
316 if (!offset)
317 return 0;
318 thisRule = (TranslationTableRule *) & table->ruleArea[offset];
319 printf ("%s %s\n", opcode,
320 showDots (&thisRule->charsdots[0], thisRule->dotslen));
321 return 1;
322}
323
324static int
325print_phraseLength (TranslationTableOffset offset, char *opcode)
326{
327 if (!offset)
328 return 0;
329 printf ("%s %d\n", opcode, offset);
Christian Eglifbfea8b2009-08-11 11:24:40 +0000330 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000331}
332
333static int
334show_brailleIndicators (void)
335{
Christian Eglif1da9822016-06-10 15:03:34 +0200336 char name[BUFSIZE];
337 char *emphNames[] = {"begemphphrase %s",
338 "endemphphrase %s before",
339 "endemphphrase %s after",
340 "begemphword %s",
341 "endemphword %s",
342 "emphletter %s",
343 "begemph %s",
344 "endemph %s",
345 NULL};
346 char *capsNames[] = {"firstwordcaps",
347 "lastwordcapsbefore",
348 "lastwordcapsafter",
349 "begcaps",
350 "endcaps",
351 "capsletter",
352 "capsword",
353 "capswordstop",
354 NULL};
355
Davy Kager68004042016-01-26 12:50:22 +0100356 // FIXME: update to include all UEB opcodes.
Christian Eglif1da9822016-06-10 15:03:34 +0200357
358 for (EmphCodeOffset offset = 0; capsNames[offset]; offset++) {
359 print_brailleIndicator (table->emphRules[capsRule][offset],capsNames[offset]);
360 }
Davy Kagerb3ff4542016-02-15 11:03:02 +0100361 print_phraseLength (table->emphRules[capsRule][lenPhraseOffset], "lencapsphrase");
John Boyer16689ac2009-01-12 15:11:39 +0000362 print_brailleIndicator (table->letterSign, "letsign");
363 print_brailleIndicator (table->numberSign, "numsign");
Christian Eglif1da9822016-06-10 15:03:34 +0200364
365 for (int i = 0; table->emphClasses[i]; i++) {
366 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
367 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
368 print_brailleIndicator (table->emphRules[emph1Rule][offset], name);
369 }
370 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
371 print_phraseLength (table->emphRules[emph1Rule][lenPhraseOffset], name);
372 }
John Boyer16689ac2009-01-12 15:11:39 +0000373 print_brailleIndicator (table->begComp, "begcomp");
374 print_brailleIndicator (table->compBegEmph1, "compbegemph1");
375 print_brailleIndicator (table->compEndEmph1, "compendemph1");
376 print_brailleIndicator (table->compBegEmph2, "compbegemph2");
377 print_brailleIndicator (table->compEndEmph2, "compendemph2");
378 print_brailleIndicator (table->compBegEmph3, "compbegemph3");
379 print_brailleIndicator (table->compEndEmph3, "compendemph3");
380 print_brailleIndicator (table->compCapSign, "compcapsign");
381 print_brailleIndicator (table->compBegCaps, "compbegcaps");
382 print_brailleIndicator (table->compEndCaps, "compendcaps");
383 print_brailleIndicator (table->endComp, "endcomp");
384 return 1;
385}
386
387static char *
388pickYN (int a)
389{
390 if (!a)
391 return "no";
392 return "yes";
393}
394
395static int
396show_misc (void)
397{
398 printf ("Table size: %d\n", table->tableSize);
399 printf ("Bytes used: %d\n", table->bytesUsed);
400 printf ("Number of passes: %d\n", table->numPasses);
Christian Egli5e8c3892009-01-15 16:30:59 +0000401 printf ("'correct' opcodes: %s\n", pickYN (table->corrections));
John Boyer16689ac2009-01-12 15:11:39 +0000402 printf ("'syllable' opcodes: %s\n", pickYN (table->syllables));
403 printf ("'capsnocont' opcode: %s\n", pickYN (table->capsNoCont));
404 printf ("Hyphenation table: %s\n", pickYN (table->hyphenStatesArray));
Christian Egli4b193942016-06-21 17:57:26 +0200405 printf ("noletsignbefore %s\n", print_chars(&table->noLetsignBefore[0],
John Boyer16689ac2009-01-12 15:11:39 +0000406 table->noLetsignBeforeCount));
Christian Egli4b193942016-06-21 17:57:26 +0200407 printf ("noletsign %s\n", print_chars(&table->noLetsign[0],
John Boyer16689ac2009-01-12 15:11:39 +0000408 table->noLetsignCount));
Christian Egli4b193942016-06-21 17:57:26 +0200409 printf ("noletsignafter %s\n", print_chars(&table->noLetsignAfter[0],
John Boyer16689ac2009-01-12 15:11:39 +0000410 table->noLetsignAfterCount));
Christian Eglifbfea8b2009-08-11 11:24:40 +0000411 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000412}
413
414static int
415show_charMap (int startHash)
416{
417 int k;
418 CharOrDots *thisChar;
419 TranslationTableOffset nextChar;
420 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
421 if (startHash < 0)
422 k = 0;
423 else
424 k = startHash;
425 for (; k < HASHNUM; k++)
426 if (table->charToDots[k])
427 {
428 printf ("Hash=%d\n", k);
429 nextChar = table->charToDots[k];
430 while (nextChar)
431 {
432 thisChar = (CharOrDots *) & table->ruleArea[nextChar];
Christian Egli4b193942016-06-21 17:57:26 +0200433 printf ("Char: %s ", print_chars(&thisChar->lookFor, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000434 printf ("dots=%s\n", showDots (&thisChar->found, 1));
435 printf ("=> ");
436 getInput ();
437 if (*inputBuffer == 'h')
438 break;
439 if (*inputBuffer == 'e')
440 return 1;
441 nextChar = thisChar->next;
442 }
443 }
444 return 1;
445}
446
447static int
448show_dotsMap (int startHash)
449{
450 int k;
451 CharOrDots *thisDots;
452 TranslationTableOffset nextDots;
453 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
454 if (startHash < 0)
455 k = 0;
456 else
457 k = startHash;
458 for (; k < HASHNUM; k++)
459 if (table->dotsToChar[k])
460 {
461 printf ("Hash=%d\n", k);
462 nextDots = table->dotsToChar[k];
463 while (nextDots)
464 {
465 thisDots = (CharOrDots *) & table->ruleArea[nextDots];
466 printf ("Dots: %s ", showDots (&thisDots->lookFor, 1));
Christian Egli4b193942016-06-21 17:57:26 +0200467 printf ("char=%s\n", print_chars(&thisDots->found, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000468 printf ("=> ");
469 getInput ();
470 if (*inputBuffer == 'h')
471 break;
472 if (*inputBuffer == 'e')
473 return 1;
474 nextDots = thisDots->next;
475 }
476 }
477 return 1;
478}
479
480static int
481show_compDots (int startChar)
482{
483 widechar k;
484 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
485 if (startChar < 0)
486 k = 0;
487 else
488 k = startChar;
489 for (; k < 256; k++)
490 if (table->compdotsPattern[k])
491 {
492 TranslationTableRule *thisRule = (TranslationTableRule *)
493 & table->ruleArea[table->compdotsPattern[k]];
Christian Egli4b193942016-06-21 17:57:26 +0200494 printf ("Char: %s ", print_chars(&k, 1));
John Boyer16689ac2009-01-12 15:11:39 +0000495 printf ("dots=%s\n",
496 showDots (&thisRule->charsdots[1], thisRule->dotslen));
497 printf ("=> ");
498 getInput ();
499 if (*inputBuffer == 'e')
500 return 1;
501 }
502 return 1;
503}
504
505static void
506part_paramLetters ()
507{
508 printf ("show particular hash chains.\n");
509 printf
510 ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
511 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
512 printf ("(z)-compdots, (h)elp, e(x)it\n");
513}
514
515static void
516particularHelp (void)
517{
518 part_paramLetters ();
519}
520
521static int
522particular (void)
523{
524 int startHash;
525 widechar parsed[BUFSIZE];
526 part_paramLetters ();
527 do
528 {
529 printf ("particular: ");
530 getInput ();
531 switch (inputBuffer[0])
532 {
533 case 0:
534 break;
535 case 'h':
536 particularHelp ();
537 break;
538 case 'c':
539 printf ("-> ");
540 getInput ();
541 if (!extParseChars (inputBuffer, parsed))
542 break;
543 startHash = charHash (*parsed);
544 if (table->characters[startHash] == 0)
545 {
546 printf ("Character not in table.\n");
547 break;
548 }
549 show_characters (startHash);
550 break;
551 case 'd':
552 printf ("-> ");
553 getInput ();
554 if (!extParseDots (inputBuffer, parsed))
555 break;
556 startHash = charHash (*parsed);
557 if (table->dots[startHash] == 0)
558 {
559 printf ("Dot pattern not in table.\n");
560 break;
561 }
562 show_dots (startHash);
563 break;
564 case 'C':
565 printf ("-> ");
566 getInput ();
567 if (!extParseChars (inputBuffer, parsed))
568 break;
569 startHash = charHash (*parsed);
570 if (table->charToDots[startHash] == 0)
571 {
572 printf ("Character not in table.\n");
573 break;
574 }
575 show_charMap (startHash);
576 break;
577 case 'D':
578 printf ("-> ");
579 getInput ();
580 if (!extParseDots (inputBuffer, parsed))
581 break;
582 startHash = charHash (*parsed);
583 if (table->dotsToChar[startHash] == 0)
584 {
585 printf ("Dot pattern not in table.\n");
586 break;
587 }
588 show_dotsMap (startHash);
589 break;
590 case 'f':
591 printf ("-> ");
592 getInput ();
593 if (!extParseChars (inputBuffer, parsed))
594 break;
595 startHash = stringHash (parsed);
596 if (table->forRules[startHash] == 0)
597 {
598 printf ("Character string not in table.\n");
599 break;
600 }
601 show_forRules (startHash);
602 break;
603 case 'b':
604 printf ("-> ");
605 getInput ();
606 if (!extParseDots (inputBuffer, parsed))
607 break;
608 startHash = stringHash (parsed);
609 if (table->backRules[startHash] == 0)
610 {
611 printf ("Dot pattern not in table.\n");
612 break;
613 }
614 show_backRules (startHash);
615 break;
616 case 'z':
617 printf ("-> ");
618 getInput ();
619 if (!extParseChars (inputBuffer, parsed))
620 break;
621 startHash = charHash (*parsed);
622 if (*parsed > 255 || table->compdotsPattern[startHash] == 0)
623 {
624 printf ("Character not in table.\n");
625 break;
626 }
627 show_compDots (startHash);
628 break;
629 case 'x':
630 return 1;
631 default:
632 printf ("Bad choice.\n");
633 break;
634 }
635 }
636 while (inputBuffer[0] != 'x');
637 return 1;
638}
639
Eitan Isaacson109996e2008-12-20 14:52:53 +0000640static void
641paramLetters (void)
642{
John Boyer16689ac2009-01-12 15:11:39 +0000643 printf ("Press one of the letters in parentheses, then enter.\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200644 printf ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
John Boyer16689ac2009-01-12 15:11:39 +0000645 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
646 printf ("show-(m)isc, show-(z)-compdots\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200647 printf ("show-braille(i)ndicators, show-(p)articulars\n");
648 printf ("(h)elp, (q)uit\n");
John Boyer16689ac2009-01-12 15:11:39 +0000649}
650
651static void
652commandHelp (void)
653{
654 paramLetters ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000655}
656
657static int
658getCommands (void)
659{
660 paramLetters ();
661 do
662 {
663 printf ("Command: ");
664 getInput ();
665 switch (inputBuffer[0])
666 {
667 case 0:
668 break;
John Boyer16689ac2009-01-12 15:11:39 +0000669 case 'h':
670 commandHelp ();
671 break;
672 case 'C':
673 show_charMap (-1);
674 break;
675 case 'D':
676 show_dotsMap (-1);
677 break;
678 case 'z':
679 show_compDots (-1);
680 break;
681 case 'c':
682 show_characters (-1);
683 break;
684 case 'd':
685 show_dots (-1);
686 break;
687 case 'f':
688 show_forRules (-1);
689 break;
690 case 'b':
691 show_backRules (-1);
692 break;
693 case 'i':
694 show_brailleIndicators ();
695 break;
696 case 'm':
697 show_misc ();
698 break;
699 case 'p':
700 particular ();
701 break;
702 case 'q':
703 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000704 default:
705 printf ("Bad choice.\n");
706 break;
707 }
708 }
John Boyer16689ac2009-01-12 15:11:39 +0000709 while (inputBuffer[0] != 'q');
Eitan Isaacson109996e2008-12-20 14:52:53 +0000710 return 1;
711}
712
713int
714main (int argc, char **argv)
715{
Christian Eglibe149002009-10-09 09:09:07 +0000716 int optc;
717
718 set_program_name (argv[0]);
719
720 while ((optc = getopt_long (argc, argv, "hv", longopts, NULL)) != -1)
721 switch (optc)
722 {
723 /* --help and --version exit immediately, per GNU coding standards. */
724 case 'v':
725 version_etc (stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *) NULL);
726 exit (EXIT_SUCCESS);
727 break;
728 case 'h':
729 print_help ();
730 exit (EXIT_SUCCESS);
731 break;
732 default:
733 fprintf (stderr, "Try `%s --help' for more information.\n",
734 program_name);
735 exit (EXIT_FAILURE);
736 break;
737 }
738
739 if (optind != argc - 1)
Eitan Isaacson109996e2008-12-20 14:52:53 +0000740 {
Christian Eglibe149002009-10-09 09:09:07 +0000741 /* Print error message and exit. */
742 if (optind < argc - 1)
743 fprintf (stderr, "%s: extra operand: %s\n",
744 program_name, argv[optind + 1]);
745 else
746 fprintf (stderr, "%s: no table specified\n",
747 program_name);
748 fprintf (stderr, "Try `%s --help' for more information.\n",
749 program_name);
750 exit (EXIT_FAILURE);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000751 }
Christian Eglibe149002009-10-09 09:09:07 +0000752
753 if (!(table = lou_getTable (argv[optind])))
John Boyer16689ac2009-01-12 15:11:39 +0000754 {
755 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000756 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +0000757 }
758 getCommands ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000759 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000760 exit (EXIT_SUCCESS);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000761}