<commit_before>#include <bashclass/BScope.h>
#include <bashclass/BFunction.h>
#include <bashclass/BGlobal.h>
#include <bashclass/BClass.h>
#include <bashclass/BWhile.h>
#include <bashclass/BIf.h>
#include <bashclass/BashClass.h>
#include <sstream>

std::shared_ptr<BScope> BScope::createClass(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto classComp = std::make_shared<BClass>();
    classComp->setParentScope(shared_from_this());
    classComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=classComp;
    return classComp;
}

std::shared_ptr<BScope> BScope::createFunction(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto functionComp = std::make_shared<BFunction>();
    functionComp->setParentScope(shared_from_this());
    functionComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=functionComp;
    return functionComp;
}

std::shared_ptr<BScope> BScope::createWhile(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto whileComp = std::make_shared<BWhile>();
    whileComp->setParentScope(shared_from_this());
    whileComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=whileComp;
    return whileComp;
}

std::shared_ptr<BScope> BScope::createIf(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto ifComp = std::make_shared<BIf>();
    ifComp->setParentScope(shared_from_this());
    ifComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=ifComp;
    return ifComp;
}

std::shared_ptr<BVariable> BScope::createVariable(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto variableComp = std::make_shared<BVariable>();
    variableComp->setParentScope(shared_from_this());
    variableComp->setLexicalToken(lexicalToken);
    m_variables[lexicalToken->getUID()]=variableComp;
    return variableComp;
}

std::vector<std::shared_ptr<BVariable>> BScope::findAllVariables(const char* name) {
    std::vector<std::shared_ptr<BVariable>> variables;
    for(auto variable : m_variables) {
        if(!name || variable.second->getName() == name) {
            variables.push_back(variable.second);
        }
    }
    return variables;
}

std::vector<std::shared_ptr<BVariable>> BScope::findAllParameters(char *name) {
    std::vector<std::shared_ptr<BVariable>> parameters;
    for(auto variable : m_variables) {
        if(variable.second->isParam() && (!name || variable.second->getName() == name)) {
            parameters.push_back(variable.second);
        }
    }
    return parameters;
}

std::vector<std::shared_ptr<BScope>> BScope::findAllClasses(const char* name) {
    std::vector<std::shared_ptr<BScope>> classes;
    for(auto scope : m_scopes) {
        std::shared_ptr<BClass> classScope = std::dynamic_pointer_cast<BClass>(scope.second);
        if(classScope && (!name || classScope->getName() == name)) {
            classes.push_back(classScope);
        }
    }
    return classes;
}

std::vector<std::shared_ptr<BScope>> BScope::findAllFunctions(const char *name) {
    std::vector<std::shared_ptr<BScope>> functions;
    for(auto scope : m_scopes) {
        std::shared_ptr<BFunction> functionScope = std::dynamic_pointer_cast<BFunction>(scope.second);
        if(functionScope && (!name || functionScope->getName() == name)) {
            functions.push_back(functionScope);
        }
    }
    return functions;
}

std::shared_ptr<BScope> BScope::getScope(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    if(m_scopes.find(lexicalToken->getUID()) != m_scopes.end()) {
        return m_scopes[lexicalToken->getUID()];
    }
    return nullptr;
}

std::shared_ptr<BVariable> BScope::getVariable(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    if(m_variables.find(lexicalToken->getUID()) != m_variables.end()) {
        return m_variables[lexicalToken->getUID()];
    }
    return nullptr;
}

std::stringstream BScope::getStructure() {
    std::stringstream structure;
    std::stack<std::shared_ptr<BScope>> structureStack;
    structureStack.push(shared_from_this());
    while(!structureStack.empty()) {

        // Get the top of the stack
        std::shared_ptr<BScope> top = structureStack.top();
        structureStack.pop();

        // Cast the top pointer
        auto castGlobal = std::dynamic_pointer_cast<BGlobal>(top);
        auto castClass = std::dynamic_pointer_cast<BClass>(top);
        auto castFunction = std::dynamic_pointer_cast<BFunction>(top);

        // Get corresponding information
        if(castClass) {
            structure << "class: " << castClass->getName() << ". Label: " << castClass->getLabel().str() << std::endl;
        } else if(castFunction) {
            structure << "function: " << castFunction->getName() << " : " << castFunction->getType() <<
            ". Label: " << castFunction->getLabel().str() << std::endl;
        } else if(castGlobal) {
            structure << "global" << std::endl;
        }

        // Get all variables
        for(auto variable : top->findAllVariables()) {
            structure << "variable" << (variable->isParam() ? "[P]" : "") << ": " << variable->getName()
            << " : " << variable->getType() << ". Label: " << variable->getLabel().str() << std::endl;
        }

        if(castGlobal || castClass || castFunction) {
            // Push all the children scopes
            for(auto scope : top->m_scopes) {
                structureStack.push(scope.second);
            }
        }
    }
    return structure;
}<commit_msg>Added new scopes to get structure<commit_after>#include <bashclass/BScope.h>
#include <bashclass/BFunction.h>
#include <bashclass/BGlobal.h>
#include <bashclass/BClass.h>
#include <bashclass/BWhile.h>
#include <bashclass/BIf.h>
#include <bashclass/BashClass.h>
#include <sstream>

std::shared_ptr<BScope> BScope::createClass(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto classComp = std::make_shared<BClass>();
    classComp->setParentScope(shared_from_this());
    classComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=classComp;
    return classComp;
}

std::shared_ptr<BScope> BScope::createFunction(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto functionComp = std::make_shared<BFunction>();
    functionComp->setParentScope(shared_from_this());
    functionComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=functionComp;
    return functionComp;
}

std::shared_ptr<BScope> BScope::createWhile(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto whileComp = std::make_shared<BWhile>();
    whileComp->setParentScope(shared_from_this());
    whileComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=whileComp;
    return whileComp;
}

std::shared_ptr<BScope> BScope::createIf(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto ifComp = std::make_shared<BIf>();
    ifComp->setParentScope(shared_from_this());
    ifComp->setLexicalToken(lexicalToken);
    m_scopes[lexicalToken->getUID()]=ifComp;
    return ifComp;
}

std::shared_ptr<BVariable> BScope::createVariable(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    auto variableComp = std::make_shared<BVariable>();
    variableComp->setParentScope(shared_from_this());
    variableComp->setLexicalToken(lexicalToken);
    m_variables[lexicalToken->getUID()]=variableComp;
    return variableComp;
}

std::vector<std::shared_ptr<BVariable>> BScope::findAllVariables(const char* name) {
    std::vector<std::shared_ptr<BVariable>> variables;
    for(auto variable : m_variables) {
        if(!name || variable.second->getName() == name) {
            variables.push_back(variable.second);
        }
    }
    return variables;
}

std::vector<std::shared_ptr<BVariable>> BScope::findAllParameters(char *name) {
    std::vector<std::shared_ptr<BVariable>> parameters;
    for(auto variable : m_variables) {
        if(variable.second->isParam() && (!name || variable.second->getName() == name)) {
            parameters.push_back(variable.second);
        }
    }
    return parameters;
}

std::vector<std::shared_ptr<BScope>> BScope::findAllClasses(const char* name) {
    std::vector<std::shared_ptr<BScope>> classes;
    for(auto scope : m_scopes) {
        std::shared_ptr<BClass> classScope = std::dynamic_pointer_cast<BClass>(scope.second);
        if(classScope && (!name || classScope->getName() == name)) {
            classes.push_back(classScope);
        }
    }
    return classes;
}

std::vector<std::shared_ptr<BScope>> BScope::findAllFunctions(const char *name) {
    std::vector<std::shared_ptr<BScope>> functions;
    for(auto scope : m_scopes) {
        std::shared_ptr<BFunction> functionScope = std::dynamic_pointer_cast<BFunction>(scope.second);
        if(functionScope && (!name || functionScope->getName() == name)) {
            functions.push_back(functionScope);
        }
    }
    return functions;
}

std::shared_ptr<BScope> BScope::getScope(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    if(m_scopes.find(lexicalToken->getUID()) != m_scopes.end()) {
        return m_scopes[lexicalToken->getUID()];
    }
    return nullptr;
}

std::shared_ptr<BVariable> BScope::getVariable(std::shared_ptr<ecc::LexicalToken> lexicalToken) {
    if(m_variables.find(lexicalToken->getUID()) != m_variables.end()) {
        return m_variables[lexicalToken->getUID()];
    }
    return nullptr;
}

std::stringstream BScope::getStructure() {
    std::stringstream structure;
    std::stack<std::shared_ptr<BScope>> structureStack;
    structureStack.push(shared_from_this());
    while(!structureStack.empty()) {

        // Get the top of the stack
        std::shared_ptr<BScope> top = structureStack.top();
        structureStack.pop();

        // Cast the top pointer
        auto castGlobal = std::dynamic_pointer_cast<BGlobal>(top);
        auto castClass = std::dynamic_pointer_cast<BClass>(top);
        auto castFunction = std::dynamic_pointer_cast<BFunction>(top);
        auto castWhile = std::dynamic_pointer_cast<BWhile>(top);
        auto castIf = std::dynamic_pointer_cast<BIf>(top);

        // Get corresponding information
        if(castClass) {
            structure << "class: " << castClass->getName() << ". Label: " << castClass->getLabel().str() << std::endl;
        } else if(castFunction) {
            structure << "function: " << castFunction->getName() << " : " << castFunction->getType() <<
            ". Label: " << castFunction->getLabel().str() << std::endl;
        } else if(castGlobal) {
            structure << "global" << std::endl;
        } else if(castWhile) {
            structure << "while. Label: " << castWhile->getLabel().str() << std::endl;
        } else if(castIf) {
            structure << "if. Label: " << castIf->getLabel().str() << std::endl;
        }

        // Get all variables
        for(auto variable : top->findAllVariables()) {
            structure << "variable" << (variable->isParam() ? "[P]" : "") << ": " << variable->getName()
            << " : " << variable->getType() << ". Label: " << variable->getLabel().str() << std::endl;
        }

        if(castGlobal || castClass || castFunction || castWhile || castIf) {
            // Push all the children scopes
            for(auto scope : top->m_scopes) {
                structureStack.push(scope.second);
            }
        }
    }
    return structure;
}<|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CONTAINERS_BITSET_HPP_
#define CONTAINERS_BITSET_HPP_

#include <stdint.h>

#include <vector>

#include "utils.hpp"

class bitset_t {
private:
    size_t _count, _size;
    std::vector<uint64_t> bits;

    void set_without_updating_count(unsigned int place, bool value) {
        rassert(place < size());
        if (value) {
            bits[place / 64] |= (uint64_t(1) << (place % 64));
        } else {
            bits[place / 64] &= ~(uint64_t(1) << (place % 64));
        }
    }

public:
    bitset_t() {
        _size = 0;
        _count = 0;
    }

    explicit bitset_t(size_t size) {
        bits.resize(ceil_aligned(size, 64) / 64, 0);
        _size = size;
        _count = 0;
    }

public:
    bool operator[](unsigned int place) const {
        return test(place);
    }

    bool test(unsigned int place) const {
        rassert(place < size(), "place=%u, size=%zu", place, size());
        return bits[place / 64] & (uint64_t(1) << (place % 64));
    }

    void set() {
        for (unsigned int i = 0; i < size(); i++) {
            set(i);
        }
    }

    void set(unsigned int place, bool value = true) {
        rassert(place < size());
        if (value) {
            if (!test(place)) _count++;
        } else {
            if (test(place)) _count--;
        }
        set_without_updating_count(place, value);
    }

    size_t size() const {
        return _size;
    }

    void reserve(size_t size) {
        bits.reserve(ceil_aligned(size, 64) / 64);
    }

    void resize(size_t new_size, bool value = false) {

        size_t old_size = _size;

        /* Update the count to no longer include any bits that we will chop off */
        for (size_t i = new_size; i < old_size; i++) {
            if (test(i)) _count--;
        }

        /* Actually resize the bitset */
        bits.resize(ceil_aligned(new_size, 64) / 64, value ? 0xFFFFFFFFFFFFFFFF : 0);
        _size = new_size;

        /* `std::vector::resize()` correctly initialized any new chunks, but we must correctly set
        the upper bits of the highest old chunk. For example, suppose that we grow from size 60 to
        68 and `value` is `true`. A new 64-bit chunk will be added, and it will contain all 1s,
        which is correct. However, the contents of the top 4 bits of the old 64-bit chunk were
        garbage and we don't know what their values are, so we must manually set them. */
        for (size_t i = old_size; i < new_size && i % 64 != 0; i++) {
            set_without_updating_count(i, value);
        }

        /* Update the count to take into account any new bits we set */
        if (value && new_size > old_size) _count += new_size - old_size;
    }

    size_t count() const {
        return _count;
    }

    /* Just for debugging; makes sure that `_count` is in agreement with the actual bit
    values */
    void verify() const {
        unsigned c = 0;
        for (unsigned i = 0; i < _size; i++) {
            if (test(i)) c++;
        }
        rassert(c == _count);
    }
};

#endif /* CONTAINERS_BITSET_HPP_ */
<commit_msg>I added a word-size specification that old versions of gcc on i386 require.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CONTAINERS_BITSET_HPP_
#define CONTAINERS_BITSET_HPP_

#include <stdint.h>

#include <vector>

#include "utils.hpp"

class bitset_t {
private:
    size_t _count, _size;
    std::vector<uint64_t> bits;

    void set_without_updating_count(unsigned int place, bool value) {
        rassert(place < size());
        if (value) {
            bits[place / 64] |= (uint64_t(1) << (place % 64));
        } else {
            bits[place / 64] &= ~(uint64_t(1) << (place % 64));
        }
    }

public:
    bitset_t() {
        _size = 0;
        _count = 0;
    }

    explicit bitset_t(size_t size) {
        bits.resize(ceil_aligned(size, 64) / 64, 0);
        _size = size;
        _count = 0;
    }

public:
    bool operator[](unsigned int place) const {
        return test(place);
    }

    bool test(unsigned int place) const {
        rassert(place < size(), "place=%u, size=%zu", place, size());
        return bits[place / 64] & (uint64_t(1) << (place % 64));
    }

    void set() {
        for (unsigned int i = 0; i < size(); i++) {
            set(i);
        }
    }

    void set(unsigned int place, bool value = true) {
        rassert(place < size());
        if (value) {
            if (!test(place)) _count++;
        } else {
            if (test(place)) _count--;
        }
        set_without_updating_count(place, value);
    }

    size_t size() const {
        return _size;
    }

    void reserve(size_t size) {
        bits.reserve(ceil_aligned(size, 64) / 64);
    }

    void resize(size_t new_size, bool value = false) {

        size_t old_size = _size;

        /* Update the count to no longer include any bits that we will chop off */
        for (size_t i = new_size; i < old_size; i++) {
            if (test(i)) _count--;
        }

        /* Actually resize the bitset */
        bits.resize(ceil_aligned(new_size, 64) / 64, value ? 0xFFFFFFFFFFFFFFFFULL : 0);
        _size = new_size;

        /* `std::vector::resize()` correctly initialized any new chunks, but we must correctly set
        the upper bits of the highest old chunk. For example, suppose that we grow from size 60 to
        68 and `value` is `true`. A new 64-bit chunk will be added, and it will contain all 1s,
        which is correct. However, the contents of the top 4 bits of the old 64-bit chunk were
        garbage and we don't know what their values are, so we must manually set them. */
        for (size_t i = old_size; i < new_size && i % 64 != 0; i++) {
            set_without_updating_count(i, value);
        }

        /* Update the count to take into account any new bits we set */
        if (value && new_size > old_size) _count += new_size - old_size;
    }

    size_t count() const {
        return _count;
    }

    /* Just for debugging; makes sure that `_count` is in agreement with the actual bit
    values */
    void verify() const {
        unsigned c = 0;
        for (unsigned i = 0; i < _size; i++) {
            if (test(i)) c++;
        }
        rassert(c == _count);
    }
};

#endif /* CONTAINERS_BITSET_HPP_ */
<|endoftext|>


<commit_before>
/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkColorTable.h"
#include "SkFlattenableBuffers.h"
#include "SkStream.h"
#include "SkTemplates.h"

SK_DEFINE_INST_COUNT(SkColorTable)

SkColorTable::SkColorTable(int count)
    : f16BitCache(NULL), fFlags(0)
{
    if (count < 0)
        count = 0;
    else if (count > 256)
        count = 256;

    fCount = SkToU16(count);
    fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
    memset(fColors, 0, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

// As copy constructor is hidden in the class hierarchy, we need to call
// default constructor explicitly to suppress a compiler warning.
SkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() {
    f16BitCache = NULL;
    fFlags = src.fFlags;
    int count = src.count();
    fCount = SkToU16(count);
    fColors = reinterpret_cast<SkPMColor*>(
                                    sk_malloc_throw(count * sizeof(SkPMColor)));
    memcpy(fColors, src.fColors, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

SkColorTable::SkColorTable(const SkPMColor colors[], int count)
    : f16BitCache(NULL), fFlags(0)
{
    if (count < 0)
        count = 0;
    else if (count > 256)
        count = 256;

    fCount = SkToU16(count);
    fColors = reinterpret_cast<SkPMColor*>(
                                    sk_malloc_throw(count * sizeof(SkPMColor)));

    if (colors)
        memcpy(fColors, colors, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

SkColorTable::~SkColorTable()
{
    SkASSERT(fColorLockCount == 0);
    SkASSERT(f16BitCacheLockCount == 0);

    sk_free(fColors);
    sk_free(f16BitCache);
}

void SkColorTable::setFlags(unsigned flags)
{
    fFlags = SkToU8(flags);
}

void SkColorTable::unlockColors(bool changed)
{
    SkASSERT(fColorLockCount != 0);
    SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);)
    if (changed)
        this->inval16BitCache();
}

void SkColorTable::inval16BitCache()
{
    SkASSERT(f16BitCacheLockCount == 0);
    if (f16BitCache)
    {
        sk_free(f16BitCache);
        f16BitCache = NULL;
    }
}

#include "SkColorPriv.h"

static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
{
    while (--count >= 0)
        *dst++ = SkPixel32ToPixel16_ToU16(*src++);
}

const uint16_t* SkColorTable::lock16BitCache()
{
    if (fFlags & kColorsAreOpaque_Flag)
    {
        if (f16BitCache == NULL) // build the cache
        {
            f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
            build_16bitcache(f16BitCache, fColors, fCount);
        }
    }
    else    // our colors have alpha, so no cache
    {
        this->inval16BitCache();
        if (f16BitCache)
        {
            sk_free(f16BitCache);
            f16BitCache = NULL;
        }
    }

    SkDEBUGCODE(f16BitCacheLockCount += 1);
    return f16BitCache;
}

void SkColorTable::setIsOpaque(bool isOpaque) {
    if (isOpaque) {
        fFlags |= kColorsAreOpaque_Flag;
    } else {
        fFlags &= ~kColorsAreOpaque_Flag;
    }
}

///////////////////////////////////////////////////////////////////////////////

SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
    f16BitCache = NULL;
    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)

    fFlags = buffer.readUInt();
    fCount = buffer.getArrayCount();
    fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
    const uint32_t countRead = buffer.readColorArray(fColors);
    SkASSERT((unsigned)fCount <= 256);
    SkASSERT(countRead == fCount);
}

void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
    buffer.writeUInt(fFlags);
    buffer.writeColorArray(fColors, fCount);
}
<commit_msg>Fix warning-as-error for var used only in an assert (and therefore not in the release build).<commit_after>
/*
 * Copyright 2009 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkColorTable.h"
#include "SkFlattenableBuffers.h"
#include "SkStream.h"
#include "SkTemplates.h"

SK_DEFINE_INST_COUNT(SkColorTable)

SkColorTable::SkColorTable(int count)
    : f16BitCache(NULL), fFlags(0)
{
    if (count < 0)
        count = 0;
    else if (count > 256)
        count = 256;

    fCount = SkToU16(count);
    fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
    memset(fColors, 0, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

// As copy constructor is hidden in the class hierarchy, we need to call
// default constructor explicitly to suppress a compiler warning.
SkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() {
    f16BitCache = NULL;
    fFlags = src.fFlags;
    int count = src.count();
    fCount = SkToU16(count);
    fColors = reinterpret_cast<SkPMColor*>(
                                    sk_malloc_throw(count * sizeof(SkPMColor)));
    memcpy(fColors, src.fColors, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

SkColorTable::SkColorTable(const SkPMColor colors[], int count)
    : f16BitCache(NULL), fFlags(0)
{
    if (count < 0)
        count = 0;
    else if (count > 256)
        count = 256;

    fCount = SkToU16(count);
    fColors = reinterpret_cast<SkPMColor*>(
                                    sk_malloc_throw(count * sizeof(SkPMColor)));

    if (colors)
        memcpy(fColors, colors, count * sizeof(SkPMColor));

    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)
}

SkColorTable::~SkColorTable()
{
    SkASSERT(fColorLockCount == 0);
    SkASSERT(f16BitCacheLockCount == 0);

    sk_free(fColors);
    sk_free(f16BitCache);
}

void SkColorTable::setFlags(unsigned flags)
{
    fFlags = SkToU8(flags);
}

void SkColorTable::unlockColors(bool changed)
{
    SkASSERT(fColorLockCount != 0);
    SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);)
    if (changed)
        this->inval16BitCache();
}

void SkColorTable::inval16BitCache()
{
    SkASSERT(f16BitCacheLockCount == 0);
    if (f16BitCache)
    {
        sk_free(f16BitCache);
        f16BitCache = NULL;
    }
}

#include "SkColorPriv.h"

static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
{
    while (--count >= 0)
        *dst++ = SkPixel32ToPixel16_ToU16(*src++);
}

const uint16_t* SkColorTable::lock16BitCache()
{
    if (fFlags & kColorsAreOpaque_Flag)
    {
        if (f16BitCache == NULL) // build the cache
        {
            f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
            build_16bitcache(f16BitCache, fColors, fCount);
        }
    }
    else    // our colors have alpha, so no cache
    {
        this->inval16BitCache();
        if (f16BitCache)
        {
            sk_free(f16BitCache);
            f16BitCache = NULL;
        }
    }

    SkDEBUGCODE(f16BitCacheLockCount += 1);
    return f16BitCache;
}

void SkColorTable::setIsOpaque(bool isOpaque) {
    if (isOpaque) {
        fFlags |= kColorsAreOpaque_Flag;
    } else {
        fFlags &= ~kColorsAreOpaque_Flag;
    }
}

///////////////////////////////////////////////////////////////////////////////

SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
    f16BitCache = NULL;
    SkDEBUGCODE(fColorLockCount = 0;)
    SkDEBUGCODE(f16BitCacheLockCount = 0;)

    fFlags = buffer.readUInt();
    fCount = buffer.getArrayCount();
    fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
    SkDEBUGCODE(const uint32_t countRead =) buffer.readColorArray(fColors);
#ifdef SK_DEBUG
    SkASSERT((unsigned)fCount <= 256);
    SkASSERT(countRead == fCount);
#endif
}

void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
    buffer.writeUInt(fFlags);
    buffer.writeColorArray(fColors, fCount);
}
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_FUNCTION_NORM_HH
#define DUNE_STUFF_FUNCTION_NORM_HH

#include "interfaces.hh"

#if HAVE_DUNE_FEM
# include <dune/fem/function/common/discretefunction.hh>
# include <dune/fem/misc/l2norm.hh>
# include <dune/fem/misc/h1norm.hh>
#endif

namespace Dune {
namespace Stuff {

#if HAVE_DUNE_FEM
template <class TraitsType>
static typename TraitsType::RangeFieldType l2norm(const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function)
{
  return Dune::Fem::L2Norm<typename TraitsType::DiscreteFunctionType::GridPartType>(function.space().gridPart()).norm(function);
}

template <class FunctionType_A, class TraitsType>
typename TraitsType::RangeFieldType l2distance(const FunctionType_A& function_A, const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function_B)
{
  static_assert(std::is_base_of<Dune::Fem::HasLocalFunction, FunctionType_A>::value, "");
  Dune::Fem::L2Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function_B.space().gridPart());
  return norm.distance(function_A, function_B);
}

template <class TraitsType>
static typename TraitsType::RangeFieldType h1norm(const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function)
{
  const Dune::Fem::H1Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function.space().gridPart());
  return norm.norm(function);
}

template <class FunctionType_A, class TraitsType>
typename TraitsType::RangeFieldType h1distance(const FunctionType_A& function_A, const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function_B)
{
  static_assert(std::is_base_of<Dune::Fem::HasLocalFunction, FunctionType_A>::value, "");
  Dune::Fem::H1Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function_B.space().gridPart());
  return norm.distance(function_A, function_B);
}
#endif

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTION_NORM_HH
<commit_msg>[functions] (faulty) l2/h1 distances for mixed stuff/fem/pdelab pairs<commit_after>#ifndef DUNE_STUFF_FUNCTION_NORM_HH
#define DUNE_STUFF_FUNCTION_NORM_HH

#include "interfaces.hh"

#if HAVE_DUNE_FEM
# include <dune/fem/function/common/discretefunction.hh>
# include <dune/fem/misc/l2norm.hh>
# include <dune/fem/misc/h1norm.hh>
#endif

#if HAVE_DUNE_PDELAB
# include <dune/pdelab/test/l2difference.hh>
# include <dune/pdelab/common/functionwrappers.hh>
# include <dune/pdelab/common/functionutilities.hh>
# include <dune/stuff/functions/pdelabadapter.hh>
#endif

namespace Dune {
namespace PDELab {
template<typename GFS, typename C>
class ISTLBlockVectorContainer;

} //namespace PDELab

namespace Stuff {

#if HAVE_DUNE_PDELAB
template <class FunctionType_A, class GFS, class C>
typename GFS::Traits::FiniteElementType::Traits::LocalBasisType::Traits::RangeFieldType
l2distance(const FunctionType_A& function_A, const PDELab::ISTLBlockVectorContainer<GFS,C>& function_B)
{
  using namespace PDELab;
  typedef DiscreteGridFunction<GFS,ISTLBlockVectorContainer<GFS,C>> DGF;
  DGF disc(function_B.gridFunctionSpace(), function_B);

  const auto grid_f = pdelabAdapted(function_A, function_B.gridFunctionSpace().gridView());
  typedef DifferenceSquaredAdapter<decltype(grid_f), DGF> DifferenceSquared;
  DifferenceSquared differencesquared(grid_f,disc);
  typename DifferenceSquared::Traits::RangeType l2errorsquared(0.0);
  const int magic_number_order = 8;
  integrateGridFunction(differencesquared, l2errorsquared, magic_number_order);
  return sqrt(l2errorsquared);
}

template <class FunctionType_A, class GFS, class C>
typename GFS::Traits::FiniteElementType::Traits::LocalBasisType::Traits::RangeFieldType
h1distance(const FunctionType_A& function_A, const PDELab::ISTLBlockVectorContainer<GFS,C>& function_B)
{
//  static_assert(std::is_base_of<Dune::Fem::HasLocalFunction, FunctionType_A>::value, "");
  using namespace PDELab;
  typedef DiscreteGridFunction<GFS,ISTLBlockVectorContainer<GFS,C>> DGF;
  DGF disc(function_B.gridFunctionSpace(), function_B);

  const auto grid_f = pdelabAdapted(function_A, function_B.gridFunctionSpace().gridView());
  typedef H1DifferenceSquaredAdapter<decltype(grid_f), PDELab::ISTLBlockVectorContainer<GFS,C>, GFS> H1DifferenceSquared;
  H1DifferenceSquared h1_difference_squared(grid_f, function_B);
  typename H1DifferenceSquared::Traits::RangeType value(0.0);
  const int magic_number_order = 8;
  integrateGridFunction(h1_difference_squared, value, magic_number_order);
  return std::sqrt(value);
}
#endif // HAVE_DUNE_PDELAB

#if HAVE_DUNE_FEM
template <class TraitsType>
static typename TraitsType::RangeFieldType l2norm(const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function)
{
  return Dune::Fem::L2Norm<typename TraitsType::DiscreteFunctionType::GridPartType>(function.space().gridPart()).norm(function);
}

template <class FunctionType_A, class TraitsType>
typename TraitsType::RangeFieldType l2distance(const FunctionType_A& function_A, const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function_B)
{
  static_assert(std::is_base_of<Dune::Fem::HasLocalFunction, FunctionType_A>::value, "");
  Dune::Fem::L2Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function_B.space().gridPart());
  return norm.distance(function_A, function_B);
}

template <class TraitsType>
static typename TraitsType::RangeFieldType h1norm(const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function)
{
  const Dune::Fem::H1Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function.space().gridPart());
  return norm.norm(function);
}

template <class FunctionType_A, class TraitsType>
typename TraitsType::RangeFieldType h1distance(const FunctionType_A& function_A, const Dune::Fem::DiscreteFunctionInterface<TraitsType>& function_B)
{
  static_assert(std::is_base_of<Dune::Fem::HasLocalFunction, FunctionType_A>::value, "");
  Dune::Fem::H1Norm<typename TraitsType::DiscreteFunctionType::GridPartType> norm(function_B.space().gridPart());
  return norm.distance(function_A, function_B);
}
#endif

} // namespace Stuff
} // namespace Dune

#endif // DUNE_STUFF_FUNCTION_NORM_HH
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#include <boost/regex.hpp>

#include <osquery/core.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/tables.h>

#include "osquery/tables/system/windows/registry.h"

namespace osquery {
namespace tables {

void keyEnumPrograms(const std::string& key,
                     std::set<std::string>& processed,
                     QueryData& results) {
  QueryData regResults;
  queryKey(key, regResults);
  for (const auto& rKey : regResults) {
    // Each subkey represents a program, skip if not a subkey
    if (rKey.at("type") != "subkey") {
      continue;
    }

    // Ensure we only process each program one time
    const auto& fullProgramName = rKey.at("path");
    if (processed.find(fullProgramName) != processed.end()) {
      continue;
    }
    processed.insert(fullProgramName);

    // Query additional information about the program
    QueryData appResults;
    queryKey(fullProgramName, appResults);
    Row r;

    // Attempt to derive the program identifying GUID
    std::string identifyingNumber;
    boost::smatch matches;
    boost::regex expression(
        "({[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+})"
        "$");
    if (boost::regex_search(fullProgramName, matches, expression)) {
      identifyingNumber = matches[0];
      r["identifying_number"] = identifyingNumber;
    }

    for (const auto& aKey : appResults) {
      auto name = aKey.find("name");
      if (identifyingNumber.empty() && name->second == "BundleIdentifier") {
        r["identifying_number"] = aKey.at("data");
      }
      if (name->second == "DisplayName") {
        r["name"] = aKey.at("data");
      }
      if (name->second == "DisplayVersion") {
        r["version"] = aKey.at("data");
      }
      if (name->second == "InstallLocation") {
        r["install_location"] = aKey.at("data");
      }
      if (name->second == "InstallSource") {
        r["install_source"] = aKey.at("data");
      }
      if (name->second == "Language") {
        r["language"] = aKey.at("data");
      }
      if (name->second == "Publisher") {
        r["publisher"] = aKey.at("data");
      }
      if (name->second == "UninstallString") {
        r["uninstall_string"] = aKey.at("data");
      }
      if (name->second == "InstallDate") {
        r["install_date"] = aKey.at("data");
      }
    }
    results.push_back(r);
  }
}

QueryData genPrograms(QueryContext& context) {
  QueryData results;

  std::set<std::string> programKeys = {
      "HKEY_LOCAL_"
      "MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
      "HKEY_LOCAL_"
      "MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
      "stall",
  };

  std::set<std::string> userProgramKeys;
  expandRegistryGlobs(
      "HKEY_USERS\\%\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
      userProgramKeys);
  programKeys.insert(userProgramKeys.begin(), userProgramKeys.end());

  std::set<std::string> processedPrograms;
  for (const auto& k : programKeys) {
    keyEnumPrograms(k, processedPrograms, results);
  }

  return results;
}
} // namespace tables
} // namespace osquery
<commit_msg>Don't return nil rows for the programs table (#5715)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#include <boost/regex.hpp>

#include <osquery/core.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/tables.h>

#include "osquery/tables/system/windows/registry.h"

namespace osquery {
namespace tables {

void keyEnumPrograms(const std::string& key,
                     std::set<std::string>& processed,
                     QueryData& results) {
  QueryData regResults;
  queryKey(key, regResults);
  for (const auto& rKey : regResults) {
    // Each subkey represents a program, skip if not a subkey
    if (rKey.at("type") != "subkey") {
      continue;
    }

    // Ensure we only process each program one time
    const auto& fullProgramName = rKey.at("path");
    if (processed.find(fullProgramName) != processed.end()) {
      continue;
    }
    processed.insert(fullProgramName);

    // Query additional information about the program
    QueryData appResults;
    queryKey(fullProgramName, appResults);
    Row r;

    // Attempt to derive the program identifying GUID
    std::string identifyingNumber;
    boost::smatch matches;
    boost::regex expression(
        "({[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+-[a-fA-F0-9]+})"
        "$");
    if (boost::regex_search(fullProgramName, matches, expression)) {
      identifyingNumber = matches[0];
      r["identifying_number"] = identifyingNumber;
    }

    for (const auto& aKey : appResults) {
      auto name = aKey.find("name");
      if (identifyingNumber.empty() && name->second == "BundleIdentifier") {
        r["identifying_number"] = aKey.at("data");
      }
      if (name->second == "DisplayName") {
        r["name"] = aKey.at("data");
      }
      if (name->second == "DisplayVersion") {
        r["version"] = aKey.at("data");
      }
      if (name->second == "InstallLocation") {
        r["install_location"] = aKey.at("data");
      }
      if (name->second == "InstallSource") {
        r["install_source"] = aKey.at("data");
      }
      if (name->second == "Language") {
        r["language"] = aKey.at("data");
      }
      if (name->second == "Publisher") {
        r["publisher"] = aKey.at("data");
      }
      if (name->second == "UninstallString") {
        r["uninstall_string"] = aKey.at("data");
      }
      if (name->second == "InstallDate") {
        r["install_date"] = aKey.at("data");
      }
    }
    if (!r.empty()) {
      results.push_back(r);
    }
  }
}

QueryData genPrograms(QueryContext& context) {
  QueryData results;

  std::set<std::string> programKeys = {
      "HKEY_LOCAL_"
      "MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
      "HKEY_LOCAL_"
      "MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
      "stall",
  };

  std::set<std::string> userProgramKeys;
  expandRegistryGlobs(
      "HKEY_USERS\\%\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
      userProgramKeys);
  programKeys.insert(userProgramKeys.begin(), userProgramKeys.end());

  std::set<std::string> processedPrograms;
  for (const auto& k : programKeys) {
    keyEnumPrograms(k, processedPrograms, results);
  }

  return results;
}
} // namespace tables
} // namespace osquery
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int p;

int main() {

  scanf("%d", &p);

  return 0;
}

<commit_msg> initial version of c modular roots<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>

using namespace std;

const int maxn = 5000009;
long long p, root;
long long n, k;
long long h[maxn];
int cnt;
long long output[maxn];

long long exp(long long a, long long b);
long long gcd(long long a, long long b) {
  while (a && b) b ^= a ^= b ^= a = a%b;

  return a+b;
}

// http://math.stackexchange.com/questions/124408/finding-a-primitive-root-of-a-prime-number
long long facts[maxn];
int fcnt = 0;
long long primitive_root(long long p) {
  long long s = p - 1;

  long long bd = (long long)sqrt(s)+1;
  for (int i = 2; i < bd; ++ i) {
    if (s % i == 0)
    {
      while (s % i == 0) {
        s /= i;
      }
      facts[fcnt++] = (p-1)/i;
    }
  }

  if (s != 1) {
    facts[fcnt++] = (p-1)/s;
  }

  for (int i = 2; i < p; ++ i) {
    int flag = 1;
    for (int j = 0; j < fcnt; ++ j) {

      if (exp(i, facts[j]) == 1) {
        flag = 0;
        break;
      }

    }

    if (flag) {
      return (long long) i;
    }

  }

  return 0;
}

long long exp(long long a, long long b) {

  long long ret = 1;
  long long base = a;

  while (b) {
    if (b & 1) {
      ret = (ret * base) % p;
    }
    base = base*base % p;
    b >>= 1;
  }

  return ret;
}

long long gcdExtended(long long a, long long b, long long *x, long long *y);

// Function to find modulo inverse of a
long long modInverse(long long a, long long m)
{
    long long x, y;
    long long g = gcdExtended(a, m, &x, &y);
    if (g != 1)
        printf("Inverse doesn't exist");
    else
    {
        // m is added to handle negative x
        long long res = (x%m + m) % m;
        while (res < 0) res += m;
        return res;
    }

    return 0;
}

// C function for extended Euclidean Algorithm
long long gcdExtended(long long a, long long b, long long *x, long long *y)
{
    // Base Case
    if (a == 0)
    {
        *x = 0, *y = 1;
        return b;
    }

    long long x1, y1; // To store results of recursive call
    long long gcd = gcdExtended(b%a, a, &x1, &y1);

    // Update x and y using results of recursive
    // call
    *x = y1 - (b/a) * x1;
    *y = x1;

    return gcd;
}

// http://math.stackexchange.com/questions/158344/how-to-find-the-solutions-for-the-n-th-root-of-unity-in-modular-arithmetic
// http://mathafou.free.fr/themes_en/kcongr.html
void solve(long long k, long long n) {
  while (n < 0) n += p;
  n %= p;
  k %= p-1;

  long long d = gcd(k, p-1);
  long long H = h[(int)n];
  if (H % d != 0) {
    printf("NONE\n");
    return;
  }
  long long K = H/d*modInverse(k/d, (p-1)/d)%((p-1)/d);

  cnt = 0;
  for (int i = 0; i < d; ++ i) {
    K += (p-1)/d;
    output[cnt++] = exp(root, K);
  }

  sort(output, output+cnt);

  for (int i = 0; i < cnt; ++ i) {
    printf("%lld ", output[i]);
  }
  printf("\n");

}

void init() {
  scanf("%lld", &p);
  root = primitive_root(p);

  for (int i = 1; i < p; ++ i) {
    long long e = exp(root, i);
    h[e] = i;
  }

}

int main() {
  init();

  int Q;
  scanf("%d", &Q);

  for (int i = 0; i < Q; ++ i) {
    long long k, n;
    scanf("%lld %lld", &k, &n);
    solve(k, n);
  }

  return 0;
}

<|endoftext|>


<commit_before>#include "signalcenter.h"
#include "dispatchentry.h"

/*!
    \class SignalCenter
    \inmodule QtxCore
    \brief The SignalCenter class provides a mechanism for dispatching
           notifications within an application.
 */

/*!
    Returns a pointer to the application's default SignalCenter instance.
*/
SignalCenter* SignalCenter::instance()
{
    static SignalCenter *center = 0;
    if (!center) {
        center = new SignalCenter();
    }
    return center;
}

/*!
    Constructs a SignalCenter object with the given \a parent.
*/
SignalCenter::SignalCenter(QObject *parent /* = 0 */)
    : QObject(parent),
      mPoster(0)
{
}

/*!
    Destroy the object.
*/
SignalCenter::~SignalCenter()
{
}

/*!
    TODO: \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QString & signal, QObject *receiver, const char *slot)
{
    observe(0, signal, receiver, slot);
}

/*!
    TODO: \a sender \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QObject *sender, const QString & signal,
                           QObject *receiver, const char *slot)
{
    DispatchEntry *entry = new DispatchEntry(sender, signal, receiver, slot);
    mDispatchTable.append(entry);

    QObject::connect(receiver, SIGNAL(destroyed(QObject *)), SLOT(onDestroyed(QObject *)));
}

/*!
    TODO: \a receiver
*/
void SignalCenter::unobserve(const QObject *receiver)
{
    unobserve(0, "", receiver);
}

/*!
    TODO: \a sender \a signal \a receiver
*/
void SignalCenter::unobserve(const QObject *sender, const QString & signal, const QObject *receiver)
{
    QMutableListIterator<DispatchEntry *> itr(mDispatchTable);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if (entry->receiver() == receiver
            && (entry->sender() == sender || !sender)
            && (entry->signal() == signal || signal.isEmpty())) {
            itr.remove();
        }
    }
}

/*!
    TODO: \a sender \a signal \a val0 \a val1 \a val2 \a val3 \a val4 \a val5 \a val6 \a val7 \a val8 \a val9
*/
void SignalCenter::post(QObject *sender, const QString & signal,
                        QGenericArgument val0 /* = QGenericArgument( 0 ) */, QGenericArgument val1 /* = QGenericArgument() */, QGenericArgument val2 /* = QGenericArgument() */, QGenericArgument val3 /* = QGenericArgument() */, QGenericArgument val4 /* = QGenericArgument() */, QGenericArgument val5 /* = QGenericArgument() */, QGenericArgument val6 /* = QGenericArgument() */, QGenericArgument val7 /* = QGenericArgument() */, QGenericArgument val8 /* = QGenericArgument() */, QGenericArgument val9 /* = QGenericArgument() */)
{
    mPoster = sender;

    QList<DispatchEntry *> table(mDispatchTable);
    QMutableListIterator<DispatchEntry *> itr(table);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if ((entry->sender() == sender || !entry->sender())
            && (entry->signal() == signal || entry->signal().isEmpty())) {

            QObject *receiver = entry->receiver();
            const char *slot = entry->slot();
            const QMetaObject* metaReceiver = receiver->metaObject();
            int idx = metaReceiver->indexOfSlot(slot);
            if (idx == -1) {
                continue;
            }
            QMetaMethod method = metaReceiver->method(idx);
            method.invoke(receiver, Qt::DirectConnection, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
        }
    }

    mPoster = 0;
}

/*!
    TODO:
*/
QObject *SignalCenter::poster() const
{
    return mPoster;
}

void SignalCenter::onDestroyed(QObject * obj /* = 0 */)
{
    if (!obj) {
        return;
    }

    unobserve(obj);
}
<commit_msg>ignore: commit to test git subtree.<commit_after>#include "signalcenter.h"
#include "dispatchentry.h"

// TEST: git subtree commit in upstream repo

/*!
    \class SignalCenter
    \inmodule QtxCore
    \brief The SignalCenter class provides a mechanism for dispatching
           notifications within an application.
 */

/*!
    Returns a pointer to the application's default SignalCenter instance.
*/
SignalCenter* SignalCenter::instance()
{
    static SignalCenter *center = 0;
    if (!center) {
        center = new SignalCenter();
    }
    return center;
}

/*!
    Constructs a SignalCenter object with the given \a parent.
*/
SignalCenter::SignalCenter(QObject *parent /* = 0 */)
    : QObject(parent),
      mPoster(0)
{
}

/*!
    Destroy the object.
*/
SignalCenter::~SignalCenter()
{
}

/*!
    TODO: \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QString & signal, QObject *receiver, const char *slot)
{
    observe(0, signal, receiver, slot);
}

/*!
    TODO: \a sender \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QObject *sender, const QString & signal,
                           QObject *receiver, const char *slot)
{
    DispatchEntry *entry = new DispatchEntry(sender, signal, receiver, slot);
    mDispatchTable.append(entry);

    QObject::connect(receiver, SIGNAL(destroyed(QObject *)), SLOT(onDestroyed(QObject *)));
}

/*!
    TODO: \a receiver
*/
void SignalCenter::unobserve(const QObject *receiver)
{
    unobserve(0, "", receiver);
}

/*!
    TODO: \a sender \a signal \a receiver
*/
void SignalCenter::unobserve(const QObject *sender, const QString & signal, const QObject *receiver)
{
    QMutableListIterator<DispatchEntry *> itr(mDispatchTable);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if (entry->receiver() == receiver
            && (entry->sender() == sender || !sender)
            && (entry->signal() == signal || signal.isEmpty())) {
            itr.remove();
        }
    }
}

/*!
    TODO: \a sender \a signal \a val0 \a val1 \a val2 \a val3 \a val4 \a val5 \a val6 \a val7 \a val8 \a val9
*/
void SignalCenter::post(QObject *sender, const QString & signal,
                        QGenericArgument val0 /* = QGenericArgument( 0 ) */, QGenericArgument val1 /* = QGenericArgument() */, QGenericArgument val2 /* = QGenericArgument() */, QGenericArgument val3 /* = QGenericArgument() */, QGenericArgument val4 /* = QGenericArgument() */, QGenericArgument val5 /* = QGenericArgument() */, QGenericArgument val6 /* = QGenericArgument() */, QGenericArgument val7 /* = QGenericArgument() */, QGenericArgument val8 /* = QGenericArgument() */, QGenericArgument val9 /* = QGenericArgument() */)
{
    mPoster = sender;

    QList<DispatchEntry *> table(mDispatchTable);
    QMutableListIterator<DispatchEntry *> itr(table);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if ((entry->sender() == sender || !entry->sender())
            && (entry->signal() == signal || entry->signal().isEmpty())) {

            QObject *receiver = entry->receiver();
            const char *slot = entry->slot();
            const QMetaObject* metaReceiver = receiver->metaObject();
            int idx = metaReceiver->indexOfSlot(slot);
            if (idx == -1) {
                continue;
            }
            QMetaMethod method = metaReceiver->method(idx);
            method.invoke(receiver, Qt::DirectConnection, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
        }
    }

    mPoster = 0;
}

/*!
    TODO:
*/
QObject *SignalCenter::poster() const
{
    return mPoster;
}

void SignalCenter::onDestroyed(QObject * obj /* = 0 */)
{
    if (!obj) {
        return;
    }

    unobserve(obj);
}
<|endoftext|>


<commit_before>#include "crashhandler.hpp"

#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__))
#error "crashhandler_unix.cpp is used on a non-UNIX platform"
#endif

#include <csignal>
#include <cstring>
#include <unistd.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <thread>
#include <atomic>
#include <map>
#include <mutex>
#include <fmt/format.h>

 // Linux/Clang, OSX/Clang, OSX/gcc
#if (defined(__clang__) || defined(__APPLE__))
#include <sys/ucontext.h>
#else
#include <ucontext.h>
#endif

#include "CLogger.hpp"

namespace
{
	const std::map<crashhandler::Signal, std::string> Signals = {
	   {SIGABRT, "SIGABRT"},
	   {SIGFPE, "SIGFPE"},
	   {SIGILL, "SIGILL"},
	   {SIGSEGV, "SIGSEGV"},
	   {SIGTERM, "SIGTERM"},
	};

	std::map<crashhandler::Signal, struct sigaction> OldSignalActions;

	bool IsFirstSignal()
	{
		static std::atomic<int> first_exit{ 0 };
		int const count = first_exit.fetch_add(1, std::memory_order_relaxed);
		return (count == 0);
	}

	void RestoreSignalHandler(int signal_number)
	{
		//try restoring old action
		auto it = OldSignalActions.find(signal_number);
		if (it != OldSignalActions.end())
			sigaction(signal_number, &(it->second), nullptr);
	}

	void ExitWithDefaultSignalHandler(crashhandler::Signal fatal_signal_id)
	{
		const int signal_number = static_cast<int>(fatal_signal_id);
		RestoreSignalHandler(signal_number);
		std::cerr << "\n\n" << "[log-core] fatal signal '" << signal_number
			<< "' (" << Signals.at(fatal_signal_id) << ") catched   \n\n" << std::flush;

		raise(signal_number);
	}

	void SignalHandler(int signal_number, siginfo_t* info, void* unused_context)
	{
		//only one signal will be allowed past this point
		if (!IsFirstSignal())
		{
			while (true)
				std::this_thread::sleep_for(std::chrono::seconds(1));
		}

		const std::string err_msg = fmt::format(
			"signal {:d} ({:s}) catched; shutting log-core down (errno: {}, signal code: {}, exit status: {})",
			signal_number, Signals.at(signal_number), info->si_errno, info->si_code, info->si_status);

		CLogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
			"log-core", LogLevel::ERROR, err_msg, { })));
		CLogManager::Get()->Destroy();

		ExitWithDefaultSignalHandler(signal_number);
	}
}

namespace crashhandler
{
	void Install()
	{
		struct sigaction action, old_action;
		memset(&action, 0, sizeof(action));
		memset(&old_action, 0, sizeof(old_action));
		sigemptyset(&action.sa_mask);
		action.sa_sigaction = &SignalHandler;
		action.sa_flags = SA_SIGINFO;

		for (const auto &signal : Signals)
		{
			if (sigaction(signal.first, &action, &old_action) < 0)
			{
				const std::string error = "sigaction - " + signal.second;
				perror(error.c_str());
			}
			else
			{
				OldSignalActions.emplace(signal.first, old_action);
			}
		}
	}
}

<commit_msg>catch interrupt signal instead of terminate<commit_after>#include "crashhandler.hpp"

#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__))
#error "crashhandler_unix.cpp is used on a non-UNIX platform"
#endif

#include <csignal>
#include <cstring>
#include <unistd.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <thread>
#include <atomic>
#include <map>
#include <mutex>
#include <fmt/format.h>

 // Linux/Clang, OSX/Clang, OSX/gcc
#if (defined(__clang__) || defined(__APPLE__))
#include <sys/ucontext.h>
#else
#include <ucontext.h>
#endif

#include "CLogger.hpp"

namespace
{
	const std::map<crashhandler::Signal, std::string> Signals = {
	   {SIGABRT, "SIGABRT"},
	   {SIGFPE, "SIGFPE"},
	   {SIGILL, "SIGILL"},
	   {SIGSEGV, "SIGSEGV"},
	   {SIGINT, "SIGINT"},
	};

	std::map<crashhandler::Signal, struct sigaction> OldSignalActions;

	bool IsFirstSignal()
	{
		static std::atomic<int> first_exit{ 0 };
		int const count = first_exit.fetch_add(1, std::memory_order_relaxed);
		return (count == 0);
	}

	void RestoreSignalHandler(int signal_number)
	{
		//try restoring old action
		auto it = OldSignalActions.find(signal_number);
		if (it != OldSignalActions.end())
			sigaction(signal_number, &(it->second), nullptr);
	}

	void ExitWithDefaultSignalHandler(crashhandler::Signal fatal_signal_id)
	{
		const int signal_number = static_cast<int>(fatal_signal_id);
		RestoreSignalHandler(signal_number);
		std::cerr << "\n\n" << "[log-core] fatal signal '" << signal_number
			<< "' (" << Signals.at(fatal_signal_id) << ") catched   \n\n" << std::flush;

		raise(signal_number);
	}

	void SignalHandler(int signal_number, siginfo_t* info, void* unused_context)
	{
		//only one signal will be allowed past this point
		if (!IsFirstSignal())
		{
			while (true)
				std::this_thread::sleep_for(std::chrono::seconds(1));
		}

		const std::string err_msg = fmt::format(
			"signal {:d} ({:s}) catched; shutting log-core down (errno: {}, signal code: {}, exit status: {})",
			signal_number, Signals.at(signal_number), info->si_errno, info->si_code, info->si_status);

		CLogManager::Get()->QueueLogMessage(std::unique_ptr<CMessage>(new CMessage(
			"log-core", LogLevel::ERROR, err_msg, { })));
		CLogManager::Get()->Destroy();

		ExitWithDefaultSignalHandler(signal_number);
	}
}

namespace crashhandler
{
	void Install()
	{
		struct sigaction action, old_action;
		memset(&action, 0, sizeof(action));
		memset(&old_action, 0, sizeof(old_action));
		sigemptyset(&action.sa_mask);
		action.sa_sigaction = &SignalHandler;
		action.sa_flags = SA_SIGINFO;

		for (const auto &signal : Signals)
		{
			if (sigaction(signal.first, &action, &old_action) < 0)
			{
				const std::string error = "sigaction - " + signal.second;
				perror(error.c_str());
			}
			else
			{
				OldSignalActions.emplace(signal.first, old_action);
			}
		}
	}
}

<|endoftext|>


<commit_before>/** ==========================================================================
 * 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
 * with no warranties. This code is yours to share, use and modify with no
 * strings attached and no restrictions or obligations.
 *
 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
 * ============================================================================*/

#include "g3log/crashhandler.hpp"
#include "g3log/logmessage.hpp"
#include "g3log/logcapture.hpp"
#include "g3log/loglevels.hpp"

#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__)) // windows and not mingw
#error "crashhandler_unix.cpp used but it's a windows system"
#endif

#include <csignal>
#include <cstring>
#include <unistd.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <thread>
#include <atomic>

// Linux/Clang, OSX/Clang, OSX/gcc
#if (defined(__clang__) || defined(__APPLE__))
#include <sys/ucontext.h>
#else
#include <ucontext.h>
#endif

namespace {
   bool shouldDoExit() {
      static std::atomic<uint64_t> firstExit{0};
      auto const count = firstExit.fetch_add(1, std::memory_order_relaxed);
      return (0 == count);
   }

   void restoreSignalHandler(int signal_number) {
      std::cerr << "\n\n" << __FUNCTION__ << " " << signal_number << " threadID: " << std::this_thread::get_id() << std::endl;
#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
      struct sigaction action;
      memset(&action, 0, sizeof (action)); //
      sigemptyset(&action.sa_mask);
      action.sa_handler = SIG_DFL; // take default action for the signal
      sigaction(signal_number, &action, NULL);
#endif
   }

   // Dump of stack,. then exit through g3log background worker
   // ALL thanks to this thread at StackOverflow. Pretty much borrowed from:
   // Ref: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
   void signalHandler(int signal_number, siginfo_t *info, void *unused_context) {

      // Only one signal will be allowed past this point
      if (false == shouldDoExit()) {
         while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
         }
      }

      using namespace g3::internal;
      {
         const auto dump = stackdump();
         std::ostringstream fatal_stream;
         const auto fatal_reason = exitReasonName(g3::internal::FATAL_SIGNAL, signal_number);
         fatal_stream << "Received fatal signal: " << fatal_reason;
         fatal_stream << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
         fatal_stream << "\n***** SIGNAL " << fatal_reason << "(" << signal_number << ")" << std::endl;
         LogCapture trigger(FATAL_SIGNAL, static_cast<g3::SignalType>(signal_number), dump.c_str());
         trigger.stream() << fatal_stream.str();
      } // message sent to g3LogWorker
      // wait to die
   }
} // end anonymous namespace

// Redirecting and using signals. In case of fatal signals g3log should log the fatal signal
// and flush the log queue and then "rethrow" the signal to exit
namespace g3 {
   // References:
   // sigaction : change the default action if a specific signal is received
   //             http://linux.die.net/man/2/sigaction
   //             http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf2%2Fsigaction.html
   //
   // signal: http://linux.die.net/man/7/signal and
   //         http://msdn.microsoft.com/en-us/library/xdkz3x12%28vs.71%29.asp
   //
   // memset +  sigemptyset: Maybe unnecessary to do both but there seems to be some confusion here
   //          ,plenty of examples when both or either are used
   //          http://stackoverflow.com/questions/6878546/why-doesnt-parent-process-return-to-the-exact-location-after-handling-signal_number
   namespace internal {

      bool shouldBlockForFatalHandling() {
         return true;  // For windows we will after fatal processing change it to false
      }

      /// Generate stackdump. Or in case a stackdump was pre-generated and non-empty just use that one
      /// i.e. the latter case is only for Windows and test purposes
      std::string stackdump(const char *rawdump) {
         if (nullptr != rawdump && !std::string(rawdump).empty()) {
            return {rawdump};
         }

         const size_t max_dump_size = 50;
         void *dump[max_dump_size];
         size_t size = backtrace(dump, max_dump_size);
         char **messages = backtrace_symbols(dump, size); // overwrite sigaction with caller's address

         // dump stack: skip first frame, since that is here
         std::ostringstream oss;
         for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
            char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
            // find parantheses and +address offset surrounding mangled name
            for (char *p = messages[idx]; *p; ++p) {
               if (*p == '(') {
                  mangled_name = p;
               } else if (*p == '+') {
                  offset_begin = p;
               } else if (*p == ')') {
                  offset_end = p;
                  break;
               }
            }

            // if the line could be processed, attempt to demangle the symbol
            if (mangled_name && offset_begin && offset_end &&
                  mangled_name < offset_begin) {
               *mangled_name++ = '\0';
               *offset_begin++ = '\0';
               *offset_end++ = '\0';

               int status;
               char *real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
               // if demangling is successful, output the demangled function name
               if (status == 0) {
                  oss << "\n\tstack dump [" << idx << "]  " << messages[idx] << " : " << real_name << "+";
                  oss << offset_begin << offset_end << std::endl;
               }// otherwise, output the mangled function name
               else {
                  oss << "\tstack dump [" << idx << "]  " << messages[idx] << mangled_name << "+";
                  oss << offset_begin << offset_end << std::endl;
               }
               free(real_name); // mallocated by abi::__cxa_demangle(...)
            } else {
               // no demangling done -- just dump the whole line
               oss << "\tstack dump [" << idx << "]  " << messages[idx] << std::endl;
            }
         } // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
         free(messages);
         return oss.str();
      }

      /// string representation of signal ID
      std::string exitReasonName(const LEVELS &level, g3::SignalType fatal_id) {

         int signal_number = static_cast<int>(fatal_id);
         switch (signal_number) {
         case SIGABRT: return "SIGABRT";
            break;
         case SIGFPE: return "SIGFPE";
            break;
         case SIGSEGV: return "SIGSEGV";
            break;
         case SIGILL: return "SIGILL";
            break;
         case SIGTERM: return "SIGTERM";
            break;
         default:
            std::ostringstream oss;
            oss << "UNKNOWN SIGNAL(" << signal_number << ") for " << level.text;
            return oss.str();
         }
      }

      // KJELL : TODO.  The Fatal Message can contain a callback function that depending on OS and test scenario does
      //       different things.
      // exitWithDefaultSignalHandler is called from g3logworke::bgFatal AFTER all the logging sinks have been cleared
      // I.e. saving a function that has the value already encapsulated within.
      // FatalMessagePtr msgPtr
      // Linux/OSX -->   msgPtr.get()->ContinueWithFatalExit();  --> exitWithDefaultSignalHandler(int signal_number);
      // Windows          .....       (if signal)                --> exitWithDefaultSignalHandler(int signal_number);
      //                              (if exception) ....
      //                              the calling thread that is in a never-ending loop should break out of that loop
      //                                    i.e. an atomic flag should be set
      //                              the next step should then be to re-throw the same exception
      //                              i.e. just call the next exception handler
      //                              we should make sure that 1) g3log exception handler is called BEFORE widows
      //                              it should continue and then be caught in Visual Studios exception handler
      //
      //

      // Triggered by g3log->g3LogWorker after receiving a FATAL trigger
      // which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
      // --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
      void exitWithDefaultSignalHandler(const LEVELS &level, g3::SignalType fatal_signal_id) {
         const int signal_number = static_cast<int>(fatal_signal_id);
         restoreSignalHandler(signal_number);
         std::cerr << "\n\n" << __FUNCTION__ << ":" << __LINE__ << ". Exiting due to " << level.text << ", " << signal_number << "   \n\n" << std::flush;

         kill(getpid(), signal_number);
         exit(signal_number);

      }
   } // end g3::internal

   //
   // Installs FATAL signal handler that is enough to handle most fatal events
   //  on *NIX systems
   void installSignalHandler() {
#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
      struct sigaction action;
      memset(&action, 0, sizeof (action));
      sigemptyset(&action.sa_mask);
      action.sa_sigaction = &signalHandler; // callback to crashHandler for fatal signals
      // sigaction to use sa_sigaction file. ref: http://www.linuxprogrammingblog.com/code-examples/sigaction
      action.sa_flags = SA_SIGINFO;

      // do it verbose style - install all signal actions
      if (sigaction(SIGABRT, &action, NULL) < 0)
         perror("sigaction - SIGABRT");
      if (sigaction(SIGFPE, &action, NULL) < 0)
         perror("sigaction - SIGFPE");
      if (sigaction(SIGILL, &action, NULL) < 0)
         perror("sigaction - SIGILL");
      if (sigaction(SIGSEGV, &action, NULL) < 0)
         perror("sigaction - SIGSEGV");
      if (sigaction(SIGTERM, &action, NULL) < 0)
         perror("sigaction - SIGTERM");
#endif
   }

   void installCrashHandler() {
      installSignalHandler();
   } // namespace g3::internal

} // end namespace g3

<commit_msg>vanilla example. dynamic signal turning on/off<commit_after>/** ==========================================================================
 * 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
 * with no warranties. This code is yours to share, use and modify with no
 * strings attached and no restrictions or obligations.
 *
 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
 * ============================================================================*/

#include "g3log/crashhandler.hpp"
#include "g3log/logmessage.hpp"
#include "g3log/logcapture.hpp"
#include "g3log/loglevels.hpp"

#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__)) // windows and not mingw
#error "crashhandler_unix.cpp used but it's a windows system"
#endif

#include <csignal>
#include <cstring>
#include <unistd.h>
#include <execinfo.h>
#include <cxxabi.h>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <thread>
#include <atomic>
#include <map>

// Linux/Clang, OSX/Clang, OSX/gcc
#if (defined(__clang__) || defined(__APPLE__))
#include <sys/ucontext.h>
#else
#include <ucontext.h>
#endif

namespace {

   const std::map<int, std::string> kSignals = {
      {SIGABRT, "SIGABRT"},
      {SIGFPE,"SIGFPE"},
      {SIGILL,"SIGILL"},
      {SIGSEGV,"SIGSEGV"},
      {SIGTERM,"SIGTERM"},
   };

   std::map<int, std::string> gSignals = kSignals;

   bool shouldDoExit() {
      static std::atomic<uint64_t> firstExit{0};
      auto const count = firstExit.fetch_add(1, std::memory_order_relaxed);
      return (0 == count);
   }

   void restoreSignalHandler(int signal_number) {
      std::cerr << "\n\n" << __FUNCTION__ << " " << signal_number << " threadID: " << std::this_thread::get_id() << std::endl;
#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
      struct sigaction action;
      memset(&action, 0, sizeof (action)); //
      sigemptyset(&action.sa_mask);
      action.sa_handler = SIG_DFL; // take default action for the signal
      sigaction(signal_number, &action, NULL);
#endif
   }

   void overrideSetupSignals(const std::map<int, std::string> overrideSignals) {
      static std::mutex signalLock;
      std::lock_guard<std::mutex> guard(signalLock);
      gSignals = overrideSignals;
      for(const auto& sig: kSignals) {
         restoreSignalHandler(sig.first);
      }
      g3::installCrashHandler();
   }

   // Dump of stack,. then exit through g3log background worker
   // ALL thanks to this thread at StackOverflow. Pretty much borrowed from:
   // Ref: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
   void signalHandler(int signal_number, siginfo_t *info, void *unused_context) {

      // Only one signal will be allowed past this point
      if (false == shouldDoExit()) {
         while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
         }
      }

      using namespace g3::internal;
      {
         const auto dump = stackdump();
         std::ostringstream fatal_stream;
         const auto fatal_reason = exitReasonName(g3::internal::FATAL_SIGNAL, signal_number);
         fatal_stream << "Received fatal signal: " << fatal_reason;
         fatal_stream << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
         fatal_stream << "\n***** SIGNAL " << fatal_reason << "(" << signal_number << ")" << std::endl;
         LogCapture trigger(FATAL_SIGNAL, static_cast<g3::SignalType>(signal_number), dump.c_str());
         trigger.stream() << fatal_stream.str();
      } // message sent to g3LogWorker
      // wait to die
   }
} // end anonymous namespace

// Redirecting and using signals. In case of fatal signals g3log should log the fatal signal
// and flush the log queue and then "rethrow" the signal to exit
namespace g3 {
   // References:
   // sigaction : change the default action if a specific signal is received
   //             http://linux.die.net/man/2/sigaction
   //             http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf2%2Fsigaction.html
   //
   // signal: http://linux.die.net/man/7/signal and
   //         http://msdn.microsoft.com/en-us/library/xdkz3x12%28vs.71%29.asp
   //
   // memset +  sigemptyset: Maybe unnecessary to do both but there seems to be some confusion here
   //          ,plenty of examples when both or either are used
   //          http://stackoverflow.com/questions/6878546/why-doesnt-parent-process-return-to-the-exact-location-after-handling-signal_number
   namespace internal {

      bool shouldBlockForFatalHandling() {
         return true;  // For windows we will after fatal processing change it to false
      }

      /// Generate stackdump. Or in case a stackdump was pre-generated and non-empty just use that one
      /// i.e. the latter case is only for Windows and test purposes
      std::string stackdump(const char *rawdump) {
         if (nullptr != rawdump && !std::string(rawdump).empty()) {
            return {rawdump};
         }

         const size_t max_dump_size = 50;
         void *dump[max_dump_size];
         size_t size = backtrace(dump, max_dump_size);
         char **messages = backtrace_symbols(dump, size); // overwrite sigaction with caller's address

         // dump stack: skip first frame, since that is here
         std::ostringstream oss;
         for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
            char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
            // find parantheses and +address offset surrounding mangled name
            for (char *p = messages[idx]; *p; ++p) {
               if (*p == '(') {
                  mangled_name = p;
               } else if (*p == '+') {
                  offset_begin = p;
               } else if (*p == ')') {
                  offset_end = p;
                  break;
               }
            }

            // if the line could be processed, attempt to demangle the symbol
            if (mangled_name && offset_begin && offset_end &&
                  mangled_name < offset_begin) {
               *mangled_name++ = '\0';
               *offset_begin++ = '\0';
               *offset_end++ = '\0';

               int status;
               char *real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
               // if demangling is successful, output the demangled function name
               if (status == 0) {
                  oss << "\n\tstack dump [" << idx << "]  " << messages[idx] << " : " << real_name << "+";
                  oss << offset_begin << offset_end << std::endl;
               }// otherwise, output the mangled function name
               else {
                  oss << "\tstack dump [" << idx << "]  " << messages[idx] << mangled_name << "+";
                  oss << offset_begin << offset_end << std::endl;
               }
               free(real_name); // mallocated by abi::__cxa_demangle(...)
            } else {
               // no demangling done -- just dump the whole line
               oss << "\tstack dump [" << idx << "]  " << messages[idx] << std::endl;
            }
         } // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
         free(messages);
         return oss.str();
      }

      /// string representation of signal ID
      std::string exitReasonName(const LEVELS &level, g3::SignalType fatal_id) {

         int signal_number = static_cast<int>(fatal_id);
         switch (signal_number) {
         case SIGABRT: return "SIGABRT";
            break;
         case SIGFPE: return "SIGFPE";
            break;
         case SIGSEGV: return "SIGSEGV";
            break;
         case SIGILL: return "SIGILL";
            break;
         case SIGTERM: return "SIGTERM";
            break;
         default:
            std::ostringstream oss;
            oss << "UNKNOWN SIGNAL(" << signal_number << ") for " << level.text;
            return oss.str();
         }
      }

      // KJELL : TODO.  The Fatal Message can contain a callback function that depending on OS and test scenario does
      //       different things.
      // exitWithDefaultSignalHandler is called from g3logworke::bgFatal AFTER all the logging sinks have been cleared
      // I.e. saving a function that has the value already encapsulated within.
      // FatalMessagePtr msgPtr
      // Linux/OSX -->   msgPtr.get()->ContinueWithFatalExit();  --> exitWithDefaultSignalHandler(int signal_number);
      // Windows          .....       (if signal)                --> exitWithDefaultSignalHandler(int signal_number);
      //                              (if exception) ....
      //                              the calling thread that is in a never-ending loop should break out of that loop
      //                                    i.e. an atomic flag should be set
      //                              the next step should then be to re-throw the same exception
      //                              i.e. just call the next exception handler
      //                              we should make sure that 1) g3log exception handler is called BEFORE widows
      //                              it should continue and then be caught in Visual Studios exception handler
      //
      //

      // Triggered by g3log->g3LogWorker after receiving a FATAL trigger
      // which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
      // --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
      void exitWithDefaultSignalHandler(const LEVELS &level, g3::SignalType fatal_signal_id) {
         const int signal_number = static_cast<int>(fatal_signal_id);
         restoreSignalHandler(signal_number);
         std::cerr << "\n\n" << __FUNCTION__ << ":" << __LINE__ << ". Exiting due to " << level.text << ", " << signal_number << "   \n\n" << std::flush;

         kill(getpid(), signal_number);
         exit(signal_number);

      }
   } // end g3::internal

   //
   // Installs FATAL signal handler that is enough to handle most fatal events
   //  on *NIX systems
   void installSignalHandler() {
#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
      struct sigaction action;
      memset(&action, 0, sizeof (action));
      sigemptyset(&action.sa_mask);
      action.sa_sigaction = &signalHandler; // callback to crashHandler for fatal signals
      // sigaction to use sa_sigaction file. ref: http://www.linuxprogrammingblog.com/code-examples/sigaction
      action.sa_flags = SA_SIGINFO;

      // do it verbose style - install all signal actions

      for (const auto& sig_pair : gSignals) {
         if (sigaction(sig_pair.first, &action, nullptr) < 0) {
            const std::string error = "sigaction - " + sig_pair.second;
            perror(error.c_str());
         }
      }

      // if (sigaction(SIGABRT, &action, NULL) < 0)
      //    perror("sigaction - SIGABRT");
      // if (sigaction(SIGFPE, &action, NULL) < 0)
      //    perror("sigaction - SIGFPE");
      // if (sigaction(SIGILL, &action, NULL) < 0)
      //    perror("sigaction - SIGILL");
      // if (sigaction(SIGSEGV, &action, NULL) < 0)
      //    perror("sigaction - SIGSEGV");
      // if (sigaction(SIGTERM, &action, NULL) < 0)
      //    perror("sigaction - SIGTERM");
#endif
   }

   void installCrashHandler() {
      installSignalHandler();
   } // namespace g3::internal

} // end namespace g3

<|endoftext|>


<commit_before>#include "makeplan.h"

MakePlan::MakePlan()
{
}

void MakePlan::removeOutliers(PointCloud::Ptr cloud_in, PointCloud::Ptr &cloud_out)
{
  pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
  // build the filter
  outrem.setInputCloud(cloud_in);
  outrem.setRadiusSearch(0.01);
  outrem.setMinNeighborsInRadius (4);
  // apply filter
  outrem.filter (*cloud_out);
}

bool MakePlan::getAveragePoint(PointCloud::Ptr cloud_in, pcl::PointXYZ &avrPt)
{
  if (!cloud_in->points.size())
  {
    return false;
  }

  pcl::PointXYZ min_dis_point;
  float min_dis = 100.0;
  for (PointCloud::const_iterator it = cloud_in->begin(); it != cloud_in->end(); ++ it)
  {
    float dis = pow(it->x, 2) + pow(it->y, 2);
    if (dis < min_dis)
    {
      min_dis = dis;
      min_dis_point = *it;
    }
  }

  smartOffset(min_dis_point, 0.02, 0.05);
  avrPt = min_dis_point;
  return true;
}

void MakePlan::smartOffset(pcl::PointXYZ &p_in, float off_xy, float off_z)
{
  float y_off = off_xy / sqrt(1 + pow(p_in.x / p_in.y, 2)) * p_in.y / fabs(p_in.y);
  float x_off = p_in.x / p_in.y * y_off;
  p_in.x += x_off;
  p_in.y += y_off;
  // To solve the detected point is higher than optimal
  p_in.z += off_z;
}

void MakePlan::removeNans(PointCloud::Ptr cloud_in, PointCloud::Ptr &cloud_out)
{
  std::vector< int >	index;
  PointCloud::Ptr cloud_filtered_nan (new PointCloud);

  pcl::removeNaNFromPointCloud(*cloud_in, *cloud_filtered_nan, index);

  pcl::PointIndices::Ptr indices_x(new pcl::PointIndices);
  pcl::PointIndices::Ptr indices_xy(new pcl::PointIndices);

  pcl::PassThrough<pcl::PointXYZ> ptfilter; // Initializing with true will allow us to extract the removed indices
  ptfilter.setInputCloud (cloud_filtered_nan);
  ptfilter.setFilterFieldName ("x");
  ptfilter.setFilterLimits (-0.2, 0.2);
  ptfilter.filter (indices_x->indices);

  ptfilter.setIndices (indices_x);
  ptfilter.setFilterFieldName ("y");
  ptfilter.setFilterLimits (-0.2, 0.2);
  ptfilter.filter (indices_xy->indices);

  ptfilter.setIndices (indices_xy);
  ptfilter.setFilterFieldName ("z");
  ptfilter.setFilterLimits (0.5, 2.0);// this method can only be used on source cloud, aka cloud whose frame is camera optical frame
  ptfilter.filter (*cloud_out);
}

bool MakePlan::process(PointCloud::Ptr cloud_in, float a, float b, float c, float d, pcl::PointXYZ &avrPt)
{
  if (!cloud_in->points.size())
  {
    return false;
  }

  PointCloud::Ptr cloud_filtered (new PointCloud);
#ifdef USE_CENTER
  cloud_filtered = cloud_in;
#else
  removeOutliers(cloud_in, cloud_filtered);
#endif
  bool success = getAveragePoint(cloud_filtered, avrPt);
  return success;
}
<commit_msg>change offset method<commit_after>#include "makeplan.h"

MakePlan::MakePlan()
{
}

void MakePlan::removeOutliers(PointCloud::Ptr cloud_in, PointCloud::Ptr &cloud_out)
{
  pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
  // build the filter
  outrem.setInputCloud(cloud_in);
  outrem.setRadiusSearch(0.01);
  outrem.setMinNeighborsInRadius (4);
  // apply filter
  outrem.filter (*cloud_out);
}

bool MakePlan::getAveragePoint(PointCloud::Ptr cloud_in, pcl::PointXYZ &avrPt)
{
  if (!cloud_in->points.size())
  {
    return false;
  }

  pcl::PointXYZ min_dis_point;
  float min_dis = 100.0;
  for (PointCloud::const_iterator it = cloud_in->begin(); it != cloud_in->end(); ++ it)
  {
    float dis = pow(it->x, 2) + pow(it->y, 2);
    if (dis < min_dis)
    {
      min_dis = dis;
      min_dis_point = *it;
    }
  }

  smartOffset(min_dis_point, 0.02, 0.05);
  avrPt = min_dis_point;
  return true;
}

void MakePlan::smartOffset(pcl::PointXYZ &p_in, float off_xy, float off_z)
{
  //  float y_off = off_xy / sqrt(1 + pow(p_in.x / p_in.y, 2)) * p_in.y / fabs(p_in.y);
  //  float x_off = p_in.x / p_in.y * y_off;
  if (p_in.x == 0) {
    p_in.x += off_xy;
  }
  else {
    float rad = atan(p_in.y/p_in.x);
    float y_off = off_xy * sin(rad);
    float x_off = off_xy * cos(rad);
    p_in.x += x_off;
    p_in.y += y_off;
  }
  // To solve the detected point is higher than optimal
  p_in.z += off_z;
}

void MakePlan::removeNans(PointCloud::Ptr cloud_in, PointCloud::Ptr &cloud_out)
{
  std::vector< int >	index;
  PointCloud::Ptr cloud_filtered_nan (new PointCloud);

  pcl::removeNaNFromPointCloud(*cloud_in, *cloud_filtered_nan, index);

  pcl::PointIndices::Ptr indices_x(new pcl::PointIndices);
  pcl::PointIndices::Ptr indices_xy(new pcl::PointIndices);

  pcl::PassThrough<pcl::PointXYZ> ptfilter; // Initializing with true will allow us to extract the removed indices
  ptfilter.setInputCloud (cloud_filtered_nan);
  ptfilter.setFilterFieldName ("x");
  ptfilter.setFilterLimits (-0.2, 0.2);
  ptfilter.filter (indices_x->indices);

  ptfilter.setIndices (indices_x);
  ptfilter.setFilterFieldName ("y");
  ptfilter.setFilterLimits (-0.2, 0.2);
  ptfilter.filter (indices_xy->indices);

  ptfilter.setIndices (indices_xy);
  ptfilter.setFilterFieldName ("z");
  ptfilter.setFilterLimits (0.5, 2.0);// this method can only be used on source cloud, aka cloud whose frame is camera optical frame
  ptfilter.filter (*cloud_out);
}

bool MakePlan::process(PointCloud::Ptr cloud_in, float a, float b, float c, float d, pcl::PointXYZ &avrPt)
{
  if (!cloud_in->points.size())
  {
    return false;
  }

  PointCloud::Ptr cloud_filtered (new PointCloud);
#ifdef USE_CENTER
  cloud_filtered = cloud_in;
#else
  removeOutliers(cloud_in, cloud_filtered);
#endif
  bool success = getAveragePoint(cloud_filtered, avrPt);
  return success;
}
<|endoftext|>