From 5b441c8f3d7600e833d9bd1e7bd256088d1325b7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 10 Nov 2024 00:03:02 +0100 Subject: [PATCH 1/9] Add a script to detect known configuration options, add this file, CI check to verify it is up-to-date --- .github/workflows/code_checks.yml | 16 + port/cpl_known_config_options.h | 1053 +++++++++++++++++++++++++++++ scripts/collect_config_options.py | 161 +++++ 3 files changed, 1230 insertions(+) create mode 100644 port/cpl_known_config_options.h create mode 100755 scripts/collect_config_options.py diff --git a/.github/workflows/code_checks.yml b/.github/workflows/code_checks.yml index 3b2fbf0ee127..629a7d81d6dc 100644 --- a/.github/workflows/code_checks.yml +++ b/.github/workflows/code_checks.yml @@ -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) + diff --git a/port/cpl_known_config_options.h b/port/cpl_known_config_options.h new file mode 100644 index 000000000000..ff5f0e714474 --- /dev/null +++ b/port/cpl_known_config_options.h @@ -0,0 +1,1053 @@ +// This file was automatically generated by collect_config_options.py +// DO NOT EDIT + +// clang-format off +constexpr static const char* const apszKnownConfigOptions[] = +{ + "ADRG_SIMULATE_MULTI_IMG", // from adrgdataset.cpp + "ALLOW_GPKG_ZOOM_OTHER_EXTENSION", // from ogrgeopackagedatasource.cpp + "ALLOW_OGR_SQL_FUNCTIONS_FROM_TRIGGER_AND_VIEW", // from ogrsqlitedatasource.cpp + "ALLOW_VIRTUAL_OGR_FROM_TRIGGER_AND_VIEW", // from ogrsqlitevirtualogr.cpp + "ALPHA_OVERVIEW", // from gt_overview.cpp + "AMIGOCLOUD_API_KEY", // from ogramigoclouddatasource.cpp + "AMIGOCLOUD_API_URL", // from ogramigoclouddatasource.cpp + "AMIGOCLOUD_MAX_CHUNK_SIZE", // from ogramigocloudtablelayer.cpp + "ATTRIBUTES_SKIP", // from ogrgeojsondriver.cpp + "AWS_ACCESS_KEY_ID", // from cpl_aws.cpp + "AWS_CONFIG_FILE", // from cpl_aws.cpp + "AWS_CONTAINER_AUTHORIZATION_TOKEN", // from cpl_aws.cpp + "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", // from cpl_aws.cpp + "AWS_CONTAINER_CREDENTIALS_FULL_URI", // from cpl_aws.cpp + "AWS_DEFAULT_PROFILE", // from cpl_aws.cpp + "AWS_DEFAULT_REGION", // from cpl_aws.cpp + "AWS_HTTPS", // from cpl_aws.cpp + "AWS_MAX_KEYS", // from cpl_vsil_s3.cpp + "AWS_NO_SIGN_REQUEST", // from cpl_aws.cpp + "AWS_PROFILE", // from cpl_aws.cpp + "AWS_REGION", // from cpl_aws.cpp + "AWS_REQUEST_PAYER", // from cpl_aws.cpp + "AWS_ROLE_ARN", // from cpl_aws.cpp + "AWS_ROLE_SESSION_NAME", // from cpl_aws.cpp + "AWS_S3_ENDPOINT", // from cpl_aws.cpp + "AWS_SECRET_ACCESS_KEY", // from cpl_aws.cpp + "AWS_SESSION_TOKEN", // from cpl_aws.cpp + "AWS_STS_ENDPOINT", // from cpl_aws.cpp + "AWS_STS_REGION", // from cpl_aws.cpp + "AWS_STS_REGIONAL_ENDPOINTS", // from cpl_aws.cpp + "AWS_TIMESTAMP", // from cpl_aws.cpp + "AWS_VIRTUAL_HOSTING", // from cpl_aws.cpp + "AWS_WEB_IDENTITY_TOKEN_FILE", // from cpl_aws.cpp + "AZURE_AUTHORITY_HOST", // from cpl_azure.cpp + "AZURE_CLIENT_ID", // from cpl_azure.cpp + "AZURE_CONFIG_DIR", // from cpl_azure.cpp + "AZURE_FEDERATED_TOKEN_FILE", // from cpl_azure.cpp + "AZURE_IMDS_CLIENT_ID", // from cpl_azure.cpp + "AZURE_IMDS_MSI_RES_ID", // from cpl_azure.cpp + "AZURE_IMDS_OBJECT_ID", // from cpl_azure.cpp + "AZURE_MAX_RESULTS", // from cpl_vsil_adls.cpp, cpl_vsil_az.cpp + "AZURE_NO_SIGN_REQUEST", // from cpl_azure.cpp + "AZURE_SAS", // from cpl_azure.cpp, cpl_vsil_az.cpp + "AZURE_STORAGE_ACCESS_KEY", // from cpl_azure.cpp + "AZURE_STORAGE_ACCESS_TOKEN", // from cpl_azure.cpp + "AZURE_STORAGE_ACCOUNT", // from cpl_azure.cpp + "AZURE_STORAGE_CONNECTION_STRING", // from cpl_azure.cpp + "AZURE_STORAGE_SAS_TOKEN", // from cpl_azure.cpp + "AZURE_TENANT_ID", // from cpl_azure.cpp + "BAG_GEOREF_MD_BLOCKXSIZE", // from bagdataset.cpp + "BAG_GEOREF_MD_BLOCKYSIZE", // from bagdataset.cpp + "BASISU_MAX_FILE_SIZE", // from basisudataset.cpp + "BIGTIFF_OVERVIEW", // from gt_overview.cpp + "BLACKLISTED_OPENCL_VENDOR", // from gdalwarpkernel_opencl.cpp + "BLOCKXSIZE", // from netcdfdataset.cpp + "BLOCKYSIZE", // from netcdfdataset.cpp + "BSB_DISABLE_INDEX", // from bsb_read.c + "BSB_IGNORE_LINENUMBERS", // from bsb_read.c + "BSB_PALETTE", // from bsb_read.c + "CARTO_API_KEY", // from ogrcartodatasource.cpp + "CARTO_API_URL", // from ogrcartodatasource.cpp + "CARTO_HTTPS", // from ogrcartodatasource.cpp + "CARTO_MAX_CHUNK_SIZE", // from ogrcartotablelayer.cpp + "CARTODB_API_KEY", // from ogrcartodatasource.cpp + "CARTODB_API_URL", // from ogrcartodatasource.cpp + "CARTODB_HTTPS", // from ogrcartodatasource.cpp + "CARTODB_MAX_CHUNK_SIZE", // from ogrcartotablelayer.cpp + "CENTER_LONG", // from ogrct.cpp + "CHECK_DISK_FREE_SPACE", // from gtiffdataset_write.cpp + "CHECK_WITH_INVERT_PROJ", // from gdaltransformer.cpp, gdalwarp_lib.cpp, gdalwarpoperation.cpp, ogrct.cpp + "COG_DELETE_TEMP_FILES", // from cogdriver.cpp + "COG_TMP_COMPRESSION", // from cogdriver.cpp + "COMPRESS_GEOM", // from ogrsqlitelayer.cpp + "COMPRESS_OVERVIEW", // from gt_overview.cpp + "CONVERT_YCBCR_TO_RGB", // from ecwdataset.cpp, geotiff.cpp, gtiffdataset.cpp, gtiffdataset_read.cpp, gtiffdataset_write.cpp, gtiffrasterband.cpp + "CPL_ACCUM_ERROR_MSG", // from cpl_error.cpp + "CPL_ALLOW_VSISTDIN", // from cpl_vsil_stdin.cpp, gdalsrsinfo.cpp + "CPL_AWS_AUTODETECT_EC2", // from cpl_aws.cpp + "CPL_AWS_CHECK_HYPERVISOR_UUID", // from cpl_aws.cpp + "CPL_AWS_CREDENTIALS_FILE", // from cpl_aws.cpp + "CPL_AWS_EC2_API_ROOT_URL", // from cpl_aws.cpp + "CPL_AWS_ROOT_DIR", // from cpl_aws.cpp + "CPL_AWS_SSO_ENDPOINT", // from cpl_aws.cpp + "CPL_AWS_STS_ROOT_URL", // from cpl_aws.cpp + "CPL_AWS_WEB_IDENTITY_ENABLE", // from cpl_aws.cpp + "CPL_AZURE_ENDPOINT", // from cpl_azure.cpp + "CPL_AZURE_TIMESTAMP", // from cpl_azure.cpp + "CPL_AZURE_USE_HTTPS", // from cpl_azure.cpp + "CPL_AZURE_VM_API_ROOT_URL", // from cpl_azure.cpp + "CPL_CREATE_ZIP64", // from cpl_minizip_zip.cpp + "CPL_CURL_ENABLE_VSIMEM", // from cpl_http.cpp, gdalhttp.cpp, ogrwfsjoinlayer.cpp, ogrwfslayer.cpp + "CPL_CURL_GZIP", // from cpl_http.cpp, cpl_vsil_curl_streaming.cpp + "CPL_CURL_IGNORE_ERROR", // from cpl_http.cpp + "CPL_CURL_VERBOSE", // from cpl_http.cpp, cpl_vsil_curl.cpp + "CPL_CURL_VERBOSE_DATA_IN", // from cpl_http.cpp + "CPL_CURL_VSIMEM_PRINT_HEADERS", // from cpl_http.cpp + "CPL_DEBUG", // from cpl_conv.cpp, cpl_error.cpp, cpl_http.cpp, gdalabstractbandblockcache.cpp, gdalinfo_bin.cpp, gdalsrsinfo.cpp, gdalwarp_bin.cpp, ogrgmlasreader.cpp + "CPL_ENABLE_USERFAULTFD", // from cpl_userfaultfd.cpp + "CPL_ERROR_SEPARATOR", // from cpl_error.cpp + "CPL_GCE_CHECK_LOCAL_FILES", // from cpl_google_cloud.cpp + "CPL_GCE_CREDENTIALS_URL", // from cpl_google_oauth2.cpp + "CPL_GCE_SKIP", // from cpl_google_cloud.cpp, eedacommon.cpp + "CPL_GS_CREDENTIALS_FILE", // from cpl_google_cloud.cpp + "CPL_GS_ENDPOINT", // from cpl_google_cloud.cpp + "CPL_GS_TIMESTAMP", // from cpl_google_cloud.cpp + "CPL_LOG", // from cpl_error.cpp + "CPL_LOG_APPEND", // from cpl_error.cpp + "CPL_LOG_ERRORS", // from cpl_error.cpp + "CPL_MACHINE_IS_GCE", // from cpl_google_cloud.cpp + "CPL_MAX_ERROR_REPORTS", // from cpl_error.cpp + "CPL_MINIXML_RELAXED", // from cpl_minixml.cpp + "CPL_OPENSSL_INIT_ENABLED", // from cpl_http.cpp + "CPL_OSS_TIMESTAMP", // from cpl_alibaba_oss.cpp + "CPL_RSA_SHA256_Sign", // from cpl_sha256.cpp + "CPL_SOZIP_ENABLED", // from cpl_minizip_zip.cpp + "CPL_SOZIP_MIN_FILE_SIZE", // from cpl_minizip_zip.cpp + "CPL_TIMESTAMP", // from cpl_error.cpp + "CPL_TMPDIR", // from cogdriver.cpp, cpl_path.cpp, gdalwmscache.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "CPL_VSIAZ_UNLINK_BATCH_SIZE", // from cpl_vsil_az.cpp + "CPL_VSIGS_UNLINK_BATCH_SIZE", // from cpl_vsil_gs.cpp + "CPL_VSIL_CURL_ADVISE_READ_TOTAL_BYTES_LIMIT", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_ALLOWED_EXTENSIONS", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_ALLOWED_FILENAME", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_AUTHORIZATION_HEADER_ALLOWED_IF_REDIRECT", // from cpl_http.cpp, cpl_vsil_curl.cpp + "CPL_VSIL_CURL_CACHE_SIZE", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_CHUNK_SIZE", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_HONOR_CACHE_CONTROL", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_IGNORE_GLACIER_STORAGE", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_IGNORE_STORAGE_CLASSES", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_MAX_RANGES", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_NON_CACHED", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_SLOW_GET_SIZE", // from cpl_vsil_curl.cpp, cpl_vsil_curl_streaming.cpp + "CPL_VSIL_CURL_STREMAING_SIMULATED_CURL_ERROR", // from cpl_vsil_curl_streaming.cpp + "CPL_VSIL_CURL_USE_HEAD", // from cpl_vsil_curl.cpp + "CPL_VSIL_CURL_USE_S3_REDIRECT", // from cpl_vsil_curl.cpp + "CPL_VSIL_DEFLATE_CHUNK_SIZE", // from cpl_minizip_zip.cpp, cpl_vsil_gzip.cpp + "CPL_VSIL_GZIP_SAVE_INFO", // from cpl_vsil_gzip.cpp + "CPL_VSIL_GZIP_WRITE_PROPERTIES", // from cpl_vsil_gzip.cpp + "CPL_VSIL_NETWORK_STATS_ENABLED", // from cpl_vsil_curl.cpp + "CPL_VSIL_SHOW_NETWORK_STATS", // from cpl_vsil_curl.cpp + "CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE", // from cpl_vsil_s3.cpp, ogrgeopackagedatasource.cpp, ogrlibkmldatasource.cpp, ogrsqlitedatasource.cpp + "CPL_VSIL_ZIP_ALLOWED_EXTENSIONS", // from cpl_vsil_gzip.cpp + "CPL_VSIS3_CREATE_DIR_OBJECT", // from cpl_vsil_s3.cpp + "CPL_VSIS3_LIST_UPLOADS_MAX", // from cpl_vsil_s3.cpp + "CPL_VSIS3_UNLINK_BATCH_SIZE", // from cpl_vsil_s3.cpp + "CPL_VSIS3_USE_BASE_RMDIR_RECURSIVE", // from cpl_vsil_s3.cpp + "CPL_VSISTDIN_BUFFER_LIMIT", // from cpl_vsil_stdin.cpp + "CPL_VSISTDIN_FILE", // from cpl_vsil_stdin.cpp + "CPL_VSISTDIN_FILE_CLOSE", // from cpl_vsil_stdin.cpp + "CPL_VSISTDIN_RESET_POSITION", // from cpl_vsil_stdin.cpp + "CPL_ZIP_ENCODING", // from cpl_minizip_unzip.cpp, cpl_minizip_zip.cpp + "CREATE_GEOMETRY_COLUMNS", // from ogrgeopackagedatasource.cpp + "CREATE_RASTER_TABLES", // from ogrgeopackagedatasource.cpp + "CREATE_TRIGGERS", // from ogrgeopackagedatasource.cpp + "CURL_CA_BUNDLE", // from cpl_http.cpp + "DGN_LINK_FORMAT", // from ogrdgnlayer.cpp + "DISABLE_OPEN_REAL_NETCDF_FILES", // from netcdfdataset.cpp, netcdfdrivercore.cpp + "DRIVER_WISHED", // from test_ogrsf.cpp + "DTED_APPLY_PIXEL_IS_POINT", // from dteddataset.cpp + "DTED_VERIFY_CHECKSUM", // from dteddataset.cpp + "DUMP_JP2_BOXES", // from gdaljp2metadata.cpp + "DWG_ALL_ATTRIBUTES", // from ogrdwgdatasource.cpp + "DWG_ATTRIBUTES", // from ogrdwgdatasource.cpp + "DWG_CLOSED_LINE_AS_POLYGON", // from ogrdwgdatasource.cpp + "DWG_ENCODING", // from ogrdwgdatasource.cpp + "DWG_INLINE_BLOCKS", // from ogrdwgdatasource.cpp + "DWG_MERGE_BLOCK_GEOMETRIES", // from ogrdwg_blockmap.cpp + "DXF_3D_EXTENSIBLE_MODE", // from ogrdxfdatasource.cpp + "DXF_CLOSED_LINE_AS_POLYGON", // from ogrdxfdatasource.cpp + "DXF_ENCODING", // from ogrdxfdatasource.cpp + "DXF_FEATURE_LIMIT_PER_BLOCK", // from ogrdxf_blockmap.cpp + "DXF_HATCH_TOLERANCE", // from ogrdxfdatasource.cpp + "DXF_HEADER_ONLY", // from ogrdxfdatasource.cpp + "DXF_INCLUDE_RAW_CODE_VALUES", // from ogrdxfdatasource.cpp + "DXF_INLINE_BLOCKS", // from ogrdxfdatasource.cpp + "DXF_MAX_BSPLINE_CONTROL_POINTS", // from ogrdxf_leader.cpp + "DXF_MERGE_BLOCK_GEOMETRIES", // from ogrdxfdatasource.cpp + "DXF_TRANSLATE_ESCAPE_SEQUENCES", // from ogrdxfdatasource.cpp + "DXF_WRITE_HATCH", // from ogrdxfwriterlayer.cpp + "ECW_ALWAYS_UPWARD", // from ecwdataset.cpp + "ECW_AUTOGEN_J2I", // from ecwdataset.cpp + "ECW_CACHE_MAXMEM", // from ecwdataset.cpp + "ECW_CACHE_MAXOPEN", // from ecwdataset.cpp + "ECW_CHECK_CORRECT_DECODING", // from ecwdataset.cpp + "ECW_CLEVER", // from ecwdataset.cpp + "ECW_DO_NOT_RESOLVE_DATUM_PROJECTION", // from ecwdataset.cpp + "ECW_ENCODE_COMPANY", // from ecwcreatecopy.cpp + "ECW_ENCODE_KEY", // from ecwcreatecopy.cpp, pdfcreatecopy.cpp + "ECW_FORCE_FILE_REOPEN", // from ecwdataset.cpp + "ECW_LARGE_OK", // from ecwcreatecopy.cpp + "ECW_OPTIMIZE_USE_NEAREST_NEIGHBOUR", // from ecwdataset.cpp + "ECW_RESILIENT_DECODING", // from ecwdataset.cpp + "ECW_TEXTURE_DITHER", // from ecwdataset.cpp + "ECWP_BLOCKING_TIME_MS", // from ecwdataset.cpp + "ECWP_CACHE_LOCATION", // from ecwdataset.cpp + "ECWP_CACHE_SIZE_MB", // from ecwdataset.cpp + "ECWP_REFRESH_TIME_MS", // from ecwdataset.cpp + "EEDA_BEARER", // from eedacommon.cpp + "EEDA_BEARER_FILE", // from eedacommon.cpp + "EEDA_CLIENT_EMAIL", // from eedacommon.cpp + "EEDA_FORCE_BLOCK_SIZE", // from eedaidataset.cpp + "EEDA_PAGE_SIZE", // from eedadataset.cpp + "EEDA_PRIVATE_KEY", // from eedacommon.cpp + "EEDA_PRIVATE_KEY_FILE", // from eedacommon.cpp + "EEDA_URL", // from eedadataset.cpp, eedaidataset.cpp + "ES_ADD_PRETTY", // from ogrelasticlayer.cpp + "ES_BULK", // from ogrelasticdatasource.cpp + "ES_FORWARD_HTTP_HEADERS_FROM_ENV", // from ogrelasticdatasource.cpp + "ES_META", // from ogrelasticdatasource.cpp + "ES_OVERWRITE", // from ogrelasticdatasource.cpp + "ES_WRITEMAP", // from ogrelasticdatasource.cpp + "ESRI_XML_PAM", // from gtiffdataset.cpp, gtiffdataset_write.cpp + "FGDB_BULK_LOAD", // from FGdbLayer.cpp + "FGDB_PER_LAYER_COPYING_TRANSACTION", // from FGdbDatasource.cpp + "FGDB_RESYNC_THRESHOLD", // from FGdbLayer.cpp + "FGDB_SIMUL_FAIL", // from FGdbDriver.cpp + "FGDB_SIMUL_FAIL_REOPEN", // from FGdbDatasource.cpp + "FGDB_STRING_WIDTH", // from FGdbUtils.cpp + "FILEGDB_DISABLE_SPARSE_PAGES", // from FGdbLayer.cpp + "FORCE_BLOCKSIZE", // from hfaopen.cpp + "FUSIL_SRC_DIR", // from ogropenfilegdbdriver.cpp + "GDAL_ALLOW_LARGE_LIBJPEG_MEM_ALLOC", // from JPEG_band.cpp, jpgdataset.cpp + "GDAL_BAG_BLOCK_SIZE", // from bagdataset.cpp + "GDAL_BAG_MAX_SIZE_VARRES_MAP", // from bagdataset.cpp + "GDAL_BAND_BLOCK_CACHE", // from gdalrasterband.cpp + "GDAL_CACHEMAX", // from gdalrasterblock.cpp, nearblack_bin.cpp + "GDAL_CONFIG_FILE", // from cpl_conv.cpp + "GDAL_CURL_CA_BUNDLE", // from cpl_http.cpp + "GDAL_DAAS_ACCESS_TOKEN", // from daasdataset.cpp + "GDAL_DAAS_API_KEY", // from daasdataset.cpp + "GDAL_DAAS_AUTH_URL", // from daasdataset.cpp + "GDAL_DAAS_AUTHORIZATION", // from daasdataset.cpp + "GDAL_DAAS_CLIENT_ID", // from daasdataset.cpp + "GDAL_DAAS_GET_BUFFER_URL", // from daasdataset.cpp + "GDAL_DAAS_INITIAL_RETRY_DELAY", // from daasdataset.cpp + "GDAL_DAAS_PERFORM_AUTH", // from daasdataset.cpp + "GDAL_DAAS_SERVER_BYTE_LIMIT", // from daasdataset.cpp + "GDAL_DAAS_X_FORWARDED_USER", // from daasdataset.cpp + "GDAL_DATA", // from cpl_csv.cpp, cpl_findfile.cpp, gdaldrivermanager.cpp + "GDAL_DEBUG_BLOCK_CACHE", // from gdalrasterblock.cpp + "GDAL_DEBUG_PROCESS_DYNAMIC_METADATA", // from gdaljp2metadata.cpp + "GDAL_DEFAULT_CREATE_COPY", // from gdaldriver.cpp + "GDAL_DEFAULT_WMS_CACHE_PATH", // from gdalwmscache.cpp + "GDAL_DISABLE_CPLLOCALEC", // from cpl_conv.cpp + "GDAL_DISABLE_READDIR_ON_OPEN", // from cpl_vsil_curl.cpp, gdalopeninfo.cpp + "GDAL_DRIVER_PATH", // from gdaldataset.cpp, gdaldrivermanager.cpp, gdalpythondriverloader.cpp + "GDAL_DTED_SINGLE_BLOCK", // from dteddataset.cpp + "GDAL_ECW_CACHE_MAXMEM", // from ecwdataset.cpp + "GDAL_ECW_PROMOTE_1BIT_ALPHA_AS_8BIT", // from ecwdataset.cpp + "GDAL_ECW_WRITE_COMPANY", // from ecwcreatecopy.cpp + "GDAL_ECW_WRITE_COMPRESSION_SOFTWARE", // from ecwcreatecopy.cpp + "GDAL_ENABLE_PYTHON_PATH", // from gdalpython.cpp + "GDAL_ENABLE_PYTHON_SYMLINK", // from gdalpython.cpp + "GDAL_ENABLE_READ_WRITE_MUTEX", // from gdaldataset.cpp + "GDAL_ENABLE_TIFF_SPLIT", // from gtiffdataset_read.cpp + "GDAL_ENABLE_WMS_CACHE", // from gdalwmsdataset.cpp + "GDAL_ERROR_ON_LIBJPEG_WARNING", // from jpgdataset.cpp + "GDAL_FILENAME_IS_UTF8", // from cpl_getexecpath.cpp, cpl_odbc.cpp, cpl_vsil_win32.cpp, cpl_vsisimple.cpp, cplgetsymbol.cpp, ecwcreatecopy.cpp, ecwdataset.cpp, gdalpython.cpp, netcdfdataset.cpp, netcdfmultidim.cpp, ogrxlsdatasource.cpp + "GDAL_FORCE_CACHING", // from gdaldataset.cpp, gdalrasterband.cpp + "GDAL_GCPS_TO_GEOTRANSFORM_APPROX_OK", // from gdal_misc.cpp + "GDAL_GCPS_TO_GEOTRANSFORM_APPROX_THRESHOLD", // from gdal_misc.cpp + "GDAL_GEOLOC_BACKMAP_OVERSAMPLE_FACTOR", // from gdalgeoloc.cpp + "GDAL_GEOLOC_INVERSE_METHOD", // from gdalgeoloc.cpp + "GDAL_GEOLOC_USE_MAX_ACCURACY", // from gdalgeoloc.cpp + "GDAL_GEOLOC_USE_TEMP_DATASETS", // from gdalgeoloc.cpp + "GDAL_GEOREF_SOURCES", // from gdalgeorefpamdataset.cpp, gdaljp2abstractdataset.cpp, gtiffdataset_read.cpp + "GDAL_GRID_POINT_COUNT_THRESHOLD", // from gdalgrid.cpp + "GDAL_GSSAPI_DELEGATION", // from cpl_http.cpp + "GDAL_GTIFF_PREDICTOR_CHECKS", // from gtiffdataset_write.cpp + "GDAL_HDF5_CHAR_AS_STRING", // from hdf5dataset.cpp + "GDAL_HDF5_TEMP_ARRAY_ALLOC_SIZE", // from hdf5multidim.cpp + "GDAL_HFA_OVR_BLOCKSIZE", // from hfaband.cpp + "GDAL_HTTP_AUTH", // from cpl_http.cpp + "GDAL_HTTP_BEARER", // from cpl_http.cpp + "GDAL_HTTP_CONNECTTIMEOUT", // from cpl_http.cpp + "GDAL_HTTP_COOKIE", // from cpl_http.cpp + "GDAL_HTTP_COOKIEFILE", // from cpl_http.cpp + "GDAL_HTTP_COOKIEJAR", // from cpl_http.cpp + "GDAL_HTTP_ENABLE_ADVISE_READ", // from cpl_vsil_curl.cpp + "GDAL_HTTP_HEADER_FILE", // from cpl_google_cloud.cpp, cpl_http.cpp + "GDAL_HTTP_HEADERS", // from cpl_google_cloud.cpp, cpl_http.cpp + "GDAL_HTTP_KEYPASSWD", // from cpl_http.cpp + "GDAL_HTTP_LOW_SPEED_LIMIT", // from cpl_http.cpp + "GDAL_HTTP_LOW_SPEED_TIME", // from cpl_http.cpp + "GDAL_HTTP_MAX_RETRY", // from cpl_http.cpp + "GDAL_HTTP_MERGE_CONSECUTIVE_RANGES", // from cpl_vsil_curl.cpp + "GDAL_HTTP_MULTIPLEX", // from cpl_vsil_curl.cpp + "GDAL_HTTP_MULTIRANGE", // from cpl_vsil_curl.cpp + "GDAL_HTTP_NETRC", // from cpl_http.cpp + "GDAL_HTTP_NETRC_FILE", // from cpl_http.cpp + "GDAL_HTTP_PROXY", // from cpl_http.cpp + "GDAL_HTTP_PROXYUSERPWD", // from cpl_http.cpp + "GDAL_HTTP_RETRY_CODES", // from cpl_http.cpp + "GDAL_HTTP_RETRY_DELAY", // from cpl_http.cpp + "GDAL_HTTP_SSL_VERIFYSTATUS", // from cpl_http.cpp + "GDAL_HTTP_SSLCERT", // from cpl_http.cpp + "GDAL_HTTP_SSLCERTTYPE", // from cpl_http.cpp + "GDAL_HTTP_SSLKEY", // from cpl_http.cpp + "GDAL_HTTP_TCP_KEEPALIVE", // from cpl_http.cpp + "GDAL_HTTP_TCP_KEEPIDLE", // from cpl_http.cpp + "GDAL_HTTP_TCP_KEEPINTVL", // from cpl_http.cpp + "GDAL_HTTP_TIMEOUT", // from cpl_http.cpp, gdalwmsdataset.cpp + "GDAL_HTTP_UNSAFESSL", // from cpl_http.cpp + "GDAL_HTTP_USE_CAPI_STORE", // from cpl_http.cpp + "GDAL_HTTP_USERAGENT", // from cpl_http.cpp, gdalwmsdataset.cpp + "GDAL_HTTP_USERPWD", // from cpl_http.cpp + "GDAL_HTTP_VERSION", // from cpl_http.cpp + "GDAL_HTTPS_PROXY", // from cpl_http.cpp + "GDAL_IGNORE_AXIS_ORIENTATION", // from gdaljp2metadata.cpp + "GDAL_INGESTED_BYTES_AT_OPEN", // from cpl_vsil_curl.cpp, gdalopeninfo.cpp + "GDAL_JP2K_ALT_OFFSETVECTOR_ORDER", // from gdaljp2metadata.cpp + "GDAL_JPEG2000_STRUCTURE_MAX_LINES", // from gdaljp2structure.cpp + "GDAL_JPEG_TO_RGB", // from jpgdataset.cpp + "GDAL_JPEGXL_MAX_BOX_BUFFER_SIZE", // from jpegxl.cpp + "GDAL_LOAD_EXTRA_DIM_METADATA_DELAY", // from gdalmultidim.cpp + "GDAL_LOCALE", // from gdaldllmain.cpp + "GDAL_MAX_BAND_COUNT", // from gdal_misc.cpp, netcdfdataset.cpp, pcidskdataset2.cpp + "GDAL_MAX_CONNECTIONS", // from gdalogcapidataset.cpp, gdalwmsdataset.cpp + "GDAL_MAX_DATASET_POOL_RAM_USAGE", // from gdalproxypool.cpp + "GDAL_MAX_DATASET_POOL_SIZE", // from gdal_translate_bin.cpp, gdalproxypool.cpp, gdalwarp_bin.cpp + "GDAL_MAX_RAW_BLOCK_CACHE_SIZE", // from gtiffrasterband_read.cpp + "GDAL_MEM_ENABLE_OPEN", // from memdataset.cpp + "GDAL_NETCDF_ASSUME_LONGLAT", // from netcdfdataset.cpp + "GDAL_NETCDF_BOTTOMUP", // from netcdfdataset.cpp + "GDAL_NETCDF_CENTERLONG_180", // from netcdfdataset.cpp + "GDAL_NETCDF_IGNORE_EQUALLY_SPACED_XY_CHECK", // from netcdfdataset.cpp + "GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS", // from netcdfdataset.cpp + "GDAL_NETCDF_REPORT_EXTRA_DIM_VALUES", // from netcdfdataset.cpp + "GDAL_NETCDF_VERIFY_DIMS", // from netcdfdataset.cpp + "GDAL_NO_COSTLY_OVERVIEW", // from rasterio.cpp + "GDAL_NUM_THREADS", // from avifdataset.cpp, common.cpp, cpl_vsil_gzip.cpp, gdal_tps.cpp, gdalgrid.cpp, gdalpansharpen.cpp, gdaltileindexdataset.cpp, gdalwarpkernel.cpp, gtiffdataset_write.cpp, jpegxl.cpp, ogr2ogr_lib.cpp, ogrmvtdataset.cpp, ogrparquetlayer.cpp, osm_parser.cpp, overview.cpp, rmfdataset.cpp, vrtdataset.cpp, zarr_array.cpp + "GDAL_OGCAPI_TILEMATRIXSET_LIMITS", // from gdalogcapidataset.cpp + "GDAL_ONE_BIG_READ", // from jp2kakdataset.cpp, jpipkakdataset.cpp, mrsiddataset.cpp, rawdataset.cpp, wcsdataset.cpp + "GDAL_OPEN_AFTER_COPY", // from jpgdataset.cpp, pngdataset.cpp + "GDAL_OPENGIS_SCHEMAS", // from cpl_xml_validate.cpp + "GDAL_OVERVIEW_OVERSAMPLING_THRESHOLD", // from rasterio.cpp, vrtwarped.cpp + "GDAL_OVR_CHUNK_MAX_SIZE", // from overview.cpp + "GDAL_OVR_CHUNKYSIZE", // from overview.cpp + "GDAL_OVR_PROPAGATE_NODATA", // from overview.cpp + "GDAL_OVR_TEMP_DRIVER", // from overview.cpp + "GDAL_PAM_ENABLE_MARK_DIRTY", // from gdalpamdataset.cpp + "GDAL_PAM_ENABLED", // from gdalpamdataset.cpp + "GDAL_PAM_MODE", // from gdalpamdataset.cpp + "GDAL_PAM_PROXY_DIR", // from gdalpamproxydb.cpp + "GDAL_PDF_GEO_ENCODING", // from pdfcreatecopy.cpp, pdfdataset.cpp + "GDAL_PDF_LAUNDER_LAYER_NAMES", // from pdfdataset.cpp + "GDAL_PDF_LIMIT_PAGE_COUNT", // from pdfdataset.cpp + "GDAL_PDF_OGC_BP_READ_WKT", // from pdfdataset.cpp + "GDAL_PDF_OGC_BP_WRITE_WKT", // from pdfcreatecopy.cpp, pdfcreatefromcomposition.cpp + "GDAL_PDF_PRINT_COMMANDS", // from pdfdataset.cpp + "GDAL_PDF_USE_SPAWN", // from pdfdataset.cpp + "GDAL_PDF_WRITE_ESRI_CODE_AS_EPSG", // from pdfcreatecopy.cpp + "GDAL_PDF_WRITE_GEOREF_ON_IMAGE", // from pdfcreatecopy.cpp + "GDAL_PNG_SINGLE_BLOCK", // from pngdataset.cpp + "GDAL_PNG_WHOLE_IMAGE_OPTIM", // from pngdataset.cpp + "GDAL_PROXY_AUTH", // from cpl_http.cpp + "GDAL_PYTHON_DRIVER_PATH", // from gdalpythondriverloader.cpp + "GDAL_RASTERIO_RESAMPLING", // from gdal_misc.cpp + "GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK", // from gdalrasterblock.cpp + "GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK", // from gdalrasterblock.cpp + "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DETACH_BEFORE_WRITE", // from gdalrasterblock.cpp + "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK", // from gdalrasterblock.cpp + "GDAL_RB_LOCK_DEBUG_CONTENTION", // from gdalrasterblock.cpp + "GDAL_RB_LOCK_TYPE", // from gdalrasterblock.cpp + "GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK", // from gdalrasterblock.cpp + "GDAL_READDIR_LIMIT_ON_OPEN", // from gdalopeninfo.cpp, gtiffdataset_read.cpp, tiledbdense.cpp + "GDAL_REPORT_DIRTY_BLOCK_FLUSHING", // from gdalabstractbandblockcache.cpp + "GDAL_RPC_DEM_OPTIM", // from gdal_rpc.cpp + "GDAL_SHARED_FILE", // from cpl_vsil_win32.cpp + "GDAL_SIMUL_MEM_ALLOC_FAILURE_NODATA_MASK_BAND", // from gdalnodatamaskband.cpp + "GDAL_SKIP", // from gdaldrivermanager.cpp + "GDAL_STACTA_SKIP_MISSING_METATILE", // from stactadataset.cpp + "GDAL_SWATH_SIZE", // from gdalmultidim.cpp, rasterio.cpp + "GDAL_TEMP_DRIVER_NAME", // from nearblack_lib_floodfill.cpp + "GDAL_TIFF_DEFLATE_SUBCODEC", // from gtiffdataset.cpp + "GDAL_TIFF_ENDIANNESS", // from gtiffdataset_write.cpp + "GDAL_TIFF_INTERNAL_MASK", // from gtiffdataset_write.cpp + "GDAL_TIFF_INTERNAL_MASK_TO_8BIT", // from gtiffdataset.cpp, gtiffdataset_write.cpp + "GDAL_TIFF_OVR_BLOCKSIZE", // from geotiff.cpp + "GDAL_TRY_PDS3_WITH_VICAR", // from pdsdrivercore.cpp + "GDAL_USE_AVX", // from gdalgrid.cpp + "GDAL_USE_GEOJP2", // from gdaljp2metadata.cpp + "GDAL_USE_GMLJP2", // from gdaljp2metadata.cpp + "GDAL_USE_OPENCL", // from gdalwarpkernel.cpp + "GDAL_USE_SSE", // from gdalgrid.cpp + "GDAL_USE_SSSE3", // from cpl_cpu_features.cpp + "GDAL_VALIDATE_CREATION_OPTIONS", // from gdaldataset.cpp, gdaldriver.cpp + "GDAL_VRT_ENABLE_PYTHON", // from vrtderivedrasterband.cpp + "GDAL_VRT_PYTHON_EXCLUSIVE_LOCK", // from vrtderivedrasterband.cpp + "GDAL_VRT_PYTHON_TRUSTED_MODULES", // from vrtderivedrasterband.cpp + "GDAL_VRT_WARP_USE_DATASET_RASTERIO", // from vrtwarped.cpp + "GDAL_WARP_USE_AFFINE_OPTIMIZATION", // from gdalwarpkernel.cpp + "GDAL_WARP_USE_TRANSLATION_OPTIM", // from gdalwarpoperation.cpp + "GDAL_WMS_MAX_CONNECTIONS", // from gdalogcapidataset.cpp + "GDAL_XML_VALIDATION", // from ogrgmlasconf.cpp, ogrvrtdriver.cpp, pdfcreatefromcomposition.cpp + "GDAL_ZARR_USE_OPTIMIZED_CODE_PATHS", // from zarr_array.cpp + "GDALCUTLINE_SKIP_CONTAINMENT_TEST", // from gdalcutline.cpp + "GDALWARP_DENSIFY_CUTLINE", // from gdalwarp_lib.cpp + "GDALWARP_DUMP_WKT_TO_FILE", // from gdalwarp_lib.cpp + "GDALWARP_IGNORE_BAD_CUTLINE", // from gdalwarp_lib.cpp + "GDALWARP_OVERSAMPLING_THRESHOLD", // from gdalwarp_lib.cpp + "GDALWARP_SKIP_CUTLINE_CONTAINMENT_TEST", // from gdalwarp_lib.cpp + "GEOJSON_FLATTEN_GEOCOUCH", // from ogrgeojsonreader.cpp + "GEOL_AS_GCPS", // from hdf4imagedataset.cpp + "GEOLOC_DUMP", // from gdalgeoloc.cpp + "GEOMETRY_AS_COLLECTION", // from ogrgeojsondriver.cpp + "GEOR_FILTER_NODATA_VALUES", // from georaster_dataset.cpp + "GEOR_INTERNAL_PYR", // from georaster_dataset.cpp + "GML_ATTRIBUTES_TO_OGR_FIELDS", // from ogrgmldatasource.cpp + "GML_CONSIDER_EPSG_AS_URN", // from ogrgmldatasource.cpp, ogrwfsdatasource.cpp, ogrwfslayer.cpp + "GML_DOWNLOAD_SCHEMA", // from ogrgmldatasource.cpp + "GML_DOWNLOAD_WFS_SCHEMA", // from ogrgmldatasource.cpp + "GML_EXPOSE_FID", // from ogrgmldatasource.cpp + "GML_EXPOSE_GML_ID", // from ogrgmldatasource.cpp, ogrwfsdatasource.cpp, ogrwfslayer.cpp + "GML_FACE_HOLE_NEGATIVE", // from gml2ogrgeometry.cpp, gmlreader.cpp, ogrgmllayer.cpp + "GML_FETCH_ALL_GEOMETRIES", // from gmlreader.cpp + "GML_FIELDTYPES", // from gmlreader.cpp, nasreader.cpp + "GML_GET_SECONDARY_GEOM", // from gml2ogrgeometry.cpp, ogrgmldatasource.cpp + "GML_GFS_TEMPLATE", // from ogrgmldatasource.cpp + "GML_HUGE_TEMPFILE", // from ogrgmldatasource.cpp + "GML_INVERT_AXIS_ORDER_IF_LAT_LONG", // from ogrcswdataset.cpp, ogrgmldatasource.cpp, ogrwfsdatasource.cpp, ogrwfslayer.cpp + "GML_PARSER", // from ogrgmldatasource.cpp + "GML_READ_MODE", // from ogrgmldatasource.cpp + "GML_REGISTRY", // from ogrgmldatasource.cpp + "GML_REPORT_COMPD_CS", // from ogrgmldatasource.cpp + "GML_SAVE_RESOLVED_TO", // from ogrgmldatasource.cpp + "GML_SCHEMA_OUTPUT_NAME", // from parsexsd.cpp + "GML_SKIP_CORRUPTED_FEATURES", // from ogrgmllayer.cpp + "GML_SKIP_RESOLVE_ELEMS", // from ogrgmldatasource.cpp + "GML_SRS_DIMENSION_IF_MISSING", // from gmlhandler.cpp + "GML_SWAP_COORDINATES", // from ogrgmldatasource.cpp + "GML_USE_OLD_FID_FORMAT", // from ogrgmllayer.cpp + "GML_USE_SCHEMA_IMPORT", // from ogrgmldatasource.cpp + "GMLAS_WARN_UNEXPECTED", // from ogrgmlasreader.cpp + "GMLAS_XLINK_RAM_CACHE_SIZE", // from ogrgmlasxlinkresolver.cpp + "GMLAS_XML_MAX_CONTENT_SIZE", // from ogrgmlasreader.cpp + "GMLAS_XML_MAX_LEVEL", // from ogrgmlasreader.cpp + "GMLJP2OVERRIDE", // from gdaljp2metadata.cpp, jp2opjlikedataset.cpp + "GMT_USE_TAB", // from ogrgmtlayer.cpp + "GO2A_AUD", // from cpl_google_oauth2.cpp + "GOA2_AUTH_URL_TOKEN", // from cpl_google_oauth2.cpp + "GOA2_CLIENT_ID", // from cpl_google_oauth2.cpp + "GOA2_CLIENT_SECRET", // from cpl_google_oauth2.cpp + "GOA2_EXPIRATION_DELAY", // from cpl_google_oauth2.cpp + "GOA2_NOW", // from cpl_google_oauth2.cpp + "GOOGLE_APPLICATION_CREDENTIALS", // from cpl_google_cloud.cpp, eedacommon.cpp + "GPKG_ALLOW_CRAZY_SETTINGS", // from ogrgeopackagedatasource.cpp + "GPKG_DEBUG", // from ogrgeopackagedatasource.cpp + "GPKG_FORCE_TEMPDB_COMPACTION", // from gdalgeopackagerasterband.cpp + "GPKG_NAME_CHECK", // from ogrgeopackagedatasource.cpp + "GPKG_NODATA", // from ogrgeopackagedatasource.cpp + "GPKG_PNG_SUPPORTS_2BANDS", // from ogrgeopackagedatasource.cpp + "GPKG_PNG_SUPPORTS_CT", // from ogrgeopackagedatasource.cpp + "GPKG_SIMUL_WEBP_3BAND", // from gdalgeopackagerasterband.cpp + "GPKG_WARN_UNRECOGNIZED_APPLICATION_ID", // from ogrgeopackagedriver.cpp + "GPX_ELE_AS_25D", // from ogrgpxlayer.cpp + "GPX_N_MAX_LINKS", // from ogrgpxlayer.cpp + "GPX_SHORT_NAMES", // from ogrgpxlayer.cpp + "GPX_USE_EXTENSIONS", // from ogrgpxlayer.cpp + "GRIB_ADJUST_LONGITUDE_RANGE", // from gribcreatecopy.cpp, gribdataset.cpp + "GRIB_CACHEMAX", // from gribdataset.cpp + "GRIB_DEFAULT_SEMI_MAJOR", // from gribdataset.cpp + "GRIB_DEFAULT_SEMI_MINOR", // from gribdataset.cpp + "GRIB_NORMALIZE_UNITS", // from gribdataset.cpp + "GRIB_PDS_ALL_BANDS", // from gribdataset.cpp + "GRIB_RESOURCE_DIR", // from metaname.cpp + "GRIB_USE_DEFAULT_SPHEROID", // from gribdataset.cpp + "GRIB_WRITE_BITMAP_TEST", // from gribcreatecopy.cpp + "GS_ACCESS_KEY_ID", // from cpl_google_cloud.cpp + "GS_NO_SIGN_REQUEST", // from cpl_google_cloud.cpp + "GS_OAUTH2_CLIENT_EMAIL", // from cpl_google_cloud.cpp + "GS_OAUTH2_CLIENT_ID", // from cpl_google_cloud.cpp + "GS_OAUTH2_CLIENT_SECRET", // from cpl_google_cloud.cpp + "GS_OAUTH2_PRIVATE_KEY", // from cpl_google_cloud.cpp + "GS_OAUTH2_PRIVATE_KEY_FILE", // from cpl_google_cloud.cpp + "GS_OAUTH2_REFRESH_TOKEN", // from cpl_google_cloud.cpp + "GS_OAUTH2_SCOPE", // from cpl_google_cloud.cpp + "GS_SECRET_ACCESS_KEY", // from cpl_google_cloud.cpp + "GS_USER_PROJECT", // from cpl_google_cloud.cpp + "GTI_NUM_THREADS", // from gdaltileindexdataset.cpp + "GTIFF_ALLOW_PREAD", // from gtiffdataset_read.cpp + "GTIFF_ALPHA", // from gtiffdataset_write.cpp, gtiffrasterband_write.cpp + "GTIFF_DELETE_ON_ERROR", // from gtiffdataset_write.cpp + "GTIFF_DIRECT_IO", // from gtiffdataset.cpp + "GTIFF_DONT_WRITE_BLOCKS", // from gtiffdataset.cpp + "GTIFF_ESRI_CITATION", // from gt_wkt_srs.cpp + "GTIFF_FORCE_RGBA", // from gtiffdataset_read.cpp + "GTIFF_HAS_OPTIMIZED_READ_MULTI_RANGE", // from gtiffdataset_read.cpp + "GTIFF_HONOUR_NEGATIVE_SCALEY", // from gtiffdataset_read.cpp + "GTIFF_IGNORE_READ_ERRORS", // from gtiffdataset.cpp + "GTIFF_IMPLICIT_JPEG_OVR", // from gtiffdataset_read.cpp + "GTIFF_IMPORT_FROM_EPSG", // from gt_wkt_srs.cpp + "GTIFF_LINEAR_UNITS", // from gt_wkt_srs.cpp + "GTIFF_MAX_CUMULATED_MEM_USAGE", // from tifvsi.cpp + "GTIFF_POINT_GEO_IGNORE", // from gt_wkt_srs.cpp, gtiffdataset_read.cpp, gtiffdataset_write.cpp + "GTIFF_READ_ANGULAR_PARAMS_IN_DEGREE", // from gt_wkt_srs.cpp + "GTIFF_REPORT_COMPD_CS", // from gtiffdataset_read.cpp, gtiffdataset_write.cpp + "GTIFF_SRS_SOURCE", // from gt_wkt_srs.cpp + "GTIFF_USE_DEFER_STRILE_LOADING", // from gtiffdataset_read.cpp + "GTIFF_USE_MMAP", // from tifvsi.cpp + "GTIFF_VIRTUAL_MEM_IO", // from gtiffdataset.cpp + "GTIFF_WRITE_ANGULAR_PARAMS_IN_DEGREE", // from gt_wkt_srs.cpp + "GTIFF_WRITE_IMAGE_STRUCTURE_METADATA", // from gtiffdataset_write.cpp + "GTIFF_WRITE_TOWGS84", // from gt_wkt_srs.cpp + "GXF_DATATYPE", // from gxfdataset.cpp + "HDF4_BLOCK_PIXELS", // from hdf4imagedataset.cpp + "HDF5_SHIFT_GCPX_BY_180", // from hdf5imagedataset.cpp + "HFA_COMPRESS_OVR", // from hfaband.cpp + "HFA_SHOW_ESRI_PE_STRING_ONLY_WARNING", // from hfadataset.cpp + "HFA_USE_ESRI_PE_STRING", // from hfadataset.cpp + "HFA_USE_RRD", // from hfaband.cpp + "HFA_WRITE_PE_STRING", // from hfaopen.cpp + "HOME", // from cpl_aws.cpp, cpl_azure.cpp, cpl_conv.cpp, cpl_google_cloud.cpp, cpl_path.cpp, gdalwmscache.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "IDB_OGR_FID", // from ogridblayer.cpp + "IDRISIDIR", // from IdrisiDataset.cpp + "INTERLEAVE_OVERVIEW", // from gt_overview.cpp + "ISG_SKIP_GEOREF_CONSISTENCY_CHECK", // from aaigriddataset.cpp + "JP2KAK_BUFFERED", // from jp2kakdataset.cpp + "JP2KAK_FUSSY", // from jp2kakdataset.cpp + "JP2KAK_MAX_BUFFER_SIZE", // from jp2kakdataset.cpp + "JP2KAK_PERSIST", // from jp2kakdataset.cpp + "JP2KAK_PRECISE", // from jp2kakdataset.cpp + "JP2KAK_RESILIENT", // from jp2kakdataset.cpp + "JP2KAK_THREADS", // from jp2kakdataset.cpp + "JP2KAK_USE_STRIPE_COMPRESSOR", // from jp2kakdataset.cpp + "JP2OPENJPEG_PROMOTE_1BIT_ALPHA_AS_8BIT", // from jp2opjlikedataset.cpp + "JP2OPENJPEG_USE_THREADED_IO", // from jp2opjlikedataset.cpp + "JPEG_FORCE_INTERNAL_OVERVIEWS", // from jpgdataset.cpp + "JPEG_MASK_BIT_ORDER", // from jpgdataset.cpp + "JPEG_QUALITY_OVERVIEW", // from gt_overview.cpp + "JPEG_READ_MASK", // from jpgdataset.cpp + "JPEG_TABLESMODE_OVERVIEW", // from gt_overview.cpp + "JPEG_WRITE_MASK_BIT_ORDER", // from jpgdataset.cpp + "JPEG_WRITE_RGB", // from jpgdataset.cpp + "JPEGMEM", // from gt_jpeg_copy.cpp, jpgdataset.cpp + "JXL_ALPHA_DISTANCE_OVERVIEW", // from gt_overview.cpp + "JXL_DISTANCE_OVERVIEW", // from gt_overview.cpp + "JXL_EFFORT_OVERVIEW", // from gt_overview.cpp + "JXL_LOSSLESS_OVERVIEW", // from gt_overview.cpp + "KML_DEBUG", // from kmlvector.cpp, ogrkmldatasource.cpp + "KTX2_MAX_FILE_SIZE", // from ktx2dataset.cpp + "KTX2_VERBOSE", // from common.cpp + "L1B_FETCH_METADATA", // from l1bdataset.cpp + "L1B_HIGH_GCP_DENSITY", // from l1bdataset.cpp + "L1B_INTERPOL_GCPS", // from l1bdataset.cpp + "L1B_METADATA_DIRECTORY", // from l1bdataset.cpp + "LIBKML_ADD_RESOURCE_MAP", // from ogrlibkmlfeature.cpp + "LIBKML_ALTITUDEMODE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_BEGIN_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_BOTTOMFOV_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_CAMERA_ALTITUDE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_CAMERA_ALTITUDEMODE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_CAMERA_LATITUDE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_CAMERA_LONGITUDE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_DESCRIPTION_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_DRAWORDER_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_END_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_EXTERNAL_STYLE", // from ogrlibkmlfeaturestyle.cpp, ogrlibkmlstyle.cpp + "LIBKML_EXTRUDE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_HEADING_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_ICON_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_ID_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_IMAGEPYRAMID_GRIDORIGIN", // from ogrlibkmlfield.cpp + "LIBKML_IMAGEPYRAMID_MAXHEIGHT", // from ogrlibkmlfield.cpp + "LIBKML_IMAGEPYRAMID_MAXWIDTH", // from ogrlibkmlfield.cpp + "LIBKML_IMAGEPYRAMID_TILESIZE", // from ogrlibkmlfield.cpp + "LIBKML_LAUNDER_FIELD_NAMES", // from ogrlibkmlfield.cpp, ogrlibkmllayer.cpp + "LIBKML_LEFTFOV_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_MODEL_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NAME_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NEARFOV_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_FLYTOVIEW_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_HTTPQUERY_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_REFRESHINTERVAL_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_REFRESHMODE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_REFRESHVISIBILITY_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_VIEWBOUNDSCALE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_VIEWFORMAT_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_VIEWREFRESHMODE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_NETWORKLINK_VIEWREFRESHTIME_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_PHOTOOVERLAY_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_PHOTOOVERLAY_SHAPE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_READ_GROUND_OVERLAY", // from ogrlibkmldatasource.cpp, ogrlibkmllayer.cpp + "LIBKML_RESOLVE_STYLE", // from ogrlibkmlfeaturestyle.cpp + "LIBKML_RIGHTFOV_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_ROLL_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_SCALE_X_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_SCALE_Y_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_SCALE_Z_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_SNIPPET_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_STRICT_COMPLIANCE", // from ogrlibkmlfeature.cpp, ogrlibkmlfield.cpp, ogrlibkmlgeometry.cpp + "LIBKML_STYLEMAP_KEY", // from ogrlibkmlstyle.cpp + "LIBKML_TESSELLATE_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_TILT_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_TIMESTAMP_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_TOPFOV_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_USE_DOC.KML", // from ogrlibkmldatasource.cpp + "LIBKML_USE_SIMPLEFIELD", // from ogrlibkmllayer.cpp + "LIBKML_VISIBILITY_FIELD", // from ogrlibkmlfield.cpp + "LIBKML_WRAPDATELINE", // from ogrlibkmlgeometry.cpp + "MAX_Z_ERROR_OVERVIEW", // from gt_overview.cpp + "MBTILES_BAND_COUNT", // from mbtilesdataset.cpp + "MBTILES_PNG_SUPPORTS_2BANDS", // from mbtilesdataset.cpp + "MBTILES_PNG_SUPPORTS_CT", // from mbtilesdataset.cpp + "MDBDRIVER_PATH", // from cpl_odbc.cpp + "MITAB_BOUNDS_FILE", // from mitab_bounds.cpp + "MITAB_MAX_LINE_LENGTH", // from mitab_middatafile.cpp + "MITAB_SET_TOWGS84_ON_KNOWN_DATUM", // from ogrmitabspatialref.cpp + "MRF_ALL_OVERVIEW_LEVELS", // from marfa_dataset.cpp + "MRF_BYPASSCACHING", // from marfa_dataset.cpp + "MSSQLSPATIAL_ALWAYS_OUTPUT_FID", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_BCP_SIZE", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_LIST_ALL_TABLES", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_OGR_FID", // from ogrmssqlspatiallayer.cpp + "MSSQLSPATIAL_PWD", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_SHOW_FID_COLUMN", // from ogrmssqlspatiallayer.cpp + "MSSQLSPATIAL_UID", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_USE_BCP", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_USE_GEOMETRY_COLUMNS", // from ogrmssqlspatialdatasource.cpp + "MSSQLSPATIAL_USE_GEOMETRY_VALIDATION", // from ogrmssqlspatialtablelayer.cpp + "MVT_USE_READDIR", // from ogrmvtdataset.cpp + "MVT_ZOOM_LEVEL_AUTO", // from mbtilesdataset.cpp, ogrpmtilesdataset.cpp + "MYSQL_TIMEOUT", // from ogrmysqldatasource.cpp + "NAS_GFS_TEMPLATE", // from ogrnasdatasource.cpp, ogrnasdriver.cpp + "NAS_INDICATOR", // from ogrnasdriver.cpp + "NAS_SKIP_CORRUPTED_FEATURES", // from ogrnaslayer.cpp + "NETCDF_TMP_FILE", // from netcdfdataset.cpp, netcdfmultidim.cpp + "NGW_BATCH_SIZE", // from gdalngwdataset.cpp + "NGW_CACHE_EXPIRES", // from gdalngwdataset.cpp + "NGW_CACHE_MAX_SIZE", // from gdalngwdataset.cpp + "NGW_EXTENSIONS", // from gdalngwdataset.cpp + "NGW_JSON_DEPTH", // from gdalngwdataset.cpp + "NGW_NATIVE_DATA", // from gdalngwdataset.cpp + "NGW_PAGE_SIZE", // from gdalngwdataset.cpp + "NGW_USERPWD", // from gdalngwdataset.cpp, ogrngwdriver.cpp + "NITF_DISABLE_RPF_LOCATION_TABLE_SANITY_TESTS", // from nitfimage.c + "NITF_OPEN_UNDERLYING_DS", // from nitfdataset.cpp, nitfrasterband.cpp + "NITF_SAR_AS_COMPLEX_TYPE", // from nitfdataset.cpp + "NITF_USEGEOLOB", // from nitfimage.c + "OCI_DEFAULT_DIM", // from ogrociwritablelayer.cpp + "OCI_FID", // from ogrocidatasource.cpp, ogrociloaderlayer.cpp, ogrociselectlayer.cpp, ogrocitablelayer.cpp + "ODBC_OGR_FID", // from ogrodbclayer.cpp + "ODS_RESOLVE_FORMULAS", // from ogrodsdatasource.cpp + "OGR2OGR_MIN_FEATURES_FOR_THREADED_REPROJ", // from ogr2ogr_lib.cpp + "OGR2OGR_USE_ARROW_API", // from ogr2ogr_lib.cpp + "OGR_API_SPY_FILE", // from ograpispy.cpp + "OGR_API_SPY_SNAPSHOT_PATH", // from ograpispy.cpp + "OGR_APPLY_GEOM_SET_PRECISION", // from ogr2ogr_lib.cpp, ogrlayer.cpp + "OGR_ARC_MAX_GAP", // from ogrgeometryfactory.cpp + "OGR_ARC_STEPSIZE", // from gml2ogrgeometry.cpp, ogrdgnv8layer.cpp, ogrgeometryfactory.cpp, ogrili1datasource.cpp, ogrili1layer.cpp, ogrpgeogeometry.cpp + "OGR_ARROW_COMPUTE_GEOMETRY_TYPE", // from ogrfeatherlayer.cpp + "OGR_ARROW_LOAD_FILE_SYSTEM_FACTORIES", // from ogrfeatherdriver.cpp + "OGR_ARROW_MEM_LIMIT", // from ograrrowarrayhelper.cpp + "OGR_ARROW_READ_GDAL_FOOTER", // from ogrfeatherlayer.cpp + "OGR_ARROW_USE_VSI", // from ogrfeatherdriver.cpp + "OGR_ARROW_WRITE_BBOX", // from ogrfeatherwriterlayer.cpp + "OGR_ARROW_WRITE_GDAL_FOOTER", // from ogrfeatherwriterlayer.cpp + "OGR_ARROW_WRITE_GDAL_GEOMETRY_TYPE", // from ogrfeatherwriterlayer.cpp + "OGR_ARROW_WRITE_GEO", // from ogrfeatherwriterlayer.cpp + "OGR_CSV_MAX_FIELD_COUNT", // from ogrcsvlayer.cpp + "OGR_CSV_MAX_LINE_SIZE", // from ogrcsvdatasource.cpp + "OGR_CSV_SIMULATE_VSISTDIN", // from ogrcsvlayer.cpp + "OGR_CT_DEBUG", // from ogrct.cpp + "OGR_CT_FORCE_TRADITIONAL_GIS_ORDER", // from ogrct.cpp + "OGR_CT_OP_SELECTION", // from ogrct.cpp + "OGR_CT_PREFER_OFFICIAL_SRS_DEF", // from ogrct.cpp + "OGR_CT_USE_SRS_COORDINATE_EPOCH", // from ogrct.cpp + "OGR_CURRENT_DATE", // from ogrgeopackagedatasource.cpp + "OGR_DEBUG_ORGANIZE_POLYGONS", // from ogrgeometryfactory.cpp + "OGR_DRIVER_PATH", // from gdaldrivermanager.cpp + "OGR_EDIGEO_CREATE_LABEL_LAYERS", // from ogredigeodatasource.cpp + "OGR_EDIGEO_FONT_SIZE_FACTOR", // from ogredigeodatasource.cpp + "OGR_EDIGEO_INCLUDE_FONT_FAMILY", // from ogredigeodatasource.cpp + "OGR_EDIGEO_RECODE_TO_UTF8", // from ogredigeodatasource.cpp + "OGR_EDIGEO_SORT_FOR_QGIS", // from ogredigeodatasource.cpp + "OGR_ENABLE_PARTIAL_REPROJECTION", // from ogrlinestring.cpp + "OGR_EXPAT_UNLIMITED_MEM_ALLOC", // from ogr_expat.cpp + "OGR_FGDB_WORKAROUND_CRASH_ON_BINARY_FIELD", // from FGdbLayer.cpp + "OGR_FLATGEOBUF_STREAM_BASE_IMPL", // from ogrflatgeobuflayer.cpp + "OGR_FORCE_ASCII", // from ogrgpxlayer.cpp, ogrlibkmlfield.cpp, ogrutils.cpp + "OGR_GENSQL_STREAM_BASE_IMPL", // from ogr_gensql.cpp + "OGR_GEOJSON_ARRAY_AS_STRING", // from ogrgeojsondatasource.cpp + "OGR_GEOJSON_DATE_AS_STRING", // from ogrgeojsondatasource.cpp + "OGR_GEOJSON_MAX_BYTES_FIRST_PASS", // from ogrgeojsondatasource.cpp, ogrgeojsonreader.cpp + "OGR_GEOJSON_MAX_FEATURES_FIRST_PASS", // from ogrgeojsonreader.cpp + "OGR_GEOJSON_MAX_OBJ_SIZE", // from ogrgeojsonreader.cpp, ogrgeojsonseqdriver.cpp + "OGR_GEOJSON_REWRITE_IN_PLACE", // from ogrgeojsondatasource.cpp + "OGR_GEOJSONSEQ_CHUNK_SIZE", // from ogrgeojsonseqdriver.cpp + "OGR_GEOMETRY_ACCEPT_UNCLOSED_RING", // from ogrcurvepolygon.cpp, ogrpolygon.cpp + "OGR_GML_NESTING_LEVEL", // from gmlhandler.cpp + "OGR_GMLAS_USE_SCHEMAS_FROM_OGC_ZIP", // from ogrgmlasxsdcache.cpp + "OGR_GMLAS_XERCES_MAX_MEMORY", // from ogrgmlasreader.cpp + "OGR_GMLAS_XERCES_MAX_TIME", // from ogrgmlasreader.cpp + "OGR_GPKG_ALLOW_THREADED_RTREE", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_CHECK_SRS", // from ogrgeopackagedatasource.cpp + "OGR_GPKG_DEFERRED_SPI_UPDATE_THRESHOLD", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_FOREIGN_KEY_CHECK", // from ogrgeopackagedatasource.cpp + "OGR_GPKG_GEOMCOLLECTION", // from ogrgeopackagedatasource.cpp + "OGR_GPKG_INTEGRITY_CHECK", // from ogrgeopackagedatasource.cpp, ogrgeopackagetablelayer.cpp + "OGR_GPKG_MAX_RAM_USAGE_RTREE", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_NUM_THREADS", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_SIMULATE_INSERT_INTO_MY_RTREE_PREPARATION_ERROR", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_STREAM_BASE_IMPL", // from ogrgeopackagelayer.cpp, ogrgeopackagetablelayer.cpp + "OGR_GPKG_THREADED_RTREE_AT_FIRST_FEATURE", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_THRESHOLD_DETECT_BROKEN_RTREE", // from ogrgeopackagetablelayer.cpp + "OGR_GPKG_USE_RTREE_FOR_GET_EXTENT", // from ogrgeopackagetablelayer.cpp + "OGR_IDF_DELETE_TEMP_DB", // from ogrvdvdatasource.cpp + "OGR_IDF_TEMP_DB_THRESHOLD", // from ogrvdvdatasource.cpp + "OGR_INTERLEAVED_READING", // from ogrosmdatasource.cpp + "OGR_JSONFG_MAX_OBJ_SIZE", // from ogrjsonfgstreamingparser.cpp + "OGR_LVBAG_CHECK_ALL_FILES", // from ogrlvbagdriver.cpp + "OGR_LVBAG_MAX_OPENED", // from ogrlvbagdatasource.cpp + "OGR_MONGODB_SPAT_INDEX_TYPE", // from ogrmongodbv3driver.cpp + "OGR_MULTIPATCH_OMIT_Z", // from ogrpgeogeometry.cpp + "OGR_MVT_CLIP", // from ogrmvtdataset.cpp + "OGR_MVT_ENFORE_EXTERNAL_RING_IS_CLOCKWISE", // from ogrmvtdataset.cpp + "OGR_MVT_REMOVE_TEMP_FILE", // from ogrmvtdataset.cpp + "OGR_MVT_REUSE_TEMP_FILE", // from ogrmvtdataset.cpp + "OGR_OAPIF_ALLOW_CQL_TEXT", // from ogroapifdriver.cpp + "OGR_ODS_FIELD_TYPES", // from ogrodsdatasource.cpp + "OGR_ODS_HEADERS", // from ogrodsdatasource.cpp + "OGR_ODS_MAX_FIELD_COUNT", // from ogrodsdatasource.cpp + "OGR_OGDI_LAUNDER_LAYER_NAMES", // from ogrogdidatasource.cpp + "OGR_OPENFILEGDB_ERROR_ON_INCONSISTENT_BUFFER_MAX_SIZE", // from filegdbtable.cpp + "OGR_OPENFILEGDB_WRITE_EMPTY_GEOMETRY", // from ogropenfilegdblayer_write.cpp + "OGR_ORGANIZE_POLYGONS", // from filegdbtable.cpp, ogrgeometryfactory.cpp + "OGR_PARQUET_BATCH_READ_AHEAD", // from ogrparquetdatasetlayer.cpp + "OGR_PARQUET_BATCH_SIZE", // from ogrparquetdatasetlayer.cpp, ogrparquetlayer.cpp + "OGR_PARQUET_COMPUTE_GEOMETRY_TYPE", // from ogrparquetlayer.cpp + "OGR_PARQUET_CRS_ENCODING", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_CRS_OMIT_IF_WGS84", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_FRAGMENT_READ_AHEAD", // from ogrparquetdatasetlayer.cpp + "OGR_PARQUET_GEO_METADATA", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_LOAD_FILE_SYSTEM_FACTORIES", // from ogrparquetdriver.cpp + "OGR_PARQUET_OPTIMIZED_ATTRIBUTE_FILTER", // from ogrparquetdatasetlayer.cpp + "OGR_PARQUET_OPTIMIZED_SPATIAL_FILTER", // from ogrparquetdatasetlayer.cpp + "OGR_PARQUET_SHOW_ROW_GROUP_EXTENT", // from ogrparquetdriver.cpp + "OGR_PARQUET_USE_BBOX", // from ogrparquetdatasetlayer.cpp, ogrparquetlayer.cpp + "OGR_PARQUET_USE_METADATA_FILE", // from ogrparquetdriver.cpp + "OGR_PARQUET_USE_STATISTICS", // from ogrparquetdataset.cpp + "OGR_PARQUET_USE_THREADS", // from ogrparquetdatasetlayer.cpp, ogrparquetlayer.cpp + "OGR_PARQUET_USE_VSI", // from ogrparquetdriver.cpp + "OGR_PARQUET_WRITE_ARROW_EXTENSION_NAME", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_ARROW_SCHEMA", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_BBOX", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_COVERING_BBOX", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_COVERING_BBOX_IN_METADATA", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_CRS", // from ogrparquetwriterlayer.cpp + "OGR_PARQUET_WRITE_GEO", // from ogrparquetwriterlayer.cpp + "OGR_PDF_READ_NON_STRUCTURED", // from pdfreadvectors.cpp + "OGR_PDF_SET_STYLE", // from pdfdataset.cpp + "OGR_PDS4_FIELD_DELIMITER", // from pds4vector.cpp + "OGR_PG_CURSOR_PAGE", // from ogrpglayer.cpp + "OGR_PG_DEBUG_GGT_CANCEL", // from ogrpgtablelayer.cpp + "OGR_PG_DEFERRED_CREATION", // from ogrpgdatasource.cpp + "OGR_PG_ENABLE_METADATA", // from ogrpgdatasource.cpp, ogrpgtablelayer.cpp + "OGR_PG_JSON_TYPE", // from ogrpgdumplayer.cpp + "OGR_PG_RETRIEVE_FID", // from ogrpgtablelayer.cpp + "OGR_PG_SKIP_CONFLICTS", // from ogrpgtablelayer.cpp + "OGR_PG_STRING_TYPE", // from ogrpgdumplayer.cpp + "OGR_PG_UUID_TYPE", // from ogrpgdumplayer.cpp + "OGR_PMTILES_ITERATOR_THRESHOLD", // from ogrpmtilestileiterator.cpp + "OGR_PROMOTE_TO_INTEGER64", // from ogrgeopackagelayer.cpp, ogrsqlitelayer.cpp + "OGR_S57_OPTIONS", // from ogrs57datasource.cpp + "OGR_SETFIELD_NUMERIC_WARNING", // from ogrfeature.cpp + "OGR_SHAPE_ALLOW_NON_FINITE_COORDINATES", // from shape2ogr.cpp + "OGR_SHAPE_LOCK_DELAY", // from ogrshapedatasource.cpp + "OGR_SHAPE_PACK_IN_PLACE", // from ogrshapedatasource.cpp, ogrshapelayer.cpp + "OGR_SHAPE_USE_VSIMEM_FOR_TEMP", // from ogrshapedatasource.cpp + "OGR_SKIP", // from gdaldrivermanager.cpp + "OGR_SQL_LIKE_AS_ILIKE", // from ogrwfsfilter.cpp, swq_op_general.cpp + "OGR_SQL_STRICT", // from swq.cpp + "OGR_SQLITE_ALLOW_EXTERNAL_ACCESS", // from ogrsqlitesqlfunctionscommon.cpp + "OGR_SQLITE_CACHE", // from ogrgmldatasource.cpp, ogrsqlitedatasource.cpp + "OGR_SQLITE_DIALECT_ALLOW_CREATE_VIRTUAL_TABLE", // from ogrsqliteexecutesql.cpp + "OGR_SQLITE_DIALECT_USE_SPATIALITE", // from ogrsqliteexecutesql.cpp + "OGR_SQLITE_DISABLE_INSERT_TRIGGERS", // from ogrsqlitetablelayer.cpp + "OGR_SQLITE_ENABLE_DATETIME", // from ogrsqlitelayer.cpp, ogrsqlitetablelayer.cpp + "OGR_SQLITE_EXACT_EXTENT", // from ogrsqlitetablelayer.cpp + "OGR_SQLITE_JOURNAL", // from ogrsqlitedatasource.cpp + "OGR_SQLITE_LIST_VIRTUAL_OGR", // from ogrsqlitedatasource.cpp + "OGR_SQLITE_LOAD_EXTENSIONS", // from ogrsqlitedatasource.cpp + "OGR_SQLITE_PRAGMA", // from ogrgeopackagedatasource.cpp, ogrsqlitedatasource.cpp + "OGR_SQLITE_REGEXP", // from ogrsqliteregexp.cpp + "OGR_SQLITE_SPATIAL_FUNCTIONS", // from ogrsqlitesqlfunctions.cpp + "OGR_SQLITE_STATIC_VIRTUAL_OGR", // from ogrsqlitedatasource.cpp, ogrsqlitevirtualogr.cpp + "OGR_SQLITE_SYNCHRONOUS", // from ogr_geocoding.cpp, ogrgeopackagedatasource.cpp, ogrsqlitedatasource.cpp + "OGR_SQLITE_USE_CUSTOM_LIKE", // from ogrsqlitesqlfunctionscommon.cpp + "OGR_SQLITE_VFS_MAXPATHNAME", // from ogrsqlitevfs.cpp + "OGR_STROKE_CURVE", // from imdreader.cpp, ogrgeometryfactory.cpp + "OGR_TABLE_LIMIT", // from ogrgeopackagedatasource.cpp + "OGR_TILEDB_OPTIMIZED_ATTRIBUTE_FILTER", // from tiledbsparse.cpp + "OGR_TILEDB_WRITE_GEOMETRY_ATTRIBUTE_NAME", // from tiledbsparse.cpp + "OGR_TRUNCATE", // from ogrpgtablelayer.cpp + "OGR_VFK_DB_DELETE", // from vfkreadersqlite.cpp + "OGR_VFK_DB_NAME", // from vfkreadersqlite.cpp + "OGR_VFK_DB_OVERWRITE", // from vfkreadersqlite.cpp + "OGR_VFK_DB_READ", // from ogrsqlitedatasource.cpp + "OGR_VFK_DB_READ_ALL_BLOCKS", // from ogrvfkdatasource.cpp + "OGR_VFK_DB_SPATIAL", // from vfkreadersqlite.cpp + "OGR_VRT_FORCE_LOADING", // from ogrvrtdriver.cpp + "OGR_VRT_MAX_OPENED", // from ogrvrtdatasource.cpp + "OGR_WFS3_API_URL", // from ogroapifdriver.cpp + "OGR_WFS_BASE_START_INDEX", // from ogrwfsdatasource.cpp + "OGR_WFS_FIX_MAXFEATURES", // from ogrwfsdatasource.cpp + "OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN", // from ogrwfsdatasource.cpp + "OGR_WFS_PAGE_SIZE", // from ogrwfsdatasource.cpp + "OGR_WFS_PAGING_ALLOWED", // from ogrwfsdatasource.cpp + "OGR_WFS_TRUST_CAPABILITIES_BOUNDS", // from ogrwfsdatasource.cpp + "OGR_WFS_USE_STREAMING", // from ogrwfsjoinlayer.cpp, ogrwfslayer.cpp + "OGR_WKT_PRECISION", // from ogrgeometry.cpp + "OGR_WKT_ROUND", // from ogrgeometry.cpp + "OGR_XERCES_TERMINATE", // from ogr_xerces.cpp + "OGR_XERCES_USE_OGR_NET_ACCESSOR", // from ogr_xerces.cpp + "OGR_XLS_FIELD_TYPES", // from ogrxlslayer.cpp + "OGR_XLS_HEADERS", // from ogrxlslayer.cpp + "OGR_XLSX_FIELD_TYPES", // from ogrxlsxdatasource.cpp + "OGR_XLSX_HEADERS", // from ogrxlsxdatasource.cpp + "OPENCL_USE_CPU", // from gdalwarpkernel_opencl.cpp + "OPENFILEGDB_CREATE_FIELD_BEFORE_GEOMETRY", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_CREATOR", // from filegdbtable_write.cpp + "OPENFILEGDB_DEFAULT_STRING_WIDTH", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_FORCE_SPX_DEPTH", // from filegdbindex_write.cpp + "OPENFILEGDB_GRID_SIZE", // from filegdbindex_write.cpp + "OPENFILEGDB_IGNORE_GDBTABLX", // from filegdbtable.cpp + "OPENFILEGDB_IGNORE_GDBTABLX_ABSENCE", // from filegdbtable.cpp + "OPENFILEGDB_IN_MEMORY_SPI", // from ogropenfilegdblayer.cpp + "OPENFILEGDB_MAX_FEATURES_PER_SPX_PAGE", // from filegdbindex_write.cpp + "OPENFILEGDB_MODIFY_IN_PLACE", // from filegdbtable_write.cpp + "OPENFILEGDB_REGENERATE_GLOBALID", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_REPORT_DELETED_FEATURES", // from filegdbtable.cpp + "OPENFILEGDB_REPORT_GENUINE_FIELD_WIDTH", // from ogropenfilegdblayer.cpp + "OPENFILEGDB_REPRODUCIBLE_UUID", // from ogropenfilegdb_generate_uuid.cpp + "OPENFILEGDB_SIMUL_ERROR_IN_RewriteTableToAddLastAddedField", // from filegdbtable_write_fields.cpp + "OPENFILEGDB_SIMUL_WIN32", // from filegdbtable_write.cpp + "OPENFILEGDB_STRING_WIDTH", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_USE_GDBTABLE_RECORD_COUNT", // from filegdbtable.cpp + "OPENFILEGDB_USE_INDEX", // from ogropenfilegdbdatasource.cpp, ogropenfilegdblayer.cpp + "OPENFILEGDB_USE_SPATIAL_INDEX", // from ogropenfilegdblayer.cpp + "OPENFILEGDB_WRITE_LATESTVCSWKID", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_WRITE_LATESTWKID", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_WRITE_VCSWKID", // from ogropenfilegdblayer_write.cpp + "OPENFILEGDB_WRITE_WKID", // from ogropenfilegdblayer_write.cpp + "OS_APPLICATION_CREDENTIAL_ID", // from cpl_swift.cpp + "OS_APPLICATION_CREDENTIAL_SECRET", // from cpl_swift.cpp + "OS_AUTH_TYPE", // from cpl_swift.cpp + "OS_AUTH_URL", // from cpl_swift.cpp + "OS_IDENTITY_API_VERSION", // from cpl_swift.cpp + "OS_PASSWORD", // from cpl_swift.cpp + "OS_PROJECT_DOMAIN_NAME", // from cpl_swift.cpp + "OS_PROJECT_NAME", // from cpl_swift.cpp + "OS_REGION_NAME", // from cpl_swift.cpp + "OS_USER_DOMAIN_NAME", // from cpl_swift.cpp + "OS_USERNAME", // from cpl_swift.cpp + "OSM_COMPRESS_NODES", // from ogrosmdatasource.cpp + "OSM_CONFIG_FILE", // from ogrosmdatasource.cpp + "OSM_EXISTING_TMPFILE", // from ogrosmdatasource.cpp + "OSM_INDEX_POINTS", // from ogrosmdatasource.cpp + "OSM_INDEX_WAYS", // from ogrosmdatasource.cpp + "OSM_MAX_INDEXED_KEYS", // from ogrosmdatasource.cpp + "OSM_MAX_INDEXED_VALUES_PER_KEY", // from ogrosmdatasource.cpp + "OSM_MAX_TMPFILE_SIZE", // from ogrosmdatasource.cpp + "OSM_SQLITE_CACHE", // from ogrosmdatasource.cpp + "OSM_UNLINK_TMPFILE", // from ogrosmdatasource.cpp + "OSM_USE_CUSTOM_INDEXING", // from ogrosmdatasource.cpp + "OSM_USE_POINTS_INDEX", // from ogrosmdatasource.cpp + "OSM_USE_WAYS_INDEX", // from ogrosmdatasource.cpp + "OSR_ADD_TOWGS84_ON_EXPORT_TO_PROJ4", // from ogrspatialreference.cpp + "OSR_ADD_TOWGS84_ON_EXPORT_TO_WKT1", // from ogrspatialreference.cpp + "OSR_ADD_TOWGS84_ON_IMPORT_FROM_EPSG", // from ogrspatialreference.cpp + "OSR_CT_USE_DEFAULT_EPSG_TOWGS84", // from ogrct.cpp + "OSR_DEFAULT_AXIS_MAPPING_STRATEGY", // from ogrspatialreference.cpp + "OSR_IMPORT_FROM_WKT_LIMIT", // from ogrspatialreference.cpp + "OSR_STRIP_TOWGS84", // from gt_wkt_srs.cpp, hfaopen.cpp, ogrspatialreference.cpp + "OSR_USE_APPROX_TMERC", // from ogrct.cpp, ogrspatialreference.cpp + "OSR_USE_ETMERC", // from ogrct.cpp, ogrspatialreference.cpp + "OSR_USE_NON_DEPRECATED", // from ogrspatialreference.cpp + "OSR_WKT_FORMAT", // from ogrspatialreference.cpp + "OSS_ACCESS_KEY_ID", // from cpl_alibaba_oss.cpp + "OSS_ENDPOINT", // from cpl_alibaba_oss.cpp + "OSS_HTTPS", // from cpl_alibaba_oss.cpp + "OSS_SECRET_ACCESS_KEY", // from cpl_alibaba_oss.cpp + "OSS_VIRTUAL_HOSTING", // from cpl_alibaba_oss.cpp + "OZI_APPROX_GEOTRANSFORM", // from gdal_misc.cpp + "PDF_COORD_DOUBLE_PRECISION", // from pdfcreatefromcomposition.cpp + "PDF_DUMP_CATALOG", // from pdfdataset.cpp + "PDF_DUMP_CONTENT", // from pdfreadvectors.cpp + "PDF_DUMP_OBJECT", // from pdfdataset.cpp + "PDF_DUMP_PARENT", // from pdfdataset.cpp + "PDF_DUMP_STREAM", // from pdfdataset.cpp + "PDF_REPORT_GCPS", // from pdfdataset.cpp + "PDF_USE_CTM", // from pdfdataset.cpp + "PDS4_ENDIANNESS", // from pds4vector.cpp + "PDS4_FORCE_MASK", // from pds4dataset.cpp + "PDS4_SIGNEDNESS", // from pds4vector.cpp + "PDS_LineProjOffset_Mult", // from pdsdataset.cpp, vicardataset.cpp + "PDS_LineProjOffset_Shift", // from pdsdataset.cpp, vicardataset.cpp + "PDS_SampleProjOffset_Mult", // from pdsdataset.cpp, vicardataset.cpp + "PDS_SampleProjOffset_Shift", // from pdsdataset.cpp, vicardataset.cpp + "PG_COMMIT_WHEN_OVERWRITING", // from ogr2ogr_lib.cpp + "PG_DEFERRED_OVERVIEWS", // from postgisrasterdataset.cpp + "PG_LIST_ALL_TABLES", // from ogrpgdatasource.cpp + "PG_SKIP_VIEWS", // from ogrpgdatasource.cpp + "PG_USE_BASE64", // from ogrpgtablelayer.cpp + "PG_USE_COPY", // from ogrpgdatasource.cpp, ogrpgdumplayer.cpp, ogrpgtablelayer.cpp + "PG_USE_GEOGRAPHY", // from ogrpgdatasource.cpp + "PG_USE_POSTGIS", // from ogrpgdatasource.cpp + "PG_USE_POSTGIS2_OPTIM", // from ogrpgdatasource.cpp + "PGCLIENTENCODING", // from ogrpgdatasource.cpp + "PGDUMP_DEBUG_ALLOW_CREATION_FIELD_WITH_FID_NAME", // from ogrpgdumplayer.cpp + "PGEO_DRIVER_TEMPLATE", // from ogrpgeodatasource.cpp + "PGHOST", // from postgisrasterdataset.cpp + "PGPASSWORD", // from postgisrasterdataset.cpp + "PGPORT", // from postgisrasterdataset.cpp + "PGSQL_OGR_FID", // from ogrpgtablelayer.cpp + "PGUSER", // from postgisrasterdataset.cpp + "PHOTOMETRIC_OVERVIEW", // from gt_overview.cpp + "PL_API_KEY", // from ogrplscenesdatav1dataset.cpp, plmosaicdataset.cpp + "PL_CACHE_PATH", // from plmosaicdataset.cpp + "PL_MOSAIC_LIST_QUAD_DOWNLOAD_ONLY", // from plmosaicdataset.cpp + "PL_URL", // from ogrplscenesdatav1dataset.cpp, plmosaicdataset.cpp + "PLSCENES_PAGE_SIZE", // from ogrplscenesdatav1layer.cpp + "PR_ALLOW_WHOLE_TABLE_SCAN", // from postgisrasterdataset.cpp + "PR_BLOCKXSIZE", // from postgisrasterrasterband.cpp + "PR_BLOCKYSIZE", // from postgisrasterrasterband.cpp + "PR_DISABLE_GIST", // from postgisrasterdataset.cpp + "PR_DISABLE_PK", // from postgisrasterdataset.cpp + "PR_FORCE_LOAD_RASTERS", // from postgisrasterdataset.cpp + "PR_NS_RES", // from postgisrasterdataset.cpp + "PR_RESOLUTION_STRATEGY", // from postgisrasterdataset.cpp + "PR_WE_RES", // from postgisrasterdataset.cpp + "PREDICTOR_OVERVIEW", // from gt_overview.cpp + "PREFERRED_OPENCL_VENDOR", // from gdalwarpkernel_opencl.cpp + "PROJ_DATA", // from ogr_proj_p.cpp + "PROJ_LIB", // from ogr_proj_p.cpp + "PST_INSTANCE", // from jpipkakdataset.cpp + "PST_OFFSET", // from jpipkakdataset.cpp + "PYTHONSO", // from gdalpython.cpp + "QGIS_HACK", // from ogrfeaturedefn.cpp + "QHULL_LOG_TO_TEMP_FILE", // from delaunay.c + "RASTERLITE_OVR_OPTIONS", // from rasterliteoverviews.cpp + "RAW_CHECK_FILE_SIZE", // from rawdataset.cpp + "RAW_MEM_ALLOC_LIMIT_MB", // from rawdataset.cpp + "REPORT_COMPD_CS", // from dteddataset.cpp, srtmhgtdataset.cpp + "RESTRICT_OUTPUT_DATASET_UPDATE", // from gdalwarp_lib.cpp + "RL2_SHOW_ALL_PYRAMID_LEVELS", // from rasterlite2.cpp + "RMF_SET_VERTCS", // from rmfdataset.cpp + "RPC_INVERSE_LOG", // from gdal_rpc.cpp + "RPC_INVERSE_VERBOSE", // from gdal_rpc.cpp + "RPFTOC_FORCE_RGBA", // from rpftocdataset.cpp + "RPFTOC_MAX_FRAME_COUNT", // from rpftocfile.cpp + "S57_CSV", // from s57classregistrar.cpp + "S57_PROFILE", // from s57classregistrar.cpp + "SENTINEL2_USE_MAIN_MTD", // from sentinel2dataset.cpp + "SHAPE_2GB_LIMIT", // from ogrshapedatasource.cpp + "SHAPE_ENCODING", // from ogrshapelayer.cpp + "SHAPE_RESTORE_SHX", // from ogrshapedatasource.cpp + "SHAPE_REWIND_ON_WRITE", // from ogrshapelayer.cpp + "SPARSE_OK_OVERVIEW", // from gt_overview.cpp + "SPATIALITE_INIT_VERBOSE", // from ogrsqlitedatasource.cpp + "SPATIALITE_LOAD", // from ogrsqlitedatasource.cpp + "SPATIALITESO", // from ogrsqlitedatasource.cpp + "SQLITE_BUSY_TIMEOUT", // from ogrsqlitedatasource.cpp + "SQLITE_LIST_ALL_TABLES", // from ogrsqlitedatasource.cpp + "SQLITE_USE_OGR_VFS", // from ogrsqlitedatasource.cpp + "SQLITE_USE_URI", // from ogrsqlitedatasource.cpp, ogrsqlitedriver.cpp + "SRP_SINGLE_GEN_IN_THF_AS_DATASET", // from srpdataset.cpp + "SSL_CERT_FILE", // from cpl_http.cpp + "SWIFT_AUTH_TOKEN", // from cpl_swift.cpp + "SWIFT_AUTH_V1_URL", // from cpl_swift.cpp + "SWIFT_KEY", // from cpl_swift.cpp + "SWIFT_MAX_KEYS", // from cpl_vsil_swift.cpp + "SWIFT_STORAGE_URL", // from cpl_swift.cpp + "SWIFT_USER", // from cpl_swift.cpp + "SXF_LAYER_FULLNAME", // from ogrsxfdatasource.cpp + "SXF_RSC_FILENAME", // from ogrsxfdatasource.cpp + "SXF_SET_VERTCS", // from ogrsxfdatasource.cpp + "TAB_APPROX_GEOTRANSFORM", // from gdal_misc.cpp + "TEMP", // from cpl_path.cpp, gdalwmscache.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "THRESHOLD", // from ogrct.cpp + "TIFF_READ_STREAMING", // from gtiffdataset_read.cpp + "TIFF_USE_OVR", // from gtiffdataset_write.cpp + "TIGER_LFIELD_AS_STRING", // from tigerfilebase.cpp + "TIGER_VERSION", // from ogrtigerdatasource.cpp + "TILEDB_ATTRIBUTE", // from tiledbdense.cpp + "TILEDB_BINARY_TYPE", // from tiledbsparse.cpp + "TILEDB_BUG", // from tiledbsparse.cpp + "TILEDB_GEOTIFF_OVERVIEWS", // from tiledbdense.cpp + "TILEDB_INT_TYPE", // from tiledbsparse.cpp + "TILEDB_WKB_GEOMETRY_TYPE", // from tiledbsparse.cpp + "TILEDB_WRITE_IMAGE_STRUCTURE", // from tiledbdense.cpp + "TMPDIR", // from cpl_path.cpp, gdalwmscache.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "USE_OSR_FIND_MATCHES", // from FGdbUtils.cpp, ogropenfilegdbdatasource.cpp, ogrshapelayer.cpp + "USE_RRD", // from gdaldefaultoverviews.cpp, gtiffdataset_write.cpp, pcidskdataset2.cpp + "USE_SPILL", // from hfaband.cpp + "USE_SQLITE_DEBUG_MEMALLOC", // from ogrsqlitedatasource.cpp + "USE_TEMPFILE", // from ogrgpsbabeldatasource.cpp, ogrgpsbabelwritedatasource.cpp + "USE_TILE_AS_BLOCK", // from jp2kakdataset.cpp + "USER", // from gdalwmscache.cpp, isis3dataset.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "USERNAME", // from gdalwmscache.cpp, isis3dataset.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "USERPROFILE", // from cpl_aws.cpp, cpl_azure.cpp, cpl_conv.cpp, cpl_google_cloud.cpp, cpl_path.cpp, gdalwmscache.cpp, ogrgmlasconf.cpp, wcsutils.cpp + "VRT_ALLOW_MEM_DRIVER", // from vrtrasterband.cpp + "VRT_MIN_MAX_FROM_SOURCES", // from vrtsourcedrasterband.cpp + "VRT_NUM_THREADS", // from vrtdataset.cpp + "VRT_SHARED_SOURCE", // from vrtsources.cpp + "VRT_VIRTUAL_OVERVIEWS", // from gdalbuildvrt_lib.cpp, vrtdataset.cpp + "VSI_CACHE", // from cpl_vsil_curl.cpp, cpl_vsil_curl_streaming.cpp, cpl_vsil_unix_stdio_64.cpp, cpl_vsil_win32.cpp + "VSI_CACHE_SIZE", // from cpl_vsil_cache.cpp + "VSI_FLUSH", // from cpl_vsil_win32.cpp + "VSIAZ_CHUNK_SIZE", // from cpl_vsil_az.cpp + "VSIAZ_CHUNK_SIZE_BYTES", // from cpl_vsil_az.cpp + "VSICRYPT_ADD_KEY_CHECK", // from cpl_vsil_crypt.cpp + "VSICRYPT_ALG", // from cpl_vsil_crypt.cpp + "VSICRYPT_CRYPTO_RANDOM", // from cpl_vsil_crypt.cpp + "VSICRYPT_DISPLAY_GENERATED_KEY", // from cpl_vsil_crypt.cpp + "VSICRYPT_FREETEXT", // from cpl_vsil_crypt.cpp + "VSICRYPT_IV", // from cpl_vsil_crypt.cpp + "VSICRYPT_KEY", // from cpl_vsil_crypt.cpp + "VSICRYPT_KEY_B64", // from cpl_vsil_crypt.cpp + "VSICRYPT_MODE", // from cpl_vsil_crypt.cpp + "VSICRYPT_SECTOR_SIZE", // from cpl_vsil_crypt.cpp + "VSICURL_PC_SAS_SIGN_HREF_URL", // from cpl_vsil_curl.cpp + "VSICURL_PC_SAS_TOKEN_URL", // from cpl_vsil_curl.cpp + "VSICURL_PC_URL_SIGNING", // from cpl_vsil_curl.cpp + "VSIS3_COPYFILE_USE_STREAMING_SOURCE", // from cpl_vsil_s3.cpp + "VSIS3_SIMULATE_THREADING", // from cpl_vsil_s3.cpp + "VSIS3_SYNC_MULTITHREADING", // from cpl_vsil_s3.cpp + "VSIWEBHDFS_SIZE", // from cpl_vsil_webhdfs.cpp + "VSIWEBHDFS_SIZE_BYTES", // from cpl_vsil_webhdfs.cpp + "WARP_THREAD_CHUNK_SIZE", // from gdalwarpkernel.cpp + "WEBHDFS_DATANODE_HOST", // from cpl_vsil_webhdfs.cpp + "WEBHDFS_DELEGATION", // from cpl_vsil_webhdfs.cpp + "WEBHDFS_PERMISSION", // from cpl_vsil_webhdfs.cpp + "WEBHDFS_REPLICATION", // from cpl_vsil_webhdfs.cpp + "WEBHDFS_USERNAME", // from cpl_vsil_webhdfs.cpp + "WEBP_LEVEL_OVERVIEW", // from gt_overview.cpp + "WEBP_LOSSLESS_OVERVIEW", // from gt_overview.cpp + "WMS_INFO_FORMAT", // from minidriver_wms.cpp + "XDG_CACHE_HOME", // from gdalwmscache.cpp + "ZARR_ALLOW_BIG_TILE_SIZE", // from zarr_v2_array.cpp, zarr_v3_array.cpp + "ZLEVEL_OVERVIEW", // from gt_overview.cpp + "ZMAP_EMIT_EOL_AT_END_OF_COLUMN", // from zmapdataset.cpp + "ZMAP_PIXEL_IS_POINT", // from zmapdataset.cpp + "ZSTD_LEVEL_OVERVIEW", // from gt_overview.cpp +}; +// clang-format on diff --git a/scripts/collect_config_options.py b/scripts/collect_config_options.py new file mode 100755 index 000000000000..753c5d680c2c --- /dev/null +++ b/scripts/collect_config_options.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 + +import glob +import os + +options = {} + + +def collect_config_options(filename): + lines = open(filename, "rt").readlines() + i = -1 + len_lines = len(lines) + + func_names = ["CPLGetConfigOption"] + if os.path.basename(filename) == "gt_overview.cpp": + func_names.append("GetOptionValue") + + while True: + i += 1 + if i >= len_lines: + break + l = lines[i][0:-1].strip() + if l.startswith("/*"): + continue + + found = False + for func_name in func_names: + pos = l.find(func_name + "(") + if pos >= 0: + pos_start = pos + len(func_name + "(") + option = None + if pos_start < len(l) and l[pos_start] == '"': + pos_end = l.find('"', pos_start + 1) + if pos_end + 1 < len(l) and l[pos_end + 1] == ",": + option = l[pos_start + 1 : pos_end] + else: + print("Skipping", l) + elif pos_start == len(l): + l = lines[i + 1][0:-1].strip() + pos_start = l.find('"') + assert pos_start >= 0, l + pos_end = l.find('"', pos_start + 1) + if pos_end + 1 < len(l) and l[pos_end + 1] == ",": + option = l[pos_start + 1 : pos_end] + elif ( + l + != """("OGR_" + GetDriverUCName() + "_USE_BBOX").c_str(), "YES")));""" + ): + print("Skipping", l) + if option: + if func_name == "GetOptionValue": + option += "_OVERVIEW" + if option not in options: + options[option] = set([os.path.basename(filename)]) + else: + options[option].add(os.path.basename(filename)) + + found = True + break + + if found: + continue + + pos = l.find("VSIGetPathSpecificOption(") + if pos >= 0 and l.find("VSIGetPathSpecificOption()") < 0: + pos_start = pos + len("VSIGetPathSpecificOption(") + option = None + if pos_start == len(l): + l += lines[i + 1][0:-1].strip() + ++i + + pos_start2 = l.find(', "', pos_start) + if pos_start2 < 0: + l += " " + lines[i + 1][0:-1].strip() + ++i + + pos_start2 = l.find(', "', pos_start) + if pos_start2 < 0: + if ( + l.endswith(', std::string("VSI")') + or l.endswith("VSIGetPathSpecificOption(pszFilename, pszFilename,") + or l.find("VSIGetPathSpecificOption(pszPath, pszKey, pszDefault)") + >= 0 + or l.find( + "VSIGetPathSpecificOption(osPathForOption.c_str(), osPathForOption.c_str()," + ) + >= 0 + or l.find( + "VSIGetPathSpecificOption(pszFilename, sTuple.pszEnvVar, nullptr)" + ) + >= 0 + or l.find( + "VSIGetPathSpecificOption(osNonStreamingFilename.c_str(), sTuple.pszEnvVar, nullptr)" + ) + >= 0 + or l.find( + "const char *VSIGetPathSpecificOption(const char *pszPath, const char *pszKey, const char *pszDefault)" + ) + >= 0 + ): + continue + assert pos_start2 >= 0, l + pos_end = l.find('"', pos_start2 + 3) + if pos_end + 1 < len(l) and l[pos_end + 1] == ",": + option = l[pos_start2 + 3 : pos_end] + else: + if ( + l.find( + 'VSIGetPathSpecificOption(osPathForOption.c_str(), pszOptionKey, "")' + ) + >= 0 + or l.find( + 'VSIGetPathSpecificOption(osPathForOption.c_str(), pszURLKey, "")' + ) + >= 0 + or l.find( + 'VSIGetPathSpecificOption(osPathForOption.c_str(), pszUserKey, "")' + ) + >= 0 + or l.find( + 'VSIGetPathSpecificOption(osPathForOption.c_str(), pszPasswordKey, "")' + ) + >= 0 + ): + continue + print("Skipping", l) + + if option: + if option not in options: + options[option] = set([os.path.basename(filename)]) + else: + options[option].add(os.path.basename(filename)) + + +def explore(dirname): + for filename in glob.glob(dirname + "/*"): + if os.path.isdir(filename): + explore(filename) + if filename.endswith(".c") or filename.endswith(".cpp"): + collect_config_options(filename) + + +for dirname in ("alg", "port", "gcore", "frmts", "ogr", "apps", "swig"): + explore(os.path.join(os.path.dirname(__file__), "..", dirname)) + +c_file = "// This file was automatically generated by collect_config_options.py\n" +c_file += "// DO NOT EDIT\n\n" +c_file += "// clang-format off\n" +c_file += "constexpr static const char* const apszKnownConfigOptions[] =\n" +c_file += "{\n" +for option in sorted(options, key=str.lower): + filename = ", ".join(sorted(options[option])) + c_file += f' "{option}", // from {filename}\n' +c_file += "};\n" +c_file += "// clang-format on\n" +# print(c_file) + +open( + os.path.join(os.path.dirname(__file__), "..", "port", "cpl_known_config_options.h"), + "wt", +).write(c_file) From 2afadad7ad21af96481ffe7853fb4692bb11bd07 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 10 Nov 2024 00:22:45 +0100 Subject: [PATCH 2/9] Add CPLIsDebugEnabled() --- port/cpl_conv.cpp | 26 ++++++++++++++++++++++++++ port/cpl_conv.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/port/cpl_conv.cpp b/port/cpl_conv.cpp index f1f68b4e8885..82ad36ae00e5 100644 --- a/port/cpl_conv.cpp +++ b/port/cpl_conv.cpp @@ -1903,6 +1903,26 @@ static void NotifyOtherComponentsConfigOptionChanged(const char *pszKey, } } +/************************************************************************/ +/* CPLIsDebugEnabled() */ +/************************************************************************/ + +static int gnDebug = -1; + +/** Returns whether CPL_DEBUG is enabled. + * + * @since 3.11 + */ +bool CPLIsDebugEnabled() +{ + if (gnDebug < 0) + { + gnDebug = CPLTestBool(CPLGetConfigOption("CPL_DEBUG", "OFF")); + } + + return gnDebug != 0; +} + /************************************************************************/ /* CPLSetConfigOption() */ /************************************************************************/ @@ -1945,6 +1965,9 @@ void CPL_STDCALL CPLSetConfigOption(const char *pszKey, const char *pszValue) OGRAPISPYCPLSetConfigOption(pszKey, pszValue); #endif + if (EQUAL(pszKey, "CPL_DEBUG") && pszValue) + gnDebug = CPLTestBool(pszValue); + g_papszConfigOptions = const_cast(CSLSetNameValue( const_cast(g_papszConfigOptions), pszKey, pszValue)); @@ -2005,6 +2028,9 @@ void CPL_STDCALL CPLSetThreadLocalConfigOption(const char *pszKey, if (bMemoryError) return; + if (EQUAL(pszKey, "CPL_DEBUG") && pszValue) + gnDebug = CPLTestBool(pszValue); + papszTLConfigOptions = CSLSetNameValue(papszTLConfigOptions, pszKey, pszValue); diff --git a/port/cpl_conv.h b/port/cpl_conv.h index f1d11eb06300..94670233f110 100644 --- a/port/cpl_conv.h +++ b/port/cpl_conv.h @@ -36,6 +36,8 @@ CPL_C_START void CPL_DLL CPLVerifyConfiguration(void); /*! @endcond */ +bool CPL_DLL CPLIsDebugEnabled(void); + const char CPL_DLL *CPL_STDCALL CPLGetConfigOption(const char *, const char *) CPL_WARN_UNUSED_RESULT; const char CPL_DLL *CPL_STDCALL CPLGetThreadLocalConfigOption( From d77436bca7512755cf80ddd4f76f8a748ca4eada Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 10 Nov 2024 00:33:51 +0100 Subject: [PATCH 3/9] Use CPLIsDebugEnabled() where possible --- gcore/gdalabstractbandblockcache.cpp | 3 +-- ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp | 3 +-- port/cpl_http.cpp | 2 +- port/cpl_known_config_options.h | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/gcore/gdalabstractbandblockcache.cpp b/gcore/gdalabstractbandblockcache.cpp index 42ea3114bd0d..1fa988c77ce6 100644 --- a/gcore/gdalabstractbandblockcache.cpp +++ b/gcore/gdalabstractbandblockcache.cpp @@ -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) { diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp index 4fce5b644754..41ceb0ea9d4c 100644 --- a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp +++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp @@ -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); diff --git a/port/cpl_http.cpp b/port/cpl_http.cpp index bc1068a4ae2e..26427cd2bc74 100644 --- a/port/cpl_http.cpp +++ b/port/cpl_http.cpp @@ -2124,7 +2124,7 @@ void *CPLHTTPSetOptions(void *pcurl, const char *pszURL, { unchecked_curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1); - if (CPLGetConfigOption("CPL_DEBUG", nullptr) != nullptr) + if (CPLIsDebugEnabled()) { unchecked_curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, CPLHTTPCurlDebugFunction); diff --git a/port/cpl_known_config_options.h b/port/cpl_known_config_options.h index ff5f0e714474..1a0336d541a9 100644 --- a/port/cpl_known_config_options.h +++ b/port/cpl_known_config_options.h @@ -100,7 +100,7 @@ constexpr static const char* const apszKnownConfigOptions[] = "CPL_CURL_VERBOSE", // from cpl_http.cpp, cpl_vsil_curl.cpp "CPL_CURL_VERBOSE_DATA_IN", // from cpl_http.cpp "CPL_CURL_VSIMEM_PRINT_HEADERS", // from cpl_http.cpp - "CPL_DEBUG", // from cpl_conv.cpp, cpl_error.cpp, cpl_http.cpp, gdalabstractbandblockcache.cpp, gdalinfo_bin.cpp, gdalsrsinfo.cpp, gdalwarp_bin.cpp, ogrgmlasreader.cpp + "CPL_DEBUG", // from cpl_conv.cpp, cpl_error.cpp, gdalinfo_bin.cpp, gdalsrsinfo.cpp, gdalwarp_bin.cpp "CPL_ENABLE_USERFAULTFD", // from cpl_userfaultfd.cpp "CPL_ERROR_SEPARATOR", // from cpl_error.cpp "CPL_GCE_CHECK_LOCAL_FILES", // from cpl_google_cloud.cpp From 182b892cae5e3c64a9ceb50a48d15c83afd0087c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 10 Nov 2024 01:19:43 +0100 Subject: [PATCH 4/9] EarlySetConfigOptions() / GDALGeneralCmdLineProcessor(): make sure setting CPL_DEBUG is done first --- apps/commonutils.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++-- gcore/gdal_misc.cpp | 65 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/apps/commonutils.cpp b/apps/commonutils.cpp index 3c5e3b29c7a8..664fce1ee545 100644 --- a/apps/commonutils.cpp +++ b/apps/commonutils.cpp @@ -60,13 +60,42 @@ 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) { @@ -74,6 +103,41 @@ void EarlySetConfigOptions(int argc, char **argv) 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; + } + } + } } /************************************************************************/ diff --git a/gcore/gdal_misc.cpp b/gcore/gdal_misc.cpp index dfbf7e7fe7d8..973e521f0083 100644 --- a/gcore/gdal_misc.cpp +++ b/gcore/gdal_misc.cpp @@ -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++) { /* -------------------------------------------------------------------- @@ -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); } @@ -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; } @@ -3631,7 +3691,6 @@ int CPL_STDCALL GDALGeneralCmdLineProcessor(int nArgc, char ***ppapszArgv, return -1; } - CPLSetConfigOption("CPL_DEBUG", papszArgv[iArg + 1]); iArg += 1; } From 74e16e3aaf2fe1ddd8248c358b75574cefb8c16c Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 10 Nov 2024 01:19:50 +0100 Subject: [PATCH 5/9] Emit a CE_Warning when CPLSet[Thread]ConfigOption() is called with a unknown config option, in debug mode and add CPLDeclareKnownConfigOption() --- autotest/cpp/test_cpl.cpp | 26 +++++--- doc/source/user/configoptions.rst | 14 +++++ port/cpl_conv.cpp | 98 ++++++++++++++++++++++++++++--- port/cpl_conv.h | 2 + 4 files changed, 123 insertions(+), 17 deletions(-) diff --git a/autotest/cpp/test_cpl.cpp b/autotest/cpp/test_cpl.cpp index ba43804e23b4..111510f688ad 100644 --- a/autotest/cpp/test_cpl.cpp +++ b/autotest/cpp/test_cpl.cpp @@ -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) diff --git a/doc/source/user/configoptions.rst b/doc/source/user/configoptions.rst index 3c9c4b7d8eaa..8c948bcb7cf5 100644 --- a/doc/source/user/configoptions.rst +++ b/doc/source/user/configoptions.rst @@ -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: diff --git a/port/cpl_conv.cpp b/port/cpl_conv.cpp index 82ad36ae00e5..0f160d6faaaa 100644 --- a/port/cpl_conv.cpp +++ b/port/cpl_conv.cpp @@ -55,6 +55,9 @@ #if HAVE_FCNTL_H #include #endif +#include +#include + #if HAVE_UNISTD_H #include #endif @@ -68,9 +71,6 @@ #include // isatty #endif -#ifdef DEBUG_CONFIG_OPTIONS -#include -#endif #include #if __cplusplus >= 202002L @@ -82,6 +82,7 @@ #include "cpl_string.h" #include "cpl_vsi.h" #include "cpl_vsil_curl_priv.h" +#include "cpl_known_config_options.h" #ifdef DEBUG #define OGRAPISPY_ENABLED @@ -1917,12 +1918,88 @@ bool CPLIsDebugEnabled() { if (gnDebug < 0) { + // Check that apszKnownConfigOptions is correctly sorted with + // STRCASECMP() criterion. + for (size_t i = 1; i < CPL_ARRAYSIZE(apszKnownConfigOptions); ++i) + { + if (STRCASECMP(apszKnownConfigOptions[i - 1], + apszKnownConfigOptions[i]) >= 0) + { + CPLError(CE_Failure, CPLE_AppDefined, + "ERROR: apszKnownConfigOptions[] isn't correctly " + "sorted: %s >= %s", + apszKnownConfigOptions[i - 1], + apszKnownConfigOptions[i]); + } + } gnDebug = CPLTestBool(CPLGetConfigOption("CPL_DEBUG", "OFF")); } return gnDebug != 0; } +/************************************************************************/ +/* CPLDeclareKnownConfigOption() */ +/************************************************************************/ + +static std::mutex goMutexDeclaredKnownConfigOptions; +static std::set goSetKnownConfigOptions; + +/** Declare that the specified configuration option is known. + * + * This is useful to avoid a warning to be emitted on unknown configuration + * options when CPL_DEBUG is enabled. + * + * @param pszKey Name of the configuration option to declare. + * @param pszDefinition Unused for now. Must be set to nullptr. + * @since 3.11 + */ +void CPLDeclareKnownConfigOption(const char *pszKey, + [[maybe_unused]] const char *pszDefinition) +{ + std::lock_guard oLock(goMutexDeclaredKnownConfigOptions); + goSetKnownConfigOptions.insert(CPLString(pszKey).toupper()); +} + +/************************************************************************/ +/* CPLSetConfigOptionDetectUnknownConfigOption() */ +/************************************************************************/ + +static void CPLSetConfigOptionDetectUnknownConfigOption(const char *pszKey, + const char *pszValue) +{ + if (EQUAL(pszKey, "CPL_DEBUG")) + { + gnDebug = pszValue ? CPLTestBool(pszValue) : false; + } + else if (CPLIsDebugEnabled()) + { + if (!std::binary_search(std::begin(apszKnownConfigOptions), + std::end(apszKnownConfigOptions), pszKey, + [](const char *a, const char *b) + { return STRCASECMP(a, b) < 0; })) + { + bool bFound; + { + std::lock_guard oLock(goMutexDeclaredKnownConfigOptions); + bFound = cpl::contains(goSetKnownConfigOptions, + CPLString(pszKey).toupper()); + } + if (!bFound) + { + const char *pszOldValue = CPLGetConfigOption(pszKey, nullptr); + if (!((!pszValue && !pszOldValue) || + (pszValue && pszOldValue && + EQUAL(pszValue, pszOldValue)))) + { + CPLError(CE_Warning, CPLE_AppDefined, + "Unknown configuration option '%s'.", pszKey); + } + } + } + } +} + /************************************************************************/ /* CPLSetConfigOption() */ /************************************************************************/ @@ -1941,13 +2018,18 @@ bool CPLIsDebugEnabled() * value provided during the last call will be used. * * Options can also be passed on the command line of most GDAL utilities - * with the with '--config KEY VALUE'. For example, - * ogrinfo --config CPL_DEBUG ON ~/data/test/point.shp + * with '--config KEY VALUE' (or '--config KEY=VALUE' since GDAL 3.10). + * For example, ogrinfo --config CPL_DEBUG ON ~/data/test/point.shp * * This function can also be used to clear a setting by passing NULL as the * value (note: passing NULL will not unset an existing environment variable; * it will just unset a value previously set by CPLSetConfigOption()). * + * Starting with GDAL 3.11, if CPL_DEBUG is enabled prior to this call, and + * CPLSetConfigOption() is called with a key that is neither a known + * configuration option of GDAL itself, or one that has been declared with + * CPLDeclareKnownConfigOption(), a warning will be emitted. + * * @param pszKey the key of the option * @param pszValue the value of the option, or NULL to clear a setting. * @@ -1965,8 +2047,7 @@ void CPL_STDCALL CPLSetConfigOption(const char *pszKey, const char *pszValue) OGRAPISPYCPLSetConfigOption(pszKey, pszValue); #endif - if (EQUAL(pszKey, "CPL_DEBUG") && pszValue) - gnDebug = CPLTestBool(pszValue); + CPLSetConfigOptionDetectUnknownConfigOption(pszKey, pszValue); g_papszConfigOptions = const_cast(CSLSetNameValue( const_cast(g_papszConfigOptions), pszKey, pszValue)); @@ -2028,8 +2109,7 @@ void CPL_STDCALL CPLSetThreadLocalConfigOption(const char *pszKey, if (bMemoryError) return; - if (EQUAL(pszKey, "CPL_DEBUG") && pszValue) - gnDebug = CPLTestBool(pszValue); + CPLSetConfigOptionDetectUnknownConfigOption(pszKey, pszValue); papszTLConfigOptions = CSLSetNameValue(papszTLConfigOptions, pszKey, pszValue); diff --git a/port/cpl_conv.h b/port/cpl_conv.h index 94670233f110..cdaaf34d0234 100644 --- a/port/cpl_conv.h +++ b/port/cpl_conv.h @@ -47,6 +47,8 @@ CPLGetGlobalConfigOption(const char *, const char *) CPL_WARN_UNUSED_RESULT; void CPL_DLL CPL_STDCALL CPLSetConfigOption(const char *, const char *); void CPL_DLL CPL_STDCALL CPLSetThreadLocalConfigOption(const char *pszKey, const char *pszValue); +void CPL_DLL CPLDeclareKnownConfigOption(const char *pszKey, + const char *pszDefinition); /** Callback for CPLSubscribeToSetConfigOption() */ typedef void (*CPLSetConfigOptionSubscriber)(const char *pszKey, From e4913d767cd7bfed2f3d8d741aad9d190b9a6a4a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Nov 2024 21:29:22 +0100 Subject: [PATCH 6/9] test_gdal2tiles: avoid failure on CI sanitize [ci skip] --- autotest/pyscripts/test_gdal2tiles.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/autotest/pyscripts/test_gdal2tiles.py b/autotest/pyscripts/test_gdal2tiles.py index e4012ce41468..7d3262a7f1a4 100755 --- a/autotest/pyscripts/test_gdal2tiles.py +++ b/autotest/pyscripts/test_gdal2tiles.py @@ -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" ) @@ -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" ) From 9e6c171f83fd871b3d3316e84912fc31aae6b2d6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Nov 2024 21:48:33 +0100 Subject: [PATCH 7/9] Revert "CI: homebrew: fix issue with pkgconf" This reverts commit f6945319679af19f2487cd76b1f62550fdb862ba. --- .github/workflows/cmake_builds.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.github/workflows/cmake_builds.yml b/.github/workflows/cmake_builds.yml index 28f7dbb7cf4c..938179c23dbd 100644 --- a/.github/workflows/cmake_builds.yml +++ b/.github/workflows/cmake_builds.yml @@ -625,26 +625,6 @@ 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 pkg-config@0.29.2. You can unlink it: - # brew unlink pkg-config@0.29.2 - # - # 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/pkg-config@0.29.2/0.29.2_3/bin/pkg-config - # /opt/homebrew/share/aclocal/pkg.m4 -> /opt/homebrew/Cellar/pkg-config@0.29.2/0.29.2_3/share/aclocal/pkg.m4 - # /opt/homebrew/share/man/man1/pkg-config.1 -> /opt/homebrew/Cellar/pkg-config@0.29.2/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 brew install --overwrite python@3.11 python@3.12 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 From 65a47f45ea216d767140e11b569fd47e79b70353 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Nov 2024 22:00:05 +0100 Subject: [PATCH 8/9] CI: homebrew: workaround again issue with pkg-config vs pkgconf --- .github/workflows/cmake_builds.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/cmake_builds.yml b/.github/workflows/cmake_builds.yml index 938179c23dbd..56c4324caa31 100644 --- a/.github/workflows/cmake_builds.yml +++ b/.github/workflows/cmake_builds.yml @@ -625,6 +625,9 @@ jobs: rm -rf /opt/homebrew/lib/node_modules # conflicts with node@18 from brew brew update brew outdated + 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 python@3.11 python@3.12 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 @@ -634,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} From edee5e90071b3a6a68ffefe4f87307cc6f00467f Mon Sep 17 00:00:00 2001 From: Krzysztof Dyba <35004826+kadyb@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:48:15 +0100 Subject: [PATCH 9/9] update gdal_sieve.rst --- doc/source/programs/gdal_sieve.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/programs/gdal_sieve.rst b/doc/source/programs/gdal_sieve.rst index 824e1e823efd..812df7d60a52 100644 --- a/doc/source/programs/gdal_sieve.rst +++ b/doc/source/programs/gdal_sieve.rst @@ -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.