<commit_before>/************************************************************************************
 * Copyright (C) 2017, Copyright Holders of the ALICE Collaboration                 *
 * 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 the <organization> 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 ALICE COLLABORATION 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.                     *
 ************************************************************************************/
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <THistManager.h>
#include <TLinearBinning.h>
#include <TLorentzVector.h>

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskEmcalJetConstituentQA.h"
#include "AliAODInputHandler.h"
#include "AliClusterContainer.h"
#include "AliEmcalAnalysisFactory.h"
#include "AliEmcalTriggerDecisionContainer.h"
#include "AliEmcalJet.h"
#include "AliInputEventHandler.h"
#include "AliJetContainer.h"
#include "AliLog.h"
#include "AliTrackContainer.h"
#include "AliVCluster.h"
#include "AliVEvent.h"
#include "AliVTrack.h"

/// \cond CLASSIMP
ClassImp(EmcalTriggerJets::AliAnalysisTaskEmcalJetConstituentQA);
/// \endcond

using namespace EmcalTriggerJets;

AliAnalysisTaskEmcalJetConstituentQA::AliAnalysisTaskEmcalJetConstituentQA():
  AliAnalysisTaskEmcalJet(),
  fHistos(nullptr),
  fNameTrackContainer(""),
  fNameClusterContainer(""),
  fTriggerSelectionString(""),
  fUseTriggerSelection(kFALSE),
  fNameTriggerDecisionContainer("EmcalTriggerDecision")
{
  this->SetUseAliAnaUtils(true);
}

AliAnalysisTaskEmcalJetConstituentQA::AliAnalysisTaskEmcalJetConstituentQA(const char *name):
  AliAnalysisTaskEmcalJet(name, true),
  fHistos(nullptr),
  fNameTrackContainer(""),
  fNameClusterContainer(""),
  fTriggerSelectionString(""),
  fUseTriggerSelection(kFALSE),
  fNameTriggerDecisionContainer("EmcalTriggerDecision")
{
  this->SetUseAliAnaUtils(true);
}

AliAnalysisTaskEmcalJetConstituentQA::~AliAnalysisTaskEmcalJetConstituentQA(){
  if(fHistos) delete fHistos;
}

void AliAnalysisTaskEmcalJetConstituentQA::UserCreateOutputObjects(){
  AliAnalysisTaskEmcalJet::UserCreateOutputObjects();

  TLinearBinning binningz(50, 0., 1), multbinning(51, -0.5, 50.5), binningnef(50, 0., 1.), binningptconst(200, 0., 200.), binningptjet(20, 0., 200.);

  const TBinning *jetbinning[4] = {&binningptjet, &binningnef, &multbinning, &multbinning},
                 *chargedbinning[6] = {&binningptjet, &binningnef, &multbinning, &multbinning, &binningptconst, &binningz},
                 *neutralbinning[7] = {&binningptjet, &binningnef, &multbinning, &multbinning, &binningptconst, &binningptconst, &binningz};

  fHistos = new THistManager(Form("histos_%s", GetName()));
  for(auto c : fNamesJetContainers){
    auto contname = dynamic_cast<TObjString *>(c);
    if(!contname) continue;
    fHistos->CreateTHnSparse(Form("hJetCounter%s", contname->String().Data()), Form("jet counter for jets %s", contname->String().Data()), 4, jetbinning);
    fHistos->CreateTHnSparse(Form("hChargedConstituents%s", contname->String().Data()), Form("charged constituents in jets %s", contname->String().Data()), 6, chargedbinning);
    fHistos->CreateTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), Form("neutral constituents in jets %s", contname->String().Data()), 7, neutralbinning);
  }

  for(auto h : *(fHistos->GetListOfHistograms())) fOutput->Add(h);
  PostData(1, fOutput);
}

bool AliAnalysisTaskEmcalJetConstituentQA::Run(){
  AliParticleContainer * tracks = GetTrackContainer(fNameTrackContainer);
  if(!tracks) tracks = GetParticleContainer(fNameTrackContainer);
  const auto clusters = GetClusterContainer(fNameClusterContainer);
  if(fNameTrackContainer.Length() && !tracks){
    AliErrorStream() << "Track container " << fNameTrackContainer << " required but missing ..." << std::endl;
    return kFALSE;
  }
  if(fNameClusterContainer.Length() && !clusters){
    AliErrorStream() << "Cluster container " << fNameClusterContainer << " required but missing ..." << std::endl;
    return kFALSE;
  }

  // Event selection
  AliDebugStream(1) << "Trigger selection string: " << fTriggerSelectionString << ", fired trigger classes: " << fInputEvent->GetFiredTriggerClasses() << std::endl;
  if(fTriggerSelectionString.Contains("INT7")){
    // INT7 trigger
    if(!(fInputHandler->IsEventSelected() & AliVEvent::kINT7)) return false;
  } else if(fTriggerSelectionString.Contains("EJ")){
    auto triggerclass = fTriggerSelectionString(fTriggerSelectionString.Index("EJ"),3); // cleanup trigger string from possible tags
    AliDebugStream(1) << "Inspecting trigger class " << triggerclass << std::endl;
    // EMCAL JET trigger
    if(!fMCEvent){ // Running on Data
      if(!(fInputHandler->IsEventSelected() & AliVEvent::kEMCEJE)) return false;
      if(!fInputEvent->GetFiredTriggerClasses().Contains(triggerclass)) return false;
    }

    if(fUseTriggerSelection) {
      auto triggerdecisions = dynamic_cast<PWG::EMCAL::AliEmcalTriggerDecisionContainer *>(fInputEvent->FindListObject(fNameTriggerDecisionContainer.Data()));
      if(!triggerdecisions) {
        AliErrorStream() << "No offline trigger selection available" << std::endl;
        return false;
      }
      else if(!triggerdecisions->IsEventSelected(triggerclass.Data())) return false;
    }
  } else return false;

  AliDebugStream(1) << "Event is selected" << std::endl;

  for(auto jc : fNamesJetContainers){
    auto contname = dynamic_cast<TObjString *>(jc);
    if(!contname) {
      AliErrorStream() << "Non-string object in the list of jet container names" << std::endl;
      continue;
    }
    const auto jetcont = GetJetContainer(contname->String().Data());
    if(!jetcont){
      AliErrorStream() << "Jet container with name " << contname->String() << " not found in the list of jet containers" << std::endl;
      continue;
    }
    AliDebugStream(2) << "Reading " << jetcont->GetArray()->GetName() << std::endl;

    for(auto jet : jetcont->accepted()){
      AliDebugStream(3) << "Next accepted jet, found " << jet->GetNumberOfTracks() << " tracks and " << jet->GetNumberOfClusters() << " clusters." << std::endl;
      Double_t pointjet[4] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters())},
               pointcharged[6] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters()), -1., 1.},
               pointneutral[7] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters()), -1., 1., -1.};
      fHistos->FillTHnSparse(Form("hJetCounter%s", contname->String().Data()), pointjet);
      if(tracks){
        for(decltype(jet->GetNumberOfTracks()) itrk = 0; itrk < jet->GetNumberOfTracks(); itrk++){
          const auto trk = jet->TrackAt(itrk, tracks->GetArray());
          if(!trk) continue;
          if(trk->Charge()){
            pointcharged[4] = std::abs(trk->Pt());
            pointcharged[5] = std::abs(jet->GetZ(trk));
            fHistos->FillTHnSparse(Form("hChargedConstituents%s", contname->String().Data()), pointcharged);
          } else {
            // particle level jets
            pointneutral[4] = pointneutral[5] = std::abs(trk->E());
            pointneutral[6] = std::abs(jet->GetZ(trk));
            fHistos->FillTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), pointneutral);
          }
        }
      }
      if(clusters){
        for(decltype(jet->GetNumberOfClusters()) icl = 0; icl < jet->GetNumberOfClusters(); icl++){
          const auto clust = jet->ClusterAt(icl, clusters->GetArray());
          if(!clust) continue;
          TLorentzVector ptvec;
          clust->GetMomentum(ptvec, this->fVertex, AliVCluster::kHadCorr);
          pointneutral[4] = std::abs(clust->GetHadCorrEnergy());
          pointneutral[5] = std::abs(clust->GetNonLinCorrEnergy());
          pointneutral[6] = jet->GetZ(ptvec.Px(), ptvec.Py(), ptvec.Pz());
          fHistos->FillTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), pointneutral);
        }
      }
    }
  }

  return kTRUE;
}

AliAnalysisTaskEmcalJetConstituentQA *AliAnalysisTaskEmcalJetConstituentQA::AddTaskEmcalJetConstituentQA(const char *trigger, bool partmode){
  using AnalysisHelpers = EMCalTriggerPtAnalysis::AliEmcalAnalysisFactory;
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr) {
    std::cerr << "[AliAnalysisTaskJetConstituentQA::AddTaskEmcalJetConstituentQA(EE)] No analysis manager provided ..." << std::endl;
    return nullptr;
  }

  std::stringstream taskname;
  taskname << "constituentQA_" << trigger;
  auto task = new AliAnalysisTaskEmcalJetConstituentQA(taskname.str().data());
  task->SetTriggerSelection(trigger);
  mgr->AddTask(task);

  auto inputhandler = mgr->GetInputEventHandler();
  auto isAOD = false;
  if(inputhandler->IsA() == AliAODInputHandler::Class()) isAOD = true;

  TString tracksname, clustername;
  AliParticleContainer *tracks(nullptr);
  AliClusterContainer *clusters(nullptr);
  if(!partmode) {
    tracksname = AnalysisHelpers::TrackContainerNameFactory(isAOD);
    tracks = task->AddTrackContainer(tracksname);
    task->SetNameTrackContainer(tracksname);
    tracks->SetMinPt(0.15);

    clustername = AnalysisHelpers::ClusterContainerNameFactory(isAOD);
    clusters = task->AddClusterContainer(clustername);
    task->SetNameClusterContainer(clustername);
    clusters->SetDefaultClusterEnergy(AliVCluster::kHadCorr);
    clusters->SetClusHadCorrEnergyCut(0.3);
  } else {
    tracksname = "mcparticles";
    tracks = task->AddParticleContainer(tracksname);
    task->SetNameTrackContainer(tracksname);
    tracks->SetMinPt(0.);
  }

  // create jet containers for R02 and R04 jets
  std::array<double, 2> jetradii = {{0.2, 0.4}};
  for(auto r : jetradii) {
    std::stringstream contname;
    contname << "fulljets_R" << std::setw(2) << std::setfill('0') << int(r*10.);
    auto jcont = task->AddJetContainer(AliJetContainer::kFullJet, AliJetContainer::antikt_algorithm, AliJetContainer::E_scheme, r, AliJetContainer::kEMCALfid, tracks, clusters, "Jet");
    jcont->SetName(contname.str().data());
    task->AddNameJetContainer(contname.str().data());
    jcont->SetMinPt(20.);
  }

  std::stringstream contname, outfilename;
  contname << "JetConstituentQA_" << trigger;
  outfilename << mgr->GetCommonFileName() << ":JetConstituentQA_" << trigger;
  if(partmode) {
    contname << "_part";
    outfilename << "_part";
  }
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, mgr->CreateContainer(contname.str().data(), AliEmcalList::Class(), AliAnalysisManager::kOutputContainer, outfilename.str().data()));

  return task;
}
<commit_msg>[Histo] Monitor cluster constituents with high z<commit_after>/************************************************************************************
 * Copyright (C) 2017, Copyright Holders of the ALICE Collaboration                 *
 * 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 the <organization> 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 ALICE COLLABORATION 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.                     *
 ************************************************************************************/
#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <THistManager.h>
#include <TLinearBinning.h>
#include <TLorentzVector.h>
#include <TVector3.h>

#include "AliAnalysisManager.h"
#include "AliAnalysisTaskEmcalJetConstituentQA.h"
#include "AliAODInputHandler.h"
#include "AliClusterContainer.h"
#include "AliEmcalAnalysisFactory.h"
#include "AliEmcalTriggerDecisionContainer.h"
#include "AliEmcalJet.h"
#include "AliInputEventHandler.h"
#include "AliJetContainer.h"
#include "AliLog.h"
#include "AliTrackContainer.h"
#include "AliVCluster.h"
#include "AliVEvent.h"
#include "AliVTrack.h"

/// \cond CLASSIMP
ClassImp(EmcalTriggerJets::AliAnalysisTaskEmcalJetConstituentQA);
/// \endcond

using namespace EmcalTriggerJets;

AliAnalysisTaskEmcalJetConstituentQA::AliAnalysisTaskEmcalJetConstituentQA():
  AliAnalysisTaskEmcalJet(),
  fHistos(nullptr),
  fNameTrackContainer(""),
  fNameClusterContainer(""),
  fTriggerSelectionString(""),
  fUseTriggerSelection(kFALSE),
  fNameTriggerDecisionContainer("EmcalTriggerDecision")
{
  this->SetUseAliAnaUtils(true);
}

AliAnalysisTaskEmcalJetConstituentQA::AliAnalysisTaskEmcalJetConstituentQA(const char *name):
  AliAnalysisTaskEmcalJet(name, true),
  fHistos(nullptr),
  fNameTrackContainer(""),
  fNameClusterContainer(""),
  fTriggerSelectionString(""),
  fUseTriggerSelection(kFALSE),
  fNameTriggerDecisionContainer("EmcalTriggerDecision")
{
  this->SetUseAliAnaUtils(true);
}

AliAnalysisTaskEmcalJetConstituentQA::~AliAnalysisTaskEmcalJetConstituentQA(){
  if(fHistos) delete fHistos;
}

void AliAnalysisTaskEmcalJetConstituentQA::UserCreateOutputObjects(){
  AliAnalysisTaskEmcalJet::UserCreateOutputObjects();

  TLinearBinning binningz(50, 0., 1), multbinning(51, -0.5, 50.5), binningnef(50, 0., 1.), binningR(50, 0., 0.5), binningptconst(200, 0., 200.), binningptjet(20, 0., 200.),
                 binningNCell(101, -0.5, 100.5), binningFracCellLeading(100, 0., 1.), binningM02(100, 0., 1.);

  const TBinning *jetbinning[4] = {&binningptjet, &binningnef, &multbinning, &multbinning},
                 *chargedbinning[7] = {&binningptjet, &binningnef, &multbinning, &multbinning, &binningptconst, &binningz, &binningR},
                 *neutralbinning[8] = {&binningptjet, &binningnef, &multbinning, &multbinning, &binningptconst, &binningptconst, &binningz, &binningR},
                 *binningHighZClusters[7] = {&binningptjet, &binningnef, &binningptconst, &binningz, &binningNCell, &binningFracCellLeading, &binningM02};

  fHistos = new THistManager(Form("histos_%s", GetName()));
  for(auto c : fNamesJetContainers){
    auto contname = dynamic_cast<TObjString *>(c);
    if(!contname) continue;
    fHistos->CreateTHnSparse(Form("hJetCounter%s", contname->String().Data()), Form("jet counter for jets %s", contname->String().Data()), 4, jetbinning);
    fHistos->CreateTHnSparse(Form("hChargedConstituents%s", contname->String().Data()), Form("charged constituents in jets %s", contname->String().Data()), 7, chargedbinning);
    fHistos->CreateTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), Form("neutral constituents in jets %s", contname->String().Data()), 8, neutralbinning);
    fHistos->CreateTHnSparse(Form("hHighZClusters"), "Properties of high-z clusters", 7, binningHighZClusters);
  }

  for(auto h : *(fHistos->GetListOfHistograms())) fOutput->Add(h);
  PostData(1, fOutput);
}

bool AliAnalysisTaskEmcalJetConstituentQA::Run(){
  AliParticleContainer * tracks = GetTrackContainer(fNameTrackContainer);
  if(!tracks) tracks = GetParticleContainer(fNameTrackContainer);
  const auto clusters = GetClusterContainer(fNameClusterContainer);
  if(fNameTrackContainer.Length() && !tracks){
    AliErrorStream() << "Track container " << fNameTrackContainer << " required but missing ..." << std::endl;
    return kFALSE;
  }
  if(fNameClusterContainer.Length() && !clusters){
    AliErrorStream() << "Cluster container " << fNameClusterContainer << " required but missing ..." << std::endl;
    return kFALSE;
  }

  // Event selection
  AliDebugStream(1) << "Trigger selection string: " << fTriggerSelectionString << ", fired trigger classes: " << fInputEvent->GetFiredTriggerClasses() << std::endl;
  if(fTriggerSelectionString.Contains("INT7")){
    // INT7 trigger
    if(!(fInputHandler->IsEventSelected() & AliVEvent::kINT7)) return false;
  } else if(fTriggerSelectionString.Contains("EJ")){
    auto triggerclass = fTriggerSelectionString(fTriggerSelectionString.Index("EJ"),3); // cleanup trigger string from possible tags
    AliDebugStream(1) << "Inspecting trigger class " << triggerclass << std::endl;
    // EMCAL JET trigger
    if(!fMCEvent){ // Running on Data
      if(!(fInputHandler->IsEventSelected() & AliVEvent::kEMCEJE)) return false;
      if(!fInputEvent->GetFiredTriggerClasses().Contains(triggerclass)) return false;
    }

    if(fUseTriggerSelection) {
      auto triggerdecisions = dynamic_cast<PWG::EMCAL::AliEmcalTriggerDecisionContainer *>(fInputEvent->FindListObject(fNameTriggerDecisionContainer.Data()));
      if(!triggerdecisions) {
        AliErrorStream() << "No offline trigger selection available" << std::endl;
        return false;
      }
      else if(!triggerdecisions->IsEventSelected(triggerclass.Data())) return false;
    }
  } else return false;

  AliDebugStream(1) << "Event is selected" << std::endl;

  for(auto jc : fNamesJetContainers){
    auto contname = dynamic_cast<TObjString *>(jc);
    if(!contname) {
      AliErrorStream() << "Non-string object in the list of jet container names" << std::endl;
      continue;
    }
    const auto jetcont = GetJetContainer(contname->String().Data());
    if(!jetcont){
      AliErrorStream() << "Jet container with name " << contname->String() << " not found in the list of jet containers" << std::endl;
      continue;
    }
    AliDebugStream(2) << "Reading " << jetcont->GetArray()->GetName() << std::endl;

    for(auto jet : jetcont->accepted()){
      AliDebugStream(3) << "Next accepted jet, found " << jet->GetNumberOfTracks() << " tracks and " << jet->GetNumberOfClusters() << " clusters." << std::endl;
      Double_t pointjet[4] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters())},
               pointcharged[7] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters()), -1., 1., -1.},
               pointneutral[8] = {std::abs(jet->Pt()), jet->NEF(), static_cast<double>(jet->GetNumberOfTracks()), static_cast<double>(jet->GetNumberOfClusters()), -1., 1., -1., -1.},
               pointHighZCluster[7] = {std::abs(jet->Pt()), jet->NEF(), -1., -1., -1., -1., -1.};
      fHistos->FillTHnSparse(Form("hJetCounter%s", contname->String().Data()), pointjet);
      TVector3 jetvec{jet->Px(), jet->Py(), jet->Pz()};
      if(tracks){
        for(decltype(jet->GetNumberOfTracks()) itrk = 0; itrk < jet->GetNumberOfTracks(); itrk++){
          const auto trk = jet->TrackAt(itrk, tracks->GetArray());
          if(!trk) continue;
          if(trk->Charge()){
            pointcharged[4] = std::abs(trk->Pt());
            pointcharged[5] = std::abs(jet->GetZ(trk));
            pointcharged[6] = jet->DeltaR(trk);
            fHistos->FillTHnSparse(Form("hChargedConstituents%s", contname->String().Data()), pointcharged);
          } else {
            // particle level jets
            pointneutral[4] = pointneutral[5] = std::abs(trk->E());
            pointneutral[6] = std::abs(jet->GetZ(trk));
            pointneutral[7] = jet->DeltaR(trk);
            fHistos->FillTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), pointneutral);
          }
        }
      }
      if(clusters){
        for(decltype(jet->GetNumberOfClusters()) icl = 0; icl < jet->GetNumberOfClusters(); icl++){
          const auto clust = jet->ClusterAt(icl, clusters->GetArray());
          if(!clust) continue;
          TLorentzVector ptvec;
          clust->GetMomentum(ptvec, this->fVertex, AliVCluster::kHadCorr);
          pointneutral[4] = std::abs(clust->GetHadCorrEnergy());
          pointneutral[5] = std::abs(clust->GetNonLinCorrEnergy());
          pointneutral[6] = jet->GetZ(ptvec.Px(), ptvec.Py(), ptvec.Pz());
          pointneutral[7] = jetvec.DeltaR(ptvec.Vect());
          fHistos->FillTHnSparse(Form("hNeutralConstituents%s", contname->String().Data()), pointneutral);

          if(pointneutral[6] > 0.95) {
            pointHighZCluster[2] = pointneutral[4];
            pointHighZCluster[3] = pointneutral[6];
            pointHighZCluster[4] = clust->GetNCells();
            pointHighZCluster[5] = *std::max_element(clust->GetCellsAmplitudeFraction(), clust->GetCellsAmplitudeFraction()+clust->GetNCells());
            pointHighZCluster[6] = clust->GetM02();
            fHistos->FillTHnSparse("hHighZClusters", pointHighZCluster);
          }
        }
      }
    }
  }

  return kTRUE;
}

AliAnalysisTaskEmcalJetConstituentQA *AliAnalysisTaskEmcalJetConstituentQA::AddTaskEmcalJetConstituentQA(const char *trigger, bool partmode){
  using AnalysisHelpers = EMCalTriggerPtAnalysis::AliEmcalAnalysisFactory;
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if(!mgr) {
    std::cerr << "[AliAnalysisTaskJetConstituentQA::AddTaskEmcalJetConstituentQA(EE)] No analysis manager provided ..." << std::endl;
    return nullptr;
  }

  std::stringstream taskname;
  taskname << "constituentQA_" << trigger;
  auto task = new AliAnalysisTaskEmcalJetConstituentQA(taskname.str().data());
  task->SetTriggerSelection(trigger);
  mgr->AddTask(task);

  auto inputhandler = mgr->GetInputEventHandler();
  auto isAOD = false;
  if(inputhandler->IsA() == AliAODInputHandler::Class()) isAOD = true;

  TString tracksname, clustername;
  AliParticleContainer *tracks(nullptr);
  AliClusterContainer *clusters(nullptr);
  if(!partmode) {
    tracksname = AnalysisHelpers::TrackContainerNameFactory(isAOD);
    tracks = task->AddTrackContainer(tracksname);
    task->SetNameTrackContainer(tracksname);
    tracks->SetMinPt(0.15);

    clustername = AnalysisHelpers::ClusterContainerNameFactory(isAOD);
    clusters = task->AddClusterContainer(clustername);
    task->SetNameClusterContainer(clustername);
    clusters->SetDefaultClusterEnergy(AliVCluster::kHadCorr);
    clusters->SetClusHadCorrEnergyCut(0.3);
  } else {
    tracksname = "mcparticles";
    tracks = task->AddParticleContainer(tracksname);
    task->SetNameTrackContainer(tracksname);
    tracks->SetMinPt(0.);
  }

  // create jet containers for R02 and R04 jets
  std::array<double, 2> jetradii = {{0.2, 0.4}};
  for(auto r : jetradii) {
    std::stringstream contname;
    contname << "fulljets_R" << std::setw(2) << std::setfill('0') << int(r*10.);
    auto jcont = task->AddJetContainer(AliJetContainer::kFullJet, AliJetContainer::antikt_algorithm, AliJetContainer::E_scheme, r, AliJetContainer::kEMCALfid, tracks, clusters, "Jet");
    jcont->SetName(contname.str().data());
    task->AddNameJetContainer(contname.str().data());
    jcont->SetMinPt(20.);
  }

  std::stringstream contname, outfilename;
  contname << "JetConstituentQA_" << trigger;
  outfilename << mgr->GetCommonFileName() << ":JetConstituentQA_" << trigger;
  if(partmode) {
    contname << "_part";
    outfilename << "_part";
  }
  mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 1, mgr->CreateContainer(contname.str().data(), AliEmcalList::Class(), AliAnalysisManager::kOutputContainer, outfilename.str().data()));

  return task;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <fb/xplat_init.h>
#include <fbjni/fbjni.h>

#include "Binding.h"
#include "EventBeatManager.h"
#include "EventEmitterWrapper.h"
#include "StateWrapperImpl.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
  return facebook::xplat::initialize(vm, [] {
    facebook::react::Binding::registerNatives();
    facebook::react::EventBeatManager::registerNatives();
    facebook::react::EventEmitterWrapper::registerNatives();
    facebook::react::StateWrapperImpl::registerNatives();
    facebook::react::ComponentFactoryDelegate::registerNatives();
  });
}
<commit_msg>Remove fb/xplat_init dependency<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <fbjni/fbjni.h>

#include "Binding.h"
#include "EventBeatManager.h"
#include "EventEmitterWrapper.h"
#include "StateWrapperImpl.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
  return facebook::jni::initialize(vm, [] {
    facebook::react::Binding::registerNatives();
    facebook::react::EventBeatManager::registerNatives();
    facebook::react::EventEmitterWrapper::registerNatives();
    facebook::react::StateWrapperImpl::registerNatives();
    facebook::react::ComponentFactoryDelegate::registerNatives();
  });
}
<|endoftext|>


<commit_before>#include <iostream>     // std::cout
#include <stdlib.h>     // rand()
#include <time.h>       // time()

#include "gtest/gtest.h"

#include "sorting.h"
#include "printarray.h"
#include "verifyarrays.h"

#define quiet

// *********************************************************************
TEST(EfficientSorts, MergeSortRecursive)
{
    const int N = 4;

    double *to_sort_data = new double[N];
    double *sorted_data  = new double[N];

    // Initialize the array with random values between 1 and 100
    // NOTE: rand() is a terrible pseudo-random number generator (PRNG).
    // It is still used here for a simple testing task, but don't use it
    // for anything serious.
    srand(time(NULL));
    for (int i = 0 ; i < N ; i++)
    {
        to_sort_data[i] = rand() % 100 + 1;
    }
    to_sort_data[0] = 6.0;
    to_sort_data[1] = 5.0;
    to_sort_data[2] = 3.0;
    to_sort_data[3] = 1.0;

    memcpy(sorted_data, to_sort_data, N*sizeof(double));

    sorting::efficient::MergeSort(sorted_data, N);

#ifndef quiet
    std::cout << "Arrays" << std::endl;
    std::cout << "Index Original     Sorted " << std::endl;
    for (int i = 0 ; i < N ; i++)
    {
        std::cout << i+1 << "/" << N << "   "
                    << to_sort_data[i] << "        "
                    << sorted_data[i] << std::endl;
    }
#endif // quiet

    for (int i = 1 ; i < N ; i++)
    {
        EXPECT_GE(sorted_data[i], sorted_data[i-1]);
    }

    for (int i = 0 ; i < N ; i++)
    {
        EXPECT_NE(sorted_data[i], 0);
    }
    ASSERT_TRUE(VerifyIfAllNotNaN(sorted_data, N));
    ASSERT_TRUE(VerifyIfOrdered(sorted_data, N));
    ASSERT_TRUE(VerifySortedUnique(to_sort_data, sorted_data, N));

    delete[] to_sort_data;
    delete[] sorted_data;
}
<commit_msg>Rename test since merge sort is not recursive<commit_after>#include <iostream>     // std::cout
#include <stdlib.h>     // rand()
#include <time.h>       // time()

#include "gtest/gtest.h"

#include "sorting.h"
#include "printarray.h"
#include "verifyarrays.h"

#define quiet

// *********************************************************************
TEST(EfficientSorts, MergeSort)
{
    const int N = 4;

    double *to_sort_data = new double[N];
    double *sorted_data  = new double[N];

    // Initialize the array with random values between 1 and 100
    // NOTE: rand() is a terrible pseudo-random number generator (PRNG).
    // It is still used here for a simple testing task, but don't use it
    // for anything serious.
    srand(time(NULL));
    for (int i = 0 ; i < N ; i++)
    {
        to_sort_data[i] = rand() % 100 + 1;
    }
    to_sort_data[0] = 6.0;
    to_sort_data[1] = 5.0;
    to_sort_data[2] = 3.0;
    to_sort_data[3] = 1.0;

    memcpy(sorted_data, to_sort_data, N*sizeof(double));

    sorting::efficient::MergeSort(sorted_data, N);

#ifndef quiet
    std::cout << "Arrays" << std::endl;
    std::cout << "Index Original     Sorted " << std::endl;
    for (int i = 0 ; i < N ; i++)
    {
        std::cout << i+1 << "/" << N << "   "
                    << to_sort_data[i] << "        "
                    << sorted_data[i] << std::endl;
    }
#endif // quiet

    for (int i = 1 ; i < N ; i++)
    {
        EXPECT_GE(sorted_data[i], sorted_data[i-1]);
    }

    for (int i = 0 ; i < N ; i++)
    {
        EXPECT_NE(sorted_data[i], 0);
    }
    ASSERT_TRUE(VerifyIfAllNotNaN(sorted_data, N));
    ASSERT_TRUE(VerifyIfOrdered(sorted_data, N));
    ASSERT_TRUE(VerifySortedUnique(to_sort_data, sorted_data, N));

    delete[] to_sort_data;
    delete[] sorted_data;
}
<|endoftext|>


<commit_before>#include <iostream>     // std::cout
#include <stdlib.h>     // rand()
#include <time.h>       // time()

#include "gtest/gtest.h"

#include "sorting.h"
#include "printarray.h"
#include "verifyarrays.h"
#include "verifysortedarrays.h"

#define quiet

// *********************************************************************
TEST(EfficientSorts, MergeSortMultipleSizes)
{
    const double to_sorts[] = {6.0, 5.0, 3.0, 1.0, 2.4, 4.0, 10.0, 7.0};

    for (int N = 1 ; N < 8 ; N++)
    {
        double *to_sort_data = new double[N];
        double *sorted_data  = new double[N];

        // Initialize the array with random values between 1 and 100
        // NOTE: rand() is a terrible pseudo-random number generator (PRNG).
        // It is still used here for a simple testing task, but don't use it
        // for anything serious.
        srand(time(NULL));
        for (int i = 0 ; i < N ; i++)
        {
            to_sort_data[i] = rand() % 100 + 1;
        }
        for (int i = 0 ; i < N ; i++)
        {
            to_sort_data[i] = to_sorts[i];
        }

        memcpy(sorted_data, to_sort_data, N*sizeof(double));

        SORT_AND_VERIFY(to_sort_data, sorted_data, N, sorting::efficient::MergeSort, false);

        delete[] to_sort_data;
        delete[] sorted_data;
    }
}

// *********************************************************************
TEST(EfficientSorts, MergeSortMultipleSizesRandom)
{
    for (int N = 1 ; N < 100 ; N++)
    {
        double *to_sort_data = new double[N];
        double *sorted_data  = new double[N];

        // Initialize the array with random values between 1 and 100
        // NOTE: rand() is a terrible pseudo-random number generator (PRNG).
        // It is still used here for a simple testing task, but don't use it
        // for anything serious.
        srand(time(NULL));
        for (int i = 0 ; i < N ; i++)
        {
            to_sort_data[i] = rand() % 100 + 1;
        }

        memcpy(sorted_data, to_sort_data, N*sizeof(double));

        SORT_AND_VERIFY(to_sort_data, sorted_data, N, sorting::efficient::MergeSort, false);

        delete[] to_sort_data;
        delete[] sorted_data;
    }
}
<commit_msg>No need to set random values if we set specific values<commit_after>#include <iostream>     // std::cout
#include <stdlib.h>     // rand()
#include <time.h>       // time()

#include "gtest/gtest.h"

#include "sorting.h"
#include "printarray.h"
#include "verifyarrays.h"
#include "verifysortedarrays.h"

#define quiet

// *********************************************************************
TEST(EfficientSorts, MergeSortMultipleSizes)
{
    const double to_sorts[] = {6.0, 5.0, 3.0, 1.0, 2.4, 4.0, 10.0, 7.0};

    for (int N = 1 ; N < 8 ; N++)
    {
        double *to_sort_data = new double[N];
        double *sorted_data  = new double[N];

        for (int i = 0 ; i < N ; i++)
        {
            to_sort_data[i] = to_sorts[i];
        }

        memcpy(sorted_data, to_sort_data, N*sizeof(double));

        SORT_AND_VERIFY(to_sort_data, sorted_data, N, sorting::efficient::MergeSort, false);

        delete[] to_sort_data;
        delete[] sorted_data;
    }
}

// *********************************************************************
TEST(EfficientSorts, MergeSortMultipleSizesRandom)
{
    for (int N = 1 ; N < 100 ; N++)
    {
        double *to_sort_data = new double[N];
        double *sorted_data  = new double[N];

        // Initialize the array with random values between 1 and 100
        // NOTE: rand() is a terrible pseudo-random number generator (PRNG).
        // It is still used here for a simple testing task, but don't use it
        // for anything serious.
        srand(time(NULL));
        for (int i = 0 ; i < N ; i++)
        {
            to_sort_data[i] = rand() % 100 + 1;
        }

        memcpy(sorted_data, to_sort_data, N*sizeof(double));

        SORT_AND_VERIFY(to_sort_data, sorted_data, N, sorting::efficient::MergeSort, false);

        delete[] to_sort_data;
        delete[] sorted_data;
    }
}
<|endoftext|>


<commit_before>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
// This file defines target properties related to datatype size/offset/alignment
// information.  It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"

// Handle the Pass registration stuff necessary to use TargetData's.
namespace {
  // Register the default SparcV9 implementation...
  RegisterPass<TargetData> X("targetdata", "Target Data Layout");
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout Annotation
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
  : Annotation(TD.getStructLayoutAID()) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::ElementTypes::const_iterator
	 TI = ST->getElementTypes().begin(),
	 TE = ST->getElementTypes().end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if necessary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Empty structures have alignment of 1 byte.
  if (StructAlignment == 0) StructAlignment = 1;

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
}

Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
				      void *D) {
  const TargetData &TD = *(const TargetData*)D;
  assert(AID == TD.AID && "Target data annotation ID mismatch!");
  const Type *Ty = cast<Type>((const Value *)T);
  assert(isa<StructType>(Ty) &&
	 "Can only create StructLayout annotation on structs!");
  return new StructLayout(cast<StructType>(Ty), TD);
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
                       bool isLittleEndian, unsigned char PtrSize,
                       unsigned char PtrAl, unsigned char DoubleAl,
                       unsigned char FloatAl, unsigned char LongAl,
                       unsigned char IntAl, unsigned char ShortAl,
                       unsigned char ByteAl)
  : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  // If this assert triggers, a pass "required" TargetData information, but the
  // top level tool did not provide once for it.  We do not want to default
  // construct, or else we might end up using a bad endianness or pointer size!
  //
  assert(!TargetName.empty() &&
         "ERROR: Tool did not specify a target data to use!");

  LittleEndian     = isLittleEndian;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  assert(DoubleAlignment == PtrAl &&
         "Double alignment and pointer alignment agree for now!");
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
}

TargetData::TargetData(const std::string &ToolName, const Module *M)
  : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  LittleEndian     = M->isLittleEndian();
  PointerSize      = M->has32BitPointers() ? 4 : 8;
  PointerAlignment = PointerSize;
  DoubleAlignment  = PointerSize;
  FloatAlignment   = 4;
  LongAlignment    = 8;
  IntAlignment     = 4;
  ShortAlignment   = 2;
  ByteAlignment    = 1;
}

TargetData::~TargetData() {
  AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:
  case Type::BoolTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = (const ArrayType *)Ty;
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    Size *= ATy->getNumElements();
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  case Type::TypeTyID:
  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
				      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
    if (Idx[CurIDX]->getType() == Type::LongTy) {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
      Result += arrayIdx * (int64_t)getTypeSize(Ty);
    } else {
      const StructType *STy = cast<StructType>(Ty);
      assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementTypes()[FieldNo];
    }
  }

  return Result;
}
<commit_msg>Add support for 'any' pointer size and endianness<commit_after>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
// This file defines target properties related to datatype size/offset/alignment
// information.  It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"

// Handle the Pass registration stuff necessary to use TargetData's.
namespace {
  // Register the default SparcV9 implementation...
  RegisterPass<TargetData> X("targetdata", "Target Data Layout");
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout Annotation
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
  : Annotation(TD.getStructLayoutAID()) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::ElementTypes::const_iterator
	 TI = ST->getElementTypes().begin(),
	 TE = ST->getElementTypes().end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if necessary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Empty structures have alignment of 1 byte.
  if (StructAlignment == 0) StructAlignment = 1;

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
}

Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
				      void *D) {
  const TargetData &TD = *(const TargetData*)D;
  assert(AID == TD.AID && "Target data annotation ID mismatch!");
  const Type *Ty = cast<Type>((const Value *)T);
  assert(isa<StructType>(Ty) &&
	 "Can only create StructLayout annotation on structs!");
  return new StructLayout(cast<StructType>(Ty), TD);
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
                       bool isLittleEndian, unsigned char PtrSize,
                       unsigned char PtrAl, unsigned char DoubleAl,
                       unsigned char FloatAl, unsigned char LongAl,
                       unsigned char IntAl, unsigned char ShortAl,
                       unsigned char ByteAl)
  : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  // If this assert triggers, a pass "required" TargetData information, but the
  // top level tool did not provide once for it.  We do not want to default
  // construct, or else we might end up using a bad endianness or pointer size!
  //
  assert(!TargetName.empty() &&
         "ERROR: Tool did not specify a target data to use!");

  LittleEndian     = isLittleEndian;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  assert(DoubleAlignment == PtrAl &&
         "Double alignment and pointer alignment agree for now!");
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
}

TargetData::TargetData(const std::string &ToolName, const Module *M)
  : AID(AnnotationManager::getID("TargetData::" + ToolName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  LittleEndian     = M->getEndianness() != Module::BigEndian;
  PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
  PointerAlignment = PointerSize;
  DoubleAlignment  = PointerSize;
  FloatAlignment   = 4;
  LongAlignment    = 8;
  IntAlignment     = 4;
  ShortAlignment   = 2;
  ByteAlignment    = 1;
}

TargetData::~TargetData() {
  AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:
  case Type::BoolTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = (const ArrayType *)Ty;
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    Size *= ATy->getNumElements();
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  case Type::TypeTyID:
  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
				      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX) {
    if (Idx[CurIDX]->getType() == Type::LongTy) {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      int64_t arrayIdx = cast<ConstantSInt>(Idx[CurIDX])->getValue();
      Result += arrayIdx * (int64_t)getTypeSize(Ty);
    } else {
      const StructType *STy = cast<StructType>(Ty);
      assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementTypes()[FieldNo];
    }
  }

  return Result;
}
<|endoftext|>


<commit_before>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target properties related to datatype size/offset/alignment
// information.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <cstdlib>
#include <sstream>
using namespace llvm;

// Handle the Pass registration stuff necessary to use TargetData's.
namespace {
  // Register the default SparcV9 implementation...
  RegisterPass<TargetData> X("targetdata", "Target Data Layout");
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
                               uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::element_iterator TI = ST->element_begin(),
         TE = ST->element_end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if necessary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Empty structures have alignment of 1 byte.
  if (StructAlignment == 0) StructAlignment = 1;

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
}

/// getElementContainingOffset - Given a valid offset into the structure,
/// return the structure index that contains it.
unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
  std::vector<uint64_t>::const_iterator SI =
    std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
                     Offset);
  assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
  --SI;
  assert(*SI <= Offset && "upper_bound didn't work");
  assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
         (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
         "Upper bound didn't work!");
  return SI-MemberOffsets.begin();
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
                       bool isLittleEndian, unsigned char PtrSize,
                       unsigned char PtrAl, unsigned char DoubleAl,
                       unsigned char FloatAl, unsigned char LongAl,
                       unsigned char IntAl, unsigned char ShortAl,
                       unsigned char ByteAl, unsigned char BoolAl) {

  // If this assert triggers, a pass "required" TargetData information, but the
  // top level tool did not provide one for it.  We do not want to default
  // construct, or else we might end up using a bad endianness or pointer size!
  //
  assert(!TargetName.empty() &&
         "ERROR: Tool did not specify a target data to use!");

  LittleEndian     = isLittleEndian;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
  BoolAlignment    = BoolAl;
}

TargetData::TargetData(const std::string &TargetName,
                       const std::string &TargetDescription) {
  std::string temp = TargetDescription;

  LittleEndian = false;
  PointerSize = 8;
  PointerAlignment   = 8;
  DoubleAlignment = 8;
  FloatAlignment = 4;
  LongAlignment   = 8;
  IntAlignment   = 4;
  ShortAlignment  = 2;
  ByteAlignment  = 1;
  BoolAlignment   = 1;

  while (temp.length() > 0) {
    std::string token = getToken(temp, "-");

    switch(token[0]) {
    case 'E':
      LittleEndian = false;
      break;
    case 'e':
      LittleEndian = true;
      break;
    case 'p':
      PointerSize = atoi(getToken(token,":").c_str()) / 8;
      PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
      break;
    case 'd':
      token = getToken(token,":"); //Ignore the size
      DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
      break;
    case 'f':
      token = getToken(token, ":"); //Ignore the size
      FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'l':
      token = getToken(token, ":"); //Ignore the size
      LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'i':
      token = getToken(token, ":"); //Ignore the size
      IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 's':
      token = getToken(token, ":"); //Ignore the size
      ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'b':
      token = getToken(token, ":"); //Ignore the size
      ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'B':
      token = getToken(token, ":"); //Ignore the size
      BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    default:
      break;
    }
  }
}

TargetData::TargetData(const std::string &ToolName, const Module *M) {
  LittleEndian     = M->getEndianness() != Module::BigEndian;
  PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
  PointerAlignment = PointerSize;
  DoubleAlignment  = PointerSize;
  FloatAlignment   = 4;
  LongAlignment    = PointerSize;
  IntAlignment     = 4;
  ShortAlignment   = 2;
  ByteAlignment    = 1;
  BoolAlignment    = 1;
}

/// Layouts - The lazy cache of structure layout information maintained by
/// TargetData.
///
static std::map<std::pair<const TargetData*,const StructType*>,
                StructLayout> *Layouts = 0;

TargetData::~TargetData() {
  if (Layouts) {
    // Remove any layouts for this TD.
    std::map<std::pair<const TargetData*,
      const StructType*>, StructLayout>::iterator
      I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
    while (I != Layouts->end() && I->first.first == this)
      Layouts->erase(I++);
    if (Layouts->empty()) {
      delete Layouts;
      Layouts = 0;
    }
  }
}

std::string TargetData::getStringRepresentation() const {
  std::stringstream repr;

  if (LittleEndian)
    repr << "e";
  else
    repr << "E";

  repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8);
  repr << "-d:64:" << (DoubleAlignment * 8);
  repr << "-f:32:" << (FloatAlignment * 8);
  repr << "-l:64:" << (LongAlignment * 8);
  repr << "-i:32:" << (IntAlignment * 8);
  repr << "-s:16:" << (ShortAlignment * 8);
  repr << "-b:8:" << (ByteAlignment * 8);
  repr << "-B:8:" << (BoolAlignment * 8);

  return repr.str();
}

const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
  if (Layouts == 0)
    Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
                           StructLayout>();
  std::map<std::pair<const TargetData*,const StructType*>,
                     StructLayout>::iterator
    I = Layouts->lower_bound(std::make_pair(this, Ty));
  if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
    return &I->second;
  else {
    return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
                                              StructLayout(Ty, *this)))->second;
  }
}

/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
/// objects.  If a TargetData object is alive when types are being refined and
/// removed, this method must be called whenever a StructType is removed to
/// avoid a dangling pointer in this cache.
void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
  if (!Layouts) return;  // No cache.

  std::map<std::pair<const TargetData*,const StructType*>,
           StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
  if (I != Layouts->end())
    Layouts->erase(I);
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
                               uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getTypeID()) {
  case Type::BoolTyID:   Size = 1; Alignment = TD->getBoolAlignment(); return;
  case Type::VoidTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = cast<ArrayType>(Ty);
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
    Size = AlignedSize*ATy->getNumElements();
    return;
  }
  case Type::PackedTyID: {
    const PackedType *PTy = cast<PackedType>(Ty);
    getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
    Size = AlignedSize*PTy->getNumElements();
    // FIXME: The alignments of specific packed types are target dependent.
    // For now, just set it to be equal to Size.
    Alignment = Size;
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
  unsigned Align = getTypeAlignment(Ty);
  assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
  return Log2_32(Align);
}

/// getIntPtrType - Return an unsigned integer type that is the same size or
/// greater to the host pointer size.
const Type *TargetData::getIntPtrType() const {
  switch (getPointerSize()) {
  default: assert(0 && "Unknown pointer size!");
  case 2: return Type::UShortTy;
  case 4: return Type::UIntTy;
  case 8: return Type::ULongTy;
  }
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
                                      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  generic_gep_type_iterator<std::vector<Value*>::const_iterator>
    TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
    if (const StructType *STy = dyn_cast<StructType>(*TI)) {
      assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementType(FieldNo);
    } else {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
      Result += arrayIdx * (int64_t)getTypeSize(Ty);
    }
  }

  return Result;
}

<commit_msg>Fix a stupid bug when parsing TargetData strings.<commit_after>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines target properties related to datatype size/offset/alignment
// information.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <cstdlib>
#include <sstream>
using namespace llvm;

// Handle the Pass registration stuff necessary to use TargetData's.
namespace {
  // Register the default SparcV9 implementation...
  RegisterPass<TargetData> X("targetdata", "Target Data Layout");
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
                               uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::element_iterator TI = ST->element_begin(),
         TE = ST->element_end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if necessary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Empty structures have alignment of 1 byte.
  if (StructAlignment == 0) StructAlignment = 1;

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;
}

/// getElementContainingOffset - Given a valid offset into the structure,
/// return the structure index that contains it.
unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
  std::vector<uint64_t>::const_iterator SI =
    std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(),
                     Offset);
  assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
  --SI;
  assert(*SI <= Offset && "upper_bound didn't work");
  assert((SI == MemberOffsets.begin() || *(SI-1) < Offset) &&
         (SI+1 == MemberOffsets.end() || *(SI+1) > Offset) &&
         "Upper bound didn't work!");
  return SI-MemberOffsets.begin();
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
                       bool isLittleEndian, unsigned char PtrSize,
                       unsigned char PtrAl, unsigned char DoubleAl,
                       unsigned char FloatAl, unsigned char LongAl,
                       unsigned char IntAl, unsigned char ShortAl,
                       unsigned char ByteAl, unsigned char BoolAl) {

  // If this assert triggers, a pass "required" TargetData information, but the
  // top level tool did not provide one for it.  We do not want to default
  // construct, or else we might end up using a bad endianness or pointer size!
  //
  assert(!TargetName.empty() &&
         "ERROR: Tool did not specify a target data to use!");

  LittleEndian     = isLittleEndian;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
  BoolAlignment    = BoolAl;
}

TargetData::TargetData(const std::string &TargetName,
                       const std::string &TargetDescription) {
  std::string temp = TargetDescription;

  LittleEndian = false;
  PointerSize = 8;
  PointerAlignment   = 8;
  DoubleAlignment = 8;
  FloatAlignment = 4;
  LongAlignment   = 8;
  IntAlignment   = 4;
  ShortAlignment  = 2;
  ByteAlignment  = 1;
  BoolAlignment   = 1;

  while (temp.length() > 0) {
    std::string token = getToken(temp, "-");

    char signal = getToken(token, ":")[0];

    switch(signal) {
    case 'E':
      LittleEndian = false;
      break;
    case 'e':
      LittleEndian = true;
      break;
    case 'p':
      PointerSize = atoi(getToken(token,":").c_str()) / 8;
      PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
      break;
    case 'd':
      token = getToken(token,":"); //Ignore the size
      DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
      break;
    case 'f':
      token = getToken(token, ":"); //Ignore the size
      FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'l':
      token = getToken(token, ":"); //Ignore the size
      LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'i':
      token = getToken(token, ":"); //Ignore the size
      IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 's':
      token = getToken(token, ":"); //Ignore the size
      ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'b':
      token = getToken(token, ":"); //Ignore the size
      ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    case 'B':
      token = getToken(token, ":"); //Ignore the size
      BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
      break;
    default:
      break;
    }
  }
}

TargetData::TargetData(const std::string &ToolName, const Module *M) {
  LittleEndian     = M->getEndianness() != Module::BigEndian;
  PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
  PointerAlignment = PointerSize;
  DoubleAlignment  = PointerSize;
  FloatAlignment   = 4;
  LongAlignment    = PointerSize;
  IntAlignment     = 4;
  ShortAlignment   = 2;
  ByteAlignment    = 1;
  BoolAlignment    = 1;
}

/// Layouts - The lazy cache of structure layout information maintained by
/// TargetData.
///
static std::map<std::pair<const TargetData*,const StructType*>,
                StructLayout> *Layouts = 0;

TargetData::~TargetData() {
  if (Layouts) {
    // Remove any layouts for this TD.
    std::map<std::pair<const TargetData*,
      const StructType*>, StructLayout>::iterator
      I = Layouts->lower_bound(std::make_pair(this, (const StructType*)0));
    while (I != Layouts->end() && I->first.first == this)
      Layouts->erase(I++);
    if (Layouts->empty()) {
      delete Layouts;
      Layouts = 0;
    }
  }
}

std::string TargetData::getStringRepresentation() const {
  std::stringstream repr;

  if (LittleEndian)
    repr << "e";
  else
    repr << "E";

  repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8);
  repr << "-d:64:" << (DoubleAlignment * 8);
  repr << "-f:32:" << (FloatAlignment * 8);
  repr << "-l:64:" << (LongAlignment * 8);
  repr << "-i:32:" << (IntAlignment * 8);
  repr << "-s:16:" << (ShortAlignment * 8);
  repr << "-b:8:" << (ByteAlignment * 8);
  repr << "-B:8:" << (BoolAlignment * 8);

  return repr.str();
}

const StructLayout *TargetData::getStructLayout(const StructType *Ty) const {
  if (Layouts == 0)
    Layouts = new std::map<std::pair<const TargetData*,const StructType*>,
                           StructLayout>();
  std::map<std::pair<const TargetData*,const StructType*>,
                     StructLayout>::iterator
    I = Layouts->lower_bound(std::make_pair(this, Ty));
  if (I != Layouts->end() && I->first.first == this && I->first.second == Ty)
    return &I->second;
  else {
    return &Layouts->insert(I, std::make_pair(std::make_pair(this, Ty),
                                              StructLayout(Ty, *this)))->second;
  }
}

/// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
/// objects.  If a TargetData object is alive when types are being refined and
/// removed, this method must be called whenever a StructType is removed to
/// avoid a dangling pointer in this cache.
void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
  if (!Layouts) return;  // No cache.

  std::map<std::pair<const TargetData*,const StructType*>,
           StructLayout>::iterator I = Layouts->find(std::make_pair(this, Ty));
  if (I != Layouts->end())
    Layouts->erase(I);
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
                               uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getTypeID()) {
  case Type::BoolTyID:   Size = 1; Alignment = TD->getBoolAlignment(); return;
  case Type::VoidTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = cast<ArrayType>(Ty);
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
    Size = AlignedSize*ATy->getNumElements();
    return;
  }
  case Type::PackedTyID: {
    const PackedType *PTy = cast<PackedType>(Ty);
    getTypeInfo(PTy->getElementType(), TD, Size, Alignment);
    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
    Size = AlignedSize*PTy->getNumElements();
    // FIXME: The alignments of specific packed types are target dependent.
    // For now, just set it to be equal to Size.
    Alignment = Size;
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const {
  unsigned Align = getTypeAlignment(Ty);
  assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
  return Log2_32(Align);
}

/// getIntPtrType - Return an unsigned integer type that is the same size or
/// greater to the host pointer size.
const Type *TargetData::getIntPtrType() const {
  switch (getPointerSize()) {
  default: assert(0 && "Unknown pointer size!");
  case 2: return Type::UShortTy;
  case 4: return Type::UIntTy;
  case 8: return Type::ULongTy;
  }
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
                                      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  generic_gep_type_iterator<std::vector<Value*>::const_iterator>
    TI = gep_type_begin(ptrTy, Idx.begin(), Idx.end());
  for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
    if (const StructType *STy = dyn_cast<StructType>(*TI)) {
      assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementType(FieldNo);
    } else {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
      Result += arrayIdx * (int64_t)getTypeSize(Ty);
    }
  }

  return Result;
}

<|endoftext|>


<commit_before>#include <sstream>
#include <iostream>
#include <cstring>
#include "datafeeder.h"

void DataFeeder::init()
{
    m_pLevel2Api->RegisterSpi(this);
    m_pLevel2Api->RegisterFront(const_cast<char*>(this->front_address.c_str()));
    // 使客户端开始与后台服务建立连接
    m_pLevel2Api->Init();
}

void DataFeeder::OnFrontConnected()
{
	CThostFtdcReqUserLoginField reqUserLogin;
    strcpy(reqUserLogin.BrokerID, this->brokerID.c_str());
    strcpy(reqUserLogin.UserID, this->userID.c_str());
    strcpy(reqUserLogin.Password, this->passwd.c_str());
    m_pLevel2Api->ReqUserLogin(&reqUserLogin, 0);
}

void DataFeeder::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
    std::cout << "OnRspUserLogin:\t" << "ErrorCode=[" << pRspInfo->ErrorID << "], ErrorMsg=[" << pRspInfo->ErrorMsg << "]" << std::endl;
    if (pRspInfo->ErrorID != 0)
        std::cout << "Error: Login Error!" << std::endl;
}

void DataFeeder::subscrib_L2_market_data(std::string stockid)
{
	CThostFtdcSpecificSecurityField query;
	memset(&query, 0, sizeof(query));
	std::string security_id = stockid.substr(2);
	std::string exchange_id = this->ExchangeIDDict[ stockid.substr(0,2) ];
	strcpy(query.SecurityID, security_id.c_str());
	strcpy(query.ExchangeID, exchange_id.c_str());

	m_pLevel2Api->SubscribeLevel2MarketData(&query, 1);
}

void DataFeeder::OnRtnLevel2MarketData(CThostFtdcLevel2MarketDataField *pLevel2MarketData)
{
	std::ostringstream oss;
	CThostFtdcLevel2MarketDataField *p = pLevel2MarketData;
	std::string stockid = this->ExchangeIDDict_Reverse[p->ExchangeID] + p->SecurityID;

	oss << stockid << ',' << p->OpenPx << ',' << p->PreClosePx << ',' << p->LastPx << ',' << p->HighPx << ',' << p->LowPx << ','
		<< p->TotalVolumeTrade << ',' << p->TotalValueTrade << ','
		<< p->BidPx1 << ',' << p->BidOrderQty1 << ',' << p->BidPx2 << ',' << p->BidOrderQty2 << ',' << p->BidPx3 << ',' << p->BidOrderQty3 << ','
		<< p->OfferPx1 << ',' << p->OfferOrderQty1 << ',' << p->OfferPx2 << ',' << p->OfferOrderQty2 << ',' << p->OfferPx3 << ',' << p->OfferOrderQty3 << ','
		<< p->TradingDay << ',' << p->DataTimeStamp;

	stock_datas[stockid] = oss.str();
//	std::cout << stock_datas[stockid] << std::endl;
}

std::string DataFeeder::get_L2_market_data(std::string stockid)
{
	return this->stock_datas[stockid];
}

<commit_msg>Delete datafeeder.cpp<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Rational
{
    int a, b;

    int gcd(int a, int b);
    void simplify();
    bool check(const Rational& f);
public:
    Rational(int a=0, int b=1) : a(a) , b(b) {
        if (b == 0)
            return;
        simplify();
    };

    Rational& operator= (const Rational& f);

    Rational& Add(const Rational& f);
    Rational& Substract(const Rational& f);
    Rational& Multiply(const Rational& f);
    Rational& Divide(const Rational& f);

    bool EqualTo(const Rational& f) const;
    int CompareTo(const Rational& f) const;

    bool IsInteger() const;

    string ToString() const;
};

int Rational::gcd (int a, int b)
{
    int c;
    while (b) {
        c = b;
        b = a % b;
        a = c;
    }
    return a;
}

void Rational::simplify()
{
    int c;
    while ((c = gcd(a, b)) != 1) {
        if (c == 0)
            break;
        a /= c;
        b /= c;
    }
}

bool Rational::check(const Rational& f)
{
    if (b == 0 || f.b == 0) {
        b = 0;
        return true;
    }
    return false;
}

Rational& Rational::operator= (const Rational& f)
{
    if (this != &f) {
        a = f.a;
        b = f.b;
    }
    return *this;
}

Rational& Rational::Add(const Rational& f)
{
    check(f);
    a = a * f.b + b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Substract(const Rational& f)
{
    check(f);
    a = a * f.b - b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Multiply(const Rational& f)
{
    check(f);
    a *= f.a;
    b *= f.b;
    simplify();
    return *this;
}

Rational& Rational::Divide(const Rational& f)
{
    check(f);
    a *= f.b;
    b *= f.a;
    simplify();
    return *this;
}

bool Rational::EqualTo(const Rational& f) const
{
    if (f.a == a && f.b == b)
        return true;
    else
        return false;
}

int Rational::CompareTo(const Rational& f) const
{
    int c = a * f.b;
    int d = b * f.a;

    if (c > d)
        return 1;
    if (c < d)
        return -1;
    return 0;
}

bool Rational::IsInteger() const
{
    if (b == 1)
        return true;
    return false;
}

string Rational::ToString() const
{
    stringstream ss;
    if (b == 0) {
        if (a >= 0)
            return "+NAN";
        if (a < 0)
            return "-NAN";
    } else {
        ss << a << "/" << b;
    }
    return ss.str();
}

const Rational a(1,1);

int main()
{
    Rational q  = Rational(1, 3), w(1, 4);
    Rational s = 4;
//    a.CompareTo(s);
    w = q;

    s.Add(q);
    cout << s.ToString() << endl;

    s.Substract(q);
    cout << s.ToString() << endl;

    s.Multiply(q);
    cout << s.ToString() << endl;

    s.Divide(q);
    cout << s.ToString() << endl;

    s.Add(q).Multiply(w);
    cout << s.ToString() << endl;

    s.EqualTo(w);
    s.CompareTo(w);

    s.IsInteger();

    cout << s.ToString() << endl;
//    cout << q.ToString() << endl;
//    cout << w.ToString() << endl;

    return 0;
}

<commit_msg>chmod -x<commit_after>#include <iostream>
#include <sstream>
#include <string>

using namespace std;

class Rational
{
    int a, b;

    int gcd(int a, int b);
    void simplify();
    bool check(const Rational& f);
public:
    Rational(int a=0, int b=1) : a(a) , b(b) {
        if (b == 0)
            return;
        simplify();
    };

    Rational& operator= (const Rational& f);

    Rational& Add(const Rational& f);
    Rational& Substract(const Rational& f);
    Rational& Multiply(const Rational& f);
    Rational& Divide(const Rational& f);

    bool EqualTo(const Rational& f) const;
    int CompareTo(const Rational& f) const;

    bool IsInteger() const;

    string ToString() const;
};

int Rational::gcd (int a, int b)
{
    int c;
    while (b) {
        c = b;
        b = a % b;
        a = c;
    }
    return a;
}

void Rational::simplify()
{
    int c;
    while ((c = gcd(a, b)) != 1) {
        if (c == 0)
            break;
        a /= c;
        b /= c;
    }
}

bool Rational::check(const Rational& f)
{
    if (b == 0 || f.b == 0) {
        b = 0;
        return true;
    }
    return false;
}

Rational& Rational::operator= (const Rational& f)
{
    if (this != &f) {
        a = f.a;
        b = f.b;
    }
    return *this;
}

Rational& Rational::Add(const Rational& f)
{
    check(f);
    a = a * f.b + b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Substract(const Rational& f)
{
    check(f);
    a = a * f.b - b * f.a;
    b = b * f.b;
    simplify();
    return *this;
}

Rational& Rational::Multiply(const Rational& f)
{
    check(f);
    a *= f.a;
    b *= f.b;
    simplify();
    return *this;
}

Rational& Rational::Divide(const Rational& f)
{
    check(f);
    a *= f.b;
    b *= f.a;
    simplify();
    return *this;
}

bool Rational::EqualTo(const Rational& f) const
{
    if (f.a == a && f.b == b)
        return true;
    else
        return false;
}

int Rational::CompareTo(const Rational& f) const
{
    int c = a * f.b;
    int d = b * f.a;

    if (c > d)
        return 1;
    if (c < d)
        return -1;
    return 0;
}

bool Rational::IsInteger() const
{
    if (b == 1)
        return true;
    return false;
}

string Rational::ToString() const
{
    stringstream ss;
    if (b == 0) {
        if (a >= 0)
            return "+NAN";
        if (a < 0)
            return "-NAN";
    } else {
        ss << a << "/" << b;
    }
    return ss.str();
}

const Rational a(1,1);

int main()
{
    Rational q  = Rational(1, 3), w(1, 4);
    Rational s = 4;
//    a.CompareTo(s);
    w = q;

    s.Add(q);
    cout << s.ToString() << endl;

    s.Substract(q);
    cout << s.ToString() << endl;

    s.Multiply(q);
    cout << s.ToString() << endl;

    s.Divide(q);
    cout << s.ToString() << endl;

    s.Add(q).Multiply(w);
    cout << s.ToString() << endl;

    s.EqualTo(w);
    s.CompareTo(w);

    s.IsInteger();

    cout << s.ToString() << endl;
//    cout << q.ToString() << endl;
//    cout << w.ToString() << endl;

    return 0;
}

<|endoftext|>


<commit_before>/*
    ircprotocol - IRC Protocol

    Copyright (c) 2002      by Nick Betcher <nbetcher@kde.org>

    Kopete    (c) 2002      by the Kopete developers <kopete-devel@kde.org>

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

#include "ircprotocol.h"

#include <qapplication.h>
#include <qcursor.h>
#include <qregexp.h>

#include <kaction.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>

#include "ircadd.h"
#include "ircidentity.h"
#include "ircaddcontactpage.h"
#include "ircpreferences.h"
#include "kopetemetacontact.h"
#include "ircchannelcontact.h"
#include "kopeteidentitymanager.h"
#include "irceditidentitywidget.h"
#include "kirc.h"

K_EXPORT_COMPONENT_FACTORY( kopete_irc, KGenericFactory<IRCProtocol> );

IRCProtocol::IRCProtocol( QObject *parent, const char *name,
	const QStringList & /* args */ )
: KopeteProtocol( parent, name )
{
	m_actionMenu = 0L;
	actionConnect = new KAction ( i18n("Online"), "", 0, this, SLOT(connect()), this, "actionIRCConnect" );
	actionDisconnect = new KAction ( i18n("Offline"), "", 0, this, SLOT(disconnect()), this, "actionIRCDisconnect" );

	kdDebug(14120) << k_funcinfo << endl;
	// Load all ICQ icons from KDE standard dirs

	setStatusIcon( "irc_protocol_offline" );

	new IRCPreferences("irc_protocol", this);

	KConfig *cfg = KGlobal::config();
	cfg->setGroup("IRC");
	identity = new IRCIdentity( cfg->readEntry("Nickname", "KopeteUser") + "@" + cfg->readEntry("Server", "irc.freenode.net") + ":" + cfg->readEntry("Port", "6667"), this);
}

IRCProtocol::~IRCProtocol()
{
	//delete identity;
}

KActionMenu* IRCProtocol::protocolActions()
{
	if (!m_actionMenu)
	{
		m_actionMenu = new KActionMenu( "IRC", this );
		m_actionMenu->popupMenu()->insertTitle(SmallIcon( "irc_protocol_small" ), i18n( "IRC" ) );
		m_actionMenu->insert(actionConnect);
		m_actionMenu->insert(actionDisconnect);
	}
	return m_actionMenu;
}

void IRCProtocol::connect()
{
	identity->connect();
}

void IRCProtocol::disconnect()
{
	identity->disconnect();
}

const QString IRCProtocol::protocolIcon()
{
	return "irc_protocol_small";
}

void IRCProtocol::init()
{

}

AddContactPage *IRCProtocol::createAddContactWidget(QWidget *parent)
{
	return new IRCAddContactPage(this,parent);
}

EditIdentityWidget *IRCProtocol::createEditIdentityWidget(KopeteIdentity *identity, QWidget *parent)
{
	return new IRCEditIdentityWidget(this, static_cast<IRCIdentity*>(identity),parent);
}

KopeteIdentity *IRCProtocol::createNewIdentity(const QString &identityId)
{
	if( !mIdentityMap.contains( identityId ) )
	{
		IRCIdentity *id = new IRCIdentity( identityId, this );
		mIdentityMap[ identityId ] = id;
		KopeteIdentityManager::manager()->registerIdentity( id );
	}

	return mIdentityMap[ identityId ];
}

void IRCProtocol::deserializeContact( KopeteMetaContact *metaContact, const QMap<QString, QString> &serializedData,
	const QMap<QString, QString> & /* addressBookData */ )
{
	QString contactId = serializedData[ "contactId" ];
	if( !contacts()[ contactId ] )
	{
		QString displayName = serializedData[ "displayName" ];
		if( displayName.isEmpty() )
			displayName = contactId;

		identity->addContact( contactId, displayName, metaContact );
	}
}

#include "ircprotocol.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>We don't need to do this it is taken care of<commit_after>/*
    ircprotocol - IRC Protocol

    Copyright (c) 2002      by Nick Betcher <nbetcher@kde.org>

    Kopete    (c) 2002      by the Kopete developers <kopete-devel@kde.org>

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

#include "ircprotocol.h"

#include <qapplication.h>
#include <qcursor.h>
#include <qregexp.h>

#include <kaction.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kgenericfactory.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>

#include "ircadd.h"
#include "ircidentity.h"
#include "ircaddcontactpage.h"
#include "ircpreferences.h"
#include "kopetemetacontact.h"
#include "ircchannelcontact.h"
#include "kopeteidentitymanager.h"
#include "irceditidentitywidget.h"
#include "kirc.h"

K_EXPORT_COMPONENT_FACTORY( kopete_irc, KGenericFactory<IRCProtocol> );

IRCProtocol::IRCProtocol( QObject *parent, const char *name,
	const QStringList & /* args */ )
: KopeteProtocol( parent, name )
{
	m_actionMenu = 0L;
	actionConnect = new KAction ( i18n("Online"), "", 0, this, SLOT(connect()), this, "actionIRCConnect" );
	actionDisconnect = new KAction ( i18n("Offline"), "", 0, this, SLOT(disconnect()), this, "actionIRCDisconnect" );

	kdDebug(14120) << k_funcinfo << endl;
	// Load all ICQ icons from KDE standard dirs

	setStatusIcon( "irc_protocol_offline" );

	new IRCPreferences("irc_protocol", this);

	KConfig *cfg = KGlobal::config();
	cfg->setGroup("IRC");
	identity = new IRCIdentity( cfg->readEntry("Nickname", "KopeteUser") + "@" + cfg->readEntry("Server", "irc.freenode.net") + ":" + cfg->readEntry("Port", "6667"), this);
}

IRCProtocol::~IRCProtocol()
{
	//delete identity;
}

KActionMenu* IRCProtocol::protocolActions()
{
	if (!m_actionMenu)
	{
		m_actionMenu = new KActionMenu( "IRC", this );
		m_actionMenu->popupMenu()->insertTitle(SmallIcon( "irc_protocol_small" ), i18n( "IRC" ) );
		m_actionMenu->insert(actionConnect);
		m_actionMenu->insert(actionDisconnect);
	}
	return m_actionMenu;
}

void IRCProtocol::connect()
{
	identity->connect();
}

void IRCProtocol::disconnect()
{
	identity->disconnect();
}

const QString IRCProtocol::protocolIcon()
{
	return "irc_protocol_small";
}

void IRCProtocol::init()
{

}

AddContactPage *IRCProtocol::createAddContactWidget(QWidget *parent)
{
	return new IRCAddContactPage(this,parent);
}

EditIdentityWidget *IRCProtocol::createEditIdentityWidget(KopeteIdentity *identity, QWidget *parent)
{
	return new IRCEditIdentityWidget(this, static_cast<IRCIdentity*>(identity),parent);
}

KopeteIdentity *IRCProtocol::createNewIdentity(const QString &identityId)
{
	if( !mIdentityMap.contains( identityId ) )
	{
		IRCIdentity *id = new IRCIdentity( identityId, this );
		mIdentityMap[ identityId ] = id;
	}

	return mIdentityMap[ identityId ];
}

void IRCProtocol::deserializeContact( KopeteMetaContact *metaContact, const QMap<QString, QString> &serializedData,
	const QMap<QString, QString> & /* addressBookData */ )
{
	QString contactId = serializedData[ "contactId" ];
	if( !contacts()[ contactId ] )
	{
		QString displayName = serializedData[ "displayName" ];
		if( displayName.isEmpty() )
			displayName = contactId;

		identity->addContact( contactId, displayName, metaContact );
	}
}

#include "ircprotocol.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>