1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
%-----------------------------------------------------------------------------%
% Copyright (C) 1995-1998 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% Main author: bromage
% Simplified by Marnix Klooster <marnix@worldonline.nl>
% This module provides file input. One can read a file entirely,
% select a single line from a read file, get the number of lines
% in a read file, and convert a read file to a list of strings.
%
% Every file has a filename attached to it.
%-----------------------------------------------------------------------------%
:- module file.
:- interface.
:- import_module io, list, string.
:- type file.
% file__read_file reads a file from a filename.
:- pred file__read_file(string, io__res(file), io__state, io__state).
:- mode file__read_file(in, out, di, uo) is det.
% file__read_input reads a file from the input
% stream.
:- pred file__read_input(string, io__res(file), io__state, io__state).
:- mode file__read_input(in, out, di, uo) is det.
% file__get_line retrieves a line from a file.
% (Lines are numbered from 0.)
% Fails if the line is out of bounds.
:- pred file__get_line(file, int, string).
:- mode file__get_line(in, in, out) is semidet.
% file__get_numlines returns the number of lines
% in a file.
:- pred file__get_numlines(file, int).
:- mode file__get_numlines(in, out) is det.
% file__from_list converts a list of lines to a file.
:- pred file__from_list(string, list(string), file).
:- mode file__from_list(in, in, out) is det.
% file__to_list converts a file into a list of
% lines.
:- pred file__to_list(file, list(string)).
:- mode file__to_list(in, out) is det.
% file__get_file_name returns the name of the file.
:- pred file__get_file_name(file, string).
:- mode file__get_file_name(in, out) is det.
% file__set_file_name sets the name of the file.
:- pred file__set_file_name(file, string, file).
:- mode file__set_file_name(in, in, out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module array, require, int, bool.
%-----------------------------------------------------------------------------%
:- type file
---> file(
string, % File name
array(string) % Contents
).
% Open the stream, read from the stream, then close
% the stream.
file__read_file(FileName, File) -->
io__open_input(FileName, Res),
( { Res = ok(InputStream) },
file__read_stream(InputStream, Contents),
io__close_input(InputStream),
{ File = ok(file(FileName, Contents)) }
; { Res = error(Error) },
{ File = error(Error) }
).
% Get the input stream, then read from it.
file__read_input(FileName, ok(file(FileName, Contents))) -->
io__input_stream(InputStream),
file__read_stream(InputStream, Contents).
% file__read_stream is the "real" file reader.
:- pred file__read_stream(io__input_stream, array(string),
io__state, io__state).
:- mode file__read_stream(in, array_uo, di, uo) is det.
file__read_stream(Stream, File) -->
file__read_stream2(Stream, 0, File).
% Given a Stream from which LinesIn lines have already been
% read, fill File[LinesIn] to File[LinesOut-1] with the rest
% of the lines. LinesOut is the number of lines in the file.
% (Note that line numbering starts at zero.)
:- pred file__read_stream2(io__input_stream, int, array(string),
io__state, io__state).
:- mode file__read_stream2(in, in, array_uo, di, uo) is det.
file__read_stream2(Stream, LineNo, File) -->
io__read_line_as_string(Stream, Res),
( { Res = eof },
{ array__init(LineNo, "", File) }
; { Res = ok(Line) },
file__read_stream2(Stream, LineNo + 1, File1),
{ array__set(File1, LineNo, Line, File) }
; { Res = error(Error) },
{ io__error_message(Error, Msg) },
{ error(Msg) }
).
%-----------------------------------------------------------------------------%
file__get_line(file(_, Contents), LineNo, Line) :-
array__semidet_lookup(Contents, LineNo, Line).
file__get_numlines(file(_, Contents), NumLines1 + 1) :-
array__bounds(Contents, _, NumLines1).
%-----------------------------------------------------------------------------%
file__to_list(file(_, Contents), List) :-
array__to_list(Contents, List).
file__from_list(FileName, List, file(FileName, Contents)) :-
array__from_list(List, Contents).
%-----------------------------------------------------------------------------%
file__get_file_name(file(FileName, _), FileName).
file__set_file_name(file(_, B), FileName, file(FileName, B)).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
|