diff options
author | Patrik Nyblom <[email protected]> | 2010-12-03 15:38:14 +0100 |
---|---|---|
committer | Patrik Nyblom <[email protected]> | 2010-12-03 15:38:14 +0100 |
commit | 73b53fe24ebc595a81c4ee023bcfef5a71e59db4 (patch) | |
tree | ed75b935318dbef275d62ab141a5f59b5b36bce0 /lib/kernel/test/file_name_SUITE.erl | |
parent | 52b0fbbc4daa4e22fcad6fe39dd8f8cec8bb8d1b (diff) | |
parent | 159d79b6657e5bb4f3accb6a0d74b74f06da4ba2 (diff) | |
download | otp-73b53fe24ebc595a81c4ee023bcfef5a71e59db4.tar.gz otp-73b53fe24ebc595a81c4ee023bcfef5a71e59db4.tar.bz2 otp-73b53fe24ebc595a81c4ee023bcfef5a71e59db4.zip |
Merge branch 'pan/unicode-filenames/OTP-8887' into dev
* pan/unicode-filenames/OTP-8887: (27 commits)
Test and correct filelib and filename
Add documentation to erlang.xml and slight correction to unicode_usage.xml
Add section about Unicode file names to stdlib users guide
Correct bug in file_name_SUITE making it fail on Unix instead of Windows7
Add documentation about raw filenames and Unicode file name translation mode
Make filelib not crash on re codepoints beyond 255 in re when filename is raw
Mend on_load_embedded testcase which did not handle windows links
Correct testcase regarding windows versions supporting soft links.
Teach filelib to use re in unicode mode when filenames are not raw
Treat soft links on Windows correctly in file_name_SUITE
Adapt new soft and hard link routines on Windos to Unicode
Corrected testcases broken by unicode filenames
Update preloaded prim_file
Teach prim_file not to accept atoms and not to throw exceptions
Adapt inet_drv to Visual Studio 2008
Teach spawn_executable about Unicode
Convert filenames read on MacOSX to canonical form
Teach file to accept codepoints beyond 255.
Add testcases
Correct shell utilities to handle unicode and possibly binaries
...
Diffstat (limited to 'lib/kernel/test/file_name_SUITE.erl')
-rw-r--r-- | lib/kernel/test/file_name_SUITE.erl | 1729 |
1 files changed, 1729 insertions, 0 deletions
diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl new file mode 100644 index 0000000000..fea4df8539 --- /dev/null +++ b/lib/kernel/test/file_name_SUITE.erl @@ -0,0 +1,1729 @@ +-module(file_name_SUITE). +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-include("test_server.hrl"). +-include_lib("kernel/include/file.hrl"). + +%% +%% File operations that take filenames as parameters (* not prim_file operation) (** a drive): +%% altname +%% copy (*) +%% del_dir +%% delete +%% get_cwd (**) +%% list_dir +%% make_dir +%% make_link +%% make_symlink +%% open +%% read_file +%% read_file_info +%% read_link +%% read_link_info +%% rename +%% set_cwd +%% write_file +%% write_file_info +%% +%% File operations that opens/uses separate driver port (not connected to file) +%% altname +%% del_dir +%% delete +%% get_cwd +%% list_dir +%% make_dir +%% make_link +%% make_symlink +%% read_file_info +%% read_link +%% read_link_info +%% rename +%% set_cwd +%% write_file_info +%% +%% Operations that use ?FD_DRV in prim_file +%% open +%% read_file +%% write_file +%% +%% +%% Operations that return a filename/path +%% altname +%% get_cwd +%% list_dir +%% read_link + +-export([all/1,init_per_testcase/2, fin_per_testcase/2]). +-export([normal/1,icky/1,very_icky/1,normalize/1]). + + +init_per_testcase(_Func, Config) -> + Dog = test_server:timetrap(test_server:seconds(60)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Func, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog). + + +all(suite) -> + [normal,icky,very_icky,normalize]. + +normalize(suite) -> + []; +normalize(doc) -> + ["Check that filename normalization works"]; +normalize(Config) when is_list(Config) -> + random:seed({1290,431421,830412}), + try + ?line UniMode = file:native_name_encoding() =/= latin1, + if + not UniMode -> + throw(need_unicode_mode); + true -> + ok + end, + ?line Pairs = [rand_comp_decomp(200) || _ <- lists:seq(1,1000)], + case os:type() of + {unix,darwin} -> + ?line [ true = (A =:= prim_file:internal_native2name(B)) || + {A,B} <- Pairs ]; + _ -> + ok + end, + ?line [ true = (A =:= prim_file:internal_normalize_utf8(B)) || + {A,B} <- Pairs ] + + catch + throw:need_unicode_mode -> + io:format("Sorry, can only run in unicode mode.~n"), + {skipped,"VM needs to be started in Unicode filename mode"} + end. + +normal(suite) -> + []; +normal(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +normal(Config) when is_list(Config) -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + ok = check_normal(prim_file), + put(file_module,file), + ok = check_normal(file) + after + file:set_cwd(Dir) + end. + + +icky(suite) -> + []; +icky(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +icky(Config) when is_list(Config) -> + case hopeless_darwin() of + true -> + {skipped,"This version of darwin does not support icky names at all."}; + false -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + ok = check_icky(prim_file), + put(file_module,file), + ok = check_icky(file) + after + file:set_cwd(Dir) + end + end. +very_icky(suite) -> + []; +very_icky(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +very_icky(Config) when is_list(Config) -> + case hopeless_darwin() of + true -> + {skipped,"This version of darwin does not support icky names at all."}; + false -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + case check_very_icky(prim_file) of + need_unicode_mode -> + {skipped,"VM needs to be started in Unicode filename mode"}; + ok -> + put(file_module,file), + ok = check_very_icky(file) + end + after + file:set_cwd(Dir) + end + end. + + +check_normal(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line make_normal_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + %erlang:display(L1), + ?line L1 = lists:sort(list(normal_dir())), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), + ?line case Mod:altname("fil1") of + {error,enotsup} -> + ok; + {ok,LLL} when is_list(LLL) -> + ok + end, + ?line [ true = is_list(El) || El <- L1], + ?line Syms = [ {S,Targ,list_to_binary(get_data(Targ,normal_dir()))} + || {T,S,Targ} <- normal_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,"temp_dir",normal_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("tmp_dir"), + ?line ok = Mod:set_cwd("temp_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r(Mod,"temp_dir"), + ?line true = is_list(Dir), + ?line [ true = is_list(FN) || FN <- L0 ], + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse"), + ?line {ok, <<"fil1">>} = Mod:read_file("nisse"), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse"), + ?line ok = Mod:delete("nisse"), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse"), + ?line {error,enoent} = Mod:read_link_info("nisse"); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- normal_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary(Content), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- normal_dir() ], + ?line Mod:rename("fil1","tmp_fil1"), + ?line {ok, <<"fil1">>} = Mod:read_file("tmp_fil1"), + ?line {error,enoent} = Mod:read_file("fil1"), + ?line Mod:rename("tmp_fil1","fil1"), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("tmp_fil1"), + ?line {ok,FI} = Mod:read_file_info("fil1"), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("fil1"), + ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("fil1"), + ok + after + case Mod:read_file_info("fil1") of + {ok,FII} -> + NewModeI = FII#file_info.mode bor 8#777, + Mod:write_file_info("fil1",FII#file_info{mode = NewModeI}); + _ -> + ok + end, + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +check_icky(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line true=(length("���") =:= 3), + ?line UniMode = file:native_name_encoding() =/= latin1, + ?line make_icky_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + io:format("~p ~p~n",[L1,list(icky_dir())]), + ?line L1 = lists:sort(convlist(list(icky_dir()))), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), +%% Altname only on windows, and there are no non native filenames there +%% ?line case Mod:altname("fil1") of +%% {error,enotsup} -> +%% ok; +%% {ok,LLL} when is_list(LLL) -> +%% ok +%% end, + ?line [ true = ((is_list(El) or (UniMode and is_binary(El)))) || El <- L1], + ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,icky_dir()))} + || {T,S,Targ} <- icky_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,"���_dir",icky_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("��_dir"), + ?line ok = Mod:set_cwd("���_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = is_list(NowAt), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,"���_dir"), + {OS,TYPE} = os:type(), + % Check that treat_icky really converts to the same as the OS + case UniMode of + true -> + ?line chk_cre_dir(Mod,[{directory,"���_dir",[]}]), + ?line ok = Mod:set_cwd("���_dir"), + ?line ok = Mod:write_file(<<"���">>,<<"hello">>), + ?line Treated = treat_icky(<<"���">>), + ?line {ok,[Treated]} = Mod:list_dir("."), + ?line ok = Mod:delete(<<"���">>), + ?line {ok,[]} = Mod:list_dir("."), + ?line ok = Mod:set_cwd(".."), + ?line rm_r2(Mod,"���_dir"); + false -> + ok + end, + + ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"���_dir">>),icky_dir()}]), + if + UniMode and (OS =/= win32) -> + ?line {error,enoent} = Mod:set_cwd("���_dir"); + true -> + ok + end, + ?line ok = Mod:set_cwd(treat_icky(<<"���_dir">>)), + ?line {ok, NowAt2} = Mod:get_cwd(), + io:format("~p~n",[NowAt2]), + % Cannot create raw unicode-breaking filenames on windows or macos + ?line true = ((((not UniMode) or (OS =:= win32) or (TYPE=:=darwin)) and is_list(NowAt2)) orelse ((UniMode) and is_binary(NowAt2))), + ?line true = BeginAt =/= NowAt2, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,conv(treat_icky(<<"���_dir">>))), + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse�"), + ?line {ok, <<"fil1">>} = Mod:read_file("nisse�"), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse�"), + ?line ok = Mod:delete("nisse�"), + ?line ok = Mod:make_link("fil1",treat_icky(<<"nisse�">>)), + ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisse�">>)), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisse�">>)), + ?line ok = Mod:delete(treat_icky(<<"nisse�">>)), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse�"), + ?line {error,enoent} = Mod:read_link_info("nisse�"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisse�">>)), + ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisse�">>)); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- icky_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary([Content]), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- icky_dir() ], + ?line Mod:rename("���2","���_fil1"), + ?line {ok, <<"���2">>} = Mod:read_file("���_fil1"), + ?line {error,enoent} = Mod:read_file("���2"), + ?line Mod:rename("���_fil1","���2"), + ?line {ok, <<"���2">>} = Mod:read_file("���2"), + ?line {error,enoent} = Mod:read_file("���_fil1"), + + ?line Mod:rename("���2",treat_icky(<<"���_fil1">>)), + ?line {ok, <<"���2">>} = Mod:read_file(treat_icky(<<"���_fil1">>)), + if + UniMode and (OS =/= win32) -> + {error,enoent} = Mod:read_file("���_fil1"); + true -> + ok + end, + ?line {error,enoent} = Mod:read_file("���2"), + ?line Mod:rename(treat_icky(<<"���_fil1">>),"���2"), + ?line {ok, <<"���2">>} = Mod:read_file("���2"), + ?line {error,enoent} = Mod:read_file("���_fil1"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"���_fil1">>)), + + ?line {ok,FI} = Mod:read_file_info("���2"), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("���2"), + ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("���2"), + + ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info(treat_icky(<<"���5">>),FII#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line ok = Mod:write_file_info(<<"���5">>,FII#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"���5">>)), + ok + after + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +check_very_icky(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line true=(length("���") =:= 3), + ?line UniMode = file:native_name_encoding() =/= latin1, + if + not UniMode -> + throw(need_unicode_mode); + true -> + ok + end, + ?line make_very_icky_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + ?line L1 = lists:sort(convlist(list(very_icky_dir()))), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), + ?line [ true = ((is_list(El) or is_binary(El))) || El <- L1], + ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,very_icky_dir()))} + || {T,S,Targ} <- very_icky_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,[1088,1079,1091]++"_dir",very_icky_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("��_dir"), + ?line ok = Mod:set_cwd([1088,1079,1091]++"_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = is_list(NowAt), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,[1088,1079,1091]++"_dir"), + + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse"++[1088,1079,1091]), + ?line {ok, <<"fil1">>} = + Mod:read_file("nisse"++[1088,1079,1091]), + ?line {ok, #file_info{type = regular}} = + Mod:read_link_info("nisse"++[1088,1079,1091]), + ?line ok = Mod:delete("nisse"++[1088,1079,1091]), + ?line ok = Mod:make_link("fil1",<<"nisse�">>), + ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisse�">>), + ?line {ok, #file_info{type = regular}} = + Mod:read_link_info(<<"nisse�">>), + ?line ok = Mod:delete(<<"nisse�">>), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse"++[1088,1079,1091]), + ?line {error,enoent} = Mod:read_link_info("nisse"++[1088,1079,1091]), + ?line {error,enoent} = Mod:read_file(<<"nisse�">>), + ?line {error,enoent} = Mod:read_link_info(<<"nisse�">>); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- very_icky_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary([Content]), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- very_icky_dir() ], + ?line Mod:rename([956,965,963,954,959,49], + [956,965,963,954,959]++"_fil1"), + ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"), + ?line {error,enoent} = Mod:read_file([956,965,963,954,959,49]), + ?line Mod:rename([956,965,963,954,959]++"_fil1",[956,965,963,954,959,49]), + ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959,49]), + ?line {error,enoent} = Mod:read_file([956,965,963,954,959]++"_fil1"), + + ?line {ok,FI} = Mod:read_file_info([956,965,963,954,959,49]), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info([956,965,963,954,959,49], + FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = + Mod:read_file_info([956,965,963,954,959,49]), + ?line ok = Mod:write_file_info([956,965,963,954,959,49], + FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = + Mod:read_file_info([956,965,963,954,959,49]), + ?line NumOK0 = case has_links() of + true -> 5; + false -> 3 + end, + ?line NumNOK0 = case has_links() of + true -> 4; + false -> 3 + end, + ?line {NumOK,NumNOK} = case is_binary(treat_icky(<<"foo">>)) of + false -> + {NumOK0+NumNOK0,0}; + true -> + {NumOK0,NumNOK0} + end, + ?line {NumOK,NumNOK} = filelib:fold_files(".",".*",true,fun(_F,{N,M}) when is_list(_F) -> io:format("~ts~n",[_F]),{N+1,M}; (_F,{N,M}) -> io:format("~p~n",[_F]),{N,M+1} end,{0,0}), + ?line ok = filelib:fold_files(".",[1076,1089,1072,124,46,42],true,fun(_F,_) -> ok end,false), + ?line SF3 = unicode:characters_to_binary("���subfil3",file:native_name_encoding()), + ?line Sorted = lists:sort([SF3,<<"���subfil2">>]), + ?line Sorted = lists:sort(filelib:wildcard("*",<<"���subdir2">>)), + ok + catch + throw:need_unicode_mode -> + io:format("Sorry, can only run in unicode mode.~n"), + need_unicode_mode + after + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +%% +%% Utilities +%% + + +rm_rf(Mod,Dir) -> + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok, Content} = Mod:list_dir(Dir), + [ rm_rf(Mod,filename:join(Dir,C)) || C <- Content ], + Mod:del_dir(Dir), + ok; + {ok, #file_info{}} -> + Mod:delete(Dir); + _ -> + ok + end. + +rm_r(Mod,Dir) -> + %erlang:display({rm_r,Dir}), + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), + {ok, Content} = Mod:list_dir(Dir), + [ true = is_list(Part) || Part <- Content ], + [ true = is_list(filename:join(Dir,Part)) || Part <- Content ], + [ rm_r(Mod,filename:join(Dir,C)) || C <- Content ], + ok = Mod:del_dir(Dir), + ok; + {ok, #file_info{type = regular}} -> + {ok,#file_info{type = regular}} = Mod:read_file_info(Dir), + ok = Mod:delete(Dir); + {ok, #file_info{type = symlink}} -> + ok = Mod:delete(Dir) + end. +%% For icky test, allow binaries sometimes +rm_r2(Mod,Dir) -> + %erlang:display({rm_r2,Dir}), + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), + {ok, Content} = Mod:list_dir(Dir), + UniMode = file:native_name_encoding() =/= latin1, + [ true = (is_list(Part) orelse UniMode) || Part <- Content ], + [ true = (is_list(filename:join(Dir,Part)) orelse UniMode) || Part <- Content ], + [ rm_r2(Mod,filename:join(Dir,C)) || C <- Content ], + ok = Mod:del_dir(Dir), + ok; + {ok, #file_info{type = regular}} -> + {ok,#file_info{type = regular}} = Mod:read_file_info(Dir), + ok = Mod:delete(Dir); + {ok, #file_info{type = symlink}} -> + ok = Mod:delete(Dir) + end. +chk_cre_dir(_,[]) -> + ok; +chk_cre_dir(Mod,[{regular,Name,Content}|T]) -> + %io:format("~p~n",[Name]), + ok = Mod:write_file(Name,Content), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{link,Name,Target}|T]) -> + ok = Mod:make_link(Target,Name), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{symlink,Name,Target}|T]) -> + ok = Mod:make_symlink(Target,Name), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{directory,Name,Content}|T]) -> + ok = Mod:make_dir(Name), + %io:format("Content = ~p~n",[Content]), + Content2 = [{Ty,filename:join(Name,N),case Ty of link -> filename:join(Name,C); _ -> C end} || {Ty,N,C} <- Content ], + %io:format("Content2 = ~p~n",[Content2]), + chk_cre_dir(Mod,Content2), + chk_cre_dir(Mod,T). + +has_links() -> + case os:type() of + {win32,_} -> + case os:version() of + {N,NN,_} when (N > 5) andalso (NN >= 1) -> + true; + _ -> + false + end; + _ -> + true + end. + +make_normal_dir(Mod) -> + rm_rf(Mod,"normal_dir"), + Mod:make_dir("normal_dir"), + Mod:set_cwd("normal_dir"), + Mod:write_file("fil1","fil1"), + Mod:write_file("fil2","fil2"), + case has_links() of + true -> + Mod:make_link("fil2","fil3"), + Mod:make_symlink("fil2","fil4"); + _ -> + ok + end, + Mod:make_dir("subdir"), + Mod:write_file(filename:join("subdir","subfil1"),"subfil1"), + ok. + +normal_dir() -> + [{regular,"fil1","fil1"}, + {regular,"fil2","fil2"}] ++ + case has_links() of + true -> + [{regular,"fil3","fil2"}, + {symlink,"fil4","fil2"}]; + false -> + [] + end ++ + [{directory,"subdir", + [{regular,"subfil1","subfil1"}]}]. + +make_icky_dir(Mod) -> + rm_rf(Mod,"icky_dir"), + Icky=icky_dir(), + chk_cre_dir(Mod,[{directory,"icky_dir",linkify([],Icky)}]), + Mod:set_cwd("icky_dir"), + ok. + +linkify(_Passed,[]) -> + []; +linkify(Passed,[{regular,Name,Content}|T]) -> + Regulars = [ {N,C} || {regular,N,C} <- Passed, N =/= Name ], + case lists:keysearch(Content,2,Regulars) of + {value, {Linkto, Content}} -> + [{link,Name,Linkto} | linkify(Passed,T)]; + _ -> + [{regular,Name,Content} | linkify([{regular,Name,Content}|Passed],T)] + end; +linkify(Passed,[{directory, Name, Content}|T]) -> + [{directory,Name, linkify(Content,Content)}|linkify(Passed,T)]; +linkify(Passed,[H|T]) -> + [H|linkify([H|Passed],T)]. + +hopeless_darwin() -> + case {os:type(),os:version()} of + {{unix,darwin},{Major,_,_}} when Major < 9 -> + true; + _ -> + false + end. + +icky_dir() -> + [{regular,"fil1","fil1"}, + {regular,"���2","���2"}] ++ + case has_links() of + true -> + [{regular,"���3","���2"}, + {symlink,"���4","���2"}]; + false -> + [] + end ++ + [{regular,treat_icky(<<"���5">>),"���5"}] ++ + case has_links() of + true -> + [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + false -> + [] + end ++ + [{directory,treat_icky(<<"���subdir2">>), + [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, + {regular,"���subfil3","���subfil13"}]}, + {directory,"���subdir", + [{regular,"���subfil1","���subfil1"}]}]. + +make_very_icky_dir(Mod) -> + rm_rf(Mod,"very_icky_dir"), + Icky=very_icky_dir(), + chk_cre_dir(Mod,[{directory,"very_icky_dir",linkify([],Icky)}]), + Mod:set_cwd("very_icky_dir"), + ok. + +very_icky_dir() -> + [{regular,"fil1","fil1"}, + {regular,[956,965,963,954,959,49],"���2"}] ++ + case has_links() of + true -> + [{regular,[956,965,963,954,959,50],"���2"}, + {symlink,[956,965,963,954,959,51],[956,965,963,954,959,49]}]; + false -> + [] + end ++ + [{regular,treat_icky(<<"���5">>),"���5"}] ++ + case has_links() of + true -> + [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + false -> + [] + end ++ + [{directory,treat_icky(<<"���subdir2">>), + [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, + {regular,"���subfil3","���subfil13"}]}, + {directory,[956,965,963,954,959]++"subdir1", + [{regular,[956,965,963,954,959]++"subfil1","���subfil1"}]}]. + +%% Some OS'es simply do not allow non UTF8 filenames +treat_icky(Bin) -> + case os:type() of + {unix,darwin} -> + binary_to_list(procentify(Bin)); + {win32,_} -> + binary_to_list(Bin); + _ -> + Bin + end. + +% Handle windows having absolute soft link targets. +fixlink({ok,Link}) -> + case os:type() of + {win32,_} -> + {ok,filename:basename(Link)}; + _ -> + {ok,Link} + end; +fixlink(X) -> + X. + +procentify(<<>>) -> + <<>>; +procentify(<<X:8,Rst/binary>>) when X > 127 -> + T=procentify(Rst), + Y = list_to_binary([$% + | io_lib:format("~2.16B",[X])]), + <<Y/binary,T/binary>>; +procentify(<<X:8,Rst/binary>>) -> + T=procentify(Rst), + <<X:8,T/binary>>. + + +list([]) -> + []; +list([{_,Name,_} | T]) -> + [Name | list(T)]. + + +get_data(FN,List) -> + case lists:keysearch(FN,2,List) of + {value,{regular,FN,C}} -> + C; + {value,{symlink,FN,NewFN}} -> + get_data(NewFN,List); + _-> + [] + end. + + +convlist(L) -> + convlist(file:native_name_encoding(),L). +convlist(latin1,[Bin|T]) when is_binary(Bin) -> + %erlang:display('Convert...'), + [binary_to_list(Bin)| convlist(latin1,T)]; +convlist(Any,[H|T]) -> + [H|convlist(Any,T)]; +convlist(_,[]) -> + []. + +conv(L) -> + NoUniMode = file:native_name_encoding() =:= latin1, + if + NoUniMode, is_binary(L) -> + binary_to_list(L); + true -> + L + end. + + +rand_comp_decomp(Max) -> + N = random:uniform(Max), + L = [ rand_decomp() || _ <- lists:seq(1,N) ], + LC = [ A || {A,_} <- L], + LD = lists:flatten([B || {_,B} <- L]), + LB = unicode:characters_to_binary(LD,unicode,utf8), + {LC,LB}. + +rand_decomp() -> + BT = bigtup(), + SZ = tuple_size(BT), + element(random:uniform(SZ),BT). +bigtup() -> + {{192,[65,768]}, + {200,[69,768]}, + {204,[73,768]}, + {210,[79,768]}, + {217,[85,768]}, + {7808,[87,768]}, + {7922,[89,768]}, + {224,[97,768]}, + {232,[101,768]}, + {236,[105,768]}, + {242,[111,768]}, + {249,[117,768]}, + {7809,[119,768]}, + {7923,[121,768]}, + {8173,[168,768]}, + {7846,[65,770,768]}, + {7872,[69,770,768]}, + {7890,[79,770,768]}, + {7847,[97,770,768]}, + {7873,[101,770,768]}, + {7891,[111,770,768]}, + {7700,[69,772,768]}, + {7760,[79,772,768]}, + {7701,[101,772,768]}, + {7761,[111,772,768]}, + {7856,[65,774,768]}, + {7857,[97,774,768]}, + {475,[85,776,768]}, + {476,[117,776,768]}, + {8146,[953,776,768]}, + {8162,[965,776,768]}, + {8074,[913,837,787,768]}, + {8090,[919,837,787,768]}, + {8106,[937,837,787,768]}, + {8066,[945,837,787,768]}, + {8082,[951,837,787,768]}, + {8098,[969,837,787,768]}, + {7946,[913,787,768]}, + {7962,[917,787,768]}, + {7978,[919,787,768]}, + {7994,[921,787,768]}, + {8010,[927,787,768]}, + {8042,[937,787,768]}, + {7938,[945,787,768]}, + {7954,[949,787,768]}, + {7970,[951,787,768]}, + {7986,[953,787,768]}, + {8002,[959,787,768]}, + {8018,[965,787,768]}, + {8034,[969,787,768]}, + {8075,[913,837,788,768]}, + {8091,[919,837,788,768]}, + {8107,[937,837,788,768]}, + {8067,[945,837,788,768]}, + {8083,[951,837,788,768]}, + {8099,[969,837,788,768]}, + {7947,[913,788,768]}, + {7963,[917,788,768]}, + {7979,[919,788,768]}, + {7995,[921,788,768]}, + {8011,[927,788,768]}, + {8027,[933,788,768]}, + {8043,[937,788,768]}, + {7939,[945,788,768]}, + {7955,[949,788,768]}, + {7971,[951,788,768]}, + {7987,[953,788,768]}, + {8003,[959,788,768]}, + {8019,[965,788,768]}, + {8035,[969,788,768]}, + {7900,[79,795,768]}, + {7914,[85,795,768]}, + {7901,[111,795,768]}, + {7915,[117,795,768]}, + {8114,[945,837,768]}, + {8130,[951,837,768]}, + {8178,[969,837,768]}, + {8122,[913,768]}, + {8136,[917,768]}, + {8138,[919,768]}, + {8154,[921,768]}, + {8184,[927,768]}, + {8170,[933,768]}, + {8186,[937,768]}, + {8048,[945,768]}, + {8050,[949,768]}, + {8052,[951,768]}, + {8054,[953,768]}, + {8056,[959,768]}, + {8058,[965,768]}, + {8060,[969,768]}, + {8141,[8127,768]}, + {8157,[8190,768]}, + {193,[65,769]}, + {262,[67,769]}, + {201,[69,769]}, + {500,[71,769]}, + {205,[73,769]}, + {7728,[75,769]}, + {313,[76,769]}, + {7742,[77,769]}, + {323,[78,769]}, + {211,[79,769]}, + {7764,[80,769]}, + {340,[82,769]}, + {346,[83,769]}, + {218,[85,769]}, + {7810,[87,769]}, + {221,[89,769]}, + {377,[90,769]}, + {225,[97,769]}, + {263,[99,769]}, + {233,[101,769]}, + {501,[103,769]}, + {237,[105,769]}, + {7729,[107,769]}, + {314,[108,769]}, + {7743,[109,769]}, + {324,[110,769]}, + {243,[111,769]}, + {7765,[112,769]}, + {341,[114,769]}, + {347,[115,769]}, + {250,[117,769]}, + {7811,[119,769]}, + {253,[121,769]}, + {378,[122,769]}, + {8174,[168,769]}, + {508,[198,769]}, + {510,[216,769]}, + {509,[230,769]}, + {511,[248,769]}, + {7844,[65,770,769]}, + {7870,[69,770,769]}, + {7888,[79,770,769]}, + {7845,[97,770,769]}, + {7871,[101,770,769]}, + {7889,[111,770,769]}, + {7756,[79,771,769]}, + {7800,[85,771,769]}, + {7757,[111,771,769]}, + {7801,[117,771,769]}, + {7702,[69,772,769]}, + {7762,[79,772,769]}, + {7703,[101,772,769]}, + {7763,[111,772,769]}, + {7854,[65,774,769]}, + {7855,[97,774,769]}, + {7726,[73,776,769]}, + {471,[85,776,769]}, + {7727,[105,776,769]}, + {472,[117,776,769]}, + {8147,[953,776,769]}, + {8163,[965,776,769]}, + {506,[65,778,769]}, + {507,[97,778,769]}, + {8076,[913,837,787,769]}, + {8092,[919,837,787,769]}, + {8108,[937,837,787,769]}, + {8068,[945,837,787,769]}, + {8084,[951,837,787,769]}, + {8100,[969,837,787,769]}, + {7948,[913,787,769]}, + {7964,[917,787,769]}, + {7980,[919,787,769]}, + {7996,[921,787,769]}, + {8012,[927,787,769]}, + {8044,[937,787,769]}, + {7940,[945,787,769]}, + {7956,[949,787,769]}, + {7972,[951,787,769]}, + {7988,[953,787,769]}, + {8004,[959,787,769]}, + {8020,[965,787,769]}, + {8036,[969,787,769]}, + {8077,[913,837,788,769]}, + {8093,[919,837,788,769]}, + {8109,[937,837,788,769]}, + {8069,[945,837,788,769]}, + {8085,[951,837,788,769]}, + {8101,[969,837,788,769]}, + {7949,[913,788,769]}, + {7965,[917,788,769]}, + {7981,[919,788,769]}, + {7997,[921,788,769]}, + {8013,[927,788,769]}, + {8029,[933,788,769]}, + {8045,[937,788,769]}, + {7941,[945,788,769]}, + {7957,[949,788,769]}, + {7973,[951,788,769]}, + {7989,[953,788,769]}, + {8005,[959,788,769]}, + {8021,[965,788,769]}, + {8037,[969,788,769]}, + {7898,[79,795,769]}, + {7912,[85,795,769]}, + {7899,[111,795,769]}, + {7913,[117,795,769]}, + {7688,[67,807,769]}, + {7689,[99,807,769]}, + {8116,[945,837,769]}, + {8132,[951,837,769]}, + {8180,[959,837,769]}, + {8123,[913,769]}, + {8137,[917,769]}, + {8139,[919,769]}, + {8155,[921,769]}, + {8185,[927,769]}, + {8171,[933,769]}, + {8187,[937,769]}, + {8049,[945,769]}, + {8051,[949,769]}, + {8053,[951,769]}, + {8055,[953,769]}, + {8057,[959,769]}, + {8059,[965,769]}, + {8061,[969,769]}, + {1027,[1043,769]}, + {1036,[1050,769]}, + {1107,[1075,769]}, + {1116,[1082,769]}, + {8142,[8127,769]}, + {8158,[8190,769]}, + {194,[65,770]}, + {264,[67,770]}, + {202,[69,770]}, + {284,[71,770]}, + {292,[72,770]}, + {206,[73,770]}, + {308,[74,770]}, + {212,[79,770]}, + {348,[83,770]}, + {219,[85,770]}, + {372,[87,770]}, + {374,[89,770]}, + {7824,[90,770]}, + {226,[97,770]}, + {265,[99,770]}, + {234,[101,770]}, + {285,[103,770]}, + {293,[104,770]}, + {238,[105,770]}, + {309,[106,770]}, + {244,[111,770]}, + {349,[115,770]}, + {251,[117,770]}, + {373,[119,770]}, + {375,[121,770]}, + {7825,[122,770]}, + {7852,[65,803,770]}, + {7878,[69,803,770]}, + {7896,[79,803,770]}, + {7853,[97,803,770]}, + {7879,[101,803,770]}, + {7897,[111,803,770]}, + {195,[65,771]}, + {7868,[69,771]}, + {296,[73,771]}, + {209,[78,771]}, + {213,[79,771]}, + {360,[85,771]}, + {7804,[86,771]}, + {7928,[89,771]}, + {227,[97,771]}, + {7869,[101,771]}, + {297,[105,771]}, + {241,[110,771]}, + {245,[111,771]}, + {361,[117,771]}, + {7805,[118,771]}, + {7929,[121,771]}, + {7850,[65,770,771]}, + {7876,[69,770,771]}, + {7894,[79,770,771]}, + {7851,[97,770,771]}, + {7877,[101,770,771]}, + {7895,[111,770,771]}, + {7860,[65,774,771]}, + {7861,[97,774,771]}, + {7904,[79,795,771]}, + {7918,[85,795,771]}, + {7905,[111,795,771]}, + {7919,[117,795,771]}, + {256,[65,772]}, + {274,[69,772]}, + {7712,[71,772]}, + {298,[73,772]}, + {332,[79,772]}, + {362,[85,772]}, + {257,[97,772]}, + {275,[101,772]}, + {7713,[103,772]}, + {299,[105,772]}, + {333,[111,772]}, + {363,[117,772]}, + {482,[198,772]}, + {483,[230,772]}, + {480,[65,775,772]}, + {481,[97,775,772]}, + {478,[65,776,772]}, + {469,[85,776,772]}, + {479,[97,776,772]}, + {470,[117,776,772]}, + {7736,[76,803,772]}, + {7772,[82,803,772]}, + {7737,[108,803,772]}, + {7773,[114,803,772]}, + {492,[79,808,772]}, + {493,[111,808,772]}, + {8121,[913,772]}, + {8153,[921,772]}, + {8169,[933,772]}, + {8113,[945,772]}, + {8145,[953,772]}, + {8161,[965,772]}, + {1250,[1048,772]}, + {1262,[1059,772]}, + {1251,[1080,772]}, + {1263,[1091,772]}, + {258,[65,774]}, + {276,[69,774]}, + {286,[71,774]}, + {300,[73,774]}, + {334,[79,774]}, + {364,[85,774]}, + {259,[97,774]}, + {277,[101,774]}, + {287,[103,774]}, + {301,[105,774]}, + {335,[111,774]}, + {365,[117,774]}, + {7862,[65,803,774]}, + {7863,[97,803,774]}, + {7708,[69,807,774]}, + {7709,[101,807,774]}, + {8120,[913,774]}, + {8152,[921,774]}, + {8168,[933,774]}, + {8112,[945,774]}, + {8144,[953,774]}, + {8160,[965,774]}, + {1232,[1040,774]}, + {1238,[1045,774]}, + {1217,[1046,774]}, + {1049,[1048,774]}, + {1038,[1059,774]}, + {1233,[1072,774]}, + {1239,[1077,774]}, + {1218,[1078,774]}, + {1081,[1080,774]}, + {1118,[1091,774]}, + {7682,[66,775]}, + {266,[67,775]}, + {7690,[68,775]}, + {278,[69,775]}, + {7710,[70,775]}, + {288,[71,775]}, + {7714,[72,775]}, + {304,[73,775]}, + {7744,[77,775]}, + {7748,[78,775]}, + {7766,[80,775]}, + {7768,[82,775]}, + {7776,[83,775]}, + {7786,[84,775]}, + {7814,[87,775]}, + {7818,[88,775]}, + {7822,[89,775]}, + {379,[90,775]}, + {7683,[98,775]}, + {267,[99,775]}, + {7691,[100,775]}, + {279,[101,775]}, + {7711,[102,775]}, + {289,[103,775]}, + {7715,[104,775]}, + {7745,[109,775]}, + {7749,[110,775]}, + {7767,[112,775]}, + {7769,[114,775]}, + {7777,[115,775]}, + {7787,[116,775]}, + {7815,[119,775]}, + {7819,[120,775]}, + {7823,[121,775]}, + {380,[122,775]}, + {7835,[383,775]}, + {7780,[83,769,775]}, + {7781,[115,769,775]}, + {784,[774,775]}, + {7782,[83,780,775]}, + {7783,[115,780,775]}, + {7784,[83,803,775]}, + {7785,[115,803,775]}, + {196,[65,776]}, + {203,[69,776]}, + {7718,[72,776]}, + {207,[73,776]}, + {214,[79,776]}, + {220,[85,776]}, + {7812,[87,776]}, + {7820,[88,776]}, + {376,[89,776]}, + {228,[97,776]}, + {235,[101,776]}, + {7719,[104,776]}, + {239,[105,776]}, + {246,[111,776]}, + {7831,[116,776]}, + {252,[117,776]}, + {7813,[119,776]}, + {7821,[120,776]}, + {255,[121,776]}, + {1242,[399,776]}, + {1258,[415,776]}, + {1243,[601,776]}, + {1259,[629,776]}, + {7758,[79,771,776]}, + {7759,[111,771,776]}, + {7802,[85,772,776]}, + {7803,[117,772,776]}, + {938,[921,776]}, + {939,[933,776]}, + {970,[953,776]}, + {971,[965,776]}, + {980,[978,776]}, + {1031,[1030,776]}, + {1234,[1040,776]}, + {1025,[1045,776]}, + {1244,[1046,776]}, + {1246,[1047,776]}, + {1252,[1048,776]}, + {1254,[1054,776]}, + {1264,[1059,776]}, + {1268,[1063,776]}, + {1272,[1067,776]}, + {1235,[1072,776]}, + {1105,[1077,776]}, + {1245,[1078,776]}, + {1247,[1079,776]}, + {1253,[1080,776]}, + {1255,[1086,776]}, + {1265,[1091,776]}, + {1269,[1095,776]}, + {1273,[1099,776]}, + {1111,[1110,776]}, + {7842,[65,777]}, + {7866,[69,777]}, + {7880,[73,777]}, + {7886,[79,777]}, + {7910,[85,777]}, + {7926,[89,777]}, + {7843,[97,777]}, + {7867,[101,777]}, + {7881,[105,777]}, + {7887,[111,777]}, + {7911,[117,777]}, + {7927,[121,777]}, + {7848,[65,770,777]}, + {7874,[69,770,777]}, + {7892,[79,770,777]}, + {7849,[97,770,777]}, + {7875,[101,770,777]}, + {7893,[111,770,777]}, + {7858,[65,774,777]}, + {7859,[97,774,777]}, + {7902,[79,795,777]}, + {7916,[85,795,777]}, + {7903,[111,795,777]}, + {7917,[117,795,777]}, + {197,[65,778]}, + {366,[85,778]}, + {229,[97,778]}, + {367,[117,778]}, + {7832,[119,778]}, + {7833,[121,778]}, + {336,[79,779]}, + {368,[85,779]}, + {337,[111,779]}, + {369,[117,779]}, + {1266,[1059,779]}, + {1267,[1091,779]}, + {461,[65,780]}, + {268,[67,780]}, + {270,[68,780]}, + {282,[69,780]}, + {486,[71,780]}, + {463,[73,780]}, + {488,[75,780]}, + {317,[76,780]}, + {327,[78,780]}, + {465,[79,780]}, + {344,[82,780]}, + {352,[83,780]}, + {356,[84,780]}, + {467,[85,780]}, + {381,[90,780]}, + {462,[97,780]}, + {269,[99,780]}, + {271,[100,780]}, + {283,[101,780]}, + {487,[103,780]}, + {464,[105,780]}, + {496,[106,780]}, + {489,[107,780]}, + {318,[108,780]}, + {328,[110,780]}, + {466,[111,780]}, + {345,[114,780]}, + {353,[115,780]}, + {357,[116,780]}, + {468,[117,780]}, + {382,[122,780]}, + {494,[439,780]}, + {495,[658,780]}, + {473,[85,776,780]}, + {474,[117,776,780]}, + {901,[168,781]}, + {912,[953,776,781]}, + {944,[965,776,781]}, + {902,[913,781]}, + {904,[917,781]}, + {905,[919,781]}, + {906,[921,781]}, + {908,[927,781]}, + {910,[933,781]}, + {911,[937,781]}, + {940,[945,781]}, + {941,[949,781]}, + {942,[951,781]}, + {943,[953,781]}, + {972,[959,781]}, + {973,[965,781]}, + {974,[969,781]}, + {979,[978,781]}, + {512,[65,783]}, + {516,[69,783]}, + {520,[73,783]}, + {524,[79,783]}, + {528,[82,783]}, + {532,[85,783]}, + {513,[97,783]}, + {517,[101,783]}, + {521,[105,783]}, + {525,[111,783]}, + {529,[114,783]}, + {533,[117,783]}, + {1142,[1140,783]}, + {1143,[1141,783]}, + {514,[65,785]}, + {518,[69,785]}, + {522,[73,785]}, + {526,[79,785]}, + {530,[82,785]}, + {534,[85,785]}, + {515,[97,785]}, + {519,[101,785]}, + {523,[105,785]}, + {527,[111,785]}, + {531,[114,785]}, + {535,[117,785]}, + {8072,[913,837,787]}, + {8088,[919,837,787]}, + {8104,[937,837,787]}, + {8064,[945,837,787]}, + {8080,[951,837,787]}, + {8096,[969,837,787]}, + {7944,[913,787]}, + {7960,[917,787]}, + {7976,[919,787]}, + {7992,[921,787]}, + {8008,[927,787]}, + {8040,[937,787]}, + {7936,[945,787]}, + {7952,[949,787]}, + {7968,[951,787]}, + {7984,[953,787]}, + {8000,[959,787]}, + {8164,[961,787]}, + {8016,[965,787]}, + {8032,[969,787]}, + {8073,[913,837,788]}, + {8089,[919,837,788]}, + {8105,[937,837,788]}, + {8065,[945,837,788]}, + {8081,[951,837,788]}, + {8097,[969,837,788]}, + {7945,[913,788]}, + {7961,[917,788]}, + {7977,[919,788]}, + {7993,[921,788]}, + {8009,[927,788]}, + {8172,[929,788]}, + {8025,[933,788]}, + {8041,[937,788]}, + {7937,[945,788]}, + {7953,[949,788]}, + {7969,[951,788]}, + {7985,[953,788]}, + {8001,[959,788]}, + {8165,[961,788]}, + {8017,[965,788]}, + {8033,[969,788]}, + {416,[79,795]}, + {431,[85,795]}, + {417,[111,795]}, + {432,[117,795]}, + {7840,[65,803]}, + {7684,[66,803]}, + {7692,[68,803]}, + {7864,[69,803]}, + {7716,[72,803]}, + {7882,[73,803]}, + {7730,[75,803]}, + {7734,[76,803]}, + {7746,[77,803]}, + {7750,[78,803]}, + {7884,[79,803]}, + {7770,[82,803]}, + {7778,[83,803]}, + {7788,[84,803]}, + {7908,[85,803]}, + {7806,[86,803]}, + {7816,[87,803]}, + {7924,[89,803]}, + {7826,[90,803]}, + {7841,[97,803]}, + {7685,[98,803]}, + {7693,[100,803]}, + {7865,[101,803]}, + {7717,[104,803]}, + {7883,[105,803]}, + {7731,[107,803]}, + {7735,[108,803]}, + {7747,[109,803]}, + {7751,[110,803]}, + {7885,[111,803]}, + {7771,[114,803]}, + {7779,[115,803]}, + {7789,[116,803]}, + {7909,[117,803]}, + {7807,[118,803]}, + {7817,[119,803]}, + {7925,[121,803]}, + {7827,[122,803]}, + {7906,[79,795,803]}, + {7920,[85,795,803]}, + {7907,[111,795,803]}, + {7921,[117,795,803]}, + {7794,[85,804]}, + {7795,[117,804]}, + {7680,[65,805]}, + {7681,[97,805]}, + {199,[67,807]}, + {7696,[68,807]}, + {290,[71,807]}, + {7720,[72,807]}, + {310,[75,807]}, + {315,[76,807]}, + {325,[78,807]}, + {342,[82,807]}, + {350,[83,807]}, + {354,[84,807]}, + {231,[99,807]}, + {7697,[100,807]}, + {291,[103,807]}, + {7721,[104,807]}, + {311,[107,807]}, + {316,[108,807]}, + {326,[110,807]}, + {343,[114,807]}, + {351,[115,807]}, + {355,[116,807]}, + {260,[65,808]}, + {280,[69,808]}, + {302,[73,808]}, + {490,[79,808]}, + {370,[85,808]}, + {261,[97,808]}, + {281,[101,808]}, + {303,[105,808]}, + {491,[111,808]}, + {371,[117,808]}, + {7698,[68,813]}, + {7704,[69,813]}, + {7740,[76,813]}, + {7754,[78,813]}, + {7792,[84,813]}, + {7798,[85,813]}, + {7699,[100,813]}, + {7705,[101,813]}, + {7741,[108,813]}, + {7755,[110,813]}, + {7793,[116,813]}, + {7799,[117,813]}, + {7722,[72,814]}, + {7723,[104,814]}, + {7706,[69,816]}, + {7724,[73,816]}, + {7796,[85,816]}, + {7707,[101,816]}, + {7725,[105,816]}, + {7797,[117,816]}, + {7686,[66,817]}, + {7694,[68,817]}, + {7732,[75,817]}, + {7738,[76,817]}, + {7752,[78,817]}, + {7774,[82,817]}, + {7790,[84,817]}, + {7828,[90,817]}, + {7687,[98,817]}, + {7695,[100,817]}, + {7830,[104,817]}, + {7733,[107,817]}, + {7739,[108,817]}, + {7753,[110,817]}, + {7775,[114,817]}, + {7791,[116,817]}, + {7829,[122,817]}, + {8129,[168,834]}, + {8151,[953,776,834]}, + {8167,[965,776,834]}, + {8078,[913,837,787,834]}, + {8094,[919,837,787,834]}, + {8110,[937,837,787,834]}, + {8070,[945,837,787,834]}, + {8086,[951,837,787,834]}, + {8102,[969,837,787,834]}, + {7950,[913,787,834]}, + {7982,[919,787,834]}, + {7998,[921,787,834]}, + {8046,[937,787,834]}, + {7942,[945,787,834]}, + {7974,[951,787,834]}, + {7990,[953,787,834]}, + {8022,[965,787,834]}, + {8038,[969,787,834]}, + {8079,[913,837,788,834]}, + {8095,[919,837,788,834]}, + {8111,[937,837,788,834]}, + {8071,[945,837,788,834]}, + {8087,[951,837,788,834]}, + {8103,[969,837,788,834]}, + {7951,[913,788,834]}, + {7983,[919,788,834]}, + {7999,[921,788,834]}, + {8031,[933,788,834]}, + {8047,[937,788,834]}, + {7943,[945,788,834]}, + {7975,[951,788,834]}, + {7991,[953,788,834]}, + {8023,[965,788,834]}, + {8039,[969,788,834]}, + {8119,[945,837,834]}, + {8135,[951,837,834]}, + {8183,[969,837,834]}, + {8118,[945,834]}, + {8134,[951,834]}, + {8150,[953,834]}, + {8166,[965,834]}, + {8182,[969,834]}, + {8143,[8127,834]}, + {8159,[8190,834]}, + {8124,[913,837]}, + {8140,[919,837]}, + {8188,[937,837]}, + {8115,[945,837]}, + {8131,[951,837]}, + {8179,[969,837]}, + {64302,[1488,1463]}, + {64287,[1522,1463]}, + {64303,[1488,1464]}, + {64331,[1493,1465]}, + {64304,[1488,1468]}, + {64305,[1489,1468]}, + {64306,[1490,1468]}, + {64307,[1491,1468]}, + {64308,[1492,1468]}, + {64309,[1493,1468]}, + {64310,[1494,1468]}, + {64312,[1496,1468]}, + {64313,[1497,1468]}, + {64314,[1498,1468]}, + {64315,[1499,1468]}, + {64316,[1500,1468]}, + {64318,[1502,1468]}, + {64320,[1504,1468]}, + {64321,[1505,1468]}, + {64323,[1507,1468]}, + {64324,[1508,1468]}, + {64326,[1510,1468]}, + {64327,[1511,1468]}, + {64328,[1512,1468]}, + {64329,[1513,1468]}, + {64330,[1514,1468]}, + {64332,[1489,1471]}, + {64333,[1499,1471]}, + {64334,[1508,1471]}, + {64300,[1513,1468,1473]}, + {64298,[1513,1473]}, + {64301,[1513,1468,1474]}, + {64299,[1513,1474]}, + {2392,[2325,2364]}, + {2393,[2326,2364]}, + {2394,[2327,2364]}, + {2395,[2332,2364]}, + {2396,[2337,2364]}, + {2397,[2338,2364]}, + {2345,[2344,2364]}, + {2398,[2347,2364]}, + {2399,[2351,2364]}, + {2353,[2352,2364]}, + {2356,[2355,2364]}, + {2524,[2465,2492]}, + {2525,[2466,2492]}, + {2480,[2476,2492]}, + {2527,[2479,2492]}, + {2507,[2503,2494]}, + {2508,[2503,2519]}, + {2649,[2582,2620]}, + {2650,[2583,2620]}, + {2651,[2588,2620]}, + {2652,[2593,2620]}, + {2654,[2603,2620]}, + {2908,[2849,2876]}, + {2909,[2850,2876]}, + {2911,[2863,2876]}, + {2891,[2887,2878]}, + {2888,[2887,2902]}, + {2892,[2887,2903]}, + {3018,[3014,3006]}, + {3019,[3015,3006]}, + {2964,[2962,3031]}, + {3020,[3014,3031]}, + {3144,[3142,3158]}, + {3274,[3270,3266]}, + {3264,[3263,3285]}, + {3275,[3270,3266,3285]}, + {3271,[3270,3285]}, + {3272,[3270,3286]}, + {3402,[3398,3390]}, + {3403,[3399,3390]}, + {3404,[3398,3415]}, + {3635,[3661,3634]}, + {3763,[3789,3762]}, + {3955,[3954,3953]}, + {3957,[3956,3953]}, + {3959,[4018,3968,3953]}, + {3961,[4019,3968,3953]}, + {3958,[4018,3968]}, + {3960,[4019,3968]}, + {3945,[3904,4021]}, + {4025,[3984,4021]}, + {3907,[3906,4023]}, + {3917,[3916,4023]}, + {3922,[3921,4023]}, + {3927,[3926,4023]}, + {3932,[3931,4023]}, + {3987,[3986,4023]}, + {3997,[3996,4023]}, + {4002,[4001,4023]}, + {4007,[4006,4023]}, + {4012,[4011,4023]}, + {12436,[12358,12441]}, + {12364,[12363,12441]}, + {12366,[12365,12441]}, + {12368,[12367,12441]}, + {12370,[12369,12441]}, + {12372,[12371,12441]}, + {12374,[12373,12441]}, + {12376,[12375,12441]}, + {12378,[12377,12441]}, + {12380,[12379,12441]}, + {12382,[12381,12441]}, + {12384,[12383,12441]}, + {12386,[12385,12441]}, + {12389,[12388,12441]}, + {12391,[12390,12441]}, + {12393,[12392,12441]}, + {12400,[12399,12441]}, + {12403,[12402,12441]}, + {12406,[12405,12441]}, + {12409,[12408,12441]}, + {12412,[12411,12441]}, + {12446,[12445,12441]}, + {12532,[12454,12441]}, + {12460,[12459,12441]}, + {12462,[12461,12441]}, + {12464,[12463,12441]}, + {12466,[12465,12441]}, + {12468,[12467,12441]}, + {12470,[12469,12441]}, + {12472,[12471,12441]}, + {12474,[12473,12441]}, + {12476,[12475,12441]}, + {12478,[12477,12441]}, + {12480,[12479,12441]}, + {12482,[12481,12441]}, + {12485,[12484,12441]}, + {12487,[12486,12441]}, + {12489,[12488,12441]}, + {12496,[12495,12441]}, + {12499,[12498,12441]}, + {12502,[12501,12441]}, + {12505,[12504,12441]}, + {12508,[12507,12441]}, + {12535,[12527,12441]}, + {12536,[12528,12441]}, + {12537,[12529,12441]}, + {12538,[12530,12441]}, + {12542,[12541,12441]}, + {12401,[12399,12442]}, + {12404,[12402,12442]}, + {12407,[12405,12442]}, + {12410,[12408,12442]}, + {12413,[12411,12442]}, + {12497,[12495,12442]}, + {12500,[12498,12442]}, + {12503,[12501,12442]}, + {12506,[12504,12442]}, + {12509,[12507,12442]}}. |