<commit_before>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

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

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

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "lotus.h"

#include <postgresql/libpq-fe.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>

const char* LotusException::what() const noexcept {
    return message.c_str();
}

Lotus::Lotus(const std::string & connection_string):
    delimiter(";"),
    null_value("NULL"),
    connection(PQconnectdb(connection_string.c_str()))
{
    if (PQstatus(this->connection) != CONNECTION_OK) {
        throw LotusException(std::string("Failed to connect: ")
                             + PQerrorMessage(this->connection));
    }
}

void Lotus::start_transaction() {
    this->exec("BEGIN", "Begin transaction");
}

void Lotus::rollback() {
    this->exec("ROLLBACK", "Rollback transaction");
}

void Lotus::commit() {
    this->exec("COMMIT", "Commit transaction");
}

void Lotus::exec(const std::string& request, const std::string& error_message, int expected_code) {
    PGresult *res = PQexec(this->connection, request.c_str());
    if (PQresultStatus(res) != expected_code) {
        std::string message = "Request failed: " + error_message + " " +  PQresultErrorMessage(res);
        PQclear(res);
        throw LotusException(message);
    }
    PQclear(res);
}

void Lotus::prepare_bulk_insert(const std::string& table, const std::vector<std::string>& columns) {
    std::string request = "COPY " + table + "(" + boost::algorithm::join(columns, ",")
        + ")  FROM STDIN WITH (FORMAT CSV, DELIMITER '" + delimiter + "', NULL '" + null_value
        + "', QUOTE '\"')";
    this->exec(request, "Prepare bulk insert",  PGRES_COPY_IN);
}

void Lotus::insert(std::vector<std::string> elements) {
    for(std::string & element : elements){
        if(element != null_value){
            element = "\"" + boost::algorithm::replace_all_copy(element, "\"", "\"\"") + "\"";
        }
    }

    std::string line = boost::algorithm::join(elements, this->delimiter) + "\n";
    int result_code = PQputCopyData(this->connection, line.c_str(),  int(line.size()));
    if(result_code != 1){
        throw LotusException(std::string("Failed to insert an entry in bulk insert ")
                             + PQerrorMessage(this->connection));
    }
}

void Lotus::finish_bulk_insert() {
    int result_code =  PQputCopyEnd(this->connection, NULL);
    if(result_code != 1){
        throw LotusException(std::string("finish bulk insert failed: ")
                             + PQerrorMessage(this->connection));
    }

    PGresult *res = NULL;
    do{
        PQclear(res);
        res = NULL;
        res = PQgetResult(this->connection);
        if(res != NULL && PQresultStatus(res) != PGRES_COMMAND_OK){
            PQclear(res);
            throw LotusException(std::string("failed to finish bulk insert in final loop: ")
                                 + PQerrorMessage(this->connection));
        }
    } while(res != NULL);

}

void Lotus::close_connection() {
    PQfinish(this->connection);
}

std::string Lotus::make_upsert_string(const std::string& table,
        const std::vector<std::pair<std::string, std::string>>& key_values) {
    std::vector<std::string> key_value_updates;
    key_value_updates.resize(key_values.size());
    std::transform(key_values.begin(), key_values.end(), key_value_updates.begin(),
            [](std::pair<std::string, std::string> kv) {
            return kv.first + "='"+ kv.second + "'";
            });
    std::string update_query = "update " + table + " set " +
        boost::algorithm::join(key_value_updates, ",");

    std::vector<std::string> keys_inserts, values_inserts;
    keys_inserts.resize(key_values.size());
    values_inserts.resize(key_values.size());
    std::transform(key_values.begin(), key_values.end(), values_inserts.begin(),
            [](std::pair<std::string, std::string> kv) {
            return "'"+ kv.second + "'";
            });
    std::transform(key_values.begin(), key_values.end(), keys_inserts.begin(),
            [](std::pair<std::string, std::string> kv) {
            return kv.first;
            });

    std::string insert_query = "insert into " + table + " ("+
        boost::algorithm::join(keys_inserts, ",") + ") select " +
        boost::algorithm::join(values_inserts, ",");

    return "WITH upsert AS "
    "(" + update_query + " RETURNING *) "
    + insert_query + " WHERE NOT EXISTS (SELECT * FROM upsert);";
}

Lotus::~Lotus() {
    this->close_connection();
}
<commit_msg>utils: modification to allow NULL as text value<commit_after>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

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

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

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "lotus.h"

#include <postgresql/libpq-fe.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>

const char* LotusException::what() const noexcept {
    return message.c_str();
}

Lotus::Lotus(const std::string & connection_string):
    delimiter(";"),
    null_value("__NULL"),
    connection(PQconnectdb(connection_string.c_str()))
{
    if (PQstatus(this->connection) != CONNECTION_OK) {
        throw LotusException(std::string("Failed to connect: ")
                             + PQerrorMessage(this->connection));
    }
}

void Lotus::start_transaction() {
    this->exec("BEGIN", "Begin transaction");
}

void Lotus::rollback() {
    this->exec("ROLLBACK", "Rollback transaction");
}

void Lotus::commit() {
    this->exec("COMMIT", "Commit transaction");
}

void Lotus::exec(const std::string& request, const std::string& error_message, int expected_code) {
    PGresult *res = PQexec(this->connection, request.c_str());
    if (PQresultStatus(res) != expected_code) {
        std::string message = "Request failed: " + error_message + " " +  PQresultErrorMessage(res);
        PQclear(res);
        throw LotusException(message);
    }
    PQclear(res);
}

void Lotus::prepare_bulk_insert(const std::string& table, const std::vector<std::string>& columns) {
    std::string request = "COPY " + table + "(" + boost::algorithm::join(columns, ",")
        + ")  FROM STDIN WITH (FORMAT CSV, DELIMITER '" + delimiter + "', NULL '" + "NULL"
        + "', QUOTE '\"')";
    this->exec(request, "Prepare bulk insert",  PGRES_COPY_IN);
}

void Lotus::insert(std::vector<std::string> elements) {
    for(std::string & element : elements){
        if(element != null_value){
            element = "\"" + boost::algorithm::replace_all_copy(element, "\"", "\"\"") + "\"";
        } else {
            element = "NULL";
        }
    }

    std::string line = boost::algorithm::join(elements, this->delimiter) + "\n";
    int result_code = PQputCopyData(this->connection, line.c_str(),  int(line.size()));
    if(result_code != 1){
        throw LotusException(std::string("Failed to insert an entry in bulk insert ")
                             + PQerrorMessage(this->connection));
    }
}

void Lotus::finish_bulk_insert() {
    int result_code =  PQputCopyEnd(this->connection, NULL);
    if(result_code != 1){
        throw LotusException(std::string("finish bulk insert failed: ")
                             + PQerrorMessage(this->connection));
    }

    PGresult *res = NULL;
    do{
        PQclear(res);
        res = NULL;
        res = PQgetResult(this->connection);
        if(res != NULL && PQresultStatus(res) != PGRES_COMMAND_OK){
            PQclear(res);
            throw LotusException(std::string("failed to finish bulk insert in final loop: ")
                                 + PQerrorMessage(this->connection));
        }
    } while(res != NULL);

}

void Lotus::close_connection() {
    PQfinish(this->connection);
}

std::string Lotus::make_upsert_string(const std::string& table,
        const std::vector<std::pair<std::string, std::string>>& key_values) {
    std::vector<std::string> key_value_updates;
    key_value_updates.resize(key_values.size());
    std::transform(key_values.begin(), key_values.end(), key_value_updates.begin(),
            [](std::pair<std::string, std::string> kv) {
            return kv.first + "='"+ kv.second + "'";
            });
    std::string update_query = "update " + table + " set " +
        boost::algorithm::join(key_value_updates, ",");

    std::vector<std::string> keys_inserts, values_inserts;
    keys_inserts.resize(key_values.size());
    values_inserts.resize(key_values.size());
    std::transform(key_values.begin(), key_values.end(), values_inserts.begin(),
            [](std::pair<std::string, std::string> kv) {
            return "'"+ kv.second + "'";
            });
    std::transform(key_values.begin(), key_values.end(), keys_inserts.begin(),
            [](std::pair<std::string, std::string> kv) {
            return kv.first;
            });

    std::string insert_query = "insert into " + table + " ("+
        boost::algorithm::join(keys_inserts, ",") + ") select " +
        boost::algorithm::join(values_inserts, ",");

    return "WITH upsert AS "
    "(" + update_query + " RETURNING *) "
    + insert_query + " WHERE NOT EXISTS (SELECT * FROM upsert);";
}

Lotus::~Lotus() {
    this->close_connection();
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
//  This utility is designed to be used by the GCC frontend for creating
// bytecode files from it's intermediate llvm assembly.  The requirements for
// this utility are thus slightly different than that of the standard as util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Transforms/Scalar/InstructionCombining.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "Support/CommandLine.h"
#include <memory>
#include <fstream>
#include <string>

cl::String InputFilename ("", "Parse <arg> file, compile to bytecode",
                          cl::Required, "");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
cl::Flag   StopAtLevelRaise("stopraise", "Stop optimization before level raise",
                            cl::Hidden);

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    cerr << E.getMessage() << endl;
    return 1;
  }

  if (M.get() == 0) {
    cerr << "assembly didn't read correctly.\n";
    return 1;
  }

  if (OutputFilename == "") {   // Didn't specify an output filename?
    std::string IFN = InputFilename;
    int Len = IFN.length();
    if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
      OutputFilename = std::string(IFN.begin(), IFN.end()-2);
    } else {
      OutputFilename = IFN;   // Append a .o to it
    }
    OutputFilename += ".o";
  }

  std::ofstream Out(OutputFilename.c_str(), ios::out);
  if (!Out.good()) {
    cerr << "Error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;
  Passes.add(createDeadInstEliminationPass());    // Remove Dead code/vars
  Passes.add(createRaiseAllocationsPass());       // call %malloc -> malloc inst
  Passes.add(createCleanupGCCOutputPass());       // Fix gccisms
  Passes.add(createIndVarSimplifyPass());         // Simplify indvars
  if (!StopAtLevelRaise) {
    Passes.add(createRaisePointerReferencesPass()); // Eliminate casts
    Passes.add(createConstantMergePass());          // Merge dup global consts
    Passes.add(createInstructionCombiningPass());   // Combine silly seq's
    Passes.add(createDeadCodeEliminationPass());    // Remove Dead code/vars
  }
  Passes.add(new WriteBytecodePass(&Out));        // Write bytecode to file...

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());
  return 0;
}

<commit_msg>Rename constructor function for mem2reg pass.<commit_after>//===----------------------------------------------------------------------===//
// LLVM 'GCCAS' UTILITY
//
//  This utility is designed to be used by the GCC frontend for creating
// bytecode files from it's intermediate llvm assembly.  The requirements for
// this utility are thus slightly different than that of the standard as util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/CleanupGCCOutput.h"
#include "llvm/Transforms/LevelChange.h"
#include "llvm/Transforms/ConstantMerge.h"
#include "llvm/Transforms/ChangeAllocations.h"
#include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
#include "llvm/Transforms/Scalar/InstructionCombining.h"
#include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "Support/CommandLine.h"
#include <memory>
#include <fstream>
#include <string>

cl::String InputFilename ("", "Parse <arg> file, compile to bytecode",
                          cl::Required, "");
cl::String OutputFilename("o", "Override output filename", cl::NoFlags, "");
cl::Flag   StopAtLevelRaise("stopraise", "Stop optimization before level raise",
                            cl::Hidden);

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    cerr << E.getMessage() << endl;
    return 1;
  }

  if (M.get() == 0) {
    cerr << "assembly didn't read correctly.\n";
    return 1;
  }

  if (OutputFilename == "") {   // Didn't specify an output filename?
    std::string IFN = InputFilename;
    int Len = IFN.length();
    if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
      OutputFilename = std::string(IFN.begin(), IFN.end()-2);
    } else {
      OutputFilename = IFN;   // Append a .o to it
    }
    OutputFilename += ".o";
  }

  std::ofstream Out(OutputFilename.c_str(), ios::out);
  if (!Out.good()) {
    cerr << "Error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;
  Passes.add(createDeadInstEliminationPass());    // Remove Dead code/vars
  Passes.add(createRaiseAllocationsPass());       // call %malloc -> malloc inst
  Passes.add(createPromoteMemoryToRegister());    // memory->register promotion
  Passes.add(createCleanupGCCOutputPass());       // Fix gccisms
  Passes.add(createIndVarSimplifyPass());         // Simplify indvars
  if (!StopAtLevelRaise) {
    Passes.add(createRaisePointerReferencesPass()); // Eliminate casts
    Passes.add(createConstantMergePass());          // Merge dup global consts
    Passes.add(createInstructionCombiningPass());   // Combine silly seq's
    Passes.add(createDeadCodeEliminationPass());    // Remove Dead code/vars
  }
  Passes.add(new WriteBytecodePass(&Out));        // Write bytecode to file...

  // Run our queue of passes all at once now, efficiently.
  Passes.run(M.get());
  return 0;
}

<|endoftext|>


<commit_before>//===-- gccas.cpp - The "optimizing assembler" used by the GCC frontend ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is designed to be used by the GCC frontend for creating bytecode
// files from its intermediate LLVM assembly.  The requirements for this utility
// are thus slightly different than that of the standard `as' util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

using namespace llvm;

namespace {
  cl::opt<std::string>
  InputFilename(cl::Positional,cl::desc("<input llvm assembly>"),cl::init("-"));

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verify("verify", cl::desc("Verify each pass result"));

  cl::opt<bool>
  DisableInline("disable-inlining", cl::desc("Do not run the inliner pass"));

  cl::opt<bool>
  DisableOptimizations("disable-opt",
                       cl::desc("Do not run any optimization passes"));
}

static inline void addPass(PassManager &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);

  // If we are verifying all of the intermediate steps, add the verifier...
  if (Verify) PM.add(createVerifierPass());
}

void AddConfiguredTransformationPasses(PassManager &PM) {
  PM.add(createVerifierPass());                  // Verify that input is correct
  addPass(PM, createLowerSetJmpPass());          // Lower llvm.setjmp/.longjmp
  addPass(PM, createFunctionResolvingPass());    // Resolve (...) functions

  if (DisableOptimizations) return;

  addPass(PM, createCFGSimplificationPass());    // Clean up disgusting code
  addPass(PM, createRaiseAllocationsPass());     // call %malloc -> malloc inst
  addPass(PM, createGlobalDCEPass());            // Remove unused globals
  addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
  addPass(PM, createDeadArgEliminationPass());   // Dead argument elimination

  addPass(PM, createPruneEHPass());              // Remove dead EH info

  if (!DisableInline)
    addPass(PM, createFunctionInliningPass());   // Inline small functions

  addPass(PM, createInstructionCombiningPass()); // Cleanup code for raise
  addPass(PM, createRaisePointerReferencesPass());// Recover type information
  addPass(PM, createTailDuplicationPass());      // Simplify cfg by copying code
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's

  addPass(PM, createReassociatePass());          // Reassociate expressions
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createTailCallEliminationPass());  // Eliminate tail calls
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createLICMPass());                 // Hoist loop invariants
  addPass(PM, createLoadValueNumberingPass());   // GVN for load instructions
  addPass(PM, createGCSEPass());                 // Remove common subexprs
  addPass(PM, createSCCPPass());                 // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  addPass(PM, createInstructionCombiningPass());
  addPass(PM, createIndVarSimplifyPass());       // Canonicalize indvars
  addPass(PM, createAggressiveDCEPass());        // SSA based 'Aggressive DCE'
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
  addPass(PM, createConstantMergePass());        // Merge dup global constants
}

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    std::cerr << argv[0] << ": " << E.getMessage() << "\n";
    return 1;
  }

  if (M.get() == 0) {
    std::cerr << argv[0] << ": assembly didn't read correctly.\n";
    return 1;
  }

  std::ostream *Out = 0;
  if (OutputFilename == "") {   // Didn't specify an output filename?
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      std::string IFN = InputFilename;
      int Len = IFN.length();
      if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
        OutputFilename = std::string(IFN.begin(), IFN.end()-2);
      } else {
        OutputFilename = IFN;   // Append a .o to it
      }
      OutputFilename += ".o";
    }
  }

  if (OutputFilename == "-")
    Out = &std::cout;
  else {
    Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);

    // Make sure that the Out file gets unlinked from the disk if we get a
    // signal
    RemoveFileOnSignal(OutputFilename);
  }

  if (!Out->good()) {
    std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;

  // Add an appropriate TargetData instance for this module...
  Passes.add(new TargetData("gccas", M.get()));

  // Add all of the transformation passes to the pass manager to do the cleanup
  // and optimization of the GCC output.
  //
  AddConfiguredTransformationPasses(Passes);

  // Make sure everything is still good.
  Passes.add(createVerifierPass());

  // Write bytecode to file...
  Passes.add(new WriteBytecodePass(Out));

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M.get());

  if (Out != &std::cout) delete Out;
  return 0;
}
<commit_msg>Now that tailduplication does not bork SSA form, run mem2reg earlier in gccas. This tremendously improves the code generated by the LLVM optimizer, primarily by making the inliner more aggressive.  For example, it improves the stepanov benchmark from 55.56 mega-additions/sec to 98.04 Ma/s.  It also improves the oopack/iterator benchmark from 338.3MFLOPS/s to 1103.4MFLOPS/s.  Less noteworthy, it improves oopack/matrix from 573 -> 641 MFLOPS/s.<commit_after>//===-- gccas.cpp - The "optimizing assembler" used by the GCC frontend ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility is designed to be used by the GCC frontend for creating bytecode
// files from its intermediate LLVM assembly.  The requirements for this utility
// are thus slightly different than that of the standard `as' util.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "Support/CommandLine.h"
#include "Support/Signals.h"
#include <memory>
#include <fstream>

using namespace llvm;

namespace {
  cl::opt<std::string>
  InputFilename(cl::Positional,cl::desc("<input llvm assembly>"),cl::init("-"));

  cl::opt<std::string>
  OutputFilename("o", cl::desc("Override output filename"),
                 cl::value_desc("filename"));

  cl::opt<bool>
  Verify("verify", cl::desc("Verify each pass result"));

  cl::opt<bool>
  DisableInline("disable-inlining", cl::desc("Do not run the inliner pass"));

  cl::opt<bool>
  DisableOptimizations("disable-opt",
                       cl::desc("Do not run any optimization passes"));
}

static inline void addPass(PassManager &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);

  // If we are verifying all of the intermediate steps, add the verifier...
  if (Verify) PM.add(createVerifierPass());
}

void AddConfiguredTransformationPasses(PassManager &PM) {
  PM.add(createVerifierPass());                  // Verify that input is correct
  addPass(PM, createLowerSetJmpPass());          // Lower llvm.setjmp/.longjmp
  addPass(PM, createFunctionResolvingPass());    // Resolve (...) functions

  if (DisableOptimizations) return;

  addPass(PM, createRaiseAllocationsPass());     // call %malloc -> malloc inst
  addPass(PM, createCFGSimplificationPass());    // Clean up disgusting code
  addPass(PM, createPromoteMemoryToRegister());  // Kill useless allocas
  addPass(PM, createGlobalDCEPass());            // Remove unused globals
  addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation
  addPass(PM, createDeadArgEliminationPass());   // Dead argument elimination
  addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE
  addPass(PM, createCFGSimplificationPass());    // Clean up after IPCP & DAE

  addPass(PM, createPruneEHPass());              // Remove dead EH info

  if (!DisableInline)
    addPass(PM, createFunctionInliningPass());   // Inline small functions

  addPass(PM, createRaisePointerReferencesPass());// Recover type information
  addPass(PM, createTailDuplicationPass());      // Simplify cfg by copying code
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's

  addPass(PM, createReassociatePass());          // Reassociate expressions
  addPass(PM, createInstructionCombiningPass()); // Combine silly seq's
  addPass(PM, createTailCallEliminationPass());  // Eliminate tail calls
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createLICMPass());                 // Hoist loop invariants
  addPass(PM, createLoadValueNumberingPass());   // GVN for load instructions
  addPass(PM, createGCSEPass());                 // Remove common subexprs
  addPass(PM, createSCCPPass());                 // Constant prop with SCCP

  // Run instcombine after redundancy elimination to exploit opportunities
  // opened up by them.
  addPass(PM, createInstructionCombiningPass());
  addPass(PM, createIndVarSimplifyPass());       // Canonicalize indvars
  addPass(PM, createAggressiveDCEPass());        // SSA based 'Aggressive DCE'
  addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
  addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
  addPass(PM, createConstantMergePass());        // Merge dup global constants
}

int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");

  std::auto_ptr<Module> M;
  try {
    // Parse the file now...
    M.reset(ParseAssemblyFile(InputFilename));
  } catch (const ParseException &E) {
    std::cerr << argv[0] << ": " << E.getMessage() << "\n";
    return 1;
  }

  if (M.get() == 0) {
    std::cerr << argv[0] << ": assembly didn't read correctly.\n";
    return 1;
  }

  std::ostream *Out = 0;
  if (OutputFilename == "") {   // Didn't specify an output filename?
    if (InputFilename == "-") {
      OutputFilename = "-";
    } else {
      std::string IFN = InputFilename;
      int Len = IFN.length();
      if (IFN[Len-2] == '.' && IFN[Len-1] == 's') {   // Source ends in .s?
        OutputFilename = std::string(IFN.begin(), IFN.end()-2);
      } else {
        OutputFilename = IFN;   // Append a .o to it
      }
      OutputFilename += ".o";
    }
  }

  if (OutputFilename == "-")
    Out = &std::cout;
  else {
    Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);

    // Make sure that the Out file gets unlinked from the disk if we get a
    // signal
    RemoveFileOnSignal(OutputFilename);
  }

  if (!Out->good()) {
    std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
    return 1;
  }

  // In addition to just parsing the input from GCC, we also want to spiff it up
  // a little bit.  Do this now.
  //
  PassManager Passes;

  // Add an appropriate TargetData instance for this module...
  Passes.add(new TargetData("gccas", M.get()));

  // Add all of the transformation passes to the pass manager to do the cleanup
  // and optimization of the GCC output.
  //
  AddConfiguredTransformationPasses(Passes);

  // Make sure everything is still good.
  Passes.add(createVerifierPass());

  // Write bytecode to file...
  Passes.add(new WriteBytecodePass(Out));

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M.get());

  if (Out != &std::cout) delete Out;
  return 0;
}
<|endoftext|>


<commit_before>//===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
//
// This tool implements a just-in-time compiler for LLVM, allowing direct
// execution of LLVM bytecode in an efficient manner.
//
// FIXME: This code will get more object oriented as we get the call back
// intercept stuff implemented.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"

#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
struct JelloMachineCodeEmitter : public MachineCodeEmitter {
  void startFunction(MachineFunction &F) {
    std::cout << "\n**** Writing machine code for function: "
              << F.getFunction()->getName() << "\n";
  }

  void startBasicBlock(MachineBasicBlock &BB) {
    std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n";
  }

  void emitByte(unsigned char B) {
    std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " ";
  }
  void emitPCRelativeDisp(Value *V) {
    std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> ";
  }
};

namespace {
  cl::opt<std::string>
  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));

  cl::opt<std::string>
  MainFunction("f", cl::desc("Function to execute"), cl::init("main"),
               cl::value_desc("function name"));
}

//===----------------------------------------------------------------------===//
// main Driver function
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm just in time compiler\n");

  // Allocate a target... in the future this will be controllable on the
  // command line.
  std::auto_ptr<TargetMachine> target(allocateX86TargetMachine());
  assert(target.get() && "Could not allocate target machine!");

  TargetMachine &Target = *target.get();

  // Parse the input bytecode file...
  std::string ErrorMsg;
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFile, &ErrorMsg));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode '" << InputFile
              << "' didn't read correctly: << " << ErrorMsg << "\n";
    return 1;
  }

  PassManager Passes;

  // Compile LLVM Code down to machine code in the intermediate representation
  if (Target.addPassesToJITCompile(Passes)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' doesn't support JIT compilation!\n";
    return 1;
  }

  // Turn the machine code intermediate representation into bytes in memory that
  // may be executed.
  //
  JelloMachineCodeEmitter MCE;
  if (Target.addPassesToEmitMachineCode(Passes, MCE)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' doesn't support machine code emission!\n";
    return 1;
  }

  // JIT all of the methods in the module.  Eventually this will JIT functions
  // on demand.
  Passes.run(*M.get());

  return 0;
}

<commit_msg>Final tweak to printer<commit_after>//===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
//
// This tool implements a just-in-time compiler for LLVM, allowing direct
// execution of LLVM bytecode in an efficient manner.
//
// FIXME: This code will get more object oriented as we get the call back
// intercept stuff implemented.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "Support/CommandLine.h"
#include "Support/Statistic.h"

#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineFunction.h"
struct JelloMachineCodeEmitter : public MachineCodeEmitter {
  void startFunction(MachineFunction &F) {
    std::cout << "\n**** Writing machine code for function: "
              << F.getFunction()->getName() << "\n";
  }
  void finishFunction(MachineFunction &F) {
    std::cout << "\n";
  }
  void startBasicBlock(MachineBasicBlock &BB) {
    std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n";
  }

  void emitByte(unsigned char B) {
    std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " ";
  }
  void emitPCRelativeDisp(Value *V) {
    std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> ";
  }
};

namespace {
  cl::opt<std::string>
  InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));

  cl::opt<std::string>
  MainFunction("f", cl::desc("Function to execute"), cl::init("main"),
               cl::value_desc("function name"));
}

//===----------------------------------------------------------------------===//
// main Driver function
//
int main(int argc, char **argv) {
  cl::ParseCommandLineOptions(argc, argv, " llvm just in time compiler\n");

  // Allocate a target... in the future this will be controllable on the
  // command line.
  std::auto_ptr<TargetMachine> target(allocateX86TargetMachine());
  assert(target.get() && "Could not allocate target machine!");

  TargetMachine &Target = *target.get();

  // Parse the input bytecode file...
  std::string ErrorMsg;
  std::auto_ptr<Module> M(ParseBytecodeFile(InputFile, &ErrorMsg));
  if (M.get() == 0) {
    std::cerr << argv[0] << ": bytecode '" << InputFile
              << "' didn't read correctly: << " << ErrorMsg << "\n";
    return 1;
  }

  PassManager Passes;

  // Compile LLVM Code down to machine code in the intermediate representation
  if (Target.addPassesToJITCompile(Passes)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' doesn't support JIT compilation!\n";
    return 1;
  }

  // Turn the machine code intermediate representation into bytes in memory that
  // may be executed.
  //
  JelloMachineCodeEmitter MCE;
  if (Target.addPassesToEmitMachineCode(Passes, MCE)) {
    std::cerr << argv[0] << ": target '" << Target.getName()
              << "' doesn't support machine code emission!\n";
    return 1;
  }

  // JIT all of the methods in the module.  Eventually this will JIT functions
  // on demand.
  Passes.run(*M.get());

  return 0;
}

<|endoftext|>


<commit_before>// #include "mmsapt.h"
// #include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
// #include "moses/TranslationTask.h"
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <iostream>
#include "mm/ug_bitext.h"
#include "generic/file_io/ug_stream.h"
#include <string>
#include <sstream>

using namespace Moses;
using namespace sapt;
using namespace std;
using namespace boost;

typedef sapt::L2R_Token<sapt::SimpleWordId> Token;
typedef mmBitext<Token> bitext_t;

struct mycmp
{
  bool operator() (pair<string,uint32_t> const& a,
		   pair<string,uint32_t> const& b) const
  {
    return a.second > b.second;
  }
};

string
basename(string const path, string const suffix)
{
  size_t p = path.find_last_of("/");
  size_t k = path.size() - suffix.size();
  cout << path << " " << suffix << endl;
  cout << path.substr(0,p) << " " << path.substr(k) << endl;
  return path.substr(p, suffix == &path[k] ? k-p : path.size() - p);
}

int main(int argc, char* argv[])
{
  bitext_t B;
  B.open(argv[1],argv[2],argv[3]);
  string line;
  string ifile = argv[4];
  string docname = basename(ifile, string(".") + argv[2] + ".gz");
  boost::iostreams::filtering_istream in;
  ugdiss::open_input_stream(ifile,in);
  while(getline(in,line))
    {
      cout << line << " [" << docname << "]" << endl;
      vector<id_type> snt;
      B.V1->fillIdSeq(line,snt);
      for (size_t i = 0; i < snt.size(); ++i)
	{
	  bitext_t::iter m(B.I1.get());
	  for (size_t k = i; k < snt.size() && m.extend(snt[k]); ++k)
	    {
	      if (m.ca() > 500) continue;
	      sapt::tsa::ArrayEntry I(m.lower_bound(-1));
	      char const* stop = m.upper_bound(-1);
	      map<string,uint32_t> cnt;
	      while (I.next != stop)
		{
		  m.root->readEntry(I.next,I);
		  ++cnt[B.docname(I.sid)];
		}
	      cout << setw(8) << int(m.ca()) << " " << B.V1->toString(&snt[i],&snt[k+1]) << endl;
	      typedef pair<string,uint32_t> entry;
	      vector<entry> ranked; ranked.reserve(cnt.size());
	      BOOST_FOREACH(entry const& e, cnt) ranked.push_back(e);
	      sort(ranked.begin(),ranked.end(),mycmp());
	      BOOST_FOREACH(entry const& e, ranked)
		cout << setw(12) << " " << e.second << " " << e.first << endl;
	      cout << endl;
	    }
	}
    }
}
<commit_msg>Adaptation to renamed functions in Bitext class.<commit_after>// #include "mmsapt.h"
// #include "moses/TranslationModel/PhraseDictionaryTreeAdaptor.h"
// #include "moses/TranslationTask.h"
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm>
#include <iostream>
#include "mm/ug_bitext.h"
#include "generic/file_io/ug_stream.h"
#include <string>
#include <sstream>

using namespace Moses;
using namespace sapt;
using namespace std;
using namespace boost;

typedef sapt::L2R_Token<sapt::SimpleWordId> Token;
typedef mmBitext<Token> bitext_t;

struct mycmp
{
  bool operator() (pair<string,uint32_t> const& a,
		   pair<string,uint32_t> const& b) const
  {
    return a.second > b.second;
  }
};

string
basename(string const path, string const suffix)
{
  size_t p = path.find_last_of("/");
  size_t k = path.size() - suffix.size();
  cout << path << " " << suffix << endl;
  cout << path.substr(0,p) << " " << path.substr(k) << endl;
  return path.substr(p, suffix == &path[k] ? k-p : path.size() - p);
}

int main(int argc, char* argv[])
{
  boost::shared_ptr<bitext_t> B(new bitext_t);
  B->open(argv[1],argv[2],argv[3]);
  string line;
  string ifile = argv[4];
  string docname = basename(ifile, string(".") + argv[2] + ".gz");
  boost::iostreams::filtering_istream in;
  ugdiss::open_input_stream(ifile,in);
  while(getline(in,line))
    {
      cout << line << " [" << docname << "]" << endl;
      vector<id_type> snt;
      B->V1->fillIdSeq(line,snt);
      for (size_t i = 0; i < snt.size(); ++i)
	{
	  bitext_t::iter m(B->I1.get());
	  for (size_t k = i; k < snt.size() && m.extend(snt[k]); ++k)
	    {
	      if (m.ca() > 500) continue;
	      sapt::tsa::ArrayEntry I(m.lower_bound(-1));
	      char const* stop = m.upper_bound(-1);
	      map<string,uint32_t> cnt;
	      while (I.next != stop)
		{
		  m.root->readEntry(I.next,I);
		  ++cnt[B->sid2docname(I.sid)];
		}
	      cout << setw(8) << int(m.ca()) << " "
		   << B->V1->toString(&snt[i],&snt[k+1]) << endl;
	      typedef pair<string,uint32_t> entry;
	      vector<entry> ranked; ranked.reserve(cnt.size());
	      BOOST_FOREACH(entry const& e, cnt) ranked.push_back(e);
	      sort(ranked.begin(),ranked.end(),mycmp());
	      BOOST_FOREACH(entry const& e, ranked)
		cout << setw(12) << " " << e.second << " " << e.first << endl;
	      cout << endl;
	    }
	}
    }
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2019 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdio.h>
#include <string.h>

#include "falco_common.h"
#include "webserver.h"
#include "json_evt.h"
#include "banned.h" // This raises a compilation error when certain functions are used

using json = nlohmann::json;
using namespace std;

string k8s_audit_handler::m_k8s_audit_event_source = "k8s_audit";

k8s_audit_handler::k8s_audit_handler(falco_engine *engine, falco_outputs *outputs):
	m_engine(engine), m_outputs(outputs)
{
}

k8s_audit_handler::~k8s_audit_handler()
{
}

bool k8s_healthz_handler::handleGet(CivetServer *server, struct mg_connection *conn)
{
	const std::string status_body = "{\"status\": \"ok\"}";
	mg_send_http_ok(conn, "application/json", status_body.size());
	mg_printf(conn, "%s", status_body.c_str());

	return true;
}

bool k8s_audit_handler::accept_data(falco_engine *engine,
				    falco_outputs *outputs,
				    std::string &data,
				    std::string &errstr)
{
	std::list<json_event> jevts;
	json j;

	try
	{
		j = json::parse(data);
	}
	catch(json::parse_error &e)
	{
		errstr = string("Could not parse data: ") + e.what();
		return false;
	}
	catch(json::out_of_range &e)
	{
		errstr = string("Could not parse data: ") + e.what();
		return false;
	}

	bool ok;
	try
	{
		ok = falco_k8s_audit::parse_k8s_audit_json(j, jevts);
	}
	catch(json::type_error &e)
	{
		ok = false;
	}
	if(!ok)
	{
		errstr = string("Data not recognized as a k8s audit event");
		return false;
	}

	for(auto &jev : jevts)
	{
		std::unique_ptr<falco_engine::rule_result> res;

		try
		{
			res = engine->process_event(m_k8s_audit_event_source, &jev);
		}
		catch(...)
		{
			errstr = string("unkown error processing audit event");
			fprintf(stderr, "%s\n", errstr.c_str());
			return false;
		}

		if(res)
		{
			try
			{
				outputs->handle_event(res->evt, res->rule,
						      res->source, res->priority_num,
						      res->format, res->tags);
			}
			catch(falco_exception &e)
			{
				errstr = string("Internal error handling output: ") + e.what();
				fprintf(stderr, "%s\n", errstr.c_str());
				return false;
			}
		}
	}

	return true;
}

bool k8s_audit_handler::accept_uploaded_data(std::string &post_data, std::string &errstr)
{
	return k8s_audit_handler::accept_data(m_engine, m_outputs, post_data, errstr);
}

bool k8s_audit_handler::handleGet(CivetServer *server, struct mg_connection *conn)
{
	mg_send_http_error(conn, 405, "GET method not allowed");

	return true;
}

// The version in CivetServer.cpp has valgrind compliants due to
// unguarded initialization of c++ string from buffer.
static void get_post_data(struct mg_connection *conn, std::string &postdata)
{
	mg_lock_connection(conn);
	char buf[2048];
	int r = mg_read(conn, buf, sizeof(buf));
	while(r > 0)
	{
		postdata.append(buf, r);
		r = mg_read(conn, buf, sizeof(buf));
	}
	mg_unlock_connection(conn);
}

bool k8s_audit_handler::handlePost(CivetServer *server, struct mg_connection *conn)
{
	// Ensure that the content-type is application/json
	const char *ct = server->getHeader(conn, string("Content-Type"));

	if(ct == NULL || string(ct) != "application/json")
	{
		mg_send_http_error(conn, 400, "Wrong Content Type");

		return true;
	}

	std::string post_data;
	get_post_data(conn, post_data);
	std::string errstr;

	if(!accept_uploaded_data(post_data, errstr))
	{
		errstr = "Bad Request: " + errstr;
		mg_send_http_error(conn, 400, "%s", errstr.c_str());

		return true;
	}

	const std::string ok_body = "Ok";
	mg_send_http_ok(conn, "text/html", ok_body.size());
	mg_printf(conn, "%s", ok_body.c_str());

	return true;
}

falco_webserver::falco_webserver():
	m_config(NULL)
{
}

falco_webserver::~falco_webserver()
{
	stop();
}

void falco_webserver::init(falco_configuration *config,
			   falco_engine *engine,
			   falco_outputs *outputs)
{
	m_config = config;
	m_engine = engine;
	m_outputs = outputs;
}

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
	return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

void falco_webserver::start()
{
	if(m_server)
	{
		stop();
	}

	if(!m_config)
	{
		throw falco_exception("No config provided to webserver");
	}

	if(!m_engine)
	{
		throw falco_exception("No engine provided to webserver");
	}

	if(!m_outputs)
	{
		throw falco_exception("No outputs provided to webserver");
	}

	std::vector<std::string> cpp_options = {
		"num_threads", to_string(1)};

	if(m_config->m_webserver_ssl_enabled)
	{
		cpp_options.push_back("listening_ports");
		cpp_options.push_back(to_string(m_config->m_webserver_listen_port) + "s");
		cpp_options.push_back("ssl_certificate");
		cpp_options.push_back(m_config->m_webserver_ssl_certificate);
	}
	else
	{
		cpp_options.push_back("listening_ports");
		cpp_options.push_back(to_string(m_config->m_webserver_listen_port));
	}

	try
	{
		m_server = make_unique<CivetServer>(cpp_options);
	}
	catch(CivetException &e)
	{
		throw falco_exception(std::string("Could not create embedded webserver: ") + e.what());
	}
	if(!m_server->getContext())
	{
		throw falco_exception("Could not create embedded webserver");
	}

	m_k8s_audit_handler = make_unique<k8s_audit_handler>(m_engine, m_outputs);
	m_server->addHandler(m_config->m_webserver_k8s_audit_endpoint, *m_k8s_audit_handler);
	m_k8s_healthz_handler = make_unique<k8s_healthz_handler>();
	m_server->addHandler(m_config->m_webserver_k8s_healthz_endpoint, *m_k8s_healthz_handler);
}

void falco_webserver::stop()
{
	if(m_server)
	{
		m_server = NULL;
		m_k8s_audit_handler = NULL;
		m_k8s_healthz_handler = NULL;
	}
}
<commit_msg>fix(userspace/falco): accept 'Content-Type' header that contains "application/json", but it is not strictly equal to it.<commit_after>/*
Copyright (C) 2019 The Falco Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include <stdio.h>
#include <string.h>

#include "falco_common.h"
#include "webserver.h"
#include "json_evt.h"
#include "banned.h" // This raises a compilation error when certain functions are used

using json = nlohmann::json;
using namespace std;

string k8s_audit_handler::m_k8s_audit_event_source = "k8s_audit";

k8s_audit_handler::k8s_audit_handler(falco_engine *engine, falco_outputs *outputs):
	m_engine(engine), m_outputs(outputs)
{
}

k8s_audit_handler::~k8s_audit_handler()
{
}

bool k8s_healthz_handler::handleGet(CivetServer *server, struct mg_connection *conn)
{
	const std::string status_body = "{\"status\": \"ok\"}";
	mg_send_http_ok(conn, "application/json", status_body.size());
	mg_printf(conn, "%s", status_body.c_str());

	return true;
}

bool k8s_audit_handler::accept_data(falco_engine *engine,
				    falco_outputs *outputs,
				    std::string &data,
				    std::string &errstr)
{
	std::list<json_event> jevts;
	json j;

	try
	{
		j = json::parse(data);
	}
	catch(json::parse_error &e)
	{
		errstr = string("Could not parse data: ") + e.what();
		return false;
	}
	catch(json::out_of_range &e)
	{
		errstr = string("Could not parse data: ") + e.what();
		return false;
	}

	bool ok;
	try
	{
		ok = falco_k8s_audit::parse_k8s_audit_json(j, jevts);
	}
	catch(json::type_error &e)
	{
		ok = false;
	}
	if(!ok)
	{
		errstr = string("Data not recognized as a k8s audit event");
		return false;
	}

	for(auto &jev : jevts)
	{
		std::unique_ptr<falco_engine::rule_result> res;

		try
		{
			res = engine->process_event(m_k8s_audit_event_source, &jev);
		}
		catch(...)
		{
			errstr = string("unkown error processing audit event");
			fprintf(stderr, "%s\n", errstr.c_str());
			return false;
		}

		if(res)
		{
			try
			{
				outputs->handle_event(res->evt, res->rule,
						      res->source, res->priority_num,
						      res->format, res->tags);
			}
			catch(falco_exception &e)
			{
				errstr = string("Internal error handling output: ") + e.what();
				fprintf(stderr, "%s\n", errstr.c_str());
				return false;
			}
		}
	}

	return true;
}

bool k8s_audit_handler::accept_uploaded_data(std::string &post_data, std::string &errstr)
{
	return k8s_audit_handler::accept_data(m_engine, m_outputs, post_data, errstr);
}

bool k8s_audit_handler::handleGet(CivetServer *server, struct mg_connection *conn)
{
	mg_send_http_error(conn, 405, "GET method not allowed");

	return true;
}

// The version in CivetServer.cpp has valgrind compliants due to
// unguarded initialization of c++ string from buffer.
static void get_post_data(struct mg_connection *conn, std::string &postdata)
{
	mg_lock_connection(conn);
	char buf[2048];
	int r = mg_read(conn, buf, sizeof(buf));
	while(r > 0)
	{
		postdata.append(buf, r);
		r = mg_read(conn, buf, sizeof(buf));
	}
	mg_unlock_connection(conn);
}

bool k8s_audit_handler::handlePost(CivetServer *server, struct mg_connection *conn)
{
	// Ensure that the content-type is application/json
	const char *ct = server->getHeader(conn, string("Content-Type"));

	if(ct == NULL || strstr(ct, "application/json") == NULL)
	{
		mg_send_http_error(conn, 400, "Wrong Content Type");

		return true;
	}

	std::string post_data;
	get_post_data(conn, post_data);
	std::string errstr;

	if(!accept_uploaded_data(post_data, errstr))
	{
		errstr = "Bad Request: " + errstr;
		mg_send_http_error(conn, 400, "%s", errstr.c_str());

		return true;
	}

	const std::string ok_body = "Ok";
	mg_send_http_ok(conn, "text/html", ok_body.size());
	mg_printf(conn, "%s", ok_body.c_str());

	return true;
}

falco_webserver::falco_webserver():
	m_config(NULL)
{
}

falco_webserver::~falco_webserver()
{
	stop();
}

void falco_webserver::init(falco_configuration *config,
			   falco_engine *engine,
			   falco_outputs *outputs)
{
	m_config = config;
	m_engine = engine;
	m_outputs = outputs;
}

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
	return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

void falco_webserver::start()
{
	if(m_server)
	{
		stop();
	}

	if(!m_config)
	{
		throw falco_exception("No config provided to webserver");
	}

	if(!m_engine)
	{
		throw falco_exception("No engine provided to webserver");
	}

	if(!m_outputs)
	{
		throw falco_exception("No outputs provided to webserver");
	}

	std::vector<std::string> cpp_options = {
		"num_threads", to_string(1)};

	if(m_config->m_webserver_ssl_enabled)
	{
		cpp_options.push_back("listening_ports");
		cpp_options.push_back(to_string(m_config->m_webserver_listen_port) + "s");
		cpp_options.push_back("ssl_certificate");
		cpp_options.push_back(m_config->m_webserver_ssl_certificate);
	}
	else
	{
		cpp_options.push_back("listening_ports");
		cpp_options.push_back(to_string(m_config->m_webserver_listen_port));
	}

	try
	{
		m_server = make_unique<CivetServer>(cpp_options);
	}
	catch(CivetException &e)
	{
		throw falco_exception(std::string("Could not create embedded webserver: ") + e.what());
	}
	if(!m_server->getContext())
	{
		throw falco_exception("Could not create embedded webserver");
	}

	m_k8s_audit_handler = make_unique<k8s_audit_handler>(m_engine, m_outputs);
	m_server->addHandler(m_config->m_webserver_k8s_audit_endpoint, *m_k8s_audit_handler);
	m_k8s_healthz_handler = make_unique<k8s_healthz_handler>();
	m_server->addHandler(m_config->m_webserver_k8s_healthz_endpoint, *m_k8s_healthz_handler);
}

void falco_webserver::stop()
{
	if(m_server)
	{
		m_server = NULL;
		m_k8s_audit_handler = NULL;
		m_k8s_healthz_handler = NULL;
	}
}
<|endoftext|>


<commit_before>#include "TransformComponent.h"

void TransformComponent::SetTranslation(float x, float y, float z)
{
	translation.x = x;
	translation.y = y;
	translation.z = z;
}
void TransformComponent::SetScale(float x, float y, float z)
{
	scale.x = x;
	scale.y = y;
	scale.z = z;
}

void TransformComponent::SetRotation(float x, float y, float z, float w)
{
	rotation.x = x;
	rotation.y = y;
	rotation.z = z;
	rotation.w = w;
}

void TransformComponent::Rotate(math::float3 euler_rotation)
{
	rotation = rotation.FromEulerXYX(euler_rotation.x, euler_rotation.y, euler_rotation.z);
}

float TransformComponent::GetAngleInRad() const
{
	return rotation.Angle();
}

math::float3 TransformComponent::GetScale() const
{
	return math::float3(scale.x, scale.y, scale.z);
}

math::float3 TransformComponent::GetTranslation() const
{
	return math::float3(translation.x, translation.y, translation.z);
}

void TransformComponent::GetTransform(math::float4x4 &_transform) const
{
	//FromTRS returns the matrix that corresponds to specific translation (position), rotation and scale
	_transform = math::float4x4::FromTRS(translation, rotation.ToFloat4x4(), scale);
	_transform.Transpose();
}
<commit_msg>Release crash fixed<commit_after>#include "TransformComponent.h"

void TransformComponent::SetTranslation(float x, float y, float z)
{
	translation.x = x;
	translation.y = y;
	translation.z = z;
}
void TransformComponent::SetScale(float x, float y, float z)
{
	scale.x = x;
	scale.y = y;
	scale.z = z;
}

void TransformComponent::SetRotation(float x, float y, float z, float w)
{
	rotation.x = x;
	rotation.y = y;
	rotation.z = z;
	rotation.w = w;
}

void TransformComponent::Rotate(math::float3 euler_rotation)
{
	rotation = rotation.FromEulerXYX(euler_rotation.x, euler_rotation.y, euler_rotation.z);
}

float TransformComponent::GetAngleInRad() const
{
	return rotation.Angle();
}

math::float3 TransformComponent::GetScale() const
{
	return math::float3(scale.x, scale.y, scale.z);
}

math::float3 TransformComponent::GetTranslation() const
{
	return math::float3(translation.x, translation.y, translation.z);
}

void TransformComponent::GetTransform(math::float4x4 &_transform) const
{
	//FromTRS returns the matrix that corresponds to specific translation (position), rotation and scale
	_transform = math::float4x4::FromTRS(translation, rotation.ToFloat3x3(), scale);
	_transform.Transpose();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: window3.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-04 11:02:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#define _SV_WINDOW_CXX

#include "svsys.h"
#include "vcl/window.h"
#include "vcl/window.hxx"
#include "vcl/waitobj.hxx"
#include "vcl/salgdi.hxx"
#include "vcl/salnativewidgets.hxx"
#include "vcl/salctrlhandle.hxx"
#include "rtl/ustring.hxx"
#include "vcl/button.hxx"

using namespace rtl;

// -----------------------------------------------------------------------
// These functions are mainly passthrough functions that allow access to
// the SalFrame behind a Window object for native widget rendering purposes.
// -----------------------------------------------------------------------

void Window::ImplInitSalControlHandle()
{
    // create SalControlHandle on demand
    // not needed for ordinary windows
    // TODO: move creation to SalGraphics
    //if( !ImplGetWinData()->mpSalControlHandle )
    //    ImplGetWinData()->mpSalControlHandle = new SalControlHandle;
}

// -----------------------------------------------------------------------

BOOL Window::IsNativeControlSupported( ControlType nType, ControlPart nPart )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    return( mpGraphics->IsNativeControlSupported(nType, nPart) );
}

// -----------------------------------------------------------------------

BOOL Window::HitTestNativeControl( ControlType nType,
                              ControlPart nPart,
                              const Region& rControlRegion,
                              const Point& aPos,
                              BOOL& rIsInside )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    ImplInitSalControlHandle();

    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());

    return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, OutputToScreenPixel( aPos ), *ImplGetWinData()->mpSalControlHandle, rIsInside, this ) );
}

// -----------------------------------------------------------------------

void Window::ImplMoveControlValue( ControlType nType, const ImplControlValue& aValue, const Point& rDelta ) const
{
    if( aValue.getOptionalVal() )
    {
        switch( nType )
        {
            case CTRL_SCROLLBAR:
            {
                ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(aValue.getOptionalVal());
                pScVal->maThumbRect.Move( rDelta.X(), rDelta.Y() );
                pScVal->maButton1Rect.Move( rDelta.X(), rDelta.Y() );
                pScVal->maButton2Rect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
            case CTRL_SPINBOX:
            case CTRL_SPINBUTTONS:
            {
                SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(aValue.getOptionalVal());
                pSpVal->maUpperRect.Move( rDelta.X(), rDelta.Y() );
                pSpVal->maLowerRect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
            case CTRL_TOOLBAR:
            {
                ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(aValue.getOptionalVal());
                pTVal->maGripRect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
        }
    }
}

BOOL Window::DrawNativeControl( ControlType nType,
                            ControlPart nPart,
                            const Region& rControlRegion,
                            ControlState nState,
                            const ImplControlValue& aValue,
                            OUString aCaption )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    /*
    if( !IsInPaint() && IsPaintTransparent() )
    {
        // only required if called directly (ie, we're not in Paint() ):
        // force redraw (Paint()) for transparent controls
        // to trigger a repaint of the background
        Region aClipRgn( GetClipRegion() );
        if( !rControlRegion.IsEmpty() )
            aClipRgn.Intersect( rControlRegion );
        Invalidate( aClipRgn, INVALIDATE_UPDATE );
        return TRUE;
    }
    */

    ImplInitSalControlHandle();

    // make sure the current clip region is initialized correctly
    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    if ( mbInitClipRegion )
        ImplInitClipRegion();
    if ( mbOutputClipped )
        return TRUE;

    if ( mbInitLineColor )
        ImplInitLineColor();
    if ( mbInitFillColor )
        ImplInitFillColor();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());

    // do so for ImplControlValue members, also
    ImplMoveControlValue( nType, aValue, aWinOffs );

    Region aTestRegion( GetActiveClipRegion() );
    aTestRegion.Intersect( rControlRegion );
    if( aTestRegion == rControlRegion )
        nState |= CTRL_CACHING_ALLOWED;   // control is not clipped, caching allowed

    BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, aValue, *ImplGetWinData()->mpSalControlHandle, aCaption, this );

    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

BOOL Window::DrawNativeControlText(ControlType nType,
                            ControlPart nPart,
                            const Region& rControlRegion,
                            ControlState nState,
                            const ImplControlValue& aValue,
                            OUString aCaption )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    ImplInitSalControlHandle();

    // make sure the current clip region is initialized correctly
    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return false;

    if ( mbInitClipRegion )
        ImplInitClipRegion();
    if ( mbOutputClipped )
        return true;

    if ( mbInitLineColor )
        ImplInitLineColor();
    if ( mbInitFillColor )
        ImplInitFillColor();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
    ImplMoveControlValue( nType, aValue, aWinOffs );

    BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, aValue, *ImplGetWinData()->mpSalControlHandle, aCaption, this );

    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

BOOL Window::GetNativeControlRegion(  ControlType nType,
                                ControlPart nPart,
                                const Region& rControlRegion,
                                ControlState nState,
                                const ImplControlValue& aValue,
                                OUString aCaption,
                                Region &rNativeBoundingRegion,
                                Region &rNativeContentRegion )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    ImplInitSalControlHandle();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
    ImplMoveControlValue( nType, aValue, aWinOffs );

    BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, aValue,
                                *ImplGetWinData()->mpSalControlHandle, aCaption, rNativeBoundingRegion,
                                rNativeContentRegion, this );
    if( bRet )
    {
        // transform back native regions
        rNativeBoundingRegion.Move( -aWinOffs.X(), -aWinOffs.Y() );
        rNativeContentRegion.Move( -aWinOffs.X(), -aWinOffs.Y() );
    }
    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

WaitObject::~WaitObject()
{
    if ( mpWindow )
        mpWindow->LeaveWait();
}

// -----------------------------------------------------------------------

Size Window::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM:
        return Size();
    case WINDOWSIZE_PREFERRED:
        return GetOptimalSize( WINDOWSIZE_MINIMUM );
    case WINDOWSIZE_MAXIMUM:
    default:
        return Size( LONG_MAX, LONG_MAX );
    }
}

// -----------------------------------------------------------------------

void Window::ImplAdjustNWFSizes()
{
    switch( GetType() )
    {
    case WINDOW_CHECKBOX:
        ((CheckBox*)this)->ImplSetMinimumNWFSize();
        break;
    case WINDOW_RADIOBUTTON:
        ((RadioButton*)this)->ImplSetMinimumNWFSize();
        break;
    default:
        {
            // iterate over children
            Window* pWin = GetWindow( WINDOW_FIRSTCHILD );
            while( pWin )
            {
                pWin->ImplAdjustNWFSizes();
                pWin = pWin->GetWindow( WINDOW_NEXT );
            }
        }
        break;
    }
}
<commit_msg>INTEGRATION: CWS changefileheader (1.11.76); FILE MERGED 2008/04/01 16:05:42 thb 1.11.76.3: #i85898# Stripping all external header guards 2008/04/01 13:01:50 thb 1.11.76.2: #i85898# Stripping all external header guards 2008/03/28 15:45:05 rt 1.11.76.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: window3.cxx,v $
 * $Revision: 1.13 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#define _SV_WINDOW_CXX

#include "svsys.h"
#include "vcl/window.h"
#include "vcl/window.hxx"
#include "vcl/waitobj.hxx"
#include "vcl/salgdi.hxx"
#include "vcl/salnativewidgets.hxx"
#include "vcl/salctrlhandle.hxx"
#include "rtl/ustring.hxx"
#include "vcl/button.hxx"

using namespace rtl;

// -----------------------------------------------------------------------
// These functions are mainly passthrough functions that allow access to
// the SalFrame behind a Window object for native widget rendering purposes.
// -----------------------------------------------------------------------

void Window::ImplInitSalControlHandle()
{
    // create SalControlHandle on demand
    // not needed for ordinary windows
    // TODO: move creation to SalGraphics
    //if( !ImplGetWinData()->mpSalControlHandle )
    //    ImplGetWinData()->mpSalControlHandle = new SalControlHandle;
}

// -----------------------------------------------------------------------

BOOL Window::IsNativeControlSupported( ControlType nType, ControlPart nPart )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    return( mpGraphics->IsNativeControlSupported(nType, nPart) );
}

// -----------------------------------------------------------------------

BOOL Window::HitTestNativeControl( ControlType nType,
                              ControlPart nPart,
                              const Region& rControlRegion,
                              const Point& aPos,
                              BOOL& rIsInside )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    ImplInitSalControlHandle();

    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());

    return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, OutputToScreenPixel( aPos ), *ImplGetWinData()->mpSalControlHandle, rIsInside, this ) );
}

// -----------------------------------------------------------------------

void Window::ImplMoveControlValue( ControlType nType, const ImplControlValue& aValue, const Point& rDelta ) const
{
    if( aValue.getOptionalVal() )
    {
        switch( nType )
        {
            case CTRL_SCROLLBAR:
            {
                ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(aValue.getOptionalVal());
                pScVal->maThumbRect.Move( rDelta.X(), rDelta.Y() );
                pScVal->maButton1Rect.Move( rDelta.X(), rDelta.Y() );
                pScVal->maButton2Rect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
            case CTRL_SPINBOX:
            case CTRL_SPINBUTTONS:
            {
                SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(aValue.getOptionalVal());
                pSpVal->maUpperRect.Move( rDelta.X(), rDelta.Y() );
                pSpVal->maLowerRect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
            case CTRL_TOOLBAR:
            {
                ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(aValue.getOptionalVal());
                pTVal->maGripRect.Move( rDelta.X(), rDelta.Y() );
            }
            break;
        }
    }
}

BOOL Window::DrawNativeControl( ControlType nType,
                            ControlPart nPart,
                            const Region& rControlRegion,
                            ControlState nState,
                            const ImplControlValue& aValue,
                            OUString aCaption )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    /*
    if( !IsInPaint() && IsPaintTransparent() )
    {
        // only required if called directly (ie, we're not in Paint() ):
        // force redraw (Paint()) for transparent controls
        // to trigger a repaint of the background
        Region aClipRgn( GetClipRegion() );
        if( !rControlRegion.IsEmpty() )
            aClipRgn.Intersect( rControlRegion );
        Invalidate( aClipRgn, INVALIDATE_UPDATE );
        return TRUE;
    }
    */

    ImplInitSalControlHandle();

    // make sure the current clip region is initialized correctly
    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    if ( mbInitClipRegion )
        ImplInitClipRegion();
    if ( mbOutputClipped )
        return TRUE;

    if ( mbInitLineColor )
        ImplInitLineColor();
    if ( mbInitFillColor )
        ImplInitFillColor();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());

    // do so for ImplControlValue members, also
    ImplMoveControlValue( nType, aValue, aWinOffs );

    Region aTestRegion( GetActiveClipRegion() );
    aTestRegion.Intersect( rControlRegion );
    if( aTestRegion == rControlRegion )
        nState |= CTRL_CACHING_ALLOWED;   // control is not clipped, caching allowed

    BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, aValue, *ImplGetWinData()->mpSalControlHandle, aCaption, this );

    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

BOOL Window::DrawNativeControlText(ControlType nType,
                            ControlPart nPart,
                            const Region& rControlRegion,
                            ControlState nState,
                            const ImplControlValue& aValue,
                            OUString aCaption )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    ImplInitSalControlHandle();

    // make sure the current clip region is initialized correctly
    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return false;

    if ( mbInitClipRegion )
        ImplInitClipRegion();
    if ( mbOutputClipped )
        return true;

    if ( mbInitLineColor )
        ImplInitLineColor();
    if ( mbInitFillColor )
        ImplInitFillColor();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
    ImplMoveControlValue( nType, aValue, aWinOffs );

    BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, aValue, *ImplGetWinData()->mpSalControlHandle, aCaption, this );

    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

BOOL Window::GetNativeControlRegion(  ControlType nType,
                                ControlPart nPart,
                                const Region& rControlRegion,
                                ControlState nState,
                                const ImplControlValue& aValue,
                                OUString aCaption,
                                Region &rNativeBoundingRegion,
                                Region &rNativeContentRegion )
{
    if( !IsNativeWidgetEnabled() )
        return FALSE;

    if ( !mpGraphics )
        if ( !ImplGetGraphics() )
            return FALSE;

    ImplInitSalControlHandle();

    // Convert the coordinates from relative to Window-absolute, so we draw
    // in the correct place in platform code
    Point aWinOffs;
    aWinOffs = OutputToScreenPixel( aWinOffs );
    Region screenRegion( rControlRegion );
    screenRegion.Move( aWinOffs.X(), aWinOffs.Y());
    ImplMoveControlValue( nType, aValue, aWinOffs );

    BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, aValue,
                                *ImplGetWinData()->mpSalControlHandle, aCaption, rNativeBoundingRegion,
                                rNativeContentRegion, this );
    if( bRet )
    {
        // transform back native regions
        rNativeBoundingRegion.Move( -aWinOffs.X(), -aWinOffs.Y() );
        rNativeContentRegion.Move( -aWinOffs.X(), -aWinOffs.Y() );
    }
    // transform back ImplControlValue members
    ImplMoveControlValue( nType, aValue, Point()-aWinOffs );

    return bRet;
}

// -----------------------------------------------------------------------

WaitObject::~WaitObject()
{
    if ( mpWindow )
        mpWindow->LeaveWait();
}

// -----------------------------------------------------------------------

Size Window::GetOptimalSize(WindowSizeType eType) const
{
    switch (eType) {
    case WINDOWSIZE_MINIMUM:
        return Size();
    case WINDOWSIZE_PREFERRED:
        return GetOptimalSize( WINDOWSIZE_MINIMUM );
    case WINDOWSIZE_MAXIMUM:
    default:
        return Size( LONG_MAX, LONG_MAX );
    }
}

// -----------------------------------------------------------------------

void Window::ImplAdjustNWFSizes()
{
    switch( GetType() )
    {
    case WINDOW_CHECKBOX:
        ((CheckBox*)this)->ImplSetMinimumNWFSize();
        break;
    case WINDOW_RADIOBUTTON:
        ((RadioButton*)this)->ImplSetMinimumNWFSize();
        break;
    default:
        {
            // iterate over children
            Window* pWin = GetWindow( WINDOW_FIRSTCHILD );
            while( pWin )
            {
                pWin->ImplAdjustNWFSizes();
                pWin = pWin->GetWindow( WINDOW_NEXT );
            }
        }
        break;
    }
}
<|endoftext|>