Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Utilities
4 : * Purpose: Common utility routines
5 : * Author: Even Rouault, <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2011-2012, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "commonutils.h"
14 :
15 : #include <cstdio>
16 : #include <cstring>
17 :
18 : #include <string>
19 :
20 : #include "cpl_conv.h"
21 : #include "cpl_string.h"
22 : #include "gdal.h"
23 :
24 : /* -------------------------------------------------------------------- */
25 : /* GetOutputDriversFor() */
26 : /* -------------------------------------------------------------------- */
27 :
28 68 : std::vector<std::string> GetOutputDriversFor(const char *pszDestFilename,
29 : int nFlagRasterVector)
30 : {
31 136 : return CPLStringList(GDALGetOutputDriversForDatasetName(
32 : pszDestFilename, nFlagRasterVector, /* bSingleMatch = */ false,
33 136 : /* bEmitWarning = */ false));
34 : }
35 :
36 : /* -------------------------------------------------------------------- */
37 : /* GetOutputDriverForRaster() */
38 : /* -------------------------------------------------------------------- */
39 :
40 2050 : CPLString GetOutputDriverForRaster(const char *pszDestFilename)
41 : {
42 : const CPLStringList aosList(GDALGetOutputDriversForDatasetName(
43 : pszDestFilename, GDAL_OF_RASTER, /* bSingleMatch = */ true,
44 4100 : /* bEmitWarning = */ true));
45 2050 : if (!aosList.empty())
46 : {
47 2048 : CPLDebug("GDAL", "Using %s driver", aosList[0]);
48 2048 : return aosList[0];
49 : }
50 2 : return CPLString();
51 : }
52 :
53 : /* -------------------------------------------------------------------- */
54 : /* EarlySetConfigOptions() */
55 : /* -------------------------------------------------------------------- */
56 :
57 1068 : void EarlySetConfigOptions(int argc, char **argv)
58 : {
59 : // Must process some config options before GDALAllRegister() or
60 : // OGRRegisterAll(), but we can't call GDALGeneralCmdLineProcessor() or
61 : // OGRGeneralCmdLineProcessor(), because it needs the drivers to be
62 : // registered for the --format or --formats options.
63 :
64 : // Start with --debug, so that "my_command --config UNKNOWN_CONFIG_OPTION --debug on"
65 : // detects and warns about a unknown config option.
66 6759 : for (int i = 1; i < argc; i++)
67 : {
68 5693 : if (EQUAL(argv[i], "--config") && i + 1 < argc)
69 : {
70 37 : const char *pszArg = argv[i + 1];
71 37 : if (strchr(pszArg, '=') != nullptr)
72 : {
73 5 : char *pszKey = nullptr;
74 5 : const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
75 5 : if (pszKey && EQUAL(pszKey, "CPL_DEBUG") && pszValue)
76 : {
77 0 : CPLSetConfigOption(pszKey, pszValue);
78 : }
79 5 : CPLFree(pszKey);
80 5 : ++i;
81 : }
82 : else
83 : {
84 32 : if (i + 2 >= argc)
85 : {
86 2 : CPLError(CE_Failure, CPLE_AppDefined,
87 : "--config option given without a key and value "
88 : "argument.");
89 2 : return;
90 : }
91 :
92 30 : if (EQUAL(argv[i + 1], "CPL_DEBUG"))
93 : {
94 0 : CPLSetConfigOption(argv[i + 1], argv[i + 2]);
95 : }
96 :
97 30 : i += 2;
98 35 : }
99 : }
100 5656 : else if (EQUAL(argv[i], "--debug") && i + 1 < argc)
101 : {
102 7 : CPLSetConfigOption("CPL_DEBUG", argv[i + 1]);
103 7 : i += 1;
104 : }
105 : }
106 6760 : for (int i = 1; i < argc; i++)
107 : {
108 5694 : if (EQUAL(argv[i], "--config") && i + 1 < argc)
109 : {
110 35 : const char *pszArg = argv[i + 1];
111 35 : if (strchr(pszArg, '=') != nullptr)
112 : {
113 5 : char *pszKey = nullptr;
114 5 : const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
115 5 : if (pszKey && !EQUAL(pszKey, "CPL_DEBUG") && pszValue)
116 : {
117 5 : CPLSetConfigOption(pszKey, pszValue);
118 : }
119 5 : CPLFree(pszKey);
120 5 : ++i;
121 : }
122 : else
123 : {
124 30 : if (i + 2 >= argc)
125 : {
126 0 : CPLError(CE_Failure, CPLE_AppDefined,
127 : "--config option given without a key and value "
128 : "argument.");
129 0 : return;
130 : }
131 :
132 30 : if (!EQUAL(argv[i + 1], "CPL_DEBUG"))
133 : {
134 30 : CPLSetConfigOption(argv[i + 1], argv[i + 2]);
135 : }
136 :
137 30 : i += 2;
138 : }
139 : }
140 : }
141 : }
142 :
143 : /************************************************************************/
144 : /* GDALRemoveBOM() */
145 : /************************************************************************/
146 :
147 : /* Remove potential UTF-8 BOM from data (must be NUL terminated) */
148 6 : void GDALRemoveBOM(GByte *pabyData)
149 : {
150 6 : if (pabyData[0] == 0xEF && pabyData[1] == 0xBB && pabyData[2] == 0xBF)
151 : {
152 1 : memmove(pabyData, pabyData + 3,
153 1 : strlen(reinterpret_cast<char *>(pabyData) + 3) + 1);
154 : }
155 6 : }
156 :
157 : /************************************************************************/
158 : /* ArgIsNumeric() */
159 : /************************************************************************/
160 :
161 259 : int ArgIsNumeric(const char *pszArg)
162 :
163 : {
164 259 : return CPLGetValueType(pszArg) != CPL_VALUE_STRING;
165 : }
166 :
167 : /************************************************************************/
168 : /* GDALPatternMatch() */
169 : /************************************************************************/
170 :
171 109755 : bool GDALPatternMatch(const char *input, const char *pattern)
172 :
173 : {
174 109755 : while (*input != '\0')
175 : {
176 109699 : if (*pattern == '\0')
177 4 : return false;
178 :
179 109695 : else if (*pattern == '?')
180 : {
181 88 : pattern++;
182 88 : if (static_cast<unsigned int>(*input) > 127)
183 : {
184 : // Continuation bytes of such characters are of the form
185 : // 10xxxxxx (0x80), whereas single-byte are 0xxxxxxx
186 : // and the start of a multi-byte is 11xxxxxx
187 0 : do
188 : {
189 0 : input++;
190 0 : } while (static_cast<unsigned int>(*input) > 127);
191 : }
192 : else
193 : {
194 88 : input++;
195 : }
196 : }
197 109607 : else if (*pattern == '*')
198 : {
199 4993 : if (pattern[1] == '\0')
200 0 : return true;
201 :
202 : // Try eating varying amounts of the input till we get a positive.
203 102895 : for (int eat = 0; input[eat] != '\0'; eat++)
204 : {
205 97956 : if (GDALPatternMatch(input + eat, pattern + 1))
206 54 : return true;
207 : }
208 :
209 4939 : return false;
210 : }
211 : else
212 : {
213 104614 : if (CPLTolower(*pattern) != CPLTolower(*input))
214 : {
215 98536 : return false;
216 : }
217 : else
218 : {
219 6078 : input++;
220 6078 : pattern++;
221 : }
222 : }
223 : }
224 :
225 56 : if (*pattern != '\0' && strcmp(pattern, "*") != 0)
226 0 : return false;
227 : else
228 56 : return true;
229 : }
|