4
%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
4
%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
6
6
%% The contents of this file are subject to the Erlang Public License,
7
7
%% Version 1.1, (the "License"); you may not use this file except in
8
8
%% compliance with the License. You should have received a copy of the
9
9
%% Erlang Public License along with this software. If not, it can be
10
10
%% retrieved online at http://www.erlang.org/.
12
12
%% Software distributed under the License is distributed on an "AS IS"
13
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
14
%% the License for the specific language governing rights and limitations
15
15
%% under the License.
23
%% Avoid warning for local function error/1 clashing with autoimported BIF.
24
-compile({no_auto_import,[error/1]}).
23
25
-export([wildcard/1, wildcard/2, is_dir/1, is_file/1, is_regular/1,
24
26
compile_wildcard/1]).
25
27
-export([fold_files/5, last_modified/1, file_size/1, ensure_dir/1]).
41
43
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43
-spec wildcard(name()) -> [file:filename()].
45
-spec wildcard(file:name()) -> [file:filename()].
44
46
wildcard(Pattern) when is_list(Pattern) ->
45
47
?HANDLE_ERROR(do_wildcard(Pattern, file)).
47
-spec wildcard(name(), name() | atom()) -> [file:filename()].
48
wildcard(Pattern, Cwd) when is_list(Pattern), is_list(Cwd) ->
49
-spec wildcard(file:name(), file:name() | atom()) -> [file:filename()].
50
wildcard(Pattern, Cwd) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) ->
49
51
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, file));
50
52
wildcard(Pattern, Mod) when is_list(Pattern), is_atom(Mod) ->
51
53
?HANDLE_ERROR(do_wildcard(Pattern, Mod)).
53
-spec wildcard(name(), name(), atom()) -> [file:filename()].
55
-spec wildcard(file:name(), file:name(), atom()) -> [file:filename()].
54
56
wildcard(Pattern, Cwd, Mod)
55
when is_list(Pattern), is_list(Cwd), is_atom(Mod) ->
57
when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)), is_atom(Mod) ->
56
58
?HANDLE_ERROR(do_wildcard(Pattern, Cwd, Mod)).
58
-spec is_dir(name()) -> boolean().
60
-spec is_dir(file:name()) -> boolean().
60
62
do_is_dir(Dir, file).
62
-spec is_dir(name(), atom()) -> boolean().
64
-spec is_dir(file:name(), atom()) -> boolean().
63
65
is_dir(Dir, Mod) when is_atom(Mod) ->
64
66
do_is_dir(Dir, Mod).
66
-spec is_file(name()) -> boolean().
68
-spec is_file(file:name()) -> boolean().
68
70
do_is_file(File, file).
70
-spec is_file(name(), atom()) -> boolean().
72
-spec is_file(file:name(), atom()) -> boolean().
71
73
is_file(File, Mod) when is_atom(Mod) ->
72
74
do_is_file(File, Mod).
74
-spec is_regular(name()) -> boolean().
76
-spec is_regular(file:name()) -> boolean().
75
77
is_regular(File) ->
76
78
do_is_regular(File, file).
78
-spec is_regular(name(), atom()) -> boolean().
80
-spec is_regular(file:name(), atom()) -> boolean().
79
81
is_regular(File, Mod) when is_atom(Mod) ->
80
82
do_is_regular(File, Mod).
82
-spec fold_files(name(), string(), boolean(), fun((_,_) -> _), _) -> _.
84
-spec fold_files(file:name(), string(), boolean(), fun((_,_) -> _), _) -> _.
83
85
fold_files(Dir, RegExp, Recursive, Fun, Acc) ->
84
86
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, file).
86
-spec fold_files(name(), string(), boolean(), fun((_,_) -> _), _, atom()) -> _.
88
-spec fold_files(file:name(), string(), boolean(), fun((_,_) -> _), _, atom()) -> _.
87
89
fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) when is_atom(Mod) ->
88
90
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod).
90
-spec last_modified(name()) -> date_time() | 0.
92
-spec last_modified(file:name()) -> file:date_time() | 0.
91
93
last_modified(File) ->
92
94
do_last_modified(File, file).
94
-spec last_modified(name(), atom()) -> date_time() | 0.
96
-spec last_modified(file:name(), atom()) -> file:date_time() | 0.
95
97
last_modified(File, Mod) when is_atom(Mod) ->
96
98
do_last_modified(File, Mod).
98
-spec file_size(name()) -> non_neg_integer().
100
-spec file_size(file:name()) -> non_neg_integer().
99
101
file_size(File) ->
100
102
do_file_size(File, file).
102
-spec file_size(name(), atom()) -> non_neg_integer().
104
-spec file_size(file:name(), atom()) -> non_neg_integer().
103
105
file_size(File, Mod) when is_atom(Mod) ->
104
106
do_file_size(File, Mod).
127
129
do_wildcard_comp({compiled_wildcard,[current|Rest]}, Cwd0, Mod) ->
128
Cwd = filename:join([Cwd0]), %Slash away redundant slashes.
129
PrefixLen = length(Cwd)+1,
130
[lists:nthtail(PrefixLen, N) || N <- do_wildcard_1([Cwd], Rest, Mod)];
130
{Cwd,PrefixLen} = case filename:join([Cwd0]) of
131
Bin when is_binary(Bin) -> {Bin,byte_size(Bin)+1};
132
Other -> {Other,length(Other)+1}
133
end, %Slash away redundant slashes.
137
<<_:PrefixLen/binary,Res/binary>> = N,
140
lists:nthtail(PrefixLen, N)
141
end || N <- do_wildcard_1([Cwd], Rest, Mod)];
131
142
do_wildcard_comp({compiled_wildcard,[Base|Rest]}, _Cwd, Mod) ->
132
143
do_wildcard_1([Base], Rest, Mod).
164
175
%% If <Recursive> is true all sub-directories to <Dir> are processed
166
177
do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) ->
167
{ok, Re1} = re:compile(RegExp),
168
do_fold_files1(Dir, Re1, Recursive, Fun, Acc, Mod).
178
{ok, Re1} = re:compile(RegExp,[unicode]),
179
do_fold_files1(Dir, Re1, RegExp, Recursive, Fun, Acc, Mod).
170
do_fold_files1(Dir, RegExp, Recursive, Fun, Acc, Mod) ->
181
do_fold_files1(Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod) ->
171
182
case eval_list_dir(Dir, Mod) of
172
{ok, Files} -> do_fold_files2(Files, Dir, RegExp, Recursive, Fun, Acc, Mod);
183
{ok, Files} -> do_fold_files2(Files, Dir, RegExp, OrigRE,
184
Recursive, Fun, Acc, Mod);
173
185
{error, _} -> Acc
176
do_fold_files2([], _Dir, _RegExp, _Recursive, _Fun, Acc, _Mod) ->
188
%% OrigRE is not to be compiled as it's for non conforming filenames,
189
%% i.e. for filenames that does not comply to the current encoding, which should
190
%% be very rare. We use it only in those cases and do not want to precompile.
191
do_fold_files2([], _Dir, _RegExp, _OrigRE, _Recursive, _Fun, Acc, _Mod) ->
178
do_fold_files2([File|T], Dir, RegExp, Recursive, Fun, Acc0, Mod) ->
193
do_fold_files2([File|T], Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod) ->
179
194
FullName = filename:join(Dir, File),
180
195
case do_is_regular(FullName, Mod) of
182
case re:run(File, RegExp, [{capture,none}]) of
197
case (catch re:run(File, if is_binary(File) -> OrigRE;
199
[{capture,none}])) of
184
201
Acc = Fun(FullName, Acc0),
185
do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc, Mod);
202
do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod);
204
do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod);
187
do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod)
206
do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod)
190
209
case Recursive andalso do_is_dir(FullName, Mod) of
192
Acc1 = do_fold_files1(FullName, RegExp, Recursive,
211
Acc1 = do_fold_files1(FullName, RegExp, OrigRE, Recursive,
194
do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc1, Mod);
213
do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc1, Mod);
196
do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod)
215
do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod)