[m-rev.] for review: fixes for deconstruct.functor and io.write

Zoltan Somogyi zoltan.somogyi at runbox.com
Thu Jun 14 20:05:38 AEST 2018



On Wed, 13 Jun 2018 22:10:51 -0400 (EDT), Julien Fischer <jfischer at opturion.com> wrote:
>   quote_special_escape_char('\\', "'\\\\'").
> -quote_special_escape_char('\'', "'\\'").
> +quote_special_escape_char('\'', "'\\''").
>   quote_special_escape_char('\a', "'\\a'").
>   quote_special_escape_char('\b', "'\\b'").
>   quote_special_escape_char('\r', "'\\r'").
> diff --git a/library/term_io.m b/library/term_io.m
> index 3fee715..a818b7a 100644
> --- a/library/term_io.m
> +++ b/library/term_io.m
> @@ -1005,12 +1005,16 @@ encode_escaped_char(Char::out, Str::in) :-
>   :- mode mercury_escape_special_char(in, out) is semidet.
>   :- mode mercury_escape_special_char(out, in) is semidet.
> 
> +mercury_escape_special_char('\a', 'a').
> +mercury_escape_special_char('\b', 'b').
> +mercury_escape_special_char('\r', 'r').
> +mercury_escape_special_char('\f', 'f').
> +mercury_escape_special_char('\t', 't').
> +mercury_escape_special_char('\n', 'n').
> +mercury_escape_special_char('\v', 'v').
> +mercury_escape_special_char('\\', '\\').
>   mercury_escape_special_char('''', '''').
>   mercury_escape_special_char('"', '"').
> -mercury_escape_special_char('\\', '\\').
> -mercury_escape_special_char('\n', 'n').
> -mercury_escape_special_char('\t', 't').
> -mercury_escape_special_char('\b', 'b').

These two places should have comments referring maintainers to the other,
if they don't already, to reduce the probability of anyone modifying one
without also modifying the other.

> diff --git a/runtime/mercury_ml_expand_body.h b/runtime/mercury_ml_expand_body.h
> index 6c1bf54..9e1bfee 100644
> --- a/runtime/mercury_ml_expand_body.h
> +++ b/runtime/mercury_ml_expand_body.h
> @@ -880,10 +880,9 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
>                   char        *str;
> 
>                   data_word = *data_word_ptr;
> -                // XXX what should we do with other non-printable characters.
>                   switch (data_word) {
>                       case '\\': str_ptr = "'\\\\'"; break;
> -                    case '\'': str_ptr = "'\\''"; break;
> +                    case '\'': str_ptr = "'\\''";  break;
>                       case '\a': str_ptr = "'\\a'";  break;

What changed here? Just white space?

> @@ -892,7 +891,28 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
>                       case '\n': str_ptr = "'\\n'";  break;
>                       case '\v': str_ptr = "'\\v'";  break;
>                       default:
> -                        sprintf(buf, "\'%c\'", (char) data_word);
> +                        // Print C0 control characters and Delete in
> +                        // octal.
> +                        if (data_word <= 0x1f || data_word == 0x7f) {
> +                            sprintf(buf, "\'\\%03o\\\'", data_word);
> +                        } else if (MR_is_ascii(data_word)) {
> +                            sprintf(buf, "\'%c\'", (char) data_word);
> +                        } else if (MR_is_surrogate(data_word)) {
> +                            // XXX Should throw an exception.
> +                            MR_fatal_error(MR_STRINGIFY(EXPAND_FUNCTION_NAME)
> +                                ": attempt to deconstruct surrogate code point");
> +                        } else {
> +                            size_t n = MR_utf8_encode(buf + 1, (MR_Char)data_word);
> +                            // XXX Should throw an exception.
> +                            if (n == 0) {
> +                                MR_fatal_error(MR_STRINGIFY(EXPAND_FUNCTION_NAME)
> +                                    ": attempt to deconstruct illegal code point");
> +                            }
> +                            buf[0] = '\'';
> +                            buf[n + 1] = '\'';
> +                            buf[n + 2] = '\0';
> +
> +                        }

Likewise, I think this code should have a comment pointing to its Mercury equivalent,
and vice versa.

> diff --git a/tests/hard_coded/write.m b/tests/hard_coded/write.m
> index 54d5b1b..3e9c9f0 100644
> --- a/tests/hard_coded/write.m
> +++ b/tests/hard_coded/write.m
> @@ -12,6 +12,7 @@
>   :- implementation.
> 
>   :- import_module array.
> +:- import_module float.
>   :- import_module int.
>   :- import_module list.
>   :- import_module map.
> @@ -125,15 +126,29 @@ test_builtins(!IO) :-
>       io.write("Hello, world\n", !IO), newline(!IO),
>       io.write("Foo%sFoo", !IO), newline(!IO),
>       io.write("""", !IO), newline(!IO),    % interesting - prints """ of course
> +    io.write("\a\b\f\t\n\r\v\"\\", !IO), newline(!IO),
> 
>       % Test characters.
>       io.write('a', !IO), newline(!IO),
>       io.write('&', !IO), newline(!IO),
> +    io.write('\a', !IO), newline(!IO),
> +    io.write('\b', !IO), newline(!IO),
> +    io.write('\f', !IO), newline(!IO),
> +    io.write('\t', !IO), newline(!IO),
> +    io.write('\n', !IO), newline(!IO),
> +    io.write('\r', !IO), newline(!IO),
> +    io.write('\v', !IO), newline(!IO),
> +    io.write('\'', !IO), newline(!IO),
> +    io.write(('\\') : character, !IO), newline(!IO),
> +    io.write('\"', !IO), newline(!IO),
> 
>       % Test floats.
>       io.write(3.14159, !IO), newline(!IO),
>       io.write(11.28324983E-22, !IO), newline(!IO),
>       io.write(22.3954899E22, !IO), newline(!IO),
> +    NegInf : float = -float.infinity,
> +    io.write(NegInf, !IO), newline(!IO),
> +    io.write(float.infinity, !IO), newline(!IO),

These would be simpler if they called io.write_line, not io.write.
(Though io.write_line did not yet exist when this test was first written.)

Other than the above, the diff seems fine.

Zoltan.


More information about the reviews mailing list