<commit_before>#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Lex/Preprocessor.h"

#include <iostream>
#include <sstream>

using namespace clang;
using namespace clang::tooling;

std::string escapeString(std::string const& input)
{
    std::ostringstream ss;
    for (auto c : input)
    {
        switch (c)
        {
        case '\\':
            ss << "\\\\";
            break;
        case '"':
            ss << "\\\"";
            break;
        case '/':
            ss << "\\/";
            break;
        case '\b':
            ss << "\\b";
            break;
        case '\f':
            ss << "\\f";
            break;
        case '\n':
            ss << "\\n";
            break;
        case '\r':
            ss << "\\r";
            break;
        case '\t':
            ss << "\\t";
            break;
        default:
            ss << c;
            break;
        }
    }
    return ss.str();
}

class DumpVisitor : public RecursiveASTVisitor<DumpVisitor>
{
  public:
    explicit DumpVisitor(ASTContext* context) : context(context) {}

    void TraverseNewScope(Stmt* stmt)
    {
        if (!isa<CompoundStmt>(stmt))
        {
            depth++;
            WriteDepth();
        }

        TraverseStmt(stmt);

        if (!isa<CompoundStmt>(stmt))
        {
            std::cout << "\n";
            depth--;
        }
    }

    bool TraverseStmt(Stmt* stmt)
    {
        if (!stmt)
            return RecursiveASTVisitor::TraverseStmt(stmt);

        if (auto compoundStmt = dyn_cast<CompoundStmt>(stmt))
        {
            depth++;
            for (auto stmt : compoundStmt->body())
            {
                if (!stmt)
                    continue;

                WriteDepth();
                TraverseStmt(stmt);
                std::cout << "\n";
            }
            depth--;
            return true;
        }

        if (auto callExpr = dyn_cast<CallExpr>(stmt))
        {
            TraverseStmt(callExpr->getCallee());
            bool first = true;
            std::cout << "(";
            for (auto param : callExpr->arguments())
            {
                if (!first)
                    std::cout << ", ";

                TraverseStmt(param);
                first = false;
            }
            std::cout << ")";
            return true;
        }

        if (auto ifStmt = dyn_cast<IfStmt>(stmt))
        {
            std::cout << "if ";
            TraverseStmt(ifStmt->getCond());
            std::cout << " then\n";

            TraverseNewScope(ifStmt->getThen());

            WriteDepth();
            std::cout << "end";
            return true;
        }

        if (auto doStmt = dyn_cast<DoStmt>(stmt))
        {
            std::cout << "repeat\n";

            TraverseNewScope(doStmt->getBody());

            WriteDepth();
            std::cout << "until not (";
            TraverseStmt(doStmt->getCond());
            std::cout << ")";
            return true;
        }

        if (auto arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(stmt))
        {
            TraverseStmt(arraySubscriptExpr->getBase());
            std::cout << "[(";
            TraverseStmt(arraySubscriptExpr->getIdx());
            // Add 1 to compensate for 1-based indexing
            std::cout << ")+1]";
            return true;
        }

        if (auto unaryOperator = dyn_cast<UnaryOperator>(stmt))
        {
            auto opcode = unaryOperator->getOpcode();
            switch (opcode)
            {
            case UO_Minus:
                std::cout << "-";
                TraverseStmt(unaryOperator->getSubExpr());
                break;
            case UO_Not:
                std::cout << "not ";
                TraverseStmt(unaryOperator->getSubExpr());
                break;
            case UO_LNot:
                std::cout << "bit._not(";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << ")";
                break;
            default:
                break;
            }
            return true;
        }

        if (auto binaryOperator = dyn_cast<BinaryOperator>(stmt))
        {
            if (binaryOperator->isCompoundAssignmentOp())
            {
                TraverseStmt(binaryOperator->getLHS());
                std::cout << " = ";
            }

            auto opcode = binaryOperator->getOpcode();

            // Lua doesn't have native bitwise operators, so these need to be lowered
            // to function calls
            bool normalBinaryOperator = false;
            switch (opcode)
            {
            case BO_Shl:
            case BO_ShlAssign:
                std::cout << "bit._shl(";
                break;
            case BO_Shr:
            case BO_ShrAssign:
                std::cout << "bit._shr(";
                break;
            case BO_And:
            case BO_AndAssign:
                std::cout << "bit._and(";
                break;
            case BO_Xor:
            case BO_XorAssign:
                std::cout << "bit._xor(";
                break;
            case BO_Or:
            case BO_OrAssign:
                std::cout << "bit._or(";
                break;
            default:
                normalBinaryOperator = true;
                break;
            }

            if (!normalBinaryOperator)
            {
                TraverseStmt(binaryOperator->getLHS());
                std::cout << ", ";
                TraverseStmt(binaryOperator->getRHS());
                std::cout << ")";
                return true;
            }

            TraverseStmt(binaryOperator->getLHS());
            switch (opcode)
            {
            case BO_Mul:
            case BO_MulAssign:
                std::cout << " * ";
                break;
            case BO_Div:
            case BO_DivAssign:
                std::cout << " / ";
                break;
            case BO_Rem:
            case BO_RemAssign:
                std::cout << " % ";
                break;
            case BO_Add:
            case BO_AddAssign:
                std::cout << " + ";
                break;
            case BO_Sub:
            case BO_SubAssign:
                std::cout << " - ";
                break;
            case BO_LT:
                std::cout << " < ";
                break;
            case BO_GT:
                std::cout << " > ";
                break;
            case BO_LE:
                std::cout << " <= ";
                break;
            case BO_GE:
                std::cout << " >= ";
                break;
            case BO_EQ:
                std::cout << " == ";
                break;
            case BO_NE:
                std::cout << " != ";
                break;
            case BO_LAnd:
                std::cout << " and ";
                break;
            case BO_LOr:
                std::cout << " or ";
                break;
            case BO_Comma:
                std::cout << ", ";
                break;
            case BO_Assign:
                std::cout << " = ";
                break;
            default:
                break;
            }
            TraverseStmt(binaryOperator->getRHS());

            return true;
        }

        if (auto parenExpr = dyn_cast<ParenExpr>(stmt))
        {
            std::cout << "(";
            TraverseStmt(parenExpr->getSubExpr());
            std::cout << ")";
            return true;
        }

        if (auto declStmt = dyn_cast<DeclStmt>(stmt))
        {
            bool first = true;

            std::vector<Expr*> initExprs;
            for (auto decl : declStmt->decls())
            {
                if (first)
                    std::cout << "local ";
                else
                    std::cout << ", ";

                if (auto varDecl = dyn_cast<VarDecl>(decl))
                {
                    auto name = varDecl->getNameAsString();
                    if (name.empty())
                        continue;

                    std::cout << name;

                    if (varDecl->hasInit())
                        initExprs.push_back(varDecl->getInit());
                    else
                        initExprs.push_back(nullptr);
                }
                else
                {
                    TraverseDecl(decl);
                }
                first = false;
            }

            auto notNullPredicate = [](Expr* e) { return e != nullptr; };
            if (initExprs.size() &&
                std::any_of(initExprs.begin(), initExprs.end(), notNullPredicate))
            {
                std::cout << " = ";
                bool first = true;
                for (auto expr : initExprs)
                {
                    if (!first)
                        std::cout << ", ";

                    if (expr == nullptr)
                        std::cout << "nil";
                    else
                        TraverseStmt(expr);

                    first = false;
                }
            }

            return true;
        }

        if (auto initListExpr = dyn_cast<InitListExpr>(stmt))
        {
            bool first = true;
            std::cout << "{";
            for (auto expr : *initListExpr)
            {
                if (!first)
                    std::cout << ", ";

                TraverseStmt(expr);
                first = false;
            }
            std::cout << "}";
            return true;
        }

        return RecursiveASTVisitor::TraverseStmt(stmt);
    }

    bool TraverseDecl(Decl* decl)
    {
        if (auto functionDecl = dyn_cast<FunctionDecl>(decl))
        {
            // Skip over function declarations
            if (!functionDecl->doesThisDeclarationHaveABody())
                return true;

            if (functionDecl->isMain())
                foundMain = true;

            std::cout << "\n";

            WriteDepth();
            std::cout << "function " << functionDecl->getNameAsString();
            std::cout << "(";
            bool first = true;
            for (auto param : functionDecl->params())
            {
                if (!first)
                    std::cout << ", ";

                std::cout << param->getNameAsString();
                first = false;
            }
            std::cout << ")";
            std::cout << "\n";

            if (functionDecl->hasBody())
                TraverseStmt(functionDecl->getBody());

            WriteDepth();
            std::cout << "end\n";
            return true;
        }

        // Duplicated from TraverseStmt: required to catch
        // unhandled var decls (see: global scope)
        if (auto varDecl = dyn_cast<VarDecl>(decl))
        {
            auto name = varDecl->getNameAsString();
            if (name.empty())
                return true;

            std::cout << name;

            if (varDecl->hasInit())
            {
                std::cout << " = ";
                TraverseStmt(varDecl->getInit());
            }

            return true;
        }

        return RecursiveASTVisitor::TraverseDecl(decl);
    }

    bool VisitStmt(Stmt* stmt)
    {
        if (auto stringLiteral = dyn_cast<StringLiteral>(stmt))
        {
            std::cout << '"' << escapeString(stringLiteral->getString().str()) << '"';
            return true;
        }

        if (auto integerLiteral = dyn_cast<IntegerLiteral>(stmt))
        {
            std::cout << integerLiteral->getValue().toString(10, true);
            return true;
        }

        if (auto floatingLiteral = dyn_cast<FloatingLiteral>(stmt))
        {
            std::cout << floatingLiteral->getValueAsApproximateDouble();
            return true;
        }

        if (auto declRefExpr = dyn_cast<DeclRefExpr>(stmt))
        {
            std::cout << declRefExpr->getDecl()->getNameAsString();
            return true;
        }

        if (auto returnStmt = dyn_cast<ReturnStmt>(stmt))
        {
            std::cout << "return";
            if (returnStmt->getRetValue())
                std::cout << " ";

            return true;
        }

        return true;
    }

    void WriteDepth()
    {
        for (uint32_t i = 0; i < depth * 4; ++i)
            std::cout << ' ';
    }

    bool HasFoundMain() { return foundMain; }

  private:
    ASTContext* context;
    uint32_t depth = 0;
    bool foundMain = false;
};

class DumpConsumer : public ASTConsumer
{
  public:
    explicit DumpConsumer(CompilerInstance& compiler)
        : visitor(&compiler.getASTContext()), sourceManager(compiler.getSourceManager())
    {
    }

    virtual void HandleTranslationUnit(ASTContext& context) override
    {
        auto decls = context.getTranslationUnitDecl()->decls();
        for (auto decl : decls)
        {
            auto const& fileId = sourceManager.getFileID(decl->getLocation());
            if (fileId != sourceManager.getMainFileID())
                continue;

            visitor.TraverseDecl(decl);
        }

        // Pass args to main(), and call it
        if (visitor.HasFoundMain())
        {
            std::cout << "return (function() "
                      << "table.insert(arg, 1, arg[0]); "
                      << "return main(#arg, arg) end)()\n";
        }
    }

  private:
    DumpVisitor visitor;
    SourceManager& sourceManager;
};

class DumpAction : public ASTFrontendAction
{
  public:
    virtual bool BeginSourceFileAction(CompilerInstance& compiler, StringRef) override
    {
        std::cout << "dofile \"shim/lua/bitwise.lua\"\n";

        class PrintIncludes : public PPCallbacks
        {
        public:
            PrintIncludes(SourceManager& sourceManager)
                : sourceManager(sourceManager)
            {
            }

            virtual void InclusionDirective(SourceLocation location, Token const&, StringRef fileName,
                                            bool isAngled, CharSourceRange, FileEntry const*,
                                            StringRef, StringRef, Module const*) override
            {
                // Skip over includes that are not from the main file
                if (sourceManager.getFileID(location) != sourceManager.getMainFileID())
                    return;

                auto newFileName = fileName.str();
                newFileName = newFileName.substr(0, newFileName.find_last_of('.'));
                newFileName += ".lua";

                if (isAngled)
                    newFileName = "shim/lua/" + newFileName;

                std::cout << "dofile \"" << newFileName << "\"\n";
            }

            SourceManager& sourceManager;
        };

        std::unique_ptr<PrintIncludes> callback(
            new PrintIncludes(compiler.getSourceManager()));
        auto& preprocessor = compiler.getPreprocessor();
        preprocessor.addPPCallbacks(std::move(callback));

        return true;
    }

    virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& compiler,
                                                           llvm::StringRef inFile) override
    {
        return std::unique_ptr<ASTConsumer>(new DumpConsumer(compiler));
    }
};

int main(int argc, char const** argv)
{
    llvm::cl::OptionCategory category("irradiant");
    // Ugly hack to get around there being no easy way of adding arguments
    std::vector<char const*> arguments(argv, argv + argc);
    if (strcmp(arguments.back(), "--") == 0)
        arguments.pop_back();
    arguments.push_back("-extra-arg=-fno-builtin");
    arguments.push_back("-extra-arg=-nostdlib");
    arguments.push_back("-extra-arg=-nostdinc");
    arguments.push_back("-extra-arg=-Ishim/c");
    arguments.push_back("--");

    int size = arguments.size();
    CommonOptionsParser parser(size, arguments.data(), category);

    ClangTool tool(parser.getCompilations(), parser.getSourcePathList());
    return tool.run(newFrontendActionFactory<DumpAction>().get());
}
<commit_msg>Added support for pre/post increment/decrement operators<commit_after>#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Lex/Preprocessor.h"

#include <iostream>
#include <sstream>

using namespace clang;
using namespace clang::tooling;

std::string escapeString(std::string const& input)
{
    std::ostringstream ss;
    for (auto c : input)
    {
        switch (c)
        {
        case '\\':
            ss << "\\\\";
            break;
        case '"':
            ss << "\\\"";
            break;
        case '/':
            ss << "\\/";
            break;
        case '\b':
            ss << "\\b";
            break;
        case '\f':
            ss << "\\f";
            break;
        case '\n':
            ss << "\\n";
            break;
        case '\r':
            ss << "\\r";
            break;
        case '\t':
            ss << "\\t";
            break;
        default:
            ss << c;
            break;
        }
    }
    return ss.str();
}

class DumpVisitor : public RecursiveASTVisitor<DumpVisitor>
{
  public:
    explicit DumpVisitor(ASTContext* context) : context(context) {}

    void TraverseNewScope(Stmt* stmt)
    {
        if (!isa<CompoundStmt>(stmt))
        {
            depth++;
            WriteDepth();
        }

        TraverseStmt(stmt);

        if (!isa<CompoundStmt>(stmt))
        {
            std::cout << "\n";
            depth--;
        }
    }

    bool TraverseStmt(Stmt* stmt)
    {
        if (!stmt)
            return RecursiveASTVisitor::TraverseStmt(stmt);

        if (auto compoundStmt = dyn_cast<CompoundStmt>(stmt))
        {
            depth++;
            for (auto stmt : compoundStmt->body())
            {
                if (!stmt)
                    continue;

                WriteDepth();
                // HACK: Fix precedence issues with closures being called straight away
                if (isa<UnaryOperator>(stmt))
                    std::cout << ";";

                TraverseStmt(stmt);
                std::cout << "\n";
            }
            depth--;
            return true;
        }

        if (auto callExpr = dyn_cast<CallExpr>(stmt))
        {
            TraverseStmt(callExpr->getCallee());
            bool first = true;
            std::cout << "(";
            for (auto param : callExpr->arguments())
            {
                if (!first)
                    std::cout << ", ";

                TraverseStmt(param);
                first = false;
            }
            std::cout << ")";
            return true;
        }

        if (auto ifStmt = dyn_cast<IfStmt>(stmt))
        {
            std::cout << "if ";
            TraverseStmt(ifStmt->getCond());
            std::cout << " then\n";

            TraverseNewScope(ifStmt->getThen());

            WriteDepth();
            std::cout << "end";
            return true;
        }

        if (auto doStmt = dyn_cast<DoStmt>(stmt))
        {
            std::cout << "repeat\n";

            TraverseNewScope(doStmt->getBody());

            WriteDepth();
            std::cout << "until not (";
            TraverseStmt(doStmt->getCond());
            std::cout << ")";
            return true;
        }

        if (auto arraySubscriptExpr = dyn_cast<ArraySubscriptExpr>(stmt))
        {
            TraverseStmt(arraySubscriptExpr->getBase());
            std::cout << "[(";
            TraverseStmt(arraySubscriptExpr->getIdx());
            // Add 1 to compensate for 1-based indexing
            std::cout << ")+1]";
            return true;
        }

        if (auto unaryOperator = dyn_cast<UnaryOperator>(stmt))
        {
            auto opcode = unaryOperator->getOpcode();
            switch (opcode)
            {
            case UO_Minus:
                std::cout << "-";
                TraverseStmt(unaryOperator->getSubExpr());
                break;
            case UO_Not:
                std::cout << "not ";
                TraverseStmt(unaryOperator->getSubExpr());
                break;
            case UO_LNot:
                std::cout << "bit._not(";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << ")";
                break;
            // Lower pre/post operators to functions
            // Pre: (function() expr = expr OP 1; return expr)()
            // Post: (function() local _ = expr; expr = expr OP 1; return _)()
            case UO_PreDec:
                std::cout << "(function() ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " - 1; return ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " end)()";
                break;
            case UO_PreInc:
                std::cout << "(function() ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " + 1; return ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " end)()";
                break;
            case UO_PostDec:
                std::cout << "(function() local _ = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << "; ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " - 1; return _ end)()";
                break;
            case UO_PostInc:
                std::cout << "(function() local _ = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << "; ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " = ";
                TraverseStmt(unaryOperator->getSubExpr());
                std::cout << " + 1; return _ end)()";
                break;
            default:
                break;
            }
            return true;
        }

        if (auto binaryOperator = dyn_cast<BinaryOperator>(stmt))
        {
            if (binaryOperator->isCompoundAssignmentOp())
            {
                TraverseStmt(binaryOperator->getLHS());
                std::cout << " = ";
            }

            auto opcode = binaryOperator->getOpcode();

            // Lua doesn't have native bitwise operators, so these need to be lowered
            // to function calls
            bool normalBinaryOperator = false;
            switch (opcode)
            {
            case BO_Shl:
            case BO_ShlAssign:
                std::cout << "bit._shl(";
                break;
            case BO_Shr:
            case BO_ShrAssign:
                std::cout << "bit._shr(";
                break;
            case BO_And:
            case BO_AndAssign:
                std::cout << "bit._and(";
                break;
            case BO_Xor:
            case BO_XorAssign:
                std::cout << "bit._xor(";
                break;
            case BO_Or:
            case BO_OrAssign:
                std::cout << "bit._or(";
                break;
            default:
                normalBinaryOperator = true;
                break;
            }

            if (!normalBinaryOperator)
            {
                TraverseStmt(binaryOperator->getLHS());
                std::cout << ", ";
                TraverseStmt(binaryOperator->getRHS());
                std::cout << ")";
                return true;
            }

            TraverseStmt(binaryOperator->getLHS());
            switch (opcode)
            {
            case BO_Mul:
            case BO_MulAssign:
                std::cout << " * ";
                break;
            case BO_Div:
            case BO_DivAssign:
                std::cout << " / ";
                break;
            case BO_Rem:
            case BO_RemAssign:
                std::cout << " % ";
                break;
            case BO_Add:
            case BO_AddAssign:
                std::cout << " + ";
                break;
            case BO_Sub:
            case BO_SubAssign:
                std::cout << " - ";
                break;
            case BO_LT:
                std::cout << " < ";
                break;
            case BO_GT:
                std::cout << " > ";
                break;
            case BO_LE:
                std::cout << " <= ";
                break;
            case BO_GE:
                std::cout << " >= ";
                break;
            case BO_EQ:
                std::cout << " == ";
                break;
            case BO_NE:
                std::cout << " != ";
                break;
            case BO_LAnd:
                std::cout << " and ";
                break;
            case BO_LOr:
                std::cout << " or ";
                break;
            case BO_Comma:
                std::cout << ", ";
                break;
            case BO_Assign:
                std::cout << " = ";
                break;
            default:
                break;
            }
            TraverseStmt(binaryOperator->getRHS());

            return true;
        }

        if (auto parenExpr = dyn_cast<ParenExpr>(stmt))
        {
            std::cout << "(";
            TraverseStmt(parenExpr->getSubExpr());
            std::cout << ")";
            return true;
        }

        if (auto declStmt = dyn_cast<DeclStmt>(stmt))
        {
            bool first = true;

            std::vector<Expr*> initExprs;
            for (auto decl : declStmt->decls())
            {
                if (first)
                    std::cout << "local ";
                else
                    std::cout << ", ";

                if (auto varDecl = dyn_cast<VarDecl>(decl))
                {
                    auto name = varDecl->getNameAsString();
                    if (name.empty())
                        continue;

                    std::cout << name;

                    if (varDecl->hasInit())
                        initExprs.push_back(varDecl->getInit());
                    else
                        initExprs.push_back(nullptr);
                }
                else
                {
                    TraverseDecl(decl);
                }
                first = false;
            }

            auto notNullPredicate = [](Expr* e) { return e != nullptr; };
            if (initExprs.size() &&
                std::any_of(initExprs.begin(), initExprs.end(), notNullPredicate))
            {
                std::cout << " = ";
                bool first = true;
                for (auto expr : initExprs)
                {
                    if (!first)
                        std::cout << ", ";

                    if (expr == nullptr)
                        std::cout << "nil";
                    else
                        TraverseStmt(expr);

                    first = false;
                }
            }

            return true;
        }

        if (auto initListExpr = dyn_cast<InitListExpr>(stmt))
        {
            bool first = true;
            std::cout << "{";
            for (auto expr : *initListExpr)
            {
                if (!first)
                    std::cout << ", ";

                TraverseStmt(expr);
                first = false;
            }
            std::cout << "}";
            return true;
        }

        return RecursiveASTVisitor::TraverseStmt(stmt);
    }

    bool TraverseDecl(Decl* decl)
    {
        if (auto functionDecl = dyn_cast<FunctionDecl>(decl))
        {
            // Skip over function declarations
            if (!functionDecl->doesThisDeclarationHaveABody())
                return true;

            if (functionDecl->isMain())
                foundMain = true;

            std::cout << "\n";

            WriteDepth();
            std::cout << "function " << functionDecl->getNameAsString();
            std::cout << "(";
            bool first = true;
            for (auto param : functionDecl->params())
            {
                if (!first)
                    std::cout << ", ";

                std::cout << param->getNameAsString();
                first = false;
            }
            std::cout << ")";
            std::cout << "\n";

            if (functionDecl->hasBody())
                TraverseStmt(functionDecl->getBody());

            WriteDepth();
            std::cout << "end\n";
            return true;
        }

        // Duplicated from TraverseStmt: required to catch
        // unhandled var decls (see: global scope)
        if (auto varDecl = dyn_cast<VarDecl>(decl))
        {
            auto name = varDecl->getNameAsString();
            if (name.empty())
                return true;

            std::cout << name;

            if (varDecl->hasInit())
            {
                std::cout << " = ";
                TraverseStmt(varDecl->getInit());
            }

            return true;
        }

        return RecursiveASTVisitor::TraverseDecl(decl);
    }

    bool VisitStmt(Stmt* stmt)
    {
        if (auto stringLiteral = dyn_cast<StringLiteral>(stmt))
        {
            std::cout << '"' << escapeString(stringLiteral->getString().str()) << '"';
            return true;
        }

        if (auto integerLiteral = dyn_cast<IntegerLiteral>(stmt))
        {
            std::cout << integerLiteral->getValue().toString(10, true);
            return true;
        }

        if (auto floatingLiteral = dyn_cast<FloatingLiteral>(stmt))
        {
            std::cout << floatingLiteral->getValueAsApproximateDouble();
            return true;
        }

        if (auto declRefExpr = dyn_cast<DeclRefExpr>(stmt))
        {
            std::cout << declRefExpr->getDecl()->getNameAsString();
            return true;
        }

        if (auto returnStmt = dyn_cast<ReturnStmt>(stmt))
        {
            std::cout << "return";
            if (returnStmt->getRetValue())
                std::cout << " ";

            return true;
        }

        return true;
    }

    void WriteDepth()
    {
        for (uint32_t i = 0; i < depth * 4; ++i)
            std::cout << ' ';
    }

    bool HasFoundMain() { return foundMain; }

  private:
    ASTContext* context;
    uint32_t depth = 0;
    bool foundMain = false;
};

class DumpConsumer : public ASTConsumer
{
  public:
    explicit DumpConsumer(CompilerInstance& compiler)
        : visitor(&compiler.getASTContext()), sourceManager(compiler.getSourceManager())
    {
    }

    virtual void HandleTranslationUnit(ASTContext& context) override
    {
        auto decls = context.getTranslationUnitDecl()->decls();
        for (auto decl : decls)
        {
            auto const& fileId = sourceManager.getFileID(decl->getLocation());
            if (fileId != sourceManager.getMainFileID())
                continue;

            visitor.TraverseDecl(decl);
        }

        // Pass args to main(), and call it
        if (visitor.HasFoundMain())
        {
            std::cout << "return (function() "
                      << "table.insert(arg, 1, arg[0]); "
                      << "return main(#arg, arg) end)()\n";
        }
    }

  private:
    DumpVisitor visitor;
    SourceManager& sourceManager;
};

class DumpAction : public ASTFrontendAction
{
  public:
    virtual bool BeginSourceFileAction(CompilerInstance& compiler, StringRef) override
    {
        std::cout << "dofile \"shim/lua/bitwise.lua\"\n";

        class PrintIncludes : public PPCallbacks
        {
        public:
            PrintIncludes(SourceManager& sourceManager)
                : sourceManager(sourceManager)
            {
            }

            virtual void InclusionDirective(SourceLocation location, Token const&, StringRef fileName,
                                            bool isAngled, CharSourceRange, FileEntry const*,
                                            StringRef, StringRef, Module const*) override
            {
                // Skip over includes that are not from the main file
                if (sourceManager.getFileID(location) != sourceManager.getMainFileID())
                    return;

                auto newFileName = fileName.str();
                newFileName = newFileName.substr(0, newFileName.find_last_of('.'));
                newFileName += ".lua";

                if (isAngled)
                    newFileName = "shim/lua/" + newFileName;

                std::cout << "dofile \"" << newFileName << "\"\n";
            }

            SourceManager& sourceManager;
        };

        std::unique_ptr<PrintIncludes> callback(
            new PrintIncludes(compiler.getSourceManager()));
        auto& preprocessor = compiler.getPreprocessor();
        preprocessor.addPPCallbacks(std::move(callback));

        return true;
    }

    virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& compiler,
                                                           llvm::StringRef inFile) override
    {
        return std::unique_ptr<ASTConsumer>(new DumpConsumer(compiler));
    }
};

int main(int argc, char const** argv)
{
    llvm::cl::OptionCategory category("irradiant");
    // Ugly hack to get around there being no easy way of adding arguments
    std::vector<char const*> arguments(argv, argv + argc);
    if (strcmp(arguments.back(), "--") == 0)
        arguments.pop_back();
    arguments.push_back("-extra-arg=-fno-builtin");
    arguments.push_back("-extra-arg=-nostdlib");
    arguments.push_back("-extra-arg=-nostdinc");
    arguments.push_back("-extra-arg=-Ishim/c");
    arguments.push_back("--");

    int size = arguments.size();
    CommonOptionsParser parser(size, arguments.data(), category);

    ClangTool tool(parser.getCompilations(), parser.getSourcePathList());
    return tool.run(newFrontendActionFactory<DumpAction>().get());
}
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/VIEW/DIALOGS/advancedOptionsDialog.h>

#include <qfiledialog.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <qcheckbox.h>

namespace BALL
{
	namespace VIEW
	{

		AdvancedOptionsDialog::AdvancedOptionsDialog(QWidget* parent, const char* name)
			:AdvancedOptions( parent, name )
		{
		}

		AdvancedOptionsDialog::~AdvancedOptionsDialog()
		{
		}

		void AdvancedOptionsDialog::browseParameterFiles()
		{
			// look up the full path of the parameter file
			Path p;
			String filename = p.find(getFilename());
			if (filename == "")
			{
				filename = getFilename();
			}
			QString tmp = filename.c_str();
			QString result = QFileDialog::getOpenFileName(tmp, "*.ini", 0, "Select an AMBER parameter file");
			if (!result.isEmpty())
			{
				// store the new filename in the lineedit field
				setFilename(String(result.ascii()));
			}
		}

		void AdvancedOptionsDialog::resetOptions()
		{
			nonbonded_cutoff_line_edit->setText("20.000000");
			vdw_cutoff_line_edit->setText("15.000000");
			vdw_cuton_line_edit->setText("13.000000");
			electrostatic_cutoff_line_edit->setText("15.000000");
			electrostatic_cuton_line_edit->setText("13.000000");
			scaling_electrostatic_1_4_line_edit->setText("2.000000");
			scaling_vdw_1_4_line_edit->setText("2.000000");

			distance_button->setChecked(false);
			constant_button->setChecked(true);
			assign_charges_checkBox->setChecked(true);
			assign_typenames_checkBox->setChecked(true);
			assign_types_checkBox->setChecked(true);
			overwrite_charges_checkBox->setChecked(true);
			overwrite_typenames_checkBox->setChecked(false);
		}

		const String& AdvancedOptionsDialog::getFilename() const
		{
			static String filename;
			filename = parameter_file_edit->text().ascii();
			return filename;
		}

		void AdvancedOptionsDialog::setFilename(const String& filename)
		{
			parameter_file_edit->setText(filename.c_str());
			parameter_file_edit->update();
		}
/*//experimental
		void AdvancedOptionsDialog::setNonbondedCutoff(float nonbonded_cutoff)
		{
			nonbonded_cutoff_line_edit->setText((String) nonbonded_cutoff);
		}
//experimtental
*/
		bool AdvancedOptionsDialog::getUseDistanceDependentDC() const
		{
			return distance_button->isChecked();
		}

		float AdvancedOptionsDialog::getNonbondedCutoff()
		{
			QString nonbondcut = nonbonded_cutoff_line_edit->text().ascii();
			float nonbond = nonbondcut.toFloat();
			return nonbond;
		}

		float AdvancedOptionsDialog::getVdwCutoff()
		{
			QString vdwcut = vdw_cutoff_line_edit->text().ascii();
			float vdw = vdwcut.toFloat();
			return vdw;
		}

		float AdvancedOptionsDialog::getVdwCuton()
		{
			QString vdwcut = vdw_cuton_line_edit->text().ascii();
			float vdw = vdwcut.toFloat();
			return vdw;
		}

		float AdvancedOptionsDialog::getElectrostaticCutoff()
		{
			QString elcut = electrostatic_cutoff_line_edit->text().ascii();
			float el = elcut.toFloat();
			return el;
		}

		float AdvancedOptionsDialog::getElectrostaticCuton()
		{
			QString elcut = electrostatic_cuton_line_edit->text().ascii();
			float el = elcut.toFloat();
			return el;
		}

		float AdvancedOptionsDialog::getScalingElectrostatic_1_4()
		{
			QString scaleel = scaling_electrostatic_1_4_line_edit->text().ascii();
			float scale = scaleel.toFloat();
			return scale;
		}

		float AdvancedOptionsDialog::getScalingVdw_1_4()
		{
			QString scalevdw = scaling_vdw_1_4_line_edit->text().ascii();
			float scale = scalevdw.toFloat();
			return scale;
		}

		bool AdvancedOptionsDialog::getAssignCharges()
		{
			return assign_charges_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getAssignTypenames()
		{
			return assign_typenames_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getAssignTypes()
		{
			return assign_types_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getOverwriteCharges()
		{
			return overwrite_charges_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getOverwriteTypenames()
		{
			return overwrite_typenames_checkBox->isChecked();
		}
		//function to restore previously changed options
		void AdvancedOptionsDialog::setOptions(float nonbonded_cutoff, float vdw_cutoff, float vdw_cuton, float electrostatic_cutoff, float electrostatic_cuton,
									    float scaling_electrostatic_1_4, float scaling_vdw_1_4, bool use_dddc, bool assign_charges,
									    bool assign_typenames, bool assign_types, bool overwrite_charges, bool overwrite_typenames)
		{
			nonbonded_cutoff_line_edit->setText(String(nonbonded_cutoff).c_str());
			vdw_cutoff_line_edit->setText(String(vdw_cutoff).c_str());
			vdw_cuton_line_edit->setText(String(vdw_cuton).c_str());
			electrostatic_cutoff_line_edit->setText(String(electrostatic_cutoff).c_str());
			electrostatic_cuton_line_edit->setText(String(electrostatic_cuton).c_str());
			scaling_electrostatic_1_4_line_edit->setText(String(scaling_electrostatic_1_4).c_str());
			scaling_vdw_1_4_line_edit->setText(String(scaling_vdw_1_4).c_str());

			distance_button->setChecked(use_dddc);
			assign_charges_checkBox->setChecked(assign_charges);
			assign_typenames_checkBox->setChecked(assign_typenames);
			assign_types_checkBox->setChecked(assign_types);
			overwrite_charges_checkBox->setChecked(overwrite_charges);
			overwrite_typenames_checkBox->setChecked(overwrite_typenames);
		}

	}//namespace View
}//namespace Ball
<commit_msg>fixed potential problem with QString->String conversion<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/VIEW/DIALOGS/advancedOptionsDialog.h>

#include <qfiledialog.h>
#include <qlineedit.h>
#include <qradiobutton.h>
#include <qcheckbox.h>

namespace BALL
{
	namespace VIEW
	{

		AdvancedOptionsDialog::AdvancedOptionsDialog(QWidget* parent, const char* name)
			:AdvancedOptions( parent, name )
		{
		}

		AdvancedOptionsDialog::~AdvancedOptionsDialog()
		{
		}

		void AdvancedOptionsDialog::browseParameterFiles()
		{
			// look up the full path of the parameter file
			Path p;
			String filename = p.find(getFilename());
			if (filename == "")
			{
				filename = getFilename();
			}
			QString tmp = filename.c_str();
			QString result = QFileDialog::getOpenFileName(tmp, "*.ini", 0, "Select an AMBER parameter file");
			if (!result.isEmpty())
			{
				// store the new filename in the lineedit field
				setFilename(String(result.ascii()));
			}
		}

		void AdvancedOptionsDialog::resetOptions()
		{
			nonbonded_cutoff_line_edit->setText("20.000000");
			vdw_cutoff_line_edit->setText("15.000000");
			vdw_cuton_line_edit->setText("13.000000");
			electrostatic_cutoff_line_edit->setText("15.000000");
			electrostatic_cuton_line_edit->setText("13.000000");
			scaling_electrostatic_1_4_line_edit->setText("2.000000");
			scaling_vdw_1_4_line_edit->setText("2.000000");

			distance_button->setChecked(false);
			constant_button->setChecked(true);
			assign_charges_checkBox->setChecked(true);
			assign_typenames_checkBox->setChecked(true);
			assign_types_checkBox->setChecked(true);
			overwrite_charges_checkBox->setChecked(true);
			overwrite_typenames_checkBox->setChecked(false);
		}

		const String& AdvancedOptionsDialog::getFilename() const
		{
			static String filename;
			filename = parameter_file_edit->text().ascii();
			return filename;
		}

		void AdvancedOptionsDialog::setFilename(const String& filename)
		{
			parameter_file_edit->setText(filename.c_str());
			parameter_file_edit->update();
		}
/*//experimental
		void AdvancedOptionsDialog::setNonbondedCutoff(float nonbonded_cutoff)
		{
			nonbonded_cutoff_line_edit->setText((String) nonbonded_cutoff);
		}
//experimtental
*/

		bool AdvancedOptionsDialog::getUseDistanceDependentDC() const
		{
			return distance_button->isChecked();
		}

		float AdvancedOptionsDialog::getNonbondedCutoff()
		{
			String nonbondcut = nonbonded_cutoff_line_edit->text().ascii();
			float nonbond = nonbondcut.toFloat();
			return nonbond;
		}

		float AdvancedOptionsDialog::getVdwCutoff()
		{
			String vdwcut = vdw_cutoff_line_edit->text().ascii();
			float vdw = vdwcut.toFloat();
			return vdw;
		}

		float AdvancedOptionsDialog::getVdwCuton()
		{
			String vdwcut = vdw_cuton_line_edit->text().ascii();
			float vdw = vdwcut.toFloat();
			return vdw;
		}

		float AdvancedOptionsDialog::getElectrostaticCutoff()
		{
			String elcut = electrostatic_cutoff_line_edit->text().ascii();
			float el = elcut.toFloat();
			return el;
		}

		float AdvancedOptionsDialog::getElectrostaticCuton()
		{
			String elcut = electrostatic_cuton_line_edit->text().ascii();
			float el = elcut.toFloat();
			return el;
		}

		float AdvancedOptionsDialog::getScalingElectrostatic_1_4()
		{
			String scaleel = scaling_electrostatic_1_4_line_edit->text().ascii();
			float scale = scaleel.toFloat();
			return scale;
		}

		float AdvancedOptionsDialog::getScalingVdw_1_4()
		{
			String scalevdw = scaling_vdw_1_4_line_edit->text().ascii();
			float scale = scalevdw.toFloat();
			return scale;
		}

		bool AdvancedOptionsDialog::getAssignCharges()
		{
			return assign_charges_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getAssignTypenames()
		{
			return assign_typenames_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getAssignTypes()
		{
			return assign_types_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getOverwriteCharges()
		{
			return overwrite_charges_checkBox->isChecked();
		}

		bool AdvancedOptionsDialog::getOverwriteTypenames()
		{
			return overwrite_typenames_checkBox->isChecked();
		}
		//function to restore previously changed options
		void AdvancedOptionsDialog::setOptions(float nonbonded_cutoff, float vdw_cutoff, float vdw_cuton, float electrostatic_cutoff, float electrostatic_cuton,
									    float scaling_electrostatic_1_4, float scaling_vdw_1_4, bool use_dddc, bool assign_charges,
									    bool assign_typenames, bool assign_types, bool overwrite_charges, bool overwrite_typenames)
		{
			nonbonded_cutoff_line_edit->setText(String(nonbonded_cutoff).c_str());
			vdw_cutoff_line_edit->setText(String(vdw_cutoff).c_str());
			vdw_cuton_line_edit->setText(String(vdw_cuton).c_str());
			electrostatic_cutoff_line_edit->setText(String(electrostatic_cutoff).c_str());
			electrostatic_cuton_line_edit->setText(String(electrostatic_cuton).c_str());
			scaling_electrostatic_1_4_line_edit->setText(String(scaling_electrostatic_1_4).c_str());
			scaling_vdw_1_4_line_edit->setText(String(scaling_vdw_1_4).c_str());

			distance_button->setChecked(use_dddc);
			assign_charges_checkBox->setChecked(assign_charges);
			assign_typenames_checkBox->setChecked(assign_typenames);
			assign_types_checkBox->setChecked(assign_types);
			overwrite_charges_checkBox->setChecked(overwrite_charges);
			overwrite_typenames_checkBox->setChecked(overwrite_typenames);
		}

	}//namespace View
}//namespace Ball
<|endoftext|>


<commit_before>#include <QtGui/QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQuickItem>
#include <QDebug>
#include <QSettings>
#include <QQmlContext>
#include <QSortFilterProxyModel>
#include <QtWidgets/QFileDialog>
#include <QTime>
#include "qtquick2applicationviewer.h"

#include "resourcelistmodel.h"
#include "humanlistmodel.h"
#include "savedgamelistmodel.h"
#include "settings.h"
#include "savesaccess.h"

#define TESTING 0

QString appVersion()
{
    // Version History
    // ---------------------
    // 0.4 - first release, only resource editing
    // 0.5 - second release, only tweaked resource list
    // 1.0 - units: add and remove, added error display
    // 1.1 - updated for T&S 1.0.
    // 1.2 - fixed the animal life toggling on load
    // 1.3 - added coffee, gave new units coffee
    // 1.4 - updated for T&S 1.1.
    // 1.5 - fixed oddly-infrequent crash
    // 1.6 - added support for patrol points
    // 1.7 - fixed adventurer (T&S v1.2 didn't change anything)
    // 1.8 - updated for T&S 1.3 (and some other tweaks)
    // 1.9 - updated for T&S 1.4
    //
    return "1.9 (for T&S v1.4) BETA";
}

int main(int argc, char *argv[])
{
    // Seed the random number generator
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

    QApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMinimumWidth(400);
    viewer.setMinimumHeight(350);

    QStringList libPaths = QCoreApplication::libraryPaths();
    libPaths.append(QCoreApplication::applicationDirPath() + "/plugins");
    app.setLibraryPaths(libPaths);

#if TESTING
    QByteArray binary;
    unsigned int result;
    bool failed(false);
    for( unsigned int value=0; value<65000; value++ )
    {
        binary = SavesAccess::toBinary(value);
        result = SavesAccess::toInt(binary);
        if( result != value)
        {
            qDebug() << "Value" << value << "returned" << result;
            failed = true;
            break;
        }
    }
    if( failed )
    {
        qDebug() << "[FAILURE] The tests did NOT succeed!";
    }
    else
    {
        qDebug() << "[PASSED]  All tests passed.";
    }
#endif

    QCoreApplication::setApplicationName("Axe and Pick");
    QCoreApplication::setOrganizationDomain("potatominingcorp.com");
    QCoreApplication::setOrganizationName("Potato Mining Corporation");

    app.setWindowIcon(QIcon());
    viewer.setTitle(QCoreApplication::applicationName() + " v" + appVersion());

    // Register the list item types for the enumerations in QML
    qmlRegisterType<Resource>("Resource", 1,0, "Resource");

    // Load and create the settings. Give QML access.
    Settings settings;
    viewer.rootContext()->setContextProperty("settings", &settings);

    //
    // SAVED GAMES
    //
    // This holds the info for all the saved games.
    SavesAccess savesAccess;
    savesAccess.setFilePath(settings.value("TimberAndStone/GameInstallationDirectory").toString());
    SavedGameListModel * savedGameModel = new SavedGameListModel(new SavedGame, qApp);
    savesAccess.setSavedGameListModel(savedGameModel);
    savesAccess.loadGamesList();
    viewer.rootContext()->setContextProperty("savesAccess", &savesAccess);
    viewer.rootContext()->setContextProperty("savedGameModel", savedGameModel);

    //
    // RESOURCES
    //
    // Create a model that holds our resource data, and
    // add the data to it. Then make it available to QML.
    ResourceListModel * resourceModel = new ResourceListModel(new Resource, qApp);
    savesAccess.setResourceListModel(resourceModel);
    viewer.rootContext()->setContextProperty("resourceModel", resourceModel);

    // Create the proxy model that contains the results of the filter.
    QSortFilterProxyModel * proxyResourceModel = new QSortFilterProxyModel();
    proxyResourceModel->setSourceModel(resourceModel);
    proxyResourceModel->setFilterRole(Resource::FilterStringRole);
    // This prevents unknown items from showing up in the list.
    proxyResourceModel->setFilterRegExp("^(?!unknown).*");
    viewer.rootContext()->setContextProperty("resourceModelProxy", proxyResourceModel);

    // Enable the case insensitivity
    proxyResourceModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    // Setup sorting the resources
    //proxyResourceModel->setSortRole(Resource::TypeRole);
    //proxyResourceModel->sort(0);

    //
    // UNITS
    //
    // Humans
    HumanListModel * humanModel = new HumanListModel(new Human, qApp);
    savesAccess.setHumanModel(humanModel);
    viewer.rootContext()->setContextProperty("humanModel", humanModel);
    QSortFilterProxyModel * proxyHumanModel = new QSortFilterProxyModel();
    proxyHumanModel->setSourceModel(humanModel);
    proxyHumanModel->setFilterRole(Human::FilterStringRole);
    proxyHumanModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("humanModelProxy", proxyHumanModel);
    proxyHumanModel->setFilterRegExp("^(?!unknown).*");

    // Neutral Mobs
    NeutralMobListModel * neutralMobModel = new NeutralMobListModel(new NeutralMob, qApp);
    savesAccess.setNeutralMobModel(neutralMobModel);
    viewer.rootContext()->setContextProperty("neutralMobModel", neutralMobModel);
    QSortFilterProxyModel * proxyNeutralMobModel = new QSortFilterProxyModel();
    proxyNeutralMobModel->setSourceModel(neutralMobModel);
    proxyNeutralMobModel->setFilterRole(NeutralMob::FilterStringRole);
    proxyNeutralMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("neutralMobModelProxy", proxyNeutralMobModel);

    // Violent Mobs
    ViolentMobListModel * violentMobModel = new ViolentMobListModel(new ViolentMob, qApp);
    savesAccess.setViolentMobModel(violentMobModel);
    viewer.rootContext()->setContextProperty("violentMobModel", violentMobModel);
    QSortFilterProxyModel * proxyViolentMobModel = new QSortFilterProxyModel();
    proxyViolentMobModel->setSourceModel(violentMobModel);
    proxyViolentMobModel->setFilterRole(ViolentMob::FilterStringRole);
    proxyViolentMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("violentMobModelProxy", proxyViolentMobModel);

    // Load the QML
    viewer.setMainQmlFile(QStringLiteral("qml/AxeAndPick/main.qml"));

    // Show the GUI
    viewer.showExpanded();

    // Start the main event loop.
    int appExecReturn = app.exec();

    // Clean up
    delete proxyResourceModel;
    delete proxyHumanModel;
    delete proxyNeutralMobModel;
    delete proxyViolentMobModel;

    return appExecReturn;
}
<commit_msg>Updated the version number with a BETA 1 tag<commit_after>#include <QtGui/QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQuickItem>
#include <QDebug>
#include <QSettings>
#include <QQmlContext>
#include <QSortFilterProxyModel>
#include <QtWidgets/QFileDialog>
#include <QTime>
#include "qtquick2applicationviewer.h"

#include "resourcelistmodel.h"
#include "humanlistmodel.h"
#include "savedgamelistmodel.h"
#include "settings.h"
#include "savesaccess.h"

#define TESTING 0

QString appVersion()
{
    // Version History
    // ---------------------
    // 0.4 - first release, only resource editing
    // 0.5 - second release, only tweaked resource list
    // 1.0 - units: add and remove, added error display
    // 1.1 - updated for T&S 1.0.
    // 1.2 - fixed the animal life toggling on load
    // 1.3 - added coffee, gave new units coffee
    // 1.4 - updated for T&S 1.1.
    // 1.5 - fixed oddly-infrequent crash
    // 1.6 - added support for patrol points
    // 1.7 - fixed adventurer (T&S v1.2 didn't change anything)
    // 1.8 - updated for T&S 1.3 (and some other tweaks)
    // 1.9 - updated for T&S 1.4
    //
    return "1.9 (for T&S v1.4) BETA 1";
}

int main(int argc, char *argv[])
{
    // Seed the random number generator
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

    QApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMinimumWidth(400);
    viewer.setMinimumHeight(350);

    QStringList libPaths = QCoreApplication::libraryPaths();
    libPaths.append(QCoreApplication::applicationDirPath() + "/plugins");
    app.setLibraryPaths(libPaths);

#if TESTING
    QByteArray binary;
    unsigned int result;
    bool failed(false);
    for( unsigned int value=0; value<65000; value++ )
    {
        binary = SavesAccess::toBinary(value);
        result = SavesAccess::toInt(binary);
        if( result != value)
        {
            qDebug() << "Value" << value << "returned" << result;
            failed = true;
            break;
        }
    }
    if( failed )
    {
        qDebug() << "[FAILURE] The tests did NOT succeed!";
    }
    else
    {
        qDebug() << "[PASSED]  All tests passed.";
    }
#endif

    QCoreApplication::setApplicationName("Axe and Pick");
    QCoreApplication::setOrganizationDomain("potatominingcorp.com");
    QCoreApplication::setOrganizationName("Potato Mining Corporation");

    app.setWindowIcon(QIcon());
    viewer.setTitle(QCoreApplication::applicationName() + " v" + appVersion());

    // Register the list item types for the enumerations in QML
    qmlRegisterType<Resource>("Resource", 1,0, "Resource");

    // Load and create the settings. Give QML access.
    Settings settings;
    viewer.rootContext()->setContextProperty("settings", &settings);

    //
    // SAVED GAMES
    //
    // This holds the info for all the saved games.
    SavesAccess savesAccess;
    savesAccess.setFilePath(settings.value("TimberAndStone/GameInstallationDirectory").toString());
    SavedGameListModel * savedGameModel = new SavedGameListModel(new SavedGame, qApp);
    savesAccess.setSavedGameListModel(savedGameModel);
    savesAccess.loadGamesList();
    viewer.rootContext()->setContextProperty("savesAccess", &savesAccess);
    viewer.rootContext()->setContextProperty("savedGameModel", savedGameModel);

    //
    // RESOURCES
    //
    // Create a model that holds our resource data, and
    // add the data to it. Then make it available to QML.
    ResourceListModel * resourceModel = new ResourceListModel(new Resource, qApp);
    savesAccess.setResourceListModel(resourceModel);
    viewer.rootContext()->setContextProperty("resourceModel", resourceModel);

    // Create the proxy model that contains the results of the filter.
    QSortFilterProxyModel * proxyResourceModel = new QSortFilterProxyModel();
    proxyResourceModel->setSourceModel(resourceModel);
    proxyResourceModel->setFilterRole(Resource::FilterStringRole);
    // This prevents unknown items from showing up in the list.
    proxyResourceModel->setFilterRegExp("^(?!unknown).*");
    viewer.rootContext()->setContextProperty("resourceModelProxy", proxyResourceModel);

    // Enable the case insensitivity
    proxyResourceModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    // Setup sorting the resources
    //proxyResourceModel->setSortRole(Resource::TypeRole);
    //proxyResourceModel->sort(0);

    //
    // UNITS
    //
    // Humans
    HumanListModel * humanModel = new HumanListModel(new Human, qApp);
    savesAccess.setHumanModel(humanModel);
    viewer.rootContext()->setContextProperty("humanModel", humanModel);
    QSortFilterProxyModel * proxyHumanModel = new QSortFilterProxyModel();
    proxyHumanModel->setSourceModel(humanModel);
    proxyHumanModel->setFilterRole(Human::FilterStringRole);
    proxyHumanModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("humanModelProxy", proxyHumanModel);
    proxyHumanModel->setFilterRegExp("^(?!unknown).*");

    // Neutral Mobs
    NeutralMobListModel * neutralMobModel = new NeutralMobListModel(new NeutralMob, qApp);
    savesAccess.setNeutralMobModel(neutralMobModel);
    viewer.rootContext()->setContextProperty("neutralMobModel", neutralMobModel);
    QSortFilterProxyModel * proxyNeutralMobModel = new QSortFilterProxyModel();
    proxyNeutralMobModel->setSourceModel(neutralMobModel);
    proxyNeutralMobModel->setFilterRole(NeutralMob::FilterStringRole);
    proxyNeutralMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("neutralMobModelProxy", proxyNeutralMobModel);

    // Violent Mobs
    ViolentMobListModel * violentMobModel = new ViolentMobListModel(new ViolentMob, qApp);
    savesAccess.setViolentMobModel(violentMobModel);
    viewer.rootContext()->setContextProperty("violentMobModel", violentMobModel);
    QSortFilterProxyModel * proxyViolentMobModel = new QSortFilterProxyModel();
    proxyViolentMobModel->setSourceModel(violentMobModel);
    proxyViolentMobModel->setFilterRole(ViolentMob::FilterStringRole);
    proxyViolentMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("violentMobModelProxy", proxyViolentMobModel);

    // Load the QML
    viewer.setMainQmlFile(QStringLiteral("qml/AxeAndPick/main.qml"));

    // Show the GUI
    viewer.showExpanded();

    // Start the main event loop.
    int appExecReturn = app.exec();

    // Clean up
    delete proxyResourceModel;
    delete proxyHumanModel;
    delete proxyNeutralMobModel;
    delete proxyViolentMobModel;

    return appExecReturn;
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "effectwidget.h"
#include "effectwidget_p.h"

#include <QtCore/QtAlgorithms>
#include <QtCore/QList>

#include "effect.h"
#include "effectparameter.h"
#include "phonondefs_p.h"
#include <QtGui/QBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QSpinBox>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QSlider>
#include <limits>

#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
static const qreal DEFAULT_MIN = std::numeric_limits<qreal>::min();
static const qreal DEFAULT_MAX = std::numeric_limits<qreal>::max();
static const int DEFAULT_MIN_INT = std::numeric_limits<int>::min();
static const int DEFAULT_MAX_INT = std::numeric_limits<int>::max();
static const int SLIDER_RANGE = 8;
static const int TICKINTERVAL = 4;

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_EFFECTWIDGET

namespace Phonon
{

EffectWidget::EffectWidget(Effect *effect, QWidget *parent)
    : QWidget(parent),
    k_ptr(new EffectWidgetPrivate(effect))
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}

EffectWidget::~EffectWidget()
{
    delete k_ptr;
}

/*
EffectWidget::EffectWidget(EffectWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent)
    , k_ptr(&dd)
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}
*/

EffectWidgetPrivate::EffectWidgetPrivate(Effect *e)
    : effect(e)
{
    //TODO: look up whether there is a specialized widget for this effect. This
    //could be a DSO or a Designer ui file found via KTrader.
    //
    //if no specialized widget is available:
}

void EffectWidgetPrivate::autogenerateUi()
{
    Q_Q(EffectWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(q);
    mainLayout->setMargin(0);
    for (int i = 0; i < effect->parameters().count(); ++i) {
        const EffectParameter &para = effect->parameters().at(i);
        QVariant value = effect->parameterValue(para);
        QHBoxLayout *pLayout = new QHBoxLayout;
        mainLayout->addLayout(pLayout);

        QLabel *label = new QLabel(q);
        pLayout->addWidget(label);
        label->setText(para.name());
#ifndef QT_NO_TOOLTIP
        label->setToolTip(para.description());
#endif

        QWidget *control = 0;
        switch (para.type()) {
        case QVariant::String:
            {
                QComboBox *cb = new QComboBox(q);
                control = cb;
                if (value.type() == QVariant::Int) {
                    //value just defines the item index
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        cb->addItem(para.possibleValues().at(i).toString());
                    }
                    cb->setCurrentIndex(value.toInt());
                    QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int)));
                } else {
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        const QVariant &item = para.possibleValues().at(i);
                        cb->addItem(item.toString());
                        if (item == value) {
                            cb->setCurrentIndex(cb->count() - 1);
                        }
                    }
                    QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString)));
                }
            }
            break;
        case QVariant::Bool:
            {
                QCheckBox *cb = new QCheckBox(q);
                control = cb;
                cb->setChecked(value.toBool());
                QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool)));
            }
            break;
        case QVariant::Int:
            {
                QSpinBox *sb = new QSpinBox(q);
                control = sb;
                bool minValueOk = false;
                bool maxValueOk = false;
                const int minValue = para.minimumValue().toInt(&minValueOk);
                const int maxValue = para.minimumValue().toInt(&maxValueOk);

                sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT);
                sb->setValue(value.toInt());
                QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int)));
            }
            break;
        case QMetaType::Float:
        case QVariant::Double:
            {
                const qreal minValue = para.minimumValue().canConvert(QVariant::Double) ?
                    para.minimumValue().toReal() : DEFAULT_MIN;
                const qreal maxValue = para.maximumValue().canConvert(QVariant::Double) ?
                    para.maximumValue().toReal() : DEFAULT_MAX;

                if (minValue == -1. && maxValue == 1.) {
                    //Special case values between -1 and 1.0 to use a slider for improved usability
                    QSlider *slider = new QSlider(Qt::Horizontal, q);
                    control = slider;
                    slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE);
                    slider->setValue(int(SLIDER_RANGE * value.toReal()));
                    slider->setTickPosition(QSlider::TicksBelow);
                    slider->setTickInterval(TICKINTERVAL);
                    QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int)));
                } else {
                    double step = 0.1;
                    if (qAbs(maxValue - minValue) > 50)
                        step = 1.0;
                    QDoubleSpinBox *sb = new QDoubleSpinBox(q);
                    control = sb;
                    sb->setRange(minValue, maxValue);
                    sb->setValue(value.toDouble());
                    sb->setSingleStep(step);
                    QObject::connect(sb, SIGNAL(valueChanged(double)), q,
                        SLOT(_k_setDoubleParameter(double)));
                }
            }
            break;
        default:
            break;
        }

        if (control) {
#ifndef QT_NO_TOOLTIP
        control->setToolTip(para.description());
#endif
#ifndef QT_NO_SHORTCUT
            label->setBuddy(control);
#endif
            pLayout->addWidget(control);
            parameterForObject.insert(control, para);
        }
    }
}

void EffectWidgetPrivate::_k_setToggleParameter(bool checked)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], checked);
    }
}

void EffectWidgetPrivate::_k_setIntParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setDoubleParameter(double value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setStringParameter(const QString &value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setSliderParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], double(value) / double(SLIDER_RANGE));
    }
}

} // namespace Phonon

#endif // QT_NO_PHONON_EFFECTWIDGET

QT_END_NAMESPACE

#include "moc_effectwidget.cpp"

// vim: sw=4 ts=4
<commit_msg>Fixed a crash when configuring an audio effect with the Phonon dialog<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "effectwidget.h"
#include "effectwidget_p.h"

#include <QtCore/QtAlgorithms>
#include <QtCore/QList>

#include "effect.h"
#include "effectparameter.h"
#include "phonondefs_p.h"
#include <QtGui/QBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QSpinBox>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QSlider>
#include <limits>

#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
static const qreal DEFAULT_MIN = std::numeric_limits<qreal>::min();
static const qreal DEFAULT_MAX = std::numeric_limits<qreal>::max();
static const int DEFAULT_MIN_INT = std::numeric_limits<int>::min();
static const int DEFAULT_MAX_INT = std::numeric_limits<int>::max();
static const int SLIDER_RANGE = 8;
static const int TICKINTERVAL = 4;

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PHONON_EFFECTWIDGET

namespace Phonon
{

EffectWidget::EffectWidget(Effect *effect, QWidget *parent)
    : QWidget(parent),
    k_ptr(new EffectWidgetPrivate(effect))
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}

EffectWidget::~EffectWidget()
{
    delete k_ptr;
}

/*
EffectWidget::EffectWidget(EffectWidgetPrivate &dd, QWidget *parent)
    : QWidget(parent)
    , k_ptr(&dd)
{
    K_D(EffectWidget);
    d->q_ptr = this;
    d->autogenerateUi();
}
*/

EffectWidgetPrivate::EffectWidgetPrivate(Effect *e)
    : effect(e)
{
    //TODO: look up whether there is a specialized widget for this effect. This
    //could be a DSO or a Designer ui file found via KTrader.
    //
    //if no specialized widget is available:
}

void EffectWidgetPrivate::autogenerateUi()
{
    Q_Q(EffectWidget);
    QVBoxLayout *mainLayout = new QVBoxLayout(q);
    mainLayout->setMargin(0);
    const QList<Phonon::EffectParameter> parameters = effect->parameters();
    for (int i = 0; i < parameters.count(); ++i) {
        const EffectParameter &para = parameters.at(i);
        QVariant value = effect->parameterValue(para);
        QHBoxLayout *pLayout = new QHBoxLayout;
        mainLayout->addLayout(pLayout);

        QLabel *label = new QLabel(q);
        pLayout->addWidget(label);
        label->setText(para.name());
#ifndef QT_NO_TOOLTIP
        label->setToolTip(para.description());
#endif

        QWidget *control = 0;
        switch (para.type()) {
        case QVariant::String:
            {
                QComboBox *cb = new QComboBox(q);
                control = cb;
                if (value.type() == QVariant::Int) {
                    //value just defines the item index
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        cb->addItem(para.possibleValues().at(i).toString());
                    }
                    cb->setCurrentIndex(value.toInt());
                    QObject::connect(cb, SIGNAL(currentIndexChanged(int)), q, SLOT(_k_setIntParameter(int)));
                } else {
                    for (int i = 0; i < para.possibleValues().count(); ++i) {
                        const QVariant &item = para.possibleValues().at(i);
                        cb->addItem(item.toString());
                        if (item == value) {
                            cb->setCurrentIndex(cb->count() - 1);
                        }
                    }
                    QObject::connect(cb, SIGNAL(currentIndexChanged(QString)), q, SLOT(_k_setStringParameter(QString)));
                }
            }
            break;
        case QVariant::Bool:
            {
                QCheckBox *cb = new QCheckBox(q);
                control = cb;
                cb->setChecked(value.toBool());
                QObject::connect(cb, SIGNAL(toggled(bool)), q, SLOT(_k_setToggleParameter(bool)));
            }
            break;
        case QVariant::Int:
            {
                QSpinBox *sb = new QSpinBox(q);
                control = sb;
                bool minValueOk = false;
                bool maxValueOk = false;
                const int minValue = para.minimumValue().toInt(&minValueOk);
                const int maxValue = para.minimumValue().toInt(&maxValueOk);

                sb->setRange(minValueOk ? minValue : DEFAULT_MIN_INT, maxValueOk ? maxValue : DEFAULT_MAX_INT);
                sb->setValue(value.toInt());
                QObject::connect(sb, SIGNAL(valueChanged(int)), q, SLOT(_k_setIntParameter(int)));
            }
            break;
        case QMetaType::Float:
        case QVariant::Double:
            {
                const qreal minValue = para.minimumValue().canConvert(QVariant::Double) ?
                    para.minimumValue().toReal() : DEFAULT_MIN;
                const qreal maxValue = para.maximumValue().canConvert(QVariant::Double) ?
                    para.maximumValue().toReal() : DEFAULT_MAX;

                if (minValue == -1. && maxValue == 1.) {
                    //Special case values between -1 and 1.0 to use a slider for improved usability
                    QSlider *slider = new QSlider(Qt::Horizontal, q);
                    control = slider;
                    slider->setRange(-SLIDER_RANGE, +SLIDER_RANGE);
                    slider->setValue(int(SLIDER_RANGE * value.toReal()));
                    slider->setTickPosition(QSlider::TicksBelow);
                    slider->setTickInterval(TICKINTERVAL);
                    QObject::connect(slider, SIGNAL(valueChanged(int)), q, SLOT(_k_setSliderParameter(int)));
                } else {
                    double step = 0.1;
                    if (qAbs(maxValue - minValue) > 50)
                        step = 1.0;
                    QDoubleSpinBox *sb = new QDoubleSpinBox(q);
                    control = sb;
                    sb->setRange(minValue, maxValue);
                    sb->setValue(value.toDouble());
                    sb->setSingleStep(step);
                    QObject::connect(sb, SIGNAL(valueChanged(double)), q,
                        SLOT(_k_setDoubleParameter(double)));
                }
            }
            break;
        default:
            break;
        }

        if (control) {
#ifndef QT_NO_TOOLTIP
        control->setToolTip(para.description());
#endif
#ifndef QT_NO_SHORTCUT
            label->setBuddy(control);
#endif
            pLayout->addWidget(control);
            parameterForObject.insert(control, para);
        }
    }
}

void EffectWidgetPrivate::_k_setToggleParameter(bool checked)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], checked);
    }
}

void EffectWidgetPrivate::_k_setIntParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setDoubleParameter(double value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setStringParameter(const QString &value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], value);
    }
}

void EffectWidgetPrivate::_k_setSliderParameter(int value)
{
    Q_Q(EffectWidget);
    if (parameterForObject.contains(q->sender())) {
        effect->setParameterValue(parameterForObject[q->sender()], double(value) / double(SLIDER_RANGE));
    }
}

} // namespace Phonon

#endif // QT_NO_PHONON_EFFECTWIDGET

QT_END_NAMESPACE

#include "moc_effectwidget.cpp"

// vim: sw=4 ts=4
<|endoftext|>


<commit_before>/**
 * \file
 * \brief Implementation of FLASH-related functions for STM32F1
 *
 * \author Copyright (C) 2016 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/chip/STM32F1-FLASH.hpp"

#include "distortos/chip/STM32F1-FLASH-bits.h"

#include "distortos/chip/CMSIS-proxy.h"

#include <cerrno>

namespace distortos
{

namespace chip
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

void configureFlashHalfCycleAccess(const bool enable)
{
	FLASH_ACR_HLFCYA_bb = enable;
}

#ifndef CONFIG_CHIP_STM32F100

int configureFlashLatency(const uint8_t latency)
{
	if (latency > maxFlashLatency)
		return EINVAL;

	FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | (latency << FLASH_ACR_LATENCY_bit);
	return 0;
}

void configurePrefetchBuffer(const bool enable)
{
	FLASH_ACR_PRFTBE_bb = enable;
}

#endif	// !def CONFIG_CHIP_STM32F100

}	// namespace chip

}	// namespace distortos
<commit_msg>Don't use STM32F1-FLASH-bits.h in STM32F1-FLASH.cpp<commit_after>/**
 * \file
 * \brief Implementation of FLASH-related functions for STM32F1
 *
 * \author Copyright (C) 2016-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "distortos/chip/STM32F1-FLASH.hpp"

#include "distortos/chip/CMSIS-proxy.h"
#include "distortos/chip/STM32-bit-banding.h"

#include <cerrno>

namespace distortos
{

namespace chip
{

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

void configureFlashHalfCycleAccess(const bool enable)
{
	STM32_BITBAND(FLASH, ACR, HLFCYA) = enable;
}

#ifndef CONFIG_CHIP_STM32F100

int configureFlashLatency(const uint8_t latency)
{
	if (latency > maxFlashLatency)
		return EINVAL;

	FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY) | (latency << FLASH_ACR_LATENCY_Pos);
	return 0;
}

void configurePrefetchBuffer(const bool enable)
{
	STM32_BITBAND(FLASH, ACR, PRFTBE) = enable;
}

#endif	// !def CONFIG_CHIP_STM32F100

}	// namespace chip

}	// namespace distortos
<|endoftext|>


<commit_before><commit_msg>fixed tests for windows<commit_after><|endoftext|>


<commit_before>#ifndef __LOSS_HPP__
#define __LOSS_HPP__

#include <utility>
#include <string>
#include <random>
#include <functional>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>

#include "elements.hpp"
#include "model.hpp"
#include "ratings.hpp"

enum loss_option_t {L1_HINGE, L2_HINGE, LOGISTIC, SQUARED};

// binary classification loss
double compute_loss(const Model& model, const std::vector<comparison>& TestComps, loss_option_t option) {
  double p = 0., loss;
  for(int i=0; i<TestComps.size(); ++i) {
    double *user_vec  = &(model.U[TestComps[i].user_id  * model.rank]);
    double *item1_vec = &(model.V[TestComps[i].item1_id * model.rank]);
    double *item2_vec = &(model.V[TestComps[i].item2_id * model.rank]);
    double d = 0.;
    for(int j=0; j<model.rank; ++j) {
      d += user_vec[j] * (item1_vec[j] - item2_vec[j]);
    }

    switch(option) {
      case SQUARED:
        loss = .5*pow(1.-d, 2.);
        break;
      case LOGISTIC:
        loss = log(1.+exp(-d));
        break;
      case L1_HINGE:
        loss = std::max(0., 1.-d);
        break;
      case L2_HINGE:
        loss = pow(std::max(0., 1.-d), 2.);
    }

    p += loss;
  }

  return p;
}

// sum of squares loss
double compute_loss(const Model& model, const RatingMatrix& test) {
  double p = 0.;
  for(int i=0; i<test.ratings.size(); ++i) {
    double *user_vec  = &(model.U[test.ratings[i].user_id * model.rank]);
    double *item_vec  = &(model.V[test.ratings[i].item_id * model.rank]);
    double d = 0.;
    for(int j=0; j<model.rank; ++j) d += user_vec[j] * item_vec[j];
    p += .5 * pow(test.ratings[i].score - d, 2.);
  }

  return p;
}

double compute_pairwiseError(const RatingMatrix& TestRating, const RatingMatrix& PredictedRating) {

  std::vector<double> score(TestRating.n_items);

  double sum_error = 0.;
  for(int uid=0; uid<TestRating.n_users; ++uid) {
    score.resize(TestRating.n_items,-1e10);
    double max_sc = -1.;

    int j = PredictedRating.idx[uid];
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;
      while((j < PredictedRating.idx[uid+1]) && (PredictedRating.ratings[j].item_id < iid)) ++j;
      if ((PredictedRating.ratings[j].user_id == uid) && (PredictedRating.ratings[j].item_id == iid)) score[iid] = PredictedRating.ratings[j].score;
      if (TestRating.ratings[i].score > max_sc) max_sc = TestRating.ratings[i].score;
    }

    max_sc = max_sc - .1;

    unsigned long long error_this = 0, n_comps_this = 0;
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]-1; ++i) {
      for(int j=i+1; j<TestRating.idx[uid+1]; ++j) {
        int item1_id = TestRating.ratings[i].item_id;
        int item2_id = TestRating.ratings[j].item_id;
        double item1_sc = TestRating.ratings[i].score;
        double item2_sc = TestRating.ratings[j].score;

        if ((item1_sc > item2_sc) && (score[item1_id] <= score[item2_id])) ++error_this;
        if ((item1_sc < item2_sc) && (score[item1_id] >= score[item2_id])) ++error_this;
        ++n_comps_this;
      }
    }

    sum_error += (double)error_this / (double)n_comps_this;
  }

  return sum_error / (double)TestRating.n_users;
}

double compute_pairwiseError(const RatingMatrix& TestRating, const Model& PredictedModel) {

  std::vector<double> score(TestRating.n_items);

  double sum_error = 0.;
  for(int uid=0; uid<TestRating.n_users; ++uid) {
    score.resize(TestRating.n_items,-1e10);
    double max_sc = -1.;

    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;

      if (iid < PredictedModel.n_items) {
        double prod = 0.;
        for(int k=0; k<PredictedModel.rank; ++k) prod += PredictedModel.U[uid * PredictedModel.rank + k] * PredictedModel.V[iid * PredictedModel.rank + k];
        score[iid] = prod;
      }
      else {
        score[iid] = -1e10;
      }

      if (TestRating.ratings[i].score > max_sc) max_sc = TestRating.ratings[i].score;
    }

    max_sc = max_sc - .1;

    unsigned long long error_this = 0, n_comps_this = 0;
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]-1; ++i) {
      for(int j=i+1; j<TestRating.idx[uid+1]; ++j) {
        int item1_id = TestRating.ratings[i].item_id;
        int item2_id = TestRating.ratings[j].item_id;
        double item1_sc = TestRating.ratings[i].score;
        double item2_sc = TestRating.ratings[j].score;

        if ((item1_sc > item2_sc) && (score[item1_id] <= score[item2_id])) ++error_this;
        if ((item1_sc < item2_sc) && (score[item1_id] >= score[item2_id])) ++error_this;
        ++n_comps_this;
/*
        if ((item1_sc >= max_sc) && (item2_sc < max_sc)) {
          if (score[item1_id] <= score[item2_id]) ++errorT;
          ++n_compsT;
        }

        if ((item2_sc >= max_sc) && (item1_sc < max_sc)) {
          if (score[item2_id] >= score[item1_id]) ++errorT;
          ++n_compsT;
        }
*/
      }
    }

    sum_error += (double)error_this / (double)n_comps_this;
  }

  //comp_error.first  = (double)error / (double)n_comps;
  //comp_error.second = (double)errorT / (double)n_compsT;

  return sum_error / (double)TestRating.n_users;
}

double compute_ndcg(const RatingMatrix& TestRating, const std::string& Predict_filename) {

  double ndcg_sum;

  std::vector<double> score;
  std::string user_str, attribute_str;
  std::stringstream attribute_sstr;

  std::ifstream f;

  f.open(Predict_filename);
  if (f.is_open()) {

    for(int uid=0; uid<TestRating.n_users; ++uid) {
      getline(f, user_str);

      size_t pos1 = 0, pos2;

      score.clear();
      for(int idx=TestRating.idx[uid]; idx<TestRating.idx[uid+1]; ++idx) {
        int iid = -1;
        double sc;

        while(iid < TestRating.ratings[idx].item_id) {
          pos2 = user_str.find(':', pos1); if (pos2 == std::string::npos) break;
          attribute_str = user_str.substr(pos1, pos2-pos1);
          attribute_sstr.clear(); attribute_sstr.str(attribute_str);
          attribute_sstr >> iid;
          --iid;
          pos1 = pos2+1;

          pos2 = user_str.find(' ', pos1); attribute_str = user_str.substr(pos1, pos2-pos1);
          attribute_sstr.clear(); attribute_sstr.str(attribute_str);
          attribute_sstr >> sc;
          pos1 = pos2+1;
        }

        if (iid == TestRating.ratings[idx].item_id)
          score.push_back(sc);
        else
          score.push_back(-1e10);

      }

      ndcg_sum += TestRating.compute_user_ndcg(uid, score);
    }

  } else {
      printf("Error in opening the extracted rating file!\n");
      std::cout << Predict_filename << std::endl;
      exit(EXIT_FAILURE);
  }

  f.close();
}

double compute_ndcg(const RatingMatrix& TestRating, const RatingMatrix& PredictedRating) {

  double ndcg_sum = 0.;
  std::vector<double> score;

  for(int uid=0; uid<TestRating.n_users; ++uid) {
    double dcg = 0.;

    score.clear();
    int j = PredictedRating.idx[uid];
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      double prod = 0.;
      while((j < PredictedRating.idx[uid+1]) && (PredictedRating.ratings[j].item_id < TestRating.ratings[i].item_id)) ++j;
      if ((PredictedRating.ratings[j].user_id == TestRating.ratings[i].user_id) && (PredictedRating.ratings[j].item_id == TestRating.ratings[i].item_id))
        score.push_back(PredictedRating.ratings[j].score);
      else
        score.push_back(-1e10);
    }

    ndcg_sum += TestRating.compute_user_ndcg(uid, score);
  }

  return ndcg_sum / (double)PredictedRating.n_users;
}

double compute_ndcg(const RatingMatrix& TestRating, const Model& PredictedModel) {

  if (!TestRating.is_dcg_max_computed) return -1.;

  double ndcg_sum = 0.;
  std::vector<double> score;

  for(int uid=0; uid<PredictedModel.n_users; ++uid) {
    double dcg = 0.;

    score.clear();
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;

      if (iid < PredictedModel.n_items) {
        double prod = 0.;
        for(int k=0; k<PredictedModel.rank; ++k) prod += PredictedModel.U[uid * PredictedModel.rank + k] * PredictedModel.V[iid * PredictedModel.rank + k];
        score.push_back(prod);
      }
      else {
        score.push_back(-1e10);
      }
    }

    ndcg_sum += TestRating.compute_user_ndcg(uid, score);
	}

  return ndcg_sum / (double)PredictedModel.n_users;
}

#endif
<commit_msg>computing loss function parallelized<commit_after>#ifndef __LOSS_HPP__
#define __LOSS_HPP__

#include <utility>
#include <string>
#include <random>
#include <functional>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <map>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <omp.h>

#include "elements.hpp"
#include "model.hpp"
#include "ratings.hpp"

enum loss_option_t {L1_HINGE, L2_HINGE, LOGISTIC, SQUARED};

// binary classification loss
double compute_loss(const Model& model, const std::vector<comparison>& TestComps, loss_option_t option) {
  double p = 0.;
  #pragma omp parallel for reduction(+:p)
  for(int i=0; i<TestComps.size(); ++i) {
    double *user_vec  = &(model.U[TestComps[i].user_id  * model.rank]);
    double *item1_vec = &(model.V[TestComps[i].item1_id * model.rank]);
    double *item2_vec = &(model.V[TestComps[i].item2_id * model.rank]);
    double d = 0., loss;
    for(int j=0; j<model.rank; ++j) {
      d += user_vec[j] * (item1_vec[j] - item2_vec[j]);
    }

    switch(option) {
      case SQUARED:
        loss = .5*pow(1.-d, 2.);
        break;
      case LOGISTIC:
        loss = log(1.+exp(-d));
        break;
      case L1_HINGE:
        loss = std::max(0., 1.-d);
        break;
      case L2_HINGE:
        loss = pow(std::max(0., 1.-d), 2.);
    }

    p += loss;
  }

  return p;
}

// sum of squares loss
double compute_loss(const Model& model, const RatingMatrix& test) {
  double p = 0.;
  #pragma omp parallel for reduction(+:p)
  for(int i=0; i<test.ratings.size(); ++i) {
    double *user_vec  = &(model.U[test.ratings[i].user_id * model.rank]);
    double *item_vec  = &(model.V[test.ratings[i].item_id * model.rank]);
    double d = 0.;
    for(int j=0; j<model.rank; ++j) d += user_vec[j] * item_vec[j];
    p += .5 * pow(test.ratings[i].score - d, 2.);
  }

  return p;
}

double compute_pairwiseError(const RatingMatrix& TestRating, const RatingMatrix& PredictedRating) {

  std::vector<double> score(TestRating.n_items);

  double sum_error = 0.;
  for(int uid=0; uid<TestRating.n_users; ++uid) {
    score.resize(TestRating.n_items,-1e10);
    double max_sc = -1.;

    int j = PredictedRating.idx[uid];
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;
      while((j < PredictedRating.idx[uid+1]) && (PredictedRating.ratings[j].item_id < iid)) ++j;
      if ((PredictedRating.ratings[j].user_id == uid) && (PredictedRating.ratings[j].item_id == iid)) score[iid] = PredictedRating.ratings[j].score;
      if (TestRating.ratings[i].score > max_sc) max_sc = TestRating.ratings[i].score;
    }

    max_sc = max_sc - .1;

    unsigned long long error_this = 0, n_comps_this = 0;
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]-1; ++i) {
      for(int j=i+1; j<TestRating.idx[uid+1]; ++j) {
        int item1_id = TestRating.ratings[i].item_id;
        int item2_id = TestRating.ratings[j].item_id;
        double item1_sc = TestRating.ratings[i].score;
        double item2_sc = TestRating.ratings[j].score;

        if ((item1_sc > item2_sc) && (score[item1_id] <= score[item2_id])) ++error_this;
        if ((item1_sc < item2_sc) && (score[item1_id] >= score[item2_id])) ++error_this;
        ++n_comps_this;
      }
    }

    sum_error += (double)error_this / (double)n_comps_this;
  }

  return sum_error / (double)TestRating.n_users;
}

double compute_pairwiseError(const RatingMatrix& TestRating, const Model& PredictedModel) {

  double sum_error = 0.;
  #pragma omp parallel for reduction(+:sum_error)
  for(int uid=0; uid<TestRating.n_users; ++uid) {
    std::vector<double> score(TestRating.n_items,-1e10);
    //double max_sc = -1.;

    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;

      if (iid < PredictedModel.n_items) {
        double prod = 0.;
        for(int k=0; k<PredictedModel.rank; ++k) prod += PredictedModel.U[uid * PredictedModel.rank + k] * PredictedModel.V[iid * PredictedModel.rank + k];
        score[iid] = prod;
      }
      else {
        score[iid] = -1e10;
      }

//      if (TestRating.ratings[i].score > max_sc) max_sc = TestRating.ratings[i].score;
    }

//    max_sc = max_sc - .1;

    unsigned long long error_this = 0, n_comps_this = 0;
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]-1; ++i) {
      for(int j=i+1; j<TestRating.idx[uid+1]; ++j) {
        int item1_id = TestRating.ratings[i].item_id;
        int item2_id = TestRating.ratings[j].item_id;
        double item1_sc = TestRating.ratings[i].score;
        double item2_sc = TestRating.ratings[j].score;

        if ((item1_sc > item2_sc) && (score[item1_id] <= score[item2_id])) ++error_this;
        if ((item1_sc < item2_sc) && (score[item1_id] >= score[item2_id])) ++error_this;
        ++n_comps_this;
/*
        if ((item1_sc >= max_sc) && (item2_sc < max_sc)) {
          if (score[item1_id] <= score[item2_id]) ++errorT;
          ++n_compsT;
        }

        if ((item2_sc >= max_sc) && (item1_sc < max_sc)) {
          if (score[item2_id] >= score[item1_id]) ++errorT;
          ++n_compsT;
        }
*/
      }
    }

    sum_error += (double)error_this / (double)n_comps_this;
  }

  //comp_error.first  = (double)error / (double)n_comps;
  //comp_error.second = (double)errorT / (double)n_compsT;

  return sum_error / (double)TestRating.n_users;
}

double compute_ndcg(const RatingMatrix& TestRating, const std::string& Predict_filename) {

  double ndcg_sum;

  std::vector<double> score;
  std::string user_str, attribute_str;
  std::stringstream attribute_sstr;

  std::ifstream f;

  f.open(Predict_filename);
  if (f.is_open()) {

    for(int uid=0; uid<TestRating.n_users; ++uid) {
      getline(f, user_str);

      size_t pos1 = 0, pos2;

      score.clear();
      for(int idx=TestRating.idx[uid]; idx<TestRating.idx[uid+1]; ++idx) {
        int iid = -1;
        double sc;

        while(iid < TestRating.ratings[idx].item_id) {
          pos2 = user_str.find(':', pos1); if (pos2 == std::string::npos) break;
          attribute_str = user_str.substr(pos1, pos2-pos1);
          attribute_sstr.clear(); attribute_sstr.str(attribute_str);
          attribute_sstr >> iid;
          --iid;
          pos1 = pos2+1;

          pos2 = user_str.find(' ', pos1); attribute_str = user_str.substr(pos1, pos2-pos1);
          attribute_sstr.clear(); attribute_sstr.str(attribute_str);
          attribute_sstr >> sc;
          pos1 = pos2+1;
        }

        if (iid == TestRating.ratings[idx].item_id)
          score.push_back(sc);
        else
          score.push_back(-1e10);

      }

      ndcg_sum += TestRating.compute_user_ndcg(uid, score);
    }

  } else {
      printf("Error in opening the extracted rating file!\n");
      std::cout << Predict_filename << std::endl;
      exit(EXIT_FAILURE);
  }

  f.close();
}

double compute_ndcg(const RatingMatrix& TestRating, const RatingMatrix& PredictedRating) {

  double ndcg_sum = 0.;
  std::vector<double> score;

  for(int uid=0; uid<TestRating.n_users; ++uid) {
    double dcg = 0.;

    score.clear();
    int j = PredictedRating.idx[uid];
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      double prod = 0.;
      while((j < PredictedRating.idx[uid+1]) && (PredictedRating.ratings[j].item_id < TestRating.ratings[i].item_id)) ++j;
      if ((PredictedRating.ratings[j].user_id == TestRating.ratings[i].user_id) && (PredictedRating.ratings[j].item_id == TestRating.ratings[i].item_id))
        score.push_back(PredictedRating.ratings[j].score);
      else
        score.push_back(-1e10);
    }

    ndcg_sum += TestRating.compute_user_ndcg(uid, score);
  }

  return ndcg_sum / (double)PredictedRating.n_users;
}

double compute_ndcg(const RatingMatrix& TestRating, const Model& PredictedModel) {

  if (!TestRating.is_dcg_max_computed) return -1.;

  double ndcg_sum = 0.;
  std::vector<double> score;

  for(int uid=0; uid<PredictedModel.n_users; ++uid) {
    double dcg = 0.;

    score.clear();
    for(int i=TestRating.idx[uid]; i<TestRating.idx[uid+1]; ++i) {
      int iid = TestRating.ratings[i].item_id;

      if (iid < PredictedModel.n_items) {
        double prod = 0.;
        for(int k=0; k<PredictedModel.rank; ++k) prod += PredictedModel.U[uid * PredictedModel.rank + k] * PredictedModel.V[iid * PredictedModel.rank + k];
        score.push_back(prod);
      }
      else {
        score.push_back(-1e10);
      }
    }

    ndcg_sum += TestRating.compute_user_ndcg(uid, score);
	}

  return ndcg_sum / (double)PredictedModel.n_users;
}

#endif
<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: amr
 *
 * Created on October 24, 2016, 8:43 PM
 */

#include <iostream>
#include <string>

#include "src/server/Server.h"

/*
 *
 */
int main(int argc, char ** argv) {
    Server* server = new Server(4000);
    server->run();

    return 0;
}
<commit_msg>Remove unnecessary header<commit_after>/*
 * File:   main.cpp
 * Author: amr
 *
 * Created on October 24, 2016, 8:43 PM
 */

#include <iostream>

#include "src/server/Server.h"

/*
 *
 */
int main(int argc, char ** argv) {
    Server* server = new Server(4000);
    server->run();

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>

#include "LuaCpp/LuaCpp.hpp"

int main(int argc, char **argv)
{
	lpp::State luaState;
	luaState.openLib("base", luaopen_base);
	luaState.openLib("math", luaopen_math);
	luaState.openLib("string", luaopen_string);
	luaState.openLib("table", luaopen_table);

	luaState.loadFile("main.lua");

	luaState["i"] = 9;
	luaState["j"] = std::vector<int>{5, 3, 2};
	luaState["m"] = std::map<std::string, std::string>{{"first", "hello"}, {"second", "world"}};

	luaState.run();

	std::string str0 = luaState["i"];
	std::string str1 = luaState["j"][1];
	std::string str2 = luaState["j"][2];
	std::string str3 = luaState["j"][3];

	std::cout << str0 << '\n';
	std::cout << str1 << '\n';
	std::cout << str2 << '\n';
	std::cout << str3 << '\n';

	return 0;
}
<commit_msg>simple lightuserdata test<commit_after>#include <iostream>

#include "LuaCpp/LuaCpp.hpp"

template<typename Type>
struct Vector2D
{
	Type x, y;
};

int main(int argc, char **argv)
{
	lpp::State luaState;
	luaState.openLib("base", luaopen_base);
	luaState.openLib("math", luaopen_math);
	luaState.openLib("string", luaopen_string);
	luaState.openLib("table", luaopen_table);

	luaState.loadFile("main.lua");

	luaState["i"] = 9;
	luaState["j"] = std::vector<int>{5, 3, 2};
	luaState["m"] = std::map<std::string, std::string>{{"first", "hello"}, {"second", "world"}};

	Vector2D<int> vec2d{5, 3};
	luaState["vec2d"] = vec2d;

	luaState.run();

	Vector2D<int>* anotherVec2d = luaState["vec2d"];

	std::cout << "vec2d.x: " << anotherVec2d->x << '\n';
	std::cout << "vec2d.y: " << anotherVec2d->y << '\n';

	std::string str0 = luaState["i"];
	std::string str1 = luaState["j"][1];
	std::string str2 = luaState["j"][2];
	std::string str3 = luaState["j"][3];

	std::cout << str0 << '\n';
	std::cout << str1 << '\n';
	std::cout << str2 << '\n';
	std::cout << str3 << '\n';

	return 0;
}
<|endoftext|>