Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from OSGeo:master #91

Merged
merged 11 commits into from
Nov 26, 2024
26 changes: 6 additions & 20 deletions .github/workflows/cmake_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -625,26 +625,9 @@ jobs:
rm -rf /opt/homebrew/lib/node_modules # conflicts with node@18 from brew
brew update
brew outdated
# Attempt at fixing:
# => Pouring pkgconf--2.3.0_1.arm64_sonoma.bottle.tar.gz
# Error: The `brew link` step did not complete successfully
# The formula built, but is not symlinked into /opt/homebrew
# Could not symlink bin/pkg-config
# Target /opt/homebrew/bin/pkg-config
# is a symlink belonging to [email protected]. You can unlink it:
# brew unlink [email protected]
#
# To force the link and overwrite all conflicting files:
# brew link --overwrite pkgconf
#
# To list all files that would be deleted:
# brew link --overwrite pkgconf --dry-run
#
# Possible conflicting files are:
# /opt/homebrew/bin/pkg-config -> /opt/homebrew/Cellar/[email protected]/0.29.2_3/bin/pkg-config
# /opt/homebrew/share/aclocal/pkg.m4 -> /opt/homebrew/Cellar/[email protected]/0.29.2_3/share/aclocal/pkg.m4
# /opt/homebrew/share/man/man1/pkg-config.1 -> /opt/homebrew/Cellar/[email protected]/0.29.2_3/share/man/man1/pkg-config.1
rm -f /opt/homebrew/bin/pkg-config /opt/homebrew/share/aclocal/pkg.m4 /opt/homebrew/share/man/man1/pkg-config.1
mv /opt/homebrew/bin/pkg-config /opt/homebrew/bin/pkg-config.old
mv /opt/homebrew/share/aclocal/pkg.m4 /opt/homebrew/share/aclocal/pkg.m4.old
mv /opt/homebrew/share/man/man1/pkg-config.1 /opt/homebrew/share/man/man1/pkg-config.1.old
brew install --overwrite [email protected] [email protected]
brew install postgresql || brew link postgresql
brew install pkg-config freexl libxml2 libspatialite geos proj libgeotiff openjpeg giflib libaec postgis poppler doxygen unixodbc jpeg-turbo aom jpeg-xl libheif libarchive libkml boost
Expand All @@ -654,6 +637,9 @@ jobs:
brew uninstall --ignore-dependencies gdal
# Workaround for https://github.com/Homebrew/homebrew-core/pull/170959#issuecomment-2379606442
sed -i .bak 's/hdf5_hl;hdf5;/hdf5_hl-shared;hdf5-shared;/g' "$(brew --prefix netcdf)/lib/cmake/netCDF/netCDFTargets.cmake"
mv /opt/homebrew/bin/pkg-config.old /opt/homebrew/bin/pkg-config
mv /opt/homebrew/share/aclocal/pkg.m4.old /opt/homebrew/share/aclocal/pkg.m4
mv /opt/homebrew/share/man/man1/pkg-config.1.old /opt/homebrew/share/man/man1/pkg-config.1
- name: Configure ccache
run: |
echo CCACHE_BASEDIR=$PWD >> ${GITHUB_ENV}
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/code_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,19 @@ jobs:
xmllint --schema ./frmts/nitf/data/nitf_spec.xsd ./frmts/nitf/data/nitf_spec.xml --noout
xmllint --schema ./ogr/ogrsf_frmts/vdv/data/vdv452.xsd ./ogr/ogrsf_frmts/vdv/data/vdv452.xml --noout
xmllint --schema ./ogr/ogrsf_frmts/gmlas/data/gmlasconf.xsd ./ogr/ogrsf_frmts/gmlas/data/gmlasconf.xml --noout

check-config-options:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- name: Set up Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: 3.8
- name: Check cmakelist
run: |
python scripts/collect_config_options.py
git diff
git diff --quiet || (echo "You need to run scripts/collect_config_options to update port/cpl_known_config_options.h" && /bin/false)

70 changes: 67 additions & 3 deletions apps/commonutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,84 @@ void EarlySetConfigOptions(int argc, char **argv)
// OGRRegisterAll(), but we can't call GDALGeneralCmdLineProcessor() or
// OGRGeneralCmdLineProcessor(), because it needs the drivers to be
// registered for the --format or --formats options.

// Start with --debug, so that "my_command --config UNKNOWN_CONFIG_OPTION --debug on"
// detects and warns about a unknown config option.
for (int i = 1; i < argc; i++)
{
if (EQUAL(argv[i], "--config") && i + 2 < argc)
if (EQUAL(argv[i], "--config") && i + 1 < argc)
{
CPLSetConfigOption(argv[i + 1], argv[i + 2]);
const char *pszArg = argv[i + 1];
if (strchr(pszArg, '=') != nullptr)
{
char *pszKey = nullptr;
const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
if (pszKey && EQUAL(pszKey, "CPL_DEBUG") && pszValue)
{
CPLSetConfigOption(pszKey, pszValue);
}
CPLFree(pszKey);
++i;
}
else
{
if (i + 2 >= argc)
{
CPLError(CE_Failure, CPLE_AppDefined,
"--config option given without a key and value "
"argument.");
return;
}

i += 2;
if (EQUAL(argv[i + 1], "CPL_DEBUG"))
{
CPLSetConfigOption(argv[i + 1], argv[i + 2]);
}

i += 2;
}
}
else if (EQUAL(argv[i], "--debug") && i + 1 < argc)
{
CPLSetConfigOption("CPL_DEBUG", argv[i + 1]);
i += 1;
}
}
for (int i = 1; i < argc; i++)
{
if (EQUAL(argv[i], "--config") && i + 1 < argc)
{
const char *pszArg = argv[i + 1];
if (strchr(pszArg, '=') != nullptr)
{
char *pszKey = nullptr;
const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
if (pszKey && !EQUAL(pszKey, "CPL_DEBUG") && pszValue)
{
CPLSetConfigOption(pszKey, pszValue);
}
CPLFree(pszKey);
++i;
}
else
{
if (i + 2 >= argc)
{
CPLError(CE_Failure, CPLE_AppDefined,
"--config option given without a key and value "
"argument.");
return;
}

if (!EQUAL(argv[i + 1], "CPL_DEBUG"))
{
CPLSetConfigOption(argv[i + 1], argv[i + 2]);
}

i += 2;
}
}
}
}

/************************************************************************/
Expand Down
26 changes: 18 additions & 8 deletions autotest/cpp/test_cpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,16 +1293,26 @@ TEST_F(test_cpl, CPLExpandTilde)
CPLSetConfigOption("HOME", nullptr);
}

TEST_F(test_cpl, CPLString_constructors)
TEST_F(test_cpl, CPLDeclareKnownConfigOption)
{
// CPLString(std::string) constructor
ASSERT_STREQ(CPLString(std::string("abc")).c_str(), "abc");

// CPLString(const char*) constructor
ASSERT_STREQ(CPLString("abc").c_str(), "abc");
CPLConfigOptionSetter oDebugSetter("CPL_DEBUG", "ON", false);
{
CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler);
CPLErrorReset();
CPLConfigOptionSetter oDeclaredConfigOptionSetter("UNDECLARED_OPTION",
"FOO", false);
EXPECT_STREQ(CPLGetLastErrorMsg(),
"Unknown configuration option 'UNDECLARED_OPTION'.");
}
{
CPLDeclareKnownConfigOption("DECLARED_OPTION", nullptr);

// CPLString(const char*, n) constructor
ASSERT_STREQ(CPLString("abc", 1).c_str(), "a");
CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler);
CPLErrorReset();
CPLConfigOptionSetter oDeclaredConfigOptionSetter("DECLARED_OPTION",
"FOO", false);
EXPECT_STREQ(CPLGetLastErrorMsg(), "");
}
}

TEST_F(test_cpl, CPLErrorSetState)
Expand Down
6 changes: 6 additions & 0 deletions autotest/pyscripts/test_gdal2tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def script_path():

def test_gdal2tiles_help(script_path):

if gdaltest.is_travis_branch("sanitize"):
pytest.skip("fails on sanitize for unknown reason")

assert "ERROR" not in test_py_scripts.run_py_script(
script_path, "gdal2tiles", "--help"
)
Expand All @@ -60,6 +63,9 @@ def test_gdal2tiles_help(script_path):

def test_gdal2tiles_version(script_path):

if gdaltest.is_travis_branch("sanitize"):
pytest.skip("fails on sanitize for unknown reason")

assert "ERROR" not in test_py_scripts.run_py_script(
script_path, "gdal2tiles", "--version"
)
Expand Down
2 changes: 1 addition & 1 deletion doc/source/programs/gdal_sieve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ Additional details on the algorithm are available in the :cpp:func:`GDALSieveFil

.. note::

gdal_retile is a Python utility, and is only available if GDAL Python bindings are available.
gdal_sieve is a Python utility, and is only available if GDAL Python bindings are available.
14 changes: 14 additions & 0 deletions doc/source/user/configoptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ they can be limited to only the current thread with
For boolean options, the values YES, TRUE or ON can be used to turn the option on;
NO, FALSE or OFF to turn it off.

How to detect if the passed configuration option is known to GDAL
-----------------------------------------------------------------

By default GDAL will not warn if the name of the configuration option is unknown.
Starting with GDAL 3.11, if you set the :config:`CPL_DEBUG` configuration
option to ``ON`` (or any value that is not ``OFF``, ``FALSE``, ``NO``), a GDAL
warning will be emitted for unknown configuration options.

.. code-block:: shell

$ gdalinfo --config BAD_OPTION=TEST --debug on --version
Warning 1: CPLSetConfigOption() called with key=BAD_OPTION, which is unknown to GDAL
[...]


.. _gdal_configuration_file:

Expand Down
65 changes: 62 additions & 3 deletions gcore/gdal_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3484,6 +3484,64 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
/* ==================================================================== */
/* Loop over all arguments. */
/* ==================================================================== */

// Start with --debug, so that "my_command --config UNKNOWN_CONFIG_OPTION --debug on"
// detects and warns about a unknown config option.
for (iArg = 1; iArg < nArgc; iArg++)
{
if (EQUAL(papszArgv[iArg], "--config") && iArg + 2 < nArgc &&
EQUAL(papszArgv[iArg + 1], "CPL_DEBUG"))
{
if (iArg + 1 >= nArgc)
{
CPLError(CE_Failure, CPLE_AppDefined,
"--config option given without a key=value argument.");
return -1;
}

const char *pszArg = papszArgv[iArg + 1];
if (strchr(pszArg, '=') != nullptr)
{
char *pszKey = nullptr;
const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
if (pszKey && !EQUAL(pszKey, "CPL_DEBUG") && pszValue)
{
CPLSetConfigOption(pszKey, pszValue);
}
CPLFree(pszKey);
++iArg;
}
else
{
if (iArg + 2 >= nArgc)
{
CPLError(CE_Failure, CPLE_AppDefined,
"--config option given without a key and value "
"argument.");
return -1;
}

if (!EQUAL(papszArgv[iArg + 1], "CPL_DEBUG"))
CPLSetConfigOption(papszArgv[iArg + 1],
papszArgv[iArg + 2]);

iArg += 2;
}
}
else if (EQUAL(papszArgv[iArg], "--debug"))
{
if (iArg + 1 >= nArgc)
{
CPLError(CE_Failure, CPLE_AppDefined,
"--debug option given without debug level.");
return -1;
}

CPLSetConfigOption("CPL_DEBUG", papszArgv[iArg + 1]);
iArg += 1;
}
}

for (iArg = 1; iArg < nArgc; iArg++)
{
/* --------------------------------------------------------------------
Expand Down Expand Up @@ -3538,7 +3596,7 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
{
char *pszKey = nullptr;
const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
if (pszKey && pszValue)
if (pszKey && !EQUAL(pszKey, "CPL_DEBUG") && pszValue)
{
CPLSetConfigOption(pszKey, pszValue);
}
Expand All @@ -3555,7 +3613,9 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
return -1;
}

CPLSetConfigOption(papszArgv[iArg + 1], papszArgv[iArg + 2]);
if (!EQUAL(papszArgv[iArg + 1], "CPL_DEBUG"))
CPLSetConfigOption(papszArgv[iArg + 1],
papszArgv[iArg + 2]);

iArg += 2;
}
Expand Down Expand Up @@ -3631,7 +3691,6 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv,
return -1;
}

CPLSetConfigOption("CPL_DEBUG", papszArgv[iArg + 1]);
iArg += 1;
}

Expand Down
3 changes: 1 addition & 2 deletions gcore/gdalabstractbandblockcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ void GDALAbstractBandBlockCache::StartDirtyBlockFlushingLog()
m_nInitialDirtyBlocksInFlushCache = 0;
if (m_nDirtyBlocks > 0 && CPLIsDefaultErrorHandlerAndCatchDebug())
{
const char *pszDebug = CPLGetConfigOption("CPL_DEBUG", nullptr);
if (pszDebug && (EQUAL(pszDebug, "ON") || EQUAL(pszDebug, "GDAL")) &&
if (CPLIsDebugEnabled() &&
CPLGetConfigOption("GDAL_REPORT_DIRTY_BLOCK_FLUSHING", nullptr) ==
nullptr)
{
Expand Down
3 changes: 1 addition & 2 deletions ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,7 @@ void GMLASReader::Context::Dump() const
CPLDebug("GMLAS", "Context");
CPLDebug("GMLAS", " m_nLevel = %d", m_nLevel);
CPLDebug("GMLAS", " m_poFeature = %p", m_poFeature);
const char *pszDebug = CPLGetConfigOption("CPL_DEBUG", "OFF");
if (EQUAL(pszDebug, "ON") || EQUAL(pszDebug, "GMLAS"))
if (CPLIsDebugEnabled())
{
if (m_poFeature)
m_poFeature->DumpReadable(stderr);
Expand Down
Loading
Loading