Coverage Report

Created: 2025-08-28 06:57

/src/gdal/gcore/gdalalgorithm.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  GDALAlgorithm class
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef GDAL_ALGORITHM_INCLUDED
14
#define GDAL_ALGORITHM_INCLUDED
15
16
#include "cpl_port.h"
17
#include "cpl_progress.h"
18
19
#include "gdal.h"
20
21
/************************************************************************/
22
/************************************************************************/
23
/*                      GDAL Algorithm C API                            */
24
/************************************************************************/
25
/************************************************************************/
26
27
CPL_C_START
28
29
/** Type of an argument */
30
typedef enum GDALAlgorithmArgType
31
{
32
    /** Boolean type. Value is a bool. */
33
    GAAT_BOOLEAN,
34
    /** Single-value string type. Value is a std::string */
35
    GAAT_STRING,
36
    /** Single-value integer type. Value is a int */
37
    GAAT_INTEGER,
38
    /** Single-value real type. Value is a double */
39
    GAAT_REAL,
40
    /** Dataset type. Value is a GDALArgDatasetValue */
41
    GAAT_DATASET,
42
    /** Multi-value string type. Value is a std::vector<std::string> */
43
    GAAT_STRING_LIST,
44
    /** Multi-value integer type. Value is a std::vector<int> */
45
    GAAT_INTEGER_LIST,
46
    /** Multi-value real type. Value is a std::vector<double> */
47
    GAAT_REAL_LIST,
48
    /** Multi-value dataset type. Value is a std::vector<GDALArgDatasetValue> */
49
    GAAT_DATASET_LIST,
50
} GDALAlgorithmArgType;
51
52
/** Return whether the argument type is a list / multi-valued one. */
53
bool CPL_DLL GDALAlgorithmArgTypeIsList(GDALAlgorithmArgType type);
54
55
/** Return the string representation of the argument type */
56
const char CPL_DLL *GDALAlgorithmArgTypeName(GDALAlgorithmArgType type);
57
58
/** Opaque C type for GDALArgDatasetValue */
59
typedef struct GDALArgDatasetValueHS *GDALArgDatasetValueH;
60
61
/** Opaque C type for GDALAlgorithmArg */
62
typedef struct GDALAlgorithmArgHS *GDALAlgorithmArgH;
63
64
/** Opaque C type for GDALAlgorithm */
65
typedef struct GDALAlgorithmHS *GDALAlgorithmH;
66
67
/** Opaque C type for GDALAlgorithmRegistry */
68
typedef struct GDALAlgorithmRegistryHS *GDALAlgorithmRegistryH;
69
70
/************************************************************************/
71
/*                  GDALAlgorithmRegistryH API                          */
72
/************************************************************************/
73
74
GDALAlgorithmRegistryH CPL_DLL GDALGetGlobalAlgorithmRegistry(void);
75
76
void CPL_DLL GDALAlgorithmRegistryRelease(GDALAlgorithmRegistryH);
77
78
char CPL_DLL **GDALAlgorithmRegistryGetAlgNames(GDALAlgorithmRegistryH);
79
80
GDALAlgorithmH CPL_DLL GDALAlgorithmRegistryInstantiateAlg(
81
    GDALAlgorithmRegistryH, const char *pszAlgName);
82
83
/************************************************************************/
84
/*                        GDALAlgorithmH API                            */
85
/************************************************************************/
86
87
void CPL_DLL GDALAlgorithmRelease(GDALAlgorithmH);
88
89
const char CPL_DLL *GDALAlgorithmGetName(GDALAlgorithmH);
90
91
const char CPL_DLL *GDALAlgorithmGetDescription(GDALAlgorithmH);
92
93
const char CPL_DLL *GDALAlgorithmGetLongDescription(GDALAlgorithmH);
94
95
const char CPL_DLL *GDALAlgorithmGetHelpFullURL(GDALAlgorithmH);
96
97
bool CPL_DLL GDALAlgorithmHasSubAlgorithms(GDALAlgorithmH);
98
99
char CPL_DLL **GDALAlgorithmGetSubAlgorithmNames(GDALAlgorithmH);
100
101
GDALAlgorithmH CPL_DLL
102
GDALAlgorithmInstantiateSubAlgorithm(GDALAlgorithmH, const char *pszSubAlgName);
103
104
bool CPL_DLL GDALAlgorithmParseCommandLineArguments(GDALAlgorithmH,
105
                                                    CSLConstList papszArgs);
106
107
GDALAlgorithmH CPL_DLL GDALAlgorithmGetActualAlgorithm(GDALAlgorithmH);
108
109
bool CPL_DLL GDALAlgorithmRun(GDALAlgorithmH, GDALProgressFunc pfnProgress,
110
                              void *pProgressData);
111
112
bool CPL_DLL GDALAlgorithmFinalize(GDALAlgorithmH);
113
114
char CPL_DLL *GDALAlgorithmGetUsageAsJSON(GDALAlgorithmH);
115
116
char CPL_DLL **GDALAlgorithmGetArgNames(GDALAlgorithmH);
117
118
GDALAlgorithmArgH CPL_DLL GDALAlgorithmGetArg(GDALAlgorithmH,
119
                                              const char *pszArgName);
120
121
GDALAlgorithmArgH CPL_DLL GDALAlgorithmGetArgNonConst(GDALAlgorithmH,
122
                                                      const char *pszArgName);
123
124
/************************************************************************/
125
/*                      GDALAlgorithmArgH API                           */
126
/************************************************************************/
127
128
void CPL_DLL GDALAlgorithmArgRelease(GDALAlgorithmArgH);
129
130
const char CPL_DLL *GDALAlgorithmArgGetName(GDALAlgorithmArgH);
131
132
GDALAlgorithmArgType CPL_DLL GDALAlgorithmArgGetType(GDALAlgorithmArgH);
133
134
const char CPL_DLL *GDALAlgorithmArgGetDescription(GDALAlgorithmArgH);
135
136
const char CPL_DLL *GDALAlgorithmArgGetShortName(GDALAlgorithmArgH);
137
138
char CPL_DLL **GDALAlgorithmArgGetAliases(GDALAlgorithmArgH);
139
140
const char CPL_DLL *GDALAlgorithmArgGetMetaVar(GDALAlgorithmArgH);
141
142
const char CPL_DLL *GDALAlgorithmArgGetCategory(GDALAlgorithmArgH);
143
144
bool CPL_DLL GDALAlgorithmArgIsPositional(GDALAlgorithmArgH);
145
146
bool CPL_DLL GDALAlgorithmArgIsRequired(GDALAlgorithmArgH);
147
148
int CPL_DLL GDALAlgorithmArgGetMinCount(GDALAlgorithmArgH);
149
150
int CPL_DLL GDALAlgorithmArgGetMaxCount(GDALAlgorithmArgH);
151
152
bool CPL_DLL GDALAlgorithmArgGetPackedValuesAllowed(GDALAlgorithmArgH);
153
154
bool CPL_DLL GDALAlgorithmArgGetRepeatedArgAllowed(GDALAlgorithmArgH);
155
156
char CPL_DLL **GDALAlgorithmArgGetChoices(GDALAlgorithmArgH);
157
158
char CPL_DLL **GDALAlgorithmArgGetMetadataItem(GDALAlgorithmArgH, const char *);
159
160
bool CPL_DLL GDALAlgorithmArgIsExplicitlySet(GDALAlgorithmArgH);
161
162
bool CPL_DLL GDALAlgorithmArgHasDefaultValue(GDALAlgorithmArgH);
163
164
bool CPL_DLL GDALAlgorithmArgGetDefaultAsBoolean(GDALAlgorithmArgH);
165
166
const char CPL_DLL *GDALAlgorithmArgGetDefaultAsString(GDALAlgorithmArgH);
167
168
int CPL_DLL GDALAlgorithmArgGetDefaultAsInteger(GDALAlgorithmArgH);
169
170
double CPL_DLL GDALAlgorithmArgGetDefaultAsDouble(GDALAlgorithmArgH);
171
172
char CPL_DLL **GDALAlgorithmArgGetDefaultAsStringList(GDALAlgorithmArgH);
173
174
const int CPL_DLL *GDALAlgorithmArgGetDefaultAsIntegerList(GDALAlgorithmArgH,
175
                                                           size_t *pnCount);
176
177
const double CPL_DLL *GDALAlgorithmArgGetDefaultAsDoubleList(GDALAlgorithmArgH,
178
                                                             size_t *pnCount);
179
180
bool CPL_DLL GDALAlgorithmArgIsHidden(GDALAlgorithmArgH);
181
182
bool CPL_DLL GDALAlgorithmArgIsHiddenForCLI(GDALAlgorithmArgH);
183
184
bool CPL_DLL GDALAlgorithmArgIsHiddenForAPI(GDALAlgorithmArgH);
185
186
bool CPL_DLL GDALAlgorithmArgIsOnlyForCLI(GDALAlgorithmArgH)
187
    CPL_WARN_DEPRECATED("Use GDALAlgorithmArgIsHiddenForAPI() instead");
188
189
bool CPL_DLL GDALAlgorithmArgIsInput(GDALAlgorithmArgH);
190
191
bool CPL_DLL GDALAlgorithmArgIsOutput(GDALAlgorithmArgH);
192
193
const char CPL_DLL *GDALAlgorithmArgGetMutualExclusionGroup(GDALAlgorithmArgH);
194
195
bool CPL_DLL GDALAlgorithmArgGetAsBoolean(GDALAlgorithmArgH);
196
197
const char CPL_DLL *GDALAlgorithmArgGetAsString(GDALAlgorithmArgH);
198
199
GDALArgDatasetValueH
200
    CPL_DLL GDALAlgorithmArgGetAsDatasetValue(GDALAlgorithmArgH);
201
202
int CPL_DLL GDALAlgorithmArgGetAsInteger(GDALAlgorithmArgH);
203
204
double CPL_DLL GDALAlgorithmArgGetAsDouble(GDALAlgorithmArgH);
205
206
char CPL_DLL **GDALAlgorithmArgGetAsStringList(GDALAlgorithmArgH);
207
208
const int CPL_DLL *GDALAlgorithmArgGetAsIntegerList(GDALAlgorithmArgH,
209
                                                    size_t *pnCount);
210
211
const double CPL_DLL *GDALAlgorithmArgGetAsDoubleList(GDALAlgorithmArgH,
212
                                                      size_t *pnCount);
213
214
bool CPL_DLL GDALAlgorithmArgSetAsBoolean(GDALAlgorithmArgH, bool);
215
216
bool CPL_DLL GDALAlgorithmArgSetAsString(GDALAlgorithmArgH, const char *);
217
218
bool CPL_DLL GDALAlgorithmArgSetAsDatasetValue(GDALAlgorithmArgH hArg,
219
                                               GDALArgDatasetValueH value);
220
221
bool CPL_DLL GDALAlgorithmArgSetDataset(GDALAlgorithmArgH hArg, GDALDatasetH);
222
223
bool CPL_DLL GDALAlgorithmArgSetDatasets(GDALAlgorithmArgH hArg, size_t nCount,
224
                                         GDALDatasetH *);
225
226
bool CPL_DLL GDALAlgorithmArgSetDatasetNames(GDALAlgorithmArgH hArg,
227
                                             CSLConstList);
228
229
bool CPL_DLL GDALAlgorithmArgSetAsInteger(GDALAlgorithmArgH, int);
230
231
bool CPL_DLL GDALAlgorithmArgSetAsDouble(GDALAlgorithmArgH, double);
232
233
bool CPL_DLL GDALAlgorithmArgSetAsStringList(GDALAlgorithmArgH, CSLConstList);
234
235
bool CPL_DLL GDALAlgorithmArgSetAsIntegerList(GDALAlgorithmArgH, size_t nCount,
236
                                              const int *pnValues);
237
238
bool CPL_DLL GDALAlgorithmArgSetAsDoubleList(GDALAlgorithmArgH, size_t nCount,
239
                                             const double *pnValues);
240
241
/** Binary-or combination of GDAL_OF_RASTER, GDAL_OF_VECTOR,
242
 * GDAL_OF_MULTIDIM_RASTER, possibly with GDAL_OF_UPDATE.
243
 */
244
typedef int GDALArgDatasetType;
245
246
GDALArgDatasetType CPL_DLL GDALAlgorithmArgGetDatasetType(GDALAlgorithmArgH);
247
248
/** Bit indicating that the name component of GDALArgDatasetValue is accepted. */
249
0
#define GADV_NAME (1 << 0)
250
/** Bit indicating that the dataset component of GDALArgDatasetValue is accepted. */
251
0
#define GADV_OBJECT (1 << 1)
252
253
int CPL_DLL GDALAlgorithmArgGetDatasetInputFlags(GDALAlgorithmArgH);
254
255
int CPL_DLL GDALAlgorithmArgGetDatasetOutputFlags(GDALAlgorithmArgH);
256
257
/************************************************************************/
258
/*                    GDALArgDatasetValueH API                          */
259
/************************************************************************/
260
261
GDALArgDatasetValueH CPL_DLL GDALArgDatasetValueCreate(void);
262
263
void CPL_DLL GDALArgDatasetValueRelease(GDALArgDatasetValueH);
264
265
const char CPL_DLL *GDALArgDatasetValueGetName(GDALArgDatasetValueH);
266
267
GDALDatasetH CPL_DLL GDALArgDatasetValueGetDatasetRef(GDALArgDatasetValueH);
268
269
GDALDatasetH
270
    CPL_DLL GDALArgDatasetValueGetDatasetIncreaseRefCount(GDALArgDatasetValueH);
271
272
void CPL_DLL GDALArgDatasetValueSetName(GDALArgDatasetValueH, const char *);
273
274
void CPL_DLL GDALArgDatasetValueSetDataset(GDALArgDatasetValueH, GDALDatasetH);
275
276
CPL_C_END
277
278
/************************************************************************/
279
/************************************************************************/
280
/*                      GDAL Algorithm C++ API                          */
281
/************************************************************************/
282
/************************************************************************/
283
284
// The rest of this header requires C++17
285
// _MSC_VER >= 1920 : Visual Studio >= 2019
286
#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) &&                 \
287
    (defined(DOXYGEN_SKIP) || __cplusplus >= 201703L || _MSC_VER >= 1920)
288
289
#include "cpl_error.h"
290
291
#include <limits>
292
#include <functional>
293
#include <map>
294
#include <memory>
295
#include <string>
296
#include <string_view>
297
#include <type_traits>
298
#include <utility>
299
#include <variant>
300
#include <vector>
301
302
class GDALDataset;
303
class OGRSpatialReference;
304
305
/** Common argument category */
306
constexpr const char *GAAC_COMMON = "Common";
307
308
/** Base argument category */
309
constexpr const char *GAAC_BASE = "Base";
310
311
/** Advanced argument category */
312
constexpr const char *GAAC_ADVANCED = "Advanced";
313
314
/** Esoteric argument category */
315
constexpr const char *GAAC_ESOTERIC = "Esoteric";
316
317
/** Argument metadata item that applies to the "input-format" and
318
 * "output-format" argument */
319
constexpr const char *GAAMDI_REQUIRED_CAPABILITIES = "required_capabilities";
320
321
/** Argument metadata item that applies to "output-format" argument */
322
constexpr const char *GAAMDI_VRT_COMPATIBLE = "vrt_compatible";
323
324
/** Name of the argument for an input dataset. */
325
constexpr const char *GDAL_ARG_NAME_INPUT = "input";
326
327
/** Name of the argument for the input format. */
328
constexpr const char *GDAL_ARG_NAME_INPUT_FORMAT = "input-format";
329
330
/** Name of the argument for the input layer. */
331
constexpr const char *GDAL_ARG_NAME_INPUT_LAYER = "input-layer";
332
333
/** Name of the argument for an open option. */
334
constexpr const char *GDAL_ARG_NAME_OPEN_OPTION = "open-option";
335
336
/** Name of the argument for an output dataset. */
337
constexpr const char *GDAL_ARG_NAME_OUTPUT = "output";
338
339
/** Name of the argument for an output string. */
340
constexpr const char *GDAL_ARG_NAME_OUTPUT_STRING = "output-string";
341
342
/** Name of the boolean argument to request outtputing directly on stdout. */
343
constexpr const char *GDAL_ARG_NAME_STDOUT = "stdout";
344
345
/** Name of the argument for an output format. */
346
constexpr const char *GDAL_ARG_NAME_OUTPUT_FORMAT = "output-format";
347
348
/** Name of the argument for the output layer. */
349
constexpr const char *GDAL_ARG_NAME_OUTPUT_LAYER = "output-layer";
350
351
/** Name of the argument for a creation option. */
352
constexpr const char *GDAL_ARG_NAME_CREATION_OPTION = "creation-option";
353
354
/** Name of the argument for a layer creation option. */
355
constexpr const char *GDAL_ARG_NAME_LAYER_CREATION_OPTION =
356
    "layer-creation-option";
357
358
/** Name of the argument for update. */
359
constexpr const char *GDAL_ARG_NAME_UPDATE = "update";
360
361
/** Name of the argument for overwriting a dataset. */
362
constexpr const char *GDAL_ARG_NAME_OVERWRITE = "overwrite";
363
364
/** Name of the argument for overwriting a layer. */
365
constexpr const char *GDAL_ARG_NAME_OVERWRITE_LAYER = "overwrite-layer";
366
367
/** Name of the argument for append. */
368
constexpr const char *GDAL_ARG_NAME_APPEND = "append";
369
370
/** Name of the argument for read-only. */
371
constexpr const char *GDAL_ARG_NAME_READ_ONLY = "read-only";
372
373
/** Name of the argument for number of threads (string). */
374
constexpr const char *GDAL_ARG_NAME_NUM_THREADS = "num-threads";
375
376
/** Name of the argument for number of threads (integer). */
377
constexpr const char *GDAL_ARG_NAME_NUM_THREADS_INT_HIDDEN =
378
    "num-threads-int-hidden";
379
380
/** Driver must expose GDAL_DCAP_RASTER or GDAL_DCAP_MULTIDIM_RASTER.
381
 * This is a potential value of GetMetadataItem(GAAMDI_REQUIRED_CAPABILITIES)
382
 */
383
constexpr const char *GDAL_ALG_DCAP_RASTER_OR_MULTIDIM_RASTER =
384
    "raster-or-multidim-raster";
385
386
/************************************************************************/
387
/*                           GDALArgDatasetValue                        */
388
/************************************************************************/
389
390
/** Return the string representation of GDALArgDatasetType */
391
std::string CPL_DLL GDALAlgorithmArgDatasetTypeName(GDALArgDatasetType);
392
393
class GDALAlgorithmArg;
394
395
/** Value for an argument that points to a GDALDataset.
396
 *
397
 * This is the value of arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
398
 */
399
class CPL_DLL GDALArgDatasetValue final
400
{
401
  public:
402
    /** Default (empty) constructor */
403
0
    GDALArgDatasetValue() = default;
404
405
    /** Constructor by dataset name. */
406
    explicit GDALArgDatasetValue(const std::string &name)
407
0
        : m_name(name), m_nameSet(true)
408
0
    {
409
0
    }
410
411
    /** Constructor by dataset instance, increasing its reference counter */
412
    explicit GDALArgDatasetValue(GDALDataset *poDS);
413
414
    /** Move constructor */
415
    GDALArgDatasetValue(GDALArgDatasetValue &&other);
416
417
    /** Destructor. Decrease m_poDS reference count, and destroy it if no
418
     * longer referenced. */
419
    ~GDALArgDatasetValue();
420
421
    /** Dereference the dataset object and close it if no longer referenced.
422
     * Return an error if an error occurred during dataset closing. */
423
    bool Close();
424
425
    /** Move-assignment operator */
426
    GDALArgDatasetValue &operator=(GDALArgDatasetValue &&other);
427
428
    /** Get the GDALDataset* instance (may be null), and increase its reference
429
     * count if not null. Once done with the dataset, the caller should call
430
     * GDALDataset::Release().
431
     */
432
    GDALDataset *GetDatasetIncreaseRefCount();
433
434
    /** Get a GDALDataset* instance (may be null). This does not modify the
435
     * reference counter, hence the lifetime of the returned object is not
436
     * guaranteed to exceed the one of this instance.
437
     */
438
    GDALDataset *GetDatasetRef()
439
0
    {
440
0
        return m_poDS;
441
0
    }
442
443
    /** Get a GDALDataset* instance (may be null). This does not modify the
444
     * reference counter, hence the lifetime of the returned object is not
445
     * guaranteed to exceed the one of this instance.
446
     */
447
    const GDALDataset *GetDatasetRef() const
448
0
    {
449
0
        return m_poDS;
450
0
    }
451
452
    /** Borrow the GDALDataset* instance (may be null), leaving its reference
453
     * counter unchanged.
454
     */
455
    GDALDataset *BorrowDataset()
456
0
    {
457
0
        GDALDataset *ret = m_poDS;
458
0
        m_poDS = nullptr;
459
0
        return ret;
460
0
    }
461
462
    /** Borrow the GDALDataset* instance from another GDALArgDatasetValue,
463
     * leaving its reference counter unchange.
464
     */
465
    void BorrowDatasetFrom(GDALArgDatasetValue &other)
466
0
    {
467
0
        Close();
468
0
        m_poDS = other.BorrowDataset();
469
0
        m_name = other.m_name;
470
0
    }
471
472
    /** Get dataset name */
473
    const std::string &GetName() const
474
0
    {
475
0
        return m_name;
476
0
    }
477
478
    /** Return whether a dataset name has been set */
479
    bool IsNameSet() const
480
0
    {
481
0
        return m_nameSet;
482
0
    }
483
484
    /** Set dataset name */
485
    void Set(const std::string &name);
486
487
    /** Transfer dataset to this instance (does not affect its reference
488
     * counter). */
489
    void Set(std::unique_ptr<GDALDataset> poDS);
490
491
    /** Set dataset object, increasing its reference counter. */
492
    void Set(GDALDataset *poDS);
493
494
    /** Set from other value, increasing the reference counter of the
495
     * GDALDataset object.
496
     */
497
    void SetFrom(const GDALArgDatasetValue &other);
498
499
    /** Set that the dataset has been opened by the algorithm */
500
    void SetDatasetOpenedByAlgorithm()
501
0
    {
502
0
        m_openedByAlgorithm = true;
503
0
    }
504
505
    /** Whether the dataset has been opened by the algorithm */
506
    bool HasDatasetBeenOpenedByAlgorithm() const
507
0
    {
508
0
        return m_openedByAlgorithm;
509
0
    }
510
511
  protected:
512
    friend class GDALAlgorithm;
513
514
    /** Set the argument that owns us. */
515
    void SetOwnerArgument(GDALAlgorithmArg *arg)
516
0
    {
517
0
        CPLAssert(!m_ownerArg);
518
0
        m_ownerArg = arg;
519
0
    }
520
521
  private:
522
    /** The owner argument (may be nullptr for freestanding objects) */
523
    GDALAlgorithmArg *m_ownerArg = nullptr;
524
525
    /** Dataset object. */
526
    GDALDataset *m_poDS = nullptr;
527
528
    /** Dataset name */
529
    std::string m_name{};
530
531
    /** Whether a dataset name (possibly empty for a MEM dataset...) has been set */
532
    bool m_nameSet = false;
533
534
    /** Whether the dataset has been opened by the algorithm */
535
    bool m_openedByAlgorithm = false;
536
537
    GDALArgDatasetValue(const GDALArgDatasetValue &) = delete;
538
    GDALArgDatasetValue &operator=(const GDALArgDatasetValue &) = delete;
539
};
540
541
/************************************************************************/
542
/*                           GDALAlgorithmArgDecl                       */
543
/************************************************************************/
544
545
/** Argument declaration.
546
 *
547
 * It does not hold its value.
548
 */
549
class CPL_DLL GDALAlgorithmArgDecl final
550
{
551
  public:
552
    /** Special value for the SetMaxCount() / GetMaxCount() to indicate
553
      * unlimited number of values. */
554
    static constexpr int UNBOUNDED = std::numeric_limits<int>::max();
555
556
    /** Constructor.
557
     *
558
     * @param longName Long name. Must be 2 characters at least. Must not start
559
     *                 with dash.
560
     * @param chShortName 1-letter short name, or NUL character
561
     * @param description Description.
562
     * @param type Type of the argument.
563
     */
564
    GDALAlgorithmArgDecl(const std::string &longName, char chShortName,
565
                         const std::string &description,
566
                         GDALAlgorithmArgType type);
567
568
    /** Declare an alias. Must be 2 characters at least. */
569
    GDALAlgorithmArgDecl &AddAlias(const std::string &alias)
570
0
    {
571
0
        m_aliases.push_back(alias);
572
0
        return *this;
573
0
    }
574
575
    /** Declare a shortname alias.*/
576
    GDALAlgorithmArgDecl &AddShortNameAlias(char shortNameAlias)
577
0
    {
578
0
        m_shortNameAliases.push_back(shortNameAlias);
579
0
        return *this;
580
0
    }
581
582
    /** Declare an hidden alias (i.e. not exposed in usage).
583
     * Must be 2 characters at least. */
584
    GDALAlgorithmArgDecl &AddHiddenAlias(const std::string &alias)
585
0
    {
586
0
        m_hiddenAliases.push_back(alias);
587
0
        return *this;
588
0
    }
589
590
    /** Declare that the argument is positional. Typically input / output files
591
     */
592
    GDALAlgorithmArgDecl &SetPositional()
593
0
    {
594
0
        m_positional = true;
595
0
        return *this;
596
0
    }
597
598
    /** Declare that the argument is required. Default is no
599
     */
600
    GDALAlgorithmArgDecl &SetRequired()
601
0
    {
602
0
        m_required = true;
603
0
        return *this;
604
0
    }
605
606
    /** Declare the "meta-var" hint.
607
     * By default, the meta-var value is the long name of the argument in
608
     * upper case.
609
     */
610
    GDALAlgorithmArgDecl &SetMetaVar(const std::string &metaVar)
611
0
    {
612
0
        m_metaVar = metaVar;
613
0
        return *this;
614
0
    }
615
616
    /** Declare the argument category: GAAC_COMMON, GAAC_BASE, GAAC_ADVANCED,
617
     * GAAC_ESOTERIC or a custom category.
618
     */
619
    GDALAlgorithmArgDecl &SetCategory(const std::string &category)
620
0
    {
621
0
        m_category = category;
622
0
        return *this;
623
0
    }
624
625
    /** Declare a default value for the argument.
626
     */
627
    template <class T> GDALAlgorithmArgDecl &SetDefault(const T &value)
628
0
    {
629
0
        m_hasDefaultValue = true;
630
0
        try
631
0
        {
632
0
            switch (m_type)
633
0
            {
634
0
                case GAAT_BOOLEAN:
635
0
                {
636
                    if constexpr (std::is_same_v<T, bool>)
637
0
                    {
638
0
                        m_defaultValue = value;
639
0
                        return *this;
640
0
                    }
641
0
                    break;
642
0
                }
643
644
0
                case GAAT_STRING:
645
0
                {
646
                    if constexpr (std::is_same_v<T, std::string>)
647
0
                    {
648
0
                        m_defaultValue = value;
649
0
                        return *this;
650
0
                    }
651
0
                    break;
652
0
                }
653
654
0
                case GAAT_INTEGER:
655
0
                {
656
                    if constexpr (std::is_same_v<T, int>)
657
                    {
658
                        m_defaultValue = value;
659
                        return *this;
660
                    }
661
0
                    break;
662
0
                }
663
664
0
                case GAAT_REAL:
665
0
                {
666
                    if constexpr (std::is_assignable_v<double &, T>)
667
0
                    {
668
0
                        m_defaultValue = static_cast<double>(value);
669
0
                        return *this;
670
0
                    }
671
0
                    break;
672
0
                }
673
674
0
                case GAAT_STRING_LIST:
675
0
                {
676
                    if constexpr (std::is_same_v<T, std::string>)
677
0
                    {
678
0
                        m_defaultValue = std::vector<std::string>{value};
679
0
                        return *this;
680
                    }
681
0
                    else if constexpr (std::is_same_v<T,
682
0
                                                      std::vector<std::string>>)
683
0
                    {
684
0
                        m_defaultValue = value;
685
0
                        return *this;
686
0
                    }
687
0
                    break;
688
0
                }
689
690
0
                case GAAT_INTEGER_LIST:
691
0
                {
692
                    if constexpr (std::is_same_v<T, int>)
693
                    {
694
                        m_defaultValue = std::vector<int>{value};
695
                        return *this;
696
                    }
697
0
                    else if constexpr (std::is_same_v<T, std::vector<int>>)
698
0
                    {
699
0
                        m_defaultValue = value;
700
0
                        return *this;
701
0
                    }
702
0
                    break;
703
0
                }
704
705
0
                case GAAT_REAL_LIST:
706
0
                {
707
                    if constexpr (std::is_assignable_v<double &, T>)
708
0
                    {
709
0
                        m_defaultValue =
710
0
                            std::vector<double>{static_cast<double>(value)};
711
0
                        return *this;
712
                    }
713
0
                    else if constexpr (std::is_same_v<T, std::vector<double>>)
714
0
                    {
715
0
                        m_defaultValue = value;
716
0
                        return *this;
717
0
                    }
718
0
                    break;
719
0
                }
720
721
0
                case GAAT_DATASET:
722
0
                case GAAT_DATASET_LIST:
723
0
                    break;
724
0
            }
725
0
        }
726
0
        catch (const std::bad_variant_access &)
727
0
        {
728
            // should not happen
729
            // fallthrough
730
0
        }
731
0
        CPLError(CE_Failure, CPLE_AppDefined,
732
0
                 "Argument %s: SetDefault(): unexpected type for value",
733
0
                 GetName().c_str());
734
0
        return *this;
735
0
    }
Unexecuted instantiation: GDALAlgorithmArgDecl& GDALAlgorithmArgDecl::SetDefault<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: GDALAlgorithmArgDecl& GDALAlgorithmArgDecl::SetDefault<bool>(bool const&)
736
737
    /** Declare a default value for the argument.
738
     */
739
    GDALAlgorithmArgDecl &SetDefault(const char *value)
740
0
    {
741
0
        return SetDefault(std::string(value));
742
0
    }
743
744
    /** Declare the minimum number of values for the argument. Defaults to 0.
745
     * Only applies to list type of arguments.
746
     * Setting it to non-zero does *not* make the argument required. It just
747
     * sets the minimum number of values when it is specified. To also make
748
     * it required, use SetRequired().
749
     */
750
    GDALAlgorithmArgDecl &SetMinCount(int count);
751
752
    /** Declare the maximum number of values for the argument.
753
     * Defaults to 1 for scalar types, and UNBOUNDED for list types.
754
     * Only applies to list type of arguments.
755
     */
756
    GDALAlgorithmArgDecl &SetMaxCount(int count);
757
758
    /** Declare whether in \--help message one should display hints about the
759
     * minimum/maximum number of values. Defaults to true.
760
     */
761
    GDALAlgorithmArgDecl &SetDisplayHintAboutRepetition(bool displayHint)
762
0
    {
763
0
        m_displayHintAboutRepetition = displayHint;
764
0
        return *this;
765
0
    }
766
767
    /** Declares whether, for list type of arguments, several values, space
768
     * separated, may be specified. That is "--foo=bar,baz".
769
     * The default is true.
770
     */
771
    GDALAlgorithmArgDecl &SetPackedValuesAllowed(bool allowed)
772
0
    {
773
0
        m_packedValuesAllowed = allowed;
774
0
        return *this;
775
0
    }
776
777
    /** Declares whether, for list type of arguments, the argument may be
778
     * repeated. That is "--foo=bar --foo=baz".
779
     * The default is true.
780
     */
781
    GDALAlgorithmArgDecl &SetRepeatedArgAllowed(bool allowed)
782
0
    {
783
0
        m_repeatedArgAllowed = allowed;
784
0
        return *this;
785
0
    }
786
787
    //! @cond Doxygen_Suppress
788
    GDALAlgorithmArgDecl &SetChoices()
789
0
    {
790
0
        return *this;
791
0
    }
792
793
    //! @endcond
794
795
    /** Declares the allowed values (as strings) for the argument.
796
     * Only honored for GAAT_STRING and GAAT_STRING_LIST types.
797
     */
798
    template <
799
        typename T, typename... U,
800
        typename std::enable_if<!std::is_same_v<T, std::vector<std::string> &>,
801
                                bool>::type = true>
802
    GDALAlgorithmArgDecl &SetChoices(T &&first, U &&...rest)
803
0
    {
804
0
        m_choices.push_back(std::forward<T>(first));
805
0
        SetChoices(std::forward<U>(rest)...);
806
0
        return *this;
807
0
    }
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA5_KcJS3_RA7_S1_RA6_S1_S5_S7_S5_S7_S5_S5_RA8_S1_S9_S9_RA9_S1_SB_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSC_6vectorINSC_12basic_stringIcNSC_11char_traitsIcEENSC_9allocatorIcEEEENSJ_ISL_EEEEEEbE4typeELb1EEERS_OSE_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA5_KcJRA7_S1_RA6_S1_S5_S7_S5_S7_S5_S5_RA8_S1_S9_S9_RA9_S1_SB_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSC_6vectorINSC_12basic_stringIcNSC_11char_traitsIcEENSC_9allocatorIcEEEENSJ_ISL_EEEEEEbE4typeELb1EEERS_OSE_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA7_KcJRA6_S1_S3_S5_S3_S5_S3_S3_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA6_KcJRA7_S1_S3_S5_S3_S5_S5_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA7_KcJRA6_S1_S3_S5_S3_S3_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA6_KcJRA7_S1_S3_S5_S5_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA7_KcJRA6_S1_S3_S3_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA6_KcJRA7_S1_S5_RA8_S1_S7_S7_RA9_S1_S9_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNSA_6vectorINSA_12basic_stringIcNSA_11char_traitsIcEENSA_9allocatorIcEEEENSH_ISJ_EEEEEEbE4typeELb1EEERS_OSC_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA7_KcJS3_RA8_S1_S5_S5_RA9_S1_S7_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS8_6vectorINS8_12basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEENSF_ISH_EEEEEEbE4typeELb1EEERS_OSA_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA7_KcJRA8_S1_S5_S5_RA9_S1_S7_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS8_6vectorINS8_12basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEENSF_ISH_EEEEEEbE4typeELb1EEERS_OSA_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA8_KcJS3_S3_RA9_S1_S5_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS6_6vectorINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENSD_ISF_EEEEEEbE4typeELb1EEERS_OS8_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA8_KcJS3_RA9_S1_S5_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS6_6vectorINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENSD_ISF_EEEEEEbE4typeELb1EEERS_OS8_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA8_KcJRA9_S1_S5_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS6_6vectorINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENSD_ISF_EEEEEEbE4typeELb1EEERS_OS8_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA9_KcJS3_ETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS4_6vectorINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENSB_ISD_EEEEEEbE4typeELb1EEERS_OS6_DpOT0_
Unexecuted instantiation: _ZN20GDALAlgorithmArgDecl10SetChoicesIRA9_KcJETnNSt3__19enable_ifIXntsr3stdE9is_same_vIT_RNS4_6vectorINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENSB_ISD_EEEEEEbE4typeELb1EEERS_OS6_DpOT0_
808
809
    /** Declares the allowed values (as strings) for the argument.
810
     * Only honored for GAAT_STRING and GAAT_STRING_LIST types.
811
     */
812
    GDALAlgorithmArgDecl &SetChoices(const std::vector<std::string> &choices)
813
0
    {
814
0
        m_choices = choices;
815
0
        return *this;
816
0
    }
817
818
    /** Set the minimum (included) value allowed.
819
     *
820
     * Only taken into account on GAAT_INTEGER, GAAT_INTEGER_LIST,
821
     * GAAT_REAL and GAAT_REAL_LIST arguments.
822
     */
823
    GDALAlgorithmArgDecl &SetMinValueIncluded(double min)
824
0
    {
825
0
        m_minVal = min;
826
0
        m_minValIsIncluded = true;
827
0
        return *this;
828
0
    }
829
830
    /** Set the minimum (excluded) value allowed.
831
     *
832
     * Only taken into account on GAAT_INTEGER, GAAT_INTEGER_LIST,
833
     * GAAT_REAL and GAAT_REAL_LIST arguments.
834
     */
835
    GDALAlgorithmArgDecl &SetMinValueExcluded(double min)
836
0
    {
837
0
        m_minVal = min;
838
0
        m_minValIsIncluded = false;
839
0
        return *this;
840
0
    }
841
842
    /** Set the maximum (included) value allowed. */
843
    GDALAlgorithmArgDecl &SetMaxValueIncluded(double max)
844
0
    {
845
0
        m_maxVal = max;
846
0
        m_maxValIsIncluded = true;
847
0
        return *this;
848
0
    }
849
850
    /** Set the maximum (excluded) value allowed. */
851
    GDALAlgorithmArgDecl &SetMaxValueExcluded(double max)
852
0
    {
853
0
        m_maxVal = max;
854
0
        m_maxValIsIncluded = false;
855
0
        return *this;
856
0
    }
857
858
    /** Sets the minimum number of characters (for arguments of type
859
     * GAAT_STRING and GAAT_STRING_LIST)
860
     */
861
    GDALAlgorithmArgDecl &SetMinCharCount(int count)
862
0
    {
863
0
        m_minCharCount = count;
864
0
        return *this;
865
0
    }
866
867
    //! @cond Doxygen_Suppress
868
    GDALAlgorithmArgDecl &SetHiddenChoices()
869
0
    {
870
0
        return *this;
871
0
    }
872
873
    //! @endcond
874
875
    /** Declares the, hidden, allowed values (as strings) for the argument.
876
     * Only honored for GAAT_STRING and GAAT_STRING_LIST types.
877
     */
878
    template <typename T, typename... U>
879
    GDALAlgorithmArgDecl &SetHiddenChoices(T &&first, U &&...rest)
880
    {
881
        m_hiddenChoices.push_back(std::forward<T>(first));
882
        SetHiddenChoices(std::forward<U>(rest)...);
883
        return *this;
884
    }
885
886
    /** Declare that the argument must not be mentioned in CLI usage.
887
     * For example, "output-value" for "gdal raster info", which is only
888
     * meant when the algorithm is used from a non-CLI context.
889
     */
890
    GDALAlgorithmArgDecl &SetHiddenForCLI(bool hiddenForCLI = true)
891
0
    {
892
0
        m_hiddenForCLI = hiddenForCLI;
893
0
        return *this;
894
0
    }
895
896
    /** Declare that the argument is hidden in the context of an API use.
897
     * Said otherwise, if it is only for CLI usage.
898
     * For example "--help" */
899
    GDALAlgorithmArgDecl &SetHiddenForAPI(bool hiddenForAPI = true)
900
0
    {
901
0
        m_hiddenForAPI = hiddenForAPI;
902
0
        return *this;
903
0
    }
904
905
    /** Declare that the argument is hidden. Default is no.
906
     * This is equivalent to calling SetHiddenForCLI() and SetHiddenForAPI()
907
     */
908
    GDALAlgorithmArgDecl &SetHidden()
909
0
    {
910
0
        m_hiddenForCLI = true;
911
0
        m_hiddenForAPI = true;
912
0
        return *this;
913
0
    }
914
915
    /** Indicate whether the value of the argument is read-only during the
916
     * execution of the algorithm. Default is true.
917
     */
918
    GDALAlgorithmArgDecl &SetIsInput(bool isInput = true)
919
0
    {
920
0
        m_isInput = isInput;
921
0
        return *this;
922
0
    }
923
924
    /** Indicate whether (at least part of) the value of the argument is set
925
     * during the execution of the algorithm.
926
     * For example, "output-value" for "gdal raster info"
927
     * Default is false.
928
     * An argument may return both IsInput() and IsOutput() as true.
929
     * For example the "gdal raster convert" algorithm consumes the dataset
930
     * name of its "output" argument, and sets the dataset object during its
931
     * execution.
932
     */
933
    GDALAlgorithmArgDecl &SetIsOutput(bool isOutput = true)
934
0
    {
935
0
        m_isOutput = isOutput;
936
0
        return *this;
937
0
    }
938
939
    /** Set the name of the mutual exclusion group to which this argument
940
     * belongs to. At most one argument in a group can be specified.
941
     */
942
    GDALAlgorithmArgDecl &SetMutualExclusionGroup(const std::string &group)
943
0
    {
944
0
        m_mutualExclusionGroup = group;
945
0
        return *this;
946
0
    }
947
948
    /** Set user-defined metadata item.
949
     */
950
    GDALAlgorithmArgDecl &
951
    AddMetadataItem(const std::string &name,
952
                    const std::vector<std::string> &values)
953
0
    {
954
0
        m_metadata[name] = values;
955
0
        return *this;
956
0
    }
957
958
    /** Set that this (string) argument accepts the \@filename syntax to
959
     * mean that the content of the specified file should be used as the
960
     * value of the argument.
961
     */
962
    GDALAlgorithmArgDecl &SetReadFromFileAtSyntaxAllowed()
963
0
    {
964
0
        m_readFromFileAtSyntaxAllowed = true;
965
0
        return *this;
966
0
    }
967
968
    /** Sets that SQL comments must be removed from a (string) argument.
969
     */
970
    GDALAlgorithmArgDecl &SetRemoveSQLCommentsEnabled()
971
0
    {
972
0
        m_removeSQLComments = true;
973
0
        return *this;
974
0
    }
975
976
    /** Sets whether the dataset should be opened automatically by
977
     * GDALAlgorithm. Only applies to GAAT_DATASET and GAAT_DATASET_LIST.
978
     */
979
    GDALAlgorithmArgDecl &SetAutoOpenDataset(bool autoOpen)
980
0
    {
981
0
        m_autoOpenDataset = autoOpen;
982
0
        return *this;
983
0
    }
984
985
    /** Declares that this argument has been created on-the-fly from user-provided
986
     * argument.
987
     */
988
    GDALAlgorithmArgDecl &SetUserProvided()
989
0
    {
990
0
        m_userProvided = true;
991
0
        return *this;
992
0
    }
993
994
    /** Return the (long) name */
995
    inline const std::string &GetName() const
996
0
    {
997
0
        return m_longName;
998
0
    }
999
1000
    /** Return the short name, or empty string if there is none */
1001
    inline const std::string &GetShortName() const
1002
0
    {
1003
0
        return m_shortName;
1004
0
    }
1005
1006
    /** Return the aliases (potentially none) */
1007
    inline const std::vector<std::string> &GetAliases() const
1008
0
    {
1009
0
        return m_aliases;
1010
0
    }
1011
1012
    /** Return the shortname aliases (potentially none) */
1013
    inline const std::vector<char> &GetShortNameAliases() const
1014
0
    {
1015
0
        return m_shortNameAliases;
1016
0
    }
1017
1018
    /** Return the description */
1019
    inline const std::string &GetDescription() const
1020
0
    {
1021
0
        return m_description;
1022
0
    }
1023
1024
    /** Return the "meta-var" hint.
1025
     * By default, the meta-var value is the long name of the argument in
1026
     * upper case.
1027
     */
1028
    inline const std::string &GetMetaVar() const
1029
0
    {
1030
0
        return m_metaVar;
1031
0
    }
1032
1033
    /** Return the argument category: GAAC_COMMON, GAAC_BASE, GAAC_ADVANCED,
1034
     * GAAC_ESOTERIC or a custom category.
1035
     */
1036
    inline const std::string &GetCategory() const
1037
0
    {
1038
0
        return m_category;
1039
0
    }
1040
1041
    /** Return the type */
1042
    inline GDALAlgorithmArgType GetType() const
1043
0
    {
1044
0
        return m_type;
1045
0
    }
1046
1047
    /** Return the allowed values (as strings) for the argument.
1048
     * Only honored for GAAT_STRING and GAAT_STRING_LIST types.
1049
     */
1050
    inline const std::vector<std::string> &GetChoices() const
1051
0
    {
1052
0
        return m_choices;
1053
0
    }
1054
1055
    /** Return the allowed hidden values (as strings) for the argument.
1056
     * Only honored for GAAT_STRING and GAAT_STRING_LIST types.
1057
     */
1058
    inline const std::vector<std::string> &GetHiddenChoices() const
1059
0
    {
1060
0
        return m_hiddenChoices;
1061
0
    }
1062
1063
    /** Return the minimum value and whether it is included. */
1064
    inline std::pair<double, bool> GetMinValue() const
1065
0
    {
1066
0
        return {m_minVal, m_minValIsIncluded};
1067
0
    }
1068
1069
    /** Return the maximum value and whether it is included. */
1070
    inline std::pair<double, bool> GetMaxValue() const
1071
0
    {
1072
0
        return {m_maxVal, m_maxValIsIncluded};
1073
0
    }
1074
1075
    /** Return the minimum number of characters (for arguments of type
1076
     * GAAT_STRING and GAAT_STRING_LIST)
1077
     */
1078
    inline int GetMinCharCount() const
1079
0
    {
1080
0
        return m_minCharCount;
1081
0
    }
1082
1083
    /** Return whether the argument is required. Defaults to false.
1084
     */
1085
    inline bool IsRequired() const
1086
0
    {
1087
0
        return m_required;
1088
0
    }
1089
1090
    /** Return the minimum number of values for the argument. Defaults to 0.
1091
     * Only applies to list type of arguments.
1092
     */
1093
    inline int GetMinCount() const
1094
0
    {
1095
0
        return m_minCount;
1096
0
    }
1097
1098
    /** Return the maximum number of values for the argument.
1099
     * Defaults to 1 for scalar types, and UNBOUNDED for list types.
1100
     * Only applies to list type of arguments.
1101
     */
1102
    inline int GetMaxCount() const
1103
0
    {
1104
0
        return m_maxCount;
1105
0
    }
1106
1107
    /** Returns whether in \--help message one should display hints about the
1108
     * minimum/maximum number of values. Defaults to true.
1109
     */
1110
    inline bool GetDisplayHintAboutRepetition() const
1111
0
    {
1112
0
        return m_displayHintAboutRepetition;
1113
0
    }
1114
1115
    /** Return whether, for list type of arguments, several values, space
1116
     * separated, may be specified. That is "--foo=bar,baz".
1117
     * The default is true.
1118
     */
1119
    inline bool GetPackedValuesAllowed() const
1120
0
    {
1121
0
        return m_packedValuesAllowed;
1122
0
    }
1123
1124
    /** Return whether, for list type of arguments, the argument may be
1125
     * repeated. That is "--foo=bar --foo=baz".
1126
     * The default is true.
1127
     */
1128
    inline bool GetRepeatedArgAllowed() const
1129
0
    {
1130
0
        return m_repeatedArgAllowed;
1131
0
    }
1132
1133
    /** Return if the argument is a positional one. */
1134
    inline bool IsPositional() const
1135
0
    {
1136
0
        return m_positional;
1137
0
    }
1138
1139
    /** Return if the argument has a declared default value. */
1140
    inline bool HasDefaultValue() const
1141
0
    {
1142
0
        return m_hasDefaultValue;
1143
0
    }
1144
1145
    /** Return whether the argument is hidden.
1146
     */
1147
    inline bool IsHidden() const
1148
0
    {
1149
0
        return m_hiddenForCLI && m_hiddenForAPI;
1150
0
    }
1151
1152
    /** Return whether the argument must not be mentioned in CLI usage.
1153
     * For example, "output-value" for "gdal raster info", which is only
1154
     * meant when the algorithm is used from a non-CLI context.
1155
     */
1156
    inline bool IsHiddenForCLI() const
1157
0
    {
1158
0
        return m_hiddenForCLI;
1159
0
    }
1160
1161
    /** Return whether the argument is only for CLI usage.
1162
     * For example "--help"
1163
     * This is an alias for IsHiddenForAPI()
1164
     */
1165
    inline bool IsOnlyForCLI() const
1166
        CPL_WARN_DEPRECATED("Use IsHiddenForAPI() instead")
1167
0
    {
1168
0
        return m_hiddenForAPI;
1169
0
    }
1170
1171
    /** Return whether the argument is hidden for API usage
1172
     * For example "--help" */
1173
    inline bool IsHiddenForAPI() const
1174
0
    {
1175
0
        return m_hiddenForAPI;
1176
0
    }
1177
1178
    /** Indicate whether the value of the argument is read-only during the
1179
     * execution of the algorithm. Default is true.
1180
     */
1181
    inline bool IsInput() const
1182
0
    {
1183
0
        return m_isInput;
1184
0
    }
1185
1186
    /** Return whether (at least part of) the value of the argument is set
1187
     * during the execution of the algorithm.
1188
     * For example, "output-value" for "gdal raster info"
1189
     * Default is false.
1190
     * An argument may return both IsInput() and IsOutput() as true.
1191
     * For example the "gdal raster convert" algorithm consumes the dataset
1192
     * name of its "output" argument, and sets the dataset object during its
1193
     * execution.
1194
     */
1195
    inline bool IsOutput() const
1196
0
    {
1197
0
        return m_isOutput;
1198
0
    }
1199
1200
    /** Return the name of the mutual exclusion group to which this argument
1201
     * belongs to, or empty string if it does not belong to any exclusion
1202
     * group.
1203
     */
1204
    inline const std::string &GetMutualExclusionGroup() const
1205
0
    {
1206
0
        return m_mutualExclusionGroup;
1207
0
    }
1208
1209
    /** Return if this (string) argument accepts the \@filename syntax to
1210
     * mean that the content of the specified file should be used as the
1211
     * value of the argument.
1212
     */
1213
    inline bool IsReadFromFileAtSyntaxAllowed() const
1214
0
    {
1215
0
        return m_readFromFileAtSyntaxAllowed;
1216
0
    }
1217
1218
    /** Returns whether SQL comments must be removed from a (string) argument.
1219
     */
1220
    bool IsRemoveSQLCommentsEnabled() const
1221
0
    {
1222
0
        return m_removeSQLComments;
1223
0
    }
1224
1225
    /** Returns whether the dataset should be opened automatically by
1226
     * GDALAlgorithm. Only applies to GAAT_DATASET and GAAT_DATASET_LIST.
1227
     */
1228
    bool AutoOpenDataset() const
1229
0
    {
1230
0
        return m_autoOpenDataset;
1231
0
    }
1232
1233
    /** Returns whether the argument has been user-provided.
1234
     */
1235
    bool IsUserProvided() const
1236
0
    {
1237
0
        return m_userProvided;
1238
0
    }
1239
1240
    /** Get user-defined metadata. */
1241
    inline const std::map<std::string, std::vector<std::string>>
1242
    GetMetadata() const
1243
0
    {
1244
0
        return m_metadata;
1245
0
    }
1246
1247
    /** Get user-defined metadata by item name. */
1248
    inline const std::vector<std::string> *
1249
    GetMetadataItem(const std::string &name) const
1250
0
    {
1251
0
        const auto iter = m_metadata.find(name);
1252
0
        return iter == m_metadata.end() ? nullptr : &(iter->second);
1253
0
    }
1254
1255
    /** Return the default value of the argument.
1256
     * Must be called with T consistent of the type of the algorithm, and only
1257
     * if HasDefaultValue() is true.
1258
     * Valid T types are:
1259
     * - bool for GAAT_BOOLEAN
1260
     * - int for GAAT_INTEGER
1261
     * - double for GAAT_REAL
1262
     * - std::string for GAAT_STRING
1263
     * - GDALArgDatasetValue for GAAT_DATASET
1264
     * - std::vector<int> for GAAT_INTEGER_LIST
1265
     * - std::vector<double for GAAT_REAL_LIST
1266
     * - std::vector<std::string> for GAAT_STRING_LIST
1267
     * - std::vector<GDALArgDatasetValue> for GAAT_DATASET_LIST
1268
     */
1269
    template <class T> inline const T &GetDefault() const
1270
0
    {
1271
0
        return std::get<T>(m_defaultValue);
1272
0
    }
Unexecuted instantiation: bool const& GDALAlgorithmArgDecl::GetDefault<bool>() const
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& GDALAlgorithmArgDecl::GetDefault<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: int const& GDALAlgorithmArgDecl::GetDefault<int>() const
Unexecuted instantiation: double const& GDALAlgorithmArgDecl::GetDefault<double>() const
Unexecuted instantiation: std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const& GDALAlgorithmArgDecl::GetDefault<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >() const
Unexecuted instantiation: std::__1::vector<int, std::__1::allocator<int> > const& GDALAlgorithmArgDecl::GetDefault<std::__1::vector<int, std::__1::allocator<int> > >() const
Unexecuted instantiation: std::__1::vector<double, std::__1::allocator<double> > const& GDALAlgorithmArgDecl::GetDefault<std::__1::vector<double, std::__1::allocator<double> > >() const
1273
1274
    /** Get which type of dataset is allowed / generated.
1275
     * Binary-or combination of GDAL_OF_RASTER, GDAL_OF_VECTOR and
1276
     * GDAL_OF_MULTIDIM_RASTER, possibly combined with GDAL_OF_UPDATE.
1277
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1278
     */
1279
    GDALArgDatasetType GetDatasetType() const
1280
0
    {
1281
0
        return m_datasetType;
1282
0
    }
1283
1284
    /** Set which type of dataset is allowed / generated.
1285
     * Binary-or combination of GDAL_OF_RASTER, GDAL_OF_VECTOR and
1286
     * GDAL_OF_MULTIDIM_RASTER.
1287
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1288
     */
1289
    void SetDatasetType(GDALArgDatasetType type)
1290
0
    {
1291
0
        m_datasetType = type;
1292
0
    }
1293
1294
    /** Indicates which components among name and dataset are accepted as
1295
     * input, when this argument serves as an input.
1296
     *
1297
     * If the GADV_NAME bit is set, it indicates a dataset name is accepted as
1298
     * input.
1299
     * If the GADV_OBJECT bit is set, it indicates a dataset object is
1300
     * accepted as input.
1301
     * If both bits are set, the algorithm can accept either a name or a dataset
1302
     * object.
1303
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1304
     */
1305
    int GetDatasetInputFlags() const
1306
0
    {
1307
0
        return m_datasetInputFlags;
1308
0
    }
1309
1310
    /** Indicates which components among name and dataset are modified,
1311
     * when this argument serves as an output.
1312
     *
1313
     * If the GADV_NAME bit is set, it indicates a dataset name is generated as
1314
     * output (that is the algorithm will generate the name. Rarely used).
1315
     * If the GADV_OBJECT bit is set, it indicates a dataset object is
1316
     * generated as output, and available for use after the algorithm has
1317
     * completed.
1318
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1319
     */
1320
    int GetDatasetOutputFlags() const
1321
0
    {
1322
0
        return m_datasetOutputFlags;
1323
0
    }
1324
1325
    /** Set which components among name and dataset are accepted as
1326
     * input, when this argument serves as an input.
1327
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1328
     */
1329
    void SetDatasetInputFlags(int flags)
1330
0
    {
1331
0
        m_datasetInputFlags = flags;
1332
0
    }
1333
1334
    /** Set which components among name and dataset are modified when this
1335
     * argument serves as an output.
1336
     * Only applies to arguments of type GAAT_DATASET or GAAT_DATASET_LIST.
1337
     */
1338
    void SetDatasetOutputFlags(int flags)
1339
0
    {
1340
0
        m_datasetOutputFlags = flags;
1341
0
    }
1342
1343
  private:
1344
    const std::string m_longName;
1345
    const std::string m_shortName;
1346
    const std::string m_description;
1347
    const GDALAlgorithmArgType m_type;
1348
    std::string m_category = GAAC_BASE;
1349
    std::string m_metaVar{};
1350
    std::string m_mutualExclusionGroup{};
1351
    int m_minCount = 0;
1352
    int m_maxCount = 0;
1353
    bool m_required = false;
1354
    bool m_positional = false;
1355
    bool m_hasDefaultValue = false;
1356
    bool m_hiddenForCLI = false;
1357
    bool m_hiddenForAPI = false;
1358
    bool m_isInput = true;
1359
    bool m_isOutput = false;
1360
    bool m_packedValuesAllowed = true;
1361
    bool m_repeatedArgAllowed = true;
1362
    bool m_displayHintAboutRepetition = true;
1363
    bool m_readFromFileAtSyntaxAllowed = false;
1364
    bool m_removeSQLComments = false;
1365
    bool m_autoOpenDataset = true;
1366
    bool m_userProvided = false;
1367
    std::map<std::string, std::vector<std::string>> m_metadata{};
1368
    std::vector<std::string> m_aliases{};
1369
    std::vector<std::string> m_hiddenAliases{};
1370
    std::vector<char> m_shortNameAliases{};
1371
    std::vector<std::string> m_choices{};
1372
    std::vector<std::string> m_hiddenChoices{};
1373
    std::variant<bool, std::string, int, double, std::vector<std::string>,
1374
                 std::vector<int>, std::vector<double>>
1375
        m_defaultValue{};
1376
    double m_minVal = std::numeric_limits<double>::quiet_NaN();
1377
    double m_maxVal = std::numeric_limits<double>::quiet_NaN();
1378
    bool m_minValIsIncluded = false;
1379
    bool m_maxValIsIncluded = false;
1380
    int m_minCharCount = 0;
1381
    GDALArgDatasetType m_datasetType =
1382
        GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_MULTIDIM_RASTER;
1383
1384
    /** Which components among name and dataset are accepted as
1385
     * input, when this argument serves as an input.
1386
     */
1387
    int m_datasetInputFlags = GADV_NAME | GADV_OBJECT;
1388
1389
    /** Which components among name and dataset are generated as
1390
     * output, when this argument serves as an output.
1391
     */
1392
    int m_datasetOutputFlags = GADV_OBJECT;
1393
};
1394
1395
/************************************************************************/
1396
/*                           GDALAlgorithmArg                           */
1397
/************************************************************************/
1398
1399
class GDALAlgorithm;
1400
1401
/** Argument of an algorithm.
1402
 */
1403
class CPL_DLL GDALAlgorithmArg /* non-final */
1404
{
1405
  public:
1406
    /** Constructor */
1407
    template <class T>
1408
    GDALAlgorithmArg(const GDALAlgorithmArgDecl &decl, T *pValue)
1409
0
        : m_decl(decl), m_value(pValue)
1410
0
    {
1411
        if constexpr (!std::is_same_v<T, GDALArgDatasetValue> &&
1412
                      !std::is_same_v<T, std::vector<GDALArgDatasetValue>>)
1413
0
        {
1414
0
            if (decl.HasDefaultValue())
1415
0
            {
1416
0
                try
1417
0
                {
1418
0
                    *std::get<T *>(m_value) = decl.GetDefault<T>();
1419
0
                }
1420
0
                catch (const std::bad_variant_access &e)
1421
0
                {
1422
                    // I don't think that can happen, but Coverity Scan thinks
1423
                    // so
1424
0
                    CPLError(CE_Failure, CPLE_AppDefined,
1425
0
                             "*std::get<T *>(m_value) = decl.GetDefault<T>() "
1426
0
                             "failed: %s",
1427
0
                             e.what());
1428
0
                }
1429
0
            }
1430
0
        }
1431
0
    }
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(GDALAlgorithmArgDecl const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<bool>(GDALAlgorithmArgDecl const&, bool*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<int>(GDALAlgorithmArgDecl const&, int*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<double>(GDALAlgorithmArgDecl const&, double*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<GDALArgDatasetValue>(GDALAlgorithmArgDecl const&, GDALArgDatasetValue*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(GDALAlgorithmArgDecl const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<std::__1::vector<int, std::__1::allocator<int> > >(GDALAlgorithmArgDecl const&, std::__1::vector<int, std::__1::allocator<int> >*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<std::__1::vector<double, std::__1::allocator<double> > >(GDALAlgorithmArgDecl const&, std::__1::vector<double, std::__1::allocator<double> >*)
Unexecuted instantiation: GDALAlgorithmArg::GDALAlgorithmArg<std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> > >(GDALAlgorithmArgDecl const&, std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> >*)
1432
1433
    /** Destructor */
1434
    virtual ~GDALAlgorithmArg();
1435
1436
    /** Return the argument declaration. */
1437
    const GDALAlgorithmArgDecl &GetDeclaration() const
1438
0
    {
1439
0
        return m_decl;
1440
0
    }
1441
1442
    /** Alias for GDALAlgorithmArgDecl::GetName() */
1443
    inline const std::string &GetName() const
1444
0
    {
1445
0
        return m_decl.GetName();
1446
0
    }
1447
1448
    /** Alias for GDALAlgorithmArgDecl::GetShortName() */
1449
    inline const std::string &GetShortName() const
1450
0
    {
1451
0
        return m_decl.GetShortName();
1452
0
    }
1453
1454
    /** Alias for GDALAlgorithmArgDecl::GetAliases() */
1455
    inline const std::vector<std::string> &GetAliases() const
1456
0
    {
1457
0
        return m_decl.GetAliases();
1458
0
    }
1459
1460
    /** Alias for GDALAlgorithmArgDecl::GetShortNameAliases() */
1461
    inline const std::vector<char> &GetShortNameAliases() const
1462
0
    {
1463
0
        return m_decl.GetShortNameAliases();
1464
0
    }
1465
1466
    /** Alias for GDALAlgorithmArgDecl::GetDescription() */
1467
    inline const std::string &GetDescription() const
1468
0
    {
1469
0
        return m_decl.GetDescription();
1470
0
    }
1471
1472
    /** Alias for GDALAlgorithmArgDecl::GetMetaVar() */
1473
    inline const std::string &GetMetaVar() const
1474
0
    {
1475
0
        return m_decl.GetMetaVar();
1476
0
    }
1477
1478
    /** Alias for GDALAlgorithmArgDecl::GetType() */
1479
    inline GDALAlgorithmArgType GetType() const
1480
0
    {
1481
0
        return m_decl.GetType();
1482
0
    }
1483
1484
    /** Alias for GDALAlgorithmArgDecl::GetCategory() */
1485
    inline const std::string &GetCategory() const
1486
0
    {
1487
0
        return m_decl.GetCategory();
1488
0
    }
1489
1490
    /** Alias for GDALAlgorithmArgDecl::IsRequired() */
1491
    inline bool IsRequired() const
1492
0
    {
1493
0
        return m_decl.IsRequired();
1494
0
    }
1495
1496
    /** Alias for GDALAlgorithmArgDecl::GetMinCount() */
1497
    inline int GetMinCount() const
1498
0
    {
1499
0
        return m_decl.GetMinCount();
1500
0
    }
1501
1502
    /** Alias for GDALAlgorithmArgDecl::GetMaxCount() */
1503
    inline int GetMaxCount() const
1504
0
    {
1505
0
        return m_decl.GetMaxCount();
1506
0
    }
1507
1508
    /** Alias for GDALAlgorithmArgDecl::GetDisplayHintAboutRepetition() */
1509
    inline bool GetDisplayHintAboutRepetition() const
1510
0
    {
1511
0
        return m_decl.GetDisplayHintAboutRepetition();
1512
0
    }
1513
1514
    /** Alias for GDALAlgorithmArgDecl::GetPackedValuesAllowed() */
1515
    inline bool GetPackedValuesAllowed() const
1516
0
    {
1517
0
        return m_decl.GetPackedValuesAllowed();
1518
0
    }
1519
1520
    /** Alias for GDALAlgorithmArgDecl::GetRepeatedArgAllowed() */
1521
    inline bool GetRepeatedArgAllowed() const
1522
0
    {
1523
0
        return m_decl.GetRepeatedArgAllowed();
1524
0
    }
1525
1526
    /** Alias for GDALAlgorithmArgDecl::IsPositional() */
1527
    inline bool IsPositional() const
1528
0
    {
1529
0
        return m_decl.IsPositional();
1530
0
    }
1531
1532
    /** Alias for GDALAlgorithmArgDecl::GetChoices() */
1533
    inline const std::vector<std::string> &GetChoices() const
1534
0
    {
1535
0
        return m_decl.GetChoices();
1536
0
    }
1537
1538
    /** Alias for GDALAlgorithmArgDecl::GetHiddenChoices() */
1539
    inline const std::vector<std::string> &GetHiddenChoices() const
1540
0
    {
1541
0
        return m_decl.GetHiddenChoices();
1542
0
    }
1543
1544
    /** Return auto completion choices, if a auto completion function has been
1545
     * registered.
1546
     */
1547
    inline std::vector<std::string>
1548
    GetAutoCompleteChoices(const std::string &currentValue) const
1549
0
    {
1550
0
        if (m_autoCompleteFunction)
1551
0
            return m_autoCompleteFunction(currentValue);
1552
0
        return {};
1553
0
    }
1554
1555
    /** Alias for GDALAlgorithmArgDecl::GetMinValue() */
1556
    inline std::pair<double, bool> GetMinValue() const
1557
0
    {
1558
0
        return m_decl.GetMinValue();
1559
0
    }
1560
1561
    /** Alias for GDALAlgorithmArgDecl::GetMaxValue() */
1562
    inline std::pair<double, bool> GetMaxValue() const
1563
0
    {
1564
0
        return m_decl.GetMaxValue();
1565
0
    }
1566
1567
    /** Alias for GDALAlgorithmArgDecl::GetMinCharCount() */
1568
    inline int GetMinCharCount() const
1569
0
    {
1570
0
        return m_decl.GetMinCharCount();
1571
0
    }
1572
1573
    /** Return whether the argument value has been explicitly set with Set() */
1574
    inline bool IsExplicitlySet() const
1575
0
    {
1576
0
        return m_explicitlySet;
1577
0
    }
1578
1579
    /** Alias for GDALAlgorithmArgDecl::HasDefaultValue() */
1580
    inline bool HasDefaultValue() const
1581
0
    {
1582
0
        return m_decl.HasDefaultValue();
1583
0
    }
1584
1585
    /** Alias for GDALAlgorithmArgDecl::IsHidden() */
1586
    inline bool IsHidden() const
1587
0
    {
1588
0
        return m_decl.IsHidden();
1589
0
    }
1590
1591
    /** Alias for GDALAlgorithmArgDecl::IsHiddenForCLI() */
1592
    inline bool IsHiddenForCLI() const
1593
0
    {
1594
0
        return m_decl.IsHiddenForCLI();
1595
0
    }
1596
1597
    /** Alias for GDALAlgorithmArgDecl::IsOnlyForCLI() */
1598
    inline bool IsOnlyForCLI() const
1599
        CPL_WARN_DEPRECATED("Use IsHiddenForAPI() instead")
1600
0
    {
1601
0
        return m_decl.IsHiddenForAPI();
1602
0
    }
1603
1604
    /** Alias for GDALAlgorithmArgDecl::IsHiddenForAPI() */
1605
    inline bool IsHiddenForAPI() const
1606
0
    {
1607
0
        return m_decl.IsHiddenForAPI();
1608
0
    }
1609
1610
    /** Alias for GDALAlgorithmArgDecl::IsInput() */
1611
    inline bool IsInput() const
1612
0
    {
1613
0
        return m_decl.IsInput();
1614
0
    }
1615
1616
    /** Alias for GDALAlgorithmArgDecl::IsOutput() */
1617
    inline bool IsOutput() const
1618
0
    {
1619
0
        return m_decl.IsOutput();
1620
0
    }
1621
1622
    /** Alias for GDALAlgorithmArgDecl::IsReadFromFileAtSyntaxAllowed() */
1623
    inline bool IsReadFromFileAtSyntaxAllowed() const
1624
0
    {
1625
0
        return m_decl.IsReadFromFileAtSyntaxAllowed();
1626
0
    }
1627
1628
    /** Alias for GDALAlgorithmArgDecl::IsRemoveSQLCommentsEnabled() */
1629
    inline bool IsRemoveSQLCommentsEnabled() const
1630
0
    {
1631
0
        return m_decl.IsRemoveSQLCommentsEnabled();
1632
0
    }
1633
1634
    /** Alias for GDALAlgorithmArgDecl::GetMutualExclusionGroup() */
1635
    inline const std::string &GetMutualExclusionGroup() const
1636
0
    {
1637
0
        return m_decl.GetMutualExclusionGroup();
1638
0
    }
1639
1640
    /** Alias for GDALAlgorithmArgDecl::GetMetadata() */
1641
    inline const std::map<std::string, std::vector<std::string>>
1642
    GetMetadata() const
1643
0
    {
1644
0
        return m_decl.GetMetadata();
1645
0
    }
1646
1647
    /** Alias for GDALAlgorithmArgDecl::GetMetadataItem() */
1648
    inline const std::vector<std::string> *
1649
    GetMetadataItem(const std::string &name) const
1650
0
    {
1651
0
        return m_decl.GetMetadataItem(name);
1652
0
    }
1653
1654
    /** Alias for GDALAlgorithmArgDecl::GetDefault() */
1655
    template <class T> inline const T &GetDefault() const
1656
0
    {
1657
0
        return m_decl.GetDefault<T>();
1658
0
    }
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& GDALAlgorithmArg::GetDefault<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: bool const& GDALAlgorithmArg::GetDefault<bool>() const
Unexecuted instantiation: int const& GDALAlgorithmArg::GetDefault<int>() const
Unexecuted instantiation: double const& GDALAlgorithmArg::GetDefault<double>() const
Unexecuted instantiation: std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const& GDALAlgorithmArg::GetDefault<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >() const
Unexecuted instantiation: std::__1::vector<int, std::__1::allocator<int> > const& GDALAlgorithmArg::GetDefault<std::__1::vector<int, std::__1::allocator<int> > >() const
Unexecuted instantiation: std::__1::vector<double, std::__1::allocator<double> > const& GDALAlgorithmArg::GetDefault<std::__1::vector<double, std::__1::allocator<double> > >() const
1659
1660
    /** Alias for GDALAlgorithmArgDecl::AutoOpenDataset() */
1661
    inline bool AutoOpenDataset() const
1662
0
    {
1663
0
        return m_decl.AutoOpenDataset();
1664
0
    }
1665
1666
    /** Alias for GDALAlgorithmArgDecl::IsUserProvided() */
1667
    inline bool IsUserProvided() const
1668
0
    {
1669
0
        return m_decl.IsUserProvided();
1670
0
    }
1671
1672
    /** Alias for GDALAlgorithmArgDecl::GetDatasetType() */
1673
    inline GDALArgDatasetType GetDatasetType() const
1674
0
    {
1675
0
        return m_decl.GetDatasetType();
1676
0
    }
1677
1678
    /** Alias for GDALAlgorithmArgDecl::GetDatasetInputFlags() */
1679
    inline int GetDatasetInputFlags() const
1680
0
    {
1681
0
        return m_decl.GetDatasetInputFlags();
1682
0
    }
1683
1684
    /** Alias for GDALAlgorithmArgDecl::GetDatasetOutputFlags() */
1685
    inline int GetDatasetOutputFlags() const
1686
0
    {
1687
0
        return m_decl.GetDatasetOutputFlags();
1688
0
    }
1689
1690
    /** Return the value of the argument, which is by decreasing order of priority:
1691
     * - the value set through Set().
1692
     * - the default value set through SetDefault().
1693
     * - the initial value of the C++ variable to which this argument is bound to.
1694
     *
1695
     * Must be called with T consistent of the type of the algorithm:
1696
     * - bool for GAAT_BOOLEAN
1697
     * - int for GAAT_INTEGER
1698
     * - double for GAAT_REAL
1699
     * - std::string for GAAT_STRING
1700
     * - GDALArgDatasetValue for GAAT_DATASET
1701
     * - std::vector<int> for GAAT_INTEGER_LIST
1702
     * - std::vector<double for GAAT_REAL_LIST
1703
     * - std::vector<std::string> for GAAT_STRING_LIST
1704
     * - std::vector<GDALArgDatasetValue> for GAAT_DATASET_LIST
1705
     */
1706
    template <class T> inline T &Get()
1707
0
    {
1708
0
        return *(std::get<T *>(m_value));
1709
0
    }
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >& GDALAlgorithmArg::Get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Unexecuted instantiation: std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >& GDALAlgorithmArg::Get<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >()
Unexecuted instantiation: int& GDALAlgorithmArg::Get<int>()
Unexecuted instantiation: std::__1::vector<int, std::__1::allocator<int> >& GDALAlgorithmArg::Get<std::__1::vector<int, std::__1::allocator<int> > >()
Unexecuted instantiation: double& GDALAlgorithmArg::Get<double>()
Unexecuted instantiation: std::__1::vector<double, std::__1::allocator<double> >& GDALAlgorithmArg::Get<std::__1::vector<double, std::__1::allocator<double> > >()
Unexecuted instantiation: std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> >& GDALAlgorithmArg::Get<std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> > >()
Unexecuted instantiation: bool& GDALAlgorithmArg::Get<bool>()
Unexecuted instantiation: GDALArgDatasetValue& GDALAlgorithmArg::Get<GDALArgDatasetValue>()
1710
1711
    /** Return the value of the argument, which is by decreasing order of priority:
1712
     * - the value set through Set().
1713
     * - the default value set through SetDefault().
1714
     * - the initial value of the C++ variable to which this argument is bound to.
1715
     *
1716
     * Must be called with T consistent of the type of the algorithm:
1717
     * - bool for GAAT_BOOLEAN
1718
     * - int for GAAT_INTEGER
1719
     * - double for GAAT_REAL
1720
     * - std::string for GAAT_STRING
1721
     * - GDALArgDatasetValue for GAAT_DATASET
1722
     * - std::vector<int> for GAAT_INTEGER_LIST
1723
     * - std::vector<double for GAAT_REAL_LIST
1724
     * - std::vector<std::string> for GAAT_STRING_LIST
1725
     * - std::vector<GDALArgDatasetValue> for GAAT_DATASET_LIST
1726
     */
1727
    template <class T> inline const T &Get() const
1728
0
    {
1729
0
        return *(std::get<T *>(m_value));
1730
0
    }
Unexecuted instantiation: GDALArgDatasetValue const& GDALAlgorithmArg::Get<GDALArgDatasetValue>() const
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& GDALAlgorithmArg::Get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: int const& GDALAlgorithmArg::Get<int>() const
Unexecuted instantiation: double const& GDALAlgorithmArg::Get<double>() const
Unexecuted instantiation: std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const& GDALAlgorithmArg::Get<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >() const
Unexecuted instantiation: std::__1::vector<int, std::__1::allocator<int> > const& GDALAlgorithmArg::Get<std::__1::vector<int, std::__1::allocator<int> > >() const
Unexecuted instantiation: std::__1::vector<double, std::__1::allocator<double> > const& GDALAlgorithmArg::Get<std::__1::vector<double, std::__1::allocator<double> > >() const
Unexecuted instantiation: std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> > const& GDALAlgorithmArg::Get<std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> > >() const
1731
1732
    /** Set the value for a GAAT_BOOLEAN argument.
1733
     * It cannot be called several times for a given argument.
1734
     * Validation checks and other actions are run.
1735
     * Return true if success.
1736
     */
1737
    bool Set(bool value);
1738
1739
    /** Set the value for a GAAT_STRING argument.
1740
     * It cannot be called several times for a given argument.
1741
     * Validation checks and other actions are run.
1742
     * Return true if success.
1743
     */
1744
    bool Set(const std::string &value);
1745
1746
    /** Set the value for a GAAT_STRING argument.
1747
     * It cannot be called several times for a given argument.
1748
     * Validation checks and other actions are run.
1749
     * Return true if success.
1750
     */
1751
    bool Set(const char *value)
1752
0
    {
1753
0
        return Set(std::string(value ? value : ""));
1754
0
    }
1755
1756
    /** Set the value for a GAAT_STRING argument from a GDALDataType
1757
     * It cannot be called several times for a given argument.
1758
     * Validation checks and other actions are run.
1759
     * Return true if success.
1760
     */
1761
    bool Set(GDALDataType dt)
1762
0
    {
1763
0
        return Set(GDALGetDataTypeName(dt));
1764
0
    }
1765
1766
    /** Set the value for a GAAT_STRING argument (representing a CRS)
1767
     * from a OGRSpatialReference
1768
     * It cannot be called several times for a given argument.
1769
     * Validation checks and other actions are run.
1770
     * Return true if success.
1771
     */
1772
    bool Set(const OGRSpatialReference &);
1773
1774
    /** Set the value for a GAAT_INTEGER (or GAAT_REAL) argument.
1775
     * It cannot be called several times for a given argument.
1776
     * Validation checks and other actions are run.
1777
     * Return true if success.
1778
     */
1779
    bool Set(int value);
1780
1781
    /** Set the value for a GAAT_REAL argument */
1782
    bool Set(double value);
1783
1784
    /** Set the value for a GAAT_DATASET argument, increasing ds' reference
1785
     * counter if ds is not null.
1786
     * It cannot be called several times for a given argument.
1787
     * Validation checks and other actions are run.
1788
     * Return true if success.
1789
     */
1790
    bool Set(GDALDataset *ds);
1791
1792
    /** Set the value for a GAAT_DATASET argument.
1793
     * It cannot be called several times for a given argument.
1794
     * Validation checks and other actions are run.
1795
     * Return true if success.
1796
     */
1797
    bool Set(std::unique_ptr<GDALDataset> ds);
1798
1799
    /** Set the value for a GAAT_DATASET argument.
1800
     * It cannot be called several times for a given argument.
1801
     * Validation checks and other actions are run.
1802
     * Return true if success.
1803
     */
1804
    bool SetDatasetName(const std::string &name);
1805
1806
    /** Set the value for a GAAT_DATASET argument.
1807
     * It references the dataset pointed by other.m_poDS.
1808
     * It cannot be called several times for a given argument.
1809
     * Validation checks and other actions are run.
1810
     * Return true if success.
1811
     */
1812
    bool SetFrom(const GDALArgDatasetValue &other);
1813
1814
    /** Set the value for a GAAT_STRING_LIST argument.
1815
     * It cannot be called several times for a given argument.
1816
     * Validation checks and other actions are run.
1817
     * Return true if success.
1818
     */
1819
    bool Set(const std::vector<std::string> &value);
1820
1821
    /** Set the value for a GAAT_INTEGER_LIST argument.
1822
     * It cannot be called several times for a given argument.
1823
     * Validation checks and other actions are run.
1824
     * Return true if success.
1825
     */
1826
    bool Set(const std::vector<int> &value);
1827
1828
    /** Set the value for a GAAT_REAL_LIST argument.
1829
     * It cannot be called several times for a given argument.
1830
     * Validation checks and other actions are run.
1831
     * Return true if success.
1832
     */
1833
    bool Set(const std::vector<double> &value);
1834
1835
    /** Set the value for a GAAT_DATASET_LIST argument.
1836
     * It cannot be called several times for a given argument.
1837
     * Validation checks and other actions are run.
1838
     * Return true if success.
1839
     */
1840
    bool Set(std::vector<GDALArgDatasetValue> &&value);
1841
1842
    /** Set the value of the argument. */
1843
    inline GDALAlgorithmArg &operator=(bool value)
1844
0
    {
1845
0
        Set(value);
1846
0
        return *this;
1847
0
    }
1848
1849
    /** Set the value of the argument. */
1850
    inline GDALAlgorithmArg &operator=(int value)
1851
0
    {
1852
0
        Set(value);
1853
0
        return *this;
1854
0
    }
1855
1856
    /** Set the value of the argument. */
1857
    inline GDALAlgorithmArg &operator=(double value)
1858
0
    {
1859
0
        Set(value);
1860
0
        return *this;
1861
0
    }
1862
1863
    /** Set the value of the argument. */
1864
    inline GDALAlgorithmArg &operator=(const std::string &value)
1865
0
    {
1866
0
        Set(value);
1867
0
        return *this;
1868
0
    }
1869
1870
    /** Set the value of the argument. */
1871
    inline GDALAlgorithmArg &operator=(const char *value)
1872
0
    {
1873
0
        Set(value);
1874
0
        return *this;
1875
0
    }
1876
1877
    /** Set the value of the argument. */
1878
    inline GDALAlgorithmArg &operator=(GDALDataType value)
1879
0
    {
1880
0
        Set(value);
1881
0
        return *this;
1882
0
    }
1883
1884
    /** Set the value of the argument. */
1885
    inline GDALAlgorithmArg &operator=(const OGRSpatialReference &value)
1886
0
    {
1887
0
        Set(value);
1888
0
        return *this;
1889
0
    }
1890
1891
    /** Set the value of the argument. */
1892
    inline GDALAlgorithmArg &operator=(const std::vector<int> &value)
1893
0
    {
1894
0
        Set(value);
1895
0
        return *this;
1896
0
    }
1897
1898
    /** Set the value of the argument. */
1899
    inline GDALAlgorithmArg &operator=(const std::vector<double> &value)
1900
0
    {
1901
0
        Set(value);
1902
0
        return *this;
1903
0
    }
1904
1905
    /** Set the value of the argument. */
1906
    inline GDALAlgorithmArg &operator=(const std::vector<std::string> &value)
1907
0
    {
1908
0
        Set(value);
1909
0
        return *this;
1910
0
    }
1911
1912
    /** Set the value of the argument. */
1913
    inline GDALAlgorithmArg &operator=(GDALDataset *value)
1914
0
    {
1915
0
        Set(value);
1916
0
        return *this;
1917
0
    }
1918
1919
    /** Set the value of the argument. */
1920
    GDALAlgorithmArg &operator=(std::unique_ptr<GDALDataset> value);
1921
1922
    /** Set the value for another argument.
1923
     * For GAAT_DATASET, it will reference the dataset pointed by other.m_poDS.
1924
     * It cannot be called several times for a given argument.
1925
     * Validation checks and other actions are run.
1926
     * Return true if success.
1927
     */
1928
    bool SetFrom(const GDALAlgorithmArg &other);
1929
1930
    /** Advanced method used to make "gdal info" and "gdal raster|vector info"
1931
     * to avoid re-opening an already opened dataset */
1932
    void SetSkipIfAlreadySet(bool skip = true)
1933
0
    {
1934
0
        m_skipIfAlreadySet = skip;
1935
0
    }
1936
1937
    /** Advanced method used to make "gdal info" and "gdal raster|vector info"
1938
     * to avoid re-opening an already opened dataset */
1939
    bool SkipIfAlreadySet() const
1940
0
    {
1941
0
        return m_skipIfAlreadySet;
1942
0
    }
1943
1944
    /** Serialize this argument and its value.
1945
     * May return false if the argument is not explicitly set or if a dataset
1946
     * is passed by value.
1947
     */
1948
    bool Serialize(std::string &serializedArg, bool absolutePath = false) const;
1949
1950
    //! @cond Doxygen_Suppress
1951
    void NotifyValueSet()
1952
0
    {
1953
0
        m_explicitlySet = true;
1954
0
    }
1955
1956
    //! @endcond
1957
1958
  protected:
1959
    friend class GDALAlgorithm;
1960
    /** Argument declaration */
1961
    GDALAlgorithmArgDecl m_decl;
1962
    /** Pointer to the value */
1963
    std::variant<bool *, std::string *, int *, double *, GDALArgDatasetValue *,
1964
                 std::vector<std::string> *, std::vector<int> *,
1965
                 std::vector<double> *, std::vector<GDALArgDatasetValue> *>
1966
        m_value{};
1967
    /** Actions */
1968
    std::vector<std::function<void()>> m_actions{};
1969
    /** Validation actions */
1970
    std::vector<std::function<bool()>> m_validationActions{};
1971
    /** Autocompletion function */
1972
    std::function<std::vector<std::string>(const std::string &)>
1973
        m_autoCompleteFunction{};
1974
    /** Algorithm that may own this argument. */
1975
    GDALAlgorithm *m_owner = nullptr;
1976
1977
  private:
1978
    bool m_skipIfAlreadySet = false;
1979
    bool m_explicitlySet = false;
1980
1981
    template <class T> bool SetInternal(const T &value)
1982
0
    {
1983
0
        m_explicitlySet = true;
1984
0
        *std::get<T *>(m_value) = value;
1985
0
        return RunAllActions();
1986
0
    }
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<bool>(bool const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<int>(int const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<double>(double const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<std::__1::vector<int, std::__1::allocator<int> > >(std::__1::vector<int, std::__1::allocator<int> > const&)
Unexecuted instantiation: bool GDALAlgorithmArg::SetInternal<std::__1::vector<double, std::__1::allocator<double> > >(std::__1::vector<double, std::__1::allocator<double> > const&)
1987
1988
    bool ProcessString(std::string &value) const;
1989
1990
    bool RunAllActions();
1991
    void RunActions();
1992
    bool RunValidationActions();
1993
    std::string ValidateChoice(const std::string &value) const;
1994
    bool ValidateIntRange(int val) const;
1995
    bool ValidateRealRange(double val) const;
1996
1997
    CPL_DISALLOW_COPY_ASSIGN(GDALAlgorithmArg)
1998
};
1999
2000
/************************************************************************/
2001
/*                     GDALInConstructionAlgorithmArg                   */
2002
/************************************************************************/
2003
2004
//! @cond Doxygen_Suppress
2005
namespace test_gdal_algorithm
2006
{
2007
struct test_gdal_algorithm;
2008
}
2009
2010
//! @endcond
2011
2012
/** Technical class used by GDALAlgorithm when constructing argument
2013
 * declarations.
2014
 */
2015
class CPL_DLL GDALInConstructionAlgorithmArg final : public GDALAlgorithmArg
2016
{
2017
    friend struct test_gdal_algorithm::test_gdal_algorithm;
2018
2019
  public:
2020
    /** Constructor */
2021
    template <class T>
2022
    GDALInConstructionAlgorithmArg(GDALAlgorithm *owner,
2023
                                   const GDALAlgorithmArgDecl &decl, T *pValue)
2024
0
        : GDALAlgorithmArg(decl, pValue)
2025
0
    {
2026
0
        m_owner = owner;
2027
0
    }
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<bool>(GDALAlgorithm*, GDALAlgorithmArgDecl const&, bool*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(GDALAlgorithm*, GDALAlgorithmArgDecl const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<int>(GDALAlgorithm*, GDALAlgorithmArgDecl const&, int*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<double>(GDALAlgorithm*, GDALAlgorithmArgDecl const&, double*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<GDALArgDatasetValue>(GDALAlgorithm*, GDALAlgorithmArgDecl const&, GDALArgDatasetValue*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(GDALAlgorithm*, GDALAlgorithmArgDecl const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<std::__1::vector<int, std::__1::allocator<int> > >(GDALAlgorithm*, GDALAlgorithmArgDecl const&, std::__1::vector<int, std::__1::allocator<int> >*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<std::__1::vector<double, std::__1::allocator<double> > >(GDALAlgorithm*, GDALAlgorithmArgDecl const&, std::__1::vector<double, std::__1::allocator<double> >*)
Unexecuted instantiation: GDALInConstructionAlgorithmArg::GDALInConstructionAlgorithmArg<std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> > >(GDALAlgorithm*, GDALAlgorithmArgDecl const&, std::__1::vector<GDALArgDatasetValue, std::__1::allocator<GDALArgDatasetValue> >*)
2028
2029
    /** Destructor */
2030
    ~GDALInConstructionAlgorithmArg() override;
2031
2032
    /** Add a documented alias for the argument */
2033
    GDALInConstructionAlgorithmArg &AddAlias(const std::string &alias);
2034
2035
    /** Add a non-documented alias for the argument */
2036
    GDALInConstructionAlgorithmArg &AddHiddenAlias(const std::string &alias);
2037
2038
    /** Add a shortname alias for the argument */
2039
    GDALInConstructionAlgorithmArg &AddShortNameAlias(char shortNameAlias);
2040
2041
    /** Alias for GDALAlgorithmArgDecl::SetPositional() */
2042
    GDALInConstructionAlgorithmArg &SetPositional();
2043
2044
    /** Alias for GDALAlgorithmArgDecl::SetRequired() */
2045
    GDALInConstructionAlgorithmArg &SetRequired()
2046
0
    {
2047
0
        m_decl.SetRequired();
2048
0
        return *this;
2049
0
    }
2050
2051
    /** Alias for GDALAlgorithmArgDecl::SetMetaVar() */
2052
    GDALInConstructionAlgorithmArg &SetMetaVar(const std::string &metaVar)
2053
0
    {
2054
0
        m_decl.SetMetaVar(metaVar);
2055
0
        return *this;
2056
0
    }
2057
2058
    /** Alias for GDALAlgorithmArgDecl::SetCategory() */
2059
    GDALInConstructionAlgorithmArg &SetCategory(const std::string &category)
2060
0
    {
2061
0
        m_decl.SetCategory(category);
2062
0
        return *this;
2063
0
    }
2064
2065
    /** Alias for GDALAlgorithmArgDecl::SetDefault() */
2066
    template <class T>
2067
    GDALInConstructionAlgorithmArg &SetDefault(const T &value)
2068
0
    {
2069
0
        m_decl.SetDefault(value);
2070
2071
        if constexpr (!std::is_same_v<T, GDALArgDatasetValue> &&
2072
                      !std::is_same_v<T, std::vector<GDALArgDatasetValue>>)
2073
0
        {
2074
0
            try
2075
0
            {
2076
0
                switch (m_decl.GetType())
2077
0
                {
2078
0
                    case GAAT_BOOLEAN:
2079
0
                        *std::get<bool *>(m_value) = m_decl.GetDefault<bool>();
2080
0
                        break;
2081
0
                    case GAAT_STRING:
2082
0
                        *std::get<std::string *>(m_value) =
2083
0
                            m_decl.GetDefault<std::string>();
2084
0
                        break;
2085
0
                    case GAAT_INTEGER:
2086
0
                        *std::get<int *>(m_value) = m_decl.GetDefault<int>();
2087
0
                        break;
2088
0
                    case GAAT_REAL:
2089
0
                        *std::get<double *>(m_value) =
2090
0
                            m_decl.GetDefault<double>();
2091
0
                        break;
2092
0
                    case GAAT_STRING_LIST:
2093
0
                        *std::get<std::vector<std::string> *>(m_value) =
2094
0
                            m_decl.GetDefault<std::vector<std::string>>();
2095
0
                        break;
2096
0
                    case GAAT_INTEGER_LIST:
2097
0
                        *std::get<std::vector<int> *>(m_value) =
2098
0
                            m_decl.GetDefault<std::vector<int>>();
2099
0
                        break;
2100
0
                    case GAAT_REAL_LIST:
2101
0
                        *std::get<std::vector<double> *>(m_value) =
2102
0
                            m_decl.GetDefault<std::vector<double>>();
2103
0
                        break;
2104
0
                    case GAAT_DATASET:
2105
0
                    case GAAT_DATASET_LIST:
2106
0
                        break;
2107
0
                }
2108
0
            }
2109
0
            catch (const std::bad_variant_access &)
2110
0
            {
2111
                // I don't think that can happen, but Coverity Scan thinks so
2112
0
                CPLError(CE_Failure, CPLE_AppDefined,
2113
0
                         "Argument %s: SetDefault(): unexpected type for value",
2114
0
                         GetName().c_str());
2115
0
            }
2116
0
        }
2117
0
        return *this;
2118
0
    }
Unexecuted instantiation: GDALInConstructionAlgorithmArg& GDALInConstructionAlgorithmArg::SetDefault<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: GDALInConstructionAlgorithmArg& GDALInConstructionAlgorithmArg::SetDefault<bool>(bool const&)
2119
2120
    /** Alias for GDALAlgorithmArgDecl::SetDefault() */
2121
    GDALInConstructionAlgorithmArg &SetDefault(const char *value)
2122
0
    {
2123
0
        return SetDefault(std::string(value));
2124
0
    }
2125
2126
    /** Alias for GDALAlgorithmArgDecl::SetMinCount() */
2127
    GDALInConstructionAlgorithmArg &SetMinCount(int count)
2128
0
    {
2129
0
        m_decl.SetMinCount(count);
2130
0
        return *this;
2131
0
    }
2132
2133
    /** Alias for GDALAlgorithmArgDecl::SetMaxCount() */
2134
    GDALInConstructionAlgorithmArg &SetMaxCount(int count)
2135
0
    {
2136
0
        m_decl.SetMaxCount(count);
2137
0
        return *this;
2138
0
    }
2139
2140
    /** Alias for GDALAlgorithmArgDecl::SetDisplayHintAboutRepetition() */
2141
    GDALInConstructionAlgorithmArg &
2142
    SetDisplayHintAboutRepetition(bool displayHint)
2143
0
    {
2144
0
        m_decl.SetDisplayHintAboutRepetition(displayHint);
2145
0
        return *this;
2146
0
    }
2147
2148
    /** Alias for GDALAlgorithmArgDecl::SetPackedValuesAllowed() */
2149
    GDALInConstructionAlgorithmArg &SetPackedValuesAllowed(bool allowed)
2150
0
    {
2151
0
        m_decl.SetPackedValuesAllowed(allowed);
2152
0
        return *this;
2153
0
    }
2154
2155
    /** Alias for GDALAlgorithmArgDecl::SetRepeatedArgAllowed() */
2156
    GDALInConstructionAlgorithmArg &SetRepeatedArgAllowed(bool allowed)
2157
0
    {
2158
0
        m_decl.SetRepeatedArgAllowed(allowed);
2159
0
        return *this;
2160
0
    }
2161
2162
    /** Alias for GDALAlgorithmArgDecl::SetChoices() */
2163
    template <
2164
        typename T, typename... U,
2165
        typename std::enable_if<!std::is_same_v<T, std::vector<std::string> &>,
2166
                                bool>::type = true>
2167
    GDALInConstructionAlgorithmArg &SetChoices(T &&first, U &&...rest)
2168
0
    {
2169
0
        m_decl.SetChoices(std::forward<T>(first), std::forward<U>(rest)...);
2170
0
        return *this;
2171
0
    }
2172
2173
    /** Alias for GDALAlgorithmArgDecl::SetChoices() */
2174
    GDALInConstructionAlgorithmArg &
2175
    SetChoices(const std::vector<std::string> &choices)
2176
0
    {
2177
0
        m_decl.SetChoices(choices);
2178
0
        return *this;
2179
0
    }
2180
2181
    /** Alias for GDALAlgorithmArgDecl::SetHiddenChoices() */
2182
    template <typename T, typename... U>
2183
    GDALInConstructionAlgorithmArg &SetHiddenChoices(T &&first, U &&...rest)
2184
    {
2185
        m_decl.SetHiddenChoices(std::forward<T>(first),
2186
                                std::forward<U>(rest)...);
2187
        return *this;
2188
    }
2189
2190
    /** Alias for GDALAlgorithmArgDecl::SetMinValueIncluded() */
2191
    GDALInConstructionAlgorithmArg &SetMinValueIncluded(double min)
2192
0
    {
2193
0
        m_decl.SetMinValueIncluded(min);
2194
0
        return *this;
2195
0
    }
2196
2197
    /** Alias for GDALAlgorithmArgDecl::SetMinValueExcluded() */
2198
    GDALInConstructionAlgorithmArg &SetMinValueExcluded(double min)
2199
0
    {
2200
0
        m_decl.SetMinValueExcluded(min);
2201
0
        return *this;
2202
0
    }
2203
2204
    /** Alias for GDALAlgorithmArgDecl::SetMaxValueIncluded() */
2205
    GDALInConstructionAlgorithmArg &SetMaxValueIncluded(double max)
2206
0
    {
2207
0
        m_decl.SetMaxValueIncluded(max);
2208
0
        return *this;
2209
0
    }
2210
2211
    /** Alias for GDALAlgorithmArgDecl::SetMaxValueExcluded() */
2212
    GDALInConstructionAlgorithmArg &SetMaxValueExcluded(double max)
2213
0
    {
2214
0
        m_decl.SetMaxValueExcluded(max);
2215
0
        return *this;
2216
0
    }
2217
2218
    /** Alias for GDALAlgorithmArgDecl::SetMinCharCount() */
2219
    GDALInConstructionAlgorithmArg &SetMinCharCount(int count)
2220
0
    {
2221
0
        m_decl.SetMinCharCount(count);
2222
0
        return *this;
2223
0
    }
2224
2225
    /** Alias for GDALAlgorithmArgDecl::SetHidden() */
2226
    GDALInConstructionAlgorithmArg &SetHidden()
2227
0
    {
2228
0
        m_decl.SetHidden();
2229
0
        return *this;
2230
0
    }
2231
2232
    /** Alias for GDALAlgorithmArgDecl::SetHiddenForCLI() */
2233
    GDALInConstructionAlgorithmArg &SetHiddenForCLI(bool hiddenForCLI = true)
2234
0
    {
2235
0
        m_decl.SetHiddenForCLI(hiddenForCLI);
2236
0
        return *this;
2237
0
    }
2238
2239
    /** Alias for GDALAlgorithmArgDecl::SetHiddenForAPI() */
2240
    GDALInConstructionAlgorithmArg &SetHiddenForAPI(bool hiddenForAPI = true)
2241
0
    {
2242
0
        m_decl.SetHiddenForAPI(hiddenForAPI);
2243
0
        return *this;
2244
0
    }
2245
2246
    /** Alias for GDALAlgorithmArgDecl::SetIsInput() */
2247
    GDALInConstructionAlgorithmArg &SetIsInput(bool isInput = true)
2248
0
    {
2249
0
        m_decl.SetIsInput(isInput);
2250
0
        return *this;
2251
0
    }
2252
2253
    /** Alias for GDALAlgorithmArgDecl::SetIsOutput() */
2254
    GDALInConstructionAlgorithmArg &SetIsOutput(bool isOutput = true)
2255
0
    {
2256
0
        m_decl.SetIsOutput(isOutput);
2257
0
        return *this;
2258
0
    }
2259
2260
    /** Alias for GDALAlgorithmArgDecl::SetReadFromFileAtSyntaxAllowed() */
2261
    GDALInConstructionAlgorithmArg &SetReadFromFileAtSyntaxAllowed()
2262
0
    {
2263
0
        m_decl.SetReadFromFileAtSyntaxAllowed();
2264
0
        return *this;
2265
0
    }
2266
2267
    /** Alias for GDALAlgorithmArgDecl::SetRemoveSQLCommentsEnabled() */
2268
    GDALInConstructionAlgorithmArg &SetRemoveSQLCommentsEnabled()
2269
0
    {
2270
0
        m_decl.SetRemoveSQLCommentsEnabled();
2271
0
        return *this;
2272
0
    }
2273
2274
    /** Alias for GDALAlgorithmArgDecl::SetAutoOpenDataset() */
2275
    GDALInConstructionAlgorithmArg &SetAutoOpenDataset(bool autoOpen)
2276
0
    {
2277
0
        m_decl.SetAutoOpenDataset(autoOpen);
2278
0
        return *this;
2279
0
    }
2280
2281
    /** Alias for GDALAlgorithmArgDecl::SetMutualExclusionGroup() */
2282
    GDALInConstructionAlgorithmArg &
2283
    SetMutualExclusionGroup(const std::string &group)
2284
0
    {
2285
0
        m_decl.SetMutualExclusionGroup(group);
2286
0
        return *this;
2287
0
    }
2288
2289
    /** Alias for GDALAlgorithmArgDecl::AddMetadataItem() */
2290
    GDALInConstructionAlgorithmArg &
2291
    AddMetadataItem(const std::string &name,
2292
                    const std::vector<std::string> &values)
2293
0
    {
2294
0
        m_decl.AddMetadataItem(name, values);
2295
0
        return *this;
2296
0
    }
2297
2298
    /** Alias for GDALAlgorithmArgDecl::SetDatasetType() */
2299
    GDALInConstructionAlgorithmArg &
2300
    SetDatasetType(GDALArgDatasetType datasetType)
2301
0
    {
2302
0
        m_decl.SetDatasetType(datasetType);
2303
0
        return *this;
2304
0
    }
2305
2306
    /** Alias for GDALAlgorithmArgDecl::SetDatasetInputFlags() */
2307
    GDALInConstructionAlgorithmArg &SetDatasetInputFlags(int flags)
2308
0
    {
2309
0
        m_decl.SetDatasetInputFlags(flags);
2310
0
        return *this;
2311
0
    }
2312
2313
    /** Alias for GDALAlgorithmArgDecl::SetDatasetOutputFlags() */
2314
    GDALInConstructionAlgorithmArg &SetDatasetOutputFlags(int flags)
2315
0
    {
2316
0
        m_decl.SetDatasetOutputFlags(flags);
2317
0
        return *this;
2318
0
    }
2319
2320
    /** Register an action that is executed, once and exactly once, if the
2321
     * argument is explicitly set, at the latest by the ValidateArguments()
2322
     * method. */
2323
    GDALInConstructionAlgorithmArg &AddAction(std::function<void()> f)
2324
0
    {
2325
0
        m_actions.push_back(f);
2326
0
        return *this;
2327
0
    }
2328
2329
    /** Register an action that is executed, once and exactly once, if the
2330
     * argument is explicitly set, at the latest by the ValidateArguments()
2331
     * method. If the provided function returns false, validation fails.
2332
     * The validation function of a given argument can only check the value of
2333
     * this argument, and cannot assume other arguments have already been set.
2334
     */
2335
    GDALInConstructionAlgorithmArg &AddValidationAction(std::function<bool()> f)
2336
0
    {
2337
0
        m_validationActions.push_back(f);
2338
0
        return *this;
2339
0
    }
2340
2341
    /** Register a function that will return a list of valid choices for
2342
     * the value of the argument. This is typically used for autocompletion.
2343
     */
2344
    GDALInConstructionAlgorithmArg &SetAutoCompleteFunction(
2345
        std::function<std::vector<std::string>(const std::string &)> f)
2346
0
    {
2347
0
        m_autoCompleteFunction = std::move(f);
2348
0
        return *this;
2349
0
    }
2350
2351
    /** Register an action to validate that the argument value is a valid
2352
     * CRS definition.
2353
     * @param noneAllowed Set to true to mean that "null" or "none" are allowed
2354
     * to mean to unset CRS.
2355
     * @param specialValues List of other allowed special values.
2356
     */
2357
    GDALInConstructionAlgorithmArg &
2358
    SetIsCRSArg(bool noneAllowed = false,
2359
                const std::vector<std::string> &specialValues =
2360
                    std::vector<std::string>());
2361
2362
    /** Alias for GDALAlgorithmArgDecl::SetUserProvided() */
2363
    GDALInConstructionAlgorithmArg &SetUserProvided()
2364
0
    {
2365
0
        m_decl.SetUserProvided();
2366
0
        return *this;
2367
0
    }
2368
};
2369
2370
/************************************************************************/
2371
/*                      GDALAlgorithmRegistry                           */
2372
/************************************************************************/
2373
2374
/** Registry of GDAL algorithms.
2375
 */
2376
class CPL_DLL GDALAlgorithmRegistry
2377
{
2378
  public:
2379
    /** Special value to put in m_aliases to separate public alias from
2380
     * hidden aliases */
2381
    static constexpr const char *HIDDEN_ALIAS_SEPARATOR = "==hide==";
2382
2383
    virtual ~GDALAlgorithmRegistry();
2384
2385
    /** Algorithm information */
2386
    class AlgInfo
2387
    {
2388
      public:
2389
        /** Algorithm (short) name */
2390
        std::string m_name{};
2391
        /** Aliases */
2392
        std::vector<std::string> m_aliases{};
2393
        /** Creation function */
2394
        std::function<std::unique_ptr<GDALAlgorithm>()> m_creationFunc{};
2395
    };
2396
2397
    /** Register the algorithm of type MyAlgorithm.
2398
     */
2399
    template <class MyAlgorithm> bool Register()
2400
    {
2401
        AlgInfo info;
2402
        info.m_name = MyAlgorithm::NAME;
2403
        info.m_aliases = MyAlgorithm::GetAliasesStatic();
2404
        info.m_creationFunc = []() -> std::unique_ptr<GDALAlgorithm>
2405
        { return std::make_unique<MyAlgorithm>(); };
2406
        return Register(info);
2407
    }
2408
2409
    /** Register an algorithm by its AlgInfo structure.
2410
     */
2411
    bool Register(const AlgInfo &info);
2412
2413
    /** Get the names of registered algorithms.
2414
     *
2415
     * This only returns the main name of each algorithm, not its potential
2416
     * alternate names.
2417
     */
2418
    std::vector<std::string> GetNames() const;
2419
2420
    /** Instantiate an algorithm by its name or one of its alias. */
2421
    virtual std::unique_ptr<GDALAlgorithm>
2422
    Instantiate(const std::string &name) const;
2423
2424
    /** Get an algorithm by its name. */
2425
    const AlgInfo *GetInfo(const std::string &name) const
2426
0
    {
2427
0
        auto iter = m_mapNameToInfo.find(name);
2428
0
        return iter != m_mapNameToInfo.end() ? &(iter->second) : nullptr;
2429
0
    }
2430
2431
    /** Returns true if there are no algorithms registered. */
2432
    bool empty() const
2433
0
    {
2434
0
        return m_mapNameToInfo.empty();
2435
0
    }
2436
2437
  private:
2438
    std::map<std::string, AlgInfo> m_mapNameToInfo{};
2439
    std::map<std::string, AlgInfo> m_mapAliasToInfo{};
2440
    std::map<std::string, AlgInfo> m_mapHiddenAliasToInfo{};
2441
};
2442
2443
/************************************************************************/
2444
/*                            GDALAlgorithm                             */
2445
/************************************************************************/
2446
2447
/** GDAL algorithm.
2448
 *
2449
 * An algorithm declares its name, description, help URL.
2450
 * It also defined arguments or (mutual exclusion) sub-algorithms.
2451
 *
2452
 * It can be used from the command line with the ParseCommandLineArguments()
2453
 * method, or users can iterate over the available arguments with the GetArgs()
2454
 * or GetArg() method and fill them programmatically with
2455
 * GDALAlgorithmArg::Set().
2456
 *
2457
 * Execution of the algorithm is done with the Run() method.
2458
 *
2459
 * This is an abstract class. Implementations must sub-class it and implement the
2460
 * RunImpl() method.
2461
 */
2462
2463
/* abstract */ class CPL_DLL GDALAlgorithm
2464
{
2465
    friend struct test_gdal_algorithm::test_gdal_algorithm;
2466
2467
  public:
2468
    virtual ~GDALAlgorithm();
2469
2470
    /** Get the algorithm name */
2471
    const std::string &GetName() const
2472
0
    {
2473
0
        return m_name;
2474
0
    }
2475
2476
    /** Get the algorithm description (a few sentences at most) */
2477
    const std::string &GetDescription() const
2478
0
    {
2479
0
        return m_description;
2480
0
    }
2481
2482
    /** Get the long algorithm description. May be empty. */
2483
    const std::string &GetLongDescription() const
2484
0
    {
2485
0
        return m_longDescription;
2486
0
    }
2487
2488
    /** Get the algorithm help URL. If starting with '/', it is relative to
2489
     * "https://gdal.org".
2490
     */
2491
    const std::string &GetHelpURL() const
2492
0
    {
2493
0
        return m_helpURL;
2494
0
    }
2495
2496
    /** Get the algorithm full URL, resolving relative URLs. */
2497
    const std::string &GetHelpFullURL() const
2498
0
    {
2499
0
        return m_helpFullURL;
2500
0
    }
2501
2502
    /** Returns whether this algorithm is hidden */
2503
    bool IsHidden() const
2504
0
    {
2505
0
        return m_hidden;
2506
0
    }
2507
2508
    /** Returns whether this algorithm has sub-algorithms */
2509
    bool HasSubAlgorithms() const;
2510
2511
    /** Get the names of registered algorithms.
2512
     *
2513
     * This only returns the main name of each algorithm, not its potential
2514
     * alternate names.
2515
     */
2516
    std::vector<std::string> GetSubAlgorithmNames() const;
2517
2518
    /** Instantiate an algorithm by its name (or its alias). */
2519
    std::unique_ptr<GDALAlgorithm>
2520
    InstantiateSubAlgorithm(const std::string &name,
2521
                            bool suggestionAllowed = true) const;
2522
2523
    /** Return the potential arguments of the algorithm. */
2524
    const std::vector<std::unique_ptr<GDALAlgorithmArg>> &GetArgs() const
2525
0
    {
2526
0
        return m_args;
2527
0
    }
2528
2529
    /** Return the potential arguments of the algorithm. */
2530
    std::vector<std::unique_ptr<GDALAlgorithmArg>> &GetArgs()
2531
0
    {
2532
0
        return m_args;
2533
0
    }
2534
2535
    /** Return a likely matching argument using a Damerau-Levenshtein distance */
2536
    std::string GetSuggestionForArgumentName(const std::string &osName) const;
2537
2538
    /** Return an argument from its long name, short name or an alias */
2539
    GDALAlgorithmArg *GetArg(const std::string &osName,
2540
                             bool suggestionAllowed = false)
2541
0
    {
2542
0
        return GetArg(osName, suggestionAllowed, /* isConst = */ false);
2543
0
    }
2544
2545
    /** Return an argument from its long name, short name or an alias */
2546
    GDALAlgorithmArg &operator[](const std::string &osName)
2547
0
    {
2548
0
        auto alg = GetArg(osName, false);
2549
0
        if (!alg)
2550
0
        {
2551
0
            ReportError(CE_Failure, CPLE_AppDefined,
2552
0
                        "Argument '%s' does not exist", osName.c_str());
2553
0
            return m_dummyArg;
2554
0
        }
2555
0
        return *alg;
2556
0
    }
2557
2558
    /** Return an argument from its long name, short name or an alias */
2559
    const GDALAlgorithmArg *GetArg(const std::string &osName,
2560
                                   bool suggestionAllowed = false) const
2561
0
    {
2562
0
        return const_cast<GDALAlgorithm *>(this)->GetArg(
2563
0
            osName, suggestionAllowed, /* isConst = */ true);
2564
0
    }
2565
2566
    /** Return an argument from its long name, short name or an alias */
2567
    const GDALAlgorithmArg &operator[](const std::string &osName) const
2568
0
    {
2569
0
        const auto alg = GetArg(osName, false);
2570
0
        if (!alg)
2571
0
        {
2572
0
            ReportError(CE_Failure, CPLE_AppDefined,
2573
0
                        "Argument '%s' does not exist", osName.c_str());
2574
0
            return m_dummyArg;
2575
0
        }
2576
0
        return *alg;
2577
0
    }
2578
2579
    /** Set the calling path to this algorithm.
2580
     *
2581
     * For example the main "gdal" CLI will set the path to the name of its
2582
     * binary before calling ParseCommandLineArguments().
2583
     */
2584
    void SetCallPath(const std::vector<std::string> &path)
2585
0
    {
2586
0
        m_callPath = path;
2587
0
    }
2588
2589
    /** Set hint before calling ParseCommandLineArguments() that it must
2590
     * try to be be graceful when possible, e.g. accepting
2591
     * "gdal raster convert in.tif out.tif --co"
2592
     */
2593
    void SetParseForAutoCompletion()
2594
0
    {
2595
0
        m_parseForAutoCompletion = true;
2596
0
    }
2597
2598
    /** Set the reference file paths used to interpret relative paths.
2599
     *
2600
     * This has only effect if called before calling ParseCommandLineArguments().
2601
     */
2602
    void SetReferencePathForRelativePaths(const std::string &referencePath)
2603
0
    {
2604
0
        m_referencePath = referencePath;
2605
0
    }
2606
2607
    /** Return the reference file paths used to interpret relative paths. */
2608
    const std::string &GetReferencePathForRelativePaths() const
2609
0
    {
2610
0
        return m_referencePath;
2611
0
    }
2612
2613
    /** Returns whether this algorithm supports a streamed output dataset. */
2614
    bool SupportsStreamedOutput() const
2615
0
    {
2616
0
        return m_supportsStreamedOutput;
2617
0
    }
2618
2619
    /** Indicates that the algorithm must be run to generate a streamed output
2620
     * dataset. In particular, this must be used as a hint by algorithms to
2621
     * avoid writing files on the filesystem. This is used by the GDALG driver
2622
     * when executing a serialized algorithm command line.
2623
     *
2624
     * This has only effect if called before calling Run().
2625
     */
2626
    void SetExecutionForStreamedOutput()
2627
0
    {
2628
0
        m_executionForStreamOutput = true;
2629
0
    }
2630
2631
    /** Parse a command line argument, which does not include the algorithm
2632
     * name, to set the value of corresponding arguments.
2633
     */
2634
    virtual bool
2635
    ParseCommandLineArguments(const std::vector<std::string> &args);
2636
2637
    /** Validate that all constraints are met.
2638
     *
2639
     * This method may emit several errors if several constraints are not met.
2640
     *
2641
     * This method is automatically executed by ParseCommandLineArguments()
2642
     * and Run(), and thus does generally not need to be explicitly called.
2643
     * Derived classes overriding this method should generally call the base
2644
     * method.
2645
     */
2646
    virtual bool ValidateArguments();
2647
2648
    /** Execute the algorithm, starting with ValidateArguments() and then
2649
     * calling RunImpl().
2650
     */
2651
    bool Run(GDALProgressFunc pfnProgress = nullptr,
2652
             void *pProgressData = nullptr);
2653
2654
    /** Complete any pending actions, and return the final status.
2655
     * This is typically useful for algorithm that generate an output dataset.
2656
     */
2657
    virtual bool Finalize();
2658
2659
    /** Usage options */
2660
    struct UsageOptions
2661
    {
2662
        /** Whether this is a pipeline step */
2663
        bool isPipelineStep;
2664
        /** Maximum width of the names of the options */
2665
        size_t maxOptLen;
2666
        /** Whether this is a pipeline main */
2667
        bool isPipelineMain;
2668
2669
        UsageOptions()
2670
0
            : isPipelineStep(false), maxOptLen(0), isPipelineMain(false)
2671
0
        {
2672
0
        }
2673
    };
2674
2675
    /** Return the usage as a string appropriate for command-line interface
2676
     * \--help output.
2677
     */
2678
    virtual std::string
2679
    GetUsageForCLI(bool shortUsage,
2680
                   const UsageOptions &usageOptions = UsageOptions()) const;
2681
2682
    /** Return the usage of the algorithm as a JSON-serialized string.
2683
     *
2684
     * This can be used to dynamically generate interfaces to algorithms.
2685
     */
2686
    virtual std::string GetUsageAsJSON() const;
2687
2688
    /** Return the actual algorithm that is going to be invoked, when the
2689
     * current algorithm has sub-algorithms.
2690
     *
2691
     * Only valid after ParseCommandLineArguments() has been called.
2692
     */
2693
    GDALAlgorithm &GetActualAlgorithm()
2694
0
    {
2695
0
        if (m_selectedSubAlg)
2696
0
            return m_selectedSubAlg->GetActualAlgorithm();
2697
0
        return *this;
2698
0
    }
2699
2700
    /** Whether the \--help flag has been specified. */
2701
    bool IsHelpRequested() const
2702
0
    {
2703
0
        return m_helpRequested;
2704
0
    }
2705
2706
    /** Whether the \--json-usage flag has been specified. */
2707
    bool IsJSONUsageRequested() const
2708
0
    {
2709
0
        return m_JSONUsageRequested;
2710
0
    }
2711
2712
    /** Whether the \--progress flag has been specified. */
2713
    bool IsProgressBarRequested() const
2714
0
    {
2715
0
        if (m_selectedSubAlg)
2716
0
            return m_selectedSubAlg->IsProgressBarRequested();
2717
0
        return m_progressBarRequested;
2718
0
    }
2719
2720
    /** Return alias names (generally short) for the current algorithm. */
2721
    const std::vector<std::string> &GetAliases() const
2722
0
    {
2723
0
        return m_aliases;
2724
0
    }
2725
2726
    //! @cond Doxygen_Suppress
2727
    /** Return alias names. This method should be redefined in derived classes
2728
     * that want to define aliases.
2729
     */
2730
    static std::vector<std::string> GetAliasesStatic()
2731
0
    {
2732
0
        return {};
2733
0
    }
2734
2735
    //! @endcond
2736
2737
    /** Used by the "gdal info" special algorithm when it first tries to
2738
     * run "gdal raster info", to inherit from the potential special flags,
2739
     * such as \--help or \--json-usage, that this later algorithm has received.
2740
     */
2741
    bool PropagateSpecialActionTo(GDALAlgorithm *target)
2742
0
    {
2743
0
        target->m_calledFromCommandLine = m_calledFromCommandLine;
2744
0
        target->m_progressBarRequested = m_progressBarRequested;
2745
0
        target->m_quiet = m_quiet;
2746
0
        if (m_specialActionRequested)
2747
0
        {
2748
0
            target->m_specialActionRequested = m_specialActionRequested;
2749
0
            target->m_helpRequested = m_helpRequested;
2750
0
            target->m_helpDocRequested = m_helpDocRequested;
2751
0
            target->m_JSONUsageRequested = m_JSONUsageRequested;
2752
0
            return true;
2753
0
        }
2754
0
        return false;
2755
0
    }
2756
2757
    /** Return auto completion suggestions */
2758
    virtual std::vector<std::string>
2759
    GetAutoComplete(std::vector<std::string> &args, bool lastWordIsComplete,
2760
                    bool showAllOptions);
2761
2762
    /** Set whether the algorithm is called from the command line. */
2763
    void SetCalledFromCommandLine()
2764
0
    {
2765
0
        m_calledFromCommandLine = true;
2766
0
    }
2767
2768
    /** Return whether the algorithm is called from the command line. */
2769
    bool IsCalledFromCommandLine() const
2770
0
    {
2771
0
        return m_calledFromCommandLine;
2772
0
    }
2773
2774
    /** Save command line in a .gdalg.json file.
2775
     * If filename is empty, outString will contain the serialized JSON content.
2776
     */
2777
    static bool SaveGDALG(const std::string &filename, std::string &outString,
2778
                          const std::string &commandLine);
2779
2780
    //! @cond Doxygen_Suppress
2781
    void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
2782
                     ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
2783
    //! @endcond
2784
2785
  protected:
2786
    friend class GDALInConstructionAlgorithmArg;
2787
    friend class GDALRasterReprojectUtils;
2788
2789
    /** Selected sub-algorithm. Set by ParseCommandLineArguments() when
2790
     * handling over on a sub-algorithm. */
2791
    GDALAlgorithm *m_selectedSubAlg = nullptr;
2792
2793
    /** Call path to the current algorithm. For example, for "gdal convert raster",
2794
     * it is ["gdal", "convert"]
2795
     */
2796
    std::vector<std::string> m_callPath{};
2797
2798
    /** Long description of the algorithm */
2799
    std::string m_longDescription{};
2800
2801
    /** Whether a progress bar is requested (value of \--progress argument) */
2802
    bool m_progressBarRequested = true;
2803
2804
    /** Whether a progress bar is disabled (value of \--quiet argument) */
2805
    bool m_quiet = false;
2806
2807
    friend class GDALVectorPipelineAlgorithm;
2808
    /** Whether ValidateArguments() should be skipped during ParseCommandLineArguments() */
2809
    bool m_skipValidationInParseCommandLine = false;
2810
2811
    friend class GDALAlgorithmRegistry;  // to set m_aliases
2812
    /** Algorithm alias names */
2813
    std::vector<std::string> m_aliases{};
2814
2815
    /** Whether this algorithm supports a streamed output dataset. */
2816
    bool m_supportsStreamedOutput = false;
2817
2818
    /** Whether this algorithm is run to generated a streamed output dataset. */
2819
    bool m_executionForStreamOutput = false;
2820
2821
    /** Whether this algorithm should be hidden (but can be instantiate if name known) */
2822
    bool m_hidden = false;
2823
2824
    /** Constructor */
2825
    GDALAlgorithm(const std::string &name, const std::string &description,
2826
                  const std::string &helpURL);
2827
2828
    /** Special processing for an argument of type GAAT_DATASET */
2829
    bool ProcessDatasetArg(GDALAlgorithmArg *arg, GDALAlgorithm *algForOutput);
2830
2831
    /** Register the sub-algorithm of type MyAlgorithm.
2832
     */
2833
    template <class MyAlgorithm> bool RegisterSubAlgorithm()
2834
    {
2835
        return m_subAlgRegistry.Register<MyAlgorithm>();
2836
    }
2837
2838
    /** Register a sub-algoritm by its AlgInfo structure.
2839
     */
2840
    bool RegisterSubAlgorithm(const GDALAlgorithmRegistry::AlgInfo &info)
2841
0
    {
2842
0
        return m_subAlgRegistry.Register(info);
2843
0
    }
2844
2845
    /** Allow arbitrary user arguments using long name syntax (--something) */
2846
    void AllowArbitraryLongNameArgs()
2847
0
    {
2848
0
        m_arbitraryLongNameArgsAllowed = true;
2849
0
    }
2850
2851
    /** Add boolean argument. */
2852
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2853
                                           char chShortName,
2854
                                           const std::string &helpMessage,
2855
                                           bool *pValue);
2856
2857
    /** Add string argument. */
2858
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2859
                                           char chShortName,
2860
                                           const std::string &helpMessage,
2861
                                           std::string *pValue);
2862
2863
    /** Add integer argument. */
2864
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2865
                                           char chShortName,
2866
                                           const std::string &helpMessage,
2867
                                           int *pValue);
2868
2869
    /** Add real argument. */
2870
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2871
                                           char chShortName,
2872
                                           const std::string &helpMessage,
2873
                                           double *pValue);
2874
2875
    /** Register an auto complete function for a filename argument */
2876
    static void
2877
    SetAutoCompleteFunctionForFilename(GDALInConstructionAlgorithmArg &arg,
2878
                                       GDALArgDatasetType type);
2879
2880
    /** Add dataset argument. */
2881
    GDALInConstructionAlgorithmArg &
2882
    AddArg(const std::string &longName, char chShortName,
2883
           const std::string &helpMessage, GDALArgDatasetValue *pValue,
2884
           GDALArgDatasetType type = GDAL_OF_RASTER | GDAL_OF_VECTOR |
2885
                                     GDAL_OF_MULTIDIM_RASTER);
2886
2887
    /** Add list of string argument. */
2888
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2889
                                           char chShortName,
2890
                                           const std::string &helpMessage,
2891
                                           std::vector<std::string> *pValue);
2892
2893
    /** Add list of integer argument. */
2894
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2895
                                           char chShortName,
2896
                                           const std::string &helpMessage,
2897
                                           std::vector<int> *pValue);
2898
2899
    /** Add list of real argument. */
2900
    GDALInConstructionAlgorithmArg &AddArg(const std::string &longName,
2901
                                           char chShortName,
2902
                                           const std::string &helpMessage,
2903
                                           std::vector<double> *pValue);
2904
2905
    /** Add list of dataset argument. */
2906
    GDALInConstructionAlgorithmArg &
2907
    AddArg(const std::string &longName, char chShortName,
2908
           const std::string &helpMessage,
2909
           std::vector<GDALArgDatasetValue> *pValue,
2910
           GDALArgDatasetType type = GDAL_OF_RASTER | GDAL_OF_VECTOR |
2911
                                     GDAL_OF_MULTIDIM_RASTER);
2912
2913
    /** Add input dataset argument. */
2914
    GDALInConstructionAlgorithmArg &AddInputDatasetArg(
2915
        GDALArgDatasetValue *pValue,
2916
        GDALArgDatasetType type = GDAL_OF_RASTER | GDAL_OF_VECTOR |
2917
                                  GDAL_OF_MULTIDIM_RASTER,
2918
        bool positionalAndRequired = true, const char *helpMessage = nullptr);
2919
2920
    /** Add input dataset argument. */
2921
    GDALInConstructionAlgorithmArg &AddInputDatasetArg(
2922
        std::vector<GDALArgDatasetValue> *pValue,
2923
        GDALArgDatasetType type = GDAL_OF_RASTER | GDAL_OF_VECTOR |
2924
                                  GDAL_OF_MULTIDIM_RASTER,
2925
        bool positionalAndRequired = true, const char *helpMessage = nullptr);
2926
2927
    /** Add open option(s) argument. */
2928
    GDALInConstructionAlgorithmArg &
2929
    AddOpenOptionsArg(std::vector<std::string> *pValue,
2930
                      const char *helpMessage = nullptr);
2931
2932
    /** Add input format(s) argument. */
2933
    GDALInConstructionAlgorithmArg &
2934
    AddInputFormatsArg(std::vector<std::string> *pValue,
2935
                       const char *helpMessage = nullptr);
2936
2937
    /** Add output dataset argument. */
2938
    GDALInConstructionAlgorithmArg &AddOutputDatasetArg(
2939
        GDALArgDatasetValue *pValue,
2940
        GDALArgDatasetType type = GDAL_OF_RASTER | GDAL_OF_VECTOR |
2941
                                  GDAL_OF_MULTIDIM_RASTER,
2942
        bool positionalAndRequired = true, const char *helpMessage = nullptr);
2943
2944
    /** Add \--overwrite argument. */
2945
    GDALInConstructionAlgorithmArg &
2946
    AddOverwriteArg(bool *pValue, const char *helpMessage = nullptr);
2947
2948
    /** Add \--overwrite-layer argument. */
2949
    GDALInConstructionAlgorithmArg &
2950
    AddOverwriteLayerArg(bool *pValue, const char *helpMessage = nullptr);
2951
2952
    /** Add \--update argument. */
2953
    GDALInConstructionAlgorithmArg &
2954
    AddUpdateArg(bool *pValue, const char *helpMessage = nullptr);
2955
2956
    /** Add \--append argument for a vector layer. */
2957
    GDALInConstructionAlgorithmArg &
2958
    AddAppendLayerArg(bool *pValue, const char *helpMessage = nullptr);
2959
2960
    /** Add (non-CLI) output-string argument. */
2961
    GDALInConstructionAlgorithmArg &
2962
    AddOutputStringArg(std::string *pValue, const char *helpMessage = nullptr);
2963
2964
    /** Add (hidden) stdout argument. */
2965
    GDALInConstructionAlgorithmArg &
2966
    AddStdoutArg(bool *pValue, const char *helpMessage = nullptr);
2967
2968
    /** Add output format argument. */
2969
    GDALInConstructionAlgorithmArg &
2970
    AddOutputFormatArg(std::string *pValue, bool bStreamAllowed = false,
2971
                       bool bGDALGAllowed = false,
2972
                       const char *helpMessage = nullptr);
2973
2974
    /** Add output data type argument. */
2975
    GDALInConstructionAlgorithmArg &
2976
    AddOutputDataTypeArg(std::string *pValue,
2977
                         const char *helpMessage = nullptr);
2978
2979
    /** Add nodata argument. */
2980
    GDALInConstructionAlgorithmArg &
2981
    AddNodataArg(std::string *pValue, bool noneAllowed,
2982
                 const std::string &optionName = "nodata",
2983
                 const char *helpMessage = nullptr);
2984
2985
    /** Add creation option(s) argument. */
2986
    GDALInConstructionAlgorithmArg &
2987
    AddCreationOptionsArg(std::vector<std::string> *pValue,
2988
                          const char *helpMessage = nullptr);
2989
2990
    /** Add layer creation option(s) argument. */
2991
    GDALInConstructionAlgorithmArg &
2992
    AddLayerCreationOptionsArg(std::vector<std::string> *pValue,
2993
                               const char *helpMessage = nullptr);
2994
2995
    /** Add (single) layer name argument. */
2996
    GDALInConstructionAlgorithmArg &
2997
    AddLayerNameArg(std::string *pValue, const char *helpMessage = nullptr);
2998
2999
    /** Add (potentially multiple) layer name(s) argument. */
3000
    GDALInConstructionAlgorithmArg &
3001
    AddLayerNameArg(std::vector<std::string> *pValue,
3002
                    const char *helpMessage = nullptr);
3003
3004
    /** Add geometry type argument */
3005
    GDALInConstructionAlgorithmArg &
3006
    AddGeometryTypeArg(std::string *pValue, const char *helpMessage = nullptr);
3007
3008
    /** Register an auto complete function for a layer name argument */
3009
    static void SetAutoCompleteFunctionForLayerName(
3010
        GDALInConstructionAlgorithmArg &layerArg,
3011
        GDALInConstructionAlgorithmArg &datasetArg);
3012
3013
    /** Add (single) band argument. */
3014
    GDALInConstructionAlgorithmArg &
3015
    AddBandArg(int *pValue, const char *helpMessage = nullptr);
3016
3017
    /** Add (potentially multiple) band argument. */
3018
    GDALInConstructionAlgorithmArg &
3019
    AddBandArg(std::vector<int> *pValue, const char *helpMessage = nullptr);
3020
3021
    /** Add bbox=xmin,ymin,xmax,ymax argument. */
3022
    GDALInConstructionAlgorithmArg &
3023
    AddBBOXArg(std::vector<double> *pValue, const char *helpMessage = nullptr);
3024
3025
    /** Add active layer argument. */
3026
    GDALInConstructionAlgorithmArg &
3027
    AddActiveLayerArg(std::string *pValue, const char *helpMessage = nullptr);
3028
3029
    /** A number of thread argument. The final value is stored in *pValue.
3030
     * pStrValue must be provided as temporary storage, and its initial value
3031
     * (if not empty) is used as the SetDefault() value.
3032
     */
3033
    GDALInConstructionAlgorithmArg &
3034
    AddNumThreadsArg(int *pValue, std::string *pStrValue,
3035
                     const char *helpMessage = nullptr);
3036
3037
    /** Add an argument to ask writing absolute paths. */
3038
    GDALInConstructionAlgorithmArg &
3039
    AddAbsolutePathArg(bool *pValue, const char *helpMessage = nullptr);
3040
3041
    /** Add an argument for pixel function name */
3042
    GDALInConstructionAlgorithmArg &
3043
    AddPixelFunctionNameArg(std::string *pValue,
3044
                            const char *helpMessage = nullptr);
3045
3046
    /** Add an argument for pixel function arguments */
3047
    GDALInConstructionAlgorithmArg &
3048
    AddPixelFunctionArgsArg(std::vector<std::string> *pValue,
3049
                            const char *helpMessage = nullptr);
3050
3051
    /** Add \--quiet (and hidden \--progress) argument. */
3052
    void AddProgressArg();
3053
3054
    /** Register an action that is executed by the ValidateArguments()
3055
     * method. If the provided function returns false, validation fails.
3056
     * Such validation function should typically be used to ensure
3057
     * cross-argument validation. For validation of individual arguments,
3058
     * GDALAlgorithmArg::AddValidationAction should rather be called.
3059
     */
3060
    void AddValidationAction(std::function<bool()> f)
3061
0
    {
3062
0
        m_validationActions.push_back(f);
3063
0
    }
3064
3065
    /** Add KEY=VALUE suggestion from open, creation options */
3066
    static bool AddOptionsSuggestions(const char *pszXML, int datasetType,
3067
                                      const std::string &currentValue,
3068
                                      std::vector<std::string> &oRet);
3069
3070
    /** Validation function to use for key=value type of arguments. */
3071
    bool ParseAndValidateKeyValue(GDALAlgorithmArg &arg);
3072
3073
    /** Method used by GDALRaster|VectorPipelineAlgorithm */
3074
    bool RunPreStepPipelineValidations() const;
3075
3076
    /** Return whether output-format or output arguments express GDALG output */
3077
    bool IsGDALGOutput() const;
3078
3079
    /** Return value for ProcessGDALGOutput */
3080
    enum class ProcessGDALGOutputRet
3081
    {
3082
        /** GDALG output requested and successful. */
3083
        GDALG_OK,
3084
        /** GDALG output requested but an error has occurred. */
3085
        GDALG_ERROR,
3086
        /** GDALG output not requeste. RunImpl() must be run. */
3087
        NOT_GDALG,
3088
    };
3089
3090
    /** Process output to a .gdalg file */
3091
    virtual ProcessGDALGOutputRet ProcessGDALGOutput();
3092
3093
    /** Method executed by Run() when m_executionForStreamOutput is set to
3094
     * ensure the command is safe to execute in a streamed dataset context.
3095
     */
3096
    virtual bool CheckSafeForStreamOutput();
3097
3098
    /** Validate a format argument */
3099
    bool ValidateFormat(const GDALAlgorithmArg &arg, bool bStreamAllowed,
3100
                        bool bGDALGAllowed) const;
3101
3102
    /** Completion function for a format argument */
3103
    static std::vector<std::string>
3104
    FormatAutoCompleteFunction(const GDALAlgorithmArg &arg, bool bStreamAllowed,
3105
                               bool bGDALGAllowed);
3106
3107
    //! @cond Doxygen_Suppress
3108
    void AddAliasFor(GDALInConstructionAlgorithmArg *arg,
3109
                     const std::string &alias);
3110
3111
    void AddShortNameAliasFor(GDALInConstructionAlgorithmArg *arg,
3112
                              char shortNameAlias);
3113
3114
    void SetPositional(GDALInConstructionAlgorithmArg *arg);
3115
3116
    //! @endcond
3117
3118
    /** Whether this argument name is the one of a well-known boolean argument */
3119
    static bool IsKnownOutputRelatedBooleanArgName(std::string_view osName);
3120
3121
    /** Set whether this algorithm should be reported in JSON usage. */
3122
    void SetDisplayInJSONUsage(bool b)
3123
0
    {
3124
0
        m_displayInJSONUsage = b;
3125
0
    }
3126
3127
    /** Method that an algorithm can implement to issue a warning message about
3128
     * its deprecation. This is called at the beginning of the Run() method.
3129
     */
3130
    virtual void WarnIfDeprecated()
3131
0
    {
3132
0
    }
3133
3134
    /** Return the list of arguments for CLI usage */
3135
    std::pair<std::vector<std::pair<GDALAlgorithmArg *, std::string>>, size_t>
3136
    GetArgNamesForCLI() const;
3137
3138
    //! @cond Doxygen_Suppress
3139
    std::string GetUsageForCLIEnd() const;
3140
    //! @endcond
3141
3142
  private:
3143
    const std::string m_name{};
3144
    const std::string m_description{};
3145
    const std::string m_helpURL{};
3146
    const std::string m_helpFullURL{};
3147
    bool m_parsedSubStringAlreadyCalled = false;
3148
    bool m_displayInJSONUsage = true;
3149
    bool m_specialActionRequested = false;
3150
    bool m_helpRequested = false;
3151
    bool m_calledFromCommandLine = false;
3152
3153
    // Used by program-output directives in .rst files
3154
    bool m_helpDocRequested = false;
3155
3156
    bool m_JSONUsageRequested = false;
3157
    bool m_parseForAutoCompletion = false;
3158
    std::string m_referencePath{};
3159
    std::vector<std::string> m_dummyConfigOptions{};
3160
    std::vector<std::unique_ptr<GDALAlgorithmArg>> m_args{};
3161
    std::map<std::string, GDALAlgorithmArg *> m_mapLongNameToArg{};
3162
    std::map<std::string, GDALAlgorithmArg *> m_mapShortNameToArg{};
3163
    std::vector<GDALAlgorithmArg *> m_positionalArgs{};
3164
    GDALAlgorithmRegistry m_subAlgRegistry{};
3165
    std::unique_ptr<GDALAlgorithm> m_selectedSubAlgHolder{};
3166
    std::function<std::vector<std::string>(const std::vector<std::string> &)>
3167
        m_autoCompleteFunction{};
3168
    std::vector<std::function<bool()>> m_validationActions{};
3169
3170
    std::string m_dummyVal{};
3171
    GDALAlgorithmArg m_dummyArg{
3172
        GDALAlgorithmArgDecl("dummy", 0, "", GAAT_STRING), &m_dummyVal};
3173
3174
    /** Whether arbitrary user arguments using long name syntax (--something)
3175
     * are allowed.
3176
     */
3177
    bool m_arbitraryLongNameArgsAllowed = false;
3178
3179
    std::vector<std::unique_ptr<std::string>>
3180
        m_arbitraryLongNameArgsValuesStr{};
3181
    std::vector<std::unique_ptr<bool>> m_arbitraryLongNameArgsValuesBool{};
3182
3183
    friend GDALAlgorithmArgH GDALAlgorithmGetArg(GDALAlgorithmH hAlg,
3184
                                                 const char *pszArgName);
3185
    friend GDALAlgorithmArgH
3186
    GDALAlgorithmGetArgNonConst(GDALAlgorithmH hAlg, const char *pszArgName);
3187
    GDALAlgorithmArg *GetArg(const std::string &osName, bool suggestionAllowed,
3188
                             bool isConst);
3189
3190
    GDALInConstructionAlgorithmArg &
3191
    AddArg(std::unique_ptr<GDALInConstructionAlgorithmArg> arg);
3192
    bool ParseArgument(
3193
        GDALAlgorithmArg *arg, const std::string &name,
3194
        const std::string &value,
3195
        std::map<
3196
            GDALAlgorithmArg *,
3197
            std::variant<std::vector<std::string>, std::vector<int>,
3198
                         std::vector<double>, std::vector<GDALArgDatasetValue>>>
3199
            &inConstructionValues);
3200
3201
    bool ValidateBandArg() const;
3202
3203
    virtual bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) = 0;
3204
3205
    /** Extract the last option and its potential value from the provided
3206
     * argument list, and remove them from the list.
3207
     */
3208
    void ExtractLastOptionAndValue(std::vector<std::string> &args,
3209
                                   std::string &option,
3210
                                   std::string &value) const;
3211
3212
    GDALAlgorithm(const GDALAlgorithm &) = delete;
3213
    GDALAlgorithm &operator=(const GDALAlgorithm &) = delete;
3214
};
3215
3216
//! @cond Doxygen_Suppress
3217
struct GDALAlgorithmHS
3218
{
3219
  private:
3220
    std::unique_ptr<GDALAlgorithm> uniquePtr{};
3221
3222
    GDALAlgorithmHS(const GDALAlgorithmHS &) = delete;
3223
    GDALAlgorithmHS &operator=(const GDALAlgorithmHS &) = delete;
3224
3225
  public:
3226
    GDALAlgorithm *ptr = nullptr;
3227
3228
0
    GDALAlgorithmHS() = default;
3229
3230
    explicit GDALAlgorithmHS(std::unique_ptr<GDALAlgorithm> alg)
3231
0
        : uniquePtr(std::move(alg)), ptr(uniquePtr.get())
3232
0
    {
3233
0
    }
3234
3235
    static std::unique_ptr<GDALAlgorithmHS> FromRef(GDALAlgorithm &alg)
3236
0
    {
3237
0
        auto ret = std::make_unique<GDALAlgorithmHS>();
3238
0
        ret->ptr = &alg;
3239
0
        return ret;
3240
0
    }
3241
};
3242
3243
/************************************************************************/
3244
/*                       GDALContainerAlgorithm                         */
3245
/************************************************************************/
3246
3247
class CPL_DLL GDALContainerAlgorithm : public GDALAlgorithm
3248
{
3249
  public:
3250
    explicit GDALContainerAlgorithm(
3251
        const std::string &name, const std::string &description = std::string(),
3252
        const std::string &helpURL = std::string())
3253
0
        : GDALAlgorithm(name, description, helpURL)
3254
0
    {
3255
0
    }
3256
3257
  protected:
3258
    bool RunImpl(GDALProgressFunc, void *) override;
3259
};
3260
3261
//! @endcond
3262
3263
/************************************************************************/
3264
/*                   GDALGlobalAlgorithmRegistry                        */
3265
/************************************************************************/
3266
3267
/** Global registry of GDAL algorithms.
3268
 */
3269
class CPL_DLL GDALGlobalAlgorithmRegistry final : public GDALAlgorithmRegistry
3270
{
3271
  public:
3272
    /** Name of the root "gdal" algorithm. */
3273
    static constexpr const char *ROOT_ALG_NAME = "gdal";
3274
3275
    /** Get the singleton */
3276
    static GDALGlobalAlgorithmRegistry &GetSingleton();
3277
3278
    /** Instantiate an algorithm by its name or one of its alias. */
3279
    std::unique_ptr<GDALAlgorithm>
3280
    Instantiate(const std::string &name) const override;
3281
3282
    /** Instantiation function */
3283
    using InstantiateFunc = std::function<std::unique_ptr<GDALAlgorithm>()>;
3284
3285
    /** Declare the algorithm designed by its path (omitting leading path)
3286
     * and provide its instantiation method.
3287
     * For example {"driver", "pdf", "list-layers"}
3288
     *
3289
     * This is typically used by plugins to register extra algorithms.
3290
     */
3291
    void DeclareAlgorithm(const std::vector<std::string> &path,
3292
                          InstantiateFunc instantiateFunc);
3293
3294
    /** Return the direct declared (as per DeclareAlgorithm()) subalgorithms
3295
     * of the given path. */
3296
    std::vector<std::string>
3297
    GetDeclaredSubAlgorithmNames(const std::vector<std::string> &path) const;
3298
3299
    /** Return whether a subalgorithm is declared at the given path. */
3300
    bool HasDeclaredSubAlgorithm(const std::vector<std::string> &path) const;
3301
3302
    /** Instantiate a declared (as per DeclareAlgorithm()) subalgorithm. */
3303
    std::unique_ptr<GDALAlgorithm>
3304
    InstantiateDeclaredSubAlgorithm(const std::vector<std::string> &path) const;
3305
3306
  private:
3307
    struct Node
3308
    {
3309
        InstantiateFunc instantiateFunc{};
3310
        std::map<std::string, Node> children{};
3311
    };
3312
3313
    Node m_root{};
3314
3315
    GDALGlobalAlgorithmRegistry();
3316
    ~GDALGlobalAlgorithmRegistry();
3317
3318
    const Node *GetNodeFromPath(const std::vector<std::string> &path) const;
3319
};
3320
3321
/************************************************************************/
3322
/*                  GDAL_STATIC_REGISTER_ALG()                          */
3323
/************************************************************************/
3324
3325
/** Static registration of an algorithm by its class name (which must implement
3326
 * GDALAlgorithm)
3327
 */
3328
#define GDAL_STATIC_REGISTER_ALG(MyAlgorithm)                                  \
3329
    static bool MyAlgorithm##_static_registration =                            \
3330
        GDALGlobalAlgorithmRegistry::GetSingleton().Register<MyAlgorithm>()
3331
3332
#endif  // #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) && (defined(DOXYGEN_SKIP) || __cplusplus >= 201703L || _MSC_VER >= 1920)
3333
3334
#endif  // GDAL_ALGORITHM_INCLUDED