26
27
%% fread(Continuation, CharList, FormatString)
27
28
%% This is the main function into the re-entrant formatted reader. It
28
29
%% repeatedly collects lines and calls fread/2 to format the input until
29
%% all the format string has been used.
30
%% all the format string has been used. And it counts the characters.
31
32
fread([], Chars, Format) ->
32
fread({[],Format,0,[]}, Chars, Format);
33
fread({Rest,RestFormat,N,Inputs}, MoreChars, _Format) ->
34
%%io:format("FREAD: ~w `~s'~n", [{Rest,RestFormat,N,Inputs},MoreChars]),
35
fread_collect(MoreChars, [], Rest, RestFormat, N, Inputs).
37
fread_collect([$\r|More], Stack, Rest, RestFormat, N, Inputs) ->
38
fread(RestFormat, Rest ++ reverse(Stack), N, Inputs, More);
39
fread_collect([$\n|More], Stack, Rest, RestFormat, N, Inputs) ->
40
fread(RestFormat, Rest ++ reverse(Stack), N, Inputs, More);
41
fread_collect([C|More], Stack, Rest, RestFormat, N, Inputs) ->
42
fread_collect(More, [C|Stack], Rest, RestFormat, N, Inputs);
43
fread_collect([], Stack, Rest, RestFormat, N, Inputs) ->
44
{more,{reverse(Stack, Rest),RestFormat,N,Inputs}};
45
fread_collect(eof, Stack, Rest, RestFormat, N, Inputs) ->
46
fread(RestFormat, Rest ++ reverse(Stack), N, Inputs, eof).
48
fread(Format, Line, N0, Inputs0, More) ->
49
%%io:format("FREAD1: `~s' `~s'~n", [Format,Line]),
50
case fread(Format, Line, N0, Inputs0) of
52
{done,{ok,Input},case More of eof -> Rest; _ -> Rest ++ More end};
53
{more,RestFormat,N,Inputs} ->
56
fread(RestFormat,eof,N,Inputs,eof);
58
%% Don't forget to count the newline.
59
{more,{More,RestFormat,N+1,Inputs}}
33
%%io:format("FREAD: ~w `~s'~n", [Format,Chars]),
34
fread_collect(Format, [], 0, [], Chars);
35
fread({Format,Stack,N,Results}=_Continuation, Chars, _) ->
36
%%io:format("FREAD: ~w `~s'~n", [_Continuation,Chars]),
37
fread_collect(Format, Stack, N, Results, Chars).
39
fread_collect(Format, [$\r|Stack], N, Results, [$\n|Chars]) ->
40
fread_line(Format, reverse(Stack), N, Results, Chars, [$\r,$\n]);
41
fread_collect(Format, Stack, N, Results, [$\n|Chars]) ->
42
fread_line(Format, reverse(Stack), N, Results, Chars, [$\n]);
43
fread_collect(Format, Stack, N, Results, []) ->
44
Continuation = {Format,Stack,N,Results},
46
fread_collect(Format, [$\r|Stack], N, Results, Chars) -> % Maybe eof
47
fread_line(Format, reverse(Stack), N, Results, Chars, [$\r]);
48
fread_collect(Format, Stack, N, Results, [C|Chars]) ->
49
fread_collect(Format, [C|Stack], N, Results, Chars);
50
fread_collect(Format, Stack, N, Results, Chars) -> % eof
51
fread_line(Format, reverse(Stack), N, Results, Chars, []).
53
fread_line(Format0, Line, N0, Results0, More, Newline) ->
54
%%io:format("FREAD1: `~s' `~s'~n", [Format0,Line]),
55
Chars = if is_list(More) -> More; true -> [] end,
56
case fread(Format0, Line, N0, Results0) of
58
{done,{ok,Results},Chars};
60
%% Don't loose the whitespace
61
{done,{ok,Results},Rest++(Newline++Chars)};
62
%% fread/4 should not return {more,...} on eof; guard just in case...
63
%% Count newline characters here since fread/4 does not get them.
64
{more,Format,N,Results} when is_list(Line), is_list(More) ->
65
fread_collect(Format, [], N+length(Newline), Results, More);
66
{more,Format,N,Results} when is_list(Line) -> % eof
67
fread_line(Format, eof, N+length(Newline), Results, More, []);
61
68
Other -> %An error has occurred
66
74
%% ~s String White terminated
67
75
%% ~d Integer terminated by ~[0-9]
112
120
%% {RestFormat,FieldWidth,Suppress}
114
fread_field([$*|Format]) -> fread_field(Format, true);
115
fread_field(Format) -> fread_field(Format, false).
117
fread_field([C|Format], Sup) when C >= $0, C =< $9 ->
118
fread_field(Format, C - $0, Sup);
119
fread_field(Format, Sup) -> {Format,none,Sup}.
121
fread_field([C|Format], F, Sup) when C >= $0, C =< $9 ->
122
fread_field(Format, 10*F + C - $0, Sup);
123
fread_field(Format, F, Sup) ->
122
fread_field([$*|Format]) -> fread_field(Format, true, false);
123
fread_field(Format) -> fread_field(Format, false, false).
125
fread_field([C|Format], Sup, Unic) when C >= $0, C =< $9 ->
126
fread_field(Format, C - $0, Sup, Unic);
127
fread_field([$t|Format], Sup, _Unic) ->
128
{Format,none,Sup,true};
129
fread_field(Format, Sup, Unic) ->
130
{Format,none,Sup,Unic}.
132
fread_field([C|Format], F, Sup, Unic) when C >= $0, C =< $9 ->
133
fread_field(Format, 10*F + C - $0, Sup, Unic);
134
fread_field([$t|Format], F, Sup, _Unic) ->
136
fread_field(Format, F, Sup, Unic) ->
126
139
%% fread1(Format, FieldWidth, Suppress, Line, N, Results, AllFormat)
127
140
%% fread1(Format, FieldWidth, Suppress, Line, N, Results)
128
141
%% The main dispatch function for the formatting commands. Done in two
129
142
%% stages so format commands that need no input can always be processed.
131
fread1([$l|Format], _F, Sup, Line, N, Res, _AllFormat) ->
144
fread1([$l|Format], _F, Sup, _U, Line, N, Res, _AllFormat) ->
132
145
fread(Format, Line, N, fread_result(Sup, N, Res));
133
fread1(_Format, _F, _Sup, [], N, Res, AllFormat) ->
146
fread1(_Format, _F, _Sup, _U, [], N, Res, AllFormat) ->
134
147
%% Need more input here.
135
148
{more,[$~|AllFormat],N,Res};
136
fread1(_Format, _F, _Sup, eof, _N, [], _AllFormat) ->
149
fread1(_Format, _F, _Sup, _U, eof, _N, [], _AllFormat) ->
137
150
%% This is at start of format string so no error.
139
fread1(_Format, _F, _Sup, eof, _N, _Res, _AllFormat) ->
152
fread1(_Format, _F, _Sup, _U, eof, _N, _Res, _AllFormat) ->
140
153
%% This is an error as there is no more input.
141
154
fread_error(input);
142
fread1(Format, F, Sup, Line, N, Res, _AllFormat) ->
143
fread1(Format, F, Sup, Line, N, Res).
155
fread1(Format, F, Sup, U, Line, N, Res, _AllFormat) ->
156
fread1(Format, F, Sup, U, Line, N, Res).
145
fread1([$f|Format], none, Sup, Line0, N0, Res) ->
158
fread1([$f|Format], none, Sup, false, Line0, N0, Res) ->
146
159
{Line,N,Cs} = fread_float_cs(Line0, N0),
147
160
fread_float(Cs, Sup, Format, Line, N, Res);
148
fread1([$f|Format], F, Sup, Line0, N, Res) ->
149
{Line,Cs} = fread_chars(Line0, F),
161
fread1([$f|Format], F, Sup, false, Line0, N, Res) ->
162
{Line,Cs} = fread_chars(Line0, F, false),
150
163
fread_float(Cs, Sup, Format, Line, N+F, Res);
151
fread1([$d|Format], none, Sup, Line0, N0, Res) ->
164
fread1([$d|Format], none, Sup, false, Line0, N0, Res) ->
152
165
{Line,N,Cs} = fread_int_cs(Line0, N0),
153
166
fread_integer(Cs, 10, Sup, Format, Line, N, Res);
154
fread1([$d|Format], F, Sup, Line0, N, Res) ->
155
{Line,Cs} = fread_chars(Line0, F),
167
fread1([$d|Format], F, Sup, false, Line0, N, Res) ->
168
{Line,Cs} = fread_chars(Line0, F, false),
156
169
fread_integer(Cs, 10, Sup, Format, Line, N+F, Res);
157
fread1([$u|Format], none, Sup, Line0, N0, Res) ->
170
fread1([$u|Format], none, Sup, false, Line0, N0, Res) ->
158
171
{Line,N,Cs} = fread_digits(Line0, N0, 10, []),
159
172
fread_unsigned(Cs, 10, Sup, Format, Line, N, Res);
160
fread1([$u|Format], F, Sup, Line0, N0, Res) when F >= 2, F =< 1+$Z-$A+10 ->
173
fread1([$u|Format], F, Sup, false, Line0, N0, Res) when F >= 2, F =< 1+$Z-$A+10 ->
161
174
{Line,N,Cs} = fread_digits(Line0, N0, F, []),
162
175
fread_unsigned(Cs, F, Sup, Format, Line, N, Res);
163
fread1([$-|Format], _F, Sup, Line, N, Res) ->
176
fread1([$-|Format], _F, Sup, false, Line, N, Res) ->
164
177
fread_sign_char(Sup, Format, Line, N, Res);
165
fread1([$#|Format], none, Sup, Line0, N0, Res) ->
178
fread1([$#|Format], none, Sup, false, Line0, N0, Res) ->
168
181
{Line1,N1,B1} = fread_base(Line0, N0),
192
fread1([$s|Format], none, Sup, Line0, N0, Res) ->
193
{Line,N,Cs} = fread_string_cs(Line0, N0),
194
fread_string(Cs, Sup, Format, Line, N, Res);
195
fread1([$s|Format], F, Sup, Line0, N, Res) ->
196
{Line,Cs} = fread_chars(Line0, F),
197
fread_string(Cs, Sup, Format, Line, N+F, Res);
198
fread1([$a|Format], none, Sup, Line0, N0, Res) ->
199
{Line,N,Cs} = fread_string_cs(Line0, N0),
205
fread1([$s|Format], none, Sup, U, Line0, N0, Res) ->
206
{Line,N,Cs} = fread_string_cs(Line0, N0, U),
207
fread_string(Cs, Sup, U, Format, Line, N, Res);
208
fread1([$s|Format], F, Sup, U, Line0, N, Res) ->
209
{Line,Cs} = fread_chars(Line0, F, U),
210
fread_string(Cs, Sup, U, Format, Line, N+F, Res);
211
%% XXX:PaN Atoms still only latin1...
212
fread1([$a|Format], none, Sup, false, Line0, N0, Res) ->
213
{Line,N,Cs} = fread_string_cs(Line0, N0, false),
200
214
fread_atom(Cs, Sup, Format, Line, N, Res);
201
fread1([$a|Format], F, Sup, Line0, N, Res) ->
202
{Line,Cs} = fread_chars(Line0, F),
215
fread1([$a|Format], F, Sup, false, Line0, N, Res) ->
216
{Line,Cs} = fread_chars(Line0, F, false),
203
217
fread_atom(Cs, Sup, Format, Line, N+F, Res);
204
fread1([$c|Format], none, Sup, Line0, N, Res) ->
205
{Line,Cs} = fread_chars(Line0, 1),
206
fread_chars(Cs, Sup, Format, Line, N+1, Res);
207
fread1([$c|Format], F, Sup, Line0, N, Res) ->
208
{Line,Cs} = fread_chars(Line0, F),
209
fread_chars(Cs, Sup, Format, Line, N+F, Res);
210
fread1([$~|Format], _F, _Sup, [$~|Line], N, Res) ->
218
fread1([$c|Format], none, Sup, U, Line0, N, Res) ->
219
{Line,Cs} = fread_chars(Line0, 1, U),
220
fread_chars(Cs, Sup, U, Format, Line, N+1, Res);
221
fread1([$c|Format], F, Sup, U, Line0, N, Res) ->
222
{Line,Cs} = fread_chars(Line0, F, U),
223
fread_chars(Cs, Sup, U, Format, Line, N+F, Res);
224
fread1([$~|Format], _F, _Sup, _U, [$~|Line], N, Res) ->
211
225
fread(Format, Line, N+1, Res);
212
fread1(_Format, _F, _Sup, _Line, _N, _Res) ->
226
fread1(_Format, _F, _Sup, _U, _Line, _N, _Res) ->
213
227
fread_error(format).
215
229
%% fread_float(FloatChars, Suppress, Format, Line, N, Results)
283
297
%% fread_chars(Characters, Suppress, Format, Line, N, Results)
285
fread_chars(error, _Sup, _Format, _Line, _N, _Res) ->
299
fread_chars(error, _Sup, _U, _Format, _Line, _N, _Res) ->
286
300
fread_error(character);
287
fread_chars(Cs, Sup, Format, Line, N, Res) ->
288
fread(Format, Line, N, fread_result(Sup, reverse(Cs), Res)).
301
fread_chars(Cs, Sup, U, Format, Line, N, Res) ->
302
fread(Format, Line, N, fread_convert(fread_result(Sup, reverse(Cs), Res),U)).
290
304
%% fread_chars(Line, Count)
292
fread_chars(Line, C) ->
293
fread_chars(C, Line, []).
306
fread_chars(Line, C, U) ->
307
fread_chars(C, Line, U, []).
295
fread_chars(0, Line, Cs) -> {Line,Cs};
296
fread_chars(_N, [$\n|Line], _Cs) -> {[$\n|Line],error};
297
fread_chars(N, [C|Line], Cs) ->
298
fread_chars(N-1, Line, [C|Cs]);
299
fread_chars(_N, [], _Cs) -> {[],error}.
309
fread_chars(0, Line, _U, Cs) -> {Line,Cs};
310
fread_chars(_N, [$\n|Line], _U, _Cs) -> {[$\n|Line],error};
311
fread_chars(N, [C|Line], true, Cs) ->
312
fread_chars(N-1, Line, true, [C|Cs]);
313
fread_chars(N, [C|Line], false, Cs) when C >= 0, C =< 255 ->
314
fread_chars(N-1, Line, false, [C|Cs]);
315
fread_chars(_N, L, _U, _Cs) ->
317
%%fread_chars(_N, [], _U,_Cs) ->
301
320
%% fread_int_cs(Line, N)
353
375
fread_skip_white(Line, N+1);
354
376
fread_skip_white([$\t|Line], N) ->
355
377
fread_skip_white(Line, N+1);
378
fread_skip_white([$\r|Line], N) ->
379
fread_skip_white(Line, N+1);
356
380
fread_skip_white([$\n|Line], N) ->
357
381
fread_skip_white(Line, N+1);
358
382
fread_skip_white(Line, N) -> {Line,N}.
384
fread_skip_latin1_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
385
fread_skip_latin1_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
386
fread_skip_latin1_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};
387
fread_skip_latin1_nonwhite([$\n|Line], N, Cs) -> {[$\n|Line],N,Cs};
388
fread_skip_latin1_nonwhite([C|Line], N, []) when C > 255 ->
390
fread_skip_latin1_nonwhite([C|Line], N, Cs) when C > 255 ->
392
fread_skip_latin1_nonwhite([C|Line], N, Cs) ->
393
fread_skip_latin1_nonwhite(Line, N+1, [C|Cs]);
394
fread_skip_latin1_nonwhite([], N, Cs) -> {[],N,Cs}.
360
396
fread_skip_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
361
397
fread_skip_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
362
398
fread_skip_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};