<commit_before>/*
 * MolecularBezierData.cpp
 *
 * Copyright (C) 2013 by TU Dresden
 * Alle Rechte vorbehalten.
 */
#include "stdafx.h"
#include "MolecularBezierData.h"
#include "vislib/BezierCurve.h"
#include "vislib/RawStorage.h"
#include "vislib/RawStorageWriter.h"
#include "vislib/Point.h"
#include <list>
#include "Color.h"
#include "vislib/NamedColours.h"

using namespace megamol;
using namespace megamol::protein;

/*
 * MolecularBezierData::MolecularBezierData
 */
MolecularBezierData::MolecularBezierData(void) : Module(),
        outDataSlot("outData", "presents data as BezierCurvesListDataCall"),
        inDataSlot("inData", "fetches data either as ExtBezierDataCall or v1.BezierDataCall"),
        hash(0), timeCode(0) {

    this->outDataSlot.SetCallback(core::misc::BezierCurvesListDataCall::ClassName(), "GetData", &MolecularBezierData::getDataCallback);
    this->outDataSlot.SetCallback(core::misc::BezierCurvesListDataCall::ClassName(), "GetExtent", &MolecularBezierData::getExtentCallback);
    this->MakeSlotAvailable(&this->outDataSlot);

    this->inDataSlot.SetCompatibleCall<MolecularDataCallDescription>();
    this->MakeSlotAvailable(&this->inDataSlot);
}

/*
 * MolecularBezierData::~MolecularBezierData
 */
MolecularBezierData::~MolecularBezierData(void) {
    this->Release();
}

/*
 * MolecularBezierData::create
 */
bool MolecularBezierData::create(void) {
    Color::ReadColorTableFromFile(nullptr, this->colorLookupTable);
    Color::MakeRainbowColorTable(100, this->rainbowColors);
    return true;
}

/*
 * MolecularBezierData::release
 */
void MolecularBezierData::release(void) {
    // intentionally empty
}

/*
 * MolecularBezierData::getDataCallback
 */
bool MolecularBezierData::getDataCallback(core::Call& caller) {
    core::misc::BezierCurvesListDataCall *bcldc = dynamic_cast<core::misc::BezierCurvesListDataCall *>(&caller);
    if (bcldc == nullptr) return false;

    core::AbstractGetData3DCall *agd3dc = this->inDataSlot.CallAs<core::AbstractGetData3DCall>();
    if (agd3dc == nullptr) return false;

    // check hash via cheap ext test
    agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());
    if (!(*agd3dc)(1u)) return false;
    agd3dc->Unlock();

    if ((bcldc->FrameID() != this->timeCode) || (this->hash == 0) || (this->hash != agd3dc->DataHash())) {
        agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());

        // fetch actual data
        if (!(*agd3dc)(0u)) return false;

        if ((this->hash != agd3dc->DataHash()) || (this->timeCode != agd3dc->FrameID())) {
            // new data: recompute bezier data
            this->hash = agd3dc->DataHash();
            this->timeCode = agd3dc->FrameID();

            MolecularDataCall *mdc = dynamic_cast<MolecularDataCall*>(agd3dc);
            if (mdc != nullptr) {
                this->update(*mdc);

            } else {
                this->data.Clear();
                this->data.SetGlobalColour(127, 127, 127);
                this->data.SetGlobalRadius(0.1f);

            }
        }
    }

    bcldc->SetDataHash(this->hash);
    bcldc->SetFrameID(this->timeCode);
    bcldc->SetUnlocker(nullptr); // HAZARD
    bcldc->SetData(&this->data, 1);

    return true;
}

/*
 * MolecularBezierData::getExtentCallback
 */
bool MolecularBezierData::getExtentCallback(core::Call& caller) {
    core::misc::BezierCurvesListDataCall *bcldc = dynamic_cast<core::misc::BezierCurvesListDataCall *>(&caller);
    if (bcldc == nullptr) return false;

    core::AbstractGetData3DCall *agd3dc = this->inDataSlot.CallAs<core::AbstractGetData3DCall>();
    if (agd3dc == nullptr) return false;

    agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());
    if (!(*agd3dc)(1u)) return false;

    bcldc->AccessBoundingBoxes() = agd3dc->AccessBoundingBoxes();
    bcldc->SetFrameID(agd3dc->FrameID(), agd3dc->IsFrameForced());
    bcldc->SetFrameCount(agd3dc->FrameCount());
    bcldc->SetDataHash(agd3dc->DataHash());
    bcldc->SetUnlocker(nullptr);

    agd3dc->Unlock();

    return true;
}

/*
 * MolecularBezierData::update
 */
void MolecularBezierData::update(MolecularDataCall& dat) {
    this->data.Clear();
    vislib::RawStorage pt_blob;
    vislib::RawStorageWriter pt(pt_blob);
    vislib::RawStorage idx_blob;
    vislib::RawStorageWriter idx(idx_blob);
    size_t cnt = 0;

    const float col_mix = 1.0f;
    Color::MakeColorTable(&dat,
        Color::STRUCTURE,
        Color::BFACTOR,
        col_mix,       // blending factor between both color maps
        1.0 - col_mix, //
        this->atomColorTable, this->colorLookupTable, this->rainbowColors,
        _T("blue"), _T("white"), _T("red"), true);

    for (unsigned int mi = 0; mi < dat.MoleculeCount(); mi++) {
        std::list<vislib::math::Point<float, 3> > poss;
        std::list<float> rads;
        std::list<vislib::math::Vector<float, 3> > cols;

        unsigned ssi = dat.Molecules()[mi].FirstSecStructIndex();
        for (unsigned int ssit = 0; ssit < dat.Molecules()[mi].SecStructCount(); ssi++, ssit++) {

            unsigned int aai = dat.SecondaryStructures()[ssi].FirstAminoAcidIndex();
            for (unsigned int aait = 0; aait < dat.SecondaryStructures()[ssi].AminoAcidCount(); aait++, aai++) {
                if (dat.Residues()[aai]->Identifier() != MolecularDataCall::Residue::AMINOACID) continue;
                unsigned int ca = static_cast<const MolecularDataCall::AminoAcid*>(dat.Residues()[aai])->CAlphaIndex();

                vislib::math::Point<float, 3> pos(dat.AtomPositions() + (ca * 3));
                float rad = 0.3f;
                vislib::math::Vector<float, 3> col(atomColorTable.PeekElements() + (ca * 3));

                switch (dat.SecondaryStructures()[ssi].Type()) {
                case MolecularDataCall::SecStructure::TYPE_HELIX:
                    rad = 0.4f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_SHEET:
                    rad = 0.4f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_TURN:
                    rad = 0.2f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_COIL: // fall through
                default: rad = 0.3f; // ngstrm
                }

                poss.push_back(pos);
                rads.push_back(rad);
                cols.push_back(col);
            }
        }

        // TODO: Fix me

        auto possE = poss.end();
        auto posI = poss.begin();
        auto radI = rads.begin();
        auto colI = cols.begin();
        for (; posI != possE; posI++, radI++, colI++) {
            pt.Write(posI->X());
            pt.Write(posI->Y());
            pt.Write(posI->Z());
            pt.Write(*radI);
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(colI->X() * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(colI->Y() * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(colI->Z() * 255.0f), 0, 255)));
            if (cnt > 1) {
                idx.Write(static_cast<unsigned int>(cnt - 1));
                idx.Write(static_cast<unsigned int>(cnt - 1));
                idx.Write(static_cast<unsigned int>(cnt));
                idx.Write(static_cast<unsigned int>(cnt));
            }
            cnt++;
        }

    }

    if (pt.Position() > 0) {
        unsigned char *pt_dat = new unsigned char[pt.Position()];
        ::memcpy(pt_dat, pt_blob, pt.Position());
        unsigned int *idx_dat = new unsigned int[idx.Position() / sizeof(unsigned int)];
        ::memcpy(idx_dat, idx_blob, idx.Position());

        this->data.Set(core::misc::BezierCurvesListDataCall::DATALAYOUT_XYZR_F_RGB_B, pt_dat, cnt, true, idx_dat, idx.Position() / sizeof(unsigned int), true, 0.5f, 127, 127, 127);
    } else {
        this->data.Set(core::misc::BezierCurvesListDataCall::DATALAYOUT_NONE, nullptr, 0, nullptr, 0);
    }
}
<commit_msg>Spline interpolation copied from SiffCSplineFitter<commit_after>/*
 * MolecularBezierData.cpp
 *
 * Copyright (C) 2013 by TU Dresden
 * Alle Rechte vorbehalten.
 */
#include "stdafx.h"
#include "MolecularBezierData.h"
#include "vislib/BezierCurve.h"
#include "vislib/RawStorage.h"
#include "vislib/RawStorageWriter.h"
#include "vislib/Point.h"
#include <vector>
#include "Color.h"
#include "vislib/NamedColours.h"

using namespace megamol;
using namespace megamol::protein;

/*
 * MolecularBezierData::MolecularBezierData
 */
MolecularBezierData::MolecularBezierData(void) : Module(),
        outDataSlot("outData", "presents data as BezierCurvesListDataCall"),
        inDataSlot("inData", "fetches data either as ExtBezierDataCall or v1.BezierDataCall"),
        hash(0), timeCode(0) {

    this->outDataSlot.SetCallback(core::misc::BezierCurvesListDataCall::ClassName(), "GetData", &MolecularBezierData::getDataCallback);
    this->outDataSlot.SetCallback(core::misc::BezierCurvesListDataCall::ClassName(), "GetExtent", &MolecularBezierData::getExtentCallback);
    this->MakeSlotAvailable(&this->outDataSlot);

    this->inDataSlot.SetCompatibleCall<MolecularDataCallDescription>();
    this->MakeSlotAvailable(&this->inDataSlot);
}

/*
 * MolecularBezierData::~MolecularBezierData
 */
MolecularBezierData::~MolecularBezierData(void) {
    this->Release();
}

/*
 * MolecularBezierData::create
 */
bool MolecularBezierData::create(void) {
    Color::ReadColorTableFromFile(nullptr, this->colorLookupTable);
    Color::MakeRainbowColorTable(100, this->rainbowColors);
    return true;
}

/*
 * MolecularBezierData::release
 */
void MolecularBezierData::release(void) {
    // intentionally empty
}

/*
 * MolecularBezierData::getDataCallback
 */
bool MolecularBezierData::getDataCallback(core::Call& caller) {
    core::misc::BezierCurvesListDataCall *bcldc = dynamic_cast<core::misc::BezierCurvesListDataCall *>(&caller);
    if (bcldc == nullptr) return false;

    core::AbstractGetData3DCall *agd3dc = this->inDataSlot.CallAs<core::AbstractGetData3DCall>();
    if (agd3dc == nullptr) return false;

    // check hash via cheap ext test
    agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());
    if (!(*agd3dc)(1u)) return false;
    agd3dc->Unlock();

    if ((bcldc->FrameID() != this->timeCode) || (this->hash == 0) || (this->hash != agd3dc->DataHash())) {
        agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());

        // fetch actual data
        if (!(*agd3dc)(0u)) return false;

        if ((this->hash != agd3dc->DataHash()) || (this->timeCode != agd3dc->FrameID())) {
            // new data: recompute bezier data
            this->hash = agd3dc->DataHash();
            this->timeCode = agd3dc->FrameID();

            MolecularDataCall *mdc = dynamic_cast<MolecularDataCall*>(agd3dc);
            if (mdc != nullptr) {
                this->update(*mdc);

            } else {
                this->data.Clear();
                this->data.SetGlobalColour(127, 127, 127);
                this->data.SetGlobalRadius(0.1f);

            }
        }
    }

    bcldc->SetDataHash(this->hash);
    bcldc->SetFrameID(this->timeCode);
    bcldc->SetUnlocker(nullptr); // HAZARD
    bcldc->SetData(&this->data, 1);

    return true;
}

/*
 * MolecularBezierData::getExtentCallback
 */
bool MolecularBezierData::getExtentCallback(core::Call& caller) {
    core::misc::BezierCurvesListDataCall *bcldc = dynamic_cast<core::misc::BezierCurvesListDataCall *>(&caller);
    if (bcldc == nullptr) return false;

    core::AbstractGetData3DCall *agd3dc = this->inDataSlot.CallAs<core::AbstractGetData3DCall>();
    if (agd3dc == nullptr) return false;

    agd3dc->SetFrameID(bcldc->FrameID(), bcldc->IsFrameForced());
    if (!(*agd3dc)(1u)) return false;

    bcldc->AccessBoundingBoxes() = agd3dc->AccessBoundingBoxes();
    bcldc->SetFrameID(agd3dc->FrameID(), agd3dc->IsFrameForced());
    bcldc->SetFrameCount(agd3dc->FrameCount());
    bcldc->SetDataHash(agd3dc->DataHash());
    bcldc->SetUnlocker(nullptr);

    agd3dc->Unlock();

    return true;
}

/**
 * local utility function for linear interpolation
 *
 * @param v1 Value 1
 * @param v2 Value 2
 * @param a Interpolation value
 *
 * @return The interpolated value
 */
static float interpolate(float v1, float v2, float a) {
    if (a < 0.0f) a = 0.0f;
    if (a > 1.0f) a = 1.0f;
    return v1 * (1.0f - a) + v2 * a;
}

/*
 * MolecularBezierData::update
 */
void MolecularBezierData::update(MolecularDataCall& dat) {
    this->data.Clear();
    vislib::RawStorage pt_blob;
    vislib::RawStorageWriter pt(pt_blob);
    vislib::RawStorage idx_blob;
    vislib::RawStorageWriter idx(idx_blob);
    size_t cnt = 0;

    const float col_mix = 0.5f;
    Color::MakeColorTable(&dat,
        Color::STRUCTURE,
        Color::BFACTOR,
        col_mix,       // blending factor between both color maps
        1.0 - col_mix, //
        this->atomColorTable, this->colorLookupTable, this->rainbowColors,
        _T("blue"), _T("white"), _T("red"), true);

    for (unsigned int mi = 0; mi < dat.MoleculeCount(); mi++) {
        std::vector<const float* > poss;
        std::vector<float> rads;
        std::vector<const float* > cols;

        unsigned ssi = dat.Molecules()[mi].FirstSecStructIndex();
        for (unsigned int ssit = 0; ssit < dat.Molecules()[mi].SecStructCount(); ssi++, ssit++) {

            unsigned int aai = dat.SecondaryStructures()[ssi].FirstAminoAcidIndex();
            for (unsigned int aait = 0; aait < dat.SecondaryStructures()[ssi].AminoAcidCount(); aait++, aai++) {
                if (dat.Residues()[aai]->Identifier() != MolecularDataCall::Residue::AMINOACID) continue;
                unsigned int ca = static_cast<const MolecularDataCall::AminoAcid*>(dat.Residues()[aai])->CAlphaIndex();

                float rad = 0.3f; // ngstrm
                switch (dat.SecondaryStructures()[ssi].Type()) {
                case MolecularDataCall::SecStructure::TYPE_HELIX:
                    rad = 0.4f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_SHEET:
                    rad = 0.4f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_TURN:
                    rad = 0.2f; // ngstrm
                    break;
                case MolecularDataCall::SecStructure::TYPE_COIL: // fall through
                default: rad = 0.3f; // ngstrm
                }

                poss.push_back(dat.AtomPositions() + (ca * 3));
                rads.push_back(rad);
                cols.push_back(atomColorTable.PeekElements() + (ca * 3));
            }
        }

        ASSERT(poss.size() == rads.size());
        ASSERT(poss.size() == cols.size());
        if (poss.size() < 2) {
            continue; // skip this empty data
        } else if (poss.size() == 2) {
            // simple line:
            pt.Write(poss[0][0]);
            pt.Write(poss[0][1]);
            pt.Write(poss[0][2]);
            pt.Write(rads[0]);
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][0] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][1] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][2] * 255.0f), 0, 255)));
            cnt++;
            pt.Write(poss[1][0]);
            pt.Write(poss[1][1]);
            pt.Write(poss[1][2]);
            pt.Write(rads[1]);
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[1][0] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[1][1] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[1][2] * 255.0f), 0, 255)));
            cnt++;
            idx.Write(static_cast<unsigned int>(cnt - 2));
            idx.Write(static_cast<unsigned int>(cnt - 2));
            idx.Write(static_cast<unsigned int>(cnt - 1));
            idx.Write(static_cast<unsigned int>(cnt - 1));
        } else {
            // more than three points (spline-siff-code from old core module)

            // first curve
            pt.Write(poss[0][0]);
            pt.Write(poss[0][1]);
            pt.Write(poss[0][2]);
            pt.Write(rads[0]);
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][0] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][1] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[0][2] * 255.0f), 0, 255)));
            idx.Write(static_cast<unsigned int>(cnt));
            cnt++;

            pt.Write(interpolate(poss[0][0], poss[1][0], 0.75f));
            pt.Write(interpolate(poss[0][1], poss[1][1], 0.75f));
            pt.Write(interpolate(poss[0][2], poss[1][2], 0.75f));
            pt.Write(interpolate(rads[0], rads[1], 0.75f));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[0][0], cols[1][0], 0.75f) * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[0][1], cols[1][1], 0.75f) * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[0][2], cols[1][2], 0.75f) * 255.0f), 0, 255)));
            idx.Write(static_cast<unsigned int>(cnt));
            cnt++;

            // inner curves
            for (unsigned int i = 1; i < poss.size() - 1; i++) {

                pt.Write(interpolate(poss[i][0], poss[i + 1][0], 0.25f));
                pt.Write(interpolate(poss[i][1], poss[i + 1][1], 0.25f));
                pt.Write(interpolate(poss[i][2], poss[i + 1][2], 0.25f));
                pt.Write(interpolate(rads[i], rads[i + 1], 0.25f));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][0], cols[i + 1][0], 0.25f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][1], cols[i + 1][1], 0.25f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][2], cols[i + 1][2], 0.25f) * 255.0f), 0, 255)));
                idx.Write(static_cast<unsigned int>(cnt));
                cnt++;

                pt.Write(interpolate(poss[i][0], poss[i + 1][0], 0.5f));
                pt.Write(interpolate(poss[i][1], poss[i + 1][1], 0.5f));
                pt.Write(interpolate(poss[i][2], poss[i + 1][2], 0.5f));
                pt.Write(interpolate(rads[i], rads[i + 1], 0.5f));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][0], cols[i + 1][0], 0.5f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][1], cols[i + 1][1], 0.5f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][2], cols[i + 1][2], 0.5f) * 255.0f), 0, 255)));
                idx.Write(static_cast<unsigned int>(cnt));
                idx.Write(static_cast<unsigned int>(cnt)); // use this point twice
                cnt++;

                pt.Write(interpolate(poss[i][0], poss[i + 1][0], 0.75f));
                pt.Write(interpolate(poss[i][1], poss[i + 1][1], 0.75f));
                pt.Write(interpolate(poss[i][2], poss[i + 1][2], 0.75f));
                pt.Write(interpolate(rads[i], rads[i + 1], 0.75f));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][0], cols[i + 1][0], 0.75f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][1], cols[i + 1][1], 0.75f) * 255.0f), 0, 255)));
                pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[i][2], cols[i + 1][2], 0.75f) * 255.0f), 0, 255)));
                idx.Write(static_cast<unsigned int>(cnt));
                cnt++;
            }

            // last curve
            pt.Write(interpolate(poss[poss.size() - 2][0], poss[poss.size() - 1][0], 0.25f));
            pt.Write(interpolate(poss[poss.size() - 2][1], poss[poss.size() - 1][1], 0.25f));
            pt.Write(interpolate(poss[poss.size() - 2][2], poss[poss.size() - 1][2], 0.25f));
            pt.Write(interpolate(rads[poss.size() - 2], rads[poss.size() - 1], 0.25f));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[poss.size() - 2][0], cols[poss.size() - 1][0], 0.25f) * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[poss.size() - 2][1], cols[poss.size() - 1][1], 0.25f) * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(interpolate(cols[poss.size() - 2][2], cols[poss.size() - 1][2], 0.25f) * 255.0f), 0, 255)));
            idx.Write(static_cast<unsigned int>(cnt));
            cnt++;

            pt.Write(poss[poss.size() - 1][0]);
            pt.Write(poss[poss.size() - 1][1]);
            pt.Write(poss[poss.size() - 1][2]);
            pt.Write(rads[poss.size() - 1]);
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[poss.size() - 1][0] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[poss.size() - 1][1] * 255.0f), 0, 255)));
            pt.Write(static_cast<unsigned char>(vislib::math::Clamp(static_cast<int>(cols[poss.size() - 1][2] * 255.0f), 0, 255)));
            idx.Write(static_cast<unsigned int>(cnt));
            cnt++;
        }

    }

    if (pt.Position() > 0) {
        unsigned char *pt_dat = new unsigned char[pt.Position()];
        ::memcpy(pt_dat, pt_blob, pt.Position());
        unsigned int *idx_dat = new unsigned int[idx.Position() / sizeof(unsigned int)];
        ::memcpy(idx_dat, idx_blob, idx.Position());

        this->data.Set(core::misc::BezierCurvesListDataCall::DATALAYOUT_XYZR_F_RGB_B, pt_dat, cnt, true, idx_dat, idx.Position() / sizeof(unsigned int), true, 0.5f, 127, 127, 127);
    } else {
        this->data.Set(core::misc::BezierCurvesListDataCall::DATALAYOUT_NONE, nullptr, 0, nullptr, 0);
    }
}
<|endoftext|>


<commit_before>/*
    Implementation of the Compiler class.

*/

#include <cctype>       //character comparison functions
#include <stdexcept>
#include "compiler.hh"

namespace ds_compiler {

const size_t Compiler::NUM_REGISTERS = 8;
const char Compiler::ERR_CHAR = '\0';
const std::unordered_set<char> Compiler::ADD_OPS({'+', '-'});
const std::unordered_set<char> Compiler::MULT_OPS;

//constructors
Compiler::Compiler ()
    : m_is (&std::cin), m_os (&std::cout)
{

}

Compiler::Compiler (std::istream *new_is, std::ostream *new_os)
    : m_is (new_is), m_os (new_os)
{

}

void Compiler::compile_intermediate () const {
    try {
        expression();
    } catch (std::exception &ex) {
        std::cerr << ex.what() << '\n';
    }
}

void Compiler::compile_full () const {

    compile_start();
    compile_intermediate();
    compile_end();

}

void Compiler::compile_start () const {

    //emit lines for necessary includes
    emit_line("#include <stack>");
    emit_line("#include <vector>");
    emit_line("#include <iostream>");
    emit_line("#include <string>");

    //create a stack and vector for registers
    std::string stack_init = "static std::stack<int> cpu_stack;";
    std::string registers_init = "static std::vector<int> cpu_registers(" + std::to_string(NUM_REGISTERS) + ", 0);";
    emit_line(stack_init);
    emit_line(registers_init);

    //emit definition of a function for easier stack handling
    emit_line("int cpu_pop() {");
    emit_line("int val = cpu_stack.top();");
    emit_line("cpu_stack.pop();");
    emit_line("return val; }");

    //emit lines for int main() {
    emit_line("int main () {");

}

void Compiler::compile_end () const {

    //dump register contents
    emit_line("std::cout << \"Register contents\\n\";");
    emit_line(
        std::string("for (int i = 0; i < ") + std::to_string(NUM_REGISTERS) + "; ++i)"
        );
    emit_line("std::cout << std::string(\"Register \") << i << \": \" << cpu_registers.at(i) << '\\n';");

    //emit lines for closing main
    emit_line("return 0;");
    emit_line("}");

}

//cradle methods

void Compiler::report_error(const std::string err) const {

    os() << '\n';
    os() << "Error: " << err << '\n';

}

void Compiler::abort(const std::string err) const {

    report_error(err);
    throw std::runtime_error("Compilation failed.\n");
}

void Compiler::expected(const std::string expect) const {

    abort(expect + " expected.\n");
}

//overload to handle single characters;
//prevents having to construct a string whenever calling expected()
void Compiler::expected(const char c) const {
    expected(std::string(1, c));
}

//checks if next character matches; if so, consume that character
void Compiler::match(const char c) const {

    if (is().peek() == c) {
        is().get();
    } else {
        expected(c);
    }
}

void Compiler::expression () const {
    term();

    while (is_in(ADD_OPS, is().peek())) {
        emit_line("cpu_stack.at(1) = cpu_stack.at(0);");
        switch (is().peek()) {
            case '+':
                add();
                break;
            case '-':
                subtract();
                break;
            default:
                expected("Addop");
        }
    }
}

void Compiler::term () const {
    char expr = get_num();

    if (expr != ERR_CHAR) {
        emit_line(
            std::string("cpu_registers.at(0) = ") + expr + ";"
        );
    }
}

// gets a valid identifier from input stream
char Compiler::get_name () const {
    if (!std::isalpha(is().peek())) {
        expected("Name");
        return ERR_CHAR;
    } else {
        return std::toupper(is().get());
    }

}

//gets a number
char Compiler::get_num () const {
    if (!std::isdigit(is().peek())) {
        expected("Integer");
        return ERR_CHAR;
    } else {
        return is().get();
    }
}

//output a string
void Compiler::emit (std::string s) const {
    os() << s;
}

//output a string with newline
void Compiler::emit_line (std::string s) const {
    emit(s);
    emit("\n");
}

//helper members to allow using stream syntax with *is, *os

void Compiler::add () const {
    match('+');
    term();
    emit_line(
        std::string("cpu_registers.at(0) = cpu_registers.at(1) + cpu_registers.at(0);")
    );
}

void Compiler::subtract () const {
    match('-');
    term();
    emit_line(
        std::string("cpu_registers.at(0) = cpu_registers.at(1) - cpu_registers.at(0);")
    );
}

bool Compiler::is_in(const std::unordered_set<char> us, const char elem) {
    return us.find(elem) != us.end();
}

void Compiler::set_is (std::istream *new_is) {
    m_is = new_is;
}

void Compiler::set_os (std::ostream *new_os) {
    m_os = new_os;
}

std::istream& Compiler::is() const {
    return *m_is;
}

std::ostream& Compiler::os() const {
    return *m_os;
}

} //end namespace<commit_msg>Included instructions in compile_end() to dump register contents.<commit_after>/*
    Implementation of the Compiler class.

*/

#include <cctype>       //character comparison functions
#include <stdexcept>
#include "compiler.hh"

namespace ds_compiler {

const size_t Compiler::NUM_REGISTERS = 8;
const char Compiler::ERR_CHAR = '\0';
const std::unordered_set<char> Compiler::ADD_OPS({'+', '-'});
const std::unordered_set<char> Compiler::MULT_OPS;

//constructors
Compiler::Compiler ()
    : m_is (&std::cin), m_os (&std::cout)
{

}

Compiler::Compiler (std::istream *new_is, std::ostream *new_os)
    : m_is (new_is), m_os (new_os)
{

}

void Compiler::compile_intermediate () const {
    try {
        expression();
    } catch (std::exception &ex) {
        std::cerr << ex.what() << '\n';
    }
}

void Compiler::compile_full () const {

    compile_start();
    compile_intermediate();
    compile_end();

}

void Compiler::compile_start () const {

    //emit lines for necessary includes
    emit_line("#include <stack>");
    emit_line("#include <vector>");
    emit_line("#include <iostream>");
    emit_line("#include <string>");

    //create a stack and vector for registers
    std::string stack_init = "static std::stack<int> cpu_stack;";
    std::string registers_init = "static std::vector<int> cpu_registers(" + std::to_string(NUM_REGISTERS) + ", 0);";
    emit_line(stack_init);
    emit_line(registers_init);

    //emit definition of a function for easier stack handling
    emit_line("int cpu_pop() {");
    emit_line("int val = cpu_stack.top();");
    emit_line("cpu_stack.pop();");
    emit_line("return val; }");

    //emit lines for int main() {
    emit_line("int main () {");

}

void Compiler::compile_end () const {

    //dump register contents
    emit_line("std::cout << \"Register contents\\n\";");
    emit_line(
        std::string("for (int i = 0; i < ") + std::to_string(NUM_REGISTERS) + "; ++i)"
        );
    emit_line("std::cout << std::string(\"Register \") << i << \": \" << cpu_registers.at(i) << '\\n';");

    //emit lines for closing main
    emit_line("return 0;");
    emit_line("}");

}

//cradle methods

void Compiler::report_error(const std::string err) const {

    os() << '\n';
    os() << "Error: " << err << '\n';

}

void Compiler::abort(const std::string err) const {

    report_error(err);
    throw std::runtime_error("Compilation failed.\n");
}

void Compiler::expected(const std::string expect) const {

    abort(expect + " expected.\n");
}

//overload to handle single characters;
//prevents having to construct a string whenever calling expected()
void Compiler::expected(const char c) const {
    expected(std::string(1, c));
}

//checks if next character matches; if so, consume that character
void Compiler::match(const char c) const {

    if (is().peek() == c) {
        is().get();
    } else {
        expected(c);
    }
}

void Compiler::expression () const {
    term();

    while (is_in(ADD_OPS, is().peek())) {
        emit_line("cpu_registers.at(1) = cpu_registers.at(0);");
        switch (is().peek()) {
            case '+':
                add();
                break;
            case '-':
                subtract();
                break;
            default:
                expected("Addop");
        }
    }
}

void Compiler::term () const {
    char expr = get_num();

    if (expr != ERR_CHAR) {
        emit_line(
            std::string("cpu_registers.at(0) = ") + expr + ";"
        );
    }
}

// gets a valid identifier from input stream
char Compiler::get_name () const {
    if (!std::isalpha(is().peek())) {
        expected("Name");
        return ERR_CHAR;
    } else {
        return std::toupper(is().get());
    }

}

//gets a number
char Compiler::get_num () const {
    if (!std::isdigit(is().peek())) {
        expected("Integer");
        return ERR_CHAR;
    } else {
        return is().get();
    }
}

//output a string
void Compiler::emit (std::string s) const {
    os() << s;
}

//output a string with newline
void Compiler::emit_line (std::string s) const {
    emit(s);
    emit("\n");
}

//helper members to allow using stream syntax with *is, *os

void Compiler::add () const {
    match('+');
    term();
    emit_line(
        std::string("cpu_registers.at(0) = cpu_registers.at(1) + cpu_registers.at(0);")
    );
}

void Compiler::subtract () const {
    match('-');
    term();
    emit_line(
        std::string("cpu_registers.at(0) = cpu_registers.at(1) - cpu_registers.at(0);")
    );
}

bool Compiler::is_in(const std::unordered_set<char> us, const char elem) {
    return us.find(elem) != us.end();
}

void Compiler::set_is (std::istream *new_is) {
    m_is = new_is;
}

void Compiler::set_os (std::ostream *new_os) {
    m_os = new_os;
}

std::istream& Compiler::is() const {
    return *m_is;
}

std::ostream& Compiler::os() const {
    return *m_os;
}

} //end namespace<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

#include "NativeControlObject.h"

#include "TiObject.h"
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <bb/cascades/Color>
#include <qtgui/QColor>

#define PROP_SETTING_FUNCTION(NAME)     prop_##NAME

#define PROP_SETTER(NAME)               static int prop_##NAME(NativeControlObject* object, TiObject* obj) \
    {\
        return object->NAME(obj);\
    }

typedef int (*NATIVE_PROPSET_CALLBACK)(NativeControlObject*, TiObject*);

// Prototypes
static void initPropertyMap();

// Statics
static vector<NATIVE_PROPSET_CALLBACK> s_functionMap;

NativeControlObject::NativeControlObject()
{
    control_ = NULL;
    initPropertyMap();
}

NativeControlObject::~NativeControlObject()
{
}

bb::cascades::Control* NativeControlObject::getControl() const
{
    return control_;
}

void NativeControlObject::setControl(bb::cascades::Control* control)
{
    control_ = control;
}

// PROP_SETTER_xxx creates a static version of functions which
// calls the non-static on method on the NativeControlObject
// class.

PROP_SETTER(setBackgroundColor)
int NativeControlObject::setBackgroundColor(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setColor)
int NativeControlObject::setColor(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setLabel)
int NativeControlObject::setLabel(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setMax)
int NativeControlObject::setMax(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setMin)
int NativeControlObject::setMin(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setText)
int NativeControlObject::setText(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTextAlign)
int NativeControlObject::setTextAlign(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTitle)
int NativeControlObject::setTitle(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTop)
int NativeControlObject::setTop(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setValue)
int NativeControlObject::setValue(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setVisible)
int NativeControlObject::setVisible(TiObject* obj)
{
    bool visible;
    int error = getBoolean(obj, &visible);
    if (error != NATIVE_ERROR_OK)
    {
        return error;
    }
    ((bb::cascades::Control*)getNativeHandle())->setVisible(visible);
    return NATIVE_ERROR_OK;
}

// PROP_SETTING_FUNCTION resolves the static name of the function, e.g.,
// PROP_SETTING_FUNCTION(setBackgroundColor) resolves to "prop_setBackgroundColor"

static void initPropertyMap()
{
    static bool initialized = false;
    if (initialized == false)
    {
        initialized = true;
        s_functionMap.resize(N_PROP_LAST);

        s_functionMap[N_PROP_UNDEFINED]                         = NULL;
        s_functionMap[N_PROP_ANCHOR_POINT]                      = NULL;
        s_functionMap[N_PROP_ANIMATED_CENTER_POINT]             = NULL;
        s_functionMap[N_PROP_AUTO_LINK]                         = NULL;
        s_functionMap[N_PROP_BACKGROUND_COLOR]                  = PROP_SETTING_FUNCTION(setBackgroundColor);
        s_functionMap[N_PROP_BACKGROUND_DISABLED_COLOR]         = NULL;
        s_functionMap[N_PROP_BACKGROUND_DISABLED_IMAGE]         = NULL;
        s_functionMap[N_PROP_BACKGROUND_FOCUSED_COLOR]          = NULL;
        s_functionMap[N_PROP_BACKGROUND_FOCUSED_IMAGE]          = NULL;
        s_functionMap[N_PROP_BACKGROUND_GRADIANT]               = NULL;
        s_functionMap[N_PROP_BACKGROUND_IMAGE]                  = NULL;
        s_functionMap[N_PROP_BACKGROUND_LEFT_CAP]               = NULL;
        s_functionMap[N_PROP_BACKGROUND_PADDING_BOTTOM]         = NULL;
        s_functionMap[N_PROP_BACKGROUND_PADDING_LEFT]           = NULL;
        s_functionMap[N_PROP_BACKGROUND_PADDING_RIGHT]          = NULL;
        s_functionMap[N_PROP_BACKGROUND_PADDING_TOP]            = NULL;
        s_functionMap[N_PROP_BACKGROUND_REPEAT]                 = NULL;
        s_functionMap[N_PROP_BACKGROUND_SELECTED_COLOR]         = NULL;
        s_functionMap[N_PROP_BACKGROUND_SELECTED_IMAGE]         = NULL;
        s_functionMap[N_PROP_BACKGROUND_TOP_CAP]                = NULL;
        s_functionMap[N_PROP_BORDER_COLOR]                      = NULL;
        s_functionMap[N_PROP_BORDER_RADIUS]                     = NULL;
        s_functionMap[N_PROP_BORDER_WIDTH]                      = NULL;
        s_functionMap[N_PROP_BOTTOM]                            = NULL;
        s_functionMap[N_PROP_CENTER]                            = NULL;
        s_functionMap[N_PROP_CHILDREN]                          = NULL;
        s_functionMap[N_PROP_COLOR]                             = PROP_SETTING_FUNCTION(setColor);
        s_functionMap[N_PROP_ELLIPSIZE]                         = NULL;
        s_functionMap[N_PROP_FOCUSABLE]                         = NULL;
        s_functionMap[N_PROP_FONT]                              = NULL;
        s_functionMap[N_PROP_HEIGHT]                            = NULL;
        s_functionMap[N_PROP_HIGHLIGHTED_COLOR]                 = NULL;
        s_functionMap[N_PROP_HINT_TEXT]                         = NULL;
        s_functionMap[N_PROP_HTML]                              = NULL;
        s_functionMap[N_PROP_IMAGE]                             = NULL;
        s_functionMap[N_PROP_KEEP_SCREEN_ON]                    = NULL;
        s_functionMap[N_PROP_LABEL]                             = PROP_SETTING_FUNCTION(setLabel);
        s_functionMap[N_PROP_LAYOUT]                            = NULL;
        s_functionMap[N_PROP_LEFT]                              = NULL;
        s_functionMap[N_PROP_MAX]                               = PROP_SETTING_FUNCTION(setMax);
        s_functionMap[N_PROP_MIN]                               = PROP_SETTING_FUNCTION(setMin);
        s_functionMap[N_PROP_MINIMUM_FONT_SIZE]                 = NULL;
        s_functionMap[N_PROP_OPACITY]                           = NULL;
        s_functionMap[N_PROP_RIGHT]                             = NULL;
        s_functionMap[N_PROP_SHADOW_COLOR]                      = NULL;
        s_functionMap[N_PROP_SHADOW_OFFSET]                     = NULL;
        s_functionMap[N_PROP_SIZE]                              = NULL;
        s_functionMap[N_PROP_SOFT_KEYBOARD_ON_FOCUS]            = NULL;
        s_functionMap[N_PROP_TEXT]                              = PROP_SETTING_FUNCTION(setText);
        s_functionMap[N_PROP_TEXT_ALIGN]                        = PROP_SETTING_FUNCTION(setTextAlign);
        s_functionMap[N_PROP_TEXT_ID]                           = NULL;
        s_functionMap[N_PROP_TITLE]                             = PROP_SETTING_FUNCTION(setTitle);
        s_functionMap[N_PROP_TOP]                               = PROP_SETTING_FUNCTION(setTop);
        s_functionMap[N_PROP_TOUCH_ENABLED]                     = NULL;
        s_functionMap[N_PROP_TRANSFORM]                         = NULL;
        s_functionMap[N_PROP_VALUE]                             = PROP_SETTING_FUNCTION(setValue);
        s_functionMap[N_PROP_VISIBLE]                           = PROP_SETTING_FUNCTION(setVisible);
        s_functionMap[N_PROP_WIDTH]                             = NULL;
        s_functionMap[N_PROP_WORD_WRAP]                         = NULL;
        s_functionMap[N_PROP_ZINDEX]                            = NULL;
    }
}

int NativeControlObject::setPropertyValue(size_t propertyNumber, TiObject* obj)
{
    if ((propertyNumber < 0) || (propertyNumber >= s_functionMap.size())
            || (s_functionMap[propertyNumber] == NULL))
    {
        return NATIVE_ERROR_NOTSUPPORTED;
    }
    return (s_functionMap[propertyNumber])(this, obj);
}

int NativeControlObject::getColorComponents(TiObject* obj, float* r, float* g, float* b, float* a)
{
    Handle<Value> value = obj->getValue();
    if ((value.IsEmpty()) || (!value->IsString()))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<String> v8color = Handle<String>::Cast(value);
    String::Utf8Value v8colorString(v8color);
    if (!QColor::isValidColor(*v8colorString))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    QColor qcolor(*v8colorString);
    qreal qr, qg, qb, qa;
    qcolor.getRgbF(&qr, &qg, &qb, &qa);
    *r = qr;
    *g = qg;
    *b = qb;
    *a = qa;
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getBoolean(TiObject* obj, bool* value)
{
    Handle<Value> v8value = obj->getValue();
    if ((v8value.IsEmpty()) || ((!v8value->IsBoolean()) && (!v8value->IsBooleanObject())))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<Boolean> b = v8value->ToBoolean();
    *value = b->Value();
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getString(TiObject* obj, QString& str)
{
    Handle<Value> value = obj->getValue();
    if ((value.IsEmpty()) || (!value->IsString()))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<String> v8string = Handle<String>::Cast(value);
    String::Utf8Value v8UtfString(v8string);
    const char* cStr = *v8UtfString;
    str = cStr;
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getFloat(TiObject* obj, float* value)
{
    Handle<Value> v8value = obj->getValue();
    if ((v8value.IsEmpty()) || ((!v8value->IsNumber()) && (!v8value->IsNumberObject())))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<Number> num = Handle<Number>::Cast(v8value);
    *value = (float)num->Value();
    return NATIVE_ERROR_OK;
}
<commit_msg>Make the functionMap const by initializing it statically, renamed the init function to initFunctionMap<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

#include "NativeControlObject.h"

#include "TiObject.h"
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <bb/cascades/Color>
#include <qtgui/QColor>

#define PROP_SETTING_FUNCTION(NAME)     prop_##NAME

#define PROP_SETTER(NAME)               static int prop_##NAME(NativeControlObject* object, TiObject* obj) \
    {\
        return object->NAME(obj);\
    }

typedef int (*NATIVE_PROPSET_CALLBACK)(NativeControlObject*, TiObject*);

// Prototypes
static vector<NATIVE_PROPSET_CALLBACK> initFunctionMap();

// Statics
static const vector<NATIVE_PROPSET_CALLBACK> s_functionMap = initFunctionMap();

NativeControlObject::NativeControlObject()
{
    control_ = NULL;
}

NativeControlObject::~NativeControlObject()
{
}

bb::cascades::Control* NativeControlObject::getControl() const
{
    return control_;
}

void NativeControlObject::setControl(bb::cascades::Control* control)
{
    control_ = control;
}

// PROP_SETTER_xxx creates a static version of functions which
// calls the non-static on method on the NativeControlObject
// class.

PROP_SETTER(setBackgroundColor)
int NativeControlObject::setBackgroundColor(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setColor)
int NativeControlObject::setColor(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setLabel)
int NativeControlObject::setLabel(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setMax)
int NativeControlObject::setMax(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setMin)
int NativeControlObject::setMin(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setText)
int NativeControlObject::setText(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTextAlign)
int NativeControlObject::setTextAlign(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTitle)
int NativeControlObject::setTitle(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setTop)
int NativeControlObject::setTop(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setValue)
int NativeControlObject::setValue(TiObject* obj)
{
    return NATIVE_ERROR_NOTSUPPORTED;
}

PROP_SETTER(setVisible)
int NativeControlObject::setVisible(TiObject* obj)
{
    bool visible;
    int error = getBoolean(obj, &visible);
    if (error != NATIVE_ERROR_OK)
    {
        return error;
    }
    ((bb::cascades::Control*)getNativeHandle())->setVisible(visible);
    return NATIVE_ERROR_OK;
}

// PROP_SETTING_FUNCTION resolves the static name of the function, e.g.,
// PROP_SETTING_FUNCTION(setBackgroundColor) resolves to "prop_setBackgroundColor"

static vector<NATIVE_PROPSET_CALLBACK> initFunctionMap()
{
    vector<NATIVE_PROPSET_CALLBACK> vect;
    vect.resize(N_PROP_LAST);

    vect[N_PROP_UNDEFINED]                         = NULL;
    vect[N_PROP_ANCHOR_POINT]                      = NULL;
    vect[N_PROP_ANIMATED_CENTER_POINT]             = NULL;
    vect[N_PROP_AUTO_LINK]                         = NULL;
    vect[N_PROP_BACKGROUND_COLOR]                  = PROP_SETTING_FUNCTION(setBackgroundColor);
    vect[N_PROP_BACKGROUND_DISABLED_COLOR]         = NULL;
    vect[N_PROP_BACKGROUND_DISABLED_IMAGE]         = NULL;
    vect[N_PROP_BACKGROUND_FOCUSED_COLOR]          = NULL;
    vect[N_PROP_BACKGROUND_FOCUSED_IMAGE]          = NULL;
    vect[N_PROP_BACKGROUND_GRADIANT]               = NULL;
    vect[N_PROP_BACKGROUND_IMAGE]                  = NULL;
    vect[N_PROP_BACKGROUND_LEFT_CAP]               = NULL;
    vect[N_PROP_BACKGROUND_PADDING_BOTTOM]         = NULL;
    vect[N_PROP_BACKGROUND_PADDING_LEFT]           = NULL;
    vect[N_PROP_BACKGROUND_PADDING_RIGHT]          = NULL;
    vect[N_PROP_BACKGROUND_PADDING_TOP]            = NULL;
    vect[N_PROP_BACKGROUND_REPEAT]                 = NULL;
    vect[N_PROP_BACKGROUND_SELECTED_COLOR]         = NULL;
    vect[N_PROP_BACKGROUND_SELECTED_IMAGE]         = NULL;
    vect[N_PROP_BACKGROUND_TOP_CAP]                = NULL;
    vect[N_PROP_BORDER_COLOR]                      = NULL;
    vect[N_PROP_BORDER_RADIUS]                     = NULL;
    vect[N_PROP_BORDER_WIDTH]                      = NULL;
    vect[N_PROP_BOTTOM]                            = NULL;
    vect[N_PROP_CENTER]                            = NULL;
    vect[N_PROP_CHILDREN]                          = NULL;
    vect[N_PROP_COLOR]                             = PROP_SETTING_FUNCTION(setColor);
    vect[N_PROP_ELLIPSIZE]                         = NULL;
    vect[N_PROP_FOCUSABLE]                         = NULL;
    vect[N_PROP_FONT]                              = NULL;
    vect[N_PROP_HEIGHT]                            = NULL;
    vect[N_PROP_HIGHLIGHTED_COLOR]                 = NULL;
    vect[N_PROP_HINT_TEXT]                         = NULL;
    vect[N_PROP_HTML]                              = NULL;
    vect[N_PROP_IMAGE]                             = NULL;
    vect[N_PROP_KEEP_SCREEN_ON]                    = NULL;
    vect[N_PROP_LABEL]                             = PROP_SETTING_FUNCTION(setLabel);
    vect[N_PROP_LAYOUT]                            = NULL;
    vect[N_PROP_LEFT]                              = NULL;
    vect[N_PROP_MAX]                               = PROP_SETTING_FUNCTION(setMax);
    vect[N_PROP_MIN]                               = PROP_SETTING_FUNCTION(setMin);
    vect[N_PROP_MINIMUM_FONT_SIZE]                 = NULL;
    vect[N_PROP_OPACITY]                           = NULL;
    vect[N_PROP_RIGHT]                             = NULL;
    vect[N_PROP_SHADOW_COLOR]                      = NULL;
    vect[N_PROP_SHADOW_OFFSET]                     = NULL;
    vect[N_PROP_SIZE]                              = NULL;
    vect[N_PROP_SOFT_KEYBOARD_ON_FOCUS]            = NULL;
    vect[N_PROP_TEXT]                              = PROP_SETTING_FUNCTION(setText);
    vect[N_PROP_TEXT_ALIGN]                        = PROP_SETTING_FUNCTION(setTextAlign);
    vect[N_PROP_TEXT_ID]                           = NULL;
    vect[N_PROP_TITLE]                             = PROP_SETTING_FUNCTION(setTitle);
    vect[N_PROP_TOP]                               = PROP_SETTING_FUNCTION(setTop);
    vect[N_PROP_TOUCH_ENABLED]                     = NULL;
    vect[N_PROP_TRANSFORM]                         = NULL;
    vect[N_PROP_VALUE]                             = PROP_SETTING_FUNCTION(setValue);
    vect[N_PROP_VISIBLE]                           = PROP_SETTING_FUNCTION(setVisible);
    vect[N_PROP_WIDTH]                             = NULL;
    vect[N_PROP_WORD_WRAP]                         = NULL;
    vect[N_PROP_ZINDEX]                            = NULL;
    return vect;
}

int NativeControlObject::setPropertyValue(size_t propertyNumber, TiObject* obj)
{
    if ((propertyNumber < 0) || (propertyNumber >= s_functionMap.size())
            || (s_functionMap[propertyNumber] == NULL))
    {
        return NATIVE_ERROR_NOTSUPPORTED;
    }
    return (s_functionMap[propertyNumber])(this, obj);
}

int NativeControlObject::getColorComponents(TiObject* obj, float* r, float* g, float* b, float* a)
{
    Handle<Value> value = obj->getValue();
    if ((value.IsEmpty()) || (!value->IsString()))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<String> v8color = Handle<String>::Cast(value);
    String::Utf8Value v8colorString(v8color);
    if (!QColor::isValidColor(*v8colorString))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    QColor qcolor(*v8colorString);
    qreal qr, qg, qb, qa;
    qcolor.getRgbF(&qr, &qg, &qb, &qa);
    *r = qr;
    *g = qg;
    *b = qb;
    *a = qa;
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getBoolean(TiObject* obj, bool* value)
{
    Handle<Value> v8value = obj->getValue();
    if ((v8value.IsEmpty()) || ((!v8value->IsBoolean()) && (!v8value->IsBooleanObject())))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<Boolean> b = v8value->ToBoolean();
    *value = b->Value();
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getString(TiObject* obj, QString& str)
{
    Handle<Value> value = obj->getValue();
    if ((value.IsEmpty()) || (!value->IsString()))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<String> v8string = Handle<String>::Cast(value);
    String::Utf8Value v8UtfString(v8string);
    const char* cStr = *v8UtfString;
    str = cStr;
    return NATIVE_ERROR_OK;
}

int NativeControlObject::getFloat(TiObject* obj, float* value)
{
    Handle<Value> v8value = obj->getValue();
    if ((v8value.IsEmpty()) || ((!v8value->IsNumber()) && (!v8value->IsNumberObject())))
    {
        return NATIVE_ERROR_INVALID_ARG;
    }
    Handle<Number> num = Handle<Number>::Cast(v8value);
    *value = (float)num->Value();
    return NATIVE_ERROR_OK;
}
<|endoftext|>


<commit_before>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2010, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
// ==========================================================================
// Tests for the sequence_journaled module.
// ==========================================================================

#include <seqan/basic.h>
#include <seqan/file.h>

#include "test_sequence_journaled.h"
#include "test_sequence_journaled_iterator.h"

SEQAN_BEGIN_TESTSUITE(test_sequence_journaled) {
    // Call tests of the sequence journal with unbalanced tree journal.
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_set);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_host);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_clear);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_erase_position);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_erase_begin_end);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_insert);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_insert_value);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign_value);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_subscript_operator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign_infix);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_length);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_virtual_to_host_position);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_copy_constructor);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_begin_end_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_begin_end_const_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_subscript_operator_randomized);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_fuzzying);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_segments_read_only);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_segments_read_write);

    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_sum);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_difference);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_relations);

    // Call tests of the sequence journal with sorted array journals.
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_set);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_host);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_clear);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_erase_position);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_erase_begin_end);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_insert);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_insert_value);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign_value);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_subscript_operator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign_infix);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_length);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_virtual_to_host_position);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_copy_constructor);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_begin_end_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_begin_end_const_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_subscript_operator_randomized);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_fuzzying);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_segments_read_only);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_segments_read_write);

    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_sum);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_difference);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_relations);

    // Verify checkpoints.
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entry.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_sorted_array.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/sequence_journaled.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/sequence_journaled_iterator.h");
}
SEQAN_END_TESTSUITE
<commit_msg>removed redundant tests<commit_after>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2010, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
// ==========================================================================
// Tests for the sequence_journaled module.
// ==========================================================================

#include <seqan/basic.h>
#include <seqan/file.h>

#include "test_sequence_journaled.h"
#include "test_sequence_journaled_iterator.h"

SEQAN_BEGIN_TESTSUITE(test_sequence_journaled) {
    // Call tests of the sequence journal with unbalanced tree journal.
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_set);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_host);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_clear);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_erase_position);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_erase_begin_end);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_insert);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_insert_value);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign_value);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_subscript_operator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_assign_infix);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_length);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_virtual_to_host_position);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_copy_constructor);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_begin_end_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_begin_end_const_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_subscript_operator_randomized);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_fuzzying);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_segments_read_only);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_segments_read_write);

    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_sum);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_difference);
    SEQAN_CALL_TEST(test_sequence_journaled_unbalanced_tree_iterator_relations);

    // Call tests of the sequence journal with sorted array journals.
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_set);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_host);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_clear);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_erase_position);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_erase_begin_end);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_insert);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_insert_value);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign_value);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_subscript_operator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_assign_infix);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_length);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_virtual_to_host_position);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_copy_constructor);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_begin_end_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_begin_end_const_iterator);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_subscript_operator_randomized);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_fuzzying);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_segments_read_only);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_segments_read_write);

    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_sum);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_difference);
    SEQAN_CALL_TEST(test_sequence_journaled_sorted_array_iterator_relations);

    // Verify checkpoints.
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entry.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/journal_entries_sorted_array.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/sequence_journaled.h");
    SEQAN_VERIFY_CHECKPOINTS("projects/library/seqan/sequence_journaled/sequence_journaled_iterator.h");
}
SEQAN_END_TESTSUITE
<|endoftext|>


<commit_before>//===--- Registry.cpp - Matcher registry -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===------------------------------------------------------------===//
///
/// \file
/// \brief Registry map populated at static initialization time.
///
//===------------------------------------------------------------===//

#include "clang/ASTMatchers/Dynamic/Registry.h"

#include <utility>

#include "Marshallers.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ManagedStatic.h"

namespace clang {
namespace ast_matchers {
namespace dynamic {
namespace {

using internal::MatcherDescriptor;

typedef llvm::StringMap<const MatcherDescriptor *> ConstructorMap;
class RegistryMaps {
public:
  RegistryMaps();
  ~RegistryMaps();

  const ConstructorMap &constructors() const { return Constructors; }

private:
  void registerMatcher(StringRef MatcherName, MatcherDescriptor *Callback);
  ConstructorMap Constructors;
};

void RegistryMaps::registerMatcher(StringRef MatcherName,
                                   MatcherDescriptor *Callback) {
  assert(Constructors.find(MatcherName) == Constructors.end());
  Constructors[MatcherName] = Callback;
}

#define REGISTER_MATCHER(name)                                                 \
  registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
                             ::clang::ast_matchers::name, #name));

#define SPECIFIC_MATCHER_OVERLOAD(name, Id)                                    \
  static_cast< ::clang::ast_matchers::name##_Type##Id>(                        \
      ::clang::ast_matchers::name)

#define REGISTER_OVERLOADED_2(name)                                            \
  do {                                                                         \
    MatcherDescriptor *Callbacks[] = {                                         \
      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0),    \
                                        #name),                                \
      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1),    \
                                        #name)                                 \
    };                                                                         \
    registerMatcher(#name,                                                     \
                    new internal::OverloadedMatcherDescriptor(Callbacks));     \
  } while (0)

/// \brief Generate a registry map with all the known matchers.
RegistryMaps::RegistryMaps() {
  // TODO: Here is the list of the missing matchers, grouped by reason.
  //
  // Need Variant/Parser fixes:
  // ofKind
  //
  // Polymorphic + argument overload:
  // findAll
  //
  // Other:
  // loc
  // equals
  // equalsNode

  REGISTER_OVERLOADED_2(callee);
  REGISTER_OVERLOADED_2(hasPrefix);
  REGISTER_OVERLOADED_2(hasType);
  REGISTER_OVERLOADED_2(isDerivedFrom);
  REGISTER_OVERLOADED_2(isSameOrDerivedFrom);
  REGISTER_OVERLOADED_2(pointsTo);
  REGISTER_OVERLOADED_2(references);
  REGISTER_OVERLOADED_2(thisPointerType);

  REGISTER_MATCHER(accessSpecDecl);
  REGISTER_MATCHER(alignOfExpr);
  REGISTER_MATCHER(allOf);
  REGISTER_MATCHER(anyOf);
  REGISTER_MATCHER(anything);
  REGISTER_MATCHER(argumentCountIs);
  REGISTER_MATCHER(arraySubscriptExpr);
  REGISTER_MATCHER(arrayType);
  REGISTER_MATCHER(asString);
  REGISTER_MATCHER(asmStmt);
  REGISTER_MATCHER(atomicType);
  REGISTER_MATCHER(autoType);
  REGISTER_MATCHER(binaryOperator);
  REGISTER_MATCHER(bindTemporaryExpr);
  REGISTER_MATCHER(blockPointerType);
  REGISTER_MATCHER(boolLiteral);
  REGISTER_MATCHER(breakStmt);
  REGISTER_MATCHER(builtinType);
  REGISTER_MATCHER(cStyleCastExpr);
  REGISTER_MATCHER(callExpr);
  REGISTER_MATCHER(castExpr);
  REGISTER_MATCHER(catchStmt);
  REGISTER_MATCHER(characterLiteral);
  REGISTER_MATCHER(classTemplateDecl);
  REGISTER_MATCHER(classTemplateSpecializationDecl);
  REGISTER_MATCHER(complexType);
  REGISTER_MATCHER(compoundLiteralExpr);
  REGISTER_MATCHER(compoundStmt);
  REGISTER_MATCHER(conditionalOperator);
  REGISTER_MATCHER(constCastExpr);
  REGISTER_MATCHER(constantArrayType);
  REGISTER_MATCHER(constructExpr);
  REGISTER_MATCHER(constructorDecl);
  REGISTER_MATCHER(containsDeclaration);
  REGISTER_MATCHER(continueStmt);
  REGISTER_MATCHER(ctorInitializer);
  REGISTER_MATCHER(decl);
  REGISTER_MATCHER(declCountIs);
  REGISTER_MATCHER(declRefExpr);
  REGISTER_MATCHER(declStmt);
  REGISTER_MATCHER(defaultArgExpr);
  REGISTER_MATCHER(deleteExpr);
  REGISTER_MATCHER(dependentSizedArrayType);
  REGISTER_MATCHER(destructorDecl);
  REGISTER_MATCHER(doStmt);
  REGISTER_MATCHER(dynamicCastExpr);
  REGISTER_MATCHER(eachOf);
  REGISTER_MATCHER(elaboratedType);
  REGISTER_MATCHER(enumConstantDecl);
  REGISTER_MATCHER(enumDecl);
  REGISTER_MATCHER(explicitCastExpr);
  REGISTER_MATCHER(expr);
  REGISTER_MATCHER(fieldDecl);
  REGISTER_MATCHER(floatLiteral);
  REGISTER_MATCHER(forEach);
  REGISTER_MATCHER(forEachDescendant);
  REGISTER_MATCHER(forField);
  REGISTER_MATCHER(forRangeStmt);
  REGISTER_MATCHER(forStmt);
  REGISTER_MATCHER(functionDecl);
  REGISTER_MATCHER(functionTemplateDecl);
  REGISTER_MATCHER(functionType);
  REGISTER_MATCHER(functionalCastExpr);
  REGISTER_MATCHER(gotoStmt);
  REGISTER_MATCHER(has);
  REGISTER_MATCHER(hasAncestor);
  REGISTER_MATCHER(hasAnyArgument);
  REGISTER_MATCHER(hasAnyConstructorInitializer);
  REGISTER_MATCHER(hasAnyParameter);
  REGISTER_MATCHER(hasAnySubstatement);
  REGISTER_MATCHER(hasAnyTemplateArgument);
  REGISTER_MATCHER(hasAnyUsingShadowDecl);
  REGISTER_MATCHER(hasArgument);
  REGISTER_MATCHER(hasArgumentOfType);
  REGISTER_MATCHER(hasBase);
  REGISTER_MATCHER(hasBody);
  REGISTER_MATCHER(hasCanonicalType);
  REGISTER_MATCHER(hasCondition);
  REGISTER_MATCHER(hasConditionVariableStatement);
  REGISTER_MATCHER(hasDeclContext);
  REGISTER_MATCHER(hasDeclaration);
  REGISTER_MATCHER(hasDeducedType);
  REGISTER_MATCHER(hasDescendant);
  REGISTER_MATCHER(hasDestinationType);
  REGISTER_MATCHER(hasEitherOperand);
  REGISTER_MATCHER(hasElementType);
  REGISTER_MATCHER(hasFalseExpression);
  REGISTER_MATCHER(hasImplicitDestinationType);
  REGISTER_MATCHER(hasIncrement);
  REGISTER_MATCHER(hasIndex);
  REGISTER_MATCHER(hasInitializer);
  REGISTER_MATCHER(hasLHS);
  REGISTER_MATCHER(hasLocalQualifiers);
  REGISTER_MATCHER(hasLoopInit);
  REGISTER_MATCHER(hasMethod);
  REGISTER_MATCHER(hasName);
  REGISTER_MATCHER(hasObjectExpression);
  REGISTER_MATCHER(hasOperatorName);
  REGISTER_MATCHER(hasOverloadedOperatorName);
  REGISTER_MATCHER(hasParameter);
  REGISTER_MATCHER(hasParent);
  REGISTER_MATCHER(hasQualifier);
  REGISTER_MATCHER(hasRHS);
  REGISTER_MATCHER(hasSingleDecl);
  REGISTER_MATCHER(hasSize);
  REGISTER_MATCHER(hasSizeExpr);
  REGISTER_MATCHER(hasSourceExpression);
  REGISTER_MATCHER(hasTargetDecl);
  REGISTER_MATCHER(hasTemplateArgument);
  REGISTER_MATCHER(hasTrueExpression);
  REGISTER_MATCHER(hasUnaryOperand);
  REGISTER_MATCHER(hasValueType);
  REGISTER_MATCHER(ifStmt);
  REGISTER_MATCHER(ignoringImpCasts);
  REGISTER_MATCHER(ignoringParenCasts);
  REGISTER_MATCHER(ignoringParenImpCasts);
  REGISTER_MATCHER(implicitCastExpr);
  REGISTER_MATCHER(incompleteArrayType);
  REGISTER_MATCHER(initListExpr);
  REGISTER_MATCHER(innerType);
  REGISTER_MATCHER(integerLiteral);
  REGISTER_MATCHER(isArrow);
  REGISTER_MATCHER(isConstQualified);
  REGISTER_MATCHER(isDefinition);
  REGISTER_MATCHER(isExplicitTemplateSpecialization);
  REGISTER_MATCHER(isExternC);
  REGISTER_MATCHER(isImplicit);
  REGISTER_MATCHER(isInteger);
  REGISTER_MATCHER(isOverride);
  REGISTER_MATCHER(isPrivate);
  REGISTER_MATCHER(isProtected);
  REGISTER_MATCHER(isPublic);
  REGISTER_MATCHER(isTemplateInstantiation);
  REGISTER_MATCHER(isVirtual);
  REGISTER_MATCHER(isWritten);
  REGISTER_MATCHER(lValueReferenceType);
  REGISTER_MATCHER(labelStmt);
  REGISTER_MATCHER(lambdaExpr);
  REGISTER_MATCHER(matchesName);
  REGISTER_MATCHER(materializeTemporaryExpr);
  REGISTER_MATCHER(member);
  REGISTER_MATCHER(memberCallExpr);
  REGISTER_MATCHER(memberExpr);
  REGISTER_MATCHER(memberPointerType);
  REGISTER_MATCHER(methodDecl);
  REGISTER_MATCHER(namedDecl);
  REGISTER_MATCHER(namesType);
  REGISTER_MATCHER(namespaceDecl);
  REGISTER_MATCHER(nestedNameSpecifier);
  REGISTER_MATCHER(nestedNameSpecifierLoc);
  REGISTER_MATCHER(newExpr);
  REGISTER_MATCHER(nullPtrLiteralExpr);
  REGISTER_MATCHER(nullStmt);
  REGISTER_MATCHER(ofClass);
  REGISTER_MATCHER(on);
  REGISTER_MATCHER(onImplicitObjectArgument);
  REGISTER_MATCHER(operatorCallExpr);
  REGISTER_MATCHER(parameterCountIs);
  REGISTER_MATCHER(parenType);
  REGISTER_MATCHER(pointee);
  REGISTER_MATCHER(pointerType);
  REGISTER_MATCHER(qualType);
  REGISTER_MATCHER(rValueReferenceType);
  REGISTER_MATCHER(recordDecl);
  REGISTER_MATCHER(recordType);
  REGISTER_MATCHER(referenceType);
  REGISTER_MATCHER(refersToDeclaration);
  REGISTER_MATCHER(refersToType);
  REGISTER_MATCHER(reinterpretCastExpr);
  REGISTER_MATCHER(returnStmt);
  REGISTER_MATCHER(returns);
  REGISTER_MATCHER(sizeOfExpr);
  REGISTER_MATCHER(specifiesNamespace);
  REGISTER_MATCHER(specifiesType);
  REGISTER_MATCHER(specifiesTypeLoc);
  REGISTER_MATCHER(statementCountIs);
  REGISTER_MATCHER(staticCastExpr);
  REGISTER_MATCHER(stmt);
  REGISTER_MATCHER(stringLiteral);
  REGISTER_MATCHER(switchCase);
  REGISTER_MATCHER(switchStmt);
  REGISTER_MATCHER(templateSpecializationType);
  REGISTER_MATCHER(thisExpr);
  REGISTER_MATCHER(throughUsingDecl);
  REGISTER_MATCHER(throwExpr);
  REGISTER_MATCHER(to);
  REGISTER_MATCHER(tryStmt);
  REGISTER_MATCHER(type);
  REGISTER_MATCHER(typeLoc);
  REGISTER_MATCHER(typedefType);
  REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
  REGISTER_MATCHER(unaryOperator);
  REGISTER_MATCHER(unless);
  REGISTER_MATCHER(userDefinedLiteral);
  REGISTER_MATCHER(usingDecl);
  REGISTER_MATCHER(varDecl);
  REGISTER_MATCHER(variableArrayType);
  REGISTER_MATCHER(whileStmt);
  REGISTER_MATCHER(withInitializer);
}

RegistryMaps::~RegistryMaps() {
  for (ConstructorMap::iterator it = Constructors.begin(),
                                end = Constructors.end();
       it != end; ++it) {
    delete it->second;
  }
}

static llvm::ManagedStatic<RegistryMaps> RegistryData;

} // anonymous namespace

// static
llvm::Optional<MatcherCtor>
Registry::lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
                            Diagnostics *Error) {
  ConstructorMap::const_iterator it =
      RegistryData->constructors().find(MatcherName);
  if (it == RegistryData->constructors().end()) {
    Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
    return llvm::Optional<MatcherCtor>();
  }

  return it->second;
}

// static
VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
                                          const SourceRange &NameRange,
                                          ArrayRef<ParserValue> Args,
                                          Diagnostics *Error) {
  return Ctor->create(NameRange, Args, Error);
}

// static
VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
                                               const SourceRange &NameRange,
                                               StringRef BindID,
                                               ArrayRef<ParserValue> Args,
                                               Diagnostics *Error) {
  VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error);
  if (Out.isNull()) return Out;

  llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
  if (Result.hasValue()) {
    llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
    if (Bound.hasValue()) {
      return VariantMatcher::SingleMatcher(*Bound);
    }
  }
  Error->addError(NameRange, Error->ET_RegistryNotBindable);
  return VariantMatcher();
}

}  // namespace dynamic
}  // namespace ast_matchers
}  // namespace clang
<commit_msg>Another pass at adding missing matchers into the registry.<commit_after>//===--- Registry.cpp - Matcher registry -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===------------------------------------------------------------===//
///
/// \file
/// \brief Registry map populated at static initialization time.
///
//===------------------------------------------------------------===//

#include "clang/ASTMatchers/Dynamic/Registry.h"

#include <utility>

#include "Marshallers.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ManagedStatic.h"

namespace clang {
namespace ast_matchers {
namespace dynamic {
namespace {

using internal::MatcherDescriptor;

typedef llvm::StringMap<const MatcherDescriptor *> ConstructorMap;
class RegistryMaps {
public:
  RegistryMaps();
  ~RegistryMaps();

  const ConstructorMap &constructors() const { return Constructors; }

private:
  void registerMatcher(StringRef MatcherName, MatcherDescriptor *Callback);
  ConstructorMap Constructors;
};

void RegistryMaps::registerMatcher(StringRef MatcherName,
                                   MatcherDescriptor *Callback) {
  assert(Constructors.find(MatcherName) == Constructors.end());
  Constructors[MatcherName] = Callback;
}

#define REGISTER_MATCHER(name)                                                 \
  registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
                             ::clang::ast_matchers::name, #name));

#define SPECIFIC_MATCHER_OVERLOAD(name, Id)                                    \
  static_cast< ::clang::ast_matchers::name##_Type##Id>(                        \
      ::clang::ast_matchers::name)

#define REGISTER_OVERLOADED_2(name)                                            \
  do {                                                                         \
    MatcherDescriptor *Callbacks[] = {                                         \
      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0),    \
                                        #name),                                \
      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1),    \
                                        #name)                                 \
    };                                                                         \
    registerMatcher(#name,                                                     \
                    new internal::OverloadedMatcherDescriptor(Callbacks));     \
  } while (0)

/// \brief Generate a registry map with all the known matchers.
RegistryMaps::RegistryMaps() {
  // TODO: Here is the list of the missing matchers, grouped by reason.
  //
  // Need Variant/Parser fixes:
  // ofKind
  //
  // Polymorphic + argument overload:
  // findAll
  //
  // Other:
  // loc
  // equals
  // equalsNode

  REGISTER_OVERLOADED_2(callee);
  REGISTER_OVERLOADED_2(hasPrefix);
  REGISTER_OVERLOADED_2(hasType);
  REGISTER_OVERLOADED_2(isDerivedFrom);
  REGISTER_OVERLOADED_2(isSameOrDerivedFrom);
  REGISTER_OVERLOADED_2(pointsTo);
  REGISTER_OVERLOADED_2(references);
  REGISTER_OVERLOADED_2(thisPointerType);

  REGISTER_MATCHER(accessSpecDecl);
  REGISTER_MATCHER(alignOfExpr);
  REGISTER_MATCHER(allOf);
  REGISTER_MATCHER(anyOf);
  REGISTER_MATCHER(anything);
  REGISTER_MATCHER(argumentCountIs);
  REGISTER_MATCHER(arraySubscriptExpr);
  REGISTER_MATCHER(arrayType);
  REGISTER_MATCHER(asString);
  REGISTER_MATCHER(asmStmt);
  REGISTER_MATCHER(atomicType);
  REGISTER_MATCHER(autoType);
  REGISTER_MATCHER(binaryOperator);
  REGISTER_MATCHER(bindTemporaryExpr);
  REGISTER_MATCHER(blockPointerType);
  REGISTER_MATCHER(boolLiteral);
  REGISTER_MATCHER(breakStmt);
  REGISTER_MATCHER(builtinType);
  REGISTER_MATCHER(cStyleCastExpr);
  REGISTER_MATCHER(callExpr);
  REGISTER_MATCHER(caseStmt);
  REGISTER_MATCHER(castExpr);
  REGISTER_MATCHER(catchStmt);
  REGISTER_MATCHER(characterLiteral);
  REGISTER_MATCHER(classTemplateDecl);
  REGISTER_MATCHER(classTemplateSpecializationDecl);
  REGISTER_MATCHER(complexType);
  REGISTER_MATCHER(compoundLiteralExpr);
  REGISTER_MATCHER(compoundStmt);
  REGISTER_MATCHER(conditionalOperator);
  REGISTER_MATCHER(constCastExpr);
  REGISTER_MATCHER(constantArrayType);
  REGISTER_MATCHER(constructExpr);
  REGISTER_MATCHER(constructorDecl);
  REGISTER_MATCHER(containsDeclaration);
  REGISTER_MATCHER(continueStmt);
  REGISTER_MATCHER(ctorInitializer);
  REGISTER_MATCHER(decl);
  REGISTER_MATCHER(declCountIs);
  REGISTER_MATCHER(declRefExpr);
  REGISTER_MATCHER(declStmt);
  REGISTER_MATCHER(declaratorDecl);
  REGISTER_MATCHER(defaultArgExpr);
  REGISTER_MATCHER(defaultStmt);
  REGISTER_MATCHER(deleteExpr);
  REGISTER_MATCHER(dependentSizedArrayType);
  REGISTER_MATCHER(destructorDecl);
  REGISTER_MATCHER(doStmt);
  REGISTER_MATCHER(dynamicCastExpr);
  REGISTER_MATCHER(eachOf);
  REGISTER_MATCHER(elaboratedType);
  REGISTER_MATCHER(enumConstantDecl);
  REGISTER_MATCHER(enumDecl);
  REGISTER_MATCHER(equalsBoundNode);
  REGISTER_MATCHER(explicitCastExpr);
  REGISTER_MATCHER(expr);
  REGISTER_MATCHER(fieldDecl);
  REGISTER_MATCHER(floatLiteral);
  REGISTER_MATCHER(forEach);
  REGISTER_MATCHER(forEachConstructorInitializer);
  REGISTER_MATCHER(forEachDescendant);
  REGISTER_MATCHER(forEachSwitchCase);
  REGISTER_MATCHER(forField);
  REGISTER_MATCHER(forRangeStmt);
  REGISTER_MATCHER(forStmt);
  REGISTER_MATCHER(friendDecl);
  REGISTER_MATCHER(functionDecl);
  REGISTER_MATCHER(functionTemplateDecl);
  REGISTER_MATCHER(functionType);
  REGISTER_MATCHER(functionalCastExpr);
  REGISTER_MATCHER(gotoStmt);
  REGISTER_MATCHER(has);
  REGISTER_MATCHER(hasAncestor);
  REGISTER_MATCHER(hasAnyArgument);
  REGISTER_MATCHER(hasAnyConstructorInitializer);
  REGISTER_MATCHER(hasAnyParameter);
  REGISTER_MATCHER(hasAnySubstatement);
  REGISTER_MATCHER(hasAnyTemplateArgument);
  REGISTER_MATCHER(hasAnyUsingShadowDecl);
  REGISTER_MATCHER(hasArgument);
  REGISTER_MATCHER(hasArgumentOfType);
  REGISTER_MATCHER(hasBase);
  REGISTER_MATCHER(hasBody);
  REGISTER_MATCHER(hasCanonicalType);
  REGISTER_MATCHER(hasCaseConstant);
  REGISTER_MATCHER(hasCondition);
  REGISTER_MATCHER(hasConditionVariableStatement);
  REGISTER_MATCHER(hasDeclContext);
  REGISTER_MATCHER(hasDeclaration);
  REGISTER_MATCHER(hasDeducedType);
  REGISTER_MATCHER(hasDescendant);
  REGISTER_MATCHER(hasDestinationType);
  REGISTER_MATCHER(hasEitherOperand);
  REGISTER_MATCHER(hasElementType);
  REGISTER_MATCHER(hasFalseExpression);
  REGISTER_MATCHER(hasImplicitDestinationType);
  REGISTER_MATCHER(hasIncrement);
  REGISTER_MATCHER(hasIndex);
  REGISTER_MATCHER(hasInitializer);
  REGISTER_MATCHER(hasLHS);
  REGISTER_MATCHER(hasLocalQualifiers);
  REGISTER_MATCHER(hasLoopInit);
  REGISTER_MATCHER(hasMethod);
  REGISTER_MATCHER(hasName);
  REGISTER_MATCHER(hasObjectExpression);
  REGISTER_MATCHER(hasOperatorName);
  REGISTER_MATCHER(hasOverloadedOperatorName);
  REGISTER_MATCHER(hasParameter);
  REGISTER_MATCHER(hasParent);
  REGISTER_MATCHER(hasQualifier);
  REGISTER_MATCHER(hasRHS);
  REGISTER_MATCHER(hasSingleDecl);
  REGISTER_MATCHER(hasSize);
  REGISTER_MATCHER(hasSizeExpr);
  REGISTER_MATCHER(hasSourceExpression);
  REGISTER_MATCHER(hasTargetDecl);
  REGISTER_MATCHER(hasTemplateArgument);
  REGISTER_MATCHER(hasTrueExpression);
  REGISTER_MATCHER(hasTypeLoc);
  REGISTER_MATCHER(hasUnaryOperand);
  REGISTER_MATCHER(hasValueType);
  REGISTER_MATCHER(ifStmt);
  REGISTER_MATCHER(ignoringImpCasts);
  REGISTER_MATCHER(ignoringParenCasts);
  REGISTER_MATCHER(ignoringParenImpCasts);
  REGISTER_MATCHER(implicitCastExpr);
  REGISTER_MATCHER(incompleteArrayType);
  REGISTER_MATCHER(initListExpr);
  REGISTER_MATCHER(innerType);
  REGISTER_MATCHER(integerLiteral);
  REGISTER_MATCHER(isArrow);
  REGISTER_MATCHER(isConst);
  REGISTER_MATCHER(isConstQualified);
  REGISTER_MATCHER(isDefinition);
  REGISTER_MATCHER(isExplicitTemplateSpecialization);
  REGISTER_MATCHER(isExternC);
  REGISTER_MATCHER(isImplicit);
  REGISTER_MATCHER(isInteger);
  REGISTER_MATCHER(isOverride);
  REGISTER_MATCHER(isPrivate);
  REGISTER_MATCHER(isProtected);
  REGISTER_MATCHER(isPublic);
  REGISTER_MATCHER(isTemplateInstantiation);
  REGISTER_MATCHER(isVirtual);
  REGISTER_MATCHER(isWritten);
  REGISTER_MATCHER(lValueReferenceType);
  REGISTER_MATCHER(labelStmt);
  REGISTER_MATCHER(lambdaExpr);
  REGISTER_MATCHER(matchesName);
  REGISTER_MATCHER(materializeTemporaryExpr);
  REGISTER_MATCHER(member);
  REGISTER_MATCHER(memberCallExpr);
  REGISTER_MATCHER(memberExpr);
  REGISTER_MATCHER(memberPointerType);
  REGISTER_MATCHER(methodDecl);
  REGISTER_MATCHER(namedDecl);
  REGISTER_MATCHER(namesType);
  REGISTER_MATCHER(namespaceDecl);
  REGISTER_MATCHER(nestedNameSpecifier);
  REGISTER_MATCHER(nestedNameSpecifierLoc);
  REGISTER_MATCHER(newExpr);
  REGISTER_MATCHER(nullPtrLiteralExpr);
  REGISTER_MATCHER(nullStmt);
  REGISTER_MATCHER(ofClass);
  REGISTER_MATCHER(on);
  REGISTER_MATCHER(onImplicitObjectArgument);
  REGISTER_MATCHER(operatorCallExpr);
  REGISTER_MATCHER(parameterCountIs);
  REGISTER_MATCHER(parenType);
  REGISTER_MATCHER(parmVarDecl);
  REGISTER_MATCHER(pointee);
  REGISTER_MATCHER(pointerType);
  REGISTER_MATCHER(qualType);
  REGISTER_MATCHER(rValueReferenceType);
  REGISTER_MATCHER(recordDecl);
  REGISTER_MATCHER(recordType);
  REGISTER_MATCHER(referenceType);
  REGISTER_MATCHER(refersToDeclaration);
  REGISTER_MATCHER(refersToType);
  REGISTER_MATCHER(reinterpretCastExpr);
  REGISTER_MATCHER(returnStmt);
  REGISTER_MATCHER(returns);
  REGISTER_MATCHER(sizeOfExpr);
  REGISTER_MATCHER(specifiesNamespace);
  REGISTER_MATCHER(specifiesType);
  REGISTER_MATCHER(specifiesTypeLoc);
  REGISTER_MATCHER(statementCountIs);
  REGISTER_MATCHER(staticCastExpr);
  REGISTER_MATCHER(stmt);
  REGISTER_MATCHER(stringLiteral);
  REGISTER_MATCHER(switchCase);
  REGISTER_MATCHER(switchStmt);
  REGISTER_MATCHER(templateSpecializationType);
  REGISTER_MATCHER(temporaryObjectExpr);
  REGISTER_MATCHER(thisExpr);
  REGISTER_MATCHER(throughUsingDecl);
  REGISTER_MATCHER(throwExpr);
  REGISTER_MATCHER(to);
  REGISTER_MATCHER(tryStmt);
  REGISTER_MATCHER(type);
  REGISTER_MATCHER(typeLoc);
  REGISTER_MATCHER(typedefType);
  REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
  REGISTER_MATCHER(unaryOperator);
  REGISTER_MATCHER(unaryTransformType);
  REGISTER_MATCHER(unless);
  REGISTER_MATCHER(unresolvedConstructExpr);
  REGISTER_MATCHER(unresolvedUsingValueDecl);
  REGISTER_MATCHER(userDefinedLiteral);
  REGISTER_MATCHER(usingDecl);
  REGISTER_MATCHER(varDecl);
  REGISTER_MATCHER(variableArrayType);
  REGISTER_MATCHER(whileStmt);
  REGISTER_MATCHER(withInitializer);
}

RegistryMaps::~RegistryMaps() {
  for (ConstructorMap::iterator it = Constructors.begin(),
                                end = Constructors.end();
       it != end; ++it) {
    delete it->second;
  }
}

static llvm::ManagedStatic<RegistryMaps> RegistryData;

} // anonymous namespace

// static
llvm::Optional<MatcherCtor>
Registry::lookupMatcherCtor(StringRef MatcherName, const SourceRange &NameRange,
                            Diagnostics *Error) {
  ConstructorMap::const_iterator it =
      RegistryData->constructors().find(MatcherName);
  if (it == RegistryData->constructors().end()) {
    Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
    return llvm::Optional<MatcherCtor>();
  }

  return it->second;
}

// static
VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
                                          const SourceRange &NameRange,
                                          ArrayRef<ParserValue> Args,
                                          Diagnostics *Error) {
  return Ctor->create(NameRange, Args, Error);
}

// static
VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
                                               const SourceRange &NameRange,
                                               StringRef BindID,
                                               ArrayRef<ParserValue> Args,
                                               Diagnostics *Error) {
  VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error);
  if (Out.isNull()) return Out;

  llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
  if (Result.hasValue()) {
    llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
    if (Bound.hasValue()) {
      return VariantMatcher::SingleMatcher(*Bound);
    }
  }
  Error->addError(NameRange, Error->ET_RegistryNotBindable);
  return VariantMatcher();
}

}  // namespace dynamic
}  // namespace ast_matchers
}  // namespace clang
<|endoftext|>


<commit_before>#include "channel.h"
#include "emotes.h"
#include "logging/loggingmanager.h"
#include "messages/message.h"
#include "windows.h"

#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <memory>

namespace chatterino {

Channel::Channel(const QString &channel)
    : messages()
    , name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1)
                                                       : channel)
    , bttvChannelEmotes()
    , ffzChannelEmotes()
    , subLink("https://www.twitch.tv/" + name +
              "/subscribe?ref=in_chat_subscriber_link")
    , channelLink("https://twitch.tv/" + name)
    , popoutPlayerLink("https://player.twitch.tv/?channel=" + name)
    , loggingChannel(logging::get(name))
{
    reloadChannelEmotes();
}

void
Channel::reloadBttvEmotes()
{
    // bttv
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QUrl url("https://api.betterttv.net/2/channels/" + this->name);
    QNetworkRequest request(url);

    QNetworkReply *reply = manager->get(request);

    QObject::connect(reply, &QNetworkReply::finished, [=] {
        if (reply->error() == QNetworkReply::NetworkError::NoError) {
            QByteArray data = reply->readAll();
            QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
            QJsonObject root = jsonDoc.object();

            auto emotes = root.value("emotes").toArray();

            QString _template = "https:" + root.value("urlTemplate").toString();

            for (const QJsonValue &emote : emotes) {
                QString id = emote.toObject().value("id").toString();
                QString code = emote.toObject().value("code").toString();
                // emote.value("imageType").toString();

                QString tmp = _template;
                tmp.detach();
                QString url =
                    tmp.replace("{{id}}", id).replace("{{image}}", "1x");

                this->getBttvChannelEmotes().insert(
                    code,
                    Emotes::getBttvChannelEmoteFromCaches().getOrAdd(
                        id, [&code, &url] {
                            return new messages::LazyLoadedImage(
                                url, 1, code, code + "\nChannel Bttv Emote");
                        }));
            }
        }

        reply->deleteLater();
        manager->deleteLater();
    });
}

void
Channel::reloadFfzEmotes()
{
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QUrl url("http://api.frankerfacez.com/v1/room/" + this->name);
    QNetworkRequest request(url);

    QNetworkReply *reply = manager->get(request);

    QObject::connect(reply, &QNetworkReply::finished, [=] {
        if (reply->error() == QNetworkReply::NetworkError::NoError) {
            QByteArray data = reply->readAll();
            QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
            QJsonObject root = jsonDoc.object();

            auto sets = root.value("sets").toObject();

            for (const QJsonValue &set : sets) {
                auto emoticons = set.toObject().value("emoticons").toArray();

                for (const QJsonValue &emote : emoticons) {
                    QJsonObject object = emote.toObject();

                    // margins

                    int id = object.value("id").toInt();
                    QString code = object.value("name").toString();

                    QJsonObject urls = object.value("urls").toObject();
                    QString url1 = "http:" + urls.value("1").toString();

                    this->getFfzChannelEmotes().insert(
                        code,
                        Emotes::getFfzChannelEmoteFromCaches().getOrAdd(
                            id, [&code, &url1] {
                                return new messages::LazyLoadedImage(
                                    url1, 1, code, code + "\nGlobal Ffz Emote");
                            }));
                }
            }
        }

        reply->deleteLater();
        manager->deleteLater();
    });
}

void
Channel::addMessage(std::shared_ptr<messages::Message> message)
{
    std::shared_ptr<messages::Message> deleted;

    if (this->loggingChannel.get() != nullptr) {
        this->loggingChannel->append(message);
    }

    if (this->messages.appendItem(message, deleted)) {
        this->messageRemovedFromStart(deleted);
    }

    this->messageAppended(message);

    Windows::repaintVisibleChatWidgets(this);
}

}  // namespace chatterino
<commit_msg>reformat channel.cpp KKona<commit_after>#include "channel.h"
#include "emotes.h"
#include "logging/loggingmanager.h"
#include "messages/message.h"
#include "windows.h"

#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

#include <memory>

namespace chatterino {

Channel::Channel(const QString &channel)
    : messages()
    , name((channel.length() > 0 && channel[0] == '#') ? channel.mid(1)
                                                       : channel)
    , bttvChannelEmotes()
    , ffzChannelEmotes()
    , subLink("https://www.twitch.tv/" + name +
              "/subscribe?ref=in_chat_subscriber_link")
    , channelLink("https://twitch.tv/" + name)
    , popoutPlayerLink("https://player.twitch.tv/?channel=" + name)
    , loggingChannel(logging::get(name))
{
    reloadChannelEmotes();
}

void
Channel::reloadBttvEmotes()
{
    // bttv
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QUrl url("https://api.betterttv.net/2/channels/" + this->name);
    QNetworkRequest request(url);

    QNetworkReply *reply = manager->get(request);

    QObject::connect(reply, &QNetworkReply::finished, [=] {
        if (reply->error() == QNetworkReply::NetworkError::NoError) {
            QByteArray data = reply->readAll();
            QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
            QJsonObject root = jsonDoc.object();

            auto emotes = root.value("emotes").toArray();

            QString _template = "https:" + root.value("urlTemplate").toString();

            for (const QJsonValue &emote : emotes) {
                QString id = emote.toObject().value("id").toString();
                QString code = emote.toObject().value("code").toString();
                // emote.value("imageType").toString();

                QString tmp = _template;
                tmp.detach();
                QString url =
                    tmp.replace("{{id}}", id).replace("{{image}}", "1x");

                this->getBttvChannelEmotes().insert(
                    code, Emotes::getBttvChannelEmoteFromCaches().getOrAdd(
                              id, [&code, &url] {
                                  return new messages::LazyLoadedImage(
                                      url, 1, code,
                                      code + "\nChannel Bttv Emote");
                              }));
            }
        }

        reply->deleteLater();
        manager->deleteLater();
    });
}

void
Channel::reloadFfzEmotes()
{
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    QUrl url("http://api.frankerfacez.com/v1/room/" + this->name);
    QNetworkRequest request(url);

    QNetworkReply *reply = manager->get(request);

    QObject::connect(reply, &QNetworkReply::finished, [=] {
        if (reply->error() == QNetworkReply::NetworkError::NoError) {
            QByteArray data = reply->readAll();
            QJsonDocument jsonDoc(QJsonDocument::fromJson(data));
            QJsonObject root = jsonDoc.object();

            auto sets = root.value("sets").toObject();

            for (const QJsonValue &set : sets) {
                auto emoticons = set.toObject().value("emoticons").toArray();

                for (const QJsonValue &emote : emoticons) {
                    QJsonObject object = emote.toObject();

                    // margins

                    int id = object.value("id").toInt();
                    QString code = object.value("name").toString();

                    QJsonObject urls = object.value("urls").toObject();
                    QString url1 = "http:" + urls.value("1").toString();

                    this->getFfzChannelEmotes().insert(
                        code, Emotes::getFfzChannelEmoteFromCaches().getOrAdd(
                                  id, [&code, &url1] {
                                      return new messages::LazyLoadedImage(
                                          url1, 1, code,
                                          code + "\nGlobal Ffz Emote");
                                  }));
                }
            }
        }

        reply->deleteLater();
        manager->deleteLater();
    });
}

void
Channel::addMessage(std::shared_ptr<messages::Message> message)
{
    std::shared_ptr<messages::Message> deleted;

    if (this->loggingChannel.get() != nullptr) {
        this->loggingChannel->append(message);
    }

    if (this->messages.appendItem(message, deleted)) {
        this->messageRemovedFromStart(deleted);
    }

    this->messageAppended(message);

    Windows::repaintVisibleChatWidgets(this);
}

}  // namespace chatterino
<|endoftext|>