Exemple #1
0
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;
}
Exemple #2
0
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);
}