blob: 468e43e4a6fc6eadfc7be0630dec5e5747d37f78 [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: ");
Bert Freesde85e652021-08-24 16:59:16 +0200147 printf("value=%s, ", print_chars(&thisChar->value, 1));
Bert Frees92a80352017-09-30 23:01:02 +0200148 } else
Bert Freesde85e652021-08-24 16:59:16 +0200149 printf("Dots: value=%s, ", _lou_showDots(&thisChar->value, 1));
Bert Frees92a80352017-09-30 23:01:02 +0200150 printf("attr=%s, ", _lou_showAttributes(thisChar->attributes));
151 nextRule = thisChar->otherRules;
152 while (nextRule) {
153 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
154 if (nextRule == thisChar->definitionRule) printf("definition ");
155 printRule(thisRule, mode);
156 printf("\n");
157 if (mode == 0)
158 nextRule = thisRule->charsnext;
159 else
160 nextRule = thisRule->dotsnext;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000161 }
Bert Frees1171cf82021-07-24 12:27:08 +0200162 if (mode == 0 && thisChar->compRule) {
163 TranslationTableRule *compRule =
164 (TranslationTableRule *)&table->ruleArea[thisChar->compRule];
165 printf("comp6 ");
166 printRule(compRule, 0);
167 printf("\n");
168 }
Bert Frees92a80352017-09-30 23:01:02 +0200169 return 1;
170}
171
172static int
173show_characters(int startHash) {
174 int k;
175 TranslationTableCharacter *thisChar;
176 TranslationTableOffset nextChar;
177 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
178 if (startHash < 0)
179 k = 0;
180 else
181 k = startHash;
182 for (; k < HASHNUM; k++)
183 if (table->characters[k]) {
184 printf("Hash=%d\n", k);
185 nextChar = table->characters[k];
186 while (nextChar) {
187 thisChar = (TranslationTableCharacter *)&table->ruleArea[nextChar];
188 printCharacter(thisChar, 0);
189 printf("=> ");
190 getInput();
191 if (*inputBuffer == 'h') break;
192 if (*inputBuffer == 'e') return 1;
193 nextChar = thisChar->next;
194 }
195 }
196 return 1;
197}
198
199static int
200show_dots(int startHash) {
201 int k;
202 TranslationTableCharacter *thisDots;
203 TranslationTableOffset nextDots;
204 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
205 if (startHash < 0)
206 k = 0;
207 else
208 k = startHash;
209 for (; k < HASHNUM; k++)
210 if (table->dots[k]) {
211 printf("Hash=%d\n", k);
212 nextDots = table->dots[k];
213 while (nextDots) {
214 thisDots = (TranslationTableCharacter *)&table->ruleArea[nextDots];
215 printCharacter(thisDots, 1);
216 printf("=> ");
217 getInput();
218 if (*inputBuffer == 'h') break;
219 if (*inputBuffer == 'e') return 1;
220 nextDots = thisDots->next;
221 }
222 }
223 return 1;
224}
225
226static int
227show_forRules(int startHash) {
228 int k;
229 TranslationTableRule *thisRule;
230 TranslationTableOffset nextRule;
231 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
232 if (startHash < 0)
233 k = 0;
234 else
235 k = startHash;
236 for (; k < HASHNUM; k++)
237 if (table->forRules[k]) {
238 printf("Hash=%d\n", k);
239 nextRule = table->forRules[k];
240 while (nextRule) {
241 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
242 printRule(thisRule, 0);
243 printf("=> ");
244 getInput();
245 if (*inputBuffer == 'h') break;
246 if (*inputBuffer == 'e') return 1;
247 nextRule = thisRule->charsnext;
248 }
249 }
250 return 1;
251}
252
253static int
254show_backRules(int startHash) {
255 int k;
256 TranslationTableRule *thisRule;
257 TranslationTableOffset nextRule;
258 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
259 if (startHash < 0)
260 k = 0;
261 else
262 k = startHash;
263 for (; k < HASHNUM; k++)
264 if (table->backRules[k]) {
265 printf("Hash=%d\n", k);
266 nextRule = table->backRules[k];
267 while (nextRule) {
268 thisRule = (TranslationTableRule *)&table->ruleArea[nextRule];
269 printRule(thisRule, 1);
270 printf("=> ");
271 getInput();
272 if (*inputBuffer == 'h') break;
273 if (*inputBuffer == 'e') return 1;
274 nextRule = thisRule->dotsnext;
275 }
276 }
277 return 1;
278}
279
280static int
Christian Egli0cfcd192018-05-08 11:22:46 +0200281print_brailleIndicator(TranslationTableOffset offset, const char *opcode) {
Bert Frees92a80352017-09-30 23:01:02 +0200282 TranslationTableRule *thisRule;
283 if (!offset) return 0;
284 thisRule = (TranslationTableRule *)&table->ruleArea[offset];
285 printf("%s %s\n", opcode, _lou_showDots(&thisRule->charsdots[0], thisRule->dotslen));
286 return 1;
287}
288
289static int
Christian Egli0cfcd192018-05-08 11:22:46 +0200290print_phraseLength(TranslationTableOffset offset, const char *opcode) {
Bert Frees92a80352017-09-30 23:01:02 +0200291 if (!offset) return 0;
Christian Eglida0d2eb2018-05-07 13:41:57 +0200292 printf("%s %u\n", opcode, offset);
Bert Frees92a80352017-09-30 23:01:02 +0200293 return 1;
294}
295
296static int
297show_brailleIndicators(void) {
298 char name[BUFSIZE];
Christian Egli0cfcd192018-05-08 11:22:46 +0200299 const char *emphNames[] = { "begemphphrase %s", "endemphphrase %s before",
Bert Frees92a80352017-09-30 23:01:02 +0200300 "endemphphrase %s after", "begemphword %s", "endemphword %s", "emphletter %s",
301 "begemph %s", "endemph %s", NULL };
Christian Eglid92cec12018-05-08 11:51:17 +0200302 const char *capsNames[] = { "firstwordcaps", "lastwordcapsbefore",
303 "lastwordcapsafter", "begcaps", "endcaps", "capsletter", "capsword",
304 "capswordstop", NULL };
Bert Frees92a80352017-09-30 23:01:02 +0200305
306 // FIXME: update to include all UEB opcodes.
307
308 for (EmphCodeOffset offset = 0; capsNames[offset]; offset++) {
309 print_brailleIndicator(table->emphRules[capsRule][offset], capsNames[offset]);
310 }
311 print_phraseLength(table->emphRules[capsRule][lenPhraseOffset], "lencapsphrase");
312 print_brailleIndicator(table->letterSign, "letsign");
313 print_brailleIndicator(table->numberSign, "numsign");
314
315 for (int i = 0; table->emphClasses[i]; i++) {
316 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
317 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
318 print_brailleIndicator(table->emphRules[emph1Rule][offset], name);
319 }
320 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
321 print_phraseLength(table->emphRules[emph1Rule][lenPhraseOffset], name);
322 }
323 print_brailleIndicator(table->begComp, "begcomp");
Bert Frees92a80352017-09-30 23:01:02 +0200324 print_brailleIndicator(table->endComp, "endcomp");
325 return 1;
326}
327
Christian Egli0cfcd192018-05-08 11:22:46 +0200328static const char *
Bert Frees92a80352017-09-30 23:01:02 +0200329pickYN(int a) {
330 if (!a) return "no";
331 return "yes";
332}
333
334static int
335show_misc(void) {
Christian Eglida0d2eb2018-05-07 13:41:57 +0200336 printf("Table size: %u\n", table->tableSize);
337 printf("Bytes used: %u\n", table->bytesUsed);
Bert Frees92a80352017-09-30 23:01:02 +0200338 printf("Number of passes: %d\n", table->numPasses);
339 printf("'correct' opcodes: %s\n", pickYN(table->corrections));
340 printf("'syllable' opcodes: %s\n", pickYN(table->syllables));
341 printf("'capsnocont' opcode: %s\n", pickYN(table->capsNoCont));
342 printf("Hyphenation table: %s\n", pickYN(table->hyphenStatesArray));
343 printf("noletsignbefore %s\n",
344 print_chars(&table->noLetsignBefore[0], table->noLetsignBeforeCount));
345 printf("noletsign %s\n", print_chars(&table->noLetsign[0], table->noLetsignCount));
346 printf("noletsignafter %s\n",
347 print_chars(&table->noLetsignAfter[0], table->noLetsignAfterCount));
348 return 1;
349}
350
351static int
352show_charMap(int startHash) {
353 int k;
Bert Freesb2b67422020-03-08 22:31:58 +0100354 CharDotsMapping *thisChar;
Bert Frees92a80352017-09-30 23:01:02 +0200355 TranslationTableOffset nextChar;
356 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
357 if (startHash < 0)
358 k = 0;
359 else
360 k = startHash;
361 for (; k < HASHNUM; k++)
Bert Freesc3223682019-07-09 23:18:43 +0200362 if (displayTable->charToDots[k]) {
Bert Frees92a80352017-09-30 23:01:02 +0200363 printf("Hash=%d\n", k);
Bert Freesc3223682019-07-09 23:18:43 +0200364 nextChar = displayTable->charToDots[k];
Bert Frees92a80352017-09-30 23:01:02 +0200365 while (nextChar) {
Bert Freesb2b67422020-03-08 22:31:58 +0100366 thisChar = (CharDotsMapping *)&displayTable->ruleArea[nextChar];
Bert Frees92a80352017-09-30 23:01:02 +0200367 printf("Char: %s ", print_chars(&thisChar->lookFor, 1));
368 printf("dots=%s\n", _lou_showDots(&thisChar->found, 1));
369 printf("=> ");
370 getInput();
371 if (*inputBuffer == 'h') break;
372 if (*inputBuffer == 'e') return 1;
373 nextChar = thisChar->next;
374 }
375 }
376 return 1;
377}
378
379static int
380show_dotsMap(int startHash) {
381 int k;
Bert Freesb2b67422020-03-08 22:31:58 +0100382 CharDotsMapping *thisDots;
Bert Frees92a80352017-09-30 23:01:02 +0200383 TranslationTableOffset nextDots;
384 printf("Press enter for next or (e)xit, next-(h)ash, then enter\n");
385 if (startHash < 0)
386 k = 0;
387 else
388 k = startHash;
389 for (; k < HASHNUM; k++)
Bert Freesc3223682019-07-09 23:18:43 +0200390 if (displayTable->dotsToChar[k]) {
Bert Frees92a80352017-09-30 23:01:02 +0200391 printf("Hash=%d\n", k);
Bert Freesc3223682019-07-09 23:18:43 +0200392 nextDots = displayTable->dotsToChar[k];
Bert Frees92a80352017-09-30 23:01:02 +0200393 while (nextDots) {
Bert Freesb2b67422020-03-08 22:31:58 +0100394 thisDots = (CharDotsMapping *)&displayTable->ruleArea[nextDots];
Bert Frees92a80352017-09-30 23:01:02 +0200395 printf("Dots: %s ", _lou_showDots(&thisDots->lookFor, 1));
396 printf("char=%s\n", print_chars(&thisDots->found, 1));
397 printf("=> ");
398 getInput();
399 if (*inputBuffer == 'h') break;
400 if (*inputBuffer == 'e') return 1;
401 nextDots = thisDots->next;
402 }
403 }
404 return 1;
405}
406
Bert Frees92a80352017-09-30 23:01:02 +0200407static void
408part_paramLetters(void) {
409 printf("show particular hash chains.\n");
410 printf("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
411 printf("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
Bert Frees1171cf82021-07-24 12:27:08 +0200412 printf("(h)elp, e(x)it\n");
Bert Frees92a80352017-09-30 23:01:02 +0200413}
414
415static void
416particularHelp(void) {
417 part_paramLetters();
418}
419
420static int
421particular(void) {
422 int startHash;
423 widechar parsed[BUFSIZE];
424 part_paramLetters();
425 do {
426 printf("particular: ");
427 getInput();
428 switch (inputBuffer[0]) {
429 case 0:
430 break;
431 case 'h':
432 particularHelp();
433 break;
434 case 'c':
435 printf("-> ");
436 getInput();
437 if (!_lou_extParseChars(inputBuffer, parsed)) break;
438 startHash = _lou_charHash(*parsed);
439 if (table->characters[startHash] == 0) {
440 printf("Character not in table.\n");
441 break;
442 }
443 show_characters(startHash);
444 break;
445 case 'd':
446 printf("-> ");
447 getInput();
448 if (!_lou_extParseDots(inputBuffer, parsed)) break;
449 startHash = _lou_charHash(*parsed);
450 if (table->dots[startHash] == 0) {
451 printf("Dot pattern not in table.\n");
452 break;
453 }
454 show_dots(startHash);
455 break;
456 case 'C':
457 printf("-> ");
458 getInput();
459 if (!_lou_extParseChars(inputBuffer, parsed)) break;
460 startHash = _lou_charHash(*parsed);
Bert Freesc3223682019-07-09 23:18:43 +0200461 if (displayTable->charToDots[startHash] == 0) {
Bert Frees92a80352017-09-30 23:01:02 +0200462 printf("Character not in table.\n");
463 break;
464 }
465 show_charMap(startHash);
466 break;
467 case 'D':
468 printf("-> ");
469 getInput();
470 if (!_lou_extParseDots(inputBuffer, parsed)) break;
471 startHash = _lou_charHash(*parsed);
Bert Freesc3223682019-07-09 23:18:43 +0200472 if (displayTable->dotsToChar[startHash] == 0) {
Bert Frees92a80352017-09-30 23:01:02 +0200473 printf("Dot pattern not in table.\n");
474 break;
475 }
476 show_dotsMap(startHash);
477 break;
478 case 'f':
479 printf("-> ");
480 getInput();
481 if (!_lou_extParseChars(inputBuffer, parsed)) break;
Bert Freesd4b7a8e2019-06-04 13:56:07 +0200482 startHash = _lou_stringHash(parsed, 0, NULL);
Bert Frees92a80352017-09-30 23:01:02 +0200483 if (table->forRules[startHash] == 0) {
484 printf("Character string not in table.\n");
485 break;
486 }
487 show_forRules(startHash);
488 break;
489 case 'b':
490 printf("-> ");
491 getInput();
492 if (!_lou_extParseDots(inputBuffer, parsed)) break;
Bert Freesd4b7a8e2019-06-04 13:56:07 +0200493 startHash = _lou_stringHash(parsed, 0, NULL);
Bert Frees92a80352017-09-30 23:01:02 +0200494 if (table->backRules[startHash] == 0) {
495 printf("Dot pattern not in table.\n");
496 break;
497 }
498 show_backRules(startHash);
499 break;
Bert Frees92a80352017-09-30 23:01:02 +0200500 case 'x':
501 return 1;
502 default:
503 printf("Bad choice.\n");
504 break;
505 }
506 } while (inputBuffer[0] != 'x');
507 return 1;
508}
509
510static void
511paramLetters(void) {
512 printf("Press one of the letters in parentheses, then enter.\n");
513 printf("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
514 printf("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
Bert Frees1171cf82021-07-24 12:27:08 +0200515 printf("show-(m)isc, show-braille(i)ndicators, show-(p)articulars\n");
Bert Frees92a80352017-09-30 23:01:02 +0200516 printf("(h)elp, (q)uit\n");
517}
518
519static void
520commandHelp(void) {
521 paramLetters();
522}
523
524static int
525getCommands(void) {
526 paramLetters();
527 do {
528 printf("Command: ");
529 getInput();
530 switch (inputBuffer[0]) {
531 case 0:
532 break;
533 case 'h':
534 commandHelp();
535 break;
536 case 'C':
537 show_charMap(-1);
538 break;
539 case 'D':
540 show_dotsMap(-1);
541 break;
Bert Frees92a80352017-09-30 23:01:02 +0200542 case 'c':
543 show_characters(-1);
544 break;
545 case 'd':
546 show_dots(-1);
547 break;
548 case 'f':
549 show_forRules(-1);
550 break;
551 case 'b':
552 show_backRules(-1);
553 break;
554 case 'i':
555 show_brailleIndicators();
556 break;
557 case 'm':
558 show_misc();
559 break;
560 case 'p':
561 particular();
562 break;
563 case 'q':
564 return 1;
565 default:
566 printf("Bad choice.\n");
567 break;
568 }
569 } while (inputBuffer[0] != 'q');
570 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000571}
572
573int
Bert Frees92a80352017-09-30 23:01:02 +0200574main(int argc, char **argv) {
575 int optc;
Christian Eglibe149002009-10-09 09:09:07 +0000576
Bert Frees92a80352017-09-30 23:01:02 +0200577 set_program_name(argv[0]);
Christian Eglibe149002009-10-09 09:09:07 +0000578
Bert Frees92a80352017-09-30 23:01:02 +0200579 while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) switch (optc) {
580 /* --help and --version exit immediately, per GNU coding standards. */
581 case 'v':
582 version_etc(
583 stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *)NULL);
584 exit(EXIT_SUCCESS);
585 break;
586 case 'h':
587 print_help();
588 exit(EXIT_SUCCESS);
589 break;
590 default:
591 fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
592 exit(EXIT_FAILURE);
593 break;
594 }
Christian Eglibe149002009-10-09 09:09:07 +0000595
Bert Frees92a80352017-09-30 23:01:02 +0200596 if (optind != argc - 1) {
597 /* Print error message and exit. */
598 if (optind < argc - 1)
599 fprintf(stderr, "%s: extra operand: %s\n", program_name, argv[optind + 1]);
600 else
601 fprintf(stderr, "%s: no table specified\n", program_name);
602 fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
603 exit(EXIT_FAILURE);
604 }
Christian Eglibe149002009-10-09 09:09:07 +0000605
Bert Frees47e69112019-08-22 13:09:36 +0200606 _lou_getTable(argv[optind], argv[optind], &table, &displayTable);
607 if (!table) {
Bert Frees92a80352017-09-30 23:01:02 +0200608 lou_free();
609 exit(EXIT_FAILURE);
610 }
611 getCommands();
612 lou_free();
613 exit(EXIT_SUCCESS);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000614}