LCOV - code coverage report
Current view: top level - apps - gdal.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 68 69 98.6 %
Date: 2025-01-18 12:42:00 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          57 : 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          57 :     std::vector<std::string> args = argsIn;
      37             : 
      38          57 :     std::string ret;
      39       32069 :     const auto addSpace = [&ret]()
      40             :     {
      41       16061 :         if (!ret.empty())
      42       16008 :             ret += " ";
      43       16118 :     };
      44             : 
      45         168 :     if (!args.empty() &&
      46          56 :         (args.back() == "--config" ||
      47         108 :          STARTS_WITH(args.back().c_str(), "--config=") ||
      48         104 :          (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        2120 :             for (const char *pszOpt : cpl::Iterate(aosConfigOptions))
      54             :             {
      55        2118 :                 addSpace();
      56        2118 :                 ret += pszOpt;
      57        2118 :                 ret += '=';
      58             :             }
      59           2 :             printf("%s", ret.c_str());
      60             :         }
      61           4 :         return;
      62             :     }
      63             : 
      64             :     // Get inner-most algorithm
      65          53 :     bool showAllOptions = true;
      66         106 :     auto curAlg = std::move(rootAlg);
      67         154 :     while (!args.empty() && !args.front().empty() && args.front()[0] != '-')
      68             :     {
      69         127 :         auto subAlg = curAlg->InstantiateSubAlgorithm(args.front());
      70         127 :         if (!subAlg)
      71          26 :             break;
      72         101 :         showAllOptions = false;
      73         101 :         args.erase(args.begin());
      74         101 :         curAlg = std::move(subAlg);
      75             :     }
      76             : 
      77       13996 :     for (const auto &choice : curAlg->GetAutoComplete(args, showAllOptions))
      78             :     {
      79       13943 :         addSpace();
      80       13943 :         ret += CPLString(choice).replaceAll(" ", "\\ ");
      81             :     }
      82             : 
      83             : #ifdef DEBUG_COMPLETION
      84             :     fprintf(stderr, "ret = '%s'\n", ret.c_str());
      85             : #endif
      86          53 :     if (!ret.empty())
      87          51 :         printf("%s", ret.c_str());
      88             : }
      89             : 
      90             : /************************************************************************/
      91             : /*                                main()                                */
      92             : /************************************************************************/
      93             : 
      94          73 : MAIN_START(argc, argv)
      95             : {
      96          73 :     auto alg = GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate(
      97         219 :         GDALGlobalAlgorithmRegistry::ROOT_ALG_NAME);
      98          73 :     assert(alg);
      99             : 
     100          73 :     if (argc >= 3 && strcmp(argv[1], "completion") == 0)
     101             :     {
     102          57 :         GDALAllRegister();
     103             : 
     104             :         // Process lines like "gdal completion gdal raster"
     105          57 :         EmitCompletion(std::move(alg),
     106         114 :                        std::vector<std::string>(argv + 3, argv + argc));
     107          57 :         return 0;
     108             :     }
     109             : 
     110          16 :     EarlySetConfigOptions(argc, argv);
     111             : 
     112             :     /* -------------------------------------------------------------------- */
     113             :     /*      Register standard GDAL drivers, and process generic GDAL        */
     114             :     /*      command options.                                                */
     115             :     /* -------------------------------------------------------------------- */
     116             : 
     117          16 :     GDALAllRegister();
     118             : 
     119          16 :     argc = GDALGeneralCmdLineProcessor(
     120             :         argc, &argv, GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_MULTIDIM_RASTER);
     121          16 :     if (argc < 1)
     122           1 :         return (-argc);
     123             : 
     124          30 :     alg->SetCallPath(std::vector<std::string>{argv[0]});
     125          30 :     std::vector<std::string> args;
     126          70 :     for (int i = 1; i < argc; ++i)
     127          55 :         args.push_back(argv[i]);
     128          15 :     CSLDestroy(argv);
     129             : 
     130          15 :     if (!alg->ParseCommandLineArguments(args))
     131             :     {
     132           3 :         fprintf(stderr, "%s", alg->GetUsageForCLI(true).c_str());
     133           3 :         return 1;
     134             :     }
     135             : 
     136             :     {
     137          12 :         const auto stdoutArg = alg->GetActualAlgorithm().GetArg("stdout");
     138          12 :         if (stdoutArg && stdoutArg->GetType() == GAAT_BOOLEAN)
     139           3 :             stdoutArg->Set(true);
     140             :     }
     141             : 
     142             :     GDALProgressFunc pfnProgress =
     143          12 :         alg->IsProgressBarRequested() ? GDALTermProgress : nullptr;
     144          12 :     void *pProgressData = nullptr;
     145             : 
     146          12 :     int ret = 0;
     147          12 :     if (alg->Run(pfnProgress, pProgressData) && alg->Finalize())
     148             :     {
     149             :         const auto outputArg =
     150          11 :             alg->GetActualAlgorithm().GetArg("output-string");
     151          14 :         if (outputArg && outputArg->GetType() == GAAT_STRING &&
     152           3 :             outputArg->IsOutput())
     153             :         {
     154           3 :             printf("%s", outputArg->Get<std::string>().c_str());
     155             :         }
     156             :     }
     157             :     else
     158             :     {
     159           1 :         ret = 1;
     160             :     }
     161             : 
     162          12 :     return ret;
     163             : }
     164             : 
     165           0 : MAIN_END

Generated by: LCOV version 1.14