Coverage Report

Created: 2025-06-13 06:29

/src/gdal/apps/commonutils.cpp
Line
Count
Source (jump to first uncovered line)
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
std::vector<std::string> GetOutputDriversFor(const char *pszDestFilename,
29
                                             int nFlagRasterVector)
30
0
{
31
0
    return CPLStringList(GDALGetOutputDriversForDatasetName(
32
0
        pszDestFilename, nFlagRasterVector, /* bSingleMatch = */ false,
33
0
        /* bEmitWarning = */ false));
34
0
}
35
36
/* -------------------------------------------------------------------- */
37
/*                      GetOutputDriverForRaster()                      */
38
/* -------------------------------------------------------------------- */
39
40
CPLString GetOutputDriverForRaster(const char *pszDestFilename)
41
0
{
42
0
    const CPLStringList aosList(GDALGetOutputDriversForDatasetName(
43
0
        pszDestFilename, GDAL_OF_RASTER, /* bSingleMatch = */ true,
44
0
        /* bEmitWarning = */ true));
45
0
    if (!aosList.empty())
46
0
    {
47
0
        CPLDebug("GDAL", "Using %s driver", aosList[0]);
48
0
        return aosList[0];
49
0
    }
50
0
    return CPLString();
51
0
}
52
53
/* -------------------------------------------------------------------- */
54
/*                        EarlySetConfigOptions()                       */
55
/* -------------------------------------------------------------------- */
56
57
void EarlySetConfigOptions(int argc, char **argv)
58
0
{
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
0
    for (int i = 1; i < argc; i++)
67
0
    {
68
0
        if (EQUAL(argv[i], "--config") && i + 1 < argc)
69
0
        {
70
0
            const char *pszArg = argv[i + 1];
71
0
            if (strchr(pszArg, '=') != nullptr)
72
0
            {
73
0
                char *pszKey = nullptr;
74
0
                const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
75
0
                if (pszKey && EQUAL(pszKey, "CPL_DEBUG") && pszValue)
76
0
                {
77
0
                    CPLSetConfigOption(pszKey, pszValue);
78
0
                }
79
0
                CPLFree(pszKey);
80
0
                ++i;
81
0
            }
82
0
            else
83
0
            {
84
0
                if (i + 2 >= argc)
85
0
                {
86
0
                    CPLError(CE_Failure, CPLE_AppDefined,
87
0
                             "--config option given without a key and value "
88
0
                             "argument.");
89
0
                    return;
90
0
                }
91
92
0
                if (EQUAL(argv[i + 1], "CPL_DEBUG"))
93
0
                {
94
0
                    CPLSetConfigOption(argv[i + 1], argv[i + 2]);
95
0
                }
96
97
0
                i += 2;
98
0
            }
99
0
        }
100
0
        else if (EQUAL(argv[i], "--debug") && i + 1 < argc)
101
0
        {
102
0
            CPLSetConfigOption("CPL_DEBUG", argv[i + 1]);
103
0
            i += 1;
104
0
        }
105
0
    }
106
0
    for (int i = 1; i < argc; i++)
107
0
    {
108
0
        if (EQUAL(argv[i], "--config") && i + 1 < argc)
109
0
        {
110
0
            const char *pszArg = argv[i + 1];
111
0
            if (strchr(pszArg, '=') != nullptr)
112
0
            {
113
0
                char *pszKey = nullptr;
114
0
                const char *pszValue = CPLParseNameValue(pszArg, &pszKey);
115
0
                if (pszKey && !EQUAL(pszKey, "CPL_DEBUG") && pszValue)
116
0
                {
117
0
                    CPLSetConfigOption(pszKey, pszValue);
118
0
                }
119
0
                CPLFree(pszKey);
120
0
                ++i;
121
0
            }
122
0
            else
123
0
            {
124
0
                if (i + 2 >= argc)
125
0
                {
126
0
                    CPLError(CE_Failure, CPLE_AppDefined,
127
0
                             "--config option given without a key and value "
128
0
                             "argument.");
129
0
                    return;
130
0
                }
131
132
0
                if (!EQUAL(argv[i + 1], "CPL_DEBUG"))
133
0
                {
134
0
                    CPLSetConfigOption(argv[i + 1], argv[i + 2]);
135
0
                }
136
137
0
                i += 2;
138
0
            }
139
0
        }
140
0
    }
141
0
}
142
143
/************************************************************************/
144
/*                          GDALRemoveBOM()                             */
145
/************************************************************************/
146
147
/* Remove potential UTF-8 BOM from data (must be NUL terminated) */
148
void GDALRemoveBOM(GByte *pabyData)
149
0
{
150
0
    if (pabyData[0] == 0xEF && pabyData[1] == 0xBB && pabyData[2] == 0xBF)
151
0
    {
152
0
        memmove(pabyData, pabyData + 3,
153
0
                strlen(reinterpret_cast<char *>(pabyData) + 3) + 1);
154
0
    }
155
0
}
156
157
/************************************************************************/
158
/*                            ArgIsNumeric()                            */
159
/************************************************************************/
160
161
int ArgIsNumeric(const char *pszArg)
162
163
0
{
164
0
    return CPLGetValueType(pszArg) != CPL_VALUE_STRING;
165
0
}
166
167
/************************************************************************/
168
/*                         GDALPatternMatch()                           */
169
/************************************************************************/
170
171
bool GDALPatternMatch(const char *input, const char *pattern)
172
173
0
{
174
0
    while (*input != '\0')
175
0
    {
176
0
        if (*pattern == '\0')
177
0
            return false;
178
179
0
        else if (*pattern == '?')
180
0
        {
181
0
            pattern++;
182
0
            if (static_cast<unsigned int>(*input) > 127)
183
0
            {
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
0
                {
189
0
                    input++;
190
0
                } while (static_cast<unsigned int>(*input) > 127);
191
0
            }
192
0
            else
193
0
            {
194
0
                input++;
195
0
            }
196
0
        }
197
0
        else if (*pattern == '*')
198
0
        {
199
0
            if (pattern[1] == '\0')
200
0
                return true;
201
202
            // Try eating varying amounts of the input till we get a positive.
203
0
            for (int eat = 0; input[eat] != '\0'; eat++)
204
0
            {
205
0
                if (GDALPatternMatch(input + eat, pattern + 1))
206
0
                    return true;
207
0
            }
208
209
0
            return false;
210
0
        }
211
0
        else
212
0
        {
213
0
            if (CPLTolower(*pattern) != CPLTolower(*input))
214
0
            {
215
0
                return false;
216
0
            }
217
0
            else
218
0
            {
219
0
                input++;
220
0
                pattern++;
221
0
            }
222
0
        }
223
0
    }
224
225
0
    if (*pattern != '\0' && strcmp(pattern, "*") != 0)
226
0
        return false;
227
0
    else
228
0
        return true;
229
0
}