14:- module(logicmoo_util_filesystem,
15 [
16 add_library_search_path/2,
17 add_file_search_path/2,
18 add_to_search_path/2,
19 add_to_search_path/3,
20 add_to_search_path_first/2,
21 add_to_search_path_last/2,
22 atom_concat_safe0/3,
23 atom_ensure_endswtih/3,
24 canonical_pathname/2,
25 load_with_asserter/4,
26 clip_dir_sep/2,
27 concat_paths/2,
28 concat_paths/3,
29 current_dirs/1,
30 current_dirs0/1,
31 32 current_filedir/1,
33 current_filesource/1,
34 enumerate_files/2,
35 enumerate_files0/2,
36 enumerate_files00/2,
37 enumerate_files01/2,
38 enumerate_files1/2,
39 enumerate_files2/2,
40 enumerate_m_files/3,
41 exists_directory_safe/1,
42 exists_dirf/1,
43 exists_file_or_dir/1,
44 exists_file_safe/1,
45 expand_file_name_safe/2,
46 expand_wfm/2,
47 filematch/2,
48 filematch3/3,
49 filematch_ext/3,
50 global_pathname/2,
51 if_startup_script/0,
52 in_include_file/0,
53 if_startup_script/1,
54 in_search_path/2,
55 is_directory/1,
56 join_path/3,
57 join_path_if_needed/3,
58 local_directory_search_combined/1,
59 local_directory_search_combined2/1,
60 locally_to_dir/2,
61 my_absolute_file_name/2,
62 63 normalize_path/2,
64 os_to_prolog_filename/2,
65 prolog_file_dir/1,
66 prolog_file_dir/2,
67 relative_pathname/2,
68 remove_search_path/2,
69 resolve_dir/2,
70 time_file_safe/2,
71 to_filename/2,
72 upcase_atom_safe/2,
73 with_filematch/1,
74 with_filematches/1,
75 contains_wildcard/1
76
77
78
79 ]). 80
81
82:- multifile
83 local_directory_search/1. 84:- meta_predicate
85 add_to_search_path(2, ?, ?),
86 enumerate_files(:, -),
87 filematch(:, -),
88 filematch_ext(+, :, -),
89 if_startup_script(0),
90 with_filematch(0). 91:- module_transparent
92 add_library_search_path/2,
93 add_file_search_path/2,
94 add_to_search_path/2,
95 add_to_search_path_first/2,
96 add_to_search_path_last/2,
97 atom_concat_safe0/3,
98 atom_ensure_endswtih/3,
99 canonical_pathname/2,
100 clip_dir_sep/2,
101 concat_paths/2,
102 concat_paths/3,
103 current_dirs/1,
104 current_dirs0/1,
105 current_filedir/1,
106 current_filesource/1,
107 enumerate_files0/2,
108 enumerate_files00/2,
109 enumerate_files01/2,
110 enumerate_files1/2,
111 enumerate_files2/2,
112 enumerate_m_files/3,
113 exists_directory_safe/1,
114 exists_dirf/1,
115 exists_file_or_dir/1,
116 exists_file_safe/1,
117 expand_file_name_safe/2,
118 expand_wfm/2,
119 filematch3/3,
120 global_pathname/2,
121 if_startup_script/0,
122 in_search_path/2,
123 is_directory/1,
124 join_path/3,
125 join_path_if_needed/3,
126 local_directory_search/1,
127 local_directory_search_combined/1,
128 local_directory_search_combined2/1,
129 locally_to_dir/2,
130 my_absolute_file_name/2,
131 normalize_path/2,
132 os_to_prolog_filename/2,
133 prolog_file_dir/1,
134 prolog_file_dir/2,
135 relative_pathname/2,
136 remove_search_path/2,
137 time_file_safe/2,
138 to_filename/2,
139 upcase_atom_safe/2,
140 141 with_filematches/1. 142:- dynamic
143 local_directory_search/1. 144
145:- set_module(class(library)). 147
148:- use_module(library(occurs)). 149:- use_module(library(gensym)). 150:- use_module(library(when)). 151
152:- use_module(library(occurs)). 153:- use_module(library(gensym)). 154:- use_module(library(when)). 155
156
157:- use_module(library(backcomp)). 158:- use_module(library(codesio)). 159:- use_module(library(charsio)). 160:- use_module(library(debug)). 161:- use_module(library(check)). 162
163
164:- use_module(library(edinburgh)). 165:- use_module(library(debug)). 166:- use_module(library(prolog_stack)). 167:- use_module(library(make)). 168
169
171:- use_module(library(system)). 172:- use_module(library(socket)). 173:- use_module(library(readutil)). 174:- abolish(system:time/1). 175:- use_module(library(statistics)). 176:- use_module(library(ssl)). 177:- use_module(library(prolog_codewalk)). 178:- use_module(library(prolog_source)). 179:- use_module(library(date)). 181:- use_module(library(listing)). 182
183:- ensure_loaded(library(logicmoo/no_repeats)). 184
185:- if(exists_source(library(filesex))). 187:- '@'( ensure_loaded(library(filesex)), 'user'). 188
189:-endif. 190
191
192assert_at_line_count(M,Pos,File,Cl):-
193 stream_position_data(line_count,Pos,Line),
194 '$compile_aux_clauses'([M:Cl], '$source_location'(File, Line)).
195
196assert_at_line_count_p1(Pred1,Cl,_Vs,_):- call(Pred1,Cl).
197assert_at_line_count_p2(Pred2,Cl, Vs,_):- call(Pred2,Cl,Vs).
198
199:- meta_predicate(load_with_asserter(+,+,1,+)). 200load_with_asserter(File0,File,Asserter,Options):-
201 once(absolute_file_name(File0, File, [access(read)]);
202 absolute_file_name(File0, File, [access(read),file_type(prolog)])),
203 open(File, read, In),
204 set_stream(In, encoding(iso_latin_1)),
205 repeat,
206 read_clause(In, Cl, Options),
207 208 call(Asserter,Cl),
209 Cl==end_of_file, !,
210 close(In).
211
212
213
216
225resolve_dir(Dir,Dir):- is_absolute_file_name(Dir),!,exists_directory(Dir),!.
226resolve_dir(Path,Dir):-
227 (prolog_load_context(directory,SDir);
228 (prolog_load_context(file,File),file_directory_name(File,SDir));
229 (prolog_load_context(source,File),file_directory_name(File,SDir));
230 (catch((current_source_file(F),to_filename(F,File),atom(File)),_,fail),file_directory_name(File,SDir));
231 working_directory(SDir,SDir)),exists_directory(SDir),
232 catch(absolute_file_name(Path,Dir,[relative_to(SDir),access(read),file_errors(fail),file_type(directory)]),_,fail),
233 exists_directory(Dir).
244add_file_search_path(Name,Path):- must(resolve_dir(Path,Dir)),
245 is_absolute_file_name(Dir), (( \+ user:file_search_path(Name,Dir)) ->asserta(user:file_search_path(Name,Dir));true).
258add_library_search_path(Path,Masks):-
259 forall(resolve_dir(Path,Dir),
260 (make_library_index(Dir, Masks),
261 (user:library_directory(Dir) -> true ; (asserta(user:library_directory(Dir)),
262 (access_file(Dir,write)->reload_library_index;true))))).
263
264
265:- meta_predicate(with_filematch(0)). 266
273with_filematch(G):- expand_wfm(G,GG),!,GG.
274
281with_filematches(G):- forall(expand_wfm(G,GG),GG).
282
283
290expand_wfm(G,GG):- once((sub_term(Sub, G),compound(Sub),Sub=wfm(F))),
291 (filematch(F,M),subst(G,wfm(F),M,GG),y_must(with_filematch(G), (G\=@=GG))).
292
293
294:- export(current_filesource/1). 295:- export(current_filedir/1). 296
303current_filedir(D):- no_repeats(D,(current_filesource(F),file_directory_name(F,D))).
304
311current_filesource(F):-source_location(F,_).
312current_filesource(F):-seeing(X),is_stream(X),stream_property(X,file_name(F)).
313current_filesource(F):-stream_property(_,file_name(F)).
314
315:- export(filematch/2). 316:- meta_predicate(filematch(:,-)). 317
324filematch(Spec,Result):- enumerate_files(Spec,Result).
325
326
327:- thread_local(t_l:file_ext/1). 328:- meta_predicate(filematch_ext(+,:,-)). 329:- export(filematch_ext/3). 330
337filematch_ext(Ext,FileIn,File):-
338 locally_tl(file_ext(Ext),findall(File,filematch(FileIn,File),List)),
339 when_ends_with(Ext,List,File).
340
341when_ends_with(_Ext,[],_File):- !,fail.
342when_ends_with(Ext,List,File):- ((member(File,List),only_if_ends_with(Ext,File)))*->true;member(File,List).
343
344only_if_ends_with(Ext,File):- atom(Ext),!,Ext\==[],atom_concat(_,Ext,File).
345only_if_ends_with([Ext|L],File):- only_if_ends_with(Ext,File)->true;only_if_ends_with(L,File).
346
348:- meta_predicate(enumerate_files(:,-)). 349:- export(enumerate_files/2).
355enumerate_files(Spec0,Result):- strip_module(Spec0,_,Spec),
356 call((atom(Spec),(exists_file_safe(Spec);exists_directory(Spec)),prolog_to_os_filename(Result,Spec))),
357 absolute_file_name(Spec,Result),exists_file_or_dir(Result),!.
358enumerate_files(Spec,Result):-absolute_file_name(Spec,Result),exists_file_or_dir(Result),!.
359enumerate_files(M:Spec,Result):-
360 call((no_repeats_old([Result],((enumerate_m_files(M,Spec,NResult),once((normalize_path(NResult,Result)->exists_file_or_dir(Result)))))))).
361
362
369:- export(enumerate_m_files/3). 370enumerate_m_files(user, Mask,File1):-!,enumerate_files0(Mask,File1).
371enumerate_m_files(M, Mask,File1):- enumerate_files0(Mask,File1)*->true;enumerate_m_files_mscoped(M, Mask,File1).
372
373
380enumerate_m_files_mscoped(M, Mask,File1):-
381 findall(t_l:search_first_dir(Dir),
382 (((M\=user,user:file_search_path(M,SP),expand_file_search_path(SP,Dir));
383 ((module_property(M, file(File)),directory_file_path(Dir,_,File)))),
384 exists_directory(Dir)),List),
385 list_to_set(List,Set),
386 locally(Set,enumerate_files0(Mask,File1)).
387
388:- export(enumerate_files0/2). 389
396enumerate_files0(Mask,File1):- absolute_file_name(Mask,X,[expand(true),file_errors(fail),solutions(all)]),expand_file_name(X,Y),Y\==[],member(File1,Y).
397enumerate_files0(Mask,File1):- one_must(filematch3('./',Mask,File1),(current_filedir(D),filematch3(D,Mask,File1))).
398enumerate_files0(Spec,Result):- enumerate_files00(Spec,Result).
399enumerate_files0(Spec,Result):- to_filename(Spec,Result).
400enumerate_files0(Mask,File1):- (current_dirs(D),filematch3(D,Mask,File1)).
401
402enumerate_files01(_Mask,_File1):-fail.
403
404
411enumerate_files00(Spec,Result):- expand_file_name_safe(Spec,ResultList),ResultList\=[],!,member(NResult,ResultList),enumerate_files2(NResult,Result).
412enumerate_files00(Spec,Result):- enumerate_files1(Spec,M),enumerate_files2(M,Result).
413
414
415:- export(filematch3/3). 416
423filematch3(RelativeTo,Mask,File1):-
424 findall(Ext,t_l:file_ext(Ext),EXTs),flatten([EXTs,'','pl.in'],Flat),
425 absolute_file_name(Mask,File1Matched,[extensions(Flat),
426 expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name_safe(File1Matched,File1S),member(File1,File1S).
427filematch3(RelativeTo,Mask,File1):-absolute_file_name(Mask,File1Matched,[file_type(directory),
428 expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name_safe(File1Matched,File1S),member(File1,File1S).
429
430:- export(enumerate_files2/2). 431
438enumerate_files2(Spec,Result):-sub_atom(Spec,_,1,_,'*') -> enumerate_files1(Spec,Result);Spec=Result.
439
440:- export(enumerate_files1/2). 441
442must_filematch(string(A),string(A)):-!.
443must_filematch(A,B):- filematch_smart(A,B) *-> true ; throw(must_filematch(A,B)).
444
445filematch_smart(Match,Each):- filematch(Match,Each)*-> true; filematch_smart_1(Match,Each) *-> true; filematch_smart_2(Match,Each).
447filematch_smart_1(Match,Each):- absolute_file_name(Match,Dir0,
448 [file_errors(fail),expand(true),solutions(all)]),
449 expand_file_name_wc(Dir0,DirS),
450 member(Each,DirS).
451filematch_smart_2(Match,Each):- atom(Match),!, \+ is_absolute_file_name(Match),!, filematch_smart_2(pddl(Match),Each).
452
453
454must_filematch_list(Match,List):- findall(File, must_filematch(Match,File), List).
455
456
463enumerate_files1(Atom,Result):- atomic(Atom),\+(is_absolute_file_name(Atom)),atomic_list_concat(List,'/',Atom),!,concat_paths(List,Result).
464enumerate_files1(Spec,Result):- exists_file_or_dir(Spec),!,Result=Spec.
465enumerate_files1(P/C,Result):- !,concat_paths(P,C,Result).
466enumerate_files1(Spec,Result):- expand_file_name_safe(Spec,ResultList),member(Result,ResultList).
467enumerate_files1(Spec,Result):- user:file_search_path(Spec,Result).
468enumerate_files1(Spec,Result):- expand_file_search_path(Spec,Result).
469enumerate_files1(Spec,Result):- absolute_file_name(Spec,Result).
470enumerate_files1(Atom,Result):- atomic(Atom),once((member(Sep,['/**/','/**','**']),atomic_list_concat([B,A|R],Sep,Atom))),concat_paths([B,'**',A|R],Result).
471
472:- export(expand_file_name_safe/2). 473
481expand_file_name_safe(I,O):-var(I),trace_or_throw(instanciation_error(expand_file_name_safe(I,O))),!.
482expand_file_name_safe(I,O):- atom(I),expand_file_name_wc(I,O),O\==[],!.
483expand_file_name_safe(I,O):- \+ compound(I), catch(expand_file_name(I,O),_,fail),O\==[I],O\=[],!.
484expand_file_name_safe(I,[O]):- catch(expand_file_search_path(I,O),_,fail),O\==[I],!.
485expand_file_name_safe(I,L):-
486 findall(O,
487 (absolute_file_name(I,O,[expand(true),solutions(all)]);
488 absolute_file_name(I,O,[expand(true),solutions(all),file_type(directory)])),
489 L),!.
490
491
492expand_file_name_wc(I,O):- atom(I),atomic_list_concat(List,'/',I),nav_each(List,O).
493
494nav_each([''|Seg],O):- !,nav_each('/',Seg,O).
495nav_each([Path|Seg],O):- nav_each('.',[Path|Seg],O).
496
497nav_each([],_,O):-!, O = [].
498nav_each([L|List],Seg,S):- !, is_list(List),
499 nav_each(L,Seg,O1), nav_each(List,Seg,O2), append(O1,O2,O), list_to_set(O,S).
500nav_each(Path,Seg,O):- notrace(catch(expand_file_name(Path,S),_,fail)), [Path]\==S,!, nav_each(S,Seg,O).
501nav_each(Path, _, O):- \+ exists_dirf(Path),!, O = [].
502nav_each(Path,[],[O]):- !, absolute_file_name(Path,O),!.
503nav_each(Path,['.'],O):- nav_each(Path,[''],O),!.
504nav_each(Path,[''],O):- !, (exists_directory(Path) -> nav_each(Path,[],O) ; O = []).
505nav_each(Path,[A|Seg],O):- directory_file_path(Path,A,Try),!,nav_each(Try,Seg,O).
506:- export(exists_file_or_dir/1). 507
508
515exists_file_or_dir(X):- nonvar(X),( X=(_:F)->exists_file_or_dir(F); (atomic(X),once((catch(exists_file_safe(X),E,(fmt(E:X),fail));is_directory(X))))).
516:- export(is_directory/1). 517
524is_directory(X):-exists_directory(X).
525
526:- export(concat_paths/3). 527
534concat_paths(A,'',A).
535concat_paths(A,'/',A):- atom_concat(_,'/',A),!.
536concat_paths(A,'/',A):- !.
537concat_paths(ParentIn,'**',Result):-!, member(Child,['./','./*/','./*/*/','./*/*/*/','./*/*/*/*/','./*/*/*/*/*/']),
538 concat_paths(ParentIn,Child,Result).
539concat_paths(ParentIn,Child,Result):-
540 filematch(ParentIn,Parent),
541 once((is_directory(Parent) -> directory_file_path(Parent,Child,Joined) ; atom_concat(Parent,Child,Joined))),!,
542 filematch(Joined,Result).
543
544:- export(concat_paths/2). 545
552concat_paths([Joined],Result):- !,filematch(Joined,Result).
553concat_paths([ParentIn,Child|MORE],Result):- concat_paths(ParentIn,Child,ResultM),concat_paths([ResultM|MORE],Result).
554
555
556:- thread_local(t_l:search_first_dir/1). 557
558
565current_dirs(DO):- no_repeats(DO,(current_dirs0(D),(atom_concat(DO,'/',D)->true;DO=D))).
566
573current_dirs0(D):- t_l:search_first_dir(D).
574current_dirs0(D):- prolog_load_context(directory,D).
575current_dirs0(D):- working_directory(D,D).
576current_dirs0(D):- quintus:current_stream(_,read,Y), stream_property(Y,file_name(FN)), file_directory_name(FN,D).
577current_dirs0(D):- stream_property(_,file_name(FN)), file_directory_name(FN,D).
578
582current_dirs0(D):- source_file_property(FN, modified(_)), file_directory_name(FN,D).
583current_dirs0('.').
584
585:- export(to_filename/2). 586:- thread_local(t_l:default_extension/1). 587
594to_filename( FileName, AFN ) :- atomic(FileName),exists_file_safe(FileName),!,AFN=FileName.
595to_filename( FileName, AFN ) :-
596 ((((t_l:default_extension( Ext ));Ext='.tlp';Ext='';Ext='.pl'),
597 current_dirs(D),
598 member(TF,[false,true]),
599 absolute_file_name(FileName,AFN,[solutions(all),expand(TF),access(read),relative_to(D),file_errors(fail),extensions(['',Ext,'.pl','.tlp','.clp','.P'])]),
600 exists_file_safe(AFN))),!.
601
602
603:- export((add_to_search_path/2,add_to_search_path_first/2,prolog_file_dir/2,if_startup_script/1,if_startup_script/0)). 604
605:- export(prolog_file_dir/1). 606
613prolog_file_dir(Here):- prolog_load_context(file, HereF),file_directory_name(HereF,Here).
614prolog_file_dir(Here):- working_directory(Here,Here).
615:- export(prolog_file_dir/2). 616
623prolog_file_dir(Rel,ABSF):-prolog_file_dir(Here),absolute_file_name(Rel,ABSF,[relative_to(Here),file_type(directory),expand(true)]),!.
624prolog_file_dir(Rel,ABSF):-prolog_file_dir(Here),absolute_file_name(Rel,ABSF,[relative_to(Here),expand(true)]),!.
631in_include_file:- prolog_load_context(file,F),!, \+ prolog_load_context(source,F).
632
639remove_search_path(Alias, Abs) :- ignore((clause(user:file_search_path(Alias, AbsW0),true,Ref),
640 absolute_file_name(AbsW0,AbsW),same_file(Abs,AbsW),erase(Ref),fail)).
641
648add_to_search_path_first(Alias, Abs) :- remove_search_path(Alias, Abs), asserta(user:file_search_path(Alias, Abs)).
649
656add_to_search_path_last(Alias, Abs) :- remove_search_path(Alias, Abs), assertz(user:file_search_path(Alias, Abs)).
657
664in_search_path(Alias, Abs) :- user:file_search_path(Alias,Was0),absolute_file_name(Was0,Was),same_file(Abs,Was).
665
666
667
674add_to_search_path(Alias, Abs):- add_to_search_path(add_to_search_path_last, Alias, Abs).
675:- meta_predicate add_to_search_path(2,?,?). 676
683add_to_search_path(How, Alias, AbsIn) :- strip_module(AbsIn,_,Abs),!,
684 ( (atom(Abs),is_absolute_file_name(Abs)) -> call(How,Alias,Abs)
685 ; (prolog_file_dir(Abs,ABSF),call(How,Alias,ABSF))).
686
687:- add_to_search_path(logicmoo, './../'). 688
689
691
698if_startup_script:- prolog_load_context(source, HereF),current_prolog_flag(associated_file,HereF),!.
699if_startup_script:- prolog_load_context(source, HereF),file_base_name(HereF,HereFB),
700 current_prolog_flag(os_argv,List),!,member(Arg,List),file_base_name(Arg,ArgFB),atom_concat(ArgFB,_,HereFB),!.
701
702:- meta_predicate(if_startup_script(0)). 703
710if_startup_script(Call):-if_startup_script->Call;dmsg(\+ if_startup_script(Call)).
711
712:- export(normalize_path/2). 713
720normalize_path(Where,WhereF3):-absolute_file_name(Where,WhereF),prolog_to_os_filename(WhereF,WhereF1),prolog_to_os_filename(WhereF2,WhereF1),!,clip_dir_sep(WhereF2,WhereF3).
721normalize_path(Where,WhereF2):-clip_dir_sep(Where,WhereF2).
722
723
730clip_dir_sep('/','/'):-!.
731clip_dir_sep(Where,WhereF2):-atom_concat(WhereF2,'/',Where),!.
732clip_dir_sep(Where,Where):-!.
733
734
735
742my_absolute_file_name(F,A):-notrace(catch(expand_file_name(F,[A]),_,fail)),F\=A,!.
743my_absolute_file_name(F,A):-notrace(catch(absolute_file_name(F,A,[access(read),file_errors(fail),file_type(directory)]),_,fail)),!.
744my_absolute_file_name(F,A):-notrace(catch(absolute_file_name(F,A,[access(read),file_errors(fail),file_ext('')]),_,fail)),!.
745my_absolute_file_name(F,A):-notrace(catch(absolute_file_name(F,A),_,fail)),!.
746
748
749
750
757join_path_if_needed(_,B,C):- atom(B), exists_directory(B)->B=C,!.
758join_path_if_needed(A,B,C):- compound(B),!, my_absolute_file_name(B,BB),atom(BB),!,join_path_if_needed(A,BB,C).
759join_path_if_needed(A,B,C):- compound(A),!, my_absolute_file_name(A,AA),atom(AA),!,join_path_if_needed(AA,B,C).
760join_path_if_needed(A,B,C):- compound(C),!, my_absolute_file_name(C,CC),atom(CC),!,join_path_if_needed(A,B,CC).
761join_path_if_needed(A,B,C):- directory_file_path(A,B,C).
762
763
770locally_to_dir(Locally,Dir):- clause(user:file_search_path(logicmoo,RunDir),true),
771 join_path_if_needed(RunDir,Locally,Directory),
772 my_absolute_file_name(Directory,Dir),exists_directory(Dir),!.
773locally_to_dir(Directory,Dir):- my_absolute_file_name(Directory,Dir),exists_directory(Dir),!.
774
775
776
777:- dynamic(local_directory_search/1). 778
779
780user:file_search_path(library,ATLIB):- getenv('PATH_INDIGOLOG',AT),atom_concat(AT,'/lib',ATLIB).
781user:file_search_path(indigolog,AT):- getenv('PATH_INDIGOLOG',AT).
782user:file_search_path(logicmoo,Dir):- local_directory_search(Locally), locally_to_dir(Locally,Dir).
783user:file_search_path(Atom,Dir):- atom(Atom),upcase_atom(Atom,ATOM),atom_concat('PATH_',ATOM,Var), getenv(Var,AT), atom_string(Dir,AT).
784
785
786
793local_directory_search_combined(X):-local_directory_search(X).
794local_directory_search_combined(X):-local_directory_search_combined2(X).
796local_directory_search_combined(PL):-local_directory_search_combined2(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
797
804local_directory_search_combined2(PL):-local_directory_search(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
805:- multifile(local_directory_search/1). 806:- dynamic(local_directory_search/1). 808local_directory_search('../..').
811local_directory_search('..').
817
824local_directory_search('../src'). 825local_directory_search('../src_lib').
826local_directory_search('../src_mud'). 828
829
830
831
832
839exists_dirf(X):-atomic(X),(exists_file_safe(X);exists_directory(X)).
840
842
843exists_file_safe(File):-
844 catch((((nonvar(File),(File=(_:F)->exists_file_safe(F);(atomic(File),exists_file(File)))))),_,fail).
845
846
860exists_directory_safe(File):- must(atomic(File)),exists_directory(File).
866
873upcase_atom_safe(A,B):-atom(A),upcase_atom(A,B),!.
874
881time_file_safe(_:F,INNER_XML):-atom(F),!,exists_file_safe(F),time_file(F,INNER_XML).
882time_file_safe(F,INNER_XML):-exists_file_safe(F),!,time_file(F,INNER_XML).
883
884
885
886
890
891
898global_pathname(B,A):- atom(B), absolute_file_name(B,A),!.
899global_pathname(B,A):-relative_pathname(B,A).
900
901
908relative_pathname(Path,Relative):-absolute_file_name(Path,[relative_to('./')],Absolute),member(Rel,['./','../','../../']),absolute_file_name(Rel,Clip),
909 canonical_pathname(Absolute,AbsoluteA),
910 canonical_pathname(Clip,ClipA),
911 atom_concat_safe0(ClipA,RelativeA,AbsoluteA),!,atom_concat_safe0(Rel,RelativeA,Relative),!.
912relative_pathname(Path,Relative):-canonical_pathname(Path,Relative),!.
913
914atom_concat_safe0(L,R,A):- ((atom(A),(atom(L);atom(R))) ; ((atom(L),atom(R)))), !, atom_concat(L,R,A),!.
915
916
923canonical_pathname(Absolute,AbsoluteB):-prolog_to_os_filename(AbsoluteA,Absolute),expand_file_name_safe(AbsoluteA,[AbsoluteB]),!.
924
925
926
930
931
932
933
940join_path(CurrentDir,Filename,Name):-
941 atom_ensure_endswtih(CurrentDir,'/',Out),atom_ensure_endswtih('./',Right,Filename),
942 atom_concat(Out,Right,Name),!.
943
944:- multifile current_directory_search/1. 945:- module_transparent current_directory_search/1. 946
947
954atom_ensure_endswtih(A,E,A):-atom(E),atom_concat(_Left,E,A),!.
955atom_ensure_endswtih(A,E,O):-atom(A),atom(E),atom_concat(A,E,O),!.
956atom_ensure_endswtih(A,E,O):-atom(A),atom(O),atom_concat(A,E,O),!.
957atom_ensure_endswtih(A,O,O):-atom(A),atom(O),!.
958
959
966os_to_prolog_filename(OS,_PL):-sanity(atom(OS)),fail.
967os_to_prolog_filename(_OS,PL):-sanity(var(PL)),fail.
968os_to_prolog_filename(OS,PL):-exists_file_safe(OS),!,PL=OS.
969os_to_prolog_filename(OS,PL):-exists_directory_safe(OS),!,PL=OS.
970os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_file_safe(PL),!.
971os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_directory_safe(PL),!.
972
973os_to_prolog_filename(OS,PL):-atom(OS),atomic_list_concat([X,Y|Z],'\\',OS),atomic_list_concat([X,Y|Z],'/',OPS),!,os_to_prolog_filename(OPS,PL).
974os_to_prolog_filename(OS,PL):-atom_concat_safe0(BeforeSlash,'/',OS),os_to_prolog_filename(BeforeSlash,PL).
975os_to_prolog_filename(OS,PL):-absolute_file_name(OS,OSP),OS \== OSP,!,os_to_prolog_filename(OSP,PL).
976
977
978dedupe_files(SL0,SL):- maplist(relative_file_name,SL0,SL1), list_to_set(SL1,SL2),maplist(absolute_file_name_or_dir,SL2,SLO),!,
979 list_to_set(SLO,SL),!.
980
981 relative_file_name(A,S):- prolog_canonical_source(A,L), file_name_on_path(L,S), atom(S), \+ name(S,[]), (exists_file_safe(S);exists_directory(S)),!.
982 relative_file_name(A,A).
983
984exists_all_filenames(S0, SL, Options):-
985 findall(N, (relative_from(D),
986 absolute_file_name_or_dir(S0, N,
987 [relative_to(D), file_errors(fail), access(read), solutions(all)|Options])), SL0),
988 dedupe_files(SL0,SL),!.
989
990
991absolute_file_name_or_dir(S0,N):-absolute_file_name_or_dir(S0,N,[file_errors(fail), access(read), solutions(all)]).
992absolute_file_name_or_dir(S0,N,Options):-
993 absolute_file_name(S0,N,Options)*-> true
994 ;(\+ member(file_ext(_),Options),
995 \+ member(file_type(_),Options),!,
996 (absolute_file_name(S0,N,[file_type(directory)|Options]) *-> true
997 ; absolute_file_name(S0,N,[file_type(txt)|Options]))).
998
999absolute_file_name_or_dir(S0,N,Options):- absolute_file_name(S0,N,Options).
1000
1001:- export(resolve_local_files/2). 1002resolve_local_files(S0,SL):- is_list(S0), !, maplist(resolve_local_files,S0,SS), append(SS,SF),dedupe_files(SF,SL).
1003resolve_local_files(S0,SL):- atom(S0), exists_file_safe(S0), !, SL = [S0].
1004resolve_local_files(S0,SS):- atom(S0),atom_concat(AA,'M.e',S0),atom_concat(AA,'.e',SL),resolve_local_files(SL,SS),!.
1005resolve_local_files(S0,SS):- atom(S0),atom_concat('answers/Mueller2004c/',AA,S0),atom_concat("ecnet/",AA,SL),resolve_local_files(SL,SS),!.
1007resolve_local_files(S0,SS):- findall(S1,resolve_local_files_1(S0,S1),SL),flatten(SL,SF),dedupe_files(SF,SS),SS\==[], !.
1010
1011resolve_local_files_1(S0,SL):- atom(S0), expand_file_name(S0,SL), SL = [E|_], exists_file_safe(E), !.
1012resolve_local_files_1(S0,SL):- exists_all_filenames(S0,SL, [expand(false)]), SL \= [].
1013resolve_local_files_1(S0,SL):- exists_all_filenames(S0,SL, [expand(true)]), SL \= [].
1014resolve_local_files_1(S0,SL):- expand_file_search_path(S0,S1),S0\==S1,resolve_local_files(S1,SL).
1015resolve_local_files_1(S0,SS):- atom(S0), file_base_name(S0,S1), S0\==S1, resolve_local_files(S1,SS).
1017
1018relative_from(D):- working_directory(D,D),exists_directory(D).
1019relative_from(F):- stream_property(_,file_name(F)),nonvar(F).
1020
1027
1028:- export(needs_resolve_local_files/2). 1029needs_resolve_local_files(F, L):- \+ is_stream(F), \+ is_filename(F),
1030 resolve_local_files(F, L), !, L \= [], L \= [F].
1031
1032:- export(is_filename/1). 1033is_filename(F):- atom(F), \+ is_stream(F),
1034 (exists_file_safe(F);is_absolute_file_name(F)).
1035
1038
1039
1040
1041contains_wildcard(Spec):- sformat(S,'~q',[Spec]),
1042 (sub_string(S, _, _, _, '*');sub_string(S, _, _, _, '?')),!.
1043
1044:- fixup_exports.