From ea6245ea32f0b0ee414c22951b1f5dc4048782de Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 27 Jan 2020 18:14:56 +0100 Subject: projinfo: add --searchpaths switch --- docs/source/apps/projinfo.rst | 10 ++++++- src/4D_api.cpp | 19 +++---------- src/apps/projinfo.cpp | 14 +++++++++- src/filemanager.cpp | 63 ++++++++++++++++++++++++++++++++++++++----- src/filemanager.hpp | 5 +++- test/cli/testprojinfo | 8 ++++++ 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 /************************************************************************/ @@ -1401,6 +1415,41 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, } } +/************************************************************************/ +/* pj_get_default_searchpaths() */ +/************************************************************************/ + +std::vector pj_get_default_searchpaths(PJ_CONTEXT *ctx) { + std::vector 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 +#include +#include #include "proj.h" #include "proj/util.hpp" @@ -92,9 +94,10 @@ class File { std::unique_ptr pj_network_file_open(PJ_CONTEXT *ctx, const char *filename); - NS_PROJ_END +std::vector 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 -- cgit v1.2.3 From 15814256e2fbbc2702422fd3d09d3a0f6be60006 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 27 Jan 2020 20:38:40 +0100 Subject: projinfo: add --remote-data switch --- docs/source/apps/projinfo.rst | 10 +++++++++- scripts/reference_exported_symbols.txt | 1 + src/apps/projinfo.cpp | 23 ++++++++++++++++++++--- src/filemanager.cpp | 3 +++ src/proj_internal.h | 3 ++- test/cli/testprojinfo | 18 ++++++++++++++++++ 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/docs/source/apps/projinfo.rst b/docs/source/apps/projinfo.rst index f0a2ae08..0b65b8a0 100644 --- a/docs/source/apps/projinfo.rst +++ b/docs/source/apps/projinfo.rst @@ -26,7 +26,8 @@ Synopsis | [--main-db-path path] [--aux-db-path path]* | [--identify] [--3d] | [--c-ify] [--single-line] - | --searchpaths | {object_definition} | {object_reference} | (-s {srs_def} -t {srs_def}) + | --searchpaths | --remote-data | {object_definition} | + | {object_reference} | (-s {srs_def} -t {srs_def}) | where {object_definition} or {srs_def} is @@ -256,6 +257,13 @@ The following control parameters can appear in any order: (if not using C API such as :cpp:func:`proj_context_set_search_paths` that will override them. +.. option:: --remote-data + + .. versionadded:: 7.0 + + Display information regarding if :ref:`network` is enabled, and the + related URL. + Examples ******** diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt index 07043504..ee174da9 100644 --- a/scripts/reference_exported_symbols.txt +++ b/scripts/reference_exported_symbols.txt @@ -739,6 +739,7 @@ pj_cleanup_lock pj_clear_initcache pj_compare_datums pj_context_get_grid_cache_filename(projCtx_t*) +pj_context_get_url_endpoint(projCtx_t*) pj_context_get_user_writable_directory(projCtx_t*, bool) pj_context_is_network_enabled(projCtx_t*) pj_ctx_alloc diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 360aafc4..9cd9b2ee 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -98,9 +98,9 @@ static void usage() { << std::endl << " [--identify] [--3d]" << std::endl << " [--c-ify] [--single-line]" << std::endl - << " --searchpaths | {object_definition} | (-s " - "{srs_def} -t {srs_def})" - << std::endl; + << " --searchpaths | --remote-data | " + "{object_definition} |" + << " (-s {srs_def} -t {srs_def})" << std::endl; std::cerr << std::endl; std::cerr << "-o: formats is a comma separated combination of: " "all,default,PROJ,WKT_ALL,WKT2:2015,WKT2:2019,WKT1:GDAL," @@ -1069,6 +1069,23 @@ int main(int argc, char **argv) { std::cout << path << std::endl; } std::exit(0); + } else if (ci_equal(arg, "--remote-data")) { +#ifdef CURL_ENABLED + if (pj_context_is_network_enabled(nullptr)) { + std::cout << "Status: enabled" << std::endl; + std::cout << "URL: " << pj_context_get_url_endpoint(nullptr) + << std::endl; + } else { + std::cout << "Status: disabled" << std::endl; + std::cout << "Reason: not enabled in proj.ini or " + "PROJ_NETWORK=ON not specified" + << std::endl; + } +#else + std::cout << "Status: disabled" << std::endl; + std::cout << "Reason: build without Curl support" << std::endl; +#endif + std::exit(0); } else if (arg == "-?" || arg == "--help") { usage(); } else if (arg[0] == '-') { diff --git a/src/filemanager.cpp b/src/filemanager.cpp index b38aeb5a..9263e9fe 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -1595,6 +1595,9 @@ int pj_find_file(projCtx ctx, const char *short_filename, /************************************************************************/ std::string pj_context_get_url_endpoint(PJ_CONTEXT *ctx) { + if (ctx == nullptr) { + ctx = pj_get_default_ctx(); + } if (!ctx->endpoint.empty()) { return ctx->endpoint; } diff --git a/src/proj_internal.h b/src/proj_internal.h index a587c037..69d583fc 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -863,7 +863,8 @@ PJ *pj_create_argv_internal (PJ_CONTEXT *ctx, int argc, char **argv); // For use by projinfo bool PROJ_DLL pj_context_is_network_enabled(PJ_CONTEXT* ctx); -std::string pj_context_get_url_endpoint(PJ_CONTEXT* ctx); +// For use by projinfo +std::string PROJ_DLL pj_context_get_url_endpoint(PJ_CONTEXT* ctx); void pj_load_ini(PJ_CONTEXT* ctx); diff --git a/test/cli/testprojinfo b/test/cli/testprojinfo index 5cc425c5..4ec1bdbb 100755 --- a/test/cli/testprojinfo +++ b/test/cli/testprojinfo @@ -183,6 +183,24 @@ fi # Hard to test content of testprojinfo_out_searchpaths.txt rm testprojinfo_out_searchpaths.txt +# Testing --remote-data +if ! $EXE --remote-data > testprojinfo_out_remotedata.txt; then + echo "--remote-data failed" + exit 100 +fi +# Hard to test content of testprojinfo_out_remotedata.txt +rm testprojinfo_out_remotedata.txt + +# Testing --remote-data +export PROJ_NETWORK=ON +if ! $EXE --remote-data > testprojinfo_out_remotedata.txt; then + echo "--remote-data failed" + exit 100 +fi +# Hard to test content of testprojinfo_out_remotedata.txt +rm testprojinfo_out_remotedata.txt +unset PROJ_NETWORK + # do 'diff' with distribution results echo "diff ${OUT} with testprojinfo_out.dist" diff -u ${OUT} ${TEST_CLI_DIR}/testprojinfo_out.dist -- cgit v1.2.3