LCOV - code coverage report
Current view: top level - apps - gdalalg_main.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 49 68 72.1 %
Date: 2025-05-15 13:16:46 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *
       3             : * Project:  GDAL
       4             : * Purpose:  gdal "main" command
       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 "gdalalg_main.h"
      14             : 
      15             : #include "gdal_priv.h"
      16             : 
      17             : //! @cond Doxygen_Suppress
      18             : 
      19             : #ifndef _
      20             : #define _(x) (x)
      21             : #endif
      22             : 
      23             : /************************************************************************/
      24             : /*                  GDALMainAlgorithm::GDALMainAlgorithm()              */
      25             : /************************************************************************/
      26             : 
      27         160 : GDALMainAlgorithm::GDALMainAlgorithm()
      28         160 :     : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
      29             : {
      30        1280 :     for (const std::string &subAlgName :
      31        2720 :          GDALGlobalAlgorithmRegistry::GetSingleton().GetNames())
      32             :     {
      33             :         const auto pInfo =
      34        1280 :             GDALGlobalAlgorithmRegistry::GetSingleton().GetInfo(subAlgName);
      35        1280 :         if (pInfo)
      36        1280 :             RegisterSubAlgorithm(*pInfo);
      37             :     }
      38             : 
      39         320 :     SetCallPath({NAME});
      40             : 
      41         320 :     AddArg("version", 0, _("Display GDAL version and exit"), &m_version)
      42         160 :         .SetOnlyForCLI();
      43         160 :     AddArg("drivers", 0, _("Display driver list as JSON document"), &m_drivers);
      44             : 
      45         160 :     AddOutputStringArg(&m_output);
      46             : 
      47             :     m_longDescription = "'gdal <FILENAME>' can also be used as a shortcut for "
      48             :                         "'gdal info <FILENAME>'.\n"
      49             :                         "And 'gdal read <FILENAME> ! ...' as a shortcut for "
      50         160 :                         "'gdal pipeline <FILENAME> ! ...'.";
      51             : 
      52         160 :     SetDisplayInJSONUsage(false);
      53         160 : }
      54             : 
      55             : /************************************************************************/
      56             : /*              GDALMainAlgorithm::ParseCommandLineArguments()          */
      57             : /************************************************************************/
      58             : 
      59          83 : bool GDALMainAlgorithm::ParseCommandLineArguments(
      60             :     const std::vector<std::string> &args)
      61             : {
      62             :     // Detect shortest form of pipeline:
      63             :     // "gdal read in.tif ! .... ! write out.tif"
      64          83 :     if (args.size() >= 2 && args[0] == "read")
      65             :     {
      66             :         m_subAlg =
      67           0 :             GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate("pipeline");
      68           0 :         if (m_subAlg)
      69             :         {
      70           0 :             bool ret = m_subAlg->ParseCommandLineArguments(args);
      71           0 :             if (ret)
      72             :             {
      73           0 :                 m_selectedSubAlg = &(m_subAlg->GetActualAlgorithm());
      74           0 :                 std::vector<std::string> callPath(m_callPath);
      75           0 :                 callPath.push_back("vector");
      76           0 :                 m_selectedSubAlg->SetCallPath(callPath);
      77           0 :                 return true;
      78             :             }
      79           0 :             else if (strstr(CPLGetLastErrorMsg(),
      80           0 :                             "has both raster and vector content"))
      81             :             {
      82           0 :                 m_showUsage = false;
      83           0 :                 return false;
      84             :             }
      85             :         }
      86             : 
      87           0 :         return GDALAlgorithm::ParseCommandLineArguments(args);
      88             :     }
      89          86 :     else if (args.size() == 1 && args[0].size() >= 2 && args[0][0] == '-' &&
      90           3 :              args[0][1] == '-')
      91             :     {
      92           3 :         return GDALAlgorithm::ParseCommandLineArguments(args);
      93             :     }
      94             : 
      95             :     // Generic case: "gdal {subcommand} arguments"
      96             :     // where subcommand is a known subcommand
      97          80 :     else if (args.size() >= 1)
      98             :     {
      99          79 :         const auto nCounter = CPLGetErrorCounter();
     100          79 :         if (InstantiateSubAlgorithm(args[0]))
     101          76 :             return GDALAlgorithm::ParseCommandLineArguments(args);
     102           4 :         if (CPLGetErrorCounter() == nCounter + 1 &&
     103           1 :             strstr(CPLGetLastErrorMsg(), "Do you mean"))
     104             :         {
     105           1 :             return false;
     106             :         }
     107             :     }
     108             : 
     109             :     // Otherwise check if that is the shortest form of "gdal read mydataset"
     110             :     // where "read" is omitted: "gdal in.tif"
     111             :     {
     112             :         VSIStatBufL sStat;
     113           7 :         for (const auto &arg : args)
     114             :         {
     115           5 :             if (VSIStatL(arg.c_str(), &sStat) == 0)
     116             :             {
     117             :                 m_subAlg =
     118           2 :                     GDALGlobalAlgorithmRegistry::GetSingleton().Instantiate(
     119           1 :                         "info");
     120           1 :                 if (m_subAlg)
     121             :                 {
     122           1 :                     bool ret = m_subAlg->ParseCommandLineArguments(args);
     123           1 :                     if (ret)
     124             :                     {
     125           1 :                         m_selectedSubAlg = &(m_subAlg->GetActualAlgorithm());
     126           1 :                         std::vector<std::string> callPath(m_callPath);
     127           1 :                         callPath.push_back(m_selectedSubAlg->GetArg("layer")
     128             :                                                ? "vector"
     129             :                                                : "raster");
     130           1 :                         m_selectedSubAlg->SetCallPath(callPath);
     131           1 :                         return true;
     132             :                     }
     133           0 :                     else if (strstr(CPLGetLastErrorMsg(),
     134           0 :                                     "has both raster and vector content"))
     135             :                     {
     136           0 :                         m_showUsage = false;
     137           0 :                         return false;
     138             :                     }
     139             :                 }
     140             :             }
     141             :         }
     142             : 
     143           2 :         return GDALAlgorithm::ParseCommandLineArguments(args);
     144             :     }
     145             : }
     146             : 
     147             : /************************************************************************/
     148             : /*                   GDALMainAlgorithm::GetUsageForCLI()                */
     149             : /************************************************************************/
     150             : 
     151             : std::string
     152           6 : GDALMainAlgorithm::GetUsageForCLI(bool shortUsage,
     153             :                                   const UsageOptions &usageOptions) const
     154             : {
     155           6 :     if (m_selectedSubAlg)
     156           3 :         return m_selectedSubAlg->GetUsageForCLI(shortUsage, usageOptions);
     157           3 :     if (m_showUsage)
     158           3 :         return GDALAlgorithm::GetUsageForCLI(shortUsage, usageOptions);
     159           0 :     return std::string();
     160             : }
     161             : 
     162             : /************************************************************************/
     163             : /*                    GDALMainAlgorithm::RunImpl()                      */
     164             : /************************************************************************/
     165             : 
     166           1 : bool GDALMainAlgorithm::RunImpl(GDALProgressFunc, void *)
     167             : {
     168           1 :     if (m_drivers)
     169             :     {
     170           1 :         m_output = GDALPrintDriverList(GDAL_OF_KIND_MASK, true);
     171             :     }
     172           1 :     return true;
     173             : }
     174             : 
     175             : //! @endcond

Generated by: LCOV version 1.14