blob: f6365e3d8d273a2c4f5f310fdea63afdd1c652a3 [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++) {
Bert Frees1b344e22021-09-30 10:20:13 +0200309 print_brailleIndicator(
310 table->emphRules[MAX_EMPH_CLASSES][offset], capsNames[offset]);
Bert Frees92a80352017-09-30 23:01:02 +0200311 }
Bert Frees1b344e22021-09-30 10:20:13 +0200312 print_phraseLength(
313 table->emphRules[MAX_EMPH_CLASSES][lenPhraseOffset], "lencapsphrase");
Bert Frees92a80352017-09-30 23:01:02 +0200314 print_brailleIndicator(table->letterSign, "letsign");
315 print_brailleIndicator(table->numberSign, "numsign");
316
Bert Frees1b344e22021-09-30 10:20:13 +0200317 for (int i = 0; i < MAX_EMPH_CLASSES && table->emphClassNames[i]; i++) {
Bert Frees92a80352017-09-30 23:01:02 +0200318 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
319 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
Bert Frees1b344e22021-09-30 10:20:13 +0200320 print_brailleIndicator(table->emphRules[i][offset], name);
Bert Frees92a80352017-09-30 23:01:02 +0200321 }
322 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
Bert Frees1b344e22021-09-30 10:20:13 +0200323 print_phraseLength(table->emphRules[i][lenPhraseOffset], name);
Bert Frees92a80352017-09-30 23:01:02 +0200324 }
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}