blob: 00aa8a860ff51ea68b21521af221c16028ef59ae [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.
Bert Frees92a80352017-09-30 23:01:02 +020014
Christian Egli08d96a72009-10-08 08:49:13 +000015 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.
Bert Frees92a80352017-09-30 23:01:02 +020019
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
Bert Frees92a80352017-09-30 23:01:02 +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
Bert Frees92a80352017-09-30 23:01:02 +020034static const struct option longopts[] = {
Christian Egli585c6762019-06-05 15:19:10 +020035 { "help", no_argument, NULL, 'h' },
36 { "version", no_argument, NULL, 'v' },
Bert Frees92a80352017-09-30 23:01:02 +020037 { NULL, 0, NULL, 0 },
Christian Eglibe149002009-10-09 09:09:07 +000038};
39
40const char version_etc_copyright[] =
Bert Frees92a80352017-09-30 23:01:02 +020041 "Copyright %s %d ViewPlus Technologies, Inc. and JJB Software, Inc.";
Christian Eglibe149002009-10-09 09:09:07 +000042
43#define AUTHORS "John J. Boyer"
44
45static void
Bert Frees92a80352017-09-30 23:01:02 +020046print_help(void) {
47 printf("\
48Usage: %s [OPTIONS] TABLE[,TABLE,...]\n",
49 program_name);
50
51 fputs("\
Christian Eglibe149002009-10-09 09:09:07 +000052Examine and debug Braille translation tables. This program allows you\n\
53to inspect liblouis translation tables and gather information about\n\
54them, such as forward and backward rules, characters and dot patterns,\n\
55specific opcodes, the size of a table, whether a hyphenation\n\
56table is used, how many passes the translation takes and much\n\
Bert Frees92a80352017-09-30 23:01:02 +020057more.\n\n",
58 stdout);
Christian Eglibe149002009-10-09 09:09:07 +000059
Bert Frees92a80352017-09-30 23:01:02 +020060 fputs("\
Christian Eglibe149002009-10-09 09:09:07 +000061 -h, --help display this help and exit\n\
Bert Frees92a80352017-09-30 23:01:02 +020062 -v, --version display version information and exit\n",
63 stdout);
Christian Eglibe149002009-10-09 09:09:07 +000064
Bert Frees92a80352017-09-30 23:01:02 +020065 printf("\n");
66 printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);
Christian Eglidc50af92012-09-27 13:10:51 +000067
68#ifdef PACKAGE_PACKAGER_BUG_REPORTS
Bert Frees92a80352017-09-30 23:01:02 +020069 printf("Report %s bugs to: %s\n", PACKAGE_PACKAGER, PACKAGE_PACKAGER_BUG_REPORTS);
Christian Eglidc50af92012-09-27 13:10:51 +000070#endif
71#ifdef PACKAGE_URL
Bert Frees92a80352017-09-30 23:01:02 +020072 printf("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL);
Christian Eglidc50af92012-09-27 13:10:51 +000073#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;
Bert Freesc3223682019-07-09 23:18:43 +020079static const DisplayTableHeader *displayTable;
Eitan Isaacson109996e2008-12-20 14:52:53 +000080static char inputBuffer[BUFSIZE];
81
82static int
Bert Frees92a80352017-09-30 23:01:02 +020083getInput(void) {
84 int inputLength;
85 inputBuffer[0] = 0;
86 if (!fgets(inputBuffer, sizeof(inputBuffer), stdin)) exit(EXIT_FAILURE);
87 inputLength = strlen(inputBuffer) - 1;
88 if (inputLength < 0) /* EOF on script */
89 exit(EXIT_FAILURE);
90 inputBuffer[inputLength] = 0;
91 return inputLength;
John Boyer16689ac2009-01-12 15:11:39 +000092}
93
94static char *
Bert Frees92a80352017-09-30 23:01:02 +020095print_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
99 u32_to_u8(buffer, length, result_buf, &result_len);
100#else
101 u16_to_u8(buffer, length, result_buf, &result_len);
102#endif
103 result_buf[result_len] = 0;
104 return result_buf;
John Boyer16689ac2009-01-12 15:11:39 +0000105}
106
107static int
Bert Frees92a80352017-09-30 23:01:02 +0200108printRule(TranslationTableRule *thisRule, int mode) {
109 printf("Rule: ");
110 printf("opcode=%s, ", _lou_findOpcodeName(thisRule->opcode));
111 if (thisRule->before) printf("before=%x, ", thisRule->before);
112 if (thisRule->after) printf("after=%x, ", thisRule->after);
113 switch (thisRule->opcode) {
114 case CTO_Context:
115 case CTO_Correct:
116 case CTO_SwapCd:
117 case CTO_SwapDd:
118 case CTO_Pass2:
119 case CTO_Pass3:
120 case CTO_Pass4:
121 printf("code=%s ",
122 print_chars(thisRule->charsdots, thisRule->charslen + thisRule->dotslen));
123 break;
John Boyer16689ac2009-01-12 15:11:39 +0000124 default:
Bert Frees92a80352017-09-30 23:01:02 +0200125 if (mode == 0) {
126 printf("chars=%s, ", print_chars(thisRule->charsdots, thisRule->charslen));
Christian Egli585c6762019-06-05 15:19:10 +0200127 printf("dots=%s, ",
128 _lou_showDots(
129 &thisRule->charsdots[thisRule->charslen], thisRule->dotslen));
Bert Frees92a80352017-09-30 23:01:02 +0200130 } else {
Christian Egli585c6762019-06-05 15:19:10 +0200131 printf("dots=%s, ",
132 _lou_showDots(
133 &thisRule->charsdots[thisRule->charslen], thisRule->dotslen));
Bert Frees92a80352017-09-30 23:01:02 +0200134 printf("chars=%s, ", print_chars(thisRule->charsdots, thisRule->charslen));
135 }
136 break;
John Boyer16689ac2009-01-12 15:11:39 +0000137 }
Bert Frees92a80352017-09-30 23:01:02 +0200138 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000139}
140
141static int
Bert Frees92a80352017-09-30 23:01:02 +0200142printCharacter(TranslationTableCharacter *thisChar, int mode) {
143 TranslationTableRule *thisRule;
144 TranslationTableOffset nextRule;
145 if (mode == 0) {
146 printf("Char: ");
147 printf("real=%s, ", print_chars(&thisChar->realchar, 1));
148 printf("upper=%s, ", print_chars(&thisChar->uppercase, 1));
149 printf("lower=%s, ", print_chars(&thisChar->lowercase, 1));
150 } else
151 printf("Dots: real=%s, ", _lou_showDots(&thisChar->realchar, 1));
152 printf("attr=%s, ", _lou_showAttributes(thisChar->attributes));
153 nextRule = thisChar->otherRules;
154 while (nextRule) {
155 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
156 if (nextRule == thisChar->definitionRule) printf("definition ");
157 printRule(thisRule, mode);
158 printf("\n");
159 if (mode == 0)
160 nextRule = thisRule->charsnext;
161 else
162 nextRule = thisRule->dotsnext;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000163 }
Bert Frees1171cf82021-07-24 12:27:08 +0200164 if (mode == 0 && thisChar->compRule) {
165 TranslationTableRule *compRule =
166 (TranslationTableRule *)&table->ruleArea[thisChar->compRule];
167 printf("comp6 ");
168 printRule(compRule, 0);
169 printf("\n");
170 }
Bert Frees92a80352017-09-30 23:01:02 +0200171 return 1;
172}
173
174static int
175show_characters(int startHash) {
176 int k;
177 TranslationTableCharacter *thisChar;
178 TranslationTableOffset nextChar;
179 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
180 if (startHash < 0)
181 k = 0;
182 else
183 k = startHash;
184 for (; k < HASHNUM; k++)
185 if (table->characters[k]) {
186 printf("Hash=%d\n", k);
187 nextChar = table->characters[k];
188 while (nextChar) {
189 thisChar = (TranslationTableCharacter *)&table->ruleArea[nextChar];
190 printCharacter(thisChar, 0);
191 printf("=> ");
192 getInput();
193 if (*inputBuffer == 'h') break;
194 if (*inputBuffer == 'e') return 1;
195 nextChar = thisChar->next;
196 }
197 }
198 return 1;
199}
200
201static int
202show_dots(int startHash) {
203 int k;
204 TranslationTableCharacter *thisDots;
205 TranslationTableOffset nextDots;
206 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
207 if (startHash < 0)
208 k = 0;
209 else
210 k = startHash;
211 for (; k < HASHNUM; k++)
212 if (table->dots[k]) {
213 printf("Hash=%d\n", k);
214 nextDots = table->dots[k];
215 while (nextDots) {
216 thisDots = (TranslationTableCharacter *)&table->ruleArea[nextDots];
217 printCharacter(thisDots, 1);
218 printf("=> ");
219 getInput();
220 if (*inputBuffer == 'h') break;
221 if (*inputBuffer == 'e') return 1;
222 nextDots = thisDots->next;
223 }
224 }
225 return 1;
226}
227
228static int
229show_forRules(int startHash) {
230 int k;
231 TranslationTableRule *thisRule;
232 TranslationTableOffset nextRule;
233 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
234 if (startHash < 0)
235 k = 0;
236 else
237 k = startHash;
238 for (; k < HASHNUM; k++)
239 if (table->forRules[k]) {
240 printf("Hash=%d\n", k);
241 nextRule = table->forRules[k];
242 while (nextRule) {
243 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
244 printRule(thisRule, 0);
245 printf("=> ");
246 getInput();
247 if (*inputBuffer == 'h') break;
248 if (*inputBuffer == 'e') return 1;
249 nextRule = thisRule->charsnext;
250 }
251 }
252 return 1;
253}
254
255static int
256show_backRules(int startHash) {
257 int k;
258 TranslationTableRule *thisRule;
259 TranslationTableOffset nextRule;
260 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
261 if (startHash < 0)
262 k = 0;
263 else
264 k = startHash;
265 for (; k < HASHNUM; k++)
266 if (table->backRules[k]) {
267 printf("Hash=%d\n", k);
268 nextRule = table->backRules[k];
269 while (nextRule) {
270 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
271 printRule(thisRule, 1);
272 printf("=> ");
273 getInput();
274 if (*inputBuffer == 'h') break;
275 if (*inputBuffer == 'e') return 1;
276 nextRule = thisRule->dotsnext;
277 }
278 }
279 return 1;
280}
281
282static int
Christian Egli0cfcd192018-05-08 11:22:46 +0200283print_brailleIndicator(TranslationTableOffset offset, const char *opcode) {
Bert Frees92a80352017-09-30 23:01:02 +0200284 TranslationTableRule *thisRule;
285 if (!offset) return 0;
286 thisRule = (TranslationTableRule *)&table->ruleArea[offset];
287 printf("%s %s\n", opcode, _lou_showDots(&thisRule->charsdots[0], thisRule->dotslen));
288 return 1;
289}
290
291static int
Christian Egli0cfcd192018-05-08 11:22:46 +0200292print_phraseLength(TranslationTableOffset offset, const char *opcode) {
Bert Frees92a80352017-09-30 23:01:02 +0200293 if (!offset) return 0;
Christian Eglida0d2eb2018-05-07 13:41:57 +0200294 printf("%s %u\n", opcode, offset);
Bert Frees92a80352017-09-30 23:01:02 +0200295 return 1;
296}
297
298static int
299show_brailleIndicators(void) {
300 char name[BUFSIZE];
Christian Egli0cfcd192018-05-08 11:22:46 +0200301 const char *emphNames[] = { "begemphphrase %s", "endemphphrase %s before",
Bert Frees92a80352017-09-30 23:01:02 +0200302 "endemphphrase %s after", "begemphword %s", "endemphword %s", "emphletter %s",
303 "begemph %s", "endemph %s", NULL };
Christian Eglid92cec12018-05-08 11:51:17 +0200304 const char *capsNames[] = { "firstwordcaps", "lastwordcapsbefore",
305 "lastwordcapsafter", "begcaps", "endcaps", "capsletter", "capsword",
306 "capswordstop", NULL };
Bert Frees92a80352017-09-30 23:01:02 +0200307
308 // FIXME: update to include all UEB opcodes.
309
310 for (EmphCodeOffset offset = 0; capsNames[offset]; offset++) {
311 print_brailleIndicator(table->emphRules[capsRule][offset], capsNames[offset]);
312 }
313 print_phraseLength(table->emphRules[capsRule][lenPhraseOffset], "lencapsphrase");
314 print_brailleIndicator(table->letterSign, "letsign");
315 print_brailleIndicator(table->numberSign, "numsign");
316
317 for (int i = 0; table->emphClasses[i]; i++) {
318 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
319 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
320 print_brailleIndicator(table->emphRules[emph1Rule][offset], name);
321 }
322 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
323 print_phraseLength(table->emphRules[emph1Rule][lenPhraseOffset], name);
324 }
325 print_brailleIndicator(table->begComp, "begcomp");
Bert Frees92a80352017-09-30 23:01:02 +0200326 print_brailleIndicator(table->endComp, "endcomp");
327 return 1;
328}
329
Christian Egli0cfcd192018-05-08 11:22:46 +0200330static const char *
Bert Frees92a80352017-09-30 23:01:02 +0200331pickYN(int a) {
332 if (!a) return "no";
333 return "yes";
334}
335
336static int
337show_misc(void) {
Christian Eglida0d2eb2018-05-07 13:41:57 +0200338 printf("Table size: %u\n", table->tableSize);
339 printf("Bytes used: %u\n", table->bytesUsed);
Bert Frees92a80352017-09-30 23:01:02 +0200340 printf("Number of passes: %d\n", table->numPasses);
341 printf("'correct' opcodes: %s\n", pickYN(table->corrections));
342 printf("'syllable' opcodes: %s\n", pickYN(table->syllables));
343 printf("'capsnocont' opcode: %s\n", pickYN(table->capsNoCont));
344 printf("Hyphenation table: %s\n", pickYN(table->hyphenStatesArray));
345 printf("noletsignbefore %s\n",
346 print_chars(&table->noLetsignBefore[0], table->noLetsignBeforeCount));
347 printf("noletsign %s\n", print_chars(&table->noLetsign[0], table->noLetsignCount));
348 printf("noletsignafter %s\n",
349 print_chars(&table->noLetsignAfter[0], table->noLetsignAfterCount));
350 return 1;
351}
352
353static int
354show_charMap(int startHash) {
355 int k;
Bert Freesb2b67422020-03-08 22:31:58 +0100356 CharDotsMapping *thisChar;
Bert Frees92a80352017-09-30 23:01:02 +0200357 TranslationTableOffset nextChar;
358 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
359 if (startHash < 0)
360 k = 0;
361 else
362 k = startHash;
363 for (; k < HASHNUM; k++)
Bert Freesc3223682019-07-09 23:18:43 +0200364 if (displayTable->charToDots[k]) {
Bert Frees92a80352017-09-30 23:01:02 +0200365 printf("Hash=%d\n", k);
Bert Freesc3223682019-07-09 23:18:43 +0200366 nextChar = displayTable->charToDots[k];
Bert Frees92a80352017-09-30 23:01:02 +0200367 while (nextChar) {
Bert Freesb2b67422020-03-08 22:31:58 +0100368 thisChar = (CharDotsMapping *)&displayTable->ruleArea[nextChar];
Bert Frees92a80352017-09-30 23:01:02 +0200369 printf("Char: %s ", print_chars(&thisChar->lookFor, 1));
370 printf("dots=%s\n", _lou_showDots(&thisChar->found, 1));
371 printf("=> ");
372 getInput();
373 if (*inputBuffer == 'h') break;
374 if (*inputBuffer == 'e') return 1;
375 nextChar = thisChar->next;
376 }
377 }
378 return 1;
379}
380
381static int
382show_dotsMap(int startHash) {
383 int k;
Bert Freesb2b67422020-03-08 22:31:58 +0100384 CharDotsMapping *thisDots;
Bert Frees92a80352017-09-30 23:01:02 +0200385 TranslationTableOffset nextDots;
386 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
387 if (startHash < 0)
388 k = 0;
389 else
390 k = startHash;
391 for (; k < HASHNUM; k++)
Bert Freesc3223682019-07-09 23:18:43 +0200392 if (displayTable->dotsToChar[k]) {
Bert Frees92a80352017-09-30 23:01:02 +0200393 printf("Hash=%d\n", k);
Bert Freesc3223682019-07-09 23:18:43 +0200394 nextDots = displayTable->dotsToChar[k];
Bert Frees92a80352017-09-30 23:01:02 +0200395 while (nextDots) {
Bert Freesb2b67422020-03-08 22:31:58 +0100396 thisDots = (CharDotsMapping *)&displayTable->ruleArea[nextDots];
Bert Frees92a80352017-09-30 23:01:02 +0200397 printf("Dots: %s ", _lou_showDots(&thisDots->lookFor, 1));
398 printf("char=%s\n", print_chars(&thisDots->found, 1));
399 printf("=> ");
400 getInput();
401 if (*inputBuffer == 'h') break;
402 if (*inputBuffer == 'e') return 1;
403 nextDots = thisDots->next;
404 }
405 }
406 return 1;
407}
408
Bert Frees92a80352017-09-30 23:01:02 +0200409static void
410part_paramLetters(void) {
411 printf("show particular hash chains.\n");
412 printf("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
413 printf("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
Bert Frees1171cf82021-07-24 12:27:08 +0200414 printf("(h)elp, e(x)it\n");
Bert Frees92a80352017-09-30 23:01:02 +0200415}
416
417static void
418particularHelp(void) {
419 part_paramLetters();
420}
421
422static int
423particular(void) {
424 int startHash;
425 widechar parsed[BUFSIZE];
426 part_paramLetters();
427 do {
428 printf("particular: ");
429 getInput();
430 switch (inputBuffer[0]) {
431 case 0:
432 break;
433 case 'h':
434 particularHelp();
435 break;
436 case 'c':
437 printf("-> ");
438 getInput();
439 if (!_lou_extParseChars(inputBuffer, parsed)) break;
440 startHash = _lou_charHash(*parsed);
441 if (table->characters[startHash] == 0) {
442 printf("Character not in table.\n");
443 break;
444 }
445 show_characters(startHash);
446 break;
447 case 'd':
448 printf("-> ");
449 getInput();
450 if (!_lou_extParseDots(inputBuffer, parsed)) break;
451 startHash = _lou_charHash(*parsed);
452 if (table->dots[startHash] == 0) {
453 printf("Dot pattern not in table.\n");
454 break;
455 }
456 show_dots(startHash);
457 break;
458 case 'C':
459 printf("-> ");
460 getInput();
461 if (!_lou_extParseChars(inputBuffer, parsed)) break;
462 startHash = _lou_charHash(*parsed);
Bert Freesc3223682019-07-09 23:18:43 +0200463 if (displayTable->charToDots[startHash] == 0) {
Bert Frees92a80352017-09-30 23:01:02 +0200464 printf("Character not in table.\n");
465 break;
466 }
467 show_charMap(startHash);
468 break;
469 case 'D':
470 printf("-> ");
471 getInput();
472 if (!_lou_extParseDots(inputBuffer, parsed)) break;
473 startHash = _lou_charHash(*parsed);
Bert Freesc3223682019-07-09 23:18:43 +0200474 if (displayTable->dotsToChar[startHash] == 0) {
Bert Frees92a80352017-09-30 23:01:02 +0200475 printf("Dot pattern not in table.\n");
476 break;
477 }
478 show_dotsMap(startHash);
479 break;
480 case 'f':
481 printf("-> ");
482 getInput();
483 if (!_lou_extParseChars(inputBuffer, parsed)) break;
Bert Freesd4b7a8e2019-06-04 13:56:07 +0200484 startHash = _lou_stringHash(parsed, 0, NULL);
Bert Frees92a80352017-09-30 23:01:02 +0200485 if (table->forRules[startHash] == 0) {
486 printf("Character string not in table.\n");
487 break;
488 }
489 show_forRules(startHash);
490 break;
491 case 'b':
492 printf("-> ");
493 getInput();
494 if (!_lou_extParseDots(inputBuffer, parsed)) break;
Bert Freesd4b7a8e2019-06-04 13:56:07 +0200495 startHash = _lou_stringHash(parsed, 0, NULL);
Bert Frees92a80352017-09-30 23:01:02 +0200496 if (table->backRules[startHash] == 0) {
497 printf("Dot pattern not in table.\n");
498 break;
499 }
500 show_backRules(startHash);
501 break;
Bert Frees92a80352017-09-30 23:01:02 +0200502 case 'x':
503 return 1;
504 default:
505 printf("Bad choice.\n");
506 break;
507 }
508 } while (inputBuffer[0] != 'x');
509 return 1;
510}
511
512static void
513paramLetters(void) {
514 printf("Press one of the letters in parentheses, then enter.\n");
515 printf("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
516 printf("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
Bert Frees1171cf82021-07-24 12:27:08 +0200517 printf("show-(m)isc, show-braille(i)ndicators, show-(p)articulars\n");
Bert Frees92a80352017-09-30 23:01:02 +0200518 printf("(h)elp, (q)uit\n");
519}
520
521static void
522commandHelp(void) {
523 paramLetters();
524}
525
526static int
527getCommands(void) {
528 paramLetters();
529 do {
530 printf("Command: ");
531 getInput();
532 switch (inputBuffer[0]) {
533 case 0:
534 break;
535 case 'h':
536 commandHelp();
537 break;
538 case 'C':
539 show_charMap(-1);
540 break;
541 case 'D':
542 show_dotsMap(-1);
543 break;
Bert Frees92a80352017-09-30 23:01:02 +0200544 case 'c':
545 show_characters(-1);
546 break;
547 case 'd':
548 show_dots(-1);
549 break;
550 case 'f':
551 show_forRules(-1);
552 break;
553 case 'b':
554 show_backRules(-1);
555 break;
556 case 'i':
557 show_brailleIndicators();
558 break;
559 case 'm':
560 show_misc();
561 break;
562 case 'p':
563 particular();
564 break;
565 case 'q':
566 return 1;
567 default:
568 printf("Bad choice.\n");
569 break;
570 }
571 } while (inputBuffer[0] != 'q');
572 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000573}
574
575int
Bert Frees92a80352017-09-30 23:01:02 +0200576main(int argc, char **argv) {
577 int optc;
Christian Eglibe149002009-10-09 09:09:07 +0000578
Bert Frees92a80352017-09-30 23:01:02 +0200579 set_program_name(argv[0]);
Christian Eglibe149002009-10-09 09:09:07 +0000580
Bert Frees92a80352017-09-30 23:01:02 +0200581 while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) switch (optc) {
582 /* --help and --version exit immediately, per GNU coding standards. */
583 case 'v':
584 version_etc(
585 stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *)NULL);
586 exit(EXIT_SUCCESS);
587 break;
588 case 'h':
589 print_help();
590 exit(EXIT_SUCCESS);
591 break;
592 default:
593 fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
594 exit(EXIT_FAILURE);
595 break;
596 }
Christian Eglibe149002009-10-09 09:09:07 +0000597
Bert Frees92a80352017-09-30 23:01:02 +0200598 if (optind != argc - 1) {
599 /* Print error message and exit. */
600 if (optind < argc - 1)
601 fprintf(stderr, "%s: extra operand: %s\n", program_name, argv[optind + 1]);
602 else
603 fprintf(stderr, "%s: no table specified\n", program_name);
604 fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
605 exit(EXIT_FAILURE);
606 }
Christian Eglibe149002009-10-09 09:09:07 +0000607
Bert Frees47e69112019-08-22 13:09:36 +0200608 _lou_getTable(argv[optind], argv[optind], &table, &displayTable);
609 if (!table) {
Bert Frees92a80352017-09-30 23:01:02 +0200610 lou_free();
611 exit(EXIT_FAILURE);
612 }
613 getCommands();
614 lou_free();
615 exit(EXIT_SUCCESS);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000616}