@@ -69,22 +69,49 @@ namespace search {
6969 return out;
7070 }
7171
72- const std::vector<fs::path> search_paths () {
72+ // / @brief Build a combination of all prefixes, subdirs, and name-like paths
73+ // / @param roots the prefix roots
74+ // / @param name the name of the package to find
75+ // / @return all of the search paths combined into concrete instances
76+ const std::vector<fs::path> expand_search_paths (const std::vector<fs::path> & roots, std::string_view name) {
7377 // TODO: Windows paths
7478 // TODO: MacOS paths
79+ const std::vector<fs::path> segments{platform::libdir (), " share" };
80+ std::vector<fs::path> paths;
81+
82+ for (auto && root : roots) {
83+ for (auto && segment : segments) {
84+ if (const fs::path subdir = root / segment / " cps" ; fs::is_directory (subdir)) {
85+ paths.emplace_back (subdir);
86+ if (const fs::path namedir = subdir / name; fs::is_directory (namedir)) {
87+ paths.emplace_back (namedir);
88+ for (const fs::path & name_subdir : fs::directory_iterator (namedir)) {
89+ if (fs::is_directory (name_subdir)) {
90+ paths.emplace_back (name_subdir);
91+ }
92+ }
93+ }
94+ }
95+ }
96+ }
97+
98+ return paths;
99+ }
100+
101+ // / @brief create concrete search paths for a specific package
102+ // / @param name the name of the pacakge
103+ // / @return a vector of those paths
104+ const std::vector<fs::path> search_paths (std::string_view name) {
105+
106+ // Build all of the roots to search
75107 std::vector<fs::path> roots;
76108 if (const char * env_c = std::getenv (" CPS_PATH" )) {
77109 auto && env = utils::split (env_c);
78110 roots.insert (roots.end (), env.begin (), env.end ());
79111 }
80112 roots.emplace_back (" /usr" );
81113
82- std::vector<fs::path> paths;
83- for (auto && root : roots) {
84- paths.emplace_back (root / platform::libdir () / " cps" );
85- paths.emplace_back (root / " share/cps" );
86- }
87- return paths;
114+ return expand_search_paths (roots, name);
88115 }
89116
90117 // / @brief Find all possible paths for a given CPS name
@@ -97,19 +124,10 @@ namespace search {
97124 }
98125
99126 // TODO: Need something like pkgconf's --personality option
100- // TODO: we likely either need to return all possible files, or load
101- // a file
102- // TODO: what to do about finding multiple versions of the same
103- // dependency?
104- auto && paths = search_paths ();
127+ auto && paths = search_paths (name);
105128 std::vector<fs::path> found{};
106129 for (auto && dir : paths) {
107- // TODO: <prefix>/<libdir>/cps/<name-like>/
108- // TODO: <prefix>/share/cps/<name-like>/
109- // TODO: <prefix>/share/cps/
110-
111130 if (fs::is_directory (dir)) {
112- // TODO: <name-like>
113131 const fs::path file = dir / fmt::format (" {}.cps" , name);
114132 if (fs::is_regular_file (file)) {
115133 found.push_back (file);
@@ -262,13 +280,25 @@ namespace search {
262280 }
263281 }
264282
265- fs::path calculate_prefix (const fs::path & path) {
283+ fs::path calculate_prefix (const fs::path & path, std::string_view name ) {
266284 // TODO: Windows
267- // TODO: /cps/<name-like>
285+ // TODO: Mac
286+
268287 std::vector<std::string> split = utils::split (std::string{path}, " /" );
288+ // Sometimes the split() function puts an empty string
269289 if (split.back () == " " ) {
270290 split.pop_back ();
271291 }
292+ // If split ends in name, ex: /usr/lib/cps/name/
293+ if (split.back () == name) {
294+ split.pop_back ();
295+ }
296+ // If split ends in name/*, ex: /usr/lib/cps/name/*
297+ // Then drop both the */ and the name/
298+ if (*(split.end () - 2 ) == name) {
299+ split.pop_back ();
300+ split.pop_back ();
301+ }
272302 if (split.back () == " cps" ) {
273303 split.pop_back ();
274304 }
@@ -352,7 +382,7 @@ namespace search {
352382 // TODO: Windows…
353383 auto && split = utils::split (s, " /" );
354384 if (split[0 ] == " @prefix@" ) {
355- fs::path p = calculate_prefix (node->data .package .cps_path );
385+ fs::path p = calculate_prefix (node->data .package .cps_path , node-> data . package . name );
356386 for (auto it = split.begin () + 1 ; it != split.end (); ++it) {
357387 p /= *it;
358388 }
0 commit comments