From 59d33db93e4bb53c8d28c9c77bade532746c0dd6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Pinard?= Date: Sun, 24 Feb 2008 18:25:29 -0500 Subject: [PATCH] Correct iconv, about loosing characters --- NEWS | 9 +- src/ChangeLog | 4 + src/iconv.c | 244 ++++++++++++++++-------------------------- tests/ChangeLog | 5 + tests/Recode.c | 234 +++++++++++++++++++--------------------- tests/Recode.pyx | 15 ++- tests/common.py | 23 ++-- tests/t70_inferenz.py | 91 ++++++++++++++++ 8 files changed, 333 insertions(+), 292 deletions(-) create mode 100644 tests/t70_inferenz.py diff --git a/NEWS b/NEWS index 86b9b5d..7e0a66a 100644 --- a/NEWS +++ b/NEWS @@ -7,12 +7,13 @@ Recode NEWS - User visible changes :Copyright: © 1993-1999, 2000, 2001, 2008 Free Software Foundation, Inc. -Version 3.7-beta1 -================= +Version 3.7 -:Author: François Pinard, 2008-02. +:Author: François Pinard, 2008-03. -+ Changes are mostly internal, and correct reported bugs. ++ Recode does no include libiconv anymore, but uses an external iconv + library if one was available at installation time. ++ Many internal changes, for correcting reported bugs. Version 3.6 =========== diff --git a/src/ChangeLog b/src/ChangeLog index 2701000..ef4ee0b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,10 @@ * outer.c (register_all_modules): Add back :libiconv: as an alias for :iconv:. + * iconv.c (wrapped_transform): Rewritten. + (transform_with_iconv): Simplified, use only one iconv_t. + There are to be limits, working around broken concepts. + 2008-03-08 François Pinard * recode.h (RECODE_AUTO_ABORT_FLAG, RECODE_NO_ICONV_FLAG): New. diff --git a/src/iconv.c b/src/iconv.c index b7e2ec4..46604e8 100644 --- a/src/iconv.c +++ b/src/iconv.c @@ -1,5 +1,5 @@ /* Conversion of files between different charsets and surfaces. - Copyright © 1999, 2000 Free Software Foundation, Inc. + Copyright © 1999, 2000, 2001, 2008 Free Software Foundation, Inc. Contributed by François Pinard , 1999, and Bruno Haible , 2000. @@ -29,159 +29,103 @@ #define BUFFER_SIZE 2048 static bool -wrapped_transform (iconv_t conversion, iconv_t conversion_to_utf8, - RECODE_SUBTASK subtask) +wrapped_transform (iconv_t conversion, RECODE_SUBTASK subtask) { - int input_char = get_byte (subtask); - char input_buffer[BUFFER_SIZE]; char output_buffer[BUFFER_SIZE]; - size_t input_left; - size_t output_left; - char *input; - char *output; - char *cursor; - size_t converted; - int saved_errno; - - cursor = input_buffer; - while (cursor > input_buffer || input_char != EOF) - { - /* Fill the input buffer as much as possible. */ - while (input_char != EOF && cursor < input_buffer + BUFFER_SIZE) - { - *cursor++ = input_char; - input_char = get_byte (subtask); - } - - /* We have at least some input. */ - assert (cursor > input_buffer); - - /* Convert accumulated input into the output buffer. */ - input_left = cursor - input_buffer; - input = input_buffer; - output_left = BUFFER_SIZE; - output = output_buffer; - converted - = iconv (conversion, &input, &input_left, &output, &output_left); - - /* Send the converted result, to free the output buffer. */ - saved_errno = errno; - for (cursor = output_buffer; cursor < output; cursor++) - put_byte (*cursor, subtask); - errno = saved_errno; - - /* Analyze the iconv return value. */ - if (converted == (size_t)(-1) && errno != E2BIG) - { - if (errno == EILSEQ) - { - /* Fail if the user requested reversible conversions. */ - RETURN_IF_NOGO (RECODE_NOT_CANONICAL, subtask); - - /* An invalid multibyte sequence was encountered in the - input, or a conversion error occurred. Distinguish the - two cases by use of conversion_to_utf8. In the first - case, skip one byte. In the second case, skip the entire - character. - FIXME: This heuristic does not work well with stateful - encodings like ISO-2022-JP. */ - char tmp_buf[6]; - size_t tmp_input_left; - size_t tmp_output_left; - char *tmp_input; - char *tmp_output; - - RETURN_IF_NOGO (RECODE_INVALID_INPUT, subtask); + char input_buffer[BUFFER_SIZE]; + int input_char = get_byte (subtask); + char *cursor = input_buffer; + bool drain_first = false; - assert (input_left > 0); - - tmp_input_left = input_left; - tmp_input = input; - tmp_output_left = sizeof (tmp_buf); - tmp_output = tmp_buf; - iconv (conversion_to_utf8, - &tmp_input, &tmp_input_left, - &tmp_output, &tmp_output_left); - /* Reset conversion_to_utf8 to the initial state. */ - iconv (conversion_to_utf8, NULL, NULL, NULL, NULL); - if (tmp_input > input) - { - /* Conversion error. Skip the entire character. */ - input = tmp_input; - input_left = tmp_input_left; - } - else + while (true) + { + /* The output buffer is fully avaible at this point. */ + + char *input = input_buffer; + char *output = output_buffer; + size_t input_left = 0; + size_t output_left = BUFFER_SIZE; + int saved_errno = 0; + size_t converted; + + if (drain_first) + { + /* Drain all accumulated partial state and emit output + to return to the initial shift state. */ + converted = iconv (conversion, NULL, NULL, &output, &output_left); + if (converted == (size_t) -1) + saved_errno = errno; + } + + if (saved_errno == 0) + { + /* Continue filling the input buffer. */ + while (input_char != EOF && cursor < input_buffer + BUFFER_SIZE) + { + *cursor++ = input_char; + input_char = get_byte (subtask); + } + + if (cursor == input_buffer) + { + if (output == output_buffer) { - /* Invalid input. Skip one byte. */ - input++; - input_left--; + /* All work has been done, just make sure we drained. */ + if (drain_first) + break; + drain_first = true; + continue; } - - /* Reset conversion state. (Why?) */ - output_left = BUFFER_SIZE; - output = output_buffer; - converted - = iconv (conversion, NULL, NULL, &output, &output_left); - /* We don't expect E2BIG here: the buffer is large enough. */ - assert (converted != (size_t)(-1)); - for (cursor = output_buffer; cursor < output; cursor++) - put_byte (*cursor, subtask); - } - else if (errno == EINVAL) - { - /* Incomplete multibyte sequence. */ - if (input + input_left < input_buffer + BUFFER_SIZE - && input_char == EOF) - { - /* Incomplete multibyte sequence at end of input. */ - RETURN_IF_NOGO (RECODE_INVALID_INPUT, subtask); - break; - } - /* Otherwise, we shift the remaining input and see whether the - error persists in the next round. */ - } - else - { - recode_perror (subtask->task->request->outer, "iconv ()"); - SET_SUBTASK_ERROR (RECODE_SYSTEM_ERROR, subtask); - SUBTASK_RETURN (subtask); - } - } - - /* If there was no progress, we have a bug in either iconv or the - above logic. */ - if (!(input > input_buffer)) - { - recode_error (subtask->task->request->outer, - "iconv.c internal error 154"); - SET_SUBTASK_ERROR (RECODE_INTERNAL_ERROR, subtask); - SUBTASK_RETURN (subtask); - } - assert (input > input_buffer); - - /* Shift back the unconverted part of the input buffer. - memcpy() doesn't do here, because the regions might overlap. - memmove() isn't worth it, because we rarely have to move more - than 12 bytes. */ - if (input > input_buffer && input_left > 0) - { - cursor = input_buffer; - do - *cursor++ = *input++; - while (--input_left > 0); - } + } + else + { + /* Convert accumulated input and add it to the output buffer. */ + input = input_buffer; + input_left = cursor - input_buffer; + converted = iconv (conversion, + &input, &input_left, + &output, &output_left); + if (converted == (size_t) -1) + saved_errno = errno; + } + } + + /* Send the converted result, so freeing the output buffer. */ + for (cursor = output_buffer; cursor < output; cursor++) + put_byte (*cursor, subtask); + + /* Act according to the outcome of the iconv call. */ + + drain_first = false; + if (saved_errno != 0 && saved_errno != E2BIG) + if (saved_errno == EILSEQ) + { + /* Invalid input. Skip one byte. */ + RETURN_IF_NOGO (RECODE_INVALID_INPUT, subtask); + assert (input_left > 0); + input++; + input_left--; + /* Why is draining required? */ + drain_first = true; + } + else if (saved_errno == EINVAL) + { + if (input + input_left < input_buffer + BUFFER_SIZE + && input_char == EOF) + /* Incomplete multibyte sequence at end of input. */ + RETURN_IF_NOGO (RECODE_INVALID_INPUT, subtask); + } + else + { + recode_perror (subtask->task->request->outer, "iconv ()"); + RETURN_IF_NOGO (RECODE_SYSTEM_ERROR, subtask); + } + + /* Move back any unprocessed part of the input buffer. */ + for (cursor = input_buffer; input_left != 0; input_left--) + *cursor++ = *input++; } - /* Drain all accumulated partial state and emit output to return to the - initial shift state. */ - output_left = BUFFER_SIZE; - output = output_buffer; - converted = iconv (conversion, NULL, NULL, &output, &output_left); - /* We don't expect E2BIG here: the buffer is large enough. */ - assert (converted != (size_t)(-1)); - for (cursor = output_buffer; cursor < output; cursor++) - put_byte (*cursor, subtask); - SUBTASK_RETURN (subtask); } @@ -190,19 +134,17 @@ transform_with_iconv (RECODE_SUBTASK subtask) { RECODE_CONST_STEP step = subtask->step; iconv_t conversion = iconv_open (step->after->name, step->before->name); - iconv_t conversion_to_utf8 = iconv_open ("UTF-8", step->before->name); bool status; - if (conversion == (iconv_t) -1 || conversion_to_utf8 == (iconv_t) -1) + if (conversion == (iconv_t) -1) { SET_SUBTASK_ERROR (RECODE_SYSTEM_ERROR, subtask); SUBTASK_RETURN (subtask); } - status = wrapped_transform (conversion, conversion_to_utf8, subtask); + status = wrapped_transform (conversion, subtask); iconv_close (conversion); - iconv_close (conversion_to_utf8); return status; } diff --git a/tests/ChangeLog b/tests/ChangeLog index c396925..862d59f 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -10,6 +10,11 @@ (Outer.__init__): Replace no_iconv by iconv, defaulting to False. * t21_names.py: Adjusted. + * Recode.pyx (Outer): Add recode method. + (global_outer, recode): Deleted. + * common.py (outer, outer_iconv, recode_iconv_output): New. + * t70_inferenz.py: New test. + 2008-03-06 François Pinard Increase Recode.so portability, by depending on distutils: diff --git a/tests/Recode.c b/tests/Recode.c index 413f607..49a6809 100644 --- a/tests/Recode.c +++ b/tests/Recode.c @@ -1,4 +1,4 @@ -/* Generated by Pyrex 0.9.6.4 on Sat Mar 8 22:48:53 2008 */ +/* Generated by Pyrex 0.9.6.4 on Sun Mar 9 16:41:44 2008 */ #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -146,7 +146,6 @@ static PyObject *__pyx_n_BYTE_ORDER_MARK_SWAPPED; static PyObject *__pyx_n_AUTO_ABORT_FLAG; static PyObject *__pyx_n_NO_ICONV_FLAG; static PyObject *__pyx_n_False; -static PyObject *__pyx_n_global_outer; static int __pyx_f_6Recode_5Outer___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_f_6Recode_5Outer___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { @@ -492,6 +491,71 @@ static PyObject *__pyx_f_6Recode_5Outer_full_charset(PyObject *__pyx_v_self, PyO return __pyx_r; } +static PyObject *__pyx_n_scan; +static PyObject *__pyx_n_string; + +static PyObject *__pyx_f_6Recode_5Outer_recode(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_f_6Recode_5Outer_recode(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + char *__pyx_v_command; + char *__pyx_v_input; + PyObject *__pyx_v_request; + PyObject *__pyx_r; + PyObject *__pyx_1 = 0; + PyObject *__pyx_2 = 0; + PyObject *__pyx_3 = 0; + static char *__pyx_argnames[] = {"command","input",0}; + if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "ss", __pyx_argnames, &__pyx_v_command, &__pyx_v_input)) return 0; + Py_INCREF(__pyx_v_self); + __pyx_v_request = Py_None; Py_INCREF(Py_None); + + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":629 */ + __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; goto __pyx_L1;} + Py_INCREF(__pyx_v_self); + PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_self); + __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_6Recode_Request), __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; goto __pyx_L1;} + Py_DECREF(__pyx_1); __pyx_1 = 0; + Py_DECREF(__pyx_v_request); + __pyx_v_request = __pyx_2; + __pyx_2 = 0; + + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":630 */ + __pyx_1 = PyObject_GetAttr(__pyx_v_request, __pyx_n_scan); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; goto __pyx_L1;} + __pyx_2 = PyString_FromString(__pyx_v_command); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; goto __pyx_L1;} + __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2); + __pyx_2 = 0; + __pyx_2 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; goto __pyx_L1;} + Py_DECREF(__pyx_1); __pyx_1 = 0; + Py_DECREF(__pyx_3); __pyx_3 = 0; + Py_DECREF(__pyx_2); __pyx_2 = 0; + + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":631 */ + __pyx_1 = PyObject_GetAttr(__pyx_v_request, __pyx_n_string); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 631; goto __pyx_L1;} + __pyx_3 = PyString_FromString(__pyx_v_input); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 631; goto __pyx_L1;} + __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 631; goto __pyx_L1;} + PyTuple_SET_ITEM(__pyx_2, 0, __pyx_3); + __pyx_3 = 0; + __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 631; goto __pyx_L1;} + Py_DECREF(__pyx_1); __pyx_1 = 0; + Py_DECREF(__pyx_2); __pyx_2 = 0; + __pyx_r = __pyx_3; + __pyx_3 = 0; + goto __pyx_L0; + + __pyx_r = Py_None; Py_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1:; + Py_XDECREF(__pyx_1); + Py_XDECREF(__pyx_2); + Py_XDECREF(__pyx_3); + __Pyx_AddTraceback("Recode.Outer.recode"); + __pyx_r = 0; + __pyx_L0:; + Py_DECREF(__pyx_v_request); + Py_DECREF(__pyx_v_self); + return __pyx_r; +} + static int __pyx_f_6Recode_7Request___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static int __pyx_f_6Recode_7Request___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { struct __pyx_obj_6Recode_Outer *__pyx_v_outer = 0; @@ -500,7 +564,7 @@ static int __pyx_f_6Recode_7Request___init__(PyObject *__pyx_v_self, PyObject *_ if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_outer)) return -1; Py_INCREF(__pyx_v_self); Py_INCREF(__pyx_v_outer); - if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_outer), __pyx_ptype_6Recode_Outer, 1, "outer")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 632; goto __pyx_L1;} + if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_outer), __pyx_ptype_6Recode_Outer, 1, "outer")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; goto __pyx_L1;} ((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request = recode_new_request(__pyx_v_outer->outer); __pyx_r = 0; @@ -539,25 +603,25 @@ static PyObject *__pyx_f_6Recode_7Request_set_verbose(PyObject *__pyx_v_self, Py Py_INCREF(__pyx_v_flag); __pyx_v_previous = Py_None; Py_INCREF(Py_None); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":639 */ - __pyx_1 = PyInt_FromLong((((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->verbose_flag != 0)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":645 */ + __pyx_1 = PyInt_FromLong((((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->verbose_flag != 0)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; goto __pyx_L1;} Py_DECREF(__pyx_v_previous); __pyx_v_previous = __pyx_1; __pyx_1 = 0; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":640 */ - __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_int); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;} - __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":646 */ + __pyx_1 = __Pyx_GetName(__pyx_b, __pyx_n_int); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} + __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} Py_INCREF(__pyx_v_flag); PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_flag); - __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;} + __pyx_3 = PyObject_CallObject(__pyx_1, __pyx_2); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} Py_DECREF(__pyx_1); __pyx_1 = 0; Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_4 = ((enum __pyx_t_6Recode_bool)PyInt_AsLong(__pyx_3)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; goto __pyx_L1;} + __pyx_4 = ((enum __pyx_t_6Recode_bool)PyInt_AsLong(__pyx_3)); if (PyErr_Occurred()) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} Py_DECREF(__pyx_3); __pyx_3 = 0; ((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->verbose_flag = __pyx_4; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":641 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":647 */ Py_INCREF(__pyx_v_previous); __pyx_r = __pyx_v_previous; goto __pyx_L0; @@ -590,20 +654,20 @@ static PyObject *__pyx_f_6Recode_7Request_scan(PyObject *__pyx_v_self, PyObject Py_INCREF(__pyx_v_self); __pyx_v_ok = Py_None; Py_INCREF(Py_None); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":644 */ - __pyx_1 = PyInt_FromLong(recode_scan_request(((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request,__pyx_v_text)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":650 */ + __pyx_1 = PyInt_FromLong(recode_scan_request(((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request,__pyx_v_text)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; goto __pyx_L1;} Py_DECREF(__pyx_v_ok); __pyx_v_ok = __pyx_1; __pyx_1 = 0; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":645 */ - __pyx_2 = PyObject_IsTrue(__pyx_v_ok); if (__pyx_2 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":651 */ + __pyx_2 = PyObject_IsTrue(__pyx_v_ok); if (__pyx_2 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; goto __pyx_L1;} __pyx_3 = (!__pyx_2); if (__pyx_3) { - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} + __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; goto __pyx_L1;} __Pyx_Raise(__pyx_1, 0, 0); Py_DECREF(__pyx_1); __pyx_1 = 0; - {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; goto __pyx_L1;} + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; goto __pyx_L1;} goto __pyx_L2; } __pyx_L2:; @@ -636,38 +700,38 @@ static PyObject *__pyx_f_6Recode_7Request_pair_sequence(PyObject *__pyx_v_self, Py_INCREF(__pyx_v_self); __pyx_v_list = Py_None; Py_INCREF(Py_None); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":649 */ - __pyx_1 = PyList_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 649; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":655 */ + __pyx_1 = PyList_New(0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; goto __pyx_L1;} Py_DECREF(__pyx_v_list); __pyx_v_list = __pyx_1; __pyx_1 = 0; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":652 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":658 */ __pyx_2 = ((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->sequence_length; for (__pyx_v_counter = 0; __pyx_v_counter < __pyx_2; ++__pyx_v_counter) { - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":653 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":659 */ __pyx_v_step = (((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->sequence_array[__pyx_v_counter]); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":654 */ - __pyx_1 = PyObject_GetAttr(__pyx_v_list, __pyx_n_append); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} - __pyx_3 = PyString_FromString(__pyx_v_step.before->name); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} - __pyx_4 = PyString_FromString(__pyx_v_step.after->name); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} - __pyx_5 = PyTuple_New(2); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":660 */ + __pyx_1 = PyObject_GetAttr(__pyx_v_list, __pyx_n_append); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} + __pyx_3 = PyString_FromString(__pyx_v_step.before->name); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} + __pyx_4 = PyString_FromString(__pyx_v_step.after->name); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} + __pyx_5 = PyTuple_New(2); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} PyTuple_SET_ITEM(__pyx_5, 0, __pyx_3); PyTuple_SET_ITEM(__pyx_5, 1, __pyx_4); __pyx_3 = 0; __pyx_4 = 0; - __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} + __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} PyTuple_SET_ITEM(__pyx_3, 0, __pyx_5); __pyx_5 = 0; - __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; goto __pyx_L1;} + __pyx_4 = PyObject_CallObject(__pyx_1, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 660; goto __pyx_L1;} Py_DECREF(__pyx_1); __pyx_1 = 0; Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_4); __pyx_4 = 0; } - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":655 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":661 */ Py_INCREF(__pyx_v_list); __pyx_r = __pyx_v_list; goto __pyx_L0; @@ -703,32 +767,32 @@ static PyObject *__pyx_f_6Recode_7Request_format_table(PyObject *__pyx_v_self, P Py_INCREF(__pyx_v_self); __pyx_v_ok = Py_None; Py_INCREF(Py_None); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":660 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":666 */ __pyx_v_outer = ((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request->outer; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":661 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":667 */ __pyx_v_saved = __pyx_v_outer->iconv_pivot->ignore; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":662 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":668 */ __pyx_v_outer->iconv_pivot->ignore = __pyx_e_6Recode_true; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":663 */ - __pyx_1 = PyInt_FromLong(recode_format_table(((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request,((enum recode_programming_language)__pyx_v_language),__pyx_v_charset)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 663; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":669 */ + __pyx_1 = PyInt_FromLong(recode_format_table(((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request,((enum recode_programming_language)__pyx_v_language),__pyx_v_charset)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 669; goto __pyx_L1;} Py_DECREF(__pyx_v_ok); __pyx_v_ok = __pyx_1; __pyx_1 = 0; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":665 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":671 */ __pyx_v_outer->iconv_pivot->ignore = __pyx_v_saved; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":666 */ - __pyx_2 = PyObject_IsTrue(__pyx_v_ok); if (__pyx_2 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":672 */ + __pyx_2 = PyObject_IsTrue(__pyx_v_ok); if (__pyx_2 < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 672; goto __pyx_L1;} __pyx_3 = (!__pyx_2); if (__pyx_3) { - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; goto __pyx_L1;} + __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; goto __pyx_L1;} __Pyx_Raise(__pyx_1, 0, 0); Py_DECREF(__pyx_1); __pyx_1 = 0; - {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; goto __pyx_L1;} + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; goto __pyx_L1;} goto __pyx_L2; } __pyx_L2:; @@ -756,22 +820,22 @@ static PyObject *__pyx_f_6Recode_7Request_string(PyObject *__pyx_v_self, PyObjec if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "s", __pyx_argnames, &__pyx_v_text)) return 0; Py_INCREF(__pyx_v_self); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":671 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":677 */ __pyx_v_result = recode_string(((struct __pyx_obj_6Recode_Request *)__pyx_v_self)->request,__pyx_v_text); - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":672 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":678 */ __pyx_1 = (__pyx_v_result == NULL); if (__pyx_1) { - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; goto __pyx_L1;} + __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_n_error); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; goto __pyx_L1;} __Pyx_Raise(__pyx_2, 0, 0); Py_DECREF(__pyx_2); __pyx_2 = 0; - {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; goto __pyx_L1;} + {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; goto __pyx_L1;} goto __pyx_L2; } __pyx_L2:; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":674 */ - __pyx_2 = PyString_FromString(__pyx_v_result); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 674; goto __pyx_L1;} + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":680 */ + __pyx_2 = PyString_FromString(__pyx_v_result); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 680; goto __pyx_L1;} __pyx_r = __pyx_2; __pyx_2 = 0; goto __pyx_L0; @@ -787,70 +851,6 @@ static PyObject *__pyx_f_6Recode_7Request_string(PyObject *__pyx_v_self, PyObjec return __pyx_r; } -static PyObject *__pyx_n_scan; -static PyObject *__pyx_n_string; - -static PyObject *__pyx_f_6Recode_recode(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static PyObject *__pyx_f_6Recode_recode(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - char *__pyx_v_text; - char *__pyx_v_string; - PyObject *__pyx_v_request; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - static char *__pyx_argnames[] = {"text","string",0}; - if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "ss", __pyx_argnames, &__pyx_v_text, &__pyx_v_string)) return 0; - __pyx_v_request = Py_None; Py_INCREF(Py_None); - - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":693 */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_n_global_outer); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; goto __pyx_L1;} - __pyx_2 = PyTuple_New(1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1); - __pyx_1 = 0; - __pyx_1 = PyObject_CallObject(((PyObject*)__pyx_ptype_6Recode_Request), __pyx_2); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(__pyx_v_request); - __pyx_v_request = __pyx_1; - __pyx_1 = 0; - - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":694 */ - __pyx_2 = PyObject_GetAttr(__pyx_v_request, __pyx_n_scan); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; goto __pyx_L1;} - __pyx_1 = PyString_FromString(__pyx_v_text); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; goto __pyx_L1;} - __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1); - __pyx_1 = 0; - __pyx_1 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(__pyx_3); __pyx_3 = 0; - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":695 */ - __pyx_2 = PyObject_GetAttr(__pyx_v_request, __pyx_n_string); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; goto __pyx_L1;} - __pyx_3 = PyString_FromString(__pyx_v_string); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; goto __pyx_L1;} - __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; goto __pyx_L1;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3); - __pyx_3 = 0; - __pyx_3 = PyObject_CallObject(__pyx_2, __pyx_1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; goto __pyx_L1;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_r = __pyx_3; - __pyx_3 = 0; - goto __pyx_L0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - __Pyx_AddTraceback("Recode.recode"); - __pyx_r = 0; - __pyx_L0:; - Py_DECREF(__pyx_v_request); - return __pyx_r; -} - static __Pyx_InternTabEntry __pyx_intern_tab[] = { {&__pyx_n_ALIAS_FIND_AS_CHARSET, "ALIAS_FIND_AS_CHARSET"}, {&__pyx_n_ALIAS_FIND_AS_EITHER, "ALIAS_FIND_AS_EITHER"}, @@ -914,7 +914,6 @@ static __Pyx_InternTabEntry __pyx_intern_tab[] = { {&__pyx_n_USER_ERROR, "USER_ERROR"}, {&__pyx_n_append, "append"}, {&__pyx_n_error, "error"}, - {&__pyx_n_global_outer, "global_outer"}, {&__pyx_n_int, "int"}, {&__pyx_n_scan, "scan"}, {&__pyx_n_string, "string"}, @@ -956,6 +955,7 @@ static struct PyMethodDef __pyx_methods_6Recode_Outer[] = { {"all_surfaces", (PyCFunction)__pyx_f_6Recode_5Outer_all_surfaces, METH_VARARGS|METH_KEYWORDS, 0}, {"concise_charset", (PyCFunction)__pyx_f_6Recode_5Outer_concise_charset, METH_VARARGS|METH_KEYWORDS, 0}, {"full_charset", (PyCFunction)__pyx_f_6Recode_5Outer_full_charset, METH_VARARGS|METH_KEYWORDS, 0}, + {"recode", (PyCFunction)__pyx_f_6Recode_5Outer_recode, METH_VARARGS|METH_KEYWORDS, 0}, {0, 0, 0, 0} }; @@ -1234,7 +1234,6 @@ PyTypeObject __pyx_type_6Recode_Request = { }; static struct PyMethodDef __pyx_methods[] = { - {"recode", (PyCFunction)__pyx_f_6Recode_recode, METH_VARARGS|METH_KEYWORDS, 0}, {0, 0, 0, 0} }; @@ -1246,7 +1245,6 @@ PyMODINIT_FUNC initRecode(void) { PyObject *__pyx_2 = 0; PyObject *__pyx_3 = 0; PyObject *__pyx_4 = 0; - PyObject *__pyx_5 = 0; __pyx_init_filenames(); __pyx_m = Py_InitModule4("Recode", __pyx_methods, 0, 0, PYTHON_API_VERSION); if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; goto __pyx_L1;}; @@ -1258,8 +1256,8 @@ PyMODINIT_FUNC initRecode(void) { if (PyType_Ready(&__pyx_type_6Recode_Outer) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 570; goto __pyx_L1;} if (PyObject_SetAttrString(__pyx_m, "Outer", (PyObject *)&__pyx_type_6Recode_Outer) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 570; goto __pyx_L1;} __pyx_ptype_6Recode_Outer = &__pyx_type_6Recode_Outer; - if (PyType_Ready(&__pyx_type_6Recode_Request) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; goto __pyx_L1;} - if (PyObject_SetAttrString(__pyx_m, "Request", (PyObject *)&__pyx_type_6Recode_Request) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; goto __pyx_L1;} + if (PyType_Ready(&__pyx_type_6Recode_Request) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; goto __pyx_L1;} + if (PyObject_SetAttrString(__pyx_m, "Request", (PyObject *)&__pyx_type_6Recode_Request) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; goto __pyx_L1;} __pyx_ptype_6Recode_Request = &__pyx_type_6Recode_Request; /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":489 */ @@ -1590,19 +1588,13 @@ PyMODINIT_FUNC initRecode(void) { __pyx_k5 = __pyx_4; __pyx_4 = 0; - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":690 */ - __pyx_5 = PyObject_CallObject(((PyObject*)__pyx_ptype_6Recode_Outer), 0); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; goto __pyx_L1;} - if (PyObject_SetAttr(__pyx_m, __pyx_n_global_outer, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; goto __pyx_L1;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - - /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":692 */ + /* "/bpi/phenix/home/pinard/entretien/recode/tests/Recode.pyx":675 */ return; __pyx_L1:; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_2); Py_XDECREF(__pyx_3); Py_XDECREF(__pyx_4); - Py_XDECREF(__pyx_5); __Pyx_AddTraceback("Recode"); } diff --git a/tests/Recode.pyx b/tests/Recode.pyx index 1cd86a5..c7e07fe 100644 --- a/tests/Recode.pyx +++ b/tests/Recode.pyx @@ -624,6 +624,12 @@ cdef class Outer: if not ok: raise error + # Lazy, all in one call. + def recode(self, char *command, char *input): + request = Request(self) + request.scan(command) + return request.string(input) + # Recode library at REQUEST level. cdef class Request: @@ -684,12 +690,3 @@ cdef class Request: #bool recode_file_to_buffer( # RECODE_CONST_REQUEST, FILE *, char **, size_t *, size_t *) #bool recode_file_to_file(RECODE_CONST_REQUEST, FILE *, FILE *) - -# Lazy, all in one call. - -global_outer = Outer() - -def recode(char *text, char *string): - request = Request(global_outer) - request.scan(text) - return request.string(string) diff --git a/tests/common.py b/tests/common.py index 547bb7d..029e66e 100644 --- a/tests/common.py +++ b/tests/common.py @@ -10,7 +10,11 @@ try: import Recode except ImportError: # The Python API has not been installed. - Recode = None + outer = None + outer_iconv = None +else: + outer = Recode.Outer(iconv=False) + outer_iconv = Recode.Outer(iconv=True) class Run(dict): @@ -36,7 +40,7 @@ def setup_module(module): 'LC_ALL', 'LC_MESSAGES', 'LC_COLLATE'): if variable in os.environ: del os.environ[variable] - run.external = Recode is None + run.external = outer is None import tempfile run.work = tempfile.mktemp() @@ -65,9 +69,14 @@ def recode_output(input): if run.external: file(run.work, 'wb').write(input) return external_output('$R %s < %s' % (run.request, run.work)) - if Recode is None: + if outer is None: py.test.skip() - return Recode.recode(run.request, input) + return outer.recode(run.request, input) + +def recode_iconv_output(input): + if run.external or outer_iconv is None: + py.test.skip() + return outer_iconv.recode(run.request, input) def recode_back_output(input): before, after = run.request.split('..') @@ -75,10 +84,10 @@ def recode_back_output(input): file(run.work, 'wb').write(input) external_output('$R %s %s' % (run.request, run.work)) return external_output('$R %s..%s < %s' % (after, before, run.work)) - if Recode is None: + if outer is None: py.test.skip() - temp = Recode.recode(run.request, input) - return Recode.recode('%s..%s' % (after, before), temp) + temp = outer.recode(run.request, input) + return outer.recode('%s..%s' % (after, before), temp) def validate(input, expected): output = recode_output(input) diff --git a/tests/t70_inferenz.py b/tests/t70_inferenz.py new file mode 100644 index 0000000..bd9ca2d --- /dev/null +++ b/tests/t70_inferenz.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +import common +from common import setup_module, teardown_module + +# Some characters were lost while u8..l1 recoding goes. +# Submitted 2001-09-28 by Volker Wysk . + +input = '''\ +:- module(inferenz, [anfrage/2, anfrage/1, anfrage_l/3, anfrage_l/2, + ohne/4, + loese/4, loese/6, loese_pos/6 + ]). + +:- module_transparent(loese/4). + +loese(Term, Sich, Schr, Prot) :- + ( + Term = (A,B) + *-> + call(Schr, tzk, loese(A), S_1, Prot_1), + call(Schr, tzk, loese(B), S_2, Prot_2), + Sich is min(S_1, S_2), + Prot = k:(Prot_1,Prot_2) + ; + Term = (A;B) + *-> + ( call(Schr, tzd, loese(A), Sich, Prot_1) + ; call(Schr, tzd, loese(B), Sich, Prot_1) + ), + Prot = d:Prot_1 + ; + Term = (\+ (A,B)) + *-> + verneint(A,A_1), + verneint(B,B_1), + call(Schr, umf, loese(A_1;B_1), Sich, Prot) + ; + Term = (\+ (A;B)) + *-> + verneint(A,A_1), + verneint(B,B_1), + call(Schr, umf, loese(A_1,B_1), Sich, Prot) + ; + Term = (\+ \+ Term_1) + *-> + call(Schr, umf, loese(Term_1), Sich, Prot) + ; + Term = true + *-> + Sich = 1, + Prot = triv:'' + ; + Term = (\+ true) + *-> + fail + + ; + % Prädikat + ( Term = (+> Term_1) + -> + % positive Anfrage + Fkt = loese_pos(Grad, Vern, Kern) + ; + % abwägende Anfrage + Term_1 = Term, + Fkt = loese(Grad, Vern, Kern) + ), + + % Anfrage ausführen + zerlegen(Term_1, ('', Grad, Vern, Kern, '')), + call(Schr, z, Fkt, Sich, Prot), + Sich > 0 + ). +loese(Grad, Vern, Kern, Sich, Schr, Prot) :- + ( + Vern = true, Kern = (A = B) *-> A = B, Sich = 1 + ; Vern = true, Kern = (A \= B) *-> A \= B, Sich = 1 + ; Vern = true, Kern = (A > B) *-> A > B, Sich = 1 + ; Vern = true, Kern = (A < B) *-> A < B, Sich = 1 + ; Vern = true, Kern = (A >= B) *-> A >= B, Sich = 1 + ; Vern = true, Kern = (A =< B) *-> A =< B, Sich = 1 + ; Vern = true, Kern = (A is B) *-> A is B, Sich = 1 + ; Vern = fail, Kern = (A = B) *-> A \= B, Sich = 1 +''' + +def test_1(): + common.request('u8..l1') + output = common.recode_iconv_output(input) + expected = ''.join(input.splitlines(True)[-6:]) + output = ''.join(output.splitlines(True)[-6:]) + common.assert_or_diff(output, expected) -- 2.40.0