LCOV - code coverage report
Current view: top level - apps - gdal.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 59 60 98.3 %
Date: 2025-03-28 11:40:40 Functions: 3 3 100.0 %

          Line data    Source code
       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             : 
      20             : // #define DEBUG_COMPLETION
      21             : 
      22             : /************************************************************************/
      23             : /*                           EmitCompletion()                           */
      24             : /************************************************************************/
      25             : 
      26             : /** Return on stdout a space-separated list of choices for bash completion */
      27          68 : static void EmitCompletion(std::unique_ptr<GDALAlgorithm> rootAlg,
      28             :                            const std::vector<std::string> &argsIn)
      29             : {
      30             : #ifdef DEBUG_COMPLETION
      31             :     for (size_t i = 0; i < argsIn.size(); ++i)
      32             :         fprintf(stderr, "arg[%d]='%s'\n", static_cast<int>(i),
      33             :                 argsIn[i].c_str());
      34             : #endif
      35             : 
      36          68 :     std::vector<std::string> args = argsIn;
      37             : 
      38          68 :     std::string ret;
      39       32320 :     const auto addSpace = [&ret]()
      40             :     {
      41       16192 :         if (!ret.empty())
      42       16128 :             ret += " ";
      43       16260 :     };
      44             : 
      45         201 :     if (!args.empty() &&
      46          67 :         (args.back() == "--config" ||
      47         130 :          STARTS_WITH(args.back().c_str(), "--config=") ||
      48         126 :          (args.size() >= 2 && args[args.size() - 2] == "--config")))
      49             :     {
      50           4 :         if (args.back() == "--config=" || args.back().back() != '=')
      51             :         {
      52           4 :             CPLStringList aosConfigOptions(CPLGetKnownConfigOptions());
      53        2098 :             for (const char *pszOpt : cpl::Iterate(aosConfigOptions))
      54             :             {
      55        2096 :                 addSpace();
      56        2096 :                 ret += pszOpt;
      57        2096 :                 ret += '=';
      58             :             }
      59           2 :             printf("%s", ret.c_str());
      60             :         }
      61           4 :         return;
      62             :     }
      63             : 
      64       14096 :     for (const auto &choice :
      65       14160 :          rootAlg->GetAutoComplete(args, /*showAllOptions = */ true))
      66             :     {
      67       14096 :         addSpace();
      68       14096 :         ret += CPLString(choice).replaceAll(" ", "\\ ");
      69             :     }
      70             : 
      71             : #ifdef DEBUG_COMPLETION
      72             :     fprintf(stderr, "ret = '%s'\n", ret.c_str());
      73             : #endif
      74          64 :     if (!ret.empty())
      75          62 :         printf("%s", ret.c_str());
      76             : }
      77             : 
      78             : /************************************************************************/
      79             : /*                                main()                                */
      80             : /************************************************************************/
      81             : 
      82          92 : MAIN_START(argc, argv)
      83             : {
      84          92 :     auto alg = GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate(
      85         276 :         GDALGlobalAlgorithmRegistry::ROOT_ALG_NAME);
      86          92 :     assert(alg);
      87             : 
      88          92 :     if (argc >= 3 && strcmp(argv[1], "completion") == 0)
      89             :     {
      90          68 :         GDALAllRegister();
      91             : 
      92             :         // Process lines like "gdal completion gdal raster"
      93          68 :         EmitCompletion(std::move(alg),
      94         136 :                        std::vector<std::string>(argv + 3, argv + argc));
      95          68 :         return 0;
      96             :     }
      97             : 
      98          24 :     EarlySetConfigOptions(argc, argv);
      99             : 
     100             :     /* -------------------------------------------------------------------- */
     101             :     /*      Register standard GDAL drivers, and process generic GDAL        */
     102             :     /*      command options.                                                */
     103             :     /* -------------------------------------------------------------------- */
     104             : 
     105          24 :     GDALAllRegister();
     106             : 
     107          24 :     argc = GDALGeneralCmdLineProcessor(
     108             :         argc, &argv, GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_MULTIDIM_RASTER);
     109          24 :     if (argc < 1)
     110           1 :         return (-argc);
     111             : 
     112          46 :     std::vector<std::string> args;
     113         116 :     for (int i = 1; i < argc; ++i)
     114          93 :         args.push_back(argv[i]);
     115          23 :     CSLDestroy(argv);
     116             : 
     117          23 :     if (!alg->ParseCommandLineArguments(args))
     118             :     {
     119           5 :         fprintf(stderr, "%s", alg->GetUsageForCLI(true).c_str());
     120           5 :         return 1;
     121             :     }
     122             : 
     123             :     {
     124          18 :         const auto stdoutArg = alg->GetActualAlgorithm().GetArg("stdout");
     125          18 :         if (stdoutArg && stdoutArg->GetType() == GAAT_BOOLEAN)
     126           3 :             stdoutArg->Set(true);
     127             :     }
     128             : 
     129             :     GDALProgressFunc pfnProgress =
     130          18 :         alg->IsProgressBarRequested() ? GDALTermProgress : nullptr;
     131          18 :     void *pProgressData = nullptr;
     132             : 
     133          18 :     int ret = 0;
     134          18 :     if (alg->Run(pfnProgress, pProgressData) && alg->Finalize())
     135             :     {
     136             :         const auto outputArg =
     137          17 :             alg->GetActualAlgorithm().GetArg("output-string");
     138          20 :         if (outputArg && outputArg->GetType() == GAAT_STRING &&
     139           3 :             outputArg->IsOutput())
     140             :         {
     141           3 :             printf("%s", outputArg->Get<std::string>().c_str());
     142             :         }
     143             :     }
     144             :     else
     145             :     {
     146           1 :         ret = 1;
     147             :     }
     148             : 
     149          18 :     return ret;
     150             : }
     151             : 
     152           0 : MAIN_END

Generated by: LCOV version 1.14