<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <alloy/runtime/debug_info.h>

using namespace alloy;
using namespace alloy::runtime;

DebugInfo::DebugInfo() :
    source_disasm_(0),
    raw_hir_disasm_(0),
    hir_disasm_(0),
    machine_code_disasm_(0),
    source_map_count_(0),
    source_map_(NULL) {
}

DebugInfo::~DebugInfo() {
  xe_free(source_map_);
  xe_free(source_disasm_);
  xe_free(raw_hir_disasm_);
  xe_free(hir_disasm_);
  xe_free(machine_code_disasm_);
}

void DebugInfo::InitializeSourceMap(size_t source_map_count,
                                    SourceMapEntry* source_map) {
  source_map_count_ = source_map_count;
  source_map_ = source_map;

  // TODO(benvanik): ensure sorted in some way? MC offset?
}

SourceMapEntry* DebugInfo::LookupSourceOffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (size_t n = 0; n < source_map_count_; n++) {
    auto entry = &source_map_[n];
    if (entry->source_offset == offset) {
      return entry;
    }
  }
  return NULL;
}

SourceMapEntry* DebugInfo::LookupHIROffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (size_t n = 0; n < source_map_count_; n++) {
    auto entry = &source_map_[n];
    if (entry->hir_offset >= offset) {
      return entry;
    }
  }
  return NULL;
}

SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (size_t n = 0; n < source_map_count_; n++) {
    auto entry = &source_map_[n];
    if (entry->code_offset >= offset) {
      return entry;
    }
  }
  return 0;
}
<commit_msg>Fixing source offsets.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <alloy/runtime/debug_info.h>

using namespace alloy;
using namespace alloy::runtime;

DebugInfo::DebugInfo() :
    source_disasm_(0),
    raw_hir_disasm_(0),
    hir_disasm_(0),
    machine_code_disasm_(0),
    source_map_count_(0),
    source_map_(NULL) {
}

DebugInfo::~DebugInfo() {
  xe_free(source_map_);
  xe_free(source_disasm_);
  xe_free(raw_hir_disasm_);
  xe_free(hir_disasm_);
  xe_free(machine_code_disasm_);
}

void DebugInfo::InitializeSourceMap(size_t source_map_count,
                                    SourceMapEntry* source_map) {
  source_map_count_ = source_map_count;
  source_map_ = source_map;

  // TODO(benvanik): ensure sorted in some way? MC offset?
}

SourceMapEntry* DebugInfo::LookupSourceOffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (size_t n = 0; n < source_map_count_; n++) {
    auto entry = &source_map_[n];
    if (entry->source_offset == offset) {
      return entry;
    }
  }
  return NULL;
}

SourceMapEntry* DebugInfo::LookupHIROffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (size_t n = 0; n < source_map_count_; n++) {
    auto entry = &source_map_[n];
    if (entry->hir_offset >= offset) {
      return entry;
    }
  }
  return NULL;
}

SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) {
  // TODO(benvanik): binary search? We know the list is sorted by code order.
  for (int n = source_map_count_ - 1; n >= 0; n--) {
    auto entry = &source_map_[n];
    if (entry->code_offset <= offset) {
      return entry;
    }
  }
  return NULL;
}
<|endoftext|>


<commit_before>#include "analyser_dtsc.h"
#include <mist/h264.h>

void AnalyserDTSC::init(Util::Config &conf){
  Analyser::init(conf);
}

AnalyserDTSC::AnalyserDTSC(Util::Config &conf) : Analyser(conf){
  conn = Socket::Connection(0, fileno(stdin));
  totalBytes = 0;
}

bool AnalyserDTSC::parsePacket(){
  P.reInit(conn);
  if (conn && !P){
    FAIL_MSG("Invalid DTSC packet @ byte %llu", totalBytes)
    return false;
  }
  if (!conn && !P){
    stop();
    return false;
  }

  switch (P.getVersion()){
  case DTSC::DTSC_V1:{
    if (detail >= 2){
      std::cout << "DTSCv1 packet: " << P.getScan().toPrettyString() << std::endl;
    }
    break;
  }
  case DTSC::DTSC_V2:{
    mediaTime = P.getTime();
    if (detail >= 2){
      std::cout << "DTSCv2 packet (Track " << P.getTrackId() << ", time " << P.getTime()
                << "): " << P.getScan().toPrettyString() << std::endl;
    }
    break;
  }
  case DTSC::DTSC_HEAD:{
    if (detail >= 3){
      std::cout << "DTSC header: ";
      DTSC::Meta(P).toPrettyString(std::cout, 0, (detail == 3 ? 0 : (detail == 4 ? 0x01 : (detail == 5 ? 0x03 : 0x07))));
    }
    if (detail == 2){std::cout << "DTSC header: " << P.getScan().toPrettyString() << std::endl;}
    if (detail == 1){
      bool hasH264 = false;
      bool hasAAC = false;
      JSON::Value result;
      std::stringstream issues;
      DTSC::Meta M(P);
      for (std::map<unsigned int, DTSC::Track>::iterator it = M.tracks.begin();
           it != M.tracks.end(); it++){
        JSON::Value track;
        track["kbits"] = (long long)((double)it->second.bps * 8 / 1024);
        track["codec"] = it->second.codec;
        uint32_t shrtest_key = 0xFFFFFFFFul;
        uint32_t longest_key = 0;
        uint32_t shrtest_prt = 0xFFFFFFFFul;
        uint32_t longest_prt = 0;
        uint32_t shrtest_cnt = 0xFFFFFFFFul;
        uint32_t longest_cnt = 0;
        for (std::deque<DTSC::Key>::iterator k = it->second.keys.begin();
             k != it->second.keys.end(); k++){
          if (!k->getLength()){continue;}
          if (k->getLength() > longest_key){longest_key = k->getLength();}
          if (k->getLength() < shrtest_key){shrtest_key = k->getLength();}
          if (k->getParts() > longest_cnt){longest_cnt = k->getParts();}
          if (k->getParts() < shrtest_cnt){shrtest_cnt = k->getParts();}
          if (k->getParts()){
            if ((k->getLength() / k->getParts()) > longest_prt){
              longest_prt = (k->getLength() / k->getParts());
            }
            if ((k->getLength() / k->getParts()) < shrtest_prt){
              shrtest_prt = (k->getLength() / k->getParts());
            }
          }
        }
        track["keys"]["ms_min"] = (long long)shrtest_key;
        track["keys"]["ms_max"] = (long long)longest_key;
        track["keys"]["frame_ms_min"] = (long long)shrtest_prt;
        track["keys"]["frame_ms_max"] = (long long)longest_prt;
        track["keys"]["frames_min"] = (long long)shrtest_cnt;
        track["keys"]["frames_max"] = (long long)longest_cnt;
        if (longest_prt > 500){
          issues << "unstable connection (" << longest_prt << "ms " << it->second.codec
                 << " frame)! ";
        }
        if (shrtest_cnt < 6){
          issues << "unstable connection (" << shrtest_cnt << " " << it->second.codec
                 << " frames in key)! ";
        }
        if (it->second.codec == "AAC"){hasAAC = true;}
        if (it->second.codec == "H264"){hasH264 = true;}
        if (it->second.type == "video"){
          track["width"] = (long long)it->second.width;
          track["height"] = (long long)it->second.height;
          track["fpks"] = it->second.fpks;
          if (it->second.codec == "H264"){
            h264::sequenceParameterSet sps;
            sps.fromDTSCInit(it->second.init);
            h264::SPSMeta spsData = sps.getCharacteristics();
            track["h264"]["profile"] = spsData.profile;
            track["h264"]["level"] = spsData.level;
          }
        }
        result[it->second.getWritableIdentifier()] = track;
      }
      if ((hasAAC || hasH264) && M.tracks.size() > 1){
        if (!hasAAC){issues << "HLS no audio!";}
        if (!hasH264){issues << "HLS no video!";}
      }
      if (issues.str().size()){result["issues"] = issues.str();}
      std::cout << result.toString() << std::endl;
      stop();
    }
    break;
  }
  case DTSC::DTCM:{
    if (detail >= 2){std::cout << "DTCM command: " << P.getScan().toPrettyString() << std::endl;}
    break;
  }
  default: FAIL_MSG("Invalid DTSC packet @ byte %llu", totalBytes); break;
  }

  totalBytes += P.getDataLen();
  return true;
}

<commit_msg>Added raw data payload printing in hex to DTSC analyser<commit_after>#include "analyser_dtsc.h"
#include <mist/h264.h>
#include <iomanip>

void AnalyserDTSC::init(Util::Config &conf){
  Analyser::init(conf);
}

AnalyserDTSC::AnalyserDTSC(Util::Config &conf) : Analyser(conf){
  conn = Socket::Connection(0, fileno(stdin));
  totalBytes = 0;
}

bool AnalyserDTSC::parsePacket(){
  P.reInit(conn);
  if (conn && !P){
    FAIL_MSG("Invalid DTSC packet @ byte %llu", totalBytes)
    return false;
  }
  if (!conn && !P){
    stop();
    return false;
  }

  switch (P.getVersion()){
  case DTSC::DTSC_V1:{
    if (detail >= 2){
      std::cout << "DTSCv1 packet: " << P.getScan().toPrettyString() << std::endl;
    }
    break;
  }
  case DTSC::DTSC_V2:{
    mediaTime = P.getTime();
    if (detail >= 2){
      std::cout << "DTSCv2 packet (Track " << P.getTrackId() << ", time " << P.getTime()
                << "): " << P.getScan().toPrettyString() << std::endl;
    }
    if (detail >= 8){
      char * payDat;
      unsigned int payLen;
      P.getString("data", payDat, payLen);
      for (uint64_t i = 0; i < payLen; ++i){
        if ((i % 32) == 0){std::cout << std::endl;}
        std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)payDat[i];
      }
    }
    break;
  }
  case DTSC::DTSC_HEAD:{
    if (detail >= 3){
      std::cout << "DTSC header: ";
      DTSC::Meta(P).toPrettyString(std::cout, 0, (detail == 3 ? 0 : (detail == 4 ? 0x01 : (detail == 5 ? 0x03 : 0x07))));
    }
    if (detail == 2){std::cout << "DTSC header: " << P.getScan().toPrettyString() << std::endl;}
    if (detail == 1){
      bool hasH264 = false;
      bool hasAAC = false;
      JSON::Value result;
      std::stringstream issues;
      DTSC::Meta M(P);
      for (std::map<unsigned int, DTSC::Track>::iterator it = M.tracks.begin();
           it != M.tracks.end(); it++){
        JSON::Value track;
        track["kbits"] = (long long)((double)it->second.bps * 8 / 1024);
        track["codec"] = it->second.codec;
        uint32_t shrtest_key = 0xFFFFFFFFul;
        uint32_t longest_key = 0;
        uint32_t shrtest_prt = 0xFFFFFFFFul;
        uint32_t longest_prt = 0;
        uint32_t shrtest_cnt = 0xFFFFFFFFul;
        uint32_t longest_cnt = 0;
        for (std::deque<DTSC::Key>::iterator k = it->second.keys.begin();
             k != it->second.keys.end(); k++){
          if (!k->getLength()){continue;}
          if (k->getLength() > longest_key){longest_key = k->getLength();}
          if (k->getLength() < shrtest_key){shrtest_key = k->getLength();}
          if (k->getParts() > longest_cnt){longest_cnt = k->getParts();}
          if (k->getParts() < shrtest_cnt){shrtest_cnt = k->getParts();}
          if (k->getParts()){
            if ((k->getLength() / k->getParts()) > longest_prt){
              longest_prt = (k->getLength() / k->getParts());
            }
            if ((k->getLength() / k->getParts()) < shrtest_prt){
              shrtest_prt = (k->getLength() / k->getParts());
            }
          }
        }
        track["keys"]["ms_min"] = (long long)shrtest_key;
        track["keys"]["ms_max"] = (long long)longest_key;
        track["keys"]["frame_ms_min"] = (long long)shrtest_prt;
        track["keys"]["frame_ms_max"] = (long long)longest_prt;
        track["keys"]["frames_min"] = (long long)shrtest_cnt;
        track["keys"]["frames_max"] = (long long)longest_cnt;
        if (longest_prt > 500){
          issues << "unstable connection (" << longest_prt << "ms " << it->second.codec
                 << " frame)! ";
        }
        if (shrtest_cnt < 6){
          issues << "unstable connection (" << shrtest_cnt << " " << it->second.codec
                 << " frames in key)! ";
        }
        if (it->second.codec == "AAC"){hasAAC = true;}
        if (it->second.codec == "H264"){hasH264 = true;}
        if (it->second.type == "video"){
          track["width"] = (long long)it->second.width;
          track["height"] = (long long)it->second.height;
          track["fpks"] = it->second.fpks;
          if (it->second.codec == "H264"){
            h264::sequenceParameterSet sps;
            sps.fromDTSCInit(it->second.init);
            h264::SPSMeta spsData = sps.getCharacteristics();
            track["h264"]["profile"] = spsData.profile;
            track["h264"]["level"] = spsData.level;
          }
        }
        result[it->second.getWritableIdentifier()] = track;
      }
      if ((hasAAC || hasH264) && M.tracks.size() > 1){
        if (!hasAAC){issues << "HLS no audio!";}
        if (!hasH264){issues << "HLS no video!";}
      }
      if (issues.str().size()){result["issues"] = issues.str();}
      std::cout << result.toString() << std::endl;
      stop();
    }
    break;
  }
  case DTSC::DTCM:{
    if (detail >= 2){std::cout << "DTCM command: " << P.getScan().toPrettyString() << std::endl;}
    break;
  }
  default: FAIL_MSG("Invalid DTSC packet @ byte %llu", totalBytes); break;
  }

  totalBytes += P.getDataLen();
  return true;
}

<|endoftext|>


<commit_before>/// \file dtsc_analyser.cpp
/// Reads an DTSC file and prints all readable data about it

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

#include <mist/dtsc.h>
#include <mist/json.h>
#include <mist/config.h>
#include <mist/defines.h>

///\brief Holds everything unique to the analysers.
namespace Analysers {
  ///\brief Debugging tool for DTSC data.
  ///
  /// Expects DTSC data in a file given on the command line, outputs human-readable information to stderr.
  ///\param conf The configuration parsed from the commandline.
  ///\return The return code of the analyser.
  int analyseDTSC(Util::Config conf){
    DTSC::File F(conf.getString("filename"));
    std::stringstream meta;
    F.getMeta().toPrettyString(meta,0, 0x03);
    std::cout << meta.str() << std::endl;

    int bPos = 0;
    F.seek_bpos(0);
    F.parseNext();
    JSON::Value tmp;
    std::string tmpStr;
    while (F.getPacket()){
      tmpStr = std::string(F.getPacket().getData(), F.getPacket().getDataLen());
      switch (F.getPacket().getVersion()){
        case DTSC::DTSC_V1: {
          unsigned int i = 8;
          JSON::fromDTMI((const unsigned char*)tmpStr.data(), tmpStr.size(), i, tmp);
          break;
        }
        case DTSC::DTSC_V2: {
          unsigned int i = 8;
          JSON::fromDTMI2((const unsigned char*)tmpStr.data(), tmpStr.size(), i, tmp);
          break;
        }
        default:
          DEBUG_MSG(DLVL_WARN,"Invalid dtsc packet @ bpos %d", bPos);
          break;
      }
      std::cout << tmp.toPrettyString() << std::endl;
      bPos = F.getBytePos();
      F.parseNext();
    }
    return 0;
  }
}

/// Reads an DTSC file and prints all readable data about it
int main(int argc, char ** argv){
  Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
  conf.addOption("filename", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the DTSC file to analyse.\"}"));
  conf.parseArgs(argc, argv);
  return Analysers::analyseDTSC(conf);
} //main
<commit_msg>Updates to the DTSC analyser - not fully complete, but still nice.<commit_after>/// \file dtsc_analyser.cpp
/// Reads an DTSC file and prints all readable data about it

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

#include <mist/dtsc.h>
#include <mist/json.h>
#include <mist/config.h>
#include <mist/defines.h>

///\brief Holds everything unique to the analysers.
namespace Analysers {
  ///\brief Debugging tool for DTSC data.
  ///
  /// Expects DTSC data in a file given on the command line, outputs human-readable information to stderr.
  ///\param conf The configuration parsed from the commandline.
  ///\return The return code of the analyser.
  int analyseDTSC(Util::Config conf){
    DTSC::File F(conf.getString("filename"));
    F.getMeta().toPrettyString(std::cout,0, 0x03);

    int bPos = 0;
    F.seek_bpos(0);
    F.parseNext();
    JSON::Value tmp;
    std::string tmpStr;
    while (F.getPacket()){
      switch (F.getPacket().getVersion()){
        case DTSC::DTSC_V1: {
          std::cout << "DTSCv1 packet: " << F.getPacket().getScan().toPrettyString() << std::endl;
          break;
        }
        case DTSC::DTSC_V2: {
          std::cout << "DTSCv2 packet: " << F.getPacket().getScan().toPrettyString() << std::endl;
          break;
        }
        default:
          DEBUG_MSG(DLVL_WARN,"Invalid dtsc packet @ bpos %d", bPos);
          break;
      }
      std::cout << tmp.toPrettyString() << std::endl;
      bPos = F.getBytePos();
      F.parseNext();
    }
    return 0;
  }
}

/// Reads an DTSC file and prints all readable data about it
int main(int argc, char ** argv){
  Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
  conf.addOption("filename", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the DTSC file to analyse.\"}"));
  conf.parseArgs(argc, argv);
  return Analysers::analyseDTSC(conf);
} //main
<|endoftext|>


<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "arch/runtime/message_hub.hpp"

#include <math.h>
#include <unistd.h>
#include <algorithm>

#include "config/args.hpp"
#include "arch/runtime/event_queue.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "logger.hpp"

// Set this to 1 if you would like some "unordered" messages to be unordered.
#ifndef NDEBUG
#define RDB_RELOOP_MESSAGES 0
#endif

linux_message_hub_t::linux_message_hub_t(linux_event_queue_t *queue,
                                         linux_thread_pool_t *thread_pool,
                                         threadnum_t current_thread)
    : queue_(queue),
      thread_pool_(thread_pool),
      is_woken_up_(false),
      current_thread_(current_thread) {

#ifndef NDEBUG
    if(MESSAGE_SCHEDULER_GRANULARITY < (1 >> (MESSAGE_SCHEDULER_MAX_PRIORITY
                                               - MESSAGE_SCHEDULER_MIN_PRIORITY
                                               + 1))) {
        logWRN("MESSAGE_SCHEDULER_GRANULARITY is too small to honor some of the "
               "lower priorities");
    }
#endif

    queue_->watch_resource(event_.get_notify_fd(), poll_event_in, this);
}

linux_message_hub_t::~linux_message_hub_t() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        guarantee(queues_[i].msg_local_list.empty());
    }
    for (int p = MESSAGE_SCHEDULER_MIN_PRIORITY;
         p <= MESSAGE_SCHEDULER_MAX_PRIORITY;
         ++p) {

        guarantee(get_priority_msg_list(p).empty());
    }

    guarantee(incoming_messages_.empty());
}

void linux_message_hub_t::do_store_message(threadnum_t nthread, linux_thread_message_t *msg) {
    rassert(0 <= nthread.threadnum && nthread.threadnum < thread_pool_->n_threads);
    queues_[nthread.threadnum].msg_local_list.push_back(msg);
}

// Collects a message for a given thread onto a local list.
void linux_message_hub_t::store_message_ordered(threadnum_t nthread,
                                                linux_thread_message_t *msg) {
    rassert(!msg->is_ordered); // Each message object can only be enqueued once,
                               // and once it is removed, is_ordered is reset to false.
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    // We default to 1, not zero, to allow store_message_sometime messages to sometimes jump ahead of
    // store_message messages.
    msg->reloop_count_ = 1;
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    msg->is_ordered = true;
    do_store_message(nthread, msg);
}

int rand_reloop_count() {
    int x;
    frexp(randint(10000) / 10000.0, &x);
    int ret = -x;
    rassert(ret >= 0);
    return ret;
}

void linux_message_hub_t::store_message_sometime(threadnum_t nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    msg->reloop_count_ = rand_reloop_count();
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

void linux_message_hub_t::insert_external_message(linux_thread_message_t *msg) {
    bool do_wake_up;
    {
        spinlock_acq_t acq(&incoming_messages_lock_);
        do_wake_up = !check_and_set_is_woken_up();
        incoming_messages_.push_back(msg);
    }

    // Wakey wakey eggs and bakey
    if (do_wake_up) {
        event_.wakey_wakey();
    }
}

linux_message_hub_t::msg_list_t &linux_message_hub_t::get_priority_msg_list(int priority) {
    rassert(priority >= MESSAGE_SCHEDULER_MIN_PRIORITY);
    rassert(priority <= MESSAGE_SCHEDULER_MAX_PRIORITY);
    return priority_msg_lists_[priority - MESSAGE_SCHEDULER_MIN_PRIORITY];
}

void linux_message_hub_t::on_event(int events) {
    if (events != poll_event_in) {
        logERR("Unexpected event mask: %d", events);
    }

    // You must read wakey-wakeys so that the pipe-based implementation doesn't fill
    // up and so that poll-based event triggering doesn't infinite-loop.
    event_.consume_wakey_wakeys();

#ifndef NDEBUG
    start_watchdog(); // Initialize watchdog before handling messages
#endif

    const int num_priorities = MESSAGE_SCHEDULER_MAX_PRIORITY
                               - MESSAGE_SCHEDULER_MIN_PRIORITY
                               + 1;

    // Loop until we have processed at least the initial batch of messages.
    size_t num_initial_msgs_left_to_process[num_priorities];
    bool initial_batch_has_been_processed = false;
    bool initial_pass = true;
    do {
        if (!initial_pass) {
            // Other threads will automatically push their messages
            // for us into the incoming queue, even while
            // we are in this loop. However we still have to pick up
            // our local messages, since this->push_messages() is not
            // going to be called while we are still running on_event()
            deliver_local_messages();
        }

        // We guarantee to process all messages that are delivered
        // before the first pass. We do not guarantee to deliver
        // incoming messages delivered during !initial_pass!
        // As a consequence, we must reset is_woken_up_ in the first
        // pass, so later incoming messages wake us up again.
        const bool reset_is_woken_up = initial_pass;
        sort_incoming_messages_by_priority(reset_is_woken_up);

        // We store how many messages we have initially for each priority.
        // Those are the messages that we *definitely* have to process during
        // this call to `on_event()`.
        // We *may* process more messages than this, such that more recent
        // messages with a high-priority can bypass older messages with lower
        // priority.
        if (initial_pass) {
            for (int i = 0; i < num_priorities; ++i) {
                num_initial_msgs_left_to_process[i] = priority_msg_lists_[i].size();
            }
            initial_pass = false;
        }

        // Compute how many messages of MESSAGE_SCHEDULER_MAX_PRIORITY we process
        // before we check the incoming queues for new messages.
        // We call this the granularity of the message scheduler, and it is
        // MESSAGE_SCHEDULER_GRANULARITY or smaller.
        size_t total_pending_msgs = 0;
        for (int i = 0; i < num_priorities; ++i) {
            total_pending_msgs += priority_msg_lists_[i].size();
        }
        const size_t effective_granularity = std::min(total_pending_msgs,
                                                      MESSAGE_SCHEDULER_GRANULARITY);

        // Process a certain number of messages from each priority
        for (int current_priority = MESSAGE_SCHEDULER_MAX_PRIORITY;
             current_priority >= MESSAGE_SCHEDULER_MIN_PRIORITY; --current_priority) {

            // Compute how many messages of `current_priority` we want to process
            // in this pass.
            // The priority has an exponential effect on how many messages
            // get processed, i.e. if we process 8 messages of priority 1 per pass,
            // we are going to process up to 16 messages of priority 2, 32 of
            // priority 3 and so on.
            // However, we process at least one message of each priority level per
            // pass (in case the granularity is too small).
            int priority_exponent = MESSAGE_SCHEDULER_MAX_PRIORITY - current_priority;
            size_t to_process_from_priority = std::max(1ul, effective_granularity >> priority_exponent);

            while (linux_thread_message_t *m = get_priority_msg_list(current_priority).head()) {
                if (to_process_from_priority == 0) break;

                get_priority_msg_list(current_priority).remove(m);
                --to_process_from_priority;
                if (num_initial_msgs_left_to_process[current_priority - MESSAGE_SCHEDULER_MIN_PRIORITY] > 0) {
                    // About to process one of the initial messages
                    --num_initial_msgs_left_to_process[current_priority - MESSAGE_SCHEDULER_MIN_PRIORITY];
                }

#ifndef NDEBUG
                if (m->reloop_count_ > 0) {
                    --m->reloop_count_;
                    do_store_message(current_thread_, m);
                    continue;
                }
#endif

                m->on_thread_switch();

#ifndef NDEBUG
                pet_watchdog(); // Verify that each message completes in the acceptable time range
#endif
            }
        }

        // Check if we have to continue in order to fulfill our guarantee
        // to at least process all of the initial messages.
        initial_batch_has_been_processed = true;
        for (int i = 0; i < num_priorities; ++i) {
            if (num_initial_msgs_left_to_process[i] > 0) {
                initial_batch_has_been_processed = false;
                break;
            }
        }
    } while (!initial_batch_has_been_processed);
}

void linux_message_hub_t::sort_incoming_messages_by_priority(bool reset_is_woken_up) {
    // We do this in two steps to release the spinlock faster.
    // append_and_clear is a very cheap operation, while
    // assigning each message to a different priority queue
    // is more expensive.

    // 1. Pull the messages
    msg_list_t new_messages;
    {
        spinlock_acq_t acq(&incoming_messages_lock_);
        new_messages.append_and_clear(&incoming_messages_);
        if (reset_is_woken_up) {
            is_woken_up_ = false;
        }
    }

    // 2. Sort the messages into their respective priority queues
    while (linux_thread_message_t *m = new_messages.head()) {
        new_messages.remove(m);
        int effective_priority = m->priority;
        if (m->is_ordered) {
            // Ordered messages are treated as if they had
            // priority MESSAGE_SCHEDULER_ORDERED_PRIORITY.
            // This ensures that they can never bypass another
            // ordered message.
            effective_priority = MESSAGE_SCHEDULER_ORDERED_PRIORITY;
            m->is_ordered = false;
        }
        get_priority_msg_list(effective_priority).push_back(m);
    }
}

void linux_message_hub_t::deliver_local_messages() {
    const int local_thread = thread_pool_->thread_id;

    if (!queues_[local_thread].msg_local_list.empty()) {
        bool do_wake_up;
        {
            spinlock_acq_t acq(&incoming_messages_lock_);
            incoming_messages_.append_and_clear(&queues_[local_thread].msg_local_list);
            do_wake_up = !check_and_set_is_woken_up();
        }
        if (do_wake_up) {
            // Wake ourselves up for another round.
            // While this might seem risky w.r.t. dead-locks when the event pipe
            // is full, it is actually ok because the is_woken_up() flag guarantees
            // that we only ever write one event onto this.
            event_.wakey_wakey();
        }
    }
}

bool linux_message_hub_t::check_and_set_is_woken_up() {
    const bool was_woken_up = is_woken_up_;
    is_woken_up_ = true;
    return was_woken_up;
}

// Pushes messages collected locally global lists available to all
// threads.
void linux_message_hub_t::push_messages() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Append the local list for ith thread to that thread's global
        // message list.
        thread_queue_t *queue = &queues_[i];
        if (!queue->msg_local_list.empty()) {
            // Transfer messages to the other core

            bool do_wake_up;
            {
                spinlock_acq_t acq(&thread_pool_->threads[i]->message_hub.incoming_messages_lock_);

                // We only need to do a wake up if we're the first people to do a
                // wake up.
                do_wake_up =
                    !thread_pool_->threads[i]->message_hub.check_and_set_is_woken_up();

                thread_pool_->threads[i]->message_hub.incoming_messages_.append_and_clear(&queue->msg_local_list);
            }

            // Wakey wakey, perhaps eggs and bakey
            if (do_wake_up) {
                thread_pool_->threads[i]->message_hub.event_.wakey_wakey();
            }
        }
    }
}
<commit_msg>Removed unnecessary include<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#include "arch/runtime/message_hub.hpp"

#include <math.h>
#include <unistd.h>

#include "config/args.hpp"
#include "arch/runtime/event_queue.hpp"
#include "arch/runtime/thread_pool.hpp"
#include "logger.hpp"

// Set this to 1 if you would like some "unordered" messages to be unordered.
#ifndef NDEBUG
#define RDB_RELOOP_MESSAGES 0
#endif

linux_message_hub_t::linux_message_hub_t(linux_event_queue_t *queue,
                                         linux_thread_pool_t *thread_pool,
                                         threadnum_t current_thread)
    : queue_(queue),
      thread_pool_(thread_pool),
      is_woken_up_(false),
      current_thread_(current_thread) {

#ifndef NDEBUG
    if(MESSAGE_SCHEDULER_GRANULARITY < (1 >> (MESSAGE_SCHEDULER_MAX_PRIORITY
                                               - MESSAGE_SCHEDULER_MIN_PRIORITY
                                               + 1))) {
        logWRN("MESSAGE_SCHEDULER_GRANULARITY is too small to honor some of the "
               "lower priorities");
    }
#endif

    queue_->watch_resource(event_.get_notify_fd(), poll_event_in, this);
}

linux_message_hub_t::~linux_message_hub_t() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        guarantee(queues_[i].msg_local_list.empty());
    }
    for (int p = MESSAGE_SCHEDULER_MIN_PRIORITY;
         p <= MESSAGE_SCHEDULER_MAX_PRIORITY;
         ++p) {

        guarantee(get_priority_msg_list(p).empty());
    }

    guarantee(incoming_messages_.empty());
}

void linux_message_hub_t::do_store_message(threadnum_t nthread, linux_thread_message_t *msg) {
    rassert(0 <= nthread.threadnum && nthread.threadnum < thread_pool_->n_threads);
    queues_[nthread.threadnum].msg_local_list.push_back(msg);
}

// Collects a message for a given thread onto a local list.
void linux_message_hub_t::store_message_ordered(threadnum_t nthread,
                                                linux_thread_message_t *msg) {
    rassert(!msg->is_ordered); // Each message object can only be enqueued once,
                               // and once it is removed, is_ordered is reset to false.
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    // We default to 1, not zero, to allow store_message_sometime messages to sometimes jump ahead of
    // store_message messages.
    msg->reloop_count_ = 1;
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    msg->is_ordered = true;
    do_store_message(nthread, msg);
}

int rand_reloop_count() {
    int x;
    frexp(randint(10000) / 10000.0, &x);
    int ret = -x;
    rassert(ret >= 0);
    return ret;
}

void linux_message_hub_t::store_message_sometime(threadnum_t nthread, linux_thread_message_t *msg) {
#ifndef NDEBUG
#if RDB_RELOOP_MESSAGES
    msg->reloop_count_ = rand_reloop_count();
#else
    msg->reloop_count_ = 0;
#endif
#endif  // NDEBUG
    do_store_message(nthread, msg);
}

void linux_message_hub_t::insert_external_message(linux_thread_message_t *msg) {
    bool do_wake_up;
    {
        spinlock_acq_t acq(&incoming_messages_lock_);
        do_wake_up = !check_and_set_is_woken_up();
        incoming_messages_.push_back(msg);
    }

    // Wakey wakey eggs and bakey
    if (do_wake_up) {
        event_.wakey_wakey();
    }
}

linux_message_hub_t::msg_list_t &linux_message_hub_t::get_priority_msg_list(int priority) {
    rassert(priority >= MESSAGE_SCHEDULER_MIN_PRIORITY);
    rassert(priority <= MESSAGE_SCHEDULER_MAX_PRIORITY);
    return priority_msg_lists_[priority - MESSAGE_SCHEDULER_MIN_PRIORITY];
}

void linux_message_hub_t::on_event(int events) {
    if (events != poll_event_in) {
        logERR("Unexpected event mask: %d", events);
    }

    // You must read wakey-wakeys so that the pipe-based implementation doesn't fill
    // up and so that poll-based event triggering doesn't infinite-loop.
    event_.consume_wakey_wakeys();

#ifndef NDEBUG
    start_watchdog(); // Initialize watchdog before handling messages
#endif

    const int num_priorities = MESSAGE_SCHEDULER_MAX_PRIORITY
                               - MESSAGE_SCHEDULER_MIN_PRIORITY
                               + 1;

    // Loop until we have processed at least the initial batch of messages.
    size_t num_initial_msgs_left_to_process[num_priorities];
    bool initial_batch_has_been_processed = false;
    bool initial_pass = true;
    do {
        if (!initial_pass) {
            // Other threads will automatically push their messages
            // for us into the incoming queue, even while
            // we are in this loop. However we still have to pick up
            // our local messages, since this->push_messages() is not
            // going to be called while we are still running on_event()
            deliver_local_messages();
        }

        // We guarantee to process all messages that are delivered
        // before the first pass. We do not guarantee to deliver
        // incoming messages delivered during !initial_pass!
        // As a consequence, we must reset is_woken_up_ in the first
        // pass, so later incoming messages wake us up again.
        const bool reset_is_woken_up = initial_pass;
        sort_incoming_messages_by_priority(reset_is_woken_up);

        // We store how many messages we have initially for each priority.
        // Those are the messages that we *definitely* have to process during
        // this call to `on_event()`.
        // We *may* process more messages than this, such that more recent
        // messages with a high-priority can bypass older messages with lower
        // priority.
        if (initial_pass) {
            for (int i = 0; i < num_priorities; ++i) {
                num_initial_msgs_left_to_process[i] = priority_msg_lists_[i].size();
            }
            initial_pass = false;
        }

        // Compute how many messages of MESSAGE_SCHEDULER_MAX_PRIORITY we process
        // before we check the incoming queues for new messages.
        // We call this the granularity of the message scheduler, and it is
        // MESSAGE_SCHEDULER_GRANULARITY or smaller.
        size_t total_pending_msgs = 0;
        for (int i = 0; i < num_priorities; ++i) {
            total_pending_msgs += priority_msg_lists_[i].size();
        }
        const size_t effective_granularity = std::min(total_pending_msgs,
                                                      MESSAGE_SCHEDULER_GRANULARITY);

        // Process a certain number of messages from each priority
        for (int current_priority = MESSAGE_SCHEDULER_MAX_PRIORITY;
             current_priority >= MESSAGE_SCHEDULER_MIN_PRIORITY; --current_priority) {

            // Compute how many messages of `current_priority` we want to process
            // in this pass.
            // The priority has an exponential effect on how many messages
            // get processed, i.e. if we process 8 messages of priority 1 per pass,
            // we are going to process up to 16 messages of priority 2, 32 of
            // priority 3 and so on.
            // However, we process at least one message of each priority level per
            // pass (in case the granularity is too small).
            int priority_exponent = MESSAGE_SCHEDULER_MAX_PRIORITY - current_priority;
            size_t to_process_from_priority = std::max(1ul, effective_granularity >> priority_exponent);

            while (linux_thread_message_t *m = get_priority_msg_list(current_priority).head()) {
                if (to_process_from_priority == 0) break;

                get_priority_msg_list(current_priority).remove(m);
                --to_process_from_priority;
                if (num_initial_msgs_left_to_process[current_priority - MESSAGE_SCHEDULER_MIN_PRIORITY] > 0) {
                    // About to process one of the initial messages
                    --num_initial_msgs_left_to_process[current_priority - MESSAGE_SCHEDULER_MIN_PRIORITY];
                }

#ifndef NDEBUG
                if (m->reloop_count_ > 0) {
                    --m->reloop_count_;
                    do_store_message(current_thread_, m);
                    continue;
                }
#endif

                m->on_thread_switch();

#ifndef NDEBUG
                pet_watchdog(); // Verify that each message completes in the acceptable time range
#endif
            }
        }

        // Check if we have to continue in order to fulfill our guarantee
        // to at least process all of the initial messages.
        initial_batch_has_been_processed = true;
        for (int i = 0; i < num_priorities; ++i) {
            if (num_initial_msgs_left_to_process[i] > 0) {
                initial_batch_has_been_processed = false;
                break;
            }
        }
    } while (!initial_batch_has_been_processed);
}

void linux_message_hub_t::sort_incoming_messages_by_priority(bool reset_is_woken_up) {
    // We do this in two steps to release the spinlock faster.
    // append_and_clear is a very cheap operation, while
    // assigning each message to a different priority queue
    // is more expensive.

    // 1. Pull the messages
    msg_list_t new_messages;
    {
        spinlock_acq_t acq(&incoming_messages_lock_);
        new_messages.append_and_clear(&incoming_messages_);
        if (reset_is_woken_up) {
            is_woken_up_ = false;
        }
    }

    // 2. Sort the messages into their respective priority queues
    while (linux_thread_message_t *m = new_messages.head()) {
        new_messages.remove(m);
        int effective_priority = m->priority;
        if (m->is_ordered) {
            // Ordered messages are treated as if they had
            // priority MESSAGE_SCHEDULER_ORDERED_PRIORITY.
            // This ensures that they can never bypass another
            // ordered message.
            effective_priority = MESSAGE_SCHEDULER_ORDERED_PRIORITY;
            m->is_ordered = false;
        }
        get_priority_msg_list(effective_priority).push_back(m);
    }
}

void linux_message_hub_t::deliver_local_messages() {
    const int local_thread = thread_pool_->thread_id;

    if (!queues_[local_thread].msg_local_list.empty()) {
        bool do_wake_up;
        {
            spinlock_acq_t acq(&incoming_messages_lock_);
            incoming_messages_.append_and_clear(&queues_[local_thread].msg_local_list);
            do_wake_up = !check_and_set_is_woken_up();
        }
        if (do_wake_up) {
            // Wake ourselves up for another round.
            // While this might seem risky w.r.t. dead-locks when the event pipe
            // is full, it is actually ok because the is_woken_up() flag guarantees
            // that we only ever write one event onto this.
            event_.wakey_wakey();
        }
    }
}

bool linux_message_hub_t::check_and_set_is_woken_up() {
    const bool was_woken_up = is_woken_up_;
    is_woken_up_ = true;
    return was_woken_up;
}

// Pushes messages collected locally global lists available to all
// threads.
void linux_message_hub_t::push_messages() {
    for (int i = 0; i < thread_pool_->n_threads; i++) {
        // Append the local list for ith thread to that thread's global
        // message list.
        thread_queue_t *queue = &queues_[i];
        if (!queue->msg_local_list.empty()) {
            // Transfer messages to the other core

            bool do_wake_up;
            {
                spinlock_acq_t acq(&thread_pool_->threads[i]->message_hub.incoming_messages_lock_);

                // We only need to do a wake up if we're the first people to do a
                // wake up.
                do_wake_up =
                    !thread_pool_->threads[i]->message_hub.check_and_set_is_woken_up();

                thread_pool_->threads[i]->message_hub.incoming_messages_.append_and_clear(&queue->msg_local_list);
            }

            // Wakey wakey, perhaps eggs and bakey
            if (do_wake_up) {
                thread_pool_->threads[i]->message_hub.event_.wakey_wakey();
            }
        }
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: numberingtypelistbox.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: os $ $Date: 2002-11-21 09:29:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifdef PRECOMPILED
#include "ui_pch.hxx"
#endif

#pragma hdrstop

#ifndef _NUMBERINGTYPELISTBOX_HXX
#include <numberingtypelistbox.hxx>
#endif
#ifndef _MISC_HRC
#include <misc.hrc>
#endif
#ifndef _CNTTAB_HXX
#include <cnttab.hxx>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XDEFAULTNUMBERINGPROVIDER_HPP_
#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_TEXT_XNUMBERINGTYPEINFO_HPP_
#include <com/sun/star/text/XNumberingTypeInfo.hpp>
#endif
#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include <svtools/languageoptions.hxx>
#endif

using namespace com::sun::star::uno;
using namespace com::sun::star::text;
using namespace com::sun::star::lang;
using namespace com::sun::star::style;
using namespace rtl;

#define C2S(cChar) UniString::CreateFromAscii(cChar)
/* -----------------------------01.03.01 16:04--------------------------------

 ---------------------------------------------------------------------------*/
struct SwNumberingTypeListBox_Impl
{
    Reference<XNumberingTypeInfo> xInfo;
};
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
SwNumberingTypeListBox::SwNumberingTypeListBox( Window* pWin, const ResId& rResId,
        USHORT nTypeFlags ) :
    ListBox(pWin, rResId),
    pImpl(new SwNumberingTypeListBox_Impl)
{
    Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
    Reference < XInterface > xI = xMSF->createInstance(
        ::rtl::OUString::createFromAscii( "com.sun.star.text.DefaultNumberingProvider" ) );
    Reference<XDefaultNumberingProvider> xDefNum(xI, UNO_QUERY);
    DBG_ASSERT(xDefNum.is(), "service missing: \"com.sun.star.text.DefaultNumberingProvider\"")

    pImpl->xInfo = Reference<XNumberingTypeInfo>(xDefNum, UNO_QUERY);
    Reload(nTypeFlags);
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
SwNumberingTypeListBox::~SwNumberingTypeListBox()
{
    delete pImpl;
}
/* -----------------------------01.03.01 16:02--------------------------------

 ---------------------------------------------------------------------------*/
void SwNumberingTypeListBox::Reload(USHORT nTypeFlags)
{
    Clear();
    SwOLENames aNames(SW_RES(STRRES_NUMTYPES));
    ResStringArray& rNames = aNames.GetNames();
    for(sal_uInt16 i = 0; i < rNames.Count(); i++)
    {
        long nValue = rNames.GetValue(i);
        sal_Bool bInsert = sal_True;
        USHORT nPos = LISTBOX_APPEND;
        switch(nValue)
        {
            case  NumberingType::NUMBER_NONE:
                bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_NO_NUMBERING);
                nPos = 0;
             break;
            case  NumberingType::CHAR_SPECIAL:  bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_BULLET); break;
            case  NumberingType::PAGE_DESCRIPTOR:bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING); break;
            case  NumberingType::BITMAP:bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_BITMAP ); break;
        }
        if(bInsert)
        {
            USHORT nEntry = InsertEntry(rNames.GetString(i), nPos);
            SetEntryData( nEntry, (void*)nValue );
        }
    }
    //#104079# extended numberings are only insert when CJK support is switched on
    SvtLanguageOptions aLangOpt;
    if(0 != (nTypeFlags&INSERT_NUM_EXTENDED_TYPES) &&
            (aLangOpt.IsCJKFontEnabled() || aLangOpt.IsCTLFontEnabled()))
    {
        if(pImpl->xInfo.is())
        {
            Sequence<sal_Int16> aTypes = pImpl->xInfo->getSupportedNumberingTypes(  );
            const sal_Int16* pTypes = aTypes.getConstArray();
            for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
            {
                sal_Int16 nCurrent = pTypes[nType];
                if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
                {
                    if(LISTBOX_ENTRY_NOTFOUND == GetEntryPos((void*)(ULONG)nCurrent))
                    {
                        OUString aIdent = pImpl->xInfo->getNumberingIdentifier( nCurrent );
                        USHORT nPos = InsertEntry(aIdent);
                        SetEntryData(nPos,(void*)(ULONG)nCurrent);
                    }
                }
            }
        }
        SelectEntryPos(0);
    }
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
sal_Int16   SwNumberingTypeListBox::GetSelectedNumberingType()
{
    sal_Int16 nRet = 0;
    USHORT nSelPos = GetSelectEntryPos();
    if(LISTBOX_ENTRY_NOTFOUND != nSelPos)
        nRet = (sal_Int16)(ULONG)GetEntryData(nSelPos);
#ifdef DBG_UTIL
    else
        DBG_ERROR("SwNumberingTypeListBox not selected")
#endif
    return nRet;
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool    SwNumberingTypeListBox::SelectNumberingType(sal_Int16 nType)
{
    USHORT nPos = GetEntryPos((void*)(ULONG)nType);
    SelectEntryPos( nPos );
    return LISTBOX_ENTRY_NOTFOUND != nPos;
}

<commit_msg>INTEGRATION: CWS os8 (1.5.138); FILE MERGED 2003/04/03 07:14:46 os 1.5.138.1: #108583# precompiled headers removed<commit_after>/*************************************************************************
 *
 *  $RCSfile: numberingtypelistbox.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-17 15:37:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _NUMBERINGTYPELISTBOX_HXX
#include <numberingtypelistbox.hxx>
#endif
#ifndef _MISC_HRC
#include <misc.hrc>
#endif
#ifndef _CNTTAB_HXX
#include <cnttab.hxx>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XDEFAULTNUMBERINGPROVIDER_HPP_
#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_TEXT_XNUMBERINGTYPEINFO_HPP_
#include <com/sun/star/text/XNumberingTypeInfo.hpp>
#endif
#ifndef _SVTOOLS_LANGUAGEOPTIONS_HXX
#include <svtools/languageoptions.hxx>
#endif

using namespace com::sun::star::uno;
using namespace com::sun::star::text;
using namespace com::sun::star::lang;
using namespace com::sun::star::style;
using namespace rtl;

#define C2S(cChar) UniString::CreateFromAscii(cChar)
/* -----------------------------01.03.01 16:04--------------------------------

 ---------------------------------------------------------------------------*/
struct SwNumberingTypeListBox_Impl
{
    Reference<XNumberingTypeInfo> xInfo;
};
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
SwNumberingTypeListBox::SwNumberingTypeListBox( Window* pWin, const ResId& rResId,
        USHORT nTypeFlags ) :
    ListBox(pWin, rResId),
    pImpl(new SwNumberingTypeListBox_Impl)
{
    Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
    Reference < XInterface > xI = xMSF->createInstance(
        ::rtl::OUString::createFromAscii( "com.sun.star.text.DefaultNumberingProvider" ) );
    Reference<XDefaultNumberingProvider> xDefNum(xI, UNO_QUERY);
    DBG_ASSERT(xDefNum.is(), "service missing: \"com.sun.star.text.DefaultNumberingProvider\"")

    pImpl->xInfo = Reference<XNumberingTypeInfo>(xDefNum, UNO_QUERY);
    Reload(nTypeFlags);
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
SwNumberingTypeListBox::~SwNumberingTypeListBox()
{
    delete pImpl;
}
/* -----------------------------01.03.01 16:02--------------------------------

 ---------------------------------------------------------------------------*/
void SwNumberingTypeListBox::Reload(USHORT nTypeFlags)
{
    Clear();
    SwOLENames aNames(SW_RES(STRRES_NUMTYPES));
    ResStringArray& rNames = aNames.GetNames();
    for(sal_uInt16 i = 0; i < rNames.Count(); i++)
    {
        long nValue = rNames.GetValue(i);
        sal_Bool bInsert = sal_True;
        USHORT nPos = LISTBOX_APPEND;
        switch(nValue)
        {
            case  NumberingType::NUMBER_NONE:
                bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_NO_NUMBERING);
                nPos = 0;
             break;
            case  NumberingType::CHAR_SPECIAL:  bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_BULLET); break;
            case  NumberingType::PAGE_DESCRIPTOR:bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_PAGE_STYLE_NUMBERING); break;
            case  NumberingType::BITMAP:bInsert = 0 != (nTypeFlags&INSERT_NUM_TYPE_BITMAP ); break;
        }
        if(bInsert)
        {
            USHORT nEntry = InsertEntry(rNames.GetString(i), nPos);
            SetEntryData( nEntry, (void*)nValue );
        }
    }
    //#104079# extended numberings are only insert when CJK support is switched on
    SvtLanguageOptions aLangOpt;
    if(0 != (nTypeFlags&INSERT_NUM_EXTENDED_TYPES) &&
            (aLangOpt.IsCJKFontEnabled() || aLangOpt.IsCTLFontEnabled()))
    {
        if(pImpl->xInfo.is())
        {
            Sequence<sal_Int16> aTypes = pImpl->xInfo->getSupportedNumberingTypes(  );
            const sal_Int16* pTypes = aTypes.getConstArray();
            for(sal_Int32 nType = 0; nType < aTypes.getLength(); nType++)
            {
                sal_Int16 nCurrent = pTypes[nType];
                if(nCurrent > NumberingType::CHARS_LOWER_LETTER_N)
                {
                    if(LISTBOX_ENTRY_NOTFOUND == GetEntryPos((void*)(ULONG)nCurrent))
                    {
                        OUString aIdent = pImpl->xInfo->getNumberingIdentifier( nCurrent );
                        USHORT nPos = InsertEntry(aIdent);
                        SetEntryData(nPos,(void*)(ULONG)nCurrent);
                    }
                }
            }
        }
        SelectEntryPos(0);
    }
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
sal_Int16   SwNumberingTypeListBox::GetSelectedNumberingType()
{
    sal_Int16 nRet = 0;
    USHORT nSelPos = GetSelectEntryPos();
    if(LISTBOX_ENTRY_NOTFOUND != nSelPos)
        nRet = (sal_Int16)(ULONG)GetEntryData(nSelPos);
#ifdef DBG_UTIL
    else
        DBG_ERROR("SwNumberingTypeListBox not selected")
#endif
    return nRet;
}
/* -----------------------------01.03.01 14:46--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool    SwNumberingTypeListBox::SelectNumberingType(sal_Int16 nType)
{
    USHORT nPos = GetEntryPos((void*)(ULONG)nType);
    SelectEntryPos( nPos );
    return LISTBOX_ENTRY_NOTFOUND != nPos;
}

<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

/// \file disparitydebug.cc
///

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Stereo/DisparityMap.h>
#include <vw/tools/Common.h>
#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>
using namespace vw;
using namespace vw::stereo;

namespace po = boost::program_options;
namespace fs = boost::filesystem;

struct Options : asp::BaseOptions {
  // Input
  std::string input_file_name;

  // Output
  std::string output_prefix, output_file_type;
};

void handle_arguments( int argc, char *argv[], Options& opt ) {
  po::options_description general_options("");
  general_options.add_options()
    ("output-prefix,o", po::value(&opt.output_prefix), "Specify the output prefix")
    ("output-filetype,t", po::value(&opt.output_file_type)->default_value("tif"), "Specify the output file");
  general_options.add( asp::BaseOptionsDescription(opt) );

  po::options_description positional("");
  positional.add_options()
    ("input-file", po::value(&opt.input_file_name), "Input disparity map");

  po::positional_options_description positional_desc;
  positional_desc.add("input-file", 1);

  std::string usage("[options] <input disparity map>");
  po::variables_map vm =
    asp::check_command_line( argc, argv, opt, general_options,
                             positional, positional_desc, usage );

  if ( opt.input_file_name.empty() )
    vw_throw( ArgumentErr() << "Missing input file!\n"
              << usage << general_options );
  if ( opt.output_prefix.empty() )
    opt.output_prefix = fs::path(opt.input_file_name).stem();
}

template <class PixelT>
void do_disparity_visualization(Options& opt) {
  DiskImageView<PixelT > disk_disparity_map(opt.input_file_name);

  vw_out() << "\t--> Computing disparity range \n";
  BBox2 disp_range = get_disparity_range(disk_disparity_map);
  vw_out() << "\t    Horizontal - [" << disp_range.min().x()
           << " " << disp_range.max().x() << "]    Vertical: ["
           << disp_range.min().y() << " " << disp_range.max().y() << "]\n";

  typedef typename PixelChannelType<PixelT>::type ChannelT;
  ImageViewRef<ChannelT> horizontal =
    apply_mask(copy_mask(clamp(normalize(select_channel(disk_disparity_map,0),
                                         disp_range.min().x(), disp_range.max().x(),
                                         ChannelRange<ChannelT>::min(),ChannelRange<ChannelT>::max())),
                         disk_disparity_map));
  ImageViewRef<ChannelT> vertical =
    apply_mask(copy_mask(clamp(normalize(select_channel(disk_disparity_map,1),
                                         disp_range.min().y(), disp_range.max().y(),
                                         ChannelRange<ChannelT>::min(),ChannelRange<ChannelT>::max())),
                         disk_disparity_map));

  vw_out() << "\t--> Saving disparity debug images\n";
  block_write_gdal_image( opt.output_prefix+"-H."+opt.output_file_type,
                          channel_cast_rescale<uint8>(horizontal),
                          opt, TerminalProgressCallback("asp","\t    Left  : "));
  block_write_gdal_image( opt.output_prefix + "-V." + opt.output_file_type,
                          channel_cast_rescale<uint8>(vertical),
                          opt, TerminalProgressCallback("asp","\t    Right : "));
}

int main( int argc, char *argv[] ) {

  Options opt;
  try {
    handle_arguments( argc, argv, opt );

    vw_out() << "Opening " << opt.input_file_name << "\n";
    ImageFormat fmt = tools::taste_image(opt.input_file_name);

    switch(fmt.pixel_format) {
    case VW_PIXEL_GENERIC_2_CHANNEL:
      switch (fmt.channel_type) {
      case VW_CHANNEL_INT32:
        do_disparity_visualization<Vector2i>(opt); break;
      default:
        do_disparity_visualization<Vector2f>(opt); break;
      } break;
    case VW_PIXEL_RGB:
    case VW_PIXEL_GENERIC_3_CHANNEL:
      switch (fmt.channel_type) {
      case VW_CHANNEL_INT32:
        do_disparity_visualization<PixelMask<Vector2i> >(opt); break;
      default:
        do_disparity_visualization<PixelMask<Vector2f> >(opt); break;
      } break;
    default:
      vw_throw( ArgumentErr() << "Unsupported pixel format. Expected GENERIC 2 or 3 CHANNEL image." );
    }

  } ASP_STANDARD_CATCHES;

  return 0;
}
<commit_msg>Speed up disparity debug range calculation<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2011 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

/// \file disparitydebug.cc
///

#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Stereo/DisparityMap.h>
#include <vw/tools/Common.h>
#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>
using namespace vw;
using namespace vw::stereo;

namespace po = boost::program_options;
namespace fs = boost::filesystem;

struct Options : asp::BaseOptions {
  // Input
  std::string input_file_name;

  // Output
  std::string output_prefix, output_file_type;
};

void handle_arguments( int argc, char *argv[], Options& opt ) {
  po::options_description general_options("");
  general_options.add_options()
    ("output-prefix,o", po::value(&opt.output_prefix), "Specify the output prefix")
    ("output-filetype,t", po::value(&opt.output_file_type)->default_value("tif"), "Specify the output file");
  general_options.add( asp::BaseOptionsDescription(opt) );

  po::options_description positional("");
  positional.add_options()
    ("input-file", po::value(&opt.input_file_name), "Input disparity map");

  po::positional_options_description positional_desc;
  positional_desc.add("input-file", 1);

  std::string usage("[options] <input disparity map>");
  po::variables_map vm =
    asp::check_command_line( argc, argv, opt, general_options,
                             positional, positional_desc, usage );

  if ( opt.input_file_name.empty() )
    vw_throw( ArgumentErr() << "Missing input file!\n"
              << usage << general_options );
  if ( opt.output_prefix.empty() )
    opt.output_prefix = fs::path(opt.input_file_name).stem();
}

template <class PixelT>
void do_disparity_visualization(Options& opt) {
  DiskImageView<PixelT > disk_disparity_map(opt.input_file_name);

  vw_out() << "\t--> Computing disparity range \n";

  // We don't want to sample every pixel as the image might be very
  // large. Let's subsample the image so that it is rough 1000x1000
  // samples.
  float subsample_amt =
    float(disk_disparity_map.cols())*float(disk_disparity_map.rows()) / ( 1000.f * 1000.f );
  BBox2 disp_range =
    get_disparity_range(subsample(disk_disparity_map,
                                  subsample_amt > 1 ? subsample_amt : 1));

  vw_out() << "\t    Horizontal - [" << disp_range.min().x()
           << " " << disp_range.max().x() << "]    Vertical: ["
           << disp_range.min().y() << " " << disp_range.max().y() << "]\n";

  typedef typename PixelChannelType<PixelT>::type ChannelT;
  ImageViewRef<ChannelT> horizontal =
    apply_mask(copy_mask(clamp(normalize(select_channel(disk_disparity_map,0),
                                         disp_range.min().x(), disp_range.max().x(),
                                         ChannelRange<ChannelT>::min(),ChannelRange<ChannelT>::max())),
                         disk_disparity_map));
  ImageViewRef<ChannelT> vertical =
    apply_mask(copy_mask(clamp(normalize(select_channel(disk_disparity_map,1),
                                         disp_range.min().y(), disp_range.max().y(),
                                         ChannelRange<ChannelT>::min(),ChannelRange<ChannelT>::max())),
                         disk_disparity_map));

  vw_out() << "\t--> Saving disparity debug images\n";
  block_write_gdal_image( opt.output_prefix+"-H."+opt.output_file_type,
                          channel_cast_rescale<uint8>(horizontal),
                          opt, TerminalProgressCallback("asp","\t    Left  : "));
  block_write_gdal_image( opt.output_prefix + "-V." + opt.output_file_type,
                          channel_cast_rescale<uint8>(vertical),
                          opt, TerminalProgressCallback("asp","\t    Right : "));
}

int main( int argc, char *argv[] ) {

  Options opt;
  try {
    handle_arguments( argc, argv, opt );

    vw_out() << "Opening " << opt.input_file_name << "\n";
    ImageFormat fmt = tools::taste_image(opt.input_file_name);

    switch(fmt.pixel_format) {
    case VW_PIXEL_GENERIC_2_CHANNEL:
      switch (fmt.channel_type) {
      case VW_CHANNEL_INT32:
        do_disparity_visualization<Vector2i>(opt); break;
      default:
        do_disparity_visualization<Vector2f>(opt); break;
      } break;
    case VW_PIXEL_RGB:
    case VW_PIXEL_GENERIC_3_CHANNEL:
      switch (fmt.channel_type) {
      case VW_CHANNEL_INT32:
        do_disparity_visualization<PixelMask<Vector2i> >(opt); break;
      default:
        do_disparity_visualization<PixelMask<Vector2f> >(opt); break;
      } break;
    default:
      vw_throw( ArgumentErr() << "Unsupported pixel format. Expected GENERIC 2 or 3 CHANNEL image." );
    }

  } ASP_STANDARD_CATCHES;

  return 0;
}
<|endoftext|>


<commit_before>//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/COFF.h"
using namespace llvm;

namespace {

class COFFAsmParser : public MCAsmParserExtension {
  template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
  void AddDirectiveHandler(StringRef Directive) {
    getParser().AddDirectiveHandler(this, Directive,
                                    HandleDirective<COFFAsmParser, Handler>);
  }

  bool ParseSectionSwitch(StringRef Section,
                          unsigned Characteristics,
                          SectionKind Kind);

  virtual void Initialize(MCAsmParser &Parser) {
    // Call the base implementation.
    MCAsmParserExtension::Initialize(Parser);

    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");

    // Win64 EH directives.
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
                                                                   ".seh_proc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
                                                                ".seh_endproc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
                                                           ".seh_startchained");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
                                                             ".seh_endchained");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
                                                                ".seh_handler");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
                                                            ".seh_handlerdata");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
                                                                ".seh_pushreg");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
                                                               ".seh_setframe");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
                                                             ".seh_stackalloc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
                                                                ".seh_savereg");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
                                                                ".seh_savexmm");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
                                                              ".seh_pushframe");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
                                                            ".seh_endprologue");
  }

  bool ParseSectionDirectiveText(StringRef, SMLoc) {
    return ParseSectionSwitch(".text",
                              COFF::IMAGE_SCN_CNT_CODE
                            | COFF::IMAGE_SCN_MEM_EXECUTE
                            | COFF::IMAGE_SCN_MEM_READ,
                              SectionKind::getText());
  }
  bool ParseSectionDirectiveData(StringRef, SMLoc) {
    return ParseSectionSwitch(".data",
                              COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getDataRel());
  }
  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
    return ParseSectionSwitch(".bss",
                              COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getBSS());
  }

  bool ParseDirectiveDef(StringRef, SMLoc);
  bool ParseDirectiveScl(StringRef, SMLoc);
  bool ParseDirectiveType(StringRef, SMLoc);
  bool ParseDirectiveEndef(StringRef, SMLoc);

  // Win64 EH directives.
  bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
  bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
  bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
  bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
  bool ParseSEHDirectiveHandler(StringRef, SMLoc);
  bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
  bool ParseSEHDirectivePushReg(StringRef, SMLoc L);
  bool ParseSEHDirectiveSetFrame(StringRef, SMLoc L);
  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc L);
  bool ParseSEHDirectiveSaveReg(StringRef, SMLoc L);
  bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc L);
  bool ParseSEHDirectivePushFrame(StringRef, SMLoc L);
  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);

  bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
public:
  COFFAsmParser() {}
};

} // end annonomous namespace.

bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
                                       unsigned Characteristics,
                                       SectionKind Kind) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in section switching directive");
  Lex();

  getStreamer().SwitchSection(getContext().getCOFFSection(
                                Section, Characteristics, Kind));

  return false;
}

bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
  StringRef SymbolName;

  if (getParser().ParseIdentifier(SymbolName))
    return TokError("expected identifier in directive");

  MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);

  getStreamer().BeginCOFFSymbolDef(Sym);

  Lex();
  return false;
}

bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
  int64_t SymbolStorageClass;
  if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
  return false;
}

bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
  int64_t Type;
  if (getParser().ParseAbsoluteExpression(Type))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitCOFFSymbolType(Type);
  return false;
}

bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
  Lex();
  getStreamer().EndCOFFSymbolDef();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
  const MCExpr *e;
  const MCSymbolRefExpr *funcExpr;
  SMLoc startLoc = getLexer().getLoc();
  if (getParser().ParseExpression(e))
    return true;

  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
    return Error(startLoc, "expected symbol");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHStartProc(&funcExpr->getSymbol());
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndProc();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHStartChained();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndChained();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
  const MCExpr *e;
  const MCSymbolRefExpr *funcExpr;
  SMLoc startLoc = getLexer().getLoc();
  if (getParser().ParseExpression(e))
    return true;

  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
    return Error(startLoc, "expected symbol");

  bool unwind = false, except = false;
  if (!ParseAtUnwindOrAtExcept(unwind, except))
    return true;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    if (!ParseAtUnwindOrAtExcept(unwind, except))
      return true;
  }
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHHandler(&funcExpr->getSymbol(), unwind, except);
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHHandlerData();
  return false;
}

bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndProlog();
  return false;
}

bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
  StringRef identifier;
  SMLoc startLoc = getLexer().getLoc();
  if (!getParser().ParseIdentifier(identifier))
    return Error(startLoc, "expected @unwind or @except");
  if (identifier == "@unwind")
    unwind = true;
  else if (identifier == "@except")
    except = true;
  else
    return Error(startLoc, "expected @unwind or @except");
  return false;
}

namespace llvm {

MCAsmParserExtension *createCOFFAsmParser() {
  return new COFFAsmParser;
}

}
<commit_msg>Implement .seh_stackalloc and .seh_pushframe parsing.<commit_after>//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/COFF.h"
using namespace llvm;

namespace {

class COFFAsmParser : public MCAsmParserExtension {
  template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
  void AddDirectiveHandler(StringRef Directive) {
    getParser().AddDirectiveHandler(this, Directive,
                                    HandleDirective<COFFAsmParser, Handler>);
  }

  bool ParseSectionSwitch(StringRef Section,
                          unsigned Characteristics,
                          SectionKind Kind);

  virtual void Initialize(MCAsmParser &Parser) {
    // Call the base implementation.
    MCAsmParserExtension::Initialize(Parser);

    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
    AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
    AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");

    // Win64 EH directives.
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
                                                                   ".seh_proc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
                                                                ".seh_endproc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
                                                           ".seh_startchained");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
                                                             ".seh_endchained");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
                                                                ".seh_handler");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
                                                            ".seh_handlerdata");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
                                                                ".seh_pushreg");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
                                                               ".seh_setframe");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
                                                             ".seh_stackalloc");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
                                                                ".seh_savereg");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
                                                                ".seh_savexmm");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
                                                              ".seh_pushframe");
    AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
                                                            ".seh_endprologue");
  }

  bool ParseSectionDirectiveText(StringRef, SMLoc) {
    return ParseSectionSwitch(".text",
                              COFF::IMAGE_SCN_CNT_CODE
                            | COFF::IMAGE_SCN_MEM_EXECUTE
                            | COFF::IMAGE_SCN_MEM_READ,
                              SectionKind::getText());
  }
  bool ParseSectionDirectiveData(StringRef, SMLoc) {
    return ParseSectionSwitch(".data",
                              COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getDataRel());
  }
  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
    return ParseSectionSwitch(".bss",
                              COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
                            | COFF::IMAGE_SCN_MEM_READ
                            | COFF::IMAGE_SCN_MEM_WRITE,
                              SectionKind::getBSS());
  }

  bool ParseDirectiveDef(StringRef, SMLoc);
  bool ParseDirectiveScl(StringRef, SMLoc);
  bool ParseDirectiveType(StringRef, SMLoc);
  bool ParseDirectiveEndef(StringRef, SMLoc);

  // Win64 EH directives.
  bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
  bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
  bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
  bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
  bool ParseSEHDirectiveHandler(StringRef, SMLoc);
  bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
  bool ParseSEHDirectivePushReg(StringRef, SMLoc L);
  bool ParseSEHDirectiveSetFrame(StringRef, SMLoc L);
  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc L);
  bool ParseSEHDirectiveSaveReg(StringRef, SMLoc L);
  bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc L);
  bool ParseSEHDirectivePushFrame(StringRef, SMLoc L);
  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);

  bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
public:
  COFFAsmParser() {}
};

} // end annonomous namespace.

bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
                                       unsigned Characteristics,
                                       SectionKind Kind) {
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in section switching directive");
  Lex();

  getStreamer().SwitchSection(getContext().getCOFFSection(
                                Section, Characteristics, Kind));

  return false;
}

bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
  StringRef SymbolName;

  if (getParser().ParseIdentifier(SymbolName))
    return TokError("expected identifier in directive");

  MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);

  getStreamer().BeginCOFFSymbolDef(Sym);

  Lex();
  return false;
}

bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
  int64_t SymbolStorageClass;
  if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
  return false;
}

bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
  int64_t Type;
  if (getParser().ParseAbsoluteExpression(Type))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitCOFFSymbolType(Type);
  return false;
}

bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
  Lex();
  getStreamer().EndCOFFSymbolDef();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
  const MCExpr *e;
  const MCSymbolRefExpr *funcExpr;
  SMLoc startLoc = getLexer().getLoc();
  if (getParser().ParseExpression(e))
    return true;

  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
    return Error(startLoc, "expected symbol");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHStartProc(&funcExpr->getSymbol());
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndProc();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHStartChained();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndChained();
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
  const MCExpr *e;
  const MCSymbolRefExpr *funcExpr;
  SMLoc startLoc = getLexer().getLoc();
  if (getParser().ParseExpression(e))
    return true;

  if (!(funcExpr = dyn_cast<MCSymbolRefExpr>(e)))
    return Error(startLoc, "expected symbol");

  bool unwind = false, except = false;
  if (!ParseAtUnwindOrAtExcept(unwind, except))
    return true;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    if (!ParseAtUnwindOrAtExcept(unwind, except))
      return true;
  }
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHHandler(&funcExpr->getSymbol(), unwind, except);
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHHandlerData();
  return false;
}

bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
  int64_t Size;
  if (getParser().ParseAbsoluteExpression(Size))
    return true;

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHAllocStack(Size);
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
  return Error(L, "not implemented yet");
}

bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
  bool Code;
  StringRef CodeID;
  SMLoc startLoc = getLexer().getLoc();
  if (!getParser().ParseIdentifier(CodeID)) {
    if (CodeID != "@code")
      return Error(startLoc, "expected @code");
    Code = true;
  }

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  Lex();
  getStreamer().EmitWin64EHPushFrame(Code);
  return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
  Lex();
  getStreamer().EmitWin64EHEndProlog();
  return false;
}

bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
  StringRef identifier;
  SMLoc startLoc = getLexer().getLoc();
  if (!getParser().ParseIdentifier(identifier))
    return Error(startLoc, "expected @unwind or @except");
  if (identifier == "@unwind")
    unwind = true;
  else if (identifier == "@except")
    except = true;
  else
    return Error(startLoc, "expected @unwind or @except");
  return false;
}

namespace llvm {

MCAsmParserExtension *createCOFFAsmParser() {
  return new COFFAsmParser;
}

}
<|endoftext|>