[erlang-bugs] function clause in io_lib_fread:fread/4 when running out of input before format
Raimo Niskanen
raimo+erlang-bugs@REDACTED
Thu Jul 21 16:52:18 CEST 2011
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
> erlang-bugs@REDACTED
> http://erlang.org/mailman/listinfo/erlang-bugs
--
/ Raimo Niskanen, Erlang/OTP, Ericsson AB
More information about the erlang-bugs
mailing list