Skip to content

Commit e245c69

Browse files
cleanup parser, add validation logic
1 parent c6068b4 commit e245c69

File tree

2 files changed

+79
-86
lines changed

2 files changed

+79
-86
lines changed

src/lib/charsio.pl

Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
:- use_module(library(lists)).
2626
:- use_module(library(between)).
2727
:- use_module(library(iso_ext), [partial_string/1,partial_string/3]).
28+
:- use_module(library(charsio/memory_stream_utils)).
2829

2930
fabricate_var_name(VarType, VarName, N) :-
3031
char_code('A', AC),
@@ -424,7 +425,7 @@
424425
% ```
425426

426427
chars_to_stream(Chars, Stream, StreamOpts) :-
427-
parse_stream_options(StreamOpts, [Alias, EOFAction, Reposition, Type]),
428+
parse_stream_options_list(StreamOpts, [Alias, EOFAction, Reposition, Type]),
428429
validate_chars(Chars, Type),
429430
'$memory_stream'(Stream),
430431
'$set_stream_options'(Stream, Alias ,EOFAction, Reposition, Type),
@@ -433,88 +434,3 @@
433434
; maplist(put_char(Stream), Chars)
434435
).
435436

436-
%% ugly ripoff of parser from library(builtins).
437-
438-
:- meta_predicate parse_options_list(?, 2, ?, ?, ?).
439-
440-
parse_options_list(Options, Selector, DefaultPairs, OptionValues, Stub) :-
441-
'$skip_max_list'(_, _, Options, Tail),
442-
( Tail == [] ->
443-
true
444-
; var(Tail) ->
445-
throw(error(instantiation_error, Stub)) % 8.11.5.3c)
446-
; Tail \== [] ->
447-
throw(error(type_error(list, Options), Stub)) % 8.11.5.3e)
448-
),
449-
( lists:maplist('$call'(nonvar), Options), % need '$call' because
450-
% maplist isn't
451-
% declared as a
452-
% meta-predicate yet
453-
catch(lists:maplist(Selector, Options, OptionPairs0),
454-
error(E, _),
455-
builtins:throw(error(E, Stub))) ->
456-
lists:append(DefaultPairs, OptionPairs0, OptionPairs1),
457-
keysort(OptionPairs1, OptionPairs),
458-
select_rightmost_options(OptionPairs, OptionValues)
459-
;
460-
throw(error(instantiation_error, Stub)) % 8.11.5.3c)
461-
).
462-
463-
parse_stream_options_(type(Type), type-Type) :-
464-
( var(Type) ->
465-
throw(error(instantiation_error, open/4)) % 8.1.3 7)
466-
;
467-
lists:member(Type, [text, binary]), !
468-
;
469-
throw(error(domain_error(stream_option, type(Type)), _))
470-
).
471-
parse_stream_options_(reposition(Bool), reposition-Bool) :-
472-
( nonvar(Bool), lists:member(Bool, [true, false]), !
473-
;
474-
throw(error(domain_error(stream_option, reposition(Bool)), _))
475-
).
476-
477-
parse_stream_options_(alias(A), alias-A) :-
478-
479-
( var(A) ->
480-
throw(error(instantiation_error, open/4)) % 8.1.3 7)
481-
;
482-
atom(A), A \== [] -> true
483-
;
484-
throw(error(domain_error(stream_option, alias(A)), _))
485-
).
486-
parse_stream_options_(eof_action(Action), eof_action-Action) :-
487-
( nonvar(Action), lists:member(Action, [eof_code, error, reset]), !
488-
;
489-
throw(error(domain_error(stream_option, eof_action(Action)), _))
490-
).
491-
parse_stream_options_(E, _) :-
492-
throw(error(domain_error(stream_option, E), _)). % 8.11.5.3i) %
493-
494-
parse_stream_options(Options, OptionValues) :-
495-
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, type-text],
496-
parse_options_list(Options, parse_stream_options_, DefaultOptions, OptionValues, chars_to_stream/3).
497-
498-
499-
select_rightmost_options([Option-Value | OptionPairs], OptionValues) :-
500-
( pairs:same_key(Option, OptionPairs, OtherValues, _),
501-
OtherValues == [] ->
502-
OptionValues = [Value | OptionValues0],
503-
select_rightmost_options(OptionPairs, OptionValues0)
504-
;
505-
select_rightmost_options(OptionPairs, OptionValues)
506-
).
507-
508-
select_rightmost_options([], []).
509-
510-
511-
valid_byte_(Byte) :-
512-
must_be(integer, Byte),
513-
Byte >= 0,
514-
Byte < 256.
515-
516-
validate_chars_(Chars, binary) :-
517-
maplist(valid_byte, Chars).
518-
519-
validate_chars_(Chars, text) :-
520-
must_be(chars, Chars).
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2+
Internal utilities supporting charsio:chars_to_stream/3.
3+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4+
5+
:- module(memory_stream_utils, [parse_stream_options_list/2, validate_chars/2]).
6+
7+
:- use_module(library(lists)).
8+
:- use_module(library(error)).
9+
10+
11+
option_default(type, text).
12+
option_default(reposition, false).
13+
option_default(alias, []).
14+
option_default(eof_action, eof_code).
15+
16+
parse_stream_options_list(Options, [Alias, EOFAction, Reposition, Type]) :-
17+
maplist(parse_option, Options),
18+
option_default(type, Type, Options),
19+
option_default(reposition, Reposition, Options),
20+
option_default(alias, Alias, Options),
21+
option_default(eof_action, EOFAction, Options).
22+
23+
option_default(Option, Resolved, Options) :-
24+
option_default(Option, Default),
25+
MaybeOption =.. [Option,Answer],
26+
( member(MaybeOption, Options) ->
27+
Resolved=Answer
28+
; Resolved=Default
29+
).
30+
31+
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32+
?- option_default(type, Resolved, []).
33+
?- option_default(type, Resolved, [type(binary)]).
34+
?- option_default(type, Resolved, [type(text)]).
35+
?- option_default(type, Resolved, [alias]).
36+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37+
38+
parse_option(type(Type)) :-
39+
( memberchk(Type, [binary, text]), !
40+
; throw(error(instantiation_error, choose_for(type, one_of(binary, text))))
41+
).
42+
43+
parse_option(reposition(Bool)) :-
44+
catch(must_be(boolean, Bool),
45+
error(_,_),
46+
throw(error(instantiation_error, choose_for(binary, one_of(true,false))))
47+
).
48+
49+
parse_option(alias(A)) :-
50+
( var(A)
51+
-> throw(error(instantiation_error, must_satisfy(alias, var)))
52+
; true
53+
),
54+
( atom(A), dif(A, []), !
55+
; throw(error(instantiation_error, must_satisfy(alias, (atom, dif([])))))
56+
)
57+
.
58+
59+
60+
parse_option(eof_action(Action)) :-
61+
( nonvar(Action), memberchk(Action, [eof_code, error, reset]), !
62+
; throw(error(domain_error(stream_option), choose_one(eof_action, [eof_code, error, reset])))
63+
).
64+
65+
validate_chars(Chars, Type) :-
66+
validate_chars_(Chars, Type).
67+
68+
valid_byte_(Byte) :-
69+
must_be(integer, Byte),
70+
Byte >= 0,
71+
Byte < 256.
72+
73+
validate_chars_(Chars, binary) :-
74+
maplist(valid_byte_, Chars).
75+
76+
validate_chars_(Chars, text) :-
77+
must_be(chars, Chars).

0 commit comments

Comments
 (0)