blob: 5c3b6e43864877b0602eb52ceff0f471d87d978c [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"
32#include "version-etc.h"
33
34static const struct option longopts[] =
35{
36 { "help", no_argument, NULL, 'h' },
37 { "version", no_argument, NULL, 'v' },
38 { NULL, 0, NULL, 0 }
39};
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;
Eitan Isaacson109996e2008-12-20 14:52:53 +000085 fgets (inputBuffer, sizeof (inputBuffer), stdin);
John Boyer16689ac2009-01-12 15:11:39 +000086 inputLength = strlen (inputBuffer) - 1;
87 if (inputLength < 0) /*EOF on script */
88 exit (0);
89 inputBuffer[inputLength] = 0;
90 return inputLength;
Eitan Isaacson109996e2008-12-20 14:52:53 +000091}
92
93static int
John Boyer16689ac2009-01-12 15:11:39 +000094printRule (TranslationTableRule * thisRule, int mode)
95{
96 printf ("Rule: ");
97 printf ("opcode=%s, ", findOpcodeName (thisRule->opcode));
98 if (thisRule->before)
99 printf ("before=%x, ", thisRule->before);
100 if (thisRule->after)
101 printf ("after=%x, ", thisRule->after);
102 switch (thisRule->opcode)
103 {
104 case CTO_Context:
105 case CTO_Correct:
106 case CTO_SwapCd:
107 case CTO_SwapDd:
108 case CTO_Pass2:
109 case CTO_Pass3:
110 case CTO_Pass4:
111 printf ("code=%s ", showString (thisRule->charsdots, thisRule->charslen
112 + thisRule->dotslen));
113 break;
114 default:
115 if (mode == 0)
116 {
117 printf ("chars=%s, ", showString (thisRule->charsdots,
118 thisRule->charslen));
119 printf ("dots=%s, ",
120 showDots (&thisRule->charsdots[thisRule->charslen],
121 thisRule->dotslen));
122 }
123 else
124 {
125 printf ("dots=%s, ",
126 showDots (&thisRule->charsdots[thisRule->charslen],
127 thisRule->dotslen));
128 printf ("chars=%s, ", showString (thisRule->charsdots,
129 thisRule->charslen));
130 }
131 break;
132 }
133 return 1;
134}
135
136static int
137printCharacter (TranslationTableCharacter * thisChar, int mode)
138{
139 TranslationTableRule *thisRule;
140 TranslationTableOffset nextRule;
141 if (mode == 0)
142 {
143 printf ("Char: ");
144 printf ("real=%s, ", showString (&thisChar->realchar, 1));
145 printf ("upper=%s, ", showString (&thisChar->uppercase, 1));
146 printf ("lower=%s, ", showString (&thisChar->lowercase, 1));
147 }
148 else
149 printf ("Dots: real=%s, ", showDots (&thisChar->realchar, 1));
150 printf ("attr=%s, ", showAttributes (thisChar->attributes));
151 nextRule = thisChar->otherRules;
152 while (nextRule)
153 {
154 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
John Boyerc675d7a2009-01-15 14:32:20 +0000155 if (nextRule == thisChar->definitionRule)
John Boyer16689ac2009-01-12 15:11:39 +0000156 printf ("definition ");
157 printRule (thisRule, mode);
158 printf ("\n");
159 if (mode == 0)
160 nextRule = thisRule->charsnext;
161 else
162 nextRule = thisRule->dotsnext;
163 }
164 return 1;
165}
166
167static int
168show_characters (int startHash)
169{
170 int k;
171 TranslationTableCharacter *thisChar;
172 TranslationTableOffset nextChar;
173 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
174 if (startHash < 0)
175 k = 0;
176 else
177 k = startHash;
178 for (; k < HASHNUM; k++)
179 if (table->characters[k])
180 {
181 printf ("Hash=%d\n", k);
182 nextChar = table->characters[k];
183 while (nextChar)
184 {
185 thisChar =
186 (TranslationTableCharacter *) & table->ruleArea[nextChar];
187 printCharacter (thisChar, 0);
188 printf ("=> ");
189 getInput ();
190 if (*inputBuffer == 'h')
191 break;
192 if (*inputBuffer == 'e')
193 return 1;
194 nextChar = thisChar->next;
195 }
196 }
197 return 1;
198}
199
200static int
201show_dots (int startHash)
202{
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 {
214 printf ("Hash=%d\n", k);
215 nextDots = table->dots[k];
216 while (nextDots)
217 {
218 thisDots =
219 (TranslationTableCharacter *) & table->ruleArea[nextDots];
220 printCharacter (thisDots, 1);
221 printf ("=> ");
222 getInput ();
223 if (*inputBuffer == 'h')
224 break;
225 if (*inputBuffer == 'e')
226 return 1;
227 nextDots = thisDots->next;
228 }
229 }
230 return 1;
231}
232
233static int
234show_forRules (int startHash)
235{
236 int k;
237 TranslationTableRule *thisRule;
238 TranslationTableOffset nextRule;
239 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
240 if (startHash < 0)
241 k = 0;
242 else
243 k = startHash;
244 for (; k < HASHNUM; k++)
245 if (table->forRules[k])
246 {
247 printf ("Hash=%d\n", k);
248 nextRule = table->forRules[k];
249 while (nextRule)
250 {
251 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
252 printRule (thisRule, 0);
253 printf ("=> ");
254 getInput ();
255 if (*inputBuffer == 'h')
256 break;
257 if (*inputBuffer == 'e')
258 return 1;
259 nextRule = thisRule->charsnext;
260 }
261 }
262 return 1;
263}
264
265static int
266show_backRules (int startHash)
267{
268 int k;
269 TranslationTableRule *thisRule;
270 TranslationTableOffset nextRule;
271 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
272 if (startHash < 0)
273 k = 0;
274 else
275 k = startHash;
276 for (; k < HASHNUM; k++)
277 if (table->backRules[k])
278 {
279 printf ("Hash=%d\n", k);
280 nextRule = table->backRules[k];
281 while (nextRule)
282 {
283 thisRule = (TranslationTableRule *) & table->ruleArea[nextRule];
284 printRule (thisRule, 1);
285 printf ("=> ");
286 getInput ();
287 if (*inputBuffer == 'h')
288 break;
289 if (*inputBuffer == 'e')
290 return 1;
291 nextRule = thisRule->dotsnext;
292 }
293 }
294 return 1;
295}
296
297static int
298print_brailleIndicator (TranslationTableOffset offset, char *opcode)
299{
300 TranslationTableRule *thisRule;
301 if (!offset)
302 return 0;
303 thisRule = (TranslationTableRule *) & table->ruleArea[offset];
304 printf ("%s %s\n", opcode,
305 showDots (&thisRule->charsdots[0], thisRule->dotslen));
306 return 1;
307}
308
309static int
310print_phraseLength (TranslationTableOffset offset, char *opcode)
311{
312 if (!offset)
313 return 0;
314 printf ("%s %d\n", opcode, offset);
Christian Eglifbfea8b2009-08-11 11:24:40 +0000315 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000316}
317
318static int
319show_brailleIndicators (void)
320{
Christian Eglif1da9822016-06-10 15:03:34 +0200321 char name[BUFSIZE];
322 char *emphNames[] = {"begemphphrase %s",
323 "endemphphrase %s before",
324 "endemphphrase %s after",
325 "begemphword %s",
326 "endemphword %s",
327 "emphletter %s",
328 "begemph %s",
329 "endemph %s",
330 NULL};
331 char *capsNames[] = {"firstwordcaps",
332 "lastwordcapsbefore",
333 "lastwordcapsafter",
334 "begcaps",
335 "endcaps",
336 "capsletter",
337 "capsword",
338 "capswordstop",
339 NULL};
340
Davy Kager68004042016-01-26 12:50:22 +0100341 // FIXME: update to include all UEB opcodes.
Christian Eglif1da9822016-06-10 15:03:34 +0200342
343 for (EmphCodeOffset offset = 0; capsNames[offset]; offset++) {
344 print_brailleIndicator (table->emphRules[capsRule][offset],capsNames[offset]);
345 }
Davy Kagerb3ff4542016-02-15 11:03:02 +0100346 print_phraseLength (table->emphRules[capsRule][lenPhraseOffset], "lencapsphrase");
John Boyer16689ac2009-01-12 15:11:39 +0000347 print_brailleIndicator (table->letterSign, "letsign");
348 print_brailleIndicator (table->numberSign, "numsign");
Christian Eglif1da9822016-06-10 15:03:34 +0200349
350 for (int i = 0; table->emphClasses[i]; i++) {
351 for (EmphCodeOffset offset = 0; emphNames[offset]; offset++) {
352 snprintf(name, BUFSIZE, emphNames[offset], table->emphClasses[i]);
353 print_brailleIndicator (table->emphRules[emph1Rule][offset], name);
354 }
355 snprintf(name, BUFSIZE, "lenemphphrase %s", table->emphClasses[i]);
356 print_phraseLength (table->emphRules[emph1Rule][lenPhraseOffset], name);
357 }
John Boyer16689ac2009-01-12 15:11:39 +0000358 print_brailleIndicator (table->begComp, "begcomp");
359 print_brailleIndicator (table->compBegEmph1, "compbegemph1");
360 print_brailleIndicator (table->compEndEmph1, "compendemph1");
361 print_brailleIndicator (table->compBegEmph2, "compbegemph2");
362 print_brailleIndicator (table->compEndEmph2, "compendemph2");
363 print_brailleIndicator (table->compBegEmph3, "compbegemph3");
364 print_brailleIndicator (table->compEndEmph3, "compendemph3");
365 print_brailleIndicator (table->compCapSign, "compcapsign");
366 print_brailleIndicator (table->compBegCaps, "compbegcaps");
367 print_brailleIndicator (table->compEndCaps, "compendcaps");
368 print_brailleIndicator (table->endComp, "endcomp");
369 return 1;
370}
371
372static char *
373pickYN (int a)
374{
375 if (!a)
376 return "no";
377 return "yes";
378}
379
380static int
381show_misc (void)
382{
383 printf ("Table size: %d\n", table->tableSize);
384 printf ("Bytes used: %d\n", table->bytesUsed);
385 printf ("Number of passes: %d\n", table->numPasses);
Christian Egli5e8c3892009-01-15 16:30:59 +0000386 printf ("'correct' opcodes: %s\n", pickYN (table->corrections));
John Boyer16689ac2009-01-12 15:11:39 +0000387 printf ("'syllable' opcodes: %s\n", pickYN (table->syllables));
388 printf ("'capsnocont' opcode: %s\n", pickYN (table->capsNoCont));
389 printf ("Hyphenation table: %s\n", pickYN (table->hyphenStatesArray));
390 printf ("noletsignbefore %s\n", showString (&table->noLetsignBefore[0],
391 table->noLetsignBeforeCount));
392 printf ("noletsign %s\n", showString (&table->noLetsign[0],
393 table->noLetsignCount));
394 printf ("noletsignafter %s\n", showString (&table->noLetsignAfter[0],
395 table->noLetsignAfterCount));
Christian Eglifbfea8b2009-08-11 11:24:40 +0000396 return 1;
John Boyer16689ac2009-01-12 15:11:39 +0000397}
398
399static int
400show_charMap (int startHash)
401{
402 int k;
403 CharOrDots *thisChar;
404 TranslationTableOffset nextChar;
405 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
406 if (startHash < 0)
407 k = 0;
408 else
409 k = startHash;
410 for (; k < HASHNUM; k++)
411 if (table->charToDots[k])
412 {
413 printf ("Hash=%d\n", k);
414 nextChar = table->charToDots[k];
415 while (nextChar)
416 {
417 thisChar = (CharOrDots *) & table->ruleArea[nextChar];
418 printf ("Char: %s ", showString (&thisChar->lookFor, 1));
419 printf ("dots=%s\n", showDots (&thisChar->found, 1));
420 printf ("=> ");
421 getInput ();
422 if (*inputBuffer == 'h')
423 break;
424 if (*inputBuffer == 'e')
425 return 1;
426 nextChar = thisChar->next;
427 }
428 }
429 return 1;
430}
431
432static int
433show_dotsMap (int startHash)
434{
435 int k;
436 CharOrDots *thisDots;
437 TranslationTableOffset nextDots;
438 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
439 if (startHash < 0)
440 k = 0;
441 else
442 k = startHash;
443 for (; k < HASHNUM; k++)
444 if (table->dotsToChar[k])
445 {
446 printf ("Hash=%d\n", k);
447 nextDots = table->dotsToChar[k];
448 while (nextDots)
449 {
450 thisDots = (CharOrDots *) & table->ruleArea[nextDots];
451 printf ("Dots: %s ", showDots (&thisDots->lookFor, 1));
452 printf ("char=%s\n", showString (&thisDots->found, 1));
453 printf ("=> ");
454 getInput ();
455 if (*inputBuffer == 'h')
456 break;
457 if (*inputBuffer == 'e')
458 return 1;
459 nextDots = thisDots->next;
460 }
461 }
462 return 1;
463}
464
465static int
466show_compDots (int startChar)
467{
468 widechar k;
469 printf ("Press enter for next or (e)xit, next-(h)ash, then enter\n");
470 if (startChar < 0)
471 k = 0;
472 else
473 k = startChar;
474 for (; k < 256; k++)
475 if (table->compdotsPattern[k])
476 {
477 TranslationTableRule *thisRule = (TranslationTableRule *)
478 & table->ruleArea[table->compdotsPattern[k]];
479 printf ("Char: %s ", showString (&k, 1));
480 printf ("dots=%s\n",
481 showDots (&thisRule->charsdots[1], thisRule->dotslen));
482 printf ("=> ");
483 getInput ();
484 if (*inputBuffer == 'e')
485 return 1;
486 }
487 return 1;
488}
489
490static void
491part_paramLetters ()
492{
493 printf ("show particular hash chains.\n");
494 printf
495 ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
496 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
497 printf ("(z)-compdots, (h)elp, e(x)it\n");
498}
499
500static void
501particularHelp (void)
502{
503 part_paramLetters ();
504}
505
506static int
507particular (void)
508{
509 int startHash;
510 widechar parsed[BUFSIZE];
511 part_paramLetters ();
512 do
513 {
514 printf ("particular: ");
515 getInput ();
516 switch (inputBuffer[0])
517 {
518 case 0:
519 break;
520 case 'h':
521 particularHelp ();
522 break;
523 case 'c':
524 printf ("-> ");
525 getInput ();
526 if (!extParseChars (inputBuffer, parsed))
527 break;
528 startHash = charHash (*parsed);
529 if (table->characters[startHash] == 0)
530 {
531 printf ("Character not in table.\n");
532 break;
533 }
534 show_characters (startHash);
535 break;
536 case 'd':
537 printf ("-> ");
538 getInput ();
539 if (!extParseDots (inputBuffer, parsed))
540 break;
541 startHash = charHash (*parsed);
542 if (table->dots[startHash] == 0)
543 {
544 printf ("Dot pattern not in table.\n");
545 break;
546 }
547 show_dots (startHash);
548 break;
549 case 'C':
550 printf ("-> ");
551 getInput ();
552 if (!extParseChars (inputBuffer, parsed))
553 break;
554 startHash = charHash (*parsed);
555 if (table->charToDots[startHash] == 0)
556 {
557 printf ("Character not in table.\n");
558 break;
559 }
560 show_charMap (startHash);
561 break;
562 case 'D':
563 printf ("-> ");
564 getInput ();
565 if (!extParseDots (inputBuffer, parsed))
566 break;
567 startHash = charHash (*parsed);
568 if (table->dotsToChar[startHash] == 0)
569 {
570 printf ("Dot pattern not in table.\n");
571 break;
572 }
573 show_dotsMap (startHash);
574 break;
575 case 'f':
576 printf ("-> ");
577 getInput ();
578 if (!extParseChars (inputBuffer, parsed))
579 break;
580 startHash = stringHash (parsed);
581 if (table->forRules[startHash] == 0)
582 {
583 printf ("Character string not in table.\n");
584 break;
585 }
586 show_forRules (startHash);
587 break;
588 case 'b':
589 printf ("-> ");
590 getInput ();
591 if (!extParseDots (inputBuffer, parsed))
592 break;
593 startHash = stringHash (parsed);
594 if (table->backRules[startHash] == 0)
595 {
596 printf ("Dot pattern not in table.\n");
597 break;
598 }
599 show_backRules (startHash);
600 break;
601 case 'z':
602 printf ("-> ");
603 getInput ();
604 if (!extParseChars (inputBuffer, parsed))
605 break;
606 startHash = charHash (*parsed);
607 if (*parsed > 255 || table->compdotsPattern[startHash] == 0)
608 {
609 printf ("Character not in table.\n");
610 break;
611 }
612 show_compDots (startHash);
613 break;
614 case 'x':
615 return 1;
616 default:
617 printf ("Bad choice.\n");
618 break;
619 }
620 }
621 while (inputBuffer[0] != 'x');
622 return 1;
623}
624
Eitan Isaacson109996e2008-12-20 14:52:53 +0000625static void
626paramLetters (void)
627{
John Boyer16689ac2009-01-12 15:11:39 +0000628 printf ("Press one of the letters in parentheses, then enter.\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200629 printf ("show-(f)orward-rules, show-(b)ackward-rules, show-(c)haracters, \n");
John Boyer16689ac2009-01-12 15:11:39 +0000630 printf ("show-(d)ot-patterns, show-(C)har-to-dots, show-(D)ots-tochar\n");
631 printf ("show-(m)isc, show-(z)-compdots\n");
Christian Egli16d25e12016-06-10 15:04:12 +0200632 printf ("show-braille(i)ndicators, show-(p)articulars\n");
633 printf ("(h)elp, (q)uit\n");
John Boyer16689ac2009-01-12 15:11:39 +0000634}
635
636static void
637commandHelp (void)
638{
639 paramLetters ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000640}
641
642static int
643getCommands (void)
644{
645 paramLetters ();
646 do
647 {
648 printf ("Command: ");
649 getInput ();
650 switch (inputBuffer[0])
651 {
652 case 0:
653 break;
John Boyer16689ac2009-01-12 15:11:39 +0000654 case 'h':
655 commandHelp ();
656 break;
657 case 'C':
658 show_charMap (-1);
659 break;
660 case 'D':
661 show_dotsMap (-1);
662 break;
663 case 'z':
664 show_compDots (-1);
665 break;
666 case 'c':
667 show_characters (-1);
668 break;
669 case 'd':
670 show_dots (-1);
671 break;
672 case 'f':
673 show_forRules (-1);
674 break;
675 case 'b':
676 show_backRules (-1);
677 break;
678 case 'i':
679 show_brailleIndicators ();
680 break;
681 case 'm':
682 show_misc ();
683 break;
684 case 'p':
685 particular ();
686 break;
687 case 'q':
688 return 1;
Eitan Isaacson109996e2008-12-20 14:52:53 +0000689 default:
690 printf ("Bad choice.\n");
691 break;
692 }
693 }
John Boyer16689ac2009-01-12 15:11:39 +0000694 while (inputBuffer[0] != 'q');
Eitan Isaacson109996e2008-12-20 14:52:53 +0000695 return 1;
696}
697
698int
699main (int argc, char **argv)
700{
Christian Eglibe149002009-10-09 09:09:07 +0000701 int optc;
702
703 set_program_name (argv[0]);
704
705 while ((optc = getopt_long (argc, argv, "hv", longopts, NULL)) != -1)
706 switch (optc)
707 {
708 /* --help and --version exit immediately, per GNU coding standards. */
709 case 'v':
710 version_etc (stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *) NULL);
711 exit (EXIT_SUCCESS);
712 break;
713 case 'h':
714 print_help ();
715 exit (EXIT_SUCCESS);
716 break;
717 default:
718 fprintf (stderr, "Try `%s --help' for more information.\n",
719 program_name);
720 exit (EXIT_FAILURE);
721 break;
722 }
723
724 if (optind != argc - 1)
Eitan Isaacson109996e2008-12-20 14:52:53 +0000725 {
Christian Eglibe149002009-10-09 09:09:07 +0000726 /* Print error message and exit. */
727 if (optind < argc - 1)
728 fprintf (stderr, "%s: extra operand: %s\n",
729 program_name, argv[optind + 1]);
730 else
731 fprintf (stderr, "%s: no table specified\n",
732 program_name);
733 fprintf (stderr, "Try `%s --help' for more information.\n",
734 program_name);
735 exit (EXIT_FAILURE);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000736 }
Christian Eglibe149002009-10-09 09:09:07 +0000737
738 if (!(table = lou_getTable (argv[optind])))
John Boyer16689ac2009-01-12 15:11:39 +0000739 {
740 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000741 exit (EXIT_FAILURE);
John Boyer16689ac2009-01-12 15:11:39 +0000742 }
743 getCommands ();
Eitan Isaacson109996e2008-12-20 14:52:53 +0000744 lou_free ();
Christian Eglibe149002009-10-09 09:09:07 +0000745 exit (EXIT_SUCCESS);
Eitan Isaacson109996e2008-12-20 14:52:53 +0000746}