<commit_before>#include <maya/MAnimControl.h>
#include <maya/MCallbackIdArray.h>
#include <maya/MEventMessage.h>
#include <maya/MGlobal.h>

#include <maya/MFnPlugin.h>

#include "EngineCommand.h"
#include "AssetCommand.h"
#include "AssetNode.h"
#include "CurveMeshInputNode.h"
#include "FluidGridConvert.h"
#include "util.h"

#include <HAPI/HAPI_Version.h>

#include <cstdlib>

void
printHAPIVersion()
{
    int i, j, k;
    char version[32];
    MString msg;

    {
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_MAJOR, &i);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_MINOR, &j);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_BUILD, &k);

        msg = "Houdini version: ";
        sprintf(version, "%d.%d.%d", i, j, k);
        msg += version;
        if(!(i == HAPI_VERSION_HOUDINI_MAJOR
                    && j == HAPI_VERSION_HOUDINI_MINOR
                    && k == HAPI_VERSION_HOUDINI_BUILD))
        {
            msg += ", expected: ";
            sprintf(version, "%d.%d.%d",
                    HAPI_VERSION_HOUDINI_MAJOR,
                    HAPI_VERSION_HOUDINI_MINOR,
                    HAPI_VERSION_HOUDINI_BUILD);
            msg += version;
        }

        MGlobal::displayInfo(msg);
    }

    {
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_MAJOR, &i);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_MINOR, &j);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_API, &k);

        msg = "Houdini Engine version: ";
        sprintf(version, "%d.%d (API: %d)", i, j, k);
        msg += version;

        if(!(i == HAPI_VERSION_HOUDINI_ENGINE_MAJOR
                    && j == HAPI_VERSION_HOUDINI_ENGINE_MINOR
                    && k == HAPI_VERSION_HOUDINI_ENGINE_API))
        {
            msg += ", expected: ";
            sprintf(version, "%d.%d (API: %d)",
                    HAPI_VERSION_HOUDINI_ENGINE_MAJOR,
                    HAPI_VERSION_HOUDINI_ENGINE_MINOR,
                    HAPI_VERSION_HOUDINI_ENGINE_API);
            msg += version;
        }

        MGlobal::displayInfo(msg);
    }
}

namespace
{
    template <typename VAL, class CHILD>
    class OptionVarBase
    {
    public:
        OptionVarBase(const char* name, const VAL& defaultValue)
            : myDefaultValue(defaultValue)
        {
            myName = "houdiniEngine";
            myName += name;

            bool exists = false;
            static_cast<const CHILD&>(*this).getImpl(exists);

            if (!exists)
            {
                MGlobal::setOptionVarValue(myName.c_str(), myDefaultValue);
            }
        }

        VAL get() const
        {
            bool exists = false;
            const VAL value = static_cast<const CHILD&>(*this).getImpl(exists);
            return exists ? value : myDefaultValue;
        }

    protected:
        std::string myName;
        const VAL myDefaultValue;

    private:
        OptionVarBase& operator=(const OptionVarBase&);
    };

    class IntOptionVar: public OptionVarBase<int, IntOptionVar>
    {
    public:
        typedef OptionVarBase<int, IntOptionVar> Base;

        IntOptionVar(const char* name, int defaultValue)
            : Base(name, defaultValue)
        {}

    private:
        friend class Base;

        int getImpl(bool& exists) const
        {
            return MGlobal::optionVarIntValue(myName.c_str(), &exists);
        }
    };

    class StringOptionVar: public OptionVarBase<MString, StringOptionVar>
    {
    public:
        typedef OptionVarBase<MString, StringOptionVar> Base;

        StringOptionVar(const char* name, const char* defaultValue)
            : Base(name, defaultValue)
        {}

    private:
        friend class Base;

        MString getImpl(bool& exists) const
        {
            return MGlobal::optionVarStringValue(myName.c_str(), &exists);
        }
    };

    struct OptionVars
    {
        OptionVars()
            : asyncMode("AsynchronousMode", 1)
            , sessionType("SessionType", 0)
            , thriftServer("ThriftServer", "localhost")
            , thriftPort("ThriftPort", 9090)
            , thriftPipe("ThriftPipe", "hapi")
        {}

        IntOptionVar     asyncMode;
        IntOptionVar     sessionType;
        StringOptionVar  thriftServer;
        IntOptionVar     thriftPort;
        StringOptionVar  thriftPipe;

    private:
        OptionVars& operator=(const OptionVars&);
    };
}

bool
initializeHAPI(const OptionVars& optionVars)
{
    if(HAPI_IsInitialized( Util::theHAPISession.get() ) == HAPI_RESULT_SUCCESS)
    {
        MGlobal::displayInfo("Houdini Engine is already initialized. Skipping initialization.");
        return true;
    }

    HAPI_Result hstat = HAPI_RESULT_SUCCESS;

    const char* otl_dir = getenv("HAPI_OTL_PATH");
    const char* dso_dir = getenv("HAPI_DSO_PATH");

    HAPI_CookOptions cook_options = HAPI_CookOptions_Create();
    cook_options.maxVerticesPerPrimitive = -1;
    cook_options.refineCurveToLinear = false;

    bool use_cooking_thread = optionVars.asyncMode.get() == 1;

    hstat = HAPI_Initialize(
            Util::theHAPISession.get(), otl_dir, dso_dir,
            &cook_options,
            use_cooking_thread,
            -1
            );
    if(hstat != HAPI_RESULT_SUCCESS)
    {
        CHECK_HAPI(hstat);
        return false;
    }

    return true;
}

bool
cleanupHAPI()
{
    HAPI_Result hstat = HAPI_RESULT_SUCCESS;

    hstat = HAPI_Cleanup( Util::theHAPISession.get() );
    if(hstat != HAPI_RESULT_SUCCESS)
    {
        CHECK_HAPI(hstat);
        return false;
    }

    return true;
}

void updateTimelineCallback(void* clientData)
{
    HAPI_TimelineOptions timelineOptions;

    MTime oneUnitTime;

    // Houdini's "frame 1" is "0 seconds", but Maya's "frame 0" is "0 seconds".
    // So we need to offset the time by 1.
    timelineOptions.fps = float( 1.0 / oneUnitTime.as(MTime::kSeconds) );
    timelineOptions.startTime =
        (MAnimControl::animationStartTime() - oneUnitTime)
        .as(MTime::kSeconds);
    timelineOptions.endTime =
        (MAnimControl::animationEndTime() - oneUnitTime)
        .as(MTime::kSeconds);

    HAPI_SetTimelineOptions(Util::theHAPISession.get(), &timelineOptions);
}

MCallbackIdArray messageCallbacks;

void
initializeMessageCallbacks()
{
    MStatus status;

    MCallbackId callbackId;

    callbackId = MEventMessage::addEventCallback(
            "playbackRangeSliderChanged",
            updateTimelineCallback,
            NULL,
            &status
            );
    if(status)
    {
        messageCallbacks.append(callbackId);
    }
    else
    {
        CHECK_MSTATUS(status);
    }

    callbackId = MEventMessage::addEventCallback(
            "timeUnitChanged",
            updateTimelineCallback,
            NULL,
            &status
            );
    if(status)
    {
        messageCallbacks.append(callbackId);
    }
    else
    {
        CHECK_MSTATUS(status);
    }
}

void
cleanupMessageCallbacks()
{
    MStatus status;

    status = MMessage::removeCallbacks(messageCallbacks);
    CHECK_MSTATUS(status);
}

#ifdef USE_LIBHASH
namespace SessionType
{
    enum Enum
    {
        ST_INPROCESS,
        ST_THRIFT_SOCKET,
        ST_THRIFT_PIPE
    };
}
#endif

MStatus
initializePlugin(MObject obj)
{
    OptionVars optionVars;

#ifdef USE_LIBHASH
    if ( Util::theHAPISession.get() )
    {
        MGlobal::displayInfo(
            "Houdini Engine session is already created. Skipping.");
    }
    else
    {
        const SessionType::Enum sessionType =
            static_cast<SessionType::Enum>( optionVars.sessionType.get() );

        switch (sessionType)
        {
        case SessionType::ST_INPROCESS:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateInProcessSession( Util::theHAPISession.get() );
            break;

        case SessionType::ST_THRIFT_SOCKET:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateThriftSocketSession(
                Util::theHAPISession.get(),
                optionVars.thriftServer.get().asChar(),
                optionVars.thriftPort.get() );
            break;

        case SessionType::ST_THRIFT_PIPE:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateThriftNamedPipeSession(
                Util::theHAPISession.get(),
                optionVars.thriftPipe.get().asChar() );
            break;
        }
    }
#endif

    printHAPIVersion();

    char engine_version[32];
    sprintf(engine_version, "%d.%d (API: %d)",
            HAPI_VERSION_HOUDINI_ENGINE_MAJOR,
            HAPI_VERSION_HOUDINI_ENGINE_MINOR,
            HAPI_VERSION_HOUDINI_ENGINE_API);

    MStatus status;
    MFnPlugin plugin(
            obj, "Side Effects",
            engine_version,
            "Any"
            );

    if ( initializeHAPI(optionVars) )
    {
        MGlobal::displayInfo("Houdini Engine initialized successfully.");
    }
    else
    {
        MGlobal::displayInfo("Houdini Engine failed to initialize.");
        return MStatus::kFailure;
    }

    status = plugin.registerUI("houdiniEngineCreateUI", "houdiniEngineDeleteUI");
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerTransform(
            AssetNode::typeName,
            AssetNode::typeId,
            AssetNode::creator,
            AssetNode::initialize,
            MPxTransformationMatrix::creator,
            MPxTransformationMatrix::baseTransformationMatrixId
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerNode(
            CurveMeshInputNode::typeName,
            CurveMeshInputNode::typeId,
            CurveMeshInputNode::creator,
            CurveMeshInputNode::initialize
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

#if MAYA_API_VERSION >= 201400
    status = plugin.registerNode(
            FluidGridConvert::typeName,
            FluidGridConvert::typeId,
            FluidGridConvert::creator,
            FluidGridConvert::initialize
            );
#endif

    status = plugin.registerCommand(
            EngineCommand::commandName,
            EngineCommand::creator,
            EngineCommand::newSyntax
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerCommand( "houdiniAsset", AssetCommand::creator,
                                     AssetCommand::newSyntax);

    CHECK_MSTATUS_AND_RETURN_IT(status);

    initializeMessageCallbacks();

    // update the timeline option for the first time
    updateTimelineCallback(NULL);

    return status;
}

MStatus
uninitializePlugin(MObject obj)
{
    MStatus status;
    MFnPlugin plugin(obj);

    cleanupMessageCallbacks();

    status = plugin.deregisterNode(AssetNode::typeId);
    CHECK_MSTATUS_AND_RETURN_IT(status);

#if MAYA_API_VERSION >= 201400
    status = plugin.deregisterNode(FluidGridConvert::typeId);
    CHECK_MSTATUS_AND_RETURN_IT(status);
#endif

    status = plugin.deregisterCommand(EngineCommand::commandName);
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.deregisterCommand("houdiniAsset");
    CHECK_MSTATUS_AND_RETURN_IT(status);

    if(cleanupHAPI())
    {
	MGlobal::displayInfo("Houdini Engine cleaned up successfully.");
    }
    else
    {
	MGlobal::displayInfo("Houdini Engine failed to clean up.");
	return MStatus::kFailure;
    }

    return status;
}
<commit_msg>fixed build break on GCC4.8<commit_after>#include <maya/MAnimControl.h>
#include <maya/MCallbackIdArray.h>
#include <maya/MEventMessage.h>
#include <maya/MGlobal.h>

#include <maya/MFnPlugin.h>

#include "EngineCommand.h"
#include "AssetCommand.h"
#include "AssetNode.h"
#include "CurveMeshInputNode.h"
#include "FluidGridConvert.h"
#include "util.h"

#include <HAPI/HAPI_Version.h>

#include <cstdlib>

void
printHAPIVersion()
{
    int i, j, k;
    char version[32];
    MString msg;

    {
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_MAJOR, &i);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_MINOR, &j);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_BUILD, &k);

        msg = "Houdini version: ";
        sprintf(version, "%d.%d.%d", i, j, k);
        msg += version;
        if(!(i == HAPI_VERSION_HOUDINI_MAJOR
                    && j == HAPI_VERSION_HOUDINI_MINOR
                    && k == HAPI_VERSION_HOUDINI_BUILD))
        {
            msg += ", expected: ";
            sprintf(version, "%d.%d.%d",
                    HAPI_VERSION_HOUDINI_MAJOR,
                    HAPI_VERSION_HOUDINI_MINOR,
                    HAPI_VERSION_HOUDINI_BUILD);
            msg += version;
        }

        MGlobal::displayInfo(msg);
    }

    {
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_MAJOR, &i);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_MINOR, &j);
        HAPI_GetEnvInt(Util::theHAPISession.get(), HAPI_ENVINT_VERSION_HOUDINI_ENGINE_API, &k);

        msg = "Houdini Engine version: ";
        sprintf(version, "%d.%d (API: %d)", i, j, k);
        msg += version;

        if(!(i == HAPI_VERSION_HOUDINI_ENGINE_MAJOR
                    && j == HAPI_VERSION_HOUDINI_ENGINE_MINOR
                    && k == HAPI_VERSION_HOUDINI_ENGINE_API))
        {
            msg += ", expected: ";
            sprintf(version, "%d.%d (API: %d)",
                    HAPI_VERSION_HOUDINI_ENGINE_MAJOR,
                    HAPI_VERSION_HOUDINI_ENGINE_MINOR,
                    HAPI_VERSION_HOUDINI_ENGINE_API);
            msg += version;
        }

        MGlobal::displayInfo(msg);
    }
}

namespace
{
    template <typename VAL, class CHILD>
    class OptionVarBase
    {
    public:
        OptionVarBase(const char* name, const VAL& defaultValue)
            : myDefaultValue(defaultValue)
        {
            myName = "houdiniEngine";
            myName += name;

            bool exists = false;
            static_cast<const CHILD&>(*this).getImpl(exists);

            if (!exists)
            {
                MGlobal::setOptionVarValue(myName.c_str(), myDefaultValue);
            }
        }

        VAL get() const
        {
            bool exists = false;
            const VAL value = static_cast<const CHILD&>(*this).getImpl(exists);
            return exists ? value : myDefaultValue;
        }

    protected:
        std::string myName;
        const VAL myDefaultValue;

    private:
        OptionVarBase& operator=(const OptionVarBase&);
    };

    class IntOptionVar: public OptionVarBase<int, IntOptionVar>
    {
    public:
        typedef OptionVarBase<int, IntOptionVar> Base;

        IntOptionVar(const char* name, int defaultValue)
            : Base(name, defaultValue)
        {}

        int getImpl(bool& exists) const
        {
            return MGlobal::optionVarIntValue(myName.c_str(), &exists);
        }
    };

    class StringOptionVar: public OptionVarBase<MString, StringOptionVar>
    {
    public:
        typedef OptionVarBase<MString, StringOptionVar> Base;

        StringOptionVar(const char* name, const char* defaultValue)
            : Base(name, defaultValue)
        {}

        MString getImpl(bool& exists) const
        {
            return MGlobal::optionVarStringValue(myName.c_str(), &exists);
        }
    };

    struct OptionVars
    {
        OptionVars()
            : asyncMode("AsynchronousMode", 1)
            , sessionType("SessionType", 0)
            , thriftServer("ThriftServer", "localhost")
            , thriftPort("ThriftPort", 9090)
            , thriftPipe("ThriftPipe", "hapi")
        {}

        IntOptionVar     asyncMode;
        IntOptionVar     sessionType;
        StringOptionVar  thriftServer;
        IntOptionVar     thriftPort;
        StringOptionVar  thriftPipe;

    private:
        OptionVars& operator=(const OptionVars&);
    };
}

bool
initializeHAPI(const OptionVars& optionVars)
{
    if(HAPI_IsInitialized( Util::theHAPISession.get() ) == HAPI_RESULT_SUCCESS)
    {
        MGlobal::displayInfo("Houdini Engine is already initialized. Skipping initialization.");
        return true;
    }

    HAPI_Result hstat = HAPI_RESULT_SUCCESS;

    const char* otl_dir = getenv("HAPI_OTL_PATH");
    const char* dso_dir = getenv("HAPI_DSO_PATH");

    HAPI_CookOptions cook_options = HAPI_CookOptions_Create();
    cook_options.maxVerticesPerPrimitive = -1;
    cook_options.refineCurveToLinear = false;

    bool use_cooking_thread = optionVars.asyncMode.get() == 1;

    hstat = HAPI_Initialize(
            Util::theHAPISession.get(), otl_dir, dso_dir,
            &cook_options,
            use_cooking_thread,
            -1
            );
    if(hstat != HAPI_RESULT_SUCCESS)
    {
        CHECK_HAPI(hstat);
        return false;
    }

    return true;
}

bool
cleanupHAPI()
{
    HAPI_Result hstat = HAPI_RESULT_SUCCESS;

    hstat = HAPI_Cleanup( Util::theHAPISession.get() );
    if(hstat != HAPI_RESULT_SUCCESS)
    {
        CHECK_HAPI(hstat);
        return false;
    }

    return true;
}

void updateTimelineCallback(void* clientData)
{
    HAPI_TimelineOptions timelineOptions;

    MTime oneUnitTime;

    // Houdini's "frame 1" is "0 seconds", but Maya's "frame 0" is "0 seconds".
    // So we need to offset the time by 1.
    timelineOptions.fps = float( 1.0 / oneUnitTime.as(MTime::kSeconds) );
    timelineOptions.startTime =
        (MAnimControl::animationStartTime() - oneUnitTime)
        .as(MTime::kSeconds);
    timelineOptions.endTime =
        (MAnimControl::animationEndTime() - oneUnitTime)
        .as(MTime::kSeconds);

    HAPI_SetTimelineOptions(Util::theHAPISession.get(), &timelineOptions);
}

MCallbackIdArray messageCallbacks;

void
initializeMessageCallbacks()
{
    MStatus status;

    MCallbackId callbackId;

    callbackId = MEventMessage::addEventCallback(
            "playbackRangeSliderChanged",
            updateTimelineCallback,
            NULL,
            &status
            );
    if(status)
    {
        messageCallbacks.append(callbackId);
    }
    else
    {
        CHECK_MSTATUS(status);
    }

    callbackId = MEventMessage::addEventCallback(
            "timeUnitChanged",
            updateTimelineCallback,
            NULL,
            &status
            );
    if(status)
    {
        messageCallbacks.append(callbackId);
    }
    else
    {
        CHECK_MSTATUS(status);
    }
}

void
cleanupMessageCallbacks()
{
    MStatus status;

    status = MMessage::removeCallbacks(messageCallbacks);
    CHECK_MSTATUS(status);
}

#ifdef USE_LIBHASH
namespace SessionType
{
    enum Enum
    {
        ST_INPROCESS,
        ST_THRIFT_SOCKET,
        ST_THRIFT_PIPE
    };
}
#endif

MStatus
initializePlugin(MObject obj)
{
    OptionVars optionVars;

#ifdef USE_LIBHASH
    if ( Util::theHAPISession.get() )
    {
        MGlobal::displayInfo(
            "Houdini Engine session is already created. Skipping.");
    }
    else
    {
        const SessionType::Enum sessionType =
            static_cast<SessionType::Enum>( optionVars.sessionType.get() );

        switch (sessionType)
        {
        case SessionType::ST_INPROCESS:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateInProcessSession( Util::theHAPISession.get() );
            break;

        case SessionType::ST_THRIFT_SOCKET:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateThriftSocketSession(
                Util::theHAPISession.get(),
                optionVars.thriftServer.get().asChar(),
                optionVars.thriftPort.get() );
            break;

        case SessionType::ST_THRIFT_PIPE:
            Util::theHAPISession.reset( new HAPI_Session );
            HAPI_CreateThriftNamedPipeSession(
                Util::theHAPISession.get(),
                optionVars.thriftPipe.get().asChar() );
            break;
        }
    }
#endif

    printHAPIVersion();

    char engine_version[32];
    sprintf(engine_version, "%d.%d (API: %d)",
            HAPI_VERSION_HOUDINI_ENGINE_MAJOR,
            HAPI_VERSION_HOUDINI_ENGINE_MINOR,
            HAPI_VERSION_HOUDINI_ENGINE_API);

    MStatus status;
    MFnPlugin plugin(
            obj, "Side Effects",
            engine_version,
            "Any"
            );

    if ( initializeHAPI(optionVars) )
    {
        MGlobal::displayInfo("Houdini Engine initialized successfully.");
    }
    else
    {
        MGlobal::displayInfo("Houdini Engine failed to initialize.");
        return MStatus::kFailure;
    }

    status = plugin.registerUI("houdiniEngineCreateUI", "houdiniEngineDeleteUI");
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerTransform(
            AssetNode::typeName,
            AssetNode::typeId,
            AssetNode::creator,
            AssetNode::initialize,
            MPxTransformationMatrix::creator,
            MPxTransformationMatrix::baseTransformationMatrixId
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerNode(
            CurveMeshInputNode::typeName,
            CurveMeshInputNode::typeId,
            CurveMeshInputNode::creator,
            CurveMeshInputNode::initialize
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

#if MAYA_API_VERSION >= 201400
    status = plugin.registerNode(
            FluidGridConvert::typeName,
            FluidGridConvert::typeId,
            FluidGridConvert::creator,
            FluidGridConvert::initialize
            );
#endif

    status = plugin.registerCommand(
            EngineCommand::commandName,
            EngineCommand::creator,
            EngineCommand::newSyntax
            );
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.registerCommand( "houdiniAsset", AssetCommand::creator,
                                     AssetCommand::newSyntax);

    CHECK_MSTATUS_AND_RETURN_IT(status);

    initializeMessageCallbacks();

    // update the timeline option for the first time
    updateTimelineCallback(NULL);

    return status;
}

MStatus
uninitializePlugin(MObject obj)
{
    MStatus status;
    MFnPlugin plugin(obj);

    cleanupMessageCallbacks();

    status = plugin.deregisterNode(AssetNode::typeId);
    CHECK_MSTATUS_AND_RETURN_IT(status);

#if MAYA_API_VERSION >= 201400
    status = plugin.deregisterNode(FluidGridConvert::typeId);
    CHECK_MSTATUS_AND_RETURN_IT(status);
#endif

    status = plugin.deregisterCommand(EngineCommand::commandName);
    CHECK_MSTATUS_AND_RETURN_IT(status);

    status = plugin.deregisterCommand("houdiniAsset");
    CHECK_MSTATUS_AND_RETURN_IT(status);

    if(cleanupHAPI())
    {
	MGlobal::displayInfo("Houdini Engine cleaned up successfully.");
    }
    else
    {
	MGlobal::displayInfo("Houdini Engine failed to clean up.");
	return MStatus::kFailure;
    }

    return status;
}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "instance_intersector.h"
#include "../common/scene.h"

namespace embree
{
  namespace isa
  {
    void InstanceBoundsFunction(void* userPtr, const Instance* instance, unsigned int item, unsigned int itime, BBox3fa& bounds_o)
    {
      assert(itime < instance->numTimeSteps);
      unsigned num_time_segments = instance->numTimeSegments();
      if (num_time_segments == 0) {
        bounds_o = xfmBounds(instance->local2world[itime],instance->object->bounds.bounds());
      }
      else {
        const float ftime = float(itime) / float(num_time_segments);
        const BBox3fa obounds = instance->object->bounds.interpolate(ftime);
        bounds_o = xfmBounds(instance->local2world[itime],obounds);
      }
    }

    RTCBoundsFunc InstanceBoundsFunc() {
      return (RTCBoundsFunc) InstanceBoundsFunction;
    }

    __forceinline void FastInstanceIntersectorN::intersect1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, unsigned int item)
    {
      const AffineSpace3fa world2local =
        likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time);
      const Vec3fa ray_org = ray.org;
      const Vec3fa ray_dir = ray.dir;
      const int ray_geomID = ray.geomID;
      const int ray_instID = ray.instID;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.geomID = RTC_INVALID_GEOMETRY_ID;
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      instance->object->intersectors.intersect((RTCRay&)ray,&context);
      ray.org = ray_org;
      ray.dir = ray_dir;
      if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
        ray.geomID = ray_geomID;
        ray.instID = ray_instID;
      }
    }

    __forceinline void FastInstanceIntersectorN::occluded1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, unsigned int item)
    {
      const AffineSpace3fa world2local =
        likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time);
      const Vec3fa ray_org = ray.org;
      const Vec3fa ray_dir = ray.dir;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      instance->object->intersectors.occluded((RTCRay&)ray,&context);
      ray.org = ray_org;
      ray.dir = ray_dir;
    }

    template<int K>
    __forceinline void intersectObject(vint<K>* valid, Scene* object, IntersectContext* context, RayK<K>& ray);
    template<int K>
    __forceinline void occludedObject(vint<K>* valid, Scene* object, IntersectContext* context, RayK<K>& ray);

#if defined (__SSE__)
    template<> __forceinline void intersectObject<4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.intersect4(valid,(RTCRay4&)ray,context); }
    template<> __forceinline void occludedObject <4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.occluded4 (valid,(RTCRay4&)ray,context); }
#endif
#if defined (__AVX__)
    template<> __forceinline void intersectObject<8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.intersect8(valid,(RTCRay8&)ray,context); }
    template<> __forceinline void occludedObject <8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.occluded8 (valid,(RTCRay8&)ray,context); }
#endif
#if defined (__AVX512F__)
    template<> __forceinline void intersectObject<16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.intersect16(valid,(RTCRay16&)ray,context); }
    template<> __forceinline void occludedObject <16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.occluded16 (valid,(RTCRay16&)ray,context); }
#endif

    template<int N>
    __noinline void FastInstanceIntersectorN::intersectN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, unsigned int item)
    {
      AffineSpace3vf<N> world2local;
      const vbool<N> valid = *validi == vint<N>(-1);
      if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local();
      else                                     world2local = instance->getWorld2Local<N>(valid,ray.time);

      const Vec3vf<N> ray_org = ray.org;
      const Vec3vf<N> ray_dir = ray.dir;
      const vint<N> ray_geomID = ray.geomID;
      const vint<N> ray_instID = ray.instID;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.geomID = RTC_INVALID_GEOMETRY_ID;
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      intersectObject((vint<N>*)validi,instance->object,&context,ray);
      ray.org = ray_org;
      ray.dir = ray_dir;
      vbool<N> nohit = ray.geomID == vint<N>(RTC_INVALID_GEOMETRY_ID);
      ray.geomID = select(nohit,ray_geomID,ray.geomID);
      ray.instID = select(nohit,ray_instID,ray.instID);
    }

    template<int N>
    __noinline void FastInstanceIntersectorN::occludedN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, unsigned int item)
    {
      AffineSpace3vf<N> world2local;
      const vbool<N> valid = *validi == vint<N>(-1);
      if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local();
      else                                     world2local = instance->getWorld2Local<N>(valid,ray.time);

      const Vec3vf<N> ray_org = ray.org;
      const Vec3vf<N> ray_dir = ray.dir;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      occludedObject((vint<N>*)validi,instance->object,&context,ray);
      ray.org = ray_org;
      ray.dir = ray_dir;
    }

    void FastInstanceIntersectorN::intersect(const int* validi, void* ptr, const RTCIntersectContext* user_context, RTCRayN* rays, unsigned int N, unsigned int item)
    {
      if (likely(N == 1)) {
        assert(*validi == -1);
        return intersect1((const Instance*)ptr,user_context,*(Ray*)rays,item);
      }
      else if (likely(N == 4)) {
        return intersectN((vint4*)validi,(const Instance*)ptr,user_context,*(Ray4*)rays,item);
      }
#if defined(__AVX__)
      else if (likely(N == 8)) {
        return intersectN((vint8*)validi,(const Instance*)ptr,user_context,*(Ray8*)rays,item);
      }
#endif
#if defined(__AVX512F__)
      else if (likely(N == 16)) {
        return intersectN((vint16*)validi,(const Instance*)ptr,user_context,*(Ray16*)rays,item);
      }
#endif
      assert(false);
    }

    void FastInstanceIntersectorN::occluded(const int* validi, void* ptr, const RTCIntersectContext* user_context, RTCRayN* rays, unsigned int N, unsigned int item)
    {
      if (likely(N == 1)) {
        assert(*validi == -1);
        return occluded1((const Instance*)ptr,user_context,*(Ray*)rays,item);
      }
      else if (likely(N == 4)) {
        return occludedN((vint4*)validi,(const Instance*)ptr,user_context,*(Ray4*)rays,item);
      }
#if defined(__AVX__)
      else if (likely(N == 8)) {
        return occludedN((vint8*)validi,(const Instance*)ptr,user_context,*(Ray8*)rays,item);
      }
#endif
#if defined(__AVX512F__)
      else if (likely(N == 16)) {
        return occludedN((vint16*)validi,(const Instance*)ptr,user_context,*(Ray16*)rays,item);
      }
#endif
      assert(false);
    }

    DEFINE_SET_INTERSECTORN(InstanceIntersectorN,FastInstanceIntersectorN);
  }
}
<commit_msg>fixed instances with new tnear,tfar mechanism<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// 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 "instance_intersector.h"
#include "../common/scene.h"

namespace embree
{
  namespace isa
  {
    void InstanceBoundsFunction(void* userPtr, const Instance* instance, unsigned int item, unsigned int itime, BBox3fa& bounds_o)
    {
      assert(itime < instance->numTimeSteps);
      unsigned num_time_segments = instance->numTimeSegments();
      if (num_time_segments == 0) {
        bounds_o = xfmBounds(instance->local2world[itime],instance->object->bounds.bounds());
      }
      else {
        const float ftime = float(itime) / float(num_time_segments);
        const BBox3fa obounds = instance->object->bounds.interpolate(ftime);
        bounds_o = xfmBounds(instance->local2world[itime],obounds);
      }
    }

    RTCBoundsFunc InstanceBoundsFunc() {
      return (RTCBoundsFunc) InstanceBoundsFunction;
    }

    __forceinline void FastInstanceIntersectorN::intersect1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, unsigned int item)
    {
      const AffineSpace3fa world2local =
        likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time);
      const Vec3fa ray_org = ray.org;
      const Vec3fa ray_dir = ray.dir;
      const int ray_geomID = ray.geomID;
      const int ray_instID = ray.instID;
      ray.org = Vec3fa(xfmPoint (world2local,ray_org),ray.tnear());
      ray.dir = Vec3fa(xfmVector(world2local,ray_dir),ray.tfar());
      ray.geomID = RTC_INVALID_GEOMETRY_ID;
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      instance->object->intersectors.intersect((RTCRay&)ray,&context);
      ray.org = ray_org;
      ray.dir = Vec3fa(ray_dir,ray.tfar());
      if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
        ray.geomID = ray_geomID;
        ray.instID = ray_instID;
      }
    }

    __forceinline void FastInstanceIntersectorN::occluded1(const Instance* instance, const RTCIntersectContext* user_context, Ray& ray, unsigned int item)
    {
      const AffineSpace3fa world2local =
        likely(instance->numTimeSteps == 1) ? instance->getWorld2Local() : instance->getWorld2Local(ray.time);
      const Vec3fa ray_org = ray.org;
      const Vec3fa ray_dir = ray.dir;
      ray.org = Vec3fa(xfmPoint (world2local,ray_org),ray.tnear());
      ray.dir = Vec3fa(xfmVector(world2local,ray_dir),ray.tfar());
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      instance->object->intersectors.occluded((RTCRay&)ray,&context);
      ray.org = ray_org;
      ray.dir = ray_dir;
    }

    template<int K>
    __forceinline void intersectObject(vint<K>* valid, Scene* object, IntersectContext* context, RayK<K>& ray);
    template<int K>
    __forceinline void occludedObject(vint<K>* valid, Scene* object, IntersectContext* context, RayK<K>& ray);

#if defined (__SSE__)
    template<> __forceinline void intersectObject<4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.intersect4(valid,(RTCRay4&)ray,context); }
    template<> __forceinline void occludedObject <4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.occluded4 (valid,(RTCRay4&)ray,context); }
#endif
#if defined (__AVX__)
    template<> __forceinline void intersectObject<8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.intersect8(valid,(RTCRay8&)ray,context); }
    template<> __forceinline void occludedObject <8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.occluded8 (valid,(RTCRay8&)ray,context); }
#endif
#if defined (__AVX512F__)
    template<> __forceinline void intersectObject<16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.intersect16(valid,(RTCRay16&)ray,context); }
    template<> __forceinline void occludedObject <16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.occluded16 (valid,(RTCRay16&)ray,context); }
#endif

    template<int N>
    __noinline void FastInstanceIntersectorN::intersectN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, unsigned int item)
    {
      AffineSpace3vf<N> world2local;
      const vbool<N> valid = *validi == vint<N>(-1);
      if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local();
      else                                     world2local = instance->getWorld2Local<N>(valid,ray.time);

      const Vec3vf<N> ray_org = ray.org;
      const Vec3vf<N> ray_dir = ray.dir;
      const vint<N> ray_geomID = ray.geomID;
      const vint<N> ray_instID = ray.instID;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.geomID = RTC_INVALID_GEOMETRY_ID;
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      intersectObject((vint<N>*)validi,instance->object,&context,ray);
      ray.org = ray_org;
      ray.dir = ray_dir;
      vbool<N> nohit = ray.geomID == vint<N>(RTC_INVALID_GEOMETRY_ID);
      ray.geomID = select(nohit,ray_geomID,ray.geomID);
      ray.instID = select(nohit,ray_instID,ray.instID);
    }

    template<int N>
    __noinline void FastInstanceIntersectorN::occludedN(vint<N>* validi, const Instance* instance, const RTCIntersectContext* user_context, RayK<N>& ray, unsigned int item)
    {
      AffineSpace3vf<N> world2local;
      const vbool<N> valid = *validi == vint<N>(-1);
      if (likely(instance->numTimeSteps == 1)) world2local = instance->getWorld2Local();
      else                                     world2local = instance->getWorld2Local<N>(valid,ray.time);

      const Vec3vf<N> ray_org = ray.org;
      const Vec3vf<N> ray_dir = ray.dir;
      ray.org = xfmPoint (world2local,ray_org);
      ray.dir = xfmVector(world2local,ray_dir);
      ray.instID = instance->geomID;
      IntersectContext context(instance->object,user_context);
      occludedObject((vint<N>*)validi,instance->object,&context,ray);
      ray.org = ray_org;
      ray.dir = ray_dir;
    }

    void FastInstanceIntersectorN::intersect(const int* validi, void* ptr, const RTCIntersectContext* user_context, RTCRayN* rays, unsigned int N, unsigned int item)
    {
      if (likely(N == 1)) {
        assert(*validi == -1);
        return intersect1((const Instance*)ptr,user_context,*(Ray*)rays,item);
      }
      else if (likely(N == 4)) {
        return intersectN((vint4*)validi,(const Instance*)ptr,user_context,*(Ray4*)rays,item);
      }
#if defined(__AVX__)
      else if (likely(N == 8)) {
        return intersectN((vint8*)validi,(const Instance*)ptr,user_context,*(Ray8*)rays,item);
      }
#endif
#if defined(__AVX512F__)
      else if (likely(N == 16)) {
        return intersectN((vint16*)validi,(const Instance*)ptr,user_context,*(Ray16*)rays,item);
      }
#endif
      assert(false);
    }

    void FastInstanceIntersectorN::occluded(const int* validi, void* ptr, const RTCIntersectContext* user_context, RTCRayN* rays, unsigned int N, unsigned int item)
    {
      if (likely(N == 1)) {
        assert(*validi == -1);
        return occluded1((const Instance*)ptr,user_context,*(Ray*)rays,item);
      }
      else if (likely(N == 4)) {
        return occludedN((vint4*)validi,(const Instance*)ptr,user_context,*(Ray4*)rays,item);
      }
#if defined(__AVX__)
      else if (likely(N == 8)) {
        return occludedN((vint8*)validi,(const Instance*)ptr,user_context,*(Ray8*)rays,item);
      }
#endif
#if defined(__AVX512F__)
      else if (likely(N == 16)) {
        return occludedN((vint16*)validi,(const Instance*)ptr,user_context,*(Ray16*)rays,item);
      }
#endif
      assert(false);
    }

    DEFINE_SET_INTERSECTORN(InstanceIntersectorN,FastInstanceIntersectorN);
  }
}
<|endoftext|>


<commit_before><?hh //partial

namespace hhpack\typesafety\spec\reporter;

use hhpack\typechecker\check\Result;
use hhpack\typesafety\reporter\TextReporter;
use hhpack\typesafety\message\StoppedMessage;
use hhpack\typesafety\ouput\ConsoleOutput;

describe(TextReporter::class, function() {
  beforeEach(function() {
    $content = file_get_contents(__DIR__ . '/../fixtures/failed/output.json');
    $content = str_replace('{$rootDirectory}', realpath(__DIR__ . '/../fixtures/failed') , $content);
    $json = json_decode($content);
    $this->result = Result::fromObject($json);
    $this->reporter = new TextReporter(new ConsoleOutput());
  });
  describe('onStop()', function() {
    it('display type check report', function () {
      $this->reporter->onStop(new StoppedMessage($this->result));
    });
  });
});
<commit_msg>fix spec<commit_after><?hh //partial

namespace hhpack\typesafety\spec\reporter;

use hhpack\typechecker\check\Result;
use hhpack\typesafety\reporter\TextReporter;
use hhpack\typesafety\message\StoppedMessage;
use hhpack\typesafety\output\ConsoleOutput;

describe(TextReporter::class, function() {
  beforeEach(function() {
    $content = file_get_contents(__DIR__ . '/../fixtures/failed/output.json');
    $content = str_replace('{$rootDirectory}', realpath(__DIR__ . '/../fixtures/failed') , $content);
    $json = json_decode($content);
    $this->result = Result::fromObject($json);
    $this->reporter = new TextReporter(new ConsoleOutput());
  });
  describe('onStop()', function() {
    it('display type check report', function () {
      $this->reporter->onStop(new StoppedMessage($this->result));
    });
  });
});
<|endoftext|>


<commit_before>#include "system.hpp"

namespace System {
	bool readFile(const char *fname, std::string &lines) {
		std::ifstream file(fname);
		if(!file.is_open()) {
			return false;
		}
		for(std::string line; std::getline(file, line);) {
			lines.append(line + "\r\n");
		}
		file.close();
		return true;
	}
	bool readFile(const char *fname, std::vector<std::string> &lines) {
		std::ifstream file(fname);
		if(!file.is_open()) {
			return false;
		}
		for(std::string line; std::getline(file, line);) {
			lines.push_back(line);
		}
		file.close();
		return true;
	}

	int split(std::string const& line, std::vector<std::string> &words) {
		int wc = 0;
		std::string word;
		std::istringstream iss(line);
		while(iss >> word) {
			words.push_back(word);
			wc++;
		}
		return wc;
	}
};
<commit_msg>(Definitions/implementations from header)<commit_after>#include "system.hpp"
#include <fstream>

namespace System {
	bool uni_special(char ch) {
		return (ch & 0xc0) == 0x80;
	}
	int uni_strlen(const char *word) {
		int len = 0;
		for(; *word; word++) {
			if(!uni_special(*word)) {
				len++;
			}
		}
		return len;
	}
	int uni_strlen(const std::string &word) {
		return uni_strlen(word.c_str());
	}

	int strlen(const char *word) {
		int len = 0;
		bool escape = false, bracket = false;
		for(; *word; word++) {
			char ch = *word;
			if(!uni_special(ch)) {
				if(bracket) {
					if(ch == 'm') {
						bracket = escape = false;
					}
				} else if(escape) {
					if(ch == '[') {
						bracket = true;
					}
				} else if(ch == '\e') {
					escape = true;
				} else {
					len++;
				}
			}
		}
		return len;
	}

	std::string repeat(int w, char c = ' ') {
		std::ostringstream oss;
		oss << std::setw(w) << std::setfill(c);
		return oss.str();
	}
	template<typename T>
	std::string stringify(const T &t) {
		std::ostringstream oss;
		oss << t;
		return oss.str();
	}
	template<typename T1, typename T2, typename... TN>
	std::string stringify(const T1 &t1, const T2 &t2, const TN &... tn) {
		return stringify(t1) + " " + stringify(t2, tn...);
	}

	bool readFile(const char *fname, std::string &lines) {
		std::ifstream file(fname);
		if(!file.is_open()) {
			return false;
		}
		for(std::string line; std::getline(file, line);) {
			lines.append(line + "\r\n");
		}
		file.close();
		return true;
	}
	bool readFile(const char *fname, std::vector<std::string> &lines) {
		std::ifstream file(fname);
		if(!file.is_open()) {
			return false;
		}
		for(std::string line; std::getline(file, line);) {
			lines.push_back(line);
		}
		file.close();
		return true;
	}

	int split(std::string const& line, std::vector<std::string> &words) {
		int wc = 0;
		std::string word;
		std::istringstream iss(line);
		while(iss >> word) {
			words.push_back(word);
			wc++;
		}
		return wc;
	}
};
<|endoftext|>


<commit_before>#include <iostream>
#include <stdexcept>
#include <memory>
#include <set>
#include <chrono>
#include <mutex>
#include <thread>
#include <atomic>
#include <ogdf/basic/Graph.h>
#include <ogdf/basic/simple_graph_alg.h>
#include <ogdf/basic/graph_generators.h>
#include "helpers.h"
#include "circuitcocircuit.h"

#define BIAS6 63
#define SMALLN 62
#define TOPBIT6 32

using namespace ogdf;
using namespace std;

/* Graph sources */

/**
 * Since the default updateOnGraphRetrieval() uses no synchronization
 * the user might get updates on the number of retrieved graphs more often
 * than once a second if the extending classes do not implement any lock
 * (e.g. RandomGraphSource does this)
 */
class AbstractGraphSource
{
	std::chrono::time_point<std::chrono::system_clock> lastOutputTime;
	atomic<int> nGraphsRetrieved = ATOMIC_VAR_INIT(0);

protected:
	AbstractGraphSource()
	{
		lastOutputTime = std::chrono::system_clock::now();
	}

	void updateOnGraphRetrieval()
	{
		++nGraphsRetrieved;
		auto now = std::chrono::system_clock::now();
		auto diff = std::chrono::duration_cast<std::chrono::seconds>
				(now-lastOutputTime).count();
		if (diff > 1) {
			cout << "Graphs retrieved: " << nGraphsRetrieved.load() << endl;
			lastOutputTime = now;
		}
	}

public:

	virtual bool get(Graph &G) = 0;
	virtual ~AbstractGraphSource() {}
};

/**
 * Reads graphs in nauty's graph6 format from stdin.
 */
class StdinGraphSource : public AbstractGraphSource
{
	mutex cin_mtx;

	/*
	 * The following two functions are from the nauty package.
	 * See http://pallini.di.uniroma1.it/
	 * stringtograph was modified to work with OGDF's Graph class
	 */

	/**
	 * Get size of graph out of graph6 or sparse6 string.
	 */
	static int graphsize(char *s)
	{
		char *p;
		int n;

		if (s[0] == ':') p = s+1;
		else             p = s;
		n = *p++ - BIAS6;

		if (n > SMALLN)	{
			n = *p++ - BIAS6;
			n = (n << 6) | (*p++ - BIAS6);
			n = (n << 6) | (*p++ - BIAS6);
		}
		return n;
	}

	/**
	 * Convert string in graph6 format to graph.
	 */
	static void	stringtograph(char *s, Graph &G)
	{
		int n = graphsize(s), x = 0;

		char *p = s + 1;
		if (n > SMALLN) p += 3;

		vector<node> vertices(n);
		for(int i = 0; i < n; ++i) {
			vertices[i] = G.newNode(i);
		}

		int k = 1;
		for (int j = 1; j < n; ++j) {
			for (int i = 0; i < j; ++i) {
				if (--k == 0) {
					k = 6;
					x = *(p++) - BIAS6;
				}

				if (x & TOPBIT6) {
					G.newEdge(vertices[i], vertices[j]);
				}
				x <<= 1;
			}
		}
	}

public:

	/**
	 * Locks cin!
	 */
	bool get(Graph &G)
	{
		string s;
		unique_lock<mutex> lock(cin_mtx);
		bool r = getline(cin, s);
		updateOnGraphRetrieval();
		lock.unlock();

		char *cp = (char*) s.c_str();
		stringtograph(cp, G);

		return r;
	}
};

class RandomGraphSource : public AbstractGraphSource
{
	int nodes, minEdges, maxEdges;

public:
	RandomGraphSource(int nodes, int minE, int maxE)
		: nodes(nodes), minEdges(minE), maxEdges(maxE) {}

	/**
	 * OGDF's solution is probably biased... TODO
	 * http://stackoverflow.com/a/14618505/247532
	 */
	bool get(Graph &G)
	{
		int edges = randomNumber(minEdges, maxEdges);
		randomSimpleGraph(G, nodes, edges);
		List<edge> added;
		makeConnected(G, added);
		updateOnGraphRetrieval();
		return true;
	}
};

/* Test runner */

class TestRunner
{
	unique_ptr<AbstractGraphSource> graphs;

protected:
	mutex errorOutputMutex;
	bool errorFound = false;

	int minComponents, maxComponents,
		cutSizeBound;

	void reportProblem(const Graph &G, const set<set<int>> &AmB, const set<set<int>> &BmA)
	{
		unique_lock<mutex> lock(errorOutputMutex, defer_lock);
		if (errorFound || !lock.try_lock()) {
			// Somebody is already reporting a problem
			return;
		}
		errorFound = true;

		cout << "\nmincuts / bf:" << endl;
		for (set<int> c : AmB) {
			cout << c << endl;
		}

		cout << "bf / mincuts:" << endl;
		for (set<int> c : BmA) {
			cout << c << endl;
		}

		ofstream fGraph("tmp/tester_in.csv");
		if (!fGraph.is_open()) {
			cerr << "tmp/tester_in.csv could not be opened" << endl;
			exit(3);
		}
		graph2csv(G, fGraph);
		cout << "Input graph written to tmp/tester_in.csv" << endl;
	}

	bool testGraph(Graph &G)
	{
		// run circuitcocircuit and bfc
		List<bond> bonds;
		CircuitCocircuit alg(G, cutSizeBound);
		for (int i = minComponents; i <= maxComponents; ++i) {
			alg.run(i, bonds);
		}

		List<List<edge>> bf_bonds;
		bruteforceGraphBonds(G, cutSizeBound, minComponents, maxComponents,
				bf_bonds);

		set<set<int>> A, B, AmB, BmA;
		for(bond b : bonds) {
			set<int> si;
			for (edge e : b.edges) si.insert(e->index());
			A.insert(si);
		}

		for(List<edge> le : bf_bonds) {
			set<int> si;
			for (edge e : le) si.insert(e->index());
			B.insert(si);
		}

		set_difference(A.begin(), A.end(), B.begin(), B.end(),
				inserter(AmB, AmB.end()));
		set_difference(B.begin(), B.end(), A.begin(), A.end(),
				inserter(BmA, BmA.end()));

		if (AmB.empty() && BmA.empty()) {
			return true;
		} else {
			reportProblem(G, AmB, BmA);
			return false;
		}
	}

public:
	TestRunner(int minC, int maxC, int cutSizeB, unique_ptr<AbstractGraphSource> graphs)
		: graphs(move(graphs)), minComponents(minC), maxComponents(maxC), cutSizeBound(cutSizeB)
	{ }

	virtual void run() final
	{
		while(!errorFound) {
			Graph G;

			// Exhausted input?
			if (!graphs->get(G)) {
				break;
			}

			// Problem found on G?
			if (!testGraph(G)) {
				break;
			}
		}
	}
};

/* --- */

void printUsage(char *name)
{
	cerr << "Usage:\t" << name << " <cut size bound> <# of components> " \
		<< "\n\t\t[-r, --randomized <# of nodes> <min>-<max edges>] [-tN]\n\n";

	cerr << "\tThis program tests CircuitCocircuit implementation.\n" \
		<< "\tExpects graphs in nauty's graph6 format on stdin.\n\n" \

		<< "\tFirst two arguments are used for any graph being tested.\n" \
		<< "\t<# of components> can be exact or range (e.g. 2-3)\n" \
		<< "\t-r generate random graphs (won't use stdin input)\n" \
		<< "\t<max edges> is not strict (if the random graph is " \
		<< "disconnected\n\t\tthen we add edges to connect it)\n" \
		<< "\t-tN use N threads (by default N == 2)\n";
}

int main(int argc, char *argv[])
{
	if (argc < 3 || argc == 5 || argc > 7) {
		printUsage(argv[0]);
		exit(1);
	}

	// Number of components and cut size bound settings
	int minComponents, maxComponents, cutSizeBound;
	try {
		cutSizeBound = stoi(argv[1]);

		// # of components
		string secondArg(argv[2]);
		size_t hyphenPos = secondArg.find('-');
		if (hyphenPos == string::npos) {
			minComponents = maxComponents = stoi(argv[2]);
		} else {
			minComponents = stoi(secondArg.substr(0, hyphenPos));
			maxComponents = stoi(secondArg.substr(hyphenPos + 1));
		}

		if (maxComponents < minComponents) {
			throw invalid_argument("max components < min components");
		}
	} catch(invalid_argument &_) { // stoi failed
		printUsage(argv[0]);
		exit(2);
	}

	// Graph source settings
	unique_ptr<AbstractGraphSource> source;

	if (argc == 3 || (argv[3] != string("-r") && argv[3] != string("--randomized"))) {
		source = unique_ptr<StdinGraphSource>(new StdinGraphSource());
	} else {
		// Configure randomized testing
		int nodes, minEdges, maxEdges;
		try {
			size_t hyphenPos;

			// # of nodes
			nodes = stoi(argv[4]);

			// min-max edges
			string fifthArg(argv[5]);
			hyphenPos = fifthArg.find('-');
			if (hyphenPos == string::npos) {
				throw invalid_argument("Number of edges is not range.");
			}
			minEdges = stoi(fifthArg.substr(0, hyphenPos));
			maxEdges = stoi(fifthArg.substr(hyphenPos + 1));

			if (maxEdges < minEdges) {
				throw invalid_argument("max edges < min edges");
			}

		} catch(invalid_argument &_) { // stoi failed
			printUsage(argv[0]);
			exit(2);
		}

		source = unique_ptr<RandomGraphSource>(new RandomGraphSource(nodes, minEdges, maxEdges));
	}

	// Parallelization settings
	int nThreads = 2;
	string lastArg(argv[argc - 1]);
	if (lastArg.substr(0, 2) == "-t") {
		nThreads = stoi(lastArg.substr(2));
	}

	// Run tester in parallel
	TestRunner testrunner(minComponents, maxComponents, cutSizeBound, move(source));

	vector<thread> threads(nThreads);
	for (int i = 0; i < nThreads; ++i) {
		threads[i] = thread(&TestRunner::run, ref(testrunner));
	}

	for (int i = 0; i < nThreads; ++i) {
		threads[i].join();
	}

	return 0;
}
<commit_msg>Fixed reaction on end of input in tester + minor changes<commit_after>#include <iostream>
#include <stdexcept>
#include <memory>
#include <set>
#include <chrono>
#include <mutex>
#include <thread>
#include <atomic>
#include <ogdf/basic/Graph.h>
#include <ogdf/basic/simple_graph_alg.h>
#include <ogdf/basic/graph_generators.h>
#include "helpers.h"
#include "circuitcocircuit.h"

#define BIAS6 63
#define SMALLN 62
#define TOPBIT6 32

using namespace ogdf;
using namespace std;

/* Graph sources */

/**
 * Since the default updateOnGraphRetrieval() uses no synchronization
 * the user might get updates on the number of retrieved graphs more often
 * than once a second if the extending classes do not implement any lock
 * (e.g. RandomGraphSource does this)
 */
class AbstractGraphSource
{
	std::chrono::time_point<std::chrono::system_clock> lastOutputTime;
	atomic<int> nGraphsRetrieved = ATOMIC_VAR_INIT(0);

protected:
	AbstractGraphSource()
	{
		lastOutputTime = std::chrono::system_clock::now();
	}

	void updateOnGraphRetrieval()
	{
		++nGraphsRetrieved;
		auto now = std::chrono::system_clock::now();
		auto diff = std::chrono::duration_cast<std::chrono::seconds>
				(now-lastOutputTime).count();
		if (diff > 1) {
			cout << "Graphs retrieved: " << nGraphsRetrieved.load() << endl;
			lastOutputTime = now;
		}
	}

public:

	virtual bool get(Graph &G) = 0;
	virtual ~AbstractGraphSource() {}
};

/**
 * Reads graphs in nauty's graph6 format from stdin.
 */
class StdinGraphSource : public AbstractGraphSource
{
	mutex cin_mtx;

	/*
	 * The following two functions are from the nauty package.
	 * See http://pallini.di.uniroma1.it/
	 * stringtograph was modified to work with OGDF's Graph class
	 */

	/**
	 * Get size of graph out of graph6 or sparse6 string.
	 */
	static int graphsize(char *s)
	{
		char *p;
		int n;

		if (s[0] == ':') p = s+1;
		else             p = s;
		n = *p++ - BIAS6;

		if (n > SMALLN)	{
			n = *p++ - BIAS6;
			n = (n << 6) | (*p++ - BIAS6);
			n = (n << 6) | (*p++ - BIAS6);
		}
		return n;
	}

	/**
	 * Convert string in graph6 format to graph.
	 */
	static void	stringtograph(char *s, Graph &G)
	{
		int n = graphsize(s), x = 0;

		char *p = s + 1;
		if (n > SMALLN) p += 3;

		vector<node> vertices(n);
		for(int i = 0; i < n; ++i) {
			vertices[i] = G.newNode(i);
		}

		int k = 1;
		for (int j = 1; j < n; ++j) {
			for (int i = 0; i < j; ++i) {
				if (--k == 0) {
					k = 6;
					x = *(p++) - BIAS6;
				}

				if (x & TOPBIT6) {
					G.newEdge(vertices[i], vertices[j]);
				}
				x <<= 1;
			}
		}
	}

public:

	/**
	 * Locks cin!
	 */
	bool get(Graph &G)
	{
		string s;
		unique_lock<mutex> lock(cin_mtx);
		bool r = getline(cin, s);
		updateOnGraphRetrieval();
		lock.unlock();

		if (r) {
			char *cp = (char*) s.c_str();
			stringtograph(cp, G);
		}

		return r;
	}
};

class RandomGraphSource : public AbstractGraphSource
{
	int nodes, minEdges, maxEdges;

public:
	RandomGraphSource(int nodes, int minE, int maxE)
		: nodes(nodes), minEdges(minE), maxEdges(maxE) {}

	/**
	 * OGDF's solution is probably biased... TODO
	 * http://stackoverflow.com/a/14618505/247532
	 */
	bool get(Graph &G)
	{
		int edges = randomNumber(minEdges, maxEdges);
		randomSimpleGraph(G, nodes, edges);
		List<edge> added;
		makeConnected(G, added);
		updateOnGraphRetrieval();
		return true;
	}
};

/* Test runner */

class TestRunner
{
	unique_ptr<AbstractGraphSource> graphs;

protected:
	mutex errorOutputMutex;
	bool errorFound = false;

	int minComponents, maxComponents,
		cutSizeBound;

	void reportProblem(const Graph &G, const set<set<int>> &AmB, const set<set<int>> &BmA)
	{
		unique_lock<mutex> lock(errorOutputMutex, defer_lock);
		if (errorFound || !lock.try_lock()) {
			// Somebody is already reporting a problem
			return;
		}
		errorFound = true;

		cout << "\nmincuts / bf:" << endl;
		for (const set<int> &c : AmB) {
			cout << c << endl;
		}

		cout << "bf / mincuts:" << endl;
		for (const set<int> &c : BmA) {
			cout << c << endl;
		}

		ofstream fGraph("tmp/tester_in.csv");
		if (!fGraph.is_open()) {
			cerr << "tmp/tester_in.csv could not be opened" << endl;
			exit(3);
		}
		graph2csv(G, fGraph);
		cout << "Input graph written to tmp/tester_in.csv" << endl;
	}

	bool testGraph(Graph &G)
	{
		// run circuitcocircuit and bfc
		List<bond> bonds;
		CircuitCocircuit alg(G, cutSizeBound);
		for (int i = minComponents; i <= maxComponents; ++i) {
			alg.run(i, bonds);
		}

		List<List<edge>> bf_bonds;
		bruteforceGraphBonds(G, cutSizeBound, minComponents, maxComponents,
				bf_bonds);

		set<set<int>> A, B, AmB, BmA;
		for(const bond &b : bonds) {
			set<int> si;
			for (edge e : b.edges) si.insert(e->index());
			A.insert(si);
		}

		for(const List<edge> &le : bf_bonds) {
			set<int> si;
			for (edge e : le) si.insert(e->index());
			B.insert(si);
		}

		set_difference(A.begin(), A.end(), B.begin(), B.end(),
				inserter(AmB, AmB.end()));
		set_difference(B.begin(), B.end(), A.begin(), A.end(),
				inserter(BmA, BmA.end()));

		if (AmB.empty() && BmA.empty()) {
			return true;
		} else {
			reportProblem(G, AmB, BmA);
			return false;
		}
	}

public:
	TestRunner(int minC, int maxC, int cutSizeB, unique_ptr<AbstractGraphSource> graphs)
		: graphs(move(graphs)), minComponents(minC), maxComponents(maxC), cutSizeBound(cutSizeB)
	{ }

	virtual void run() final
	{
		while(!errorFound) {
			Graph G;

			// Exhausted input?
			if (!graphs->get(G)) {
				break;
			}

			// Problem found on G?
			if (!testGraph(G)) {
				break;
			}
		}
	}
};

/* --- */

void printUsage(char *name)
{
	cerr << "Usage:\t" << name << " <cut size bound> <# of components> " \
		<< "\n\t\t[-r, --randomized <# of nodes> <min>-<max edges>] [-tN]\n\n";

	cerr << "\tThis program tests CircuitCocircuit implementation.\n" \
		<< "\tExpects graphs in nauty's graph6 format on stdin.\n\n" \

		<< "\tFirst two arguments are used for any graph being tested.\n" \
		<< "\t<# of components> can be exact or range (e.g. 2-3)\n" \
		<< "\t-r generate random graphs (won't use stdin input)\n" \
		<< "\t<max edges> is not strict (if the random graph is " \
		<< "disconnected\n\t\tthen we add edges to connect it)\n" \
		<< "\t-tN use N threads (by default N == 2)\n";
}

int main(int argc, char *argv[])
{
	if (argc < 3 || argc == 5 || argc > 7) {
		printUsage(argv[0]);
		exit(1);
	}

	// Number of components and cut size bound settings
	int minComponents, maxComponents, cutSizeBound;
	try {
		cutSizeBound = stoi(argv[1]);

		// # of components
		string secondArg(argv[2]);
		size_t hyphenPos = secondArg.find('-');
		if (hyphenPos == string::npos) {
			minComponents = maxComponents = stoi(argv[2]);
		} else {
			minComponents = stoi(secondArg.substr(0, hyphenPos));
			maxComponents = stoi(secondArg.substr(hyphenPos + 1));
		}

		if (maxComponents < minComponents) {
			throw invalid_argument("max components < min components");
		}
	} catch(invalid_argument &_) { // stoi failed
		printUsage(argv[0]);
		exit(2);
	}

	// Graph source settings
	unique_ptr<AbstractGraphSource> source;

	if (argc == 3 || (argv[3] != string("-r") && argv[3] != string("--randomized"))) {
		source = unique_ptr<StdinGraphSource>(new StdinGraphSource());
	} else {
		// Configure randomized testing
		int nodes, minEdges, maxEdges;
		try {
			size_t hyphenPos;

			// # of nodes
			nodes = stoi(argv[4]);

			// min-max edges
			string fifthArg(argv[5]);
			hyphenPos = fifthArg.find('-');
			if (hyphenPos == string::npos) {
				throw invalid_argument("Number of edges is not range.");
			}
			minEdges = stoi(fifthArg.substr(0, hyphenPos));
			maxEdges = stoi(fifthArg.substr(hyphenPos + 1));

			if (maxEdges < minEdges) {
				throw invalid_argument("max edges < min edges");
			}

		} catch(invalid_argument &_) { // stoi failed
			printUsage(argv[0]);
			exit(2);
		}

		source = unique_ptr<RandomGraphSource>(new RandomGraphSource(nodes, minEdges, maxEdges));
	}

	// Parallelization settings
	int nThreads = 2;
	string lastArg(argv[argc - 1]);
	if (lastArg.substr(0, 2) == "-t") {
		nThreads = stoi(lastArg.substr(2));
	}

	// Run tester in parallel
	try {
		TestRunner testrunner(minComponents, maxComponents, cutSizeBound, move(source));

		vector<thread> threads(nThreads);
		for (int i = 0; i < nThreads; ++i) {
			threads[i] = thread(&TestRunner::run, ref(testrunner));
		}

		for (int i = 0; i < nThreads; ++i) {
			threads[i].join();
		}
	} catch (const exception& e) {
		cerr << e.what() << endl;
		exit(3);
	}

	return 0;
}
<|endoftext|>


<commit_before>#include "lcov.h"

#include <string>
#include <vector>

#include "log/log.h"
#include "config/settingsNode.h"
#include "core/task.h"

#include "pluginUtils.h"
#include "configValue.h"
#include "executePlugin.h"

using std::string;
using std::vector;

using execHelper::config::SettingsNode;
using execHelper::core::Options;
using execHelper::core::Task;
using execHelper::core::Command;
using execHelper::core::TaskCollection;
using execHelper::core::PatternCombinations;

using execHelper::plugins::replacePatternCombinations;
using execHelper::plugins::registerTask;

namespace {
    const string lcovBinary("lcov");
    const string baseDirectoryOption("--base-directory");
    const string directoryOption("--directory");

    void runTask(const Task& task, const Options& options, const PatternCombinations& combination) {
        replacePatternCombinations(task, combination);
        registerTask(task, options);
    }
}

namespace execHelper { namespace plugins {
    bool Lcov::apply(const Command& command, Task& task, const Options& options) const noexcept {
        const string lcovConfigKey("lcov");

        const SettingsNode& rootSettings = options.getSettings(lcovConfigKey);

        static string runCommandConfigKey("run-command");
        boost::optional<string> runCommandValue = ConfigValue<string>::getSetting(runCommandConfigKey, command, rootSettings);
        if(runCommandValue == boost::none) {
            user_feedback_error("Could not find the '" << runCommandConfigKey << "' setting for command '" << command << "' in the '" << lcovConfigKey << "' settings");
            return false;
        }
        const string runCommand = runCommandValue.get();

        const string infoFile = ConfigValue<string>::get("info-file", "lcov-plugin.info", command, rootSettings);
        const string baseDirectory = ConfigValue<string>::get("base-directory", ".", command, rootSettings);
        const string directory = ConfigValue<string>::get("directory", ".", command, rootSettings);
        const TaskCollection commandLine = ConfigValue<TaskCollection>::get("command-line", {}, command, rootSettings);

        Task zeroCountersTask = task;
        const bool zeroCounters = generateZeroCountersTask(command, rootSettings, baseDirectory, directory, commandLine, zeroCountersTask);

        Task genHtmlTask = task;
        const bool genHtml = generateGenHtmlTask(command, rootSettings, infoFile, genHtmlTask);

        Task captureTask = task;
        generateCaptureTask(baseDirectory, directory, infoFile, commandLine, captureTask);

        Task excludeTask = task;
        bool exclude = generateExcludeTask(command, rootSettings, infoFile, commandLine, excludeTask);

        for(const auto& combination : makePatternPermutator(command, rootSettings, options)) {
            if(zeroCounters) {
                runTask(zeroCountersTask, options, combination);
            }

            ExecutePlugin execute({runCommand});
            if(! execute.apply(command, task, options)) {
                return false;
            }

            runTask(captureTask, options, combination);
            if(exclude) {
                runTask(excludeTask, options, combination);
            }
            if(genHtml) {
                runTask(genHtmlTask, options, combination);
            }
        }
        return true;
    }

    inline bool Lcov::generateGenHtmlTask(const Command& command, const SettingsNode& rootSettings, const string& infoFile, Task& task) noexcept {
        const string genHtmlOutput = ConfigValue<string>::get("gen-html-output", ".", command, rootSettings);
        const string genHtmlTitle = ConfigValue<string>::get("gen-html-title", "Hello", command, rootSettings);
        const TaskCollection genHtmlCommandLine = ConfigValue<TaskCollection>::get("gen-html-command-line", {}, command, rootSettings);

        const string genHtmlValue = ConfigValue<string>::get("gen-html", "no", command, rootSettings);
        if(genHtmlValue == "yes") {
            task.append(TaskCollection({"genhtml", "--output-directory", genHtmlOutput, "--title", genHtmlTitle, infoFile}));
            task.append(genHtmlCommandLine);
            return true;
        }
        return false;
    }

    inline bool Lcov::generateZeroCountersTask(const Command& command, const SettingsNode& rootSettings, const string& baseDirectory, const string& directory, const TaskCollection& commandLine, Task& task) noexcept {
        const string zeroCountersValue = ConfigValue<string>::get("zero-counters", "no", command, rootSettings);
        if(zeroCountersValue == "yes") {
            task = task;
            task.append(TaskCollection({lcovBinary, baseDirectoryOption, baseDirectory, directoryOption, directory, "--zerocounters"}));
            task.append(commandLine);
            return true;
        }
        return false;
    }

    inline TaskCollection Lcov::getExcludes(const Command& command, const SettingsNode& rootSettings) noexcept {
        TaskCollection excludes = ConfigValue<TaskCollection>::get("excludes", {}, command, rootSettings);
        for(auto& exclude : excludes) {
            exclude = '"' + exclude + '"';
        }
        return excludes;
    }

    inline bool Lcov::generateExcludeTask(const Command& command, const SettingsNode& rootSettings, const string& infoFile, const TaskCollection& commandLine, Task& task) noexcept {
        const TaskCollection excludes = getExcludes(command, rootSettings);
        if(excludes.empty()) {
            return false;
        }

        task.append(TaskCollection({lcovBinary}));
        task.append(TaskCollection({"--remove", infoFile}));
        task.append(excludes);
        task.append(TaskCollection({"--output-file", infoFile}));
        task.append(commandLine);
        return true;
    }

    inline void Lcov::generateCaptureTask(const string& baseDirectory, const string& directory, const string& infoFile, const TaskCollection& commandLine, Task& task) noexcept {
        task.append(TaskCollection({lcovBinary, baseDirectoryOption, baseDirectory, directoryOption, directory, "--capture", "--output", infoFile}));
        task.append(commandLine);
    }
} }
<commit_msg>Temporarily added debugging command to lcov to check issues with gitlab<commit_after>#include "lcov.h"

#include <string>
#include <vector>

#include "log/log.h"
#include "config/settingsNode.h"
#include "core/task.h"

#include "pluginUtils.h"
#include "configValue.h"
#include "executePlugin.h"

using std::string;
using std::vector;

using execHelper::config::SettingsNode;
using execHelper::core::Options;
using execHelper::core::Task;
using execHelper::core::Command;
using execHelper::core::TaskCollection;
using execHelper::core::PatternCombinations;

using execHelper::plugins::replacePatternCombinations;
using execHelper::plugins::registerTask;

namespace {
    const string lcovBinary("lcov");
    const string baseDirectoryOption("--base-directory");
    const string directoryOption("--directory");

    void runTask(const Task& task, const Options& options, const PatternCombinations& combination) {
        replacePatternCombinations(task, combination);
        registerTask(task, options);
    }
}

namespace execHelper { namespace plugins {
    bool Lcov::apply(const Command& command, Task& task, const Options& options) const noexcept {
        const string lcovConfigKey("lcov");

        const SettingsNode& rootSettings = options.getSettings(lcovConfigKey);

        static string runCommandConfigKey("run-command");
        boost::optional<string> runCommandValue = ConfigValue<string>::getSetting(runCommandConfigKey, command, rootSettings);
        if(runCommandValue == boost::none) {
            user_feedback_error("Could not find the '" << runCommandConfigKey << "' setting for command '" << command << "' in the '" << lcovConfigKey << "' settings");
            return false;
        }
        const string runCommand = runCommandValue.get();

        const string infoFile = ConfigValue<string>::get("info-file", "lcov-plugin.info", command, rootSettings);
        const string baseDirectory = ConfigValue<string>::get("base-directory", ".", command, rootSettings);
        const string directory = ConfigValue<string>::get("directory", ".", command, rootSettings);
        const TaskCollection commandLine = ConfigValue<TaskCollection>::get("command-line", {}, command, rootSettings);

        Task zeroCountersTask = task;
        const bool zeroCounters = generateZeroCountersTask(command, rootSettings, baseDirectory, directory, commandLine, zeroCountersTask);

        Task genHtmlTask = task;
        const bool genHtml = generateGenHtmlTask(command, rootSettings, infoFile, genHtmlTask);

        Task captureTask = task;
        generateCaptureTask(baseDirectory, directory, infoFile, commandLine, captureTask);

        Task excludeTask = task;
        bool exclude = generateExcludeTask(command, rootSettings, infoFile, commandLine, excludeTask);

        for(const auto& combination : makePatternPermutator(command, rootSettings, options)) {
            if(zeroCounters) {
                runTask(zeroCountersTask, options, combination);
            }

            ExecutePlugin execute({runCommand});
            if(! execute.apply(command, task, options)) {
                return false;
            }

            Task tmpTask({"find", ".", "-name", "*.gcno"});
            registerTask(tmpTask, options);

            runTask(captureTask, options, combination);
            if(exclude) {
                runTask(excludeTask, options, combination);
            }
            if(genHtml) {
                runTask(genHtmlTask, options, combination);
            }
        }
        return true;
    }

    inline bool Lcov::generateGenHtmlTask(const Command& command, const SettingsNode& rootSettings, const string& infoFile, Task& task) noexcept {
        const string genHtmlOutput = ConfigValue<string>::get("gen-html-output", ".", command, rootSettings);
        const string genHtmlTitle = ConfigValue<string>::get("gen-html-title", "Hello", command, rootSettings);
        const TaskCollection genHtmlCommandLine = ConfigValue<TaskCollection>::get("gen-html-command-line", {}, command, rootSettings);

        const string genHtmlValue = ConfigValue<string>::get("gen-html", "no", command, rootSettings);
        if(genHtmlValue == "yes") {
            task.append(TaskCollection({"genhtml", "--output-directory", genHtmlOutput, "--title", genHtmlTitle, infoFile}));
            task.append(genHtmlCommandLine);
            return true;
        }
        return false;
    }

    inline bool Lcov::generateZeroCountersTask(const Command& command, const SettingsNode& rootSettings, const string& baseDirectory, const string& directory, const TaskCollection& commandLine, Task& task) noexcept {
        const string zeroCountersValue = ConfigValue<string>::get("zero-counters", "no", command, rootSettings);
        if(zeroCountersValue == "yes") {
            task = task;
            task.append(TaskCollection({lcovBinary, baseDirectoryOption, baseDirectory, directoryOption, directory, "--zerocounters"}));
            task.append(commandLine);
            return true;
        }
        return false;
    }

    inline TaskCollection Lcov::getExcludes(const Command& command, const SettingsNode& rootSettings) noexcept {
        TaskCollection excludes = ConfigValue<TaskCollection>::get("excludes", {}, command, rootSettings);
        for(auto& exclude : excludes) {
            exclude = '"' + exclude + '"';
        }
        return excludes;
    }

    inline bool Lcov::generateExcludeTask(const Command& command, const SettingsNode& rootSettings, const string& infoFile, const TaskCollection& commandLine, Task& task) noexcept {
        const TaskCollection excludes = getExcludes(command, rootSettings);
        if(excludes.empty()) {
            return false;
        }

        task.append(TaskCollection({lcovBinary}));
        task.append(TaskCollection({"--remove", infoFile}));
        task.append(excludes);
        task.append(TaskCollection({"--output-file", infoFile}));
        task.append(commandLine);
        return true;
    }

    inline void Lcov::generateCaptureTask(const string& baseDirectory, const string& directory, const string& infoFile, const TaskCollection& commandLine, Task& task) noexcept {
        task.append(TaskCollection({lcovBinary, baseDirectoryOption, baseDirectory, directoryOption, directory, "--capture", "--output", infoFile}));
        task.append(commandLine);
    }
} }
<|endoftext|>


<commit_before><commit_msg>ppl: initialize top_grid_<commit_after><|endoftext|>


<commit_before>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     28
#define BUILD_NUMBER      41
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<commit_msg>[Auto-roll] Bump up version to 3.28.42.0<commit_after>// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     28
#define BUILD_NUMBER      42
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<|endoftext|>