int check_cursor_pos(const char *tableList, const char *str, const int *expected_pos) { widechar *inbuf; widechar *outbuf; int *inpos, *outpos; int inlen = strlen(str); int outlen = inlen; int cursor_pos; int i, retval = 0; inbuf = malloc(sizeof(widechar) * inlen); outbuf = malloc(sizeof(widechar) * inlen); inpos = malloc(sizeof(int) * inlen); outpos = malloc(sizeof(int) * inlen); inlen = _lou_extParseChars(str, inbuf); for (i = 0; i < inlen; i++) { cursor_pos = i; if (!lou_translate(tableList, inbuf, &inlen, outbuf, &outlen, NULL, NULL, NULL, NULL, &cursor_pos, compbrlAtCursor)) { fprintf(stderr, "Translation failed.\n"); retval = 1; goto fail; } if (expected_pos[i] != cursor_pos) { if (!retval) // Print only once fprintf(stderr, "Cursorpos failure:\n"); fprintf(stderr, "string='%s' cursor=%d ('%c') expected=%d received=%d ('%c')\n", str, i, str[i], expected_pos[i], cursor_pos, (char)outbuf[cursor_pos]); retval = 1; } } fail: free(inbuf); free(outbuf); free(inpos); free(outpos); return retval; }
int check_base(const char *tableList, const char *input, const char *expected, optional_test_params in) { int i, retval = 0; int direction = in.direction; const int *expected_inputPos = in.expected_inputPos; const int *expected_outputPos = in.expected_outputPos; if (in.direction < 0 || in.direction > 2) { fprintf(stderr, "Invalid direction.\n"); return 1; } if (in.direction != 0 && in.typeform != NULL) { // Currently, in backward translation, nothing is done with the initial value of // the typeform argument, and on return it always contains all zeros, so it // doesn't make any sense to use typeforms in backward translation tests. fprintf(stderr, "typeforms only supported with testmode 'forward'\n"); return 1; } if (in.direction == 2 && in.cursorPos >= 0) { fprintf(stderr, "cursorPos not supported with testmode 'bothDirections'\n"); return 1; } if (in.direction == 2 && in.max_outlen >= 0) { fprintf(stderr, "maxOutputLength not supported with testmode 'bothDirections'\n"); return 1; } if (in.real_inlen >= 0 && in.max_outlen < 0) { fprintf(stderr, "realInputLength not supported when maxOutputLength is not specified\n"); return 1; } while (1) { widechar *inbuf, *outbuf, *expectedbuf; int inlen = strlen(input); int actualInlen; const int outlen_multiplier = 4 + sizeof(widechar) * 2; int outlen = inlen * outlen_multiplier; int expectedlen = strlen(expected); int funcStatus = 0; formtype *typeformbuf = NULL; int *inputPos = NULL; int *outputPos = NULL; int cursorPos = 0; inbuf = malloc(sizeof(widechar) * inlen); outbuf = malloc(sizeof(widechar) * outlen); expectedbuf = malloc(sizeof(widechar) * expectedlen); if (in.typeform != NULL) { typeformbuf = malloc(outlen * sizeof(formtype)); memcpy(typeformbuf, in.typeform, inlen * sizeof(formtype)); } if (in.cursorPos >= 0) { cursorPos = in.cursorPos; } if (in.max_outlen >= 0) { outlen = in.max_outlen; } inlen = _lou_extParseChars(input, inbuf); if (!inlen) { fprintf(stderr, "Cannot parse input string.\n"); retval = 1; goto fail; } if (in.real_inlen > inlen) { fprintf(stderr, "expected realInputLength (%d) may not exceed total input length " "(%d)\n", in.real_inlen, inlen); return 1; } if (expected_inputPos) { inputPos = malloc(sizeof(int) * outlen); } if (expected_outputPos) { outputPos = malloc(sizeof(int) * inlen); } actualInlen = inlen; // Note that this loop is not strictly needed to make the current tests pass, but // in the general case it is needed because it is theoretically possible that we // provided a too short output buffer. for (int k = 1; k <= 3; k++) { if (direction == 1) { funcStatus = lou_backTranslate(tableList, inbuf, &actualInlen, outbuf, &outlen, typeformbuf, NULL, outputPos, inputPos, &cursorPos, in.mode); } else { funcStatus = lou_translate(tableList, inbuf, &actualInlen, outbuf, &outlen, typeformbuf, NULL, outputPos, inputPos, &cursorPos, in.mode); } if (!funcStatus) { fprintf(stderr, "Translation failed.\n"); retval = 1; goto fail; } if (in.max_outlen >= 0 || inlen == actualInlen) { break; } else if (k < 3) { // Hm, something is not quite right. Try again with a larger outbuf free(outbuf); outlen = inlen * outlen_multiplier * (k + 1); outbuf = malloc(sizeof(widechar) * outlen); if (expected_inputPos) { free(inputPos); inputPos = malloc(sizeof(int) * outlen); } fprintf(stderr, "Warning: For %s: returned inlen (%d) differs from passed inlen " "(%d) " "using outbuf of size %d. Trying again with bigger outbuf " "(%d).\n", input, actualInlen, inlen, inlen * outlen_multiplier * k, outlen); actualInlen = inlen; } } expectedlen = _lou_extParseChars(expected, expectedbuf); for (i = 0; i < outlen && i < expectedlen && expectedbuf[i] == outbuf[i]; i++) ; if (i < outlen || i < expectedlen) { retval = 1; if (in.diagnostics) { outbuf[outlen] = 0; fprintf(stderr, "Input: '%s'\n", input); /* Print the original typeform not the typeformbuf, as the * latter has been modified by the translation and contains some * information about outbuf */ if (in.typeform != NULL) print_typeform(in.typeform, inlen); if (in.cursorPos >= 0) fprintf(stderr, "Cursor: %d\n", in.cursorPos); fprintf(stderr, "Expected: '%s' (length %d)\n", expected, expectedlen); fprintf(stderr, "Received: '"); print_widechars(outbuf, outlen); fprintf(stderr, "' (length %d)\n", outlen); uint8_t *expected_utf8; uint8_t *out_utf8; size_t expected_utf8_len; size_t out_utf8_len; #ifdef WIDECHARS_ARE_UCS4 expected_utf8 = u32_to_u8(&expectedbuf[i], 1, NULL, &expected_utf8_len); out_utf8 = u32_to_u8(&outbuf[i], 1, NULL, &out_utf8_len); #else expected_utf8 = u16_to_u8(&expectedbuf[i], 1, NULL, &expected_utf8_len); out_utf8 = u16_to_u8(&outbuf[i], 1, NULL, &out_utf8_len); #endif if (i < outlen && i < expectedlen) { fprintf(stderr, "Diff: Expected '%.*s' but received '%.*s' in index %d\n", (int)expected_utf8_len, expected_utf8, (int)out_utf8_len, out_utf8, i); } else if (i < expectedlen) { fprintf(stderr, "Diff: Expected '%.*s' but received nothing in index " "%d\n", (int)expected_utf8_len, expected_utf8, i); } else { fprintf(stderr, "Diff: Expected nothing but received '%.*s' in index " "%d\n", (int)out_utf8_len, out_utf8, i); } free(expected_utf8); free(out_utf8); } } if (expected_inputPos) { int error_printed = 0; for (i = 0; i < outlen; i++) { if (expected_inputPos[i] != inputPos[i]) { if (!error_printed) { // Print only once fprintf(stderr, "Input position failure:\n"); error_printed = 1; } fprintf(stderr, "Expected %d, received %d in index %d\n", expected_inputPos[i], inputPos[i], i); retval = 1; } } } if (expected_outputPos) { int error_printed = 0; for (i = 0; i < inlen; i++) { if (expected_outputPos[i] != outputPos[i]) { if (!error_printed) { // Print only once fprintf(stderr, "Output position failure:\n"); error_printed = 1; } fprintf(stderr, "Expected %d, received %d in index %d\n", expected_outputPos[i], outputPos[i], i); retval = 1; } } } if ((in.expected_cursorPos >= 0) && (cursorPos != in.expected_cursorPos)) { fprintf(stderr, "Cursor position failure:\n"); fprintf(stderr, "Initial:%d Expected:%d Actual:%d \n", in.cursorPos, in.expected_cursorPos, cursorPos); retval = 1; } if (in.max_outlen < 0 && inlen != actualInlen) { fprintf(stderr, "Unexpected error happened: input length is not the same before as " "after the translation:\n"); fprintf(stderr, "Before: %d After: %d \n", inlen, actualInlen); retval = 1; } else if (actualInlen > inlen) { fprintf(stderr, "Unexpected error happened: returned input length (%d) exceeds " "total input length (%d)\n", actualInlen, inlen); retval = 1; } else if (in.real_inlen >= 0 && in.real_inlen != actualInlen) { fprintf(stderr, "Real input length failure:\n"); fprintf(stderr, "Expected: %d, received: %d\n", in.real_inlen, actualInlen); retval = 1; } fail: free(inbuf); free(outbuf); free(expectedbuf); free(typeformbuf); free(inputPos); free(outputPos); if (direction == 2) { const char *tmp = input; input = expected; expected = tmp; expected_inputPos = in.expected_outputPos; expected_outputPos = in.expected_inputPos; direction = 1; continue; } else { break; } } return retval; }
int main (int argc, char **argv) { char *charbuf; widechar inbuf[BUFSIZE]; widechar transbuf[BUFSIZE]; widechar outbuf[BUFSIZE]; int outputPos[BUFSIZE]; int inputPos[BUFSIZE]; int inlen; int translen; int outlen; int cursorPos = -1; int realInlen = 0; int k; int optc; set_program_name (argv[0]); while ((optc = getopt_long (argc, argv, "hv", longopts, NULL)) != -1) switch (optc) { /* --help and --version exit immediately, per GNU coding standards. */ 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) { /* Print error message and exit. */ fprintf (stderr, "%s: extra operand: %s\n", program_name, argv[optind]); fprintf (stderr, "Try `%s --help' for more information.\n", program_name); exit (EXIT_FAILURE); } validTable = NULL; enteredCursorPos = -1; mode = 0; while (1) { getCommands (); printf ("Type something, press enter, and view the results.\n"); printf ("A blank line returns to command entry.\n"); if (minimalist) while (1) { translen = outputSize; outlen = outputSize; inlen = getInput (); if (inlen == 0) break; if (!(realInlen = extParseChars (inputBuffer, inbuf))) break; inlen = realInlen; if (!lou_translateString (table, inbuf, &inlen, transbuf, &translen, NULL, NULL, 0)) break; transbuf[translen] = 0; printf ("Translation:\n"); charbuf = showString (transbuf, translen); k = strlen (charbuf) - 1; charbuf[k] = 0; printf ("%s\n", &charbuf[1]); if (showSizes) printf ("input length = %d; output length = %d\n", inlen, translen); lou_backTranslateString (table, transbuf, &translen, outbuf, &outlen, NULL, NULL, 0); printf ("Back-translation:\n"); charbuf = showString (outbuf, outlen); k = strlen (charbuf) - 1; charbuf[k] = 0; printf ("%s\n", &charbuf[1]); if (showSizes) printf ("input length = %d; output length = %d.\n", translen, outlen); if (outlen == realInlen) { for (k = 0; k < realInlen; k++) if (inbuf[k] != outbuf[k]) break; if (k == realInlen) printf ("Perfect roundtrip!\n"); } } else while (1) { for (k = 0; k < strlen (enteredEmphasis); k++) emphasis[k] = (formtype) enteredEmphasis[k]; emphasis[k] = 0; strcpy (spacing, enteredSpacing); cursorPos = enteredCursorPos; inlen = getInput (); if (inlen == 0) break; outlen = outputSize; if (backOnly) { if (!(translen = extParseChars (inputBuffer, transbuf))) break; inlen = realInlen; } else { translen = outputSize; if (!(realInlen = extParseChars (inputBuffer, inbuf))) break; inlen = realInlen; if (!lou_translate (table, inbuf, &inlen, transbuf, &translen, emphasis, spacing, &outputPos[0], &inputPos[0], &cursorPos, mode)) break; transbuf[translen] = 0; if (mode & dotsIO) { printf ("Translation dot patterns:\n"); printf ("%s\n", showDots (transbuf, translen)); } else { printf ("Translation:\n"); charbuf = showString (transbuf, translen); k = strlen (charbuf) - 1; charbuf[k] = 0; printf ("%s\n", &charbuf[1]); if (showSizes) printf ("input length = %d; output length = %d\n", inlen, translen); } } if (cursorPos != -1) printf ("Cursor position: %d\n", cursorPos); if (enteredSpacing[0]) printf ("Returned spacing: %s\n", spacing); if (showPositions) { printf ("Output positions:\n"); for (k = 0; k < inlen; k++) printf ("%d ", outputPos[k]); printf ("\n"); printf ("Input positions:\n"); for (k = 0; k < translen; k++) printf ("%d ", inputPos[k]); printf ("\n"); } if (!forwardOnly) { if (!lou_backTranslate (table, transbuf, &translen, outbuf, &outlen, emphasis, spacing, &outputPos[0], &inputPos[0], &cursorPos, mode)) break; printf ("Back-translation:\n"); charbuf = showString (outbuf, outlen); k = strlen (charbuf) - 1; charbuf[k] = 0; printf ("%s\n", &charbuf[1]); if (showSizes) printf ("input length = %d; output length = %d\n", translen, outlen); if (cursorPos != -1) printf ("Cursor position: %d\n", cursorPos); if (enteredSpacing[0]) printf ("Returned spacing: %s\n", spacing); if (showPositions) { printf ("Output positions:\n"); for (k = 0; k < translen; k++) printf ("%d ", outputPos[k]); printf ("\n"); printf ("Input positions:\n"); for (k = 0; k < outlen; k++) printf ("%d ", inputPos[k]); printf ("\n"); } } if (!(forwardOnly || backOnly)) { if (outlen == realInlen) { for (k = 0; k < realInlen; k++) if (inbuf[k] != outbuf[k]) break; if (k == realInlen) printf ("Perfect roundtrip!\n"); } } } } lou_free (); exit (EXIT_SUCCESS); }