Revision: 864 Author: bertfrees@xxxxxxxxx Date: Fri Dec 14 07:43:45 2012Log: New debug tool lou_trace: prints out all the applied rules for a given input
http://code.google.com/p/liblouis/source/detail?r=864 Added: /trunk/tools/lou_trace.c Modified: /trunk/tools/Makefile.am ======================================= --- /dev/null +++ /trunk/tools/lou_trace.c Fri Dec 14 07:43:45 2012 @@ -0,0 +1,252 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "louis.h" +#include <getopt.h> +#include "progname.h" +#include "version-etc.h" + +static const struct option longopts[] = { + {"help", no_argument, NULL, 'h' }, + {"version", no_argument, NULL, 'v'}, + {NULL, 0, NULL, 0}}; + +const char version_etc_copyright[] = + "Copyright %s %d ViewPlus Technologies, Inc. and JJB Software, Inc."; + +#define AUTHORS "John J. Boyer" + +static void print_help (void) { + printf("\ +Usage: %s [OPTION] TABLE\n", program_name); + fputs("\ +Examine and debug Braille translation tables. This program allows you\n\ +to inspect liblouis translation tables by printing out the list of\n\ +applied translation rules for a given input.\n\n", stdout); + fputs("\ + -h, --help display this help and exit\n\ + -v, --version display version information and exit\n\n", stdout); + printf("Report bugs to %s.\n", PACKAGE_BUGREPORT); +#ifdef PACKAGE_PACKAGER_BUG_REPORTS+ printf("Report %s bugs to: %s\n", PACKAGE_PACKAGER, PACKAGE_PACKAGER_BUG_REPORTS);
+#endif +#ifdef PACKAGE_URL + printf("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL); +#endif +} + +#define BUFSIZE 512 +#define RULESSIZE 512 + +static char *get_input(void) { + static char input_buffer[BUFSIZE]; + size_t input_length; + input_buffer[0] = 0; + fgets(input_buffer, sizeof(input_buffer), stdin); + input_length = strlen(input_buffer) - 1; + if (input_length < 0) + exit(0); + input_buffer[input_length] = 0; + return input_buffer; +} + +static int get_wide_input(widechar *buffer) { + return extParseChars(get_input(), buffer); +} + +static char *print_chars(widechar *buffer, int length) { + static char chars[BUFSIZE]; + strcpy(chars, &showString(buffer, length)[1]); + chars[strlen(chars) - 1] = 0; + return chars; +} + +static char *print_dots(widechar *buffer, int length) { + static char dots[BUFSIZE]; + strcpy(dots, showDots(buffer, length)); + return dots; +} + +static char *print_number(widechar c) { + static char number[BUFSIZE]; + sprintf(number, "%d", c); + return number; +} + +static char *print_attributes(unsigned int a) { + static char attr[BUFSIZE]; + strcpy(attr, showAttributes(a)); + return attr; +} + +static void append_char(char *destination, int *length, char source) { + destination[(*length)++] = source; +} + +static void append_string(char *destination, int *length, char *source) { + strcpy(&destination[(*length)], source); + (*length) += strlen(source); +} + +static char *print_script(widechar *buffer, int length) { + static char script[BUFSIZE]; + int i = 0; + int j = 0; + int action = 0; + while (i < length) { + switch (buffer[i]) { + case pass_first: + case pass_last: + case pass_not: + case pass_startReplace: + case pass_endReplace: + case pass_search: + case pass_copy: + case pass_omit: + append_char(script, &j, buffer[i++]); + break; + case pass_lookback: + append_char(script, &j, buffer[i++]); + append_string(script, &j, print_number(buffer[i++])); + break; + case pass_string: + append_char(script, &j, buffer[i++]); + append_string(script, &j, print_chars(&buffer[i+1], buffer[i])); + i += (1 + buffer[i]); + break; + case pass_dots: + append_char(script, &j, buffer[i++]); + append_string(script, &j, print_dots(&buffer[i+1], buffer[i])); + i += (1 + buffer[i]); + break; + case pass_eq: + case pass_lt: + case pass_gt: + case pass_lteq: + case pass_gteq: + append_char(script, &j, '#'); + append_string(script, &j, print_number(buffer[i+1])); + append_char(script, &j, buffer[i]); + append_string(script, &j, print_number(buffer[i+2])); + i += 3; + break; + case pass_hyphen: + case pass_plus: + append_char(script, &j, '#'); + append_string(script, &j, print_number(buffer[i+1])); + append_char(script, &j, buffer[i]); + i += 2; + break; + case pass_attributes: + append_char(script, &j, buffer[i]);+ append_string(script, &j, print_attributes(buffer[i+1] << 16 | buffer[i+2]));
+ i += 3; + if (buffer[i] == 1 && buffer[i+1] == 1) {} + else if (buffer[i] == 1 && buffer[i+1] == 0xffff) + append_char(script, &j, pass_until); + else if (buffer[i] == buffer[i+1]) + append_string(script, &j, print_number(buffer[i])); + else { + append_string(script, &j, print_number(buffer[i])); + append_char(script, &j, '-'); + append_string(script, &j, print_number(buffer[i+1])); } + i += 2; + break; + case pass_endTest: + append_char(script, &j, '\t'); + action = 1; + i++; + break; + case pass_swap: + case pass_groupstart: + case pass_groupend: + case pass_groupreplace: + /* TBD */ + default: + i++; + break; }} + script[j] = 0; + return script; +} + +static void print_rule(TranslationTableRule *rule) { + char *opcode = findOpcodeName(rule->opcode); + char *chars; + char *dots; + char *script; + switch (rule->opcode) { + case CTO_Context: + case CTO_Correct: + case CTO_SwapCd: + case CTO_SwapDd: + case CTO_Pass2: + case CTO_Pass3: + case CTO_Pass4:+ script = print_script(&rule->charsdots[rule->charslen], rule->dotslen);
+ printf("%s\t%s\n", opcode, script); + break; + default: + chars = print_chars(rule->charsdots, rule->charslen); + dots = print_dots(&rule->charsdots[rule->charslen], rule->dotslen); + printf("%s\t%s\t%s\n", opcode, chars, dots); + break; } +} + +static void main_loop(char *table) { + widechar inbuf[BUFSIZE]; + widechar outbuf[BUFSIZE]; + int inlen; + int outlen;+ TranslationTableRule **rules = malloc(512 * sizeof(TranslationTableRule));
+ int ruleslen; + int i; + while (1) { + inlen = get_wide_input(inbuf); + outlen = BUFSIZE; + ruleslen = RULESSIZE; + if (!trace_translate(table, inbuf, &inlen, outbuf, &outlen,+ NULL, NULL, NULL, NULL, NULL, rules, &ruleslen, 0))
+ break; + printf("%s\n", print_chars(outbuf, outlen)); + for (i=0; i<ruleslen; i++) { + printf("%d.\t", i+1); + print_rule(rules[i]); }} +} + +int main(int argc, char **argv) { + int optc; + char *table; + set_program_name(argv[0]); + while ((optc = getopt_long(argc, argv, "hv", longopts, NULL)) != -1) { + switch (optc) { + case 'v':+ version_etc(stdout, program_name, PACKAGE_NAME, VERSION, AUTHORS, (char *)NULL);
+ exit(EXIT_SUCCESS); + break; + case 'h': + print_help(); + exit(EXIT_SUCCESS); + break; + default:+ fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
+ exit(EXIT_FAILURE); + break; }} + if (optind != argc - 1) { + if (optind < argc - 1)+ fprintf(stderr, "%s: extra operand: %s\n", program_name, argv[optind + 1]);
+ else + fprintf(stderr, "%s: no table specified\n", program_name);+ fprintf(stderr, "Try `%s --help' for more information.\n", program_name);
+ exit(EXIT_FAILURE); } + table = argv[optind]; + if (!lou_getTable(table)) { + lou_free(); + exit(EXIT_FAILURE); } + main_loop(table); + lou_free(); + exit(EXIT_SUCCESS); +} ======================================= --- /trunk/tools/Makefile.am Wed Sep 5 02:06:10 2012 +++ /trunk/tools/Makefile.am Fri Dec 14 07:43:45 2012 @@ -12,7 +12,8 @@ lou_checkhyphens \ lou_checktable \ lou_debug \ - lou_translate + lou_translate \ + lou_trace lou_allround_SOURCES= \ lou_allround.c @@ -24,6 +25,8 @@ lou_debug.c lou_translate_SOURCES = \ lou_translate.c +lou_trace_SOURCES = \ + lou_trace.c # distribute the harness generator but do not install it dist_bin_SCRIPTS = lou_harnessGenerator For a description of the software, to download it and links to project pages go to http://www.abilitiessoft.com