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 194 78.4 %
Date: 2026-03-04 11:41:08 Functions: 23 24 95.8 %
Branches: 55 92 59.8 %

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

Generated by: LCOV version 1.14