LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/base - exception.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 60 81 74.1 %
Date: 2026-05-13 10:48:54 Functions: 9 10 90.0 %
Branches: 20 52 38.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                 :            :  * cvc5's exception base class and some associated utilities.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "base/exception.h"
      14                 :            : 
      15                 :            : #include <cstdarg>
      16                 :            : #include <cstdio>
      17                 :            : #include <cstdlib>
      18                 :            : #include <cstring>
      19                 :            : #include <ostream>
      20                 :            : #include <sstream>
      21                 :            : #include <string>
      22                 :            : 
      23                 :            : #include "base/check.h"
      24                 :            : 
      25                 :            : using namespace std;
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : 
      29                 :          3 : std::string Exception::toString() const
      30                 :            : {
      31                 :          3 :   std::stringstream ss;
      32                 :          3 :   toStream(ss);
      33                 :          6 :   return ss.str();
      34                 :          3 : }
      35                 :            : 
      36                 :         93 : void Exception::toStream(std::ostream& os) const { os << d_msg; }
      37                 :            : 
      38                 :            : thread_local LastExceptionBuffer* LastExceptionBuffer::s_currentBuffer =
      39                 :            :     nullptr;
      40                 :            : 
      41                 :      28355 : LastExceptionBuffer::LastExceptionBuffer() : d_contents(nullptr) {}
      42                 :            : 
      43                 :          0 : LastExceptionBuffer::~LastExceptionBuffer()
      44                 :            : {
      45         [ -  - ]:          0 :   if (d_contents != nullptr)
      46                 :            :   {
      47                 :          0 :     free(d_contents);
      48                 :          0 :     d_contents = nullptr;
      49                 :            :   }
      50                 :          0 : }
      51                 :            : 
      52                 :         24 : void LastExceptionBuffer::setContents(const char* string)
      53                 :            : {
      54         [ -  + ]:         24 :   if (d_contents != nullptr)
      55                 :            :   {
      56                 :          0 :     free(d_contents);
      57                 :          0 :     d_contents = nullptr;
      58                 :            :   }
      59                 :            : 
      60         [ +  - ]:         24 :   if (string != nullptr)
      61                 :            :   {
      62                 :         24 :     d_contents = strdup(string);
      63                 :            :   }
      64                 :         24 : }
      65                 :            : 
      66                 :            : const char* IllegalArgumentException::s_header = "Illegal argument detected";
      67                 :            : 
      68                 :          1 : std::string IllegalArgumentException::formatVariadic() { return std::string(); }
      69                 :            : 
      70                 :         40 : std::string IllegalArgumentException::formatVariadic(const char* format, ...)
      71                 :            : {
      72                 :            :   va_list args;
      73                 :         40 :   va_start(args, format);
      74                 :            : 
      75                 :         40 :   int n = 512;
      76                 :         40 :   char* buf = nullptr;
      77                 :            : 
      78         [ +  - ]:         40 :   for (int i = 0; i < 2; ++i)
      79                 :            :   {
      80 [ -  + ][ -  + ]:         40 :     Assert(n > 0);
                 [ -  - ]
      81         [ -  + ]:         40 :     delete[] buf;
      82                 :         40 :     buf = new char[n];
      83                 :            : 
      84                 :            :     va_list args_copy;
      85                 :         40 :     va_copy(args_copy, args);
      86                 :         40 :     int size = vsnprintf(buf, n, format, args);
      87                 :         40 :     va_end(args_copy);
      88                 :            : 
      89         [ -  + ]:         40 :     if (size >= n)
      90                 :            :     {
      91                 :          0 :       buf[n - 1] = '\0';
      92                 :          0 :       n = size + 1;
      93                 :            :     }
      94                 :            :     else
      95                 :            :     {
      96                 :         40 :       break;
      97                 :            :     }
      98                 :            :   }
      99                 :            :   // buf is not nullptr is an invariant.
     100                 :            :   // buf is also 0 terminated.
     101 [ -  + ][ -  + ]:         40 :   Assert(buf != nullptr);
                 [ -  - ]
     102                 :         40 :   std::string result(buf);
     103         [ +  - ]:         40 :   delete[] buf;
     104                 :         40 :   va_end(args);
     105                 :         80 :   return result;
     106                 :            : }
     107                 :            : 
     108                 :         42 : std::string IllegalArgumentException::format_extra(const char* condStr,
     109                 :            :                                                    const char* argDesc)
     110                 :            : {
     111                 :         84 :   return (std::string("`") + argDesc + "' is a bad argument"
     112                 :         42 :           + (*condStr == '\0'
     113         [ +  + ]:        124 :                  ? std::string()
     114                 :        124 :                  : (std::string("; expected ") + condStr + " to hold")));
     115                 :            : }
     116                 :            : 
     117                 :         41 : void IllegalArgumentException::construct(const char* header,
     118                 :            :                                          const char* extra,
     119                 :            :                                          const char* function,
     120                 :            :                                          const char* tail)
     121                 :            : {
     122                 :            :   // try building the exception msg with a smallish buffer first,
     123                 :            :   // then with a larger one if sprintf tells us to.
     124                 :         41 :   int n = 512;
     125                 :            :   char* buf;
     126                 :            : 
     127                 :            :   for (;;)
     128                 :            :   {
     129                 :         41 :     buf = new char[n];
     130                 :            : 
     131                 :            :     int size;
     132         [ -  + ]:         41 :     if (extra == nullptr)
     133                 :            :     {
     134                 :          0 :       size = snprintf(buf, n, "%s\n%s\n%s", header, function, tail);
     135                 :            :     }
     136                 :            :     else
     137                 :            :     {
     138                 :            :       size =
     139                 :         41 :           snprintf(buf, n, "%s\n%s\n\n  %s\n%s", header, function, extra, tail);
     140                 :            :     }
     141                 :            : 
     142         [ +  - ]:         41 :     if (size < n)
     143                 :            :     {
     144                 :         41 :       break;
     145                 :            :     }
     146                 :            :     else
     147                 :            :     {
     148                 :            :       // size >= n
     149                 :            :       // try again with a buffer that's large enough
     150                 :          0 :       n = size + 1;
     151         [ -  - ]:          0 :       delete[] buf;
     152                 :            :     }
     153                 :          0 :   }
     154                 :            : 
     155                 :         41 :   setMessage(string(buf));
     156                 :            : 
     157                 :            : #ifdef CVC5_DEBUG
     158                 :         41 :   LastExceptionBuffer* buffer = LastExceptionBuffer::getCurrent();
     159         [ -  + ]:         41 :   if (buffer != nullptr)
     160                 :            :   {
     161         [ -  - ]:          0 :     if (buffer->getContents() == nullptr)
     162                 :            :     {
     163                 :          0 :       buffer->setContents(buf);
     164                 :            :     }
     165                 :            :   }
     166                 :            : #endif /* CVC5_DEBUG */
     167         [ +  - ]:         41 :   delete[] buf;
     168                 :         41 : }
     169                 :            : 
     170                 :          1 : void IllegalArgumentException::construct(const char* header,
     171                 :            :                                          const char* extra,
     172                 :            :                                          const char* function)
     173                 :            : {
     174                 :            :   // try building the exception msg with a smallish buffer first,
     175                 :            :   // then with a larger one if sprintf tells us to.
     176                 :          1 :   int n = 256;
     177                 :            :   char* buf;
     178                 :            : 
     179                 :            :   for (;;)
     180                 :            :   {
     181                 :          1 :     buf = new char[n];
     182                 :            : 
     183                 :            :     int size;
     184         [ -  + ]:          1 :     if (extra == nullptr)
     185                 :            :     {
     186                 :          0 :       size = snprintf(buf, n, "%s.\n%s\n", header, function);
     187                 :            :     }
     188                 :            :     else
     189                 :            :     {
     190                 :          1 :       size = snprintf(buf, n, "%s.\n%s\n\n  %s\n", header, function, extra);
     191                 :            :     }
     192                 :            : 
     193         [ +  - ]:          1 :     if (size < n)
     194                 :            :     {
     195                 :          1 :       break;
     196                 :            :     }
     197                 :            :     else
     198                 :            :     {
     199                 :            :       // try again with a buffer that's large enough
     200                 :          0 :       n = size + 1;
     201         [ -  - ]:          0 :       delete[] buf;
     202                 :            :     }
     203                 :          0 :   }
     204                 :            : 
     205                 :          1 :   setMessage(string(buf));
     206                 :            : 
     207                 :            : #ifdef CVC5_DEBUG
     208                 :          1 :   LastExceptionBuffer* buffer = LastExceptionBuffer::getCurrent();
     209         [ -  + ]:          1 :   if (buffer != nullptr)
     210                 :            :   {
     211         [ -  - ]:          0 :     if (buffer->getContents() == nullptr)
     212                 :            :     {
     213                 :          0 :       buffer->setContents(buf);
     214                 :            :     }
     215                 :            :   }
     216                 :            : #endif /* CVC5_DEBUG */
     217         [ +  - ]:          1 :   delete[] buf;
     218                 :          1 : }
     219                 :            : 
     220                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14