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: 152 188 80.9 %
Date: 2026-08-19 10:34:29 Functions: 23 24 95.8 %
Branches: 56 90 62.2 %

           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         [ +  + ]:      50028 :   for (const auto& t : tags)
      50                 :            :   {
      51                 :      49995 :     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                 :      78094 : 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                 :      31260 : Language OptionsHandler::stringToLanguage(const std::string& flag,
     115                 :            :                                           const std::string& optarg) const
     116                 :            : {
     117         [ -  + ]:      31260 :   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                 :            :   smt2-tptp                      custom SMT-LIB v2.6-derived output format for tptpmodels
     131                 :            :   ast                            internal format (simple syntax trees)
     132                 :          0 : )FOOBAR" << std::endl;
     133                 :          0 :     throw OptionException("help is not a valid language");
     134                 :            :   }
     135                 :            : 
     136                 :            :   try
     137                 :            :   {
     138                 :      31260 :     return language::toLanguage(optarg);
     139                 :            :   }
     140         [ -  + ]:        247 :   catch (OptionException& oe)
     141                 :            :   {
     142                 :        741 :     throw OptionException("Error in " + flag + ": " + oe.getMessage()
     143                 :        988 :                           + "\nTry --lang help");
     144                 :        247 :   }
     145                 :            : 
     146                 :            :   Unreachable();
     147                 :            : }
     148                 :            : 
     149                 :      24661 : void OptionsHandler::setInputLanguage(const std::string& flag,
     150                 :            :                                       const Language lang) const
     151                 :            : {
     152 [ +  - ][ -  + ]:      24661 :   if (lang == Language::LANG_AST || lang == Language::LANG_SMTLIB_V2_6_TPTP)
     153                 :            :   {
     154                 :          0 :     throw OptionException("This language is not allowed for " + flag);
     155                 :            :   }
     156         [ +  + ]:      24661 :   if (!d_options->printer.outputLanguageWasSetByUser)
     157                 :            :   {
     158                 :      20553 :     d_options->write_printer().outputLanguage = lang;
     159                 :      20553 :     ioutils::setDefaultOutputLanguage(lang);
     160                 :            :   }
     161                 :      24661 : }
     162                 :            : 
     163                 :        646 : void OptionsHandler::setVerbosity(CVC5_UNUSED const std::string& flag,
     164                 :            :                                   const int value) const
     165                 :            : {
     166         [ -  + ]:        646 :   if (Configuration::isMuzzledBuild())
     167                 :            :   {
     168                 :          0 :     TraceChannel.setStream(&cvc5::internal::null_os);
     169                 :          0 :     WarningChannel.setStream(&cvc5::internal::null_os);
     170                 :            :   }
     171                 :            :   else
     172                 :            :   {
     173         [ +  + ]:        646 :     if (value < 0)
     174                 :            :     {
     175                 :        634 :       WarningChannel.setStream(&cvc5::internal::null_os);
     176                 :            :     }
     177                 :            :     else
     178                 :            :     {
     179                 :         12 :       WarningChannel.setStream(&std::cerr);
     180                 :            :     }
     181                 :            :   }
     182                 :        646 : }
     183                 :            : 
     184                 :        633 : void OptionsHandler::decreaseVerbosity(CVC5_UNUSED const std::string& flag,
     185                 :            :                                        CVC5_UNUSED bool value)
     186                 :            : {
     187                 :        633 :   d_options->write_base().verbosity -= 1;
     188                 :        633 :   setVerbosity(flag, d_options->base.verbosity);
     189                 :        633 : }
     190                 :            : 
     191                 :          3 : void OptionsHandler::increaseVerbosity(CVC5_UNUSED const std::string& flag,
     192                 :            :                                        CVC5_UNUSED bool value)
     193                 :            : {
     194                 :          3 :   d_options->write_base().verbosity += 1;
     195                 :          3 :   setVerbosity(flag, d_options->base.verbosity);
     196                 :          3 : }
     197                 :            : 
     198                 :         63 : void OptionsHandler::setStats(CVC5_UNUSED const std::string& flag,
     199                 :            :                               const bool value) const
     200                 :            : {
     201                 :            : #ifndef CVC5_STATISTICS_ON
     202                 :            :   if (value)
     203                 :            :   {
     204                 :            :     std::stringstream ss;
     205                 :            :     ss << "option `" << flag
     206                 :            :        << "' requires a statistics-enabled build of cvc5; this binary was not "
     207                 :            :           "built with statistics support";
     208                 :            :     throw OptionException(ss.str());
     209                 :            :   }
     210                 :            : #endif /* CVC5_STATISTICS_ON */
     211         [ +  + ]:         63 :   if (!value)
     212                 :            :   {
     213                 :         33 :     d_options->write_base().statisticsAll = false;
     214                 :         33 :     d_options->write_base().statisticsEveryQuery = false;
     215                 :         33 :     d_options->write_base().statisticsInternal = false;
     216                 :            :   }
     217                 :         63 : }
     218                 :            : 
     219                 :        184 : void OptionsHandler::setStatsDetail(CVC5_UNUSED const std::string& flag,
     220                 :            :                                     const bool value) const
     221                 :            : {
     222                 :            : #ifndef CVC5_STATISTICS_ON
     223                 :            :   if (value)
     224                 :            :   {
     225                 :            :     std::stringstream ss;
     226                 :            :     ss << "option `" << flag
     227                 :            :        << "' requires a statistics-enabled build of cvc5; this binary was not "
     228                 :            :           "built with statistics support";
     229                 :            :     throw OptionException(ss.str());
     230                 :            :   }
     231                 :            : #endif /* CVC5_STATISTICS_ON */
     232         [ +  + ]:        184 :   if (value)
     233                 :            :   {
     234                 :         92 :     d_options->write_base().statistics = true;
     235                 :            :   }
     236                 :        184 : }
     237                 :            : 
     238                 :         11 : void OptionsHandler::enableTraceTag(CVC5_UNUSED const std::string& flag,
     239                 :            :                                     const std::string& optarg) const
     240                 :            : {
     241         [ -  + ]:         11 :   if (!Configuration::isTracingBuild())
     242                 :            :   {
     243                 :          0 :     throw OptionException("trace tags not available in non-tracing builds");
     244                 :            :   }
     245                 :         11 :   const auto tags = selectTags(Configuration::getTraceTags(), optarg);
     246         [ +  + ]:         11 :   if (tags.empty())
     247                 :            :   {
     248         [ -  + ]:          8 :     if (optarg == "help")
     249                 :            :     {
     250                 :          0 :       d_options->write_driver().showTraceTags = true;
     251                 :          0 :       showTraceTags("", true);
     252                 :          0 :       return;
     253                 :            :     }
     254                 :            : 
     255                 :          8 :     throw OptionException(
     256                 :         16 :         std::string("no trace tag matching ") + optarg
     257                 :         32 :         + std::string(" was found.")
     258                 :         32 :         + suggestTags(Configuration::getTraceTags(), optarg, {}));
     259                 :            :   }
     260         [ +  + ]:          6 :   for (const auto& tag : tags)
     261                 :            :   {
     262                 :          3 :     TraceChannel.on(tag);
     263                 :            :   }
     264         [ +  - ]:         11 : }
     265                 :            : 
     266                 :       4418 : void OptionsHandler::enableOutputTag(CVC5_UNUSED const std::string& flag,
     267                 :            :                                      const OutputTag optarg) const
     268                 :            : {
     269                 :       4418 :   const size_t tagid = static_cast<size_t>(optarg);
     270 [ -  + ][ -  + ]:       4418 :   Assert(d_options->base.outputTagHolder.size() > tagid)
                 [ -  - ]
     271                 :          0 :       << "Output tag is larger than the bitset that holds it.";
     272                 :       4418 :   d_options->write_base().outputTagHolder.set(tagid);
     273                 :       4418 : }
     274                 :            : 
     275                 :         35 : void OptionsHandler::setResourceWeight(CVC5_UNUSED const std::string& flag,
     276                 :            :                                        const std::string& optarg) const
     277                 :            : {
     278                 :         35 :   d_options->write_base().resourceWeightHolder.emplace_back(optarg);
     279                 :         35 : }
     280                 :            : 
     281                 :        300 : void OptionsHandler::checkBvSatSolver(const std::string& flag,
     282                 :            :                                       const BvSatSolverMode m) const
     283                 :            : {
     284                 :        300 :   if (m == BvSatSolverMode::CRYPTOMINISAT
     285 [ +  + ][ -  + ]:        300 :       && !Configuration::isBuiltWithCryptominisat())
                 [ -  + ]
     286                 :            :   {
     287                 :          0 :     std::stringstream ss;
     288                 :            :     ss << "option `" << flag
     289                 :            :        << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
     290                 :          0 :           "with CryptoMiniSat support";
     291                 :          0 :     throw OptionException(ss.str());
     292                 :          0 :   }
     293                 :            : 
     294 [ +  + ][ +  - ]:        300 :   if (m == BvSatSolverMode::KISSAT && !Configuration::isBuiltWithKissat())
                 [ +  + ]
     295                 :            :   {
     296                 :         90 :     std::stringstream ss;
     297                 :            :     ss << "option `" << flag
     298                 :            :        << "' requires a Kissat build of cvc5; this binary was not built with "
     299                 :         90 :           "Kissat support";
     300                 :         90 :     throw OptionException(ss.str());
     301                 :         90 :   }
     302                 :            : 
     303         [ -  + ]:        210 :   if (d_options->bv.bvSolver != options::BVSolver::BITBLAST
     304 [ -  - ][ -  - ]:          0 :       && (m == BvSatSolverMode::CRYPTOMINISAT || m == BvSatSolverMode::CADICAL
     305         [ -  - ]:          0 :           || m == BvSatSolverMode::KISSAT))
     306                 :            :   {
     307         [ -  - ]:          0 :     if (d_options->bv.bitblastMode == options::BitblastMode::LAZY
     308         [ -  - ]:          0 :         && d_options->bv.bitblastModeWasSetByUser)
     309                 :            :     {
     310                 :          0 :       std::stringstream ss;
     311                 :          0 :       ss << m << " does not support lazy bit-blasting." << std::endl
     312                 :          0 :          << "Try --bv-sat-solver=minisat";
     313                 :          0 :       throw OptionException(ss.str());
     314                 :          0 :     }
     315         [ -  - ]:          0 :     if (!d_options->bv.bitvectorToBoolWasSetByUser)
     316                 :            :     {
     317                 :          0 :       d_options->write_bv().bitvectorToBool = true;
     318                 :            :     }
     319                 :            :   }
     320                 :        210 : }
     321                 :            : 
     322                 :            : namespace {
     323                 :     111826 : void print_config(std::ostream& out, const char* str, const std::string& config)
     324                 :            : {
     325                 :     111826 :   std::string s(str);
     326                 :     111826 :   constexpr unsigned sz = 14;
     327         [ +  - ]:     111826 :   if (s.size() < sz) s.resize(sz, ' ');
     328                 :     111826 :   out << s << ": " << config << std::endl;
     329                 :     111826 : }
     330                 :            : 
     331                 :      98923 : void print_config_cond(std::ostream& out, const char* str, bool cond = false)
     332                 :            : {
     333         [ +  + ]:      98923 :   print_config(out, str, cond ? "yes" : "no");
     334                 :      98923 : }
     335                 :            : }  // namespace
     336                 :            : 
     337                 :       4335 : void OptionsHandler::showConfiguration(CVC5_UNUSED const std::string& flag,
     338                 :            :                                        const bool value) const
     339                 :            : {
     340         [ +  + ]:       4335 :   if (!value) return;
     341                 :       4301 :   std::ostream& o = d_options->base.out;
     342                 :       4301 :   print_config(o, "package", Configuration::getPackageName());
     343                 :       4301 :   print_config(o, "version", Configuration::getVersionString());
     344         [ +  - ]:       4301 :   if (Configuration::isGitBuild())
     345                 :            :   {
     346                 :       4301 :     print_config(o, "scm", Configuration::getGitInfo());
     347                 :            :   }
     348                 :            :   else
     349                 :            :   {
     350                 :          0 :     print_config_cond(o, "scm", false);
     351                 :            :   }
     352                 :            : 
     353                 :       4301 :   o << std::endl;
     354                 :            : 
     355                 :       4301 :   print_config_cond(o, "safe-mode", Configuration::isSafeBuild());
     356                 :       4301 :   print_config_cond(o, "stable-mode", Configuration::isStableBuild());
     357                 :       4301 :   print_config_cond(o, "debug code", Configuration::isDebugBuild());
     358                 :       4301 :   print_config_cond(o, "statistics", configuration::isStatisticsBuild());
     359                 :       4301 :   print_config_cond(o, "tracing", Configuration::isTracingBuild());
     360                 :       4301 :   print_config_cond(o, "muzzled", Configuration::isMuzzledBuild());
     361                 :       4301 :   print_config_cond(o, "assertions", Configuration::isAssertionBuild());
     362                 :       4301 :   print_config_cond(o, "coverage", Configuration::isCoverageBuild());
     363                 :       4301 :   print_config_cond(o, "profiling", Configuration::isProfilingBuild());
     364                 :       4301 :   print_config_cond(o, "asan", Configuration::isAsanBuild());
     365                 :       4301 :   print_config_cond(o, "ubsan", Configuration::isUbsanBuild());
     366                 :       4301 :   print_config_cond(o, "tsan", Configuration::isTsanBuild());
     367                 :       4301 :   print_config_cond(o, "competition", Configuration::isCompetitionBuild());
     368                 :       4301 :   print_config_cond(o, "portfolio", Configuration::isBuiltWithPortfolio());
     369                 :            : 
     370                 :       4301 :   o << std::endl;
     371                 :            : 
     372                 :       4301 :   print_config_cond(o, "cln", Configuration::isBuiltWithCln());
     373                 :       4301 :   print_config_cond(o, "glpk", Configuration::isBuiltWithGlpk());
     374                 :       4301 :   print_config_cond(
     375                 :       4301 :       o, "cryptominisat", Configuration::isBuiltWithCryptominisat());
     376                 :       4301 :   print_config_cond(o, "gmp", Configuration::isBuiltWithGmp());
     377                 :       4301 :   print_config_cond(o, "kissat", Configuration::isBuiltWithKissat());
     378                 :       4301 :   print_config_cond(o, "poly", Configuration::isBuiltWithPoly());
     379                 :       4301 :   print_config_cond(o, "cocoa", Configuration::isBuiltWithCoCoA());
     380                 :       4301 :   print_config_cond(o, "normaliz", Configuration::isBuiltWithNormaliz());
     381                 :       4301 :   print_config_cond(o, "editline", Configuration::isBuiltWithEditline());
     382                 :            : }
     383                 :            : 
     384                 :        167 : void OptionsHandler::showCopyright(CVC5_UNUSED const std::string& flag,
     385                 :            :                                    const bool value) const
     386                 :            : {
     387         [ +  + ]:        167 :   if (!value) return;
     388                 :         83 :   d_options->base.out << Configuration::copyright() << std::endl;
     389                 :            : }
     390                 :            : 
     391                 :          6 : void OptionsHandler::showVersion(CVC5_UNUSED const std::string& flag,
     392                 :            :                                  const bool value) const
     393                 :            : {
     394         [ +  + ]:          6 :   if (!value) return;
     395                 :          4 :   d_options->base.out << Configuration::aboutAndCopyright() << std::endl;
     396                 :            : }
     397                 :            : 
     398                 :         66 : void OptionsHandler::showTraceTags(CVC5_UNUSED const std::string& flag,
     399                 :            :                                    const bool value) const
     400                 :            : {
     401         [ +  + ]:         66 :   if (!value) return;
     402         [ -  + ]:         33 :   if (!Configuration::isTracingBuild())
     403                 :            :   {
     404                 :          0 :     throw OptionException("trace tags not available in non-tracing build");
     405                 :            :   }
     406                 :         33 :   printTags(d_options->base.out, Configuration::getTraceTags());
     407                 :            : }
     408                 :            : 
     409                 :        124 : void OptionsHandler::strictParsing(CVC5_UNUSED const std::string& flag,
     410                 :            :                                    const bool value) const
     411                 :            : {
     412         [ +  + ]:        124 :   if (value)
     413                 :            :   {
     414                 :         66 :     d_options->write_parser().parsingMode = options::ParsingMode::STRICT;
     415                 :            :   }
     416         [ +  + ]:         58 :   else if (d_options->parser.parsingMode == options::ParsingMode::STRICT)
     417                 :            :   {
     418                 :         30 :     d_options->write_parser().parsingMode = options::ParsingMode::DEFAULT;
     419                 :            :   }
     420                 :        124 : }
     421                 :            : 
     422                 :            : }  // namespace options
     423                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14