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