File indexing completed on 2024-04-28 05:42:10

0001 /*
0002  * Port for usage with qt-framework and development for kdesvn
0003  * Copyright (C) 2005-2009 by Rajko Albrecht (ral@alwins-world.de)
0004  * https://kde.org/applications/development/org.kde.kdesvn
0005  */
0006 /*
0007  * ====================================================================
0008  * Copyright (c) 2002-2005 The RapidSvn Group.  All rights reserved.
0009  * dev@rapidsvn.tigris.org
0010  *
0011  * This library is free software; you can redistribute it and/or
0012  * modify it under the terms of the GNU Lesser General Public
0013  * License as published by the Free Software Foundation; either
0014  * version 2.1 of the License, or (at your option) any later version.
0015  *
0016  * This library is distributed in the hope that it will be useful,
0017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0019  * Lesser General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU Lesser General Public
0022  * License along with this library (in the file LGPL.txt); if not,
0023  * write to the Free Software Foundation, Inc., 51 Franklin St,
0024  * Fifth Floor, Boston, MA  02110-1301  USA
0025  *
0026  * This software consists of voluntary contributions made by many
0027  * individuals.  For exact contribution history, see the revision
0028  * history and logs, available at http://rapidsvn.tigris.org/.
0029  * ====================================================================
0030  */
0031 
0032 // svncpp
0033 #include "exception.h"
0034 #include "svnqt_defines.h"
0035 
0036 #ifdef HAS_BACKTRACE_H
0037 #include <execinfo.h>
0038 #include <qstringlist.h>
0039 #define SVNQT_BACKTRACE_LENGTH 20
0040 #endif
0041 
0042 namespace svn
0043 {
0044 
0045 struct Exception::Data {
0046 public:
0047     QString message;
0048     apr_status_t apr_err;
0049 
0050     Data(const char *msg)
0051         : message(QString::fromUtf8(msg))
0052         , apr_err(0)
0053     {
0054     }
0055 
0056     Data(const QString &msg)
0057         : message(msg)
0058         , apr_err(0)
0059     {
0060     }
0061 };
0062 
0063 Exception::Exception(const char *message) throw()
0064 {
0065     m = new Data(message);
0066 }
0067 
0068 Exception::Exception(const QString &message) throw()
0069 {
0070     m = new Data(message);
0071 }
0072 
0073 Exception::Exception(const Exception &other) throw()
0074 {
0075     m = new Data(*other.m);
0076 }
0077 
0078 Exception::~Exception() throw()
0079 {
0080     delete m;
0081 }
0082 
0083 apr_status_t Exception::apr_err() const
0084 {
0085     return m->apr_err;
0086 }
0087 
0088 const QString &Exception::msg() const
0089 {
0090     return m->message;
0091 }
0092 
0093 void Exception::setMessage(const QString &aMsg)
0094 {
0095     m->message = aMsg;
0096 }
0097 
0098 QString Exception::error2msg(svn_error_t *error)
0099 {
0100     QString message;
0101     if (error == nullptr) {
0102         return message;
0103     }
0104     svn_error_t *next = error->child;
0105     if (error->message) {
0106         message = QString::fromUtf8(error->message);
0107     } else {
0108         message = QLatin1String("Unknown error!\n");
0109         if (error->file) {
0110             message += QLatin1String("In file ");
0111             message += QString::fromUtf8(error->file);
0112             message += QLatin1String(" Line ") + QString::number(error->line);
0113         }
0114     }
0115     while (next != nullptr && next->message != nullptr) {
0116         message = message + QLatin1Char('\n') + QString::fromUtf8(next->message);
0117 
0118         next = next->child;
0119     }
0120 
0121     return message;
0122 }
0123 
0124 ClientException::ClientException(const char *msg) throw()
0125     : Exception(msg)
0126 {
0127 }
0128 
0129 ClientException::ClientException(const QString &msg) throw()
0130     : Exception(msg)
0131 {
0132 }
0133 
0134 ClientException::ClientException(svn_error_t *error) throw()
0135     : Exception(QString())
0136 {
0137     init();
0138     if (error == nullptr) {
0139         return;
0140     }
0141 
0142     m->apr_err = error->apr_err;
0143     m->message += error2msg(error);
0144     svn_error_clear(error);
0145 }
0146 
0147 ClientException::ClientException(apr_status_t status) throw()
0148     : Exception(QString())
0149 {
0150     init();
0151     m->apr_err = status;
0152 }
0153 
0154 ClientException::~ClientException() throw()
0155 {
0156 }
0157 
0158 ClientException::ClientException(const ClientException &src) throw()
0159     : Exception(src.msg())
0160 {
0161     m->apr_err = src.apr_err();
0162     m_backTraceConstr = src.m_backTraceConstr;
0163 }
0164 
0165 void ClientException::init()
0166 {
0167 #ifdef USE_BACKTRACE
0168     if (m_backTraceConstr.isEmpty()) {
0169         m_backTraceConstr = getBackTrace();
0170         m->message = m_backTraceConstr;
0171     }
0172 #else
0173     m_backTraceConstr.clear();
0174 #endif
0175 }
0176 
0177 QString ClientException::getBackTrace()
0178 {
0179     QString Result;
0180 #ifdef HAS_BACKTRACE_H
0181     void *array[SVNQT_BACKTRACE_LENGTH];
0182 
0183     int size = backtrace(array, SVNQT_BACKTRACE_LENGTH);
0184     if (!size) {
0185         return Result;
0186     }
0187 
0188     char **strings = backtrace_symbols(array, size);
0189 
0190     QStringList r;
0191     r.reserve(size);
0192     for (int i = 0; i < size; ++i) {
0193         r.push_back(QString::number(i) + QLatin1String(": ") + QString::fromUtf8(strings[i]));
0194     }
0195     Result = QLatin1String("[\n") + r.join(QLatin1String("\n")) + QLatin1String("]\n");
0196     free(strings);
0197 #endif
0198     return Result;
0199 }
0200 
0201 }
0202 /* -----------------------------------------------------------------
0203  * local variables:
0204  * eval: (load-file "../../rapidsvn-dev.el")
0205  * end:
0206  */