File: file.m

package info (click to toggle)
mercury 0.9-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 18,488 kB
  • ctags: 9,800
  • sloc: objc: 146,680; ansic: 51,418; sh: 6,436; lisp: 1,567; cpp: 1,040; perl: 854; makefile: 450; asm: 232; awk: 203; exp: 32; fortran: 3; csh: 1
file content (141 lines) | stat: -rw-r--r-- 4,838 bytes parent folder | download | duplicates (2)
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)).

%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%