<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include <caf/all.hpp>

#include "vast/concept/printable/std/chrono.hpp"
#include "vast/concept/printable/to_string.hpp"
#include "vast/concept/printable/vast/event.hpp"
#include "vast/concept/printable/vast/expression.hpp"
#include "vast/concept/printable/vast/uuid.hpp"
#include "vast/detail/assert.hpp"
#include "vast/event.hpp"
#include "vast/expression_visitors.hpp"
#include "vast/logger.hpp"
#include "vast/table_slice.hpp"
#include "vast/to_events.hpp"

#include "vast/system/archive.hpp"
#include "vast/system/atoms.hpp"
#include "vast/system/exporter.hpp"

#include "vast/detail/assert.hpp"

using namespace std::chrono;
using namespace std::string_literals;
using namespace caf;

namespace vast {
namespace system {

namespace {

void ship_results(stateful_actor<exporter_state>* self) {
  VAST_TRACE("");
  if (self->state.results.empty() || self->state.query.requested == 0) {
    return;
  }
  VAST_INFO(self, "relays", self->state.results.size(), "events");
  message msg;
  if (self->state.results.size() <= self->state.query.requested) {
    self->state.query.requested -= self->state.results.size();
    self->state.query.shipped += self->state.results.size();
    msg = make_message(std::move(self->state.results));
    self->state.results = {};
  } else {
    std::vector<event> remainder;
    remainder.reserve(self->state.results.size() - self->state.query.requested);
    auto begin = self->state.results.begin() + self->state.query.requested;
    auto end = self->state.results.end();
    std::move(begin, end, std::back_inserter(remainder));
    self->state.results.resize(self->state.query.requested);
    msg = make_message(std::move(self->state.results));
    self->state.results = std::move(remainder);
    self->state.query.shipped += self->state.query.requested;
    self->state.query.requested = 0;
  }
  self->send(self->state.sink, msg);
}

void report_statistics(stateful_actor<exporter_state>* self) {
  timespan runtime = steady_clock::now() - self->state.start;
  self->state.query.runtime = runtime;
  VAST_INFO(self, "completed in", runtime);
  self->send(self->state.sink, self->state.id, self->state.query);
  if (self->state.accountant) {
    auto hits = rank(self->state.hits);
    auto processed = self->state.query.processed;
    auto shipped = self->state.query.shipped;
    auto results = shipped + self->state.results.size();
    auto selectivity = double(results) / hits;
    self->send(self->state.accountant, "exporter.hits", hits);
    self->send(self->state.accountant, "exporter.processed", processed);
    self->send(self->state.accountant, "exporter.results", results);
    self->send(self->state.accountant, "exporter.shipped", shipped);
    self->send(self->state.accountant, "exporter.selectivity", selectivity);
    self->send(self->state.accountant, "exporter.runtime", runtime);
  }
}

void shutdown(stateful_actor<exporter_state>* self, caf::error err) {
  VAST_DEBUG(self, "initiates shutdown with error", self->system().render(err));
  self->send_exit(self, std::move(err));
}

void shutdown(stateful_actor<exporter_state>* self) {
  if (has_continuous_option(self->state.options))
    return;
  VAST_DEBUG(self, "initiates shutdown");
  self->send_exit(self, exit_reason::normal);
}

void request_more_hits(stateful_actor<exporter_state>* self) {
  const auto& st = self->state;
  if (!has_historical_option(st.options))
    return;
  auto waiting_for_hits =
    st.query.received == st.query.scheduled;
  auto need_more_results = st.query.requested > 0;
  auto have_no_inflight_requests =
    st.query.lookups_issued == st.query.lookups_complete;
  // If we're (1) no longer waiting for index hits, (2) still need more
  // results, and (3) have no inflight requests to the archive, we ask
  // the index for more hits.
  if (!waiting_for_hits && need_more_results && have_no_inflight_requests) {
    auto remaining = st.query.expected - st.query.received;
    VAST_ASSERT(remaining > 0);
    // TODO: Figure out right number of partitions to ask for. For now, we
    // bound the number by an arbitrary constant.
    auto n = std::min(remaining, size_t{2});
    VAST_DEBUG(self, "asks index to process", n, "more partitions");
    self->send(st.index, st.id, n);
  }
}

} // namespace <anonymous>

behavior exporter(stateful_actor<exporter_state>* self, expression expr,
                  query_options options) {
  auto eu = self->system().dummy_execution_unit();
  self->state.sink = actor_pool::make(eu, actor_pool::broadcast());
  if (auto a = self->system().registry().get(accountant_atom::value))
    self->state.accountant = actor_cast<accountant_type>(a);
  self->state.options = options;
  if (has_continuous_option(options))
    VAST_DEBUG(self, "has continuous query option");
  self->set_exit_handler(
    [=](const exit_msg& msg) {
      VAST_DEBUG(self, "received exit from", msg.source, "with reason:", msg.reason);
      self->send<message_priority::high>(self->state.index, self->state.id, 0);
      self->send(self->state.sink, sys_atom::value, delete_atom::value);
      self->send_exit(self->state.sink, msg.reason);
      self->quit(msg.reason);
      if (msg.reason != exit_reason::kill)
        report_statistics(self);
    }
  );
  self->set_down_handler(
    [=](const down_msg& msg) {
      VAST_DEBUG(self, "received DOWN from", msg.source);
      if (has_continuous_option(self->state.options)
          && (msg.source == self->state.archive
              || msg.source == self->state.index))
        report_statistics(self);
    }
  );
  auto finished = [&](const query_status& qs) -> bool {
    return qs.received == qs.expected
      && qs.lookups_issued == qs.lookups_complete;
  };
  auto handle_batch = [=](std::vector<event> candidates) {
    VAST_DEBUG(self, "got batch of", candidates.size(), "events");
    auto sender = self->current_sender();
    for (auto& candidate : candidates) {
      auto& checker = self->state.checkers[candidate.type()];
      // Construct a candidate checker if we don't have one for this type.
      if (caf::holds_alternative<caf::none_t>(checker)) {
        auto x = tailor(expr, candidate.type());
        if (!x) {
          VAST_ERROR(self, "failed to tailor expression:",
                     self->system().render(x.error()));
          ship_results(self);
          self->send_exit(self, exit_reason::normal);
          return;
        }
        checker = std::move(*x);
        VAST_DEBUG(self, "tailored AST to", candidate.type() << ':', checker);
      }
      // Perform candidate check and keep event as result on success.
      if (caf::visit(event_evaluator{candidate}, checker))
        self->state.results.push_back(std::move(candidate));
      else
        VAST_DEBUG(self, "ignores false positive:", candidate);
    }
    self->state.query.processed += candidates.size();
    ship_results(self);
  };
  return {
    // The INDEX (or the EVALUATOR, to be more precise) sends us a series of
    // `ids` in response to an expression (query), terminated by 'done'.
    [=](ids& hits) {
      // Add `hits` to the total result set and update all stats.
      auto& st = self->state;
      timespan runtime = steady_clock::now() - st.start;
      st.query.runtime = runtime;
      auto count = rank(hits);
      if (st.accountant) {
        if (st.hits.empty())
          self->send(st.accountant, "exporter.hits.first", runtime);
        self->send(st.accountant, "exporter.hits.arrived", runtime);
        self->send(st.accountant, "exporter.hits.count", count);
      }
      if (count == 0) {
        VAST_WARNING(self, "got an empty delta from INDEX lookup");
      } else {
        VAST_DEBUG(self, "got", count, "index hits in [", (select(hits, 1)),
                   ',', (select(hits, -1) + 1), ')');
        st.hits |= hits;
        VAST_DEBUG(self, "forwards hits to archive");
        // FIXME: restrict according to configured limit.
        ++st.query.lookups_issued;
        self->send(st.archive, std::move(hits));
      }
    },
    [=](table_slice_ptr slice) {
      handle_batch(to_events(*slice, self->state.hits));
    },
    [=](done_atom) {
      // Figure out if we're done by bumping the counter for `received` and
      // check whether it reaches `expected`.
      auto& st = self->state;
      timespan runtime = steady_clock::now() - st.start;
      st.query.runtime = runtime;
      st.query.received += st.query.scheduled;
      if (st.query.received < st.query.expected) {
        VAST_DEBUG(self, "received", st.query.received, '/',
                   st.query.expected, "ID sets");
        request_more_hits(self);
      } else {
        VAST_DEBUG(self, "received all", st.query.expected,
                   "ID set(s) in", runtime);
        if (st.accountant)
          self->send(st.accountant, "exporter.hits.runtime", runtime);
        if (finished(st.query))
          shutdown(self);
      }
    },
    [=](done_atom, const caf::error& err) {
      auto& st = self->state;
      auto sender = self->current_sender();
      if (sender == st.archive) {
        if (err)
          VAST_DEBUG(self, "received error from archive:",
              self->system().render(err));
        ++st.query.lookups_complete;
      }
      if (finished(st.query))
        shutdown(self);
    },
    [=](extract_atom) {
      if (self->state.query.requested == max_events) {
        VAST_WARNING(self, "ignores extract request, already getting all");
        return;
      }
      self->state.query.requested = max_events;
      ship_results(self);
      request_more_hits(self);
    },
    [=](extract_atom, uint64_t requested) {
      if (self->state.query.requested == max_events) {
        VAST_WARNING(self, "ignores extract request, already getting all");
        return;
      }
      auto n = std::min(max_events - requested, requested);
      self->state.query.requested += n;
      VAST_DEBUG(self, "got request to extract", n, "new events in addition to",
                 self->state.query.requested, "pending results");
      ship_results(self);
      request_more_hits(self);
    },
    [=](const archive_type& archive) {
      VAST_DEBUG(self, "registers archive", archive);
      self->state.archive = archive;
      if (has_continuous_option(self->state.options))
        self->monitor(archive);
      // Register self at the archive
      if (has_historical_option(self->state.options))
        self->send(archive, exporter_atom::value, self);
    },
    [=](index_atom, const actor& index) {
      VAST_DEBUG(self, "registers index", index);
      self->state.index = index;
      if (has_continuous_option(self->state.options))
        self->monitor(index);
    },
    [=](sink_atom, const actor& sink) {
      VAST_DEBUG(self, "registers sink", sink);
      self->send(self->state.sink, sys_atom::value, put_atom::value, sink);
      self->monitor(self->state.sink);
    },
    [=](importer_atom, const std::vector<actor>& importers) {
      // Register for events at running IMPORTERs.
      if (has_continuous_option(self->state.options))
        for (auto& x : importers)
          self->send(x, exporter_atom::value, self);
    },
    [=](run_atom) {
      VAST_INFO(self, "executes query", expr);
      self->state.start = steady_clock::now();
      if (!has_historical_option(self->state.options))
        return;
      self->request(self->state.index, infinite, expr).then(
        [=](const uuid& lookup, size_t partitions, size_t scheduled) {
          VAST_DEBUG(self, "got lookup handle", lookup << ", scheduled",
                     scheduled << '/' << partitions, "partitions");
          self->state.id = lookup;
          if (partitions > 0) {
            self->state.query.expected = partitions;
            self->state.query.scheduled = scheduled;
          } else {
            shutdown(self);
          }
        },
        [=](const error& e) {
          shutdown(self, e);
        }
      );
    },
    [=](caf::stream<table_slice_ptr> in) {
      return self->make_sink(
        in,
        [](caf::unit_t&) {
          // nop
        },
        [=](caf::unit_t&, const table_slice_ptr& slice) {
          // TODO: port to new table slice API
          auto candidates = to_events(*slice);
          handle_batch(std::move(candidates));
        },
        [=](caf::unit_t&, const error& err) {
          VAST_IGNORE_UNUSED(err);
          VAST_ERROR(self, "got error during streaming: ", err);
        }
      );
    },
  };
}

} // namespace system
} // namespace vast
<commit_msg>Clarify log message text<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include <caf/all.hpp>

#include "vast/concept/printable/std/chrono.hpp"
#include "vast/concept/printable/to_string.hpp"
#include "vast/concept/printable/vast/event.hpp"
#include "vast/concept/printable/vast/expression.hpp"
#include "vast/concept/printable/vast/uuid.hpp"
#include "vast/detail/assert.hpp"
#include "vast/event.hpp"
#include "vast/expression_visitors.hpp"
#include "vast/logger.hpp"
#include "vast/table_slice.hpp"
#include "vast/to_events.hpp"

#include "vast/system/archive.hpp"
#include "vast/system/atoms.hpp"
#include "vast/system/exporter.hpp"

#include "vast/detail/assert.hpp"

using namespace std::chrono;
using namespace std::string_literals;
using namespace caf;

namespace vast {
namespace system {

namespace {

void ship_results(stateful_actor<exporter_state>* self) {
  VAST_TRACE("");
  if (self->state.results.empty() || self->state.query.requested == 0) {
    return;
  }
  VAST_INFO(self, "relays", self->state.results.size(), "events");
  message msg;
  if (self->state.results.size() <= self->state.query.requested) {
    self->state.query.requested -= self->state.results.size();
    self->state.query.shipped += self->state.results.size();
    msg = make_message(std::move(self->state.results));
    self->state.results = {};
  } else {
    std::vector<event> remainder;
    remainder.reserve(self->state.results.size() - self->state.query.requested);
    auto begin = self->state.results.begin() + self->state.query.requested;
    auto end = self->state.results.end();
    std::move(begin, end, std::back_inserter(remainder));
    self->state.results.resize(self->state.query.requested);
    msg = make_message(std::move(self->state.results));
    self->state.results = std::move(remainder);
    self->state.query.shipped += self->state.query.requested;
    self->state.query.requested = 0;
  }
  self->send(self->state.sink, msg);
}

void report_statistics(stateful_actor<exporter_state>* self) {
  timespan runtime = steady_clock::now() - self->state.start;
  self->state.query.runtime = runtime;
  VAST_INFO(self, "completed in", runtime);
  self->send(self->state.sink, self->state.id, self->state.query);
  if (self->state.accountant) {
    auto hits = rank(self->state.hits);
    auto processed = self->state.query.processed;
    auto shipped = self->state.query.shipped;
    auto results = shipped + self->state.results.size();
    auto selectivity = double(results) / hits;
    self->send(self->state.accountant, "exporter.hits", hits);
    self->send(self->state.accountant, "exporter.processed", processed);
    self->send(self->state.accountant, "exporter.results", results);
    self->send(self->state.accountant, "exporter.shipped", shipped);
    self->send(self->state.accountant, "exporter.selectivity", selectivity);
    self->send(self->state.accountant, "exporter.runtime", runtime);
  }
}

void shutdown(stateful_actor<exporter_state>* self, caf::error err) {
  VAST_DEBUG(self, "initiates shutdown with error", self->system().render(err));
  self->send_exit(self, std::move(err));
}

void shutdown(stateful_actor<exporter_state>* self) {
  if (has_continuous_option(self->state.options))
    return;
  VAST_DEBUG(self, "initiates shutdown");
  self->send_exit(self, exit_reason::normal);
}

void request_more_hits(stateful_actor<exporter_state>* self) {
  const auto& st = self->state;
  if (!has_historical_option(st.options))
    return;
  auto waiting_for_hits =
    st.query.received == st.query.scheduled;
  auto need_more_results = st.query.requested > 0;
  auto have_no_inflight_requests =
    st.query.lookups_issued == st.query.lookups_complete;
  // If we're (1) no longer waiting for index hits, (2) still need more
  // results, and (3) have no inflight requests to the archive, we ask
  // the index for more hits.
  if (!waiting_for_hits && need_more_results && have_no_inflight_requests) {
    auto remaining = st.query.expected - st.query.received;
    VAST_ASSERT(remaining > 0);
    // TODO: Figure out right number of partitions to ask for. For now, we
    // bound the number by an arbitrary constant.
    auto n = std::min(remaining, size_t{2});
    VAST_DEBUG(self, "asks index to process", n, "more partitions");
    self->send(st.index, st.id, n);
  }
}

} // namespace <anonymous>

behavior exporter(stateful_actor<exporter_state>* self, expression expr,
                  query_options options) {
  auto eu = self->system().dummy_execution_unit();
  self->state.sink = actor_pool::make(eu, actor_pool::broadcast());
  if (auto a = self->system().registry().get(accountant_atom::value))
    self->state.accountant = actor_cast<accountant_type>(a);
  self->state.options = options;
  if (has_continuous_option(options))
    VAST_DEBUG(self, "has continuous query option");
  self->set_exit_handler(
    [=](const exit_msg& msg) {
      VAST_DEBUG(self, "received exit from", msg.source, "with reason:", msg.reason);
      self->send<message_priority::high>(self->state.index, self->state.id, 0);
      self->send(self->state.sink, sys_atom::value, delete_atom::value);
      self->send_exit(self->state.sink, msg.reason);
      self->quit(msg.reason);
      if (msg.reason != exit_reason::kill)
        report_statistics(self);
    }
  );
  self->set_down_handler(
    [=](const down_msg& msg) {
      VAST_DEBUG(self, "received DOWN from", msg.source);
      if (has_continuous_option(self->state.options)
          && (msg.source == self->state.archive
              || msg.source == self->state.index))
        report_statistics(self);
    }
  );
  auto finished = [&](const query_status& qs) -> bool {
    return qs.received == qs.expected
      && qs.lookups_issued == qs.lookups_complete;
  };
  auto handle_batch = [=](std::vector<event> candidates) {
    VAST_DEBUG(self, "got batch of", candidates.size(), "events");
    auto sender = self->current_sender();
    for (auto& candidate : candidates) {
      auto& checker = self->state.checkers[candidate.type()];
      // Construct a candidate checker if we don't have one for this type.
      if (caf::holds_alternative<caf::none_t>(checker)) {
        auto x = tailor(expr, candidate.type());
        if (!x) {
          VAST_ERROR(self, "failed to tailor expression:",
                     self->system().render(x.error()));
          ship_results(self);
          self->send_exit(self, exit_reason::normal);
          return;
        }
        checker = std::move(*x);
        VAST_DEBUG(self, "tailored AST to", candidate.type() << ':', checker);
      }
      // Perform candidate check and keep event as result on success.
      if (caf::visit(event_evaluator{candidate}, checker))
        self->state.results.push_back(std::move(candidate));
      else
        VAST_DEBUG(self, "ignores false positive:", candidate);
    }
    self->state.query.processed += candidates.size();
    ship_results(self);
  };
  return {
    // The INDEX (or the EVALUATOR, to be more precise) sends us a series of
    // `ids` in response to an expression (query), terminated by 'done'.
    [=](ids& hits) {
      // Add `hits` to the total result set and update all stats.
      auto& st = self->state;
      timespan runtime = steady_clock::now() - st.start;
      st.query.runtime = runtime;
      auto count = rank(hits);
      if (st.accountant) {
        if (st.hits.empty())
          self->send(st.accountant, "exporter.hits.first", runtime);
        self->send(st.accountant, "exporter.hits.arrived", runtime);
        self->send(st.accountant, "exporter.hits.count", count);
      }
      if (count == 0) {
        VAST_WARNING(self, "got empty hits");
      } else {
        VAST_DEBUG(self, "got", count, "index hits in [", (select(hits, 1)),
                   ',', (select(hits, -1) + 1), ')');
        st.hits |= hits;
        VAST_DEBUG(self, "forwards hits to archive");
        // FIXME: restrict according to configured limit.
        ++st.query.lookups_issued;
        self->send(st.archive, std::move(hits));
      }
    },
    [=](table_slice_ptr slice) {
      handle_batch(to_events(*slice, self->state.hits));
    },
    [=](done_atom) {
      // Figure out if we're done by bumping the counter for `received` and
      // check whether it reaches `expected`.
      auto& st = self->state;
      timespan runtime = steady_clock::now() - st.start;
      st.query.runtime = runtime;
      st.query.received += st.query.scheduled;
      if (st.query.received < st.query.expected) {
        VAST_DEBUG(self, "received", st.query.received, '/',
                   st.query.expected, "ID sets");
        request_more_hits(self);
      } else {
        VAST_DEBUG(self, "received all", st.query.expected,
                   "ID set(s) in", runtime);
        if (st.accountant)
          self->send(st.accountant, "exporter.hits.runtime", runtime);
        if (finished(st.query))
          shutdown(self);
      }
    },
    [=](done_atom, const caf::error& err) {
      auto& st = self->state;
      auto sender = self->current_sender();
      if (sender == st.archive) {
        if (err)
          VAST_DEBUG(self, "received error from archive:",
              self->system().render(err));
        ++st.query.lookups_complete;
      }
      if (finished(st.query))
        shutdown(self);
    },
    [=](extract_atom) {
      if (self->state.query.requested == max_events) {
        VAST_WARNING(self, "ignores extract request, already getting all");
        return;
      }
      self->state.query.requested = max_events;
      ship_results(self);
      request_more_hits(self);
    },
    [=](extract_atom, uint64_t requested) {
      if (self->state.query.requested == max_events) {
        VAST_WARNING(self, "ignores extract request, already getting all");
        return;
      }
      auto n = std::min(max_events - requested, requested);
      self->state.query.requested += n;
      VAST_DEBUG(self, "got request to extract", n, "new events in addition to",
                 self->state.query.requested, "pending results");
      ship_results(self);
      request_more_hits(self);
    },
    [=](const archive_type& archive) {
      VAST_DEBUG(self, "registers archive", archive);
      self->state.archive = archive;
      if (has_continuous_option(self->state.options))
        self->monitor(archive);
      // Register self at the archive
      if (has_historical_option(self->state.options))
        self->send(archive, exporter_atom::value, self);
    },
    [=](index_atom, const actor& index) {
      VAST_DEBUG(self, "registers index", index);
      self->state.index = index;
      if (has_continuous_option(self->state.options))
        self->monitor(index);
    },
    [=](sink_atom, const actor& sink) {
      VAST_DEBUG(self, "registers sink", sink);
      self->send(self->state.sink, sys_atom::value, put_atom::value, sink);
      self->monitor(self->state.sink);
    },
    [=](importer_atom, const std::vector<actor>& importers) {
      // Register for events at running IMPORTERs.
      if (has_continuous_option(self->state.options))
        for (auto& x : importers)
          self->send(x, exporter_atom::value, self);
    },
    [=](run_atom) {
      VAST_INFO(self, "executes query", expr);
      self->state.start = steady_clock::now();
      if (!has_historical_option(self->state.options))
        return;
      self->request(self->state.index, infinite, expr).then(
        [=](const uuid& lookup, size_t partitions, size_t scheduled) {
          VAST_DEBUG(self, "got lookup handle", lookup << ", scheduled",
                     scheduled << '/' << partitions, "partitions");
          self->state.id = lookup;
          if (partitions > 0) {
            self->state.query.expected = partitions;
            self->state.query.scheduled = scheduled;
          } else {
            shutdown(self);
          }
        },
        [=](const error& e) {
          shutdown(self, e);
        }
      );
    },
    [=](caf::stream<table_slice_ptr> in) {
      return self->make_sink(
        in,
        [](caf::unit_t&) {
          // nop
        },
        [=](caf::unit_t&, const table_slice_ptr& slice) {
          // TODO: port to new table slice API
          auto candidates = to_events(*slice);
          handle_batch(std::move(candidates));
        },
        [=](caf::unit_t&, const error& err) {
          VAST_IGNORE_UNUSED(err);
          VAST_ERROR(self, "got error during streaming: ", err);
        }
      );
    },
  };
}

} // namespace system
} // namespace vast
<|endoftext|>


<commit_before>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value, User, and SymTabValue classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/ValueHolderImpl.h"
#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/SymTabValue.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Type.h"
#ifndef NDEBUG      // Only in -g mode...
#include "llvm/Assembly/Writer.h"
#endif
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

Value::Value(const Type *ty, ValueTy vty, const string &name = "")
  : Name(name), Ty(ty, this) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
      cerr << "Use still stuck around after Def is destroyed:" << *I << endl;
  }
#endif
  assert(Uses.begin() == Uses.end());
}

void Value::replaceAllUsesWith(Value *D) {
  assert(D && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(D != this && "V->replaceAllUsesWith(V) is NOT valid!");
  while (!Uses.empty()) {
    User *Use = Uses.back();
#ifndef NDEBUG
    unsigned NumUses = Uses.size();
#endif
    Use->replaceUsesOfWith(this, D);

#ifndef NDEBUG      // only in -g mode...
    if (Uses.size() == NumUses)
      cerr << "Use: " << Use << "replace with: " << D;
#endif
    assert(Uses.size() != NumUses && "Didn't remove definition!");
  }
}

// refineAbstractType - This function is implemented because we use
// potentially abstract types, and these types may be resolved to more
// concrete types after we are constructed.  For the value class, we simply
// change Ty to point to the right type.  :)
//
void Value::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
  assert(Ty.get() == (const Type*)OldTy &&"Can't refine anything but my type!");
  Ty = NewTy;
}

void Value::killUse(User *i) {
  if (i == 0) return;
  use_iterator I = find(Uses.begin(), Uses.end(), i);

  assert(I != Uses.end() && "Use not in uses list!!");
  Uses.erase(I);
}

User *Value::use_remove(use_iterator &I) {
  assert(I != Uses.end() && "Trying to remove the end of the use list!!!");
  User *i = *I;
  I = Uses.erase(I);
  return i;
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

//===----------------------------------------------------------------------===//
//                             SymTabValue Class
//===----------------------------------------------------------------------===//

SymTabValue::SymTabValue(Value *p) : ValueParent(p) {
  assert(ValueParent && "SymTavValue without parent!?!");
  ParentSymTab = SymTab = 0;
}

SymTabValue::~SymTabValue() {
  delete SymTab;
}

void SymTabValue::setParentSymTab(SymbolTable *ST) {
  ParentSymTab = ST;
  if (SymTab)
    SymTab->setParentSymTab(ST);
}

SymbolTable *SymTabValue::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(ParentSymTab);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool SymTabValue::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin();
       I != SymTab->end(); ++I) {
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!
  }

  return false;
}
<commit_msg>Added debugging support.<commit_after>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value, User, and SymTabValue classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/ValueHolderImpl.h"
#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/SymTabValue.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Type.h"
#ifndef NDEBUG      // Only in -g mode...
#include "llvm/Assembly/Writer.h"
#endif
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

Value::Value(const Type *ty, ValueTy vty, const string &name = "")
  : Name(name), Ty(ty, this) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
      cerr << "Use still stuck around after Def is destroyed:" << *I << endl;
  }
#endif
  assert(Uses.begin() == Uses.end());
}

void Value::replaceAllUsesWith(Value *D) {
  assert(D && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(D != this && "V->replaceAllUsesWith(V) is NOT valid!");
  while (!Uses.empty()) {
    User *Use = Uses.back();
#ifndef NDEBUG
    unsigned NumUses = Uses.size();
#endif
    Use->replaceUsesOfWith(this, D);

#ifndef NDEBUG      // only in -g mode...
    if (Uses.size() == NumUses)
      cerr << "Use: " << Use << "replace with: " << D;
#endif
    assert(Uses.size() != NumUses && "Didn't remove definition!");
  }
}

// refineAbstractType - This function is implemented because we use
// potentially abstract types, and these types may be resolved to more
// concrete types after we are constructed.  For the value class, we simply
// change Ty to point to the right type.  :)
//
void Value::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
  assert(Ty.get() == (const Type*)OldTy &&"Can't refine anything but my type!");
  Ty = NewTy;
}

void Value::killUse(User *i) {
  if (i == 0) return;
  use_iterator I = find(Uses.begin(), Uses.end(), i);

  assert(I != Uses.end() && "Use not in uses list!!");
  Uses.erase(I);
}

User *Value::use_remove(use_iterator &I) {
  assert(I != Uses.end() && "Trying to remove the end of the use list!!!");
  User *i = *I;
  I = Uses.erase(I);
  return i;
}

void
Value::dump() const
{
  DebugValue(*this);
}

ostream&
operator<<(ostream &o, const Value& I)
{
  switch (I.getValueType()) {
  case Value::TypeVal:       return o << I.castTypeAsserting();
  case Value::ConstantVal:   WriteToAssembly((const ConstPoolVal*)&I,o);break;
  case Value::MethodArgumentVal: return o << I.getType() << " "<< I.getName();
  case Value::InstructionVal:WriteToAssembly((const Instruction *)&I, o);break;
  case Value::BasicBlockVal: WriteToAssembly((const BasicBlock  *)&I, o);break;
  case Value::MethodVal:     WriteToAssembly((const Method      *)&I, o);break;
  case Value::GlobalVal:     WriteToAssembly((const GlobalVariable*)&I,o);break;
  case Value::ModuleVal:     WriteToAssembly((const Module      *)&I,o); break;
  default: return o << "<unknown value type: " << I.getValueType() << ">";
  }
  return o;
}

void
DebugValue(const Value* V)
{
  if (V)
    cerr << *V << endl;
  else
    cerr << "<NULL value>" << endl;
}

void
DebugValue(const Value& V)
{
  cerr << V << endl;
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

//===----------------------------------------------------------------------===//
//                             SymTabValue Class
//===----------------------------------------------------------------------===//

SymTabValue::SymTabValue(Value *p) : ValueParent(p) {
  assert(ValueParent && "SymTavValue without parent!?!");
  ParentSymTab = SymTab = 0;
}

SymTabValue::~SymTabValue() {
  delete SymTab;
}

void SymTabValue::setParentSymTab(SymbolTable *ST) {
  ParentSymTab = ST;
  if (SymTab)
    SymTab->setParentSymTab(ST);
}

SymbolTable *SymTabValue::getSymbolTableSure() {
  if (!SymTab) SymTab = new SymbolTable(ParentSymTab);
  return SymTab;
}

// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it!
//
bool SymTabValue::hasSymbolTable() const {
  if (!SymTab) return false;

  for (SymbolTable::const_iterator I = SymTab->begin();
       I != SymTab->end(); ++I) {
    if (I->second.begin() != I->second.end())
      return true;                                // Found nonempty type plane!
  }

  return false;
}
<|endoftext|>


<commit_before><commit_msg>Fix sign mismatch issues.<commit_after><|endoftext|>


<commit_before>#include "acmacs-base/time-series.hh"
#include "acmacs-base/rjson-v3-helper.hh"
#include "acmacs-base/string-compare.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

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

//  "?start": "2019-01", "?end": "2019-11",
//  "interval": {"month": 1}, "?": "month, week, year, day (interval: month also supported)",
//  "output": "/path/name-{ts-name}.pdf",
// "shown-on-all": <Select Antigens>, -- reference antigens and sera are shown on all maps, select here other antigens to show on all the maps
//  "report": true

bool acmacs::mapi::v1::Settings::apply_time_series()
{
    using namespace std::string_view_literals;

    auto ts_params = getenv("interval"sv).visit([]<typename Val>(const Val& val) -> acmacs::time_series::parameters {
        if constexpr (std::is_same_v<Val, rjson::v3::detail::object>) {
            for (const auto& interval_n : {"year"sv, "month"sv, "week"sv, "day"sv}) {
                if (const auto& num = val[interval_n]; !num.is_null())
                    return {interval_n, num.template to<date::period_diff_t>()};
            }
            AD_WARNING("unrecognized interval specification: {}, month assumed", val);
            return {"month"sv};
        }
        else if constexpr (std::is_same_v<Val, rjson::v3::detail::string>) {
            return {val.template to<std::string_view>()};
        }
        else {
            AD_WARNING("unrecognized interval specification: {}, month assumed", val);
            return {"month"sv};
        }
    });

    if (const auto& start = getenv("start"sv); !start.is_null())
        ts_params.first = date::from_string(start.to<std::string_view>(), date::allow_incomplete::yes, date::throw_on_error::yes);
    if (const auto& end = getenv("end"sv); !end.is_null())
        ts_params.after_last = date::from_string(end.to<std::string_view>(), date::allow_incomplete::yes, date::throw_on_error::yes);

    const auto& chart_access = chart_draw().chart(0); // can draw just the chart 0 // get_chart(getenv("chart"sv), 0);
    const auto ts_stat = acmacs::time_series::stat(ts_params, chart_access.chart().antigens()->all_dates());
    const auto [first, after_last] = acmacs::time_series::suggest_start_end(ts_params, ts_stat);

    auto series = acmacs::time_series::make(ts_params);

    if (!ts_stat.counter().empty())
        AD_INFO("time series full range {} .. {}", ts_stat.counter().begin()->first, ts_stat.counter().rbegin()->first);
    AD_INFO("time series suggested  {} .. {}", first, after_last);
    AD_INFO("time series used       {} .. {}", ts_params.first, ts_params.after_last);
    if (rjson::v3::read_bool(getenv("report"sv), false)) {
        AD_INFO("time series report:\n{}", ts_stat.report("    {value}  {counter:6d}\n"));
    }

    if (const auto filename_pattern = rjson::v3::read_string(getenv("output"sv, toplevel_only::no, throw_if_partial_substitution::no)); filename_pattern.has_value()) {
        auto filename{substitute_chart_metadata(*filename_pattern, chart_access)};
        if (!acmacs::string::endswith_ignore_case(filename, ".pdf"sv))
            filename = fmt::format("{}.pdf", filename);
        chart_draw().calculate_viewport();
        chart_draw().draw(filename, rjson::v3::read_number(getenv("width"sv), 800.0), report_time::no);
    }
    else
        AD_WARNING("Cannot make time series: no \"output\" in {}", getenv_toplevel());
    return true;

} // acmacs::mapi::v1::Settings::apply_time_series

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

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>mapi: time series<commit_after>#include "acmacs-base/time-series.hh"
#include "acmacs-base/rjson-v3-helper.hh"
#include "acmacs-base/string-compare.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

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

//  "?start": "2019-01", "?end": "2019-11",
//  "interval": {"month": 1}, "?": "month, week, year, day (interval: month also supported)",
//  "output": "/path/name-{ts-name}.pdf",
// "shown-on-all": <Select Antigens>, -- reference antigens and sera are shown on all maps, select here other antigens to show on all the maps
//  "report": true

bool acmacs::mapi::v1::Settings::apply_time_series()
{
    using namespace std::string_view_literals;

    auto ts_params = getenv("interval"sv).visit([]<typename Val>(const Val& val) -> acmacs::time_series::parameters {
        if constexpr (std::is_same_v<Val, rjson::v3::detail::object>) {
            for (const auto& interval_n : {"year"sv, "month"sv, "week"sv, "day"sv}) {
                if (const auto& num = val[interval_n]; !num.is_null())
                    return {interval_n, num.template to<date::period_diff_t>()};
            }
            AD_WARNING("unrecognized interval specification: {}, month assumed", val);
            return {"month"sv};
        }
        else if constexpr (std::is_same_v<Val, rjson::v3::detail::string>) {
            return {val.template to<std::string_view>()};
        }
        else {
            AD_WARNING("unrecognized interval specification: {}, month assumed", val);
            return {"month"sv};
        }
    });

    if (const auto& start = getenv("start"sv); !start.is_null())
        ts_params.first = date::from_string(start.to<std::string_view>(), date::allow_incomplete::yes, date::throw_on_error::yes);
    if (const auto& end = getenv("end"sv); !end.is_null())
        ts_params.after_last = date::from_string(end.to<std::string_view>(), date::allow_incomplete::yes, date::throw_on_error::yes);

    const auto& chart_access = chart_draw().chart(0); // can draw just the chart 0 // get_chart(getenv("chart"sv), 0);
    const auto ts_stat = acmacs::time_series::stat(ts_params, chart_access.chart().antigens()->all_dates(acmacs::chart::Antigens::include_reference::no));
    const auto [first, after_last] = acmacs::time_series::suggest_start_end(ts_params, ts_stat);

    auto series = acmacs::time_series::make(ts_params);

    if (!ts_stat.counter().empty())
        AD_INFO("time series full range {} .. {}", ts_stat.counter().begin()->first, ts_stat.counter().rbegin()->first);
    AD_INFO("time series suggested  {} .. {}", first, after_last);
    AD_INFO("time series used       {} .. {}", ts_params.first, ts_params.after_last);
    if (rjson::v3::read_bool(getenv("report"sv), false)) {
        AD_INFO("time series report:\n{}", ts_stat.report("    {value}  {counter:6d}\n"));
    }

    if (const auto filename_pattern = rjson::v3::read_string(getenv("output"sv, toplevel_only::no, throw_if_partial_substitution::no)); filename_pattern.has_value()) {
        auto filename{substitute_chart_metadata(*filename_pattern, chart_access)};
        if (!acmacs::string::endswith_ignore_case(filename, ".pdf"sv))
            filename = fmt::format("{}.pdf", filename);
        chart_draw().calculate_viewport();
        chart_draw().draw(filename, rjson::v3::read_number(getenv("width"sv), 800.0), report_time::no);
    }
    else
        AD_WARNING("Cannot make time series: no \"output\" in {}", getenv_toplevel());
    return true;

} // acmacs::mapi::v1::Settings::apply_time_series

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

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include <node.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <string>
#include <string.h>
#include "lexer.h"

using namespace v8;

/* Type Definitions */
#define STRINGTYPE 0x03
#define COMMENTTYPE 0x01
#define KEYTYPE 0x02

/* State definitions */
#define NONESTATE 0x01
#define COMMENTSTATE 0x02
#define KEYSTATE 0x03
#define STRINGSTATE 0x04

#define VALLENGTH 100

char *v8StrToCharStar(v8::Local<v8::Value> value) {
    v8::String::Utf8Value string(value);
    char *str = (char *) malloc(string.length() + 1);
    strcpy(str, *string);
    return str;
}

void parse(const FunctionCallbackInfo<Value>& args) {
    bool escaped = false;
    char chr;
    int i;
    int ntokens;
    int state = NONESTATE;
    struct Token * tokens;
    char * po_string;
    char * buffer;

    buffer = NULL;
    tokens = NULL;
    ntokens = 0;

    Isolate* isolate = Isolate::GetCurrent();
    Local<Object> catalog_obj;
    Local<String> catalog_str;

    HandleScope scope(isolate);

    if (args.Length() < 1) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "Takes two arguments")));
        return;
    }

    if (!args[0]->IsString()) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "First argument must be a string")));
        return;
    }

    catalog_obj = Object::New(isolate);
    po_string = v8StrToCharStar(args[0]);
    catalog_str = args[0]->ToString();

    for (i = 0; i < catalog_str->Length(); i++) {
        chr = po_string[i];

        switch(state) {
            case NONESTATE:
                if (chr == '\'' || chr == '"') {
                    state = STRINGSTATE;
                    tokens = append(tokens, ntokens, STRINGTYPE, chr, NULL);
                    ++ntokens;
                } else if (chr == '#') {
                    state = COMMENTSTATE;
                    tokens = append(tokens, ntokens, COMMENTTYPE, '\0', NULL);
                    ++ntokens;
                } else if (!isspace(chr)) {
                    state = KEYSTATE;
                    buffer = append_to_buffer(buffer, chr);
                } else if (isspace(chr) && buffer != NULL) {
                    tokens = append(tokens, ntokens, KEYTYPE, '\0', buffer);
                    free(buffer);
                    buffer = NULL;
                    ++ntokens;
                }

                break;

            case COMMENTSTATE:
                if (chr == '\n') {
                    tokens = append(tokens, ntokens, COMMENTTYPE, '\0', buffer);
                    state = NONESTATE;
                    free(buffer);
                    buffer = NULL;
                    ++ntokens;
                } else if (chr != '\r') {
                    buffer = append_to_buffer(buffer, chr);
                }

                break;

            case STRINGSTATE:
                if(escaped) {
                    switch(chr) {
                        case 't':
                            buffer = append_to_buffer(buffer, '\t');
                            break;

                        case 'n':
                            buffer = append_to_buffer(buffer, '\n');
                            break;

                        case 'r':
                            buffer = append_to_buffer(buffer, '\r');
                            break;
                    }

                    escaped = false;

                } else {
                    if(chr == quote) {
                        tokens = append(tokens, ntokens, STRINGTYPE, quote, buffer);
                        free(buffer);
                        buffer = NULL;
                        state = NONESTATE;
                        ++ntokens;
                    } else if (chr == '\\') {
                        escaped = true;
                        break;
                    } else {
                        buffer = append_to_buffer(buffer, chr);
                    }
                    escaped = false;
                }

                break;

            case KEYSTATE:
                if(isalpha(chr) || chr == '-' || chr == '[' || chr == ']') {
                    buffer = append_to_buffer(buffer, chr);
                } else {
                    state = NONESTATE;
                    --i;
                }

                break;
        }
    }

    args.GetReturnValue().Set(catalog_obj);
    print_token_array(tokens, ntokens);
    free_token_array(tokens, ntokens);
    free(po_string);
}

void Init(Handle<Object> exports) {
    NODE_SET_METHOD(exports, "parse", parse);
}

NODE_MODULE(gettextlexer, Init)
<commit_msg>Record the quote type used in comments<commit_after>#include <node.h>
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <string>
#include <string.h>
#include "lexer.h"

using namespace v8;

/* Type Definitions */
#define STRINGTYPE 0x03
#define COMMENTTYPE 0x01
#define KEYTYPE 0x02

/* State definitions */
#define NONESTATE 0x01
#define COMMENTSTATE 0x02
#define KEYSTATE 0x03
#define STRINGSTATE 0x04

#define VALLENGTH 100

char *v8StrToCharStar(v8::Local<v8::Value> value) {
    v8::String::Utf8Value string(value);
    char *str = (char *) malloc(string.length() + 1);
    strcpy(str, *string);
    return str;
}

void parse(const FunctionCallbackInfo<Value>& args) {
    bool escaped = false;
    char chr;
    char quote;
    int i;
    int ntokens;
    int state = NONESTATE;
    struct Token * tokens;
    char * po_string;
    char * buffer;

    buffer = NULL;
    tokens = NULL;
    ntokens = 0;
    quote = '\0';

    Isolate* isolate = Isolate::GetCurrent();
    Local<Object> catalog_obj;
    Local<String> catalog_str;

    HandleScope scope(isolate);

    if (args.Length() < 1) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "Takes two arguments")));
        return;
    }

    if (!args[0]->IsString()) {
        isolate->ThrowException(Exception::TypeError(
            String::NewFromUtf8(isolate, "First argument must be a string")));
        return;
    }

    catalog_obj = Object::New(isolate);
    po_string = v8StrToCharStar(args[0]);
    catalog_str = args[0]->ToString();

    for (i = 0; i < catalog_str->Length(); i++) {
        chr = po_string[i];

        switch(state) {
            case NONESTATE:
                if (chr == '\'' || chr == '"') {
                    state = STRINGSTATE;
                    quote = chr;
                } else if (chr == '#') {
                    state = COMMENTSTATE;
                    tokens = append(tokens, ntokens, COMMENTTYPE, '\0', NULL);
                    ++ntokens;
                } else if (!isspace(chr)) {
                    state = KEYSTATE;
                    buffer = append_to_buffer(buffer, chr);
                } else if (isspace(chr) && buffer != NULL) {
                    tokens = append(tokens, ntokens, KEYTYPE, '\0', buffer);
                    free(buffer);
                    buffer = NULL;
                    ++ntokens;
                }

                break;

            case COMMENTSTATE:
                if (chr == '\n') {
                    tokens = append(tokens, ntokens, COMMENTTYPE, '\0', buffer);
                    state = NONESTATE;
                    free(buffer);
                    buffer = NULL;
                    ++ntokens;
                } else if (chr != '\r') {
                    buffer = append_to_buffer(buffer, chr);
                }

                break;

            case STRINGSTATE:
                if(escaped) {
                    switch(chr) {
                        case 't':
                            buffer = append_to_buffer(buffer, '\t');
                            break;

                        case 'n':
                            buffer = append_to_buffer(buffer, '\n');
                            break;

                        case 'r':
                            buffer = append_to_buffer(buffer, '\r');
                            break;
                    }

                    escaped = false;

                } else {
                    if(chr == quote) {
                        tokens = append(tokens, ntokens, STRINGTYPE, quote, buffer);
                        free(buffer);
                        buffer = NULL;
                        state = NONESTATE;
                        ++ntokens;
                    } else if (chr == '\\') {
                        escaped = true;
                        break;
                    } else {
                        buffer = append_to_buffer(buffer, chr);
                    }
                    escaped = false;
                }

                break;

            case KEYSTATE:
                if(isalpha(chr) || chr == '-' || chr == '[' || chr == ']') {
                    buffer = append_to_buffer(buffer, chr);
                } else {
                    state = NONESTATE;
                    --i;
                }

                break;
        }
    }

    args.GetReturnValue().Set(catalog_obj);
    print_token_array(tokens, ntokens);
    free_token_array(tokens, ntokens);
    free(po_string);
}

void Init(Handle<Object> exports) {
    NODE_SET_METHOD(exports, "parse", parse);
}

NODE_MODULE(gettextlexer, Init)
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_layout_test.h"

static const char kTestCompleteCookie[] = "status";
static const char kTestCompleteSuccess[] = "OK";

class WorkerTest : public UILayoutTest {
 protected:
  virtual ~WorkerTest() { }

  void RunTest(const std::wstring& test_case) {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    GURL url = GetTestUrl(L"workers", test_case);
    ASSERT_TRUE(tab->NavigateToURL(url));

    std::string value = WaitUntilCookieNonEmpty(tab.get(), url,
        kTestCompleteCookie, kTestIntervalMs, kTestWaitTimeoutMs);
    ASSERT_STREQ(kTestCompleteSuccess, value.c_str());
  }

  bool WaitForProcessCountToBe(int tabs, int workers) {
    // The 1 is for the browser process.
    int number_of_processes = 1 + workers +
        (UITest::in_process_renderer() ? 0 : tabs);
#if defined(OS_LINUX)
    // On Linux, we also have a zygote process and a sandbox host process.
    number_of_processes += 2;
#endif

    int cur_process_count;
    for (int i = 0; i < 10; ++i) {
      cur_process_count = GetBrowserProcessCount();
      if (cur_process_count == number_of_processes)
        return true;

      PlatformThread::Sleep(sleep_timeout_ms() / 10);
    }

    EXPECT_EQ(number_of_processes, cur_process_count);
    return false;
  }
};

TEST_F(WorkerTest, SingleWorker) {
  RunTest(L"single_worker.html");
}

TEST_F(WorkerTest, MultipleWorkers) {
  RunTest(L"multi_worker.html");
}

// WorkerFastLayoutTests works on the linux try servers.
#if defined(OS_LINUX)
#define WorkerFastLayoutTests DISABLED_WorkerFastLayoutTests
#endif

TEST_F(WorkerTest, WorkerFastLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    "stress-js-execution.html",
    "use-machine-stack.html",
    "worker-call.html",
    // Disabled because cloning ports are too slow in Chromium to meet the
    // thresholds in this test.
    // http://code.google.com/p/chromium/issues/detail?id=22780
    // "worker-cloneport.html",

    "worker-close.html",
    "worker-constructor.html",
    "worker-context-gc.html",
    "worker-context-multi-port.html",
    "worker-event-listener.html",
    "worker-gc.html",
    // worker-lifecycle.html relies on layoutTestController.workerThreadCount
    // which is not currently implemented.
    // "worker-lifecycle.html",
    "worker-location.html",
    "worker-messageport.html",
    // Disabled after r27089 (WebKit merge), http://crbug.com/22947
    // "worker-messageport-gc.html",
    "worker-multi-port.html",
    "worker-navigator.html",
    "worker-replace-global-constructor.html",
    "worker-replace-self.html",
    // Disabled afer r27553 (WebKit merge), http://crbug.com/23391
    // "worker-script-error.html",
    "worker-terminate.html",
    "worker-timeout.html"
  };

  FilePath fast_test_dir;
  fast_test_dir = fast_test_dir.AppendASCII("LayoutTests");
  fast_test_dir = fast_test_dir.AppendASCII("fast");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(fast_test_dir, worker_test_dir, false);

  // Worker tests also rely on common files in js/resources.
  FilePath js_dir = fast_test_dir.AppendASCII("js");
  FilePath resource_dir;
  resource_dir = resource_dir.AppendASCII("resources");
  AddResourceForLayoutTest(js_dir, resource_dir);

  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], false);
}

TEST_F(WorkerTest, WorkerHttpLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    // flakey? BUG 16934 "text-encoding.html",
#if defined(OS_WIN)
    // Fails on the mac (and linux?):
    // http://code.google.com/p/chromium/issues/detail?id=22599
    "worker-importScripts.html",
#endif
    "worker-redirect.html",
  };

  FilePath http_test_dir;
  http_test_dir = http_test_dir.AppendASCII("LayoutTests");
  http_test_dir = http_test_dir.AppendASCII("http");
  http_test_dir = http_test_dir.AppendASCII("tests");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(http_test_dir, worker_test_dir, true);

  StartHttpServer(new_http_root_dir_);
  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], true);
  StopHttpServer();
}

TEST_F(WorkerTest, WorkerXhrHttpLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    "abort-exception-assert.html",
#if defined(OS_WIN)
    // Fails on the mac (and linux?):
    // http://code.google.com/p/chromium/issues/detail?id=22599
    "close.html",
#endif
    //"methods-async.html",
    //"methods.html",
    "xmlhttprequest-file-not-found.html"
  };

  FilePath http_test_dir;
  http_test_dir = http_test_dir.AppendASCII("LayoutTests");
  http_test_dir = http_test_dir.AppendASCII("http");
  http_test_dir = http_test_dir.AppendASCII("tests");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("xmlhttprequest");
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(http_test_dir, worker_test_dir, true);

  StartHttpServer(new_http_root_dir_);
  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], true);
  StopHttpServer();
}

TEST_F(WorkerTest, MessagePorts) {
  static const char* kLayoutTestFiles[] = {
    "message-channel-gc.html",
    "message-channel-gc-2.html",
    "message-channel-gc-3.html",
    "message-channel-gc-4.html",
    "message-port.html",
    "message-port-clone.html",
    // http://code.google.com/p/chromium/issues/detail?id=23709
    // "message-port-constructor-for-deleted-document.html",
    "message-port-deleted-document.html",
    "message-port-deleted-frame.html",
    // http://crbug.com/23597 (caused by http://trac.webkit.org/changeset/48978)
    // "message-port-inactive-document.html",
    "message-port-multi.html",
    "message-port-no-wrapper.html",
    // Only works with run-webkit-tests --leaks.
    //"message-channel-listener-circular-ownership.html",
  };

  FilePath fast_test_dir;
  fast_test_dir = fast_test_dir.AppendASCII("LayoutTests");
  fast_test_dir = fast_test_dir.AppendASCII("fast");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("events");
  InitializeForLayoutTest(fast_test_dir, worker_test_dir, false);

  // MessagePort tests also rely on common files in js/resources.
  FilePath js_dir = fast_test_dir.AppendASCII("js");
  FilePath resource_dir;
  resource_dir = resource_dir.AppendASCII("resources");
  AddResourceForLayoutTest(js_dir, resource_dir);

  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], false);
}

// Disable LimitPerPage on Linux. Seems to work on Mac though:
// http://code.google.com/p/chromium/issues/detail?id=22608
#if !defined(OS_LINUX)
// This test fails after WebKit merge 49414:49432. (BUG=24652)
TEST_F(WorkerTest, LimitPerPage) {
  int max_workers_per_tab = WorkerService::kMaxWorkersPerTabWhenSeparate;
  GURL url = GetTestUrl(L"workers", L"many_workers.html");
  url = GURL(url.spec() + StringPrintf("?count=%d", max_workers_per_tab + 1));

  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(url));

  EXPECT_EQ(max_workers_per_tab + 1 + (UITest::in_process_renderer() ? 0 : 1),
            UITest::GetBrowserProcessCount());
}
#endif

TEST_F(WorkerTest, LimitTotal) {
  int max_workers_per_tab = WorkerService::kMaxWorkersPerTabWhenSeparate;
  int total_workers = WorkerService::kMaxWorkersWhenSeparate;

  int tab_count = (total_workers / max_workers_per_tab) + 1;
  GURL url = GetTestUrl(L"workers", L"many_workers.html");
  url = GURL(url.spec() + StringPrintf("?count=%d", max_workers_per_tab));

  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(url));
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  for (int i = 1; i < tab_count; ++i)
    window->AppendTab(url);

  // Check that we didn't create more than the max number of workers.
  ASSERT_TRUE(WaitForProcessCountToBe(tab_count, total_workers));

  // Now close a page and check that the queued workers were started.
  tab->NavigateToURL(GetTestUrl(L"google", L"google.html"));

  ASSERT_TRUE(WaitForProcessCountToBe(tab_count, total_workers));
}
<commit_msg>Re-enable worker-script-error.html in ui_test now that r49408 form WebKit has been rolled in.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_layout_test.h"

static const char kTestCompleteCookie[] = "status";
static const char kTestCompleteSuccess[] = "OK";

class WorkerTest : public UILayoutTest {
 protected:
  virtual ~WorkerTest() { }

  void RunTest(const std::wstring& test_case) {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());

    GURL url = GetTestUrl(L"workers", test_case);
    ASSERT_TRUE(tab->NavigateToURL(url));

    std::string value = WaitUntilCookieNonEmpty(tab.get(), url,
        kTestCompleteCookie, kTestIntervalMs, kTestWaitTimeoutMs);
    ASSERT_STREQ(kTestCompleteSuccess, value.c_str());
  }

  bool WaitForProcessCountToBe(int tabs, int workers) {
    // The 1 is for the browser process.
    int number_of_processes = 1 + workers +
        (UITest::in_process_renderer() ? 0 : tabs);
#if defined(OS_LINUX)
    // On Linux, we also have a zygote process and a sandbox host process.
    number_of_processes += 2;
#endif

    int cur_process_count;
    for (int i = 0; i < 10; ++i) {
      cur_process_count = GetBrowserProcessCount();
      if (cur_process_count == number_of_processes)
        return true;

      PlatformThread::Sleep(sleep_timeout_ms() / 10);
    }

    EXPECT_EQ(number_of_processes, cur_process_count);
    return false;
  }
};

TEST_F(WorkerTest, SingleWorker) {
  RunTest(L"single_worker.html");
}

TEST_F(WorkerTest, MultipleWorkers) {
  RunTest(L"multi_worker.html");
}

// WorkerFastLayoutTests works on the linux try servers.
#if defined(OS_LINUX)
#define WorkerFastLayoutTests DISABLED_WorkerFastLayoutTests
#endif

TEST_F(WorkerTest, WorkerFastLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    "stress-js-execution.html",
    "use-machine-stack.html",
    "worker-call.html",
    // Disabled because cloning ports are too slow in Chromium to meet the
    // thresholds in this test.
    // http://code.google.com/p/chromium/issues/detail?id=22780
    // "worker-cloneport.html",

    "worker-close.html",
    "worker-constructor.html",
    "worker-context-gc.html",
    "worker-context-multi-port.html",
    "worker-event-listener.html",
    "worker-gc.html",
    // worker-lifecycle.html relies on layoutTestController.workerThreadCount
    // which is not currently implemented.
    // "worker-lifecycle.html",
    "worker-location.html",
    "worker-messageport.html",
    // Disabled after r27089 (WebKit merge), http://crbug.com/22947
    // "worker-messageport-gc.html",
    "worker-multi-port.html",
    "worker-navigator.html",
    "worker-replace-global-constructor.html",
    "worker-replace-self.html",
    "worker-script-error.html",
    "worker-terminate.html",
    "worker-timeout.html"
  };

  FilePath fast_test_dir;
  fast_test_dir = fast_test_dir.AppendASCII("LayoutTests");
  fast_test_dir = fast_test_dir.AppendASCII("fast");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(fast_test_dir, worker_test_dir, false);

  // Worker tests also rely on common files in js/resources.
  FilePath js_dir = fast_test_dir.AppendASCII("js");
  FilePath resource_dir;
  resource_dir = resource_dir.AppendASCII("resources");
  AddResourceForLayoutTest(js_dir, resource_dir);

  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], false);
}

TEST_F(WorkerTest, WorkerHttpLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    // flakey? BUG 16934 "text-encoding.html",
#if defined(OS_WIN)
    // Fails on the mac (and linux?):
    // http://code.google.com/p/chromium/issues/detail?id=22599
    "worker-importScripts.html",
#endif
    "worker-redirect.html",
  };

  FilePath http_test_dir;
  http_test_dir = http_test_dir.AppendASCII("LayoutTests");
  http_test_dir = http_test_dir.AppendASCII("http");
  http_test_dir = http_test_dir.AppendASCII("tests");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(http_test_dir, worker_test_dir, true);

  StartHttpServer(new_http_root_dir_);
  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], true);
  StopHttpServer();
}

TEST_F(WorkerTest, WorkerXhrHttpLayoutTests) {
  static const char* kLayoutTestFiles[] = {
    "abort-exception-assert.html",
#if defined(OS_WIN)
    // Fails on the mac (and linux?):
    // http://code.google.com/p/chromium/issues/detail?id=22599
    "close.html",
#endif
    //"methods-async.html",
    //"methods.html",
    "xmlhttprequest-file-not-found.html"
  };

  FilePath http_test_dir;
  http_test_dir = http_test_dir.AppendASCII("LayoutTests");
  http_test_dir = http_test_dir.AppendASCII("http");
  http_test_dir = http_test_dir.AppendASCII("tests");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("xmlhttprequest");
  worker_test_dir = worker_test_dir.AppendASCII("workers");
  InitializeForLayoutTest(http_test_dir, worker_test_dir, true);

  StartHttpServer(new_http_root_dir_);
  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], true);
  StopHttpServer();
}

TEST_F(WorkerTest, MessagePorts) {
  static const char* kLayoutTestFiles[] = {
    "message-channel-gc.html",
    "message-channel-gc-2.html",
    "message-channel-gc-3.html",
    "message-channel-gc-4.html",
    "message-port.html",
    "message-port-clone.html",
    // http://code.google.com/p/chromium/issues/detail?id=23709
    // "message-port-constructor-for-deleted-document.html",
    "message-port-deleted-document.html",
    "message-port-deleted-frame.html",
    // http://crbug.com/23597 (caused by http://trac.webkit.org/changeset/48978)
    // "message-port-inactive-document.html",
    "message-port-multi.html",
    "message-port-no-wrapper.html",
    // Only works with run-webkit-tests --leaks.
    //"message-channel-listener-circular-ownership.html",
  };

  FilePath fast_test_dir;
  fast_test_dir = fast_test_dir.AppendASCII("LayoutTests");
  fast_test_dir = fast_test_dir.AppendASCII("fast");

  FilePath worker_test_dir;
  worker_test_dir = worker_test_dir.AppendASCII("events");
  InitializeForLayoutTest(fast_test_dir, worker_test_dir, false);

  // MessagePort tests also rely on common files in js/resources.
  FilePath js_dir = fast_test_dir.AppendASCII("js");
  FilePath resource_dir;
  resource_dir = resource_dir.AppendASCII("resources");
  AddResourceForLayoutTest(js_dir, resource_dir);

  for (size_t i = 0; i < arraysize(kLayoutTestFiles); ++i)
    RunLayoutTest(kLayoutTestFiles[i], false);
}

// Disable LimitPerPage on Linux. Seems to work on Mac though:
// http://code.google.com/p/chromium/issues/detail?id=22608
#if !defined(OS_LINUX)
// This test fails after WebKit merge 49414:49432. (BUG=24652)
TEST_F(WorkerTest, LimitPerPage) {
  int max_workers_per_tab = WorkerService::kMaxWorkersPerTabWhenSeparate;
  GURL url = GetTestUrl(L"workers", L"many_workers.html");
  url = GURL(url.spec() + StringPrintf("?count=%d", max_workers_per_tab + 1));

  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(url));

  EXPECT_EQ(max_workers_per_tab + 1 + (UITest::in_process_renderer() ? 0 : 1),
            UITest::GetBrowserProcessCount());
}
#endif

TEST_F(WorkerTest, LimitTotal) {
  int max_workers_per_tab = WorkerService::kMaxWorkersPerTabWhenSeparate;
  int total_workers = WorkerService::kMaxWorkersWhenSeparate;

  int tab_count = (total_workers / max_workers_per_tab) + 1;
  GURL url = GetTestUrl(L"workers", L"many_workers.html");
  url = GURL(url.spec() + StringPrintf("?count=%d", max_workers_per_tab));

  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(url));
  scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0));
  for (int i = 1; i < tab_count; ++i)
    window->AppendTab(url);

  // Check that we didn't create more than the max number of workers.
  ASSERT_TRUE(WaitForProcessCountToBe(tab_count, total_workers));

  // Now close a page and check that the queued workers were started.
  tab->NavigateToURL(GetTestUrl(L"google", L"google.html"));

  ASSERT_TRUE(WaitForProcessCountToBe(tab_count, total_workers));
}
<|endoftext|>


<commit_before><commit_msg>Enable worker layout tests after the WebKit patch to fix an assert is landed.<commit_after><|endoftext|>


<commit_before>//
// Created by jannis on 01.09.18.
//

#ifndef NOVA_RENDERER_X_11_WINDOW_HPP
#define NOVA_RENDERER_X_11_WINDOW_HPP

#ifdef NOVA_LINUX

#include <X11/Xlib.h>
#include <cstdint>
#include <nova_renderer/window.hpp>

namespace nova::renderer {
    class x11_window : public iwindow {
    private:
        Window window;
        Display* display;
        bool should_window_close = false;
        Atom wm_protocols;
        Atom wm_delete_window;

    public:
        explicit x11_window(uint32_t width, uint32_t height, const std::string& title);

        x11_window(x11_window&& other) noexcept = delete;
        x11_window& operator=(x11_window&& other) noexcept = delete;

        x11_window(const x11_window& other) = delete;
        x11_window& operator=(const x11_window& other) = delete;

        virtual ~x11_window();

        Window& get_x11_window();
        Display* get_display();

        void on_frame_end() override;
        [[nodiscard]] bool should_close() const override;

        [[nodiscard]] glm::uvec2 get_window_size() const override;
    };
} // namespace nova::renderer

#endif

// X11 macros that are bad
#ifdef Always
#undef Always
#endif

#ifdef None
#undef None
#endif

#ifdef Bool
#undef Bool
#endif

#endif // NOVA_RENDERER_X_11_WINDOW_HPP
<commit_msg>Include the thing properly I guess<commit_after>//
// Created by jannis on 01.09.18.
//

#ifndef NOVA_RENDERER_X_11_WINDOW_HPP
#define NOVA_RENDERER_X_11_WINDOW_HPP

#ifdef NOVA_LINUX

#include <X11/Xlib.h>
#include <cstdint>
#include "nova_renderer/window.hpp"

namespace nova::renderer {
    class x11_window : public iwindow {
    private:
        Window window;
        Display* display;
        bool should_window_close = false;
        Atom wm_protocols;
        Atom wm_delete_window;

    public:
        explicit x11_window(uint32_t width, uint32_t height, const std::string& title);

        x11_window(x11_window&& other) noexcept = delete;
        x11_window& operator=(x11_window&& other) noexcept = delete;

        x11_window(const x11_window& other) = delete;
        x11_window& operator=(const x11_window& other) = delete;

        virtual ~x11_window();

        Window& get_x11_window();
        Display* get_display();

        void on_frame_end() override;
        [[nodiscard]] bool should_close() const override;

        [[nodiscard]] glm::uvec2 get_window_size() const override;
    };
} // namespace nova::renderer

#endif

// X11 macros that are bad
#ifdef Always
#undef Always
#endif

#ifdef None
#undef None
#endif

#ifdef Bool
#undef Bool
#endif

#endif // NOVA_RENDERER_X_11_WINDOW_HPP
<|endoftext|>


<commit_before>#include <string>

class Object
{
public:
    virtual std::string toString() = 0;
};

#include <any.h>

#include <nullable.h>
#include <sequence.h>
#include <reflect.h>

#include <org/w3c/dom/NameList.h>
#include <org/w3c/dom/html/Window.h>

#include <org/w3c/dom/css/CSSStyleDeclaration.h>

#include <org/w3c/dom/Document.h>
#include <org/w3c/dom/Element.h>
#include <org/w3c/dom/html/ApplicationCache.h>
#include <org/w3c/dom/html/BarProp.h>
#include <org/w3c/dom/html/Function.h>
#include <org/w3c/dom/html/History.h>
#include <org/w3c/dom/html/Location.h>
#include <org/w3c/dom/html/MessagePort.h>
#include <org/w3c/dom/html/Navigator.h>
#include <org/w3c/dom/html/Screen.h>
#include <org/w3c/dom/html/Selection.h>
#include <org/w3c/dom/html/StyleMedia.h>
#include <org/w3c/dom/html/UndoManager.h>
#include <org/w3c/dom/html/Window.h>

#include <org/w3c/dom/webdatabase/Database.h>
#include <org/w3c/dom/webdatabase/DatabaseCallback.h>

#include <org/w3c/dom/webstorage/Storage.h>

#include <iostream>
#include <string>

using namespace std;
using namespace org::w3c::dom;

template<class B>
class Object_Bridge : public B
{
public:
    virtual std::string toString()
    {
        return "";
    }
};

Any invoke(Object* object, unsigned interfaceNumber, unsigned methodNumber,
           const char* meta, unsigned offset,
           unsigned paramCount, Any* arguments)
{
    Reflect::Interface interface(meta);
    cout << interface.getName() << endl;
    Reflect::Method method(meta + offset);
    cout << method.getName() << ':' << method.getParameterCount() << endl;
    return Nullable<string>("Hi");
}

int main()
{
    Object_Bridge<NameList_Bridge<Any, invoke> > nameList;

    Nullable<string> name = nameList.getName(3);
    cout << name.value() << endl;

    name = nameList.getNamespaceURI(2);
    cout << name.value() << endl;

    Object_Bridge<html::Window_Bridge<Any, invoke> > window;
    window.close();
    window.setLength(100);
    window.postMessage("hi", "hmm");
}
<commit_msg>(invoke) : Clean up.<commit_after>#include <string>

class Object
{
public:
    virtual std::string toString() = 0;
};

#include <any.h>

#include <nullable.h>
#include <sequence.h>
#include <reflect.h>

#include <org/w3c/dom/NameList.h>
#include <org/w3c/dom/html/Window.h>

#include <org/w3c/dom/css/CSSStyleDeclaration.h>

#include <org/w3c/dom/Document.h>
#include <org/w3c/dom/Element.h>
#include <org/w3c/dom/html/ApplicationCache.h>
#include <org/w3c/dom/html/BarProp.h>
#include <org/w3c/dom/html/Function.h>
#include <org/w3c/dom/html/History.h>
#include <org/w3c/dom/html/Location.h>
#include <org/w3c/dom/html/MessagePort.h>
#include <org/w3c/dom/html/Navigator.h>
#include <org/w3c/dom/html/Screen.h>
#include <org/w3c/dom/html/Selection.h>
#include <org/w3c/dom/html/StyleMedia.h>
#include <org/w3c/dom/html/UndoManager.h>
#include <org/w3c/dom/html/Window.h>

#include <org/w3c/dom/webdatabase/Database.h>
#include <org/w3c/dom/webdatabase/DatabaseCallback.h>

#include <org/w3c/dom/webstorage/Storage.h>

#include <iostream>
#include <string>

using namespace std;
using namespace org::w3c::dom;

template<class B>
class Object_Bridge : public B
{
public:
    virtual std::string toString()
    {
        return "";
    }
};

Any invoke(Object* object, unsigned interfaceNumber, unsigned methodNumber,
           const char* meta, unsigned offset,
           unsigned argumentCount, Any* arguments)
{
    Reflect::Interface interface(meta);
    cout << interface.getName() << endl;
    Reflect::Method method(meta + offset);
    cout << method.getName() << ':' << method.getParameterCount() << endl;
    return Nullable<string>("Hi");
}

int main()
{
    Object_Bridge<NameList_Bridge<Any, invoke> > nameList;

    Nullable<string> name = nameList.getName(3);
    cout << name.value() << endl;

    name = nameList.getNamespaceURI(2);
    cout << name.value() << endl;

    Object_Bridge<html::Window_Bridge<Any, invoke> > window;
    window.close();
    window.setLength(100);
    window.postMessage("hi", "hmm");
}
<|endoftext|>


<commit_before>
#include <cassert>
#include <QFileSystemWatcher>
#include <QTextStream>
#include <QFileInfo>
#include "FileAssociatedShader.h"

QMap<QString, QOpenGLShader *> FileAssociatedShader::s_shaderByFilePath;
QMultiMap<QOpenGLShader *, QOpenGLShaderProgram *> FileAssociatedShader::s_programsByShader;

FileAssociatedShader::FileAssociatedShader()
{}

FileAssociatedShader::~FileAssociatedShader()
{
    s_shaderByFilePath.clear();
    s_programsByShader.clear();
}

QOpenGLShader * FileAssociatedShader::getOrCreate(
    QOpenGLShader::ShaderType type
,   const QString & fileName
,   QOpenGLShaderProgram & program)
{
    QOpenGLShader * shader(nullptr);

	QFileInfo fi(fileName);
	if (!fi.exists())
	{
		qWarning() << fileName << " does not exist: shader is without source and associated file.";
		return shader;
	}

	QString filePath(fi.absoluteFilePath());
    if (s_shaderByFilePath.contains(filePath))
    {
        shader = s_shaderByFilePath[filePath];
    }
    else
    {
		instance()->addResourcePath(filePath);

        shader = new QOpenGLShader(type);
        shader->compileSourceFile(filePath);

        connect(
			shader,
			&QOpenGLShader::destroyed,
			static_cast<FileAssociatedShader*>(instance()),
			&FileAssociatedShader::shaderDestroyed);

        s_shaderByFilePath.insert(filePath, shader);
    }

    if (!s_programsByShader.contains(shader, &program))
    {
        connect(
			&program,
			&QOpenGLShaderProgram::destroyed,
			static_cast<FileAssociatedShader*>(instance()),
			&FileAssociatedShader::programDestroyed);

        s_programsByShader.insert(shader, &program);

        program.addShader(shader);
    }
    return shader;
}

void FileAssociatedShader::shaderDestroyed(QObject * object)
{
    QOpenGLShader * shader = static_cast<QOpenGLShader*>(object);

    const QString filePath(s_shaderByFilePath.key(shader));
    assert(!filePath.isEmpty());

    fileSystemWatcher()->removePath(filePath);
    s_shaderByFilePath.remove(filePath);

    const auto affectedPrograms = s_programsByShader.values(shader);
    s_programsByShader.remove(shader);

    // disconnect from all programs that have no file associated shaders anymore...
    for (QOpenGLShaderProgram * program : affectedPrograms)
        if (s_programsByShader.keys(program).isEmpty())
            disconnect(
				program,
				&QOpenGLShaderProgram::destroyed,
				static_cast<FileAssociatedShader*>(instance()),
				&FileAssociatedShader::programDestroyed);
}

void FileAssociatedShader::programDestroyed(QObject * object)
{
    QOpenGLShaderProgram * program = static_cast<QOpenGLShaderProgram*>(object);

    const auto affectedShaders = s_programsByShader.keys(program);

    for (QOpenGLShader * shader : affectedShaders)
        s_programsByShader.remove(shader, program);

    for (QOpenGLShader * shader : affectedShaders)
        if (s_programsByShader.values(shader).isEmpty())
        {
            const QString filePath(s_shaderByFilePath.key(shader));
            assert(!filePath.isEmpty());

            fileSystemWatcher()->removePath(filePath);
            s_shaderByFilePath.remove(filePath);

			disconnect(shader,
				&QOpenGLShader::destroyed,
				static_cast<FileAssociatedShader*>(instance()),
				&FileAssociatedShader::shaderDestroyed);
        }
}

QList<QOpenGLShaderProgram *> FileAssociatedShader::process()
{
    QList<QOpenGLShaderProgram *> programsWithInvalidatedUniforms;

    while (!s_queue.isEmpty())
    {
        QString filePath = s_queue.first();
        s_queue.removeFirst();

        QOpenGLShader * shader(s_shaderByFilePath[filePath]);
        assert(shader != nullptr);

        qDebug() << "Recompiling" << filePath;

        if (shader->isCompiled())
        {
            const QByteArray backup(shader->sourceCode());

            // if current version works, use its source code as
            // backup if new changes lead to uncompilable shader.
            if (!shader->compileSourceFile(filePath))
                shader->compileSourceCode(backup);
        }
        else
            shader->compileSourceFile(filePath);

        auto programs(s_programsByShader.values(shader));
        assert(!programs.isEmpty());

        programsWithInvalidatedUniforms << programs;

        for (QOpenGLShaderProgram * program : programs)
            if (!program->link())
                qWarning() << program->log();
    }

    return programsWithInvalidatedUniforms;
}
<commit_msg>fixed FileAssociatedShader "incompatibility" with vim<commit_after>
#include <cassert>
#include <QFileSystemWatcher>
#include <QTextStream>
#include <QFileInfo>
#include <QStringList>
#include "FileAssociatedShader.h"

QMap<QString, QOpenGLShader *> FileAssociatedShader::s_shaderByFilePath;
QMultiMap<QOpenGLShader *, QOpenGLShaderProgram *> FileAssociatedShader::s_programsByShader;

FileAssociatedShader::FileAssociatedShader()
{}

FileAssociatedShader::~FileAssociatedShader()
{
    s_shaderByFilePath.clear();
    s_programsByShader.clear();
}

QOpenGLShader * FileAssociatedShader::getOrCreate(
    QOpenGLShader::ShaderType type
,   const QString & fileName
,   QOpenGLShaderProgram & program)
{
    QOpenGLShader * shader(nullptr);

	QFileInfo fi(fileName);
	if (!fi.exists())
	{
		qWarning() << fileName << " does not exist: shader is without source and associated file.";
		return shader;
	}

	QString filePath(fi.absoluteFilePath());
    if (s_shaderByFilePath.contains(filePath))
    {
        shader = s_shaderByFilePath[filePath];
    }
    else
    {
		instance()->addResourcePath(filePath);

        shader = new QOpenGLShader(type);
        shader->compileSourceFile(filePath);

        connect(
			shader,
			&QOpenGLShader::destroyed,
			static_cast<FileAssociatedShader*>(instance()),
			&FileAssociatedShader::shaderDestroyed);

        s_shaderByFilePath.insert(filePath, shader);
    }

    if (!s_programsByShader.contains(shader, &program))
    {
        connect(
			&program,
			&QOpenGLShaderProgram::destroyed,
			static_cast<FileAssociatedShader*>(instance()),
			&FileAssociatedShader::programDestroyed);

        s_programsByShader.insert(shader, &program);

        program.addShader(shader);
    }
    return shader;
}

void FileAssociatedShader::shaderDestroyed(QObject * object)
{
    QOpenGLShader * shader = static_cast<QOpenGLShader*>(object);

    const QString filePath(s_shaderByFilePath.key(shader));
    assert(!filePath.isEmpty());

    fileSystemWatcher()->removePath(filePath);
    s_shaderByFilePath.remove(filePath);

    const auto affectedPrograms = s_programsByShader.values(shader);
    s_programsByShader.remove(shader);

    // disconnect from all programs that have no file associated shaders anymore...
    for (QOpenGLShaderProgram * program : affectedPrograms)
        if (s_programsByShader.keys(program).isEmpty())
            disconnect(
				program,
				&QOpenGLShaderProgram::destroyed,
				static_cast<FileAssociatedShader*>(instance()),
				&FileAssociatedShader::programDestroyed);
}

void FileAssociatedShader::programDestroyed(QObject * object)
{
    QOpenGLShaderProgram * program = static_cast<QOpenGLShaderProgram*>(object);

    const auto affectedShaders = s_programsByShader.keys(program);

    for (QOpenGLShader * shader : affectedShaders)
        s_programsByShader.remove(shader, program);

    for (QOpenGLShader * shader : affectedShaders)
        if (s_programsByShader.values(shader).isEmpty())
        {
            const QString filePath(s_shaderByFilePath.key(shader));
            assert(!filePath.isEmpty());

            fileSystemWatcher()->removePath(filePath);
            s_shaderByFilePath.remove(filePath);

			disconnect(shader,
				&QOpenGLShader::destroyed,
				static_cast<FileAssociatedShader*>(instance()),
				&FileAssociatedShader::shaderDestroyed);
        }
}

QList<QOpenGLShaderProgram *> FileAssociatedShader::process()
{
    QList<QOpenGLShaderProgram *> programsWithInvalidatedUniforms;

	{
		auto inst = static_cast<FileAssociatedShader*>(instance());
		auto watchedFiles = inst->fileSystemWatcher()->files();
		if (watchedFiles.count() != inst->s_shaderByFilePath.count())
		{
			for (auto path : inst->s_shaderByFilePath.keys())
			{
				if (!watchedFiles.contains(path) && QFileInfo(path).exists())
				{
					inst->m_fileSystemWatcher->addPath(path);
				}
			}
		}
	}

    while (!s_queue.isEmpty())
    {
        QString filePath = s_queue.first();
        s_queue.removeFirst();

        QOpenGLShader * shader(s_shaderByFilePath[filePath]);
        assert(shader != nullptr);

        qDebug() << "Recompiling" << filePath;

        if (shader->isCompiled())
        {
            const QByteArray backup(shader->sourceCode());

            // if current version works, use its source code as
            // backup if new changes lead to uncompilable shader.
            if (!shader->compileSourceFile(filePath))
                shader->compileSourceCode(backup);
        }
        else
            shader->compileSourceFile(filePath);

        auto programs(s_programsByShader.values(shader));
        assert(!programs.isEmpty());

        programsWithInvalidatedUniforms << programs;

        for (QOpenGLShaderProgram * program : programs)
            if (!program->link())
                qWarning() << program->log();
    }

    return programsWithInvalidatedUniforms;
}
<|endoftext|>


<commit_before><commit_msg>Marking rejected satellites with a negative id is a bad idea.<commit_after><|endoftext|>


<commit_before><commit_msg>JO:fin journée vendredi<commit_after><|endoftext|>


<commit_before>//===--- RequestedInformation.cpp - Requested Information Utilities ---===//
//
// This file is part of the Election Method Mathematics Application (EMMA) project.
//
// Copyright (c) 2015 - 2016 Frank D. Martinez and the EMMA project authors
// Licensed under the GNU Affero General Public License, version 3.0.
//
// See the file called "LICENSE" included with this distribution for license information.
//
//===----------------------------------------------------------------------===//
//
// Functionality related to determining requested information.
// Analyzes information passed to the application and determines
// how the application should act.
//
//===----------------------------------------------------------------------===//

#include <iostream>
#include "RequestedInformation.h"
#include "docopt/docopt.h"

namespace RequestedInformation {
  typedef std::map<std::string, docopt::value> RawParsedOptions;
  // Parses given options; `argc` and `argv` are the arguments
  // from `main()`.
  RawParsedOptions parseOptions(int argc, char **argv);
  // Determines the mode in which to run based on the parsed
  // options
  void determineMode();
  // Determines the statistics to collect based on the parsed
  // options
  void determineStatisticsToCollect();

  void determine(int argc, char **argv) {
    std::cout << "determine what is requested from simulations" << std::endl;
    parseOptions(argc, argv);
    determineMode();
    determineStatisticsToCollect();
  }

  void determineMode() {
    std::cout << "\tdetermine the mode to run in based on such parsing" << std::endl;
  }

  void determineStatisticsToCollect() {
    std::cout << "\tdetermine what statistics to collect based on such parsing" << std::endl;
  }

  RawParsedOptions parseOptions(int argc, char **argv) {
    const std::string usage =
    R"(Usage:
        emma (-h | --help)
        emma options...

        Options:
          -h --help                                   Show this screen.
          --use-seed=<#>                              The seed to pass to the PRNG function [default: a number representing the current time].
          --number-of-elections=<#>                   Number of elections to simulate [default: 1].
          --number-of-candidates=<#>                  Number of Candidates in each election [default: 3].
          --number-of-voters=<#>                      Number of Voters in each election [default: 64].
          --check-condorcet-agreement=yes|no          Check each method for agreement with the Condorcet Candidate [default: yes].
          --check-true-condorcet-agreement=<yes|no>   Check each method for agreement with the True Condorcet Candidate [default: yes].
          --test                                      Perform diagnostic testing.
          --verbose                                   Activate verbosity.
    )";
    RawParsedOptions raw_options = docopt::docopt(usage,
                                              { argv + 1, argv + argc },
                                              true);
    if (raw_options["--verbose"].asLong() == 1) {
      std::cout << "parsing given options: success" << std::endl;
    }
    return raw_options;
  }
}
<commit_msg>Distributing the parsed option information<commit_after>//===--- RequestedInformation.cpp - Requested Information Utilities ---===//
//
// This file is part of the Election Method Mathematics Application (EMMA) project.
//
// Copyright (c) 2015 - 2016 Frank D. Martinez and the EMMA project authors
// Licensed under the GNU Affero General Public License, version 3.0.
//
// See the file called "LICENSE" included with this distribution for license information.
//
//===----------------------------------------------------------------------===//
//
// Functionality related to determining requested information.
// Analyzes information passed to the application and determines
// how the application should act.
//
//===----------------------------------------------------------------------===//

#include <iostream>
#include "RequestedInformation.h"
#include "docopt/docopt.h"

namespace RequestedInformation {
  typedef std::map<std::string, docopt::value> RawParsedOptions;
  // Parses given options; `argc` and `argv` are the arguments
  // from `main()`.
  RawParsedOptions parseOptions(int argc, char **argv);
  // Determines the mode in which to run based on the parsed
  // options
  void determineMode(RawParsedOptions raw_parsed_options);
  // Determines the statistics to collect based on the parsed
  // options
  void determineStatisticsToCollect(RawParsedOptions raw_parsed_options);

  void determine(int argc, char **argv) {
    std::cout << "determine what is requested from simulations" << std::endl;
    RawParsedOptions raw_options = parseOptions(argc, argv);
    determineMode(raw_options);
    determineStatisticsToCollect();
  }

  void determineMode(RawParsedOptions raw_parsed_options) {
    std::cout << "\tdetermine the mode to run in based on such parsing" << std::endl;
  }

  void determineStatisticsToCollect(RawParsedOptions raw_parsed_options) {
    std::cout << "\tdetermine what statistics to collect based on such parsing" << std::endl;
  }

  RawParsedOptions parseOptions(int argc, char **argv) {
    const std::string usage =
    R"(Usage:
        emma (-h | --help)
        emma options...

        Options:
          -h --help                                   Show this screen.
          --use-seed=<#>                              The seed to pass to the PRNG function [default: a number representing the current time].
          --number-of-elections=<#>                   Number of elections to simulate [default: 1].
          --number-of-candidates=<#>                  Number of Candidates in each election [default: 3].
          --number-of-voters=<#>                      Number of Voters in each election [default: 64].
          --check-condorcet-agreement=yes|no          Check each method for agreement with the Condorcet Candidate [default: yes].
          --check-true-condorcet-agreement=<yes|no>   Check each method for agreement with the True Condorcet Candidate [default: yes].
          --test                                      Perform diagnostic testing.
          --verbose                                   Activate verbosity.
    )";
    RawParsedOptions raw_options = docopt::docopt(usage,
                                              { argv + 1, argv + argc },
                                              true);
    if (raw_options["--verbose"].asLong() == 1) {
      std::cout << "parsing given options: success" << std::endl;
    }
    return raw_options;
  }
}
<|endoftext|>