Coverage Report

Created: 2025-06-13 06:29

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