File indexing completed on 2024-05-12 17:16:24

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  * http://kdesvn.alwins-world.de
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)), apr_err(0)
0052     {
0053     }
0054 
0055     Data(const QString &msg)
0056         : message(msg), apr_err(0)
0057     {
0058     }
0059 };
0060 
0061 Exception::Exception(const char *message) throw ()
0062 {
0063     m = new Data(message);
0064 }
0065 
0066 Exception::Exception(const QString &message) throw ()
0067 {
0068     m = new Data(message);
0069 }
0070 
0071 Exception::Exception(const Exception &other) throw ()
0072 {
0073     m = new Data(*other.m);
0074 }
0075 
0076 Exception::~Exception() throw ()
0077 {
0078     delete m;
0079 }
0080 
0081 apr_status_t
0082 Exception::apr_err() const
0083 {
0084     return m->apr_err;
0085 }
0086 
0087 const QString &
0088 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 
0125 ClientException::ClientException(const char *msg) throw ()
0126     : Exception(msg)
0127 {
0128 }
0129 
0130 ClientException::ClientException(const QString &msg) throw ()
0131     : Exception(msg)
0132 {
0133 }
0134 
0135 ClientException::ClientException(svn_error_t *error) throw ()
0136     : Exception(QString())
0137 {
0138     init();
0139     if (error == nullptr) {
0140         return;
0141     }
0142 
0143     m->apr_err = error->apr_err;
0144     m->message += error2msg(error);
0145     svn_error_clear(error);
0146 }
0147 
0148 ClientException::ClientException(apr_status_t status) throw ()
0149     : Exception(QString())
0150 {
0151     init();
0152     m->apr_err = status;
0153 }
0154 
0155 ClientException::~ClientException() throw ()
0156 {
0157 }
0158 
0159 ClientException::ClientException(const ClientException &src) throw ()
0160     : Exception(src.msg())
0161 {
0162     m->apr_err = src.apr_err();
0163     m_backTraceConstr = src.m_backTraceConstr;
0164 }
0165 
0166 void ClientException::init()
0167 {
0168 #ifdef USE_BACKTRACE
0169     if (m_backTraceConstr.isEmpty()) {
0170         m_backTraceConstr = getBackTrace();
0171         m->message = m_backTraceConstr;
0172     }
0173 #else
0174     m_backTraceConstr.clear();
0175 #endif
0176 }
0177 
0178 QString ClientException::getBackTrace()
0179 {
0180     QString Result;
0181 #ifdef HAS_BACKTRACE_H
0182     void *array[SVNQT_BACKTRACE_LENGTH];
0183 
0184     int size = backtrace(array, SVNQT_BACKTRACE_LENGTH);
0185     if (!size) {
0186         return Result;
0187     }
0188 
0189     char **strings = backtrace_symbols(array, size);
0190 
0191     QStringList r;
0192     r.reserve(size);
0193     for (int i = 0; i < size; ++i) {
0194         r.push_back(QString::number(i) +
0195                     QLatin1String(": ") +
0196                     QString::fromUtf8(strings[i]));
0197     }
0198     Result = QLatin1String("[\n") +
0199              r.join(QLatin1String("\n")) +
0200              QLatin1String("]\n");
0201     free(strings);
0202 #endif
0203     return Result;
0204 }
0205 
0206 }
0207 /* -----------------------------------------------------------------
0208  * local variables:
0209  * eval: (load-file "../../rapidsvn-dev.el")
0210  * end:
0211  */