LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/options - options_handler.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 151 187 80.7 %
Date: 2026-05-01 10:46:14 Functions: 23 24 95.8 %
Branches: 55 88 62.5 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Interface for custom handlers and predicates options.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "options/options_handler.h"
      14                 :            : 
      15                 :            : #include <iostream>
      16                 :            : #include <ostream>
      17                 :            : #include <regex>
      18                 :            : #include <string>
      19                 :            : 
      20                 :            : #include "base/check.h"
      21                 :            : #include "base/configuration.h"
      22                 :            : #include "base/configuration_private.h"
      23                 :            : #include "base/cvc5config.h"
      24                 :            : #include "base/exception.h"
      25                 :            : #include "base/modal_exception.h"
      26                 :            : #include "base/output.h"
      27                 :            : #include "lib/strtok_r.h"
      28                 :            : #include "options/base_options.h"
      29                 :            : #include "options/bv_options.h"
      30                 :            : #include "options/decision_options.h"
      31                 :            : #include "options/io_utils.h"
      32                 :            : #include "options/language.h"
      33                 :            : #include "options/main_options.h"
      34                 :            : #include "options/option_exception.h"
      35                 :            : #include "options/parser_options.h"
      36                 :            : #include "options/smt_options.h"
      37                 :            : #include "options/theory_options.h"
      38                 :            : #include "util/didyoumean.h"
      39                 :            : 
      40                 :            : namespace cvc5::internal {
      41                 :            : namespace options {
      42                 :            : 
      43                 :            : // helper functions
      44                 :            : namespace {
      45                 :            : 
      46                 :         33 : void printTags(std::ostream& out, const std::vector<std::string>& tags)
      47                 :            : {
      48                 :         33 :   out << "available tags:" << std::endl;
      49         [ +  + ]:      49929 :   for (const auto& t : tags)
      50                 :            :   {
      51                 :      49896 :     out << "  " << t << std::endl;
      52                 :            :   }
      53                 :         33 :   out << std::endl;
      54                 :         33 : }
      55                 :            : 
      56                 :          8 : std::string suggestTags(const std::vector<std::string>& validTags,
      57                 :            :                         const std::string& inputTag,
      58                 :            :                         const std::vector<std::string>& additionalTags)
      59                 :            : {
      60                 :          8 :   DidYouMean didYouMean;
      61                 :          8 :   didYouMean.addWords(validTags);
      62                 :          8 :   didYouMean.addWords(additionalTags);
      63                 :         16 :   return didYouMean.getMatchAsString(inputTag);
      64                 :          8 : }
      65                 :            : 
      66                 :            : /**
      67                 :            :  * Select all tags from validTags that match the given (globbing) pattern.
      68                 :            :  * The pattern may contain `*` as wildcards. These are internally converted to
      69                 :            :  * `.*` and matched using std::regex. If no wildcards are present, regular
      70                 :            :  * string comparisons are used.
      71                 :            :  */
      72                 :         11 : std::vector<std::string> selectTags(const std::vector<std::string>& validTags,
      73                 :            :                                     std::string pattern)
      74                 :            : {
      75                 :         11 :   bool isRegex = false;
      76                 :         11 :   size_t pos = 0;
      77         [ -  + ]:         11 :   while ((pos = pattern.find('*', pos)) != std::string::npos)
      78                 :            :   {
      79                 :          0 :     pattern.replace(pos, 1, ".*");
      80                 :          0 :     pos += 2;
      81                 :          0 :     isRegex = true;
      82                 :            :   }
      83                 :         11 :   std::vector<std::string> results;
      84         [ -  + ]:         11 :   if (isRegex)
      85                 :            :   {
      86                 :          0 :     std::regex re(pattern);
      87                 :          0 :     std::copy_if(validTags.begin(),
      88                 :            :                  validTags.end(),
      89                 :            :                  std::back_inserter(results),
      90                 :          0 :                  [&re](const auto& tag) { return std::regex_match(tag, re); });
      91                 :          0 :   }
      92                 :            :   else
      93                 :            :   {
      94                 :         11 :     if (std::find(validTags.begin(), validTags.end(), pattern)
      95         [ +  + ]:         22 :         != validTags.end())
      96                 :            :     {
      97                 :          3 :       results.emplace_back(pattern);
      98                 :            :     }
      99                 :            :   }
     100                 :         11 :   return results;
     101                 :          0 : }
     102                 :            : 
     103                 :            : }  // namespace
     104                 :            : 
     105                 :     146334 : OptionsHandler::OptionsHandler(Options* options) : d_options(options) {}
     106                 :            : 
     107                 :          2 : void OptionsHandler::setErrStream(CVC5_UNUSED const std::string& flag,
     108                 :            :                                   const ManagedErr& me) const
     109                 :            : {
     110         [ -  + ]:          2 :   Warning.setStream(me);
     111                 :          2 :   TraceChannel.setStream(me);
     112                 :          2 : }
     113                 :            : 
     114                 :      31476 : Language OptionsHandler::stringToLanguage(const std::string& flag,
     115                 :            :                                           const std::string& optarg) const
     116                 :            : {
     117         [ -  + ]:      31476 :   if (optarg == "help")
     118                 :            :   {
     119                 :          0 :     *d_options->base.out << R"FOOBAR(
     120                 :            : Languages currently supported as arguments to the -L / --lang option:
     121                 :            :   auto                           attempt to automatically determine language
     122                 :            :   smt | smtlib | smt2 |
     123                 :            :   smt2.6 | smtlib2.6             SMT-LIB format 2.6 with support for the strings standard
     124                 :            :   sygus | sygus2                 SyGuS version 2.0
     125                 :            : 
     126                 :            : Languages currently supported as arguments to the --output-lang option:
     127                 :            :   auto                           match output language to input language
     128                 :            :   smt | smtlib | smt2 |
     129                 :            :   smt2.6 | smtlib2.6             SMT-LIB format 2.6 with support for the strings standard
     130                 :            :   ast                            internal format (simple syntax trees)
     131                 :          0 : )FOOBAR" << std::endl;
     132                 :          0 :     throw OptionException("help is not a valid language");
     133                 :            :   }
     134                 :            : 
     135                 :            :   try
     136                 :            :   {
     137                 :      31476 :     return language::toLanguage(optarg);
     138                 :            :   }
     139         [ -  + ]:        247 :   catch (OptionException& oe)
     140                 :            :   {
     141                 :        741 :     throw OptionException("Error in " + flag + ": " + oe.getMessage()
     142                 :        988 :                           + "\nTry --lang help");
     143                 :        247 :   }
     144                 :            : 
     145                 :            :   Unreachable();
     146                 :            : }
     147                 :            : 
     148                 :      24338 : void OptionsHandler::setInputLanguage(const std::string& flag,
     149                 :            :                                       const Language lang) const
     150                 :            : {
     151         [ -  + ]:      24338 :   if (lang == Language::LANG_AST)
     152                 :            :   {
     153                 :          0 :     throw OptionException("Language LANG_AST is not allowed for " + flag);
     154                 :            :   }
     155         [ +  + ]:      24338 :   if (!d_options->printer.outputLanguageWasSetByUser)
     156                 :            :   {
     157                 :      20288 :     d_options->write_printer().outputLanguage = lang;
     158                 :      20288 :     ioutils::setDefaultOutputLanguage(lang);
     159                 :            :   }
     160                 :      24338 : }
     161                 :            : 
     162                 :        869 : void OptionsHandler::setVerbosity(CVC5_UNUSED const std::string& flag,
     163                 :            :                                   const int value) const
     164                 :            : {
     165         [ -  + ]:        869 :   if (Configuration::isMuzzledBuild())
     166                 :            :   {
     167                 :          0 :     TraceChannel.setStream(&cvc5::internal::null_os);
     168                 :          0 :     WarningChannel.setStream(&cvc5::internal::null_os);
     169                 :            :   }
     170                 :            :   else
     171                 :            :   {
     172         [ +  + ]:        869 :     if (value < 0)
     173                 :            :     {
     174                 :        621 :       WarningChannel.setStream(&cvc5::internal::null_os);
     175                 :            :     }
     176                 :            :     else
     177                 :            :     {
     178                 :        248 :       WarningChannel.setStream(&std::cerr);
     179                 :            :     }
     180                 :            :   }
     181                 :        869 : }
     182                 :            : 
     183                 :        621 : void OptionsHandler::decreaseVerbosity(CVC5_UNUSED const std::string& flag,
     184                 :            :                                        CVC5_UNUSED bool value)
     185                 :            : {
     186                 :        621 :   d_options->write_base().verbosity -= 1;
     187                 :        621 :   setVerbosity(flag, d_options->base.verbosity);
     188                 :        621 : }
     189                 :            : 
     190                 :          3 : void OptionsHandler::increaseVerbosity(CVC5_UNUSED const std::string& flag,
     191                 :            :                                        CVC5_UNUSED bool value)
     192                 :            : {
     193                 :          3 :   d_options->write_base().verbosity += 1;
     194                 :          3 :   setVerbosity(flag, d_options->base.verbosity);
     195                 :          3 : }
     196                 :            : 
     197                 :         63 : void OptionsHandler::setStats(CVC5_UNUSED const std::string& flag,
     198                 :            :                               const bool value) const
     199                 :            : {
     200                 :            : #ifndef CVC5_STATISTICS_ON
     201                 :            :   if (value)
     202                 :            :   {
     203                 :            :     std::stringstream ss;
     204                 :            :     ss << "option `" << flag
     205                 :            :        << "' requires a statistics-enabled build of cvc5; this binary was not "
     206                 :            :           "built with statistics support";
     207                 :            :     throw OptionException(ss.str());
     208                 :            :   }
     209                 :            : #endif /* CVC5_STATISTICS_ON */
     210         [ +  + ]:         63 :   if (!value)
     211                 :            :   {
     212                 :         33 :     d_options->write_base().statisticsAll = false;
     213                 :         33 :     d_options->write_base().statisticsEveryQuery = false;
     214                 :         33 :     d_options->write_base().statisticsInternal = false;
     215                 :            :   }
     216                 :         63 : }
     217                 :            : 
     218                 :        184 : void OptionsHandler::setStatsDetail(CVC5_UNUSED const std::string& flag,
     219                 :            :                                     const bool value) const
     220                 :            : {
     221                 :            : #ifndef CVC5_STATISTICS_ON
     222                 :            :   if (value)
     223                 :            :   {
     224                 :            :     std::stringstream ss;
     225                 :            :     ss << "option `" << flag
     226                 :            :        << "' requires a statistics-enabled build of cvc5; this binary was not "
     227                 :            :           "built with statistics support";
     228                 :            :     throw OptionException(ss.str());
     229                 :            :   }
     230                 :            : #endif /* CVC5_STATISTICS_ON */
     231         [ +  + ]:        184 :   if (value)
     232                 :            :   {
     233                 :         92 :     d_options->write_base().statistics = true;
     234                 :            :   }
     235                 :        184 : }
     236                 :            : 
     237                 :         11 : void OptionsHandler::enableTraceTag(CVC5_UNUSED const std::string& flag,
     238                 :            :                                     const std::string& optarg) const
     239                 :            : {
     240         [ -  + ]:         11 :   if (!Configuration::isTracingBuild())
     241                 :            :   {
     242                 :          0 :     throw OptionException("trace tags not available in non-tracing builds");
     243                 :            :   }
     244                 :         11 :   const auto tags = selectTags(Configuration::getTraceTags(), optarg);
     245         [ +  + ]:         11 :   if (tags.empty())
     246                 :            :   {
     247         [ -  + ]:          8 :     if (optarg == "help")
     248                 :            :     {
     249                 :          0 :       d_options->write_driver().showTraceTags = true;
     250                 :          0 :       showTraceTags("", true);
     251                 :          0 :       return;
     252                 :            :     }
     253                 :            : 
     254                 :          8 :     throw OptionException(
     255                 :         16 :         std::string("no trace tag matching ") + optarg
     256                 :         32 :         + std::string(" was found.")
     257                 :         32 :         + suggestTags(Configuration::getTraceTags(), optarg, {}));
     258                 :            :   }
     259         [ +  + ]:          6 :   for (const auto& tag : tags)
     260                 :            :   {
     261                 :          3 :     TraceChannel.on(tag);
     262                 :            :   }
     263         [ +  - ]:         11 : }
     264                 :            : 
     265                 :       4339 : void OptionsHandler::enableOutputTag(CVC5_UNUSED const std::string& flag,
     266                 :            :                                      const OutputTag optarg) const
     267                 :            : {
     268                 :       4339 :   const size_t tagid = static_cast<size_t>(optarg);
     269 [ -  + ][ -  + ]:       4339 :   Assert(d_options->base.outputTagHolder.size() > tagid)
                 [ -  - ]
     270                 :          0 :       << "Output tag is larger than the bitset that holds it.";
     271                 :       4339 :   d_options->write_base().outputTagHolder.set(tagid);
     272                 :       4339 : }
     273                 :            : 
     274                 :         35 : void OptionsHandler::setResourceWeight(CVC5_UNUSED const std::string& flag,
     275                 :            :                                        const std::string& optarg) const
     276                 :            : {
     277                 :         35 :   d_options->write_base().resourceWeightHolder.emplace_back(optarg);
     278                 :         35 : }
     279                 :            : 
     280                 :        441 : void OptionsHandler::checkBvSatSolver(const std::string& flag,
     281                 :            :                                       const BvSatSolverMode m) const
     282                 :            : {
     283                 :        441 :   if (m == BvSatSolverMode::CRYPTOMINISAT
     284 [ +  + ][ -  + ]:        441 :       && !Configuration::isBuiltWithCryptominisat())
                 [ -  + ]
     285                 :            :   {
     286                 :          0 :     std::stringstream ss;
     287                 :            :     ss << "option `" << flag
     288                 :            :        << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
     289                 :          0 :           "with CryptoMiniSat support";
     290                 :          0 :     throw OptionException(ss.str());
     291                 :          0 :   }
     292                 :            : 
     293 [ +  + ][ +  - ]:        441 :   if (m == BvSatSolverMode::KISSAT && !Configuration::isBuiltWithKissat())
                 [ +  + ]
     294                 :            :   {
     295                 :         90 :     std::stringstream ss;
     296                 :            :     ss << "option `" << flag
     297                 :            :        << "' requires a Kissat build of cvc5; this binary was not built with "
     298                 :         90 :           "Kissat support";
     299                 :         90 :     throw OptionException(ss.str());
     300                 :         90 :   }
     301                 :            : 
     302         [ -  + ]:        351 :   if (d_options->bv.bvSolver != options::BVSolver::BITBLAST
     303 [ -  - ][ -  - ]:          0 :       && (m == BvSatSolverMode::CRYPTOMINISAT || m == BvSatSolverMode::CADICAL
     304         [ -  - ]:          0 :           || m == BvSatSolverMode::KISSAT))
     305                 :            :   {
     306         [ -  - ]:          0 :     if (d_options->bv.bitblastMode == options::BitblastMode::LAZY
     307         [ -  - ]:          0 :         && d_options->bv.bitblastModeWasSetByUser)
     308                 :            :     {
     309                 :          0 :       std::stringstream ss;
     310                 :          0 :       ss << m << " does not support lazy bit-blasting." << std::endl
     311                 :          0 :          << "Try --bv-sat-solver=minisat";
     312                 :          0 :       throw OptionException(ss.str());
     313                 :          0 :     }
     314         [ -  - ]:          0 :     if (!d_options->bv.bitvectorToBoolWasSetByUser)
     315                 :            :     {
     316                 :          0 :       d_options->write_bv().bitvectorToBool = true;
     317                 :            :     }
     318                 :            :   }
     319                 :        351 : }
     320                 :            : 
     321                 :            : namespace {
     322                 :     106125 : void print_config(std::ostream& out, const char* str, const std::string& config)
     323                 :            : {
     324                 :     106125 :   std::string s(str);
     325                 :     106125 :   constexpr unsigned sz = 14;
     326         [ +  - ]:     106125 :   if (s.size() < sz) s.resize(sz, ' ');
     327                 :     106125 :   out << s << ": " << config << std::endl;
     328                 :     106125 : }
     329                 :            : 
     330                 :      93390 : void print_config_cond(std::ostream& out, const char* str, bool cond = false)
     331                 :            : {
     332         [ +  + ]:      93390 :   print_config(out, str, cond ? "yes" : "no");
     333                 :      93390 : }
     334                 :            : }  // namespace
     335                 :            : 
     336                 :       4279 : void OptionsHandler::showConfiguration(CVC5_UNUSED const std::string& flag,
     337                 :            :                                        const bool value) const
     338                 :            : {
     339         [ +  + ]:       4279 :   if (!value) return;
     340                 :       4245 :   std::ostream& o = d_options->base.out;
     341                 :       4245 :   print_config(o, "package", Configuration::getPackageName());
     342                 :       4245 :   print_config(o, "version", Configuration::getVersionString());
     343         [ +  - ]:       4245 :   if (Configuration::isGitBuild())
     344                 :            :   {
     345                 :       4245 :     print_config(o, "scm", Configuration::getGitInfo());
     346                 :            :   }
     347                 :            :   else
     348                 :            :   {
     349                 :          0 :     print_config_cond(o, "scm", false);
     350                 :            :   }
     351                 :            : 
     352                 :       4245 :   o << std::endl;
     353                 :            : 
     354                 :       4245 :   print_config_cond(o, "safe-mode", Configuration::isSafeBuild());
     355                 :       4245 :   print_config_cond(o, "stable-mode", Configuration::isStableBuild());
     356                 :       4245 :   print_config_cond(o, "debug code", Configuration::isDebugBuild());
     357                 :       4245 :   print_config_cond(o, "statistics", configuration::isStatisticsBuild());
     358                 :       4245 :   print_config_cond(o, "tracing", Configuration::isTracingBuild());
     359                 :       4245 :   print_config_cond(o, "muzzled", Configuration::isMuzzledBuild());
     360                 :       4245 :   print_config_cond(o, "assertions", Configuration::isAssertionBuild());
     361                 :       4245 :   print_config_cond(o, "coverage", Configuration::isCoverageBuild());
     362                 :       4245 :   print_config_cond(o, "profiling", Configuration::isProfilingBuild());
     363                 :       4245 :   print_config_cond(o, "asan", Configuration::isAsanBuild());
     364                 :       4245 :   print_config_cond(o, "ubsan", Configuration::isUbsanBuild());
     365                 :       4245 :   print_config_cond(o, "tsan", Configuration::isTsanBuild());
     366                 :       4245 :   print_config_cond(o, "competition", Configuration::isCompetitionBuild());
     367                 :       4245 :   print_config_cond(o, "portfolio", Configuration::isBuiltWithPortfolio());
     368                 :            : 
     369                 :       4245 :   o << std::endl;
     370                 :            : 
     371                 :       4245 :   print_config_cond(o, "cln", Configuration::isBuiltWithCln());
     372                 :       4245 :   print_config_cond(o, "glpk", Configuration::isBuiltWithGlpk());
     373                 :       4245 :   print_config_cond(
     374                 :       4245 :       o, "cryptominisat", Configuration::isBuiltWithCryptominisat());
     375                 :       4245 :   print_config_cond(o, "gmp", Configuration::isBuiltWithGmp());
     376                 :       4245 :   print_config_cond(o, "kissat", Configuration::isBuiltWithKissat());
     377                 :       4245 :   print_config_cond(o, "poly", Configuration::isBuiltWithPoly());
     378                 :       4245 :   print_config_cond(o, "cocoa", Configuration::isBuiltWithCoCoA());
     379                 :       4245 :   print_config_cond(o, "editline", Configuration::isBuiltWithEditline());
     380                 :            : }
     381                 :            : 
     382                 :        167 : void OptionsHandler::showCopyright(CVC5_UNUSED const std::string& flag,
     383                 :            :                                    const bool value) const
     384                 :            : {
     385         [ +  + ]:        167 :   if (!value) return;
     386                 :         83 :   d_options->base.out << Configuration::copyright() << std::endl;
     387                 :            : }
     388                 :            : 
     389                 :          6 : void OptionsHandler::showVersion(CVC5_UNUSED const std::string& flag,
     390                 :            :                                  const bool value) const
     391                 :            : {
     392         [ +  + ]:          6 :   if (!value) return;
     393                 :          4 :   d_options->base.out << Configuration::aboutAndCopyright() << std::endl;
     394                 :            : }
     395                 :            : 
     396                 :         66 : void OptionsHandler::showTraceTags(CVC5_UNUSED const std::string& flag,
     397                 :            :                                    const bool value) const
     398                 :            : {
     399         [ +  + ]:         66 :   if (!value) return;
     400         [ -  + ]:         33 :   if (!Configuration::isTracingBuild())
     401                 :            :   {
     402                 :          0 :     throw OptionException("trace tags not available in non-tracing build");
     403                 :            :   }
     404                 :         33 :   printTags(d_options->base.out, Configuration::getTraceTags());
     405                 :            : }
     406                 :            : 
     407                 :        124 : void OptionsHandler::strictParsing(CVC5_UNUSED const std::string& flag,
     408                 :            :                                    const bool value) const
     409                 :            : {
     410         [ +  + ]:        124 :   if (value)
     411                 :            :   {
     412                 :         66 :     d_options->write_parser().parsingMode = options::ParsingMode::STRICT;
     413                 :            :   }
     414         [ +  + ]:         58 :   else if (d_options->parser.parsingMode == options::ParsingMode::STRICT)
     415                 :            :   {
     416                 :         30 :     d_options->write_parser().parsingMode = options::ParsingMode::DEFAULT;
     417                 :            :   }
     418                 :        124 : }
     419                 :            : 
     420                 :            : }  // namespace options
     421                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14