<commit_before>// $Id$

AliAnalysisTaskSE* AddTaskJetPreparation(
  const char*    dataType           = "ESD",
  const char*    periodstr          = "LHC11h",
  const char*    usedTracks         = "PicoTracks",
  const char*    usedMCParticles    = "MCParticlesSelected",
  const char*    usedClusters       = "CaloClusters",
  const char*    outClusName        = "CaloClustersCorr",
  const Double_t hadcorr            = 2.0,
  const Double_t Eexcl              = 0.00,
  const Double_t phiMatch           = 0.03,
  const Double_t etaMatch           = 0.015,
  const Double_t minPtEt            = 0.15,
  const UInt_t   pSel               = AliVEvent::kAny,
  const Bool_t   trackclus          = kTRUE,
  const Bool_t   doHistos           = kFALSE,
  const Bool_t   makePicoTracks     = kTRUE,
  const Bool_t   isEmcalTrain       = kFALSE
)
{
  // Add task macros for all jet related helper tasks.

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
  {
    Error("AddTaskJetPreparation","No analysis manager found.");
    return 0;
  }

  // Set trackcuts according to period. Every period used should be definied here
  TString period(periodstr);
  TString clusterColName(usedClusters);
  TString particleColName(usedMCParticles);
  TString dType(dataType);

  if ((dType == "AOD") && (clusterColName == "CaloClusters"))
    clusterColName = "caloClusters";

  if (makePicoTracks && (dType == "ESD" || dType == "AOD") )
  {
    TString inputTracks = "tracks";

    if (dType == "ESD")
    {
      inputTracks = "HybridTracks";
      TString trackCuts(Form("Hybrid_%s", period.Data()));
      // Hybrid tracks maker for ESD
      gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalEsdTpcTrack.C");
      AliEmcalEsdTpcTrackTask *hybTask = AddTaskEmcalEsdTpcTrack(inputTracks.Data(),trackCuts.Data());
      hybTask->SelectCollisionCandidates(pSel);

      // Track propagator to extend track to the TPC boundaries
      gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalTrackPropagator.C");
      AliEmcalTrackPropagatorTask *propTask = AddTaskEmcalTrackPropagator(inputTracks.Data());
      propTask->SelectCollisionCandidates(pSel);
    }
    // Produce PicoTracks
    gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalPicoTrackMaker.C");
    AliEmcalPicoTrackMaker *pTrackTask = AddTaskEmcalPicoTrackMaker("PicoTracks", inputTracks.Data(), period.Data());
    pTrackTask->SelectCollisionCandidates(pSel);
  }

  // Produce particles used for hadronic correction
  gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalParticleMaker.C");
  AliEmcalParticleMaker *emcalParts = AddTaskEmcalParticleMaker(usedTracks,clusterColName.Data(),"EmcalTracks","EmcalClusters");
  emcalParts->SelectCollisionCandidates(pSel);

  // Relate tracks and clusters
  gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalClusTrackMatcher.C");
  AliEmcalClusTrackMatcherTask *emcalClus =  AddTaskEmcalClusTrackMatcher("EmcalTracks","EmcalClusters",0.1);
  emcalClus->SelectCollisionCandidates(pSel);
  if (isEmcalTrain)
    RequestMemory(emcalClus,100*1024);
  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/EMCALJetTasks/macros/AddTaskHadCorr.C");
  AliHadCorrTask *hCorr = AddTaskHadCorr("EmcalTracks","EmcalClusters",outClusName,hadcorr,minPtEt,phiMatch,etaMatch,Eexcl,trackclus,doHistos);
  hCorr->SelectCollisionCandidates(pSel);
  if (isEmcalTrain) {
    if (doHistos)
      RequestMemory(hCorr,250*1024);
  }

  // Produce MC particles
  if(particleColName != "")
  {
    gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskMCTrackSelector.C");
    AliEmcalMCTrackSelector *mcPartTask = AddTaskMCTrackSelector(particleColName.Data(), kFALSE, kFALSE);
    mcPartTask->SelectCollisionCandidates(pSel);
  }

  // Return one task that represents the jet preparation on LEGO trains
  return emcalParts;
}
<commit_msg>more mem (Megan)<commit_after>// $Id$

AliAnalysisTaskSE* AddTaskJetPreparation(
  const char*    dataType           = "ESD",
  const char*    periodstr          = "LHC11h",
  const char*    usedTracks         = "PicoTracks",
  const char*    usedMCParticles    = "MCParticlesSelected",
  const char*    usedClusters       = "CaloClusters",
  const char*    outClusName        = "CaloClustersCorr",
  const Double_t hadcorr            = 2.0,
  const Double_t Eexcl              = 0.00,
  const Double_t phiMatch           = 0.03,
  const Double_t etaMatch           = 0.015,
  const Double_t minPtEt            = 0.15,
  const UInt_t   pSel               = AliVEvent::kAny,
  const Bool_t   trackclus          = kTRUE,
  const Bool_t   doHistos           = kFALSE,
  const Bool_t   makePicoTracks     = kTRUE,
  const Bool_t   isEmcalTrain       = kFALSE
)
{
  // Add task macros for all jet related helper tasks.

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
  {
    Error("AddTaskJetPreparation","No analysis manager found.");
    return 0;
  }

  // Set trackcuts according to period. Every period used should be definied here
  TString period(periodstr);
  TString clusterColName(usedClusters);
  TString particleColName(usedMCParticles);
  TString dType(dataType);

  if ((dType == "AOD") && (clusterColName == "CaloClusters"))
    clusterColName = "caloClusters";

  if (makePicoTracks && (dType == "ESD" || dType == "AOD") )
  {
    TString inputTracks = "tracks";

    if (dType == "ESD")
    {
      inputTracks = "HybridTracks";
      TString trackCuts(Form("Hybrid_%s", period.Data()));
      // Hybrid tracks maker for ESD
      gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalEsdTpcTrack.C");
      AliEmcalEsdTpcTrackTask *hybTask = AddTaskEmcalEsdTpcTrack(inputTracks.Data(),trackCuts.Data());
      hybTask->SelectCollisionCandidates(pSel);

      // Track propagator to extend track to the TPC boundaries
      gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalTrackPropagator.C");
      AliEmcalTrackPropagatorTask *propTask = AddTaskEmcalTrackPropagator(inputTracks.Data());
      propTask->SelectCollisionCandidates(pSel);
    }
    // Produce PicoTracks
    gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalPicoTrackMaker.C");
    AliEmcalPicoTrackMaker *pTrackTask = AddTaskEmcalPicoTrackMaker("PicoTracks", inputTracks.Data(), period.Data());
    pTrackTask->SelectCollisionCandidates(pSel);
  }

  // Produce particles used for hadronic correction
  gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalParticleMaker.C");
  AliEmcalParticleMaker *emcalParts = AddTaskEmcalParticleMaker(usedTracks,clusterColName.Data(),"EmcalTracks","EmcalClusters");
  emcalParts->SelectCollisionCandidates(pSel);

  // Relate tracks and clusters
  gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskEmcalClusTrackMatcher.C");
  AliEmcalClusTrackMatcherTask *emcalClus =  AddTaskEmcalClusTrackMatcher("EmcalTracks","EmcalClusters",0.1);
  emcalClus->SelectCollisionCandidates(pSel);
  if (isEmcalTrain)
    RequestMemory(emcalClus,100*1024);
  gROOT->LoadMacro("$ALICE_ROOT/PWGJE/EMCALJetTasks/macros/AddTaskHadCorr.C");
  AliHadCorrTask *hCorr = AddTaskHadCorr("EmcalTracks","EmcalClusters",outClusName,hadcorr,minPtEt,phiMatch,etaMatch,Eexcl,trackclus,doHistos);
  hCorr->SelectCollisionCandidates(pSel);
  if (isEmcalTrain) {
    if (doHistos)
      RequestMemory(hCorr,500*1024);
  }

  // Produce MC particles
  if(particleColName != "")
  {
    gROOT->LoadMacro("$ALICE_ROOT/PWG/EMCAL/macros/AddTaskMCTrackSelector.C");
    AliEmcalMCTrackSelector *mcPartTask = AddTaskMCTrackSelector(particleColName.Data(), kFALSE, kFALSE);
    mcPartTask->SelectCollisionCandidates(pSel);
  }

  // Return one task that represents the jet preparation on LEGO trains
  return emcalParts;
}
<|endoftext|>


<commit_before>#include<iostream>
#include <cstdlib>
#include <cstdio>
#include <array>
#include <utility>

#include <boost/test/unit_test.hpp>

using RawField = std::array<std::array<char, 32>, 32>;
using RawStone = std::array<std::array<char, 8>, 8>;

constexpr int ROTATE_90 = 1,
          ROTATE_180 = 2,
          ROTATE_270 = 4,
          REVERSED = 8;

class Field {
  private:
    int score = 0;
  public:
    RawField raw = {};
    int Score() const {
      return score;
    }
    bool TryPutStone(int stone_number, int base_x, int base_y, int manipulate_info);
};

class Stone {
  public:
    RawStone raw = {};
};

Field max_score_field;
Stone reserved_stones[256];
int number_of_stone = 0;

void Parse(Field* f) {
  for (int i = 0; i < 32; ++i) {
    fread(f->raw[i].data(), sizeof(char[32]), 1, stdin);
    getchar(); //CR
    getchar(); //LF
  }
  scanf("\n%d\n", &number_of_stone);
  for (int i = 0; i < number_of_stone; ++i) {
    for (int j = 0; j < 8; ++j) {
      fread(reserved_stones[i].raw[j].data(), sizeof(char[8]), 1, stdin);
      getchar(); //CR
      getchar(); //LF
    }
    getchar(); //CR
    getchar(); //LF
  }

}
void DumpField(const Field& f) {
  for (int i = 0; i < 32; ++i) {
    for (int j = 0; j < 32; ++j) {
      putc(f.raw[i][j], stdout);
    }
    puts("");
  }
}

void Solve(Field f, const int look_nth_stone) {
  if (look_nth_stone > number_of_stone) {
    if (f.Score() > max_score_field.Score()) {
      max_score_field = f;
    }
      return;
  }

  Solve(f, look_nth_stone + 1);
  Field backup = f;

  for (int x = -7; x < 32; ++x) {
    for (int y = -7; y < 32; ++y) {
      if (f.TryPutStone(look_nth_stone, x, y, 0)) {
        Solve(f, look_nth_stone+1);
        f = backup;
      }
    }
  }
}

void DumpStones() {
  for (int i = 0; i < number_of_stone; ++i) {
    for (int j = 0; j < 8; ++j) {
      for (int k = 0; k < 8; ++k) {
        putc(reserved_stones[i].raw[j][k], stdout);
      }
      puts("");
    }
    puts("");
  }
}
int main() {
  Field reserved_field;
  // get_problemfile();
  Parse(&reserved_field);
  Solve(reserved_field, 0);
  DumpField(max_score_field);
  // solve();
  // submit_answer();
  return 0;
}

RawStone StoneRotate(RawStone& stone, int manipulate_info) {
  RawStone rotated;
  switch (manipulate_info) {
    case ROTATE_90:
      for (int y = 0; y < 8; ++y) {
        for (int x = 0; x < 8; ++x){
          rotated[y][x] = stone[x][7-y];
        }
      }
      return rotated;
    case ROTATE_180:
      return StoneRotate(std::move(StoneRotate(stone, ROTATE_90)), ROTATE_90);
    case ROTATE_270:
      return StoneRotate(std::move(StoneRotate(stone, ROTATE_180)), ROTATE_90);
    case REVERSED:
      for (int y = 0; y < 8; ++y) {
        for (int x = 0; x < 8; ++x) {
          rotated[y][x] = stone[y][7-x];
        }
      }
      return rotated;
    case REVERSED | ROTATE_90:
      return StoneRotate(std::move(StoneRotate(stone, ROTATE_90), REVERSED);
    case REVERSED | ROTATE_180:
      return StoneRotate(std::move(StoneRotate(stone, ROTATE_180), REVERSED);
    case REVERSED | ROTATE_270:
      return StoneRotate(std::move(StoneRotate(stone, ROTATE_270), REVERSED);
  }
  return stone;
}

bool Field::TryPutStone(int stone_number, int base_x, int base_y, int manipulate_info) {
  // 書き換えるので、もどせるようにしておく
  RawField backup_field = raw;
  int backup_score = score;
  RawStone& sraw = reserved_stones[stone_number].raw;
  for (int x = 0; x < 8; ++x) {
    for (int y = 0; y < 8; ++y) {
      if (y + base_y < 0 || y + base_y >= 32 || x + base_x < 0 || x + base_x >= 32) {
        continue;
      }
      if (sraw[y][x] == '1') {
        if(backup_score != 0 && raw[y + base_y][x + base_x] == '1') { //score = 1、つまり最初に置く石なら判定しない
          raw = backup_field;
          score = backup_score;
          return false;
        }
        raw[y + base_y][x + base_x] = '1';
        ++score;
      }
    }
  }
  return true;
}

//
BOOST_AUTO_TEST_CASE(StoneRotate_Test) {
  RawStone rawstone = {
    "11111111",
    "00000000",
    "00000000",
    "00000000",
    "00000000",
    "00000000",
    "00000000",
    "00000000"
  };
  RawStone rotated_90 = {
    "00000001",
    "00000001",
    "00000001",
    "00000001",
    "00000001",
    "00000001",
    "00000001",
    "00000001"
  };
  RawStone rotated_by_f = std::move(StoneRotate(rawstone));

  BOOST_CHECK_EQUAL(rotated_90, rotated_by_f);
}
<commit_msg>modified rotate algorithm<commit_after>#include<iostream>
#include <cstdlib>
#include <cstdio>
#include <array>
#include <utility>
#include <cassert>

using RawField = std::array<std::array<char, 32>, 32>;
using RawStone = std::array<std::array<char, 8>, 8>;

constexpr int ROTATE_90 = 1,
          ROTATE_180 = 2,
          ROTATE_270 = 4,
          REVERSE = 8;

class Field {
  private:
    int score = 0;
  public:
    RawField raw = {};
    int Score() const {
      return score;
    }
    bool TryPutStone(int stone_number, int base_x, int base_y, int manipulate_info);
};

class Stone {
  public:
    RawStone raw = {};
};

Field max_score_field;
Stone reserved_stones[256];
int number_of_stone = 0;

void Parse(Field* f) {
  for (int i = 0; i < 32; ++i) {
    fread(f->raw[i].data(), sizeof(char[32]), 1, stdin);
    getchar(); //CR
    getchar(); //LF
  }
  scanf("\n%d\n", &number_of_stone);
  for (int i = 0; i < number_of_stone; ++i) {
    for (int j = 0; j < 8; ++j) {
      fread(reserved_stones[i].raw[j].data(), sizeof(char[8]), 1, stdin);
      getchar(); //CR
      getchar(); //LF
    }
    getchar(); //CR
    getchar(); //LF
  }

}
void DumpField(const Field& f) {
  for (int i = 0; i < 32; ++i) {
    for (int j = 0; j < 32; ++j) {
      putc(f.raw[i][j], stdout);
    }
    puts("");
  }
}

void Solve(Field f, const int look_nth_stone) {
  if (look_nth_stone > number_of_stone) {
    if (f.Score() > max_score_field.Score()) {
      max_score_field = f;
    }
      return;
  }

  Solve(f, look_nth_stone + 1);
  Field backup = f;

  for (int x = -7; x < 32; ++x) {
    for (int y = -7; y < 32; ++y) {
      if (f.TryPutStone(look_nth_stone, x, y, 0)) {
        Solve(f, look_nth_stone+1);
        f = backup;
      }
    }
  }
}

void DumpStones() {
  for (int i = 0; i < number_of_stone; ++i) {
    for (int j = 0; j < 8; ++j) {
      for (int k = 0; k < 8; ++k) {
        putc(reserved_stones[i].raw[j][k], stdout);
      }
      puts("");
    }
    puts("");
  }
}

void test();
int main() {
  test();
  Field reserved_field;
  // get_problemfile();
  Parse(&reserved_field);
  Solve(reserved_field, 0);
  DumpField(max_score_field);
  // solve();
  // submit_answer();
  return 0;
}

RawStone StoneRotate(RawStone stone, int manipulate_info) {
  RawStone rotated;
  switch (manipulate_info) {
    case ROTATE_90:
      for (int a = 0; a < 8; ++a) {
        for (int b = 0; b < 8; ++b) {
          rotated[b][7-a] = stone[a][b];
        }
      }
      return rotated;
    case ROTATE_180:
      return StoneRotate(std::move(StoneRotate(std::move(stone), ROTATE_90)), ROTATE_90);
    case ROTATE_270:
      return StoneRotate(std::move(StoneRotate(std::move(stone), ROTATE_180)), ROTATE_90);
    case REVERSE:
      for (int y = 0; y < 8; ++y) {
        for (int x = 0; x < 8; ++x) {
          rotated[y][x] = stone[y][7-x];
        }
      }
      return rotated;
    case REVERSE | ROTATE_90:
      return StoneRotate(std::move(StoneRotate(std::move(stone), ROTATE_90)), REVERSE);
    case REVERSE | ROTATE_180:
      return StoneRotate(std::move(StoneRotate(std::move(stone), ROTATE_180)), REVERSE);
    case REVERSE | ROTATE_270:
      return StoneRotate(std::move(StoneRotate(std::move(stone), ROTATE_270)), REVERSE);
  }
  return stone;
}

bool Field::TryPutStone(int stone_number, int base_x, int base_y, int manipulate_info) {
  // 書き換えるので、もどせるようにしておく
  RawField backup_field = raw;
  int backup_score = score;
  RawStone& sraw = reserved_stones[stone_number].raw;
  for (int x = 0; x < 8; ++x) {
    for (int y = 0; y < 8; ++y) {
      if (y + base_y < 0 || y + base_y >= 32 || x + base_x < 0 || x + base_x >= 32) {
        continue;
      }
      if (sraw[y][x] == '1') {
        if(backup_score != 0 && raw[y + base_y][x + base_x] == '1') { //score = 1、つまり最初に置く石なら判定しない
          raw = backup_field;
          score = backup_score;
          return false;
        }
        raw[y + base_y][x + base_x] = '1';
        ++score;
      }
    }
  }
  return true;
}

//
void test() {
  RawStone rawstone;
  for (int x = 0; x < 8; ++x) {
    rawstone[0][x] = '1';
  }
  for (int y = 1; y < 8; ++y) {
    for (int x = 0; x < 8; ++x) {
      rawstone[y][x] = '0';
    }
  }
  RawStone rotated_90;
  for (int y = 0; y < 8; ++y) {
    rotated_90[y][7] = '1';
  }
  for (int y = 0; y < 8; ++y) {
    for (int x = 0; x < 7; ++x) {
      rotated_90[y][x] = '0';
    }
  }
  RawStone rotated_by_f = std::move(StoneRotate(rawstone, ROTATE_270|REVERSE));

  assert(rotated_by_f == rotated_90);
}
<|endoftext|>


<commit_before>#include "from_json.h"

#include <unordered_map>
#include <stack>

#include <asdf_multiplat/utilities/utilities.h>

using namespace asdf;
using namespace asdf::util;

namespace tired_of_build_issues
{
    std::string read_text_file(std::string const& filepath) {
        //if(!is_file(filepath))
        //{
        //    //throw file_open_exception(filepath);
        //    EXPLODE("C'est une probleme");
        //}

        std::string outputstring;
        std::ifstream ifs(filepath, std::ifstream::in);
        ifs.exceptions( std::ios::failbit );

        // ASSERT(ifs.good(), "Error loading text file %s", filepath.c_str());
        if(!ifs.good())
        {
            //throw file_open_exception(filepath);
            EXPLODE("C'est une probleme");
        }

        ifs.seekg(0, std::ios::end);		//seek to the end to get the size the output string should be
        outputstring.reserve(size_t(ifs.tellg()));	//reserve necessary memory up front
        ifs.seekg(0, std::ios::beg);		//seek back to the start

        outputstring.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

        ifs.close();

        return outputstring;
    }
}

// custom hash function for std::path so that I can use it as
// a key in unordered_map
namespace std
{
template<>
struct hash<stdfs::path> {
    size_t operator()(const stdfs::path &p) const {
        return std::hash<std::string>()(canonical(p));
    }
};
}

namespace plantgen
{
    // global stack used for resolving relative filepaths
    // when including other json files as node properties / values
    // I should probably devise a better method of doing this, since
    // I don't think this will handle more than one level of inclusion
    // if the JSON files are not all in the same directory

    //FIXME make this not global
    std::stack<stdfs::path> include_dir_stack;
    std::unordered_map<stdfs::path, pregen_node_t> include_cache;

    bool str_eq(char const* a, char const* b)
    {
        return strcmp(a, b) == 0;
    }

    std::vector<std::string> value_string_list_from_json_array(cJSON* json_array)
    {
        ASSERT(json_array, "");
        ASSERT(json_array->type == cJSON_Array, "json_array is not actually a JSON array");
        std::vector<std::string> values;

        cJSON* j = json_array->child;
        while(j)
        {
            ASSERT(j->type == cJSON_String, "Expected a JSON string");
            values.emplace_back(j->valuestring);
            j = j->next;
        }

        return values;
    }

    multi_value_t multi_value_from_json(cJSON* json)
    {
        ASSERT(str_eq(json->child->string, "Multi"), "Expected a \"Multi\" json_obj");
        ASSERT(json->child->type == cJSON_Number, "JSON Value of \"Multi\" should be an integer");

        multi_value_t v;
        v.num_to_pick = json->child->valueint;
        v.values = std::move(value_string_list_from_json_array(json->child->next));

        return v;
    }

    range_value_t range_value_from_json(cJSON* json)
    {
        ASSERT(str_eq(json->string, "Range"), "Expected a \"Range\" json_obj");
        return value_string_list_from_json_array(json);
    }

    weighted_value_t value_type_from_json(cJSON* json)
    {
        if(json->type == cJSON_String)
        {
            return std::string(json->valuestring);
        }
        else if(!json->child)
        {
            EXPLODE("invalid value object %s", json->string);
            return null_value_t();
        }
        else if(str_eq(json->child->string, "Multi"))
        {
            return multi_value_from_json(json);
        }
        else if(str_eq(json->child->string, "Range"))
        {
            return range_value_from_json(json->child);
        }
        else
        {
            EXPLODE("unrecognized value object %s", json->child->string);
            return weighted_value_t(null_value_t());
        }
    }

    pregen_node_t node_from_json(cJSON* json_node)
    {
        pregen_node_t node;
        node.name = std::string(CJSON_STR(json_node, Name));

        cJSON* cur_child = json_node->child;
        while(cur_child)
        {
            if(str_eq(cur_child->string, "Properties"))
            {
                cJSON* property_json = cur_child->child;
                while(property_json)
                {
                    node.add_child(node_from_json(property_json));
                    property_json = property_json->next;
                }
            }
            else if(str_eq(cur_child->string, "Values"))
            {
                cJSON* value_json = cur_child->child;
                while(value_json)
                {
                    // if the value is a node, load it differently
                    // since we can't return a node as part of the variant

                    //if the value is an object starting with a child named "Name", it's a node
                    if(value_json->type == cJSON_Object
                    && value_json->child
                    && str_eq(value_json->child->string, "Name"))
                    {
                        node.value_nodes.push_back(std::move(node_from_json(value_json)));
                    }
                    else
                    {
                        node.values.push_back(std::move(value_type_from_json(value_json)));
                    }

                    value_json = value_json->next;
                }
            }
            else if(str_eq(cur_child->string, "Include"))
            {
                ASSERT(cur_child->type == cJSON_String, "Include filepath must be a string");
                stdfs::path relpath(cur_child->valuestring);

                auto parent_path = include_dir_stack.top().parent_path();
                stdfs::path fullpath = parent_path / relpath;

                try{
                    auto included_node = node_from_json(fullpath);

                    if(included_node.name == node.name)
                    {
                        node.merge_with(std::move(included_node));
                    }
                    else
                    {
                        node.add_child(std::move(included_node));
                    }
                }
                catch(file_not_found_exception const&)
                {
                    throw include_exception{include_dir_stack.top(), fullpath};
                }
            }
            else if(str_eq(cur_child->string, "Weight"))
            {
                if(cur_child->type != cJSON_Number)
                    throw json_type_exception(include_dir_stack.top(), cur_child, cJSON_Number);

                node.weight = cur_child->valueint;
            }
            else
            {
                // LOG("Unrecognized tag '%s' in node '%s'", cur_child->string, json_node->string);
            }

            cur_child = cur_child->next;
        }

        return node;
    }

    pregen_node_t node_from_json(stdfs::path const& filepath)
    {
        if(!stdfs::is_regular_file(filepath))
            throw file_not_found_exception{filepath};

        auto canonical_path = stdfs::canonical(filepath);

        auto cached_node_entry = include_cache.find(canonical_path);
        if(cached_node_entry != include_cache.end())
        {
            return cached_node_entry->second;
        }
        else
        {
            //std::string json_str = asdf::util::read_text_file(filepath);
            std::string json_str = tired_of_build_issues::read_text_file(canonical_path.string());
            cJSON* json_root = cJSON_Parse(json_str.c_str());

            if(!json_root)
            {
                throw json_parse_exception(filepath, cJSON_GetErrorPtr());
            }

            include_dir_stack.push(canonical_path);
            auto node = node_from_json(json_root);
            cJSON_Delete(json_root);
            include_dir_stack.pop();

            include_cache.insert({canonical_path, node});

            return node;
        }
    }

    generated_node_t generate_node_from_json(stdfs::path const& filepath)
    {
        auto node = node_from_json(filepath);
        return generate_node(node);
    }

}<commit_msg>msvc fix<commit_after>#include "from_json.h"

#include <unordered_map>
#include <stack>

#include <asdf_multiplat/utilities/utilities.h>

using namespace asdf;
using namespace asdf::util;

namespace tired_of_build_issues
{
    std::string read_text_file(std::string const& filepath) {
        //if(!is_file(filepath))
        //{
        //    //throw file_open_exception(filepath);
        //    EXPLODE("C'est une probleme");
        //}

        std::string outputstring;
        std::ifstream ifs(filepath, std::ifstream::in);
        ifs.exceptions( std::ios::failbit );

        // ASSERT(ifs.good(), "Error loading text file %s", filepath.c_str());
        if(!ifs.good())
        {
            //throw file_open_exception(filepath);
            EXPLODE("C'est une probleme");
        }

        ifs.seekg(0, std::ios::end);		//seek to the end to get the size the output string should be
        outputstring.reserve(size_t(ifs.tellg()));	//reserve necessary memory up front
        ifs.seekg(0, std::ios::beg);		//seek back to the start

        outputstring.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());

        ifs.close();

        return outputstring;
    }
}

// custom hash function for std::path so that I can use it as
// a key in unordered_map
namespace std
{
template<>
struct hash<stdfs::path> {
    size_t operator()(const stdfs::path &p) const {
        return std::hash<std::string>()(canonical(p).string());
    }
};
}

namespace plantgen
{
    // global stack used for resolving relative filepaths
    // when including other json files as node properties / values
    // I should probably devise a better method of doing this, since
    // I don't think this will handle more than one level of inclusion
    // if the JSON files are not all in the same directory

    //FIXME make this not global
    std::stack<stdfs::path> include_dir_stack;
    std::unordered_map<stdfs::path, pregen_node_t> include_cache;

    bool str_eq(char const* a, char const* b)
    {
        return strcmp(a, b) == 0;
    }

    std::vector<std::string> value_string_list_from_json_array(cJSON* json_array)
    {
        ASSERT(json_array, "");
        ASSERT(json_array->type == cJSON_Array, "json_array is not actually a JSON array");
        std::vector<std::string> values;

        cJSON* j = json_array->child;
        while(j)
        {
            ASSERT(j->type == cJSON_String, "Expected a JSON string");
            values.emplace_back(j->valuestring);
            j = j->next;
        }

        return values;
    }

    multi_value_t multi_value_from_json(cJSON* json)
    {
        ASSERT(str_eq(json->child->string, "Multi"), "Expected a \"Multi\" json_obj");
        ASSERT(json->child->type == cJSON_Number, "JSON Value of \"Multi\" should be an integer");

        multi_value_t v;
        v.num_to_pick = json->child->valueint;
        v.values = std::move(value_string_list_from_json_array(json->child->next));

        return v;
    }

    range_value_t range_value_from_json(cJSON* json)
    {
        ASSERT(str_eq(json->string, "Range"), "Expected a \"Range\" json_obj");
        return value_string_list_from_json_array(json);
    }

    weighted_value_t value_type_from_json(cJSON* json)
    {
        if(json->type == cJSON_String)
        {
            return std::string(json->valuestring);
        }
        else if(!json->child)
        {
            EXPLODE("invalid value object %s", json->string);
            return null_value_t();
        }
        else if(str_eq(json->child->string, "Multi"))
        {
            return multi_value_from_json(json);
        }
        else if(str_eq(json->child->string, "Range"))
        {
            return range_value_from_json(json->child);
        }
        else
        {
            EXPLODE("unrecognized value object %s", json->child->string);
            return weighted_value_t(null_value_t());
        }
    }

    pregen_node_t node_from_json(cJSON* json_node)
    {
        pregen_node_t node;
        node.name = std::string(CJSON_STR(json_node, Name));

        cJSON* cur_child = json_node->child;
        while(cur_child)
        {
            if(str_eq(cur_child->string, "Properties"))
            {
                cJSON* property_json = cur_child->child;
                while(property_json)
                {
                    node.add_child(node_from_json(property_json));
                    property_json = property_json->next;
                }
            }
            else if(str_eq(cur_child->string, "Values"))
            {
                cJSON* value_json = cur_child->child;
                while(value_json)
                {
                    // if the value is a node, load it differently
                    // since we can't return a node as part of the variant

                    //if the value is an object starting with a child named "Name", it's a node
                    if(value_json->type == cJSON_Object
                    && value_json->child
                    && str_eq(value_json->child->string, "Name"))
                    {
                        node.value_nodes.push_back(std::move(node_from_json(value_json)));
                    }
                    else
                    {
                        node.values.push_back(std::move(value_type_from_json(value_json)));
                    }

                    value_json = value_json->next;
                }
            }
            else if(str_eq(cur_child->string, "Include"))
            {
                ASSERT(cur_child->type == cJSON_String, "Include filepath must be a string");
                stdfs::path relpath(cur_child->valuestring);

                auto parent_path = include_dir_stack.top().parent_path();
                stdfs::path fullpath = parent_path / relpath;

                try{
                    auto included_node = node_from_json(fullpath);

                    if(included_node.name == node.name)
                    {
                        node.merge_with(std::move(included_node));
                    }
                    else
                    {
                        node.add_child(std::move(included_node));
                    }
                }
                catch(file_not_found_exception const&)
                {
                    throw include_exception{include_dir_stack.top(), fullpath};
                }
            }
            else if(str_eq(cur_child->string, "Weight"))
            {
                if(cur_child->type != cJSON_Number)
                    throw json_type_exception(include_dir_stack.top(), cur_child, cJSON_Number);

                node.weight = cur_child->valueint;
            }
            else
            {
                // LOG("Unrecognized tag '%s' in node '%s'", cur_child->string, json_node->string);
            }

            cur_child = cur_child->next;
        }

        return node;
    }

    pregen_node_t node_from_json(stdfs::path const& filepath)
    {
        if(!stdfs::is_regular_file(filepath))
            throw file_not_found_exception{filepath};

        auto canonical_path = stdfs::canonical(filepath);

        auto cached_node_entry = include_cache.find(canonical_path);
        if(cached_node_entry != include_cache.end())
        {
            return cached_node_entry->second;
        }
        else
        {
            //std::string json_str = asdf::util::read_text_file(filepath);
            std::string json_str = tired_of_build_issues::read_text_file(canonical_path.string());
            cJSON* json_root = cJSON_Parse(json_str.c_str());

            if(!json_root)
            {
                throw json_parse_exception(filepath, cJSON_GetErrorPtr());
            }

            include_dir_stack.push(canonical_path);
            auto node = node_from_json(json_root);
            cJSON_Delete(json_root);
            include_dir_stack.pop();

            include_cache.insert({canonical_path, node});

            return node;
        }
    }

    generated_node_t generate_node_from_json(stdfs::path const& filepath)
    {
        auto node = node_from_json(filepath);
        return generate_node(node);
    }

}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 copyright holders 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 THE COPYRIGHT
 * OWNER OR CONTRIBUTORS 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.
 */

#ifndef __SYSTEM_HH__
#define __SYSTEM_HH__

#include <string>
#include <vector>

#include "base/statistics.hh"
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "kern/system_events.hh"
#include "sim/sim_object.hh"

class BaseCPU;
class ExecContext;
class GDBListener;
class MemoryController;
class ObjectFile;
class PhysicalMemory;
class Platform;
class RemoteGDB;
namespace Kernel { class Binning; }

class System : public SimObject
{
  public:
    MemoryController *memctrl;
    PhysicalMemory *physmem;
    Platform *platform;
    PCEventQueue pcEventQueue;
    uint64_t init_param;

    std::vector<ExecContext *> execContexts;
    int numcpus;

    int getNumCPUs()
    {
        if (numcpus != execContexts.size())
            panic("cpu array not fully populated!");

        return numcpus;
    }

    /** kernel symbol table */
    SymbolTable *kernelSymtab;

    /** console symbol table */
    SymbolTable *consoleSymtab;

    /** pal symbol table */
    SymbolTable *palSymtab;

    /** Object pointer for the kernel code */
    ObjectFile *kernel;

    /** Object pointer for the console code */
    ObjectFile *console;

    /** Object pointer for the PAL code */
    ObjectFile *pal;

    /** Begining of kernel code */
    Addr kernelStart;

    /** End of kernel code */
    Addr kernelEnd;

    /** Entry point in the kernel to start at */
    Addr kernelEntry;

    Kernel::Binning *kernelBinning;

#ifdef DEBUG
    /** Event to halt the simulator if the console calls panic() */
    BreakPCEvent *consolePanicEvent;
#endif

  protected:

    /**
     * Fix up an address used to match PCs for hooking simulator
     * events on to target function executions.  See comment in
     * system.cc for details.
     */
    Addr fixFuncEventAddr(Addr addr);

    /**
     * Add a function-based event to the given function, to be looked
     * up in the specified symbol table.
     */
    template <class T>
    T *System::addFuncEvent(SymbolTable *symtab, const char *lbl)
    {
        Addr addr;

        if (symtab->findAddress(lbl, addr)) {
            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
            return ev;
        }

        return NULL;
    }

    /** Add a function-based event to kernel code. */
    template <class T>
    T *System::addKernelFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(kernelSymtab, lbl);
    }

    /** Add a function-based event to PALcode. */
    template <class T>
    T *System::addPalFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(palSymtab, lbl);
    }

    /** Add a function-based event to the console code. */
    template <class T>
    T *System::addConsoleFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(consoleSymtab, lbl);
    }

  public:
    std::vector<RemoteGDB *> remoteGDB;
    std::vector<GDBListener *> gdbListen;
    bool breakpoint();

  public:
    struct Params
    {
        std::string name;
        Tick boot_cpu_frequency;
        MemoryController *memctrl;
        PhysicalMemory *physmem;
        uint64_t init_param;
        bool bin;
        std::vector<std::string> binned_fns;
        bool bin_int;

        std::string kernel_path;
        std::string console_path;
        std::string palcode;
        std::string boot_osflags;

        std::string readfile;
        uint64_t system_type;
        uint64_t system_rev;
    };
    Params *params;

    System(Params *p);
    ~System();

    void startup();

  public:
    /**
     * Set the m5AlphaAccess pointer in the console
     */
    void setAlphaAccess(Addr access);

    /**
     * Returns the addess the kernel starts at.
     * @return address the kernel starts at
     */
    Addr getKernelStart() const { return kernelStart; }

    /**
     * Returns the addess the kernel ends at.
     * @return address the kernel ends at
     */
    Addr getKernelEnd() const { return kernelEnd; }

    /**
     * Returns the addess the entry point to the kernel code.
     * @return entry point of the kernel code
     */
    Addr getKernelEntry() const { return kernelEntry; }

    int registerExecContext(ExecContext *xc, int xcIndex);
    void replaceExecContext(ExecContext *xc, int xcIndex);

    void regStats();
    void serialize(std::ostream &os);
    void unserialize(Checkpoint *cp, const std::string &section);

  public:
    ////////////////////////////////////////////
    //
    // STATIC GLOBAL SYSTEM LIST
    //
    ////////////////////////////////////////////

    static std::vector<System *> systemList;
    static int numSystemsRunning;

    static void printSystems();
};

#endif // __SYSTEM_HH__
<commit_msg>Fix for g++ 4 warning... not sure why this is just popping up now.<commit_after>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 copyright holders 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 THE COPYRIGHT
 * OWNER OR CONTRIBUTORS 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.
 */

#ifndef __SYSTEM_HH__
#define __SYSTEM_HH__

#include <string>
#include <vector>

#include "base/statistics.hh"
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "kern/system_events.hh"
#include "sim/sim_object.hh"

class BaseCPU;
class ExecContext;
class GDBListener;
class MemoryController;
class ObjectFile;
class PhysicalMemory;
class Platform;
class RemoteGDB;
namespace Kernel { class Binning; }

class System : public SimObject
{
  public:
    MemoryController *memctrl;
    PhysicalMemory *physmem;
    Platform *platform;
    PCEventQueue pcEventQueue;
    uint64_t init_param;

    std::vector<ExecContext *> execContexts;
    int numcpus;

    int getNumCPUs()
    {
        if (numcpus != execContexts.size())
            panic("cpu array not fully populated!");

        return numcpus;
    }

    /** kernel symbol table */
    SymbolTable *kernelSymtab;

    /** console symbol table */
    SymbolTable *consoleSymtab;

    /** pal symbol table */
    SymbolTable *palSymtab;

    /** Object pointer for the kernel code */
    ObjectFile *kernel;

    /** Object pointer for the console code */
    ObjectFile *console;

    /** Object pointer for the PAL code */
    ObjectFile *pal;

    /** Begining of kernel code */
    Addr kernelStart;

    /** End of kernel code */
    Addr kernelEnd;

    /** Entry point in the kernel to start at */
    Addr kernelEntry;

    Kernel::Binning *kernelBinning;

#ifdef DEBUG
    /** Event to halt the simulator if the console calls panic() */
    BreakPCEvent *consolePanicEvent;
#endif

  protected:

    /**
     * Fix up an address used to match PCs for hooking simulator
     * events on to target function executions.  See comment in
     * system.cc for details.
     */
    Addr fixFuncEventAddr(Addr addr);

    /**
     * Add a function-based event to the given function, to be looked
     * up in the specified symbol table.
     */
    template <class T>
    T *System::addFuncEvent(SymbolTable *symtab, const char *lbl)
    {
        Addr addr = 0; // initialize only to avoid compiler warning

        if (symtab->findAddress(lbl, addr)) {
            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
            return ev;
        }

        return NULL;
    }

    /** Add a function-based event to kernel code. */
    template <class T>
    T *System::addKernelFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(kernelSymtab, lbl);
    }

    /** Add a function-based event to PALcode. */
    template <class T>
    T *System::addPalFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(palSymtab, lbl);
    }

    /** Add a function-based event to the console code. */
    template <class T>
    T *System::addConsoleFuncEvent(const char *lbl)
    {
        return addFuncEvent<T>(consoleSymtab, lbl);
    }

  public:
    std::vector<RemoteGDB *> remoteGDB;
    std::vector<GDBListener *> gdbListen;
    bool breakpoint();

  public:
    struct Params
    {
        std::string name;
        Tick boot_cpu_frequency;
        MemoryController *memctrl;
        PhysicalMemory *physmem;
        uint64_t init_param;
        bool bin;
        std::vector<std::string> binned_fns;
        bool bin_int;

        std::string kernel_path;
        std::string console_path;
        std::string palcode;
        std::string boot_osflags;

        std::string readfile;
        uint64_t system_type;
        uint64_t system_rev;
    };
    Params *params;

    System(Params *p);
    ~System();

    void startup();

  public:
    /**
     * Set the m5AlphaAccess pointer in the console
     */
    void setAlphaAccess(Addr access);

    /**
     * Returns the addess the kernel starts at.
     * @return address the kernel starts at
     */
    Addr getKernelStart() const { return kernelStart; }

    /**
     * Returns the addess the kernel ends at.
     * @return address the kernel ends at
     */
    Addr getKernelEnd() const { return kernelEnd; }

    /**
     * Returns the addess the entry point to the kernel code.
     * @return entry point of the kernel code
     */
    Addr getKernelEntry() const { return kernelEntry; }

    int registerExecContext(ExecContext *xc, int xcIndex);
    void replaceExecContext(ExecContext *xc, int xcIndex);

    void regStats();
    void serialize(std::ostream &os);
    void unserialize(Checkpoint *cp, const std::string &section);

  public:
    ////////////////////////////////////////////
    //
    // STATIC GLOBAL SYSTEM LIST
    //
    ////////////////////////////////////////////

    static std::vector<System *> systemList;
    static int numSystemsRunning;

    static void printSystems();
};

#endif // __SYSTEM_HH__
<|endoftext|>


<commit_before>/*
Copyright (C) 2015 Yannick Mueller

This file is part of longscroll-qt.

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

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

You should have received a copy of the GNU Affero General Public License
along with longscroll-qt.  If not see <http://www.gnu.org/licenses/>.
*/

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "itemfactories.h"
#include "valueeditdialog.h"
#include <longscroll-qt/contentwidget.h>
#include <longscroll-qt/contentwidgetitemfactory.h>
#include <QScrollBar>
#include <QMetaProperty>
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <QDebug>
#include <algorithm>
#include <random>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	ContentWidget * cw = ui->longscroll->getContentWidget();

	const QMetaObject * mo = cw->metaObject();

	QStringList blacklist;
	blacklist << "dragEnabled" << "selectedItems" << "currentItem";
	for (int i = mo->superClass()->propertyCount(), count = mo->propertyCount(); i < count; ++i)
	{
		QMetaProperty const & prop = mo->property(i);
		if (prop.userType() == QMetaType::UnknownType || !prop.isReadable() || !prop.isWritable() || blacklist.contains(prop.name()))
			continue;
		ui->menuProperties->addAction(QString())->setData(i);
	}

	demoGroup = new QActionGroup(ui->menuProperties);
	for (int i = 0; i < 5; ++i)
	{
		QAction * a = new QAction(tr("Demo %1").arg(i+1), demoGroup);
		a->setData(i);
		a->setCheckable(true);
		a->setChecked(i == 0);
	}
	ui->menuDemo->addActions(demoGroup->actions());

	setDemoNumber(0);

	connect(ui->menuFile, &QMenu::aboutToShow, this, &MainWindow::updateFileMenu);
	connect(ui->menuProperties, &QMenu::aboutToShow, this, &MainWindow::updatePropertyMenu);
	connect(ui->menuProperties, &QMenu::triggered, this, &MainWindow::propertyMenuTriggered);
	connect(demoGroup, &QActionGroup::triggered, this, &MainWindow::demoMenuTriggered);
}

MainWindow::~MainWindow()
{
	delete ui;
}

void MainWindow::setItemInfos(const QList<ContentItemInfo> & infos, int fixedSize, bool shuffle)
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	QList<ContentItemInfo> displayInfos = infos;

	if (fixedSize == -1)
		fixedSize = fixedInfoSize;
	if (fixedSize > 0)
	{
		qDebug() << "creating items ...";
		displayInfos.clear();
		for (int i = 0; i < fixedSize; ++i)
			displayInfos.append(infos.at(i % infos.count()));
		qDebug() << "created" << fixedSize << "items";
	}
	if (shuffle)
	{
		std::random_device rd;
		std::mt19937 rng(rd());
		std::shuffle(displayInfos.begin(), displayInfos.end(), rng);
		qDebug() << "shuffled";
	}

	fixedInfoSize = fixedSize;
	itemInfos = infos;
	cw->setItemInfos(displayInfos);
}

void MainWindow::setFixedItemCount(int fixedSize)
{
	setItemInfos(itemInfos, fixedSize);
}

void MainWindow::setDemoNumber(int demoNo)
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	ContentWidgetItemFactory * cwif = 0;
	switch (demoNo)
	{
		default:
		case 0:
			//Default Values
			cw->setRowHeight(200);
			cw->setItemWidth(0);
			cw->setStretchRows(true);
			cw->setStretchLastRow(false);
			cw->setScaleRows(false);
			cw->setAllowOverfill(true);
			cw->setNavigatorHeight(500);
			cwif = new ContentWidgetLoaderImageItemFactory(false);
			break;
		case 1:
			cw->setRowHeight(200);
			cw->setItemWidth(0);
			cw->setStretchRows(true);
			cw->setStretchLastRow(false);
			cw->setScaleRows(true);
			cw->setAllowOverfill(true);
			cw->setNavigatorHeight(500);
			cwif = new ContentWidgetLoaderImageItemFactory(false);
			break;
		case 2:
			cw->setRowHeight(100);
			cw->setItemWidth(100);
			cw->setStretchRows(false);
			cw->setStretchLastRow(false);
			cw->setScaleRows(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetLoaderImageItemFactory(true);
			break;
		case 3:
			cw->setRowHeight(100);
			cw->setItemWidth(-1);
			cw->setStretchRows(true);
			cw->setStretchLastRow(true);
			cw->setScaleRows(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetLoaderImageItemFactory(true);
			break;
		case 4:
			cw->setRowHeight(100);
			cw->setItemWidth(200);
			cw->setStretchRows(false);
			cw->setScaleRows(false);
			cw->setStretchLastRow(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetImageInfoFactory();
			break;
	}
	cw->setItemFactory(cwif);
	demoGroup->blockSignals(true);
	QAction * a = demoGroup->actions().value(demoNo);
	a->setChecked(a);
	demoGroup->blockSignals(false);
}

void MainWindow::loadDir(const QDir & dir, bool useCache)
{
	if (!dir.exists())
		return;
	QMap<QString, ContentItemInfo> cache, loadedCache;
	QFile cacheFile(dir.absoluteFilePath("images.cache"));
	if (cacheFile.exists())
	{
		if (cacheFile.open(QIODevice::ReadOnly))
		{
			QByteArray const & buffer = qUncompress(cacheFile.readAll());
			cacheFile.close();
			QDataStream ds(buffer);
			ds >> loadedCache;
		}
		else
		{
			qWarning() << "could not open cache file:" << cacheFile.fileName();
		}
	}
	cache = loadedCache;
	qDebug() << "cached images:" << cache.size();

	QStringList fileNamefilters;
	for (QString const & format : QImageReader::supportedImageFormats())
		fileNamefilters.append(QString("*.%1").arg(format));

	QImageReader ir;
	qDebug() << "loading file list for" << dir.absolutePath() << "...";
	QFileInfoList const & files = dir.entryInfoList(fileNamefilters, QDir::Files | QDir::Readable);
	qDebug() << "loading images from" << dir.absolutePath() << "...";
	for (QFileInfo const & file : files)
	{
		QString const & fileName = file.absoluteFilePath();
		if (cache.contains(fileName))
			continue;

		ir.setFileName(fileName);
		cache.insert(fileName, ContentItemInfo(fileName, ir.size()));
	}

	qDebug() << "checking file existence ...";
	for (auto it = cache.begin(); it != cache.end(); )
	{
		QFileInfo fi(it.key());
		if (fi.exists())
			++it;
		else
			it = cache.erase(it);
	}

	if (useCache && cache != loadedCache)
	{
		qDebug() << "storing cache file ...";
		QByteArray buffer;
		if (cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
		{
			QDataStream ds(&buffer, QIODevice::WriteOnly);
			ds << cache;
			cacheFile.write(qCompress(buffer, 9));
			cacheFile.close();
		}
		else
		{
			qWarning() << "Could not open" << cacheFile.fileName() << "for write.";
		}
	}

	qDebug() << "loaded" << cache.size() << "images";
	qDebug() << "loading gui ...";

	setItemInfos(cache.values(), fixedInfoSize);
}

void MainWindow::updateFileMenu()
{
	ui->actionCount->setText(tr("Count = %1").arg(fixedInfoSize));
}

void MainWindow::updatePropertyMenu()
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	const QMetaObject * mo = cw->metaObject();

	for (QAction * a : ui->menuProperties->actions())
	{
		QMetaProperty const & prop = mo->property(a->data().toInt());
		QString const & name = prop.name();
		int type = prop.userType();
		QVariant const & value = prop.read(cw);

		QString const & displayName = QString("%1 = %2").arg(name, prop.read(cw).toString());
		a->setText(displayName);
		switch (type)
		{
			case QMetaType::Bool:
				a->setCheckable(true);
				a->setChecked(value.toBool());
				break;
			default:
				break;
		}
	}
}

void MainWindow::propertyMenuTriggered(QAction * action)
{
	for (QAction * a : demoGroup->actions())
		a->setChecked(false);

	ContentWidget * cw = ui->longscroll->getContentWidget();
	const QMetaObject * mo = cw->metaObject();
	QMetaProperty const & prop = mo->property(action->data().toInt());
	switch (prop.userType())
	{
		case QMetaType::Bool:
			prop.write(cw, action->isChecked());
			break;
		default:
			ValueEditDialog ved(this);
			ved.setValue(prop.name(), prop.read(cw));
			if (ved.exec() == QDialog::Accepted)
				prop.write(cw, ved.getValue());
			break;
	}
}

void MainWindow::demoMenuTriggered(QAction * action)
{
	setDemoNumber(action->data().toInt());
}

void MainWindow::on_actionOpen_triggered()
{
	if (fileDialog == 0)
	{
		fileDialog = new QFileDialog(this);
		fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
		fileDialog->setFileMode(QFileDialog::Directory);
		fileDialog->setOption(QFileDialog::ShowDirsOnly, true);
	}
	if (fileDialog->exec() != QDialog::Accepted)
		return;
	QDir dir(fileDialog->selectedFiles().first());
	dir.makeAbsolute();
	QFileInfo cacheInfo(dir.filePath("images.cache"));

	qDebug() << cacheInfo.absoluteFilePath() << cacheInfo.exists() << cacheInfo.isFile() << cacheInfo.isWritable() << cacheInfo.permissions();
	QFileInfo dirInfo(dir.absolutePath());
	qDebug() << dirInfo.absoluteFilePath() << dirInfo.isWritable() << dirInfo.permissions();

	bool useCache = ((!cacheInfo.exists() && QFileInfo(dir.absolutePath()).isWritable()) || (cacheInfo.isFile() && cacheInfo.isWritable()));
	if (useCache && QMessageBox::question(this, tr("Write Cache File?"), tr("Write a cache file?\nThis is useful if you open a directory with a large number of files more than once.")) != QMessageBox::Yes)
		useCache = false;
	loadDir(dir, useCache);
}

void MainWindow::on_actionCount_triggered()
{
	bool ok;
	int val = QInputDialog::getInt(this, "Count", "Fixed number of images", fixedInfoSize, 0, std::numeric_limits<int>::max(), 1, &ok);
	if (ok)
		setFixedItemCount(val);
}

void MainWindow::on_actionShuffle_triggered()
{
	setItemInfos(itemInfos, fixedInfoSize, true);
}
<commit_msg>Fixed demo 5<commit_after>/*
Copyright (C) 2015 Yannick Mueller

This file is part of longscroll-qt.

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

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

You should have received a copy of the GNU Affero General Public License
along with longscroll-qt.  If not see <http://www.gnu.org/licenses/>.
*/

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "itemfactories.h"
#include "valueeditdialog.h"
#include <longscroll-qt/contentwidget.h>
#include <longscroll-qt/contentwidgetitemfactory.h>
#include <QScrollBar>
#include <QMetaProperty>
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <QDebug>
#include <algorithm>
#include <random>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      ui(new Ui::MainWindow)
{
	ui->setupUi(this);

	ContentWidget * cw = ui->longscroll->getContentWidget();

	const QMetaObject * mo = cw->metaObject();

	QStringList blacklist;
	blacklist << "dragEnabled" << "selectedItems" << "currentItem";
	for (int i = mo->superClass()->propertyCount(), count = mo->propertyCount(); i < count; ++i)
	{
		QMetaProperty const & prop = mo->property(i);
		if (prop.userType() == QMetaType::UnknownType || !prop.isReadable() || !prop.isWritable() || blacklist.contains(prop.name()))
			continue;
		ui->menuProperties->addAction(QString())->setData(i);
	}

	demoGroup = new QActionGroup(ui->menuProperties);
	for (int i = 0; i < 5; ++i)
	{
		QAction * a = new QAction(tr("Demo %1").arg(i+1), demoGroup);
		a->setData(i);
		a->setCheckable(true);
		a->setChecked(i == 0);
	}
	ui->menuDemo->addActions(demoGroup->actions());

	setDemoNumber(0);

	connect(ui->menuFile, &QMenu::aboutToShow, this, &MainWindow::updateFileMenu);
	connect(ui->menuProperties, &QMenu::aboutToShow, this, &MainWindow::updatePropertyMenu);
	connect(ui->menuProperties, &QMenu::triggered, this, &MainWindow::propertyMenuTriggered);
	connect(demoGroup, &QActionGroup::triggered, this, &MainWindow::demoMenuTriggered);
}

MainWindow::~MainWindow()
{
	delete ui;
}

void MainWindow::setItemInfos(const QList<ContentItemInfo> & infos, int fixedSize, bool shuffle)
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	QList<ContentItemInfo> displayInfos = infos;

	if (fixedSize == -1)
		fixedSize = fixedInfoSize;
	if (fixedSize > 0)
	{
		qDebug() << "creating items ...";
		displayInfos.clear();
		for (int i = 0; i < fixedSize; ++i)
			displayInfos.append(infos.at(i % infos.count()));
		qDebug() << "created" << fixedSize << "items";
	}
	if (shuffle)
	{
		std::random_device rd;
		std::mt19937 rng(rd());
		std::shuffle(displayInfos.begin(), displayInfos.end(), rng);
		qDebug() << "shuffled";
	}

	fixedInfoSize = fixedSize;
	itemInfos = infos;
	cw->setItemInfos(displayInfos);
}

void MainWindow::setFixedItemCount(int fixedSize)
{
	setItemInfos(itemInfos, fixedSize);
}

void MainWindow::setDemoNumber(int demoNo)
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	ContentWidgetItemFactory * cwif = 0;
	switch (demoNo)
	{
		default:
		case 0:
			//Default Values
			cw->setRowHeight(200);
			cw->setItemWidth(0);
			cw->setStretchRows(true);
			cw->setStretchLastRow(false);
			cw->setScaleRows(false);
			cw->setAllowOverfill(true);
			cw->setNavigatorHeight(500);
			cwif = new ContentWidgetLoaderImageItemFactory(false);
			break;
		case 1:
			cw->setRowHeight(200);
			cw->setItemWidth(0);
			cw->setStretchRows(true);
			cw->setStretchLastRow(false);
			cw->setScaleRows(true);
			cw->setAllowOverfill(true);
			cw->setNavigatorHeight(500);
			cwif = new ContentWidgetLoaderImageItemFactory(false);
			break;
		case 2:
			cw->setRowHeight(100);
			cw->setItemWidth(100);
			cw->setStretchRows(false);
			cw->setStretchLastRow(false);
			cw->setScaleRows(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetLoaderImageItemFactory(true);
			break;
		case 3:
			cw->setRowHeight(100);
			cw->setItemWidth(-1);
			cw->setStretchRows(true);
			cw->setStretchLastRow(true);
			cw->setScaleRows(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetLoaderImageItemFactory(true);
			break;
		case 4:
			cw->setRowHeight(100);
			cw->setItemWidth(400);
			cw->setStretchRows(false);
			cw->setScaleRows(false);
			cw->setStretchLastRow(false);
			cw->setAllowOverfill(false);
			cw->setNavigatorHeight(200);
			cwif = new ContentWidgetImageInfoFactory();
			break;
	}
	cw->setItemFactory(cwif);
	demoGroup->blockSignals(true);
	QAction * a = demoGroup->actions().value(demoNo);
	a->setChecked(a);
	demoGroup->blockSignals(false);
}

void MainWindow::loadDir(const QDir & dir, bool useCache)
{
	if (!dir.exists())
		return;
	QMap<QString, ContentItemInfo> cache, loadedCache;
	QFile cacheFile(dir.absoluteFilePath("images.cache"));
	if (cacheFile.exists())
	{
		if (cacheFile.open(QIODevice::ReadOnly))
		{
			QByteArray const & buffer = qUncompress(cacheFile.readAll());
			cacheFile.close();
			QDataStream ds(buffer);
			ds >> loadedCache;
		}
		else
		{
			qWarning() << "could not open cache file:" << cacheFile.fileName();
		}
	}
	cache = loadedCache;
	qDebug() << "cached images:" << cache.size();

	QStringList fileNamefilters;
	for (QString const & format : QImageReader::supportedImageFormats())
		fileNamefilters.append(QString("*.%1").arg(format));

	QImageReader ir;
	qDebug() << "loading file list for" << dir.absolutePath() << "...";
	QFileInfoList const & files = dir.entryInfoList(fileNamefilters, QDir::Files | QDir::Readable);
	qDebug() << "loading images from" << dir.absolutePath() << "...";
	for (QFileInfo const & file : files)
	{
		QString const & fileName = file.absoluteFilePath();
		if (cache.contains(fileName))
			continue;

		ir.setFileName(fileName);
		cache.insert(fileName, ContentItemInfo(fileName, ir.size()));
	}

	qDebug() << "checking file existence ...";
	for (auto it = cache.begin(); it != cache.end(); )
	{
		QFileInfo fi(it.key());
		if (fi.exists())
			++it;
		else
			it = cache.erase(it);
	}

	if (useCache && cache != loadedCache)
	{
		qDebug() << "storing cache file ...";
		QByteArray buffer;
		if (cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
		{
			QDataStream ds(&buffer, QIODevice::WriteOnly);
			ds << cache;
			cacheFile.write(qCompress(buffer, 9));
			cacheFile.close();
		}
		else
		{
			qWarning() << "Could not open" << cacheFile.fileName() << "for write.";
		}
	}

	qDebug() << "loaded" << cache.size() << "images";
	qDebug() << "loading gui ...";

	setItemInfos(cache.values(), fixedInfoSize);
}

void MainWindow::updateFileMenu()
{
	ui->actionCount->setText(tr("Count = %1").arg(fixedInfoSize));
}

void MainWindow::updatePropertyMenu()
{
	ContentWidget * cw = ui->longscroll->getContentWidget();
	const QMetaObject * mo = cw->metaObject();

	for (QAction * a : ui->menuProperties->actions())
	{
		QMetaProperty const & prop = mo->property(a->data().toInt());
		QString const & name = prop.name();
		int type = prop.userType();
		QVariant const & value = prop.read(cw);

		QString const & displayName = QString("%1 = %2").arg(name, prop.read(cw).toString());
		a->setText(displayName);
		switch (type)
		{
			case QMetaType::Bool:
				a->setCheckable(true);
				a->setChecked(value.toBool());
				break;
			default:
				break;
		}
	}
}

void MainWindow::propertyMenuTriggered(QAction * action)
{
	for (QAction * a : demoGroup->actions())
		a->setChecked(false);

	ContentWidget * cw = ui->longscroll->getContentWidget();
	const QMetaObject * mo = cw->metaObject();
	QMetaProperty const & prop = mo->property(action->data().toInt());
	switch (prop.userType())
	{
		case QMetaType::Bool:
			prop.write(cw, action->isChecked());
			break;
		default:
			ValueEditDialog ved(this);
			ved.setValue(prop.name(), prop.read(cw));
			if (ved.exec() == QDialog::Accepted)
				prop.write(cw, ved.getValue());
			break;
	}
}

void MainWindow::demoMenuTriggered(QAction * action)
{
	setDemoNumber(action->data().toInt());
}

void MainWindow::on_actionOpen_triggered()
{
	if (fileDialog == 0)
	{
		fileDialog = new QFileDialog(this);
		fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
		fileDialog->setFileMode(QFileDialog::Directory);
		fileDialog->setOption(QFileDialog::ShowDirsOnly, true);
	}
	if (fileDialog->exec() != QDialog::Accepted)
		return;
	QDir dir(fileDialog->selectedFiles().first());
	dir.makeAbsolute();
	QFileInfo cacheInfo(dir.filePath("images.cache"));

	qDebug() << cacheInfo.absoluteFilePath() << cacheInfo.exists() << cacheInfo.isFile() << cacheInfo.isWritable() << cacheInfo.permissions();
	QFileInfo dirInfo(dir.absolutePath());
	qDebug() << dirInfo.absoluteFilePath() << dirInfo.isWritable() << dirInfo.permissions();

	bool useCache = ((!cacheInfo.exists() && QFileInfo(dir.absolutePath()).isWritable()) || (cacheInfo.isFile() && cacheInfo.isWritable()));
	if (useCache && QMessageBox::question(this, tr("Write Cache File?"), tr("Write a cache file?\nThis is useful if you open a directory with a large number of files more than once.")) != QMessageBox::Yes)
		useCache = false;
	loadDir(dir, useCache);
}

void MainWindow::on_actionCount_triggered()
{
	bool ok;
	int val = QInputDialog::getInt(this, "Count", "Fixed number of images", fixedInfoSize, 0, std::numeric_limits<int>::max(), 1, &ok);
	if (ok)
		setFixedItemCount(val);
}

void MainWindow::on_actionShuffle_triggered()
{
	setItemInfos(itemInfos, fixedInfoSize, true);
}
<|endoftext|>


<commit_before>//===- Optimize.cpp - Optimize a complete program -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements all optimization of the linked module for llvm-ld.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include <iostream>
using namespace llvm;

// Pass Name Options as generated by the PassNameParser
static cl::list<const PassInfo*, bool, PassNameParser>
  OptimizationList(cl::desc("Optimizations available:"));

// Optimization Enumeration
enum OptimizationLevels {
  OPT_FAST_COMPILE         = 1,
  OPT_SIMPLE               = 2,
  OPT_AGGRESSIVE           = 3,
  OPT_LINK_TIME            = 4,
  OPT_AGGRESSIVE_LINK_TIME = 5
};

// Optimization Options
static cl::opt<OptimizationLevels> OptLevel(
  cl::desc("Choose level of optimization to apply:"),
  cl::init(OPT_FAST_COMPILE), cl::values(
    clEnumValN(OPT_FAST_COMPILE,"O0",
      "An alias for the -O1 option."),
    clEnumValN(OPT_FAST_COMPILE,"O1",
      "Optimize for linking speed, not execution speed."),
    clEnumValN(OPT_SIMPLE,"O2",
      "Perform only required/minimal optimizations"),
    clEnumValN(OPT_AGGRESSIVE,"O3",
      "An alias for the -O2 option."),
    clEnumValN(OPT_LINK_TIME,"O4",
      "Perform standard link time optimizations"),
    clEnumValN(OPT_AGGRESSIVE_LINK_TIME,"O5",
      "Perform aggressive link time optimizations"),
    clEnumValEnd
  )
);

static cl::opt<bool> DisableInline("disable-inlining",
  cl::desc("Do not run the inliner pass"));

static cl::opt<bool>
DisableOptimizations("disable-opt",
  cl::desc("Do not run any optimization passes"));

static cl::opt<bool> DisableInternalize("disable-internalize",
  cl::desc("Do not mark all symbols as internal"));

static cl::opt<bool> VerifyEach("verify-each",
 cl::desc("Verify intermediate results of all passes"));

static cl::alias ExportDynamic("export-dynamic",
  cl::aliasopt(DisableInternalize),
  cl::desc("Alias for -disable-internalize"));

static cl::opt<bool> Strip("strip-all",
  cl::desc("Strip all symbol info from executable"));

static cl::alias A0("s", cl::desc("Alias for --strip-all"),
  cl::aliasopt(Strip));

static cl::opt<bool> StripDebug("strip-debug",
  cl::desc("Strip debugger symbol info from executable"));

static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
  cl::aliasopt(StripDebug));

// A utility function that adds a pass to the pass manager but will also add
// a verifier pass after if we're supposed to verify.
static inline void addPass(PassManager &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);

  // If we are verifying all of the intermediate steps, add the verifier...
  if (VerifyEach)
    PM.add(createVerifierPass());
}

namespace llvm {

/// Optimize - Perform link time optimizations. This will run the scalar
/// optimizations, any loaded plugin-optimization modules, and then the
/// inter-procedural optimizations if applicable.
void Optimize(Module* M) {

  // Instantiate the pass manager to organize the passes.
  PassManager Passes;

  // If we're verifying, start off with a verification pass.
  if (VerifyEach)
    Passes.add(createVerifierPass());

  // Add an appropriate TargetData instance for this module...
  addPass(Passes, new TargetData(M));

  if (!DisableOptimizations) {
    // Now that composite has been compiled, scan through the module, looking
    // for a main function.  If main is defined, mark all other functions
    // internal.
    addPass(Passes, createInternalizePass(!DisableInternalize));

    // Propagate constants at call sites into the functions they call.  This
    // opens opportunities for globalopt (and inlining) by substituting function
    // pointers passed as arguments to direct uses of functions.
    addPass(Passes, createIPSCCPPass());

    // Now that we internalized some globals, see if we can hack on them!
    addPass(Passes, createGlobalOptimizerPass());

    // Linking modules together can lead to duplicated global constants, only
    // keep one copy of each constant...
    addPass(Passes, createConstantMergePass());

    // Remove unused arguments from functions...
    addPass(Passes, createDeadArgEliminationPass());

    // Reduce the code after globalopt and ipsccp.  Both can open up significant
    // simplification opportunities, and both can propagate functions through
    // function pointers.  When this happens, we often have to resolve varargs
    // calls, etc, so let instcombine do this.
    addPass(Passes, createInstructionCombiningPass());

    if (!DisableInline)
      addPass(Passes, createFunctionInliningPass()); // Inline small functions

    addPass(Passes, createPruneEHPass());            // Remove dead EH info
    addPass(Passes, createGlobalOptimizerPass());    // Optimize globals again.
    addPass(Passes, createGlobalDCEPass());          // Remove dead functions

    // If we didn't decide to inline a function, check to see if we can
    // transform it to pass arguments by value instead of by reference.
    addPass(Passes, createArgumentPromotionPass());

    // The IPO passes may leave cruft around.  Clean up after them.
    addPass(Passes, createInstructionCombiningPass());

    addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas

    // Run a few AA driven optimizations here and now, to cleanup the code.
    addPass(Passes, createGlobalsModRefPass());      // IP alias analysis

    addPass(Passes, createLICMPass());               // Hoist loop invariants
    addPass(Passes, createLoadValueNumberingPass()); // GVN for load instrs
    addPass(Passes, createGCSEPass());               // Remove common subexprs
    addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores

    // Cleanup and simplify the code after the scalar optimizations.
    addPass(Passes, createInstructionCombiningPass());

    // Delete basic blocks, which optimization passes may have killed...
    addPass(Passes, createCFGSimplificationPass());

    // Now that we have optimized the program, discard unreachable functions...
    addPass(Passes, createGlobalDCEPass());
  }

  // If the -s or -S command line options were specified, strip the symbols out
  // of the resulting program to make it smaller.  -s and -S are GNU ld options
  // that we are supporting; they alias -strip-all and -strip-debug.
  if (Strip || StripDebug)
    addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));

  // Create a new optimization pass for each one specified on the command line
  std::auto_ptr<TargetMachine> target;
  for (unsigned i = 0; i < OptimizationList.size(); ++i) {
    const PassInfo *Opt = OptimizationList[i];
    if (Opt->getNormalCtor())
      addPass(Passes, Opt->getNormalCtor()());
    else
      std::cerr << "llvm-ld: cannot create pass: " << Opt->getPassName()
                << "\n";
  }

  // The user's passes may leave cruft around. Clean up after them them but
  // only if we haven't got DisableOptimizations set
  if (!DisableOptimizations) {
    addPass(Passes, createInstructionCombiningPass());
    addPass(Passes, createCFGSimplificationPass());
    addPass(Passes, createGlobalDCEPass());
  }

  // Make sure everything is still good.
  Passes.add(createVerifierPass());

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M);
}

}
<commit_msg>run a late dce pass to clean up extra cruft.<commit_after>//===- Optimize.cpp - Optimize a complete program -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements all optimization of the linked module for llvm-ld.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/LoadValueNumbering.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/System/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include <iostream>
using namespace llvm;

// Pass Name Options as generated by the PassNameParser
static cl::list<const PassInfo*, bool, PassNameParser>
  OptimizationList(cl::desc("Optimizations available:"));

// Optimization Enumeration
enum OptimizationLevels {
  OPT_FAST_COMPILE         = 1,
  OPT_SIMPLE               = 2,
  OPT_AGGRESSIVE           = 3,
  OPT_LINK_TIME            = 4,
  OPT_AGGRESSIVE_LINK_TIME = 5
};

// Optimization Options
static cl::opt<OptimizationLevels> OptLevel(
  cl::desc("Choose level of optimization to apply:"),
  cl::init(OPT_FAST_COMPILE), cl::values(
    clEnumValN(OPT_FAST_COMPILE,"O0",
      "An alias for the -O1 option."),
    clEnumValN(OPT_FAST_COMPILE,"O1",
      "Optimize for linking speed, not execution speed."),
    clEnumValN(OPT_SIMPLE,"O2",
      "Perform only required/minimal optimizations"),
    clEnumValN(OPT_AGGRESSIVE,"O3",
      "An alias for the -O2 option."),
    clEnumValN(OPT_LINK_TIME,"O4",
      "Perform standard link time optimizations"),
    clEnumValN(OPT_AGGRESSIVE_LINK_TIME,"O5",
      "Perform aggressive link time optimizations"),
    clEnumValEnd
  )
);

static cl::opt<bool> DisableInline("disable-inlining",
  cl::desc("Do not run the inliner pass"));

static cl::opt<bool>
DisableOptimizations("disable-opt",
  cl::desc("Do not run any optimization passes"));

static cl::opt<bool> DisableInternalize("disable-internalize",
  cl::desc("Do not mark all symbols as internal"));

static cl::opt<bool> VerifyEach("verify-each",
 cl::desc("Verify intermediate results of all passes"));

static cl::alias ExportDynamic("export-dynamic",
  cl::aliasopt(DisableInternalize),
  cl::desc("Alias for -disable-internalize"));

static cl::opt<bool> Strip("strip-all",
  cl::desc("Strip all symbol info from executable"));

static cl::alias A0("s", cl::desc("Alias for --strip-all"),
  cl::aliasopt(Strip));

static cl::opt<bool> StripDebug("strip-debug",
  cl::desc("Strip debugger symbol info from executable"));

static cl::alias A1("S", cl::desc("Alias for --strip-debug"),
  cl::aliasopt(StripDebug));

// A utility function that adds a pass to the pass manager but will also add
// a verifier pass after if we're supposed to verify.
static inline void addPass(PassManager &PM, Pass *P) {
  // Add the pass to the pass manager...
  PM.add(P);

  // If we are verifying all of the intermediate steps, add the verifier...
  if (VerifyEach)
    PM.add(createVerifierPass());
}

namespace llvm {

/// Optimize - Perform link time optimizations. This will run the scalar
/// optimizations, any loaded plugin-optimization modules, and then the
/// inter-procedural optimizations if applicable.
void Optimize(Module* M) {

  // Instantiate the pass manager to organize the passes.
  PassManager Passes;

  // If we're verifying, start off with a verification pass.
  if (VerifyEach)
    Passes.add(createVerifierPass());

  // Add an appropriate TargetData instance for this module...
  addPass(Passes, new TargetData(M));

  if (!DisableOptimizations) {
    // Now that composite has been compiled, scan through the module, looking
    // for a main function.  If main is defined, mark all other functions
    // internal.
    addPass(Passes, createInternalizePass(!DisableInternalize));

    // Propagate constants at call sites into the functions they call.  This
    // opens opportunities for globalopt (and inlining) by substituting function
    // pointers passed as arguments to direct uses of functions.
    addPass(Passes, createIPSCCPPass());

    // Now that we internalized some globals, see if we can hack on them!
    addPass(Passes, createGlobalOptimizerPass());

    // Linking modules together can lead to duplicated global constants, only
    // keep one copy of each constant...
    addPass(Passes, createConstantMergePass());

    // Remove unused arguments from functions...
    addPass(Passes, createDeadArgEliminationPass());

    // Reduce the code after globalopt and ipsccp.  Both can open up significant
    // simplification opportunities, and both can propagate functions through
    // function pointers.  When this happens, we often have to resolve varargs
    // calls, etc, so let instcombine do this.
    addPass(Passes, createInstructionCombiningPass());

    if (!DisableInline)
      addPass(Passes, createFunctionInliningPass()); // Inline small functions

    addPass(Passes, createPruneEHPass());            // Remove dead EH info
    addPass(Passes, createGlobalOptimizerPass());    // Optimize globals again.
    addPass(Passes, createGlobalDCEPass());          // Remove dead functions

    // If we didn't decide to inline a function, check to see if we can
    // transform it to pass arguments by value instead of by reference.
    addPass(Passes, createArgumentPromotionPass());

    // The IPO passes may leave cruft around.  Clean up after them.
    addPass(Passes, createInstructionCombiningPass());

    addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas

    // Run a few AA driven optimizations here and now, to cleanup the code.
    addPass(Passes, createGlobalsModRefPass());      // IP alias analysis

    addPass(Passes, createLICMPass());               // Hoist loop invariants
    addPass(Passes, createLoadValueNumberingPass()); // GVN for load instrs
    addPass(Passes, createGCSEPass());               // Remove common subexprs
    addPass(Passes, createDeadStoreEliminationPass()); // Nuke dead stores

    // Cleanup and simplify the code after the scalar optimizations.
    addPass(Passes, createInstructionCombiningPass());

    // Delete basic blocks, which optimization passes may have killed...
    addPass(Passes, createCFGSimplificationPass());

    // Now that we have optimized the program, discard unreachable functions...
    addPass(Passes, createGlobalDCEPass());
  }

  // If the -s or -S command line options were specified, strip the symbols out
  // of the resulting program to make it smaller.  -s and -S are GNU ld options
  // that we are supporting; they alias -strip-all and -strip-debug.
  if (Strip || StripDebug)
    addPass(Passes, createStripSymbolsPass(StripDebug && !Strip));

  // Create a new optimization pass for each one specified on the command line
  std::auto_ptr<TargetMachine> target;
  for (unsigned i = 0; i < OptimizationList.size(); ++i) {
    const PassInfo *Opt = OptimizationList[i];
    if (Opt->getNormalCtor())
      addPass(Passes, Opt->getNormalCtor()());
    else
      std::cerr << "llvm-ld: cannot create pass: " << Opt->getPassName()
                << "\n";
  }

  // The user's passes may leave cruft around. Clean up after them them but
  // only if we haven't got DisableOptimizations set
  if (!DisableOptimizations) {
    addPass(Passes, createInstructionCombiningPass());
    addPass(Passes, createCFGSimplificationPass());
    addPass(Passes, createDeadCodeEliminationPass());
    addPass(Passes, createGlobalDCEPass());
  }

  // Make sure everything is still good.
  Passes.add(createVerifierPass());

  // Run our queue of passes all at once now, efficiently.
  Passes.run(*M);
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MNSTerminateListener.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 03:01:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#ifndef _MNSTERMINATELISTENER_HXX
#include <MNSTerminateListener.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDESKTOP_HPP_
#include <com/sun/star/frame/XDesktop.hpp>
#endif
#ifndef _CONNECTIVITY_MAB_NS_INIT_HXX_
#include <MNSInit.hxx>
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
::com::sun::star::uno::Reference< ::com::sun::star::frame::XTerminateListener>          MNSTerminateListener::mxTerminateListener = new MNSTerminateListener();

// -----------------------------------------
// - MNSTerminateListener -
// -----------------------------------------

MNSTerminateListener::MNSTerminateListener(  )
{
}

// -----------------------------------------------------------------------------

MNSTerminateListener::~MNSTerminateListener()
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::disposing( const EventObject& /*Source*/ ) throw( RuntimeException )
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::queryTermination( const EventObject& /*aEvent*/ ) throw( TerminationVetoException, RuntimeException )
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::notifyTermination( const EventObject& /*aEvent*/ ) throw( RuntimeException )
{
    MNS_Term(sal_True); //Force XPCOM to shutdown
}

void MNSTerminateListener::addTerminateListener()
{
    Reference< XMultiServiceFactory >   xFact( ::comphelper::getProcessServiceFactory() );

    if( xFact.is() )
    {
        Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );

        if( xDesktop.is() )
            xDesktop->addTerminateListener(mxTerminateListener);
    }
}

<commit_msg>INTEGRATION: CWS changefileheader (1.5.216); FILE MERGED 2008/04/01 15:09:01 thb 1.5.216.3: #i85898# Stripping all external header guards 2008/04/01 10:53:13 thb 1.5.216.2: #i85898# Stripping all external header guards 2008/03/28 15:23:58 rt 1.5.216.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MNSTerminateListener.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#include <MNSTerminateListener.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/frame/XDesktop.hpp>
#include <MNSInit.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
::com::sun::star::uno::Reference< ::com::sun::star::frame::XTerminateListener>          MNSTerminateListener::mxTerminateListener = new MNSTerminateListener();

// -----------------------------------------
// - MNSTerminateListener -
// -----------------------------------------

MNSTerminateListener::MNSTerminateListener(  )
{
}

// -----------------------------------------------------------------------------

MNSTerminateListener::~MNSTerminateListener()
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::disposing( const EventObject& /*Source*/ ) throw( RuntimeException )
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::queryTermination( const EventObject& /*aEvent*/ ) throw( TerminationVetoException, RuntimeException )
{
}

// -----------------------------------------------------------------------------

void SAL_CALL MNSTerminateListener::notifyTermination( const EventObject& /*aEvent*/ ) throw( RuntimeException )
{
    MNS_Term(sal_True); //Force XPCOM to shutdown
}

void MNSTerminateListener::addTerminateListener()
{
    Reference< XMultiServiceFactory >   xFact( ::comphelper::getProcessServiceFactory() );

    if( xFact.is() )
    {
        Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );

        if( xDesktop.is() )
            xDesktop->addTerminateListener(mxTerminateListener);
    }
}

<|endoftext|>