<commit_before>#include "mangaupdates_parser.hpp"
#include "http_utility.hpp"

#include <algorithm>
#include <cstdint>
#include <functional>
#include <numeric>

#include <utf8/utf8.h>

namespace
{
    static std::string const name_entry_search_str = "alt='Series Info'>";
    static std::string const id_search_str = "<a href='http://www.mangaupdates.com/series.html?id=";
    static std::string const desc_search_str = "
Description
";
    static std::string const ass_names_search_str = "
Associated Names
";
    static std::string const genres_search_str = "act=genresearch&genre=";
    static std::string const authors_search_str = "
Author(s)
";
    static std::string const artists_search_str = "
Artist(s)
";
    static std::string const year_search_str = "
Year
";
    static std::string const img_search_str = "
<img";

    static std::pair<std::string, std::string> const junk_table[] =
    {
        { "", "" },  // Name junk in search results
        { "  [", "]" } // Artists and Authors junk
    };

    enum junk_type
    {
        NAME_SEARCH = 0,
        ARTIST_AUTHOR,
    };

    static std::string & find_remove_junk(std::string & str, junk_type type)
    {
        auto const & start_pattern = junk_table[type].first;
        auto const & end_pattern = junk_table[type].second;

        auto start_pos = str.find(start_pattern);
        if (start_pos != std::string::npos)
        {
            auto end_pos = str.find(end_pattern, start_pos + start_pattern.length());
            if (end_pos != std::string::npos)
            {
                str.erase(start_pos, start_pattern.length());
                str.erase(end_pos - start_pattern.length(), end_pattern.length());
            }
        }

        return str;
    }

    //https://en.wikipedia.org/wiki/Levenshtein_distance
    static uint32_t levenshtein_distance(std::string const & s,
        std::string const & t)
    {
        if (s == t)
            return 0;
        if (s.length() == 0)
            return t.length();
        if (t.length() == 0)
            return s.length();

        std::vector<uint32_t> v0(t.length() + 1);
        std::vector<uint32_t> v1(t.length() + 1);

        auto n = 0;
        std::generate(v0.begin(), v0.end(), [&n]() { return n++; });

        for (size_t i = 0; i < s.length(); i++)
        {
            v1[0] = i + 1;

            for (size_t j = 0; j < t.length(); j++)
            {
                auto cost = s[i] == t[j] ? 0 : 1;
                v1[j + 1] = std::min({ v1[j] + 1,
                    v0[j + 1],
                    v0[j] + cost });
            }

            v0 = v1;
        }

        return v1[t.length()];
    }
}

std::string const mangaupdates::get_id(std::string const & contents, std::string const & name)
{
    using match_type = std::pair<float, std::string>;
    std::vector<match_type> matches;
    std::string id;

    // mangaupdates sends the names NCR encoded, so we must encode ours to NCR as well
    auto ncr_name = http_utility::encode_ncr(name);
    size_t id_start_pos = contents.find(id_search_str);
    // Iterate through every search result entry
    while (id_start_pos != std::string::npos)
    {
        id_start_pos += id_search_str.length();
        size_t id_end_pos = contents.find("'", id_start_pos);
        if (id_end_pos == std::string::npos)
            break;

        id = contents.substr(id_start_pos, id_end_pos - id_start_pos);
        size_t name_start_pos = contents.find(name_entry_search_str, id_start_pos);
        if (name_start_pos != std::string::npos)
        {
            name_start_pos += name_entry_search_str.length();
            size_t name_end_pos = contents.find("", name_start_pos);
            if (name_end_pos == std::string::npos)
                break;
            // Get the string from positions and remove any junk
            auto potential_match = contents.substr(name_start_pos, name_end_pos - name_start_pos);
            potential_match = find_remove_junk(potential_match, NAME_SEARCH);
            // Do the names match?
            if (potential_match == ncr_name)
                return id;

            auto larger_length = std::max(potential_match.length(), name.length());
            auto match_percentage = 1.0f - (static_cast<float>(levenshtein_distance(potential_match, name)) / larger_length);

            matches.emplace_back(match_percentage, id);
        }

        id_start_pos = contents.find(id_search_str, id_start_pos);
    }

    // Sort the potential matches based on their match percentage; the frontmost being the highest
    std::sort(matches.begin(), matches.end(),
        [](match_type const & left, match_type const & right) -> bool
    {
        return left.first > right.first;
    });

    return matches.size() > 0 ? matches.front().second : "";
}

std::string const mangaupdates::get_description(std::string const & contents)
{
    std::string description;

    size_t start_pos = contents.find(desc_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += desc_search_str.length();

        start_pos = contents.find(">", start_pos);
        if (start_pos != std::string::npos)
        {
            ++start_pos;

            size_t end_pos = contents.find("
", start_pos);
            if (end_pos != std::string::npos)
                description = contents.substr(start_pos, end_pos - start_pos);
        }
    }

    return description;
}

std::vector<std::string> const mangaupdates::get_associated_names(std::string const & contents)
{
    std::vector<std::string> associated_names;

    size_t start_pos = contents.find(ass_names_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += ass_names_search_str.length();

        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            size_t end_pos = 0;
            start_pos = contents.find(">", start_pos);
            if (start_pos != std::string::npos)
            {
                ++start_pos;

                for (size_t i = 0; start_pos < div_end_pos; i++)
                {
                    end_pos = contents.find("
", start_pos);
                    if (end_pos == std::string::npos)
                        break;

                    associated_names.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                    start_pos = end_pos + 6;
                }
            }
        }
    }

    return associated_names;
}

std::vector<std::string> const mangaupdates::get_genres(std::string const & contents)
{
    std::vector<std::string> genres;

    size_t start_pos = contents.find(genres_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += genres_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("", start_pos);
                if (end_pos == std::string::npos)
                    break;

                genres.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 4;
            }

			/* ******** IMPROVE THIS ******  */
            // Remove the last two elements as they're rubbish we don't need
            genres.pop_back();
            genres.pop_back();
			/* ***************************** */
        }
    }

    return genres;
}

std::vector<std::string> const mangaupdates::get_authors(std::string const & contents)
{
    std::vector<std::string> authors;

    size_t start_pos = contents.find(authors_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += authors_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);

        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("
", start_pos);
                if (end_pos == std::string::npos)
                    break;

                authors.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 12;
            }
        }
    }

    return authors;
}

std::vector<std::string> const mangaupdates::get_artists(std::string const & contents)
{
    std::vector<std::string> artists;

    size_t start_pos = contents.find(artists_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += artists_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("
", start_pos);
                if (end_pos == std::string::npos)
                    break;

                artists.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 12;
            }
        }
    }

    return artists;
}

std::string const mangaupdates::get_year(std::string const & contents)
{
    std::string year;

    size_t start_pos = contents.find(year_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += year_search_str.length();
        start_pos = contents.find(">", start_pos);
        if (start_pos != std::string::npos)
        {
            ++start_pos;
            size_t end_pos = contents.find("
", start_pos);
            if (end_pos != std::string::npos)
            {
                --end_pos; // new line character
                year = contents.substr(start_pos, end_pos - start_pos);
            }
        }
    }

    return year;
}

std::string const mangaupdates::get_img_url(std::string const & contents)
{
    std::string img_url;

    size_t start_pos = contents.find(img_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += img_search_str.length();
        start_pos = contents.find("src='", start_pos);
        if (start_pos != std::string::npos)
        {
            start_pos += 5;
            size_t end_pos = contents.find('\'', start_pos);
            if (end_pos != std::string::npos)
            {
                img_url = contents.substr(start_pos, end_pos - start_pos);
            }
        }
    }

    return img_url;
}<commit_msg>Modify search string for MU id Would result in failure with HTTPS<commit_after>#include "mangaupdates_parser.hpp"
#include "http_utility.hpp"

#include <algorithm>
#include <cstdint>
#include <functional>
#include <numeric>

#include <utf8/utf8.h>

namespace
{
    static std::string const name_entry_search_str = "alt='Series Info'>";
    static std::string const id_search_str = "www.mangaupdates.com/series.html?id=";
    static std::string const desc_search_str = "
Description
";
    static std::string const ass_names_search_str = "
Associated Names
";
    static std::string const genres_search_str = "act=genresearch&genre=";
    static std::string const authors_search_str = "
Author(s)
";
    static std::string const artists_search_str = "
Artist(s)
";
    static std::string const year_search_str = "
Year
";
    static std::string const img_search_str = "
<img";

    static std::pair<std::string, std::string> const junk_table[] =
    {
        { "", "" },  // Name junk in search results
        { "  [", "]" } // Artists and Authors junk
    };

    enum junk_type
    {
        NAME_SEARCH = 0,
        ARTIST_AUTHOR,
    };

    static std::string & find_remove_junk(std::string & str, junk_type type)
    {
        auto const & start_pattern = junk_table[type].first;
        auto const & end_pattern = junk_table[type].second;

        auto start_pos = str.find(start_pattern);
        if (start_pos != std::string::npos)
        {
            auto end_pos = str.find(end_pattern, start_pos + start_pattern.length());
            if (end_pos != std::string::npos)
            {
                str.erase(start_pos, start_pattern.length());
                str.erase(end_pos - start_pattern.length(), end_pattern.length());
            }
        }

        return str;
    }

    //https://en.wikipedia.org/wiki/Levenshtein_distance
    static uint32_t levenshtein_distance(std::string const & s,
        std::string const & t)
    {
        if (s == t)
            return 0;
        if (s.length() == 0)
            return t.length();
        if (t.length() == 0)
            return s.length();

        std::vector<uint32_t> v0(t.length() + 1);
        std::vector<uint32_t> v1(t.length() + 1);

        auto n = 0;
        std::generate(v0.begin(), v0.end(), [&n]() { return n++; });

        for (size_t i = 0; i < s.length(); i++)
        {
            v1[0] = i + 1;

            for (size_t j = 0; j < t.length(); j++)
            {
                auto cost = s[i] == t[j] ? 0 : 1;
                v1[j + 1] = std::min({ v1[j] + 1,
                    v0[j + 1],
                    v0[j] + cost });
            }

            v0 = v1;
        }

        return v1[t.length()];
    }
}

std::string const mangaupdates::get_id(std::string const & contents, std::string const & name)
{
    using match_type = std::pair<float, std::string>;
    std::vector<match_type> matches;
    std::string id;

    // mangaupdates sends the names NCR encoded, so we must encode ours to NCR as well
    auto ncr_name = http_utility::encode_ncr(name);
    size_t id_start_pos = contents.find(id_search_str);
    // Iterate through every search result entry
    while (id_start_pos != std::string::npos)
    {
        id_start_pos += id_search_str.length();
        size_t id_end_pos = contents.find("'", id_start_pos);
        if (id_end_pos == std::string::npos)
            break;

        id = contents.substr(id_start_pos, id_end_pos - id_start_pos);
        size_t name_start_pos = contents.find(name_entry_search_str, id_start_pos);
        if (name_start_pos != std::string::npos)
        {
            name_start_pos += name_entry_search_str.length();
            size_t name_end_pos = contents.find("", name_start_pos);
            if (name_end_pos == std::string::npos)
                break;
            // Get the string from positions and remove any junk
            auto potential_match = contents.substr(name_start_pos, name_end_pos - name_start_pos);
            potential_match = find_remove_junk(potential_match, NAME_SEARCH);
            // Do the names match?
            if (potential_match == ncr_name)
                return id;

            auto larger_length = std::max(potential_match.length(), name.length());
            auto match_percentage = 1.0f - (static_cast<float>(levenshtein_distance(potential_match, name)) / larger_length);

            matches.emplace_back(match_percentage, id);
        }

        id_start_pos = contents.find(id_search_str, id_start_pos);
    }

    // Sort the potential matches based on their match percentage; the frontmost being the highest
    std::sort(matches.begin(), matches.end(),
        [](match_type const & left, match_type const & right) -> bool
    {
        return left.first > right.first;
    });

    return matches.size() > 0 ? matches.front().second : "";
}

std::string const mangaupdates::get_description(std::string const & contents)
{
    std::string description;

    size_t start_pos = contents.find(desc_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += desc_search_str.length();

        start_pos = contents.find(">", start_pos);
        if (start_pos != std::string::npos)
        {
            ++start_pos;

            size_t end_pos = contents.find("
", start_pos);
            if (end_pos != std::string::npos)
                description = contents.substr(start_pos, end_pos - start_pos);
        }
    }

    return description;
}

std::vector<std::string> const mangaupdates::get_associated_names(std::string const & contents)
{
    std::vector<std::string> associated_names;

    size_t start_pos = contents.find(ass_names_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += ass_names_search_str.length();

        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            size_t end_pos = 0;
            start_pos = contents.find(">", start_pos);
            if (start_pos != std::string::npos)
            {
                ++start_pos;

                for (size_t i = 0; start_pos < div_end_pos; i++)
                {
                    end_pos = contents.find("
", start_pos);
                    if (end_pos == std::string::npos)
                        break;

                    associated_names.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                    start_pos = end_pos + 6;
                }
            }
        }
    }

    return associated_names;
}

std::vector<std::string> const mangaupdates::get_genres(std::string const & contents)
{
    std::vector<std::string> genres;

    size_t start_pos = contents.find(genres_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += genres_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("", start_pos);
                if (end_pos == std::string::npos)
                    break;

                genres.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 4;
            }

			/* ******** IMPROVE THIS ******  */
            // Remove the last two elements as they're rubbish we don't need
            genres.pop_back();
            genres.pop_back();
			/* ***************************** */
        }
    }

    return genres;
}

std::vector<std::string> const mangaupdates::get_authors(std::string const & contents)
{
    std::vector<std::string> authors;

    size_t start_pos = contents.find(authors_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += authors_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);

        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("
", start_pos);
                if (end_pos == std::string::npos)
                    break;

                authors.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 12;
            }
        }
    }

    return authors;
}

std::vector<std::string> const mangaupdates::get_artists(std::string const & contents)
{
    std::vector<std::string> artists;

    size_t start_pos = contents.find(artists_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += artists_search_str.length();

        size_t end_pos = 0;
        size_t div_end_pos = contents.find("
", start_pos);
        if (div_end_pos != std::string::npos)
        {
            --div_end_pos;

            for (size_t i = 0; start_pos < div_end_pos; i++)
            {
                start_pos = contents.find("", start_pos);
                if (start_pos == std::string::npos)
                    break;

                start_pos += 3;
                end_pos = contents.find("
", start_pos);
                if (end_pos == std::string::npos)
                    break;

                artists.emplace_back(contents.substr(start_pos, end_pos - start_pos));
                start_pos = end_pos + 12;
            }
        }
    }

    return artists;
}

std::string const mangaupdates::get_year(std::string const & contents)
{
    std::string year;

    size_t start_pos = contents.find(year_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += year_search_str.length();
        start_pos = contents.find(">", start_pos);
        if (start_pos != std::string::npos)
        {
            ++start_pos;
            size_t end_pos = contents.find("
", start_pos);
            if (end_pos != std::string::npos)
            {
                --end_pos; // new line character
                year = contents.substr(start_pos, end_pos - start_pos);
            }
        }
    }

    return year;
}

std::string const mangaupdates::get_img_url(std::string const & contents)
{
    std::string img_url;

    size_t start_pos = contents.find(img_search_str);
    if (start_pos != std::string::npos)
    {
        start_pos += img_search_str.length();
        start_pos = contents.find("src='", start_pos);
        if (start_pos != std::string::npos)
        {
            start_pos += 5;
            size_t end_pos = contents.find('\'', start_pos);
            if (end_pos != std::string::npos)
            {
                img_url = contents.substr(start_pos, end_pos - start_pos);
            }
        }
    }

    return img_url;
}<|endoftext|>


<commit_before>void emcal_digits()
{
  AliRunLoader* rl =  Alieve::Event::AssertRunLoader();

  rl->LoadgAlice();
  AliEMCAL         * emcal = (AliEMCAL*) rl->GetAliRun()->GetDetector("EMCAL");
  AliEMCALGeometry * geom  = emcal->GetGeometry();

  rl->LoadDigits("EMCAL");
  TTree* dt = rl->GetTreeD("EMCAL", kFALSE);

  gGeoManager = gReve->GetGeometry("$REVESYS/alice-data/alice_fullgeo.root");
  TGeoNode* node = gGeoManager->GetTopVolume()->FindNode("XEN1_1");

  TGeoBBox* bbbox = (TGeoBBox*) node->GetDaughter(0) ->GetVolume()->GetShape();
  bbbox->Dump();
  TGeoBBox* sbbox = (TGeoBBox*) node->GetDaughter(10)->GetVolume()->GetShape();
  sbbox->Dump();

  Reve::RenderElementList* l = new Reve::RenderElementList("EMCAL");
  l->SetTitle("Tooltip");
  gReve->AddRenderElement(l);

  Reve::FrameBox* frame_big = new Reve::FrameBox();
  frame_big->SetAABoxCenterHalfSize(0, 0, 0, bbbox->GetDX(), bbbox->GetDY(), bbbox->GetDZ());

  Reve::FrameBox* frame_sml = new Reve::FrameBox();
  frame_sml->SetAABoxCenterHalfSize(0, 0, 0, sbbox->GetDX(), sbbox->GetDY(), sbbox->GetDZ());

  Reve::QuadSet* smodules[12];

  for (Int_t sm=0; sm<12; ++sm)
  {
    Reve::QuadSet* q = new Reve::QuadSet(Form("SM %d", sm+1));
    q->SetOwnIds(kTRUE);
    q->Reset(Reve::QuadSet::QT_RectangleXYFixedDimZ, kFALSE, 32);
    q->SetDefWidth (geom->GetPhiTileSize());
    q->SetDefHeight(geom->GetEtaTileSize());

    // node->GetDaughter(sm)->GetMatrix()->Print();

    q->RefHMTrans().SetFrom(*node->GetDaughter(sm)->GetMatrix());
    q->RefHMTrans().TransposeRotationPart(); // Spook?

    q->SetFrame(sm < 10 ? frame_big : frame_sml);

    gReve->AddRenderElement(l, q);
    smodules[sm] = q;
  }

  TClonesArray *digits = 0;
  dt->SetBranchAddress("EMCAL", &digits);
  dt->GetEntry(0);
  Int_t nEnt = digits->GetEntriesFast();
  AliEMCALDigit * dig;

  Int_t iEvent  = -1 ;
  Float_t amp   = -1 ;
  Float_t time  = -1 ;
  Int_t id      = -1 ;
  Int_t iSupMod =  0 ;
  Int_t iTower  =  0 ;
  Int_t iIphi   =  0 ;
  Int_t iIeta   =  0 ;
  Int_t iphi    =  0 ;
  Int_t ieta    =  0 ;
  Double_t x, y, z;

  for(Int_t idig = 0; idig<nEnt; idig++)
  {
    dig = static_cast<AliEMCALDigit *>(digits->At(idig));

    if(dig != 0) {
      id   = dig->GetId() ; //cell (digit) label
      amp  = dig->GetAmp(); //amplitude in cell (digit)
      time = dig->GetTime();//time of creation of digit after collision

      cout<<"Cell ID "<<id<<" Amp "<<amp<<endl;//" time "<<time<<endl;

      //Geometry methods
      geom->GetCellIndex(id,iSupMod,iTower,iIphi,iIeta);
      //Gives SuperModule and Tower numbers
      geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
					iIphi, iIeta,iphi,ieta);
      //Gives label of cell in eta-phi position per each supermodule

      cout<< "SModule "<<iSupMod<<"; Tower "<<iTower
	  <<"; Eta "<<iIeta<<"; Phi "<<iIphi
	  <<"; Cell Eta "<<ieta<<"; Cell Phi "<<iphi<<endl;

      geom->RelPosCellInSModule(id, x, y, z);
      cout << x <<" "<< y <<" "<< z <<endl;

      Reve::QuadSet* q = smodules[iSupMod];
      q->AddQuad(y, z);
      q->QuadValue(amp);
      q->QuadId(dig);
    } else {
      cout<<"Digit pointer 0x0"<<endl;
    }
  }

  gReve->Redraw3D();
}
<commit_msg>Use the y-z mode of QuadSet to represent calo-cells.<commit_after>void emcal_digits()
{
  AliRunLoader* rl =  Alieve::Event::AssertRunLoader();

  rl->LoadgAlice();
  AliEMCAL         * emcal = (AliEMCAL*) rl->GetAliRun()->GetDetector("EMCAL");
  AliEMCALGeometry * geom  = emcal->GetGeometry();

  rl->LoadDigits("EMCAL");
  TTree* dt = rl->GetTreeD("EMCAL", kFALSE);

  gGeoManager = gReve->GetGeometry("$REVESYS/alice-data/alice_fullgeo.root");
  TGeoNode* node = gGeoManager->GetTopVolume()->FindNode("XEN1_1");

  TGeoBBox* bbbox = (TGeoBBox*) node->GetDaughter(0) ->GetVolume()->GetShape();
  bbbox->Dump();
  TGeoBBox* sbbox = (TGeoBBox*) node->GetDaughter(10)->GetVolume()->GetShape();
  sbbox->Dump();

  Reve::RenderElementList* l = new Reve::RenderElementList("EMCAL");
  l->SetTitle("Tooltip");
  gReve->AddRenderElement(l);

  Reve::FrameBox* frame_big = new Reve::FrameBox();
  frame_big->SetAABoxCenterHalfSize(0, 0, 0, bbbox->GetDX(), bbbox->GetDY(), bbbox->GetDZ());

  Reve::FrameBox* frame_sml = new Reve::FrameBox();
  frame_sml->SetAABoxCenterHalfSize(0, 0, 0, sbbox->GetDX(), sbbox->GetDY(), sbbox->GetDZ());

  gStyle->SetPalette(1, 0);
  Reve::RGBAPalette* pal = new Reve::RGBAPalette(0, 512);
  pal->SetLimits(0, 1024);

  Reve::QuadSet* smodules[12];

  for (Int_t sm=0; sm<12; ++sm)
  {
    Reve::QuadSet* q = new Reve::QuadSet(Form("SM %d", sm+1));
    q->SetOwnIds(kTRUE);
    q->Reset(Reve::QuadSet::QT_RectangleYZFixedDimX, kFALSE, 32);
    q->SetDefWidth (geom->GetPhiTileSize());
    q->SetDefHeight(geom->GetEtaTileSize());

    // node->GetDaughter(sm)->GetMatrix()->Print();

    q->RefHMTrans().SetFrom(*node->GetDaughter(sm)->GetMatrix());
    q->RefHMTrans().TransposeRotationPart(); // Spook?

    q->SetFrame(sm < 10 ? frame_big : frame_sml);
    q->SetPalette(pal);

    gReve->AddRenderElement(l, q);
    smodules[sm] = q;
  }

  TClonesArray *digits = 0;
  dt->SetBranchAddress("EMCAL", &digits);
  dt->GetEntry(0);
  Int_t nEnt = digits->GetEntriesFast();
  AliEMCALDigit * dig;

  Int_t iEvent  = -1 ;
  Float_t amp   = -1 ;
  Float_t time  = -1 ;
  Int_t id      = -1 ;
  Int_t iSupMod =  0 ;
  Int_t iTower  =  0 ;
  Int_t iIphi   =  0 ;
  Int_t iIeta   =  0 ;
  Int_t iphi    =  0 ;
  Int_t ieta    =  0 ;
  Double_t x, y, z;

  for(Int_t idig = 0; idig<nEnt; idig++)
  {
    dig = static_cast<AliEMCALDigit *>(digits->At(idig));

    if(dig != 0) {
      id   = dig->GetId() ; //cell (digit) label
      amp  = dig->GetAmp(); //amplitude in cell (digit)
      time = dig->GetTime();//time of creation of digit after collision

      cout<<"Cell ID "<<id<<" Amp "<<amp<<endl;//" time "<<time<<endl;

      //Geometry methods
      geom->GetCellIndex(id,iSupMod,iTower,iIphi,iIeta);
      //Gives SuperModule and Tower numbers
      geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
					iIphi, iIeta,iphi,ieta);
      //Gives label of cell in eta-phi position per each supermodule

      cout<< "SModule "<<iSupMod<<"; Tower "<<iTower
	  <<"; Eta "<<iIeta<<"; Phi "<<iIphi
	  <<"; Cell Eta "<<ieta<<"; Cell Phi "<<iphi<<endl;

      geom->RelPosCellInSModule(id, x, y, z);
      cout << x <<" "<< y <<" "<< z <<endl;

      Reve::QuadSet* q = smodules[iSupMod];
      q->AddQuad(y, z);
      q->QuadValue(amp);
      q->QuadId(dig);
    } else {
      cout<<"Digit pointer 0x0"<<endl;
    }
  }

  for (Int_t sm=0; sm<12; ++sm)
  {
    smodules[iSupMod]->RefitPlex();
  }

  gReve->Redraw3D();
}
<|endoftext|>


<commit_before>/*
Copyright(c) 2016-2017 Panos Karabelas

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

//= INCLUDES ====================
#include "Hierarchy.h"
#include "../imgui/imgui.h"
#include "Scene/Scene.h"
#include "Scene/GameObject.h"
#include "Components/Transform.h"
#include "Core/Engine.h"
//===============================

//= NAMESPACES ==========
using namespace std;
using namespace Directus;
//=======================

weak_ptr<GameObject> Hierarchy::m_gameObjectSelected;
weak_ptr<GameObject> g_gameObjectEmpty;
static Engine* g_engine = nullptr;
static Scene* g_scene	= nullptr;
static bool g_wasItemHovered = false;

Hierarchy::Hierarchy()
{
	m_title = "Hierarchy";

	m_context = nullptr;
	g_scene = nullptr;
}

void Hierarchy::Initialize(Context* context)
{
	Widget::Initialize(context);
	g_engine = m_context->GetSubsystem<Engine>();
	g_scene = m_context->GetSubsystem<Scene>();
}

void Hierarchy::Update()
{
	g_wasItemHovered = false;

	// If the engine is not updating, don't populate the hierarchy yet
	if (!g_engine->IsUpdating())
		return;

	if (ImGui::TreeNodeEx("Scene", ImGuiTreeNodeFlags_DefaultOpen))
	{
		ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 3); // Increase spacing to differentiate leaves from expanded contents.
		Tree_Populate();
		ImGui::PopStyleVar();
		ImGui::TreePop();
	}
}

void Hierarchy::Tree_Populate()
{
	auto rootGameObjects = g_scene->GetRootGameObjects();
	for (const auto& gameObject : rootGameObjects)
	{
		Tree_AddGameObject(gameObject);
	}
}

void Hierarchy::Tree_AddGameObject(const weak_ptr<GameObject>& currentGameObject)
{
	GameObject* gameObjPtr = currentGameObject.lock().get();

	// Node children visibility
	bool hasVisibleChildren = false;
	auto children = gameObjPtr->GetTransform()->GetChildren();
	for (const auto& child : children)
	{
		if (child->GetGameObject()->IsVisibleInHierarchy())
		{
			hasVisibleChildren = true;
			break;
		}
	}

	// Node flags -> Default
	ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnDoubleClick;
	// Node flags -> Expandable?
	node_flags |= hasVisibleChildren ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf;
	// Node flags -> Selected?
	if (!m_gameObjectSelected.expired())
	{
		node_flags |= (m_gameObjectSelected.lock()->GetID() == gameObjPtr->GetID()) ? ImGuiTreeNodeFlags_Selected : 0;
	}

	// Node
	bool isNodeOpen = ImGui::TreeNodeEx((void*)(intptr_t)gameObjPtr->GetID(), node_flags, gameObjPtr->GetName().c_str());

	// Handle clicking
	if (ImGui::IsMouseHoveringWindow())
	{
		// Left click
		if (ImGui::IsMouseClicked(0) && ImGui::IsItemHovered(ImGuiHoveredFlags_Default))
		{
			m_gameObjectSelected = currentGameObject;
			g_wasItemHovered = true;
		}

		// Right click
		if (ImGui::IsMouseClicked(1))
		{
			if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
			{
				m_gameObjectSelected = currentGameObject;
			}
			else
			{
				ImGui::OpenPopup("##HierarchyContextMenu");
			}
			g_wasItemHovered = true;
		}

		// Clicking inside the window (but not on an item)
		if ((ImGui::IsMouseClicked(0) || ImGui::IsMouseClicked(1)) && !g_wasItemHovered)
		{
			m_gameObjectSelected = g_gameObjectEmpty;
		}
	}

	// Context menu
	if (ImGui::BeginPopup("##HierarchyContextMenu"))
	{
		if (!m_gameObjectSelected.expired())
		{
			ImGui::MenuItem("Rename");
			if (ImGui::MenuItem("Delete"))
			{
				GameObject_Delete(m_gameObjectSelected);
			}
			ImGui::Separator();
		}
		if (ImGui::MenuItem("Creaty Empty"))
		{
			GameObject_CreateEmpty();
		}
		ImGui::EndPopup();
	}

	// Child nodes
	if (isNodeOpen)
	{
		if (hasVisibleChildren)
		{
			for (const auto& child : children)
			{
				if (!child->GetGameObject()->IsVisibleInHierarchy())
					continue;

				Tree_AddGameObject(child->GetGameObjectRef());
			}
		}
		ImGui::TreePop();
	}
}

void Hierarchy::GameObject_Delete(weak_ptr<GameObject> gameObject)
{
	g_scene->RemoveGameObject(gameObject);
}

void Hierarchy::GameObject_CreateEmpty()
{
	g_scene->CreateGameObject();
}
<commit_msg>Creating an empty GameObject will another GameObject is selected, will cause it to become a child.<commit_after>/*
Copyright(c) 2016-2017 Panos Karabelas

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

//= INCLUDES ====================
#include "Hierarchy.h"
#include "../imgui/imgui.h"
#include "Scene/Scene.h"
#include "Scene/GameObject.h"
#include "Components/Transform.h"
#include "Core/Engine.h"
//===============================

//= NAMESPACES ==========
using namespace std;
using namespace Directus;
//=======================

weak_ptr<GameObject> Hierarchy::m_gameObjectSelected;
weak_ptr<GameObject> g_gameObjectEmpty;
static Engine* g_engine = nullptr;
static Scene* g_scene	= nullptr;
static bool g_wasItemHovered = false;

Hierarchy::Hierarchy()
{
	m_title = "Hierarchy";

	m_context = nullptr;
	g_scene = nullptr;
}

void Hierarchy::Initialize(Context* context)
{
	Widget::Initialize(context);
	g_engine = m_context->GetSubsystem<Engine>();
	g_scene = m_context->GetSubsystem<Scene>();
}

void Hierarchy::Update()
{
	g_wasItemHovered = false;

	// If the engine is not updating, don't populate the hierarchy yet
	if (!g_engine->IsUpdating())
		return;

	if (ImGui::TreeNodeEx("Scene", ImGuiTreeNodeFlags_DefaultOpen))
	{
		ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 3); // Increase spacing to differentiate leaves from expanded contents.
		Tree_Populate();
		ImGui::PopStyleVar();
		ImGui::TreePop();
	}
}

void Hierarchy::Tree_Populate()
{
	auto rootGameObjects = g_scene->GetRootGameObjects();
	for (const auto& gameObject : rootGameObjects)
	{
		Tree_AddGameObject(gameObject);
	}
}

void Hierarchy::Tree_AddGameObject(const weak_ptr<GameObject>& currentGameObject)
{
	GameObject* gameObjPtr = currentGameObject.lock().get();

	// Node children visibility
	bool hasVisibleChildren = false;
	auto children = gameObjPtr->GetTransform()->GetChildren();
	for (const auto& child : children)
	{
		if (child->GetGameObject()->IsVisibleInHierarchy())
		{
			hasVisibleChildren = true;
			break;
		}
	}

	// Node flags -> Default
	ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnDoubleClick;
	// Node flags -> Expandable?
	node_flags |= hasVisibleChildren ? ImGuiTreeNodeFlags_OpenOnArrow : ImGuiTreeNodeFlags_Leaf;
	// Node flags -> Selected?
	if (!m_gameObjectSelected.expired())
	{
		node_flags |= (m_gameObjectSelected.lock()->GetID() == gameObjPtr->GetID()) ? ImGuiTreeNodeFlags_Selected : 0;
	}

	// Node
	bool isNodeOpen = ImGui::TreeNodeEx((void*)(intptr_t)gameObjPtr->GetID(), node_flags, gameObjPtr->GetName().c_str());

	// Handle clicking
	if (ImGui::IsMouseHoveringWindow())
	{
		// Left click
		if (ImGui::IsMouseClicked(0) && ImGui::IsItemHovered(ImGuiHoveredFlags_Default))
		{
			m_gameObjectSelected = currentGameObject;
			g_wasItemHovered = true;
		}

		// Right click
		if (ImGui::IsMouseClicked(1))
		{
			if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
			{
				m_gameObjectSelected = currentGameObject;
			}
			else
			{
				ImGui::OpenPopup("##HierarchyContextMenu");
			}
			g_wasItemHovered = true;
		}

		// Clicking inside the window (but not on an item)
		if ((ImGui::IsMouseClicked(0) || ImGui::IsMouseClicked(1)) && !g_wasItemHovered)
		{
			m_gameObjectSelected = g_gameObjectEmpty;
		}
	}

	// Context menu
	if (ImGui::BeginPopup("##HierarchyContextMenu"))
	{
		if (!m_gameObjectSelected.expired())
		{
			ImGui::MenuItem("Rename");
			if (ImGui::MenuItem("Delete"))
			{
				GameObject_Delete(m_gameObjectSelected);
			}
			ImGui::Separator();
		}
		if (ImGui::MenuItem("Creaty Empty"))
		{
			GameObject_CreateEmpty();
		}
		ImGui::EndPopup();
	}

	// Child nodes
	if (isNodeOpen)
	{
		if (hasVisibleChildren)
		{
			for (const auto& child : children)
			{
				if (!child->GetGameObject()->IsVisibleInHierarchy())
					continue;

				Tree_AddGameObject(child->GetGameObjectRef());
			}
		}
		ImGui::TreePop();
	}
}

void Hierarchy::GameObject_Delete(weak_ptr<GameObject> gameObject)
{
	g_scene->RemoveGameObject(gameObject);
}

void Hierarchy::GameObject_CreateEmpty()
{
	auto gameObject = g_scene->CreateGameObject();
	if (auto selected = m_gameObjectSelected.lock())
	{
		gameObject.lock()->GetTransform()->SetParent(selected->GetTransform());
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CXX_ATTRIBUTES_HPP
#define IOX_UTILS_CXX_ATTRIBUTES_HPP

namespace iox
{
namespace cxx
{
/// @brief if a function has a return value which you do not want to use then you can wrap the function with that macro.
/// Purpose is to suppress the unused compiler warning by adding an attribute to the return value
/// @param[in] expr name of the function where the return value is not used.
/// @code
///     uint32_t foo();
///     IOX_DISCARD_RESULT(foo()); // suppress compiler warning for unused return value
/// @endcode
#define IOX_DISCARD_RESULT(expr) static_cast<void>(expr) // NOLINT

/// @brief IOX_NO_DISCARD adds the [[nodiscard]] keyword if it is available for the current compiler.
///        If additionally the keyword [[gnu::warn_unused]] is present it will be added as well.
/// @note
//    [[nodiscard]], [[gnu::warn_unused]] supported since gcc 4.8 (https://gcc.gnu.org/projects/cxx-status.html)
///   [[nodiscard]], [[gnu::warn_unused]] supported since clang 3.9 (https://clang.llvm.org/cxx_status.html)
///   activate keywords for gcc>=5 or clang>=4
#if defined(_WIN32)
// On WIN32 we are using C++17 which makes the keyword [[nodiscard]] available
#define IOX_NO_DISCARD [[nodiscard]] // NOLINT
#elif defined(__APPLE__) && defined(__clang__)
// On APPLE we are using C++17 which makes the keyword [[nodiscard]] available
#define IOX_NO_DISCARD [[nodiscard, gnu::warn_unused]] // NOLINT
#elif (defined(__clang__) && __clang_major__ >= 4)
#define IOX_NO_DISCARD [[gnu::warn_unused]] // NOLINT
#elif (defined(__GNUC__) && __GNUC__ >= 5)
#define IOX_NO_DISCARD [[nodiscard, gnu::warn_unused]] // NOLINT
#else
// on an unknown platform we use for now nothing since we do not know what is supported there
#define IOX_NO_DISCARD
#endif
#endif

/// @brief IOX_FALLTHROUGH adds the [[fallthrough]] keyword when it is available for the current compiler.
/// @note
//    [[fallthrough]] supported since gcc 7 (https://gcc.gnu.org/projects/cxx-status.html)
///   [[fallthrough]] supported since clang 3.9 (https://clang.llvm.org/cxx_status.html)
///   activate keywords for gcc>=7 or clang>=4
#if (defined(__GNUC__) && __GNUC__ >= 7) || (defined(__clang__) && __clang_major__ >= 4)
#define IOX_FALLTHROUGH [[fallthrough]] // NOLINT
#else
// On WIN32 we are using C++17 which makes the keyword [[fallthrough]] available
#if defined(_WIN32)
#define IOX_FALLTHROUGH [[fallthrough]] // NOLINT
// on an unknown platform we use for now nothing since we do not know what is supported there
#else
#define IOX_FALLTHROUGH
#endif
#endif

/// @brief IOX_MAYBE_UNUSED adds the [[gnu::unused]] or [[maybe_unused]] attribute when it is available for the current
/// compiler.
/// @note
///   activate attribute for gcc or clang
#if defined(__GNUC__) || defined(__clang__)
#define IOX_MAYBE_UNUSED [[gnu::unused]] // NOLINT
#else
// On WIN32 we are using C++17 which makes the attribute [[maybe_unused]] available
#if defined(_WIN32)
#define IOX_MAYBE_UNUSED [[maybe_unused]] // NOLINT
// on an unknown platform we use for now nothing since we do not know what is supported there
#else
#define IOX_MAYBE_UNUSED
#endif
#endif

} // namespace cxx
} // namespace iox

#endif

<commit_msg>iox-#743 adjusted endif and using elif instead of else and another if in attribute macros<commit_after>// Copyright (c) 2021 by Apex.AI Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CXX_ATTRIBUTES_HPP
#define IOX_UTILS_CXX_ATTRIBUTES_HPP

namespace iox
{
namespace cxx
{
/// @brief if a function has a return value which you do not want to use then you can wrap the function with that macro.
/// Purpose is to suppress the unused compiler warning by adding an attribute to the return value
/// @param[in] expr name of the function where the return value is not used.
/// @code
///     uint32_t foo();
///     IOX_DISCARD_RESULT(foo()); // suppress compiler warning for unused return value
/// @endcode
#define IOX_DISCARD_RESULT(expr) static_cast<void>(expr) // NOLINT

/// @brief IOX_NO_DISCARD adds the [[nodiscard]] keyword if it is available for the current compiler.
///        If additionally the keyword [[gnu::warn_unused]] is present it will be added as well.
/// @note
//    [[nodiscard]], [[gnu::warn_unused]] supported since gcc 4.8 (https://gcc.gnu.org/projects/cxx-status.html)
///   [[nodiscard]], [[gnu::warn_unused]] supported since clang 3.9 (https://clang.llvm.org/cxx_status.html)
///   activate keywords for gcc>=5 or clang>=4
#if defined(_WIN32)
// On WIN32 we are using C++17 which makes the keyword [[nodiscard]] available
#define IOX_NO_DISCARD [[nodiscard]] // NOLINT
#elif defined(__APPLE__) && defined(__clang__)
// On APPLE we are using C++17 which makes the keyword [[nodiscard]] available
#define IOX_NO_DISCARD [[nodiscard, gnu::warn_unused]] // NOLINT
#elif (defined(__clang__) && __clang_major__ >= 4)
#define IOX_NO_DISCARD [[gnu::warn_unused]] // NOLINT
#elif (defined(__GNUC__) && __GNUC__ >= 5)
#define IOX_NO_DISCARD [[nodiscard, gnu::warn_unused]] // NOLINT
#else
// on an unknown platform we use for now nothing since we do not know what is supported there
#define IOX_NO_DISCARD
#endif

/// @brief IOX_FALLTHROUGH adds the [[fallthrough]] keyword when it is available for the current compiler.
/// @note
//    [[fallthrough]] supported since gcc 7 (https://gcc.gnu.org/projects/cxx-status.html)
///   [[fallthrough]] supported since clang 3.9 (https://clang.llvm.org/cxx_status.html)
///   activate keywords for gcc>=7 or clang>=4
#if (defined(__GNUC__) && __GNUC__ >= 7) || (defined(__clang__) && __clang_major__ >= 4)
#define IOX_FALLTHROUGH [[fallthrough]] // NOLINT
#elif defined(_WIN32)
// On WIN32 we are using C++17 which makes the keyword [[fallthrough]] available
#define IOX_FALLTHROUGH [[fallthrough]] // NOLINT
// on an unknown platform we use for now nothing since we do not know what is supported there
#else
#define IOX_FALLTHROUGH
#endif

/// @brief IOX_MAYBE_UNUSED adds the [[gnu::unused]] or [[maybe_unused]] attribute when it is available for the current
/// compiler.
/// @note
///   activate attribute for gcc or clang
#if defined(__GNUC__) || defined(__clang__)
#define IOX_MAYBE_UNUSED [[gnu::unused]] // NOLINT
#elif defined(_WIN32)
// On WIN32 we are using C++17 which makes the attribute [[maybe_unused]] available
#define IOX_MAYBE_UNUSED [[maybe_unused]] // NOLINT
// on an unknown platform we use for now nothing since we do not know what is supported there
#else
#define IOX_MAYBE_UNUSED
#endif

} // namespace cxx
} // namespace iox

#endif

<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <tudocomp/compressors/lz78/LZ78Trie.hpp>
#include <tudocomp/Algorithm.hpp>

namespace tdc {
namespace lz78 {

class BinarySortedTrie : public Algorithm, public LZ78Trie<factorid_t> {
	/*
	 * The trie is not stored in standard form. Each node stores the pointer to its first child and a pointer to its next sibling (first as first come first served)
	 */
	std::vector<factorid_t> m_first_child;
	std::vector<factorid_t> m_next_sibling;
	std::vector<literal_t> m_literal;

    IF_STATS(
        size_t m_resizes = 0;
        size_t m_specialresizes = 0;
    )
public:
    inline static Meta meta() {
        Meta m("lz78trie", "binarysorted", "Lempel-Ziv 78 Sorted Binary Trie");
		return m;
	}
    inline BinarySortedTrie(Env&& env, size_t n, const size_t& remaining_characters, factorid_t reserve = 0)
		: Algorithm(std::move(env))
		  , LZ78Trie(n,remaining_characters)
	{
		if(reserve > 0) {
			m_first_child.reserve(reserve);
			m_next_sibling.reserve(reserve);
			m_literal.reserve(reserve);
		}
    }

	node_t add_rootnode(uliteral_t c) override {
        m_first_child.push_back(undef_id);
		m_next_sibling.push_back(undef_id);
		m_literal.push_back(c);
		return size() - 1;
	}

    node_t get_rootnode(uliteral_t c) override {
        return c;
    }

	void clear() override {
        m_first_child.clear();
		m_next_sibling.clear();
		m_literal.clear();

	}

	inline factorid_t new_node(uliteral_t c, const factorid_t m_first_child_id, const factorid_t m_next_sibling_id) {
        m_first_child.push_back(m_first_child_id);
		m_next_sibling.push_back(m_next_sibling_id);
		m_literal.push_back(c);
		return undef_id;
	}

    node_t find_or_insert(const node_t& parent_w, uliteral_t c) override {
        auto parent = parent_w.id();
        const factorid_t newleaf_id = size(); //! if we add a new node, its index will be equal to the current size of the dictionary

		DCHECK_LT(parent, size());

		if(m_first_child[parent] == undef_id) {
			m_first_child[parent] = newleaf_id;
			return new_node(c, undef_id, undef_id);
		} else {
        	factorid_t node = m_first_child[parent];
			if(m_literal[node] > c) {
				m_first_child[parent] = newleaf_id;
				return new_node(c, undef_id, node);
			}
            while(true) { // search the binary tree stored in parent (following left/right siblings)
				if(c == m_literal[node]) return node;
				if(m_next_sibling[node] == undef_id) {
					m_next_sibling[node] = newleaf_id;
					return new_node(c, undef_id, undef_id);
				}
				const factorid_t nextnode = m_next_sibling[node];
				if(m_literal[nextnode] > c) {
					m_next_sibling[node] = newleaf_id;
					return new_node(c, undef_id, nextnode);
				}
				node = m_next_sibling[node];
        if(m_first_child.capacity() == m_first_child.size()) {
            const size_t newbound =    m_first_child.size()+lz78_expected_number_of_remaining_elements(size(),m_n,m_remaining_characters);
            if(newbound < m_first_child.size()*2 ) {
                m_first_child.reserve   (newbound);
                m_next_sibling.reserve  (newbound);
                m_literal.reserve       (newbound);
                IF_STATS(++m_specialresizes);
            }
            IF_STATS(++m_resizes);
        }
            }
		}
		DCHECK(false);
        return undef_id;
    }

    factorid_t size() const override {
        return m_first_child.size();
    }

};

}} //ns

<commit_msg>remove tabs<commit_after>#pragma once

#include <vector>
#include <tudocomp/compressors/lz78/LZ78Trie.hpp>
#include <tudocomp/Algorithm.hpp>

namespace tdc {
namespace lz78 {

class BinarySortedTrie : public Algorithm, public LZ78Trie<factorid_t> {
    /*
     * The trie is not stored in standard form. Each node stores the pointer to its first child and a pointer to its next sibling (first as first come first served)
     */
    std::vector<factorid_t> m_first_child;
    std::vector<factorid_t> m_next_sibling;
    std::vector<literal_t> m_literal;

    IF_STATS(
        size_t m_resizes = 0;
        size_t m_specialresizes = 0;
    )
public:
    inline static Meta meta() {
        Meta m("lz78trie", "binarysorted", "Lempel-Ziv 78 Sorted Binary Trie");
        return m;
    }
    inline BinarySortedTrie(Env&& env, size_t n, const size_t& remaining_characters, factorid_t reserve = 0)
        : Algorithm(std::move(env))
          , LZ78Trie(n,remaining_characters)
    {
        if(reserve > 0) {
            m_first_child.reserve(reserve);
            m_next_sibling.reserve(reserve);
            m_literal.reserve(reserve);
        }
    }

    node_t add_rootnode(uliteral_t c) override {
        m_first_child.push_back(undef_id);
        m_next_sibling.push_back(undef_id);
        m_literal.push_back(c);
        return size() - 1;
    }

    node_t get_rootnode(uliteral_t c) override {
        return c;
    }

    void clear() override {
        m_first_child.clear();
        m_next_sibling.clear();
        m_literal.clear();

    }

    inline factorid_t new_node(uliteral_t c, const factorid_t m_first_child_id, const factorid_t m_next_sibling_id) {
        m_first_child.push_back(m_first_child_id);
        m_next_sibling.push_back(m_next_sibling_id);
        m_literal.push_back(c);
        return undef_id;
    }

    node_t find_or_insert(const node_t& parent_w, uliteral_t c) override {
        auto parent = parent_w.id();
        const factorid_t newleaf_id = size(); //! if we add a new node, its index will be equal to the current size of the dictionary

        DCHECK_LT(parent, size());

        if(m_first_child[parent] == undef_id) {
            m_first_child[parent] = newleaf_id;
            return new_node(c, undef_id, undef_id);
        } else {
            factorid_t node = m_first_child[parent];
            if(m_literal[node] > c) {
                m_first_child[parent] = newleaf_id;
                return new_node(c, undef_id, node);
            }
            while(true) { // search the binary tree stored in parent (following left/right siblings)
                if(c == m_literal[node]) return node;
                if(m_next_sibling[node] == undef_id) {
                    m_next_sibling[node] = newleaf_id;
                    return new_node(c, undef_id, undef_id);
                }
                const factorid_t nextnode = m_next_sibling[node];
                if(m_literal[nextnode] > c) {
                    m_next_sibling[node] = newleaf_id;
                    return new_node(c, undef_id, nextnode);
                }
                node = m_next_sibling[node];
        if(m_first_child.capacity() == m_first_child.size()) {
            const size_t newbound =    m_first_child.size()+lz78_expected_number_of_remaining_elements(size(),m_n,m_remaining_characters);
            if(newbound < m_first_child.size()*2 ) {
                m_first_child.reserve   (newbound);
                m_next_sibling.reserve  (newbound);
                m_literal.reserve       (newbound);
                IF_STATS(++m_specialresizes);
            }
            IF_STATS(++m_resizes);
        }
            }
        }
        DCHECK(false);
        return undef_id;
    }

    factorid_t size() const override {
        return m_first_child.size();
    }

};

}} //ns

<|endoftext|>


<commit_before><commit_msg>Fix crash on startup<commit_after><|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Manasij Mukherjee  <manasij7479@gmail.com>
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Path.h"

#include "clang/Sema/Sema.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h" // for operator new[](unsigned long, ASTCtx..)
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/AutoloadCallback.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/Output.h"
#include "DeclUnloader.h"

#include <clang/Lex/HeaderSearch.h>

namespace {
  static const char annoTag[] = "$clingAutoload$";
  static const size_t lenAnnoTag = sizeof(annoTag) - 1;
}

using namespace clang;

namespace cling {

  void AutoloadCallback::report(clang::SourceLocation l, llvm::StringRef name,
                                llvm::StringRef header) {
    Sema& sema= m_Interpreter->getSema();

    unsigned id
      = sema.getDiagnostics().getCustomDiagID (DiagnosticsEngine::Level::Warning,
                                                 "Note: '%0' can be found in %1");
/*    unsigned idn //TODO: To be enabled after we have a way to get the full path
      = sema.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Level::Note,
                                                "Type : %0 , Full Path: %1")*/;

    if (header.startswith(llvm::StringRef(annoTag, lenAnnoTag)))
      sema.Diags.Report(l, id) << name << header.drop_front(lenAnnoTag);

  }

  bool AutoloadCallback::LookupObject (TagDecl *t) {
    if (m_ShowSuggestions && t->hasAttr<AnnotateAttr>())
      report(t->getLocation(),t->getNameAsString(),t->getAttr<AnnotateAttr>()->getAnnotation());
    return false;
  }

  class AutoloadingVisitor: public RecursiveASTVisitor<AutoloadingVisitor> {
  private:
    ///\brief Flag determining the visitor's actions. If true, register autoload
    /// entries, i.e. remember the connection between filename and the declaration
    /// that needs to be updated on #include of the filename.
    /// If false, react on an #include by adjusting the forward decls, e.g. by
    /// removing the default tremplate arguments (that will now be provided by
    /// the definition read from the include) and by removing enum declarations
    /// that would otherwise be duplicates.
    bool m_IsStoringState;
    bool m_IsAutloadEntry;  // True during the traversal of an explicitly annotated decl.
    AutoloadCallback::FwdDeclsMap* m_Map;
    clang::Preprocessor* m_PP;
    clang::Sema* m_Sema;

    std::pair<const clang::FileEntry*,const clang::FileEntry*> m_PrevFE;
    std::pair<std::string,std::string> m_PrevFileName;
  private:
    bool IsAutoloadEntry(Decl *D) {
      for(auto attr = D->specific_attr_begin<AnnotateAttr>(),
               end = D->specific_attr_end<AnnotateAttr> ();
          attr != end;
          ++attr)
      {
        //        cling::errs() << "Annotation: " << c->getAnnotation() << "\n";
        if (!attr->isInherited()) {
          llvm::StringRef annotation = attr->getAnnotation();
          assert(!annotation.empty() && "Empty annotation!");
          if (annotation.startswith(llvm::StringRef(annoTag, lenAnnoTag))) {
            // autoload annotation.
            return true;
          }
        }
      }
      return false;
    }

    using Annotations_t = std::pair<llvm::StringRef,llvm::StringRef>;

    void InsertIntoAutoloadingState(Decl* decl, Annotations_t FileNames) {

      assert(m_PP);

      auto addFile = [this,decl](llvm::StringRef FileName, bool warn) {
        if (FileName.empty()) return (const FileEntry*)nullptr;

        const FileEntry* FE = 0;
        SourceLocation fileNameLoc;
        bool isAngled = false;
        const DirectoryLookup* FromDir = 0;
        const FileEntry* FromFile = 0;
        const DirectoryLookup* CurDir = 0;
        bool needCacheUpdate = false;

        if (FileName.equals(m_PrevFileName.first))
          FE = m_PrevFE.first;
        else if (FileName.equals(m_PrevFileName.second))
          FE = m_PrevFE.second;
        else {
          FE = m_PP->LookupFile(fileNameLoc, FileName, isAngled,
                                FromDir, FromFile, CurDir, /*SearchPath*/0,
                                /*RelativePath*/ 0, /*suggestedModule*/0,
                                /*IsMapped*/0, /*SkipCache*/ false,
                                /*OpenFile*/ false, /*CacheFail*/ true);
          needCacheUpdate = true;
        }

        if (FE) {
          auto& Vec = (*m_Map)[FE];
          Vec.push_back(decl);
          if (needCacheUpdate) return FE;
          else return (const FileEntry*)nullptr;
        } else if (warn) {
          // If the top level header is expected to be findable at run-time,
          // the direct header might not because the include path might be
          // different enough and only the top-header is guaranteed to be seen
          // by the user as an interface header to be available on the
          // run-time include path.
          cling::errs()
          << "Error in cling::AutoloadingVisitor::InsertIntoAutoloadingState:\n"
          "   Missing FileEntry for " << FileName << "\n";
          if (NamedDecl* ND = dyn_cast<NamedDecl>(decl)) {
            cling::errs() << "   requested to autoload type ";
            ND->getNameForDiagnostic(cling::errs(),
                                     ND->getASTContext().getPrintingPolicy(),
                                     true /*qualified*/);
            cling::errs() << "\n";
          }
          return (const FileEntry*)nullptr;
        } else {
          // Case of the direct header that is not a top level header, no
          // warning in this case (to likely to be a false positive).
          return (const FileEntry*)nullptr;
        }
      };

      const FileEntry* cacheUpdate;

      if ( (cacheUpdate = addFile(FileNames.first,true)) ) {
        m_PrevFE.first = cacheUpdate;
        m_PrevFileName.first = FileNames.first;
      }
      if ( (cacheUpdate = addFile(FileNames.second,false)) ) {
        m_PrevFE.second = cacheUpdate;
        m_PrevFileName.second = FileNames.second;
      }

    }

  public:
    AutoloadingVisitor():
      m_IsStoringState(false), m_IsAutloadEntry(false), m_Map(0), m_PP(0),
    m_Sema(0), m_PrevFE({nullptr,nullptr})
    {}

    void RemoveDefaultArgsOf(Decl* D, Sema* S) {
      m_Sema = S;

      auto cursor = D->getMostRecentDecl();
      m_IsAutloadEntry = IsAutoloadEntry(cursor);
      TraverseDecl(cursor);
      while (cursor != D && (cursor = cursor->getPreviousDecl())) {
        m_IsAutloadEntry = IsAutoloadEntry(cursor);
        TraverseDecl(cursor);
      }
      m_IsAutloadEntry = false;
    }

    void TrackDefaultArgStateOf(Decl* D, AutoloadCallback::FwdDeclsMap& map,
                                Preprocessor& PP) {
      m_IsStoringState = true;
      m_Map = ↦
      m_PP = &PP;
      TraverseDecl(D);
      m_PP = 0;
      m_Map = 0;
      m_IsStoringState = false;
    }

    bool shouldVisitTemplateInstantiations() { return true; }

    bool VisitDecl(Decl* D) {
      if (!m_IsStoringState)
        return true;

      if (!D->hasAttr<AnnotateAttr>())
        return true;

      Annotations_t annotations;
      for(auto attr = D->specific_attr_begin<AnnotateAttr> (),
          end = D->specific_attr_end<AnnotateAttr> ();
          attr != end;
          ++attr)
      {
        if (!attr->isInherited()) {
          auto annot = attr->getAnnotation();
          if (annot.startswith(llvm::StringRef(annoTag, lenAnnoTag))) {
            if (annotations.first.empty()) {
              annotations.first = annot.drop_front(lenAnnoTag);
            } else {
              annotations.second = annot.drop_front(lenAnnoTag);
            }
          }
        }
      }
      InsertIntoAutoloadingState(D, annotations);

      return true;
    }

    bool VisitCXXRecordDecl(CXXRecordDecl* D) {
      // Since we are only interested in fixing forward declaration
      // there is no need to continue on when we see a complete definition.
      if (D->isCompleteDefinition())
        return false;

      if (!D->hasAttr<AnnotateAttr>())
        return true;

      if (ClassTemplateDecl* TmplD = D->getDescribedClassTemplate())
        return VisitTemplateDecl(TmplD);
      return true;
    }

    bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitTemplateDecl(TemplateDecl* D) {
      if (D->getTemplatedDecl() &&
          !D->getTemplatedDecl()->hasAttr<AnnotateAttr>())
        return true;

      // If we have a definition we might be about to re-#include the
      // same header containing definition that was #included previously,
      // i.e. we might have multiple fwd decls for the same template.
      // DO NOT remove the defaults here; the definition needs to keep it.
      // (ROOT-7037)
      if (ClassTemplateDecl* CTD = dyn_cast<ClassTemplateDecl>(D))
        if (CXXRecordDecl* TemplatedD = CTD->getTemplatedDecl())
          if (TemplatedD->getDefinition())
            return true;

      for(auto P: D->getTemplateParameters()->asArray())
        TraverseDecl(P);
      return true;
    }

    bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitParmVarDecl(ParmVarDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArg() && !D->hasInheritedDefaultArg())
          D->setDefaultArg(nullptr);
      } else {
        if (D->hasDefaultArg() && D->hasInheritedDefaultArg())
          D->setDefaultArg(nullptr);
      }
      return true;
    }

    bool VisitEnumDecl(EnumDecl* D) {
      if (m_IsStoringState)
        return true;

      // Now that we will read the full enum, unload the forward decl.
      if (IsAutoloadEntry(D))
        UnloadDecl(m_Sema, D);
      return true;
    }
  };

  void AutoloadCallback::InclusionDirective(clang::SourceLocation HashLoc,
                          const clang::Token &IncludeTok,
                          llvm::StringRef FileName,
                          bool IsAngled,
                          clang::CharSourceRange FilenameRange,
                          const clang::FileEntry *File,
                          llvm::StringRef SearchPath,
                          llvm::StringRef RelativePath,
                          const clang::Module *Imported) {
    // If File is 0 this means that the #included file doesn't exist.
    if (!File)
      return;

    auto found = m_Map.find(File);
    if (found == m_Map.end())
     return; // nothing to do, file not referred in any annotation

    AutoloadingVisitor defaultArgsCleaner;
    for (auto D : found->second) {
      defaultArgsCleaner.RemoveDefaultArgsOf(D, &getInterpreter()->getSema());
    }
    // Don't need to keep track of cleaned up decls from file.
    m_Map.erase(found);
  }

  AutoloadCallback::~AutoloadCallback() {
  }

  void AutoloadCallback::TransactionCommitted(const Transaction &T) {
    if (T.decls_begin() == T.decls_end())
      return;
    if (T.decls_begin()->m_DGR.isNull())
      return;

    // The first decl must be
    //   extern int __Cling_Autoloading_Map;
    bool HaveAutoloadingMapMarker = false;
    for (auto I = T.decls_begin(), E = T.decls_end();
         !HaveAutoloadingMapMarker && I != E; ++I) {
      if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl)
        return;
      for (auto&& D: I->m_DGR) {
        if (isa<EmptyDecl>(D))
          continue;
        else if (auto VD = dyn_cast<VarDecl>(D)) {
          HaveAutoloadingMapMarker
            = VD->hasExternalStorage() && VD->getIdentifier()
              && VD->getName().equals("__Cling_Autoloading_Map");
          if (!HaveAutoloadingMapMarker)
            return;
          break;
        } else
          return;
      }
    }

    if (!HaveAutoloadingMapMarker)
      return;

    AutoloadingVisitor defaultArgsStateCollector;
    Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
    for (auto I = T.decls_begin(), E = T.decls_end(); I != E; ++I)
      for (auto&& D: I->m_DGR)
        defaultArgsStateCollector.TrackDefaultArgStateOf(D, m_Map, PP);
  }

} //end namespace cling
<commit_msg>Claim #include <auto-parse-hdr> to remember the full path (ROOT-8863).<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Manasij Mukherjee  <manasij7479@gmail.com>
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Path.h"

#include "clang/Sema/Sema.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h" // for operator new[](unsigned long, ASTCtx..)
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/AutoloadCallback.h"
#include "cling/Interpreter/Transaction.h"
#include "cling/Utils/Output.h"
#include "DeclUnloader.h"

#include <clang/Lex/HeaderSearch.h>

namespace {
  static const char annoTag[] = "$clingAutoload$";
  static const size_t lenAnnoTag = sizeof(annoTag) - 1;
}

using namespace clang;

namespace cling {

  void AutoloadCallback::report(clang::SourceLocation l, llvm::StringRef name,
                                llvm::StringRef header) {
    Sema& sema= m_Interpreter->getSema();

    unsigned id
      = sema.getDiagnostics().getCustomDiagID (DiagnosticsEngine::Level::Warning,
                                                 "Note: '%0' can be found in %1");
/*    unsigned idn //TODO: To be enabled after we have a way to get the full path
      = sema.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Level::Note,
                                                "Type : %0 , Full Path: %1")*/;

    if (header.startswith(llvm::StringRef(annoTag, lenAnnoTag)))
      sema.Diags.Report(l, id) << name << header.drop_front(lenAnnoTag);

  }

  bool AutoloadCallback::LookupObject (TagDecl *t) {
    if (m_ShowSuggestions && t->hasAttr<AnnotateAttr>())
      report(t->getLocation(),t->getNameAsString(),t->getAttr<AnnotateAttr>()->getAnnotation());
    return false;
  }

  class AutoloadingVisitor: public RecursiveASTVisitor<AutoloadingVisitor> {
  private:
    ///\brief Flag determining the visitor's actions. If true, register autoload
    /// entries, i.e. remember the connection between filename and the declaration
    /// that needs to be updated on #include of the filename.
    /// If false, react on an #include by adjusting the forward decls, e.g. by
    /// removing the default tremplate arguments (that will now be provided by
    /// the definition read from the include) and by removing enum declarations
    /// that would otherwise be duplicates.
    bool m_IsStoringState;
    bool m_IsAutloadEntry;  // True during the traversal of an explicitly annotated decl.
    AutoloadCallback::FwdDeclsMap* m_Map;
    clang::Preprocessor* m_PP;
    clang::Sema* m_Sema;

    std::pair<const clang::FileEntry*,const clang::FileEntry*> m_PrevFE;
    std::pair<std::string,std::string> m_PrevFileName;
  private:
    bool IsAutoloadEntry(Decl *D) {
      for(auto attr = D->specific_attr_begin<AnnotateAttr>(),
               end = D->specific_attr_end<AnnotateAttr> ();
          attr != end;
          ++attr)
      {
        //        cling::errs() << "Annotation: " << c->getAnnotation() << "\n";
        if (!attr->isInherited()) {
          llvm::StringRef annotation = attr->getAnnotation();
          assert(!annotation.empty() && "Empty annotation!");
          if (annotation.startswith(llvm::StringRef(annoTag, lenAnnoTag))) {
            // autoload annotation.
            return true;
          }
        }
      }
      return false;
    }

    using Annotations_t = std::pair<llvm::StringRef,llvm::StringRef>;

    void InsertIntoAutoloadingState(Decl* decl, Annotations_t FileNames) {

      assert(m_PP);

      auto addFile = [this,decl](llvm::StringRef FileName, bool warn) {
        if (FileName.empty()) return (const FileEntry*)nullptr;

        const FileEntry* FE = 0;
        SourceLocation fileNameLoc;
        // Remember this file wth full path, not "./File.h" (ROOT-8863).
        bool isAngled = true;
        const DirectoryLookup* FromDir = 0;
        const FileEntry* FromFile = 0;
        const DirectoryLookup* CurDir = 0;
        bool needCacheUpdate = false;

        if (FileName.equals(m_PrevFileName.first))
          FE = m_PrevFE.first;
        else if (FileName.equals(m_PrevFileName.second))
          FE = m_PrevFE.second;
        else {
          FE = m_PP->LookupFile(fileNameLoc, FileName, isAngled,
                                FromDir, FromFile, CurDir, /*SearchPath*/0,
                                /*RelativePath*/ 0, /*suggestedModule*/0,
                                /*IsMapped*/0, /*SkipCache*/ false,
                                /*OpenFile*/ false, /*CacheFail*/ true);
          needCacheUpdate = true;
        }

        if (FE) {
          auto& Vec = (*m_Map)[FE];
          Vec.push_back(decl);
          if (needCacheUpdate) return FE;
          else return (const FileEntry*)nullptr;
        } else if (warn) {
          // If the top level header is expected to be findable at run-time,
          // the direct header might not because the include path might be
          // different enough and only the top-header is guaranteed to be seen
          // by the user as an interface header to be available on the
          // run-time include path.
          cling::errs()
          << "Error in cling::AutoloadingVisitor::InsertIntoAutoloadingState:\n"
          "   Missing FileEntry for " << FileName << "\n";
          if (NamedDecl* ND = dyn_cast<NamedDecl>(decl)) {
            cling::errs() << "   requested to autoload type ";
            ND->getNameForDiagnostic(cling::errs(),
                                     ND->getASTContext().getPrintingPolicy(),
                                     true /*qualified*/);
            cling::errs() << "\n";
          }
          return (const FileEntry*)nullptr;
        } else {
          // Case of the direct header that is not a top level header, no
          // warning in this case (to likely to be a false positive).
          return (const FileEntry*)nullptr;
        }
      };

      const FileEntry* cacheUpdate;

      if ( (cacheUpdate = addFile(FileNames.first,true)) ) {
        m_PrevFE.first = cacheUpdate;
        m_PrevFileName.first = FileNames.first;
      }
      if ( (cacheUpdate = addFile(FileNames.second,false)) ) {
        m_PrevFE.second = cacheUpdate;
        m_PrevFileName.second = FileNames.second;
      }

    }

  public:
    AutoloadingVisitor():
      m_IsStoringState(false), m_IsAutloadEntry(false), m_Map(0), m_PP(0),
    m_Sema(0), m_PrevFE({nullptr,nullptr})
    {}

    void RemoveDefaultArgsOf(Decl* D, Sema* S) {
      m_Sema = S;

      auto cursor = D->getMostRecentDecl();
      m_IsAutloadEntry = IsAutoloadEntry(cursor);
      TraverseDecl(cursor);
      while (cursor != D && (cursor = cursor->getPreviousDecl())) {
        m_IsAutloadEntry = IsAutoloadEntry(cursor);
        TraverseDecl(cursor);
      }
      m_IsAutloadEntry = false;
    }

    void TrackDefaultArgStateOf(Decl* D, AutoloadCallback::FwdDeclsMap& map,
                                Preprocessor& PP) {
      m_IsStoringState = true;
      m_Map = ↦
      m_PP = &PP;
      TraverseDecl(D);
      m_PP = 0;
      m_Map = 0;
      m_IsStoringState = false;
    }

    bool shouldVisitTemplateInstantiations() { return true; }

    bool VisitDecl(Decl* D) {
      if (!m_IsStoringState)
        return true;

      if (!D->hasAttr<AnnotateAttr>())
        return true;

      Annotations_t annotations;
      for(auto attr = D->specific_attr_begin<AnnotateAttr> (),
          end = D->specific_attr_end<AnnotateAttr> ();
          attr != end;
          ++attr)
      {
        if (!attr->isInherited()) {
          auto annot = attr->getAnnotation();
          if (annot.startswith(llvm::StringRef(annoTag, lenAnnoTag))) {
            if (annotations.first.empty()) {
              annotations.first = annot.drop_front(lenAnnoTag);
            } else {
              annotations.second = annot.drop_front(lenAnnoTag);
            }
          }
        }
      }
      InsertIntoAutoloadingState(D, annotations);

      return true;
    }

    bool VisitCXXRecordDecl(CXXRecordDecl* D) {
      // Since we are only interested in fixing forward declaration
      // there is no need to continue on when we see a complete definition.
      if (D->isCompleteDefinition())
        return false;

      if (!D->hasAttr<AnnotateAttr>())
        return true;

      if (ClassTemplateDecl* TmplD = D->getDescribedClassTemplate())
        return VisitTemplateDecl(TmplD);
      return true;
    }

    bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitTemplateDecl(TemplateDecl* D) {
      if (D->getTemplatedDecl() &&
          !D->getTemplatedDecl()->hasAttr<AnnotateAttr>())
        return true;

      // If we have a definition we might be about to re-#include the
      // same header containing definition that was #included previously,
      // i.e. we might have multiple fwd decls for the same template.
      // DO NOT remove the defaults here; the definition needs to keep it.
      // (ROOT-7037)
      if (ClassTemplateDecl* CTD = dyn_cast<ClassTemplateDecl>(D))
        if (CXXRecordDecl* TemplatedD = CTD->getTemplatedDecl())
          if (TemplatedD->getDefinition())
            return true;

      for(auto P: D->getTemplateParameters()->asArray())
        TraverseDecl(P);
      return true;
    }

    bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      } else {
        if (D->hasDefaultArgument() && D->defaultArgumentWasInherited())
          D->removeDefaultArgument();
      }
      return true;
    }

    bool VisitParmVarDecl(ParmVarDecl* D) {
      if (m_IsStoringState)
        return true;

      if (m_IsAutloadEntry) {
        if (D->hasDefaultArg() && !D->hasInheritedDefaultArg())
          D->setDefaultArg(nullptr);
      } else {
        if (D->hasDefaultArg() && D->hasInheritedDefaultArg())
          D->setDefaultArg(nullptr);
      }
      return true;
    }

    bool VisitEnumDecl(EnumDecl* D) {
      if (m_IsStoringState)
        return true;

      // Now that we will read the full enum, unload the forward decl.
      if (IsAutoloadEntry(D))
        UnloadDecl(m_Sema, D);
      return true;
    }
  };

  void AutoloadCallback::InclusionDirective(clang::SourceLocation HashLoc,
                          const clang::Token &IncludeTok,
                          llvm::StringRef FileName,
                          bool IsAngled,
                          clang::CharSourceRange FilenameRange,
                          const clang::FileEntry *File,
                          llvm::StringRef SearchPath,
                          llvm::StringRef RelativePath,
                          const clang::Module *Imported) {
    // If File is 0 this means that the #included file doesn't exist.
    if (!File)
      return;

    auto found = m_Map.find(File);
    if (found == m_Map.end())
     return; // nothing to do, file not referred in any annotation

    AutoloadingVisitor defaultArgsCleaner;
    for (auto D : found->second) {
      defaultArgsCleaner.RemoveDefaultArgsOf(D, &getInterpreter()->getSema());
    }
    // Don't need to keep track of cleaned up decls from file.
    m_Map.erase(found);
  }

  AutoloadCallback::~AutoloadCallback() {
  }

  void AutoloadCallback::TransactionCommitted(const Transaction &T) {
    if (T.decls_begin() == T.decls_end())
      return;
    if (T.decls_begin()->m_DGR.isNull())
      return;

    // The first decl must be
    //   extern int __Cling_Autoloading_Map;
    bool HaveAutoloadingMapMarker = false;
    for (auto I = T.decls_begin(), E = T.decls_end();
         !HaveAutoloadingMapMarker && I != E; ++I) {
      if (I->m_Call != cling::Transaction::kCCIHandleTopLevelDecl)
        return;
      for (auto&& D: I->m_DGR) {
        if (isa<EmptyDecl>(D))
          continue;
        else if (auto VD = dyn_cast<VarDecl>(D)) {
          HaveAutoloadingMapMarker
            = VD->hasExternalStorage() && VD->getIdentifier()
              && VD->getName().equals("__Cling_Autoloading_Map");
          if (!HaveAutoloadingMapMarker)
            return;
          break;
        } else
          return;
      }
    }

    if (!HaveAutoloadingMapMarker)
      return;

    AutoloadingVisitor defaultArgsStateCollector;
    Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
    for (auto I = T.decls_begin(), E = T.decls_end(); I != E; ++I)
      for (auto&& D: I->m_DGR)
        defaultArgsStateCollector.TrackDefaultArgStateOf(D, m_Map, PP);
  }

} //end namespace cling
<|endoftext|>


<commit_before>#define GUILITE_ON	//Do not define this macro once more!!!
#include "GuiLite.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 3D engine
void multiply(int m, int n, int p, float* a, float* b, float* c)// a[m][n] * b[n][p] = c[m][p]
{
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < p; j++) {
			c[i * p + j] = 0;
			for (int k = 0; k < n; k++) {
				c[i * p + j] += a[i * n + k] * b[k * p + j];
			}
		}
	}
}

void rotateX(float angle, float* point, float* output)// rotate matrix for X
{
	static float rotation[3][3];
	rotation[0][0] = 1;
	rotation[1][1] = cos(angle);
	rotation[1][2] = 0 - sin(angle);
	rotation[2][1] = sin(angle);
	rotation[2][2] = cos(angle);
	multiply(3, 3, 1, (float*)rotation, point, output);
}

void rotateY(float angle, float* point, float* output)// rotate matrix for Y
{
	static float rotation[3][3];
	rotation[0][0] = cos(angle);
	rotation[0][2] = sin(angle);
	rotation[1][1] = 1;
	rotation[2][0] = 0 - sin(angle);
	rotation[2][2] = cos(angle);
    multiply(3, 3, 1, (float*)rotation, point, output);
}

void rotateZ(float angle, float* point, float* output)// rotate matrix for Z
{
	static float rotation[3][3];
	rotation[0][0] = cos(angle);
	rotation[0][1] = 0 - sin(angle);
	rotation[1][0] = sin(angle);
	rotation[1][1] = cos(angle);
	rotation[2][2] = 1;
    multiply(3, 3, 1, (float*)rotation, point, output);
}

void projectOnXY(float* point, float* output, float zFactor = 1)
{
	static float projection[2][3];//project on X/Y face
	projection[0][0] = zFactor;//the raio of point.z and camera.z
	projection[1][1] = zFactor;//the raio of point.z and camera.z
    multiply(2, 3, 1, (float*)projection, point, output);
}

#define UI_WIDTH	240
#define UI_HEIGHT	320
#define SPACE		20
#define ROW			10
#define COL			10
#define POINT_CNT	ROW * COL
#define AMPLITUDE	50
static c_surface* s_surface;
static c_display* s_display;

class Cwave
{
public:
	Cwave()
	{
		rotate_angle = 1.0;
		angle = 0;
		memset(points2d, 0, sizeof(points2d));
		for (int y = 0; y < ROW; y++)
		{
			for (int x = 0; x < COL; x++)
			{
				points[y * COL + x][0] = x * SPACE;
				points[y * COL + x][1] = y * SPACE - (UI_WIDTH / 2);
			}
		}
	}
	virtual void draw(int x, int y, bool isErase)
	{
		for (int i = 0; i < POINT_CNT; i++)
		{
			unsigned int color = (points[i][2] > 0) ? GL_RGB(231, 11, 117) : GL_RGB(92, 45, 145);
			s_surface->fill_rect(points2d[i][0] + x - 1, points2d[i][1] + y - 1, points2d[i][0] + x + 1, points2d[i][1] + y + 1, (isErase) ? 0 : color, Z_ORDER_LEVEL_0);
		}
	}
	virtual void swing()
	{
		angle += 0.1;
		for (int y = 0; y < ROW; y++)
		{
			for (int x = 0; x < COL; x++)
			{
				float offset = sqrt((x - 5) * (x - 5) + (y - 5) * (y - 5)) / 2;
				points[y * COL + x][2] = sin(angle + offset) * AMPLITUDE;
			}
		}

		float rotateOut1[3][1];
		for (int i = 0; i < POINT_CNT; i++)
		{
			rotateX(rotate_angle, points[i], (float*)rotateOut1);
			projectOnXY((float*)rotateOut1, (float*)points2d[i]);
		}
		//rotate_angle += 0.1;
	}
private:
	static float points[POINT_CNT][3];
	float points2d[POINT_CNT][2];
	float angle, rotate_angle;
};

float Cwave::points[POINT_CNT][3];//x, y, z

// Demo
void create_ui(void* phy_fb, int screen_width, int screen_height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) {
	if (phy_fb)
	{
		static c_surface surface(UI_WIDTH, UI_HEIGHT, color_bytes, Z_ORDER_LEVEL_0);
		static c_display display(phy_fb, screen_width, screen_height, &surface);
		s_surface = &surface;
		s_display = &display;
	}
	else
	{//for MCU without framebuffer
		static c_surface_no_fb surface_no_fb(UI_WIDTH, UI_HEIGHT, color_bytes, gfx_op, Z_ORDER_LEVEL_0);
		static c_display display(phy_fb, screen_width, screen_height, &surface_no_fb);
		s_surface = &surface_no_fb;
		s_display = &display;
	}
	s_surface->fill_rect(0, 0, UI_WIDTH - 1, UI_HEIGHT - 1, 0, Z_ORDER_LEVEL_0);

	Cwave theCwave;
	while(1) {
		theCwave.draw(30, UI_HEIGHT / 2, true);//erase footprint
		theCwave.swing();
		theCwave.draw(30, UI_HEIGHT / 2, false);//refresh Cwave

		thread_sleep(50);
	}
}

//////////////////////// interface for all platform ////////////////////////
extern "C" void startHello3Dwave(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) {
	create_ui(phy_fb, width, height, color_bytes, gfx_op);
}

extern "C" void* getUiOfHello3Dwave(int* width, int* height, bool force_update)
{
    return s_display->get_updated_fb(width, height, force_update);
}
<commit_msg>change color of hell3Dwave<commit_after>#define GUILITE_ON	//Do not define this macro once more!!!
#include "GuiLite.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 3D engine
void multiply(int m, int n, int p, float* a, float* b, float* c)// a[m][n] * b[n][p] = c[m][p]
{
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < p; j++) {
			c[i * p + j] = 0;
			for (int k = 0; k < n; k++) {
				c[i * p + j] += a[i * n + k] * b[k * p + j];
			}
		}
	}
}

void rotateX(float angle, float* point, float* output)// rotate matrix for X
{
	static float rotation[3][3];
	rotation[0][0] = 1;
	rotation[1][1] = cos(angle);
	rotation[1][2] = 0 - sin(angle);
	rotation[2][1] = sin(angle);
	rotation[2][2] = cos(angle);
	multiply(3, 3, 1, (float*)rotation, point, output);
}

void rotateY(float angle, float* point, float* output)// rotate matrix for Y
{
	static float rotation[3][3];
	rotation[0][0] = cos(angle);
	rotation[0][2] = sin(angle);
	rotation[1][1] = 1;
	rotation[2][0] = 0 - sin(angle);
	rotation[2][2] = cos(angle);
    multiply(3, 3, 1, (float*)rotation, point, output);
}

void rotateZ(float angle, float* point, float* output)// rotate matrix for Z
{
	static float rotation[3][3];
	rotation[0][0] = cos(angle);
	rotation[0][1] = 0 - sin(angle);
	rotation[1][0] = sin(angle);
	rotation[1][1] = cos(angle);
	rotation[2][2] = 1;
    multiply(3, 3, 1, (float*)rotation, point, output);
}

void projectOnXY(float* point, float* output, float zFactor = 1)
{
	static float projection[2][3];//project on X/Y face
	projection[0][0] = zFactor;//the raio of point.z and camera.z
	projection[1][1] = zFactor;//the raio of point.z and camera.z
    multiply(2, 3, 1, (float*)projection, point, output);
}

#define UI_WIDTH	240
#define UI_HEIGHT	320
#define SPACE		13
#define ROW			15
#define COL			15
#define POINT_CNT	ROW * COL
#define AMPLITUDE	50
static c_surface* s_surface;
static c_display* s_display;

class Cwave
{
public:
	Cwave()
	{
		rotate_angle = 1.0;//1.57;
		angle = 0;
		memset(points2d, 0, sizeof(points2d));
		for (int y = 0; y < ROW; y++)
		{
			for (int x = 0; x < COL; x++)
			{
				points[y * COL + x][0] = x * SPACE;
				points[y * COL + x][1] = y * SPACE - (UI_WIDTH / 2);
			}
		}
	}
	virtual void draw(int x, int y, bool isErase)
	{
		for (int i = 0; i < POINT_CNT; i++)
		{
			float factor = (1 + points[i][2] / AMPLITUDE) / 2;
			unsigned int color = GL_RGB(147 * factor, 72 * factor, 232 *  factor);
			s_surface->fill_rect(points2d[i][0] + x - 1, points2d[i][1] + y - 1, points2d[i][0] + x + 1, points2d[i][1] + y + 1, (isErase) ? 0 : color, Z_ORDER_LEVEL_0);
		}
	}
	virtual void swing()
	{
		angle += 0.1;
		for (int y = 0; y < ROW; y++)
		{
			for (int x = 0; x < COL; x++)
			{
				float offset = sqrt((x - COL / 2) * (x - COL / 2) + (y - ROW / 2) * (y - ROW / 2)) / 2;
				points[y * COL + x][2] = sin(angle + offset) * AMPLITUDE;
			}
		}

		float rotateOut1[3][1];
		for (int i = 0; i < POINT_CNT; i++)
		{
			rotateX(rotate_angle, points[i], (float*)rotateOut1);
			float zFactor = UI_WIDTH / (UI_WIDTH - rotateOut1[2][0]);
			projectOnXY((float*)rotateOut1, (float*)points2d[i], zFactor);
		}
		//rotate_angle += 0.001;
	}
private:
	static float points[POINT_CNT][3];
	float points2d[POINT_CNT][2];
	float angle, rotate_angle;
};

float Cwave::points[POINT_CNT][3];//x, y, z

// Demo
void create_ui(void* phy_fb, int screen_width, int screen_height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) {
	if (phy_fb)
	{
		static c_surface surface(UI_WIDTH, UI_HEIGHT, color_bytes, Z_ORDER_LEVEL_0);
		static c_display display(phy_fb, screen_width, screen_height, &surface);
		s_surface = &surface;
		s_display = &display;
	}
	else
	{//for MCU without framebuffer
		static c_surface_no_fb surface_no_fb(UI_WIDTH, UI_HEIGHT, color_bytes, gfx_op, Z_ORDER_LEVEL_0);
		static c_display display(phy_fb, screen_width, screen_height, &surface_no_fb);
		s_surface = &surface_no_fb;
		s_display = &display;
	}
	s_surface->fill_rect(0, 0, UI_WIDTH - 1, UI_HEIGHT - 1, 0, Z_ORDER_LEVEL_0);

	Cwave theCwave;
	while(1) {
		theCwave.draw(30, UI_HEIGHT / 2, true);//erase footprint
		theCwave.swing();
		theCwave.draw(30, UI_HEIGHT / 2, false);//refresh Cwave

		thread_sleep(50);
	}
}

//////////////////////// interface for all platform ////////////////////////
extern "C" void startHello3Dwave(void* phy_fb, int width, int height, int color_bytes, struct EXTERNAL_GFX_OP* gfx_op) {
	create_ui(phy_fb, width, height, color_bytes, gfx_op);
}

extern "C" void* getUiOfHello3Dwave(int* width, int* height, bool force_update)
{
    return s_display->get_updated_fb(width, height, force_update);
}
<|endoftext|>