guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. v2.1.0-22-g098818a


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. v2.1.0-22-g098818a
Date: Tue, 14 Feb 2012 13:26:30 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=098818a165bea6cbfee8f56a833bc2e48e4f30b0

The branch, master has been updated
       via  098818a165bea6cbfee8f56a833bc2e48e4f30b0 (commit)
       via  33aadcab8a975753d757924f4eb59fe1223dfbd2 (commit)
       via  03a2eeb0cc032f48f8b789a04a41f37a6459d879 (commit)
       via  6c98257f2ead0855f218369ea7f9a823cdb9727e (commit)
       via  ca2ec018f2131fc137e7bfb9119287d1fa915435 (commit)
      from  aac980de43a0466b968a56607664f5ebbca6b751 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 098818a165bea6cbfee8f56a833bc2e48e4f30b0
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 14 09:35:22 2012 +0100

    scm_from_stringn utf8 optimization
    
    * libguile/strings.c (scm_from_stringn): Optimize scm_from_stringn for
      utf-8.

commit 33aadcab8a975753d757924f4eb59fe1223dfbd2
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 14 14:24:04 2012 +0100

    fix buggy scm_from_utf8_stringn (!)
    
    * libguile/strings.c (scm_from_utf8_stringn): Embarassingly, my
      scm_from_utf8_stringn implementation was buggy for non-ascii
      characters, since October (41d1d984).  Fixed.  Will be tested with the
      next patch.

commit 03a2eeb0cc032f48f8b789a04a41f37a6459d879
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 14 14:01:52 2012 +0100

    ports: avoid adding port table entries and finalizers if possible
    
    * libguile/ports.h (scm_t_port_type_flags, scm_t_ptob_descriptor): Add
      flags to ptob descriptors.
    
    * libguile/ports.c (scm_set_port_flush): Set the SCM_PORT_TYPE_HAS_FLUSH
      flag here.
      (scm_c_make_port_with_encoding): Only add ports to the table if
      SCM_PORT_TYPE_HAS_FLUSH is set.  Only add finalizers to ports if there
      is a free function.
      (scm_close_port): Inline scm_i_remove_port here.  Only remove from the
      weak set if SCM_PORT_TYPE_HAS_FLUSH is set.
      (scm_set_port_revealed_x): Add a comment.

commit 6c98257f2ead0855f218369ea7f9a823cdb9727e
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 14 13:09:34 2012 +0100

    refactor port encoding modes: utf-8 and iconv
    
    * libguile/ports.h (struct scm_t_port): Add a flag for the port encoding
      mode: UTF8 or iconv.  The iconv descriptors are now in a separate
      structure so that we can avoid attaching finalizers to the ports
      themselves, in some cases.
    
    * libguile/ports.c (scm_c_make_port_with_encoding): Init the encoding
      mode.
      (scm_i_remove_port): Adapt to call close_iconv_descriptors.
      (finalize_iconv_descriptors, open_iconv_descriptors):
      (close_iconv_descriptors): New infrastructure to manage iconv
      descriptors.
      (scm_i_port_iconv_descriptors): New internal helper.
      (scm_i_set_port_encoding_x): Use open_iconv_descriptors, if needed.
      (get_iconv_codepoint): Use pt->iconv_descriptors.
      (get_codepoint): Check the port encoding mode flags.
    
    * libguile/print.c (display_string_using_iconv): Use
      scm_i_port_iconv_descriptors.
      (display_string): Use pt->encoding_mode flag.

commit ca2ec018f2131fc137e7bfb9119287d1fa915435
Author: Andy Wingo <address@hidden>
Date:   Tue Feb 14 00:11:39 2012 +0100

    string ports simplification
    
    * libguile/strports.c (st_fill_input): Rename from stfill_buffer, and
      remove an unneeded scm_return_first_int.
      (st_resize_port): Minor variable renaming.
      (st_write): Keep read_pos updated to be the same as write_pos.  If we
      need to resize, do so only once.
      (st_seek): No more need to flush.
      (st_truncate): Update read_pos here too.
      (scm_mkstrport): No need to flush here.
      (scm_strport_to_string): Just call scm_from_stringn; rely on it to
      detect the latin1 case.
      (scm_make_stptob): No more flush function.

-----------------------------------------------------------------------

Summary of changes:
 libguile/ports.c    |  263 +++++++++++++++++++++++++++++++--------------------
 libguile/ports.h    |   34 +++++--
 libguile/print.c    |   15 +--
 libguile/strings.c  |   14 +--
 libguile/strports.c |   85 ++++-------------
 5 files changed, 215 insertions(+), 196 deletions(-)

diff --git a/libguile/ports.c b/libguile/ports.c
index 7acf062..c1da25e 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -250,7 +250,9 @@ scm_set_port_close (scm_t_bits tc, int (*close) (SCM))
 void
 scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port))
 {
-   scm_c_port_type_ref (SCM_TC2PTOBNUM (tc))->flush = flush;
+  scm_t_ptob_descriptor *ptob = scm_c_port_type_ref (SCM_TC2PTOBNUM (tc));
+  ptob->flush = flush;
+  ptob->flags |= SCM_PORT_TYPE_HAS_FLUSH;
 }
 
 void
@@ -563,20 +565,12 @@ finalize_port (GC_PTR ptr, GC_PTR data)
       else
        {
           scm_t_ptob_descriptor *ptob = SCM_PORT_DESCRIPTOR (port);
-         scm_t_port *entry;
 
          if (ptob->free)
            /* Yes, I really do mean `free' rather than `close'.  `close'
               is for explicit `close-port' by user.  */
            ptob->free (port);
 
-         entry = SCM_PTAB_ENTRY (port);
-
-         if (entry->input_cd != (iconv_t) -1)
-           iconv_close (entry->input_cd);
-         if (entry->output_cd != (iconv_t) -1)
-           iconv_close (entry->output_cd);
-
          SCM_SETSTREAM (port, 0);
          SCM_CLR_PORT_OPEN_FLAG (port);
 
@@ -613,16 +607,18 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned 
long mode_bits,
   entry->port = ret;
   entry->stream = stream;
   entry->encoding = encoding ? scm_gc_strdup (encoding, "port") : NULL;
-  /* The conversion descriptors will be opened lazily.  */
-  entry->input_cd = (iconv_t) -1;
-  entry->output_cd = (iconv_t) -1;
+  if (encoding && strcmp (encoding, "UTF-8") == 0)
+    entry->encoding_mode = SCM_PORT_ENCODING_MODE_UTF8;
+  else
+    entry->encoding_mode = SCM_PORT_ENCODING_MODE_ICONV;
   entry->ilseq_handler = handler;
+  entry->iconv_descriptors = NULL;
 
-  scm_weak_set_add_x (scm_i_port_weak_set, ret);
+  if (SCM_PORT_DESCRIPTOR (ret)->flags & SCM_PORT_TYPE_HAS_FLUSH)
+    scm_weak_set_add_x (scm_i_port_weak_set, ret);
 
-  /* For each new port, register a finalizer so that it port type's free
-     function can be invoked eventually.  */
-  register_finalizer_for_port (ret);
+  if (SCM_PORT_DESCRIPTOR (ret)->free)
+    register_finalizer_for_port (ret);
 
   return ret;
 }
@@ -642,37 +638,6 @@ scm_new_port_table_entry (scm_t_bits tag)
   return scm_c_make_port (tag, 0, 0);
 }
 
-/* Remove a port from the table and destroy it.  */
-
-static void
-scm_i_remove_port (SCM port)
-#define FUNC_NAME "scm_remove_port"
-{
-  scm_t_port *p;
-
-  p = SCM_PTAB_ENTRY (port);
-  scm_port_non_buffer (p);
-  SCM_SETPTAB_ENTRY (port, 0);
-  scm_weak_set_remove_x (scm_i_port_weak_set, port);
-
-  p->putback_buf = NULL;
-  p->putback_buf_size = 0;
-
-  if (p->input_cd != (iconv_t) -1)
-    {
-      iconv_close (p->input_cd);
-      p->input_cd = (iconv_t) -1;
-    }
-  
-  if (p->output_cd != (iconv_t) -1)
-    {
-      iconv_close (p->output_cd);
-      p->output_cd = (iconv_t) -1;
-    }
-}
-#undef FUNC_NAME
-
-
 
 
 /* Predicates.  */
@@ -737,6 +702,8 @@ SCM_DEFINE (scm_eof_object_p, "eof-object?", 1, 0, 0,
 
 /* Closing ports.  */
 
+static void close_iconv_descriptors (scm_t_iconv_descriptors *id);
+
 /* scm_close_port
  * Call the close operation on a port object. 
  * see also scm_close.
@@ -751,6 +718,7 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
            "descriptors.")
 #define FUNC_NAME s_scm_close_port
 {
+  scm_t_port *p;
   int rv;
 
   port = SCM_COERCE_OUTPORT (port);
@@ -762,8 +730,26 @@ SCM_DEFINE (scm_close_port, "close-port", 1, 0, 0,
     rv = SCM_PORT_DESCRIPTOR (port)->close (port);
   else
     rv = 0;
-  scm_i_remove_port (port);
+
+  p = SCM_PTAB_ENTRY (port);
+
+  scm_port_non_buffer (p);
+  SCM_SETPTAB_ENTRY (port, 0);
+
+  if (SCM_PORT_DESCRIPTOR (port)->flags & SCM_PORT_TYPE_HAS_FLUSH)
+    scm_weak_set_remove_x (scm_i_port_weak_set, port);
+
+  p->putback_buf = NULL;
+  p->putback_buf_size = 0;
+
+  if (p->iconv_descriptors)
+    {
+      close_iconv_descriptors (p->iconv_descriptors);
+      p->iconv_descriptors = NULL;
+    }
+
   SCM_CLR_PORT_OPEN_FLAG (port);
+
   return scm_from_bool (rv >= 0);
 }
 #undef FUNC_NAME
@@ -852,73 +838,145 @@ scm_i_default_port_encoding (void)
     }
 }
 
-void
-scm_i_set_port_encoding_x (SCM port, const char *encoding)
+static void
+finalize_iconv_descriptors (GC_PTR ptr, GC_PTR data)
 {
-  scm_t_port *pt;
-  iconv_t new_input_cd, new_output_cd;
-
-  new_input_cd = (iconv_t) -1;
-  new_output_cd = (iconv_t) -1;
+  close_iconv_descriptors (ptr);
+}
 
-  /* Set the character encoding for this port.  */
-  pt = SCM_PTAB_ENTRY (port);
+static scm_t_iconv_descriptors *
+open_iconv_descriptors (const char *encoding, int reading, int writing)
+{
+  scm_t_iconv_descriptors *id;
+  iconv_t input_cd, output_cd;
 
-  if (encoding == NULL)
-    encoding = "ISO-8859-1";
+  input_cd = (iconv_t) -1;
+  output_cd = (iconv_t) -1;
 
-  if (pt->encoding != encoding)
-    pt->encoding = scm_gc_strdup (encoding, "port");
+  if (reading)
+    {
+      /* Open an input iconv conversion descriptor, from ENCODING
+         to UTF-8.  We choose UTF-8, not UTF-32, because iconv
+         implementations can typically convert from anything to
+         UTF-8, but not to UTF-32 (see
+         
<http://lists.gnu.org/archive/html/bug-libunistring/2010-09/msg00007.html>).  */
+
+      /* Assume opening an iconv descriptor causes about 16 KB of
+         allocation.  */
+      scm_gc_register_allocation (16 * 1024);
+
+      input_cd = iconv_open ("UTF-8", encoding);
+      if (input_cd == (iconv_t) -1)
+        goto invalid_encoding;
+    }
 
-  /* If ENCODING is UTF-8, then no conversion descriptor is opened
-     because we do I/O ourselves.  This saves 100+ KiB for each
-     descriptor.  */
-  if (strcmp (encoding, "UTF-8"))
+  if (writing)
     {
-      if (SCM_CELL_WORD_0 (port) & SCM_RDNG)
-       {
-         /* Open an input iconv conversion descriptor, from ENCODING
-            to UTF-8.  We choose UTF-8, not UTF-32, because iconv
-            implementations can typically convert from anything to
-            UTF-8, but not to UTF-32 (see
-            
<http://lists.gnu.org/archive/html/bug-libunistring/2010-09/msg00007.html>).  */
-         new_input_cd = iconv_open ("UTF-8", encoding);
-         if (new_input_cd == (iconv_t) -1)
-           goto invalid_encoding;
-       }
+      /* Assume opening an iconv descriptor causes about 16 KB of
+         allocation.  */
+      scm_gc_register_allocation (16 * 1024);
 
-      if (SCM_CELL_WORD_0 (port) & SCM_WRTNG)
-       {
-         new_output_cd = iconv_open (encoding, "UTF-8");
-         if (new_output_cd == (iconv_t) -1)
-           {
-             if (new_input_cd != (iconv_t) -1)
-               iconv_close (new_input_cd);
-             goto invalid_encoding;
-           }
-       }
+      output_cd = iconv_open (encoding, "UTF-8");
+      if (output_cd == (iconv_t) -1)
+        {
+          if (input_cd != (iconv_t) -1)
+            iconv_close (input_cd);
+          goto invalid_encoding;
+        }
     }
 
-  if (pt->input_cd != (iconv_t) -1)
-    iconv_close (pt->input_cd);
-  if (pt->output_cd != (iconv_t) -1)
-    iconv_close (pt->output_cd);
+  id = scm_gc_malloc_pointerless (sizeof (*id), "iconv descriptors");
+  id->input_cd = input_cd;
+  id->output_cd = output_cd;
 
-  pt->input_cd = new_input_cd;
-  pt->output_cd = new_output_cd;
+  {
+    GC_finalization_proc prev_finalizer;
+    GC_PTR prev_finalization_data;
+
+    /* Register a finalizer to close the descriptors.  */
+    GC_REGISTER_FINALIZER_NO_ORDER (id, finalize_iconv_descriptors, 0,
+                                    &prev_finalizer, &prev_finalization_data);
+  }
 
-  return;
+  return id;
 
  invalid_encoding:
   {
     SCM err;
     err = scm_from_locale_string (encoding);
-    scm_misc_error ("scm_i_set_port_encoding_x",
+    scm_misc_error ("open_iconv_descriptors",
                    "invalid or unknown character encoding ~s",
                    scm_list_1 (err));
   }
 }
 
+static void
+close_iconv_descriptors (scm_t_iconv_descriptors *id)
+{
+  if (id->input_cd != (iconv_t) -1)
+    iconv_close (id->input_cd);
+  if (id->output_cd != (iconv_t) -1)
+    iconv_close (id->output_cd);
+  id->input_cd = (void *) -1;
+  id->output_cd = (void *) -1;
+}
+
+scm_t_iconv_descriptors *
+scm_i_port_iconv_descriptors (SCM port)
+{
+  scm_t_port *pt;
+
+  pt = SCM_PTAB_ENTRY (port);
+
+  assert (pt->encoding_mode == SCM_PORT_ENCODING_MODE_ICONV);
+
+  if (!pt->iconv_descriptors)
+    {
+      if (!pt->encoding)
+        pt->encoding = "ISO-8859-1";
+      pt->iconv_descriptors =
+        open_iconv_descriptors (pt->encoding,
+                                SCM_INPUT_PORT_P (port),
+                                SCM_OUTPUT_PORT_P (port));
+    }
+
+  return pt->iconv_descriptors;
+}
+
+void
+scm_i_set_port_encoding_x (SCM port, const char *encoding)
+{
+  scm_t_port *pt;
+  scm_t_iconv_descriptors *prev;
+
+  /* Set the character encoding for this port.  */
+  pt = SCM_PTAB_ENTRY (port);
+  prev = pt->iconv_descriptors;
+
+  if (encoding == NULL)
+    encoding = "ISO-8859-1";
+
+  if (strcmp (encoding, "UTF-8") == 0)
+    {
+      pt->encoding = "UTF-8";
+      pt->encoding_mode = SCM_PORT_ENCODING_MODE_UTF8;
+      pt->iconv_descriptors = NULL;
+    }
+  else
+    {
+      /* Open descriptors before mutating the port. */
+      pt->iconv_descriptors =
+        open_iconv_descriptors (encoding,
+                                SCM_INPUT_PORT_P (port),
+                                SCM_OUTPUT_PORT_P (port));
+      pt->encoding = scm_gc_strdup (encoding, "port");
+      pt->encoding_mode = SCM_PORT_ENCODING_MODE_ICONV;
+    }
+
+  if (prev)
+    close_iconv_descriptors (prev);
+}
+
 SCM_DEFINE (scm_port_encoding, "port-encoding", 1, 0, 0,
            (SCM port),
            "Returns, as a string, the character encoding that @var{port}\n"
@@ -1192,6 +1250,9 @@ SCM_DEFINE (scm_set_port_revealed_x, 
"set-port-revealed!", 2, 0, 0,
   int r;
   scm_i_pthread_mutex_t *lock;
   
+  /* FIXME: It doesn't make sense to manipulate revealed counts on ports
+     without a free function.  */
+
   port = SCM_COERCE_OUTPORT (port);
   SCM_VALIDATE_OPENPORT (1, port);
   r = scm_to_int (rcount);
@@ -1616,13 +1677,13 @@ static int
 get_iconv_codepoint (SCM port, scm_t_wchar *codepoint,
                     char buf[SCM_MBCHAR_BUF_SIZE], size_t *len)
 {
-  scm_t_port *pt;
+  scm_t_iconv_descriptors *id;
   int err, byte_read;
   size_t bytes_consumed, output_size;
   char *output;
   scm_t_uint8 utf8_buf[SCM_MBCHAR_BUF_SIZE];
 
-  pt = SCM_PTAB_ENTRY (port);
+  id = scm_i_port_iconv_descriptors (port);
 
   for (output_size = 0, output = (char *) utf8_buf,
         bytes_consumed = 0, err = 0;
@@ -1652,8 +1713,7 @@ get_iconv_codepoint (SCM port, scm_t_wchar *codepoint,
       input_left = bytes_consumed + 1;
       output_left = sizeof (utf8_buf);
 
-      done = iconv (pt->input_cd, &input, &input_left,
-                   &output, &output_left);
+      done = iconv (id->input_cd, &input, &input_left, &output, &output_left);
       if (done == (size_t) -1)
        {
          err = errno;
@@ -1689,12 +1749,7 @@ get_codepoint (SCM port, scm_t_wchar *codepoint,
   int err;
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->input_cd == (iconv_t) -1)
-    /* Initialize the conversion descriptors, if needed.  */
-    scm_i_set_port_encoding_x (port, pt->encoding);
-
-  /* FIXME: In 2.1, add a flag to determine whether a port is UTF-8.  */
-  if (pt->input_cd == (iconv_t) -1)
+  if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8)
     err = get_utf8_codepoint (port, codepoint, (scm_t_uint8 *) buf, len);
   else
     err = get_iconv_codepoint (port, codepoint, buf, len);
diff --git a/libguile/ports.h b/libguile/ports.h
index f4a1908..b44ec66 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -4,7 +4,7 @@
 #define SCM_PORTS_H
 
 /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
- *   2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ *   2006, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -48,6 +48,20 @@ typedef enum scm_t_port_rw_active {
   SCM_PORT_WRITE = 2
 } scm_t_port_rw_active;
 
+typedef enum scm_t_port_encoding_mode {
+  SCM_PORT_ENCODING_MODE_UTF8,
+  SCM_PORT_ENCODING_MODE_ICONV
+} scm_t_port_encoding_mode;
+
+/* This is a separate object so that only those ports that use iconv
+   cause finalizers to be registered.  */
+typedef struct scm_t_iconv_descriptors
+{
+  /* input/output iconv conversion descriptors */
+  void *input_cd;
+  void *output_cd;
+} scm_t_iconv_descriptors;
+
 /* C representation of a Scheme port.  */
 
 typedef struct 
@@ -65,10 +79,6 @@ typedef struct
   long line_number;            /* debugging support.  */
   int column_number;           /* debugging support.  */
 
-  /* Character encoding support  */
-  char *encoding;
-  scm_t_string_failed_conversion_handler ilseq_handler;
-
   /* port buffers.  the buffer(s) are set up for all ports.  
      in the case of string ports, the buffer is the string itself.
      in the case of unbuffered file ports, the buffer is a
@@ -119,9 +129,11 @@ typedef struct
   unsigned char *putback_buf;
   size_t putback_buf_size;        /* allocated size of putback_buf.  */
 
-  /* input/output iconv conversion descriptors */
-  void *input_cd;
-  void *output_cd;
+  /* Character encoding support  */
+  char *encoding;
+  scm_t_port_encoding_mode encoding_mode;
+  scm_t_string_failed_conversion_handler ilseq_handler;
+  scm_t_iconv_descriptors *iconv_descriptors;
 } scm_t_port;
 
 
@@ -179,6 +191,10 @@ SCM_INTERNAL SCM scm_i_port_weak_set;
 
 
 
+typedef enum scm_t_port_type_flags {
+  SCM_PORT_TYPE_HAS_FLUSH = 1 << 0
+} scm_t_port_type_flags;
+
 /* port-type description.  */
 typedef struct scm_t_ptob_descriptor
 {
@@ -199,6 +215,7 @@ typedef struct scm_t_ptob_descriptor
   scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE);
   void (*truncate) (SCM port, scm_t_off length);
 
+  unsigned flags;
 } scm_t_ptob_descriptor;
 
 #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
@@ -284,6 +301,7 @@ SCM_API SCM scm_close_output_port (SCM port);
    characters.  */
 SCM_INTERNAL const char *scm_i_default_port_encoding (void);
 SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
+SCM_INTERNAL scm_t_iconv_descriptors *scm_i_port_iconv_descriptors (SCM port);
 SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
 SCM_API SCM scm_port_encoding (SCM port);
 SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
diff --git a/libguile/print.c b/libguile/print.c
index 10b16f3..a1bf5ed 100644
--- a/libguile/print.c
+++ b/libguile/print.c
@@ -861,9 +861,9 @@ display_string_using_iconv (const void *str, int narrow_p, 
size_t len,
                            scm_t_string_failed_conversion_handler strategy)
 {
   size_t printed;
-  scm_t_port *pt;
+  scm_t_iconv_descriptors *id;
 
-  pt = SCM_PTAB_ENTRY (port);
+  id = scm_i_port_iconv_descriptors (port);
 
   printed = 0;
 
@@ -892,7 +892,7 @@ display_string_using_iconv (const void *str, int narrow_p, 
size_t len,
       output = encoded_output;
       output_left = sizeof (encoded_output);
 
-      done = iconv (pt->output_cd, &input, &input_left,
+      done = iconv (id->output_cd, &input, &input_left,
                    &output, &output_left);
 
       output_len = sizeof (encoded_output) - output_left;
@@ -902,7 +902,7 @@ display_string_using_iconv (const void *str, int narrow_p, 
size_t len,
           int errno_save = errno;
 
          /* Reset the `iconv' state.  */
-         iconv (pt->output_cd, NULL, NULL, NULL, NULL);
+         iconv (id->output_cd, NULL, NULL, NULL, NULL);
 
          /* Print the OUTPUT_LEN bytes successfully converted.  */
          scm_lfwrite_unlocked (encoded_output, output_len, port);
@@ -966,12 +966,7 @@ display_string (const void *str, int narrow_p,
 
   pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->output_cd == (iconv_t) -1)
-    /* Initialize the conversion descriptors, if needed.  */
-    scm_i_set_port_encoding_x (port, pt->encoding);
-
-  /* FIXME: In 2.1, add a flag to determine whether a port is UTF-8.  */
-  if (pt->output_cd == (iconv_t) -1)
+  if (pt->encoding_mode == SCM_PORT_ENCODING_MODE_UTF8)
     return display_string_as_utf8 (str, narrow_p, len, port);
   else
     return display_string_using_iconv (str, narrow_p, len,
diff --git a/libguile/strings.c b/libguile/strings.c
index bdd0065..9617057 100644
--- a/libguile/strings.c
+++ b/libguile/strings.c
@@ -1525,13 +1525,9 @@ scm_from_stringn (const char *str, size_t len, const 
char *encoding,
     len = strlen (str);
 
   if (encoding == NULL || len == 0)
-    {
-      /* If encoding is null (or the string is empty), use Latin-1.  */
-      char *buf;
-      res = scm_i_make_string (len, &buf, 0);
-      memcpy (buf, str, len);
-      return res;
-    }
+    return scm_from_latin1_stringn (str, len);
+  else if (strcmp (encoding, "UTF-8") == 0)
+    return scm_from_utf8_stringn (str, len);
 
   u32len = 0;
   u32 = (scm_t_wchar *) u32_conv_from_encoding (encoding,
@@ -1669,7 +1665,7 @@ scm_from_utf8_stringn (const char *str, size_t len)
 
       res = scm_i_make_string (char_len, &dst, 0);
 
-      for (i = 0, j = 0; i < len; i++, j++)
+      for (i = 0, j = 0; i < len; j++)
         {
           i += u8_mbtouc_unsafe (&c, ustr + i, len - i);
           dst[j] = (signed char) c;
@@ -1683,7 +1679,7 @@ scm_from_utf8_stringn (const char *str, size_t len)
 
       res = scm_i_make_wide_string (char_len, &dst, 0);
 
-      for (i = 0, j = 0; i < len; i++, j++)
+      for (i = 0, j = 0; i < len; j++)
         {
           i += u8_mbtouc_unsafe (&c, ustr + i, len - i);
           dst[j] = c;
diff --git a/libguile/strports.c b/libguile/strports.c
index fc52a86..c8cce35 100644
--- a/libguile/strports.c
+++ b/libguile/strports.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006, 2009, 
2010, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002, 2003, 2005, 2006, 2009, 
2010, 2011, 2012 Free Software Foundation, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -56,10 +56,8 @@
 /* NOTES:
 
    write_buf/write_end point to the ends of the allocated bytevector.
-   read_buf/read_end in principle point to the part of the bytevector which
-   has been written to, but this is only updated after a flush.
-   read_pos and write_pos in principle should be equal, but this is only true
-   when rw_active is SCM_PORT_NEITHER.
+   read_buf/read_end point to the part of the bytevector which has been
+   written to.  read_pos and write_pos are always equal.
 
    ENHANCE-ME - output blocks:
 
@@ -89,14 +87,14 @@ scm_t_bits scm_tc16_strport;
 
 
 static int
-stfill_buffer (SCM port)
+st_fill_input (SCM port)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
   
   if (pt->read_pos >= pt->read_end)
     return EOF;
   else
-    return scm_return_first_int (*pt->read_pos, port);
+    return *pt->read_pos;
 }
 
 /* Change the size of a port's bytevector to NEW_SIZE.  This doesn't
@@ -111,7 +109,7 @@ st_resize_port (scm_t_port *pt, scm_t_off new_size)
   unsigned long int old_size = SCM_BYTEVECTOR_LENGTH (old_stream);
   unsigned long int min_size = min (old_size, new_size);
 
-  scm_t_off index = pt->write_pos - pt->write_buf;
+  scm_t_off offset = pt->write_pos - pt->write_buf;
 
   pt->write_buf_size = new_size;
 
@@ -123,50 +121,29 @@ st_resize_port (scm_t_port *pt, scm_t_off new_size)
   {
     pt->stream = SCM_UNPACK (new_stream);
     pt->read_buf = pt->write_buf = (unsigned char *)dst;
-    pt->read_pos = pt->write_pos = pt->write_buf + index;
+    pt->read_pos = pt->write_pos = pt->write_buf + offset;
     pt->write_end = pt->write_buf + pt->write_buf_size;
     pt->read_end = pt->read_buf + pt->read_buf_size;
   }
 }
 
-/* Ensure that `write_pos' < `write_end' by enlarging the buffer when
-   necessary.  Update `read_buf' to account for written chars.  The
-   buffer is enlarged geometrically.  */
 static void
-st_flush (SCM port)
+st_write (SCM port, const void *data, size_t size)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->write_pos == pt->write_end)
-    st_resize_port (pt, pt->write_buf_size * 2);
+  if (size > pt->write_end - pt->write_pos)
+    st_resize_port (pt, max (pt->write_buf_size * 2,
+                             pt->write_end - pt->write_pos + size));
+
+  memcpy ((char *) pt->write_pos, data, size);
+  pt->read_pos = (pt->write_pos += size);
 
-  pt->read_pos = pt->write_pos;
   if (pt->read_pos > pt->read_end)
     {
       pt->read_end = (unsigned char *) pt->read_pos;
       pt->read_buf_size = pt->read_end - pt->read_buf;
     }
-  pt->rw_active = SCM_PORT_NEITHER;
-}
-
-static void
-st_write (SCM port, const void *data, size_t size)
-{
-  scm_t_port *pt = SCM_PTAB_ENTRY (port);
-  const char *input = (char *) data;
-
-  while (size > 0)
-    {
-      int space = pt->write_end - pt->write_pos;
-      int write_len = (size > space) ? space : size;
-      
-      memcpy ((char *) pt->write_pos, input, write_len);
-      pt->write_pos += write_len;
-      size -= write_len;
-      input += write_len;
-      if (write_len == space)
-       st_flush (port);
-    }
 }
 
 static void
@@ -203,12 +180,11 @@ st_seek (SCM port, scm_t_off offset, int whence)
   else
     /* all other cases.  */
     {
-      if (pt->rw_active == SCM_PORT_WRITE)
-       st_flush (port);
-  
       if (pt->rw_active == SCM_PORT_READ)
        scm_end_input_unlocked (port);
 
+      pt->rw_active = SCM_PORT_NEITHER;
+
       switch (whence)
        {
        case SEEK_CUR:
@@ -260,10 +236,7 @@ st_truncate (SCM port, scm_t_off length)
   pt->read_buf_size = length;
   pt->read_end = pt->read_buf + length;
   if (pt->read_pos > pt->read_end)
-    pt->read_pos = pt->read_end;
-  
-  if (pt->write_pos > pt->read_end)
-    pt->write_pos = pt->read_end;
+    pt->read_pos = pt->write_pos = pt->read_end;
 }
 
 /* The initial size in bytes of a string port's buffer.  */
@@ -330,10 +303,6 @@ scm_mkstrport (SCM pos, SCM str, long modes, const char 
*caller)
   pt->write_end = pt->read_end = pt->read_buf + pt->read_buf_size;
   pt->rw_random = 1;
 
-  /* Ensure WRITE_POS is writable.  */
-  if ((modes & SCM_WRTNG) && pt->write_pos == pt->write_end)
-    st_flush (z);
-
   return z;
 }
 
@@ -342,26 +311,13 @@ scm_mkstrport (SCM pos, SCM str, long modes, const char 
*caller)
 SCM
 scm_strport_to_string (SCM port)
 {
-  SCM str;
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
-  if (pt->rw_active == SCM_PORT_WRITE)
-    st_flush (port);
-
   if (pt->read_buf_size == 0)
     return scm_nullstr;
 
-  if (pt->encoding == NULL)
-    {
-      char *buf;
-      str = scm_i_make_string (pt->read_buf_size, &buf, 0);
-      memcpy (buf, pt->read_buf, pt->read_buf_size);
-    }
-  else
-    str = scm_from_stringn ((char *)pt->read_buf, pt->read_buf_size,
-                            pt->encoding, pt->ilseq_handler);
-  scm_remember_upto_here_1 (port);
-  return str;
+  return scm_from_stringn ((char *)pt->read_buf, pt->read_buf_size,
+                           pt->encoding, pt->ilseq_handler);
 }
 
 SCM_DEFINE (scm_object_to_string, "object->string", 1, 1, 0,
@@ -541,10 +497,9 @@ scm_eval_string (SCM string)
 static scm_t_bits
 scm_make_stptob ()
 {
-  scm_t_bits tc = scm_make_port_type ("string", stfill_buffer, st_write);
+  scm_t_bits tc = scm_make_port_type ("string", st_fill_input, st_write);
 
   scm_set_port_end_input   (tc, st_end_input);
-  scm_set_port_flush       (tc, st_flush);
   scm_set_port_seek        (tc, st_seek);
   scm_set_port_truncate    (tc, st_truncate);
 


hooks/post-receive
-- 
GNU Guile



reply via email to

[Prev in Thread] Current Thread [Next in Thread]