aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/source/apps/projinfo.rst10
-rw-r--r--src/4D_api.cpp19
-rw-r--r--src/apps/projinfo.cpp14
-rw-r--r--src/filemanager.cpp63
-rw-r--r--src/filemanager.hpp5
-rwxr-xr-xtest/cli/testprojinfo8
6 files changed, 93 insertions, 26 deletions
diff --git a/docs/source/apps/projinfo.rst b/docs/source/apps/projinfo.rst
index 47deaaeb..f0a2ae08 100644
--- a/docs/source/apps/projinfo.rst
+++ b/docs/source/apps/projinfo.rst
@@ -26,7 +26,7 @@ Synopsis
| [--main-db-path path] [--aux-db-path path]*
| [--identify] [--3d]
| [--c-ify] [--single-line]
- | {object_definition} | {object_reference} | (-s {srs_def} -t {srs_def})
+ | --searchpaths | {object_definition} | {object_reference} | (-s {srs_def} -t {srs_def})
|
where {object_definition} or {srs_def} is
@@ -248,6 +248,14 @@ The following control parameters can appear in any order:
Output WKT or PROJJSON strings on a single line, instead of multiple intended lines by
default.
+.. option:: --searchpaths
+
+ .. versionadded:: 7.0
+
+ Output the directories into which PROJ resources will be looked for
+ (if not using C API such as :cpp:func:`proj_context_set_search_paths`
+ that will override them.
+
Examples
********
diff --git a/src/4D_api.cpp b/src/4D_api.cpp
index dabd44a0..91510c35 100644
--- a/src/4D_api.cpp
+++ b/src/4D_api.cpp
@@ -1484,23 +1484,10 @@ PJ_INFO proj_info (void) {
/* build search path string */
auto ctx = pj_get_default_ctx();
if (!ctx || ctx->search_paths.empty()) {
- // Env var mostly for testing purposes and being independent from
- // an existing installation
- const char* ignoreUserWritableDirectory =
- getenv("PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY");
- if( ignoreUserWritableDirectory == nullptr ||
- ignoreUserWritableDirectory[0] == '\0' ) {
- buf = path_append(buf,
- pj_context_get_user_writable_directory(ctx, false).c_str(),
- &buf_size);
- }
- const std::string envPROJ_LIB = NS_PROJ::FileManager::getProjLibEnvVar(ctx);
- buf = path_append(buf, envPROJ_LIB.empty() ? nullptr : envPROJ_LIB.c_str(), &buf_size);
-#ifdef PROJ_LIB
- if (envPROJ_LIB.empty()) {
- buf = path_append(buf, PROJ_LIB, &buf_size);
+ const auto searchpaths = pj_get_default_searchpaths(ctx);
+ for( const auto& path: searchpaths ) {
+ buf = path_append(buf, path.c_str(), &buf_size);
}
-#endif
} else {
for (const auto &path : ctx->search_paths) {
buf = path_append(buf, path.c_str(), &buf_size);
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp
index 27ea278a..360aafc4 100644
--- a/src/apps/projinfo.cpp
+++ b/src/apps/projinfo.cpp
@@ -98,7 +98,8 @@ static void usage() {
<< std::endl
<< " [--identify] [--3d]" << std::endl
<< " [--c-ify] [--single-line]" << std::endl
- << " {object_definition} | (-s {srs_def} -t {srs_def})"
+ << " --searchpaths | {object_definition} | (-s "
+ "{srs_def} -t {srs_def})"
<< std::endl;
std::cerr << std::endl;
std::cerr << "-o: formats is a comma separated combination of: "
@@ -1057,6 +1058,17 @@ int main(int argc, char **argv) {
outputOpt.strict = false;
} else if (ci_equal(arg, "--3d")) {
promoteTo3D = true;
+ } else if (ci_equal(arg, "--searchpaths")) {
+#ifdef _WIN32
+ constexpr char delim = ';';
+#else
+ constexpr char delim = ':';
+#endif
+ const auto paths = split(proj_info().searchpath, delim);
+ for (const auto &path : paths) {
+ std::cout << path << std::endl;
+ }
+ std::exit(0);
} else if (arg == "-?" || arg == "--help") {
usage();
} else if (arg[0] == '-') {
diff --git a/src/filemanager.cpp b/src/filemanager.cpp
index 005e734b..b38aeb5a 100644
--- a/src/filemanager.cpp
+++ b/src/filemanager.cpp
@@ -1196,9 +1196,8 @@ static bool is_rel_or_absolute_filename(const char *name) {
// ---------------------------------------------------------------------------
#ifdef _WIN32
-static const char *get_path_from_win32_projlib(PJ_CONTEXT *ctx,
- const char *name,
- std::string &out) {
+
+static std::string pj_get_win32_projlib() {
/* Check if proj.db lieves in a share/proj dir parallel to bin/proj.dll */
/* Based in
* https://stackoverflow.com/questions/9112893/how-to-get-path-to-executable-in-c-running-on-windows
@@ -1214,10 +1213,10 @@ static const char *get_path_from_win32_projlib(PJ_CONTEXT *ctx,
DWORD last_error = GetLastError();
if (result == 0) {
- return nullptr;
+ return std::string();
} else if (result == path_size - 1) {
if (ERROR_INSUFFICIENT_BUFFER != last_error) {
- return nullptr;
+ return std::string();
}
path_size = path_size * 2;
} else {
@@ -1227,18 +1226,33 @@ static const char *get_path_from_win32_projlib(PJ_CONTEXT *ctx,
// Now remove the program's name. It was (example)
// "C:\programs\gmt6\bin\gdal_translate.exe"
wout.resize(wcslen(wout.c_str()));
- out = NS_PROJ::WStringToUTF8(wout);
+ std::string out = NS_PROJ::WStringToUTF8(wout);
size_t k = out.size();
while (k > 0 && out[--k] != '\\') {
}
out.resize(k);
- out += "/../share/proj/";
+ out += "/../share/proj";
+ return out;
+}
+
+// ---------------------------------------------------------------------------
+
+static const char *get_path_from_win32_projlib(PJ_CONTEXT *ctx,
+ const char *name,
+ std::string &out) {
+
+ out = pj_get_win32_projlib();
+ if (out.empty()) {
+ return nullptr;
+ }
+ out += '/';
out += name;
return NS_PROJ::FileManager::exists(ctx, out.c_str()) ? out.c_str()
: nullptr;
}
+
#endif
/************************************************************************/
@@ -1402,6 +1416,41 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode,
}
/************************************************************************/
+/* pj_get_default_searchpaths() */
+/************************************************************************/
+
+std::vector<std::string> pj_get_default_searchpaths(PJ_CONTEXT *ctx) {
+ std::vector<std::string> ret;
+
+ // Env var mostly for testing purposes and being independent from
+ // an existing installation
+ const char *ignoreUserWritableDirectory =
+ getenv("PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY");
+ if (ignoreUserWritableDirectory == nullptr ||
+ ignoreUserWritableDirectory[0] == '\0') {
+ ret.push_back(pj_context_get_user_writable_directory(ctx, false));
+ }
+ const std::string envPROJ_LIB = NS_PROJ::FileManager::getProjLibEnvVar(ctx);
+ if (!envPROJ_LIB.empty()) {
+ ret.push_back(envPROJ_LIB);
+ }
+#ifdef _WIN32
+ if (envPROJ_LIB.empty()) {
+ const std::string win32Dir = pj_get_win32_projlib();
+ if (!win32Dir.empty()) {
+ ret.push_back(win32Dir);
+ }
+ }
+#endif
+#ifdef PROJ_LIB
+ if (envPROJ_LIB.empty()) {
+ ret.push_back(PROJ_LIB);
+ }
+#endif
+ return ret;
+}
+
+/************************************************************************/
/* pj_open_file_with_manager() */
/************************************************************************/
diff --git a/src/filemanager.hpp b/src/filemanager.hpp
index 554bd325..787af342 100644
--- a/src/filemanager.hpp
+++ b/src/filemanager.hpp
@@ -29,6 +29,8 @@
#define FILEMANAGER_HPP_INCLUDED
#include <memory>
+#include <string>
+#include <vector>
#include "proj.h"
#include "proj/util.hpp"
@@ -92,9 +94,10 @@ class File {
std::unique_ptr<File> pj_network_file_open(PJ_CONTEXT *ctx,
const char *filename);
-
NS_PROJ_END
+std::vector<std::string> pj_get_default_searchpaths(PJ_CONTEXT *ctx);
+
//! @endcond Doxygen_Suppress
#endif // FILEMANAGER_HPP_INCLUDED
diff --git a/test/cli/testprojinfo b/test/cli/testprojinfo
index b9c452fb..5cc425c5 100755
--- a/test/cli/testprojinfo
+++ b/test/cli/testprojinfo
@@ -175,6 +175,14 @@ echo 'Testing -k operation EPSG:8457 -o PROJ -q' >> ${OUT}
$EXE -k operation EPSG:8457 -o PROJ -q >>${OUT} 2>&1
echo "" >>${OUT}
+# Testing --searchpaths
+if ! $EXE --searchpaths > testprojinfo_out_searchpaths.txt; then
+ echo "--searchpaths failed"
+ exit 100
+fi
+# Hard to test content of testprojinfo_out_searchpaths.txt
+rm testprojinfo_out_searchpaths.txt
+
# do 'diff' with distribution results
echo "diff ${OUT} with testprojinfo_out.dist"
diff -u ${OUT} ${TEST_CLI_DIR}/testprojinfo_out.dist