HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_PathSearch.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_PathSearch.h ( FS Library, C++)
7  *
8  * COMMENTS:
9  * This class defines Houdini path searching. The class assumes that you
10  * will be searching for sub-paths within a given path. Each path class
11  * will cache the list of directories to scan for. This is done in the
12  * creation of the path searcher.
13  * Each path search is given a default path (which defaults to the
14  * houdini path), a path environment variable.
15  *
16  * In the path expansion, the following rules apply:
17  * @ = Expands to the HOUDINI_PATH
18  * & = Expands to the default path
19  * ^ = Expands to the default sub-path
20  * Paths may be colon or semi-colon separated.
21  *
22  * For example:
23  * UT_PathSearch theHotkeyPath(def = "@/config/Hotkeys",
24  * env = "HOUDINI_HOTKEY_PATH");
25  * UT_PathSearch theVexPath(
26  * def = "@/vex/^",
27  * env = "HOUDINI_VEX_PATH");
28  *
29  * When searching for a file, can use one of:
30  * int findFile(const char *search, UT_String &path);
31  * int findAllFiles(const char *search,
32  * UT_StringArray &paths);
33  *
34  * There are a number of well known paths. Typically, you should simply
35  * call the static access method to get the path that you're interested
36  * in.
37  */
38 
39 #ifndef __UT_PathSearch__
40 #define __UT_PathSearch__
41 
42 #include "UT_API.h"
43 #include "UT_KnownPath.h"
44 #include "UT_StringArray.h"
45 #include "UT_UniquePtr.h"
46 #include "UT_WorkBuffer.h"
47 #include <SYS/SYS_Compiler.h>
48 
49 
50 template <typename T> class UT_ValArray;
52 class UT_StringSet;
53 
54 
56 {
57 public:
58  UT_PathSearch() = delete;
59  UT_PathSearch(const char *defpath,
60  int var_id, // From UT_EnvControl
61  const char *carat_expand = "",
62  int at_expand = UT_HOUDINI_PATH);
63  UT_PathSearch(const UT_PathSearch &copy) = default;
64 
65  static bool pathMap(UT_String &path);
66  static bool pathMap(UT_StringHolder &result, const char *path);
67  static void pathMapSave(UT_WorkBuffer &wbuf, bool pretty);
68  static void pathMapLoad(const char *dict);
69  static void pathMapAdd(const char *src, const char *dest,
70  bool case_sensitive);
71  static bool pathMapRemove(const char *src);
72 
73  /// Given a variable name (e.g. "HOUDINI_PATH") return the known path enum
74  /// associated with it. If the name doesn't match a known path, the
75  /// function will return @c UT_MAX_KNOWN_PATHS.
76  static UT_KnownPath lookupPath(const char *name);
77 
78  /// Given a known path, return the variable name associated with the path
79  /// Returns @c nullptr on error.
80  static const char *lookupPath(UT_KnownPath path);
81 
82  static const UT_PathSearch *getInstance(UT_KnownPath path_type);
83 
84  // Make your own copy of a UT_PathSearch class.
85  // Using this, you can add to the path dynamically (eg. CPP)
86  static UT_UniquePtr<UT_PathSearch> getHardPath(UT_KnownPath path_type);
87 
88  // Cause all known paths to be re-built.
89  static void rehashAll();
90  // Rehashes a specific known path - note that this will not rehash
91  // copies of known paths.
92  static void rehashSpecific(UT_KnownPath pathid);
93  void rehash();
94 
95  static void refreshStartupPathCacheDirectory(const UT_StringHolder &directory_path);
96  static void clearStartupCache();
97 
98  // A useful little convenience function which will return the expansion of
99  // $HOME/houdini$HOUDINI_VER
100  /// @{
101  static void getHomeHoudini(UT_String &str);
103  static UT_StringHolder getHomeHoudini();
104  /// @}
105 
106  // extending the path allows multiple paths to be created in a single
107  // search path. For example, when scanning for Surface shaders, the
108  // carat_expand can be set to "Surface" and then extended with "include"
109  void extendPath(const char *defpath = 0,
110  int var_id = -1,
111  const char *carat_expand = 0,
112  int at_expand = -1);
113 
114  // Add a single path to the search path. The path must be unique
115  // otherwise the function returns false. The new path condensed
116  // format is added if condensed=true.
117  // Return true if a new path is added or false otherwise.
118  bool appendPath(const char *path, bool condensed = false);
119 
120  // Removes a path from the search path.
121  // Returns true if the path ws removed, false otherwise.
122  bool removePath(const char *path);
123 
124  // Prepend single path to the search path. The path must be unique
125  // otherwise the function returns false. The new path condensed
126  // format is prepended if condensed=true.
127  // Return true if a new path is prepended or false otherwise.
128  bool prependPath(const char *path, bool condensed = false);
129 
130  // Find the first file that occurs in the path
131  int findFile(UT_String &result, const char *search) const;
132  int findFile(UT_WorkBuffer &result, const char *search) const;
133  int findDirectory(UT_String &result, const char *search) const;
134 
135  // Find the first of the given list of files in the path. If they exist
136  // in the same directory, then the order is determined from the search_list
137  bool findFileFromList(UT_String &result,
138  const UT_StringArray &search_list) const;
139  bool findDirectoryFromList(UT_String &result,
140  const UT_StringArray &search_list) const;
141 
142  // Find all files in the path.
143  // The contents of the list is APPENDED to,
144  // it isn't automatically cleared.
145  int findAllFiles(const char *search,
146  UT_StringArray &list) const;
147 
148  int findAllDirectories(const char *search,
149  UT_StringArray &list) const;
150 
151  // This function will match all files with the given extension in the
152  // search path and fill the given list with the filenames only. Returns the
153  // # of entries in the filled list. (sample extension = ".vex")
154  int matchAllFiles(const char *extension,
155  bool returnfullpaths,
156  UT_StringArray &list,
157  bool recurse=false,
158  bool skip_dup_paths=false) const;
159 
160  // This function will match all files with one of the given extensions
161  // in the search path and fill the given list with the filenames only.
162  // Returns the # of entries in the filled list. The extensions should begin
163  // with a period.
164  int matchAllFiles(const UT_StringList &exts,
165  bool returnfullpaths,
166  UT_StringArray &list,
167  bool recurse=false,
168  bool skip_dup_paths=false) const;
169 
170  int matchAllFilesInSubdirectory(const char *extension,
171  const char *subdirectory,
172  bool returnfullpaths,
173  UT_StringArray &list,
174  bool recurse=false,
175  bool skip_dup_paths=false) const;
176  int matchAllFilesInSubdirectory(const UT_StringList &exts,
177  const char *subdirectory,
178  bool returnfullpaths,
179  UT_StringArray &list,
180  bool recurse=false,
181  bool skip_dup_paths=false) const;
182 
183  // Old style find-file. If a result buffer is passed in, the search
184  // result will be stored in it. This is a little dangerous since it's a
185  // fixed length buffer.
186  int houdiniFindFile(const char *find, UT_String &result) const;
187  int houdiniFindFile(const char *find, UT_WorkBuffer &result) const;
188 
189  int houdiniFindDirectory(const char *find, UT_String &result) const;
190  int houdiniFindDirectory(const char *find, UT_WorkBuffer &r) const;
191 
192  int getEntries() const { return myPaths.entries(); }
193  const char *getPathComponent(int i) const { return myPaths(i); }
194 
195  // Base paths are all paths tested, whether they are valid directories or
196  // not.
197  int getBaseEntries() const { return myBasePaths.entries(); }
198  const char *getBaseComponent(int i) const { return myBasePaths(i); }
199  const char *getCondensedComponent(int i) const
200  { return myCondensedPaths(i); }
201 
202  const char *getDefaultPath() const { return myDefaultPath; }
203  const char *getCaratExpand() const { return myCaratExpand; }
204 
205  int getVariableId() const { return myVariableId; }
206  int getAtExpand() const { return myAtExpand; }
207 
208  // Take a fully qualified path and collapse just the $HIP part of the path
209  static int condenseHip(UT_String &path);
210  static int condenseHip(UT_WorkBuffer &path);
211 
212  // Take a fully qualified path and collapse just the $JOB part of the path
213  static int condenseJob(UT_String &path);
214 
215  // Helper struct which constructs with myPaths/myCondensedPaths suitable
216  // for calling into condensePath().
218  {
219  CommonPaths();
220 
221  enum { NUM_PATHS = 8 };
222 
223  int size() const { return NUM_PATHS; }
224  const char *hip() const { return myPaths[2]; }
225 
226  const char *myPaths[NUM_PATHS];
227  const char *myCondensedPaths[NUM_PATHS];
228  };
229 
230  // Take a fully qualified path and collapse it to a "common" variable path.
231  // For example, $HFS/... instead of /usr/hfs5.3.391/...
232  // @{
233  // @note This is slow if you use it in a loop. Instead, use the alternate
234  // form of condenseCommon() with a CommonPaths object constructed outside
235  // the loop.
236  static inline bool
238  {
239  CommonPaths common;
240  return condenseCommon(path, path, common);
241  }
242 
243  // @note This is slow if you use it in a loop. Instead, use the alternate
244  // form of condenseCommon() with a CommonPaths object constructed outside
245  // the loop.
246  static inline bool
248  {
249  CommonPaths common;
250  return condenseCommon(path, path.buffer(), common);
251  }
252 
253  // @note This is slow if you use it in a loop. Instead, use the alternate
254  // form of condenseCommon() with a CommonPaths object constructed outside
255  // the loop.
256  static inline bool
257  condenseCommon(UT_String &condensed, const char *path)
258  {
259  CommonPaths common;
260  return condenseCommon(condensed, path, common);
261  }
262 
263  // @note This is slow if you use it in a loop. Instead, use the alternate
264  // form of condenseCommon() with a CommonPaths object constructed outside
265  // the loop.
266  static inline bool
267  condenseCommon(UT_WorkBuffer &condensed, const char *path)
268  {
269  CommonPaths common;
270  return condenseCommon(condensed, path, common);
271  }
272 
273  static inline bool
274  condenseCommon(UT_String &path, const CommonPaths &common)
275  {
276  return condenseCommon(path, path, common);
277  }
278 
279  static inline bool
281  {
282  return condenseCommon(path, path.buffer(), common);
283  }
284 
285  static inline bool
286  condenseCommon(UT_String &path, const char *source_path,
287  const CommonPaths &common)
288  {
289  return condensePath(path, source_path, common.myPaths,
290  common.myCondensedPaths, common.size());
291  }
292 
293  static inline bool
294  condenseCommon(UT_WorkBuffer &path, const char *source_path,
295  const CommonPaths &common)
296  {
297  return condensePath(path, source_path, common.myPaths,
298  common.myCondensedPaths, common.size());
299  }
300  // @}
301 
302  // The path variables passed in should ALWAYS be UT_StrControl types.
303  // The values of these variables are tested against the leading portion of
304  // the full path specified and the "longest" match is used for replacement
305  // of the lead. For example the result might be $HOME/relpath.
306  static bool condensePath(UT_WorkBuffer &result,
307  const char *source_path,
308  const char *const paths[],
309  const char *const condensed_paths[],
310  int npaths);
311 
312  static inline bool
314  const char *source_path,
315  const char *const paths[],
316  const char *const condensed_paths[],
317  int npaths)
318  {
319  UT_WorkBuffer condensed;
320  bool ok = condensePath(condensed, source_path,
321  paths, condensed_paths, npaths);
322  if (ok)
323  condensed.copyIntoString(path);
324  else if (path.buffer() != source_path)
325  path.harden(source_path);
326  return ok;
327  }
328 
329  static inline bool
331  const char *const paths[],
332  const char *const condensed_paths[],
333  int npaths)
334  {
335  return condensePath(path, path, paths, condensed_paths, npaths);
336  }
337 
338  // This method will take a fully qualified path and strip off the lead
339  // characters of the pathname -- resulting in path which can still be found
340  // by the path searching code, but which is simpler in nature...
341  // For example, the path $HOME/houdini/fonts/Type1/Courier might be
342  // stripped to simply "Type1/Courier"
343  static int stripLeadPath(UT_String &path, UT_KnownPath pathvar);
344 
345  // Similar to stripLeadPath except that it will always return the shortest
346  // path, irrespective of the order of the paths.
347  static int stripMaxLeadPath(UT_String &path, UT_KnownPath pathvar);
348 
349  // This method, given a filename that is possibly fully specified, will
350  // try to return the fully specified path to the file. Returns true
351  // if absolute_path is valid, false otherwise.
352  static bool resolveAbsolutePath(const char *filename,
353  UT_String &absolute_path);
354 
355  // return the expansion of $HOME/houdini$HOUDINI_VER as though it was
356  // the @ in the search pattern. If there is no search pattern then just
357  // return $HOME/houdini$HOUDINI_VER
358  void getHomeHoudiniSearch(UT_StringArray &strs) const;
359 
360  // Utility for splitting an environment variable path. The function expects
361  // the path to be separated with these characters:
362  // Windows: ";"
363  // Linux or Mac: ":" or ";"
364  //
365  // path: path content. May contain "&" as insertion point of an existing path.
366  // list: return list of splitted elements
367  // insert_path: insert_path is prepended to path at the insertion point (&).
368  static void splitPath(const char *path, UT_StringArray &list,
369  const char *insert_path);
370 
371 private:
372  UT_PathSearch & operator=( const UT_PathSearch &copy ); // not implemented
373 
374 private:
375  void initialize(const char *def,
376  int var_id,
377  const char *carat,
378  int at_expand);
379  void clearPath();
380 
381  /// Helper function for matchAllFiles() and matchAllFilesInSubdirectory().
382  void matchAllFilesInPath(const UT_StringList &exts,
383  const char *path,
384  bool returnfullpaths,
385  bool recurse,
386  UT_StringArray &list,
387  UT_StringSet *seen)const;
388 
389  int myVariableId;
390  UT_String myDefaultPath;
391  UT_String myCaratExpand;
392  int myAtExpand;
393  int myMaxPath; // Max path length
394 
395  UT_StringArray myPaths;
396  UT_StringArray myBasePaths;
397  UT_StringArray myCondensedPaths;
398 };
399 
400 inline int
402 {
404  houdiniFindFile(find, result))
405  result = 0;
406  return result.isstring();
407 }
408 
409 inline int
411 {
413  houdiniFindFile(find, result))
414  result.clear();
415  return result.length() != 0;
416 }
417 
418 inline int
420 {
421  result.clear();
423  findAllFiles(find, result);
424  return result.entries();
425 }
426 
427 inline int
429 {
431  houdiniFindDirectory(find, result))
432  result = 0;
433  return result.isstring();
434 }
435 
436 inline int
438 {
440  houdiniFindDirectory(find, result))
441  result.clear();
442  return result.length() != 0;
443 }
444 
445 inline int
447 {
448  result.clear();
450  findAllDirectories(find, result);
451  return result.entries();
452 }
453 
454 #endif
static const UT_PathSearch * getInstance(UT_KnownPath path_type)
const char * getCondensedComponent(int i) const
path_type
CLI enumeration of different file types.
Definition: CLI11.h:2963
int HoudiniFindFile(const char *find, UT_String &result)
GT_API const UT_StringHolder filename
SYS_FORCE_INLINE exint length() const
UT_KnownPath
Definition: UT_KnownPath.h:14
int getBaseEntries() const
static bool condensePath(UT_String &path, const char *const paths[], const char *const condensed_paths[], int npaths)
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
const char * getBaseComponent(int i) const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
const char * myPaths[NUM_PATHS]
SYS_FORCE_INLINE const char * buffer() const
#define UT_API
Definition: UT_API.h:14
void copyIntoString(UT_String &str) const
**But if you need a result
Definition: thread.h:622
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2138
static bool condensePath(UT_String &path, const char *source_path, const char *const paths[], const char *const condensed_paths[], int npaths)
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
int HoudiniFindDir(const char *find, UT_String &result)
const char * buffer() const
Definition: UT_String.h:516
const char * myCondensedPaths[NUM_PATHS]
static bool condenseCommon(UT_WorkBuffer &path, const char *source_path, const CommonPaths &common)
static bool condenseCommon(UT_WorkBuffer &path, const CommonPaths &common)
UT_ValArray< const char * > UT_StringList
Definition: UT_PathSearch.h:50
static bool condenseCommon(UT_String &path, const char *source_path, const CommonPaths &common)
void harden()
Take shallow copy and make it deep.
Definition: UT_String.h:222
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:93
GLuint const GLchar * name
Definition: glcorearb.h:786
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
static bool condenseCommon(UT_WorkBuffer &condensed, const char *path)
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
Definition: CLI11.h:3170
const char * getDefaultPath() const
exint entries() const
Alias of size(). size() is preferred.
Definition: UT_Array.h:655
const char * hip() const
const char * getPathComponent(int i) const
static bool condenseCommon(UT_WorkBuffer &path)
int HoudiniFindMulti(const char *find, UT_StringArray &result)
const char * getCaratExpand() const
LeafData & operator=(const LeafData &)=delete
static bool condenseCommon(UT_String &path, const CommonPaths &common)
static bool condenseCommon(UT_String &condensed, const char *path)
bool isstring() const
Definition: UT_String.h:698
SYS_FORCE_INLINE void clear()
int HoudiniFindDirMulti(const char *find, UT_StringArray &result)
GLboolean r
Definition: glcorearb.h:1222
void clear()
Resets list to an empty list.
Definition: UT_Array.h:736
int getEntries() const
int getAtExpand() const
static bool condenseCommon(UT_String &path)
OIIO_UTIL_API std::string extension(string_view filepath, bool include_dot=true) noexcept
int getVariableId() const
GLenum src
Definition: glcorearb.h:1793