<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include "qsysteminfo.h"

QTM_USE_NAMESPACE
Q_DECLARE_METATYPE(QSystemNetworkInfo::NetworkStatus);
Q_DECLARE_METATYPE(QSystemNetworkInfo::NetworkMode);

class tst_QSystemNetworkInfo : public QObject
{
    Q_OBJECT

private slots:

    void initTestCase();
    void tst_networkStatus();

    void tst_networkSignalStrength_data();
    void tst_networkSignalStrength();
    void tst_cellId();
    void tst_locationAreaCode();

    void tst_currentMobileCountryCode(); // Mobile Country Code
    void tst_currentMobileNetworkCode(); // Mobile Network Code

    void tst_homeMobileCountryCode();
    void tst_homeMobileNetworkCode();

    void tst_networkName();

    void tst_macAddress_data();
    void tst_macAddress();

    void tst_interfaceForMode();
};
//signal todo:
//    void networkStatusChanged(QSystemNetworkInfo::NetworkMode netmode, QSystemNetworkInfo::CellNetworkStatus netStatus);

void tst_QSystemNetworkInfo::initTestCase()
{
    qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
    qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
}

void tst_QSystemNetworkInfo::tst_networkStatus()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QSystemNetworkInfo::NetworkStatus status = ni.networkStatus(mode);

        QVERIFY( status == QSystemNetworkInfo::UndefinedStatus
                 || status == QSystemNetworkInfo::NoNetworkAvailable
                 || status == QSystemNetworkInfo::EmergencyOnly
                 || status == QSystemNetworkInfo::Searching
                 || status == QSystemNetworkInfo::Busy
                 || status == QSystemNetworkInfo::Connected
                 || status == QSystemNetworkInfo::HomeNetwork
                 || status == QSystemNetworkInfo::Denied
                 || status == QSystemNetworkInfo::Roaming);
    }

}

void tst_QSystemNetworkInfo::tst_networkSignalStrength_data()
{
    QTest::addColumn<QSystemNetworkInfo::NetworkMode>("mode");

    QTest::newRow("GsmMode") << QSystemNetworkInfo::GsmMode;
    QTest::newRow("CdmaMode") << QSystemNetworkInfo::CdmaMode;
    QTest::newRow("WcdmaMode") << QSystemNetworkInfo::WcdmaMode;
    QTest::newRow("WlanMode") << QSystemNetworkInfo::WlanMode;
    QTest::newRow("EthernetMode") << QSystemNetworkInfo::EthernetMode;
    QTest::newRow("BluetoothMode") << QSystemNetworkInfo::BluetoothMode;
    QTest::newRow("WimaxMode") << QSystemNetworkInfo::WimaxMode;
}

void tst_QSystemNetworkInfo::tst_networkSignalStrength()
{
    {
        QFETCH(QSystemNetworkInfo::NetworkMode, mode);
        QSystemNetworkInfo ni;
        qint32 strength = ni.networkSignalStrength(mode);
        QVERIFY( strength > -2
                && strength < 101);
    }
}

void  tst_QSystemNetworkInfo::tst_cellId()
{
    QSystemNetworkInfo ni;
    qint32 id = ni.cellId();
    QVERIFY(id > -2);
}

void  tst_QSystemNetworkInfo::tst_locationAreaCode()
{
    QSystemNetworkInfo ni;
    qint32 lac = ni.locationAreaCode();
    QVERIFY(lac > -2);
}

void  tst_QSystemNetworkInfo::tst_currentMobileCountryCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.currentMobileCountryCode().isEmpty());
    } else {
        QVERIFY(ni.currentMobileCountryCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_currentMobileNetworkCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.currentMobileNetworkCode().isEmpty());
    } else {
        QVERIFY(ni.currentMobileNetworkCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_homeMobileCountryCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.homeMobileCountryCode().isEmpty());
    } else {
        QVERIFY(ni.homeMobileCountryCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_homeMobileNetworkCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.homeMobileNetworkCode().isEmpty());
    } else {
        QVERIFY(ni.homeMobileNetworkCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_networkName()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QVERIFY(!ni.networkName(mode).isEmpty()
                ||ni.networkName(mode).isEmpty());
    }
}

void tst_QSystemNetworkInfo::tst_macAddress_data()
{
   tst_networkSignalStrength_data();
}

void tst_QSystemNetworkInfo::tst_macAddress()
{
   QFETCH(QSystemNetworkInfo::NetworkMode, mode);
   QSystemNetworkInfo ni;
   QString mac = ni.macAddress(mode);
   if (!mac.isEmpty()) {
      QVERIFY(mac.length() == 17);
      QVERIFY(mac.contains(":"));
   }
}

void tst_QSystemNetworkInfo::tst_interfaceForMode()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QVERIFY(!ni.interfaceForMode(mode).name().isEmpty()
            || !ni.interfaceForMode(mode).isValid());
    }

}

QTEST_MAIN(tst_QSystemNetworkInfo)
#include "tst_qsystemnetworkinfo.moc"
<commit_msg>Modified tst_qsystemnetworkinfo.cpp autotest again<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include "qsysteminfo.h"

QTM_USE_NAMESPACE
Q_DECLARE_METATYPE(QSystemNetworkInfo::NetworkStatus);
Q_DECLARE_METATYPE(QSystemNetworkInfo::NetworkMode);

class tst_QSystemNetworkInfo : public QObject
{
    Q_OBJECT

private slots:

    void initTestCase();
    void tst_networkStatus();

    void tst_networkSignalStrength_data();
    void tst_networkSignalStrength();
    void tst_cellId();
    void tst_locationAreaCode();

    void tst_currentMobileCountryCode(); // Mobile Country Code
    void tst_currentMobileNetworkCode(); // Mobile Network Code

    void tst_homeMobileCountryCode();
    void tst_homeMobileNetworkCode();

    void tst_networkName();

    void tst_macAddress_data();
    void tst_macAddress();

    void tst_interfaceForMode();
};
//signal todo:
//    void networkStatusChanged(QSystemNetworkInfo::NetworkMode netmode, QSystemNetworkInfo::CellNetworkStatus netStatus);

void tst_QSystemNetworkInfo::initTestCase()
{
    qRegisterMetaType<QSystemNetworkInfo::NetworkStatus>("QSystemNetworkInfo::NetworkStatus");
    qRegisterMetaType<QSystemNetworkInfo::NetworkMode>("QSystemNetworkInfo::NetworkMode");
}

void tst_QSystemNetworkInfo::tst_networkStatus()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QSystemNetworkInfo::NetworkStatus status = ni.networkStatus(mode);

        QVERIFY( status == QSystemNetworkInfo::UndefinedStatus
                 || status == QSystemNetworkInfo::NoNetworkAvailable
                 || status == QSystemNetworkInfo::EmergencyOnly
                 || status == QSystemNetworkInfo::Searching
                 || status == QSystemNetworkInfo::Busy
                 || status == QSystemNetworkInfo::Connected
                 || status == QSystemNetworkInfo::HomeNetwork
                 || status == QSystemNetworkInfo::Denied
                 || status == QSystemNetworkInfo::Roaming);
    }

}

void tst_QSystemNetworkInfo::tst_networkSignalStrength_data()
{
    QTest::addColumn<QSystemNetworkInfo::NetworkMode>("mode");

    QTest::newRow("GsmMode") << QSystemNetworkInfo::GsmMode;
    QTest::newRow("CdmaMode") << QSystemNetworkInfo::CdmaMode;
    QTest::newRow("WcdmaMode") << QSystemNetworkInfo::WcdmaMode;
    QTest::newRow("WlanMode") << QSystemNetworkInfo::WlanMode;
    QTest::newRow("EthernetMode") << QSystemNetworkInfo::EthernetMode;
    QTest::newRow("BluetoothMode") << QSystemNetworkInfo::BluetoothMode;
    QTest::newRow("WimaxMode") << QSystemNetworkInfo::WimaxMode;
}

void tst_QSystemNetworkInfo::tst_networkSignalStrength()
{
    {
        QFETCH(QSystemNetworkInfo::NetworkMode, mode);
        QSystemNetworkInfo ni;
        qint32 strength = ni.networkSignalStrength(mode);
        QVERIFY( strength > -2
                && strength < 101);
    }
}

void  tst_QSystemNetworkInfo::tst_cellId()
{
    QSystemNetworkInfo ni;
    qint32 id = ni.cellId();
    QVERIFY(id > -2);
}

void  tst_QSystemNetworkInfo::tst_locationAreaCode()
{
    QSystemNetworkInfo ni;
    qint32 lac = ni.locationAreaCode();
    QVERIFY(lac > -2);
}

void  tst_QSystemNetworkInfo::tst_currentMobileCountryCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.currentMobileCountryCode().isEmpty());
    } else {
        QVERIFY(ni.currentMobileCountryCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_currentMobileNetworkCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.currentMobileNetworkCode().isEmpty());
    } else {
        QVERIFY(ni.currentMobileNetworkCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_homeMobileCountryCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.homeMobileCountryCode().isEmpty());
    } else {
        QVERIFY(ni.homeMobileCountryCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_homeMobileNetworkCode()
{
    QSystemNetworkInfo ni;
    if(QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::HomeNetwork == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::GsmMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::CdmaMode)
        || QSystemNetworkInfo::Roaming == ni.networkStatus(QSystemNetworkInfo::WcdmaMode)) {
        QVERIFY(!ni.homeMobileNetworkCode().isEmpty());
    } else {
        QVERIFY(ni.homeMobileNetworkCode().isEmpty());
    }
}

void  tst_QSystemNetworkInfo::tst_networkName()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QVERIFY(!ni.networkName(mode).isEmpty()
                ||ni.networkName(mode).isEmpty());
    }
}

void tst_QSystemNetworkInfo::tst_macAddress_data()
{
   tst_networkSignalStrength_data();
}

void tst_QSystemNetworkInfo::tst_macAddress()
{
   QFETCH(QSystemNetworkInfo::NetworkMode, mode);
   QSystemNetworkInfo ni;
   QString mac = ni.macAddress(mode);
   if (!mac.isEmpty()) {
      QVERIFY(mac.length() == 17);
      QVERIFY(mac.contains(":"));
   }
}

void tst_QSystemNetworkInfo::tst_interfaceForMode()
{
    QSystemNetworkInfo ni;
    QList<QSystemNetworkInfo::NetworkMode> modeList;
    modeList << QSystemNetworkInfo::GsmMode;
    modeList << QSystemNetworkInfo::CdmaMode;
    modeList << QSystemNetworkInfo::WcdmaMode;
    modeList << QSystemNetworkInfo::WlanMode;
    modeList << QSystemNetworkInfo::EthernetMode;
    modeList << QSystemNetworkInfo::BluetoothMode;
    modeList << QSystemNetworkInfo::WimaxMode;

    foreach(QSystemNetworkInfo::NetworkMode mode, modeList) {
        QVERIFY(!ni.interfaceForMode(mode).name().isEmpty()
            || !ni.interfaceForMode(mode).isValid());
    }

}

QTEST_MAIN(tst_QSystemNetworkInfo)
#include "tst_qsystemnetworkinfo.moc"
<|endoftext|>


<commit_before>//===- ExecutionEngine.cpp - MLIR Execution engine and utils --------------===//
//
// Copyright 2019 The MLIR 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.
// =============================================================================
//
// This file implements the execution engine for MLIR modules based on LLVM Orc
// JIT engine.
//
//===----------------------------------------------------------------------===//
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/IR/Function.h"
#include "mlir/IR/Module.h"
#include "mlir/Target/LLVMIR.h"

#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/TargetRegistry.h"

using namespace mlir;
using llvm::Error;
using llvm::Expected;

namespace {
// Memory manager for the JIT's objectLayer.  Its main goal is to fallback to
// resolving functions in the current process if they cannot be resolved in the
// JIT-compiled modules.
class MemoryManager : public llvm::SectionMemoryManager {
public:
  MemoryManager(llvm::orc::ExecutionSession &execSession)
      : session(execSession) {}

  // Resolve the named symbol.  First, try looking it up in the main library of
  // the execution session.  If there is no such symbol, try looking it up in
  // the current process (for example, if it is a standard library function).
  // Return `nullptr` if lookup fails.
  llvm::JITSymbol findSymbol(const std::string &name) override {
    auto mainLibSymbol = session.lookup({&session.getMainJITDylib()}, name);
    if (mainLibSymbol)
      return mainLibSymbol.get();
    auto address = llvm::RTDyldMemoryManager::getSymbolAddressInProcess(name);
    if (!address) {
      llvm::errs() << "Could not look up: " << name << '\n';
      return nullptr;
    }
    return llvm::JITSymbol(address, llvm::JITSymbolFlags::Exported);
  }

private:
  llvm::orc::ExecutionSession &session;
};
} // end anonymous namespace

namespace mlir {
namespace impl {

/// Wrapper class around DynamicLibrarySearchGenerator to allow searching
/// in-process symbols that have not been explicitly exported.
/// This first tries to resolve a symbol by using DynamicLibrarySearchGenerator.
/// For symbols that are not found this way, it then uses
///   `llvm::sys::DynamicLibrary::SearchForAddressOfSymbol` to extract symbols
/// that have been explicitly added with `llvm::sys::DynamicLibrary::AddSymbol`,
/// previously.
class SearchGenerator {
public:
  SearchGenerator(char GlobalPrefix)
      : defaultGenerator(cantFail(
            llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
                GlobalPrefix))) {}

  // This function forwards to DynamicLibrarySearchGenerator::operator() and
  // adds an extra resolution for names explicitly registered via
  // `llvm::sys::DynamicLibrary::AddSymbol`.
  Expected<llvm::orc::SymbolNameSet>
  operator()(llvm::orc::JITDylib &JD, const llvm::orc::SymbolNameSet &Names) {
    auto res = defaultGenerator(JD, Names);
    if (!res)
      return res;
    llvm::orc::SymbolMap newSymbols;
    for (auto &Name : Names) {
      if (res.get().count(Name) > 0)
        continue;
      res.get().insert(Name);
      auto addedSymbolAddress =
          llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(*Name);
      if (!addedSymbolAddress)
        continue;
      llvm::JITEvaluatedSymbol Sym(
          reinterpret_cast<uintptr_t>(addedSymbolAddress),
          llvm::JITSymbolFlags::Exported);
      newSymbols[Name] = Sym;
    }
    if (!newSymbols.empty())
      cantFail(JD.define(absoluteSymbols(std::move(newSymbols))));
    return res;
  }

private:
  llvm::orc::DynamicLibrarySearchGenerator defaultGenerator;
};

// Simple layered Orc JIT compilation engine.
class OrcJIT {
public:
  using IRTransformer = std::function<Error(llvm::Module *)>;

  // Construct a JIT engine for the target host defined by `machineBuilder`,
  // using the data layout provided as `dataLayout`.
  // Setup the object layer to use our custom memory manager in order to
  // resolve calls to library functions present in the process.
  OrcJIT(llvm::orc::JITTargetMachineBuilder machineBuilder,
         llvm::DataLayout layout, IRTransformer transform,
         ArrayRef<StringRef> sharedLibPaths)
      : irTransformer(transform),
        objectLayer(
            session,
            [this]() { return llvm::make_unique<MemoryManager>(session); }),
        compileLayer(
            session, objectLayer,
            llvm::orc::ConcurrentIRCompiler(std::move(machineBuilder))),
        transformLayer(session, compileLayer, makeIRTransformFunction()),
        dataLayout(layout), mangler(session, this->dataLayout),
        threadSafeCtx(llvm::make_unique<llvm::LLVMContext>()) {
    session.getMainJITDylib().setGenerator(
        SearchGenerator(layout.getGlobalPrefix()));
    loadLibraries(sharedLibPaths);
  }

  // Create a JIT engine for the current host.
  static Expected<std::unique_ptr<OrcJIT>>
  createDefault(IRTransformer transformer, ArrayRef<StringRef> sharedLibPaths) {
    auto machineBuilder = llvm::orc::JITTargetMachineBuilder::detectHost();
    if (!machineBuilder)
      return machineBuilder.takeError();

    auto dataLayout = machineBuilder->getDefaultDataLayoutForTarget();
    if (!dataLayout)
      return dataLayout.takeError();

    return llvm::make_unique<OrcJIT>(std::move(*machineBuilder),
                                     std::move(*dataLayout), transformer,
                                     sharedLibPaths);
  }

  // Add an LLVM module to the main library managed by the JIT engine.
  Error addModule(std::unique_ptr<llvm::Module> M) {
    return transformLayer.add(
        session.getMainJITDylib(),
        llvm::orc::ThreadSafeModule(std::move(M), threadSafeCtx));
  }

  // Lookup a symbol in the main library managed by the JIT engine.
  Expected<llvm::JITEvaluatedSymbol> lookup(StringRef Name) {
    return session.lookup({&session.getMainJITDylib()}, mangler(Name.str()));
  }

private:
  // Wrap the `irTransformer` into a function that can be called by the
  // IRTranformLayer.  If `irTransformer` is not set up, return the module as
  // is without errors.
  llvm::orc::IRTransformLayer::TransformFunction makeIRTransformFunction() {
    return [this](llvm::orc::ThreadSafeModule module,
                  const llvm::orc::MaterializationResponsibility &resp)
               -> Expected<llvm::orc::ThreadSafeModule> {
      (void)resp;
      if (!irTransformer)
        return std::move(module);
      if (Error err = irTransformer(module.getModule()))
        return std::move(err);
      return std::move(module);
    };
  }

  // Iterate over shareLibPaths and load the corresponding libraries for symbol
  // resolution.
  void loadLibraries(ArrayRef<StringRef> sharedLibPaths);

  IRTransformer irTransformer;
  llvm::orc::ExecutionSession session;
  llvm::orc::RTDyldObjectLinkingLayer objectLayer;
  llvm::orc::IRCompileLayer compileLayer;
  llvm::orc::IRTransformLayer transformLayer;
  llvm::DataLayout dataLayout;
  llvm::orc::MangleAndInterner mangler;
  llvm::orc::ThreadSafeContext threadSafeCtx;
};
} // end namespace impl
} // namespace mlir

void mlir::impl::OrcJIT::loadLibraries(ArrayRef<StringRef> sharedLibPaths) {
  for (auto libPath : sharedLibPaths) {
    auto mb = llvm::MemoryBuffer::getFile(libPath);
    if (!mb) {
      llvm::errs() << "Could not create MemoryBuffer for: " << libPath << " "
                   << mb.getError().message() << "\n";
      continue;
    }
    auto &JD = session.createJITDylib(libPath);
    auto loaded = llvm::orc::DynamicLibrarySearchGenerator::Load(
        libPath.data(), dataLayout.getGlobalPrefix());
    if (!loaded) {
      llvm::errs() << "Could not load: " << libPath << " " << loaded.takeError()
                   << "\n";
      continue;
    }
    JD.setGenerator(loaded.get());
    auto res = objectLayer.add(JD, std::move(mb.get()));
    if (res)
      llvm::errs() << "Could not add: " << libPath << " " << res << "\n";
  }
}

// Wrap a string into an llvm::StringError.
static inline Error make_string_error(const llvm::Twine &message) {
  return llvm::make_error<llvm::StringError>(message.str(),
                                             llvm::inconvertibleErrorCode());
}

// Setup LLVM target triple from the current machine.
bool ExecutionEngine::setupTargetTriple(llvm::Module *llvmModule) {
  // Setup the machine properties from the current architecture.
  auto targetTriple = llvm::sys::getDefaultTargetTriple();
  std::string errorMessage;
  auto target = llvm::TargetRegistry::lookupTarget(targetTriple, errorMessage);
  if (!target) {
    llvm::errs() << "NO target: " << errorMessage << "\n";
    return true;
  }
  auto machine =
      target->createTargetMachine(targetTriple, "generic", "", {}, {});
  llvmModule->setDataLayout(machine->createDataLayout());
  llvmModule->setTargetTriple(targetTriple);
  return false;
}

static std::string makePackedFunctionName(StringRef name) {
  return "_mlir_" + name.str();
}

// For each function in the LLVM module, define an interface function that wraps
// all the arguments of the original function and all its results into an i8**
// pointer to provide a unified invocation interface.
void packFunctionArguments(llvm::Module *module) {
  auto &ctx = module->getContext();
  llvm::IRBuilder<> builder(ctx);
  llvm::DenseSet<llvm::Function *> interfaceFunctions;
  for (auto &func : module->getFunctionList()) {
    if (func.isDeclaration()) {
      continue;
    }
    if (interfaceFunctions.count(&func)) {
      continue;
    }

    // Given a function `foo(<...>)`, define the interface function
    // `mlir_foo(i8**)`.
    auto newType = llvm::FunctionType::get(
        builder.getVoidTy(), builder.getInt8PtrTy()->getPointerTo(),
        /*isVarArg=*/false);
    auto newName = makePackedFunctionName(func.getName());
    auto funcCst = module->getOrInsertFunction(newName, newType);
    llvm::Function *interfaceFunc =
        llvm::cast<llvm::Function>(funcCst.getCallee());
    interfaceFunctions.insert(interfaceFunc);

    // Extract the arguments from the type-erased argument list and cast them to
    // the proper types.
    auto bb = llvm::BasicBlock::Create(ctx);
    bb->insertInto(interfaceFunc);
    builder.SetInsertPoint(bb);
    llvm::Value *argList = interfaceFunc->arg_begin();
    llvm::SmallVector<llvm::Value *, 8> args;
    args.reserve(llvm::size(func.args()));
    for (auto &indexedArg : llvm::enumerate(func.args())) {
      llvm::Value *argIndex = llvm::Constant::getIntegerValue(
          builder.getInt64Ty(), llvm::APInt(64, indexedArg.index()));
      llvm::Value *argPtrPtr = builder.CreateGEP(argList, argIndex);
      llvm::Value *argPtr = builder.CreateLoad(argPtrPtr);
      argPtr = builder.CreateBitCast(
          argPtr, indexedArg.value().getType()->getPointerTo());
      llvm::Value *arg = builder.CreateLoad(argPtr);
      args.push_back(arg);
    }

    // Call the implementation function with the extracted arguments.
    llvm::Value *result = builder.CreateCall(&func, args);

    // Assuming the result is one value, potentially of type `void`.
    if (!result->getType()->isVoidTy()) {
      llvm::Value *retIndex = llvm::Constant::getIntegerValue(
          builder.getInt64Ty(), llvm::APInt(64, llvm::size(func.args())));
      llvm::Value *retPtrPtr = builder.CreateGEP(argList, retIndex);
      llvm::Value *retPtr = builder.CreateLoad(retPtrPtr);
      retPtr = builder.CreateBitCast(retPtr, result->getType()->getPointerTo());
      builder.CreateStore(result, retPtr);
    }

    // The interface function returns void.
    builder.CreateRetVoid();
  }
}

// Out of line for PIMPL unique_ptr.
ExecutionEngine::~ExecutionEngine() = default;

Expected<std::unique_ptr<ExecutionEngine>>
ExecutionEngine::create(ModuleOp m,
                        std::function<llvm::Error(llvm::Module *)> transformer,
                        ArrayRef<StringRef> sharedLibPaths) {
  auto engine = llvm::make_unique<ExecutionEngine>();
  auto expectedJIT = impl::OrcJIT::createDefault(transformer, sharedLibPaths);
  if (!expectedJIT)
    return expectedJIT.takeError();

  auto llvmModule = translateModuleToLLVMIR(m);
  if (!llvmModule)
    return make_string_error("could not convert to LLVM IR");
  // FIXME: the triple should be passed to the translation or dialect conversion
  // instead of this.  Currently, the LLVM module created above has no triple
  // associated with it.
  setupTargetTriple(llvmModule.get());
  packFunctionArguments(llvmModule.get());

  if (auto err = (*expectedJIT)->addModule(std::move(llvmModule)))
    return std::move(err);
  engine->jit = std::move(*expectedJIT);

  return std::move(engine);
}

Expected<void (*)(void **)> ExecutionEngine::lookup(StringRef name) const {
  auto expectedSymbol = jit->lookup(makePackedFunctionName(name));
  if (!expectedSymbol)
    return expectedSymbol.takeError();
  auto rawFPtr = expectedSymbol->getAddress();
  auto fptr = reinterpret_cast<void (*)(void **)>(rawFPtr);
  if (!fptr)
    return make_string_error("looked up function is null");
  return fptr;
}

llvm::Error ExecutionEngine::invoke(StringRef name,
                                    MutableArrayRef<void *> args) {
  auto expectedFPtr = lookup(name);
  if (!expectedFPtr)
    return expectedFPtr.takeError();
  auto fptr = *expectedFPtr;

  (*fptr)(args.data());

  return llvm::Error::success();
}
<commit_msg>Fix ExecutionEngine post-update in upstream LLVM<commit_after>//===- ExecutionEngine.cpp - MLIR Execution engine and utils --------------===//
//
// Copyright 2019 The MLIR 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.
// =============================================================================
//
// This file implements the execution engine for MLIR modules based on LLVM Orc
// JIT engine.
//
//===----------------------------------------------------------------------===//
#include "mlir/ExecutionEngine/ExecutionEngine.h"
#include "mlir/IR/Function.h"
#include "mlir/IR/Module.h"
#include "mlir/Target/LLVMIR.h"

#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/TargetRegistry.h"

using namespace mlir;
using llvm::Error;
using llvm::Expected;

namespace {
// Memory manager for the JIT's objectLayer.  Its main goal is to fallback to
// resolving functions in the current process if they cannot be resolved in the
// JIT-compiled modules.
class MemoryManager : public llvm::SectionMemoryManager {
public:
  MemoryManager(llvm::orc::ExecutionSession &execSession)
      : session(execSession) {}

  // Resolve the named symbol.  First, try looking it up in the main library of
  // the execution session.  If there is no such symbol, try looking it up in
  // the current process (for example, if it is a standard library function).
  // Return `nullptr` if lookup fails.
  llvm::JITSymbol findSymbol(const std::string &name) override {
    auto mainLibSymbol = session.lookup({&session.getMainJITDylib()}, name);
    if (mainLibSymbol)
      return mainLibSymbol.get();
    auto address = llvm::RTDyldMemoryManager::getSymbolAddressInProcess(name);
    if (!address) {
      llvm::errs() << "Could not look up: " << name << '\n';
      return nullptr;
    }
    return llvm::JITSymbol(address, llvm::JITSymbolFlags::Exported);
  }

private:
  llvm::orc::ExecutionSession &session;
};
} // end anonymous namespace

namespace mlir {
namespace impl {

/// Wrapper class around DynamicLibrarySearchGenerator to allow searching
/// in-process symbols that have not been explicitly exported.
/// This first tries to resolve a symbol by using DynamicLibrarySearchGenerator.
/// For symbols that are not found this way, it then uses
///   `llvm::sys::DynamicLibrary::SearchForAddressOfSymbol` to extract symbols
/// that have been explicitly added with `llvm::sys::DynamicLibrary::AddSymbol`,
/// previously.
class SearchGenerator {
public:
  SearchGenerator(char GlobalPrefix)
      : defaultGenerator(cantFail(
            llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
                GlobalPrefix))) {}

  // This function forwards to DynamicLibrarySearchGenerator::operator() and
  // adds an extra resolution for names explicitly registered via
  // `llvm::sys::DynamicLibrary::AddSymbol`.
  Expected<llvm::orc::SymbolNameSet>
  operator()(llvm::orc::JITDylib &JD, const llvm::orc::SymbolNameSet &Names) {
    auto res = defaultGenerator(JD, Names);
    if (!res)
      return res;
    llvm::orc::SymbolMap newSymbols;
    for (auto &Name : Names) {
      if (res.get().count(Name) > 0)
        continue;
      res.get().insert(Name);
      auto addedSymbolAddress =
          llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(*Name);
      if (!addedSymbolAddress)
        continue;
      llvm::JITEvaluatedSymbol Sym(
          reinterpret_cast<uintptr_t>(addedSymbolAddress),
          llvm::JITSymbolFlags::Exported);
      newSymbols[Name] = Sym;
    }
    if (!newSymbols.empty())
      cantFail(JD.define(absoluteSymbols(std::move(newSymbols))));
    return res;
  }

private:
  llvm::orc::DynamicLibrarySearchGenerator defaultGenerator;
};

// Simple layered Orc JIT compilation engine.
class OrcJIT {
public:
  using IRTransformer = std::function<Error(llvm::Module *)>;

  // Construct a JIT engine for the target host defined by `machineBuilder`,
  // using the data layout provided as `dataLayout`.
  // Setup the object layer to use our custom memory manager in order to
  // resolve calls to library functions present in the process.
  OrcJIT(llvm::orc::JITTargetMachineBuilder machineBuilder,
         llvm::DataLayout layout, IRTransformer transform,
         ArrayRef<StringRef> sharedLibPaths)
      : irTransformer(transform),
        objectLayer(
            session,
            [this]() { return llvm::make_unique<MemoryManager>(session); }),
        compileLayer(
            session, objectLayer,
            llvm::orc::ConcurrentIRCompiler(std::move(machineBuilder))),
        transformLayer(session, compileLayer, makeIRTransformFunction()),
        dataLayout(layout), mangler(session, this->dataLayout),
        threadSafeCtx(llvm::make_unique<llvm::LLVMContext>()) {
    session.getMainJITDylib().setGenerator(
        SearchGenerator(layout.getGlobalPrefix()));
    loadLibraries(sharedLibPaths);
  }

  // Create a JIT engine for the current host.
  static Expected<std::unique_ptr<OrcJIT>>
  createDefault(IRTransformer transformer, ArrayRef<StringRef> sharedLibPaths) {
    auto machineBuilder = llvm::orc::JITTargetMachineBuilder::detectHost();
    if (!machineBuilder)
      return machineBuilder.takeError();

    auto dataLayout = machineBuilder->getDefaultDataLayoutForTarget();
    if (!dataLayout)
      return dataLayout.takeError();

    return llvm::make_unique<OrcJIT>(std::move(*machineBuilder),
                                     std::move(*dataLayout), transformer,
                                     sharedLibPaths);
  }

  // Add an LLVM module to the main library managed by the JIT engine.
  Error addModule(std::unique_ptr<llvm::Module> M) {
    return transformLayer.add(
        session.getMainJITDylib(),
        llvm::orc::ThreadSafeModule(std::move(M), threadSafeCtx));
  }

  // Lookup a symbol in the main library managed by the JIT engine.
  Expected<llvm::JITEvaluatedSymbol> lookup(StringRef Name) {
    return session.lookup({&session.getMainJITDylib()}, mangler(Name.str()));
  }

private:
  // Wrap the `irTransformer` into a function that can be called by the
  // IRTranformLayer.  If `irTransformer` is not set up, return the module as
  // is without errors.
  llvm::orc::IRTransformLayer::TransformFunction makeIRTransformFunction() {
    return [this](llvm::orc::ThreadSafeModule module,
                  const llvm::orc::MaterializationResponsibility &resp)
               -> Expected<llvm::orc::ThreadSafeModule> {
      (void)resp;
      if (!irTransformer)
        return std::move(module);
      Error err = module.withModuleDo(
          [this](llvm::Module &module) { return irTransformer(&module); });
      if (err)
        return std::move(err);
      return std::move(module);
    };
  }

  // Iterate over shareLibPaths and load the corresponding libraries for symbol
  // resolution.
  void loadLibraries(ArrayRef<StringRef> sharedLibPaths);

  IRTransformer irTransformer;
  llvm::orc::ExecutionSession session;
  llvm::orc::RTDyldObjectLinkingLayer objectLayer;
  llvm::orc::IRCompileLayer compileLayer;
  llvm::orc::IRTransformLayer transformLayer;
  llvm::DataLayout dataLayout;
  llvm::orc::MangleAndInterner mangler;
  llvm::orc::ThreadSafeContext threadSafeCtx;
};
} // end namespace impl
} // namespace mlir

void mlir::impl::OrcJIT::loadLibraries(ArrayRef<StringRef> sharedLibPaths) {
  for (auto libPath : sharedLibPaths) {
    auto mb = llvm::MemoryBuffer::getFile(libPath);
    if (!mb) {
      llvm::errs() << "Could not create MemoryBuffer for: " << libPath << " "
                   << mb.getError().message() << "\n";
      continue;
    }
    auto &JD = session.createJITDylib(libPath);
    auto loaded = llvm::orc::DynamicLibrarySearchGenerator::Load(
        libPath.data(), dataLayout.getGlobalPrefix());
    if (!loaded) {
      llvm::errs() << "Could not load: " << libPath << " " << loaded.takeError()
                   << "\n";
      continue;
    }
    JD.setGenerator(loaded.get());
    auto res = objectLayer.add(JD, std::move(mb.get()));
    if (res)
      llvm::errs() << "Could not add: " << libPath << " " << res << "\n";
  }
}

// Wrap a string into an llvm::StringError.
static inline Error make_string_error(const llvm::Twine &message) {
  return llvm::make_error<llvm::StringError>(message.str(),
                                             llvm::inconvertibleErrorCode());
}

// Setup LLVM target triple from the current machine.
bool ExecutionEngine::setupTargetTriple(llvm::Module *llvmModule) {
  // Setup the machine properties from the current architecture.
  auto targetTriple = llvm::sys::getDefaultTargetTriple();
  std::string errorMessage;
  auto target = llvm::TargetRegistry::lookupTarget(targetTriple, errorMessage);
  if (!target) {
    llvm::errs() << "NO target: " << errorMessage << "\n";
    return true;
  }
  auto machine =
      target->createTargetMachine(targetTriple, "generic", "", {}, {});
  llvmModule->setDataLayout(machine->createDataLayout());
  llvmModule->setTargetTriple(targetTriple);
  return false;
}

static std::string makePackedFunctionName(StringRef name) {
  return "_mlir_" + name.str();
}

// For each function in the LLVM module, define an interface function that wraps
// all the arguments of the original function and all its results into an i8**
// pointer to provide a unified invocation interface.
void packFunctionArguments(llvm::Module *module) {
  auto &ctx = module->getContext();
  llvm::IRBuilder<> builder(ctx);
  llvm::DenseSet<llvm::Function *> interfaceFunctions;
  for (auto &func : module->getFunctionList()) {
    if (func.isDeclaration()) {
      continue;
    }
    if (interfaceFunctions.count(&func)) {
      continue;
    }

    // Given a function `foo(<...>)`, define the interface function
    // `mlir_foo(i8**)`.
    auto newType = llvm::FunctionType::get(
        builder.getVoidTy(), builder.getInt8PtrTy()->getPointerTo(),
        /*isVarArg=*/false);
    auto newName = makePackedFunctionName(func.getName());
    auto funcCst = module->getOrInsertFunction(newName, newType);
    llvm::Function *interfaceFunc =
        llvm::cast<llvm::Function>(funcCst.getCallee());
    interfaceFunctions.insert(interfaceFunc);

    // Extract the arguments from the type-erased argument list and cast them to
    // the proper types.
    auto bb = llvm::BasicBlock::Create(ctx);
    bb->insertInto(interfaceFunc);
    builder.SetInsertPoint(bb);
    llvm::Value *argList = interfaceFunc->arg_begin();
    llvm::SmallVector<llvm::Value *, 8> args;
    args.reserve(llvm::size(func.args()));
    for (auto &indexedArg : llvm::enumerate(func.args())) {
      llvm::Value *argIndex = llvm::Constant::getIntegerValue(
          builder.getInt64Ty(), llvm::APInt(64, indexedArg.index()));
      llvm::Value *argPtrPtr = builder.CreateGEP(argList, argIndex);
      llvm::Value *argPtr = builder.CreateLoad(argPtrPtr);
      argPtr = builder.CreateBitCast(
          argPtr, indexedArg.value().getType()->getPointerTo());
      llvm::Value *arg = builder.CreateLoad(argPtr);
      args.push_back(arg);
    }

    // Call the implementation function with the extracted arguments.
    llvm::Value *result = builder.CreateCall(&func, args);

    // Assuming the result is one value, potentially of type `void`.
    if (!result->getType()->isVoidTy()) {
      llvm::Value *retIndex = llvm::Constant::getIntegerValue(
          builder.getInt64Ty(), llvm::APInt(64, llvm::size(func.args())));
      llvm::Value *retPtrPtr = builder.CreateGEP(argList, retIndex);
      llvm::Value *retPtr = builder.CreateLoad(retPtrPtr);
      retPtr = builder.CreateBitCast(retPtr, result->getType()->getPointerTo());
      builder.CreateStore(result, retPtr);
    }

    // The interface function returns void.
    builder.CreateRetVoid();
  }
}

// Out of line for PIMPL unique_ptr.
ExecutionEngine::~ExecutionEngine() = default;

Expected<std::unique_ptr<ExecutionEngine>>
ExecutionEngine::create(ModuleOp m,
                        std::function<llvm::Error(llvm::Module *)> transformer,
                        ArrayRef<StringRef> sharedLibPaths) {
  auto engine = llvm::make_unique<ExecutionEngine>();
  auto expectedJIT = impl::OrcJIT::createDefault(transformer, sharedLibPaths);
  if (!expectedJIT)
    return expectedJIT.takeError();

  auto llvmModule = translateModuleToLLVMIR(m);
  if (!llvmModule)
    return make_string_error("could not convert to LLVM IR");
  // FIXME: the triple should be passed to the translation or dialect conversion
  // instead of this.  Currently, the LLVM module created above has no triple
  // associated with it.
  setupTargetTriple(llvmModule.get());
  packFunctionArguments(llvmModule.get());

  if (auto err = (*expectedJIT)->addModule(std::move(llvmModule)))
    return std::move(err);
  engine->jit = std::move(*expectedJIT);

  return std::move(engine);
}

Expected<void (*)(void **)> ExecutionEngine::lookup(StringRef name) const {
  auto expectedSymbol = jit->lookup(makePackedFunctionName(name));
  if (!expectedSymbol)
    return expectedSymbol.takeError();
  auto rawFPtr = expectedSymbol->getAddress();
  auto fptr = reinterpret_cast<void (*)(void **)>(rawFPtr);
  if (!fptr)
    return make_string_error("looked up function is null");
  return fptr;
}

llvm::Error ExecutionEngine::invoke(StringRef name,
                                    MutableArrayRef<void *> args) {
  auto expectedFPtr = lookup(name);
  if (!expectedFPtr)
    return expectedFPtr.takeError();
  auto fptr = *expectedFPtr;

  (*fptr)(args.data());

  return llvm::Error::success();
}
<|endoftext|>


<commit_before>#include <UnitTest++.h>

#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGBaseInitFunctions.h>

int main(int argc, char *argv[])
{
    OSG::osgInit(argc, argv);

    return UnitTest::RunAllTests();
}
<commit_msg>Added ability to only run named suite<commit_after>#include <UnitTest++.h>
#include <TestReporterStdout.h>

#include <OpenSG/OSGConfig.h>
#include <OpenSG/OSGBaseInitFunctions.h>

int main(int argc, char *argv[])
{
    OSG::osgInit(argc, argv);

    if(argc < 2)
        return UnitTest::RunAllTests();

    UnitTest::TestReporterStdout rep;

    return UnitTest::RunAllTests(rep, UnitTest::Test::GetTestList(), argv[1]);
}
<|endoftext|>


<commit_before>#include "SDL.h"
#include "SDL_opengl.h"
#include <cmath>

const float kPi = 4.0f * std::atan(1.0f);
const Uint32 kLagThreshold = 1000;
const Uint32 kFrameTime = 10;

const float kPlayerForwardSpeed = 10.0f * (kFrameTime * 0.001f);
const float kPlayerTurnSpeed = 100.0f * (kFrameTime * 0.001f);

const float kGridSpacing = 2.0f;
const int kGridSize = 8;

bool buttonLeft = false, buttonRight = false,
    buttonUp = false, buttonDown = false;
float playerX = 0.0f, playerY = 0.0f, playerFace = 0.0f;
Uint32 tickref = 0;

void init(void)
{
    SDL_Surface *screen = NULL;
    int flags;

    if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "Could not initialize SDL: %s\n",
                SDL_GetError());
        exit(1);
    }
    flags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
    screen = SDL_SetVideoMode(640, 480, 32, flags);
    if (!screen) {
        fprintf(stderr, "Could not initialize video: %s\n",
                SDL_GetError());
        SDL_Quit();
        exit(1);
    }
}

void handleKey(SDL_keysym *key, bool state)
{
    switch (key->sym) {
    case SDLK_ESCAPE:
        if (state) {
            SDL_Quit();
            exit(0);
        }
        break;
    case SDLK_UP:
    case SDLK_w:
        buttonUp = state;
        break;
    case SDLK_DOWN:
    case SDLK_s:
        buttonDown = state;
        break;
    case SDLK_LEFT:
    case SDLK_a:
        buttonLeft = state;
        break;
    case SDLK_RIGHT:
    case SDLK_d:
        buttonRight = state;
        break;
    default:
        break;
    }
}

void handleEvents(void)
{
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_KEYDOWN:
            handleKey(&event.key.keysym, true);
            break;
        case SDL_KEYUP:
            handleKey(&event.key.keysym, false);
            break;
        case SDL_QUIT:
            SDL_Quit();
            exit(0);
            break;
        }
    }
}

void advanceFrame(void)
{
    float forward = 0.0f, turn = 0.0f, face;
    if (buttonLeft)
        turn += kPlayerTurnSpeed;
    if (buttonRight)
        turn -= kPlayerTurnSpeed;
    if (buttonUp)
        forward += kPlayerForwardSpeed;
    if (buttonDown)
        forward -= kPlayerForwardSpeed;
    playerFace += turn;
    face = playerFace * (kPi / 180.0f);
    playerX += forward * std::cos(face);
    playerY += forward * std::sin(face);
}

void updateState(void)
{
    Uint32 tick = SDL_GetTicks();
    if (tick > tickref + kLagThreshold) {
        advanceFrame();
        tickref = tick;
    } else if (tick > tickref + kFrameTime) {
        do {
            advanceFrame();
            tickref += kFrameTime;
        } while (tick > tickref + kFrameTime);
    } else if (tick < tickref)
        tickref = tick;
}

struct gradient_point {
    float pos;
    unsigned char color[3];
};

const gradient_point sky[] = {
    { -0.50f, {   0,   0,  51 } },
    { -0.02f, {   0,   0,   0 } },
    {  0.00f, { 102, 204, 255 } },
    {  0.20f, {  51,   0, 255 } },
    {  0.70f, {   0,   0,   0 } }
};

void drawSky(void)
{
    glPushAttrib(GL_CURRENT_BIT);
    glBegin(GL_TRIANGLE_STRIP);
    glColor3ubv(sky[0].color);
    glVertex3f(-2.0f, 1.0f, -1.0f);
    glVertex3f( 2.0f, 1.0f, -1.0f);
    for (int i = 0; i < sizeof(sky) / sizeof(*sky); ++i) {
        glColor3ubv(sky[i].color);
        glVertex3f(-2.0f, 1.0f, sky[i].pos);
        glVertex3f( 2.0f, 1.0f, sky[i].pos);
    }
    glVertex3f(-2.0f, 0.0f, 1.0f);
    glVertex3f( 2.0f, 0.0f, 1.0f);
    glEnd();
    glPopAttrib();
}

void drawGround(void)
{
    float px = std::floor(playerX / kGridSpacing + 0.5f) * kGridSpacing;
    float py = std::floor(playerY / kGridSpacing + 0.5f) * kGridSpacing;
    glPushAttrib(GL_CURRENT_BIT);
    glPushMatrix();
    glTranslatef(px, py, 0.0f);
    glScalef(kGridSpacing, kGridSpacing, 1.0f);
    glColor3ub(51, 0, 255);
    glBegin(GL_LINES);
    for (int i = -kGridSize; i <= kGridSize; ++i) {
        glVertex3f(i, -kGridSize, 0.0f);
        glVertex3f(i,  kGridSize, 0.0f);
        glVertex3f(-kGridSize, i, 0.0f);
        glVertex3f( kGridSize, i, 0.0f);
    }
    glEnd();
    glPopAttrib();
    glPopMatrix();
}

void drawScene(void)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-0.1f, 0.1f, -0.075f, 0.075f, 0.1f, 100.0f);
    glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    drawSky();

    glRotatef(90.0f - playerFace, 0.0f, 0.0f, 1.0f);
    glTranslatef(-playerX, -playerY, -1.0f);

    drawGround();

    SDL_GL_SwapBuffers();
}

int main(int argc, char *argv[])
{
    init();
    while (1) {
        handleEvents();
        updateState();
        drawScene();
    }
    return 0;
}
<commit_msg>Fixed warning on Linux.<commit_after>#include "SDL.h"
#include "SDL_opengl.h"
#include <cmath>

const float kPi = 4.0f * std::atan(1.0f);
const Uint32 kLagThreshold = 1000;
const Uint32 kFrameTime = 10;

const float kPlayerForwardSpeed = 10.0f * (kFrameTime * 0.001f);
const float kPlayerTurnSpeed = 100.0f * (kFrameTime * 0.001f);

const float kGridSpacing = 2.0f;
const int kGridSize = 8;

bool buttonLeft = false, buttonRight = false,
    buttonUp = false, buttonDown = false;
float playerX = 0.0f, playerY = 0.0f, playerFace = 0.0f;
Uint32 tickref = 0;

void init(void)
{
    SDL_Surface *screen = NULL;
    int flags;

    if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0) {
        fprintf(stderr, "Could not initialize SDL: %s\n",
                SDL_GetError());
        exit(1);
    }
    flags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
    screen = SDL_SetVideoMode(640, 480, 32, flags);
    if (!screen) {
        fprintf(stderr, "Could not initialize video: %s\n",
                SDL_GetError());
        SDL_Quit();
        exit(1);
    }
}

void handleKey(SDL_keysym *key, bool state)
{
    switch (key->sym) {
    case SDLK_ESCAPE:
        if (state) {
            SDL_Quit();
            exit(0);
        }
        break;
    case SDLK_UP:
    case SDLK_w:
        buttonUp = state;
        break;
    case SDLK_DOWN:
    case SDLK_s:
        buttonDown = state;
        break;
    case SDLK_LEFT:
    case SDLK_a:
        buttonLeft = state;
        break;
    case SDLK_RIGHT:
    case SDLK_d:
        buttonRight = state;
        break;
    default:
        break;
    }
}

void handleEvents(void)
{
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_KEYDOWN:
            handleKey(&event.key.keysym, true);
            break;
        case SDL_KEYUP:
            handleKey(&event.key.keysym, false);
            break;
        case SDL_QUIT:
            SDL_Quit();
            exit(0);
            break;
        }
    }
}

void advanceFrame(void)
{
    float forward = 0.0f, turn = 0.0f, face;
    if (buttonLeft)
        turn += kPlayerTurnSpeed;
    if (buttonRight)
        turn -= kPlayerTurnSpeed;
    if (buttonUp)
        forward += kPlayerForwardSpeed;
    if (buttonDown)
        forward -= kPlayerForwardSpeed;
    playerFace += turn;
    face = playerFace * (kPi / 180.0f);
    playerX += forward * std::cos(face);
    playerY += forward * std::sin(face);
}

void updateState(void)
{
    Uint32 tick = SDL_GetTicks();
    if (tick > tickref + kLagThreshold) {
        advanceFrame();
        tickref = tick;
    } else if (tick > tickref + kFrameTime) {
        do {
            advanceFrame();
            tickref += kFrameTime;
        } while (tick > tickref + kFrameTime);
    } else if (tick < tickref)
        tickref = tick;
}

struct gradient_point {
    float pos;
    unsigned char color[3];
};

const gradient_point sky[] = {
    { -0.50f, {   0,   0,  51 } },
    { -0.02f, {   0,   0,   0 } },
    {  0.00f, { 102, 204, 255 } },
    {  0.20f, {  51,   0, 255 } },
    {  0.70f, {   0,   0,   0 } }
};

void drawSky(void)
{
    glPushAttrib(GL_CURRENT_BIT);
    glBegin(GL_TRIANGLE_STRIP);
    glColor3ubv(sky[0].color);
    glVertex3f(-2.0f, 1.0f, -1.0f);
    glVertex3f( 2.0f, 1.0f, -1.0f);
    for (unsigned int i = 0; i < sizeof(sky) / sizeof(*sky); ++i) {
        glColor3ubv(sky[i].color);
        glVertex3f(-2.0f, 1.0f, sky[i].pos);
        glVertex3f( 2.0f, 1.0f, sky[i].pos);
    }
    glVertex3f(-2.0f, 0.0f, 1.0f);
    glVertex3f( 2.0f, 0.0f, 1.0f);
    glEnd();
    glPopAttrib();
}

void drawGround(void)
{
    float px = std::floor(playerX / kGridSpacing + 0.5f) * kGridSpacing;
    float py = std::floor(playerY / kGridSpacing + 0.5f) * kGridSpacing;
    glPushAttrib(GL_CURRENT_BIT);
    glPushMatrix();
    glTranslatef(px, py, 0.0f);
    glScalef(kGridSpacing, kGridSpacing, 1.0f);
    glColor3ub(51, 0, 255);
    glBegin(GL_LINES);
    for (int i = -kGridSize; i <= kGridSize; ++i) {
        glVertex3f(i, -kGridSize, 0.0f);
        glVertex3f(i,  kGridSize, 0.0f);
        glVertex3f(-kGridSize, i, 0.0f);
        glVertex3f( kGridSize, i, 0.0f);
    }
    glEnd();
    glPopAttrib();
    glPopMatrix();
}

void drawScene(void)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-0.1f, 0.1f, -0.075f, 0.075f, 0.1f, 100.0f);
    glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    drawSky();

    glRotatef(90.0f - playerFace, 0.0f, 0.0f, 1.0f);
    glTranslatef(-playerX, -playerY, -1.0f);

    drawGround();

    SDL_GL_SwapBuffers();
}

int main(int argc, char *argv[])
{
    init();
    while (1) {
        handleEvents();
        updateState();
        drawScene();
    }
    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: adtabdlg.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: oj $ $Date: 2002-07-11 12:05:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_QYDLGTAB_HXX
#include "adtabdlg.hxx"
#endif
#ifndef DBAUI_ADTABDLG_HRC
#include "adtabdlg.hrc"
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#include "dbaccess_helpid.hrc"
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif
#ifndef _SFXSIDS_HRC
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_XVIEWSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif

// slot ids
using namespace dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace dbtools;

DBG_NAME(OAddTableDlg)
//------------------------------------------------------------------------------
OAddTableDlg::OAddTableDlg( Window* pParent,OJoinTableView* _pTableView)
             :ModelessDialog( pParent, ModuleRes(DLG_JOIN_TABADD) )
             ,aFTTable( this, ResId( FT_TABLE ) )
             ,aTableList( this, ResId( LB_TABLE ),sal_False,sal_False )
             ,aAddButton( this, ResId( PB_ADDTABLE ) )
             ,aCloseButton( this, ResId( PB_CLOSE ) )
             ,aHelpButton( this, ResId( PB_HELP ) )
             ,aFixedLineTable( this, ResId( FL_TABLE ) )
             ,aDefaultString( ResId( STR_DEFAULT ) )
             ,m_pTableView(_pTableView)
             ,m_bInitialized(sal_False)
{
    DBG_CTOR(OAddTableDlg,NULL);
    OSL_ENSURE(_pTableView,"Must be a valid pointer!");
    // der Close-Button hat schon einen Standard-Help-Text, den ich aber hier nicht haben moechte, also den Text ruecksetzen
    // und eine neue ID verteilen
    aCloseButton.SetHelpText(String());
    aCloseButton.SetHelpId(HID_JOINSH_ADDTAB_CLOSE);

    aTableList.SetHelpId(HID_JOINSH_ADDTAB_TABLELIST);

    //////////////////////////////////////////////////////////////////////
    // Handler setzen
    aAddButton.SetClickHdl( LINK(this,OAddTableDlg, AddClickHdl) );
    aCloseButton.SetClickHdl( LINK(this,OAddTableDlg, CloseClickHdl) );
    aTableList.SetDoubleClickHdl( LINK(this,OAddTableDlg, TableListDoubleClickHdl) );

    aTableList.EnableInplaceEditing( FALSE );
    aTableList.SetWindowBits(WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HASLINESATROOT | WB_SORT | WB_HSCROLL );
    aTableList.EnableCheckButton( NULL ); // do not show any buttons
    aTableList.SetSelectionMode( SINGLE_SELECTION );
    aTableList.notifyHiContrastChanged();

    FreeResource();
}

//------------------------------------------------------------------------------
OAddTableDlg::~OAddTableDlg()
{
    DBG_DTOR(OAddTableDlg,NULL);
}

//------------------------------------------------------------------------------
void OAddTableDlg::Update()
{
    if(!m_bInitialized)
    {
        UpdateTableList(m_pTableView->getDesignView()->getController()->isViewAllowed());
        m_bInitialized = sal_True;
    }
}

//------------------------------------------------------------------------------
void OAddTableDlg::AddTable()
{
    //////////////////////////////////////////////////////////////////
    // Tabelle hinzufuegen
    SvLBoxEntry* pEntry = aTableList.FirstSelected();
    if( pEntry && !aTableList.GetModel()->HasChilds(pEntry))
    {
        ::rtl::OUString aCatalog,aSchema,aTableName;
        SvLBoxEntry* pSchema = aTableList.GetParent(pEntry);
        if(pSchema && pSchema != aTableList.getAllObjectsEntry())
        {
            SvLBoxEntry* pCatalog = aTableList.GetParent(pSchema);
            if(pCatalog && pCatalog != aTableList.getAllObjectsEntry())
                aCatalog = aTableList.GetEntryText(pCatalog);
            aSchema = aTableList.GetEntryText(pSchema);
        }
        aTableName = aTableList.GetEntryText(pEntry);

        // den Datenbank-Namen besorgen

        ::rtl::OUString aComposedName;
        ::dbtools::composeTableName(m_pTableView->getDesignView()->getController()->getConnection()->getMetaData(),
                                    aCatalog,aSchema,aTableName,aComposedName,sal_False);
        // aOrigTableName is used because AddTabWin would like to have this
        // und das Ganze dem Container uebergeben
        m_pTableView->AddTabWin( aComposedName,aTableName, TRUE );
    }
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, AddClickHdl, Button*, pButton )
{
    TableListDoubleClickHdl(NULL);
    return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, TableListDoubleClickHdl, ListBox *, EMPTY_ARG )
{
    if (IsAddAllowed())
        AddTable();

    if (!IsAddAllowed())
        Close();

    return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, CloseClickHdl, Button*, pButton )
{
    return Close();
}

//------------------------------------------------------------------------------
BOOL OAddTableDlg::Close()
{
    m_pTableView->getDesignView()->getController()->InvalidateFeature(ID_BROWSER_ADDTABLE);
    m_pTableView->getDesignView()->getController()->getView()->GrabFocus();
    return ModelessDialog::Close();
}

//------------------------------------------------------------------------------
BOOL OAddTableDlg::IsAddAllowed()
{
    return  m_pTableView && m_pTableView->IsAddAllowed();
}

//------------------------------------------------------------------------------
void OAddTableDlg::UpdateTableList(BOOL bViewsAllowed)
{
    //////////////////////////////////////////////////////////////////////
    // Datenbank- und Tabellennamen setzen
    Reference< XTablesSupplier > xTableSupp(m_pTableView->getDesignView()->getController()->getConnection(),UNO_QUERY);
    Reference< XViewsSupplier > xViewSupp;
    Reference< XNameAccess > xTables, xViews;

    xTables = xTableSupp->getTables();

    // get the views supplier and the views
    Sequence< ::rtl::OUString> sTables,sViews;
    if (xTables.is())
        sTables = xTables->getElementNames();

    xViewSupp = Reference< XViewsSupplier >(xTableSupp, UNO_QUERY);
    if (xViewSupp.is())
    {
        xViews = xViewSupp->getViews();
        if (xViews.is())
            sViews = xViews->getElementNames();
    }
    // if no views are allowed remove the views also out the table name filter
    if ( !bViewsAllowed )
    {
        const ::rtl::OUString* pTableBegin  = sTables.getConstArray();
        const ::rtl::OUString* pTableEnd    = pTableBegin + sTables.getLength();
        ::std::vector< ::rtl::OUString > aTables(pTableBegin,pTableEnd);

        const ::rtl::OUString* pViewBegin = sViews.getConstArray();
        const ::rtl::OUString* pViewEnd   = pViewBegin + sViews.getLength();
        ::comphelper::TStringMixEqualFunctor aEqualFunctor;
        for(;pViewBegin != pViewEnd;++pViewBegin)
            aTables.erase(::std::remove_if(aTables.begin(),aTables.end(),::std::not1(::std::bind2nd(aEqualFunctor,*pViewBegin))));
        sTables = Sequence< ::rtl::OUString>(aTables.begin(),aTables.size());
        sViews = Sequence< ::rtl::OUString>();
    }

    aTableList.UpdateTableList(Reference< XConnection>(xTableSupp,UNO_QUERY)->getMetaData(),sTables,sViews);
}
// -----------------------------------------------------------------------------

<commit_msg>#100000# included algorithm header<commit_after>/*************************************************************************
 *
 *  $RCSfile: adtabdlg.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: vg $ $Date: 2002-07-16 09:53:18 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_QYDLGTAB_HXX
#include "adtabdlg.hxx"
#endif
#ifndef DBAUI_ADTABDLG_HRC
#include "adtabdlg.hrc"
#endif
#ifndef _DBAUI_SQLMESSAGE_HXX_
#include "sqlmessage.hxx"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#include "dbaccess_helpid.hrc"
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif
#ifndef _SFXSIDS_HRC
#include <sfx2/sfxsids.hrc>
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNVIEW_HXX
#include "QueryDesignView.hxx"
#endif
#ifndef DBAUI_QUERYCONTROLLER_HXX
#include "querycontroller.hxx"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBCX_XVIEWSSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <algorithm>

// slot ids
using namespace dbaui;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace dbtools;

DBG_NAME(OAddTableDlg)
//------------------------------------------------------------------------------
OAddTableDlg::OAddTableDlg( Window* pParent,OJoinTableView* _pTableView)
             :ModelessDialog( pParent, ModuleRes(DLG_JOIN_TABADD) )
             ,aFTTable( this, ResId( FT_TABLE ) )
             ,aTableList( this, ResId( LB_TABLE ),sal_False,sal_False )
             ,aAddButton( this, ResId( PB_ADDTABLE ) )
             ,aCloseButton( this, ResId( PB_CLOSE ) )
             ,aHelpButton( this, ResId( PB_HELP ) )
             ,aFixedLineTable( this, ResId( FL_TABLE ) )
             ,aDefaultString( ResId( STR_DEFAULT ) )
             ,m_pTableView(_pTableView)
             ,m_bInitialized(sal_False)
{
    DBG_CTOR(OAddTableDlg,NULL);
    OSL_ENSURE(_pTableView,"Must be a valid pointer!");
    // der Close-Button hat schon einen Standard-Help-Text, den ich aber hier nicht haben moechte, also den Text ruecksetzen
    // und eine neue ID verteilen
    aCloseButton.SetHelpText(String());
    aCloseButton.SetHelpId(HID_JOINSH_ADDTAB_CLOSE);

    aTableList.SetHelpId(HID_JOINSH_ADDTAB_TABLELIST);

    //////////////////////////////////////////////////////////////////////
    // Handler setzen
    aAddButton.SetClickHdl( LINK(this,OAddTableDlg, AddClickHdl) );
    aCloseButton.SetClickHdl( LINK(this,OAddTableDlg, CloseClickHdl) );
    aTableList.SetDoubleClickHdl( LINK(this,OAddTableDlg, TableListDoubleClickHdl) );

    aTableList.EnableInplaceEditing( FALSE );
    aTableList.SetWindowBits(WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HASLINESATROOT | WB_SORT | WB_HSCROLL );
    aTableList.EnableCheckButton( NULL ); // do not show any buttons
    aTableList.SetSelectionMode( SINGLE_SELECTION );
    aTableList.notifyHiContrastChanged();

    FreeResource();
}

//------------------------------------------------------------------------------
OAddTableDlg::~OAddTableDlg()
{
    DBG_DTOR(OAddTableDlg,NULL);
}

//------------------------------------------------------------------------------
void OAddTableDlg::Update()
{
    if(!m_bInitialized)
    {
        UpdateTableList(m_pTableView->getDesignView()->getController()->isViewAllowed());
        m_bInitialized = sal_True;
    }
}

//------------------------------------------------------------------------------
void OAddTableDlg::AddTable()
{
    //////////////////////////////////////////////////////////////////
    // Tabelle hinzufuegen
    SvLBoxEntry* pEntry = aTableList.FirstSelected();
    if( pEntry && !aTableList.GetModel()->HasChilds(pEntry))
    {
        ::rtl::OUString aCatalog,aSchema,aTableName;
        SvLBoxEntry* pSchema = aTableList.GetParent(pEntry);
        if(pSchema && pSchema != aTableList.getAllObjectsEntry())
        {
            SvLBoxEntry* pCatalog = aTableList.GetParent(pSchema);
            if(pCatalog && pCatalog != aTableList.getAllObjectsEntry())
                aCatalog = aTableList.GetEntryText(pCatalog);
            aSchema = aTableList.GetEntryText(pSchema);
        }
        aTableName = aTableList.GetEntryText(pEntry);

        // den Datenbank-Namen besorgen

        ::rtl::OUString aComposedName;
        ::dbtools::composeTableName(m_pTableView->getDesignView()->getController()->getConnection()->getMetaData(),
                                    aCatalog,aSchema,aTableName,aComposedName,sal_False);
        // aOrigTableName is used because AddTabWin would like to have this
        // und das Ganze dem Container uebergeben
        m_pTableView->AddTabWin( aComposedName,aTableName, TRUE );
    }
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, AddClickHdl, Button*, pButton )
{
    TableListDoubleClickHdl(NULL);
    return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, TableListDoubleClickHdl, ListBox *, EMPTY_ARG )
{
    if (IsAddAllowed())
        AddTable();

    if (!IsAddAllowed())
        Close();

    return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( OAddTableDlg, CloseClickHdl, Button*, pButton )
{
    return Close();
}

//------------------------------------------------------------------------------
BOOL OAddTableDlg::Close()
{
    m_pTableView->getDesignView()->getController()->InvalidateFeature(ID_BROWSER_ADDTABLE);
    m_pTableView->getDesignView()->getController()->getView()->GrabFocus();
    return ModelessDialog::Close();
}

//------------------------------------------------------------------------------
BOOL OAddTableDlg::IsAddAllowed()
{
    return  m_pTableView && m_pTableView->IsAddAllowed();
}

//------------------------------------------------------------------------------
void OAddTableDlg::UpdateTableList(BOOL bViewsAllowed)
{
    //////////////////////////////////////////////////////////////////////
    // Datenbank- und Tabellennamen setzen
    Reference< XTablesSupplier > xTableSupp(m_pTableView->getDesignView()->getController()->getConnection(),UNO_QUERY);
    Reference< XViewsSupplier > xViewSupp;
    Reference< XNameAccess > xTables, xViews;

    xTables = xTableSupp->getTables();

    // get the views supplier and the views
    Sequence< ::rtl::OUString> sTables,sViews;
    if (xTables.is())
        sTables = xTables->getElementNames();

    xViewSupp = Reference< XViewsSupplier >(xTableSupp, UNO_QUERY);
    if (xViewSupp.is())
    {
        xViews = xViewSupp->getViews();
        if (xViews.is())
            sViews = xViews->getElementNames();
    }
    // if no views are allowed remove the views also out the table name filter
    if ( !bViewsAllowed )
    {
        const ::rtl::OUString* pTableBegin  = sTables.getConstArray();
        const ::rtl::OUString* pTableEnd    = pTableBegin + sTables.getLength();
        ::std::vector< ::rtl::OUString > aTables(pTableBegin,pTableEnd);

        const ::rtl::OUString* pViewBegin = sViews.getConstArray();
        const ::rtl::OUString* pViewEnd   = pViewBegin + sViews.getLength();
        ::comphelper::TStringMixEqualFunctor aEqualFunctor;
        for(;pViewBegin != pViewEnd;++pViewBegin)
            aTables.erase(::std::remove_if(aTables.begin(),aTables.end(),::std::not1(::std::bind2nd(aEqualFunctor,*pViewBegin))));
        sTables = Sequence< ::rtl::OUString>(aTables.begin(),aTables.size());
        sViews = Sequence< ::rtl::OUString>();
    }

    aTableList.UpdateTableList(Reference< XConnection>(xTableSupp,UNO_QUERY)->getMetaData(),sTables,sViews);
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2019 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <stdafx.h>

#include <core/support/Common.h>
#include <cursespp/Text.h>
#include <cursespp/ScrollAdapterBase.h>
#include <cursespp/SingleLineEntry.h>

#include "DirectoryAdapter.h"

using namespace musik::cube;
using namespace cursespp;
using namespace boost::filesystem;

#ifdef WIN32
static void buildDriveList(std::vector<std::string>& target) {
    target.clear();
    static char buffer[4096];
    DWORD result = ::GetLogicalDriveStringsA(4096, buffer);
    if (result) {
        char* current = buffer;
        while (*current) {
            target.push_back(std::string(current));
            current += strlen(current) + 1;
        }
    }
}
#endif

static bool hasSubdirectories(
    boost::filesystem::path p, bool showDotfiles)
{
    try {
        directory_iterator end;
        directory_iterator file(p);

        while (file != end) {
            if (is_directory(file->status())) {
                if (showDotfiles || file->path().leaf().string()[0] != '.') {
                    return true;
                }
            }
            ++file;
        }
    }
    catch (...) {
    }

    return false;
}

static void buildDirectoryList(
    const path& p,
    std::vector<std::string>& target,
    bool showDotfiles)
{
    target.clear();

    try {
        directory_iterator end;
        directory_iterator file(p);

        while (file != end) {
            if (is_directory(file->status())) {
                std::string leaf = file->path().leaf().string();
                if (showDotfiles || leaf[0] != '.') {
                    target.push_back(leaf);
                }
            }
            ++file;
        }
    }
    catch (...) {
    }

    try {
        std::sort(
            target.begin(),
            target.end(),
            std::locale(setlocale(LC_ALL, nullptr)));
    }
    catch (...) {
        std::sort(target.begin(), target.end());
    }
}

static std::string normalizePath(boost::filesystem::path path) {
    return musik::core::NormalizeDir(path.string());
}

DirectoryAdapter::DirectoryAdapter() {
    this->showDotfiles = false;
    this->dir = musik::core::GetHomeDirectory();
    buildDirectoryList(dir, subdirs, showDotfiles);
}

DirectoryAdapter::~DirectoryAdapter() {

}

void DirectoryAdapter::SetAllowEscapeRoot(bool allow) {
    this->allowEscapeRoot = allow;
}

size_t DirectoryAdapter::Select(cursespp::ListWindow* window) {
    bool hasParent = this->ShowParentPath();
    size_t selectedIndex = NO_INDEX;
    size_t initialIndex = window->GetSelectedIndex();

    if (hasParent && initialIndex == 0) {
        if (selectedIndexStack.size()) {
            selectedIndex = this->selectedIndexStack.top();
            this->selectedIndexStack.pop();
        }

        this->dir = this->dir.parent_path();
    }
    else {
        selectedIndexStack.push(initialIndex);
        this->dir /= this->subdirs[hasParent ? initialIndex - 1 : initialIndex];
    }

#ifdef WIN32
    std::string pathstr = this->dir.string();
    if ((pathstr.size() == 2 && pathstr[1] == ':') ||
        (pathstr.size() == 3 && pathstr[2] == ':'))
    {
        dir = path();
        buildDriveList(subdirs);
        return selectedIndex;
    }
#endif

    buildDirectoryList(dir, subdirs, showDotfiles);
    window->OnAdapterChanged();

    return selectedIndex;
}

void DirectoryAdapter::SetRootDirectory(const std::string& directory) {
    if (directory.size()) {
        dir = rootDir = directory;
    }
    else {
        dir = musik::core::GetHomeDirectory();
        rootDir = boost::filesystem::path();
    }

    buildDirectoryList(dir, subdirs, showDotfiles);
}

std::string DirectoryAdapter::GetFullPathAt(size_t index) {
    bool hasParent = this->ShowParentPath();
    if (hasParent && index == 0) {
        return "";
    }

    index = (hasParent ? index - 1 : index);
    return normalizePath((dir / this->subdirs[index]).string());
}

std::string DirectoryAdapter::GetLeafAt(size_t index) {
    if (this->ShowParentPath() && index == 0) {
        return "..";
    }

    return this->subdirs[index];
}

size_t DirectoryAdapter::IndexOf(const std::string& leaf) {
   for (size_t i = 0; i < this->subdirs.size(); i++) {
        if (this->subdirs[i] == leaf) {
            return i;
        }
    }

   return NO_INDEX;
}

size_t DirectoryAdapter::GetEntryCount() {
    size_t count = subdirs.size();
    return this->ShowParentPath() ? count + 1 : count;
}

void DirectoryAdapter::SetDotfilesVisible(bool visible) {
    if (showDotfiles != visible) {
        showDotfiles = visible;
        buildDirectoryList(dir, subdirs, showDotfiles);
    }
}

std::string DirectoryAdapter::GetParentPath() {
    if (dir.has_parent_path() &&
        normalizePath(this->dir) != normalizePath(this->rootDir))
    {
        return normalizePath(dir.parent_path().string());
    }

    return "";
}

std::string DirectoryAdapter::GetCurrentPath() {
    return normalizePath(dir.string());
}

void DirectoryAdapter::Refresh() {
    buildDirectoryList(dir, subdirs, showDotfiles);
}

bool DirectoryAdapter::ShowParentPath() {
    if (normalizePath(this->dir) == normalizePath(this->rootDir)
        && !this->allowEscapeRoot)
    {
        return false;
    }

    return dir.has_parent_path();
}

bool DirectoryAdapter::HasSubDirectories(size_t index) {
    bool hasParent = this->ShowParentPath();
    if (index == 0 && hasParent) {
        return true;
    }

    index = hasParent ? index - 1 : index;
    return hasSubdirectories(this->dir / this->subdirs[index], this->showDotfiles);
}

bool DirectoryAdapter::HasSubDirectories() {
    return hasSubdirectories(this->dir, this->showDotfiles);
}

IScrollAdapter::EntryPtr DirectoryAdapter::GetEntry(cursespp::ScrollableWindow* window, size_t index) {
    if (this->ShowParentPath()) {
        if (index == 0) {
            return IScrollAdapter::EntryPtr(new SingleLineEntry(".."));
        }
        --index;
    }

    auto text = text::Ellipsize(this->subdirs[index], this->GetWidth());
    return IScrollAdapter::EntryPtr(new SingleLineEntry(text));
}
<commit_msg>Fix #299: directory list disappears after toggling 'show dotfiles' in settings.<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2019 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include <stdafx.h>

#include <core/support/Common.h>
#include <cursespp/Text.h>
#include <cursespp/ScrollAdapterBase.h>
#include <cursespp/SingleLineEntry.h>

#include "DirectoryAdapter.h"

using namespace musik::cube;
using namespace cursespp;
using namespace boost::filesystem;

#ifdef WIN32
static void buildDriveList(std::vector<std::string>& target) {
    target.clear();
    static char buffer[4096];
    DWORD result = ::GetLogicalDriveStringsA(4096, buffer);
    if (result) {
        char* current = buffer;
        while (*current) {
            target.push_back(std::string(current));
            current += strlen(current) + 1;
        }
    }
}

static bool shouldBuildDriveList(const boost::filesystem::path& dir) {
    std::string pathstr = dir.string();
    return
        (pathstr.size() == 2 && pathstr[1] == ':') ||
        (pathstr.size() == 3 && pathstr[2] == ':') ||
        (pathstr.size() == 0);
}
#endif

static bool hasSubdirectories(
    boost::filesystem::path p, bool showDotfiles)
{
    try {
        directory_iterator end;
        directory_iterator file(p);

        while (file != end) {
            if (is_directory(file->status())) {
                if (showDotfiles || file->path().leaf().string()[0] != '.') {
                    return true;
                }
            }
            ++file;
        }
    }
    catch (...) {
    }

    return false;
}

static void buildDirectoryList(
    const path& p,
    std::vector<std::string>& target,
    bool showDotfiles)
{
    target.clear();

    try {
        directory_iterator end;
        directory_iterator file(p);

        while (file != end) {
            if (is_directory(file->status())) {
                std::string leaf = file->path().leaf().string();
                if (showDotfiles || leaf[0] != '.') {
                    target.push_back(leaf);
                }
            }
            ++file;
        }
    }
    catch (...) {
    }

    try {
        std::sort(
            target.begin(),
            target.end(),
            std::locale(setlocale(LC_ALL, nullptr)));
    }
    catch (...) {
        std::sort(target.begin(), target.end());
    }
}

static std::string normalizePath(boost::filesystem::path path) {
    return musik::core::NormalizeDir(path.string());
}

DirectoryAdapter::DirectoryAdapter() {
    this->showDotfiles = false;
    this->dir = musik::core::GetHomeDirectory();
    buildDirectoryList(dir, subdirs, showDotfiles);
}

DirectoryAdapter::~DirectoryAdapter() {

}

void DirectoryAdapter::SetAllowEscapeRoot(bool allow) {
    this->allowEscapeRoot = allow;
}

size_t DirectoryAdapter::Select(cursespp::ListWindow* window) {
    bool hasParent = this->ShowParentPath();
    size_t selectedIndex = NO_INDEX;
    size_t initialIndex = window->GetSelectedIndex();

    if (hasParent && initialIndex == 0) {
        if (selectedIndexStack.size()) {
            selectedIndex = this->selectedIndexStack.top();
            this->selectedIndexStack.pop();
        }

        this->dir = this->dir.parent_path();
    }
    else {
        selectedIndexStack.push(initialIndex);
        this->dir /= this->subdirs[hasParent ? initialIndex - 1 : initialIndex];
    }

#ifdef WIN32
    if (shouldBuildDriveList(this->dir)) {
        dir = path();
        buildDriveList(subdirs);
        return selectedIndex;
    }
#endif

    buildDirectoryList(dir, subdirs, showDotfiles);
    window->OnAdapterChanged();

    return selectedIndex;
}

void DirectoryAdapter::SetRootDirectory(const std::string& directory) {
    if (directory.size()) {
        dir = rootDir = directory;
    }
    else {
        dir = musik::core::GetHomeDirectory();
        rootDir = boost::filesystem::path();
    }

    buildDirectoryList(dir, subdirs, showDotfiles);
}

std::string DirectoryAdapter::GetFullPathAt(size_t index) {
    bool hasParent = this->ShowParentPath();
    if (hasParent && index == 0) {
        return "";
    }

    index = (hasParent ? index - 1 : index);
    return normalizePath((dir / this->subdirs[index]).string());
}

std::string DirectoryAdapter::GetLeafAt(size_t index) {
    if (this->ShowParentPath() && index == 0) {
        return "..";
    }

    return this->subdirs[index];
}

size_t DirectoryAdapter::IndexOf(const std::string& leaf) {
   for (size_t i = 0; i < this->subdirs.size(); i++) {
        if (this->subdirs[i] == leaf) {
            return i;
        }
    }

   return NO_INDEX;
}

size_t DirectoryAdapter::GetEntryCount() {
    size_t count = subdirs.size();
    return this->ShowParentPath() ? count + 1 : count;
}

void DirectoryAdapter::SetDotfilesVisible(bool visible) {
    if (showDotfiles != visible) {
        showDotfiles = visible;
#ifdef WIN32
        if (shouldBuildDriveList(this->dir)) {
            buildDriveList(subdirs);
            return;
        }
#endif
        buildDirectoryList(dir, subdirs, showDotfiles);
    }
}

std::string DirectoryAdapter::GetParentPath() {
    if (dir.has_parent_path() &&
        normalizePath(this->dir) != normalizePath(this->rootDir))
    {
        return normalizePath(dir.parent_path().string());
    }

    return "";
}

std::string DirectoryAdapter::GetCurrentPath() {
    return normalizePath(dir.string());
}

void DirectoryAdapter::Refresh() {
    buildDirectoryList(dir, subdirs, showDotfiles);
}

bool DirectoryAdapter::ShowParentPath() {
    if (normalizePath(this->dir) == normalizePath(this->rootDir)
        && !this->allowEscapeRoot)
    {
        return false;
    }

    return dir.has_parent_path();
}

bool DirectoryAdapter::HasSubDirectories(size_t index) {
    bool hasParent = this->ShowParentPath();
    if (index == 0 && hasParent) {
        return true;
    }

    index = hasParent ? index - 1 : index;
    return hasSubdirectories(this->dir / this->subdirs[index], this->showDotfiles);
}

bool DirectoryAdapter::HasSubDirectories() {
    return hasSubdirectories(this->dir, this->showDotfiles);
}

IScrollAdapter::EntryPtr DirectoryAdapter::GetEntry(cursespp::ScrollableWindow* window, size_t index) {
    if (this->ShowParentPath()) {
        if (index == 0) {
            return IScrollAdapter::EntryPtr(new SingleLineEntry(".."));
        }
        --index;
    }

    auto text = text::Ellipsize(this->subdirs[index], this->GetWidth());
    return IScrollAdapter::EntryPtr(new SingleLineEntry(text));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: LayerDialogChildWindow.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:07:22 $
 *
 *  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
 *
 ************************************************************************/

#ifndef SD_LAYER_DIALOG_CHILD_WINDOW_HXX
#define SD_LAYER_DIALOG_CHILD_WINDOW_HXX

#ifndef _SFX_CHILDWIN_HXX
#include <sfx2/childwin.hxx>
#endif

namespace sd {

/** Floating container for the layout dialog.
    What is missing is a way to inform the layer dialog of changing views.
*/
class LayerDialogChildWindow
    : public SfxChildWindow
{
public:
    LayerDialogChildWindow (
        ::Window*,
        USHORT,
        SfxBindings*,
        SfxChildWinInfo*);
    virtual ~LayerDialogChildWindow (void);

    SFX_DECL_CHILDWINDOW(LayerDialogChildWindow);
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.624); FILE MERGED 2008/04/01 15:35:10 thb 1.3.624.2: #i85898# Stripping all external header guards 2008/03/31 13:58:09 rt 1.3.624.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: LayerDialogChildWindow.hxx,v $
 * $Revision: 1.4 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef SD_LAYER_DIALOG_CHILD_WINDOW_HXX
#define SD_LAYER_DIALOG_CHILD_WINDOW_HXX

#include <sfx2/childwin.hxx>

namespace sd {

/** Floating container for the layout dialog.
    What is missing is a way to inform the layer dialog of changing views.
*/
class LayerDialogChildWindow
    : public SfxChildWindow
{
public:
    LayerDialogChildWindow (
        ::Window*,
        USHORT,
        SfxBindings*,
        SfxChildWinInfo*);
    virtual ~LayerDialogChildWindow (void);

    SFX_DECL_CHILDWINDOW(LayerDialogChildWindow);
};

} // end of namespace sd

#endif
<|endoftext|>