1 /*
2     This file is part of GNU APL, a free implementation of the
3     ISO/IEC Standard 13751, "Programming Language APL, Extended"
4 
5     Copyright (C) 2015  Dr. Jürgen Sauermann
6 
7     This program is free software: you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation, either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef __LIBPATHS_HH_DEFINED__
22 #define __LIBPATHS_HH_DEFINED__
23 
24 #include "UTF8_string.hh"
25 
26 //-----------------------------------------------------------------------------
27 
28 /// a library reference number for commands )LOAD, )SAVE, and )COPY.
29 /// No library reference number is the same as LIB0.
30 enum LibRef
31 {
32    LIB0 = 0,         ///< library 0
33    LIB1 = 1,         ///< library 1
34    LIB2 = 2,         ///< library 2
35    LIB3 = 3,         ///< library 3
36    LIB4 = 4,         ///< library 4
37    LIB5 = 5,         ///< library 5
38    LIB6 = 6,         ///< library 6
39    LIB7 = 7,         ///< library 7
40    LIB8 = 8,         ///< library 8
41    LIB9 = 9,         ///< library 9
42    LIB_MAX,          ///< valid library references are smaller than this
43    LIB_WSNAME,       ///< WS name may start with a library reference
44    LIB_NONE = LIB0   ///< no library reference specified.
45 };
46 //-----------------------------------------------------------------------------
47 /// a class mapping library reference numbers to directories
48 class LibPaths
49 {
50 public:
51    /// one library directory
52    struct LibDir
53       {
54         /// constructor: unspecified LibDir
LibDirLibPaths::LibDir55         LibDir()
56         : cfg_src(CSRC_NONE)
57         {}
58 
59         /// the path (name) of the lib directory
60         UTF8_string dir_path;
61 
62         /// how a dir_path was computed
63         enum CfgSrc
64            {
65              CSRC_NONE      = 0,   ///< not at all
66              CSRC_ENV       = 1,   ///< lib root from env. variable APL_LIB_ROOT
67              CSRC_PWD       = 2,   ///< lib root from current directory
68              CSRC_PREF_SYS  = 3,   ///< path from preferences file below /etc/
69              CSRC_PREF_HOME = 4,   ///< path from preferences file below $HOME
70              CSRC_CMD       = 5,   ///< lib root from )LIBS command
71            };
72 
73         /// how dir_path was computed
74         CfgSrc cfg_src;
75       };
76 
77    /// initialize library paths based on the location of the APL binary
78    static void init(const char * argv0, bool logit);
79 
80    /// return the path (directory) of the APL interpreter binary
get_APL_bin_path()81    static const char * get_APL_bin_path()   { return APL_bin_path; }
82 
83    /// return the name (without directory) of the APL interpreter binary
get_APL_bin_name()84    static const char * get_APL_bin_name()   { return APL_bin_name; }
85 
86    /// return directory containing (file or directory) workspaces and wslib1
get_APL_lib_root()87    static const char * get_APL_lib_root()   { return APL_lib_root; }
88 
89    /// set library root to \b new_root
90    static void set_APL_lib_root(const char * new_root);
91 
92    /// set library path (from config file)
93    static void set_lib_dir(LibRef lib, const char * path, LibDir::CfgSrc src);
94 
95    /// return true iff directory \b lib) is present
96    static bool is_present(LibRef lib);
97 
98    /// return library path (from config file or from libroot)
99    static UTF8_string get_lib_dir(LibRef lib);
100 
101    /// return source that configured \b this entry
get_cfg_src(LibRef lib)102    static LibDir::CfgSrc get_cfg_src(LibRef lib)
103       { return lib_dirs[lib].cfg_src; }
104 
105    /// return full path for file \b name, possibly adding .ext1 or .ext2
106    static UTF8_string get_lib_filename(LibRef lib, const UTF8_string & name,
107                                       bool existing, const char * ext1,
108                                                      const char * ext2);
109 protected:
110    /// maybe warn the user if two files that differ only by extension exist
111    static void maybe_warn_ambiguous(int name_has_extension,
112                                     const UTF8_string name,
113                                     const char * ext1, const char * ext2);
114 
115    /// compute the location of the apl binary
116    static void compute_bin_path(const char * argv0, bool logit);
117 
118    /// set library root, searching from APL_bin_path
119    static void search_APL_lib_root();
120 
121    /// return true if directory \b dir contains two (files or sub-directories)
122    /// workspaces and wslib1
123    static bool is_lib_root(const char * dir);
124 
125    /// the path (directory) of the APL interpreter binary
126    static char APL_bin_path[];
127 
128    /// the name (without directory) of the APL interpreter binary
129    static const char * APL_bin_name;
130 
131    /// a directory containing sub-directories workspaces and wslib1
132    static char APL_lib_root[];
133 
134    /// directories for each library reference as specified in file preferences
135    static LibDir lib_dirs[LIB_MAX];
136 
137    /// true if APL_lib_root was computed from environment variable APL_LIB_ROOT
138    static bool root_from_env;
139 
140    /// true if APL_lib_root was not found ("." taken)
141    static bool root_from_pwd;
142 };
143 //-----------------------------------------------------------------------------
144 #endif // __LIBPATHS_HH_DEFINED__
145