-added Log feature for QT .

-fixed Prefences and General Dialog
-disabled show function from main.cpp it will not allow to start minimized, it blocks minimize gui function.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@686 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
defnax 2008-08-15 17:49:57 +00:00
parent 8b9e64f9f6
commit cb891ff08a
29 changed files with 961 additions and 1063 deletions

View file

@ -0,0 +1,181 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2008, crypton
* Copyright (c) 2008, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QDateTime>
#include <QTextStream>
#include "log.h"
/** Open log files for appending as write-only text. */
#define LOGFILE_MODE \
(QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text)
/** Format for log message timestamps. */
#define TIMESTAMP_FMT "MMM dd HH:mm:ss.zzz"
/** Default constructor. Logs at level Notice by default. */
Log::Log()
{
_logLevel = Notice;
}
/** Destructor. Closes the log file. */
Log::~Log()
{
close();
}
/** Returns a list of strings representing available log levels. */
QStringList
Log::logLevels()
{
return (QStringList() << "debug" << "info" << "notice"
<< "warn" << "error");
}
/** Sets the current log level to <b>level</b>. If <b>level</b> is Off, then
* the log file will be closed as well. If <b>level</b> is Unknown, no change
* to the current log level is made. */
void
Log::setLogLevel(LogLevel level)
{
if (level >= Debug && level < Unknown)
_logLevel = level;
if (level == Off)
_logFile.close();
}
/** Opens <b>file</b> for appending, to which log messages will be written. */
bool
Log::open(FILE *file)
{
if (_logFile.isOpen())
close();
_logFile.open(file, LOGFILE_MODE);
return isOpen();
}
/** Opens <b>file</b> for appending, to which log messages will be written. */
bool
Log::open(QString file)
{
if (_logFile.isOpen())
close();
_logFile.setFileName(file);
_logFile.open(LOGFILE_MODE);
return isOpen();
}
/** Flushes any outstanding log messages and closes the log file. */
void
Log::close()
{
if (_logFile.isOpen()) {
_logFile.flush();
_logFile.close();
}
}
/** Creates a log message with severity <b>level</b> and initial message
* contents <b>message</b>. The log message can be appended to until the
* returned LogMessage's destructor is called, at which point the complete
* message is written to the log file. */
inline Log::LogMessage
Log::log(LogLevel level)
{
if (level < _logLevel)
return LogMessage(level, 0);
return LogMessage(level, &_logFile);
}
/** Creates a log message with severity <b>level</b>. The log message can be
* appended to until the returned LogMessage's destructor is called, at
* which point the complete message is written to the log file. */
Log::LogMessage
Log::log(LogLevel level, QString msg)
{
return log(level) << msg;
}
/** Returns a string description of the given LogLevel <b>level</b>. */
inline QString
Log::logLevelToString(LogLevel level)
{
switch (level) {
case Debug: return "debug";
case Info: return "info";
case Notice: return "notice";
case Warn: return "warn";
case Error: return "error";
case Off: return "off";
default: return "unknown";
}
}
/** Returns a LogLevel for the level given by <b>str</b>, or Unknown if the
* given string does not represent a valid LogLevel value. */
Log::LogLevel
Log::stringToLogLevel(QString str)
{
str = str.toLower();
if (str == "debug")
return Debug;
else if (str == "info")
return Info;
else if (str == "notice")
return Notice;
else if (str == "warn")
return Warn;
else if (str == "error")
return Error;
else if (str == "off")
return Off;
return Unknown;
}
/** Returns a formatted log message, prefixed with a timestamp and the log
* message severity level. */
inline QString
Log::LogMessage::toString() const
{
QString msg = QDateTime::currentDateTime().toString(TIMESTAMP_FMT);
msg.append(" [" + Log::logLevelToString(stream->type) + "] ");
msg.append(stream->buf);
return msg;
}
/** Destructor. Writes the buffered log message out to the log file specified
* in the constructor. */
Log::LogMessage::~LogMessage()
{
if (!--stream->ref) {
if (stream->out && !stream->buf.isEmpty()) {
QTextStream log(stream->out);
log << toString() << endl;
log.flush();
}
delete stream;
}
}

View file

@ -0,0 +1,163 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _LOG_H
#define _LOG_H
#include <QObject>
#include <QFile>
#include <QStringList>
#include <QIODevice>
#include <QHostAddress>
/** The Log class is similar to the QDebug class provided with Qt, but with
* finer-grained logging levels, slightly different output (for example, not
* everything is wrapped in double quotes), supports using .arg(), and can
* still be used even if Qt was compiled with QT_NO_DEBUG_STREAM. */
class Log
{
public:
/** Logging severity levels. */
enum LogLevel {
Debug = 0, /**< Verbose debugging output. */
Info, /**< Primarily program flow output. */
Notice, /**< Non-failure (but important) events. */
Warn, /**< Recoverable failure conditions. */
Error, /**< Critical, non-recoverable errors. */
Off, /**< No logging output. */
Unknown /**< Unknown/invalid log level. */
};
class LogMessage;
/** Default constructor. */
Log();
/** Destructor. */
~Log();
/** Opens a file on disk (or stdout or stderr) to which log messages will be
* written. */
bool open(FILE *file);
/** Opens a file on disk to which log messages will be written. */
bool open(QString file);
/** Closes the log file. */
void close();
/** Returns true if the log file is open and ready for writing. */
bool isOpen() { return _logFile.isOpen() && _logFile.isWritable(); }
/** Returns a string description of the last file error encountered. */
QString errorString() { return _logFile.errorString(); }
/** Sets the current log level to <b>level</b>. */
void setLogLevel(LogLevel level);
/** Returns a list of strings representing valid log levels. */
static QStringList logLevels();
/** Returns a string description of the given LogLevel <b>level</b>. */
static inline QString logLevelToString(LogLevel level);
/** Returns a LogLevel for the level given by <b>str</b>. */
static LogLevel stringToLogLevel(QString str);
/** Creates a log message with severity <b>level</b> and initial message
* contents <b>message</b>. The log message can be appended to until the
* returned LogMessage's destructor is called, at which point the complete
* message is written to the log file. */
LogMessage log(LogLevel level, QString message);
/** Creates a log message with severity <b>level</b>. The log message can be
* appended to until the returned LogMessage's destructor is called, at
* which point the complete message is written to the log file. */
inline LogMessage log(LogLevel level);
private:
LogLevel _logLevel; /**< Minimum log severity level. */
QFile _logFile; /**< Log output destination. */
};
/** This internal class represents a single message that is to be written to
* the log destination. The message is buffered until it is written to the
* log in this class's destructor. */
class Log::LogMessage
{
public:
struct Stream {
Stream(Log::LogLevel t, QIODevice *o)
: type(t), out(o), ref(1) {}
Log::LogLevel type;
QIODevice *out;
int ref;
QString buf;
} *stream;
inline LogMessage(Log::LogLevel t, QIODevice *o)
: stream(new Stream(t,o)) {}
inline LogMessage(const LogMessage &o)
: stream(o.stream) { ++stream->ref; }
inline QString toString() const;
~LogMessage();
/* Support both the << and .arg() methods */
inline LogMessage &operator<<(const QString &t)
{ stream->buf += t; return *this; }
inline LogMessage arg(const QString &a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(const QStringList &a)
{ stream->buf += a.join(","); return *this; }
inline LogMessage arg(const QStringList &a)
{ stream->buf = stream->buf.arg(a.join(",")); return *this; }
inline LogMessage &operator<<(const QHostAddress &a)
{ stream->buf += a.toString(); return *this; }
inline LogMessage arg(const QHostAddress &a)
{ stream->buf = stream->buf.arg(a.toString()); return *this; }
inline LogMessage &operator<<(short a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(short a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(ushort a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(ushort a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(int a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(int a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(uint a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(uint a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(long a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(long a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(ulong a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(ulong a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(qlonglong a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(qlonglong a)
{ stream->buf = stream->buf.arg(a); return *this; }
inline LogMessage &operator<<(qulonglong a)
{ stream->buf += QString::number(a); return *this; }
inline LogMessage arg(qulonglong a)
{ stream->buf = stream->buf.arg(a); return *this; }
};
#endif

View file

@ -1,124 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QDir>
#include <QFile>
#include <QTextStream>
#include "string.h"
#include "process.h"
/** Returns the PID of the current process. */
qint64
get_pid()
{
#if defined(Q_OS_WIN)
return (qint64)GetCurrentProcessId();
#else
return (qint64)getpid();
#endif
}
/** Returns true if a process with the given PID is running. */
bool
is_process_running(qint64 pid)
{
#if defined(Q_OS_WIN)
BOOL rc;
DWORD exitCode;
/* Try to open the process to see if it exists */
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pid);
if (hProcess == NULL) {
return false;
}
/* It exists, so see if it's still active or if it terminated already */
rc = GetExitCodeProcess(hProcess, &exitCode);
CloseHandle(hProcess);
if (!rc) {
/* Error. Assume it doesn't exist (is this a bad assumption?) */
return false;
}
/* If GetExitCodeProcess() returns a non-zero value, and the process is
* still running, exitCode should equal STILL_ACTIVE. Otherwise, this means
* the process has terminated. */
return (exitCode == STILL_ACTIVE);
#else
/* Send the "null" signal to check if a process exists */
if (kill((pid_t)pid, 0) < 0) {
return (errno != ESRCH);
}
return true;
#endif
}
/** Writes the given file to disk containing the current process's PID. */
bool
write_pidfile(QString pidFileName, QString *errmsg)
{
/* Make sure the directory exists */
QDir pidFileDir = QFileInfo(pidFileName).absoluteDir();
if (!pidFileDir.exists()) {
pidFileDir.mkpath(QDir::convertSeparators(pidFileDir.absolutePath()));
}
/* Try to open (and create if it doesn't exist) the pidfile */
QFile pidfile(pidFileName);
if (!pidfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
return err(errmsg, pidfile.errorString());
}
/* Write our current PID to it */
QTextStream pidstream(&pidfile);
pidstream << get_pid();
return true;
}
/** Reads the given pidfile and returns the value contained in it. If the file
* does not exist 0 is returned. Returns -1 if an error occurs. */
qint64
read_pidfile(QString pidFileName, QString *errmsg)
{
qint64 pid;
/* Open the pidfile, if it exists */
QFile pidfile(pidFileName);
if (!pidfile.exists()) {
return 0;
}
if (!pidfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errmsg) {
*errmsg = pidfile.errorString();
}
return -1;
}
/* Read the PID in from the file */
QTextStream pidstream(&pidfile);
pidstream >> pid;
return pid;
}

View file

@ -1,54 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _PROCESS_H
#define _PROCESS_H
#include <QString>
#if defined(Q_OS_WIN)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#endif
/** Returns the PID of the current process. */
qint64 get_pid();
/** Returns true if a process with the given PID is running. */
bool is_process_running(qint64 pid);
/** Writes the given file to disk containing the current process's PID. */
bool write_pidfile(QString pidfile, QString *errmsg = 0);
/** Reads the giiven pidfile and returns the value in it. If the file does not
* exist, -1 is returned. */
qint64 read_pidfile(QString pidfile, QString *errmsg = 0);
#endif

View file

@ -1,111 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include "registry.h"
/** Returns the value in keyName at keyLocation.
* Returns an empty QString if the keyName doesn't exist */
QString
registry_get_key_value(QString keyLocation, QString keyName)
{
#if 0
HKEY key;
char data[255] = {0};
DWORD size = sizeof(data);
/* Open the key for reading (opens new key if it doesn't exist) */
if (RegOpenKeyExA(HKEY_CURRENT_USER,
qPrintable(keyLocation),
0L, KEY_READ, &key) == ERROR_SUCCESS) {
/* Key exists, so read the value into data */
RegQueryValueExA(key, qPrintable(keyName),
NULL, NULL, (LPBYTE)data, &size);
}
/* Close anything that was opened */
RegCloseKey(key);
return QString(data);
#endif
return keyName;
}
/** Creates and/or sets the key to the specified value */
void
registry_set_key_value(QString keyLocation, QString keyName, QString keyValue)
{
#if 0
HKEY key;
/* Open the key for writing (opens new key if it doesn't exist */
if (RegOpenKeyExA(HKEY_CURRENT_USER,
qPrintable(keyLocation),
0, KEY_WRITE, &key) != ERROR_SUCCESS) {
/* Key didn't exist, so write the newly opened key */
RegCreateKeyExA(HKEY_CURRENT_USER,
qPrintable(keyLocation),
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
&key, NULL);
}
/* Save the value in the key */
RegSetValueExA(key, qPrintable(keyName), 0, REG_SZ,
(BYTE *)qPrintable(keyValue),
(DWORD)keyValue.length() + 1); // include null terminator
/* Close the key */
RegCloseKey(key);
#endif
}
/** Removes the key from the registry if it exists */
void
registry_remove_key(QString keyLocation, QString keyName)
{
#if 0
HKEY key;
/* Open the key for writing (opens new key if it doesn't exist */
if (RegOpenKeyExA(HKEY_CURRENT_USER,
qPrintable(keyLocation),
0, KEY_SET_VALUE, &key) == ERROR_SUCCESS) {
/* Key exists so delete it */
RegDeleteValueA(key, qPrintable(keyName));
}
/* Close anything that was opened */
RegCloseKey(key);
#endif
}

View file

@ -1,47 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _REGISTRY_H
#define _REGISTRY_H
#include <QString>
#define WIN32_LEAN_AND_MEAN
#if 0
#include "windows.h"
#endif
/** Returns value of keyName or empty QString if keyName doesn't exist */
QString registry_get_key_value(QString keyLocation, QString keyName);
/** Creates and/or sets the key to the specified value */
void registry_set_key_value(QString keyLocation, QString keyName, QString keyValue);
/** Removes the key from the registry if it exists */
void registry_remove_key(QString keyLocation, QString keyName);
#endif

View file

@ -1,66 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include "string.h"
/** Create a QStringList from the array of C-style strings. */
QStringList
char_array_to_stringlist(char **arr, int len)
{
QStringList list;
for (int i = 0; i < len; i++) {
list << QString(arr[i]);
}
return list;
}
/** Conditionally assigns errmsg to str if str is not null and returns false.
* This is a seemingly pointless function, but it saves some messiness in
* methods whose QString *errmsg parameter is optional. */
bool
err(QString *str, QString errmsg)
{
if (str) {
*str = errmsg;
}
return false;
}
/** Ensures all characters in str are in validChars. If a character appears
* in str but not in validChars, it will be removed and the resulting
* string returned. */
QString
ensure_valid_chars(QString str, QString validChars)
{
QString out = str;
for (int i = 0; i < str.length(); i++) {
QChar c = str.at(i);
if (validChars.indexOf(c) < 0) {
out.remove(c);
}
}
return out;
}

View file

@ -1,43 +0,0 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2006-2007, crypton
* Copyright (c) 2006, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef __STRING_H
#define __STRING_H
#include <QStringList>
/** Creates a QStringList from the array of C strings. */
QStringList char_array_to_stringlist(char **arr, int len);
/** Ensures all characters in str are in validChars. If a character appears
* in str but not in validChars, it will be removed and the resulting
* string returned. */
QString ensure_valid_chars(QString str, QString validChars);
/** Conditionally assigns errmsg to string if str is not null and returns
* false. */
bool err(QString *str, QString errmsg);
#endif

View file

@ -0,0 +1,319 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2008, crypton
* Copyright (c) 2008, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
/*
** \file stringutil.cpp
** \version $Id: stringutil.cpp 2486 2008-04-05 14:43:08Z edmanm $
** \brief Common string manipulation functions
*/
#include "stringutil.h"
/** Create a QStringList from the array of C-style strings. */
QStringList
char_array_to_stringlist(char **arr, int len)
{
QStringList list;
for (int i = 0; i < len; i++) {
list << QString(arr[i]);
}
return list;
}
/** Conditionally assigns errmsg to str if str is not null and returns false.
* This is a seemingly pointless function, but it saves some messiness in
* methods whose QString *errmsg parameter is optional. */
bool
err(QString *str, const QString &errmsg)
{
if (str) {
*str = errmsg;
}
return false;
}
/** Ensures all characters in str are in validChars. If a character appears
* in str but not in validChars, it will be removed and the resulting
* string returned. */
QString
ensure_valid_chars(const QString &str, const QString &validChars)
{
QString out = str;
for (int i = 0; i < str.length(); i++) {
QChar c = str.at(i);
if (validChars.indexOf(c) < 0) {
out.remove(c);
}
}
return out;
}
/** Scrubs an email address by replacing "@" with " at " and "." with " dot ". */
QString
scrub_email_addr(const QString &email)
{
QString scrubbed = email;
scrubbed = scrubbed.replace("@", " at ");
scrubbed = scrubbed.replace(".", " dot ");
return scrubbed;
}
/** Wraps <b>str</b> at <b>width</b> characters wide, using <b>sep</b> as the
* word separator (" ", for example), and placing the line ending <b>le</b> at
* the end of each line, except the last. */
QString
string_wrap(const QString &str, int width,
const QString &sep, const QString &le)
{
QString wrapped;
int pos, nextsep, wordlen, n;
int seplen = sep.length();
if (str.length() < width) {
return str;
}
pos = 0;
n = width;
while (pos < str.length()) {
/* Get the length of a "word" */
nextsep = str.indexOf(sep, pos);
if (nextsep < 0) {
nextsep = str.length();
}
wordlen = nextsep-pos;
/* Check if there is room for the word on this line */
if (wordlen > n) {
/* Create a new line */
wrapped.append(le);
n = width;
}
/* Add the word to the current line */
wrapped.append(str.mid(pos, wordlen+seplen));
n = n - wordlen - seplen;
pos += wordlen + seplen;
}
return wrapped.trimmed();
}
/** Encodes the bytes in <b>buf</b> as an uppercase hexadecimal string and
* returns the result. This function is derived from base16_encode() in Tor's
* util.c. See LICENSE for details on Tor's license. */
QString
base16_encode(const QByteArray &buf)
{
QString hex;
for (int i = 0; i < buf.size(); i++) {
hex += "0123456789ABCDEF"[((quint8)buf[i]) >> 4];
hex += "0123456789ABCDEF"[((quint8)buf[i]) & 0xf];
}
return hex;
}
/** Given a string <b>str</b>, this function returns a quoted string with all
* '"' and '\' characters escaped with a single '\'. */
QString
string_escape(const QString &str)
{
QString out;
out.append("\"");
for (int i = 0; i < str.length(); i++) {
if (str[i] == '\"' || str[i] == '\\')
out.append('\\');
out.append(str[i]);
}
out.append("\"");
return out;
}
/** Given a quoted string <b>str</b>, this function returns an unquoted,
* unescaped string. <b>str</b> must start and end with an unescaped quote. */
QString
string_unescape(const QString &str, bool *ok)
{
QString out;
/* The string must start and end with an unescaped dquote */
if (str.length() < 2 || !str.startsWith("\"") || !str.endsWith("\"") ||
(str.endsWith("\\\"") && !str.endsWith("\\\\\""))) {
if (ok)
*ok = false;
return QString();
}
for (int i = 1; i < str.length()-1; i++) {
if (str[i] == '\\')
i++;
out.append(str[i]);
}
if (ok)
*ok = true;
return out;
}
/** Parses a series of space-separated key[=value|="value"] tokens from
* <b>str</b> and returns the mappings in a QHash. If <b>str</b> was unable
* to be parsed, <b>ok</b> is set to false. */
QHash<QString,QString>
string_parse_keyvals(const QString &str, bool *ok)
{
int i, len;
bool tmp_ok;
QHash<QString,QString> keyvals;
i = 0;
len = str.length();
while (i < len && str[i].isSpace())
i++; /* Skip initial whitespace */
while (i < len) {
QString key, val;
while (i < len && !str[i].isSpace() && str[i] != '=')
key.append(str[i++]);
if (i < len && str[i] == '=') {
if (++i < len && str[i] == '\"') {
/* The value is wrapped in quotes */
val.append(str[i]);
while (++i < len) {
val.append(str[i]);
if (str[i] == '\\') {
if (++i == len)
goto error;
val.append(str[i]);
} else if (str[i] == '\"') {
i++;
break;
}
}
val = string_unescape(val, &tmp_ok);
if (!tmp_ok)
goto error;
keyvals.insert(key, val);
} else {
/* The value was not wrapped in quotes */
while (i < len && !str[i].isSpace())
val.append(str[i++]);
keyvals.insert(key, val);
}
} else {
/* The key had no value */
keyvals.insert(key, QString(""));
}
while (i < len && str[i].isSpace())
i++;
}
if (ok)
*ok = true;
return keyvals;
error:
if (ok)
*ok = false;
return QHash<QString,QString>();
}
/** Parses a series of command line arguments from <b>str</b>. If <b>str</b>
* was unable to be parsed, <b>ok</b> is set to false. */
QStringList
string_parse_arguments(const QString &str, bool *ok)
{
QStringList args;
int i, len;
bool tmp_ok;
i = 0;
len = str.length();
while (i < len && str[i].isSpace())
i++; /* Skip initial whitespace */
while (i < len) {
QString arg;
if (str[i] == '\"') {
/* The value is wrapped in quotes */
arg.append(str[i]);
while (++i < len) {
arg.append(str[i]);
if (str[i] == '\\') {
if (++i == len)
goto error;
arg.append(str[i]);
} else if (str[i] == '\"') {
i++;
break;
}
}
arg = string_unescape(arg, &tmp_ok);
if (!tmp_ok)
goto error;
args << arg;
} else {
/* The value was not wrapped in quotes */
while (i < len && !str[i].isSpace())
arg.append(str[i++]);
args << arg;
}
while (i < len && str[i].isSpace())
i++;
}
if (ok)
*ok = true;
return args;
error:
if (ok)
*ok = false;
return QStringList();
}
/** Formats the list of command line arguments in <b>args</b> as a string.
* Arguments that contain ' ', '\', or '"' tokens will be escaped and
* wrapped in double quotes. */
QString
string_format_arguments(const QStringList &args)
{
QStringList out;
foreach (QString arg, args) {
if (arg.contains("\"") || arg.contains("\\") || arg.contains(" "))
out << string_escape(arg);
else
out << arg;
}
return out.join(" ");
}
/** Returns true if <b>str</b> is a valid hexademical string. Returns false
* otherwise. */
bool
string_is_hex(const QString &str)
{
for (int i = 0; i < str.length(); i++) {
char c = str[i].toUpper().toAscii();
if ((c < 'A' || c > 'F') && (c < '0' || c > '9'))
return false;
}
return true;
}

View file

@ -0,0 +1,88 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2008, crypton
* Copyright (c) 2008, Matt Edman, Justin Hipple
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* 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 General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
/*
** \file stringutil.h
** \version $Id: stringutil.h 2486 2008-04-05 14:43:08Z edmanm $
** \brief Common string manipulation functions
*/
#ifndef _STRINGUTIL_H
#define _STRINGUTIL_H
#include <QStringList>
#include <QHash>
/** Creates a QStringList from the array of C strings. */
QStringList char_array_to_stringlist(char **arr, int len);
/** Ensures all characters in str are in validChars. If a character appears
* in str but not in validChars, it will be removed and the resulting
* string returned. */
QString ensure_valid_chars(const QString &str, const QString &validChars);
/** Scrubs an email address by replacing "@" with " at " and "." with " dot ". */
QString scrub_email_addr(const QString &email);
/** Conditionally assigns errmsg to string if str is not null and returns
* false. */
bool err(QString *str, const QString &errmsg);
/** Wraps <b>str</b> at <b>width</b> characters wide, using <b>sep</b> as the
* word separator (" ", for example), and placing the line ending <b>le</b> at
* the end of each line, except the last.*/
QString string_wrap(const QString &str, int width,
const QString &sep, const QString &le);
/** Encodes the bytes in <b>buf</b> as an uppercase hexadecimal string and
* returns the result. This function is derived from base16_encode() in Tor's
* util.c. See LICENSE for details on Tor's license. */
QString base16_encode(const QByteArray &buf);
/** Given a string <b>str</b>, this function returns a quoted string with all
* '"' and '\' characters escaped with a single '\'. */
QString string_escape(const QString &str);
/** Given a quoted string <b>str</b>, this function returns an unquoted,
* unescaped string. <b>str</b> must start and end with an unescaped quote. */
QString string_unescape(const QString &str, bool *ok = 0);
/** Parses a series of space-separated key[=value|="value"] tokens from
* <b>str</b> and returns the mappings in a QHash. If <b>str</b> was unable
* to be parsed, <b>ok</b> is set to false. */
QHash<QString,QString> string_parse_keyvals(const QString &str, bool *ok = 0);
/** Parses a series of command line arguments from <b>str</b>. If <b>str</b>
* was unable to be parsed, <b>ok</b> is set to false. */
QStringList string_parse_arguments(const QString &str, bool *ok = 0);
/** Formats the list of command line arguments in <b>args</b> as a string.
* Arguments that contain ' ', '\', or '"' tokens will be escaped and wrapped
* in double quotes. */
QString string_format_arguments(const QStringList &args);
/** Returns true if <b>str</b> is a valid hexademical string. Returns false
* otherwise. */
bool string_is_hex(const QString &str);
#endif