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:- 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
  156
  157% '/root/lib/swipl/pack/mpi'
  158% pack_property(Pack, directory(PackDir)),atom_concat(PackDir,'/*',writeln(WC),expand_file_name(WC,O),O\=[],length(O,L).
  159
  160% file_tree(Dir,Files):-
 resolve_dir(?Dir, ?Dir) is semidet
Resolve Dir.
  168resolve_dir(Dir,Dir):- is_absolute_file_name(Dir),!,exists_directory(Dir),!.
  169resolve_dir(Path,Dir):- 
  170  (prolog_load_context(directory,SDir);
  171   (prolog_load_context(file,File),file_directory_name(File,SDir));
  172   (prolog_load_context(source,File),file_directory_name(File,SDir));
  173   (catch((current_source_file(F),to_filename(F,File),atom(File)),_,fail),file_directory_name(File,SDir));
  174    working_directory(SDir,SDir)),exists_directory(SDir),
  175    catch(absolute_file_name(Path,Dir,[relative_to(SDir),access(read),file_errors(fail),file_type(directory)]),_,fail),
  176    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/').
  187add_file_search_path(Name,Path):-  must(resolve_dir(Path,Dir)),
  188   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']).
  201add_library_search_path(Path,Masks):- 
  202   forall(resolve_dir(Path,Dir), 
  203      (make_library_index(Dir, Masks), 
  204        (user:library_directory(Dir) -> true ; (asserta(user:library_directory(Dir)), 
  205          (access_file(Dir,write)->reload_library_index;true))))).
  206
  207
  208:- meta_predicate(with_filematch(0)).  209
  210%= 	 	 
 with_filematch(:GoalG) is semidet
Using Filematch.
  216with_filematch(G):- expand_wfm(G,GG),!,GG.
  217
  218%= 	 	 
 with_filematches(?G) is semidet
Using Filematches.
  224with_filematches(G):- forall(expand_wfm(G,GG),GG).
  225
  226
  227%= 	 	 
 expand_wfm(?G, ?GG) is semidet
Expand Wfm.
  233expand_wfm(G,GG):- once((sub_term(Sub, G),compound(Sub),Sub=wfm(F))),
  234   (filematch(F,M),subst(G,wfm(F),M,GG),y_must(with_filematch(G), (G\=@=GG))).
  235
  236
  237:- export(current_filesource/1).  238:- export(current_filedir/1).  239
  240%= 	 	 
 current_filedir(?D) is semidet
Current Filedir.
  246current_filedir(D):- no_repeats(D,(current_filesource(F),file_directory_name(F,D))).
  247
  248%= 	 	 
 current_filesource(?F) is semidet
Current Filesource.
  254current_filesource(F):-source_location(F,_).
  255current_filesource(F):-seeing(X),is_stream(X),stream_property(X,file_name(F)).
  256current_filesource(F):-stream_property(_,file_name(F)).
  257
  258:- export(filematch/2).  259:- meta_predicate(filematch(:,-)).  260
  261%= 	 	 
 filematch(?Spec, -Result) is semidet
Filematch.
  267filematch(Spec,Result):-  enumerate_files(Spec,Result).
  268
  269
  270:- thread_local(t_l:file_ext/1).  271:- meta_predicate(filematch_ext(+,:,-)).  272:- export(filematch_ext/3).  273
  274%= 	 	 
 filematch_ext(+Ext, ?FileIn, -File) is semidet
Filematch Ext.
  280filematch_ext(Ext,FileIn,File):-
  281  locally_tl(file_ext(Ext),findall(File,filematch(FileIn,File),List)),
  282   when_ends_with(Ext,List,File).
  283
  284when_ends_with(_Ext,[],_File):- !,fail.
  285when_ends_with(Ext,List,File):- ((member(File,List),only_if_ends_with(Ext,File)))*->true;member(File,List).
  286
  287only_if_ends_with(Ext,File):- atom(Ext),!,Ext\==[],atom_concat(_,Ext,File).
  288only_if_ends_with([Ext|L],File):- only_if_ends_with(Ext,File)->true;only_if_ends_with(L,File).
  289
  290%= 	 	 
  291:- meta_predicate(enumerate_files(:,-)).  292:- export(enumerate_files/2).
 enumerate_files(?CALL1, -Result) is semidet
Enumerate Files.
  298enumerate_files(Spec0,Result):- strip_module(Spec0,_,Spec),
  299   call((atom(Spec),(exists_file(Spec);exists_directory(Spec)),prolog_to_os_filename(Result,Spec))),!,
  300   absolute_file_name(Spec,Result).
  301enumerate_files(M:Spec,Result):-
  302   call((no_repeats_old([Result],((enumerate_m_files(M,Spec,NResult),once((normalize_path(NResult,Result)->exists_file_or_dir(Result)))))))).
  303
  304
  305%= 	 	 
 enumerate_m_files(?M, ?Mask, ?File1) is semidet
Enumerate Module Files.
  311:- export(enumerate_m_files/3).  312enumerate_m_files(user, Mask,File1):-!,enumerate_files0(Mask,File1).
  313enumerate_m_files(M, Mask,File1):- enumerate_files0(Mask,File1)*->true;enumerate_m_files_mscoped(M, Mask,File1).
  314
  315
  316%= 	 	 
 enumerate_m_files_mscoped(?M, ?Mask, ?File1) is semidet
Enumerate Module Files Mscoped.
  322enumerate_m_files_mscoped(M, Mask,File1):- 
  323  findall(t_l:search_first_dir(Dir),
  324   (((M\=user,user:file_search_path(M,SP),expand_file_search_path(SP,Dir));((module_property(M, file(File)),directory_file_path(Dir,_,File)))),
  325   exists_directory(Dir)),List),
  326  list_to_set(List,Set),
  327  locally(Set,enumerate_files0(Mask,File1)).
  328
  329:- export(enumerate_files0/2).  330
  331%= 	 	 
 enumerate_files0(?Mask, ?File1) is semidet
Enumerate Files Primary Helper.
  337enumerate_files0(Mask,File1):- absolute_file_name(Mask,X,[expand(true),file_errors(fail),solutions(all)]),expand_file_name(X,Y),Y\==[],member(File1,Y).
  338enumerate_files0(Mask,File1):- one_must(filematch3('./',Mask,File1),(current_filedir(D),filematch3(D,Mask,File1))).
  339enumerate_files0(Spec,Result):- enumerate_files00(Spec,Result).
  340enumerate_files0(Spec,Result):- to_filename(Spec,Result).
  341enumerate_files0(Mask,File1):-  (current_dirs(D),filematch3(D,Mask,File1)).
  342
  343enumerate_files01(_Mask,_File1):-fail.
  344
  345
  346%= 	 	 
 enumerate_files00(?Spec, ?Result) is semidet
Enumerate Files Primary Helper Primary Helper.
  352enumerate_files00(Spec,Result):- expand_file_name_safe(Spec,ResultList),ResultList\=[],!,member(NResult,ResultList),enumerate_files2(NResult,Result).
  353enumerate_files00(Spec,Result):- enumerate_files1(Spec,M),enumerate_files2(M,Result).
  354
  355
  356:- export(filematch3/3).  357
  358%= 	 	 
 filematch3(?RelativeTo, ?Mask, ?File1) is semidet
Filematch3.
  364filematch3(RelativeTo,Mask,File1):-
  365   findall(Ext,t_l:file_ext(Ext),EXTs),flatten([EXTs,'','pl.in'],Flat),
  366   absolute_file_name(Mask,File1Matched,[extensions(Flat),
  367   expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name(File1Matched,File1S),member(File1,File1S).
  368filematch3(RelativeTo,Mask,File1):-absolute_file_name(Mask,File1Matched,[file_type(directory),
  369   expand(true),file_errors(fail),solutions(all),relative_to(RelativeTo),access(read)]),expand_file_name(File1Matched,File1S),member(File1,File1S).
  370
  371:- export(enumerate_files2/2).  372
  373%= 	 	 
 enumerate_files2(?Spec, ?Result) is semidet
Enumerate Files Extended Helper.
  379enumerate_files2(Spec,Result):-sub_atom(Spec,_,1,_,'*') -> enumerate_files1(Spec,Result);Spec=Result.
  380
  381:- export(enumerate_files1/2).  382
  383%= 	 	 
 enumerate_files1(:TermAtom, ?Result) is semidet
Enumerate Files Secondary Helper.
  389enumerate_files1(Atom,Result):- atomic(Atom),\+(is_absolute_file_name(Atom)),atomic_list_concat(List,'/',Atom),!,concat_paths(List,Result).
  390enumerate_files1(Spec,Result):- exists_file_or_dir(Spec),!,Result=Spec.
  391enumerate_files1(P/C,Result):- !,concat_paths(P,C,Result).
  392enumerate_files1(Spec,Result):- expand_file_name_safe(Spec,ResultList),member(Result,ResultList).
  393enumerate_files1(Spec,Result):- user:file_search_path(Spec,Result).
  394enumerate_files1(Spec,Result):- expand_file_search_path(Spec,Result).
  395enumerate_files1(Spec,Result):- absolute_file_name(Spec,Result).
  396enumerate_files1(Atom,Result):- atomic(Atom),once((member(Sep,['/**/','/**','**']),atomic_list_concat([B,A|R],Sep,Atom))),concat_paths([B,'**',A|R],Result).
  397
  398:- export(expand_file_name_safe/2).  399
  400%= 	 	 
 expand_file_name_safe(?I, ?O) is semidet
Expand File Name Safely Paying Attention To Corner Cases.
  406expand_file_name_safe(I,O):-var(I),trace_or_throw(expand_file_name_safe(I,O)),!.
  407expand_file_name_safe(I,O):- \+ compound(I), catch(expand_file_name(I,O),_,fail),O\=[],!.
  408expand_file_name_safe(I,[O]):- catch(expand_file_search_path(I,O),_,fail),!.
  409expand_file_name_safe(I,L):- 
  410  findall(O,
  411    (absolute_file_name(I,O,[expand(true),solutions(all)]);absolute_file_name(I,O,[expand(true),solutions(all),file_type(directory)])),
  412    L),!.
  413
  414:- export(exists_file_or_dir/1).  415
  416%= 	 	 
 exists_file_or_dir(?X) is semidet
Exists File Or Dir.
  422exists_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))))).
  423:- export(is_directory/1).  424
  425%= 	 	 
 is_directory(?X) is semidet
If Is A Directory.
  431is_directory(X):-exists_directory(X).
  432
  433:- export(concat_paths/3).  434
  435%= 	 	 
 concat_paths(?ParentIn, ?Child, ?Result) is semidet
Concat Paths.
  441concat_paths(A,'',A).
  442concat_paths(A,'/',A).
  443concat_paths(ParentIn,'**',Result):-!, member(Child,['./','./*/','./*/*/','./*/*/*/','./*/*/*/*/','./*/*/*/*/*/']),concat_paths(ParentIn,Child,Result).
  444concat_paths(ParentIn,Child,Result):- filematch(ParentIn,Parent),
  445   once((is_directory(Parent) -> directory_file_path(Parent,Child,Joined) ; atom_concat(Parent,Child,Joined))),!,
  446   filematch(Joined,Result).
  447
  448:- export(concat_paths/2).  449
  450%= 	 	 
 concat_paths(:TermJoined, ?Result) is semidet
Concat Paths.
  456concat_paths([Joined],Result):- !,filematch(Joined,Result).
  457concat_paths([ParentIn,Child|MORE],Result):- concat_paths(ParentIn,Child,ResultM),concat_paths([ResultM|MORE],Result).
  458
  459
  460:- thread_local(t_l:search_first_dir/1).  461
  462
  463%= 	 	 
 current_dirs(?DO) is semidet
Current Dirs.
  469current_dirs(DO):- no_repeats(DO,(current_dirs0(D),(atom_concat(DO,'/',D)->true;DO=D))).
  470
  471%= 	 	 
 current_dirs0(?D) is semidet
Current Dirs Primary Helper.
  477current_dirs0(D):- t_l:search_first_dir(D).
  478current_dirs0(D):- prolog_load_context(directory,D).
  479current_dirs0(D):- working_directory(D,D).
  480current_dirs0(D):- current_stream(_,read,Y), stream_property(Y,file_name(FN)), file_directory_name(FN,D).
  481current_dirs0(D):- stream_property(_,file_name(FN)), file_directory_name(FN,D).
  482
  483%current_dirs0(D):- expand_file_name('*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  484%current_dirs0(D):- expand_file_name('*/*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  485%current_dirs0(D):- expand_file_name('*/*/*/',X),member(E,X),absolute_file_name(E,D),exists_directory(D).
  486current_dirs0(D):- source_file_property(FN, modified(_)), file_directory_name(FN,D).
  487current_dirs0('.').
  488
  489:- export(to_filename/2).  490:- thread_local(t_l:default_extension/1).  491
  492%= 	 	 
 to_filename(?FileName, ?AFN) is semidet
Converted To Filename.
  498to_filename( FileName, AFN ) :- atomic(FileName),exists_file(FileName),!,AFN=FileName.
  499to_filename( FileName, AFN ) :-
  500 ((((t_l:default_extension( Ext ));Ext='.tlp';Ext='';Ext='.pl'), 
  501     current_dirs(D),
  502     member(TF,[false,true]),
  503        absolute_file_name(FileName,AFN,[solutions(all),expand(TF),access(read),relative_to(D),file_errors(fail),extensions(['',Ext,'.pl','.tlp','.clp','.P'])]),
  504        exists_file(AFN))),!.
  505
  506
  507:- export((add_to_search_path/2,add_to_search_path_first/2,prolog_file_dir/2,if_startup_script/1,if_startup_script/0)).  508
  509:- export(prolog_file_dir/1).  510
  511%= 	 	 
 prolog_file_dir(?Here) is semidet
Prolog File Dir.
  517prolog_file_dir(Here):- prolog_load_context(file, HereF),file_directory_name(HereF,Here).
  518prolog_file_dir(Here):- working_directory(Here,Here).
  519:- export(prolog_file_dir/2).  520
  521%= 	 	 
 prolog_file_dir(?Rel, ?ABSF) is semidet
Prolog File Dir.
  527prolog_file_dir(Rel,ABSF):-prolog_file_dir(Here),absolute_file_name(Rel,ABSF,[relative_to(Here),file_type(directory),expand(true)]),!.
  528prolog_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.
  535in_include_file:- prolog_load_context(file,F),!, \+ prolog_load_context(source,F).
  536
  537%= 	 	 
 remove_search_path(?Alias, ?Abs) is semidet
Remove Search Path.
  543remove_search_path(Alias, Abs) :- ignore((clause(user:file_search_path(Alias, AbsW0),true,Ref),
  544                                          absolute_file_name(AbsW0,AbsW),same_file(Abs,AbsW),erase(Ref),fail)).
  545
  546%= 	 	 
 add_to_search_path_first(?Alias, ?Abs) is semidet
Add Converted To Search Path First.
  552add_to_search_path_first(Alias, Abs) :- remove_search_path(Alias, Abs), asserta(user:file_search_path(Alias, Abs)).
  553
  554%= 	 	 
 add_to_search_path_last(?Alias, ?Abs) is semidet
Add Converted To Search Path Last.
  560add_to_search_path_last(Alias, Abs) :- remove_search_path(Alias, Abs), assertz(user:file_search_path(Alias, Abs)).
  561
  562%= 	 	 
 in_search_path(?Alias, ?Abs) is semidet
In Search Path.
  568in_search_path(Alias, Abs) :- user:file_search_path(Alias,Was0),absolute_file_name(Was0,Was),same_file(Abs,Was).
  569
  570
  571
  572%= 	 	 
 add_to_search_path(?Alias, ?Abs) is semidet
Add Converted To Search Path.
  578add_to_search_path(Alias, Abs):- add_to_search_path(add_to_search_path_last, Alias, Abs).
  579:- meta_predicate add_to_search_path(2,?,?).  580
  581%= 	 	 
 add_to_search_path(:PRED2How, ?Alias, ?Abs) is semidet
Add Converted To Search Path.
  587add_to_search_path(How, Alias, AbsIn) :- strip_module(AbsIn,_,Abs),!,
  588  ( (atom(Abs),is_absolute_file_name(Abs)) -> call(How,Alias,Abs)     
  589   ; (prolog_file_dir(Abs,ABSF),call(How,Alias,ABSF))).
  590
  591:- add_to_search_path(logicmoo, './../').  592
  593
  594% Was this our startup file?
  595
  596%= 	 	 
 if_startup_script is semidet
If Startup Script.
  602if_startup_script:- prolog_load_context(source, HereF),current_prolog_flag(associated_file,HereF),!.
  603if_startup_script:- prolog_load_context(source, HereF),file_base_name(HereF,HereFB),
  604   current_prolog_flag(os_argv,List),!,member(Arg,List),file_base_name(Arg,ArgFB),atom_concat(ArgFB,_,HereFB),!.
  605
  606:- meta_predicate(if_startup_script(0)).  607
  608%= 	 	 
 if_startup_script(:Goal) is semidet
If Startup Script.
  614if_startup_script(Call):-if_startup_script->Call;dmsg(\+ if_startup_script(Call)).
  615
  616:- export(normalize_path/2).  617
  618%= 	 	 
 normalize_path(?Where, ?WhereF3) is semidet
Normalize Path.
  624normalize_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).
  625normalize_path(Where,WhereF2):-clip_dir_sep(Where,WhereF2).
  626
  627
  628%= 	 	 
 clip_dir_sep(?Where, ?WhereF2) is semidet
Clip Dir Sep.
  634clip_dir_sep('/','/'):-!.
  635clip_dir_sep(Where,WhereF2):-atom_concat(WhereF2,'/',Where),!.
  636clip_dir_sep(Where,Where):-!.
  637
  638
  639
  640%= 	 	 
 my_absolute_file_name(?F, ?A) is semidet
My Absolute File Name.
  646my_absolute_file_name(F,A):-catch(expand_file_name(F,[A]),_,fail),F\=A,!.
  647my_absolute_file_name(F,A):-catch(absolute_file_name(F,A),_,fail),!.
  648
  649% register search path hook
  650
  651
  652
  653%= 	 	 
 join_path_if_needed(?A, ?B, ?C) is semidet
Join Path If Needed.
  659join_path_if_needed(A,B,C):-exists_directory(B)->B=C;directory_file_path(A,B,C).
  660
  661
  662%= 	 	 
 locally_to_dir(?Locally, ?Dir) is semidet
Locally Converted To Dir.
  668locally_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),!.
  669locally_to_dir(Directory,Dir):-my_absolute_file_name(Directory,Dir),exists_directory(Dir),!.
  670
  671
  672
  673:- dynamic(local_directory_search/1).  674
  675
  676% user:file_search_path(library,ATLIB):-getenv('PATH_INDIGOLOG',AT),atom_concat(AT,'/lib',ATLIB).
  677% user:file_search_path(indigolog,AT):-getenv('PATH_INDIGOLOG',AT).
  678% user:file_search_path(logicmoo,Dir):-  local_directory_search(Locally), locally_to_dir(Locally,Dir).
  679
  680
  681
  682%= 	 	 
 local_directory_search_combined(?X) is semidet
Local Directory Search Combined.
  688local_directory_search_combined(X):-local_directory_search(X).
  689local_directory_search_combined(X):-local_directory_search_combined2(X).
  690% for now dont do the concat 3 version
  691local_directory_search_combined(PL):-local_directory_search_combined2(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
  692
  693%= 	 	 
 local_directory_search_combined2(?PL) is semidet
Local Directory Search Combined Extended Helper.
  699local_directory_search_combined2(PL):-local_directory_search(A),local_directory_search(B),join_path(A,B,PL),exists_directory_safe(PL).
  700:- multifile(local_directory_search/1).  701:- dynamic(local_directory_search/1).  702% Add the locations that the MUD source files will be picked up by the system
  703%local_directory_search('../..').
  704%local_directory_search('~logicmoo-mud/cynd/startrek'). % home vtDirection CynD world
  705% local_directory_search('.').
  706% local_directory_search('..'). 
  707%local_directory_search('../runtime'). 
  708%local_directory_search('../src_game'). % for user overrides and uploads
  709%local_directory_search('../src_assets').  % for non uploadables (downloadables)
  710%local_directory_search('../src_modules'). % for big modules
  711%local_directory_search('../src_webui').  % for web UI modules
  712
  713%= 	 	 
 local_directory_search(?VALUE1) is semidet
Local Directory Search.
  719local_directory_search('../src'). % shared_library preds
  720local_directory_search('../src_lib').
  721local_directory_search('../src_mud').  % for vetted src of the MUD
  722%local_directory_search('../externals/XperiMental/src_incoming').  % areeba underlay
  723
  724
  725
  726
  727
  728%= 	 	 
 exists_dirf(?X) is semidet
Exists Dirf.
  734exists_dirf(X):-atomic(X),(exists_file(X);exists_directory(X)).
  735
  736%= 	 	 
  737
  738
  739%= 	 	 
 exists_file_safe(?File) is semidet
Exists File Safely Paying Attention To Corner Cases.
  745exists_file_safe(File):- ((nonvar(File),(File=(_:F)->exists_file_safe(F);(atomic(File),exists_file(File))))).
  746
  747%= 	 	 
 exists_directory_safe(?File) is semidet
Exists Directory Safely Paying Attention To Corner Cases.
  753exists_directory_safe(File):- must(atomic(File)),exists_directory(File).
  754/*
  755concat_atom_safe(List,Sep,[Atom]):-atom(Atom),!,concat_atom(List,Sep,Atom),!.
  756concat_atom_safe(List,Sep,Atom):-atom(Atom),!,concat_atom(ListM,Sep,Atom),!,List = ListM.
  757concat_atom_safe(List,Sep,Atom):- concat_atom(List,Sep,Atom),!.
  758*/
  759
  760%= 	 	 
 upcase_atom_safe(?A, ?B) is semidet
Upcase Atom Safely Paying Attention To Corner Cases.
  766upcase_atom_safe(A,B):-atom(A),upcase_atom(A,B),!.
  767
  768%= 	 	 
 time_file_safe(?F, ?INNER_XML) is semidet
Time File Safely Paying Attention To Corner Cases.
  774time_file_safe(_:F,INNER_XML):-atom(F),!,exists_file_safe(F),time_file(F,INNER_XML).
  775time_file_safe(F,INNER_XML):-exists_file_safe(F),!,time_file(F,INNER_XML).
  776
  777
  778
  779
  780% =================================================================================
  781% Utils
  782% =================================================================================
  783
  784
  785%= 	 	 
 global_pathname(?B, ?A) is semidet
Global Pathname.
  791global_pathname(B,A):-absolute_file_name(B,A),!.
  792global_pathname(B,A):-relative_pathname(B,A).
  793
  794
  795%= 	 	 
 relative_pathname(?Path, ?Relative) is semidet
Relative Pathname.
  801relative_pathname(Path,Relative):-absolute_file_name(Path,[relative_to('./')],Absolute),member(Rel,['./','../','../../']),absolute_file_name(Rel,Clip),
  802  canonical_pathname(Absolute,AbsoluteA),
  803  canonical_pathname(Clip,ClipA),
  804  atom_concat_safe0(ClipA,RelativeA,AbsoluteA),!,atom_concat_safe0(Rel,RelativeA,Relative),!.
  805relative_pathname(Path,Relative):-canonical_pathname(Path,Relative),!.
  806
  807atom_concat_safe0(L,R,A):- ((atom(A),(atom(L);atom(R))) ; ((atom(L),atom(R)))), !, atom_concat(L,R,A),!.
  808
  809
  810%= 	 	 
 canonical_pathname(?Absolute, ?AbsoluteB) is semidet
Canonical Pathname.
  816canonical_pathname(Absolute,AbsoluteB):-prolog_to_os_filename(AbsoluteA,Absolute),expand_file_name(AbsoluteA,[AbsoluteB]),!.
  817
  818
  819
  820% ===============================================================================================
  821% join_path(CurrentDir,Filename,Name)
  822% ===============================================================================================
  823
  824
  825
  826
  827%= 	 	 
 join_path(?CurrentDir, ?Filename, ?Name) is semidet
Join Path.
  833join_path(CurrentDir,Filename,Name):-
  834     atom_ensure_endswtih(CurrentDir,'/',Out),atom_ensure_endswtih('./',Right,Filename),
  835     atom_concat(Out,Right,Name),!.
  836
  837:- multifile current_directory_search/1.  838:- module_transparent current_directory_search/1.  839
  840
  841%= 	 	 
 atom_ensure_endswtih(?A, ?E, ?A) is semidet
Atom Ensure Endswtih.
  847atom_ensure_endswtih(A,E,A):-atom(E),atom_concat(_Left,E,A),!.
  848atom_ensure_endswtih(A,E,O):-atom(A),atom(E),atom_concat(A,E,O),!.
  849atom_ensure_endswtih(A,E,O):-atom(A),atom(O),atom_concat(A,E,O),!.
  850atom_ensure_endswtih(A,O,O):-atom(A),atom(O),!.
  851
  852
  853%= 	 	 
 os_to_prolog_filename(?OS, ?PL) is semidet
Outputs Converted To Prolog Filename.
  859os_to_prolog_filename(OS,_PL):-sanity(atom(OS)),fail.
  860os_to_prolog_filename(_OS,PL):-sanity(var(PL)),fail.
  861os_to_prolog_filename(OS,PL):-exists_file_safe(OS),!,PL=OS.
  862os_to_prolog_filename(OS,PL):-exists_directory_safe(OS),!,PL=OS.
  863os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_file_safe(PL),!.
  864os_to_prolog_filename(OS,PL):-current_directory_search(CurrentDir),join_path(CurrentDir,OS,PL),exists_directory_safe(PL),!.
  865
  866os_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).
  867os_to_prolog_filename(OS,PL):-atom_concat_safe0(BeforeSlash,'/',OS),os_to_prolog_filename(BeforeSlash,PL).
  868os_to_prolog_filename(OS,PL):-absolute_file_name(OS,OSP),OS \== OSP,!,os_to_prolog_filename(OSP,PL).
  869
  870:- fixup_exports.