set domain_error exception & use format/3 with setup_call_cleanup/3 for stream writing

This commit is contained in:
Cyrille Duret
2020-07-17 01:21:40 +02:00
parent 5705c42820
commit 920644afaf

View File

@@ -57,13 +57,15 @@
write_csv/3 write_csv/3
]). ]).
:- use_module(library(format)).
:- use_module(library(dcgs)). :- use_module(library(dcgs)).
:- use_module(library(iso_ext)).
:- use_module(library(lists)). :- use_module(library(lists)).
option(W, O) :- option(W, O) :-
( member(W, O) -> true ( member(W, O) -> true
; throw(error(unknown_opt_error(W, O), option/2)). ; throw(error(domain_error(csv_option, W), option/2))).
option_extends([], Opt, Opt). option_extends([], Opt, Opt).
@@ -92,51 +94,54 @@ ensure_escaped([X | Y], Field) :-
escaped_field([X | Y], Field). escaped_field([X | Y], Field).
write_field(Field, Opt) :- write_field(Out, Field, Opt) :-
( Field \== [] -> ( Field \== [] ->
ensure_escaped(Field, Field0), ensure_escaped(Field, Field0),
write(Field0) format(Out, "~w", [Field0])
; option(null_value(Null_Value), Opt), ; option(null_value(Null_Value), Opt),
( Null_Value == empty -> true ( Null_Value == empty -> true
; write(Null_Value))). ; format(Out, "~w", [Null_Value]))).
write_row([Field], Opt) :- write_row(Out, [Field], Opt) :-
write_field(Field, Opt). write_field(Out, Field, Opt).
write_row([Field, X | Y], Opt) :- write_row(Out, [Field, X | Y], Opt) :-
write_field(Field, Opt), write_field(Out, Field, Opt),
option(token_separator(Tk_Sep), Opt), option(token_separator(Tk_Sep), Opt),
write(Tk_Sep), format(Out, "~w", [Tk_Sep]),
write_row([X | Y], Opt). write_row(Out, [X | Y], Opt).
write_rows([Row], Opt) :- write_rows(Out, [Row], Opt) :-
write_row(Row, Opt). write_row(Out, Row, Opt).
write_rows([Row, X | Y], Opt) :- write_rows(Out, [Row, X | Y], Opt) :-
option(line_separator(Line_Sep), Opt), option(line_separator(Line_Sep), Opt),
write_row(Row, Opt), write_row(Out, Row, Opt),
write(Line_Sep), format(Out, "~w", [Line_Sep]),
write_rows([X | Y], Opt). write_rows(Out, [X | Y], Opt).
write_csv(File_Name, frame(Header, Rows), Opt) :- write_csv_(Out, frame(Header, Rows), Opt) :-
option(with_header(With_Header), Opt),
( With_Header == true ->
write_row(Out, Header, Opt),
option(line_separator(Line_Sep), Opt),
format(Out, "~w", [Line_Sep])
; true),
write_rows(Out, Rows, Opt).
write_csv(File_Name, Frm, Opt) :-
option_extends(Opt, [ option_extends(Opt, [
null_value(empty), null_value(empty),
token_separator(','), token_separator(','),
with_header(true), with_header(true),
line_separator('\n') line_separator('\n')
], Opt0), ], Opt0),
open(File_Name, write, Out), setup_call_cleanup(
set_output(Out), open(File_Name, write, Out),
option(with_header(With_Header), Opt0), write_csv_(Out, Frm, Opt0),
( With_Header == true -> close(Out)).
write_row(Header, Opt0),
option(line_separator(Line_Sep), Opt0),
write(Line_Sep)
; true),
write_rows(Rows, Opt0),
close(Out),
set_output(user_output).
write_csv(File_Name, Frm) :- write_csv(File_Name, Frm) :-
write_csv(File_Name, Frm, []). write_csv(File_Name, Frm, []).