]> granicus.if.org Git - recode/commitdiff
Correct iconv, about loosing characters
authorFrançois Pinard <pinard@iro.umontreal.ca>
Sun, 24 Feb 2008 23:25:29 +0000 (18:25 -0500)
committerFrançois Pinard <pinard@iro.umontreal.ca>
Mon, 10 Mar 2008 00:22:27 +0000 (20:22 -0400)
NEWS
src/ChangeLog
src/iconv.c
tests/ChangeLog
tests/Recode.c
tests/Recode.pyx
tests/common.py
tests/t70_inferenz.py [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 86b9b5db9c03faba3691b3c4876ac8472cadf78d..7e0a66ad05f8346439326c0d07bda681f7d243e6 100644 (file)
--- 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
 ===========
index 27010000478627ab8f2f5a64aba1cfc006975535..ef4ee0b63bf3015921cd202d875c44d94728ebac 100644 (file)
@@ -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  <pinard@iro.umontreal.ca>
 
        * recode.h (RECODE_AUTO_ABORT_FLAG, RECODE_NO_ICONV_FLAG): New.
index b7e2ec45692f06d05c91bb0aaeae066671c58b88..46604e88903ffb7e6b9a5c6e3b053060524598e4 100644 (file)
@@ -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 <pinard@iro.umontreal.ca>, 1999,
    and Bruno Haible <haible@clisp.cons.org>, 2000.
 
 #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;
 }
 
index c396925d2724cb3992b8b90c10126aadfe14eb3b..862d59f2372ce3a237a9cb586476574e752b6aa3 100644 (file)
        (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  <pinard@iro.umontreal.ca>
 
        Increase Recode.so portability, by depending on distutils:
index 413f607a67543415ec69a73c03c32f843546e01c..49a6809dbc3b4d9abf17b25c5f06cf7a65b98f29 100644 (file)
@@ -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");
 }
 
index 1cd86a506c0771a6100c0d26ac5c38228913ef69..c7e07fee4c454821f32db1b450454d5e49f9b972 100644 (file)
@@ -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)
index 547bb7d32792fc9facafaab867d96629edd71ee3..029e66e821777ffb02ffcd6f9c4c5d9c60b2ce88 100644 (file)
@@ -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 (file)
index 0000000..bd9ca2d
--- /dev/null
@@ -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 <post@volker-wysk.de>.
+
+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)