LCOV - code coverage report
Current view: top level - apps - gdal.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 65 66 98.5 %
Date: 2025-05-15 13:16:46 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          75 : static void EmitCompletion(std::unique_ptr<GDALAlgorithm> rootAlg,
      28             :                            const std::vector<std::string> &argsIn,
      29             :                            bool lastWordIsComplete)
      30             : {
      31             : #ifdef DEBUG_COMPLETION
      32             :     for (size_t i = 0; i < argsIn.size(); ++i)
      33             :         fprintf(stderr, "arg[%d]='%s'\n", static_cast<int>(i),
      34             :                 argsIn[i].c_str());
      35             : #endif
      36             : 
      37          75 :     std::vector<std::string> args = argsIn;
      38             : 
      39          75 :     std::string ret;
      40       33460 :     const auto addSpace = [&ret]()
      41             :     {
      42       16765 :         if (!ret.empty())
      43       16695 :             ret += " ";
      44       16840 :     };
      45             : 
      46         222 :     if (!args.empty() &&
      47          74 :         (args.back() == "--config" ||
      48         144 :          STARTS_WITH(args.back().c_str(), "--config=") ||
      49         140 :          (args.size() >= 2 && args[args.size() - 2] == "--config")))
      50             :     {
      51           4 :         if (args.back() == "--config=" || args.back().back() != '=')
      52             :         {
      53           4 :             CPLStringList aosConfigOptions(CPLGetKnownConfigOptions());
      54        2128 :             for (const char *pszOpt : cpl::Iterate(aosConfigOptions))
      55             :             {
      56        2126 :                 addSpace();
      57        2126 :                 ret += pszOpt;
      58        2126 :                 ret += '=';
      59             :             }
      60           2 :             printf("%s", ret.c_str());
      61             :         }
      62           4 :         return;
      63             :     }
      64             : 
      65       14710 :     for (const auto &choice : rootAlg->GetAutoComplete(
      66       14710 :              args, lastWordIsComplete, /*showAllOptions = */ true))
      67             :     {
      68       14639 :         addSpace();
      69       14639 :         ret += CPLString(choice).replaceAll(" ", "\\ ");
      70             :     }
      71             : 
      72             : #ifdef DEBUG_COMPLETION
      73             :     fprintf(stderr, "ret = '%s'\n", ret.c_str());
      74             : #endif
      75          71 :     if (!ret.empty())
      76          68 :         printf("%s", ret.c_str());
      77             : }
      78             : 
      79             : /************************************************************************/
      80             : /*                                main()                                */
      81             : /************************************************************************/
      82             : 
      83         106 : MAIN_START(argc, argv)
      84             : {
      85         106 :     auto alg = GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate(
      86         318 :         GDALGlobalAlgorithmRegistry::ROOT_ALG_NAME);
      87         106 :     assert(alg);
      88             : 
      89         106 :     if (argc >= 3 && strcmp(argv[1], "completion") == 0)
      90             :     {
      91          75 :         GDALAllRegister();
      92             : 
      93          75 :         const bool bLastWordIsComplete =
      94          75 :             EQUAL(argv[argc - 1], "last_word_is_complete=true");
      95          75 :         if (STARTS_WITH(argv[argc - 1], "last_word_is_complete="))
      96           2 :             --argc;
      97             : 
      98             :         // Process lines like "gdal completion gdal raster last_word_is_complete=true|false"
      99          75 :         EmitCompletion(std::move(alg),
     100         150 :                        std::vector<std::string>(argv + 3, argv + argc),
     101             :                        bLastWordIsComplete);
     102          75 :         return 0;
     103             :     }
     104             : 
     105          31 :     EarlySetConfigOptions(argc, argv);
     106             : 
     107             :     /* -------------------------------------------------------------------- */
     108             :     /*      Register standard GDAL drivers, and process generic GDAL        */
     109             :     /*      command options.                                                */
     110             :     /* -------------------------------------------------------------------- */
     111             : 
     112          31 :     GDALAllRegister();
     113             : 
     114          31 :     argc = GDALGeneralCmdLineProcessor(
     115             :         argc, &argv, GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_MULTIDIM_RASTER);
     116          31 :     if (argc < 1)
     117           1 :         return (-argc);
     118             : 
     119          60 :     std::vector<std::string> args;
     120         143 :     for (int i = 1; i < argc; ++i)
     121         113 :         args.push_back(argv[i]);
     122          30 :     CSLDestroy(argv);
     123             : 
     124          30 :     if (!alg->ParseCommandLineArguments(args))
     125             :     {
     126           8 :         if (strstr(CPLGetLastErrorMsg(), "Do you mean") == nullptr)
     127             :         {
     128           5 :             fprintf(stderr, "%s", alg->GetUsageForCLI(true).c_str());
     129             :         }
     130           8 :         return 1;
     131             :     }
     132             : 
     133             :     {
     134          22 :         const auto stdoutArg = alg->GetActualAlgorithm().GetArg("stdout");
     135          22 :         if (stdoutArg && stdoutArg->GetType() == GAAT_BOOLEAN)
     136           4 :             stdoutArg->Set(true);
     137             :     }
     138             : 
     139             :     GDALProgressFunc pfnProgress =
     140          22 :         alg->IsProgressBarRequested() ? GDALTermProgress : nullptr;
     141          22 :     void *pProgressData = nullptr;
     142             : 
     143          22 :     alg->SetCalledFromCommandLine();
     144             : 
     145          22 :     int ret = 0;
     146          22 :     if (alg->Run(pfnProgress, pProgressData) && alg->Finalize())
     147             :     {
     148             :         const auto outputArg =
     149          21 :             alg->GetActualAlgorithm().GetArg("output-string");
     150          29 :         if (outputArg && outputArg->GetType() == GAAT_STRING &&
     151           8 :             outputArg->IsOutput())
     152             :         {
     153           8 :             printf("%s", outputArg->Get<std::string>().c_str());
     154             :         }
     155             :     }
     156             :     else
     157             :     {
     158           1 :         ret = 1;
     159             :     }
     160             : 
     161          22 :     return ret;
     162             : }
     163             : 
     164           0 : MAIN_END

Generated by: LCOV version 1.14