00001 /* Part of the culibs project, <http://www.eideticdew.org/culibs/>. 00002 * Copyright (C) 2009 Petter Urkedal <urkedal@nbi.dk> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef CUOS_TOPDIRS_H 00019 #define CUOS_TOPDIRS_H 00020 00021 #include <cuos/fwd.h> 00022 #include <cucon/list.h> 00023 00024 CU_BEGIN_DECLARATIONS 00025 /** \defgroup cuos_dirpile_h cuos/dirpile.h: Prioritised Collection of Search Directories 00026 ** @{\ingroup cuos_mod 00027 ** 00028 ** This class holds a list of directory paths and provides functions to locate 00029 ** files with given relative paths under these. The semantics is suitable for 00030 ** implementing search paths similar to the compiler's -I flags or environment 00031 ** variables like $PATH, $PYTHONPATH, etc. 00032 **/ 00033 00034 /** A "pile" of directories for prioritized searches of relative paths. */ 00035 struct cuos_dirpile 00036 { 00037 struct cucon_list top_dirs; 00038 }; 00039 00040 /** Initialise an empty pile of directories. */ 00041 void cuos_dirpile_init(cuos_dirpile_t pile); 00042 00043 /** Returns an empty pile of directories. */ 00044 cuos_dirpile_t cuos_dirpile_new(void); 00045 00046 /** Initialise \a new_pile with the existing subdirectories \a src_subdir of \a 00047 ** src_pile in the order of occurence in \a src_pile. */ 00048 void cuos_dirpile_init_sub(cuos_dirpile_t new_pile, 00049 cuos_dirpile_t src_pile, cu_str_t src_subdir); 00050 00051 /** Return a dirpile of the existing subdirectories \a src_subdir of \a 00052 ** src_pile in the order of occurrence in \a src_pile. */ 00053 cuos_dirpile_t cuos_dirpile_new_sub(cuos_dirpile_t src_pile, 00054 cu_str_t src_subdir); 00055 00056 /** If \a dir exists, add it to \a pile and return true, else return false. If 00057 ** \a on_top, then \a dir will be tried before the current list, otherwise 00058 ** after. */ 00059 cu_bool_t cuos_dirpile_insert(cuos_dirpile_t pile, cu_str_t dir, 00060 cu_bool_t on_top); 00061 00062 /** \copydoc cuos_dirpile_insert */ 00063 cu_bool_t cuos_dirpile_insert_cstr(cuos_dirpile_t pile, char const *dir, 00064 cu_bool_t on_top); 00065 00066 /** Add the existing subdirectories \a subdir of directories from the 00067 ** colon-separated directories in \a var to \a pile. If \a subdir is \c NULL, 00068 ** "." is used. If \a on_top, then the added directories will be tried before 00069 ** the current list, otherwise after. Returns -1 if envvar is unset, 00070 ** otherwise the number of inserted directories. */ 00071 int cuos_dirpile_insert_env(cuos_dirpile_t pile, cu_bool_t on_top, 00072 char const *var, cu_str_t subdir); 00073 00074 /** \deprecated Use cuos_dirpile_insert_env appsind \c NULL for \a subdir. */ 00075 CU_SINLINE cu_bool_t 00076 cuos_dirpile_insert_envvar(cuos_dirpile_t pile, char const *var, 00077 cu_bool_t on_top) 00078 { return cuos_dirpile_insert_env(pile, on_top, var, NULL); } 00079 00080 /** If \a dir exists, add it to the bottom of \a pile and return true, else 00081 ** return false. */ 00082 CU_SINLINE cu_bool_t 00083 cuos_dirpile_append(cuos_dirpile_t pile, cu_str_t dir) 00084 { return cuos_dirpile_insert(pile, dir, cu_false); } 00085 00086 /** \copydoc cuos_dirpile_append */ 00087 CU_SINLINE cu_bool_t 00088 cuos_dirpile_append_cstr(cuos_dirpile_t pile, char const *dir) 00089 { return cuos_dirpile_insert_cstr(pile, dir, cu_false); } 00090 00091 /** Calls \a f with each top-level directory of \a pile in order. Stops the 00092 ** iteration and returns false if \a f returns false, else returns true. */ 00093 cu_bool_t cuos_dirpile_iterA_top(cuos_dirpile_t pile, 00094 cu_clop(f, cu_bool_t, cu_str_t)); 00095 00096 /** Returns the full path of the first file or directory with a path \a 00097 ** rel_path relative to a top-level path of \a pile, or \c NULL if no such 00098 ** file or directory exists. */ 00099 cu_str_t cuos_dirpile_first_match(cuos_dirpile_t pile, cu_str_t rel_path); 00100 00101 /** Calls \a f with the full path of each existing file or directory with a 00102 ** path \a rel_path relative to a top-level path of \a pile in order. Stops 00103 ** and returns false as soon as \a f returns false, else returns true. */ 00104 cu_bool_t cuos_dirpile_iterA_matches(cuos_dirpile_t pile, 00105 cu_clop(f, cu_bool_t, cu_str_t), 00106 cu_str_t rel_path); 00107 00108 void cuos_dirpile_append_matches(cuos_dirpile_t dst_pile, 00109 cuos_dirpile_t src_pile, cu_str_t src_subdir); 00110 00111 /** @} */ 00112 CU_END_DECLARATIONS 00113 00114 #endif