1/* Part of LogicMOO Base Logicmoo Path Setups
    2% ===================================================================
    3% File '$FILENAME.pl'
    4% Purpose: An Implementation in SWI-Prolog of certain debugging tools
    5% Maintainer: Douglas Miles
    6% Contact: $Author: dmiles $@users.sourceforge.net ;
    7% Version: '$FILENAME.pl' 1.0.0
    8% Revision: $Revision: 1.1 $
    9% Revised At:  $Date: 2002/07/11 21:57:28 $
   10% Licience: LGPL
   11% ===================================================================
   12*/
   13% File: /opt/PrologMUD/pack/logicmoo_base/prolog/logicmoo/util/logicmoo_util_filesystem.pl
   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            clip_dir_sep/2,
   26            concat_paths/2,
   27            concat_paths/3,
   28            current_dirs/1,
   29            current_dirs0/1,
   30            %maybe_add_import_module/3,
   31            current_filedir/1,
   32            current_filesource/1,
   33            enumerate_files/2,
   34            enumerate_files0/2,
   35            enumerate_files00/2,
   36            enumerate_files01/2,
   37            enumerate_files1/2,
   38            enumerate_files2/2,
   39            enumerate_m_files/3,
   40            exists_directory_safe/1,
   41            exists_dirf/1,
   42            exists_file_or_dir/1,
   43            exists_file_safe/1,
   44            expand_file_name_safe/2,
   45            expand_wfm/2,
   46            filematch/2,
   47            filematch3/3,
   48            filematch_ext/3,
   49            global_pathname/2,
   50            if_startup_script/0,
   51            in_include_file/0,
   52            if_startup_script/1,
   53            in_search_path/2,
   54            is_directory/1,
   55            join_path/3,
   56            join_path_if_needed/3,
   57            local_directory_search_combined/1,
   58            local_directory_search_combined2/1,
   59            locally_to_dir/2,
   60            my_absolute_file_name/2,
   61            %maybe_delete_import_module/2,
   62            normalize_path/2,
   63            os_to_prolog_filename/2,
   64            prolog_file_dir/1,
   65            prolog_file_dir/2,
   66            relative_pathname/2,
   67            remove_search_path/2,
   68            resolve_dir/2,
   69            time_file_safe/2,
   70            to_filename/2,
   71            upcase_atom_safe/2,
   72            with_filematch/1,
   73            with_filematches/1
   74
   75
   76            
   77          ]).   78
   79
   80:- multifile
   81        local_directory_search/1.   82:- meta_predicate
   83        add_to_search_path(2, ?, ?),
   84        enumerate_files(:, -),
   85        filematch(:, -),
   86        filematch_ext(+, :, -),
   87        if_startup_script(0),
   88        with_filematch(0).   89:- module_transparent
   90        add_library_search_path/2,
   91        add_file_search_path/2,
   92        add_to_search_path/2,
   93        add_to_search_path_first/2,
   94        add_to_search_path_last/2,
   95        atom_concat_safe0/3,
   96        atom_ensure_endswtih/3,
   97        canonical_pathname/2,
   98        clip_dir_sep/2,
   99        concat_paths/2,
  100        concat_paths/3,
  101        current_dirs/1,
  102        current_dirs0/1,
  103        current_filedir/1,
  104        current_filesource/1,
  105        enumerate_files0/2,
  106        enumerate_files00/2,
  107        enumerate_files01/2,
  108        enumerate_files1/2,
  109        enumerate_files2/2,
  110        enumerate_m_files/3,
  111        exists_directory_safe/1,
  112        exists_dirf/1,
  113        exists_file_or_dir/1,
  114        exists_file_safe/1,
  115        expand_file_name_safe/2,
  116        expand_wfm/2,
  117        filematch3/3,
  118        global_pathname/2,
  119        if_startup_script/0,
  120        in_search_path/2,
  121        is_directory/1,
  122        join_path/3,
  123        join_path_if_needed/3,
  124        local_directory_search/1,
  125        local_directory_search_combined/1,
  126        local_directory_search_combined2/1,
  127        locally_to_dir/2,
  128        my_absolute_file_name/2,
  129        normalize_path/2,
  130        os_to_prolog_filename/2,
  131        prolog_file_dir/1,
  132        prolog_file_dir/2,
  133        relative_pathname/2,
  134        remove_search_path/2,
  135        time_file_safe/2,
  136        to_filename/2,
  137        upcase_atom_safe/2,
  138        %maybe_add_import_module/3,
  139        with_filematches/1.  140:- dynamic
  141        local_directory_search/1.  142
  143:- set_module(class(library)).  144% % % OFF :- system:use_module(library(dialect)).
  145
  146
  147:- ensure_loaded(library(logicmoo/no_repeats)).  148
  149:- if(exists_source(library(filesex))).  150%:- set_prolog_flag(generate_debug_info, true).=
  151:- '@'( ensure_loaded(library(filesex)), 'user').  152
  153:-endif.  154
  155
  156assert_at_line_count(M,Pos,File,Cl):-
  157  stream_position_data(line_count,Pos,Line),
  158  '$compile_aux_clauses'([M:Cl], '$source_location'(File, Line)).
  159
  160assert_at_line_count_p1(Pred1,Cl,_Vs,_):- call(Pred1,Cl).
  161assert_at_line_count_p2(Pred2,Cl, Vs,_):- call(Pred2,Cl,Vs).
  162
  163load_with_asserter(File0,File,Asserter,Options):-    
  164   once(absolute_file_name(File0, File, [access(read)]);
  165        absolute_file_name(File0, File, [access(read),file_type(prolog)])),
  166   open(File, read, In),
  167   set_stream(In, encoding(iso_latin_1)),
  168   repeat,
  169   read_clause(In, Cl, Options),
  170   % DMiles: i am putting them in backwards (cuz, the hypens- confuse me if they pop out first in the debugger)
  171   call(Asserter,Cl),
  172   Cl==end_of_file, !,
  173   close(In).
  174   
  175
  176
  177% '/root/lib/swipl/pack/mpi'
  178% pack_property(Pack, directory(PackDir)),atom_concat(PackDir,'/*',writeln(WC),expand_file_name(WC,O),O\=[],length(O,L).
  179
  180% file_tree(Dir,Files):-
 resolve_dir(?Dir, ?Dir) is semidet
Resolve Dir.
  188resolve_dir(Dir,Dir):- is_absolute_file_name(Dir),!,exists_directory(Dir),!.
  189resolve_dir(Path,Dir):- 
  190  (prolog_load_context(directory,SDir);
  191   (prolog_load_context(file,File),file_directory_name(File,SDir));
  192   (prolog_load_context(source,File),file_directory_name(File,SDir));
  193   (catch((current_source_file(F),to_filename(F,File),atom(File)),_,fail),file_directory_name(File,SDir));
  194    working_directory(SDir,SDir)),exists_directory(SDir),
  195    catch(absolute_file_name(Path,Dir,[relative_to(SDir),access(read),file_errors(fail),file_type(directory)]),_,fail),
  196    exists_directory(Dir).
 add_file_search_path(+Alias, +WildCard) is det
Create an alias when it is missing
:- add_file_search_path(all_utils, '../*/util/').
  207add_file_search_path(Name,Path):-  must(resolve_dir(Path,Dir)),
  208   is_absolute_file_name(Dir), (( \+ user:file_search_path(Name,Dir)) ->asserta(user:file_search_path(Name,Dir));true).
 add_library_search_path(+Dir, +Patterns:list(atom)) is det
Create an autoload index INDEX.pl for Dir by scanning all files that match any of the file-patterns in Patterns. Typically, this appears as a directive in MKINDEX.pl. For example:
:- add_library_search_path('../*/util/',[ 'logicmoo_util_*.pl']).
  221add_library_search_path(Path,Masks):- 
  222   forall(resolve_dir(Path,Dir), 
  223      (make_library_index(Dir, Masks), 
  224        (user:library_directory(Dir) -> true ; (asserta(user:library_directory(Dir)), 
  225          (access_file(Dir,write)->reload_library_index;true))))).
  226
  227
  228:- meta_predicate(with_filematch(0)).  229
  230%= 	 	 
 with_filematch(:GoalG) is semidet
Using Filematch.
  236with_filematch(G):- expand_wfm(G,GG),!,GG.
  237
  238%= 	 	 
 with_filematches(?G) is semidet
Using Filematches.
  244with_filematches(G):- forall(expand_wfm(G,GG),GG).
  245
  246
  247%= 	 	 
 expand_wfm(?G, ?GG) is semidet
Expand Wfm.
  253expand_wfm(G,GG):- once((sub_term(Sub, G),compound(Sub),Sub=wfm(F))),
  254   (filematch(F,M),subst(G,wfm(F),M,GG),y_must(with_filematch(G), (G\=@=GG))).
  255
  256
  257:- export(current_filesource/1).  258:- export(current_filedir/1).  259
  260%= 	 	 
 current_filedir(?D) is semidet
Current Filedir.
  266current_filedir(D):- no_repeats(D,(current_filesource(F),file_directory_name(F,D))).
  267
  268%= 	 	 
 current_filesource(?F) is semidet
Current Filesource.
  274current_filesource(F):-source_location(F,_).
  275current_filesource(F):-seeing(X),is_stream(X),stream_property(X,file_name(F)).
  276current_filesource(F):-stream_property(_,file_name(F)).
  277
  278:- export(filematch/2).  279:- meta_predicate(filematch(:,-)).  280
  281%= 	 	 
 filematch(?Spec, -Result) is semidet
Filematch.
  287filematch(Spec,Result):-  enumerate_files(Spec,Result).
  288
  289
  290:- thread_local(t_l:file_ext/1).  291:- meta_predicate(filematch_ext(+,:,-)).  292:- export(filematch_ext/3).  293
  294%= 	 	 
 filematch_ext(+Ext, ?FileIn, -File) is semidet
Filematch Ext.
  300filematch_ext(Ext,FileIn,File):-
  301  locally_tl(file_ext(Ext),findall(File,filematch(FileIn,File),List)),
  302   when_ends_with(Ext,List,File).
  303
  304when_ends_with(_Ext,[],_File):- !,fail.
  305when_ends_with(Ext,List,File):- ((member(File,List),only_if_ends_with(Ext,File)))*->true;member(File,List).
  306
  307only_if_ends_with(Ext,File):- atom(Ext),!,Ext\==[],atom_concat(_,Ext,File).
  308only_if_ends_with([Ext|L],File):- only_if_ends_with(Ext,File)->true;only_if_ends_with(L,File).
  309
  310%= 	 	 
  311:- meta_predicate(enumerate_files(:,-)).  312:- export(enumerate_files/2).
 enumerate_files(?CALL1, -Result) is semidet
Enumerate Files.
  318enumerate_files(Spec0,Result):- strip_module(Spec0,_,Spec),
  319   call((atom(Spec),(exists_file(Spec);exists_directory(Spec)),prolog_to_os_filename(Result,Spec))),!,
  320   absolute_file_name(Spec,Result).
  321enumerate_files(M:Spec,Result):-
  322   call((no_repeats_old([Result],((enumerate_m_files(M,Spec,NResult),once((normalize_path(NResult,Result)->exists_file_or_dir(Result)))))))).
  323
  324
  325%= 	 	 
 enumerate_m_files(?M, ?Mask, ?File1) is semidet
Enumerate Module Files.
  331:- export(enumerate_m_files/3).  332enumerate_m_files(user, Mask,File1):-!,enumerate_files0(Mask,File1).
  333enumerate_m_files(M, Mask,File1):- enumerate_files0(Mask,File1)*->true;enumerate_m_files_mscoped(M, Mask,File1).
  334
  335
  336%= 	 	 
 enumerate_m_files_mscoped(?M, ?Mask, ?File1) is semidet
Enumerate Module Files Mscoped.
  342enumerate_m_files_mscoped(M, Mask,File1):- 
  343  findall(t_l:search_first_dir(Dir),
  344   (((M\=user,user:file_search_path(M,SP),expand_file_search_path(SP,Dir));((module_property(M, file(File)),directory_file_path(Dir,_,File)))),
  345   exists_directory(Dir)),List),
  346  list_to_set(List,Set),
  347  locally(Set,enumerate_files0(Mask,File1)).
  348
  349:- export(enumerate_files0/2).  350
  351%= 	 	 
 enumerate_files0(?Mask, ?File1) is semidet
Enumerate Files Primary Helper.
  357enumerate_files0(Mask,File1):- absolute_file_name(Mask,X,[expand(true),file_errors(fail),solutions(all)]),expand_file_name(X,Y),Y\==[],member(File1,Y).
  358enumerate_files0(Mask,File1):- one_must(filematch3('./',Mask,File1),(current_filedir(D),filematch3(D,Mask,File1))).
  359enumerate_files0(Spec,Result):- enumerate_files00(Spec,Result).
  360enumerate_files0(Spec,Result):- to_filename(Spec,Result).
  361enumerate_files0(Mask,File1):-  (current_dirs(D),filematch3(D,Mask,File1)).
  362
  363enumerate_files01(_Mask,_File1):-fail.
  364
  365
  366%= 	 	 
 enumerate_files00(?Spec, ?Result) is semidet
Enumerate Files Primary Helper Primary Helper.
  372enumerate_files00(Spec,Result):- expand_file_name_safe(Spec,ResultList),ResultList\=[],!,member(NResult,ResultList),enumerate_files2(NResult,Result).
  373enumerate_files00(Spec,Result):- enumerate_files1(Spec,M),enumerate_files2(M,Result).
  374
  375
  376:- export(filematch3/3).  377
  378%= 	 	 
 filematch3(?RelativeTo, ?Mask, ?File1) is semidet
Filematch3.
  384filematch3(RelativeTo,Mask,File1):-
  385   findall(Ext,t_l:file_ext(Ext),EXTs),flatten([EXTs,'','pl.in'],Flat),
  386   absolute_file_name(Mask,File1Matched,[extensions(Flat),
  387   expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name(File1Matched,File1S),member(File1,File1S).
  388filematch3(RelativeTo,Mask,File1):-absolute_file_name(Mask,File1Matched,[file_type(directory),
  389   expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name(File1Matched,File1S),member(File1,File1S).
  390
  391:- export(enumerate_files2/2).  392
  393%= 	 	 
 enumerate_files2(?Spec, ?Result) is semidet
Enumerate Files Extended Helper.
  399enumerate_files2(Spec,Result):-sub_atom(Spec,_,1,_,'*') -> enumerate_files1(Spec,Result);Spec=Result.
  400
  401:- export(enumerate_files1/2).  402
  403%= 	 	 
 enumerate_files1(:TermAtom, ?Result) is semidet
Enumerate Files Secondary Helper.
  409enumerate_files1(Atom,Result):- atomic(Atom),\+(is_absolute_file_name(Atom)),atomic_list_concat(List,'/',Atom),!,concat_paths(List,Result).
  410enumerate_files1(Spec,Result):- exists_file_or_dir(Spec),!,Result=Spec.
  411enumerate_files1(P/C,Result):- !,concat_paths(P,C,Result).
  412enumerate_files1(Spec,Result):- expand_file_name_safe(Spec,ResultList),member(Result,ResultList).
  413enumerate_files1(Spec,Result):- user:file_search_path(Spec,Result).
  414enumerate_files1(Spec,Result):- expand_file_search_path(Spec,Result).
  415enumerate_files1(Spec,Result):- absolute_file_name(Spec,Result).
  416enumerate_files1(Atom,Result):- atomic(Atom),once((member(Sep,['/**/','/**','**']),atomic_list_concat([B,A|R],Sep,Atom))),concat_paths([B,'**',A|R],Result).
  417
  418:- export(expand_file_name_safe/2).  419
  420%= 	 	 
 expand_file_name_safe(?I, ?O) is semidet
Expand File Name Safely Paying Attention To Corner Cases.
  426expand_file_name_safe(I,O):-var(I),trace_or_throw(expand_file_name_safe(I,O)),!.
  427expand_file_name_safe(I,O):- \+ compound(I), catch(expand_file_name(I,O),_,fail),O\=[],!.
  428expand_file_name_safe(I,[O]):- catch(expand_file_search_path(I,O),_,fail),!.
  429expand_file_name_safe(I,L):- 
  430  findall(O,
  431    (absolute_file_name(I,O,[expand(true),solutions(all)]);absolute_file_name(I,O,[expand(true),solutions(all),file_type(directory)])),
  432    L),!.
  433
  434:- export(exists_file_or_dir/1).  435
  436%= 	 	 
 exists_file_or_dir(?X) is semidet
Exists File Or Dir.
  442exists_file_or_dir(X):- nonvar(X),( X=(_:F)->exists_file_or_dir(F); (atomic(X),once((catch(exists_file(X),E,(fmt(E:X),fail));is_directory(X))))).
  443:- export(is_directory/1).  444
  445%= 	 	 
 is_directory(?X) is semidet
If Is A Directory.
  451is_directory(X):-exists_directory(X).
  452
  453:- export(concat_paths/3).  454
  455%= 	 	 
 concat_paths(?ParentIn, ?Child, ?Result) is semidet
Concat Paths.
  461concat_paths(A,'',A).
  462concat_paths(A,'/',A).
  463concat_paths(ParentIn,'**',Result):-!, member(Child,['./','./*/','./*/*/','./*/*/*/','./*/*/*/*/','./*/*/*/*/*/']),concat_paths(ParentIn,Child,Result).
  464concat_paths(ParentIn,Child,Result):- filematch(ParentIn,Parent),
  465   once((is_directory(Parent) -> directory_file_path(Parent,Child,Joined) ; atom_concat(Parent,Child,Joined))),!,
  466   filematch(Joined,Result).
  467
  468:- export(concat_paths/2).  469
  470%= 	 	 
 concat_paths(:TermJoined, ?Result) is semidet
Concat Paths.
  476concat_paths([Joined],Result):- !,filematch(Joined,Result).
  477concat_paths([ParentIn,Child|MORE],Result):- concat_paths(ParentIn,Child,ResultM),concat_paths([ResultM|MORE],Result).
  478
  479
  480:- thread_local(t_l:search_first_dir/1).  481
  482
  483%= 	 	 
 current_dirs(?DO) is semidet
Current Dirs.
  489current_dirs(DO):- no_repeats(DO,(current_dirs0(D),(atom_concat(DO,'/',D)->true;DO=D))).
  490
  491%= 	 	 
 current_dirs0(?D) is semidet
Current Dirs Primary Helper.
  497current_dirs0(D):- t_l:search_first_dir(D).
  498current_dirs0(D):- prolog_load_context(directory,D).
  499current_dirs0(D):- working_directory(D,D).
  500current_dirs0(D):- current_stream(_,read,Y), stream_property(Y,file_name(FN)), file_directory_name(FN,D).
  501current_dirs0(D):- stream_property(_,file_name(FN)), file_directory_name(FN,D).
  502
  503%current_dirs0(D):- expand_file_name('*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  504%current_dirs0(D):- expand_file_name('*/*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  505%current_dirs0(D):- expand_file_name('*/*/*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  506current_dirs0(D):- source_file_property(FN, modified(_)), file_directory_name(FN,D).
  507current_dirs0('.').
  508
  509:- export(to_filename/2).  510:- thread_local(t_l:default_extension/1).  511
  512%= 	 	 
 to_filename(?FileName, ?AFN) is semidet
Converted To Filename.
  518to_filename( FileName, AFN ) :- atomic(FileName),exists_file(FileName),!,AFN=FileName.
  519to_filename( FileName, AFN ) :-
  520 ((((t_l:default_extension( Ext ));Ext='.tlp';Ext='';Ext='.pl'), 
  521     current_dirs(D),
  522     member(TF,[false,true]),
  523        absolute_file_name(FileName,AFN,[solutions(all),expand(TF),access(read),relative_to(D),file_errors(fail),extensions(['',Ext,'.pl','.tlp','.clp','.P'])]),
  524        exists_file(AFN))),!.
  525
  526
  527:- export((add_to_search_path/2,add_to_search_path_first/2,prolog_file_dir/2,if_startup_script/1,if_startup_script/0)).  528
  529:- export(prolog_file_dir/1).  530
  531%= 	 	 
 prolog_file_dir(?Here) is semidet
Prolog File Dir.
  537prolog_file_dir(Here):- prolog_load_context(file, HereF),file_directory_name(HereF,Here).
  538prolog_file_dir(Here):- working_directory(Here,Here).
  539:- export(prolog_file_dir/2).  540
  541%= 	 	 
 prolog_file_dir(?Rel, ?ABSF) is semidet
Prolog File Dir.
  547prolog_file_dir(Rel,ABSF):-prolog_file_dir(Here),absolute_file_name(Rel,ABSF,[relative_to(Here),file_type(directory),expand(true)]),!.
  548prolog_file_dir(Rel,ABSF):-prolog_file_dir(Here),absolute_file_name(Rel,ABSF,[relative_to(Here),expand(true)]),!.
 in_include_file is semidet
In Include File.
  555in_include_file:- prolog_load_context(file,F),!, \+ prolog_load_context(source,F).
  556
  557%= 	 	 
 remove_search_path(?Alias, ?Abs) is semidet
Remove Search Path.
  563remove_search_path(Alias, Abs) :- ignore((clause(user:file_search_path(Alias, AbsW0),true,Ref),
  564                                          absolute_file_name(AbsW0,AbsW),same_file(Abs,AbsW),erase(Ref),fail)).
  565
  566%= 	 	 
 add_to_search_path_first(?Alias, ?Abs) is semidet
Add Converted To Search Path First.
  572add_to_search_path_first(Alias, Abs) :- remove_search_path(Alias, Abs), asserta(user:file_search_path(Alias, Abs)).
  573
  574%= 	 	 
 add_to_search_path_last(?Alias, ?Abs) is semidet
Add Converted To Search Path Last.
  580add_to_search_path_last(Alias, Abs) :- remove_search_path(Alias, Abs), assertz(user:file_search_path(Alias, Abs)).
  581
  582%= 	 	 
 in_search_path(?Alias, ?Abs) is semidet
In Search Path.
  588in_search_path(Alias, Abs) :- user:file_search_path(Alias,Was0),absolute_file_name(Was0,Was),same_file(Abs,Was).
  589
  590
  591
  592%= 	 	 
 add_to_search_path(?Alias, ?Abs) is semidet
Add Converted To Search Path.
  598add_to_search_path(Alias, Abs):- add_to_search_path(add_to_search_path_last, Alias, Abs).
  599:- meta_predicate add_to_search_path(2,?,?).  600
  601%= 	 	 
 add_to_search_path(:PRED2How, ?Alias, ?Abs) is semidet
Add Converted To Search Path.
  607add_to_search_path(How, Alias, AbsIn) :- strip_module(AbsIn,_,Abs),!,
  608  ( (atom(Abs),is_absolute_file_name(Abs)) -> call(How,Alias,Abs)     
  609   ; (prolog_file_dir(Abs,ABSF),call(How,Alias,ABSF))).
  610
  611:- add_to_search_path(logicmoo, './../').  612
  613
  614% Was this our startup file?
  615
  616%= 	 	 
 if_startup_script is semidet
If Startup Script.
  622if_startup_script:- prolog_load_context(source, HereF),current_prolog_flag(associated_file,HereF),!.
  623if_startup_script:- prolog_load_context(source, HereF),file_base_name(HereF,HereFB),
  624   current_prolog_flag(os_argv,List),!,member(Arg,List),file_base_name(Arg,ArgFB),atom_concat(ArgFB,_,HereFB),!.
  625
  626:- meta_predicate(if_startup_script(0)).  627
  628%= 	 	 
 if_startup_script(:Goal) is semidet
If Startup Script.
  634if_startup_script(Call):-if_startup_script->Call;dmsg(\+ if_startup_script(Call)).
  635
  636:- export(normalize_path/2).  637
  638%= 	 	 
 normalize_path(?Where, ?WhereF3) is semidet
Normalize Path.
  644normalize_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).
  645normalize_path(Where,WhereF2):-clip_dir_sep(Where,WhereF2).
  646
  647
  648%= 	 	 
 clip_dir_sep(?Where, ?WhereF2) is semidet
Clip Dir Sep.
  654clip_dir_sep('/','/'):-!.
  655clip_dir_sep(Where,WhereF2):-atom_concat(WhereF2,'/',Where),!.
  656clip_dir_sep(Where,Where):-!.
  657
  658
  659
  660%= 	 	 
 my_absolute_file_name(?F, ?A) is semidet
My Absolute File Name.
  666my_absolute_file_name(F,A):-catch(expand_file_name(F,[A]),_,fail),F\=A,!.
  667my_absolute_file_name(F,A):-catch(absolute_file_name(F,A),_,fail),!.
  668
  669% register search path hook
  670
  671
  672
  673%= 	 	 
 join_path_if_needed(?A, ?B, ?C) is semidet
Join Path If Needed.
  679join_path_if_needed(A,B,C):-exists_directory(B)->B=C;directory_file_path(A,B,C).
  680
  681
  682%= 	 	 
 locally_to_dir(?Locally, ?Dir) is semidet
Locally Converted To Dir.
  688locally_to_dir(Locally,Dir):- clause(user:file_search_path(logicmoo,RunDir),true),join_path_if_needed(RunDir,Locally,Directory),my_absolute_file_name(Directory,Dir),exists_directory(Dir),!.
  689locally_to_dir(Directory,Dir):-my_absolute_file_name(Directory,Dir),exists_directory(Dir),!.
  690
  691
  692
  693:- dynamic(local_directory_search/1).  694
  695
  696% user:file_search_path(library,ATLIB):-getenv('PATH_INDIGOLOG',AT),atom_concat(AT,'/lib',ATLIB).
  697% user:file_search_path(indigolog,AT):-getenv('PATH_INDIGOLOG',AT).
  698% user:file_search_path(logicmoo,Dir):-  local_directory_search(Locally), locally_to_dir(Locally,Dir).
  699
  700
  701
  702%= 	 	 
 local_directory_search_combined(?X) is semidet
Local Directory Search Combined.
  708local_directory_search_combined(X):-local_directory_search(X).
  709local_directory_search_combined(X):-local_directory_search_combined2(X).
  710% for now dont do the concat 3 version
  711local_directory_search_combined(PL):-local_directory_search_combined2(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
  712
  713%= 	 	 
 local_directory_search_combined2(?PL) is semidet
Local Directory Search Combined Extended Helper.
  719local_directory_search_combined2(PL):-local_directory_search(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
  720:- multifile(local_directory_search/1).  721:- dynamic(local_directory_search/1).  722% Add the locations that the MUD source files will be picked up by the system
  723%local_directory_search('../..').
  724%local_directory_search('~logicmoo-mud/cynd/startrek'). % home vtDirection CynD world
  725% local_directory_search('.').
  726% local_directory_search('..'). 
  727%local_directory_search('../runtime'). 
  728%local_directory_search('../src_game'). % for user overrides and uploads
  729%local_directory_search('../src_assets').  % for non uploadables (downloadables)
  730%local_directory_search('../src_modules'). % for big modules
  731%local_directory_search('../src_webui').  % for web UI modules
  732
  733%= 	 	 
 local_directory_search(?VALUE1) is semidet
Local Directory Search.
  739local_directory_search('../src'). % shared_library preds
  740local_directory_search('../src_lib').
  741local_directory_search('../src_mud').  % for vetted src of the MUD
  742%local_directory_search('../externals/XperiMental/src_incoming').  % areeba underlay
  743
  744
  745
  746
  747
  748%= 	 	 
 exists_dirf(?X) is semidet
Exists Dirf.
  754exists_dirf(X):-atomic(X),(exists_file(X);exists_directory(X)).
  755
  756%= 	 	 
  757
  758
  759%= 	 	 
 exists_file_safe(?File) is semidet
Exists File Safely Paying Attention To Corner Cases.
  765exists_file_safe(File):- ((nonvar(File),(File=(_:F)->exists_file_safe(F);(atomic(File),exists_file(File))))).
  766
  767%= 	 	 
 exists_directory_safe(?File) is semidet
Exists Directory Safely Paying Attention To Corner Cases.
  773exists_directory_safe(File):- must(atomic(File)),exists_directory(File).
  774/*
  775concat_atom_safe(List,Sep,[Atom]):-atom(Atom),!,concat_atom(List,Sep,Atom),!.
  776concat_atom_safe(List,Sep,Atom):-atom(Atom),!,concat_atom(ListM,Sep,Atom),!,List = ListM.
  777concat_atom_safe(List,Sep,Atom):- concat_atom(List,Sep,Atom),!.
  778*/
  779
  780%= 	 	 
 upcase_atom_safe(?A, ?B) is semidet
Upcase Atom Safely Paying Attention To Corner Cases.
  786upcase_atom_safe(A,B):-atom(A),upcase_atom(A,B),!.
  787
  788%= 	 	 
 time_file_safe(?F, ?INNER_XML) is semidet
Time File Safely Paying Attention To Corner Cases.
  794time_file_safe(_:F,INNER_XML):-atom(F),!,exists_file_safe(F),time_file(F,INNER_XML).
  795time_file_safe(F,INNER_XML):-exists_file_safe(F),!,time_file(F,INNER_XML).
  796
  797
  798
  799
  800% =================================================================================
  801% Utils
  802% =================================================================================
  803
  804
  805%= 	 	 
 global_pathname(?B, ?A) is semidet
Global Pathname.
  811global_pathname(B,A):-absolute_file_name(B,A),!.
  812global_pathname(B,A):-relative_pathname(B,A).
  813
  814
  815%= 	 	 
 relative_pathname(?Path, ?Relative) is semidet
Relative Pathname.
  821relative_pathname(Path,Relative):-absolute_file_name(Path,[relative_to('./')],Absolute),member(Rel,['./','../','../../']),absolute_file_name(Rel,Clip),
  822  canonical_pathname(Absolute,AbsoluteA),
  823  canonical_pathname(Clip,ClipA),
  824  atom_concat_safe0(ClipA,RelativeA,AbsoluteA),!,atom_concat_safe0(Rel,RelativeA,Relative),!.
  825relative_pathname(Path,Relative):-canonical_pathname(Path,Relative),!.
  826
  827atom_concat_safe0(L,R,A):- ((atom(A),(atom(L);atom(R))) ; ((atom(L),atom(R)))), !, atom_concat(L,R,A),!.
  828
  829
  830%= 	 	 
 canonical_pathname(?Absolute, ?AbsoluteB) is semidet
Canonical Pathname.
  836canonical_pathname(Absolute,AbsoluteB):-prolog_to_os_filename(AbsoluteA,Absolute),expand_file_name(AbsoluteA,[AbsoluteB]),!.
  837
  838
  839
  840% ===============================================================================================
  841% join_path(CurrentDir,Filename,Name)
  842% ===============================================================================================
  843
  844
  845
  846
  847%= 	 	 
 join_path(?CurrentDir, ?Filename, ?Name) is semidet
Join Path.
  853join_path(CurrentDir,Filename,Name):-
  854     atom_ensure_endswtih(CurrentDir,'/',Out),atom_ensure_endswtih('./',Right,Filename),
  855     atom_concat(Out,Right,Name),!.
  856
  857:- multifile current_directory_search/1.  858:- module_transparent current_directory_search/1.  859
  860
  861%= 	 	 
 atom_ensure_endswtih(?A, ?E, ?A) is semidet
Atom Ensure Endswtih.
  867atom_ensure_endswtih(A,E,A):-atom(E),atom_concat(_Left,E,A),!.
  868atom_ensure_endswtih(A,E,O):-atom(A),atom(E),atom_concat(A,E,O),!.
  869atom_ensure_endswtih(A,E,O):-atom(A),atom(O),atom_concat(A,E,O),!.
  870atom_ensure_endswtih(A,O,O):-atom(A),atom(O),!.
  871
  872
  873%= 	 	 
 os_to_prolog_filename(?OS, ?PL) is semidet
Outputs Converted To Prolog Filename.
  879os_to_prolog_filename(OS,_PL):-sanity(atom(OS)),fail.
  880os_to_prolog_filename(_OS,PL):-sanity(var(PL)),fail.
  881os_to_prolog_filename(OS,PL):-exists_file_safe(OS),!,PL=OS.
  882os_to_prolog_filename(OS,PL):-exists_directory_safe(OS),!,PL=OS.
  883os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_file_safe(PL),!.
  884os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_directory_safe(PL),!.
  885
  886os_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).
  887os_to_prolog_filename(OS,PL):-atom_concat_safe0(BeforeSlash,'/',OS),os_to_prolog_filename(BeforeSlash,PL).
  888os_to_prolog_filename(OS,PL):-absolute_file_name(OS,OSP),OS \== OSP,!,os_to_prolog_filename(OSP,PL).
  889
  890:- fixup_exports.