Commit 83bf1ff5 authored by Denis Zalevskiy's avatar Denis Zalevskiy

Merge pull request #15 from nemomobile/staging

Moving qtaround to the separate repository
parents ec9edf4e a83e942c
......@@ -21,3 +21,6 @@ examples/use_cutes
src/vault-cli
units/vault-*
*.moc
tests/tests.xml
tests/*_unit.cpp
tests/*_vault_test
\ No newline at end of file
......@@ -41,7 +41,22 @@ set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -gdwarf-3"
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/src
)
pkg_check_modules(QTAROUND qtaround REQUIRED)
pkg_check_modules(COR cor REQUIRED)
include_directories(
${COR_INCLUDE_DIRS}
${QTAROUND_INCLUDE_DIRS}
)
link_directories(
${COR_LIBRARY_DIRS}
${QTAROUND_LIBRARY_DIRS}
)
add_subdirectory(src)
add_subdirectory(examples)
add_subdirectory(tests)
......@@ -49,11 +64,9 @@ add_subdirectory(qml/Vault)
configure_file(vault-unit.pc.in vault-unit.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vault-unit.pc DESTINATION ${DST_LIB}/pkgconfig)
configure_file(qtaround.pc.in qtaround.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qtaround.pc DESTINATION ${DST_LIB}/pkgconfig)
install(
DIRECTORY include/vault include/qtaround
DIRECTORY include/vault
DESTINATION include
FILES_MATCHING
PATTERN "*.hpp"
......
......@@ -7,6 +7,12 @@
#include <QCoreApplication>
#include <QDebug>
namespace os = qtaround::os;
namespace error = qtaround::error;
namespace sys = qtaround::sys;
namespace json = qtaround::json;
namespace debug = qtaround::debug;
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
......
#ifndef _CUTES_DEBUG_HPP_
#define _CUTES_DEBUG_HPP_
/**
* @file debug.hpp
* @brief Debug tracing support
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include <QVariant>
#include <QDebug>
#include <QTextStream>
#include <memory>
namespace debug {
enum class Level { Debug = 1, Info, Warning, Error, Critical };
QDebug stream();
template <typename T, typename ... Args>
QDebug & operator << (QDebug &d, std::function<T(Args...)> const &)
{
d << "std::function<...>";
return d;
}
static inline void print(QDebug &&d)
{
QDebug dd(std::move(d));
}
template <typename T, typename ... A>
void print(QDebug &&d, T &&v1, A&& ...args)
{
d << v1;
return print(std::move(d), std::forward<A>(args)...);
}
template <typename ... A>
void print(A&& ...args)
{
return print(stream(), std::forward<A>(args)...);
}
void level(Level);
bool is_tracing_level(Level);
template <typename ... A>
void print_ge(Level print_level, A&& ...args)
{
if (is_tracing_level(print_level))
print(std::forward<A>(args)...);
}
template <typename ... A>
void debug(A&& ...args)
{
print_ge(Level::Debug, std::forward<A>(args)...);
}
template <typename ... A>
void info(A&& ...args)
{
print_ge(Level::Info, std::forward<A>(args)...);
}
template <typename ... A>
void warning(A&& ...args)
{
print_ge(Level::Warning, std::forward<A>(args)...);
}
template <typename ... A>
void error(A&& ...args)
{
print_ge(Level::Error, std::forward<A>(args)...);
}
template <typename ... A>
void critical(A&& ...args)
{
print_ge(Level::Critical, std::forward<A>(args)...);
}
}
#endif // _CUTES_DEBUG_HPP_
#ifndef _CUTES_ERROR_HPP_
#define _CUTES_ERROR_HPP_
/**
* @file error.hpp
* @brief Unified exceptions
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include <exception>
#include <QVariantMap>
#include <QDebug>
namespace error {
template <typename T>
QString dump(T && t)
{
QString s;
QDebug d(&s);
d << t;
return s;
}
class Error : public std::exception
{
public:
Error(QVariantMap const &from) : m(from) {}
virtual ~Error() noexcept(true) {}
virtual const char* what() const noexcept(true)
{
if (s.isEmpty())
s = dump(m);
return s.toUtf8();
}
QVariantMap m;
mutable QString s;
};
static inline QDebug operator << (QDebug dst, error::Error const &src)
{
dst << src.m;
return dst;
}
static inline void raise(QVariantMap const &m)
{
throw Error(m);
}
static inline void raise(std::initializer_list<std::pair<QString, QVariant> > src)
{
raise(QVariantMap(src));
}
template <typename T, typename T2, typename ... A>
void raise(T const &m1, T2 const &m2, A && ...args)
{
QVariantMap x = m1;
QVariantMap y = m2;
x.unite(y);
raise(x, std::forward<A>(args)...);
}
}
#endif // _CUTES_ERROR_HPP_
#ifndef _CUTES_JSON_HPP_
#define _CUTES_JSON_HPP_
/**
* @file json.hpp
* @brief Json access wrappers
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include <qtaround/os.hpp>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
namespace json {
QJsonObject read(QString const &);
ssize_t write(QJsonObject const &, QString const &);
ssize_t write(QVariantMap const &, QString const &);
}
namespace {
QVariant get(QJsonValue const &v)
{
return v.toVariant();
}
QVariant get(QJsonObject const &m, QString const &k)
{
return m[k].toVariant();
}
QVariant get(QJsonArray const &a, size_t i)
{
return a[i].toVariant();
}
}
template <typename ... A>
QVariant get(QJsonValue const &v, QString const &k, A&& ...args)
{
if (!v.isObject())
return QVariant();
return get(v.toObject()[k], std::forward<A>(args)...);
}
template <typename ... A>
QVariant get(QJsonValue const &v, size_t i, A&& ...args)
{
if (!v.isArray())
return QVariant();
auto const a = v.toArray();
return get(a[i], std::forward<A>(args)...);
}
template <typename ... A>
QVariant get(QJsonObject const &m, QString const &k, A&& ...args)
{
auto v = m[k];
return get(v, std::forward<A>(args)...);
}
#endif // _CUTES_JSON_HPP_
#ifndef _CUTES_OS_HPP_
#define _CUTES_OS_HPP_
/**
* @file os.hpp
* @brief Wrappers to support API looking familiar for python/shell developers
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include "error.hpp"
#include "sys.hpp"
#include "subprocess.hpp"
#include <QFileInfo>
#include <QDir>
#include <QString>
#include <QVariant>
#include <QDateTime>
using subprocess::Process;
namespace os {
class path
{
public:
static inline QString join(QString const& a)
{
return a;
}
template <typename ...A>
static QString join(QString const& a, QString const& b, A&& ...args)
{
return join(QStringList({a, b}).join("/"), std::forward<A>(args)...);
}
static inline bool exists(QString const &p)
{
return QFileInfo(p).exists();
}
static inline QString canonical(QString const &p)
{
return QFileInfo(p).canonicalFilePath();
}
static inline QString relative(QString const &p, QString const &d)
{
return QDir(d).relativeFilePath(p);
}
static inline QString deref(QString const &p)
{
return QFileInfo(p).symLinkTarget();
}
static QString target(QString const &link);
static inline bool isDir(QString const &p)
{
return QFileInfo(p).isDir();
}
static inline bool isSymLink(QString const &p)
{
return QFileInfo(p).isSymLink();
}
static inline bool isFile(QString const &p)
{
return QFileInfo(p).isFile();
}
static inline QString dirName(QString const &p)
{
return QFileInfo(p).dir().path();
}
static inline QString fileName(QString const &p)
{
return QFileInfo(p).fileName();
}
static QStringList split(QString const &p);
static bool isDescendent(QString const &p, QString const &other);
private:
};
int system(QString const &cmd, QStringList const &args = QStringList());
bool mkdir(QString const &path, QVariantMap const &options);
static inline bool mkdir(QString const &path)
{
return mkdir(path, QVariantMap());
}
QByteArray read_file(QString const &fname);
ssize_t write_file(QString const &fname, QByteArray const &data);
static inline ssize_t write_file(QString const &fname, QString const &data)
{
return write_file(fname, data.toUtf8());
}
static inline ssize_t write_file(QString const &fname, char const *data)
{
return write_file(fname, QString(data).toUtf8());
}
namespace {
inline QString home()
{
return QDir::homePath();
}
inline int symlink(QString const &tgt, QString const &link)
{
return system("ln", {"-s", tgt, link});
}
inline int rmtree(QString const &path)
{
return system("rm", {"-rf", path});
}
inline int unlink(QString const &what)
{
return system("unlink", {what});
}
inline int rename(QString const &from, QString const &to)
{
return system("mv", {from, to});
}
inline QDateTime lastModified(QString const &path)
{
return QFileInfo(path).lastModified();
}
inline int setLastModified(QString const &path, QDateTime const &timeval)
{
return system("touch", {"-d", timeval.toString(), path});
};
inline int rm(QString const &path)
{
return system("rm", {path});
}
inline QString environ(QString const &name)
{
auto c = ::getenv(name.toUtf8());
return c ? str(c) : QString();
}
}
int cp(QString const &, QString const &, QVariantMap &&);
static inline int cp(QString const &src, QString const &dst)
{
return cp(src, dst, QVariantMap());
}
int update(QString const &src, QString const &dst
, QVariantMap &&options = QVariantMap());
int update_tree(QString const &, QString const &, QVariantMap &&);
static inline int update_tree(QString const &src, QString const &dst)
{
return update_tree(src, dst, QVariantMap());
}
int cptree(QString const &src, QString const &dst
, QVariantMap &&options = QVariantMap());
size_t get_block_size(QString const &);
QList<QVariantMap> mount();
QString mountpoint(QString const &path);
string_map_type stat(QString const &path, QVariantMap &&options = QVariantMap());
QVariant du(QString const &path, QVariantMap &&options = map({{"summarize", true}
, {"one_filesystem", true}, {"block_size", "K"}}));
double diskFree(QString const &path);
QString mkTemp(QVariantMap &&options = QVariantMap());
}
#endif // _CUTES_OS_HPP_
#ifndef _CUTES_SUBPROCESS_HPP_
#define _CUTES_SUBPROCESS_HPP_
/**
* @file subprocess.hpp
* @brief Subprocess execution API resembing std python lib
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include <memory>
#include <QProcess>
#include <QVariant>
namespace subprocess {
class Process : public QObject
{
public:
Process()
: ps(new QProcess())
, isRunning_(false)
, isError_(false)
{}
Process(Process &&from)
: ps(std::move(from.ps))
, isRunning_(from.isRunning_)
, isError_(from.isError_)
{}
void setWorkingDirectory(QString const &d)
{
ps->setWorkingDirectory(d);
}
void start(QString const &, QStringList const &);
bool wait(int timeout);
bool is_error() const;
QString errorInfo() const;
void popen_sync(QString const &cmd, QStringList const &args)
{
start(cmd, args);
ps->waitForStarted(-1);
}
int rc() const
{
return is_error() ? -1111 : ps->exitCode();
}
qint64 write(QString const &data)
{
return ps->write(data.toUtf8());
}
QByteArray stdout() const;
QByteArray stderr() const;
void stdinClose()
{
ps->closeWriteChannel();
}
Q_PID pid() const
{
return ps->pid();
}
void check_error(QVariantMap const &error_info);
void check_error()
{
check_error(QVariantMap());
}
QByteArray check_output(QString const &, QStringList const &, QVariantMap const &);
QByteArray check_output(QString const &cmd, QStringList const &args)
{
return check_output(cmd, args, QVariantMap());
}
int check_call(QString const &, QStringList const &, QVariantMap const &);
int check_call(QString const &cmd, QStringList const &args)
{
return check_call(cmd, args, QVariantMap());
}
private:
mutable std::unique_ptr<QProcess> ps;
bool isRunning_;
bool isError_;
private slots:
void onError(QProcess::ProcessError);
void onFinished(int, QProcess::ExitStatus);
};
QByteArray check_output(QString const &cmd, QStringList const &args, QVariantMap const &);
static inline QByteArray check_output(QString const &cmd, QStringList const &args)
{
return check_output(cmd, args, QVariantMap());
}
int check_call(QString const &cmd, QStringList const &args, QVariantMap const &);
static inline int check_call(QString const &cmd, QStringList const &args)
{
return check_call(cmd, args, QVariantMap());
}
}
#endif // _CUTES_SUBPROCESS_HPP_
#ifndef _CUTES_SYS_HPP_
#define _CUTES_SYS_HPP_
/**
* @file sys.hpp
* @brief Command line parsing and generation etc.
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include <qtaround/util.hpp>
#include <QSet>
namespace sys {
QStringList command_line_options
(QVariantMap const &options
, string_map_type const &short_options = string_map_type()
, string_map_type const &long_options = string_map_type()
, QSet<QString> const &options_has_param = QSet<QString>());
class GetOpt
{
public:
virtual ~GetOpt() {}
virtual QString value(QString const &name) const =0;
virtual bool isSet(QString const &name) const =0;
virtual QStringList arguments() const =0;
};
std::unique_ptr<GetOpt> getopt(QVariantMap const &, bool requireAll = true);
}
#endif // _CUTES_SYS_HPP_
#ifndef _CUTES_UTIL_HPP_
#define _CUTES_UTIL_HPP_
/**
* @file util.hpp
* @brief Misc. helpful utilities
* @author Denis Zalevskiy <denis.zalevskiy@jolla.com>
* @copyright (C) 2014 Jolla Ltd.
* @par License: LGPL 2.1 http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
*/
#include "error.hpp"
#include <QVariant>
#include <QDebug>
#include <QTextStream>
#include <QMap>
#include <QStringList>
#include <tuple>
#include <memory>
#include <array>
namespace {
inline QString str(QVariant const &v)
{
return v.toString();
}
inline QString str(QByteArray const &v)
{
return QString::fromUtf8(v);
}
inline QString str(int v)
{
return QString::number(v);
}
inline QString str(char const *v)
{
return QString(v);
}
inline bool is(QVariant const &v)
{
return v.toBool();
}
inline bool is(QString const &v)
{
return v.isEmpty() ? false : v.toUInt();
}
inline bool hasType(QVariant const &v, QMetaType::Type t)
{
return static_cast<QMetaType::Type>(v.type()) == t;
}
template <typename X, typename Y> X get(Y const &);
template <>
double get<double>(QVariant const &v)
{
return v.toDouble();
}
typedef QVariantMap map_type;
typedef QMap<QString, QString> string_map_type;
typedef QList<QVariant> list_type;
typedef std::tuple<QString, QVariant> map_tuple_type;
inline QVariantMap map(std::initializer_list<std::pair<QString, QVariant> > data)
{
return QVariantMap(data);
}
inline QVariantList list(std::initializer_list<QVariant> data)
{
return QVariantList(data);
}
inline QVariantMap map(QVariant const &v, bool check_type = true)
{
if (check_type && !hasType(v, QMetaType::QVariantMap))
error::raise({{"msg", "Need QVariantMap"}, {"value", v}});
return v.toMap();
}
inline QVariantMap const & map(QVariantMap const &data)
{
return data;
}
template <typename X, typename Y>