• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15171299595

21 May 2025 07:51PM UTC coverage: 70.949% (+0.03%) from 70.921%
15171299595

Pull #12392

github

web-flow
Merge 405a716f5 into ce2393a45
Pull Request #12392: GDALOverviews: Limit external file size in GDALRegenerateOverviewsMultiBand

174 of 189 new or added lines in 2 files covered. (92.06%)

22859 existing lines in 88 files now uncovered.

568261 of 800943 relevant lines covered (70.95%)

235911.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.75
/apps/gdal.cpp
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  CLI front-end
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
#include "gdalalgorithm.h"
14
#include "commonutils.h"
15

16
#include "gdal.h"
17

18
#include <cassert>
19
#include <utility>
20

21
// #define DEBUG_COMPLETION
22

23
/************************************************************************/
24
/*                           EmitCompletion()                           */
25
/************************************************************************/
26

27
/** Return on stdout a space-separated list of choices for bash completion */
28
static void EmitCompletion(std::unique_ptr<GDALAlgorithm> rootAlg,
80✔
29
                           const std::vector<std::string> &argsIn,
30
                           bool lastWordIsComplete)
31
{
32
#ifdef DEBUG_COMPLETION
33
    for (size_t i = 0; i < argsIn.size(); ++i)
34
        fprintf(stderr, "arg[%d]='%s'\n", static_cast<int>(i),
35
                argsIn[i].c_str());
36
#endif
37

38
    std::vector<std::string> args = argsIn;
80✔
39

40
    std::string ret;
80✔
41
    const auto addSpace = [&ret]()
33,471✔
42
    {
43
        if (!ret.empty())
16,772✔
44
            ret += " ";
16,699✔
45
    };
16,852✔
46

47
    if (!args.empty() &&
237✔
48
        (args.back() == "--config" ||
79✔
49
         STARTS_WITH(args.back().c_str(), "--config=") ||
154✔
50
         (args.size() >= 2 && args[args.size() - 2] == "--config")))
150✔
51
    {
52
        if (args.back() == "--config=" || args.back().back() != '=')
4✔
53
        {
54
            CPLStringList aosConfigOptions(CPLGetKnownConfigOptions());
4✔
55
            for (const char *pszOpt : cpl::Iterate(aosConfigOptions))
2,128✔
56
            {
57
                addSpace();
2,126✔
58
                ret += pszOpt;
2,126✔
59
                ret += '=';
2,126✔
60
            }
61
            printf("%s", ret.c_str());
2✔
62
        }
63
        return;
4✔
64
    }
65

66
    for (const auto &choice : rootAlg->GetAutoComplete(
14,722✔
67
             args, lastWordIsComplete, /*showAllOptions = */ true))
14,722✔
68
    {
69
        addSpace();
14,646✔
70
        ret += CPLString(choice).replaceAll(" ", "\\ ");
14,646✔
71
    }
72

73
#ifdef DEBUG_COMPLETION
74
    fprintf(stderr, "ret = '%s'\n", ret.c_str());
75
#endif
76
    if (!ret.empty())
76✔
77
        printf("%s", ret.c_str());
71✔
78
}
79

80
/************************************************************************/
81
/*                                main()                                */
82
/************************************************************************/
83

84
MAIN_START(argc, argv)
117✔
85
{
86
    auto alg = GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate(
117✔
87
        GDALGlobalAlgorithmRegistry::ROOT_ALG_NAME);
351✔
88
    assert(alg);
117✔
89

90
    if (argc >= 3 && strcmp(argv[1], "completion") == 0)
117✔
91
    {
92
        GDALAllRegister();
80✔
93

94
        const bool bLastWordIsComplete =
80✔
95
            EQUAL(argv[argc - 1], "last_word_is_complete=true");
80✔
96
        if (STARTS_WITH(argv[argc - 1], "last_word_is_complete="))
80✔
97
            --argc;
2✔
98

99
        // Process lines like "gdal completion gdal raster last_word_is_complete=true|false"
100
        EmitCompletion(std::move(alg),
80✔
101
                       std::vector<std::string>(argv + 3, argv + argc),
160✔
102
                       bLastWordIsComplete);
103
        return 0;
80✔
104
    }
105

106
    EarlySetConfigOptions(argc, argv);
37✔
107

108
    /* -------------------------------------------------------------------- */
109
    /*      Register standard GDAL drivers, and process generic GDAL        */
110
    /*      command options.                                                */
111
    /* -------------------------------------------------------------------- */
112

113
    GDALAllRegister();
37✔
114

115
    // Prevent GDALGeneralCmdLineProcessor() to process --format XXX, unless
116
    // "gdal" is invoked only with it. Cf #12411
117
    std::vector<std::pair<char **, char *>> apOrigFormat;
74✔
118
    constexpr const char *pszFormatReplaced = "--format-XXXX";
37✔
119
    if (!(argc == 3 && strcmp(argv[1], "--format") == 0))
37✔
120
    {
121
        for (int i = 1; i < argc; ++i)
177✔
122
        {
123
            if (strcmp(argv[i], "--format") == 0)
141✔
124
            {
125
                apOrigFormat.emplace_back(argv + i, argv[i]);
1✔
126
                argv[i] = const_cast<char *>(pszFormatReplaced);
1✔
127
            }
128
        }
129
    }
130

131
    argc = GDALGeneralCmdLineProcessor(
37✔
132
        argc, &argv, GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_MULTIDIM_RASTER);
133
    for (auto &pair : apOrigFormat)
38✔
134
    {
135
        *(pair.first) = pair.second;
1✔
136
    }
137

138
    if (argc < 1)
37✔
139
        return (-argc);
2✔
140

141
    std::vector<std::string> args;
70✔
142
    for (int i = 1; i < argc; ++i)
173✔
143
        args.push_back(strcmp(argv[i], pszFormatReplaced) == 0 ? "--format"
275✔
144
                                                               : argv[i]);
137✔
145
    CSLDestroy(argv);
35✔
146

147
    alg->SetCalledFromCommandLine();
35✔
148

149
    if (!alg->ParseCommandLineArguments(args))
35✔
150
    {
151
        if (strstr(CPLGetLastErrorMsg(), "Do you mean") == nullptr &&
12✔
152
            strstr(CPLGetLastErrorMsg(), "Should be one among") == nullptr &&
9✔
153
            strstr(CPLGetLastErrorMsg(), "Potential values for argument") ==
9✔
154
                nullptr &&
21✔
155
            strstr(CPLGetLastErrorMsg(),
7✔
156
                   "Single potential value for argument") == nullptr)
157
        {
158
            fprintf(stderr, "%s", alg->GetUsageForCLI(true).c_str());
5✔
159
        }
160
        return 1;
12✔
161
    }
162

163
    {
164
        const auto stdoutArg = alg->GetActualAlgorithm().GetArg("stdout");
23✔
165
        if (stdoutArg && stdoutArg->GetType() == GAAT_BOOLEAN)
23✔
166
            stdoutArg->Set(true);
4✔
167
    }
168

169
    GDALProgressFunc pfnProgress =
170
        alg->IsProgressBarRequested() ? GDALTermProgress : nullptr;
23✔
171
    void *pProgressData = nullptr;
23✔
172

173
    int ret = 0;
23✔
174
    if (alg->Run(pfnProgress, pProgressData) && alg->Finalize())
23✔
175
    {
176
        const auto outputArg =
177
            alg->GetActualAlgorithm().GetArg("output-string");
22✔
178
        if (outputArg && outputArg->GetType() == GAAT_STRING &&
30✔
179
            outputArg->IsOutput())
8✔
180
        {
181
            printf("%s", outputArg->Get<std::string>().c_str());
8✔
182
        }
183
    }
184
    else
185
    {
186
        ret = 1;
1✔
187
    }
188

189
    return ret;
23✔
190
}
191

UNCOV
192
MAIN_END
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc