1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2001-2013, University of Amsterdam 7 VU University Amsterdam 8 All rights reserved. 9 10 Redistribution and use in source and binary forms, with or without 11 modification, are permitted provided that the following conditions 12 are met: 13 14 1. Redistributions of source code must retain the above copyright 15 notice, this list of conditions and the following disclaimer. 16 17 2. Redistributions in binary form must reproduce the above copyright 18 notice, this list of conditions and the following disclaimer in 19 the documentation and/or other materials provided with the 20 distribution. 21 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 POSSIBILITY OF SUCH DAMAGE. 34*/ 35 36:- module(read_util, 37 [ read_line_to_codes/2, % +Stream, -Codes (without trailing \n) 38 read_line_to_codes/3, % +Stream, -Codes, ?Tail 39 read_stream_to_codes/2, % +Stream, -Codes 40 read_stream_to_codes/3, % +Stream, -Codes, ?Tail 41 read_file_to_codes/3, % +File, -Codes, +Options 42 43 read_line_to_string/2, % +Stream, -Line (without trailing \n) 44 read_file_to_string/3, % +File, -Codes, +Options 45 46 read_file_to_terms/3 % +File, -Terms, +Options 47 ]). 48:- use_module(library(shlib)). 49:- use_module(library(error)). 50:- use_module(library(option)).
63:- predicate_options(read_file_to_codes/3, 3, 64 [ tail(list_or_partial_list), 65 pass_to(system:open/4, 4) 66 ]). 67:- predicate_options(read_file_to_string/3, 3, 68 [ pass_to(system:open/4, 4) 69 ]). 70:- predicate_options(read_file_to_terms/3, 3, 71 [ tail(list_or_partial_list), 72 pass_to(read_stream_to_terms/4, 4), 73 pass_to(system:absolute_file_name/3, 3), 74 pass_to(system:open/4, 4) 75 ]). 76 77:- volatile 78 read_line_to_codes/2, 79 read_line_to_codes/3, 80 read_stream_to_codes/2, 81 read_stream_to_codes/3. 82 83link_foreign :- 84 catch(load_foreign_library(foreign(readutil)), _, fail), 85 !. 86link_foreign :- 87 assertz((read_line_to_codes(Stream, Line) :- 88 pl_read_line_to_codes(Stream, Line))), 89 assertz((read_line_to_codes(Stream, Line, Tail) :- 90 pl_read_line_to_codes(Stream, Line, Tail))), 91 assertz((read_stream_to_codes(Stream, Content) :- 92 pl_read_stream_to_codes(Stream, Content))), 93 assertz((read_stream_to_codes(Stream, Content, Tail) :- 94 pl_read_stream_to_codes(Stream, Content, Tail))), 95 compile_predicates([ read_line_to_codes/2, 96 read_line_to_codes/3, 97 read_stream_to_codes/2, 98 read_stream_to_codes/3 99 ]). 100 101:- initialization(link_foreign, now). 102 103 104 /******************************* 105 * LINES * 106 *******************************/
end_of_file
.114pl_read_line_to_codes(Stream, Codes) :- 115 get_code(Stream, C0), 116 ( C0 == -1 117 -> Codes0 = end_of_file 118 ; read_1line_to_codes(C0, Stream, Codes0) 119 ), 120 Codes = Codes0. 121 122read_1line_to_codes(-1, _, []) :- !. 123read_1line_to_codes(10, _, []) :- !. 124read_1line_to_codes(13, Stream, L) :- 125 !, 126 get_code(Stream, C2), 127 read_1line_to_codes(C2, Stream, L). 128read_1line_to_codes(C, Stream, [C|T]) :- 129 get_code(Stream, C2), 130 read_1line_to_codes(C2, Stream, T).
138pl_read_line_to_codes(Stream, Codes, Tail) :- 139 get_code(Stream, C0), 140 read_line_to_codes(C0, Stream, Codes0, Tail), 141 Codes = Codes0. 142 143read_line_to_codes(-1, _, Tail, Tail) :- 144 !, 145 Tail = []. 146read_line_to_codes(10, _, [10|Tail], Tail) :- !. 147read_line_to_codes(C, Stream, [C|T], Tail) :- 148 get_code(Stream, C2), 149 read_line_to_codes(C2, Stream, T, Tail).
161read_line_to_string(Stream, String) :- 162 read_string(Stream, '\n', '\r', Sep, String0), 163 ( Sep \== -1 164 -> String = String0 165 ; String0 == "" 166 -> String = end_of_file 167 ; String = String0 168 ). 169 170 171 /******************************* 172 * STREAM (ENTIRE INPUT) * 173 *******************************/
181pl_read_stream_to_codes(Stream, Codes) :- 182 pl_read_stream_to_codes(Stream, Codes, []). 183pl_read_stream_to_codes(Stream, Codes, Tail) :- 184 get_code(Stream, C0), 185 read_stream_to_codes(C0, Stream, Codes0, Tail), 186 Codes = Codes0. 187 188read_stream_to_codes(-1, _, Tail, Tail) :- !. 189read_stream_to_codes(C, Stream, [C|T], Tail) :- 190 get_code(Stream, C2), 191 read_stream_to_codes(C2, Stream, T, Tail).
196read_stream_to_terms(Stream, Terms, Tail, Options) :- 197 read_term(Stream, C0, Options), 198 read_stream_to_terms(C0, Stream, Terms0, Tail, Options), 199 Terms = Terms0. 200 201read_stream_to_terms(end_of_file, _, Tail, Tail, _) :- !. 202read_stream_to_terms(C, Stream, [C|T], Tail, Options) :- 203 read_term(Stream, C2, Options), 204 read_stream_to_terms(C2, Stream, T, Tail, Options). 205 206 207 /******************************* 208 * FILE (ENTIRE INPUT) * 209 *******************************/
222read_file_to_codes(Spec, Codes, Options) :-
223 must_be(list, Options),
224 option(tail(Tail), Options, []),
225 absolute_file_name(Spec,
226 [ access(read)
227 | Options
228 ],
229 Path),
230 setup_call_cleanup(
231 open(Path, read, Stream, Options),
232 read_stream_to_codes(Stream, Codes, Tail),
233 close(Stream)).
242read_file_to_string(Spec, Codes, Options) :-
243 must_be(list, Options),
244 absolute_file_name(Spec,
245 [ access(read)
246 | Options
247 ],
248 Path),
249 setup_call_cleanup(
250 open(Path, read, Stream, Options),
251 read_string(Stream, _Len, Codes),
252 close(Stream)).
Note that the `output' options of read_term/3, such as
variable_names
or subterm_positions
will cause
read_file_to_terms/3 to fail if Spec contains multiple terms
because the values for the different terms will not unify.
268read_file_to_terms(Spec, Terms, Options) :-
269 must_be(list, Options),
270 option(tail(Tail), Options, []),
271 absolute_file_name(Spec,
272 [ access(read)
273 | Options
274 ],
275 Path),
276 setup_call_cleanup(
277 open(Path, read, Stream, Options),
278 read_stream_to_terms(Stream, Terms, Tail, Options),
279 close(Stream))
Read utilities
This library provides some commonly used reading predicates. As these predicates have proven to be time-critical in some applications we moved them to C. For compatibility as well as to reduce system dependency, we link the foreign code at runtime and fallback to the Prolog implementation if the shared object cannot be found.
library(pure_input)
allows for processing files with DCGs. */