Quantcast

function clause in io_lib_fread:fread/4 when running out of input before format

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

function clause in io_lib_fread:fread/4 when running out of input before format

Klas Johansson
Hi,

Stumbled upon a bug in io_lib (rather in io_lib_fread) when parsing
ISO 8601 timestamps.

Given that I parse something like "2009-10-17T18:37:26Z" but (by
mistake) leave out the trailing "Z" in the input string I get a
function clause:

    1> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009-10-17T18:37:26").
    ** exception error: no function clause matching
                        io_lib_fread:fread("Z",[],19,[26,37,18,17,10,2009])

Same thing if I stop at any of the non-control characters (like a dash
or colon):

    2> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
    ** exception error: no function clause matching
                        io_lib_fread:fread("-~2d-~2dT~2d:~2d:~2dZ",[],4,[2009])

Minimal (and silly) test case:

    3> io_lib:fread("Z", "").
    ** exception error: no function clause matching
                    io_lib_fread:fread("Z",[],0,[])

I'd expect something like this:

    4> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
    {more,"~2d-~2dT~2d:~2d:~2dZ",4,[2009]}

Should be easy to fix, but I've resorted to using re.erl for now.


Cheers,
Klas
_______________________________________________
erlang-bugs mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-bugs
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: function clause in io_lib_fread:fread/4 when running out of input before format

Raimo Niskanen-6
On Wed, Jul 20, 2011 at 12:11:45PM +0200, Klas Johansson wrote:

> Hi,
>
> Stumbled upon a bug in io_lib (rather in io_lib_fread) when parsing
> ISO 8601 timestamps.
>
> Given that I parse something like "2009-10-17T18:37:26Z" but (by
> mistake) leave out the trailing "Z" in the input string I get a
> function clause:
>
>     1> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009-10-17T18:37:26").
>     ** exception error: no function clause matching
>                         io_lib_fread:fread("Z",[],19,[26,37,18,17,10,2009])
>
> Same thing if I stop at any of the non-control characters (like a dash
> or colon):
>
>     2> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>     ** exception error: no function clause matching
>                         io_lib_fread:fread("-~2d-~2dT~2d:~2d:~2dZ",[],4,[2009])
>
> Minimal (and silly) test case:
>
>     3> io_lib:fread("Z", "").
>     ** exception error: no function clause matching
>                     io_lib_fread:fread("Z",[],0,[])
>
> I'd expect something like this:
>
>     4> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>     {more,"~2d-~2dT~2d:~2d:~2dZ",4,[2009]}
>
> Should be easy to fix, but I've resorted to using re.erl for now.

I confirm it must be a bug, and I will put this solution
into the daily builds 'dev' branch:
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -121,6 +121,14 @@ fread([C|Format], [C|Line], N, Results) ->
     fread(Format, Line, N+1, Results);
 fread([_F|_Format], [_C|_Line], _N, _Results) ->
     fread_error(input);
+fread([_|_]=Format, [], N, Results) ->
+    {more,Format,N,Results};
+fread([_|_], eof, _N, []) ->
+    %% This is at start of format string so no error.
+    eof;
+fread([_|_], eof, _N, _Results) ->
+    %% This is an error as there is no more input.
+    fread_error(input);
 fread([], Line, _N, Results) ->
     {ok,reverse(Results),Line}.

I'll have a look at one other pecularity while I'm at it;
reading using io:fread(F, " X") from an io server that
gives some whitespaces followed by EOF will return
'eof' while I think it should return {error,{fread,input}}.
The same for io:fread(F, " ~d").

I think this is a misinterpeted feature of when being at EOF
an io:fread should immediately return 'eof'.

>
>
> Cheers,
> Klas
> _______________________________________________
> erlang-bugs mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-bugs

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-bugs mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-bugs
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: function clause in io_lib_fread:fread/4 when running out of input before format

Klas Johansson
On Thu, Jul 21, 2011 at 4:52 PM, Raimo Niskanen
<[hidden email]> wrote:

> On Wed, Jul 20, 2011 at 12:11:45PM +0200, Klas Johansson wrote:
>> Hi,
>>
>> Stumbled upon a bug in io_lib (rather in io_lib_fread) when parsing
>> ISO 8601 timestamps.
>>
>> Given that I parse something like "2009-10-17T18:37:26Z" but (by
>> mistake) leave out the trailing "Z" in the input string I get a
>> function clause:
>>
>>     1> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009-10-17T18:37:26").
>>     ** exception error: no function clause matching
>>                         io_lib_fread:fread("Z",[],19,[26,37,18,17,10,2009])
>>
>> Same thing if I stop at any of the non-control characters (like a dash
>> or colon):
>>
>>     2> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>>     ** exception error: no function clause matching
>>                         io_lib_fread:fread("-~2d-~2dT~2d:~2d:~2dZ",[],4,[2009])
>>
>> Minimal (and silly) test case:
>>
>>     3> io_lib:fread("Z", "").
>>     ** exception error: no function clause matching
>>                     io_lib_fread:fread("Z",[],0,[])
>>
>> I'd expect something like this:
>>
>>     4> io_lib:fread("~4d-~2d-~2dT~2d:~2d:~2dZ", "2009").
>>     {more,"~2d-~2dT~2d:~2d:~2dZ",4,[2009]}
>>
>> Should be easy to fix, but I've resorted to using re.erl for now.
>
> I confirm it must be a bug, and I will put this solution
> into the daily builds 'dev' branch:
> --- a/lib/stdlib/src/io_lib_fread.erl
> +++ b/lib/stdlib/src/io_lib_fread.erl
> @@ -121,6 +121,14 @@ fread([C|Format], [C|Line], N, Results) ->
>     fread(Format, Line, N+1, Results);
>  fread([_F|_Format], [_C|_Line], _N, _Results) ->
>     fread_error(input);
> +fread([_|_]=Format, [], N, Results) ->
> +    {more,Format,N,Results};
> +fread([_|_], eof, _N, []) ->
> +    %% This is at start of format string so no error.
> +    eof;
> +fread([_|_], eof, _N, _Results) ->
> +    %% This is an error as there is no more input.
> +    fread_error(input);
>  fread([], Line, _N, Results) ->
>     {ok,reverse(Results),Line}.
>
> I'll have a look at one other pecularity while I'm at it;
> reading using io:fread(F, " X") from an io server that
> gives some whitespaces followed by EOF will return
> 'eof' while I think it should return {error,{fread,input}}.
> The same for io:fread(F, " ~d").
>
> I think this is a misinterpeted feature of when being at EOF
> an io:fread should immediately return 'eof'.
>
>>
>>
>> Cheers,
>> Klas
>> _______________________________________________
>> erlang-bugs mailing list
>> [hidden email]
>> http://erlang.org/mailman/listinfo/erlang-bugs
>
> --
>
> / Raimo Niskanen, Erlang/OTP, Ericsson AB
>

Thanks for a quick reply!

Cheers,
Klas
_______________________________________________
erlang-bugs mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-bugs
Loading...