<commit_before>//----------------------------------------------------------------------------
/// \file   error.hpp
/// \author <NAME>
//----------------------------------------------------------------------------
/// \brief Definition of exception classes.
//----------------------------------------------------------------------------
// Copyright (c) 2010 <NAME> <<EMAIL>>
// Created: 2010-09-30
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2010 <NAME> <<EMAIL>>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/
#ifndef _IO_UTXX_ERROR_HPP_
#define _IO_UTXX_ERROR_HPP_

#include <exception>
#include <sstream>
#include <stdio.h>
#include <errno.h>
#include <execinfo.h>
#include <signal.h>
#include <assert.h>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/current_function.hpp>
#include <sys/socket.h>
#include <string.h>
#include <utxx/compiler_hints.hpp>
#include <utxx/typeinfo.hpp>

#define UTXX_THROW(Exception, ...) \
    throw Exception \
        (src_info(UTXX_FILE_SRC_LOCATION, BOOST_CURRENT_FUNCTION), ##__VA_ARGS__)

namespace utxx {

/// Thread-safe function returning error string.
static inline std::string errno_string(int a_errno) {
    return strerror(a_errno);
}

class not_implemented : public std::exception {
public:
    not_implemented() {}
    virtual ~not_implemented() {}

    virtual const char* what() const throw() { return "Not implemented!"; }
};

class traced_exception : public std::exception {
    static const size_t s_frames = 25;
    void*  m_backtrace[s_frames];
    size_t m_size;
    char** m_symbols;
public:
    virtual const char* what() const throw() { return ""; }

    size_t      backtrace_size() const { return m_size; }
    const char* backtrace_frame(size_t i) {
        assert(i < m_size);
        return m_symbols[i];
    }

    std::ostream& print_backtrace(const char* a_prefix = "") const {
        return print_backtrace(std::cerr, a_prefix);
    }

    std::ostream& print_backtrace(std::ostream& out, const char* a_prefix = "") const {
        for(size_t i = 0; i < m_size; i++)
            out << a_prefix << detail::demangle(m_symbols[i]) << std::endl;
        return out;
    }

    traced_exception() : m_symbols(NULL) {
        m_size    = backtrace(m_backtrace, s_frames);
        m_symbols = backtrace_symbols(m_backtrace, m_size);
    }

    virtual ~traced_exception() throw() {
        if (m_symbols) free(m_symbols);
    }
};

/// Structure encapsulating source file:line information and source function.
///
/// It can be used for logging and throwing exceptions
class src_info {
    const char* m_srcloc;
    const char* m_fun;
    int         m_srcloc_len;
    int         m_fun_len;
public:
    template <int N, int M>
    constexpr src_info(const char (&a_srcloc)[N], const char (&a_fun)[M]) noexcept
        : m_srcloc(a_srcloc), m_fun(a_fun)
        , m_srcloc_len(N-1),  m_fun_len(M-1)
    {
        static_assert(N >= 1, "Invalid string literal! Length is zero!");
        static_assert(M >= 1, "Invalid string literal! Length is zero!");
    }

    src_info(const char* a_srcloc, size_t N, const char* a_fun, size_t M)
        : m_srcloc(a_srcloc), m_fun(a_fun)
        , m_srcloc_len(N),    m_fun_len(M)
    {
        assert(N >  0);
        assert(M >= 0);
    }

    src_info(const src_info& a)             = default;
    src_info& operator=(src_info&& a)       = default;
    src_info(src_info&& a)                  = default;
    src_info& operator=(const src_info& a)  = default;

    const char* srcloc()     const { return m_srcloc;     }
    const char* fun()        const { return m_fun;        }

    int         srcloc_len() const { return m_srcloc_len; }
    int         fun_len()    const { return m_fun_len;    }

    operator std::string() { return to_string(); }

    std::string to_string(const char* a_pfx = "", const char* a_sfx = "") const {
        char buf[256];
        const char* end = buf + sizeof(buf)-1;
        char* p = stpncpy(buf, a_pfx, end - buf);
        p = to_string(p, end - p, m_srcloc, m_srcloc_len, m_fun, m_fun_len);
        p = stpncpy(p, a_sfx, end - p);
        return std::string(buf, p - buf);
    }

    /// Format and write "file:line function" information to \a a_buf
    static char* to_string(char* a_buf, size_t a_sz,
        const char* a_srcloc, size_t a_sl_len,
        const char* a_srcfun, size_t a_sf_len,
        bool a_write_srcfun = true)
    {
        static const char s_sep =
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN64__) || defined(__CYGWIN__)
            '\\';
#elif defined(__linux__) || defined(__MACH__) || defined(__APPLE__) || defined(__unix__)
            '/';
#else
            '/';
#           error Unknown platform!
#endif

        auto q = strrchr(a_srcloc, s_sep);
        q = q ? q+1 : a_srcloc;
        auto e   = a_srcloc + a_sl_len;
        // extra byte for possible '\n'
        auto p   = a_buf;
        auto end = a_buf + a_sz;<commit_msg>Add src_info::to_string<commit_after>//----------------------------------------------------------------------------
/// \file   error.hpp
/// \author <NAME>
//----------------------------------------------------------------------------
/// \brief Definition of exception classes.
//----------------------------------------------------------------------------
// Copyright (c) 2010 <NAME> <<EMAIL>>
// Created: 2010-09-30
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is part of the utxx open-source project.

Copyright (C) 2010 <NAME> <<EMAIL>>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

***** END LICENSE BLOCK *****
*/
#ifndef _IO_UTXX_ERROR_HPP_
#define _IO_UTXX_ERROR_HPP_

#include <exception>
#include <sstream>
#include <stdio.h>
#include <errno.h>
#include <execinfo.h>
#include <signal.h>
#include <assert.h>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/current_function.hpp>
#include <sys/socket.h>
#include <string.h>
#include <utxx/compiler_hints.hpp>
#include <utxx/typeinfo.hpp>

// Alias for source location information
#define UTXX_SRC utxx::src_info(UTXX_FILE_SRC_LOCATION, BOOST_CURRENT_FUNCTION)

// Throw given exception with provided source location information
#define UTXX_SRC_THROW(Exception, SrcInfo, ...) throw Exception(SrcInfo, ##__VA_ARGS__)

// Throw given exception with current source location information
#define UTXX_THROW(Exception, ...) UTXX_SRC_THROW(Exception, UTXX_SRC, ##__VA_ARGS__)

namespace utxx {

/// Thread-safe function returning error string.
static inline std::string errno_string(int a_errno) {
    return strerror(a_errno);
}

class not_implemented : public std::exception {
public:
    not_implemented() {}
    virtual ~not_implemented() {}

    virtual const char* what() const throw() { return "Not implemented!"; }
};

class traced_exception : public std::exception {
    static const size_t s_frames = 25;
    void*  m_backtrace[s_frames];
    size_t m_size;
    char** m_symbols;
public:
    virtual const char* what() const throw() { return ""; }

    size_t      backtrace_size() const { return m_size; }
    const char* backtrace_frame(size_t i) {
        assert(i < m_size);
        return m_symbols[i];
    }

    std::ostream& print_backtrace(const char* a_prefix = "") const {
        return print_backtrace(std::cerr, a_prefix);
    }

    std::ostream& print_backtrace(std::ostream& out, const char* a_prefix = "") const {
        for(size_t i = 0; i < m_size; i++)
            out << a_prefix << detail::demangle(m_symbols[i]) << std::endl;
        return out;
    }

    traced_exception() : m_symbols(NULL) {
        m_size    = backtrace(m_backtrace, s_frames);
        m_symbols = backtrace_symbols(m_backtrace, m_size);
    }

    virtual ~traced_exception() throw() {
        if (m_symbols) free(m_symbols);
    }
};

/// Structure encapsulating source file:line information and source function.
///
/// It can be used for logging and throwing exceptions
class src_info {
    const char* m_srcloc;
    const char* m_fun;
    int         m_srcloc_len;
    int         m_fun_len;
public:
    template <int N, int M>
    constexpr src_info(const char (&a_srcloc)[N], const char (&a_fun)[M]) noexcept
        : m_srcloc(a_srcloc), m_fun(a_fun)
        , m_srcloc_len(N-1),  m_fun_len(M-1)
    {
        static_assert(N >= 1, "Invalid string literal! Length is zero!");
        static_assert(M >= 1, "Invalid string literal! Length is zero!");
    }

    src_info(const char* a_srcloc, size_t N, const char* a_fun, size_t M)
        : m_srcloc(a_srcloc), m_fun(a_fun)
        , m_srcloc_len(N),    m_fun_len(M)
    {
        assert(N >  0);
        assert(M >= 0);
    }

    src_info(const src_info& a)             = default;
    src_info& operator=(src_info&& a)       = default;
    src_info(src_info&& a)                  = default;
    src_info& operator=(const src_info& a)  = default;

    const char* srcloc()     const { return m_srcloc;     }
    const char* fun()        const { return m_fun;        }

    int         srcloc_len() const { return m_srcloc_len; }
    int         fun_len()    const { return m_fun_len;    }

    operator std::string() { return to_string(); }

    std::string to_string(const char* a_pfx = "", const char* a_sfx = "") const {
        char buf[256];
        char* p = to_string(buf, sizeof(buf), a_pfx, a_sfx);
        return std::string(buf, p - buf);
    }

    char* to_string(char* a_buf, size_t a_sz,
                    const char* a_pfx = "", const char* a_sfx = "") const {
        const char* end = a_buf + a_sz-1;
        char* p = stpncpy(a_buf, a_pfx, end - a_buf);
        p = to_string(p, end - p, m_srcloc, m_srcloc_len, m_fun, m_fun_len);
        p = stpncpy(p, a_sfx, end - p);
        return p;
    }

    /// Format and write "file:line function" information to \a a_buf
    static char* to_string(char* a_buf, size_t a_sz,
        const char* a_srcloc, size_t a_sl_len,
        const char* a_srcfun, size_t a_sf_len,
        bool a_write_srcfun = true)
    {
        static const char s_sep =
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN64__) || defined(__CYGWIN__)
            '\\';
#elif defined(__linux__) || defined(__MACH__) || defined(__APPLE__) || defined(__unix__)
            '/';
#else
            '/';
#           error Unknown platform!
#endif

        auto q = strrchr(a_srcloc, s_sep);
        q = q ? q+1 : a_srcloc;
        auto e   = a_srcloc + a_sl_len;
        // extra byte for possible '\n'
        auto p   = a_buf;
        auto end = a_buf + a_sz;
{'fraction_non_alphanumeric': 0.16290081408871906, 'fraction_numerical': 0.008639308855291577, 'mean_word_length': 2.4201704545454548, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2812073', 'n_tokens_mistral': 3944, 'n_tokens_neox': 3799, 'n_words': 1113}