guile-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] Fix `get-string-n!' &i/o-decoding exception behavior


From: Mark H Weaver
Subject: Re: [PATCH] Fix `get-string-n!' &i/o-decoding exception behavior
Date: Sun, 11 Nov 2012 02:26:59 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux)

Hi Andreas,

Thanks for the patch.  See below for my comments.

Andreas Rottmann <address@hidden> writes:

> Previously, `get-string-n!' from `(rnrs io ports)' would not throw the
> exception required by R6RS, and could not easily do so due to being
> implemented entirely in C.
>
> This change fixes this by introducing a corresponding internal C
> function reporting errors by return value and reimplementing the
> `get-string-n!' in Scheme on top of that.  Along with `get-string-n!',
> `get-string-n' gets fixed, inheriting the correct behavior.
>
> * libguile/ports.c (scm_i_getc): New function, a version of `scm_getc'
>   not using exceptions.
>   (scm_getc): Implemented using `scm_i_getc'.
> * libguile/ports.h (scm_i_getc): Add prototype marked SCM_INTERNAL.
>
> * libguile/r6rs-ports.c (scm_i_get_string_n_x): Exception-free version
>   of `get-string-n!', making use of `scm_i_getc'.
>   (scm_get_string_n_x): Removed, now implemented in Scheme.
>
> * module/ice-9/binary-ports.scm (get-string-n!): Removed from export
>   list, it doesn't fit the module module purpose anyway.
> * module/rnrs/io/ports.scm (%get-string-n): Newly defined by internal
>   reference to `(ice-9 binary-ports)'.
>   (get-string-n!): Implemented in Scheme on top of `%get-string-n!'.
>
> * test-suite/tests/r6rs-ports.test ("8.2.9 Textual
>   input")["read-error"]: Activate commented-out exception-behavior tests
>   of `get-string-n!'.
>   ["decoding error"]: New test prefix with tests for `get-char',
>   `get-string-n!' and `get-string-n' and `get-line'.
> ---
>  libguile/ports.c                 |   20 ++++++++++++++++----
>  libguile/ports.h                 |    1 +
>  libguile/r6rs-ports.c            |   21 +++++++++++----------
>  module/ice-9/binary-ports.scm    |    6 +++---
>  module/rnrs/io/ports.scm         |   14 ++++++++++++++
>  test-suite/tests/r6rs-ports.test |   24 ++++++++++++++++++++----
>  6 files changed, 65 insertions(+), 21 deletions(-)
>
> diff --git a/libguile/ports.c b/libguile/ports.c
> index 55808e2..b653af4 100644
> --- a/libguile/ports.c
> +++ b/libguile/ports.c
> @@ -1392,12 +1392,10 @@ scm_t_wchar
>  scm_getc (SCM port)
>  #define FUNC_NAME "scm_getc"
>  {
> -  int err;
> -  size_t len;
> +  int err = 0;
>    scm_t_wchar codepoint;
> -  char buf[SCM_MBCHAR_BUF_SIZE];
>  
> -  err = get_codepoint (port, &codepoint, buf, &len);
> +  codepoint = scm_i_getc (port, &err);
>    if (SCM_UNLIKELY (err != 0))
>      /* At this point PORT should point past the invalid encoding, as per
>         R6RS-lib Section 8.2.4.  */
> @@ -1407,6 +1405,20 @@ scm_getc (SCM port)
>  }
>  #undef FUNC_NAME
>  
> +/* Read a codepoint from PORT and return it.  This version reports
> +   errors via the ERROR argument instead of via exceptions. */
> +scm_t_wchar
> +scm_i_getc (SCM port, int *error)
> +{
> +  size_t len;
> +  scm_t_wchar codepoint;
> +  char buf[SCM_MBCHAR_BUF_SIZE];
> +
> +  *error = get_codepoint (port, &codepoint, buf, &len);
> +
> +  return codepoint;
> +}

Given how trivial 'scm_i_getc' is, I think I'd prefer to leave
'scm_getc' alone, to avoid the additional overhead of another non-static
C function call, which has to be done via the procedure linkage table
(PLT) when libguile is a shared library and is thus not entirely
trivial.

> diff --git a/libguile/r6rs-ports.c b/libguile/r6rs-ports.c
> index e867429..bd10081 100644
> --- a/libguile/r6rs-ports.c
> +++ b/libguile/r6rs-ports.c
> @@ -1242,18 +1242,17 @@ SCM_DEFINE (scm_i_make_transcoded_port,
>  
>  /* Textual I/O */
>  
> -SCM_DEFINE (scm_get_string_n_x,
> -            "get-string-n!", 4, 0, 0,
> +SCM_DEFINE (scm_i_get_string_n_x,
> +            "%get-string-n!", 4, 0, 0,

I'm a little bit nervous about this.  Although it is not documented in
the manual, 'scm_get_string_n_x' is declared in r6rs-ports.h as SCM_API.
I'm not sure it's safe to make that go away.

Why not leave the API as-is, and in the event of an error, just raise
the proper R6RS exception from within 'scm_get_string_n_x'?

> diff --git a/module/ice-9/binary-ports.scm b/module/ice-9/binary-ports.scm
> index c07900b..3f7b9e6 100644
> --- a/module/ice-9/binary-ports.scm
> +++ b/module/ice-9/binary-ports.scm
> @@ -37,14 +37,14 @@
>              get-bytevector-n!
>              get-bytevector-some
>              get-bytevector-all
> -            get-string-n!

Users may have come to rely on this export from (ice-9 binary-ports).
I don't think it's safe to remove it.

    Regards,
      Mark



reply via email to

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