Restructured locations of source.

This commit is contained in:
Eelke Klein 2017-08-27 07:34:42 +02:00
parent 78a4c6d730
commit 7c4e8e95e8
151 changed files with 1 additions and 0 deletions

View file

@ -1,100 +0,0 @@
#include "BackupFormatModel.h"
#include <vector>
namespace {
class BackupFormatItem {
public:
const QString shortFlag;
const QString longFlag;
const QString description;
BackupFormatItem(QString s, QString l, QString d)
: shortFlag(std::move(s))
, longFlag(std::move(l))
, description(std::move(d))
{}
};
using t_BackupFormatItemVector = std::vector<BackupFormatItem>;
t_BackupFormatItemVector g_BackupFormats = {
BackupFormatItem{ "p", "plain", "Output a plaintext SQL script, restore with psql" },
BackupFormatItem{ "c", "custom", "Postgresql's own format most flexible and compressed, restore with pg_restore" },
BackupFormatItem{ "d", "directory", "Generates a directory with a file for each table or blob" },
BackupFormatItem{ "t", "tar", "Similar to directory if untarred it results in a valid directory backup" }
};
} // end of unnamed namespace
BackupFormatModel::BackupFormatModel(QObject *parent)
: QAbstractListModel(parent)
{
}
//QVariant BackupFormatModel::headerData(int section, Qt::Orientation orientation, int role) const
//{
// QVariant result;
// if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
// switch (section) {
// case Column::Short:
// result = tr("Short");
// break;
// case Column::Long:
// result = tr("Long");
// break;
// case Column::Description:
// result = tr("Description");
// break;
// }
// }
// return result;
//}
int BackupFormatModel::rowCount(const QModelIndex &) const
{
int size = g_BackupFormats.size();
return size;
}
int BackupFormatModel::columnCount(const QModelIndex &) const
{
return 3;
}
QVariant BackupFormatModel::data(const QModelIndex &index, int role) const
{
QVariant result;
if (index.isValid()) {
const int row = index.row();
const int col = index.column();
if (role == Qt::DisplayRole) {
const auto &item = g_BackupFormats.at(row);
switch (col) {
case ColumnShort:
result = item.shortFlag;
break;
case ColumnLong:
result = item.longFlag;
break;
case ColumnDescription:
result = item.description;
break;
}
}
else if (role == Qt::ToolTipRole) {
const auto &item = g_BackupFormats.at(row);
result = item.description;
}
}
return result;
}

View file

@ -1,26 +0,0 @@
#ifndef BACKUPFORMATMODEL_H
#define BACKUPFORMATMODEL_H
#include <QAbstractListModel>
class BackupFormatModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Column { ColumnShort=1, ColumnLong=0, ColumnDescription=2 };
explicit BackupFormatModel(QObject *parent);
// Header:
// QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
};
#endif // BACKUPFORMATMODEL_H

View file

@ -1,64 +0,0 @@
#include "CsvWriter.h"
CsvWriter::CsvWriter()
{}
CsvWriter::CsvWriter(QTextStream *output)
: m_output(output)
{}
void CsvWriter::setDestination(QTextStream *output)
{
m_output = output;
m_column = 0;
}
void CsvWriter::setSeperator(QChar ch)
{
m_seperator = ch;
}
void CsvWriter::setQuote(QChar ch)
{
m_quote = ch;
}
void CsvWriter::writeField(QString field)
{
QTextStream &out = *m_output;
if (m_column > 0) {
out << m_seperator;
}
// if field contains any of seperator, quote or newline then it needs to be quoted
// when quoted quotes need to be doubled to escape them
bool needs_quotes = false;
for (auto ch : field) {
if (ch == '\n' || ch == m_seperator || ch == m_quote) {
needs_quotes = true;
break;
}
}
if (needs_quotes) {
out << m_quote;
for (auto ch : field) {
if (ch == m_quote)
out << m_quote;
out << ch;
}
out << m_quote;
}
else {
out << field;
}
++m_column;
}
void CsvWriter::nextRow()
{
QTextStream &out = *m_output;
out << '\n';
m_column = 0;
}

View file

@ -1,23 +0,0 @@
#ifndef CSVWRITER_H
#define CSVWRITER_H
#include <ostream>
#include <QTextStream>
class CsvWriter {
public:
CsvWriter();
explicit CsvWriter(QTextStream *output);
void setDestination(QTextStream *output);
void setSeperator(QChar ch);
void setQuote(QChar ch);
void writeField(QString field);
void nextRow();
private:
QChar m_seperator = ',';
QChar m_quote = '"';
QTextStream *m_output = nullptr;
int m_column = 0;
};
#endif // CSVWRITER_H

View file

@ -1,271 +0,0 @@
#ifndef EXPECTED_H
#define EXPECTED_H
#include <stdexcept>
#include <typeinfo>
#include <utility>
template <typename T>
class Expected {
union {
T m_value;
std::exception_ptr m_error;
};
bool m_valid;
Expected() {} // internal use
public:
Expected(const T& rhs)
: m_value(rhs), m_valid(true)
{}
Expected(T&& rhs)
: m_value(std::move(rhs))
, m_valid(true)
{}
Expected(const Expected& rhs)
: m_valid(rhs.valid)
{
if (m_valid) {
new (&m_value) T(rhs.m_value);
}
else {
new (&m_error) std::exception_ptr(rhs.m_error);
}
}
Expected(Expected &&rhs)
: m_valid(rhs.m_valid)
{
if (m_valid) {
new (&m_value) T(std::move(rhs.m_value));
}
else {
new (&m_error) std::exception_ptr(std::move(rhs.m_error));
}
}
~Expected()
{
if (m_valid) {
m_value.~T();
}
else {
using std::exception_ptr;
m_error.~exception_ptr();
}
}
// void swap(Expected& rhs)
// {
// if (m_valid) {
// if (rhs.m_valid) {
// using std::swap;
// swap(m_value, rhs.m_value);
// }
// else {
// auto t = std::move(rhs.m_error);
// new(&rhs.m_value) T(std::move(m_value));
// new(&m_error) std::exception_ptr(t);
// std::swap(m_valid, rhs.m_valid);
// }
// }
// else {
// if (rhs.m_valid) {
// rhs.swap(*this);
// }
// else {
// using std::swap;
// swap(m_error, rhs.m_error);
// std::swap(m_valid, rhs.m_valid);
// }
// }
// }
template <class E>
static Expected<T> fromException(const E& exception)
{
if (typeid(exception) != typeid(E)) {
throw std::invalid_argument("slicing detected");
}
return fromException(std::make_exception_ptr(exception));
}
static Expected<T> fromException(std::exception_ptr p)
{
Expected<T> result;
result.m_valid = false;
new (&result.m_error) std::exception_ptr(std::move(p));
return result;
}
static Expected<T> fromException()
{
return fromException(std::current_exception());
}
bool valid() const
{
return m_valid;
}
T& get()
{
if (!m_valid) {
std::rethrow_exception(m_error);
}
return m_value;
}
const T& get() const
{
if (!m_valid) {
std::rethrow_exception(m_error);
}
return m_value;
}
template <class E>
bool hasException() const
{
try {
if (!m_valid) {
std::rethrow_exception(m_error);
}
}
catch (const E& ) {
return true;
}
catch (...) {
}
return false;
}
template <class F>
static Expected fromCode(F fun)
{
try {
return Expected(fun());
}
catch (...) {
return fromException();
}
}
};
template <>
class Expected<void> {
std::exception_ptr m_error;
bool m_valid;
public:
Expected<void>()
: m_valid(true)
{}
Expected(const Expected& rhs)
: m_error(rhs.m_error)
, m_valid(rhs.m_valid)
{}
Expected(Expected<void> &&rhs)
: m_error(std::move(rhs.m_error))
, m_valid(rhs.m_valid)
{}
~Expected()
{}
// void swap(Expected& rhs)
// {
// if (m_valid) {
// if (!rhs.m_valid) {
// m_error = rhs.m_error;
// std::swap(m_valid, rhs.m_valid);
// }
// }
// else {
// if (rhs.m_valid) {
// rhs.swap(*this);
// }
// else {
// using std::swap;
// swap(m_error, rhs.m_error);
// std::swap(m_valid, rhs.m_valid);
// }
// }
// }
template <class E>
static Expected<void> fromException(const E& exception)
{
if (typeid(exception) != typeid(E)) {
throw std::invalid_argument("slicing detected");
}
return fromException(std::make_exception_ptr(exception));
}
static Expected<void> fromException(std::exception_ptr p)
{
Expected<void> result;
result.m_valid = false;
result.m_error = std::exception_ptr(std::move(p));
return result;
}
static Expected<void> fromException()
{
return fromException(std::current_exception());
}
bool valid() const
{
return m_valid;
}
void get() const
{
if (!m_valid) {
std::rethrow_exception(m_error);
}
}
template <class E>
bool hasException() const
{
try {
if (!m_valid) {
std::rethrow_exception(m_error);
}
}
catch (const E& ) {
return true;
}
catch (...) {
}
return false;
}
template <class F>
static Expected fromCode(F fun)
{
try {
fun();
return Expected<void>();
}
catch (...) {
return fromException();
}
}
};
#endif // EXPECTED_H

View file

@ -1,243 +0,0 @@
#include "PasswordManager.h"
#include <botan/filters.h>
#include <botan/pipe.h>
#include <botan/sha2_64.h>
#include <botan/hash.h>
#include <botan/hmac.h>
#include <botan/pbkdf2.h>
#include <botan/rng.h>
#include <botan/base64.h>
#include <botan/loadstor.h>
#include <botan/mem_ops.h>
#include <boost/assert.hpp>
using namespace Botan;
namespace {
/*
First 24 bits of SHA-256("Botan Cryptobox"), followed by 8 0 bits
for later use as flags, etc if needed
*/
const uint8_t c_PasswordVersionCode = 0x10;
const size_t c_VersionCodeLen = 1;
const size_t CIPHER_KEY_LEN = 32;
const size_t CIPHER_IV_LEN = 16;
const size_t MAC_KEY_LEN = 32;
const size_t MAC_OUTPUT_LEN = 20;
const size_t PBKDF_SALT_LEN = 10;
const size_t PBKDF_ITERATIONS = 8 * 1024;
const size_t PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + CIPHER_IV_LEN + MAC_KEY_LEN;
const char * const c_Cipher = "Serpent/CTR-BE";
const char * const c_IniGroupSecurity = "Security";
StrengthenedKey generateKey(const std::string &passphrase, const uint8_t *salt, int saltlength)
{
PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));
OctetString master_key = pbkdf.derive_key(
PBKDF_OUTPUT_LEN,
passphrase,
salt, saltlength,
PBKDF_ITERATIONS);
const uint8_t* mk = master_key.begin();
return StrengthenedKey(
SymmetricKey(mk, CIPHER_KEY_LEN),
SymmetricKey(mk + CIPHER_KEY_LEN, MAC_KEY_LEN),
InitializationVector(mk + CIPHER_KEY_LEN + MAC_KEY_LEN, CIPHER_IV_LEN));
}
// secure_vector<uint8_t> pbkdf_salt(PBKDF_SALT_LEN);
// rng.randomize( pbkdf_salt.data(), pbkdf_salt.size());
// StrengthenedKey strengthened_key = generateKey(passphrase, pbkdf_salt.data(), pbkdf_salt.size());
std::string encrypt(const std::string &input,
const StrengthenedKey &strengthened_key)
{
Pipe pipe(get_cipher(c_Cipher, strengthened_key.cipher_key,
strengthened_key.iv, ENCRYPTION),
new Fork(
nullptr,
new MAC_Filter(new HMAC(new SHA_512),
strengthened_key.mac_key, MAC_OUTPUT_LEN)));
pipe.process_msg((const uint8_t*)input.data(), input.length());
/*
Output format is:
mac (20 bytes)
ciphertext
*/
const size_t ciphertext_len = pipe.remaining(0);
std::vector<uint8_t> out_buf(MAC_OUTPUT_LEN + ciphertext_len);
BOTAN_ASSERT_EQUAL(
pipe.read(&out_buf[0], MAC_OUTPUT_LEN, 1),
MAC_OUTPUT_LEN, "MAC output");
BOTAN_ASSERT_EQUAL(
pipe.read(&out_buf[MAC_OUTPUT_LEN], ciphertext_len, 0),
ciphertext_len, "Ciphertext size");
return base64_encode(out_buf.data(), out_buf.size());
}
std::string decrypt(const std::string &input, const StrengthenedKey &strengthened_key)
{
secure_vector<uint8_t> ciphertext = base64_decode(input);
if(ciphertext.size() < (MAC_OUTPUT_LEN)) {
throw Decoding_Error("Invalid encrypted password input");
}
Pipe pipe(new Fork(
get_cipher(c_Cipher, strengthened_key.cipher_key, strengthened_key.iv, DECRYPTION),
new MAC_Filter(new HMAC(new SHA_512), strengthened_key.mac_key, MAC_OUTPUT_LEN)
));
const size_t ciphertext_offset = MAC_OUTPUT_LEN;
pipe.process_msg(&ciphertext[ciphertext_offset], ciphertext.size() - ciphertext_offset);
uint8_t computed_mac[MAC_OUTPUT_LEN];
BOTAN_ASSERT_EQUAL(MAC_OUTPUT_LEN, pipe.read(computed_mac, MAC_OUTPUT_LEN, 1), "MAC size");
if(!same_mem(computed_mac, &ciphertext[0], MAC_OUTPUT_LEN)) {
throw Decoding_Error("Encrypted password integrity failure");
}
return pipe.read_all_as_string(0);
}
struct constants {
const int pbkdf_salt_len;
};
constants v1_consts = {
10
};
} // end of unnamed namespace
/*
* File layout:
*
* Header
* version
* key_salt
* hash_salt
* master_hash
*
*
* Passwords
* key = pw
*/
PasswordManager::PasswordManager()
{
}
Expected<bool> PasswordManager::unlock(const std::string &master_password)
{
try {
bool result = false;
if (m_masterHash.length() == 0 && master_password.empty()) {
result = true;
} else {
StrengthenedKey key = generateKey(master_password, m_keySalt.begin(), m_keySalt.length());
OctetString hash = hashStrengthenedKey(key, m_hashSalt);
BOOST_ASSERT_MSG(hash.length() == m_masterHash.length(), "Both hashes should have the same length! Versioning error?");
if (same_mem(m_masterHash.begin(), hash.begin(), hash.length())) {
result = true;
m_masterKey = key;
}
}
return result;
} catch (...) {
return Expected<bool>::fromException();
}
}
Expected<bool> PasswordManager::changeMasterPassword(const std::string &old_master_password,
const std::string &new_master_password)
{
try {
bool result = false;
if (m_masterHash.length() == 0 && old_master_password.empty()) {
// Nothing set yet so we initialize for first use
m_keySalt = OctetString(m_rng, v1_consts.pbkdf_salt_len);
m_masterKey = generateKey(new_master_password, m_keySalt.begin(), m_keySalt.length());
m_hashSalt = OctetString(m_rng, v1_consts.pbkdf_salt_len);
m_masterHash = hashStrengthenedKey(m_masterKey, m_hashSalt);
result = true;
}
return result;
} catch (...) {
return Expected<bool>::fromException();
}
}
void PasswordManager::lock()
{
m_masterKey = StrengthenedKey();
}
bool PasswordManager::locked() const
{
return m_masterKey.cipher_key.size() == 0;
}
Expected<void> PasswordManager::savePassword(const std::string &key, const std::string &password)
{
if (locked()) {
return Expected<void>::fromException(std::logic_error("Need to unlock the password manager first"));
}
std::string epw = encrypt(password, m_masterKey);
m_store.emplace(key, epw);
return Expected<void>();
}
Expected<bool> PasswordManager::getPassword(const std::string &key, std::string &out)
{
if (locked()) {
return Expected<bool>::fromException(std::logic_error("Need to unlock the password manager first"));
}
auto fi = m_store.find(key);
bool result = false;
if (fi != m_store.end()) {
out = decrypt(fi->second, m_masterKey);
result = true;
}
return result;
}
Botan::OctetString PasswordManager::hashStrengthenedKey(const StrengthenedKey &key, const OctetString &salt)
{
std::unique_ptr<Botan::HashFunction> hash3(Botan::HashFunction::create("SHA-3"));
BOOST_ASSERT_MSG(hash3 != nullptr, "SHA-3 algorithm not available");
hash3->update(salt.begin(), salt.length());
hash3->update(key.cipher_key.begin(), key.cipher_key.length());
hash3->update(key.mac_key.begin(), key.mac_key.length());
hash3->update(key.iv.begin(), key.iv.length());
return hash3->final();
}

View file

@ -1,66 +0,0 @@
#ifndef PASSWORDMANAGER_H
#define PASSWORDMANAGER_H
#include "Expected.h"
#include <string>
#include <botan/botan.h>
#include <botan/symkey.h>
#include <map>
struct StrengthenedKey {
Botan::SymmetricKey cipher_key;
Botan::SymmetricKey mac_key;
Botan::InitializationVector iv;
StrengthenedKey() {}
StrengthenedKey(const Botan::SymmetricKey &ck, const Botan::SymmetricKey &mk,
const Botan::InitializationVector &i)
: cipher_key(ck)
, mac_key(mk)
, iv(i)
{}
};
class PasswordManager {
public:
// static PasswordManager create(const std::string &file_name);
PasswordManager();
/** Unlocks the passwords of the connections.
*
* \return Normally it return a bool specifying if the password was accepted.
* on rare occasions it could return an error.
*/
Expected<bool> unlock(const std::string &master_password);
Expected<bool> changeMasterPassword(const std::string &master_password,
const std::string &new_master_password);
/** Forget master password
*/
void lock();
bool locked() const;
Expected<void> savePassword(const std::string &key, const std::string &password);
Expected<bool> getPassword(const std::string &key, std::string &out);
private:
Botan::AutoSeeded_RNG m_rng;
Botan::OctetString m_keySalt; // salt for generating crypto key
StrengthenedKey m_masterKey; // crypto key
Botan::OctetString m_hashSalt; // salt of the hash of the passphrase
Botan::OctetString m_masterHash; // hash for checking the passphrase
using t_KeyPasswords = std::map<std::string, std::string>;
t_KeyPasswords m_store;
static Botan::OctetString hashStrengthenedKey(const StrengthenedKey &key, const Botan::OctetString &salt);
};
#endif // PASSWORDMANAGER_H

View file

@ -1,69 +0,0 @@
#ifndef SCOPEGUARD_H
#define SCOPEGUARD_H
/** \brief Template class for executing code at scope exit.
*
* By default the object will be an active mode and execute the function
* passed to the constructor when the object is destructed. You can however
* cancel this action by calling dismiss().
*
* There is a clever macro that allows you to write something like
* SCOPE_EXIT { foo(); };
*/
template<class Fun>
class ScopeGuard {
Fun f_;
bool active_;
public:
ScopeGuard(Fun f)
: f_(std::move(f))
, active_(true) {
}
~ScopeGuard() { if(active_) f_(); }
void dismiss() { active_=false; }
ScopeGuard() = delete;
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(const ScopeGuard&) = delete;
ScopeGuard(ScopeGuard&& rhs)
: f_(std::move(rhs.f_))
, active_(rhs.active_)
{
rhs.dismiss();
}
};
template<class Fun>
ScopeGuard<Fun> scopeGuard(Fun f)
{
return ScopeGuard<Fun>(std::move(f));
}
namespace ScopeGuard_detail {
enum class ScopeGuardOnExit {};
template<typename Fun>
ScopeGuard<Fun> operator+(ScopeGuardOnExit, Fun&& fn) {
return ScopeGuard<Fun>(std::forward<Fun>(fn));
}
}
#define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
#ifdef __COUNTER__
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str,__COUNTER__)
#else
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str,__LINE__)
#endif
#define SCOPE_EXIT \
auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
= ::ScopeGuard_detail::ScopeGuardOnExit() + [&]()
#endif // SCOPEGUARD_H

View file

@ -1,162 +0,0 @@
#include "SqlLexer.h"
SqlLexer::SqlLexer(const QString &block, LexerState currentstate)
: m_block(block)
, m_state(currentstate)
{}
QChar SqlLexer::nextChar()
{
QChar result = QChar::Null;
if (m_pos < m_block.size()) {
result = m_block.at(m_pos++);
}
return result;
}
QChar SqlLexer::peekChar()
{
QChar result = QChar::Null;
if (m_pos < m_block.size()) {
result = m_block.at(m_pos);
}
return result;
}
/**
* @brief NextBasicToken
* @param in
* @param ofs
* @param start
* @param length
* @return false when input seems invalid, it will return what it did recognize but something wasn't right, parser should try to recover
*/
bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokentype, QString &out)
{
// Basically chops based on white space
// it does also recognize comments and quoted strings/identifiers
while (true) {
startpos = m_pos;
QChar c = nextChar();
// if (LexerState::Null == m_state) {
if (c.isSpace()) {
// Just skip whitespace
}
else if (c == '-' && peekChar() == '-') { // two dashes, start of comment
// Loop till end of line or end of block
c = nextChar();
for (;;) {
c = peekChar();
if (c != QChar::Null && c != '\n')
nextChar();
else
break;
}
length = m_pos - startpos;
tokentype = BasicTokenType::Comment;
return true;
}
else if (c == '\'') {
// Single quoted string so it's an SQL text literal
while (true) {
c = peekChar();
if (c == QChar::Null || c == '\n') {
// unexpected end, pretend nothings wrong
length = m_pos - startpos;
tokentype = BasicTokenType::QuotedString;
return true;
}
else {
nextChar();
if (c == '\'') {
// maybe end of string literal
if (peekChar() == '\'') {
// Nope, just double quote to escape quote
nextChar(); // eat it
}
else {
length = m_pos - startpos;
tokentype = BasicTokenType::QuotedString;
return true;
}
}
}
}
}
else if (c == '"') {
// Double quoted identifier
while (true) {
c = peekChar();
if (c == QChar::Null || c == '\n') {
// unexpected end, pretend nothings wrong
length = m_pos - startpos;
tokentype = BasicTokenType::QuotedIdentifier;
return true;
}
else {
nextChar();
if (c == '"') {
// maybe end of string literal
if (peekChar() == '"') {
// Nope, just double quote to escape quote
nextChar(); // eat it
}
else {
length = m_pos - startpos;
tokentype = BasicTokenType::QuotedIdentifier;
return true;
}
}
}
}
}
// else if (c == '/' && peekChar() == '*') {
// nextChar();
// m_state = LexerState::InBlockComment;
// }
else if (c == QChar::Null) {
break;
}
else {
// Undetermined symbol
for (;;) {
c = peekChar();
if (c.isLetterOrNumber() || c == '_')
nextChar();
else
break;
}
length = m_pos - startpos;
tokentype = BasicTokenType::Symbol;
QStringRef sr(&m_block, startpos, length);
out = sr.toString();
return true;
}
// }
// else if (LexerState::InBlockComment == m_state) {
// if (c == QChar::Null) {
// // eof current buffer, we need to return state so
// if (m_pos == startpos) {
// break;
// }
// else {
// length = m_pos - startpos;
// tokentype = BasicTokenType::OpenBlockComment;
// return true;
// }
// }
// else if (c == '*') {
// nextChar();
// if (peekChar() == '/') {
// nextChar();
// length = m_pos - startpos;
// tokentype = BasicTokenType::BlockComment;
// m_state = LexerState::Null;
// return true;
// }
// }
// }
}
return false;
}

View file

@ -1,49 +0,0 @@
#ifndef SQLLEXER_H
#define SQLLEXER_H
#include <QString>
enum class BasicTokenType {
None,
End, // End of input
Symbol, // can be many things, keyword, object name, operator, ..
Comment,
BlockComment,
OpenBlockComment, // Busy with a block comment end not detected before end of current input
QuotedString,
DollarQuotedString,
QuotedIdentifier
};
enum class LexerState {
Null,
InDollarQuotedString,
InBlockComment
};
class SqlLexer {
public:
SqlLexer(const QString &block, LexerState currentstate);
QChar nextChar();
QChar peekChar();
/**
* @brief NextBasicToken
* @param in
* @param ofs
* @param start
* @param length
* @return false when input seems invalid, it will return what it did recognize but something wasn't right, parser should try to recover
*/
bool nextBasicToken(int &startpos, int &length, BasicTokenType &tokentype, QString &out);
LexerState currentState() const { return m_state; }
private:
QString m_block;
int m_pos = 0;
LexerState m_state;
};
#endif // SQLLEXER_H

View file

@ -1,20 +0,0 @@
#include <sstream>
#include <stdexcept>
namespace boost
{
void assertion_failed(char const * expr, char const * function, char const * file, long line)
{
std::ostringstream out;
out << "Assertion failure int " << function << " " << file << ":" << line;
throw std::runtime_error(out.str());
}
void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line)
{
std::ostringstream out;
out << "Assertion failure int " << function << " " << file << ":" << line << "\n"<< msg;
throw std::runtime_error(out.str());
}
}