<commit_before>/*
   This file is part of the clazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

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

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "missingtypeinfo.h"
#include "Utils.h"
#include "TemplateUtils.h"
#include "TypeUtils.h"
#include "QtUtils.h"
#include "checkmanager.h"

#include <clang/AST/AST.h>
#include <clang/AST/DeclTemplate.h>

#include <sstream>

using namespace std;
using namespace clang;

MissingTypeinfo::MissingTypeinfo(const std::string &name, const clang::CompilerInstance &ci)
    : CheckBase(name, ci)
{
}

void MissingTypeinfo::VisitDecl(clang::Decl *decl)
{
    // Catches QTypeInfo<Foo> to know type classification
    auto templateDef = dyn_cast<ClassTemplateSpecializationDecl>(decl);
    if (templateDef)
        registerQTypeInfo(templateDef);

    // Catches QList<Foo>
    ClassTemplateSpecializationDecl *tstdecl = TemplateUtils::templateDecl(decl);
    if (!tstdecl)
        return;

    const bool isQList = tstdecl->getName() == "QList";
    const bool isQVector = tstdecl->getName() == "QVector";

    if (!isQList && !isQVector)
        return;

    const TemplateArgumentList &tal = tstdecl->getTemplateArgs();

    if (tal.size() != 1) return;
    QualType qt2 = tal[0].getAsType();

    const Type *t = qt2.getTypePtrOrNull();
    CXXRecordDecl *record = t ? t->getAsCXXRecordDecl() : nullptr;
    if (!record || !record->getDefinition())
        return; // Don't crash if we only have a fwd decl

    const bool isCopyable = qt2.isTriviallyCopyableType(m_ci.getASTContext());
    const bool isTooBigForQList = QtUtils::isTooBigForQList(qt2, m_ci);

    if (isCopyable && (isQVector || (isQList && isTooBigForQList))) {
        if (m_typeInfos.count(record->getQualifiedNameAsString()) != 0)
            return;

        std::string typeName = record->getName();
        if (t->isRecordType() && !ignoreTypeInfo(typeName)) {
            std::string s;
            std::stringstream out;
            out << m_ci.getASTContext().getTypeSize(qt2)/8;
            s = "Missing Q_DECLARE_TYPEINFO: " + typeName;
            emitWarning(decl->getLocStart(), s.c_str());
            emitWarning(record->getLocStart(), "Type declared here:", false);
        }
    }
}

void MissingTypeinfo::registerQTypeInfo(ClassTemplateSpecializationDecl *decl)
{
    if (decl->getName() == "QTypeInfo") {
        auto &args = decl->getTemplateArgs();
        if (args.size() != 1)
            return;

        QualType qt = args[0].getAsType();
        const Type *t = qt.getTypePtrOrNull();
        CXXRecordDecl *recordDecl =  t ? t->getAsCXXRecordDecl() : nullptr;
        if (recordDecl) {
            m_typeInfos.insert(recordDecl->getQualifiedNameAsString());
        }
    }
}

bool MissingTypeinfo::ignoreTypeInfo(const std::string &className) const
{
    std::vector<std::string> primitives {"QPair", "QTime"}; // clazy bug
    return clazy_std::contains(primitives, className);
}

REGISTER_CHECK_WITH_FLAGS("missing-typeinfo", MissingTypeinfo, CheckLevel3)
<commit_msg>missing-type-info: Use TemplateUtils::getTemplateArgumentTypeStr()<commit_after>/*
   This file is part of the clazy static checker.

  Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
  Author: Sérgio Martins <sergio.martins@kdab.com>

  Copyright (C) 2015 Sergio Martins <smartins@kde.org>

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

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

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

#include "missingtypeinfo.h"
#include "Utils.h"
#include "TemplateUtils.h"
#include "TypeUtils.h"
#include "QtUtils.h"
#include "checkmanager.h"

#include <clang/AST/AST.h>
#include <clang/AST/DeclTemplate.h>

#include <sstream>

using namespace std;
using namespace clang;

MissingTypeinfo::MissingTypeinfo(const std::string &name, const clang::CompilerInstance &ci)
    : CheckBase(name, ci)
{
}

void MissingTypeinfo::VisitDecl(clang::Decl *decl)
{
    // Catches QTypeInfo<Foo> to know type classification
    auto templateDef = dyn_cast<ClassTemplateSpecializationDecl>(decl);
    if (templateDef)
        registerQTypeInfo(templateDef);

    // Catches QList<Foo>
    ClassTemplateSpecializationDecl *tstdecl = TemplateUtils::templateDecl(decl);
    if (!tstdecl)
        return;

    const bool isQList = tstdecl->getName() == "QList";
    const bool isQVector = tstdecl->getName() == "QVector";

    if (!isQList && !isQVector)
        return;

    const TemplateArgumentList &tal = tstdecl->getTemplateArgs();

    if (tal.size() != 1) return;
    QualType qt2 = tal[0].getAsType();

    const Type *t = qt2.getTypePtrOrNull();
    CXXRecordDecl *record = t ? t->getAsCXXRecordDecl() : nullptr;
    if (!record || !record->getDefinition())
        return; // Don't crash if we only have a fwd decl

    const bool isCopyable = qt2.isTriviallyCopyableType(m_ci.getASTContext());
    const bool isTooBigForQList = QtUtils::isTooBigForQList(qt2, m_ci);

    if (isCopyable && (isQVector || (isQList && isTooBigForQList))) {
        if (m_typeInfos.count(record->getQualifiedNameAsString()) != 0)
            return;

        std::string typeName = record->getName();
        if (t->isRecordType() && !ignoreTypeInfo(typeName)) {
            std::string s;
            std::stringstream out;
            out << m_ci.getASTContext().getTypeSize(qt2)/8;
            s = "Missing Q_DECLARE_TYPEINFO: " + typeName;
            emitWarning(decl->getLocStart(), s.c_str());
            emitWarning(record->getLocStart(), "Type declared here:", false);
        }
    }
}

void MissingTypeinfo::registerQTypeInfo(ClassTemplateSpecializationDecl *decl)
{
    if (decl->getName() == "QTypeInfo") {
        const string typeName = TemplateUtils::getTemplateArgumentTypeStr(decl, 0, lo(), /**recordOnly=*/true);
        if (!typeName.empty())
            m_typeInfos.insert(typeName);
    }
}

bool MissingTypeinfo::ignoreTypeInfo(const std::string &className) const
{
    std::vector<std::string> primitives {"QPair", "QTime"}; // clazy bug
    return clazy_std::contains(primitives, className);
}

REGISTER_CHECK_WITH_FLAGS("missing-typeinfo", MissingTypeinfo, CheckLevel3)
<|endoftext|>


<commit_before>#include <string>

#include <ros/ros.h>
#include <geometry_msgs/TransformStamped.h>
#include <goal_sender_msgs/ApplyGoals.h>
#include <goal_sender_msgs/GoalSequence.h>
#include <tf2_ros/transform_listener.h>

/**
 * Waypoint update service manager
 */
class WaypointManager
{
public:
  bool operator()(goal_sender_msgs::ApplyGoals::Request& req,
                  goal_sender_msgs::ApplyGoals::Response& res){
    return true;
  }

  goal_sender_msgs::GoalSequence get() const
  {
    return sequence_;
  }

  goal_sender_msgs::GoalSequence operator()() const
  {
    return get();
  }

private:
  goal_sender_msgs::GoalSequence sequence_;
};

/**
 * Tf lookup API
 */
class TfPositionManager
{
public:
  TfPositionManager(tf2_ros::Buffer& tfBuffer)
    : buffer_ {tfBuffer}
  {
  }

  geometry_msgs::TransformStamped operator()(std::string parent, std::string child) const
  {
    return buffer_.lookupTransform(parent, child, ros::Time(0));
  }

private:
  tf2_ros::Buffer& buffer_;
};

class GoalSender
{
public:
  GoalSender(WaypointManager point_manager,
             TfPositionManager lookupper)
    : point_manager_ {point_manager},
      lookupper_ {lookupper}
  {
  }

  void once()
  {
  }

private:
  WaypointManager point_manager_;
  TfPositionManager lookupper_;
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "goal_sender");
  ros::NodeHandle nh {};

  WaypointManager point_manager {};
  ros::ServiceServer srv {
      nh.advertiseService<goal_sender_msgs::ApplyGoals::Request,
                          goal_sender_msgs::ApplyGoals::Response>(
          "apply_goals", point_manager)};

  tf2_ros::Buffer tfBuffer;
  tf2_ros::TransformListener tfListener {tfBuffer};
  TfPositionManager lookupper {tfBuffer};

  GoalSender goal_sender {point_manager, lookupper};
}
<commit_msg>Implement waypoint manager and tf position manager<commit_after>#include <stdexcept>
#include <string>

#include <ros/ros.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/TransformStamped.h>
#include <goal_sender_msgs/ApplyGoals.h>
#include <goal_sender_msgs/GoalSequence.h>
#include <tf2_ros/transform_listener.h>

inline double squaring_distance(const geometry_msgs::Point& a, const geometry_msgs::Point& b) {
  const auto x {a.x - b.x};
  const auto y {a.y - b.y};
  return x*x + y*y;
}

/**
 * Waypoint update service manager
 */
class WaypointManager
{
public:
  bool operator()(goal_sender_msgs::ApplyGoals::Request& req,
                  goal_sender_msgs::ApplyGoals::Response& res){
    return true;
  }

  const geometry_msgs::Point& point() const
  {
    if (is_end()) throw std::logic_error {"range error: Please check is_end() before point()"};
    return now_goal->position;
  }

  double radius() const
  {
    if (is_end()) throw std::logic_error {"range error: Please check is_end() before radius()"};
    return now_goal->radius;
  }

  bool next()
  {
    if (is_end()) throw std::logic_error {"range error: Please check is_end() before next()"}; // wrong way.
    if (++now_goal == sequence_.waypoints.end())
      return false; // correct way: this is last one.
    return true;
  }

  bool is_end() const
  {
    return sequence_.waypoints.end() == now_goal;
  }

  [[deprecated]]
  const goal_sender_msgs::Waypoint& get() const
  {
    if (is_end()) throw std::logic_error {"range error: Please check is_end() before get()"};
    return *now_goal;
  }

private:
  goal_sender_msgs::GoalSequence sequence_;
  decltype(sequence_.waypoints)::iterator now_goal;
};

/**
 * Tf lookup API
 */
class TfPositionManager
{
public:
  TfPositionManager(tf2_ros::Buffer& tfBuffer)
    : buffer_ {tfBuffer}
  {
  }

  geometry_msgs::Point operator()(std::string parent, std::string child) const
  {
    const auto ts {buffer_.lookupTransform(parent, child, ros::Time(0))};
    geometry_msgs::Point point;
    point.x = ts.transform.translation.x;
    point.y = ts.transform.translation.y;
    return point;
  }

private:
  tf2_ros::Buffer& buffer_;
};

class GoalSender
{
public:
  GoalSender(WaypointManager point_manager,
             TfPositionManager lookupper)
    : point_manager_ {point_manager},
      lookupper_ {lookupper}
  {
  }

  void once()
  {
    if (point_manager_.is_end())
      return; // no work
    if (is_reach()) {
      point_manager_.next();
    }
  }

private:
  bool is_reach() const
  {
    const auto robot_point {lookupper_("/map", "/base_link")};
    const auto waypoint_point {point_manager_.point()};
    const auto sqr_distance {squaring_distance(robot_point, waypoint_point)};

    const auto radius {point_manager_.radius()};
    const auto sqr_radius {radius * radius};

    if (sqr_distance < sqr_radius) // into valid range
      return true;
    return false;
  }

  WaypointManager point_manager_;
  TfPositionManager lookupper_;
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "goal_sender");
  ros::NodeHandle nh {};

  WaypointManager point_manager {};
  ros::ServiceServer srv {
      nh.advertiseService<goal_sender_msgs::ApplyGoals::Request,
                          goal_sender_msgs::ApplyGoals::Response>(
          "apply_goals", point_manager)};

  tf2_ros::Buffer tfBuffer;
  tf2_ros::TransformListener tfListener {tfBuffer};
  TfPositionManager lookupper {tfBuffer};

  GoalSender goal_sender {point_manager, lookupper};

  ros::Rate rate {10};
  while (ros::ok()) {
    ros::spinOnce();
    goal_sender.once();
  }
}
<|endoftext|>


<commit_before>#include "DeviceRegistry.h"
#include "register.h"

namespace ZPUino {

    int DeviceRegistry::registerDevice(int slot) {
        if (slot>=MAX_SLOTS)
            return -2;
        if (m_sDeviceRegistry & (1<<slot))
            return -1;
        m_sDeviceRegistry |= (1<<slot);
        return 0;
    }

    uint8_t DeviceRegistry::scanDevice(unsigned vendor, unsigned product, int instance) {
        int i;
        for (i=0;i!=16;i++) {
            unsigned val = REGISTER(SYSCTLBASE,16+i);
            if (val!=0) {
                if (vendor!=VENDOR_ANY) {
                    if (vendor != ((val>>8)&0xff))
                        continue; /* No match */
                }
                if (product!=PRODUCT_ANY) {
                    if (product != (val&0xff))
                        continue; /* No match */
                }
                if (isRegistered(i))
                    --instance; // Must decrement instance even for already-registered devices.
                    continue;

                if (instance=0xff || --instance==0)
                    return i;
            }
        }
        return NO_DEVICE;
    }

    int DeviceRegistry::getPPSInputPin(int masterslot, int offset)
    {
        return getPPSPin(masterslot,offset,16);
    }

    int DeviceRegistry::getPPSOutputPin(int masterslot, int offset)
    {
        return getPPSPin(masterslot,offset,0);
    }

    int DeviceRegistry::getPPSPin(int masterslot, int offset, int shift)
    {
        unsigned count = REGISTER(SYSCTLBASE, 32+shift);
        unsigned start = -1;
        register_t startreg = &REGISTER(SYSCTLBASE, 64);

        while(count--) {
            start++;
            unsigned val = *startreg++;
            unsigned char dev = (val>>shift)&0xff;
            if (dev!=masterslot) {
                continue;
            } else {
                int pin = (val>>(8+shift))&0xff;
                if (offset==0)
                    return start;
                offset--;
            }
        }
        return -1;
    }

    uint32_t DeviceRegistry::m_sDeviceRegistry = 0;
};
<commit_msg>Fixed device scanner.<commit_after>#include "DeviceRegistry.h"
#include "register.h"

namespace ZPUino {

    int DeviceRegistry::registerDevice(int slot) {
        if (slot>=MAX_SLOTS)
            return -2;
        if (m_sDeviceRegistry & (1<<slot))
            return -1;
        m_sDeviceRegistry |= (1<<slot);
        return 0;
    }

    uint8_t DeviceRegistry::scanDevice(unsigned vendor, unsigned product, int instance) {
        int i;
        for (i=0;i!=16;i++) {
            unsigned val = REGISTER(SYSCTLBASE,16+i);
            if (val!=0) {
                if (vendor!=VENDOR_ANY) {
                    if (vendor != ((val>>8)&0xff))
                        continue; /* No match */
                }
                if (product!=PRODUCT_ANY) {
                    if (product != (val&0xff))
                        continue; /* No match */
                }
                if (isRegistered(i))
                {
                    --instance;
                    continue;
                }

                if (instance==0xff || --instance==0)
                    return i;
            }
        }
        return NO_DEVICE;
    }

    int DeviceRegistry::getPPSInputPin(int masterslot, int offset)
    {
        return getPPSPin(masterslot,offset,16);
    }

    int DeviceRegistry::getPPSOutputPin(int masterslot, int offset)
    {
        return getPPSPin(masterslot,offset,0);
    }

    int DeviceRegistry::getPPSPin(int masterslot, int offset, int shift)
    {
        unsigned count = REGISTER(SYSCTLBASE, 32+shift);
        unsigned start = -1;
        register_t startreg = &REGISTER(SYSCTLBASE, 64);

        while(count--) {
            start++;
            unsigned val = *startreg++;
            unsigned char dev = (val>>shift)&0xff;
            if (dev!=masterslot) {
                continue;
            } else {
                int pin = (val>>(8+shift))&0xff;
                if (offset==0)
                    return start;
                offset--;
            }
        }
        return -1;
    }

    uint32_t DeviceRegistry::m_sDeviceRegistry = 0;
};
<|endoftext|>


<commit_before>/*
*
*  Copyright 2013 Mario Alviano, Carmine Dodaro, and Francesco Ricca.
*
*  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 "MyPythonInterpreter.h"
#include <cstring>
using namespace std;
#include "../util/WaspErrorMessage.h"

#ifdef ENABLE_PYTHON

MyPythonInterpreter::MyPythonInterpreter(
    char* filename,
    string scriptDirectory,
    bool callPyFinalize_ ) : Interpreter(), callPyFinalize( callPyFinalize_ )
{
    setenv( "PYTHONPATH", ".", 1 );
    Py_Initialize();
    PyObject* pName =
    #ifdef PYTHON_THREE
        PyUnicode_FromString( filename );
    #else
        PyString_FromString( filename );
    #endif
    if( scriptDirectory != "" )
    {
        string s( "import sys; sys.path.append('" + scriptDirectory + "')" );
        PyRun_SimpleString( s.c_str() );
    }
    pModule = PyImport_Import( pName );
    Py_DECREF( pName );
    if( pModule == NULL )
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        string message = "Module " + string( filename ) + " does not exist.\n";
        WaspErrorMessage::errorGeneric( message );
    }
}

MyPythonInterpreter::~MyPythonInterpreter()
{
    Py_XDECREF( pModule );
    if( callPyFinalize )
        Py_Finalize();
}

void
MyPythonInterpreter::callListMethod(
    const string& method_name,
    const vector< int >& parameters,
    vector< int >& output )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( parameters.size() );
        for( unsigned int i = 0; i < parameters.size(); i++ )
        {
            PyObject* pParam = Py_BuildValue( "i", parameters[ i ] );
            PyTuple_SetItem( pArgs, i, pParam );
        }
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
        {
            bool isInt =
            #ifdef PYTHON_THREE
                PyLong_Check( result );
            #else
                PyInt_Check( result );
            #endif
            if( PyList_Check( result ) )
            {
                int size = PyList_Size( result );
                for( int i = size - 1; i >= 0; i-- )
                {
                    PyObject* item = PyList_GetItem( result, i );
                    bool isInt =
                    #ifdef PYTHON_THREE
                        PyLong_Check( item );
                    #else
                        PyInt_Check( item );
                    #endif
                    if( isInt )
                    {
                        int value =
                        #ifdef PYTHON_THREE
                            PyLong_AsLong( item );
                        #else
                            PyInt_AsLong( item );
                        #endif
                        output.push_back( value );
                    }
                }
                Py_XDECREF( result );
            }
            else if( isInt )
            {
                int value =
                #ifdef PYTHON_THREE
                    PyLong_AsLong( result );
                #else
                    PyInt_AsLong( result );
                #endif
                output.push_back( value );
            }
            else if( PyErr_Occurred() )
                PyErr_Print();
        }
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Method %s not found\n", method_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

void MyPythonInterpreter::callListMethod(
    const string& method_name,
    const vector< int >& parameters,
    vector< uint64_t >& output )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule,method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( parameters.size() );
        for( unsigned int i = 0; i < parameters.size(); i++ )
        {
            PyObject* pParam = Py_BuildValue( "i", parameters[ i ] );
            PyTuple_SetItem( pArgs, i, pParam );
        }
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
        {
            bool isInt = PyLong_Check( result );
            if( PyList_Check( result ) )
            {
                int size = PyList_Size( result );
                for( int i = size - 1; i >= 0; i-- )
                {
                    PyObject* item = PyList_GetItem( result, i );
                    if( PyLong_Check( item ) )
                    {
                        uint64_t value = PyLong_AsUnsignedLongLongMask( item );
                        output.push_back( value );
                    }
                }
                Py_XDECREF( result );
            }
            else if( isInt )
            {
                uint64_t value =
                #ifdef PYTHON_THREE
                    PyLong_AsUnsignedLongLongMask( result );
                #else
                    PyInt_AsUnsignedLongLongMask( result );
                #endif
                output.push_back( value );
            }
            else if( PyErr_Occurred() )
                PyErr_Print();
        }
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf("Method %s not found\n", method_name.c_str());
    }
    Py_XDECREF( pFunc );
}

void MyPythonInterpreter::callVoidMethod(
    const string& method_name,
    int param1,
    const string& param2 )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( 2 );
        PyObject* param1_python =
        #ifdef PYTHON_THREE
            PyLong_FromSize_t( param1 );
        #else
            PyInt_FromSize_t( param1 );
        #endif

        PyObject* param2_python =
        #ifdef PYTHON_THREE
            PyUnicode_FromString( param2.c_str() );
        #else
            PyString_FromString( param2.c_str() );
        #endif

        PyTuple_SetItem( pArgs, 0, param1_python );
        PyTuple_SetItem( pArgs, 1, param2_python );
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
            Py_XDECREF( result );
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Method %s not found\n", method_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

bool MyPythonInterpreter::checkMethod(
    const string& method_name ) const
{
    bool res = false;
    if( pModule == NULL )
        return res;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
       res = true;
    else if( PyErr_Occurred() )
        PyErr_Clear();

    Py_XDECREF( pFunc );
    return res;
}

void MyPythonInterpreter::addElementInMap(
    const string& map_name,
    const string& key,
    unsigned int value )
{
    PyObject* pFunc = PyObject_GetAttrString( pModule, map_name.c_str() );
    if( pFunc )
    {
        PyObject* value_python =
        #ifdef PYTHON_THREE
            PyLong_FromSize_t( value );
        #else
            PyInt_FromSize_t( value );
        #endif

        char *cstr = new char[key.length() + 1];
        strcpy(cstr, key.c_str());
        int res = PyMapping_SetItemString(pFunc, cstr, value_python);
        if( res == -1 || PyErr_Occurred() )
            PyErr_Print();
        delete [] cstr;
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Element %s not found\n", map_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

bool MyPythonInterpreter::checkAttribute(
    const string& map_name ) const
{
    bool res = false;
    if( pModule == NULL )
        return res;
    PyObject* pFunc = PyObject_GetAttrString( pModule, map_name.c_str() );
    if( pFunc )
       res = true;
    else if( PyErr_Occurred() )
        PyErr_Clear();

    Py_XDECREF( pFunc );
    return res;
}

#endif
<commit_msg>Fixed bug of MyPythonInterpreter.<commit_after>/*
*
*  Copyright 2013 Mario Alviano, Carmine Dodaro, and Francesco Ricca.
*
*  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 "MyPythonInterpreter.h"
#include <cstring>
using namespace std;
#include "../util/WaspErrorMessage.h"

#ifdef ENABLE_PYTHON

MyPythonInterpreter::MyPythonInterpreter(
    char* filename,
    string scriptDirectory,
    bool callPyFinalize_ ) : Interpreter(), callPyFinalize( callPyFinalize_ )
{
    setenv( "PYTHONPATH", ".", 1 );
    Py_Initialize();
    PyObject* pName =
    #ifdef PYTHON_THREE
        PyUnicode_FromString( filename );
    #else
        PyString_FromString( filename );
    #endif
    if( scriptDirectory != "" )
    {
        string s( "import sys; sys.path.append('" + scriptDirectory + "')" );
        PyRun_SimpleString( s.c_str() );
    }
    pModule = PyImport_Import( pName );
    Py_DECREF( pName );
    if( pModule == NULL )
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        string message = "Module " + string( filename ) + " does not exist.\n";
        WaspErrorMessage::errorGeneric( message );
    }
}

MyPythonInterpreter::~MyPythonInterpreter()
{
    if( callPyFinalize )
        Py_Finalize();
}

void
MyPythonInterpreter::callListMethod(
    const string& method_name,
    const vector< int >& parameters,
    vector< int >& output )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( parameters.size() );
        for( unsigned int i = 0; i < parameters.size(); i++ )
        {
            PyObject* pParam = Py_BuildValue( "i", parameters[ i ] );
            PyTuple_SetItem( pArgs, i, pParam );
        }
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
        {
            bool isInt =
            #ifdef PYTHON_THREE
                PyLong_Check( result );
            #else
                PyInt_Check( result );
            #endif
            if( PyList_Check( result ) )
            {
                int size = PyList_Size( result );
                for( int i = size - 1; i >= 0; i-- )
                {
                    PyObject* item = PyList_GetItem( result, i );
                    bool isInt =
                    #ifdef PYTHON_THREE
                        PyLong_Check( item );
                    #else
                        PyInt_Check( item );
                    #endif
                    if( isInt )
                    {
                        int value =
                        #ifdef PYTHON_THREE
                            PyLong_AsLong( item );
                        #else
                            PyInt_AsLong( item );
                        #endif
                        output.push_back( value );
                    }
                }
                Py_XDECREF( result );
            }
            else if( isInt )
            {
                int value =
                #ifdef PYTHON_THREE
                    PyLong_AsLong( result );
                #else
                    PyInt_AsLong( result );
                #endif
                output.push_back( value );
            }
            else if( PyErr_Occurred() )
                PyErr_Print();
        }
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Method %s not found\n", method_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

void MyPythonInterpreter::callListMethod(
    const string& method_name,
    const vector< int >& parameters,
    vector< uint64_t >& output )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule,method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( parameters.size() );
        for( unsigned int i = 0; i < parameters.size(); i++ )
        {
            PyObject* pParam = Py_BuildValue( "i", parameters[ i ] );
            PyTuple_SetItem( pArgs, i, pParam );
        }
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
        {
            bool isInt = PyLong_Check( result );
            if( PyList_Check( result ) )
            {
                int size = PyList_Size( result );
                for( int i = size - 1; i >= 0; i-- )
                {
                    PyObject* item = PyList_GetItem( result, i );
                    if( PyLong_Check( item ) )
                    {
                        uint64_t value = PyLong_AsUnsignedLongLongMask( item );
                        output.push_back( value );
                    }
                }
                Py_XDECREF( result );
            }
            else if( isInt )
            {
                uint64_t value =
                #ifdef PYTHON_THREE
                    PyLong_AsUnsignedLongLongMask( result );
                #else
                    PyInt_AsUnsignedLongLongMask( result );
                #endif
                output.push_back( value );
            }
            else if( PyErr_Occurred() )
                PyErr_Print();
        }
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf("Method %s not found\n", method_name.c_str());
    }
    Py_XDECREF( pFunc );
}

void MyPythonInterpreter::callVoidMethod(
    const string& method_name,
    int param1,
    const string& param2 )
{
    if( pModule == NULL )
        return;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
    {
        PyObject* pArgs = PyTuple_New( 2 );
        PyObject* param1_python =
        #ifdef PYTHON_THREE
            PyLong_FromSize_t( param1 );
        #else
            PyInt_FromSize_t( param1 );
        #endif

        PyObject* param2_python =
        #ifdef PYTHON_THREE
            PyUnicode_FromString( param2.c_str() );
        #else
            PyString_FromString( param2.c_str() );
        #endif

        PyTuple_SetItem( pArgs, 0, param1_python );
        PyTuple_SetItem( pArgs, 1, param2_python );
        PyObject* result = PyObject_CallObject( pFunc, pArgs );
        if( result )
            Py_XDECREF( result );
        else if( PyErr_Occurred() )
            PyErr_Print();
        Py_XDECREF( pArgs );
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Method %s not found\n", method_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

bool MyPythonInterpreter::checkMethod(
    const string& method_name ) const
{
    bool res = false;
    if( pModule == NULL )
        return res;
    PyObject* pFunc = PyObject_GetAttrString( pModule, method_name.c_str() );
    if( pFunc && PyCallable_Check( pFunc ) )
       res = true;
    else if( PyErr_Occurred() )
        PyErr_Clear();

    Py_XDECREF( pFunc );
    return res;
}

void MyPythonInterpreter::addElementInMap(
    const string& map_name,
    const string& key,
    unsigned int value )
{
    PyObject* pFunc = PyObject_GetAttrString( pModule, map_name.c_str() );
    if( pFunc )
    {
        PyObject* value_python =
        #ifdef PYTHON_THREE
            PyLong_FromSize_t( value );
        #else
            PyInt_FromSize_t( value );
        #endif

        char *cstr = new char[key.length() + 1];
        strcpy(cstr, key.c_str());
        int res = PyMapping_SetItemString(pFunc, cstr, value_python);
        if( res == -1 || PyErr_Occurred() )
            PyErr_Print();
        delete [] cstr;
    }
    else
    {
        if( PyErr_Occurred() )
            PyErr_Print();
        printf( "Element %s not found\n", map_name.c_str() );
    }
    Py_XDECREF( pFunc );
}

bool MyPythonInterpreter::checkAttribute(
    const string& map_name ) const
{
    bool res = false;
    if( pModule == NULL )
        return res;
    PyObject* pFunc = PyObject_GetAttrString( pModule, map_name.c_str() );
    if( pFunc )
       res = true;
    else if( PyErr_Occurred() )
        PyErr_Clear();

    Py_XDECREF( pFunc );
    return res;
}

#endif
<|endoftext|>


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

#include "qgeoareamonitor_polling_p.h"
#include "qgeocoordinate.h"

QTM_BEGIN_NAMESPACE

#define UPDATE_INTERVAL_5S  5000

QGeoAreaMonitorPolling::QGeoAreaMonitorPolling(QObject *parent) : QGeoAreaMonitor(parent)
{
    insideArea = false;
    location = QGeoPositionInfoSource::createDefaultSource(this);
    if (location) {
        location->setUpdateInterval(UPDATE_INTERVAL_5S);
        connect(location, SIGNAL(positionUpdated(QGeoPositionInfo)),
                this, SLOT(positionUpdated(QGeoPositionInfo)));
    }
}

QGeoAreaMonitorPolling::~QGeoAreaMonitorPolling()
{
    if (location)
        location->stopUpdates();
}

void QGeoAreaMonitorPolling::setCenter(const QGeoCoordinate& coordinate)
{
    if (coordinate.isValid()) {
        QGeoAreaMonitor::setCenter(coordinate);
        checkStartStop();
    }
}

void QGeoAreaMonitorPolling::setRadius(qreal radius)
{
    QGeoAreaMonitor::setRadius(radius);
    checkStartStop();
}

void QGeoAreaMonitorPolling::connectNotify(const char *signal)
{
    if (signal == SIGNAL(areaEntered(QGeoPositionInfo)) ||
            signal == SIGNAL(areaExited(QGeoPositionInfo)))
        checkStartStop();
}

void QGeoAreaMonitorPolling::disconnectNotify(const char *signal)
{
    if (signal == SIGNAL(areaEntered(QGeoPositionInfo)) ||
            signal == SIGNAL(areaExited(QGeoPositionInfo)))
        checkStartStop();
}

void QGeoAreaMonitorPolling::checkStartStop()
{
    if (!location) return;

    if (QObject::receivers(SIGNAL(areaEntered(QGeoPositionInfo))) > 0 &&
            QObject::receivers(SIGNAL(areaExited(QGeoPositionInfo))) > 0 &&
            QGeoAreaMonitor::center().isValid() &&
            QGeoAreaMonitor::radius() > qreal(0.0)) {
        location->startUpdates();
    } else {
        location->stopUpdates();
    }
}

void QGeoAreaMonitorPolling::positionUpdated(const QGeoPositionInfo &info)
{
    double distance = info.coordinate().distanceTo(QGeoAreaMonitor::center());

    if (distance <= QGeoAreaMonitor::radius()) {
        if (!insideArea)
            emit areaEntered(info);
        insideArea = true;
    } else if (insideArea) {
        emit areaExited(info);
        insideArea = false;
    }
}

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

#include "qgeoareamonitor_polling_p.h"
#include "qgeocoordinate.h"

QTM_BEGIN_NAMESPACE

#define UPDATE_INTERVAL_5S  5000

QGeoAreaMonitorPolling::QGeoAreaMonitorPolling(QObject *parent) : QGeoAreaMonitor(parent)
{
    insideArea = false;
    location = QGeoPositionInfoSource::createDefaultSource(this);
    if (location) {
        location->setUpdateInterval(UPDATE_INTERVAL_5S);
        connect(location, SIGNAL(positionUpdated(QGeoPositionInfo)),
                this, SLOT(positionUpdated(QGeoPositionInfo)));
    }
}

QGeoAreaMonitorPolling::~QGeoAreaMonitorPolling()
{
    if (location)
        location->stopUpdates();
}

void QGeoAreaMonitorPolling::setCenter(const QGeoCoordinate& coordinate)
{
    if (coordinate.isValid()) {
        QGeoAreaMonitor::setCenter(coordinate);
        checkStartStop();
    }
}

void QGeoAreaMonitorPolling::setRadius(qreal radius)
{
    QGeoAreaMonitor::setRadius(radius);
    checkStartStop();
}

void QGeoAreaMonitorPolling::connectNotify(const char *signal)
{
    if (signal == SIGNAL(areaEntered(QGeoPositionInfo)) ||
            signal == SIGNAL(areaExited(QGeoPositionInfo)))
        checkStartStop();
}

void QGeoAreaMonitorPolling::disconnectNotify(const char *signal)
{
    if (signal == SIGNAL(areaEntered(QGeoPositionInfo)) ||
            signal == SIGNAL(areaExited(QGeoPositionInfo)))
        checkStartStop();
}

void QGeoAreaMonitorPolling::checkStartStop()
{
    if (!location) return;

    if ((QObject::receivers(SIGNAL(areaEntered(QGeoPositionInfo))) > 0 ||
            QObject::receivers(SIGNAL(areaExited(QGeoPositionInfo))) > 0) &&
            QGeoAreaMonitor::center().isValid() &&
            QGeoAreaMonitor::radius() > qreal(0.0)) {
        location->startUpdates();
    } else {
        location->stopUpdates();
    }
}

void QGeoAreaMonitorPolling::positionUpdated(const QGeoPositionInfo &info)
{
    double distance = info.coordinate().distanceTo(QGeoAreaMonitor::center());

    if (distance <= QGeoAreaMonitor::radius()) {
        if (!insideArea)
            emit areaEntered(info);
        insideArea = true;
    } else if (insideArea) {
        emit areaExited(info);
        insideArea = false;
    }
}

#include "moc_qgeoareamonitor_polling_p.cpp"
QTM_END_NAMESPACE
<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// 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 "iceoryx_posh/internal/runtime/message_queue_message.hpp"

#include <algorithm>

namespace iox
{
namespace runtime
{
const char MqMessage::m_separator = ',';

MqMessage::MqMessage(const std::initializer_list<std::string>& msg) noexcept
{
    for (auto element : msg)
    {
        addEntry(element);
    }
}

MqMessage::MqMessage(const std::string& msg) noexcept
{
    setMessage(msg);
}

uint32_t MqMessage::getNumberOfElements() const noexcept
{
    return m_numberOfElements;
}

std::string MqMessage::getElementAtIndex(const uint32_t index) const noexcept
{
    std::string messageRemainder(m_msg);
    size_t startPos = 0;
    size_t endPos = messageRemainder.find_first_of(m_separator, startPos);

    for (uint32_t counter = 0; endPos != std::string::npos; ++counter)
    {
        if (counter == index)
        {
            return messageRemainder.substr(startPos, endPos - startPos);
        }

        startPos = endPos + 1;
        endPos = messageRemainder.find_first_of(m_separator, startPos);
    }

    return std::string();
}

bool MqMessage::isValidEntry(const std::string& entry) const noexcept
{
    if (entry.find(m_separator) != std::string::npos)
    {
        return false;
    }
    return true;
}

bool MqMessage::isValid() const noexcept
{
    return m_isValid;
}

std::string MqMessage::getMessage() const noexcept
{
    return m_msg;
}

void MqMessage::setMessage(const std::string& msg) noexcept
{
    clearMessage();

    m_msg = msg;
    if (m_msg.back() != m_separator && m_msg.size() > 0) /// @todo shouldn't this be "if (m_msg.size() == 0 || m_msg.back() != m_separator)"???
    {
        m_isValid = false;
    }
    else
    {
        m_numberOfElements = static_cast<uint32_t>(
            std::count_if(m_msg.begin(), m_msg.end(), [&](char c) { return c == m_separator; }));
    }
}

void MqMessage::clearMessage() noexcept
{
    m_msg.clear();
    m_numberOfElements = 0;
    m_isValid = true;
}

bool MqMessage::operator==(const MqMessage& rhs) const noexcept
{
    return this->getMessage() == rhs.getMessage();
}

} // namespace runtime
} // namespace iox
<commit_msg>iox-#33 we have to first check if the message is not empty and then check the last character<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// 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 "iceoryx_posh/internal/runtime/message_queue_message.hpp"

#include <algorithm>

namespace iox
{
namespace runtime
{
const char MqMessage::m_separator = ',';

MqMessage::MqMessage(const std::initializer_list<std::string>& msg) noexcept
{
    for (auto element : msg)
    {
        addEntry(element);
    }
}

MqMessage::MqMessage(const std::string& msg) noexcept
{
    setMessage(msg);
}

uint32_t MqMessage::getNumberOfElements() const noexcept
{
    return m_numberOfElements;
}

std::string MqMessage::getElementAtIndex(const uint32_t index) const noexcept
{
    std::string messageRemainder(m_msg);
    size_t startPos = 0;
    size_t endPos = messageRemainder.find_first_of(m_separator, startPos);

    for (uint32_t counter = 0; endPos != std::string::npos; ++counter)
    {
        if (counter == index)
        {
            return messageRemainder.substr(startPos, endPos - startPos);
        }

        startPos = endPos + 1;
        endPos = messageRemainder.find_first_of(m_separator, startPos);
    }

    return std::string();
}

bool MqMessage::isValidEntry(const std::string& entry) const noexcept
{
    if (entry.find(m_separator) != std::string::npos)
    {
        return false;
    }
    return true;
}

bool MqMessage::isValid() const noexcept
{
    return m_isValid;
}

std::string MqMessage::getMessage() const noexcept
{
    return m_msg;
}

void MqMessage::setMessage(const std::string& msg) noexcept
{
    clearMessage();

    m_msg = msg;
    if (!m_msg.empty() && m_msg.back() != m_separator)
    {
        m_isValid = false;
    }
    else
    {
        m_numberOfElements =
            static_cast<uint32_t>(std::count_if(m_msg.begin(), m_msg.end(), [&](char c) { return c == m_separator; }));
    }
}

void MqMessage::clearMessage() noexcept
{
    m_msg.clear();
    m_numberOfElements = 0;
    m_isValid = true;
}

bool MqMessage::operator==(const MqMessage& rhs) const noexcept
{
    return this->getMessage() == rhs.getMessage();
}

} // namespace runtime
} // namespace iox
<|endoftext|>


<commit_before>//  To parse this JSON data, first install
//
//      Boost     http://www.boost.org
//      json.hpp  https://github.com/nlohmann/json
//
//  Then include this file, and then do
//
//     SPIInProperties.hpp data = nlohmann::json::parse(jsonString);

#pragma once

#include <nlohmann/json.hpp>

namespace dai {

/**
 * Properties for SPIIn node
 */
struct SPIInProperties {
    /**
     * Name of stream
     */
    std::string streamName;

    /**
     * SPI bus to use
     */
    int busId;

    /**
     * Maximum input data size
     */
    std::uint32_t maxDataSize = dai::XLINK_USB_BUFFER_MAX_SIZE;

    /**
     * Number of frames in pool
     */
    std::uint32_t numFrames = 4;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SPIInProperties, streamName, busId);

}  // namespace dai
<commit_msg>Fix includes in SPIInProperties.hpp<commit_after>#pragma once

#include <nlohmann/json.hpp>

#include "depthai-shared/xlink/XLinkConstants.hpp"

namespace dai {

/**
 * Properties for SPIIn node
 */
struct SPIInProperties {
    /**
     * Name of stream
     */
    std::string streamName;

    /**
     * SPI bus to use
     */
    int busId;

    /**
     * Maximum input data size
     */
    std::uint32_t maxDataSize = dai::XLINK_USB_BUFFER_MAX_SIZE;

    /**
     * Number of frames in pool
     */
    std::uint32_t numFrames = 4;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(SPIInProperties, streamName, busId, maxDataSize, numFrames);

}  // namespace dai
<|endoftext|>


<commit_before>#include "ASTImportSource.h"
#include "cling/Interpreter/Interpreter.h"

using namespace clang;

namespace {
    class ClingASTImporter : public ASTImporter {
    private:
    cling::ASTImportSource& m_source;

    public:
      ClingASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                       ASTContext &FromContext, FileManager &FromFileManager,
                       bool MinimalImport, cling::ASTImportSource& source) :
                    ASTImporter(ToContext, ToFileManager, FromContext,
                                FromFileManager, MinimalImport), m_source(source) {}

      Decl *Imported(Decl *From, Decl *To) override {
        ASTImporter::Imported(From, To);

        // Put the name of the Decl imported with the
        // DeclarationName coming from the parent, in  my map.
        if (DeclContext *declContextParent = llvm::dyn_cast<DeclContext>(From)) {
          DeclContext *declContextChild = llvm::dyn_cast<DeclContext>(To);
          m_source.addToDeclContext(declContextChild, declContextParent);
        }

        return To;
      }

    };
}

namespace cling {

    ASTImportSource::ASTImportSource(const cling::Interpreter *parent_interpreter,
    cling::Interpreter *child_interpreter) :
    m_parent_Interp(parent_interpreter), m_child_Interp(child_interpreter) {

      clang::DeclContext *parentTUDeclContext =
        clang::TranslationUnitDecl::castToDeclContext(
          m_parent_Interp->getCI()->getASTContext().getTranslationUnitDecl());

      clang::DeclContext *childTUDeclContext =
        clang::TranslationUnitDecl::castToDeclContext(
          m_child_Interp->getCI()->getASTContext().getTranslationUnitDecl());

      // Also keep in the map of Decl Contexts the Translation Unit Decl Context
      m_DeclContexts_map[childTUDeclContext] = parentTUDeclContext;
    }

    void ASTImportSource::ImportDecl(Decl *declToImport,
                                     ASTImporter &importer,
                                     DeclarationName &childDeclName,
                                     DeclarationName &parentDeclName,
                                     const DeclContext *childCurrentDeclContext) {

      // Don't do the import if we have a Function Template.
      // Not supported by clang.
      // FIXME: This is also a temporary check. Will be de-activated
      // once clang supports the import of function templates.
      if (declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())
        return;

      if (Decl *importedDecl = importer.Import(declToImport)) {
        if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDecl)) {
          std::vector < NamedDecl * > declVector{importedNamedDecl};
          llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
          SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                         importedNamedDecl->getDeclName(),
                                         FoundDecls);
        }
        // Put the name of the Decl imported with the
        // DeclarationName coming from the parent, in  my map.
        m_DeclName_map[childDeclName] = parentDeclName;
      }
    }

    void ASTImportSource::ImportDeclContext(DeclContext *declContextToImport,
                                            ASTImporter &importer,
                                            DeclarationName &childDeclName,
                                            DeclarationName &parentDeclName,
                                            const DeclContext *childCurrentDeclContext) {

      if (DeclContext *importedDeclContext = importer.ImportContext(declContextToImport)) {

        importedDeclContext->setHasExternalVisibleStorage(true);

        if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDeclContext)) {
          std::vector < NamedDecl * > declVector{importedNamedDecl};
          llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
          SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                         importedNamedDecl->getDeclName(),
                                         FoundDecls);
        }
        // Put the name of the DeclContext imported with the
        // DeclarationName coming from the parent, in  my map.
        m_DeclName_map[childDeclName] = parentDeclName;

        // And also put the declaration context I found from the parent Interpreter
        // in the map of the child Interpreter to have it for the future.
        m_DeclContexts_map[importedDeclContext] = declContextToImport;
      }
    }

    bool ASTImportSource::Import(DeclContext::lookup_result lookup_result,
                                 ASTContext &from_ASTContext,
                                 ASTContext &to_ASTContext,
                                 const DeclContext *childCurrentDeclContext,
                                 DeclarationName &childDeclName,
                                 DeclarationName &parentDeclName) {

      // Prepare to import the Decl(Context)  we found in the
      // child interpreter by getting the file managers from
      // each interpreter.
      FileManager &child_FM = m_child_Interp->getCI()->getFileManager();
      FileManager &parent_FM = m_parent_Interp->getCI()->getFileManager();

      // Cling's ASTImporter
      ClingASTImporter importer(to_ASTContext, child_FM,
                           from_ASTContext, parent_FM,
                           /*MinimalImport : ON*/ true, *this);

      for (DeclContext::lookup_iterator I = lookup_result.begin(),
             E = lookup_result.end();
             I != E; ++I) {
        // Check if this Name we are looking for is
        // a DeclContext (for example a Namespace, function etc.).
        if (DeclContext *declContextToImport = llvm::dyn_cast<DeclContext>(*I)) {

          ImportDeclContext(declContextToImport, importer, childDeclName,
                            parentDeclName, childCurrentDeclContext);

        } else if (Decl *declToImport = llvm::dyn_cast<Decl>(*I)) {

          // else it is a Decl
          ImportDecl(declToImport, importer, childDeclName,
                     parentDeclName, childCurrentDeclContext);
        }
      }
      return true;
    }

    ///\brief This is the most important function of the class ASTImportSource
    /// since from here initiates the lookup and import part of the missing
    /// Decl(s) (Contexts).
    ///
    bool ASTImportSource::FindExternalVisibleDeclsByName(
      const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) {

      assert(childDeclName && "Child Decl name is empty");

      assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
             "DeclContext has no visible decls in storage");

      //Check if we have already found this declaration Name before
      DeclarationName parentDeclName;
      std::map<clang::DeclarationName,
        clang::DeclarationName>::iterator II = m_DeclName_map.find(childDeclName);
      if (II != m_DeclName_map.end()) {
        parentDeclName = II->second;
      } else {
        // Get the identifier info from the parent interpreter
        // for this Name.
        std::string name = childDeclName.getAsString();
        if (!name.empty()) {
          llvm::StringRef nameRef(name);
          IdentifierTable &parentIdentifierTable =
                              m_parent_Interp->getCI()->getASTContext().Idents;
          IdentifierInfo &parentIdentifierInfo =
                              parentIdentifierTable.get(nameRef);
          parentDeclName = DeclarationName(&parentIdentifierInfo);
        }
      }

      // Search in the map of the stored Decl Contexts for this
      // Decl Context.
      std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I;
      // If childCurrentDeclContext was found before and is already in the map,
      // then do the lookup using the stored pointer.
      if ((I = m_DeclContexts_map.find(childCurrentDeclContext))
           != m_DeclContexts_map.end()) {
        DeclContext *parentDeclContext = I->second;

        Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext);
        ASTContext &from_ASTContext = fromDeclContext->getASTContext();

        Decl *toDeclContext = Decl::castFromDeclContext(childCurrentDeclContext);
        ASTContext &to_ASTContext = toDeclContext->getASTContext();

        DeclContext::lookup_result lookup_result =
          parentDeclContext->lookup(parentDeclName);

        // Check if we found this Name in the parent interpreter
        if (!lookup_result.empty()) {
          // Do the import
          if (Import(lookup_result, from_ASTContext, to_ASTContext,
                     childCurrentDeclContext, childDeclName, parentDeclName))
            return true;
        }
      }
      return false;
    }

    ///\brief Make available to child all decls in parent's decl context
    /// that corresponds to child decl context.
    void ASTImportSource::completeVisibleDeclsMap(
                                  const clang::DeclContext *childDeclContext) {
      assert (childDeclContext && "No child decl context!");

      if (!childDeclContext->hasExternalVisibleStorage())
        return;

      // Search in the map of the stored Decl Contexts for this
      // Decl Context.
      std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I;
      // If childCurrentDeclContext was found before and is already in the map,
      // then do the lookup using the stored pointer.
      if ((I = m_DeclContexts_map.find(childDeclContext))
          != m_DeclContexts_map.end()) {

        DeclContext *parentDeclContext = I->second;

        Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext);
        ASTContext &from_ASTContext = fromDeclContext->getASTContext();

        Decl *toDeclContext = Decl::castFromDeclContext(childDeclContext);
        ASTContext &to_ASTContext = toDeclContext->getASTContext();

        // Prepare to import the Decl(Context)  we found in the
        // child interpreter by getting the file managers from
        // each interpreter.
        FileManager &child_FM = m_child_Interp->getCI()->getFileManager();
        FileManager &parent_FM = m_parent_Interp->getCI()->getFileManager();

        // Cling's ASTImporter
        ClingASTImporter importer(to_ASTContext, child_FM,
                             from_ASTContext, parent_FM,
                             /*MinimalImport : ON*/ true, *this);

        for (DeclContext::decl_iterator I_decl = parentDeclContext->decls_begin(),
          E_decl = parentDeclContext->decls_end(); I_decl != E_decl; ++I_decl) {
          if (NamedDecl* parentNamedDecl = llvm::dyn_cast<NamedDecl>(*I_decl)) {
            DeclarationName newDeclName = parentNamedDecl->getDeclName();
            ImportDecl(parentNamedDecl, importer, newDeclName, newDeclName,
                       childDeclContext);
          }
        }

        const_cast<DeclContext *>(childDeclContext)->
                                          setHasExternalVisibleStorage(false);
      }
    }

} // end namespace cling
<commit_msg>Mark the external visibility of imported decls.<commit_after>#include "ASTImportSource.h"
#include "cling/Interpreter/Interpreter.h"

using namespace clang;

namespace {
    class ClingASTImporter : public ASTImporter {
    private:
    cling::ASTImportSource& m_source;

    public:
      ClingASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                       ASTContext &FromContext, FileManager &FromFileManager,
                       bool MinimalImport, cling::ASTImportSource& source) :
                    ASTImporter(ToContext, ToFileManager, FromContext,
                                FromFileManager, MinimalImport), m_source(source) {}

      Decl *Imported(Decl *From, Decl *To) override {
        ASTImporter::Imported(From, To);

        if (isa<TagDecl>(From)) {
          clang::TagDecl* toTagDecl = dyn_cast<TagDecl>(To);
          toTagDecl->setHasExternalVisibleStorage();
        }

        if (isa<NamespaceDecl>(From))
        {
            NamespaceDecl *to_namespace_decl = dyn_cast<NamespaceDecl>(To);
            to_namespace_decl->setHasExternalVisibleStorage();
        }

        if (isa<ObjCContainerDecl>(From))
        {
            ObjCContainerDecl *to_container_decl = dyn_cast<ObjCContainerDecl>(To);
            to_container_decl->setHasExternalLexicalStorage();
            to_container_decl->setHasExternalVisibleStorage();
        }

        // Put the name of the Decl imported with the
        // DeclarationName coming from the parent, in  my map.
        if (DeclContext *declContextParent = llvm::dyn_cast<DeclContext>(From)) {
          DeclContext *declContextChild = llvm::dyn_cast<DeclContext>(To);
          m_source.addToDeclContext(declContextChild, declContextParent);
        }

        return To;
      }

    };
}

namespace cling {

    ASTImportSource::ASTImportSource(const cling::Interpreter *parent_interpreter,
    cling::Interpreter *child_interpreter) :
    m_parent_Interp(parent_interpreter), m_child_Interp(child_interpreter) {

      clang::DeclContext *parentTUDeclContext =
        clang::TranslationUnitDecl::castToDeclContext(
          m_parent_Interp->getCI()->getASTContext().getTranslationUnitDecl());

      clang::DeclContext *childTUDeclContext =
        clang::TranslationUnitDecl::castToDeclContext(
          m_child_Interp->getCI()->getASTContext().getTranslationUnitDecl());

      // Also keep in the map of Decl Contexts the Translation Unit Decl Context
      m_DeclContexts_map[childTUDeclContext] = parentTUDeclContext;
    }

    void ASTImportSource::ImportDecl(Decl *declToImport,
                                     ASTImporter &importer,
                                     DeclarationName &childDeclName,
                                     DeclarationName &parentDeclName,
                                     const DeclContext *childCurrentDeclContext) {

      // Don't do the import if we have a Function Template.
      // Not supported by clang.
      // FIXME: This is also a temporary check. Will be de-activated
      // once clang supports the import of function templates.
      if (declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())
        return;

      //cling::Interpreter::PushTransactionRAII RAII(parent_int);
      if (Decl *importedDecl = importer.Import(declToImport)) {
        if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDecl)) {
          std::vector < NamedDecl * > declVector{importedNamedDecl};
          llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
          SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                         importedNamedDecl->getDeclName(),
                                         FoundDecls);
        }
        // Put the name of the Decl imported with the
        // DeclarationName coming from the parent, in  my map.
        m_DeclName_map[childDeclName] = parentDeclName;
      }
    }

    void ASTImportSource::ImportDeclContext(DeclContext *declContextToImport,
                                            ASTImporter &importer,
                                            DeclarationName &childDeclName,
                                            DeclarationName &parentDeclName,
                                            const DeclContext *childCurrentDeclContext) {

      if (DeclContext *importedDeclContext = importer.ImportContext(declContextToImport)) {

        importedDeclContext->setHasExternalVisibleStorage(true);

        if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDeclContext)) {
          std::vector < NamedDecl * > declVector{importedNamedDecl};
          llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
          SetExternalVisibleDeclsForName(childCurrentDeclContext,
                                         importedNamedDecl->getDeclName(),
                                         FoundDecls);
        }
        // Put the name of the DeclContext imported with the
        // DeclarationName coming from the parent, in  my map.
        m_DeclName_map[childDeclName] = parentDeclName;

        // And also put the declaration context I found from the parent Interpreter
        // in the map of the child Interpreter to have it for the future.
        m_DeclContexts_map[importedDeclContext] = declContextToImport;
      }
    }

    bool ASTImportSource::Import(DeclContext::lookup_result lookup_result,
                                 ASTContext &from_ASTContext,
                                 ASTContext &to_ASTContext,
                                 const DeclContext *childCurrentDeclContext,
                                 DeclarationName &childDeclName,
                                 DeclarationName &parentDeclName) {

      // Prepare to import the Decl(Context)  we found in the
      // child interpreter by getting the file managers from
      // each interpreter.
      FileManager &child_FM = m_child_Interp->getCI()->getFileManager();
      FileManager &parent_FM = m_parent_Interp->getCI()->getFileManager();

      // Cling's ASTImporter
      ClingASTImporter importer(to_ASTContext, child_FM,
                           from_ASTContext, parent_FM,
                           /*MinimalImport : ON*/ true, *this);

      for (DeclContext::lookup_iterator I = lookup_result.begin(),
             E = lookup_result.end();
             I != E; ++I) {
        // Check if this Name we are looking for is
        // a DeclContext (for example a Namespace, function etc.).
        if (DeclContext *declContextToImport = llvm::dyn_cast<DeclContext>(*I)) {

          ImportDeclContext(declContextToImport, importer, childDeclName,
                            parentDeclName, childCurrentDeclContext);

        } else if (Decl *declToImport = llvm::dyn_cast<Decl>(*I)) {

          // else it is a Decl
          ImportDecl(declToImport, importer, childDeclName,
                     parentDeclName, childCurrentDeclContext);
        }
      }
      return true;
    }

    ///\brief This is the most important function of the class ASTImportSource
    /// since from here initiates the lookup and import part of the missing
    /// Decl(s) (Contexts).
    ///
    bool ASTImportSource::FindExternalVisibleDeclsByName(
      const DeclContext *childCurrentDeclContext, DeclarationName childDeclName) {

      assert(childDeclName && "Child Decl name is empty");

      assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
             "DeclContext has no visible decls in storage");

      //Check if we have already found this declaration Name before
      DeclarationName parentDeclName;
      std::map<clang::DeclarationName,
        clang::DeclarationName>::iterator II = m_DeclName_map.find(childDeclName);
      if (II != m_DeclName_map.end()) {
        parentDeclName = II->second;
      } else {
        // Get the identifier info from the parent interpreter
        // for this Name.
        std::string name = childDeclName.getAsString();
        if (!name.empty()) {
          llvm::StringRef nameRef(name);
          IdentifierTable &parentIdentifierTable =
                              m_parent_Interp->getCI()->getASTContext().Idents;
          IdentifierInfo &parentIdentifierInfo =
                              parentIdentifierTable.get(nameRef);
          parentDeclName = DeclarationName(&parentIdentifierInfo);
        }
      }

      // Search in the map of the stored Decl Contexts for this
      // Decl Context.
      std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I;
      // If childCurrentDeclContext was found before and is already in the map,
      // then do the lookup using the stored pointer.
      if ((I = m_DeclContexts_map.find(childCurrentDeclContext))
           != m_DeclContexts_map.end()) {
        DeclContext *parentDeclContext = I->second;

        Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext);
        ASTContext &from_ASTContext = fromDeclContext->getASTContext();

        Decl *toDeclContext = Decl::castFromDeclContext(childCurrentDeclContext);
        ASTContext &to_ASTContext = toDeclContext->getASTContext();

        DeclContext::lookup_result lookup_result =
          parentDeclContext->lookup(parentDeclName);

        // Check if we found this Name in the parent interpreter
        if (!lookup_result.empty()) {
          // Do the import
          if (Import(lookup_result, from_ASTContext, to_ASTContext,
                     childCurrentDeclContext, childDeclName, parentDeclName))
            return true;
        }
      }
      return false;
    }

    ///\brief Make available to child all decls in parent's decl context
    /// that corresponds to child decl context.
    void ASTImportSource::completeVisibleDeclsMap(
                                  const clang::DeclContext *childDeclContext) {
      assert (childDeclContext && "No child decl context!");

      if (!childDeclContext->hasExternalVisibleStorage())
        return;

      // Search in the map of the stored Decl Contexts for this
      // Decl Context.
      std::map<const clang::DeclContext *, clang::DeclContext *>::iterator I;
      // If childCurrentDeclContext was found before and is already in the map,
      // then do the lookup using the stored pointer.
      if ((I = m_DeclContexts_map.find(childDeclContext))
          != m_DeclContexts_map.end()) {

        DeclContext *parentDeclContext = I->second;

        Decl *fromDeclContext = Decl::castFromDeclContext(parentDeclContext);
        ASTContext &from_ASTContext = fromDeclContext->getASTContext();

        Decl *toDeclContext = Decl::castFromDeclContext(childDeclContext);
        ASTContext &to_ASTContext = toDeclContext->getASTContext();

        // Prepare to import the Decl(Context)  we found in the
        // child interpreter by getting the file managers from
        // each interpreter.
        FileManager &child_FM = m_child_Interp->getCI()->getFileManager();
        FileManager &parent_FM = m_parent_Interp->getCI()->getFileManager();

        // Cling's ASTImporter
        ClingASTImporter importer(to_ASTContext, child_FM,
                             from_ASTContext, parent_FM,
                             /*MinimalImport : ON*/ true, *this);

        StringRef filter = m_child_Interp->getCI()->getPreprocessor().getCodeCompletionFilter();
        for (DeclContext::decl_iterator I_decl = parentDeclContext->decls_begin(),
          E_decl = parentDeclContext->decls_end(); I_decl != E_decl; ++I_decl) {
          if (NamedDecl* parentNamedDecl = llvm::dyn_cast<NamedDecl>(*I_decl)) {
            // Filter using the stem from the input line
            DeclarationName newDeclName = parentNamedDecl->getDeclName();
            if (newDeclName.getAsIdentifierInfo()) {
              StringRef name = newDeclName.getAsIdentifierInfo()->getName();
              if (!name.empty() && name.startswith(filter))
              ImportDecl(parentNamedDecl, importer, newDeclName, newDeclName,
                         childDeclContext);
            }
          }
        }

        const_cast<DeclContext *>(childDeclContext)->
                                          setHasExternalVisibleStorage(false);
      }
    }

} // end namespace cling
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#include <config.h>

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include "version.hpp"
#include <glib/gstdio.h>
#include <ftw.h>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>

#include "TransportFactory.hpp"

#include <SignalHandler.hpp>
#include <ServerMethods.hpp>
#include <gst/gst.h>

#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "logging.hpp"
#include "modules.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

const std::string DEFAULT_CONFIG_FILE = "/etc/kurento/kurento.conf.json";
const std::string ENV_PREFIX = "KURENTO_";

using namespace ::kurento;
namespace logging = boost::log;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static std::shared_ptr<Transport>
load_config (boost::property_tree::ptree &config, const std::string &file_name)
{
  std::shared_ptr<Transport> transport;
  boost::filesystem::path configFilePath (file_name);
  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    boost::property_tree::read_json (file_name, config);
  } catch (boost::property_tree::ptree_error &e) {
    GST_ERROR ("Error reading configuration: %s", e.what() );
    std::cerr << "Error reading configuration: " << e.what() << std::endl;
    exit (1);
  }

  config.add ("configPath", configFilePath.parent_path().string() );

  GST_INFO ("Configuration loaded successfully");

  std::shared_ptr<ServerMethods> serverMethods (new ServerMethods (config) );

  try {
    transport = TransportFactory::create_transport (config, serverMethods);
  } catch (std::exception &e) {
    GST_ERROR ("Error creating transport: %s", e.what() );
    exit (1);
  }

  return transport;
}

static void
signal_handler (uint32_t signo)
{
  static unsigned int __terminated = 0;

  switch (signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    break;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }
}

static void
kms_init_dependencies (int argc, char **argv)
{
  Glib::init();

  gst_init (&argc, &argv);

  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);

  /* Initialization routine to add commonly used */
  /* attributes to the logging system */
  logging::add_common_attributes();
}

int
main (int argc, char **argv)
{
  sigset_t mask;
  std::shared_ptr <SignalHandler> signalHandler;
  std::shared_ptr<Transport> transport;
  boost::property_tree::ptree config;
  std::string confFile;
  std::string path, logs_path;

  kms_init_dependencies (argc, argv);

  try {
    boost::program_options::options_description desc ("kurento-media-server usage");

    desc.add_options()
    ("help,h", "Display this help message")
    ("version,v", "Display the version number")
    ("list,l", "Lists all available factories")
    ("modules-path,p", boost::program_options::value<std::string>
     (&path), "Path where kurento modules can be found")
    ("conf-file,f", boost::program_options::value<std::string>
     (&confFile)->default_value (DEFAULT_CONFIG_FILE),
     "Configuration file location")
    ("logs-path,d", boost::program_options::value <std::string> (&logs_path),
     "Path where debug files will be stored");

    boost::program_options::command_line_parser clp (argc, argv);
    clp.options (desc).allow_unregistered();
    boost::program_options::variables_map vm;
    auto parsed = clp.run();
    boost::program_options::store (parsed, vm);

    boost::program_options::store (boost::program_options::parse_environment (desc,
    [&desc] (std::string & input) -> std::string {
      /* Look for KURENTO_ prefix and change to lower case */
      if (input.find (ENV_PREFIX) == 0)
      {
        std::string aux = input.substr (ENV_PREFIX.size() );
        std::transform (aux.begin(), aux.end(), aux.begin(), [] (int c) -> int {
          return (c == '_') ? '-' : tolower (c);
        });

        if (!desc.find_nothrow (aux, false) ) {
          return "";
        }

        return aux;
      }

      return "";
    }), vm);

    boost::program_options::notify (vm);

    if (vm.count ("logs-path") ) {
      if (kms_init_logging (logs_path) ) {
        GST_DEBUG ("Dumping logs to %s", logs_path.c_str() );
      } else {
        GST_WARNING ("Can no set debugging path %s", logs_path.c_str() );
      }
    }

    if (vm.count ("help") ) {
      std::cout << desc << "\n";
      exit (0);
    }

    if (vm.count ("version") || vm.count ("list") ) {
      // Disable log to just print version
      gst_debug_remove_log_function_by_data (NULL);
    }

    loadModules (path);

    if (vm.count ("list") ) {
      std::cout << "Available factories:" << std::endl;

      for (auto it : kurento::getModuleManager().getLoadedFactories() ) {
        std::cout << "\t" << it.first << std::endl;
      }

      exit (0);
    }

    if (vm.count ("version") ) {
      print_version();
      exit (0);
    }

  } catch (boost::program_options::error &e) {
    std::cerr <<  "Error : " << e.what() << std::endl;
    exit (1);
  }

  /* Install our signal handler */
  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);
  signalHandler = std::shared_ptr <SignalHandler> (new SignalHandler (mask,
                  signal_handler) );

  GST_INFO ("Kmsc version: %s", get_version () );

  transport = load_config (config, confFile);

  /* Start transport */
  transport->start ();

  GST_INFO ("Mediaserver started");

  loop->run ();

  transport->stop();

  GST_INFO ("Mediaserver stopped");

  return 0;
}
<commit_msg>Allow loading different config files for external modules<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#include <config.h>

#include <queue>
#include <boost/foreach.hpp>

#include <glibmm.h>
#include <fstream>
#include <iostream>
#include <boost/filesystem.hpp>
#include "version.hpp"
#include <glib/gstdio.h>
#include <ftw.h>

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>

#include "TransportFactory.hpp"

#include <SignalHandler.hpp>
#include <ServerMethods.hpp>
#include <gst/gst.h>

#include <boost/program_options.hpp>
#include <boost/exception/diagnostic_information.hpp>

#include "logging.hpp"
#include "modules.hpp"

#define GST_CAT_DEFAULT kurento_media_server
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaServer"

const std::string DEFAULT_CONFIG_FILE = "/etc/kurento/kurento.conf.json";
const std::string ENV_PREFIX = "KURENTO_";

using namespace ::kurento;
namespace logging = boost::log;

Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create ();

static std::list<std::string>
split (const std::string &s, char delim)
{
  std::list<std::string> elems;
  std::stringstream ss (s);
  std::string item;

  while (std::getline (ss, item, delim) ) {
    elems.push_back (item);
  }

  return elems;
}

static void
mergePropertyTrees (boost::property_tree::ptree &ptMerged,
                    const boost::property_tree::ptree &rptSecond )
{
  // Keep track of keys and values (subtrees) in second property tree
  std::queue<std::string> qKeys;
  std::queue<boost::property_tree::ptree> qValues;
  qValues.push ( rptSecond );

  // Iterate over second property tree
  while ( !qValues.empty() ) {
    // Setup keys and corresponding values
    boost::property_tree::ptree ptree = qValues.front();
    qValues.pop();
    std::string keychain;

    if ( !qKeys.empty() ) {
      keychain = qKeys.front();
      qKeys.pop();
    }

    BOOST_FOREACH ( const boost::property_tree::ptree::value_type & child, ptree ) {
      if ( child.second.size() == 0 ) {
        std::string s;

        if ( !keychain.empty() ) {
          s = keychain + "." + child.first.data();
        } else {
          s = child.first.data();
        }

        // Put into combined property tree
        ptMerged.put ( s, child.second.data() );
      } else {
        // Put keys (identifiers of subtrees) and all of its parents (where present)
        // aside for later iteration.
        if ( !keychain.empty() ) {
          qKeys.push ( keychain + "." + child.first.data() );
        } else {
          qKeys.push ( child.first.data() );
        }

        // Put values (the subtrees) aside, too
        qValues.push ( child.second );
      }
    }
  }
}

static void
loadModulesConfigFromDir (boost::property_tree::ptree &config,
                          const boost::filesystem::path &dir, const boost::filesystem::path &parentDir)
{
  GST_INFO ("Looking for config files in %s", dir.string().c_str() );

  if (!boost::filesystem::is_directory (dir) ) {
    GST_WARNING ("Unable to load config files from: %s, it is not a directory",
                 dir.string().c_str() );
    return;
  }

  boost::filesystem::directory_iterator end_itr;

  for ( boost::filesystem::directory_iterator itr ( dir ); itr != end_itr;
        ++itr ) {
    if (boost::filesystem::is_regular (*itr) ) {
      boost::filesystem::path extension = itr->path().extension();
      boost::filesystem::path extension2 = itr->path().stem().extension();
      std::string fileName = itr->path().filename().string();

      if (extension.string() == ".json" && extension2.string() == ".conf") {
        boost::property_tree::ptree moduleConfig;

        boost::property_tree::read_json (itr->path().string(), moduleConfig);

        moduleConfig.add ("configPath", itr->path().parent_path().string() );

        {
          boost::filesystem::path diffpath;

          boost::filesystem::path tmppath = itr->path().parent_path();

          while (tmppath != parentDir) {
            diffpath = tmppath.stem() / diffpath;
            tmppath = tmppath.parent_path();
          }

          tmppath = diffpath;

          boost::property_tree::ptree loadedConfig;
          std::string key = "modules";

          for (auto it = tmppath.begin(); it != tmppath.end(); it ++) {
            key += "." + it->string();
          }

          fileName = fileName.substr (0, fileName.size() - extension.string().size() );
          fileName = fileName.substr (0, fileName.size() - extension2.string().size() );

          key += "." + fileName;

          loadedConfig.put_child (key, moduleConfig);

          mergePropertyTrees (config, loadedConfig);
        }

        GST_INFO ("Loaded module config from: %s", itr->path().string().c_str() );
      }
    } else if (boost::filesystem::is_directory (*itr) ) {
      loadModulesConfigFromDir (config, itr->path(), parentDir);
    }
  }
}

static void
loadModulesConfig (boost::property_tree::ptree &config,
                   const boost::filesystem::path &configFilePath, std::string modulesConfigPath)
{
  std::list <std::string> locations;

  if (modulesConfigPath.empty() ) {
    boost::filesystem::path modulesConfigDir = configFilePath.parent_path() /
        "modules";

    modulesConfigPath = modulesConfigDir.string();
  }

  locations = split (modulesConfigPath, ':');

  for (std::string location : locations) {
    boost::filesystem::path dir (location);

    loadModulesConfigFromDir (config, dir, dir);
  }
}

static std::shared_ptr<Transport>
load_config (boost::property_tree::ptree &config, const std::string &file_name,
             const std::string &modulesConfigPath)
{
  std::shared_ptr<Transport> transport;
  boost::filesystem::path configFilePath (file_name);
  GST_INFO ("Reading configuration from: %s", file_name.c_str () );

  try {
    boost::property_tree::read_json (file_name, config);
  } catch (boost::property_tree::ptree_error &e) {
    GST_ERROR ("Error reading configuration: %s", e.what() );
    std::cerr << "Error reading configuration: " << e.what() << std::endl;
    exit (1);
  }

  loadModulesConfig (config, configFilePath, modulesConfigPath);

  config.add ("configPath", configFilePath.parent_path().string() );

  GST_INFO ("Configuration loaded successfully");

  std::ostringstream oss;
  boost::property_tree::write_json (oss, config, true);
  std::string jsonConfig = oss.str();

  GST_DEBUG ("Effective loaded config:\n%s", jsonConfig.c_str() );

  std::shared_ptr<ServerMethods> serverMethods (new ServerMethods (config) );

  try {
    transport = TransportFactory::create_transport (config, serverMethods);
  } catch (std::exception &e) {
    GST_ERROR ("Error creating transport: %s", e.what() );
    exit (1);
  }

  return transport;
}

static void
signal_handler (uint32_t signo)
{
  static unsigned int __terminated = 0;

  switch (signo) {
  case SIGINT:
  case SIGTERM:
    if (__terminated == 0) {
      GST_DEBUG ("Terminating.");
      loop->quit ();
    }

    __terminated = 1;
    break;

  case SIGPIPE:
    GST_DEBUG ("Ignore sigpipe signal");
    break;

  case SIGSEGV:
    GST_DEBUG ("Segmentation fault. Aborting process execution");
    abort ();

  default:
    break;
  }
}

static void
kms_init_dependencies (int argc, char **argv)
{
  Glib::init();

  gst_init (&argc, &argv);

  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);

  /* Initialization routine to add commonly used */
  /* attributes to the logging system */
  logging::add_common_attributes();
}

int
main (int argc, char **argv)
{
  sigset_t mask;
  std::shared_ptr <SignalHandler> signalHandler;
  std::shared_ptr<Transport> transport;
  boost::property_tree::ptree config;
  std::string confFile;
  std::string path, logs_path, modulesConfigPath;

  kms_init_dependencies (argc, argv);

  try {
    boost::program_options::options_description desc ("kurento-media-server usage");

    desc.add_options()
    ("help,h", "Display this help message")
    ("version,v", "Display the version number")
    ("list,l", "Lists all available factories")
    ("modules-path,p", boost::program_options::value<std::string>
     (&path), "Path where kurento modules can be found")
    ("conf-file,f", boost::program_options::value<std::string>
     (&confFile)->default_value (DEFAULT_CONFIG_FILE),
     "Configuration file location")
    ("logs-path,d", boost::program_options::value <std::string> (&logs_path),
     "Path where debug files will be stored")
    ("modules-config-path,c",
     boost::program_options::value <std::string> (&modulesConfigPath),
     "Path where modules config files can be found");

    boost::program_options::command_line_parser clp (argc, argv);
    clp.options (desc).allow_unregistered();
    boost::program_options::variables_map vm;
    auto parsed = clp.run();
    boost::program_options::store (parsed, vm);

    boost::program_options::store (boost::program_options::parse_environment (desc,
    [&desc] (std::string & input) -> std::string {
      /* Look for KURENTO_ prefix and change to lower case */
      if (input.find (ENV_PREFIX) == 0)
      {
        std::string aux = input.substr (ENV_PREFIX.size() );
        std::transform (aux.begin(), aux.end(), aux.begin(), [] (int c) -> int {
          return (c == '_') ? '-' : tolower (c);
        });

        if (!desc.find_nothrow (aux, false) ) {
          return "";
        }

        return aux;
      }

      return "";
    }), vm);

    boost::program_options::notify (vm);

    if (vm.count ("logs-path") ) {
      if (kms_init_logging (logs_path) ) {
        GST_DEBUG ("Dumping logs to %s", logs_path.c_str() );
      } else {
        GST_WARNING ("Can no set debugging path %s", logs_path.c_str() );
      }
    }

    if (vm.count ("help") ) {
      std::cout << desc << "\n";
      exit (0);
    }

    if (vm.count ("version") || vm.count ("list") ) {
      // Disable log to just print version
      gst_debug_remove_log_function_by_data (NULL);
    }

    loadModules (path);

    if (vm.count ("list") ) {
      std::cout << "Available factories:" << std::endl;

      for (auto it : kurento::getModuleManager().getLoadedFactories() ) {
        std::cout << "\t" << it.first << std::endl;
      }

      exit (0);
    }

    if (vm.count ("version") ) {
      print_version();
      exit (0);
    }

  } catch (boost::program_options::error &e) {
    std::cerr <<  "Error : " << e.what() << std::endl;
    exit (1);
  }

  /* Install our signal handler */
  sigemptyset (&mask);
  sigaddset (&mask, SIGINT);
  sigaddset (&mask, SIGTERM);
  sigaddset (&mask, SIGSEGV);
  sigaddset (&mask, SIGPIPE);
  signalHandler = std::shared_ptr <SignalHandler> (new SignalHandler (mask,
                  signal_handler) );

  GST_INFO ("Kmsc version: %s", get_version () );

  transport = load_config (config, confFile, modulesConfigPath);

  /* Start transport */
  transport->start ();

  GST_INFO ("Mediaserver started");

  loop->run ();

  transport->stop();

  GST_INFO ("Mediaserver stopped");

  return 0;
}
<|endoftext|>