<commit_before>/***********************************************************************
created:    18/4/2015
author:     Lukas E Meindl
*************************************************************************/
/***************************************************************************
*   Copyright (C) 2004 - 2015 Paul D Turner & Thce CEGUI Development Team
*
*   Permission is hereby granted, free of charge, to any person obtaining
*   a copy of this software and associated documentation files (the
*   "Software"), to deal in the Software without restriction, including
*   without limitation the rights to use, copy, modify, merge, publish,
*   distribute, sublicense, and/or sell copies of the Software, and to
*   permit persons to whom the Software is furnished to do so, subject to
*   the following conditions:
*
*   The above copyright notice and this permission notice shall be
*   included in all copies or substantial portions of the Software.
*
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include "LookNFeelOverview.h"

#include "CEGUI/CEGUI.h"

#include <cmath>

using namespace CEGUI;

//////////////////////////////////////////////////////////////////////////
/*************************************************************************

LookNFeelOverviewSample class

*************************************************************************/

LookNFeelOverviewSample::LookNFeelOverviewSample()
{
    Sample::d_name = "LookNFeelOverviewSample";
    Sample::d_credits = "Lukas "Ident" Meindl";
    Sample::d_description =
        "This sample gives a quick overview of the available stock LookNFeels (Skins) and their skinned widgets."
        "Most widgets and most skins are shown here and can be directly interacted with.";
    Sample::d_summary =
        "The demo uses loads several layouts, each showing a set of widgets from a single skin. "
        "A combobox is used for selection. It also shows how font and widget scaling works on different resolutions";
    Sample::d_priority = 99;
}

/*************************************************************************
Sample specific initialisation goes here.
*************************************************************************/
bool LookNFeelOverviewSample::initialise(CEGUI::GUIContext* guiContext)
{
    using namespace CEGUI;

    d_usedFiles = CEGUI::String(__FILE__);

    d_guiContext = guiContext;
    WindowManager& winMgr = WindowManager::getSingleton();

    // load scheme and set up defaults
    SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
    SchemeManager::getSingleton().createFromFile("AlfiskoSkin.scheme");
    SchemeManager::getSingleton().createFromFile("WindowsLook.scheme");
    SchemeManager::getSingleton().createFromFile("VanillaSkin.scheme");
    SchemeManager::getSingleton().createFromFile("OgreTray.scheme");
    guiContext->getCursor().setDefaultImage("Vanilla-Images/MouseArrow");

    // load all Fonts we are going to use and which are not loaded via scheme
    FontManager::FontList loadedFonts = FontManager::getSingleton().createFromFile("Jura-10.font");
    Font* defaultFont = loadedFonts.empty() ? 0 : loadedFonts.front();
    FontManager::getSingleton().createFromFile("DejaVuSans-10.font");

    // load all layouts we want to use later
    d_taharezOverviewLayout = winMgr.loadLayoutFromFile("TaharezLookOverview.layout");
    d_vanillaOverviewLayout = winMgr.loadLayoutFromFile("VanillaLookOverview.layout");

    // create a root window
    Window* root = winMgr.createWindow("DefaultWindow", "root");
    guiContext->setRootWindow(root);

    CEGUI::Window* skinSelectionContainer = winMgr.createWindow("Vanilla/StaticText", "SkinSelectionContainer");
    skinSelectionContainer->setPosition(CEGUI::UVector2(cegui_reldim(0.0f), cegui_reldim(0.0f)));
    skinSelectionContainer->setSize(CEGUI::USize(cegui_reldim(1.0f), cegui_reldim(1.0f)));
    root->addChild(skinSelectionContainer);

    d_loadedLayoutContainer = winMgr.createWindow("DefaultWindow", "LoadedLayoutContainer");
    d_loadedLayoutContainer->setPosition(CEGUI::UVector2(cegui_reldim(0.0f), cegui_reldim(0.1f)));
    d_loadedLayoutContainer->setSize(CEGUI::USize(cegui_reldim(1.0f), cegui_reldim(0.9f)));
    skinSelectionContainer->addChild(d_loadedLayoutContainer);

    CEGUI::Window* skinSelectionComboboxLabel = winMgr.createWindow("Vanilla/Label", "SkinSelectionComboboxLabel");
    skinSelectionContainer->addChild(skinSelectionComboboxLabel);
    skinSelectionComboboxLabel->setHorizontalAlignment(HA_CENTRE);
    skinSelectionComboboxLabel->setText("Choose a Look N' Feel (= a skin) to display");
    skinSelectionComboboxLabel->setPosition(CEGUI::UVector2(cegui_reldim(-0.18f), cegui_reldim(0.0f)));
    skinSelectionComboboxLabel->setSize(CEGUI::USize(cegui_reldim(0.36f), cegui_reldim(0.04f)));
    skinSelectionComboboxLabel->setProperty("HorzFormatting", "RightAligned");

    CEGUI::Combobox* skinSelectionCombobox = static_cast<CEGUI::Combobox*>(winMgr.createWindow("Vanilla/Combobox", "SkinSelectionCombobox"));
    skinSelectionContainer->addChild(skinSelectionCombobox);
    skinSelectionCombobox->setHorizontalAlignment(HA_CENTRE);
    skinSelectionCombobox->setPosition(CEGUI::UVector2(cegui_reldim(0.08f), cegui_reldim(0.003f)));
    skinSelectionCombobox->setSize(CEGUI::USize(cegui_reldim(0.15f), cegui_reldim(0.3f)));
    skinSelectionCombobox->setReadOnly(true);
    skinSelectionCombobox->setSortingEnabled(false);
    skinSelectionCombobox->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted, Event::Subscriber(&LookNFeelOverviewSample::handleSkinSelectionAccepted, this));

    d_taharezLookListboxItem = new CEGUI::StandardItem("TaharezLook");
    skinSelectionCombobox->addItem(d_taharezLookListboxItem);
    //d_taharezLookListboxItem->setSelectionBrushImage("Vanilla-Images/GenericBrush");

    d_vanillaLookListboxItem = new CEGUI::StandardItem("Vanilla");
    skinSelectionCombobox->addItem(d_vanillaLookListboxItem);
    //d_vanillaLookListboxItem->setSelectionBrushImage("Vanilla-Images/GenericBrush");

    CEGUI::ListboxTextItem* blaLookListboxItem = new CEGUI::ListboxTextItem("TaharezLook");

    // success!
    return true;
}

/*************************************************************************
Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void LookNFeelOverviewSample::deinitialise()
{
}

/*************************************************************************
An event handler to handle selections
*************************************************************************/
bool LookNFeelOverviewSample::handleSkinSelectionAccepted(const CEGUI::EventArgs& args)
{
    const CEGUI::WindowEventArgs& winEventArgs = static_cast<const CEGUI::WindowEventArgs&>(args);
    CEGUI::Combobox* skinSelectionCombobox = static_cast<CEGUI::Combobox*>(winEventArgs.window);

    StandardItem* selectedItem = skinSelectionCombobox->getSelectedItem();

    while(d_loadedLayoutContainer->getChildCount() > 0)
        d_loadedLayoutContainer->removeChild(d_loadedLayoutContainer->getChildAtIdx(0));

    if(selectedItem == d_taharezLookListboxItem)
    {
        d_loadedLayoutContainer->addChild(d_taharezOverviewLayout);

        // Set default font for the gui context
        d_guiContext->setDefaultFont(d_fontForTaharez);
    }
    else if(selectedItem == d_vanillaLookListboxItem)
    {
        d_loadedLayoutContainer->addChild(d_vanillaOverviewLayout);
        d_guiContext->setDefaultFont(d_fontForTaharez);
    }

    return false;
}<commit_msg>MOD: Fixed a bug introduced when adapting the Demos for the FontMgr changes<commit_after>/***********************************************************************
created:    18/4/2015
author:     Lukas E Meindl
*************************************************************************/
/***************************************************************************
*   Copyright (C) 2004 - 2015 Paul D Turner & Thce CEGUI Development Team
*
*   Permission is hereby granted, free of charge, to any person obtaining
*   a copy of this software and associated documentation files (the
*   "Software"), to deal in the Software without restriction, including
*   without limitation the rights to use, copy, modify, merge, publish,
*   distribute, sublicense, and/or sell copies of the Software, and to
*   permit persons to whom the Software is furnished to do so, subject to
*   the following conditions:
*
*   The above copyright notice and this permission notice shall be
*   included in all copies or substantial portions of the Software.
*
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*   OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#include "LookNFeelOverview.h"

#include "CEGUI/CEGUI.h"

#include <cmath>

using namespace CEGUI;

//////////////////////////////////////////////////////////////////////////
/*************************************************************************

LookNFeelOverviewSample class

*************************************************************************/

LookNFeelOverviewSample::LookNFeelOverviewSample()
    : d_fontForTaharez(0)
{
    Sample::d_name = "LookNFeelOverviewSample";
    Sample::d_credits = "Lukas "Ident" Meindl";
    Sample::d_description =
        "This sample gives a quick overview of the available stock LookNFeels (Skins) and their skinned widgets."
        "Most widgets and most skins are shown here and can be directly interacted with.";
    Sample::d_summary =
        "The demo uses loads several layouts, each showing a set of widgets from a single skin. "
        "A combobox is used for selection. It also shows how font and widget scaling works on different resolutions";
    Sample::d_priority = 99;
}

/*************************************************************************
Sample specific initialisation goes here.
*************************************************************************/
bool LookNFeelOverviewSample::initialise(CEGUI::GUIContext* guiContext)
{
    using namespace CEGUI;

    d_usedFiles = CEGUI::String(__FILE__);

    d_guiContext = guiContext;
    WindowManager& winMgr = WindowManager::getSingleton();

    // load scheme and set up defaults
    SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
    SchemeManager::getSingleton().createFromFile("AlfiskoSkin.scheme");
    SchemeManager::getSingleton().createFromFile("WindowsLook.scheme");
    SchemeManager::getSingleton().createFromFile("VanillaSkin.scheme");
    SchemeManager::getSingleton().createFromFile("OgreTray.scheme");
    guiContext->getCursor().setDefaultImage("Vanilla-Images/MouseArrow");

    // load all Fonts we are going to use and which are not loaded via scheme
    FontManager::FontList loadedFonts = FontManager::getSingleton().createFromFile("Jura-10.font");
    d_fontForTaharez = loadedFonts.empty() ? 0 : loadedFonts.front();
    FontManager::getSingleton().createFromFile("DejaVuSans-10.font");

    // load all layouts we want to use later
    d_taharezOverviewLayout = winMgr.loadLayoutFromFile("TaharezLookOverview.layout");
    d_vanillaOverviewLayout = winMgr.loadLayoutFromFile("VanillaLookOverview.layout");

    // create a root window
    Window* root = winMgr.createWindow("DefaultWindow", "root");
    guiContext->setRootWindow(root);

    CEGUI::Window* skinSelectionContainer = winMgr.createWindow("Vanilla/StaticText", "SkinSelectionContainer");
    skinSelectionContainer->setPosition(CEGUI::UVector2(cegui_reldim(0.0f), cegui_reldim(0.0f)));
    skinSelectionContainer->setSize(CEGUI::USize(cegui_reldim(1.0f), cegui_reldim(1.0f)));
    root->addChild(skinSelectionContainer);

    d_loadedLayoutContainer = winMgr.createWindow("DefaultWindow", "LoadedLayoutContainer");
    d_loadedLayoutContainer->setPosition(CEGUI::UVector2(cegui_reldim(0.0f), cegui_reldim(0.1f)));
    d_loadedLayoutContainer->setSize(CEGUI::USize(cegui_reldim(1.0f), cegui_reldim(0.9f)));
    skinSelectionContainer->addChild(d_loadedLayoutContainer);

    CEGUI::Window* skinSelectionComboboxLabel = winMgr.createWindow("Vanilla/Label", "SkinSelectionComboboxLabel");
    skinSelectionContainer->addChild(skinSelectionComboboxLabel);
    skinSelectionComboboxLabel->setHorizontalAlignment(HA_CENTRE);
    skinSelectionComboboxLabel->setText("Choose a Look N' Feel (= a skin) to display");
    skinSelectionComboboxLabel->setPosition(CEGUI::UVector2(cegui_reldim(-0.18f), cegui_reldim(0.0f)));
    skinSelectionComboboxLabel->setSize(CEGUI::USize(cegui_reldim(0.36f), cegui_reldim(0.04f)));
    skinSelectionComboboxLabel->setProperty("HorzFormatting", "RightAligned");

    CEGUI::Combobox* skinSelectionCombobox = static_cast<CEGUI::Combobox*>(winMgr.createWindow("Vanilla/Combobox", "SkinSelectionCombobox"));
    skinSelectionContainer->addChild(skinSelectionCombobox);
    skinSelectionCombobox->setHorizontalAlignment(HA_CENTRE);
    skinSelectionCombobox->setPosition(CEGUI::UVector2(cegui_reldim(0.08f), cegui_reldim(0.003f)));
    skinSelectionCombobox->setSize(CEGUI::USize(cegui_reldim(0.15f), cegui_reldim(0.3f)));
    skinSelectionCombobox->setReadOnly(true);
    skinSelectionCombobox->setSortingEnabled(false);
    skinSelectionCombobox->subscribeEvent(CEGUI::Combobox::EventListSelectionAccepted, Event::Subscriber(&LookNFeelOverviewSample::handleSkinSelectionAccepted, this));

    d_taharezLookListboxItem = new CEGUI::StandardItem("TaharezLook");
    skinSelectionCombobox->addItem(d_taharezLookListboxItem);
    //d_taharezLookListboxItem->setSelectionBrushImage("Vanilla-Images/GenericBrush");

    d_vanillaLookListboxItem = new CEGUI::StandardItem("Vanilla");
    skinSelectionCombobox->addItem(d_vanillaLookListboxItem);
    //d_vanillaLookListboxItem->setSelectionBrushImage("Vanilla-Images/GenericBrush");

    CEGUI::ListboxTextItem* blaLookListboxItem = new CEGUI::ListboxTextItem("TaharezLook");

    // success!
    return true;
}

/*************************************************************************
Cleans up resources allocated in the initialiseSample call.
*************************************************************************/
void LookNFeelOverviewSample::deinitialise()
{
}

/*************************************************************************
An event handler to handle selections
*************************************************************************/
bool LookNFeelOverviewSample::handleSkinSelectionAccepted(const CEGUI::EventArgs& args)
{
    const CEGUI::WindowEventArgs& winEventArgs = static_cast<const CEGUI::WindowEventArgs&>(args);
    CEGUI::Combobox* skinSelectionCombobox = static_cast<CEGUI::Combobox*>(winEventArgs.window);

    StandardItem* selectedItem = skinSelectionCombobox->getSelectedItem();

    while(d_loadedLayoutContainer->getChildCount() > 0)
        d_loadedLayoutContainer->removeChild(d_loadedLayoutContainer->getChildAtIdx(0));

    if(selectedItem == d_taharezLookListboxItem)
    {
        d_loadedLayoutContainer->addChild(d_taharezOverviewLayout);

        // Set default font for the gui context
        d_guiContext->setDefaultFont(d_fontForTaharez);
    }
    else if(selectedItem == d_vanillaLookListboxItem)
    {
        d_loadedLayoutContainer->addChild(d_vanillaOverviewLayout);
        d_guiContext->setDefaultFont(d_fontForTaharez);
    }

    return false;
}<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "joynr/JoynrClusterControllerRuntime.h"
#include "joynr/Settings.h"
#include "joynr/SystemServicesSettings.h"
#include "joynr/system/ProviderReregistrationControllerProxy.h"

using namespace ::testing;
using namespace joynr;

TEST(ProviderReregistrationControllerTest, queryProviderReregistrationControllerSucceedsOnCCRuntime)
{
    auto integrationSettings = std::make_unique<Settings>("test-resources/MqttSystemIntegrationTest1.settings");
    joynr::SystemServicesSettings systemServiceSettings(*integrationSettings);
    const std::string domain(systemServiceSettings.getDomain());

    auto runtime = std::make_shared<JoynrClusterControllerRuntime>(std::move(integrationSettings));
    runtime->init();
    runtime->start();

    auto providerReregistrationControllerProxyBuilder = runtime->createProxyBuilder<joynr::system::ProviderReregistrationControllerProxy>(domain);
    auto providerReregistrationControllerProxy = providerReregistrationControllerProxyBuilder->build();

    Semaphore finishedSemaphore;
    providerReregistrationControllerProxy->triggerGlobalProviderReregistrationAsync([&finishedSemaphore]() { finishedSemaphore.notify(); }, nullptr);
    finishedSemaphore.waitFor(std::chrono::seconds(2));
}
<commit_msg>[C++] Ensure runtime destruction in sys-int-test<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "joynr/JoynrClusterControllerRuntime.h"
#include "joynr/Settings.h"
#include "joynr/SystemServicesSettings.h"
#include "joynr/system/ProviderReregistrationControllerProxy.h"

using namespace ::testing;
using namespace joynr;

TEST(ProviderReregistrationControllerTest, queryProviderReregistrationControllerSucceedsOnCCRuntime)
{
    auto integrationSettings = std::make_unique<Settings>("test-resources/MqttSystemIntegrationTest1.settings");
    joynr::SystemServicesSettings systemServiceSettings(*integrationSettings);
    const std::string domain(systemServiceSettings.getDomain());

    auto runtime = std::make_shared<JoynrClusterControllerRuntime>(std::move(integrationSettings));
    runtime->init();
    runtime->start();

    auto providerReregistrationControllerProxyBuilder = runtime->createProxyBuilder<joynr::system::ProviderReregistrationControllerProxy>(domain);
    auto providerReregistrationControllerProxy = providerReregistrationControllerProxyBuilder->build();

    Semaphore finishedSemaphore;
    providerReregistrationControllerProxy->triggerGlobalProviderReregistrationAsync([&finishedSemaphore]() { finishedSemaphore.notify(); }, nullptr);
    finishedSemaphore.waitFor(std::chrono::seconds(2));

    runtime->stop();
    runtime = nullptr;
}
<|endoftext|>


<commit_before>//  Copyright (c) 2016-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#if !defined(ROCKSDB_LITE) && !defined(OS_WIN)

#include "util/env_chroot.h"

#include <unistd.h>

#include <string>
#include <utility>
#include <vector>

#include "rocksdb/status.h"

namespace rocksdb {

class ChrootEnv : public EnvWrapper {
 public:
  ChrootEnv(Env* base_env, const std::string& chroot_dir)
      : EnvWrapper(base_env), chroot_dir_(chroot_dir) {}

  virtual Status NewSequentialFile(const std::string& fname,
                                   std::unique_ptr<SequentialFile>* result,
                                   const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewSequentialFile(status_and_enc_path.second, result,
                                         options);
  }

  virtual Status NewRandomAccessFile(const std::string& fname,
                                     unique_ptr<RandomAccessFile>* result,
                                     const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewRandomAccessFile(status_and_enc_path.second, result,
                                           options);
  }

  virtual Status NewWritableFile(const std::string& fname,
                                 unique_ptr<WritableFile>* result,
                                 const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewWritableFile(status_and_enc_path.second, result,
                                       options);
  }

  virtual Status ReuseWritableFile(const std::string& fname,
                                   const std::string& old_fname,
                                   unique_ptr<WritableFile>* result,
                                   const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    auto status_and_old_enc_path = EncodePath(old_fname);
    if (!status_and_old_enc_path.first.ok()) {
      return status_and_old_enc_path.first;
    }
    return EnvWrapper::ReuseWritableFile(status_and_old_enc_path.second,
                                         status_and_old_enc_path.second, result,
                                         options);
  }

  virtual Status NewDirectory(const std::string& dir,
                              unique_ptr<Directory>* result) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewDirectory(status_and_enc_path.second, result);
  }

  virtual Status FileExists(const std::string& fname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::FileExists(status_and_enc_path.second);
  }

  virtual Status GetChildren(const std::string& dir,
                             std::vector<std::string>* result) override {
    auto status_and_enc_path = EncodePath(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetChildren(status_and_enc_path.second, result);
  }

  virtual Status GetChildrenFileAttributes(
      const std::string& dir, std::vector<FileAttributes>* result) override {
    auto status_and_enc_path = EncodePath(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetChildrenFileAttributes(status_and_enc_path.second,
                                                 result);
  }

  virtual Status DeleteFile(const std::string& fname) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::DeleteFile(status_and_enc_path.second);
  }

  virtual Status CreateDir(const std::string& dirname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::CreateDir(status_and_enc_path.second);
  }

  virtual Status CreateDirIfMissing(const std::string& dirname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::CreateDirIfMissing(status_and_enc_path.second);
  }

  virtual Status DeleteDir(const std::string& dirname) override {
    auto status_and_enc_path = EncodePath(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::DeleteDir(status_and_enc_path.second);
  }

  virtual Status GetFileSize(const std::string& fname,
                             uint64_t* file_size) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetFileSize(status_and_enc_path.second, file_size);
  }

  virtual Status GetFileModificationTime(const std::string& fname,
                                         uint64_t* file_mtime) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetFileModificationTime(status_and_enc_path.second,
                                               file_mtime);
  }

  virtual Status RenameFile(const std::string& src,
                            const std::string& dest) override {
    auto status_and_src_enc_path = EncodePath(src);
    if (!status_and_src_enc_path.first.ok()) {
      return status_and_src_enc_path.first;
    }
    auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
    if (!status_and_dest_enc_path.first.ok()) {
      return status_and_dest_enc_path.first;
    }
    return EnvWrapper::RenameFile(status_and_src_enc_path.second,
                                  status_and_dest_enc_path.second);
  }

  virtual Status LinkFile(const std::string& src,
                          const std::string& dest) override {
    auto status_and_src_enc_path = EncodePath(src);
    if (!status_and_src_enc_path.first.ok()) {
      return status_and_src_enc_path.first;
    }
    auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
    if (!status_and_dest_enc_path.first.ok()) {
      return status_and_dest_enc_path.first;
    }
    return EnvWrapper::LinkFile(status_and_src_enc_path.second,
                                status_and_dest_enc_path.second);
  }

  virtual Status LockFile(const std::string& fname, FileLock** lock) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    // FileLock subclasses may store path (e.g., PosixFileLock stores it). We
    // can skip stripping the chroot directory from this path because callers
    // shouldn't use it.
    return EnvWrapper::LockFile(status_and_enc_path.second, lock);
  }

  virtual Status GetTestDirectory(std::string* path) override {
    // Adapted from PosixEnv's implementation since it doesn't provide a way to
    // create directory in the chroot.
    char buf[256];
    snprintf(buf, sizeof(buf), "/rocksdbtest-%d", static_cast<int>(geteuid()));
    *path = buf;

    // Directory may already exist, so ignore return
    CreateDir(*path);
    return Status::OK();
  }

  virtual Status NewLogger(const std::string& fname,
                           shared_ptr<Logger>* result) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewLogger(status_and_enc_path.second, result);
  }

  virtual Status GetAbsolutePath(const std::string& db_path,
                                 std::string* output_path) override {
    auto status_and_enc_path = EncodePath(db_path);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetAbsolutePath(status_and_enc_path.second, output_path);
  }

 private:
  // Returns status and expanded absolute path including the chroot directory.
  // Checks whether the provided path breaks out of the chroot. If it returns
  // non-OK status, the returned path should not be used.
  std::pair<Status, std::string> EncodePath(const std::string& path) {
    if (path.empty() || path[0] != '/') {
      return {Status::InvalidArgument(path, "Not an absolute path"), ""};
    }
    std::pair<Status, std::string> res;
    res.second = chroot_dir_ + path;
    char* normalized_path = realpath(res.second.c_str(), nullptr);
    if (normalized_path == nullptr) {
      res.first = Status::NotFound(res.second, strerror(errno));
    } else if (strlen(normalized_path) < chroot_dir_.size() ||
               strncmp(normalized_path, chroot_dir_.c_str(),
                       chroot_dir_.size()) != 0) {
      res.first = Status::IOError(res.second,
                                  "Attempted to access path outside chroot");
    } else {
      res.first = Status::OK();
    }
    free(normalized_path);
    return res;
  }

  // Similar to EncodePath() except assumes the basename in the path hasn't been
  // created yet.
  std::pair<Status, std::string> EncodePathWithNewBasename(
      const std::string& path) {
    if (path.empty() || path[0] != '/') {
      return {Status::InvalidArgument(path, "Not an absolute path"), ""};
    }
    // Basename may be followed by trailing slashes
    size_t final_idx = path.find_last_not_of('/');
    if (final_idx == std::string::npos) {
      // It's only slashes so no basename to extract
      return EncodePath(path);
    }

    // Pull off the basename temporarily since realname(3) (used by
    // EncodePath()) requires a path that exists
    size_t base_sep = path.rfind('/', final_idx);
    auto status_and_enc_path = EncodePath(path.substr(0, base_sep + 1));
    status_and_enc_path.second.append(path.substr(base_sep + 1));
    return status_and_enc_path;
  }

  const std::string chroot_dir_;
};

Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir) {
  if (!base_env->FileExists(chroot_dir).ok()) {
    return nullptr;
  }
  return new ChrootEnv(base_env, chroot_dir);
}

}  // namespace rocksdb

#endif  // !defined(ROCKSDB_LITE) && !defined(OS_WIN)
<commit_msg>Fix includes for clang on OS X<commit_after>//  Copyright (c) 2016-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#if !defined(ROCKSDB_LITE) && !defined(OS_WIN)

#include "util/env_chroot.h"

#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <string>
#include <utility>
#include <vector>

#include "rocksdb/status.h"

namespace rocksdb {

class ChrootEnv : public EnvWrapper {
 public:
  ChrootEnv(Env* base_env, const std::string& chroot_dir)
      : EnvWrapper(base_env), chroot_dir_(chroot_dir) {}

  virtual Status NewSequentialFile(const std::string& fname,
                                   std::unique_ptr<SequentialFile>* result,
                                   const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewSequentialFile(status_and_enc_path.second, result,
                                         options);
  }

  virtual Status NewRandomAccessFile(const std::string& fname,
                                     unique_ptr<RandomAccessFile>* result,
                                     const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewRandomAccessFile(status_and_enc_path.second, result,
                                           options);
  }

  virtual Status NewWritableFile(const std::string& fname,
                                 unique_ptr<WritableFile>* result,
                                 const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewWritableFile(status_and_enc_path.second, result,
                                       options);
  }

  virtual Status ReuseWritableFile(const std::string& fname,
                                   const std::string& old_fname,
                                   unique_ptr<WritableFile>* result,
                                   const EnvOptions& options) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    auto status_and_old_enc_path = EncodePath(old_fname);
    if (!status_and_old_enc_path.first.ok()) {
      return status_and_old_enc_path.first;
    }
    return EnvWrapper::ReuseWritableFile(status_and_old_enc_path.second,
                                         status_and_old_enc_path.second, result,
                                         options);
  }

  virtual Status NewDirectory(const std::string& dir,
                              unique_ptr<Directory>* result) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewDirectory(status_and_enc_path.second, result);
  }

  virtual Status FileExists(const std::string& fname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::FileExists(status_and_enc_path.second);
  }

  virtual Status GetChildren(const std::string& dir,
                             std::vector<std::string>* result) override {
    auto status_and_enc_path = EncodePath(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetChildren(status_and_enc_path.second, result);
  }

  virtual Status GetChildrenFileAttributes(
      const std::string& dir, std::vector<FileAttributes>* result) override {
    auto status_and_enc_path = EncodePath(dir);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetChildrenFileAttributes(status_and_enc_path.second,
                                                 result);
  }

  virtual Status DeleteFile(const std::string& fname) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::DeleteFile(status_and_enc_path.second);
  }

  virtual Status CreateDir(const std::string& dirname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::CreateDir(status_and_enc_path.second);
  }

  virtual Status CreateDirIfMissing(const std::string& dirname) override {
    auto status_and_enc_path = EncodePathWithNewBasename(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::CreateDirIfMissing(status_and_enc_path.second);
  }

  virtual Status DeleteDir(const std::string& dirname) override {
    auto status_and_enc_path = EncodePath(dirname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::DeleteDir(status_and_enc_path.second);
  }

  virtual Status GetFileSize(const std::string& fname,
                             uint64_t* file_size) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetFileSize(status_and_enc_path.second, file_size);
  }

  virtual Status GetFileModificationTime(const std::string& fname,
                                         uint64_t* file_mtime) override {
    auto status_and_enc_path = EncodePath(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetFileModificationTime(status_and_enc_path.second,
                                               file_mtime);
  }

  virtual Status RenameFile(const std::string& src,
                            const std::string& dest) override {
    auto status_and_src_enc_path = EncodePath(src);
    if (!status_and_src_enc_path.first.ok()) {
      return status_and_src_enc_path.first;
    }
    auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
    if (!status_and_dest_enc_path.first.ok()) {
      return status_and_dest_enc_path.first;
    }
    return EnvWrapper::RenameFile(status_and_src_enc_path.second,
                                  status_and_dest_enc_path.second);
  }

  virtual Status LinkFile(const std::string& src,
                          const std::string& dest) override {
    auto status_and_src_enc_path = EncodePath(src);
    if (!status_and_src_enc_path.first.ok()) {
      return status_and_src_enc_path.first;
    }
    auto status_and_dest_enc_path = EncodePathWithNewBasename(dest);
    if (!status_and_dest_enc_path.first.ok()) {
      return status_and_dest_enc_path.first;
    }
    return EnvWrapper::LinkFile(status_and_src_enc_path.second,
                                status_and_dest_enc_path.second);
  }

  virtual Status LockFile(const std::string& fname, FileLock** lock) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    // FileLock subclasses may store path (e.g., PosixFileLock stores it). We
    // can skip stripping the chroot directory from this path because callers
    // shouldn't use it.
    return EnvWrapper::LockFile(status_and_enc_path.second, lock);
  }

  virtual Status GetTestDirectory(std::string* path) override {
    // Adapted from PosixEnv's implementation since it doesn't provide a way to
    // create directory in the chroot.
    char buf[256];
    snprintf(buf, sizeof(buf), "/rocksdbtest-%d", static_cast<int>(geteuid()));
    *path = buf;

    // Directory may already exist, so ignore return
    CreateDir(*path);
    return Status::OK();
  }

  virtual Status NewLogger(const std::string& fname,
                           shared_ptr<Logger>* result) override {
    auto status_and_enc_path = EncodePathWithNewBasename(fname);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::NewLogger(status_and_enc_path.second, result);
  }

  virtual Status GetAbsolutePath(const std::string& db_path,
                                 std::string* output_path) override {
    auto status_and_enc_path = EncodePath(db_path);
    if (!status_and_enc_path.first.ok()) {
      return status_and_enc_path.first;
    }
    return EnvWrapper::GetAbsolutePath(status_and_enc_path.second, output_path);
  }

 private:
  // Returns status and expanded absolute path including the chroot directory.
  // Checks whether the provided path breaks out of the chroot. If it returns
  // non-OK status, the returned path should not be used.
  std::pair<Status, std::string> EncodePath(const std::string& path) {
    if (path.empty() || path[0] != '/') {
      return {Status::InvalidArgument(path, "Not an absolute path"), ""};
    }
    std::pair<Status, std::string> res;
    res.second = chroot_dir_ + path;
    char* normalized_path = realpath(res.second.c_str(), nullptr);
    if (normalized_path == nullptr) {
      res.first = Status::NotFound(res.second, strerror(errno));
    } else if (strlen(normalized_path) < chroot_dir_.size() ||
               strncmp(normalized_path, chroot_dir_.c_str(),
                       chroot_dir_.size()) != 0) {
      res.first = Status::IOError(res.second,
                                  "Attempted to access path outside chroot");
    } else {
      res.first = Status::OK();
    }
    free(normalized_path);
    return res;
  }

  // Similar to EncodePath() except assumes the basename in the path hasn't been
  // created yet.
  std::pair<Status, std::string> EncodePathWithNewBasename(
      const std::string& path) {
    if (path.empty() || path[0] != '/') {
      return {Status::InvalidArgument(path, "Not an absolute path"), ""};
    }
    // Basename may be followed by trailing slashes
    size_t final_idx = path.find_last_not_of('/');
    if (final_idx == std::string::npos) {
      // It's only slashes so no basename to extract
      return EncodePath(path);
    }

    // Pull off the basename temporarily since realname(3) (used by
    // EncodePath()) requires a path that exists
    size_t base_sep = path.rfind('/', final_idx);
    auto status_and_enc_path = EncodePath(path.substr(0, base_sep + 1));
    status_and_enc_path.second.append(path.substr(base_sep + 1));
    return status_and_enc_path;
  }

  const std::string chroot_dir_;
};

Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir) {
  if (!base_env->FileExists(chroot_dir).ok()) {
    return nullptr;
  }
  return new ChrootEnv(base_env, chroot_dir);
}

}  // namespace rocksdb

#endif  // !defined(ROCKSDB_LITE) && !defined(OS_WIN)
<|endoftext|>


<commit_before>/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */

#include "brw_cfg.h"

/** @file brw_cfg.cpp
 *
 * Walks the shader instructions generated and creates a set of basic
 * blocks with successor/predecessor edges connecting them.
 */

static bblock_t *
pop_stack(exec_list *list)
{
   bblock_link *link = (bblock_link *)list->get_tail();
   bblock_t *block = link->block;
   link->link.remove();

   return block;
}

static exec_node *
link(void *mem_ctx, bblock_t *block)
{
   bblock_link *l = new(mem_ctx) bblock_link(block);
   return &l->link;
}

bblock_t::bblock_t() :
   start_ip(0), end_ip(0), block_num(0)
{
   start = NULL;
   end = NULL;

   parents.make_empty();
   children.make_empty();

   if_inst = NULL;
   else_inst = NULL;
   endif_inst = NULL;
}

void
bblock_t::add_successor(void *mem_ctx, bblock_t *successor)
{
   successor->parents.push_tail(link(mem_ctx, this));
   children.push_tail(link(mem_ctx, successor));
}

void
bblock_t::dump(backend_visitor *v)
{
   int ip = this->start_ip;
   for (backend_instruction *inst = (backend_instruction *)this->start;
	inst != this->end->next;
	inst = (backend_instruction *) inst->next) {
      fprintf(stderr, "%5d: ", ip);
      v->dump_instruction(inst);
      ip++;
   }
}

cfg_t::cfg_t(exec_list *instructions)
{
   mem_ctx = ralloc_context(NULL);
   block_list.make_empty();
   blocks = NULL;
   num_blocks = 0;

   bblock_t *cur = NULL;
   int ip = 0;

   bblock_t *entry = new_block();
   bblock_t *cur_if = NULL;    /**< BB ending with IF. */
   bblock_t *cur_else = NULL;  /**< BB ending with ELSE. */
   bblock_t *cur_endif = NULL; /**< BB starting with ENDIF. */
   bblock_t *cur_do = NULL;    /**< BB ending with DO. */
   bblock_t *cur_while = NULL; /**< BB immediately following WHILE. */
   exec_list if_stack, else_stack, do_stack, while_stack;
   bblock_t *next;

   set_next_block(&cur, entry, ip);

   entry->start = (backend_instruction *) instructions->get_head();

   foreach_list(node, instructions) {
      backend_instruction *inst = (backend_instruction *)node;

      cur->end = inst;

      /* set_next_block wants the post-incremented ip */
      ip++;

      switch (inst->opcode) {
      case BRW_OPCODE_IF:
	 /* Push our information onto a stack so we can recover from
	  * nested ifs.
	  */
	 if_stack.push_tail(link(mem_ctx, cur_if));
	 else_stack.push_tail(link(mem_ctx, cur_else));

	 cur_if = cur;
	 cur_else = NULL;
         cur_endif = NULL;

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_ELSE:
         cur_else = cur;

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_ENDIF: {
         if (cur->start == inst) {
            /* New block was just created; use it. */
            cur_endif = cur;
         } else {
            cur_endif = new_block();
            cur_endif->start = inst;

            cur->end = (backend_instruction *)inst->prev;
            cur->add_successor(mem_ctx, cur_endif);

            set_next_block(&cur, cur_endif, ip - 1);
         }

         backend_instruction *else_inst = NULL;
         if (cur_else) {
            else_inst = (backend_instruction *)cur_else->end;

            cur_else->add_successor(mem_ctx, cur_endif);
         } else {
            cur_if->add_successor(mem_ctx, cur_endif);
         }

         assert(cur_if->end->opcode == BRW_OPCODE_IF);
         assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE);
         assert(inst->opcode == BRW_OPCODE_ENDIF);

         cur_if->if_inst = cur_if->end;
         cur_if->else_inst = else_inst;
         cur_if->endif_inst = inst;

	 if (cur_else) {
            cur_else->if_inst = cur_if->end;
            cur_else->else_inst = else_inst;
            cur_else->endif_inst = inst;
         }

         cur->if_inst = cur_if->end;
         cur->else_inst = else_inst;
         cur->endif_inst = inst;

	 /* Pop the stack so we're in the previous if/else/endif */
	 cur_if = pop_stack(&if_stack);
	 cur_else = pop_stack(&else_stack);
	 break;
      }
      case BRW_OPCODE_DO:
	 /* Push our information onto a stack so we can recover from
	  * nested loops.
	  */
	 do_stack.push_tail(link(mem_ctx, cur_do));
	 while_stack.push_tail(link(mem_ctx, cur_while));

	 /* Set up the block just after the while.  Don't know when exactly
	  * it will start, yet.
	  */
	 cur_while = new_block();

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur->add_successor(mem_ctx, next);
	 cur_do = next;

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_CONTINUE:
	 cur->add_successor(mem_ctx, cur_do);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_BREAK:
	 cur->add_successor(mem_ctx, cur_while);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_WHILE:
	 cur_while->start = (backend_instruction *)inst->next;

	 cur->add_successor(mem_ctx, cur_do);
	 set_next_block(&cur, cur_while, ip);

	 /* Pop the stack so we're in the previous loop */
	 cur_do = pop_stack(&do_stack);
	 cur_while = pop_stack(&while_stack);
	 break;

      default:
	 break;
      }
   }

   cur->end_ip = ip;

   make_block_array();
}

cfg_t::~cfg_t()
{
   ralloc_free(mem_ctx);
}

bblock_t *
cfg_t::new_block()
{
   bblock_t *block = new(mem_ctx) bblock_t();

   return block;
}

void
cfg_t::set_next_block(bblock_t **cur, bblock_t *block, int ip)
{
   if (*cur) {
      assert((*cur)->end->next == block->start);
      (*cur)->end_ip = ip - 1;
   }

   block->start_ip = ip;
   block->block_num = num_blocks++;
   block_list.push_tail(link(mem_ctx, block));
   *cur = block;
}

void
cfg_t::make_block_array()
{
   blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks);

   int i = 0;
   foreach_list_typed(bblock_link, link, link, &block_list) {
      blocks[i++] = link->block;
   }
   assert(i == num_blocks);
}

void
cfg_t::dump(backend_visitor *v)
{
   for (int b = 0; b < this->num_blocks; b++) {
        bblock_t *block = this->blocks[b];
      fprintf(stderr, "START B%d", b);
      foreach_list_typed(bblock_link, link, link, &block->parents) {
         fprintf(stderr, " <-B%d",
                 link->block->block_num);
      }
      fprintf(stderr, "\n");
      block->dump(v);
      fprintf(stderr, "END B%d", b);
      foreach_list_typed(bblock_link, link, link, &block->children) {
         fprintf(stderr, " ->B%d",
                 link->block->block_num);
      }
      fprintf(stderr, "\n");
   }
}
<commit_msg>i965/cfg: Make DO instruction begin a basic block.<commit_after>/*
 * Copyright © 2012 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */

#include "brw_cfg.h"

/** @file brw_cfg.cpp
 *
 * Walks the shader instructions generated and creates a set of basic
 * blocks with successor/predecessor edges connecting them.
 */

static bblock_t *
pop_stack(exec_list *list)
{
   bblock_link *link = (bblock_link *)list->get_tail();
   bblock_t *block = link->block;
   link->link.remove();

   return block;
}

static exec_node *
link(void *mem_ctx, bblock_t *block)
{
   bblock_link *l = new(mem_ctx) bblock_link(block);
   return &l->link;
}

bblock_t::bblock_t() :
   start_ip(0), end_ip(0), block_num(0)
{
   start = NULL;
   end = NULL;

   parents.make_empty();
   children.make_empty();

   if_inst = NULL;
   else_inst = NULL;
   endif_inst = NULL;
}

void
bblock_t::add_successor(void *mem_ctx, bblock_t *successor)
{
   successor->parents.push_tail(link(mem_ctx, this));
   children.push_tail(link(mem_ctx, successor));
}

void
bblock_t::dump(backend_visitor *v)
{
   int ip = this->start_ip;
   for (backend_instruction *inst = (backend_instruction *)this->start;
	inst != this->end->next;
	inst = (backend_instruction *) inst->next) {
      fprintf(stderr, "%5d: ", ip);
      v->dump_instruction(inst);
      ip++;
   }
}

cfg_t::cfg_t(exec_list *instructions)
{
   mem_ctx = ralloc_context(NULL);
   block_list.make_empty();
   blocks = NULL;
   num_blocks = 0;

   bblock_t *cur = NULL;
   int ip = 0;

   bblock_t *entry = new_block();
   bblock_t *cur_if = NULL;    /**< BB ending with IF. */
   bblock_t *cur_else = NULL;  /**< BB ending with ELSE. */
   bblock_t *cur_endif = NULL; /**< BB starting with ENDIF. */
   bblock_t *cur_do = NULL;    /**< BB starting with DO. */
   bblock_t *cur_while = NULL; /**< BB immediately following WHILE. */
   exec_list if_stack, else_stack, do_stack, while_stack;
   bblock_t *next;

   set_next_block(&cur, entry, ip);

   entry->start = (backend_instruction *) instructions->get_head();

   foreach_list(node, instructions) {
      backend_instruction *inst = (backend_instruction *)node;

      cur->end = inst;

      /* set_next_block wants the post-incremented ip */
      ip++;

      switch (inst->opcode) {
      case BRW_OPCODE_IF:
	 /* Push our information onto a stack so we can recover from
	  * nested ifs.
	  */
	 if_stack.push_tail(link(mem_ctx, cur_if));
	 else_stack.push_tail(link(mem_ctx, cur_else));

	 cur_if = cur;
	 cur_else = NULL;
         cur_endif = NULL;

	 /* Set up our immediately following block, full of "then"
	  * instructions.
	  */
	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_ELSE:
         cur_else = cur;

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 cur_if->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_ENDIF: {
         if (cur->start == inst) {
            /* New block was just created; use it. */
            cur_endif = cur;
         } else {
            cur_endif = new_block();
            cur_endif->start = inst;

            cur->end = (backend_instruction *)inst->prev;
            cur->add_successor(mem_ctx, cur_endif);

            set_next_block(&cur, cur_endif, ip - 1);
         }

         backend_instruction *else_inst = NULL;
         if (cur_else) {
            else_inst = (backend_instruction *)cur_else->end;

            cur_else->add_successor(mem_ctx, cur_endif);
         } else {
            cur_if->add_successor(mem_ctx, cur_endif);
         }

         assert(cur_if->end->opcode == BRW_OPCODE_IF);
         assert(!else_inst || else_inst->opcode == BRW_OPCODE_ELSE);
         assert(inst->opcode == BRW_OPCODE_ENDIF);

         cur_if->if_inst = cur_if->end;
         cur_if->else_inst = else_inst;
         cur_if->endif_inst = inst;

	 if (cur_else) {
            cur_else->if_inst = cur_if->end;
            cur_else->else_inst = else_inst;
            cur_else->endif_inst = inst;
         }

         cur->if_inst = cur_if->end;
         cur->else_inst = else_inst;
         cur->endif_inst = inst;

	 /* Pop the stack so we're in the previous if/else/endif */
	 cur_if = pop_stack(&if_stack);
	 cur_else = pop_stack(&else_stack);
	 break;
      }
      case BRW_OPCODE_DO:
	 /* Push our information onto a stack so we can recover from
	  * nested loops.
	  */
	 do_stack.push_tail(link(mem_ctx, cur_do));
	 while_stack.push_tail(link(mem_ctx, cur_while));

	 /* Set up the block just after the while.  Don't know when exactly
	  * it will start, yet.
	  */
	 cur_while = new_block();

         if (cur->start == inst) {
            /* New block was just created; use it. */
            cur_do = cur;
         } else {
            cur_do = new_block();
            cur_do->start = inst;

            cur->end = (backend_instruction *)inst->prev;
            cur->add_successor(mem_ctx, cur_do);

            set_next_block(&cur, cur_do, ip - 1);
         }
	 break;

      case BRW_OPCODE_CONTINUE:
	 cur->add_successor(mem_ctx, cur_do);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_BREAK:
	 cur->add_successor(mem_ctx, cur_while);

	 next = new_block();
	 next->start = (backend_instruction *)inst->next;
	 if (inst->predicate)
	    cur->add_successor(mem_ctx, next);

	 set_next_block(&cur, next, ip);
	 break;

      case BRW_OPCODE_WHILE:
	 cur_while->start = (backend_instruction *)inst->next;

	 cur->add_successor(mem_ctx, cur_do);
	 set_next_block(&cur, cur_while, ip);

	 /* Pop the stack so we're in the previous loop */
	 cur_do = pop_stack(&do_stack);
	 cur_while = pop_stack(&while_stack);
	 break;

      default:
	 break;
      }
   }

   cur->end_ip = ip;

   make_block_array();
}

cfg_t::~cfg_t()
{
   ralloc_free(mem_ctx);
}

bblock_t *
cfg_t::new_block()
{
   bblock_t *block = new(mem_ctx) bblock_t();

   return block;
}

void
cfg_t::set_next_block(bblock_t **cur, bblock_t *block, int ip)
{
   if (*cur) {
      assert((*cur)->end->next == block->start);
      (*cur)->end_ip = ip - 1;
   }

   block->start_ip = ip;
   block->block_num = num_blocks++;
   block_list.push_tail(link(mem_ctx, block));
   *cur = block;
}

void
cfg_t::make_block_array()
{
   blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks);

   int i = 0;
   foreach_list_typed(bblock_link, link, link, &block_list) {
      blocks[i++] = link->block;
   }
   assert(i == num_blocks);
}

void
cfg_t::dump(backend_visitor *v)
{
   for (int b = 0; b < this->num_blocks; b++) {
        bblock_t *block = this->blocks[b];
      fprintf(stderr, "START B%d", b);
      foreach_list_typed(bblock_link, link, link, &block->parents) {
         fprintf(stderr, " <-B%d",
                 link->block->block_num);
      }
      fprintf(stderr, "\n");
      block->dump(v);
      fprintf(stderr, "END B%d", b);
      foreach_list_typed(bblock_link, link, link, &block->children) {
         fprintf(stderr, " ->B%d",
                 link->block->block_num);
      }
      fprintf(stderr, "\n");
   }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "combined_matrix_store.h"
#include "dense_matrix.h"
#include "local_matrix_store.h"

namespace fm
{

namespace detail
{

struct mat_info
{
	size_t nrow;
	size_t ncol;
	bool in_mem;
};

static mat_info get_matrix_info(const std::vector<matrix_store::const_ptr> &mats)
{
	mat_info info;
	bool is_wide = mats.front()->is_wide();
	info.nrow = mats.front()->get_num_rows();
	info.ncol = mats.front()->get_num_cols();
	info.in_mem = mats.front()->is_in_mem();

	for (size_t i = 1; i < mats.size(); i++) {
		if (is_wide)
			info.nrow += mats[i]->get_num_rows();
		else
			info.ncol += mats[i]->get_num_cols();
		info.in_mem = info.in_mem && mats[i]->is_in_mem();
	}
	return info;
}

combined_matrix_store::ptr combined_matrix_store::create(
		const std::vector<matrix_store::const_ptr> &mats, matrix_layout_t layout)
{
	if (mats.empty()) {
		BOOST_LOG_TRIVIAL(error) << "can't combine 0 matrices";
		return combined_matrix_store::ptr();
	}
	const scalar_type &type = mats.front()->get_type();
	bool is_wide = mats.front()->is_wide();
	for (size_t i = 1; i < mats.size(); i++) {
		if (mats[i]->get_type() != type) {
			BOOST_LOG_TRIVIAL(error)
				<< "can't combine matrices of different element types";
			return combined_matrix_store::ptr();
		}
		if (mats[i]->is_wide() != is_wide) {
			BOOST_LOG_TRIVIAL(error)
				<< "can't combine matrices of different row/col length";
			return combined_matrix_store::ptr();
		}
	}
	if (is_wide) {
		size_t num_cols = mats.front()->get_num_cols();
		for (size_t i = 1; i < mats.size(); i++) {
			if (mats[i]->get_num_cols() != num_cols) {
				BOOST_LOG_TRIVIAL(error)
					<< "can't combine matrices with different row lengths";
				return combined_matrix_store::ptr();
			}
		}
		return ptr(new combined_matrix_store(mats, layout));
	}
	else {
		size_t num_rows = mats.front()->get_num_rows();
		for (size_t i = 1; i < mats.size(); i++) {
			if (mats[i]->get_num_rows() != num_rows) {
				BOOST_LOG_TRIVIAL(error)
					<< "can't combine matrices with different col lengths";
				return combined_matrix_store::ptr();
			}
		}
		return ptr(new combined_matrix_store(mats, layout));
	}
}

namespace
{

class combine_tall_op: public portion_mapply_op
{
public:
	combine_tall_op(size_t num_rows, size_t num_cols,
			const scalar_type &t): portion_mapply_op(num_rows, num_cols, t) {
	}

	virtual portion_mapply_op::const_ptr transpose() const;
	virtual void run(const std::vector<local_matrix_store::const_ptr> &ins,
			local_matrix_store &out) const;
	virtual std::string to_string(
			const std::vector<matrix_store::const_ptr> &mats) const {
		// TODO
		return "";
	}
};

class combine_wide_op: public portion_mapply_op
{
public:
	combine_wide_op(size_t num_rows, size_t num_cols,
			const scalar_type &t): portion_mapply_op(num_rows, num_cols, t) {
	}

	virtual portion_mapply_op::const_ptr transpose() const;
	virtual void run(const std::vector<local_matrix_store::const_ptr> &ins,
			local_matrix_store &out) const;
	virtual std::string to_string(
			const std::vector<matrix_store::const_ptr> &mats) const {
		// TODO
		return "";
	}
};

portion_mapply_op::const_ptr combine_tall_op::transpose() const
{
	return portion_mapply_op::const_ptr(new combine_wide_op(get_out_num_cols(),
				get_out_num_rows(), get_output_type()));
}

void combine_tall_op::run(const std::vector<local_matrix_store::const_ptr> &ins,
		local_matrix_store &out) const
{
	size_t col_idx = 0;
	local_matrix_store::exposed_area area = out.get_exposed_area();
	off_t local_start_row = out.get_local_start_row();
	off_t local_start_col = out.get_local_start_col();
	for (size_t i = 0; i < ins.size(); i++) {
		out.resize(local_start_row, local_start_col + col_idx,
				out.get_num_rows(), ins[i]->get_num_cols());
		out.copy_from(*ins[i]);
		col_idx += ins[i]->get_num_cols();
	}
	out.restore_size(area);
	assert(col_idx == out.get_num_cols());
}

portion_mapply_op::const_ptr combine_wide_op::transpose() const
{
	return portion_mapply_op::const_ptr(new combine_tall_op(get_out_num_cols(),
				get_out_num_rows(), get_output_type()));
}

void combine_wide_op::run(const std::vector<local_matrix_store::const_ptr> &ins,
		local_matrix_store &out) const
{
	size_t row_idx = 0;
	local_matrix_store::exposed_area area = out.get_exposed_area();
	off_t local_start_row = out.get_local_start_row();
	off_t local_start_col = out.get_local_start_col();
	for (size_t i = 0; i < ins.size(); i++) {
		out.resize(local_start_row + row_idx, local_start_col,
				ins[i]->get_num_rows(), out.get_num_cols());
		// TODO I need to test the performance of memory copy
		// It might be slow.
		out.copy_from(*ins[i]);
		row_idx += ins[i]->get_num_rows();
	}
	out.restore_size(area);
	assert(row_idx == out.get_num_rows());
}

}

static portion_mapply_op::const_ptr get_combine_op(
		const std::vector<matrix_store::const_ptr> &mats)
{
	mat_info info = get_matrix_info(mats);
	const scalar_type &type = mats.front()->get_type();
	if (mats.front()->is_wide())
		return portion_mapply_op::const_ptr(new combine_wide_op(info.nrow,
					info.ncol, type));
	else
		return portion_mapply_op::const_ptr(new combine_tall_op(info.nrow,
					info.ncol, type));
}

combined_matrix_store::combined_matrix_store(
		const std::vector<matrix_store::const_ptr> &mats,
		matrix_layout_t layout): mapply_matrix_store(mats,
			get_combine_op(mats), layout)
{
	this->mats = mats;
}

std::string combined_matrix_store::get_name() const
{
	std::string name = std::string("combine(") + mats[0]->get_name();
	for (size_t i = 1; mats.size(); i++)
		name += std::string(", ") + mats[i]->get_name();
	name += ")";
	return name;
}

matrix_store::const_ptr combined_matrix_store::transpose() const
{
	std::vector<matrix_store::const_ptr> tmp(mats.size());
	for (size_t i = 0; i < tmp.size(); i++)
		tmp[i] = mats[i]->transpose();
	matrix_layout_t layout;
	if (store_layout() == matrix_layout_t::L_ROW)
		layout = matrix_layout_t::L_COL;
	else
		layout = matrix_layout_t::L_ROW;
	return matrix_store::const_ptr(new combined_matrix_store(tmp, layout));
}

matrix_store::const_ptr combined_matrix_store::get_rows(
		const std::vector<off_t> &idxs) const
{
	if (!is_wide()) {
		BOOST_LOG_TRIVIAL(error) << "Cannot get rows from a tall matrix";
		return matrix_store::const_ptr();
	}

	off_t start_row = 0;
	matrix_store::const_ptr mat;
	// Find the right matrix.
	for (size_t i = 0; i < mats.size(); i++) {
		// We assume all required rows are from the same matrix.
		if (idxs[0] >= start_row
				&& (size_t) idxs[0] < start_row + mats[i]->get_num_rows()) {
			mat = mats[i];
			break;
		}
		start_row += mats[i]->get_num_rows();
	}
	if (mat == NULL) {
		BOOST_LOG_TRIVIAL(error) << "row idxs are out of bounds";
		return matrix_store::const_ptr();
	}

	assert((size_t) start_row < get_num_rows()
			&& start_row + mat->get_num_rows() <= get_num_rows());
	std::vector<off_t> local_idxs(idxs.size());
	for (size_t i = 0; i < idxs.size(); i++) {
		if (idxs[i] < start_row
				|| (size_t) idxs[i] >= start_row + mat->get_num_rows()) {
			BOOST_LOG_TRIVIAL(error)
				<< "Not all rows are in the same physical matrix.";
			return matrix_store::const_ptr();
		}
		local_idxs[i] = idxs[i] - start_row;
	}
	// If we want to access all rows of the matrix, we can return
	// the entire matrix directly.
	if (local_idxs.size() == mat->get_num_rows()
			&& std::is_sorted(local_idxs.begin(), local_idxs.end()))
		return mat;
	else
		return mat->get_rows(local_idxs);
}

}

}
<commit_msg>[Matrix]: fix a bug in get_name of combined_matrix_store.<commit_after>/*
 * Copyright 2016 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "combined_matrix_store.h"
#include "dense_matrix.h"
#include "local_matrix_store.h"

namespace fm
{

namespace detail
{

struct mat_info
{
	size_t nrow;
	size_t ncol;
	bool in_mem;
};

static mat_info get_matrix_info(const std::vector<matrix_store::const_ptr> &mats)
{
	mat_info info;
	bool is_wide = mats.front()->is_wide();
	info.nrow = mats.front()->get_num_rows();
	info.ncol = mats.front()->get_num_cols();
	info.in_mem = mats.front()->is_in_mem();

	for (size_t i = 1; i < mats.size(); i++) {
		if (is_wide)
			info.nrow += mats[i]->get_num_rows();
		else
			info.ncol += mats[i]->get_num_cols();
		info.in_mem = info.in_mem && mats[i]->is_in_mem();
	}
	return info;
}

combined_matrix_store::ptr combined_matrix_store::create(
		const std::vector<matrix_store::const_ptr> &mats, matrix_layout_t layout)
{
	if (mats.empty()) {
		BOOST_LOG_TRIVIAL(error) << "can't combine 0 matrices";
		return combined_matrix_store::ptr();
	}
	const scalar_type &type = mats.front()->get_type();
	bool is_wide = mats.front()->is_wide();
	for (size_t i = 1; i < mats.size(); i++) {
		if (mats[i]->get_type() != type) {
			BOOST_LOG_TRIVIAL(error)
				<< "can't combine matrices of different element types";
			return combined_matrix_store::ptr();
		}
		if (mats[i]->is_wide() != is_wide) {
			BOOST_LOG_TRIVIAL(error)
				<< "can't combine matrices of different row/col length";
			return combined_matrix_store::ptr();
		}
	}
	if (is_wide) {
		size_t num_cols = mats.front()->get_num_cols();
		for (size_t i = 1; i < mats.size(); i++) {
			if (mats[i]->get_num_cols() != num_cols) {
				BOOST_LOG_TRIVIAL(error)
					<< "can't combine matrices with different row lengths";
				return combined_matrix_store::ptr();
			}
		}
		return ptr(new combined_matrix_store(mats, layout));
	}
	else {
		size_t num_rows = mats.front()->get_num_rows();
		for (size_t i = 1; i < mats.size(); i++) {
			if (mats[i]->get_num_rows() != num_rows) {
				BOOST_LOG_TRIVIAL(error)
					<< "can't combine matrices with different col lengths";
				return combined_matrix_store::ptr();
			}
		}
		return ptr(new combined_matrix_store(mats, layout));
	}
}

namespace
{

class combine_tall_op: public portion_mapply_op
{
public:
	combine_tall_op(size_t num_rows, size_t num_cols,
			const scalar_type &t): portion_mapply_op(num_rows, num_cols, t) {
	}

	virtual portion_mapply_op::const_ptr transpose() const;
	virtual void run(const std::vector<local_matrix_store::const_ptr> &ins,
			local_matrix_store &out) const;
	virtual std::string to_string(
			const std::vector<matrix_store::const_ptr> &mats) const {
		// TODO
		return "";
	}
};

class combine_wide_op: public portion_mapply_op
{
public:
	combine_wide_op(size_t num_rows, size_t num_cols,
			const scalar_type &t): portion_mapply_op(num_rows, num_cols, t) {
	}

	virtual portion_mapply_op::const_ptr transpose() const;
	virtual void run(const std::vector<local_matrix_store::const_ptr> &ins,
			local_matrix_store &out) const;
	virtual std::string to_string(
			const std::vector<matrix_store::const_ptr> &mats) const {
		// TODO
		return "";
	}
};

portion_mapply_op::const_ptr combine_tall_op::transpose() const
{
	return portion_mapply_op::const_ptr(new combine_wide_op(get_out_num_cols(),
				get_out_num_rows(), get_output_type()));
}

void combine_tall_op::run(const std::vector<local_matrix_store::const_ptr> &ins,
		local_matrix_store &out) const
{
	size_t col_idx = 0;
	local_matrix_store::exposed_area area = out.get_exposed_area();
	off_t local_start_row = out.get_local_start_row();
	off_t local_start_col = out.get_local_start_col();
	for (size_t i = 0; i < ins.size(); i++) {
		out.resize(local_start_row, local_start_col + col_idx,
				out.get_num_rows(), ins[i]->get_num_cols());
		out.copy_from(*ins[i]);
		col_idx += ins[i]->get_num_cols();
	}
	out.restore_size(area);
	assert(col_idx == out.get_num_cols());
}

portion_mapply_op::const_ptr combine_wide_op::transpose() const
{
	return portion_mapply_op::const_ptr(new combine_tall_op(get_out_num_cols(),
				get_out_num_rows(), get_output_type()));
}

void combine_wide_op::run(const std::vector<local_matrix_store::const_ptr> &ins,
		local_matrix_store &out) const
{
	size_t row_idx = 0;
	local_matrix_store::exposed_area area = out.get_exposed_area();
	off_t local_start_row = out.get_local_start_row();
	off_t local_start_col = out.get_local_start_col();
	for (size_t i = 0; i < ins.size(); i++) {
		out.resize(local_start_row + row_idx, local_start_col,
				ins[i]->get_num_rows(), out.get_num_cols());
		// TODO I need to test the performance of memory copy
		// It might be slow.
		out.copy_from(*ins[i]);
		row_idx += ins[i]->get_num_rows();
	}
	out.restore_size(area);
	assert(row_idx == out.get_num_rows());
}

}

static portion_mapply_op::const_ptr get_combine_op(
		const std::vector<matrix_store::const_ptr> &mats)
{
	mat_info info = get_matrix_info(mats);
	const scalar_type &type = mats.front()->get_type();
	if (mats.front()->is_wide())
		return portion_mapply_op::const_ptr(new combine_wide_op(info.nrow,
					info.ncol, type));
	else
		return portion_mapply_op::const_ptr(new combine_tall_op(info.nrow,
					info.ncol, type));
}

combined_matrix_store::combined_matrix_store(
		const std::vector<matrix_store::const_ptr> &mats,
		matrix_layout_t layout): mapply_matrix_store(mats,
			get_combine_op(mats), layout)
{
	this->mats = mats;
}

std::string combined_matrix_store::get_name() const
{
	std::string name = std::string("combine(") + mats[0]->get_name();
	for (size_t i = 1; i < mats.size(); i++)
		name += std::string(", ") + mats[i]->get_name();
	name += ")";
	return name;
}

matrix_store::const_ptr combined_matrix_store::transpose() const
{
	std::vector<matrix_store::const_ptr> tmp(mats.size());
	for (size_t i = 0; i < tmp.size(); i++)
		tmp[i] = mats[i]->transpose();
	matrix_layout_t layout;
	if (store_layout() == matrix_layout_t::L_ROW)
		layout = matrix_layout_t::L_COL;
	else
		layout = matrix_layout_t::L_ROW;
	return matrix_store::const_ptr(new combined_matrix_store(tmp, layout));
}

matrix_store::const_ptr combined_matrix_store::get_rows(
		const std::vector<off_t> &idxs) const
{
	if (!is_wide()) {
		BOOST_LOG_TRIVIAL(error) << "Cannot get rows from a tall matrix";
		return matrix_store::const_ptr();
	}

	off_t start_row = 0;
	matrix_store::const_ptr mat;
	// Find the right matrix.
	for (size_t i = 0; i < mats.size(); i++) {
		// We assume all required rows are from the same matrix.
		if (idxs[0] >= start_row
				&& (size_t) idxs[0] < start_row + mats[i]->get_num_rows()) {
			mat = mats[i];
			break;
		}
		start_row += mats[i]->get_num_rows();
	}
	if (mat == NULL) {
		BOOST_LOG_TRIVIAL(error) << "row idxs are out of bounds";
		return matrix_store::const_ptr();
	}

	assert((size_t) start_row < get_num_rows()
			&& start_row + mat->get_num_rows() <= get_num_rows());
	std::vector<off_t> local_idxs(idxs.size());
	for (size_t i = 0; i < idxs.size(); i++) {
		if (idxs[i] < start_row
				|| (size_t) idxs[i] >= start_row + mat->get_num_rows()) {
			BOOST_LOG_TRIVIAL(error)
				<< "Not all rows are in the same physical matrix.";
			return matrix_store::const_ptr();
		}
		local_idxs[i] = idxs[i] - start_row;
	}
	// If we want to access all rows of the matrix, we can return
	// the entire matrix directly.
	if (local_idxs.size() == mat->get_num_rows()
			&& std::is_sorted(local_idxs.begin(), local_idxs.end()))
		return mat;
	else
		return mat->get_rows(local_idxs);
}

}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PresentationViewShellBase.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 19:06:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "PresentationViewShellBase.hxx"

#ifndef SD_RESID_HXX
#include "sdresid.hxx"
#endif
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#include "strings.hrc"
#include "ViewTabBar.hxx"
#include "UpdateLockManager.hxx"

#include <sfx2/viewfrm.hxx>
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <com/sun/star/frame/XLayoutManager.hpp>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace sd {

class DrawDocShell;

TYPEINIT1(PresentationViewShellBase, ViewShellBase);

// We have to expand the SFX_IMPL_VIEWFACTORY macro to call LateInit() after a
// new PresentationViewShellBase object has been constructed.

/*
SFX_IMPL_VIEWFACTORY(PresentationViewShellBase, SdResId(STR_DEFAULTVIEW))
{
    SFX_VIEW_REGISTRATION(DrawDocShell);
}
*/
SfxViewFactory* PresentationViewShellBase::pFactory;
SfxViewShell* __EXPORT PresentationViewShellBase::CreateInstance (
    SfxViewFrame *_pFrame, SfxViewShell *pOldView)
{
    PresentationViewShellBase* pBase =
        new PresentationViewShellBase(_pFrame, pOldView);
    pBase->LateInit();
    return pBase;
}
void PresentationViewShellBase::RegisterFactory( USHORT nPrio )
{
    pFactory = new SfxViewFactory(
        &CreateInstance,&InitFactory,nPrio,SdResId(STR_DEFAULTVIEW));
    InitFactory();
}
void PresentationViewShellBase::InitFactory()
{
    SFX_VIEW_REGISTRATION(DrawDocShell);
}

PresentationViewShellBase::PresentationViewShellBase (
    SfxViewFrame* _pFrame,
    SfxViewShell* pOldShell)
    : ViewShellBase (_pFrame, pOldShell, ViewShell::ST_PRESENTATION)
{
    GetUpdateLockManager().Disable();

    // Hide the automatic (non-context sensitive) tool bars.
    if (_pFrame!=NULL && _pFrame->GetFrame()!=NULL)
    {
        Reference<beans::XPropertySet> xFrameSet (
            _pFrame->GetFrame()->GetFrameInterface(),
            UNO_QUERY);
        if (xFrameSet.is())
        {
            Reference<beans::XPropertySet> xLayouterSet (
                xFrameSet->getPropertyValue(::rtl::OUString::createFromAscii("LayoutManager")),
                UNO_QUERY);
            if (xLayouterSet.is())
            {
                xLayouterSet->setPropertyValue(
                    ::rtl::OUString::createFromAscii("AutomaticToolbars"),
                    makeAny(sal_False));
            }
        }
    }
}

ViewTabBar* PresentationViewShellBase::CreateViewTabBar (void)
{
    // The ViewTabBar is not supported.
    return NULL;
}

PresentationViewShellBase::~PresentationViewShellBase (void)
{
}

} // end of namespace sd

<commit_msg>INTEGRATION: CWS components1 (1.6.96); FILE MERGED 2007/01/31 13:52:53 af 1.6.96.6: #i68075# UpdateLockManager stored as shared_ptr. 2007/01/25 15:34:34 af 1.6.96.5: RESYNC: (1.8-1.9); FILE MERGED 2006/09/25 17:41:08 af 1.6.96.4: RESYNC: (1.6-1.8); FILE MERGED 2006/09/07 14:51:55 af 1.6.96.3: #i68075# Transition from URL to ResourceId. 2006/08/28 14:32:33 af 1.6.96.2: #i68075# Fixed compiler problems. 2006/08/22 12:43:11 af 1.6.96.1: #i68075# Transition to new drawing framework.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PresentationViewShellBase.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-03 16:27:25 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "PresentationViewShellBase.hxx"

#ifndef SD_RESID_HXX
#include "sdresid.hxx"
#endif
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#include "strings.hrc"
#include "UpdateLockManager.hxx"
#include "framework/FrameworkHelper.hxx"
#include "framework/PresentationModule.hxx"

#include <sfx2/viewfrm.hxx>
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <com/sun/star/frame/XLayoutManager.hpp>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace sd {

class DrawDocShell;

TYPEINIT1(PresentationViewShellBase, ViewShellBase);

// We have to expand the SFX_IMPL_VIEWFACTORY macro to call LateInit() after a
// new PresentationViewShellBase object has been constructed.

/*
SFX_IMPL_VIEWFACTORY(PresentationViewShellBase, SdResId(STR_DEFAULTVIEW))
{
    SFX_VIEW_REGISTRATION(DrawDocShell);
}
*/
SfxViewFactory* PresentationViewShellBase::pFactory;
SfxViewShell* __EXPORT PresentationViewShellBase::CreateInstance (
    SfxViewFrame *_pFrame, SfxViewShell *pOldView)
{
    PresentationViewShellBase* pBase =
        new PresentationViewShellBase(_pFrame, pOldView);
    pBase->LateInit(framework::FrameworkHelper::msPresentationViewURL);
    return pBase;
}
void PresentationViewShellBase::RegisterFactory( USHORT nPrio )
{
    pFactory = new SfxViewFactory(
        &CreateInstance,&InitFactory,nPrio,SdResId(STR_DEFAULTVIEW));
    InitFactory();
}
void PresentationViewShellBase::InitFactory()
{
    SFX_VIEW_REGISTRATION(DrawDocShell);
}

PresentationViewShellBase::PresentationViewShellBase (
    SfxViewFrame* _pFrame,
    SfxViewShell* pOldShell)
    : ViewShellBase (_pFrame, pOldShell)
{
    GetUpdateLockManager()->Disable();

    // Hide the automatic (non-context sensitive) tool bars.
    if (_pFrame!=NULL && _pFrame->GetFrame()!=NULL)
    {
        Reference<beans::XPropertySet> xFrameSet (
            _pFrame->GetFrame()->GetFrameInterface(),
            UNO_QUERY);
        if (xFrameSet.is())
        {
            Reference<beans::XPropertySet> xLayouterSet (
                xFrameSet->getPropertyValue(::rtl::OUString::createFromAscii("LayoutManager")),
                UNO_QUERY);
            if (xLayouterSet.is())
            {
                xLayouterSet->setPropertyValue(
                    ::rtl::OUString::createFromAscii("AutomaticToolbars"),
                    makeAny(sal_False));
            }
        }
    }
}

PresentationViewShellBase::~PresentationViewShellBase (void)
{
}

void PresentationViewShellBase::InitializeFramework (void)
{
    com::sun::star::uno::Reference<com::sun::star::frame::XController>
        xController (GetController());
    sd::framework::PresentationModule::Initialize(xController);
}

} // end of namespace sd

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: types.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-02-03 12:52:17 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "bridges/cpp_uno/shared/types.hxx"
#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX

#include "typelib/typeclass.h"
#include "typelib/typedescription.h"

namespace {

bool isSimpleTypeClass(typelib_TypeClass typeClass) {
    return typeClass <= typelib_TypeClass_DOUBLE
        || typeClass == typelib_TypeClass_ENUM;
}

}

namespace bridges { namespace cpp_uno { namespace shared {

bool isSimpleType(typelib_TypeDescriptionReference const * type) {
    return isSimpleTypeClass(type->eTypeClass);
}

bool isSimpleType(typelib_TypeDescription const * type) {
    return isSimpleTypeClass(type->eTypeClass);
}

bool relatesToInterfaceType(typelib_TypeDescription const * type) {
    switch (type->eTypeClass) {
    case typelib_TypeClass_ANY:
    case typelib_TypeClass_INTERFACE:
        return true;

    case typelib_TypeClass_STRUCT:
    case typelib_TypeClass_EXCEPTION:
        {
            typelib_CompoundTypeDescription const * p
                = reinterpret_cast< typelib_CompoundTypeDescription const * >(
                    type);
            for (sal_Int32 i = 0; i < p->nMembers; ++i) {
                switch (p->ppTypeRefs[i]->eTypeClass) {
                case typelib_TypeClass_ANY:
                case typelib_TypeClass_INTERFACE:
                    return true;

                case typelib_TypeClass_STRUCT:
                case typelib_TypeClass_EXCEPTION:
                case typelib_TypeClass_SEQUENCE:
                    {
                        typelib_TypeDescription * t = 0;
                        TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
                        bool b = relatesToInterfaceType(t);
                        TYPELIB_DANGER_RELEASE(t);
                        if (b) {
                            return true;
                        }
                    }
                    break;
                }
            }
            if (p->pBaseTypeDescription != 0) {
                return relatesToInterfaceType(&p->pBaseTypeDescription->aBase);
            }
        }
        break;

    case typelib_TypeClass_SEQUENCE:
        switch (reinterpret_cast< typelib_IndirectTypeDescription const * >(
                    type)->pType->eTypeClass) {
        case typelib_TypeClass_ANY:
        case typelib_TypeClass_INTERFACE:
            return true;

        case typelib_TypeClass_STRUCT:
        case typelib_TypeClass_EXCEPTION:
        case typelib_TypeClass_SEQUENCE:
            {
                typelib_TypeDescription * t = 0;
                TYPELIB_DANGER_GET(
                    &t,
                    reinterpret_cast< typelib_IndirectTypeDescription const * >(
                        type)->pType);
                bool b = relatesToInterfaceType(t);
                TYPELIB_DANGER_RELEASE(t);
                return b;
            }
        }
        break;
    }
    return false;
}

} } }
<commit_msg>INTEGRATION: CWS sb29 (1.2.68); FILE MERGED 2005/01/31 13:32:04 sb 1.2.68.1: #i41344# Adapted Solaris Intel cpp_uno bridge to multiple-inheritance UNO interface types.<commit_after>/*************************************************************************
 *
 *  $RCSfile: types.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-21 12:15:30 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "bridges/cpp_uno/shared/types.hxx"
#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX

#include "typelib/typeclass.h"
#include "typelib/typedescription.h"

namespace bridges { namespace cpp_uno { namespace shared {

bool isSimpleType(typelib_TypeClass typeClass) {
    return typeClass <= typelib_TypeClass_DOUBLE
        || typeClass == typelib_TypeClass_ENUM;
}

bool isSimpleType(typelib_TypeDescriptionReference const * type) {
    return isSimpleType(type->eTypeClass);
}

bool isSimpleType(typelib_TypeDescription const * type) {
    return isSimpleType(type->eTypeClass);
}

bool relatesToInterfaceType(typelib_TypeDescription const * type) {
    switch (type->eTypeClass) {
    case typelib_TypeClass_ANY:
    case typelib_TypeClass_INTERFACE:
        return true;

    case typelib_TypeClass_STRUCT:
    case typelib_TypeClass_EXCEPTION:
        {
            typelib_CompoundTypeDescription const * p
                = reinterpret_cast< typelib_CompoundTypeDescription const * >(
                    type);
            for (sal_Int32 i = 0; i < p->nMembers; ++i) {
                switch (p->ppTypeRefs[i]->eTypeClass) {
                case typelib_TypeClass_ANY:
                case typelib_TypeClass_INTERFACE:
                    return true;

                case typelib_TypeClass_STRUCT:
                case typelib_TypeClass_EXCEPTION:
                case typelib_TypeClass_SEQUENCE:
                    {
                        typelib_TypeDescription * t = 0;
                        TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
                        bool b = relatesToInterfaceType(t);
                        TYPELIB_DANGER_RELEASE(t);
                        if (b) {
                            return true;
                        }
                    }
                    break;
                }
            }
            if (p->pBaseTypeDescription != 0) {
                return relatesToInterfaceType(&p->pBaseTypeDescription->aBase);
            }
        }
        break;

    case typelib_TypeClass_SEQUENCE:
        switch (reinterpret_cast< typelib_IndirectTypeDescription const * >(
                    type)->pType->eTypeClass) {
        case typelib_TypeClass_ANY:
        case typelib_TypeClass_INTERFACE:
            return true;

        case typelib_TypeClass_STRUCT:
        case typelib_TypeClass_EXCEPTION:
        case typelib_TypeClass_SEQUENCE:
            {
                typelib_TypeDescription * t = 0;
                TYPELIB_DANGER_GET(
                    &t,
                    reinterpret_cast< typelib_IndirectTypeDescription const * >(
                        type)->pType);
                bool b = relatesToInterfaceType(t);
                TYPELIB_DANGER_RELEASE(t);
                return b;
            }
        }
        break;
    }
    return false;
}

} } }
<|endoftext|>