OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogutil / opencog / util / exceptions.cc

303 lines · cc ref:
/*
 * opencog/util/exceptions.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by Thiago Maia <thiago@vettatech.com>
 *            Andre Senna <senna@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "exceptions.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <opencog/util/platform.h>
#include <opencog/util/Logger.h>

#define MAX_MSG_LENGTH 2048

using namespace opencog;

/*
 * ----------------------------------------------------------------------
 * StandardException class
 * ----------------------------------------------------------------------
 */
void StandardException::parse_error_message(const char* fmt, va_list ap, bool logError)
{
    char buf[MAX_MSG_LENGTH];

    vsnprintf(buf, sizeof(buf), fmt, ap);

    // If buf contains %s %x %d %u etc. because one of the ap's did,
    // then it becomes a horrid strange crash. So be careful, use %s.
    if (logError) opencog::logger().error("%s", buf);
    set_message(buf);
}

void StandardException::parse_error_message(const char *trace, const char * msg, va_list ap, bool logError)
{
    size_t tlen = 0;
    if (trace) tlen = strlen(trace);

    size_t mlen = strlen(msg);
    char * concatMsg = new char[tlen + mlen + 1];

    strcpy(concatMsg, msg);
    if (trace) {
        // If "trace" is a string that contains %d %s %x %u or any
        // format string, there will be confusing horrors!  Thus,
        // blank out any %'s in "trace".
        char * pcnt = concatMsg + mlen;
        strcpy(pcnt, trace);
        do {
            pcnt = strchr(pcnt, '%');
            if (pcnt) *pcnt = ' ';
        } while (pcnt);
    }

    parse_error_message(concatMsg, ap, logError);

    delete [] concatMsg;
}

StandardException::StandardException() :
    message(nullptr)
{}

// Exceptions must have a copy constructor, as otherwise the
// catcher will not be able to see the message! Ouch!
StandardException::StandardException(const StandardException& ex) :
    message(nullptr)
{
    if (ex.message)
    {
        set_message(ex.message);
    }
}

StandardException& StandardException::operator=(const StandardException& ex)
{
    if (ex.message)
    {
        set_message(ex.message);
    }
    return *this;
}

StandardException::~StandardException() _GLIBCXX_USE_NOEXCEPT
{
    // clear memory
    delete [] message;
}

const char * StandardException::get_message() const
{
    if (message == NULL) {
        return "";
    }
    return message;
}

void StandardException::set_message(const char * msg) const
{
    // clear msg
    delete [] message;

    message = new char[strlen(msg) + 1];
    strcpy(message, msg);
}

/*
 * ----------------------------------------------------------------------
 * RuntimeException class
 * ----------------------------------------------------------------------
 */
RuntimeException::RuntimeException(const char *trace, const char* fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap, false);
    va_end(ap);
}

RuntimeException::RuntimeException(const char *trace, const char* fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap, false);
}

RuntimeException::RuntimeException()
{
}

/*
 * ----------------------------------------------------------------------
 * SyntaxException class
 * ----------------------------------------------------------------------
 */
SyntaxException::SyntaxException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap, false);
    va_end(ap);
}

SyntaxException::SyntaxException(const char * trace, const char * fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap, false);
}

/*
 * ----------------------------------------------------------------------
 * IOException class
 * ----------------------------------------------------------------------
 */
IOException::IOException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap);
    va_end(ap);
}

IOException::IOException(const char * trace, const char * fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap);
}

/*
 * ----------------------------------------------------------------------
 * IndexErrorException class
 * ----------------------------------------------------------------------
 */
IndexErrorException::IndexErrorException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap);
    va_end(ap);
}

IndexErrorException::IndexErrorException(const char* trace, const char* fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap);
}

/*
 * ----------------------------------------------------------------------
 * InvalidException class
 * ----------------------------------------------------------------------
 */
InvalidParamException::InvalidParamException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap, false);
    va_end(ap);
}

InvalidParamException::InvalidParamException(const char* trace, const char* fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap, false);
}

/*
 * ----------------------------------------------------------------------
 * FatalErrorException class
 * ----------------------------------------------------------------------
 */
FatalErrorException::FatalErrorException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap, true);
    va_end(ap);
}

FatalErrorException::FatalErrorException(const char* trace, const char* fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap, true);
}

/*
 * ----------------------------------------------------------------------
 * PythonException class
 * ----------------------------------------------------------------------
 */
PythonException::PythonException(const std::string& pythonExcType,
                                 const char * trace,
                                 const char * fmt, ...)
    : _python_exception_type(pythonExcType)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap);
    va_end(ap);
}

PythonException::PythonException(const std::string& pythonExcType,
                                 const char* trace,
                                 const char* fmt,
                                 va_list ap)
    : _python_exception_type(pythonExcType)
{
    parse_error_message(trace, fmt, ap);
}

/*
 * ----------------------------------------------------------------------
 * NotFoundException class
 * ----------------------------------------------------------------------
 */
NotFoundException::NotFoundException(const char * trace, const char * fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(trace, fmt, ap, false);
    va_end(ap);
}

NotFoundException::NotFoundException(const char* trace, const char* fmt, va_list ap)
{
    parse_error_message(trace, fmt, ap, false);
}

/*
 * ----------------------------------------------------------------------
 * AssertionException class
 * ----------------------------------------------------------------------
 */
AssertionException::AssertionException(const char* fmt, ...)
{
    va_list  ap;
    va_start(ap, fmt);
    parse_error_message(nullptr, fmt, ap, true);
    va_end(ap);
}

AssertionException::AssertionException(const char* fmt, va_list ap)
{
    parse_error_message(nullptr, fmt, ap, true);
}