<commit_before>/** \file
 *
 *  Copyright (c) 2012-2014 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#include "char_convert.hpp"

#include "detail/fixed_map.hpp"

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <map>
#include <ostream>
#include <stdexcept>

namespace jsonv
{
namespace detail
{

decode_error::decode_error(size_type offset, const std::string& message):
        runtime_error(message),
        _offset(offset)
{ }

decode_error::~decode_error() throw()
{ }

#define ESCAPES_LIST(item) \
    item('\b', 'b')  \
    item('\f', 'f')  \
    item('\n', 'n')  \
    item('\r', 'r')  \
    item('\t', 't')  \
    item('\\', '\\') \
    item('/',  '/')  \
    item('\"', '\"') \

#define TUPLE_PLUS_1_GEN(a, b) +1
typedef detail::fixed_map<char, char, ESCAPES_LIST(TUPLE_PLUS_1_GEN)> converter_map;

/** These entries are sorted by the numeric value of the ASCII character (\c less_entry_cpp).
 *
 *  \note
 *  The encode and decode map must be in a different order (even though they contain the same data) because the ASCII
 *  representations of escape sequences are not in the same order as the characters they are escaping.
**/
#define TUPLE_FIRST_SECOND(a, b) { a, b },
const converter_map encode_map = { ESCAPES_LIST(TUPLE_FIRST_SECOND) };

/** These entries are sorted by the character value of the escape sequence (\c less_entry_json).
**/
#define TUPLE_SECOND_FIRST(a, b) { b, a },
const converter_map decode_map = { ESCAPES_LIST(TUPLE_SECOND_FIRST) };

const char* find(const converter_map& source, char key)
{
    converter_map::const_iterator iter = source.find(key);
    if (iter != source.end())
        return &iter->second;
    else
        return NULL;
}

static const char* find_encoding(char native_character)
{
    return find(encode_map, native_character);
}

static const char* find_decoding(char char_after_backslash)
{
    return find(decode_map, char_after_backslash);
}

static bool needs_unicode_escaping(char c)
{
    return !isprint(c)
        || (c & '\x80');
}

static bool char_bitmatch(char c, char pos, char neg)
{
    return (c & pos) == pos
        && !(c & neg);
}

static void utf8_extract_info(char c, unsigned& length, char& bitmask)
{
    if (!(c & '\x80'))
    {
        length = 1;
        bitmask = '\x7f';
    }
    else if (char_bitmatch(c, '\xc0', '\x20'))
    {
        length = 2;
        bitmask = '\x1f';
    }
    else if (char_bitmatch(c, '\xe0', '\x10'))
    {
        length = 3;
        bitmask = '\x0f';
    }
    else if (char_bitmatch(c, '\xf0', '\x08'))
    {
        length = 4;
        bitmask = '\x07';
    }
    else if (char_bitmatch(c, '\xf8', '\x04'))
    {
        length = 5;
        bitmask = '\x03';
    }
    else if (char_bitmatch(c, '\xfc', '\x02'))
    {
        length = 6;
        bitmask = '\x01';
    }
    else
    {
        // This is not an acceptable/valid UTF8 string.  A failure here means I can't trust or don't understand the
        // encoding on the platform.
        assert(false);
        // In release mode, we'll spit out *potentially* garbage JSON.
        length = 1;
        bitmask = '\x7f';
    }
}

/** All these code extraction algorithms are probably wrong...the UTF8 encoding standard allows for 6-byte sequences,
 *  which allows for all 2^31 UCS codes. However, Unicode ends at 0x10ffff with the PUA-B plane (which people shouldn't
 *  be sending around in JSON in the first place). JSON's escape sequence for unicode is 4 hexidecimal digits, which is
 *  only a \c uint16_t. This means that JSON is only capable of encoding the basic multilingual plane, which means no
 *  alchemical symbols ಠಠ.
**/
static uint16_t utf8_extract_code(const char* c, unsigned length, char bitmask)
{
    const char submask = '\x3f';

    assert(length <= 4);
    uint16_t num(*c & bitmask);
    ++c;

    for (unsigned i = 1; i < length; ++i, ++c)
    {
        assert(char_bitmatch(*c, '\x80', '\x40'));
        num = uint16_t(num << 6);
        num = uint16_t(num | (*c & submask));
    }

    return num;
}

static const char hex_codes[] = "0123456789abcdef";

static void to_hex(std::ostream& stream, uint16_t code)
{
    for (int pos = 3; pos >= 0; --pos)
    {
        uint16_t local_code = (code >> (4 * pos)) & uint16_t(0x000f);
        stream << hex_codes[local_code];
    }
}

std::ostream& string_encode(std::ostream& stream, const std::string& source)
{
    typedef std::string::size_type size_type;

    for (size_type idx = 0, source_size = source.size(); idx < source_size; /* incremented inline */)
    {
        const char& current = source[idx];
        if (const char* replacement = find_encoding(current))
        {
            stream << "\\" << *replacement;
            ++idx;
        }
        else
        {
            unsigned length;
            char bitmask;
            utf8_extract_info(current, length, bitmask);
            assert(idx + length <= source_size);

            if (!needs_unicode_escaping(current))
                stream << current;
            else
            {
                uint16_t code = utf8_extract_code(&current, length, bitmask);
                stream << "\\u";
                to_hex(stream, code);
            }

            idx += length;
        }
    }

    return stream;
}

static uint16_t from_hex_digit(char c)
{
    switch (c)
    {
    case '0':
        return 0;
    case '1':
        return 1;
    case '2':
        return 2;
    case '3':
        return 3;
    case '4':
        return 4;
    case '5':
        return 5;
    case '6':
        return 6;
    case '7':
        return 7;
    case '8':
        return 8;
    case '9':
        return 9;
    // The JSON spec isn't clear if it wants capitals or lowercase, so I'll just assume both are okay
    case 'a':
    case 'A':
        return 0xa;
    case 'b':
    case 'B':
        return 0xb;
    case 'c':
    case 'C':
        return 0xc;
    case 'd':
    case 'D':
        return 0xd;
    case 'e':
    case 'E':
        return 0xe;
    case 'f':
    case 'F':
        return 0xf;
    default:
        throw std::range_error(std::string("The character '") + c + "' is not a valid hexidecimal digit.");
    }
}

static uint16_t from_hex(const char* s)
{
    uint16_t x = 0U;
    for (int idx = 3; idx >= 0; --idx)
    {
        x = uint16_t(x + (from_hex_digit(*s) << (idx * 4)));
        ++s;
    }

    return x;
}

static void utf8_sequence_info(char32_t val, std::size_t* length, char* first)
{
    if (val < 0x00000080U)
    {
        *length = 1;
        *first = char(val);
    }
    else if (val < 0x00000800U)
    {
        *length = 2;
        *first = char('\xc0' | ('\x1f' & (val >> 6)));
    }
    else if (val < 0x00010000U)
    {
        *length = 3;
        *first = char('\xe0' | ('\x0f' & (val >> 12)));
    }
    else if (val < 0x00200000U)
    {
        *length = 4;
        *first = char('\xf0' | ('\x07' & (val >> 18)));
    }
    else if (val < 0x04000000U)
    {
        *length = 5;
        *first = char('\xf8' | ('\x03' & (val >> 24)));
    }
    else
    {
        *length = 6;
        *first = char('\xfc' | char('\x01' & (val >> 30)));
    }
}

static void utf8_append_code(std::string& str, char32_t val)
{
    char c;
    std::size_t length;
    utf8_sequence_info(val, &length, &c);

    char buffer[8];
    char* bufferOut = buffer;
    *bufferOut++ = c;

    int shift = (length - 2) * 6;
    for (std::size_t idx = 1; idx < length; ++idx)
    {
        c = char('\x80' | ('\x3f' & (val >> shift)));
        *bufferOut++ = c;
        shift -= 6;
    }

    str.append(buffer, bufferOut);
}

static bool utf16_combine_surrogates(uint16_t high, uint16_t low, char32_t* out)
{
    if ((high & 0xfc00U) != 0xd800 || (low & 0xfc00U) != 0xdc00)
    {
        // invalid surrogate pair
        return false;
    }
    else
    {
        // surrogate pairs take the form:
        // | high               | low                |
        //  1101 10aa aaaa aaaa  1101 11bb bbbb bbbb
        // result:
        //   0000 0000 0000 aaaa  aaaa aabb bbbb bbbb
        // + 0000 0000 0000 0001  0000 0000 0000 0000
        *out = 0x10000
             + (((char32_t(high) & 0x03ff) << 10) | (char32_t(low)  & 0x03ff));
        return true;
    }
}

std::string string_decode(const char* source, std::string::size_type source_size)
{
    typedef std::string::size_type size_type;

    std::string output;
    const char* last_pushed_src = source;

    for (size_type idx = 0; idx < source_size; /* incremented inline */)
    {
        const char& current = source[idx];
        if (current == '\\')
        {
            output.append(last_pushed_src, source+idx);

            const char& next = source[idx + 1];
            if (const char* replacement = find_decoding(next))
            {
                output += *replacement;
                idx += 2;
            }
            else if (next == 'u')
            {
                if (idx + 6 > source_size)
                    throw decode_error(idx, "unterminated Unicode escape sequence (must have 4 hex characters)");
                uint16_t hexval = from_hex(&source[idx + 2]);

                if (hexval < 0xd800U || hexval > 0xdfffU)
                {
                    utf8_append_code(output, hexval);

                    idx += 6;
                }
                // numeric encoding is in U+d800 - U+dfff, so deal with surrogate pairing...
                else
                {
                    auto surrogateString = [&] () { return std::string(source+idx, 6); };
                    if (  idx + 12 > source_size
                       || idx +  8 > source_size
                       || source[idx + 6] != '\\'
                       || source[idx + 7] != 'u'
                       )
                        throw decode_error(idx, std::string("unpaired high surrogate (") + surrogateString() + ")");
                    uint16_t hexlowval = from_hex(&source[idx + 8]);
                    char32_t codepoint;
                    if (!utf16_combine_surrogates(hexval, hexlowval, &codepoint))
                        throw decode_error(idx, std::string("unpaired high surrogate (") + surrogateString() + ")");

                    utf8_append_code(output, codepoint);

                    idx += 12;
                }
            }
            else
            {
                throw decode_error(idx, std::string("Unknown escape character: ") + next);
                //output += '?'; Maybe better solution if we don't want to throw
                //++idx;
            }

            last_pushed_src = source + idx;
        }
        else
        {
            ++idx;
        }
    }

    output.append(last_pushed_src, source+source_size);
    return output;
}

}
}
<commit_msg>Makes char_bitmatch a constexpr.<commit_after>/** \file
 *
 *  Copyright (c) 2012-2014 by Travis Gockel. All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
 *  as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  \author Travis Gockel (travis@gockelhut.com)
**/
#include "char_convert.hpp"

#include "detail/fixed_map.hpp"

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <map>
#include <ostream>
#include <stdexcept>

namespace jsonv
{
namespace detail
{

decode_error::decode_error(size_type offset, const std::string& message):
        runtime_error(message),
        _offset(offset)
{ }

decode_error::~decode_error() throw()
{ }

#define ESCAPES_LIST(item) \
    item('\b', 'b')  \
    item('\f', 'f')  \
    item('\n', 'n')  \
    item('\r', 'r')  \
    item('\t', 't')  \
    item('\\', '\\') \
    item('/',  '/')  \
    item('\"', '\"') \

#define TUPLE_PLUS_1_GEN(a, b) +1
typedef detail::fixed_map<char, char, ESCAPES_LIST(TUPLE_PLUS_1_GEN)> converter_map;

/** These entries are sorted by the numeric value of the ASCII character (\c less_entry_cpp).
 *
 *  \note
 *  The encode and decode map must be in a different order (even though they contain the same data) because the ASCII
 *  representations of escape sequences are not in the same order as the characters they are escaping.
**/
#define TUPLE_FIRST_SECOND(a, b) { a, b },
const converter_map encode_map = { ESCAPES_LIST(TUPLE_FIRST_SECOND) };

/** These entries are sorted by the character value of the escape sequence (\c less_entry_json).
**/
#define TUPLE_SECOND_FIRST(a, b) { b, a },
const converter_map decode_map = { ESCAPES_LIST(TUPLE_SECOND_FIRST) };

const char* find(const converter_map& source, char key)
{
    converter_map::const_iterator iter = source.find(key);
    if (iter != source.end())
        return &iter->second;
    else
        return NULL;
}

static const char* find_encoding(char native_character)
{
    return find(encode_map, native_character);
}

static const char* find_decoding(char char_after_backslash)
{
    return find(decode_map, char_after_backslash);
}

static bool needs_unicode_escaping(char c)
{
    return !isprint(c)
        || (c & '\x80');
}

static constexpr bool char_bitmatch(char c, char pos, char neg)
{
    return (c & pos) == pos
        && !(c & neg);
}

static void utf8_extract_info(char c, unsigned& length, char& bitmask)
{
    if (!(c & '\x80'))
    {
        length = 1;
        bitmask = '\x7f';
    }
    else if (char_bitmatch(c, '\xc0', '\x20'))
    {
        length = 2;
        bitmask = '\x1f';
    }
    else if (char_bitmatch(c, '\xe0', '\x10'))
    {
        length = 3;
        bitmask = '\x0f';
    }
    else if (char_bitmatch(c, '\xf0', '\x08'))
    {
        length = 4;
        bitmask = '\x07';
    }
    else if (char_bitmatch(c, '\xf8', '\x04'))
    {
        length = 5;
        bitmask = '\x03';
    }
    else if (char_bitmatch(c, '\xfc', '\x02'))
    {
        length = 6;
        bitmask = '\x01';
    }
    else
    {
        // This is not an acceptable/valid UTF8 string.  A failure here means I can't trust or don't understand the
        // encoding on the platform.
        assert(false);
        // In release mode, we'll spit out *potentially* garbage JSON.
        length = 1;
        bitmask = '\x7f';
    }
}

/** All these code extraction algorithms are probably wrong...the UTF8 encoding standard allows for 6-byte sequences,
 *  which allows for all 2^31 UCS codes. However, Unicode ends at 0x10ffff with the PUA-B plane (which people shouldn't
 *  be sending around in JSON in the first place). JSON's escape sequence for unicode is 4 hexidecimal digits, which is
 *  only a \c uint16_t. This means that JSON is only capable of encoding the basic multilingual plane, which means no
 *  alchemical symbols ಠಠ.
**/
static uint16_t utf8_extract_code(const char* c, unsigned length, char bitmask)
{
    const char submask = '\x3f';

    assert(length <= 4);
    uint16_t num(*c & bitmask);
    ++c;

    for (unsigned i = 1; i < length; ++i, ++c)
    {
        assert(char_bitmatch(*c, '\x80', '\x40'));
        num = uint16_t(num << 6);
        num = uint16_t(num | (*c & submask));
    }

    return num;
}

static const char hex_codes[] = "0123456789abcdef";

static void to_hex(std::ostream& stream, uint16_t code)
{
    for (int pos = 3; pos >= 0; --pos)
    {
        uint16_t local_code = (code >> (4 * pos)) & uint16_t(0x000f);
        stream << hex_codes[local_code];
    }
}

std::ostream& string_encode(std::ostream& stream, const std::string& source)
{
    typedef std::string::size_type size_type;

    for (size_type idx = 0, source_size = source.size(); idx < source_size; /* incremented inline */)
    {
        const char& current = source[idx];
        if (const char* replacement = find_encoding(current))
        {
            stream << "\\" << *replacement;
            ++idx;
        }
        else
        {
            unsigned length;
            char bitmask;
            utf8_extract_info(current, length, bitmask);
            assert(idx + length <= source_size);

            if (!needs_unicode_escaping(current))
                stream << current;
            else
            {
                uint16_t code = utf8_extract_code(&current, length, bitmask);
                stream << "\\u";
                to_hex(stream, code);
            }

            idx += length;
        }
    }

    return stream;
}

static uint16_t from_hex_digit(char c)
{
    switch (c)
    {
    case '0':
        return 0;
    case '1':
        return 1;
    case '2':
        return 2;
    case '3':
        return 3;
    case '4':
        return 4;
    case '5':
        return 5;
    case '6':
        return 6;
    case '7':
        return 7;
    case '8':
        return 8;
    case '9':
        return 9;
    // The JSON spec isn't clear if it wants capitals or lowercase, so I'll just assume both are okay
    case 'a':
    case 'A':
        return 0xa;
    case 'b':
    case 'B':
        return 0xb;
    case 'c':
    case 'C':
        return 0xc;
    case 'd':
    case 'D':
        return 0xd;
    case 'e':
    case 'E':
        return 0xe;
    case 'f':
    case 'F':
        return 0xf;
    default:
        throw std::range_error(std::string("The character '") + c + "' is not a valid hexidecimal digit.");
    }
}

static uint16_t from_hex(const char* s)
{
    uint16_t x = 0U;
    for (int idx = 3; idx >= 0; --idx)
    {
        x = uint16_t(x + (from_hex_digit(*s) << (idx * 4)));
        ++s;
    }

    return x;
}

static void utf8_sequence_info(char32_t val, std::size_t* length, char* first)
{
    if (val < 0x00000080U)
    {
        *length = 1;
        *first = char(val);
    }
    else if (val < 0x00000800U)
    {
        *length = 2;
        *first = char('\xc0' | ('\x1f' & (val >> 6)));
    }
    else if (val < 0x00010000U)
    {
        *length = 3;
        *first = char('\xe0' | ('\x0f' & (val >> 12)));
    }
    else if (val < 0x00200000U)
    {
        *length = 4;
        *first = char('\xf0' | ('\x07' & (val >> 18)));
    }
    else if (val < 0x04000000U)
    {
        *length = 5;
        *first = char('\xf8' | ('\x03' & (val >> 24)));
    }
    else
    {
        *length = 6;
        *first = char('\xfc' | char('\x01' & (val >> 30)));
    }
}

static void utf8_append_code(std::string& str, char32_t val)
{
    char c;
    std::size_t length;
    utf8_sequence_info(val, &length, &c);

    char buffer[8];
    char* bufferOut = buffer;
    *bufferOut++ = c;

    int shift = (length - 2) * 6;
    for (std::size_t idx = 1; idx < length; ++idx)
    {
        c = char('\x80' | ('\x3f' & (val >> shift)));
        *bufferOut++ = c;
        shift -= 6;
    }

    str.append(buffer, bufferOut);
}

static bool utf16_combine_surrogates(uint16_t high, uint16_t low, char32_t* out)
{
    if ((high & 0xfc00U) != 0xd800 || (low & 0xfc00U) != 0xdc00)
    {
        // invalid surrogate pair
        return false;
    }
    else
    {
        // surrogate pairs take the form:
        // | high               | low                |
        //  1101 10aa aaaa aaaa  1101 11bb bbbb bbbb
        // result:
        //   0000 0000 0000 aaaa  aaaa aabb bbbb bbbb
        // + 0000 0000 0000 0001  0000 0000 0000 0000
        *out = 0x10000
             + (((char32_t(high) & 0x03ff) << 10) | (char32_t(low)  & 0x03ff));
        return true;
    }
}

std::string string_decode(const char* source, std::string::size_type source_size)
{
    typedef std::string::size_type size_type;

    std::string output;
    const char* last_pushed_src = source;

    for (size_type idx = 0; idx < source_size; /* incremented inline */)
    {
        const char& current = source[idx];
        if (current == '\\')
        {
            output.append(last_pushed_src, source+idx);

            const char& next = source[idx + 1];
            if (const char* replacement = find_decoding(next))
            {
                output += *replacement;
                idx += 2;
            }
            else if (next == 'u')
            {
                if (idx + 6 > source_size)
                    throw decode_error(idx, "unterminated Unicode escape sequence (must have 4 hex characters)");
                uint16_t hexval = from_hex(&source[idx + 2]);

                if (hexval < 0xd800U || hexval > 0xdfffU)
                {
                    utf8_append_code(output, hexval);

                    idx += 6;
                }
                // numeric encoding is in U+d800 - U+dfff, so deal with surrogate pairing...
                else
                {
                    auto surrogateString = [&] () { return std::string(source+idx, 6); };
                    if (  idx + 12 > source_size
                       || idx +  8 > source_size
                       || source[idx + 6] != '\\'
                       || source[idx + 7] != 'u'
                       )
                        throw decode_error(idx, std::string("unpaired high surrogate (") + surrogateString() + ")");
                    uint16_t hexlowval = from_hex(&source[idx + 8]);
                    char32_t codepoint;
                    if (!utf16_combine_surrogates(hexval, hexlowval, &codepoint))
                        throw decode_error(idx, std::string("unpaired high surrogate (") + surrogateString() + ")");

                    utf8_append_code(output, codepoint);

                    idx += 12;
                }
            }
            else
            {
                throw decode_error(idx, std::string("Unknown escape character: ") + next);
                //output += '?'; Maybe better solution if we don't want to throw
                //++idx;
            }

            last_pushed_src = source + idx;
        }
        else
        {
            ++idx;
        }
    }

    output.append(last_pushed_src, source+source_size);
    return output;
}

}
}
<|endoftext|>


<commit_before>/* Copyright (C) 2004-2005 ian reinhart geiser <geiseri@sourcextreme.com> */

#include <kconfig.h>
#include <kmacroexpander.h>
#include <kconfiggroup.h>
#include <kaboutdata.h>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QHash>
#include <QString>
#include <QStringList>
#include <QTextStream>

static const char classHeader[] =   "/**\n"
                                    "* This file was autogenerated by kgendesignerplugin. Any changes will be lost!\n"
                                    "* The generated code in this file is licensed under the same license that the\n"
                                    "* input file.\n"
                                    "*/\n"
                                    "#include <QIcon>\n"
                                    "#include <QtDesigner/QDesignerContainerExtension>\n"
                                    "#include <QDesignerCustomWidgetInterface>\n"
                                    "#include <qplugin.h>\n"
                                    "#include <qdebug.h>\n";

static const char collClassDef[] = "class %CollName : public QObject, public QDesignerCustomWidgetCollectionInterface\n"
                                   "{\n"
                                   "	Q_OBJECT\n"
                                   "	Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)\n"
                                   "       Q_PLUGIN_METADATA(IID \"org.qt-project.Qt.QDesignerCustomWidgetInterface\")\n"
                                   "public:\n"
                                   "	%CollName(QObject *parent = 0);\n"
                                   "	virtual ~%CollName() {}\n"
                                   "	QList<QDesignerCustomWidgetInterface*> customWidgets() const { return m_plugins; } \n"
                                   "	\n"
                                   "private:\n"
                                   "	QList<QDesignerCustomWidgetInterface*> m_plugins;\n"
                                   "};\n\n"
                                   ;

static const char collClassImpl[] = "%CollName::%CollName(QObject *parent)\n"
                                    "	: QObject(parent)"
                                    "{\n"
                                    "%CollectionAdd\n"
                                    "}\n\n";

static const char classDef[] =  "class %PluginName : public QObject, public QDesignerCustomWidgetInterface\n"
                                "{\n"
                                "	Q_OBJECT\n"
                                "	Q_INTERFACES(QDesignerCustomWidgetInterface)\n"
                                "public:\n"
                                "	%PluginName(QObject *parent = 0) :\n\t\tQObject(parent), mInitialized(false) {}\n"
                                "	virtual ~%PluginName() {}\n"
                                "	\n"
                                "	bool isContainer() const { return %IsContainer; }\n"
                                "	bool isInitialized() const { return mInitialized; }\n"
                                "	QIcon icon() const { return QIcon(QLatin1String(\"%IconName\")); }\n"
                                "	QString codeTemplate() const { return QLatin1String(\"%CodeTemplate\");}\n"
                                "	QString domXml() const { return %DomXml; }\n"
                                "	QString group() const { return QLatin1String(\"%Group\"); }\n"
                                "	QString includeFile() const { return QLatin1String(\"%IncludeFile\"); }\n"
                                "	QString name() const { return QLatin1String(\"%Class\"); }\n"
                                "	QString toolTip() const { return QLatin1String(\"%ToolTip\"); }\n"
                                "	QString whatsThis() const { return QLatin1String(\"%WhatsThis\"); }\n\n"
                                "	QWidget* createWidget( QWidget* parent ) \n\t{%CreateWidget\n\t}\n"
                                "	void initialize(QDesignerFormEditorInterface *core) \n\t{%Initialize\n\t}\n"
                                "\n"
                                "private:\n"
                                "	bool mInitialized;\n"
                                "};\n\n";

static QString denamespace(const QString &str);
static QString buildCollClass(KConfig &input, const QStringList &classes);
static QString buildWidgetClass(const QString &name, KConfig &input, const QString &group);
static QString buildWidgetInclude(const QString &name, KConfig &input);
static void buildFile(QTextStream &stream, const QString &group, const QString &fileName, const QString &pluginName);

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QString description = QCoreApplication::translate("main", "Builds Qt widget plugins from an ini style description file.");
    const char version[] = "0.5";
    app.setApplicationVersion(version);

    QCommandLineParser parser;
    parser.addVersionOption();
    parser.addHelpOption();
    //options.add("+file", QCoreApplication::translate("kgendesignerplugin about data",  "Input file" ) );
    parser.addOption(QCommandLineOption(QStringList() << "o", QCoreApplication::translate("main", "Output file"), "file"));
    parser.addOption(QCommandLineOption(QStringList() << "n", QCoreApplication::translate("main", "Name of the plugin class to generate"), "plugin name", "WidgetsPlugin"));
    parser.addOption(QCommandLineOption(QStringList() << "g", QCoreApplication::translate("main", "Default widget group name to display in designer"), "group", "Custom"));

    KAboutData about("kgendesignerplugin", 0, QCoreApplication::translate("kgendesignerplugin about data",  "kgendesignerplugin"), version, description, KAboutData::License_GPL, QCoreApplication::translate("kgendesignerplugin about data", "(C) 2004-2005 Ian Reinhart Geiser"), QString(), 0, "geiseri@kde.org");
    about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Ian Reinhart Geiser"), QString(), "geiseri@kde.org");
    about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Daniel Molkentin"), QString(), "molkentin@kde.org");
    about.setupCommandLine(&parser);

    parser.process(app);
    about.processCommandLine(&parser);
    if (parser.positionalArguments().count() < 1) {
        parser.showHelp();
        return 1;
    }

    QFileInfo fi(parser.positionalArguments().at(0));

    QString outputFile = parser.value("o");
    QString pluginName = parser.value("n");
    QString group = parser.value("g");
    QString fileName = fi.absoluteFilePath();

    if (parser.isSet("o")) {
        QFile output(outputFile);
        if (output.open(QIODevice::WriteOnly)) {
            QTextStream ts(&output);
            buildFile(ts, group, fileName, pluginName);
            QString mocFile = output.fileName();
            mocFile.replace(".cpp", ".moc");
            ts << QString("#include <%1>\n").arg(mocFile) << endl;
        }
        output.close();
    } else {
        QTextStream ts(stdout, QIODevice::WriteOnly);
        buildFile(ts, group, fileName, pluginName);
    }
}

void buildFile(QTextStream &ts, const QString &group, const QString &fileName, const QString &pluginName)
{
    KConfig input(fileName, KConfig::NoGlobals);
    KConfigGroup cg(&input, "Global");
    QHash<QString, QString> MainMap;
    MainMap.insert("PluginName", cg.readEntry("PluginName", pluginName));
    MainMap.insert("PluginNameLower", cg.readEntry("PluginName", pluginName).toLower());
    MainMap.insert("Init", cg.readEntry("Init", ""));
    MainMap.insert("Destroy", cg.readEntry("Destroy", ""));
    ts << classHeader << endl;

    QStringList includes = cg.readEntry("Includes", QStringList());
    QStringList classes = input.groupList();
    classes.removeAll("Global");

    foreach (const QString &myInclude, classes) {
        includes += buildWidgetInclude(myInclude, input);
    }

    foreach (const QString &myInclude, includes) {
        ts << "#include <" << myInclude << ">" << endl;
    }

    ts << QLatin1String("\n\n");

    // Autogenerate widget defs here
    foreach (const QString &myClass, classes) {
        ts << buildWidgetClass(myClass, input, group) << endl;
    }

    ts << buildCollClass(input, classes);

}

QString denamespace(const QString &str)
{
    QString denamespaced = str;
    denamespaced.remove("::");
    return denamespaced;
}

QString buildCollClass(KConfig &_input, const QStringList &classes)
{
    KConfigGroup input(&_input, "Global");
    QHash<QString, QString> defMap;
    const QString collName = input.readEntry("PluginName");
    Q_ASSERT(!collName.isEmpty());
    defMap.insert("CollName", collName);
    QString genCode;

    foreach (const QString &myClass, classes) {
        genCode += QString("\t\tm_plugins.append( new %1(this) );\n").arg(denamespace(myClass) + "Plugin");
    }

    defMap.insert("CollectionAdd", genCode);

    QString str = KMacroExpander::expandMacros(collClassDef, defMap);
    str += KMacroExpander::expandMacros(collClassImpl, defMap);
    return str;
}

QString buildWidgetClass(const QString &name, KConfig &_input, const QString &group)
{
    KConfigGroup input(&_input, name);
    QHash<QString, QString> defMap;

    defMap.insert("Group", input.readEntry("Group", group).replace('\"', "\\\""));
    defMap.insert("IconSet", input.readEntry("IconSet", QString(name.toLower() + ".png")).replace(':', '_'));
    defMap.insert("Pixmap", name.toLower().replace(':', '_') + "_xpm");
    defMap.insert("IncludeFile", input.readEntry("IncludeFile", QString(name.toLower() + ".h")).remove(':'));
    defMap.insert("ToolTip", input.readEntry("ToolTip", QString(name + " Widget")).replace('\"', "\\\""));
    defMap.insert("WhatsThis", input.readEntry("WhatsThis", QString(name + " Widget")).replace('\"', "\\\""));
    defMap.insert("IsContainer", input.readEntry("IsContainer", "false"));
    defMap.insert("IconName", input.readEntry("IconName", QString::fromLatin1(":/pics/%1.png").arg(denamespace(name).toLower())));
    defMap.insert("Class", name);
    defMap.insert("PluginName", denamespace(name) + QLatin1String("Plugin"));

    // FIXME: ### make this more useful, i.e. outsource to separate file
    QString domXml = input.readEntry("DomXML", QString());
    // If domXml is empty then we should call base class function
    if (domXml.isEmpty()) {
        domXml = QLatin1String("QDesignerCustomWidgetInterface::domXml()");
    } else {
        // Wrap domXml value into QLatin1String
        domXml = QString(QLatin1String("QLatin1String(\"%1\")")).arg(domXml.replace('\"', "\\\""));
    }
    defMap.insert("DomXml", domXml);
    defMap.insert("CodeTemplate", input.readEntry("CodeTemplate"));
    defMap.insert("CreateWidget", input.readEntry("CreateWidget",
                  QString("\n\t\treturn new %1%2;")
                  .arg(input.readEntry("ImplClass", name))
                  .arg(input.readEntry("ConstructorArgs", "( parent )"))));
    defMap.insert("Initialize", input.readEntry("Initialize", "\n\t\tQ_UNUSED(core);\n\t\tif (mInitialized) return;\n\t\tmInitialized=true;"));

    return KMacroExpander::expandMacros(classDef, defMap);
}

QString buildWidgetInclude(const QString &name, KConfig &_input)
{
    KConfigGroup input(&_input, name);
    return input.readEntry("IncludeFile", QString(name.toLower() + ".h"));
}
<commit_msg>Remove unused code in kgendesignerplugin<commit_after>/* Copyright (C) 2004-2005 ian reinhart geiser <geiseri@sourcextreme.com> */

#include <kconfig.h>
#include <kmacroexpander.h>
#include <kconfiggroup.h>
#include <kaboutdata.h>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QHash>
#include <QString>
#include <QStringList>
#include <QTextStream>

static const char classHeader[] =   "/**\n"
                                    "* This file was autogenerated by kgendesignerplugin. Any changes will be lost!\n"
                                    "* The generated code in this file is licensed under the same license that the\n"
                                    "* input file.\n"
                                    "*/\n"
                                    "#include <QIcon>\n"
                                    "#include <QtDesigner/QDesignerContainerExtension>\n"
                                    "#include <QDesignerCustomWidgetInterface>\n"
                                    "#include <qplugin.h>\n"
                                    "#include <qdebug.h>\n";

static const char collClassDef[] = "class %CollName : public QObject, public QDesignerCustomWidgetCollectionInterface\n"
                                   "{\n"
                                   "	Q_OBJECT\n"
                                   "	Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)\n"
                                   "       Q_PLUGIN_METADATA(IID \"org.qt-project.Qt.QDesignerCustomWidgetInterface\")\n"
                                   "public:\n"
                                   "	%CollName(QObject *parent = 0);\n"
                                   "	virtual ~%CollName() {}\n"
                                   "	QList<QDesignerCustomWidgetInterface*> customWidgets() const { return m_plugins; } \n"
                                   "	\n"
                                   "private:\n"
                                   "	QList<QDesignerCustomWidgetInterface*> m_plugins;\n"
                                   "};\n\n"
                                   ;

static const char collClassImpl[] = "%CollName::%CollName(QObject *parent)\n"
                                    "	: QObject(parent)"
                                    "{\n"
                                    "%CollectionAdd\n"
                                    "}\n\n";

static const char classDef[] =  "class %PluginName : public QObject, public QDesignerCustomWidgetInterface\n"
                                "{\n"
                                "	Q_OBJECT\n"
                                "	Q_INTERFACES(QDesignerCustomWidgetInterface)\n"
                                "public:\n"
                                "	%PluginName(QObject *parent = 0) :\n\t\tQObject(parent), mInitialized(false) {}\n"
                                "	virtual ~%PluginName() {}\n"
                                "	\n"
                                "	bool isContainer() const { return %IsContainer; }\n"
                                "	bool isInitialized() const { return mInitialized; }\n"
                                "	QIcon icon() const { return QIcon(QLatin1String(\"%IconName\")); }\n"
                                "	QString codeTemplate() const { return QLatin1String(\"%CodeTemplate\");}\n"
                                "	QString domXml() const { return %DomXml; }\n"
                                "	QString group() const { return QLatin1String(\"%Group\"); }\n"
                                "	QString includeFile() const { return QLatin1String(\"%IncludeFile\"); }\n"
                                "	QString name() const { return QLatin1String(\"%Class\"); }\n"
                                "	QString toolTip() const { return QLatin1String(\"%ToolTip\"); }\n"
                                "	QString whatsThis() const { return QLatin1String(\"%WhatsThis\"); }\n\n"
                                "	QWidget* createWidget( QWidget* parent ) \n\t{%CreateWidget\n\t}\n"
                                "	void initialize(QDesignerFormEditorInterface *core) \n\t{%Initialize\n\t}\n"
                                "\n"
                                "private:\n"
                                "	bool mInitialized;\n"
                                "};\n\n";

static QString denamespace(const QString &str);
static QString buildCollClass(KConfig &input, const QStringList &classes);
static QString buildWidgetClass(const QString &name, KConfig &input, const QString &group);
static QString buildWidgetInclude(const QString &name, KConfig &input);
static void buildFile(QTextStream &stream, const QString &group, const QString &fileName, const QString &pluginName);

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    QString description = QCoreApplication::translate("main", "Builds Qt widget plugins from an ini style description file.");
    const char version[] = "0.5";
    app.setApplicationVersion(version);

    QCommandLineParser parser;
    parser.addVersionOption();
    parser.addHelpOption();
    //options.add("+file", QCoreApplication::translate("kgendesignerplugin about data",  "Input file" ) );
    parser.addOption(QCommandLineOption(QStringList() << "o", QCoreApplication::translate("main", "Output file"), "file"));
    parser.addOption(QCommandLineOption(QStringList() << "n", QCoreApplication::translate("main", "Name of the plugin class to generate"), "plugin name", "WidgetsPlugin"));
    parser.addOption(QCommandLineOption(QStringList() << "g", QCoreApplication::translate("main", "Default widget group name to display in designer"), "group", "Custom"));

    KAboutData about("kgendesignerplugin", 0, QCoreApplication::translate("kgendesignerplugin about data",  "kgendesignerplugin"), version, description, KAboutData::License_GPL, QCoreApplication::translate("kgendesignerplugin about data", "(C) 2004-2005 Ian Reinhart Geiser"), QString(), 0, "geiseri@kde.org");
    about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Ian Reinhart Geiser"), QString(), "geiseri@kde.org");
    about.addAuthor(QCoreApplication::translate("kgendesignerplugin about data", "Daniel Molkentin"), QString(), "molkentin@kde.org");
    about.setupCommandLine(&parser);

    parser.process(app);
    about.processCommandLine(&parser);
    if (parser.positionalArguments().count() < 1) {
        parser.showHelp();
        return 1;
    }

    QFileInfo fi(parser.positionalArguments().at(0));

    QString outputFile = parser.value("o");
    QString pluginName = parser.value("n");
    QString group = parser.value("g");
    QString fileName = fi.absoluteFilePath();

    if (parser.isSet("o")) {
        QFile output(outputFile);
        if (output.open(QIODevice::WriteOnly)) {
            QTextStream ts(&output);
            buildFile(ts, group, fileName, pluginName);
            QString mocFile = output.fileName();
            mocFile.replace(".cpp", ".moc");
            ts << QString("#include <%1>\n").arg(mocFile) << endl;
        }
        output.close();
    } else {
        QTextStream ts(stdout, QIODevice::WriteOnly);
        buildFile(ts, group, fileName, pluginName);
    }
}

void buildFile(QTextStream &ts, const QString &group, const QString &fileName, const QString &pluginName)
{
    KConfig input(fileName, KConfig::NoGlobals);
    KConfigGroup cg(&input, "Global");
    ts << classHeader << endl;

    QStringList includes = cg.readEntry("Includes", QStringList());
    QStringList classes = input.groupList();
    classes.removeAll("Global");

    foreach (const QString &myInclude, classes) {
        includes += buildWidgetInclude(myInclude, input);
    }

    foreach (const QString &myInclude, includes) {
        ts << "#include <" << myInclude << ">" << endl;
    }

    ts << QLatin1String("\n\n");

    // Autogenerate widget defs here
    foreach (const QString &myClass, classes) {
        ts << buildWidgetClass(myClass, input, group) << endl;
    }

    ts << buildCollClass(input, classes);

}

QString denamespace(const QString &str)
{
    QString denamespaced = str;
    denamespaced.remove("::");
    return denamespaced;
}

QString buildCollClass(KConfig &_input, const QStringList &classes)
{
    KConfigGroup input(&_input, "Global");
    QHash<QString, QString> defMap;
    const QString collName = input.readEntry("PluginName");
    Q_ASSERT(!collName.isEmpty());
    defMap.insert("CollName", collName);
    QString genCode;

    foreach (const QString &myClass, classes) {
        genCode += QString("\t\tm_plugins.append( new %1(this) );\n").arg(denamespace(myClass) + "Plugin");
    }

    defMap.insert("CollectionAdd", genCode);

    QString str = KMacroExpander::expandMacros(collClassDef, defMap);
    str += KMacroExpander::expandMacros(collClassImpl, defMap);
    return str;
}

QString buildWidgetClass(const QString &name, KConfig &_input, const QString &group)
{
    KConfigGroup input(&_input, name);
    QHash<QString, QString> defMap;

    defMap.insert("Group", input.readEntry("Group", group).replace('\"', "\\\""));
    defMap.insert("IncludeFile", input.readEntry("IncludeFile", QString(name.toLower() + ".h")).remove(':'));
    defMap.insert("ToolTip", input.readEntry("ToolTip", QString(name + " Widget")).replace('\"', "\\\""));
    defMap.insert("WhatsThis", input.readEntry("WhatsThis", QString(name + " Widget")).replace('\"', "\\\""));
    defMap.insert("IsContainer", input.readEntry("IsContainer", "false"));
    defMap.insert("IconName", input.readEntry("IconName", QString::fromLatin1(":/pics/%1.png").arg(denamespace(name).toLower())));
    defMap.insert("Class", name);
    defMap.insert("PluginName", denamespace(name) + QLatin1String("Plugin"));

    // FIXME: ### make this more useful, i.e. outsource to separate file
    QString domXml = input.readEntry("DomXML", QString());
    // If domXml is empty then we should call base class function
    if (domXml.isEmpty()) {
        domXml = QLatin1String("QDesignerCustomWidgetInterface::domXml()");
    } else {
        // Wrap domXml value into QLatin1String
        domXml = QString(QLatin1String("QLatin1String(\"%1\")")).arg(domXml.replace('\"', "\\\""));
    }
    defMap.insert("DomXml", domXml);
    defMap.insert("CodeTemplate", input.readEntry("CodeTemplate"));
    defMap.insert("CreateWidget", input.readEntry("CreateWidget",
                  QString("\n\t\treturn new %1%2;")
                  .arg(input.readEntry("ImplClass", name))
                  .arg(input.readEntry("ConstructorArgs", "( parent )"))));
    defMap.insert("Initialize", input.readEntry("Initialize", "\n\t\tQ_UNUSED(core);\n\t\tif (mInitialized) return;\n\t\tmInitialized=true;"));

    return KMacroExpander::expandMacros(classDef, defMap);
}

QString buildWidgetInclude(const QString &name, KConfig &_input)
{
    KConfigGroup input(&_input, name);
    return input.readEntry("IncludeFile", QString(name.toLower() + ".h"));
}
<|endoftext|>


<commit_before>/*
* PK Key
* (C) 1999-2010,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/pk_algs.h>
#include <botan/oids.h>

#if defined(BOTAN_HAS_RSA)
  #include <botan/rsa.h>
#endif

#if defined(BOTAN_HAS_DSA)
  #include <botan/dsa.h>
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
  #include <botan/dh.h>
#endif

#if defined(BOTAN_HAS_ECDSA)
  #include <botan/ecdsa.h>
#endif

#if defined(BOTAN_HAS_ECGDSA)
  #include <botan/ecgdsa.h>
#endif

#if defined(BOTAN_HAS_ECKCDSA)
  #include <botan/eckcdsa.h>
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
  #include <botan/gost_3410.h>
#endif

#if defined(BOTAN_HAS_ELGAMAL)
  #include <botan/elgamal.h>
#endif

#if defined(BOTAN_HAS_ECDH)
  #include <botan/ecdh.h>
#endif

#if defined(BOTAN_HAS_CURVE_25519)
  #include <botan/curve25519.h>
#endif

#if defined(BOTAN_HAS_MCELIECE)
  #include <botan/mceliece.h>
#endif

namespace Botan {

std::unique_ptr<Public_Key>
load_public_key(const AlgorithmIdentifier& alg_id,
                const secure_vector<byte>& key_bits)
   {
   const std::string alg_name = OIDS::lookup(alg_id.oid);
   if(alg_name == "")
      throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      return std::unique_ptr<Public_Key>(new McEliece_PublicKey(unlock(key_bits)));
#endif

#if defined(BOTAN_HAS_ECDSA)
   if(alg_name == "ECDSA")
      return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECDH)
   if(alg_name == "ECDH")
      return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
   if(alg_name == "DH")
      return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DSA)
   if(alg_name == "DSA")
      return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
   if(alg_name == "ElGamal")
      return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECGDSA)
   if(alg_name == "ECGDSA")
      return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
   if(alg_name == "ECKCDSA")
      return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
   if(alg_name == "GOST-34.10")
      return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
#endif

   throw Decoding_Error("Unhandled PK algorithm " + alg_name);
   }

std::unique_ptr<Private_Key>
load_private_key(const AlgorithmIdentifier& alg_id,
                 const secure_vector<byte>& key_bits,
                 RandomNumberGenerator& rng)
   {
   const std::string alg_name = OIDS::lookup(alg_id.oid);
   if(alg_name == "")
      throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_ECDSA)
   if(alg_name == "ECDSA")
      return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECDH)
   if(alg_name == "ECDH")
      return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
   if(alg_name == "DH")
      return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_DSA)
   if(alg_name == "DSA")
      return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
#endif

#if defined(BOTAN_HAS_ECGDSA)
   if(alg_name == "ECGDSA")
      return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
   if(alg_name == "ECKCDSA")
      return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
   if(alg_name == "GOST-34.10")
      return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
   if(alg_name == "ElGamal")
      return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits, rng));
#endif

   throw Decoding_Error("Unhandled PK algorithm " + alg_name);
   }

std::unique_ptr<Private_Key>
create_private_key(const std::string& alg_name,
                   RandomNumberGenerator& rng,
                   const std::string& params)
   {
   /*
   * Default paramaters are chosen for work factor > 2**128 where possible
   */

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
#endif

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      {
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
      }
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      {
      std::vector<std::string> mce_param =
         Botan::split_on(params.empty() ? "2960,57" : params, ',');

      if(mce_param.size() != 2)
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);

      size_t mce_n = Botan::to_u32bit(mce_param[0]);
      size_t mce_t = Botan::to_u32bit(mce_param[1]);

      return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
      }
#endif

   // ECC crypto
#if defined(BOTAN_HAS_ECC_CRYPTO)

   if(alg_name == "ECDSA" ||
      alg_name == "ECDH" ||
      alg_name == "ECKCDSA" ||
      alg_name == "ECGDSA" ||
      alg_name == "GOST-34.10")
      {
      const EC_Group ec_group(params.empty() ? "secp256r1" : params);

#if defined(BOTAN_HAS_ECDSA)
      if(alg_name == "ECDSA")
         return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECDH)
      if(alg_name == "ECDH")
         return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
      if(alg_name == "ECKCDSA")
         return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
      if(alg_name == "GOST-34.10")
         return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECGDSA)
      if(alg_name == "ECGDSA")
         return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
#endif
      }
#endif

   // DL crypto
#if defined(BOTAN_HAS_DL_GROUP)
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
      {
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
      DL_Group modp_group(params.empty() ? default_group : params);

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
      if(alg_name == "DH")
         return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_DSA)
      if(alg_name == "DSA")
         return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
      if(alg_name == "ElGamal")
         return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
#endif
      }
#endif

   return std::unique_ptr<Private_Key>();
   }

}
<commit_msg>Use correct macro for ECC in create_private_key<commit_after>/*
* PK Key
* (C) 1999-2010,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/pk_algs.h>
#include <botan/oids.h>

#if defined(BOTAN_HAS_RSA)
  #include <botan/rsa.h>
#endif

#if defined(BOTAN_HAS_DSA)
  #include <botan/dsa.h>
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
  #include <botan/dh.h>
#endif

#if defined(BOTAN_HAS_ECDSA)
  #include <botan/ecdsa.h>
#endif

#if defined(BOTAN_HAS_ECGDSA)
  #include <botan/ecgdsa.h>
#endif

#if defined(BOTAN_HAS_ECKCDSA)
  #include <botan/eckcdsa.h>
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
  #include <botan/gost_3410.h>
#endif

#if defined(BOTAN_HAS_ELGAMAL)
  #include <botan/elgamal.h>
#endif

#if defined(BOTAN_HAS_ECDH)
  #include <botan/ecdh.h>
#endif

#if defined(BOTAN_HAS_CURVE_25519)
  #include <botan/curve25519.h>
#endif

#if defined(BOTAN_HAS_MCELIECE)
  #include <botan/mceliece.h>
#endif

namespace Botan {

std::unique_ptr<Public_Key>
load_public_key(const AlgorithmIdentifier& alg_id,
                const secure_vector<byte>& key_bits)
   {
   const std::string alg_name = OIDS::lookup(alg_id.oid);
   if(alg_name == "")
      throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      return std::unique_ptr<Public_Key>(new RSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Public_Key>(new Curve25519_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      return std::unique_ptr<Public_Key>(new McEliece_PublicKey(unlock(key_bits)));
#endif

#if defined(BOTAN_HAS_ECDSA)
   if(alg_name == "ECDSA")
      return std::unique_ptr<Public_Key>(new ECDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECDH)
   if(alg_name == "ECDH")
      return std::unique_ptr<Public_Key>(new ECDH_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
   if(alg_name == "DH")
      return std::unique_ptr<Public_Key>(new DH_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DSA)
   if(alg_name == "DSA")
      return std::unique_ptr<Public_Key>(new DSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
   if(alg_name == "ElGamal")
      return std::unique_ptr<Public_Key>(new ElGamal_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECGDSA)
   if(alg_name == "ECGDSA")
      return std::unique_ptr<Public_Key>(new ECGDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
   if(alg_name == "ECKCDSA")
      return std::unique_ptr<Public_Key>(new ECKCDSA_PublicKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
   if(alg_name == "GOST-34.10")
      return std::unique_ptr<Public_Key>(new GOST_3410_PublicKey(alg_id, key_bits));
#endif

   throw Decoding_Error("Unhandled PK algorithm " + alg_name);
   }

std::unique_ptr<Private_Key>
load_private_key(const AlgorithmIdentifier& alg_id,
                 const secure_vector<byte>& key_bits,
                 RandomNumberGenerator& rng)
   {
   const std::string alg_name = OIDS::lookup(alg_id.oid);
   if(alg_name == "")
      throw Decoding_Error("Unknown algorithm OID: " + alg_id.oid.as_string());

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_ECDSA)
   if(alg_name == "ECDSA")
      return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECDH)
   if(alg_name == "ECDH")
      return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
   if(alg_name == "DH")
      return std::unique_ptr<Private_Key>(new DH_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_DSA)
   if(alg_name == "DSA")
      return std::unique_ptr<Private_Key>(new DSA_PrivateKey(alg_id, key_bits, rng));
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      return std::unique_ptr<Private_Key>(new McEliece_PrivateKey(key_bits));
#endif

#if defined(BOTAN_HAS_ECGDSA)
   if(alg_name == "ECGDSA")
      return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
   if(alg_name == "ECKCDSA")
      return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
   if(alg_name == "GOST-34.10")
      return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(alg_id, key_bits));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
   if(alg_name == "ElGamal")
      return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(alg_id, key_bits, rng));
#endif

   throw Decoding_Error("Unhandled PK algorithm " + alg_name);
   }

std::unique_ptr<Private_Key>
create_private_key(const std::string& alg_name,
                   RandomNumberGenerator& rng,
                   const std::string& params)
   {
   /*
   * Default paramaters are chosen for work factor > 2**128 where possible
   */

#if defined(BOTAN_HAS_CURVE_25519)
   if(alg_name == "Curve25519")
      return std::unique_ptr<Private_Key>(new Curve25519_PrivateKey(rng));
#endif

#if defined(BOTAN_HAS_RSA)
   if(alg_name == "RSA")
      {
      const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
      return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
      }
#endif

#if defined(BOTAN_HAS_MCELIECE)
   if(alg_name == "McEliece")
      {
      std::vector<std::string> mce_param =
         Botan::split_on(params.empty() ? "2960,57" : params, ',');

      if(mce_param.size() != 2)
         throw Invalid_Argument("create_private_key bad McEliece parameters " + params);

      size_t mce_n = Botan::to_u32bit(mce_param[0]);
      size_t mce_t = Botan::to_u32bit(mce_param[1]);

      return std::unique_ptr<Botan::Private_Key>(new Botan::McEliece_PrivateKey(rng, mce_n, mce_t));
      }
#endif

   // ECC crypto
#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)

   if(alg_name == "ECDSA" ||
      alg_name == "ECDH" ||
      alg_name == "ECKCDSA" ||
      alg_name == "ECGDSA" ||
      alg_name == "GOST-34.10")
      {
      const EC_Group ec_group(params.empty() ? "secp256r1" : params);

#if defined(BOTAN_HAS_ECDSA)
      if(alg_name == "ECDSA")
         return std::unique_ptr<Private_Key>(new ECDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECDH)
      if(alg_name == "ECDH")
         return std::unique_ptr<Private_Key>(new ECDH_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECKCDSA)
      if(alg_name == "ECKCDSA")
         return std::unique_ptr<Private_Key>(new ECKCDSA_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_GOST_34_10_2001)
      if(alg_name == "GOST-34.10")
         return std::unique_ptr<Private_Key>(new GOST_3410_PrivateKey(rng, ec_group));
#endif

#if defined(BOTAN_HAS_ECGDSA)
      if(alg_name == "ECGDSA")
         return std::unique_ptr<Private_Key>(new ECGDSA_PrivateKey(rng, ec_group));
#endif
      }
#endif

   // DL crypto
#if defined(BOTAN_HAS_DL_GROUP)
   if(alg_name == "DH" || alg_name == "DSA" || alg_name == "ElGamal")
      {
      std::string default_group = (alg_name == "DSA") ? "dsa/botan/2048" : "modp/ietf/2048";
      DL_Group modp_group(params.empty() ? default_group : params);

#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
      if(alg_name == "DH")
         return std::unique_ptr<Private_Key>(new DH_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_DSA)
      if(alg_name == "DSA")
         return std::unique_ptr<Private_Key>(new DSA_PrivateKey(rng, modp_group));
#endif

#if defined(BOTAN_HAS_ELGAMAL)
      if(alg_name == "ElGamal")
         return std::unique_ptr<Private_Key>(new ElGamal_PrivateKey(rng, modp_group));
#endif
      }
#endif

   return std::unique_ptr<Private_Key>();
   }

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "fileinfo.h"

#include <logging/translator.h>
#include <tools/hostosinfo.h>

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>

#include <cassert>

#ifdef Q_OS_UNIX
#include <sys/stat.h>
#endif

namespace qbs {
namespace Internal {

QString FileInfo::fileName(const QString &fp)
{
    int last = fp.lastIndexOf(QLatin1Char('/'));
    if (last < 0)
        return fp;
    return fp.mid(last + 1);
}

QString FileInfo::baseName(const QString &fp)
{
    QString fn = fileName(fp);
    int dot = fn.indexOf(QLatin1Char('.'));
    if (dot < 0)
        return fp;
    return fn.mid(0, dot);
}

QString FileInfo::completeBaseName(const QString &fp)
{
    QString fn = fileName(fp);
    int dot = fn.lastIndexOf(QLatin1Char('.'));
    if (dot < 0)
        return fp;
    return fn.mid(0, dot);
}

QString FileInfo::path(const QString &fp)
{
    if (fp.isEmpty())
        return QString();
    if (fp.at(fp.size() - 1) == QLatin1Char('/'))
        return fp;
    int last = fp.lastIndexOf(QLatin1Char('/'));
    if (last < 0)
        return QLatin1String(".");
    return QDir::cleanPath(fp.mid(0, last));
}

void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QString *dirPath, QString *fileName)
{
    int idx = filePath.lastIndexOf(QLatin1Char('/'));
    if (idx < 0) {
        dirPath->clear();
        *fileName = filePath;
        return;
    }
    *dirPath = filePath.left(idx);
    *fileName = filePath.mid(idx + 1);
}

void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QStringRef *dirPath, QStringRef *fileName)
{
    int idx = filePath.lastIndexOf(QLatin1Char('/'));
    if (idx < 0) {
        dirPath->clear();
        *fileName = QStringRef(&filePath);
        return;
    }
    *dirPath = filePath.leftRef(idx);
    *fileName = filePath.midRef(idx + 1);
}

bool FileInfo::exists(const QString &fp)
{
    return FileInfo(fp).exists();
}

// from creator/src/shared/proparser/ioutils.cpp
bool FileInfo::isAbsolute(const QString &path)
{
    const int n = path.size();
    if (n == 0)
        return false;
    const QChar at0 = path.at(0);
    if (at0 == QLatin1Char('/'))
        return true;
    if (HostOsInfo::isWindowsHost()) {
        if (at0 == QLatin1Char('\\'))
            return true;
        // Unlike QFileInfo, this won't accept a relative path with a drive letter.
        // Such paths result in a royal mess anyway ...
        if (n >= 3 && path.at(1) == QLatin1Char(':') && at0.isLetter()
                && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\')))
            return true;
    }
    return false;
}

bool FileInfo::isPattern(const QString &str)
{
    return isPattern(QStringRef(&str));
}

bool FileInfo::isPattern(const QStringRef &str)
{
    for (int i = 0; i < str.size(); ++i) {
        const QChar ch = str.at(i);
        if (ch == QLatin1Char('*') || ch == QLatin1Char('?')
                || ch == QLatin1Char(']') || ch == QLatin1Char('[')) {
            return true;
        }
    }
    return false;
}

/**
 * Concatenates the paths \a base and \a rel.
 * Base must be an absolute path.
 * Double dots at the start of \a rel are handled.
 * This function assumes that both paths are clean, that is they don't contain
 * double slashes or redundant dot parts.
 */
QString FileInfo::resolvePath(const QString &base, const QString &rel)
{
    Q_ASSERT(isAbsolute(base));
    if (isAbsolute(rel))
        return rel;
    if (rel.size() == 1 && rel.at(0) == QLatin1Char('.'))
        return base;

    QString r = base;
    if (r.endsWith(QLatin1Char('/')))
        r.chop(1);

    QString s = rel;
    while (s.startsWith(QLatin1String("../"))) {
        s.remove(0, 3);
        int idx = r.lastIndexOf(QLatin1Char('/'));
        if (idx >= 0)
            r.truncate(idx);
    }

    r.reserve(r.length() + 1 + s.length());
    r += QLatin1Char('/');
    r += s;
    return r;
}

bool FileInfo::globMatches(const QRegExp &regexp, const QString &fileName)
{
    const QString pattern = regexp.pattern();
    // May be it's simple wildcard, i.e. "*.cpp"?
    if (pattern.startsWith(QLatin1Char('*')) && !isPattern(pattern.midRef(1))) {
        // Yes, it's rather simple to just check the extension
        return fileName.endsWith(pattern.midRef(1));
    }
    return regexp.exactMatch(fileName);
}

#if defined(Q_OS_WIN)

#include <qt_windows.h>

#define z(x) reinterpret_cast<WIN32_FILE_ATTRIBUTE_DATA*>(const_cast<FileInfo::InternalStatType*>(&x))

template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true> {};

FileInfo::FileInfo(const QString &fileName)
{
    static CompileTimeAssert<
        sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA)
            > internal_type_has_wrong_size;
    if (!GetFileAttributesEx(reinterpret_cast<const WCHAR*>(fileName.utf16()),
                             GetFileExInfoStandard, &m_stat))
    {
        ZeroMemory(z(m_stat), sizeof(WIN32_FILE_ATTRIBUTE_DATA));
        z(m_stat)->dwFileAttributes = INVALID_FILE_ATTRIBUTES;
    }
}

bool FileInfo::exists() const
{
    return z(m_stat)->dwFileAttributes != INVALID_FILE_ATTRIBUTES;
}

FileTime FileInfo::lastModified() const
{
    return FileTime(*reinterpret_cast<const FileTime::InternalType*>(
        &z(m_stat)->ftLastWriteTime));
}

FileTime FileInfo::lastStatusChange() const
{
    return lastModified();
}

bool FileInfo::isDir() const
{
    return z(m_stat)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
}

static QString resolveSymlinks(const QString &fileName)
{
    QFileInfo fi(fileName);
    while (fi.isSymLink())
        fi.setFile(fi.symLinkTarget());
    return fi.absoluteFilePath();
}

QString applicationDirPath()
{
    static const QString appDirPath = FileInfo::path(resolveSymlinks(QCoreApplication::applicationFilePath()));
    return appDirPath;
}

#elif defined(Q_OS_UNIX)

FileInfo::FileInfo(const QString &fileName)
{
    if (stat(fileName.toLocal8Bit(), &m_stat) == -1)
        m_stat.st_mtime = 0;
}

bool FileInfo::exists() const
{
    return m_stat.st_mtime != 0;
}

FileTime FileInfo::lastModified() const
{
    return m_stat.st_mtime;
}

FileTime FileInfo::lastStatusChange() const
{
    return m_stat.st_ctime;
}

bool FileInfo::isDir() const
{
    return S_ISDIR(m_stat.st_mode);
}

QString applicationDirPath()
{
    return QCoreApplication::applicationDirPath();
}

#endif

// adapted from qtc/plugins/vcsbase/cleandialog.cpp
bool removeFileRecursion(const QFileInfo &f, QString *errorMessage)
{
    if (!f.exists())
        return true;
    if (f.isDir()) {
        const QDir dir(f.absoluteFilePath());
        foreach(const QFileInfo &fi, dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden))
            removeFileRecursion(fi, errorMessage);
        QDir parent = f.absoluteDir();
        if (!parent.rmdir(f.fileName())) {
            errorMessage->append(Tr::tr("The directory %1 could not be deleted.").
                                 arg(QDir::toNativeSeparators(f.absoluteFilePath())));
            return false;
        }
    } else if (!QFile::remove(f.absoluteFilePath())) {
        if (!errorMessage->isEmpty())
            errorMessage->append(QLatin1Char('\n'));
        errorMessage->append(Tr::tr("The file %1 could not be deleted.").
                             arg(QDir::toNativeSeparators(f.absoluteFilePath())));
        return false;
    }
    return true;
}

bool removeDirectoryWithContents(const QString &path, QString *errorMessage)
{
    QFileInfo f(path);
    if (f.exists() && !f.isDir()) {
        *errorMessage = Tr::tr("%1 is not a directory.").arg(QDir::toNativeSeparators(path));
        return false;
    }
    return removeFileRecursion(f, errorMessage);
}

/*!
  Copies the directory specified by \a srcFilePath recursively to \a tgtFilePath.
  \a tgtFilePath will contain the target directory, which will be created. Example usage:

  \code
    QString error;
    book ok = Utils::FileUtils::copyRecursively("/foo/bar", "/foo/baz", &error);
    if (!ok)
      qDebug() << error;
  \endcode

  This will copy the contents of /foo/bar into to the baz directory under /foo,
  which will be created in the process.

  \return Whether the operation succeeded.
  \note Function was adapted from qtc/src/libs/fileutils.cpp
*/

bool copyFileRecursion(const QString &srcFilePath, const QString &tgtFilePath,
    QString *errorMessage)
{
    QFileInfo srcFileInfo(srcFilePath);
    if (srcFileInfo.isDir()) {
        QDir targetDir(tgtFilePath);
        targetDir.cdUp();
        if (!targetDir.mkpath(QFileInfo(tgtFilePath).fileName())) {
            *errorMessage = Tr::tr("The directory '%1' could not be created.")
               .arg(QDir::toNativeSeparators(tgtFilePath));
            return false;
        }
        QDir sourceDir(srcFilePath);
        QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot
            | QDir::Hidden | QDir::System);
        foreach (const QString &fileName, fileNames) {
            const QString newSrcFilePath = srcFilePath + QLatin1Char('/') + fileName;
            const QString newTgtFilePath = tgtFilePath + QLatin1Char('/') + fileName;
            if (!copyFileRecursion(newSrcFilePath, newTgtFilePath, errorMessage))
                return false;
        }
    } else {
        QFile file(srcFilePath);
        if (!file.copy(tgtFilePath)) {
            *errorMessage = Tr::tr("Could not copy file '%1' to '%2'. %3")
                .arg(QDir::toNativeSeparators(srcFilePath), QDir::toNativeSeparators(tgtFilePath),
                     file.errorString());
            return false;
        }
    }
    return true;
}

QString qbsRootPath()
{
    return QDir::cleanPath(applicationDirPath() + QLatin1String("/../"));
}

} // namespace Internal
} // namespace qbs
<commit_msg>MinGW-w64 compilation fix.<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Build Suite.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "fileinfo.h"

#include <logging/translator.h>
#include <tools/hostosinfo.h>

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>

#include <cassert>

#ifdef Q_OS_UNIX
#include <sys/stat.h>
#endif

namespace qbs {
namespace Internal {

QString FileInfo::fileName(const QString &fp)
{
    int last = fp.lastIndexOf(QLatin1Char('/'));
    if (last < 0)
        return fp;
    return fp.mid(last + 1);
}

QString FileInfo::baseName(const QString &fp)
{
    QString fn = fileName(fp);
    int dot = fn.indexOf(QLatin1Char('.'));
    if (dot < 0)
        return fp;
    return fn.mid(0, dot);
}

QString FileInfo::completeBaseName(const QString &fp)
{
    QString fn = fileName(fp);
    int dot = fn.lastIndexOf(QLatin1Char('.'));
    if (dot < 0)
        return fp;
    return fn.mid(0, dot);
}

QString FileInfo::path(const QString &fp)
{
    if (fp.isEmpty())
        return QString();
    if (fp.at(fp.size() - 1) == QLatin1Char('/'))
        return fp;
    int last = fp.lastIndexOf(QLatin1Char('/'));
    if (last < 0)
        return QLatin1String(".");
    return QDir::cleanPath(fp.mid(0, last));
}

void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QString *dirPath, QString *fileName)
{
    int idx = filePath.lastIndexOf(QLatin1Char('/'));
    if (idx < 0) {
        dirPath->clear();
        *fileName = filePath;
        return;
    }
    *dirPath = filePath.left(idx);
    *fileName = filePath.mid(idx + 1);
}

void FileInfo::splitIntoDirectoryAndFileName(const QString &filePath, QStringRef *dirPath, QStringRef *fileName)
{
    int idx = filePath.lastIndexOf(QLatin1Char('/'));
    if (idx < 0) {
        dirPath->clear();
        *fileName = QStringRef(&filePath);
        return;
    }
    *dirPath = filePath.leftRef(idx);
    *fileName = filePath.midRef(idx + 1);
}

bool FileInfo::exists(const QString &fp)
{
    return FileInfo(fp).exists();
}

// from creator/src/shared/proparser/ioutils.cpp
bool FileInfo::isAbsolute(const QString &path)
{
    const int n = path.size();
    if (n == 0)
        return false;
    const QChar at0 = path.at(0);
    if (at0 == QLatin1Char('/'))
        return true;
    if (HostOsInfo::isWindowsHost()) {
        if (at0 == QLatin1Char('\\'))
            return true;
        // Unlike QFileInfo, this won't accept a relative path with a drive letter.
        // Such paths result in a royal mess anyway ...
        if (n >= 3 && path.at(1) == QLatin1Char(':') && at0.isLetter()
                && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\')))
            return true;
    }
    return false;
}

bool FileInfo::isPattern(const QString &str)
{
    return isPattern(QStringRef(&str));
}

bool FileInfo::isPattern(const QStringRef &str)
{
    for (int i = 0; i < str.size(); ++i) {
        const QChar ch = str.at(i);
        if (ch == QLatin1Char('*') || ch == QLatin1Char('?')
                || ch == QLatin1Char(']') || ch == QLatin1Char('[')) {
            return true;
        }
    }
    return false;
}

/**
 * Concatenates the paths \a base and \a rel.
 * Base must be an absolute path.
 * Double dots at the start of \a rel are handled.
 * This function assumes that both paths are clean, that is they don't contain
 * double slashes or redundant dot parts.
 */
QString FileInfo::resolvePath(const QString &base, const QString &rel)
{
    Q_ASSERT(isAbsolute(base));
    if (isAbsolute(rel))
        return rel;
    if (rel.size() == 1 && rel.at(0) == QLatin1Char('.'))
        return base;

    QString r = base;
    if (r.endsWith(QLatin1Char('/')))
        r.chop(1);

    QString s = rel;
    while (s.startsWith(QLatin1String("../"))) {
        s.remove(0, 3);
        int idx = r.lastIndexOf(QLatin1Char('/'));
        if (idx >= 0)
            r.truncate(idx);
    }

    r.reserve(r.length() + 1 + s.length());
    r += QLatin1Char('/');
    r += s;
    return r;
}

bool FileInfo::globMatches(const QRegExp &regexp, const QString &fileName)
{
    const QString pattern = regexp.pattern();
    // May be it's simple wildcard, i.e. "*.cpp"?
    if (pattern.startsWith(QLatin1Char('*')) && !isPattern(pattern.midRef(1))) {
        // Yes, it's rather simple to just check the extension
        return fileName.endsWith(pattern.midRef(1));
    }
    return regexp.exactMatch(fileName);
}

#if defined(Q_OS_WIN)

#include <qt_windows.h>

#define z(x) reinterpret_cast<WIN32_FILE_ATTRIBUTE_DATA*>(const_cast<FileInfo::InternalStatType*>(&x))

template<bool> struct CompileTimeAssert;
template<> struct CompileTimeAssert<true> {};

FileInfo::FileInfo(const QString &fileName)
{
    static CompileTimeAssert<
        sizeof(FileInfo::InternalStatType) == sizeof(WIN32_FILE_ATTRIBUTE_DATA)
            > internal_type_has_wrong_size;
    if (!GetFileAttributesEx(reinterpret_cast<const WCHAR*>(fileName.utf16()),
                             GetFileExInfoStandard, &m_stat))
    {
        ZeroMemory(z(m_stat), sizeof(WIN32_FILE_ATTRIBUTE_DATA));
        z(m_stat)->dwFileAttributes = INVALID_FILE_ATTRIBUTES;
    }
}

bool FileInfo::exists() const
{
    return z(m_stat)->dwFileAttributes != INVALID_FILE_ATTRIBUTES;
}

FileTime FileInfo::lastModified() const
{
    const FileTime::InternalType* ft_it;
    ft_it = reinterpret_cast<const FileTime::InternalType*>(&z(m_stat)->ftLastWriteTime);
    return FileTime(*ft_it);
}

FileTime FileInfo::lastStatusChange() const
{
    return lastModified();
}

bool FileInfo::isDir() const
{
    return z(m_stat)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
}

static QString resolveSymlinks(const QString &fileName)
{
    QFileInfo fi(fileName);
    while (fi.isSymLink())
        fi.setFile(fi.symLinkTarget());
    return fi.absoluteFilePath();
}

QString applicationDirPath()
{
    static const QString appDirPath = FileInfo::path(resolveSymlinks(QCoreApplication::applicationFilePath()));
    return appDirPath;
}

#elif defined(Q_OS_UNIX)

FileInfo::FileInfo(const QString &fileName)
{
    if (stat(fileName.toLocal8Bit(), &m_stat) == -1)
        m_stat.st_mtime = 0;
}

bool FileInfo::exists() const
{
    return m_stat.st_mtime != 0;
}

FileTime FileInfo::lastModified() const
{
    return m_stat.st_mtime;
}

FileTime FileInfo::lastStatusChange() const
{
    return m_stat.st_ctime;
}

bool FileInfo::isDir() const
{
    return S_ISDIR(m_stat.st_mode);
}

QString applicationDirPath()
{
    return QCoreApplication::applicationDirPath();
}

#endif

// adapted from qtc/plugins/vcsbase/cleandialog.cpp
bool removeFileRecursion(const QFileInfo &f, QString *errorMessage)
{
    if (!f.exists())
        return true;
    if (f.isDir()) {
        const QDir dir(f.absoluteFilePath());
        foreach(const QFileInfo &fi, dir.entryInfoList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::Hidden))
            removeFileRecursion(fi, errorMessage);
        QDir parent = f.absoluteDir();
        if (!parent.rmdir(f.fileName())) {
            errorMessage->append(Tr::tr("The directory %1 could not be deleted.").
                                 arg(QDir::toNativeSeparators(f.absoluteFilePath())));
            return false;
        }
    } else if (!QFile::remove(f.absoluteFilePath())) {
        if (!errorMessage->isEmpty())
            errorMessage->append(QLatin1Char('\n'));
        errorMessage->append(Tr::tr("The file %1 could not be deleted.").
                             arg(QDir::toNativeSeparators(f.absoluteFilePath())));
        return false;
    }
    return true;
}

bool removeDirectoryWithContents(const QString &path, QString *errorMessage)
{
    QFileInfo f(path);
    if (f.exists() && !f.isDir()) {
        *errorMessage = Tr::tr("%1 is not a directory.").arg(QDir::toNativeSeparators(path));
        return false;
    }
    return removeFileRecursion(f, errorMessage);
}

/*!
  Copies the directory specified by \a srcFilePath recursively to \a tgtFilePath.
  \a tgtFilePath will contain the target directory, which will be created. Example usage:

  \code
    QString error;
    book ok = Utils::FileUtils::copyRecursively("/foo/bar", "/foo/baz", &error);
    if (!ok)
      qDebug() << error;
  \endcode

  This will copy the contents of /foo/bar into to the baz directory under /foo,
  which will be created in the process.

  \return Whether the operation succeeded.
  \note Function was adapted from qtc/src/libs/fileutils.cpp
*/

bool copyFileRecursion(const QString &srcFilePath, const QString &tgtFilePath,
    QString *errorMessage)
{
    QFileInfo srcFileInfo(srcFilePath);
    if (srcFileInfo.isDir()) {
        QDir targetDir(tgtFilePath);
        targetDir.cdUp();
        if (!targetDir.mkpath(QFileInfo(tgtFilePath).fileName())) {
            *errorMessage = Tr::tr("The directory '%1' could not be created.")
               .arg(QDir::toNativeSeparators(tgtFilePath));
            return false;
        }
        QDir sourceDir(srcFilePath);
        QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot
            | QDir::Hidden | QDir::System);
        foreach (const QString &fileName, fileNames) {
            const QString newSrcFilePath = srcFilePath + QLatin1Char('/') + fileName;
            const QString newTgtFilePath = tgtFilePath + QLatin1Char('/') + fileName;
            if (!copyFileRecursion(newSrcFilePath, newTgtFilePath, errorMessage))
                return false;
        }
    } else {
        QFile file(srcFilePath);
        if (!file.copy(tgtFilePath)) {
            *errorMessage = Tr::tr("Could not copy file '%1' to '%2'. %3")
                .arg(QDir::toNativeSeparators(srcFilePath), QDir::toNativeSeparators(tgtFilePath),
                     file.errorString());
            return false;
        }
    }
    return true;
}

QString qbsRootPath()
{
    return QDir::cleanPath(applicationDirPath() + QLatin1String("/../"));
}

} // namespace Internal
} // namespace qbs
<|endoftext|>


<commit_before>#include "coreBlocksFactory.h"

#include <qrutils/interpreter/blocks/initialBlock.h>
#include <qrutils/interpreter/blocks/finalBlock.h>

#include "details/timerBlock.h"
#include <qrutils/interpreter/blocks/functionBlock.h>
#include <qrutils/interpreter/blocks/variableInitBlock.h>

#include <qrutils/interpreter/blocks/loopBlock.h>
#include <qrutils/interpreter/blocks/forkBlock.h>
#include <qrutils/interpreter/blocks/ifBlock.h>
#include <qrutils/interpreter/blocks/switchBlock.h>
#include <qrutils/interpreter/blocks/commentBlock.h>
#include <qrutils/interpreter/blocks/subprogramBlock.h>
#include <qrutils/interpreter/blocks/unsupportedBlock.h>

#include "details/printTextBlock.h"
#include "details/clearScreenBlock.h"

#include <commonTwoDModel/blocks/markerDownBlock.h>
#include <commonTwoDModel/blocks/markerUpBlock.h>

using namespace interpreterCore::coreBlocks;

qReal::interpretation::Block *CoreBlocksFactory::produceBlock(const qReal::Id &element)
{
	if (elementMetatypeIs(element, "InitialNode")) {
		return new qReal::interpretation::blocks::InitialBlock();
	} else if (elementMetatypeIs(element, "FinalNode")) {
		return new qReal::interpretation::blocks::FinalBlock();
	} else if (elementMetatypeIs(element, "Timer")) {
		return new details::TimerBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "CommentBlock")) {
		return new qReal::interpretation::blocks::CommentBlock;
	} else if (elementMetatypeIs(element, "IfBlock")) {
		return new qReal::interpretation::blocks::IfBlock();
	} else if (elementMetatypeIs(element, "SwitchBlock")) {
		return new qReal::interpretation::blocks::SwitchBlock();
	} else if (elementMetatypeIs(element, "Loop")) {
		return new qReal::interpretation::blocks::LoopBlock();
	} else if (elementMetatypeIs(element, "Fork")) {
		return new qReal::interpretation::blocks::ForkBlock();
	} else if (elementMetatypeIs(element, "Join")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "SendMessageThreads")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "ReceiveMessageThreads")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "Subprogram")) {
		return new qReal::interpretation::blocks::SubprogramBlock();
	} else if (elementMetatypeIs(element, "Function")) {
		return new qReal::interpretation::blocks::FunctionBlock();
	} else if (elementMetatypeIs(element, "VariableInit")) {
		return new qReal::interpretation::blocks::VariableInitBlock();
	} else if (elementMetatypeIs(element, "PrintText")) {
		return new details::PrintTextBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "ClearScreen")) {
		return new details::ClearScreenBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "MarkerDown")) {
		return new twoDModel::blocks::MarkerDownBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "MarkerUp")) {
		return new twoDModel::blocks::MarkerUpBlock(mRobotModelManager->model());
	}

	return nullptr;
}

qReal::IdList CoreBlocksFactory::providedBlocks() const
{
	return {
		id("ControlFlow")
		, id("InitialNode")
		, id("FinalNode")
		, id("Timer")
		, id("CommentBlock")
		, id("IfBlock")
		, id("SwitchBlock")
		, id("Loop")
		, id("Fork")
		, id("Join")
		, id("SendMessageThreads")
		, id("ReceiveMessageThreads")
		, id("Subprogram")
		, id("Function")
		, id("VariableInit")
		, id("ClearScreen")
		, id("PrintText")
		, id("MarkerDown")
		, id("MarkerUp")
	};
}

qReal::IdList CoreBlocksFactory::blocksToDisable() const
{
	qReal::IdList result;

	if (!mRobotModelManager->model().name().contains("TwoD")) {
		result
				<< id("MarkerDown")
				<< id("MarkerUp")
				;
	}

	return result;
}
<commit_msg>disable joins and messages in 2D model<commit_after>#include "coreBlocksFactory.h"

#include <qrutils/interpreter/blocks/initialBlock.h>
#include <qrutils/interpreter/blocks/finalBlock.h>

#include "details/timerBlock.h"
#include <qrutils/interpreter/blocks/functionBlock.h>
#include <qrutils/interpreter/blocks/variableInitBlock.h>

#include <qrutils/interpreter/blocks/loopBlock.h>
#include <qrutils/interpreter/blocks/forkBlock.h>
#include <qrutils/interpreter/blocks/ifBlock.h>
#include <qrutils/interpreter/blocks/switchBlock.h>
#include <qrutils/interpreter/blocks/commentBlock.h>
#include <qrutils/interpreter/blocks/subprogramBlock.h>
#include <qrutils/interpreter/blocks/unsupportedBlock.h>

#include "details/printTextBlock.h"
#include "details/clearScreenBlock.h"

#include <commonTwoDModel/blocks/markerDownBlock.h>
#include <commonTwoDModel/blocks/markerUpBlock.h>

using namespace interpreterCore::coreBlocks;

qReal::interpretation::Block *CoreBlocksFactory::produceBlock(const qReal::Id &element)
{
	if (elementMetatypeIs(element, "InitialNode")) {
		return new qReal::interpretation::blocks::InitialBlock();
	} else if (elementMetatypeIs(element, "FinalNode")) {
		return new qReal::interpretation::blocks::FinalBlock();
	} else if (elementMetatypeIs(element, "Timer")) {
		return new details::TimerBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "CommentBlock")) {
		return new qReal::interpretation::blocks::CommentBlock;
	} else if (elementMetatypeIs(element, "IfBlock")) {
		return new qReal::interpretation::blocks::IfBlock();
	} else if (elementMetatypeIs(element, "SwitchBlock")) {
		return new qReal::interpretation::blocks::SwitchBlock();
	} else if (elementMetatypeIs(element, "Loop")) {
		return new qReal::interpretation::blocks::LoopBlock();
	} else if (elementMetatypeIs(element, "Fork")) {
		return new qReal::interpretation::blocks::ForkBlock();
	} else if (elementMetatypeIs(element, "Join")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "SendMessageThreads")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "ReceiveMessageThreads")) {
		return new qReal::interpretation::blocks::UnsupportedBlock();
	} else if (elementMetatypeIs(element, "Subprogram")) {
		return new qReal::interpretation::blocks::SubprogramBlock();
	} else if (elementMetatypeIs(element, "Function")) {
		return new qReal::interpretation::blocks::FunctionBlock();
	} else if (elementMetatypeIs(element, "VariableInit")) {
		return new qReal::interpretation::blocks::VariableInitBlock();
	} else if (elementMetatypeIs(element, "PrintText")) {
		return new details::PrintTextBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "ClearScreen")) {
		return new details::ClearScreenBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "MarkerDown")) {
		return new twoDModel::blocks::MarkerDownBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "MarkerUp")) {
		return new twoDModel::blocks::MarkerUpBlock(mRobotModelManager->model());
	}

	return nullptr;
}

qReal::IdList CoreBlocksFactory::providedBlocks() const
{
	return {
		id("ControlFlow")
		, id("InitialNode")
		, id("FinalNode")
		, id("Timer")
		, id("CommentBlock")
		, id("IfBlock")
		, id("SwitchBlock")
		, id("Loop")
		, id("Fork")
		, id("Join")
		, id("SendMessageThreads")
		, id("ReceiveMessageThreads")
		, id("Subprogram")
		, id("Function")
		, id("VariableInit")
		, id("ClearScreen")
		, id("PrintText")
		, id("MarkerDown")
		, id("MarkerUp")
	};
}

qReal::IdList CoreBlocksFactory::blocksToDisable() const
{
	qReal::IdList result;

	if (!mRobotModelManager->model().name().contains("TwoD")) {
		result
				<< id("MarkerDown")
				<< id("MarkerUp");
	} else {
		result
				<< id("Join")
				<< id("SendMessageThreads")
				<< id("ReceiveMessageThreads");
	}

	return result;
}
<|endoftext|>