<commit_before>/*
 * Copyright 2015 Ricardo Delfin Garcia <ricardo.delfin.garcia@gmail.com>
 *
 * 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 <iostream>
#include <boost/regex.hpp>

#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>

#include <twitcher_actions/GoToLocationAction.h>

#include "twitcher_interpreter/dialog_message.h"

ros::NodeHandle node;
boost::regex goToTweetRegex;
actionlib::SimpleActionClient<twitcher_actions::GoToLocationAction>* client;

void messageReceiver(const twitcher_interpreter::dialog_message::ConstPtr&);

int main(int argc, char* argv[])
{

    goToTweetRegex = boost::regex("(?<=Go to room )l3_([\\d]{3}|414[ab])$",
                                  boost::regex::icase);

    ros::init(argc, argv, "twitcher_interpreter_node");
    node = ros::NodeHandle();

    client = new actionlib::SimpleActionClient<twitcher_actions::GoToLocationAction>(node, "GoToLocation", true);

    client->waitForServer();

    ros::Subscriber subscriber = node.subscribe("dialog", 1000, messageReceiver);

    ros::spin();

    delete client;
}

void messageReceiver(const twitcher_interpreter::dialog_message::ConstPtr& msg)
{
    boost::smatch matchResult;

    std::string message = msg->message;
    boost::match_flag_type flags = boost::match_default;

    /* If regex matches for current tweet, then service request */
    if(boost::regex_search(message, matchResult, goToTweetRegex, flags)) {

        std::string dialogMessage = msg->message;
        twitcher_actions::GoToLocationGoal goal;
        std::string location = "l3_";
        location += matchResult[0];
        goal.location_name = location;

        client->sendGoal(goal);
    }
}<commit_msg>Removed end-of-string character in the go to tweet regex<commit_after>/*
 * Copyright 2015 Ricardo Delfin Garcia <ricardo.delfin.garcia@gmail.com>
 *
 * 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 <iostream>
#include <boost/regex.hpp>

#include <ros/ros.h>
#include <actionlib/client/simple_action_client.h>

#include <twitcher_actions/GoToLocationAction.h>

#include "twitcher_interpreter/dialog_message.h"

ros::NodeHandle node;
boost::regex goToTweetRegex;
actionlib::SimpleActionClient<twitcher_actions::GoToLocationAction>* client;

void messageReceiver(const twitcher_interpreter::dialog_message::ConstPtr&);

int main(int argc, char* argv[])
{

    goToTweetRegex = boost::regex("(?<=Go to room )l3_([\\d]{3}|414[ab])",
                                  boost::regex::icase);

    ros::init(argc, argv, "twitcher_interpreter_node");
    node = ros::NodeHandle();

    client = new actionlib::SimpleActionClient<twitcher_actions::GoToLocationAction>(node, "GoToLocation", true);

    client->waitForServer();

    ros::Subscriber subscriber = node.subscribe("dialog", 1000, messageReceiver);

    ros::spin();

    delete client;
}

void messageReceiver(const twitcher_interpreter::dialog_message::ConstPtr& msg)
{
    boost::smatch matchResult;

    std::string message = msg->message;
    boost::match_flag_type flags = boost::match_default;

    /* If regex matches for current tweet, then service request */
    if(boost::regex_search(message, matchResult, goToTweetRegex, flags)) {

        std::string dialogMessage = msg->message;
        twitcher_actions::GoToLocationGoal goal;
        std::string location = "l3_";
        location += matchResult[0];
        goal.location_name = location;

        client->sendGoal(goal);
    }
}<|endoftext|>


<commit_before>#include "kwm.h"

static CGWindowListOption OsxWindowListOption = kCGWindowListOptionOnScreenOnly |
                                                   kCGWindowListExcludeDesktopElements;

extern std::vector<window_info> WindowLst;
extern ProcessSerialNumber FocusedPSN;
extern AXUIElementRef FocusedWindowRef;
extern window_info FocusedWindow;
extern bool EnableAutoraise;

bool WindowsAreEqual(window_info *Window, window_info *Match)
{
    if(Window->X == Match->X &&
        Window->Y == Match->Y &&
        Window->Width == Match->Width &&
        Window->Height == Match->Height &&
        Window->Name == Match->Name)
            return true;

    return false;
}

bool IsWindowBelowCursor(window_info *Window)
{
    CGEventRef Event = CGEventCreate(NULL);
    CGPoint Cursor = CGEventGetLocation(Event);
    CFRelease(Event);
    if(Cursor.x >= Window->X &&
            Cursor.x <= Window->X + Window->Width &&
            Cursor.y >= Window->Y &&
            Cursor.y <= Window->Y + Window->Height)
        return true;

    return false;
}

void DetectWindowBelowCursor()
{
    WindowLst.clear();

    CFArrayRef OsxWindowLst = CGWindowListCopyWindowInfo(OsxWindowListOption, kCGNullWindowID);
    if(OsxWindowLst)
    {
        CFIndex OsxWindowCount = CFArrayGetCount(OsxWindowLst);
        for(CFIndex WindowIndex = 0; WindowIndex < OsxWindowCount; ++WindowIndex)
        {
            CFDictionaryRef Elem = (CFDictionaryRef)CFArrayGetValueAtIndex(OsxWindowLst, WindowIndex);
            WindowLst.push_back(window_info());
            CFDictionaryApplyFunction(Elem, GetWindowInfo, NULL);
        }
        CFRelease(OsxWindowLst);

        for(int i = 0; i < WindowLst.size(); ++i)
        {
            if(IsWindowBelowCursor(&WindowLst[i]))
            {
                if(!WindowsAreEqual(&FocusedWindow, &WindowLst[i]))
                {
                    SetWindowFocus(&WindowLst[i]);
                }
                break;
            }
        }
    }
}

bool GetExpressionFromShiftDirection(window_info *Window, const std::string &Direction)
{
    int Shift = 0;
    if(Direction == "prev")
        Shift = -1;
    else if(Direction == "next")
        Shift = 1;

    return (GetLayoutIndexOfWindow(Window) == GetLayoutIndexOfWindow(&FocusedWindow) + Shift);
}

void ShiftWindowFocus(const std::string &Direction)
{
    int ScreenIndex = GetDisplayOfWindow(&FocusedWindow)->ID;
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        window_info *Window = ScreenWindowLst[WindowIndex];
        if(GetExpressionFromShiftDirection(Window, Direction))
        {
            SetWindowFocus(Window);
            break;
        }
    }
}

void SetWindowRefFocus(AXUIElementRef WindowRef, window_info *Window)
{
    ProcessSerialNumber NewPSN;
    GetProcessForPID(Window->PID, &NewPSN);

    FocusedPSN = NewPSN;
    FocusedWindow = *Window;

    AXUIElementSetAttributeValue(WindowRef, kAXMainAttribute, kCFBooleanTrue);
    AXUIElementSetAttributeValue(WindowRef, kAXFocusedAttribute, kCFBooleanTrue);
    AXUIElementPerformAction (WindowRef, kAXRaiseAction);

    if(FocusedWindowRef != NULL)
        CFRelease(FocusedWindowRef);

    FocusedWindowRef = WindowRef;
    std::cout << "current space: " << GetSpaceOfWindow(&FocusedWindow) << std::endl;

    if(EnableAutoraise)
        SetFrontProcessWithOptions(&FocusedPSN, kSetFrontProcessFrontWindowOnly);

    std::cout << "Keyboard focus: " << FocusedWindow.PID << std::endl;
}

void SetWindowFocus(window_info *Window)
{
    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        SetWindowRefFocus(WindowRef, Window);
    }
}

void SetWindowDimensions(AXUIElementRef WindowRef, window_info *Window, int X, int Y, int Width, int Height)
{
    if(WindowRef != NULL)
    {
        CGPoint WindowPos = CGPointMake(X, Y);
        CFTypeRef NewWindowPos = (CFTypeRef)AXValueCreate(kAXValueCGPointType, (const void*)&WindowPos);

        CGSize WindowSize = CGSizeMake(Width, Height);
        CFTypeRef NewWindowSize = (CFTypeRef)AXValueCreate(kAXValueCGSizeType, (void*)&WindowSize);

        if(AXUIElementSetAttributeValue(WindowRef, kAXPositionAttribute, NewWindowPos) == kAXErrorSuccess)
        {
            Window->X = WindowPos.x;
            Window->Y = WindowPos.y;
        }

        if(AXUIElementSetAttributeValue(WindowRef, kAXSizeAttribute, NewWindowSize) == kAXErrorSuccess)
        {
            Window->Width = WindowSize.width;
            Window->Height = WindowSize.height;
        }

        if(NewWindowPos != NULL)
            CFRelease(NewWindowPos);
        if(NewWindowSize != NULL)
            CFRelease(NewWindowSize);
    }
}

bool GetWindowRef(window_info *Window, AXUIElementRef *WindowRef)
{
    AXUIElementRef App = AXUIElementCreateApplication(Window->PID);
    CFArrayRef AppWindowLst;
    bool Result = false;

    if(App)
    {
        AXError Error = AXUIElementCopyAttributeValue(App, kAXWindowsAttribute, (CFTypeRef*)&AppWindowLst);
        if(Error == kAXErrorSuccess)
        {
            CFIndex DoNotFree = -1;
            CFIndex AppWindowCount = CFArrayGetCount(AppWindowLst);
            for(CFIndex WindowIndex = 0; WindowIndex < AppWindowCount; ++WindowIndex)
            {
                AXUIElementRef AppWindowRef = (AXUIElementRef)CFArrayGetValueAtIndex(AppWindowLst, WindowIndex);
                if(AppWindowRef != NULL)
                {
                    if(!Result)
                    {
                        AXValueRef Temp;

                        CFStringRef AppWindowTitle;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXTitleAttribute, (CFTypeRef*)&AppWindowTitle);

                        std::string AppWindowName;
                        if(CFStringGetCStringPtr(AppWindowTitle, kCFStringEncodingMacRoman))
                            AppWindowName = CFStringGetCStringPtr(AppWindowTitle, kCFStringEncodingMacRoman);
                        if(AppWindowTitle != NULL)
                            CFRelease(AppWindowTitle);

                        CGSize AppWindowSize;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXSizeAttribute, (CFTypeRef*)&Temp);
                        AXValueGetValue(Temp, kAXValueCGSizeType, &AppWindowSize);
                        if(Temp != NULL)
                            CFRelease(Temp);

                        CGPoint AppWindowPos;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXPositionAttribute, (CFTypeRef*)&Temp);
                        AXValueGetValue(Temp, kAXValueCGPointType, &AppWindowPos);
                        if(Temp != NULL)
                            CFRelease(Temp);

                        if(Window->X == AppWindowPos.x &&
                                Window->Y == AppWindowPos.y &&
                                Window->Width == AppWindowSize.width &&
                                Window->Height == AppWindowSize.height &&
                                Window->Name == AppWindowName)
                        {
                            *WindowRef = AppWindowRef;
                            DoNotFree = WindowIndex;
                            Result = true;
                        }

                    }

                    if(WindowIndex != DoNotFree)
                        CFRelease(AppWindowRef);
                }
            }
        }
        CFRelease(App);
    }

    return Result;
}

// Currently not in use
window_info GetWindowInfoFromRef(AXUIElementRef WindowRef)
{
    window_info Info;
    Info.Name = "invalid";
    if(WindowRef != NULL)
    {

        CFStringRef WindowTitle;
        AXValueRef Temp;
        CGSize WindowSize;
        CGPoint WindowPos;

        AXUIElementCopyAttributeValue(WindowRef, kAXTitleAttribute, (CFTypeRef*)&WindowTitle);
        if(CFStringGetCStringPtr(WindowTitle, kCFStringEncodingMacRoman))
            Info.Name = CFStringGetCStringPtr(WindowTitle, kCFStringEncodingMacRoman);

        if(WindowTitle != NULL)
            CFRelease(WindowTitle);

        AXUIElementCopyAttributeValue(WindowRef, kAXSizeAttribute, (CFTypeRef*)&Temp);
        AXValueGetValue(Temp, kAXValueCGSizeType, &WindowSize);
        if(Temp != NULL)
            CFRelease(Temp);

        AXUIElementCopyAttributeValue(WindowRef, kAXPositionAttribute, (CFTypeRef*)&Temp);
        AXValueGetValue(Temp, kAXValueCGPointType, &WindowPos);
        if(Temp !=NULL)
            CFRelease(Temp);

        Info.X = WindowPos.x;
        Info.Y = WindowPos.y;
        Info.Width = WindowSize.width;
        Info.Height = WindowSize.height;

        return Info;
    }
}

void GetWindowInfo(const void *Key, const void *Value, void *Context)
{
    CFStringRef K = (CFStringRef)Key;
    std::string KeyStr = CFStringGetCStringPtr(K, kCFStringEncodingMacRoman);

    CFTypeID ID = CFGetTypeID(Value);
    if(ID == CFStringGetTypeID())
    {
        CFStringRef V = (CFStringRef)Value;
        if(CFStringGetCStringPtr(V, kCFStringEncodingMacRoman))
        {
            std::string ValueStr = CFStringGetCStringPtr(V, kCFStringEncodingMacRoman);
            if(KeyStr == "kCGWindowName")
                WindowLst[WindowLst.size()-1].Name = ValueStr;
        }
    }
    else if(ID == CFNumberGetTypeID())
    {
        int MyInt;
        CFNumberRef V = (CFNumberRef)Value;
        CFNumberGetValue(V, kCFNumberSInt64Type, &MyInt);
        if(KeyStr == "kCGWindowNumber")
            WindowLst[WindowLst.size()-1].WID = MyInt;
        else if(KeyStr == "kCGWindowOwnerPID")
            WindowLst[WindowLst.size()-1].PID = MyInt;
        else if(KeyStr == "X")
            WindowLst[WindowLst.size()-1].X = MyInt;
        else if(KeyStr == "Y")
            WindowLst[WindowLst.size()-1].Y = MyInt;
        else if(KeyStr == "Width")
            WindowLst[WindowLst.size()-1].Width = MyInt;
        else if(KeyStr == "Height")
            WindowLst[WindowLst.size()-1].Height = MyInt;
    }
    else if(ID == CFDictionaryGetTypeID())
    {
        CFDictionaryRef Elem = (CFDictionaryRef)Value;
        CFDictionaryApplyFunction(Elem, GetWindowInfo, NULL);
    }
}
<commit_msg>removed unused function<commit_after>#include "kwm.h"

static CGWindowListOption OsxWindowListOption = kCGWindowListOptionOnScreenOnly |
                                                   kCGWindowListExcludeDesktopElements;

extern std::vector<window_info> WindowLst;
extern ProcessSerialNumber FocusedPSN;
extern AXUIElementRef FocusedWindowRef;
extern window_info FocusedWindow;
extern bool EnableAutoraise;

bool WindowsAreEqual(window_info *Window, window_info *Match)
{
    if(Window->X == Match->X &&
        Window->Y == Match->Y &&
        Window->Width == Match->Width &&
        Window->Height == Match->Height &&
        Window->Name == Match->Name)
            return true;

    return false;
}

bool IsWindowBelowCursor(window_info *Window)
{
    CGEventRef Event = CGEventCreate(NULL);
    CGPoint Cursor = CGEventGetLocation(Event);
    CFRelease(Event);
    if(Cursor.x >= Window->X &&
            Cursor.x <= Window->X + Window->Width &&
            Cursor.y >= Window->Y &&
            Cursor.y <= Window->Y + Window->Height)
        return true;

    return false;
}

void DetectWindowBelowCursor()
{
    WindowLst.clear();

    CFArrayRef OsxWindowLst = CGWindowListCopyWindowInfo(OsxWindowListOption, kCGNullWindowID);
    if(OsxWindowLst)
    {
        CFIndex OsxWindowCount = CFArrayGetCount(OsxWindowLst);
        for(CFIndex WindowIndex = 0; WindowIndex < OsxWindowCount; ++WindowIndex)
        {
            CFDictionaryRef Elem = (CFDictionaryRef)CFArrayGetValueAtIndex(OsxWindowLst, WindowIndex);
            WindowLst.push_back(window_info());
            CFDictionaryApplyFunction(Elem, GetWindowInfo, NULL);
        }
        CFRelease(OsxWindowLst);

        for(int i = 0; i < WindowLst.size(); ++i)
        {
            if(IsWindowBelowCursor(&WindowLst[i]))
            {
                if(!WindowsAreEqual(&FocusedWindow, &WindowLst[i]))
                {
                    SetWindowFocus(&WindowLst[i]);
                }
                break;
            }
        }
    }
}

bool GetExpressionFromShiftDirection(window_info *Window, const std::string &Direction)
{
    int Shift = 0;
    if(Direction == "prev")
        Shift = -1;
    else if(Direction == "next")
        Shift = 1;

    return (GetLayoutIndexOfWindow(Window) == GetLayoutIndexOfWindow(&FocusedWindow) + Shift);
}

void ShiftWindowFocus(const std::string &Direction)
{
    int ScreenIndex = GetDisplayOfWindow(&FocusedWindow)->ID;
    std::vector<window_info*> ScreenWindowLst = GetAllWindowsOnDisplay(ScreenIndex);
    for(int WindowIndex = 0; WindowIndex < ScreenWindowLst.size(); ++WindowIndex)
    {
        window_info *Window = ScreenWindowLst[WindowIndex];
        if(GetExpressionFromShiftDirection(Window, Direction))
        {
            SetWindowFocus(Window);
            break;
        }
    }
}

void SetWindowRefFocus(AXUIElementRef WindowRef, window_info *Window)
{
    ProcessSerialNumber NewPSN;
    GetProcessForPID(Window->PID, &NewPSN);

    FocusedPSN = NewPSN;
    FocusedWindow = *Window;

    AXUIElementSetAttributeValue(WindowRef, kAXMainAttribute, kCFBooleanTrue);
    AXUIElementSetAttributeValue(WindowRef, kAXFocusedAttribute, kCFBooleanTrue);
    AXUIElementPerformAction (WindowRef, kAXRaiseAction);

    if(FocusedWindowRef != NULL)
        CFRelease(FocusedWindowRef);

    FocusedWindowRef = WindowRef;
    std::cout << "current space: " << GetSpaceOfWindow(&FocusedWindow) << std::endl;

    if(EnableAutoraise)
        SetFrontProcessWithOptions(&FocusedPSN, kSetFrontProcessFrontWindowOnly);

    std::cout << "Keyboard focus: " << FocusedWindow.PID << std::endl;
}

void SetWindowFocus(window_info *Window)
{
    AXUIElementRef WindowRef;
    if(GetWindowRef(Window, &WindowRef))
    {
        SetWindowRefFocus(WindowRef, Window);
    }
}

void SetWindowDimensions(AXUIElementRef WindowRef, window_info *Window, int X, int Y, int Width, int Height)
{
    if(WindowRef != NULL)
    {
        CGPoint WindowPos = CGPointMake(X, Y);
        CFTypeRef NewWindowPos = (CFTypeRef)AXValueCreate(kAXValueCGPointType, (const void*)&WindowPos);

        CGSize WindowSize = CGSizeMake(Width, Height);
        CFTypeRef NewWindowSize = (CFTypeRef)AXValueCreate(kAXValueCGSizeType, (void*)&WindowSize);

        if(AXUIElementSetAttributeValue(WindowRef, kAXPositionAttribute, NewWindowPos) == kAXErrorSuccess)
        {
            Window->X = WindowPos.x;
            Window->Y = WindowPos.y;
        }

        if(AXUIElementSetAttributeValue(WindowRef, kAXSizeAttribute, NewWindowSize) == kAXErrorSuccess)
        {
            Window->Width = WindowSize.width;
            Window->Height = WindowSize.height;
        }

        if(NewWindowPos != NULL)
            CFRelease(NewWindowPos);
        if(NewWindowSize != NULL)
            CFRelease(NewWindowSize);
    }
}

bool GetWindowRef(window_info *Window, AXUIElementRef *WindowRef)
{
    AXUIElementRef App = AXUIElementCreateApplication(Window->PID);
    CFArrayRef AppWindowLst;
    bool Result = false;

    if(App)
    {
        AXError Error = AXUIElementCopyAttributeValue(App, kAXWindowsAttribute, (CFTypeRef*)&AppWindowLst);
        if(Error == kAXErrorSuccess)
        {
            CFIndex DoNotFree = -1;
            CFIndex AppWindowCount = CFArrayGetCount(AppWindowLst);
            for(CFIndex WindowIndex = 0; WindowIndex < AppWindowCount; ++WindowIndex)
            {
                AXUIElementRef AppWindowRef = (AXUIElementRef)CFArrayGetValueAtIndex(AppWindowLst, WindowIndex);
                if(AppWindowRef != NULL)
                {
                    if(!Result)
                    {
                        AXValueRef Temp;

                        CFStringRef AppWindowTitle;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXTitleAttribute, (CFTypeRef*)&AppWindowTitle);

                        std::string AppWindowName;
                        if(CFStringGetCStringPtr(AppWindowTitle, kCFStringEncodingMacRoman))
                            AppWindowName = CFStringGetCStringPtr(AppWindowTitle, kCFStringEncodingMacRoman);
                        if(AppWindowTitle != NULL)
                            CFRelease(AppWindowTitle);

                        CGSize AppWindowSize;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXSizeAttribute, (CFTypeRef*)&Temp);
                        AXValueGetValue(Temp, kAXValueCGSizeType, &AppWindowSize);
                        if(Temp != NULL)
                            CFRelease(Temp);

                        CGPoint AppWindowPos;
                        AXUIElementCopyAttributeValue(AppWindowRef, kAXPositionAttribute, (CFTypeRef*)&Temp);
                        AXValueGetValue(Temp, kAXValueCGPointType, &AppWindowPos);
                        if(Temp != NULL)
                            CFRelease(Temp);

                        if(Window->X == AppWindowPos.x &&
                                Window->Y == AppWindowPos.y &&
                                Window->Width == AppWindowSize.width &&
                                Window->Height == AppWindowSize.height &&
                                Window->Name == AppWindowName)
                        {
                            *WindowRef = AppWindowRef;
                            DoNotFree = WindowIndex;
                            Result = true;
                        }

                    }

                    if(WindowIndex != DoNotFree)
                        CFRelease(AppWindowRef);
                }
            }
        }
        CFRelease(App);
    }

    return Result;
}

void GetWindowInfo(const void *Key, const void *Value, void *Context)
{
    CFStringRef K = (CFStringRef)Key;
    std::string KeyStr = CFStringGetCStringPtr(K, kCFStringEncodingMacRoman);

    CFTypeID ID = CFGetTypeID(Value);
    if(ID == CFStringGetTypeID())
    {
        CFStringRef V = (CFStringRef)Value;
        if(CFStringGetCStringPtr(V, kCFStringEncodingMacRoman))
        {
            std::string ValueStr = CFStringGetCStringPtr(V, kCFStringEncodingMacRoman);
            if(KeyStr == "kCGWindowName")
                WindowLst[WindowLst.size()-1].Name = ValueStr;
        }
    }
    else if(ID == CFNumberGetTypeID())
    {
        int MyInt;
        CFNumberRef V = (CFNumberRef)Value;
        CFNumberGetValue(V, kCFNumberSInt64Type, &MyInt);
        if(KeyStr == "kCGWindowNumber")
            WindowLst[WindowLst.size()-1].WID = MyInt;
        else if(KeyStr == "kCGWindowOwnerPID")
            WindowLst[WindowLst.size()-1].PID = MyInt;
        else if(KeyStr == "X")
            WindowLst[WindowLst.size()-1].X = MyInt;
        else if(KeyStr == "Y")
            WindowLst[WindowLst.size()-1].Y = MyInt;
        else if(KeyStr == "Width")
            WindowLst[WindowLst.size()-1].Width = MyInt;
        else if(KeyStr == "Height")
            WindowLst[WindowLst.size()-1].Height = MyInt;
    }
    else if(ID == CFDictionaryGetTypeID())
    {
        CFDictionaryRef Elem = (CFDictionaryRef)Value;
        CFDictionaryApplyFunction(Elem, GetWindowInfo, NULL);
    }
}
<|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "TrackingSystem.h"
#include "TrackedBody.h"
#include "TrackedBodyTarget.h"
#include "UndistortMeasurements.h"
#include "ForEachTracked.h"
#include "TrackingSystem_Impl.h"
#include "SBDBlobExtractor.h"
#include "RoomCalibration.h"

// Library/third-party includes
#include <boost/assert.hpp>

#include <util/Stride.h>

// Standard includes
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>
#include <stdexcept>

namespace osvr {
namespace vbtracker {

    TrackingSystem::TrackingSystem(ConfigParams const &params)
        : m_params(params), m_impl(new Impl(params)) {}

    TrackingSystem::~TrackingSystem() {}

    TrackedBody *TrackingSystem::createTrackedBody() {
        auto newId = BodyId(static_cast<BodyId::wrapped_type>(m_bodies.size()));
        BodyPtr newBody(new TrackedBody(*this, newId));
        m_bodies.emplace_back(std::move(newBody));
        return m_bodies.back().get();
    }

    TrackedBodyTarget *TrackingSystem::getTarget(BodyTargetId target) {
        return getBody(target.first).getTarget(target.second);
    }

    ImageOutputDataPtr TrackingSystem::performInitialImageProcessing(
        util::time::TimeValue const &tv, cv::Mat const &frame,
        cv::Mat const &frameGray, CameraParameters const &camParams) {

        ImageOutputDataPtr ret(new ImageProcessingOutput);
        ret->tv = tv;
        ret->frame = frame;
        ret->frameGray = frameGray;
        ret->camParams = camParams.createUndistortedVariant();
        auto rawMeasurements =
            m_impl->blobExtractor->extractBlobs(ret->frameGray);
        ret->ledMeasurements = undistortLeds(rawMeasurements, camParams);
        return ret;
    }

    LedUpdateCount const &
    TrackingSystem::updateLedsFromVideoData(ImageOutputDataPtr &&imageData) {
        /// Clear internal data, we're invalidating things here.
        m_updated.clear();
        auto &updateCount = m_impl->updateCount;
        updateCount.clear();

        /// Update our frame cache, since we're taking ownership of the image
        /// data now.
        m_impl->frame = imageData->frame;
        m_impl->frameGray = imageData->frameGray;
        m_impl->camParams = imageData->camParams;
        m_impl->lastFrame = imageData->tv;

        /// Go through each target and try to process the measurements.
        forEachTarget(*this, [&](TrackedBodyTarget &target) {
            auto usedMeasurements =
                target.processLedMeasurements(imageData->ledMeasurements);
            if (usedMeasurements != 0) {
                updateCount[target.getQualifiedId()] = usedMeasurements;
            }
        });
        return updateCount;
    }

    BodyIndices const &
    TrackingSystem::updateBodiesFromVideoData(ImageOutputDataPtr &&imageData) {
        /// Do the second phase of stuff
        updateLedsFromVideoData(std::move(imageData));

        /// Do the third phase of tracking.
        updatePoseEstimates();

        /// Trigger debug display, if activated.
        m_impl->triggerDebugDisplay(*this);

        return m_updated;
    }
    inline void
    validateTargetPointerFromUpdateList(TrackedBodyTarget *targetPtr) {

        BOOST_ASSERT_MSG(targetPtr != nullptr, "We should never be "
                                               "retrieving a nullptr for a "
                                               "target with measurements!");
        if (!targetPtr) {
            throw std::logic_error("Logical impossibility: Couldn't "
                                   "retrieve a valid pointer for a target "
                                   "that we were just told updated its "
                                   "LEDs from data this frame.");
        }
    }
    void TrackingSystem::updatePoseEstimates() {
        if (!isRoomCalibrationComplete()) {
            /// If we need calibration, we need calibration. Go get it done.
            calibrationVideoPhaseThree();
            return;
        }

        auto const &updateCount = m_impl->updateCount;
        for (auto &bodyTargetWithMeasurements : updateCount) {
            auto targetPtr = getTarget(bodyTargetWithMeasurements.first);
            validateTargetPointerFromUpdateList(targetPtr);
            auto &target = *targetPtr;

            /// @todo right now assumes one target per body here!
            auto &body = target.getBody();
            util::time::TimeValue stateTime = {};
            BodyState state;
            auto newTime = m_impl->lastFrame;
            auto validState =
                body.getStateAtOrBefore(newTime, stateTime, state);
            auto initialTime = stateTime;

            auto gotPose = target.updatePoseEstimateFromLeds(
                m_impl->camParams, newTime, state, stateTime, validState);
            if (gotPose) {
                body.replaceStateSnapshot(initialTime, newTime, state);
#if 0
                static auto s = ::util::Stride{101};
                if (++s) {
                    std::cout << body.getState().position().transpose() << "\n";
                }
#endif
                /// @todo deduplicate in making this list.
                m_updated.push_back(body.getId());
            }
        }
        /// Prune history after video update.
        for (auto &body : m_bodies) {
            body->pruneHistory();
        }
    }

    void TrackingSystem::calibrationVideoPhaseThree() {
        auto const &updateCount = m_impl->updateCount;
        for (auto &bodyTargetWithMeasurements : updateCount) {
            auto &bodyTargetId = bodyTargetWithMeasurements.first;
            if (!m_impl->calib.wantVideoData(*this, bodyTargetId)) {
                // If the room calibrator doesn't want video tracking data from
                // this target, then move along.
                continue;
            }
            auto targetPtr = getTarget(bodyTargetId);
            validateTargetPointerFromUpdateList(targetPtr);
            auto &target = *targetPtr;
            Eigen::Vector3d xlate;
            Eigen::Quaterniond quat;
            auto gotPose = target.uncalibratedRANSACPoseEstimateFromLeds(
                m_impl->camParams, xlate, quat);
            if (gotPose) {
                m_impl->calib.processVideoData(*this, bodyTargetId,
                                               m_impl->lastFrame, xlate, quat);
            }
        }

        m_impl->calib.postCalibrationUpdate(*this);
    }

    void
    TrackingSystem::calibrationHandleIMUData(BodyId id,
                                             util::time::TimeValue const &tv,
                                             Eigen::Quaterniond const &quat) {
        m_impl->calib.processIMUData(*this, id, tv, quat);
        m_impl->calib.postCalibrationUpdate(*this);
    }

    void TrackingSystem::setCameraPose(Eigen::Isometry3d const &camPose) {
        m_impl->haveCameraPose = true;
        m_impl->cameraPose = camPose;
        m_impl->cameraPoseInv = camPose.inverse();
    }

    bool TrackingSystem::haveCameraPose() const {
        return m_impl->haveCameraPose;
    }

    Eigen::Isometry3d const &TrackingSystem::getCameraPose() const {
        return m_impl->cameraPose;
    }

    Eigen::Isometry3d const &TrackingSystem::getRoomToCamera() const {
        return m_impl->cameraPoseInv;
    }

    bool TrackingSystem::isRoomCalibrationComplete() {
        /// @todo should just be able to do this by checking the state of the
        /// calibrator.

        /// If this is true, we know it's true. If it's false, we must go check.
        if (m_impl->roomCalibCompleteCached) {
            return true;
        }
        /// Update the cached value.
        m_impl->roomCalibCompleteCached =
            vbtracker::isRoomCalibrationComplete(*this);
        return m_impl->roomCalibCompleteCached;
    }

} // namespace vbtracker
} // namespace osvr
<commit_msg>Skip brights in room calibration<commit_after>/** @file
    @brief Implementation

    @date 2016

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2016 Sensics, Inc.
//
// 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.

// Internal Includes
#include "TrackingSystem.h"
#include "TrackedBody.h"
#include "TrackedBodyTarget.h"
#include "UndistortMeasurements.h"
#include "ForEachTracked.h"
#include "TrackingSystem_Impl.h"
#include "SBDBlobExtractor.h"
#include "RoomCalibration.h"

// Library/third-party includes
#include <boost/assert.hpp>

#include <util/Stride.h>

// Standard includes
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>
#include <stdexcept>

static const auto ROOM_CALIBRATION_SKIP_BRIGHTS_CUTOFF = 4;

namespace osvr {
namespace vbtracker {

    TrackingSystem::TrackingSystem(ConfigParams const &params)
        : m_params(params), m_impl(new Impl(params)) {}

    TrackingSystem::~TrackingSystem() {}

    TrackedBody *TrackingSystem::createTrackedBody() {
        auto newId = BodyId(static_cast<BodyId::wrapped_type>(m_bodies.size()));
        BodyPtr newBody(new TrackedBody(*this, newId));
        m_bodies.emplace_back(std::move(newBody));
        return m_bodies.back().get();
    }

    TrackedBodyTarget *TrackingSystem::getTarget(BodyTargetId target) {
        return getBody(target.first).getTarget(target.second);
    }

    ImageOutputDataPtr TrackingSystem::performInitialImageProcessing(
        util::time::TimeValue const &tv, cv::Mat const &frame,
        cv::Mat const &frameGray, CameraParameters const &camParams) {

        ImageOutputDataPtr ret(new ImageProcessingOutput);
        ret->tv = tv;
        ret->frame = frame;
        ret->frameGray = frameGray;
        ret->camParams = camParams.createUndistortedVariant();
        auto rawMeasurements =
            m_impl->blobExtractor->extractBlobs(ret->frameGray);
        ret->ledMeasurements = undistortLeds(rawMeasurements, camParams);
        return ret;
    }

    LedUpdateCount const &
    TrackingSystem::updateLedsFromVideoData(ImageOutputDataPtr &&imageData) {
        /// Clear internal data, we're invalidating things here.
        m_updated.clear();
        auto &updateCount = m_impl->updateCount;
        updateCount.clear();

        /// Update our frame cache, since we're taking ownership of the image
        /// data now.
        m_impl->frame = imageData->frame;
        m_impl->frameGray = imageData->frameGray;
        m_impl->camParams = imageData->camParams;
        m_impl->lastFrame = imageData->tv;

        /// Go through each target and try to process the measurements.
        forEachTarget(*this, [&](TrackedBodyTarget &target) {
            auto usedMeasurements =
                target.processLedMeasurements(imageData->ledMeasurements);
            if (usedMeasurements != 0) {
                updateCount[target.getQualifiedId()] = usedMeasurements;
            }
        });
        return updateCount;
    }

    BodyIndices const &
    TrackingSystem::updateBodiesFromVideoData(ImageOutputDataPtr &&imageData) {
        /// Do the second phase of stuff
        updateLedsFromVideoData(std::move(imageData));

        /// Do the third phase of tracking.
        updatePoseEstimates();

        /// Trigger debug display, if activated.
        m_impl->triggerDebugDisplay(*this);

        return m_updated;
    }
    inline void
    validateTargetPointerFromUpdateList(TrackedBodyTarget *targetPtr) {

        BOOST_ASSERT_MSG(targetPtr != nullptr, "We should never be "
                                               "retrieving a nullptr for a "
                                               "target with measurements!");
        if (!targetPtr) {
            throw std::logic_error("Logical impossibility: Couldn't "
                                   "retrieve a valid pointer for a target "
                                   "that we were just told updated its "
                                   "LEDs from data this frame.");
        }
    }
    void TrackingSystem::updatePoseEstimates() {
        if (!isRoomCalibrationComplete()) {
            /// If we need calibration, we need calibration. Go get it done.
            calibrationVideoPhaseThree();
            return;
        }

        auto const &updateCount = m_impl->updateCount;
        for (auto &bodyTargetWithMeasurements : updateCount) {
            auto targetPtr = getTarget(bodyTargetWithMeasurements.first);
            validateTargetPointerFromUpdateList(targetPtr);
            auto &target = *targetPtr;

            /// @todo right now assumes one target per body here!
            auto &body = target.getBody();
            util::time::TimeValue stateTime = {};
            BodyState state;
            auto newTime = m_impl->lastFrame;
            auto validState =
                body.getStateAtOrBefore(newTime, stateTime, state);
            auto initialTime = stateTime;

            auto gotPose = target.updatePoseEstimateFromLeds(
                m_impl->camParams, newTime, state, stateTime, validState);
            if (gotPose) {
                body.replaceStateSnapshot(initialTime, newTime, state);
#if 0
                static auto s = ::util::Stride{101};
                if (++s) {
                    std::cout << body.getState().position().transpose() << "\n";
                }
#endif
                /// @todo deduplicate in making this list.
                m_updated.push_back(body.getId());
            }
        }
        /// Prune history after video update.
        for (auto &body : m_bodies) {
            body->pruneHistory();
        }
    }

    void TrackingSystem::calibrationVideoPhaseThree() {
        auto const &updateCount = m_impl->updateCount;
        for (auto &bodyTargetWithMeasurements : updateCount) {
            auto &bodyTargetId = bodyTargetWithMeasurements.first;
            if (!m_impl->calib.wantVideoData(*this, bodyTargetId)) {
                // If the room calibrator doesn't want video tracking data from
                // this target, then move along.
                continue;
            }
            auto targetPtr = getTarget(bodyTargetId);
            validateTargetPointerFromUpdateList(targetPtr);
            auto &target = *targetPtr;
            Eigen::Vector3d xlate;
            Eigen::Quaterniond quat;
            auto gotPose = target.uncalibratedRANSACPoseEstimateFromLeds(
                m_impl->camParams, xlate, quat,
                ROOM_CALIBRATION_SKIP_BRIGHTS_CUTOFF);
            if (gotPose) {
                m_impl->calib.processVideoData(*this, bodyTargetId,
                                               m_impl->lastFrame, xlate, quat);
            }
        }

        m_impl->calib.postCalibrationUpdate(*this);
    }

    void
    TrackingSystem::calibrationHandleIMUData(BodyId id,
                                             util::time::TimeValue const &tv,
                                             Eigen::Quaterniond const &quat) {
        m_impl->calib.processIMUData(*this, id, tv, quat);
        m_impl->calib.postCalibrationUpdate(*this);
    }

    void TrackingSystem::setCameraPose(Eigen::Isometry3d const &camPose) {
        m_impl->haveCameraPose = true;
        m_impl->cameraPose = camPose;
        m_impl->cameraPoseInv = camPose.inverse();
    }

    bool TrackingSystem::haveCameraPose() const {
        return m_impl->haveCameraPose;
    }

    Eigen::Isometry3d const &TrackingSystem::getCameraPose() const {
        return m_impl->cameraPose;
    }

    Eigen::Isometry3d const &TrackingSystem::getRoomToCamera() const {
        return m_impl->cameraPoseInv;
    }

    bool TrackingSystem::isRoomCalibrationComplete() {
        /// @todo should just be able to do this by checking the state of the
        /// calibrator.

        /// If this is true, we know it's true. If it's false, we must go check.
        if (m_impl->roomCalibCompleteCached) {
            return true;
        }
        /// Update the cached value.
        m_impl->roomCalibCompleteCached =
            vbtracker::isRoomCalibrationComplete(*this);
        return m_impl->roomCalibCompleteCached;
    }

} // namespace vbtracker
} // namespace osvr
<|endoftext|>


<commit_before>/// \file You-QueryEngine/internal/filter.h
/// Defines the base class for filters.
/// \author A0112054Y
#include "stdafx.h"
#include "filter.h"

namespace You {
namespace QueryEngine {

using FFilter = Filter::FFilter;
// Common filters
std::unique_ptr<Filter> Filter::anyTask() {
	auto f = [] (const Task&) -> bool {
		return true;
	};
	return std::unique_ptr<Filter>(new Filter(f));
}

Filter& Filter::operator&&(const Filter& filter) {
	ffilter = AND(ffilter, filter.ffilter);
	return *this;
}

Filter& Filter::operator||(const Filter& filter) {
	ffilter = OR(ffilter, filter.ffilter);
	return *this;
}

Filter& Filter::operator!() {
	ffilter = NOT(ffilter);
	return *this;
}

FFilter Filter::AND(const FFilter& f, const FFilter& g) {
	return [=] (FFilter::argument_type x) {
		return f(x) && g(x);
	};
}

FFilter Filter::OR(const FFilter& f, const FFilter& g) {
	return [=] (FFilter::argument_type x) {
		return f(x) || g(x);
	};
}

FFilter Filter::NOT(const FFilter& f) {
	return [=] (FFilter::argument_type x) {
		return !f(x);
	};
}

}  // namespace QueryEngine
}  // namespace You
<commit_msg>Forgot to implement operator FFilter()<commit_after>/// \file You-QueryEngine/internal/filter.h
/// Defines the base class for filters.
/// \author A0112054Y
#include "stdafx.h"
#include "filter.h"

namespace You {
namespace QueryEngine {

using FFilter = Filter::FFilter;
// Common filters
std::unique_ptr<Filter> Filter::anyTask() {
	auto f = [] (const Task&) -> bool {
		return true;
	};
	return std::unique_ptr<Filter>(new Filter(f));
}

Filter& Filter::operator&&(const Filter& filter) {
	ffilter = AND(ffilter, filter.ffilter);
	return *this;
}

Filter& Filter::operator||(const Filter& filter) {
	ffilter = OR(ffilter, filter.ffilter);
	return *this;
}

Filter& Filter::operator!() {
	ffilter = NOT(ffilter);
	return *this;
}

Filter::operator FFilter() const {
	return ffilter;
}

FFilter Filter::AND(const FFilter& f, const FFilter& g) {
	return [=] (FFilter::argument_type x) {
		return f(x) && g(x);
	};
}

FFilter Filter::OR(const FFilter& f, const FFilter& g) {
	return [=] (FFilter::argument_type x) {
		return f(x) || g(x);
	};
}

FFilter Filter::NOT(const FFilter& f) {
	return [=] (FFilter::argument_type x) {
		return !f(x);
	};
}

}  // namespace QueryEngine
}  // namespace You
<|endoftext|>


<commit_before>/*
 Copyright 2014 Arjan van der Velde, vandervelde.ag [at] gmail

 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.
 */

#pragma once

#include "Exception.hpp"

namespace TwoBit
{

class Region
{ // zero-based, open-ended region
private:
	uint32_t start_;
	uint32_t end_;

public:

	Region(const uint32_t start, const uint32_t end) :
			start_(start), end_(end)
	{
		if (start >= end)
		{
			throw Exception("Region cannot be of zero or negative length.");
		}
	}

	const bool comp(const Region& a, const Region& b) const
	{
		return (a.start_ < b.start_);
	}

	const bool equiv(const Region& a, const Region& b) const
	{
		return (!comp(a, b) && !comp(b, a));
	}

	const bool operator<(const Region& other) const
	{
		return comp(*this, other);
	}

	const bool operator>(const Region& other) const
	{
		return comp(other, *this);
	}

	const bool operator==(const Region& other) const
	{
		return equiv(*this, other);
	}

	const bool overlap(const Region& other) const
	{
		return (other.start_ >= start_ && other.start_ < end_) ||
			(start_ >= other.start_ && start_ < other.end_);
	}

	const uint32_t start() const
	{
		return start_;
	}

	const uint32_t end() const
	{
		return end_;
	}

};

} // namespace TwoBit
<commit_msg>remove dead code.<commit_after><|endoftext|>


<commit_before>// $Id$

/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
 *                  for The ALICE HLT Project.                            *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/** @file   testAliHLTRootSchemaEvolutionComponent.C
    @author Matthias Richter
    @date
    @brief  Test macro/program for the AliHLTRootSchemaEvolutionComponent
 */
int testAliHLTRootSchemaEvolutionComponent(const char* rawfile, int firstevent=0, int lastevent=-1)
{
  AliRawReader* rawreader=AliRawReader::Create(rawfile);
  if (!rawreader) {
    cerr << "error: can not open raw file " << rawfile << endl;
    return -1;
  }

  AliHLTSystem* pHLT=AliHLTPluginBase::GetInstance();
  pHLT->SetGlobalLoggingLevel(kHLTLogAll);
  pHLT->LoadComponentLibraries("libAliHLTUtil.so");

  AliHLTConfiguration publisher("hltout-publisher", "AliHLTOUTPublisher" , NULL, "");
  AliHLTConfiguration esdfilter("esdfilter", "BlockFilter" , "hltout-publisher", "-datatype ALIESDV0 'HLT ' -prescalar 2 -skip-events 3");
  AliHLTConfiguration objfilter("objfilter", "BlockFilter" , "hltout-publisher", "-datatype ROOTTOBJ 'HLT '");
  AliHLTConfiguration streamerinfo("streamerinfo", "ROOTSchemaEvolutionComponent" , "esdfilter objfilter", "");

  pHLT->BuildTaskList("streamerinfo");
  AliHLTOfflineInterface::SetParamsToComponents(NULL, rawreader);

  if (!rawreader->GotoEvent(firstevent)) {
    cerr << "error: can not access event " << firstevent << endl;
    return 0;
  }
  int event=firstevent;
  do {
    pHLT->Run(1,0);
  } while ((++event<=lastevent || lastevent<0) && rawreader->NextEvent());
  pHLT->Run(-1);
}
<commit_msg>attaching file writer to the StreamerInfo component<commit_after>// $Id$

/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
 *                  for The ALICE HLT Project.                            *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/** @file   testAliHLTRootSchemaEvolutionComponent.C
    @author Matthias Richter
    @date
    @brief  Test macro/program for the AliHLTRootSchemaEvolutionComponent
 */
int testAliHLTRootSchemaEvolutionComponent(const char* rawfile, int firstevent=0, int lastevent=-1)
{
  AliRawReader* rawreader=AliRawReader::Create(rawfile);
  if (!rawreader) {
    cerr << "error: can not open raw file " << rawfile << endl;
    return -1;
  }

  AliHLTSystem* pHLT=AliHLTPluginBase::GetInstance();
  pHLT->SetGlobalLoggingLevel(kHLTLogAll);
  pHLT->LoadComponentLibraries("libAliHLTUtil.so");

  AliHLTConfiguration publisher("hltout-publisher", "AliHLTOUTPublisher" , NULL, "");
  AliHLTConfiguration esdfilter("esdfilter", "BlockFilter" , "hltout-publisher", "-datatype ALIESDV0 'HLT ' -prescalar 2 -skip-events 3");
  AliHLTConfiguration objfilter("objfilter", "BlockFilter" , "hltout-publisher", "-datatype ROOTTOBJ 'HLT '");
  AliHLTConfiguration streamerinfo("streamerinfo", "ROOTSchemaEvolutionComponent" , "esdfilter objfilter", "");
  AliHLTConfiguration writer("writer", "FileWriter" , "streamerinfo", "-write-all-events -directory streamerinfo");

  pHLT->BuildTaskList("writer");
  AliHLTOfflineInterface::SetParamsToComponents(NULL, rawreader);

  if (!rawreader->GotoEvent(firstevent)) {
    cerr << "error: can not access event " << firstevent << endl;
    return 0;
  }
  int event=firstevent;
  do {
    pHLT->Run(1,0);
  } while ((++event<=lastevent || lastevent<0) && rawreader->NextEvent());
  pHLT->Run(-1);
}
<|endoftext|>


<commit_before>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/assembler/disassembler_kbc.h"

#include "platform/assert.h"
#include "vm/constants_kbc.h"
#include "vm/cpu.h"
#include "vm/instructions.h"

namespace dart {

static const char* kOpcodeNames[] = {
#define BYTECODE_NAME(name, encoding, kind, op1, op2, op3) #name,
    KERNEL_BYTECODES_LIST(BYTECODE_NAME)
#undef BYTECODE_NAME
};

static const size_t kOpcodeCount =
    sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]);
static_assert(kOpcodeCount <= 256, "Opcode should fit into a byte");

typedef void (*BytecodeFormatter)(char* buffer,
                                  intptr_t size,
                                  KernelBytecode::Opcode opcode,
                                  const KBCInstr* instr);
typedef void (*Fmt)(char** buf,
                    intptr_t* size,
                    const KBCInstr* instr,
                    int32_t value);

template <typename ValueType>
void FormatOperand(char** buf,
                   intptr_t* size,
                   const char* fmt,
                   ValueType value) {
  intptr_t written = Utils::SNPrint(*buf, *size, fmt, value);
  if (written < *size) {
    *buf += written;
    *size += written;
  } else {
    *size = -1;
  }
}

static void Fmt___(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {}

static void Fmttgt(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "-> %" Px, instr + value);
}

static void Fmtlit(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "k%d", value);
}

static void Fmtreg(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "r%d", value);
}

static void Fmtxeg(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  if (value < 0) {
    FormatOperand(buf, size, "FP[%d]", value);
  } else {
    Fmtreg(buf, size, instr, value);
  }
}

static void Fmtnum(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "#%d", value);
}

static void Apply(char** buf,
                  intptr_t* size,
                  const KBCInstr* instr,
                  Fmt fmt,
                  int32_t value,
                  const char* suffix) {
  if (*size <= 0) {
    return;
  }

  fmt(buf, size, instr, value);
  if (*size > 0) {
    FormatOperand(buf, size, "%s", suffix);
  }
}

static void Format0(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {}

static void FormatA(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  Apply(&buf, &size, instr, op1, a, "");
}

static void FormatD(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t bc = KernelBytecode::DecodeD(instr);
  Apply(&buf, &size, instr, op1, bc, "");
}

static void FormatX(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t bc = KernelBytecode::DecodeX(instr);
  Apply(&buf, &size, instr, op1, bc, "");
}

static void FormatT(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t x = KernelBytecode::DecodeT(instr);
  Apply(&buf, &size, instr, op1, x, "");
}

static void FormatA_D(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t bc = KernelBytecode::DecodeD(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, bc, "");
}

static void FormatA_X(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t bc = KernelBytecode::DecodeX(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, bc, "");
}

static void FormatA_E(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t e = KernelBytecode::DecodeE(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, e, "");
}

static void FormatA_Y(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t y = KernelBytecode::DecodeY(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, y, "");
}

static void FormatD_F(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t d = KernelBytecode::DecodeD(instr);
  const int32_t f = KernelBytecode::DecodeF(instr);
  Apply(&buf, &size, instr, op1, d, ", ");
  Apply(&buf, &size, instr, op2, f, "");
}

static void FormatA_B_C(char* buf,
                        intptr_t size,
                        KernelBytecode::Opcode opcode,
                        const KBCInstr* instr,
                        Fmt op1,
                        Fmt op2,
                        Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t b = KernelBytecode::DecodeB(instr);
  const int32_t c = KernelBytecode::DecodeC(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, b, ", ");
  Apply(&buf, &size, instr, op3, c, "");
}

#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3)                \
  static void Format##name(char* buf, intptr_t size,                           \
                           KernelBytecode::Opcode opcode,                      \
                           const KBCInstr* instr) {                            \
    Format##encoding(buf, size, opcode, instr, Fmt##op1, Fmt##op2, Fmt##op3);  \
  }
KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
#undef BYTECODE_FORMATTER

static const BytecodeFormatter kFormatters[] = {
#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3) &Format##name,
    KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
#undef BYTECODE_FORMATTER
};

static intptr_t GetConstantPoolIndex(const KBCInstr* instr) {
  switch (KernelBytecode::DecodeOpcode(instr)) {
    case KernelBytecode::kLoadConstant_Old:
    case KernelBytecode::kInstantiateTypeArgumentsTOS_Old:
    case KernelBytecode::kAssertAssignable_Old:
    case KernelBytecode::kPushConstant_Old:
    case KernelBytecode::kStoreStaticTOS_Old:
    case KernelBytecode::kPushStatic_Old:
    case KernelBytecode::kAllocate_Old:
    case KernelBytecode::kAllocateClosure_Old:
    case KernelBytecode::kInstantiateType_Old:
    case KernelBytecode::kDirectCall_Old:
    case KernelBytecode::kInterfaceCall_Old:
    case KernelBytecode::kUncheckedInterfaceCall_Old:
    case KernelBytecode::kDynamicCall_Old:
      return KernelBytecode::DecodeD(instr);

    case KernelBytecode::kLoadConstant:
    case KernelBytecode::kLoadConstant_Wide:
    case KernelBytecode::kInstantiateTypeArgumentsTOS:
    case KernelBytecode::kInstantiateTypeArgumentsTOS_Wide:
    case KernelBytecode::kAssertAssignable:
    case KernelBytecode::kAssertAssignable_Wide:
      return KernelBytecode::DecodeE(instr);

    case KernelBytecode::kPushConstant:
    case KernelBytecode::kPushConstant_Wide:
    case KernelBytecode::kStoreStaticTOS:
    case KernelBytecode::kStoreStaticTOS_Wide:
    case KernelBytecode::kPushStatic:
    case KernelBytecode::kPushStatic_Wide:
    case KernelBytecode::kAllocate:
    case KernelBytecode::kAllocate_Wide:
    case KernelBytecode::kAllocateClosure:
    case KernelBytecode::kAllocateClosure_Wide:
    case KernelBytecode::kInstantiateType:
    case KernelBytecode::kInstantiateType_Wide:
    case KernelBytecode::kDirectCall:
    case KernelBytecode::kDirectCall_Wide:
    case KernelBytecode::kInterfaceCall:
    case KernelBytecode::kInterfaceCall_Wide:
    case KernelBytecode::kUncheckedInterfaceCall:
    case KernelBytecode::kUncheckedInterfaceCall_Wide:
    case KernelBytecode::kDynamicCall:
    case KernelBytecode::kDynamicCall_Wide:
      return KernelBytecode::DecodeD(instr);

    default:
      return -1;
  }
}

static bool GetLoadedObjectAt(uword pc,
                              const ObjectPool& object_pool,
                              Object* obj) {
  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
  const intptr_t index = GetConstantPoolIndex(instr);
  if (index >= 0) {
    if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
      *obj = object_pool.ObjectAt(index);
      return true;
    }
  }
  return false;
}

void KernelBytecodeDisassembler::DecodeInstruction(char* hex_buffer,
                                                   intptr_t hex_size,
                                                   char* human_buffer,
                                                   intptr_t human_size,
                                                   int* out_instr_size,
                                                   const Bytecode& bytecode,
                                                   Object** object,
                                                   uword pc) {
  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
  const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
  ASSERT(opcode < kOpcodeCount);
  const intptr_t instr_size = KernelBytecode::kInstructionSize[opcode];

  size_t name_size =
      Utils::SNPrint(human_buffer, human_size, "%-10s\t", kOpcodeNames[opcode]);
  human_buffer += name_size;
  human_size -= name_size;
  kFormatters[opcode](human_buffer, human_size, opcode, instr);

  const intptr_t kCharactersPerByte = 3;
  if (hex_size > instr_size * kCharactersPerByte) {
    for (intptr_t i = 0; i < instr_size; ++i) {
      Utils::SNPrint(hex_buffer + (i * kCharactersPerByte),
                     hex_size - (i * kCharactersPerByte), " %02x", instr[i]);
    }
  }
  if (out_instr_size) {
    *out_instr_size = instr_size;
  }

  *object = NULL;
  if (!bytecode.IsNull()) {
    *object = &Object::Handle();
    const ObjectPool& pool = ObjectPool::Handle(bytecode.object_pool());
    if (!GetLoadedObjectAt(pc, pool, *object)) {
      *object = NULL;
    }
  }
}

void KernelBytecodeDisassembler::Disassemble(uword start,
                                             uword end,
                                             DisassemblyFormatter* formatter,
                                             const Bytecode& bytecode) {
#if !defined(PRODUCT)
  ASSERT(formatter != NULL);
  char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
  char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
  uword pc = start;
  GrowableArray<const Function*> inlined_functions;
  GrowableArray<TokenPosition> token_positions;
  while (pc < end) {
    int instruction_length;
    Object* object;
    DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                      sizeof(human_buffer), &instruction_length, bytecode,
                      &object, pc);
    formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                                  sizeof(human_buffer), object, pc);
    pc += instruction_length;
  }
#else
  UNREACHABLE();
#endif
}

void KernelBytecodeDisassembler::Disassemble(const Function& function) {
#if !defined(PRODUCT)
  ASSERT(function.HasBytecode());
  const char* function_fullname = function.ToFullyQualifiedCString();
  Zone* zone = Thread::Current()->zone();
  const Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode());
  THR_Print("Bytecode for function '%s' {\n", function_fullname);
  uword start = bytecode.PayloadStart();
  DisassembleToStdout stdout_formatter;
  LogBlock lb;
  Disassemble(start, start + bytecode.Size(), &stdout_formatter, bytecode);
  THR_Print("}\n");

  const ObjectPool& object_pool =
      ObjectPool::Handle(zone, bytecode.object_pool());
  object_pool.DebugPrint();

  THR_Print("PC Descriptors for function '%s' {\n", function_fullname);
  PcDescriptors::PrintHeaderString();
  const PcDescriptors& descriptors =
      PcDescriptors::Handle(zone, bytecode.pc_descriptors());
  THR_Print("%s}\n", descriptors.ToCString());

  THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
  const ExceptionHandlers& handlers =
      ExceptionHandlers::Handle(zone, bytecode.exception_handlers());
  THR_Print("%s}\n", handlers.ToCString());
#else
  UNREACHABLE();
#endif
}

}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
<commit_msg>[vm/disassembler] Remove redundant assert.<commit_after>// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/globals.h"
#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/compiler/assembler/disassembler_kbc.h"

#include "platform/assert.h"
#include "vm/constants_kbc.h"
#include "vm/cpu.h"
#include "vm/instructions.h"

namespace dart {

static const char* kOpcodeNames[] = {
#define BYTECODE_NAME(name, encoding, kind, op1, op2, op3) #name,
    KERNEL_BYTECODES_LIST(BYTECODE_NAME)
#undef BYTECODE_NAME
};

static const size_t kOpcodeCount =
    sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]);
static_assert(kOpcodeCount <= 256, "Opcode should fit into a byte");

typedef void (*BytecodeFormatter)(char* buffer,
                                  intptr_t size,
                                  KernelBytecode::Opcode opcode,
                                  const KBCInstr* instr);
typedef void (*Fmt)(char** buf,
                    intptr_t* size,
                    const KBCInstr* instr,
                    int32_t value);

template <typename ValueType>
void FormatOperand(char** buf,
                   intptr_t* size,
                   const char* fmt,
                   ValueType value) {
  intptr_t written = Utils::SNPrint(*buf, *size, fmt, value);
  if (written < *size) {
    *buf += written;
    *size += written;
  } else {
    *size = -1;
  }
}

static void Fmt___(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {}

static void Fmttgt(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "-> %" Px, instr + value);
}

static void Fmtlit(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "k%d", value);
}

static void Fmtreg(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "r%d", value);
}

static void Fmtxeg(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  if (value < 0) {
    FormatOperand(buf, size, "FP[%d]", value);
  } else {
    Fmtreg(buf, size, instr, value);
  }
}

static void Fmtnum(char** buf,
                   intptr_t* size,
                   const KBCInstr* instr,
                   int32_t value) {
  FormatOperand(buf, size, "#%d", value);
}

static void Apply(char** buf,
                  intptr_t* size,
                  const KBCInstr* instr,
                  Fmt fmt,
                  int32_t value,
                  const char* suffix) {
  if (*size <= 0) {
    return;
  }

  fmt(buf, size, instr, value);
  if (*size > 0) {
    FormatOperand(buf, size, "%s", suffix);
  }
}

static void Format0(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {}

static void FormatA(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  Apply(&buf, &size, instr, op1, a, "");
}

static void FormatD(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t bc = KernelBytecode::DecodeD(instr);
  Apply(&buf, &size, instr, op1, bc, "");
}

static void FormatX(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t bc = KernelBytecode::DecodeX(instr);
  Apply(&buf, &size, instr, op1, bc, "");
}

static void FormatT(char* buf,
                    intptr_t size,
                    KernelBytecode::Opcode opcode,
                    const KBCInstr* instr,
                    Fmt op1,
                    Fmt op2,
                    Fmt op3) {
  const int32_t x = KernelBytecode::DecodeT(instr);
  Apply(&buf, &size, instr, op1, x, "");
}

static void FormatA_D(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t bc = KernelBytecode::DecodeD(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, bc, "");
}

static void FormatA_X(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t bc = KernelBytecode::DecodeX(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, bc, "");
}

static void FormatA_E(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t e = KernelBytecode::DecodeE(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, e, "");
}

static void FormatA_Y(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t y = KernelBytecode::DecodeY(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, y, "");
}

static void FormatD_F(char* buf,
                      intptr_t size,
                      KernelBytecode::Opcode opcode,
                      const KBCInstr* instr,
                      Fmt op1,
                      Fmt op2,
                      Fmt op3) {
  const int32_t d = KernelBytecode::DecodeD(instr);
  const int32_t f = KernelBytecode::DecodeF(instr);
  Apply(&buf, &size, instr, op1, d, ", ");
  Apply(&buf, &size, instr, op2, f, "");
}

static void FormatA_B_C(char* buf,
                        intptr_t size,
                        KernelBytecode::Opcode opcode,
                        const KBCInstr* instr,
                        Fmt op1,
                        Fmt op2,
                        Fmt op3) {
  const int32_t a = KernelBytecode::DecodeA(instr);
  const int32_t b = KernelBytecode::DecodeB(instr);
  const int32_t c = KernelBytecode::DecodeC(instr);
  Apply(&buf, &size, instr, op1, a, ", ");
  Apply(&buf, &size, instr, op2, b, ", ");
  Apply(&buf, &size, instr, op3, c, "");
}

#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3)                \
  static void Format##name(char* buf, intptr_t size,                           \
                           KernelBytecode::Opcode opcode,                      \
                           const KBCInstr* instr) {                            \
    Format##encoding(buf, size, opcode, instr, Fmt##op1, Fmt##op2, Fmt##op3);  \
  }
KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
#undef BYTECODE_FORMATTER

static const BytecodeFormatter kFormatters[] = {
#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3) &Format##name,
    KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER)
#undef BYTECODE_FORMATTER
};

static intptr_t GetConstantPoolIndex(const KBCInstr* instr) {
  switch (KernelBytecode::DecodeOpcode(instr)) {
    case KernelBytecode::kLoadConstant_Old:
    case KernelBytecode::kInstantiateTypeArgumentsTOS_Old:
    case KernelBytecode::kAssertAssignable_Old:
    case KernelBytecode::kPushConstant_Old:
    case KernelBytecode::kStoreStaticTOS_Old:
    case KernelBytecode::kPushStatic_Old:
    case KernelBytecode::kAllocate_Old:
    case KernelBytecode::kAllocateClosure_Old:
    case KernelBytecode::kInstantiateType_Old:
    case KernelBytecode::kDirectCall_Old:
    case KernelBytecode::kInterfaceCall_Old:
    case KernelBytecode::kUncheckedInterfaceCall_Old:
    case KernelBytecode::kDynamicCall_Old:
      return KernelBytecode::DecodeD(instr);

    case KernelBytecode::kLoadConstant:
    case KernelBytecode::kLoadConstant_Wide:
    case KernelBytecode::kInstantiateTypeArgumentsTOS:
    case KernelBytecode::kInstantiateTypeArgumentsTOS_Wide:
    case KernelBytecode::kAssertAssignable:
    case KernelBytecode::kAssertAssignable_Wide:
      return KernelBytecode::DecodeE(instr);

    case KernelBytecode::kPushConstant:
    case KernelBytecode::kPushConstant_Wide:
    case KernelBytecode::kStoreStaticTOS:
    case KernelBytecode::kStoreStaticTOS_Wide:
    case KernelBytecode::kPushStatic:
    case KernelBytecode::kPushStatic_Wide:
    case KernelBytecode::kAllocate:
    case KernelBytecode::kAllocate_Wide:
    case KernelBytecode::kAllocateClosure:
    case KernelBytecode::kAllocateClosure_Wide:
    case KernelBytecode::kInstantiateType:
    case KernelBytecode::kInstantiateType_Wide:
    case KernelBytecode::kDirectCall:
    case KernelBytecode::kDirectCall_Wide:
    case KernelBytecode::kInterfaceCall:
    case KernelBytecode::kInterfaceCall_Wide:
    case KernelBytecode::kUncheckedInterfaceCall:
    case KernelBytecode::kUncheckedInterfaceCall_Wide:
    case KernelBytecode::kDynamicCall:
    case KernelBytecode::kDynamicCall_Wide:
      return KernelBytecode::DecodeD(instr);

    default:
      return -1;
  }
}

static bool GetLoadedObjectAt(uword pc,
                              const ObjectPool& object_pool,
                              Object* obj) {
  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
  const intptr_t index = GetConstantPoolIndex(instr);
  if (index >= 0) {
    if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
      *obj = object_pool.ObjectAt(index);
      return true;
    }
  }
  return false;
}

void KernelBytecodeDisassembler::DecodeInstruction(char* hex_buffer,
                                                   intptr_t hex_size,
                                                   char* human_buffer,
                                                   intptr_t human_size,
                                                   int* out_instr_size,
                                                   const Bytecode& bytecode,
                                                   Object** object,
                                                   uword pc) {
  const KBCInstr* instr = reinterpret_cast<const KBCInstr*>(pc);
  const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
  const intptr_t instr_size = KernelBytecode::kInstructionSize[opcode];

  size_t name_size =
      Utils::SNPrint(human_buffer, human_size, "%-10s\t", kOpcodeNames[opcode]);
  human_buffer += name_size;
  human_size -= name_size;
  kFormatters[opcode](human_buffer, human_size, opcode, instr);

  const intptr_t kCharactersPerByte = 3;
  if (hex_size > instr_size * kCharactersPerByte) {
    for (intptr_t i = 0; i < instr_size; ++i) {
      Utils::SNPrint(hex_buffer + (i * kCharactersPerByte),
                     hex_size - (i * kCharactersPerByte), " %02x", instr[i]);
    }
  }
  if (out_instr_size) {
    *out_instr_size = instr_size;
  }

  *object = NULL;
  if (!bytecode.IsNull()) {
    *object = &Object::Handle();
    const ObjectPool& pool = ObjectPool::Handle(bytecode.object_pool());
    if (!GetLoadedObjectAt(pc, pool, *object)) {
      *object = NULL;
    }
  }
}

void KernelBytecodeDisassembler::Disassemble(uword start,
                                             uword end,
                                             DisassemblyFormatter* formatter,
                                             const Bytecode& bytecode) {
#if !defined(PRODUCT)
  ASSERT(formatter != NULL);
  char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
  char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
  uword pc = start;
  GrowableArray<const Function*> inlined_functions;
  GrowableArray<TokenPosition> token_positions;
  while (pc < end) {
    int instruction_length;
    Object* object;
    DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                      sizeof(human_buffer), &instruction_length, bytecode,
                      &object, pc);
    formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                                  sizeof(human_buffer), object, pc);
    pc += instruction_length;
  }
#else
  UNREACHABLE();
#endif
}

void KernelBytecodeDisassembler::Disassemble(const Function& function) {
#if !defined(PRODUCT)
  ASSERT(function.HasBytecode());
  const char* function_fullname = function.ToFullyQualifiedCString();
  Zone* zone = Thread::Current()->zone();
  const Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode());
  THR_Print("Bytecode for function '%s' {\n", function_fullname);
  uword start = bytecode.PayloadStart();
  DisassembleToStdout stdout_formatter;
  LogBlock lb;
  Disassemble(start, start + bytecode.Size(), &stdout_formatter, bytecode);
  THR_Print("}\n");

  const ObjectPool& object_pool =
      ObjectPool::Handle(zone, bytecode.object_pool());
  object_pool.DebugPrint();

  THR_Print("PC Descriptors for function '%s' {\n", function_fullname);
  PcDescriptors::PrintHeaderString();
  const PcDescriptors& descriptors =
      PcDescriptors::Handle(zone, bytecode.pc_descriptors());
  THR_Print("%s}\n", descriptors.ToCString());

  THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
  const ExceptionHandlers& handlers =
      ExceptionHandlers::Handle(zone, bytecode.exception_handlers());
  THR_Print("%s}\n", handlers.ToCString());
#else
  UNREACHABLE();
#endif
}

}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
<|endoftext|>