<commit_before>#include "include/parser.h"

#include <cctype>
#include <stack>
#include <cstdio>

#include "include/operator.h"
#include "include/error.h"

SpParser::SpParser() {
   /* initialize the operators table */
   operators_ = std::unordered_map<std::string, SpOperator> ({
      { "*", SpOperator("*", 10, ASSOC_LEFT, "*") },
      { "/", SpOperator("/", 10, ASSOC_LEFT, "/") },
      { "+", SpOperator("+", 5, ASSOC_LEFT, "+") },
      { "-", SpOperator("-", 5, ASSOC_LEFT, "-") }
   });
}

SpParser::~SpParser() {
   while (!token_list_.empty()) delete token_list_.back(), token_list_.pop_back();
}

void SpParser::load(const std::string source) {
   source_ = source;
   it_ = source.cbegin();

   /* delete any existing token list */
   while (!token_list_.empty()) delete token_list_.back(), token_list_.pop_back();
}

SpOperator *SpParser::find_operator(const std::string value) {
   /* find the operator in the hash table */
   auto result = operators_.find(value);
   if (result != operators_.end()) {
      return &result->second;
   } else return NULL;
}

char SpParser::peek_next() {
   return it_ == source().end() ? '\0' : *(it_ + 1);
}

SpToken *SpParser::next_token() {
   /* ignore whitespace by moving to the next non-whitespace character */
   while (it_ != source().end() && isspace(*it_)) { ++it_; }

   /* keep track of where this token started */
   StrIter start_it = it_;
   size_t start = std::distance(start_it, source().cbegin());

   /* check what type of token begins at the current character */
   switch (*it_) {
      /* operator tokens */
      case '*': case '/': case '+': case '-': {
         /* create a new operator token */
         return new SpToken(*it_++, TOKEN_OPERATOR, 2, start);
      }

      /* parenthesis and brackets */
      case '(': ++it_; return new SpToken('(', TOKEN_LEFT_PARENS, 1, start);
      case ')': ++it_; return new SpToken(')', TOKEN_RIGHT_PARENS, 1, start);
      case '[': ++it_; return new SpToken('[', TOKEN_LEFT_SQUARE_BRACKET, 1, start);
      case ']': ++it_; return new SpToken(']', TOKEN_RIGHT_SQUARE_BRACKET, 1, start);

      /* numeric tokens (TODO: handle decimal numbers) */
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9': {
         /* move the iterator to the first non-digit_ character */
         while (it_ != source().end() && isdigit(*it_)) { ++it_; }
         return new SpToken(std::string(start_it, it_), TOKEN_NUMERIC, 0, start);
      }

      /* comment */
      case '#':
         /* ignore the entire line */
         while (it_ != source().end() && *it_ != '\n') { ++it_; }
         return next_token();

      default:
         /* name tokens (TODO: change into a case jump) */
         if (isalpha(*it_)) {
            /* move the iterator to the first non-name character */
            while (it_ != source().end() && (
               isalpha(*it_) || isdigit(*it_))) { ++it_; }

            return new SpToken(std::string(start_it, it_), TOKEN_NAME, 0, start);
         } else {
            /* Unrecognized symbol */
            return new SpToken();
            // return new SpToken("", TOKEN_UNKNOWN, 0, start);
         }
   }

   /* we've reached EOF */
   return new SpToken(); /* empty constructor creates EOF token */
}

SpError *SpParser::parse_expr() {
   std::stack<SpToken *> op_s; /* delayed operator stack */

   SpToken *token = NULL, *prev_token = NULL;
   while (token = next_token(), token->type() != TOKEN_EOF) {
      switch (token->type()) {
         case TOKEN_NUMERIC:
            push_token(token);
            break;
         case TOKEN_OPERATOR: {
            /* if the previous token is NULL, then that means this operator is
               the first token in an expr i.e. it is a prefix operator */
            /* TODO: implement prefix operators */

            /* identify the new operator, and the operator at the top of the stack
               pop the top operator if the new operator has a lower precedence than the top */
            SpOperator *op_n = find_operator(token->value()), *op_t = NULL;
            while (op_n && !op_s.empty() &&
                   (op_t = find_operator(op_s.top()->value())) &&
                   ((op_n->assoc() == ASSOC_LEFT && op_n->prec() <= op_t->prec()) ||
                   (op_n->assoc() == ASSOC_RIGHT && op_n->prec() < op_t->prec()))) {
               /* this means that op_t should be processed before op_n */
               push_token(op_s.top()); op_s.pop();
            }

            /* finally, push the new token on to the stack */
            op_s.push(token);
            break;
         }
         case TOKEN_LEFT_PARENS: {
            /* parsing a new expression */
            SpError *err = parse_expr();
            if (err) return err;
            break;
         }
         case TOKEN_RIGHT_PARENS:
            /* this has expression closed */
            /* TODO: possibly in the far future, have post-fix operators */

            /* output the leftover operators */
            while (!op_s.empty()) {
               push_token(op_s.top());
               op_s.pop();
            }
            return NO_ERROR;
         case TOKEN_LEFT_SQUARE_BRACKET: {
            /* left square bracket, beginning of a function call */
            SpError *err = parse_function();
            if (err) return err;
            break;
         }
         default: return PARSE_ERROR("Unimplemented!");
      }

      prev_token = token;
   }

   /* we arrive here if we hit an EOF before we see a right parenthesis,
      which means this expression is not closed. This should never happen
      if the REPL balances the expressions for us */
   return PARSE_ERROR("Expected ')' at end of expression");
}

SpError *SpParser::parse_function() {
   int arg_count = 0; /* number of arguments in this function */
   SpToken *token = NULL;

   /* a function call must begin with TOKEN_NAME or TOKEN_OPERATOR,
      followed by args */
   if (token = next_token(),
         (token->type() == TOKEN_NAME || token->type() == TOKEN_OPERATOR)) {
      /* keep track of the name of this function and its start */
      std::string name = token->value();
      int start = token->start_pos();

      /* parse the function arguments */
      while (token = next_token(), token->type() != TOKEN_EOF) {
         switch (token->type()) {
            case TOKEN_LEFT_SQUARE_BRACKET: {
               /* a new function call */
               SpError *err = parse_function();
               if (err) return err;
               break;
            }
            case TOKEN_RIGHT_SQUARE_BRACKET:
               /* this function call ended, so we push on the function call token */
               push_token(new SpToken(name, TOKEN_FUNCTION_CALL, arg_count, start));
               return NO_ERROR;
            case TOKEN_LEFT_PARENS: {
               /* a new expr */
               SpError *err = parse_expr();
               if (err) return err;
               break;
            }
            default:
               /* an argument of this function */
               push_token(token);
         }

         arg_count++;
      }
   } else {
      return PARSE_ERROR_F("%s cannot be used as a function", token->value().c_str());
   }

   /* the function call wasn't complete */
   return PARSE_ERROR("Function call incomplete. Expected ']'");
}

void SpParser::push_token(SpToken *token) {
   token_list_.push_back(token);
}

<commit_msg>Add support for implicit concatenation<commit_after>#include "include/parser.h"

#include <cctype>
#include <stack>
#include <cstdio>

#include "include/operator.h"
#include "include/error.h"

SpParser::SpParser() {
   /* initialize the operators table */
   operators_ = std::unordered_map<std::string, SpOperator> ({
      { "*", SpOperator("*", 10, ASSOC_LEFT, "*") },
      { "/", SpOperator("/", 10, ASSOC_LEFT, "/") },
      { "+", SpOperator("+", 5, ASSOC_LEFT, "+") },
      { "-", SpOperator("-", 5, ASSOC_LEFT, "-") }
   });
}

SpParser::~SpParser() {
   while (!token_list_.empty()) delete token_list_.back(), token_list_.pop_back();
}

void SpParser::load(const std::string source) {
   source_ = source;
   it_ = source.cbegin();

   /* delete any existing token list */
   while (!token_list_.empty()) delete token_list_.back(), token_list_.pop_back();
}

SpOperator *SpParser::find_operator(const std::string value) {
   /* find the operator in the hash table */
   auto result = operators_.find(value);
   if (result != operators_.end()) {
      return &result->second;
   } else return NULL;
}

char SpParser::peek_next() {
   return it_ == source().end() ? '\0' : *(it_ + 1);
}

SpToken *SpParser::next_token() {
   /* ignore whitespace by moving to the next non-whitespace character */
   while (it_ != source().end() && isspace(*it_)) { ++it_; }

   /* keep track of where this token started */
   StrIter start_it = it_;
   size_t start = std::distance(start_it, source().cbegin());

   /* check what type of token begins at the current character */
   switch (*it_) {
      /* operator tokens */
      case '*': case '/': case '+': case '-': {
         /* create a new operator token */
         return new SpToken(*it_++, TOKEN_OPERATOR, 2, start);
      }

      /* parenthesis and brackets */
      case '(': ++it_; return new SpToken('(', TOKEN_LEFT_PARENS, 1, start);
      case ')': ++it_; return new SpToken(')', TOKEN_RIGHT_PARENS, 1, start);
      case '[': ++it_; return new SpToken('[', TOKEN_LEFT_SQUARE_BRACKET, 1, start);
      case ']': ++it_; return new SpToken(']', TOKEN_RIGHT_SQUARE_BRACKET, 1, start);

      /* numeric tokens (TODO: handle decimal numbers) */
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9': {
         /* move the iterator to the first non-digit_ character */
         while (it_ != source().end() && isdigit(*it_)) { ++it_; }
         return new SpToken(std::string(start_it, it_), TOKEN_NUMERIC, 0, start);
      }

      /* comment */
      case '#':
         /* ignore the entire line */
         while (it_ != source().end() && *it_ != '\n') { ++it_; }
         return next_token();

      default:
         /* name tokens (TODO: change into a case jump) */
         if (isalpha(*it_)) {
            /* move the iterator to the first non-name character */
            while (it_ != source().end() && (
               isalpha(*it_) || isdigit(*it_))) { ++it_; }

            return new SpToken(std::string(start_it, it_), TOKEN_NAME, 0, start);
         } else {
            /* Unrecognized symbol */
            return new SpToken();
            // return new SpToken("", TOKEN_UNKNOWN, 0, start);
         }
   }

   /* we've reached EOF */
   return new SpToken(); /* empty constructor creates EOF token */
}

SpError *SpParser::parse_expr() {
   std::stack<SpToken *> op_s; /* delayed operator stack */

   SpToken *token = NULL, *prev_token = NULL;
   while (token = next_token(), token->type() != TOKEN_EOF) {
      switch (token->type()) {
         case TOKEN_NUMERIC:
            push_token(token);
            if (prev_token && prev_token->type() == TOKEN_NUMERIC) {
               /* implicit concatenation */
               push_token(new SpToken("append", TOKEN_FUNCTION_CALL, 2, token->start_pos()));
            }
            break;
         case TOKEN_OPERATOR: {
            /* if the previous token is NULL, then that means this operator is
               the first token in an expr i.e. it is a prefix operator */
            /* TODO: implement prefix operators */

            /* identify the new operator, and the operator at the top of the stack
               pop the top operator if the new operator has a lower precedence than the top */
            SpOperator *op_n = find_operator(token->value()), *op_t = NULL;
            while (op_n && !op_s.empty() &&
                   (op_t = find_operator(op_s.top()->value())) &&
                   ((op_n->assoc() == ASSOC_LEFT && op_n->prec() <= op_t->prec()) ||
                   (op_n->assoc() == ASSOC_RIGHT && op_n->prec() < op_t->prec()))) {
               /* this means that op_t should be processed before op_n */
               push_token(op_s.top()); op_s.pop();
            }

            /* finally, push the new token on to the stack */
            op_s.push(token);
            break;
         }
         case TOKEN_LEFT_PARENS: {
            /* parsing a new expression */
            SpError *err = parse_expr();
            if (err) return err;
            break;
         }
         case TOKEN_RIGHT_PARENS:
            /* this has expression closed */
            /* TODO: possibly in the far future, have post-fix operators */

            /* output the leftover operators */
            while (!op_s.empty()) {
               push_token(op_s.top());
               op_s.pop();
            }
            return NO_ERROR;
         case TOKEN_LEFT_SQUARE_BRACKET: {
            /* left square bracket, beginning of a function call */
            SpError *err = parse_function();
            if (err) return err;
            break;
         }
         default: return PARSE_ERROR("Unimplemented!");
      }

      prev_token = token;
   }

   /* we arrive here if we hit an EOF before we see a right parenthesis,
      which means this expression is not closed. This should never happen
      if the REPL balances the expressions for us */
   return PARSE_ERROR("Expected ')' at end of expression");
}

SpError *SpParser::parse_function() {
   int arg_count = 0; /* number of arguments in this function */
   SpToken *token = NULL;

   /* a function call must begin with TOKEN_NAME or TOKEN_OPERATOR,
      followed by args */
   if (token = next_token(),
         (token->type() == TOKEN_NAME || token->type() == TOKEN_OPERATOR)) {
      /* keep track of the name of this function and its start */
      std::string name = token->value();
      int start = token->start_pos();

      /* parse the function arguments */
      while (token = next_token(), token->type() != TOKEN_EOF) {
         switch (token->type()) {
            case TOKEN_LEFT_SQUARE_BRACKET: {
               /* a new function call */
               SpError *err = parse_function();
               if (err) return err;
               break;
            }
            case TOKEN_RIGHT_SQUARE_BRACKET:
               /* this function call ended, so we push on the function call token */
               push_token(new SpToken(name, TOKEN_FUNCTION_CALL, arg_count, start));
               return NO_ERROR;
            case TOKEN_LEFT_PARENS: {
               /* a new expr */
               SpError *err = parse_expr();
               if (err) return err;
               break;
            }
            default:
               /* an argument of this function */
               push_token(token);
         }

         arg_count++;
      }
   } else {
      return PARSE_ERROR_F("%s cannot be used as a function", token->value().c_str());
   }

   /* the function call wasn't complete */
   return PARSE_ERROR("Function call incomplete. Expected ']'");
}

void SpParser::push_token(SpToken *token) {
   token_list_.push_back(token);
}

<|endoftext|>


<commit_before>#include "perfmon.hpp"
#include "arch/arch.hpp"
#include "utils.hpp"
#include <stdarg.h>
#include "coroutine/coroutines.hpp"

/* The var list keeps track of all of the perfmon_t objects. */

intrusive_list_t<perfmon_t> &get_var_list() {
    /* Getter function so that we can be sure that var_list is initialized before it is needed,
    as advised by the C++ FAQ. Otherwise, a perfmon_t might be initialized before the var list
    was initialized. */

    static intrusive_list_t<perfmon_t> var_list;
    return var_list;
}

/* Class that wraps a pthread spinlock.

TODO: This should live in the arch/ directory. */

class spinlock_t {
    pthread_spinlock_t l;
public:
    spinlock_t() {
        pthread_spin_init(&l, PTHREAD_PROCESS_PRIVATE);
    }
    ~spinlock_t() {
        pthread_spin_destroy(&l);
    }
    void lock() {
        int res = pthread_spin_lock(&l);
        guarantee_err(res == 0, "could not lock spin lock");
    }
    void unlock() {
        int res = pthread_spin_unlock(&l);
        guarantee_err(res == 0, "could not unlock spin lock");
    }
};

/* The var lock protects the var list when it is being modified. In theory, this should all work
automagically because the constructor of every perfmon_t calls get_var_lock(), causing the var lock
to be constructed before the first perfmon, so it is destroyed after the last perfmon. */

spinlock_t &get_var_lock() {
    /* To avoid static initialization fiasco */

    static spinlock_t lock;
    return lock;
}

/* This is the function that actually gathers the stats. It is illegal to create or destroy
perfmon_t objects while a perfmon_fsm_t is active. */

void co_perfmon_visit(int thread, const std::vector<void*> &data, coro_t::multi_wait_t *multi_wait) {
    coro_t::on_thread_t moving(thread);
    int i = 0;
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        p->visit_stats(data[i++]);
    }
    printf("I'm done\n");
    multi_wait->notify();
}

void co_perfmon_get_stats(perfmon_stats_t *dest, perfmon_callback_t *cb) {
    std::vector<void*> data;
    data.reserve(get_var_list().size());
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        data.push_back(p->begin_stats());
    }
    int threads = get_num_threads();
    coro_t::multi_wait_t *multi_wait = new coro_t::multi_wait_t(threads);
    for (int i = 0; i < threads; i++) {
        coro_t::spawn(co_perfmon_visit, i, data, multi_wait);
    }
    coro_t::wait();
    printf("Let's finish this up\n");
    int i = 0;
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        p->end_stats(data[i++], dest);
    }
    cb->on_perfmon_stats();
}

bool perfmon_get_stats(perfmon_stats_t *dest, perfmon_callback_t *cb) {
    coro_t::spawn(co_perfmon_get_stats, dest, cb);
    return false;
}

/* Constructor and destructor register and deregister the perfmon.

Right now, it is illegal to make perfmon_t objects that are not static variables, so
we don't have to worry about locking the var list. If we locked it, then we could
create and destroy perfmon_ts at runtime. */

perfmon_t::perfmon_t()
{
    get_var_lock().lock();
    get_var_list().push_back(this);
    get_var_lock().unlock();
}

perfmon_t::~perfmon_t() {
    get_var_lock().lock();
    get_var_list().remove(this);
    get_var_lock().unlock();
}

/* perfmon_counter_t */

perfmon_counter_t::perfmon_counter_t(std::string name)
    : name(name)
{
    for (int i = 0; i < MAX_THREADS; i++) values[i] = 0;
}

int64_t &perfmon_counter_t::get() {
    return values[get_thread_id()];
}

void *perfmon_counter_t::begin_stats() {
    return new int64_t[get_num_threads()];
}

void perfmon_counter_t::visit_stats(void *data) {
    ((int64_t *)data)[get_thread_id()] = get();
}

void perfmon_counter_t::end_stats(void *data, perfmon_stats_t *dest) {
    int64_t value = 0;
    for (int i = 0; i < get_num_threads(); i++) value += ((int64_t *)data)[i];
    (*dest)[name] = format(value);
    delete[] (int64_t *)data;
}

/* perfmon_sampler_t */

perfmon_sampler_t::perfmon_sampler_t(std::string name, ticks_t length, bool include_rate)
    : name(name), length(length), include_rate(include_rate) { }

void perfmon_sampler_t::expire() {
    ticks_t now = get_ticks();
    std::deque<sample_t> &queue = values[get_thread_id()];
    while (!queue.empty() && queue.front().timestamp + length < now) queue.pop_front();
}

void perfmon_sampler_t::record(value_t v) {
    expire();
    values[get_thread_id()].push_back(sample_t(v, get_ticks()));
}

struct perfmon_sampler_step_t {
    uint64_t counts[MAX_THREADS];
    perfmon_sampler_t::value_t values[MAX_THREADS], mins[MAX_THREADS], maxes[MAX_THREADS];
};

void *perfmon_sampler_t::begin_stats() {
    return new perfmon_sampler_step_t;
}

void perfmon_sampler_t::visit_stats(void *data) {
    perfmon_sampler_step_t *d = (perfmon_sampler_step_t *)data;
    expire();
    d->values[get_thread_id()] = 0;
    d->counts[get_thread_id()] = 0;
    for (std::deque<perfmon_sampler_t::sample_t>::iterator it = values[get_thread_id()].begin();
         it != values[get_thread_id()].end(); it++) {
        d->values[get_thread_id()] += (*it).value;
        if (d->counts[get_thread_id()] > 0) {
            d->mins[get_thread_id()] = std::min(d->mins[get_thread_id()], (*it).value);
            d->maxes[get_thread_id()] = std::max(d->maxes[get_thread_id()], (*it).value);
        } else {
            d->mins[get_thread_id()] = (*it).value;
            d->maxes[get_thread_id()] = (*it).value;
        }
        d->counts[get_thread_id()]++;
    }
}

void perfmon_sampler_t::end_stats(void *data, perfmon_stats_t *dest) {
    perfmon_sampler_step_t *d = (perfmon_sampler_step_t *)data;
    perfmon_sampler_t::value_t value = 0;
    uint64_t count = 0;
    perfmon_sampler_t::value_t min = 0, max = 0;   /* Initializers to make GCC shut up */
    bool have_any = false;
    for (int i = 0; i < get_num_threads(); i++) {
        value += d->values[i];
        count += d->counts[i];
        if (d->counts[i]) {
            if (have_any) {
                min = std::min(d->mins[i], min);
                max = std::max(d->maxes[i], max);
            } else {
                min = d->mins[i];
                max = d->maxes[i];
                have_any = true;
            }
        }
    }
    if (have_any) {
        (*dest)[name + "_avg"] = format(value / count);
        (*dest)[name + "_min"] = format(min);
        (*dest)[name + "_max"] = format(max);
    } else {
        (*dest)[name + "_avg"] = "-";
        (*dest)[name + "_min"] = "-";
        (*dest)[name + "_max"] = "-";
    }
    if (include_rate) {
        (*dest)[name + "_persec"] = format(count / ticks_to_secs(length));
    }
    delete d;
};

<commit_msg>Removing debug messages from Perfmon<commit_after>#include "perfmon.hpp"
#include "arch/arch.hpp"
#include "utils.hpp"
#include <stdarg.h>
#include "coroutine/coroutines.hpp"

/* The var list keeps track of all of the perfmon_t objects. */

intrusive_list_t<perfmon_t> &get_var_list() {
    /* Getter function so that we can be sure that var_list is initialized before it is needed,
    as advised by the C++ FAQ. Otherwise, a perfmon_t might be initialized before the var list
    was initialized. */

    static intrusive_list_t<perfmon_t> var_list;
    return var_list;
}

/* Class that wraps a pthread spinlock.

TODO: This should live in the arch/ directory. */

class spinlock_t {
    pthread_spinlock_t l;
public:
    spinlock_t() {
        pthread_spin_init(&l, PTHREAD_PROCESS_PRIVATE);
    }
    ~spinlock_t() {
        pthread_spin_destroy(&l);
    }
    void lock() {
        int res = pthread_spin_lock(&l);
        guarantee_err(res == 0, "could not lock spin lock");
    }
    void unlock() {
        int res = pthread_spin_unlock(&l);
        guarantee_err(res == 0, "could not unlock spin lock");
    }
};

/* The var lock protects the var list when it is being modified. In theory, this should all work
automagically because the constructor of every perfmon_t calls get_var_lock(), causing the var lock
to be constructed before the first perfmon, so it is destroyed after the last perfmon. */

spinlock_t &get_var_lock() {
    /* To avoid static initialization fiasco */

    static spinlock_t lock;
    return lock;
}

/* This is the function that actually gathers the stats. It is illegal to create or destroy
perfmon_t objects while a perfmon_fsm_t is active. */

void co_perfmon_visit(int thread, const std::vector<void*> &data, coro_t::multi_wait_t *multi_wait) {
    coro_t::on_thread_t moving(thread);
    int i = 0;
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        p->visit_stats(data[i++]);
    }
    multi_wait->notify();
}

void co_perfmon_get_stats(perfmon_stats_t *dest, perfmon_callback_t *cb) {
    std::vector<void*> data;
    data.reserve(get_var_list().size());
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        data.push_back(p->begin_stats());
    }
    int threads = get_num_threads();
    coro_t::multi_wait_t *multi_wait = new coro_t::multi_wait_t(threads);
    for (int i = 0; i < threads; i++) {
        coro_t::spawn(co_perfmon_visit, i, data, multi_wait);
    }
    coro_t::wait();
    int i = 0;
    for (perfmon_t *p = get_var_list().head(); p; p = get_var_list().next(p)) {
        p->end_stats(data[i++], dest);
    }
    cb->on_perfmon_stats();
}

bool perfmon_get_stats(perfmon_stats_t *dest, perfmon_callback_t *cb) {
    coro_t::spawn(co_perfmon_get_stats, dest, cb);
    return false;
}

/* Constructor and destructor register and deregister the perfmon.

Right now, it is illegal to make perfmon_t objects that are not static variables, so
we don't have to worry about locking the var list. If we locked it, then we could
create and destroy perfmon_ts at runtime. */

perfmon_t::perfmon_t()
{
    get_var_lock().lock();
    get_var_list().push_back(this);
    get_var_lock().unlock();
}

perfmon_t::~perfmon_t() {
    get_var_lock().lock();
    get_var_list().remove(this);
    get_var_lock().unlock();
}

/* perfmon_counter_t */

perfmon_counter_t::perfmon_counter_t(std::string name)
    : name(name)
{
    for (int i = 0; i < MAX_THREADS; i++) values[i] = 0;
}

int64_t &perfmon_counter_t::get() {
    return values[get_thread_id()];
}

void *perfmon_counter_t::begin_stats() {
    return new int64_t[get_num_threads()];
}

void perfmon_counter_t::visit_stats(void *data) {
    ((int64_t *)data)[get_thread_id()] = get();
}

void perfmon_counter_t::end_stats(void *data, perfmon_stats_t *dest) {
    int64_t value = 0;
    for (int i = 0; i < get_num_threads(); i++) value += ((int64_t *)data)[i];
    (*dest)[name] = format(value);
    delete[] (int64_t *)data;
}

/* perfmon_sampler_t */

perfmon_sampler_t::perfmon_sampler_t(std::string name, ticks_t length, bool include_rate)
    : name(name), length(length), include_rate(include_rate) { }

void perfmon_sampler_t::expire() {
    ticks_t now = get_ticks();
    std::deque<sample_t> &queue = values[get_thread_id()];
    while (!queue.empty() && queue.front().timestamp + length < now) queue.pop_front();
}

void perfmon_sampler_t::record(value_t v) {
    expire();
    values[get_thread_id()].push_back(sample_t(v, get_ticks()));
}

struct perfmon_sampler_step_t {
    uint64_t counts[MAX_THREADS];
    perfmon_sampler_t::value_t values[MAX_THREADS], mins[MAX_THREADS], maxes[MAX_THREADS];
};

void *perfmon_sampler_t::begin_stats() {
    return new perfmon_sampler_step_t;
}

void perfmon_sampler_t::visit_stats(void *data) {
    perfmon_sampler_step_t *d = (perfmon_sampler_step_t *)data;
    expire();
    d->values[get_thread_id()] = 0;
    d->counts[get_thread_id()] = 0;
    for (std::deque<perfmon_sampler_t::sample_t>::iterator it = values[get_thread_id()].begin();
         it != values[get_thread_id()].end(); it++) {
        d->values[get_thread_id()] += (*it).value;
        if (d->counts[get_thread_id()] > 0) {
            d->mins[get_thread_id()] = std::min(d->mins[get_thread_id()], (*it).value);
            d->maxes[get_thread_id()] = std::max(d->maxes[get_thread_id()], (*it).value);
        } else {
            d->mins[get_thread_id()] = (*it).value;
            d->maxes[get_thread_id()] = (*it).value;
        }
        d->counts[get_thread_id()]++;
    }
}

void perfmon_sampler_t::end_stats(void *data, perfmon_stats_t *dest) {
    perfmon_sampler_step_t *d = (perfmon_sampler_step_t *)data;
    perfmon_sampler_t::value_t value = 0;
    uint64_t count = 0;
    perfmon_sampler_t::value_t min = 0, max = 0;   /* Initializers to make GCC shut up */
    bool have_any = false;
    for (int i = 0; i < get_num_threads(); i++) {
        value += d->values[i];
        count += d->counts[i];
        if (d->counts[i]) {
            if (have_any) {
                min = std::min(d->mins[i], min);
                max = std::max(d->maxes[i], max);
            } else {
                min = d->mins[i];
                max = d->maxes[i];
                have_any = true;
            }
        }
    }
    if (have_any) {
        (*dest)[name + "_avg"] = format(value / count);
        (*dest)[name + "_min"] = format(min);
        (*dest)[name + "_max"] = format(max);
    } else {
        (*dest)[name + "_avg"] = "-";
        (*dest)[name + "_min"] = "-";
        (*dest)[name + "_max"] = "-";
    }
    if (include_rate) {
        (*dest)[name + "_persec"] = format(count / ticks_to_secs(length));
    }
    delete d;
};

<|endoftext|>


<commit_before>/**
 * @file metric_test.cpp
 *
 * Unit tests for the 'LMetric' class.
 */
#include <mlpack/core.hpp>
#include <mlpack/core/metrics/lmetric.hpp>
#include <boost/test/unit_test.hpp>
#include "old_boost_test_definitions.hpp"

using namespace std;
using namespace mlpack::metric;

BOOST_AUTO_TEST_SUITE(LMetricTest);

BOOST_AUTO_TEST_CASE(L1MetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  ManhattanDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a1 - b1)),
                      lMetric.Evaluate(a1, b1), 1e-5);

  BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a2 - b2)),
                      lMetric.Evaluate(a2, b2), 1e-5);
}

BOOST_AUTO_TEST_CASE(L2MetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  EuclideanDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a1 - b1))),
                      lMetric.Evaluate(a1, b1), 1e-5);

  BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a2 - b2))),
                      lMetric.Evaluate(a2, b2), 1e-5);
}

BOOST_AUTO_TEST_CASE(LINFMetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  ChebyshevDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a1 - b1)),
                      lMetric.Evaluate(a1, b1), 1e-5));

  BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a2 - b2)),
                      lMetric.Evaluate(a2, b2), 1e-5));
}

BOOST_AUTO_TEST_SUITE_END();
<commit_msg>Oh holy crap, I am the worst, and I have broken everything.<commit_after>/**
 * @file metric_test.cpp
 *
 * Unit tests for the 'LMetric' class.
 */
#include <mlpack/core.hpp>
#include <mlpack/core/metrics/lmetric.hpp>
#include <boost/test/unit_test.hpp>
#include "old_boost_test_definitions.hpp"

using namespace std;
using namespace mlpack::metric;

BOOST_AUTO_TEST_SUITE(LMetricTest);

BOOST_AUTO_TEST_CASE(L1MetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  ManhattanDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a1 - b1)),
                      lMetric.Evaluate(a1, b1), 1e-5);

  BOOST_REQUIRE_CLOSE((double) arma::accu(arma::abs(a2 - b2)),
                      lMetric.Evaluate(a2, b2), 1e-5);
}

BOOST_AUTO_TEST_CASE(L2MetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  EuclideanDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a1 - b1))),
                      lMetric.Evaluate(a1, b1), 1e-5);

  BOOST_REQUIRE_CLOSE((double) sqrt(arma::accu(arma::square(a2 - b2))),
                      lMetric.Evaluate(a2, b2), 1e-5);
}

BOOST_AUTO_TEST_CASE(LINFMetricTest)
{
  arma::vec a1(5);
  a1.randn();

  arma::vec b1(5);
  b1.randn();

  arma::Col<size_t> a2(5);
  a2 << 1 << 2 << 1 << 0 << 5;

  arma::Col<size_t> b2(5);
  b2 << 2 << 5 << 2 << 0 << 1;

  ChebyshevDistance lMetric;

  BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a1 - b1)),
                      lMetric.Evaluate(a1, b1)), 1e-5);

  BOOST_REQUIRE_CLOSE((double) arma::as_scalar(arma::max(arma::abs(a2 - b2)),
                      lMetric.Evaluate(a2, b2)), 1e-5);
}

BOOST_AUTO_TEST_SUITE_END();
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "progresspie.h"
#include "stylehelper.h"

#include <QtGui/QPainter>
#include <QtGui/QFont>
#include <QtGui/QBrush>
#include <QtGui/QColor>
#include <QtDebug>
#define PROGRESSBAR_HEIGHT 11

ProgressBar::ProgressBar(QWidget *parent)
    : QProgressBar(parent), m_error(false)
{
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    setMouseTracking(true);
}

ProgressBar::~ProgressBar()
{
}

QString ProgressBar::title() const
{
    return m_title;
}

bool ProgressBar::hasError() const
{
    return m_error;
}

void ProgressBar::setTitle(const QString &title)
{
    m_title = title;
}

void ProgressBar::setError(bool on)
{
    m_error = on;
    update();
}

QSize ProgressBar::sizeHint() const
{
    QSize s;
    s.setWidth(50);
    s.setHeight(fontMetrics().height() + PROGRESSBAR_HEIGHT + 7);
    return s;
}

namespace { const int INDENT = 7; }

void ProgressBar::mousePressEvent(QMouseEvent *event)
{
    if (event->modifiers() == Qt::NoModifier
        && event->x() >= size().width()-INDENT-m_progressHeight) {
        event->accept();
        emit clicked();
        return;
    }
    QProgressBar::mousePressEvent(event);
}

void ProgressBar::mouseMoveEvent(QMouseEvent *)
{
    update();
}

void ProgressBar::paintEvent(QPaintEvent *)
{
    // TODO move font into stylehelper
    // TODO use stylehelper white

    double range = maximum() - minimum();
    double percent = 0.50;
    if (range != 0)
        percent = (value() - minimum()) / range;
    if (percent > 1)
        percent = 1;
    else if (percent < 0)
        percent = 0;

    QPainter p(this);
    QFont boldFont(p.font());
    boldFont.setPointSizeF(StyleHelper::sidebarFontSize());
    boldFont.setBold(true);
    p.setFont(boldFont);
    QFontMetrics fm(boldFont);

    // Draw separator
    int h = fm.height();
    p.setPen(QColor(0, 0, 0, 70));
    p.drawLine(0,0, size().width(), 0);

    p.setPen(QColor(255, 255, 255, 70));
    p.drawLine(0, 1, size().width(), 1);

    QRect textRect = rect();
    textRect.setHeight(h+5);

    p.setPen(QColor(30, 30, 30, 80));
    p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
    p.translate(0, -1);
    p.setPen(StyleHelper::panelTextColor());
    p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
    p.translate(0, 1);

    m_progressHeight = PROGRESSBAR_HEIGHT;
    m_progressHeight += ((m_progressHeight % 2) + 1) % 2; // make odd
    // draw outer rect
    QRect rect(INDENT - 1, h+6, size().width()-2*INDENT, m_progressHeight-1);
    p.setPen(StyleHelper::panelTextColor());
    p.drawRect(rect);

    // draw inner rect
    QColor c = StyleHelper::panelTextColor();
    c.setAlpha(180);
    p.setPen(Qt::NoPen);

    QRect inner = rect.adjusted(2, 2, -1, -1);
    inner.adjust(0, 0, qRound((percent - 1) * inner.width()), 0);
    if (m_error) {
        // TODO this is not fancy enough
        QColor red(255, 0, 0, 180);
        p.setBrush(red);
        // avoid too small red bar
        if (inner.width() < 10)
            inner.adjust(0, 0, 10 - inner.width(), 0);
    } else if (value() == maximum()) {
        c = QColor(120, 245, 90, 180);
    }

    QLinearGradient grad(inner.topLeft(), inner.bottomLeft());
    grad.setColorAt(0, c.lighter(114));
    grad.setColorAt(0.5, c.lighter(104));
    grad.setColorAt(0.51, c.darker(108));
    grad.setColorAt(1, c.darker(120));

    p.setBrush(grad);
    p.drawRect(inner);

    if (value() < maximum() && !m_error) {
        QColor cancelOutline = StyleHelper::panelTextColor();
        p.setPen(cancelOutline);
        QRect cancelRect(rect.right() - m_progressHeight + 2, rect.top(), m_progressHeight-1, rect.height());
        if (cancelRect.contains(mapFromGlobal(QCursor::pos())))
            p.setBrush(QColor(230, 90, 40, 190));
        else
            p.setBrush(Qt::NoBrush);

        p.drawRect(cancelRect);

        p.setPen(QPen(QColor(0, 0, 0, 70), 3));
        p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
        p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));

        p.setPen(StyleHelper::panelTextColor());
        p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
        p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));
    }
}
<commit_msg>Fixes:    Fix red color on error for progressbars<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "progresspie.h"
#include "stylehelper.h"

#include <QtGui/QPainter>
#include <QtGui/QFont>
#include <QtGui/QBrush>
#include <QtGui/QColor>
#include <QtDebug>
#define PROGRESSBAR_HEIGHT 11

ProgressBar::ProgressBar(QWidget *parent)
    : QProgressBar(parent), m_error(false)
{
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
    setMouseTracking(true);
}

ProgressBar::~ProgressBar()
{
}

QString ProgressBar::title() const
{
    return m_title;
}

bool ProgressBar::hasError() const
{
    return m_error;
}

void ProgressBar::setTitle(const QString &title)
{
    m_title = title;
}

void ProgressBar::setError(bool on)
{
    m_error = on;
    update();
}

QSize ProgressBar::sizeHint() const
{
    QSize s;
    s.setWidth(50);
    s.setHeight(fontMetrics().height() + PROGRESSBAR_HEIGHT + 7);
    return s;
}

namespace { const int INDENT = 7; }

void ProgressBar::mousePressEvent(QMouseEvent *event)
{
    if (event->modifiers() == Qt::NoModifier
        && event->x() >= size().width()-INDENT-m_progressHeight) {
        event->accept();
        emit clicked();
        return;
    }
    QProgressBar::mousePressEvent(event);
}

void ProgressBar::mouseMoveEvent(QMouseEvent *)
{
    update();
}

void ProgressBar::paintEvent(QPaintEvent *)
{
    // TODO move font into stylehelper
    // TODO use stylehelper white

    double range = maximum() - minimum();
    double percent = 0.50;
    if (range != 0)
        percent = (value() - minimum()) / range;
    if (percent > 1)
        percent = 1;
    else if (percent < 0)
        percent = 0;

    QPainter p(this);
    QFont boldFont(p.font());
    boldFont.setPointSizeF(StyleHelper::sidebarFontSize());
    boldFont.setBold(true);
    p.setFont(boldFont);
    QFontMetrics fm(boldFont);

    // Draw separator
    int h = fm.height();
    p.setPen(QColor(0, 0, 0, 70));
    p.drawLine(0,0, size().width(), 0);

    p.setPen(QColor(255, 255, 255, 70));
    p.drawLine(0, 1, size().width(), 1);

    QRect textRect = rect();
    textRect.setHeight(h+5);

    p.setPen(QColor(30, 30, 30, 80));
    p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
    p.translate(0, -1);
    p.setPen(StyleHelper::panelTextColor());
    p.drawText(textRect, Qt::AlignHCenter | Qt::AlignBottom, m_title);
    p.translate(0, 1);

    m_progressHeight = PROGRESSBAR_HEIGHT;
    m_progressHeight += ((m_progressHeight % 2) + 1) % 2; // make odd
    // draw outer rect
    QRect rect(INDENT - 1, h+6, size().width()-2*INDENT, m_progressHeight-1);
    p.setPen(StyleHelper::panelTextColor());
    p.drawRect(rect);

    // draw inner rect
    QColor c = StyleHelper::panelTextColor();
    c.setAlpha(180);
    p.setPen(Qt::NoPen);

    QRect inner = rect.adjusted(2, 2, -1, -1);
    inner.adjust(0, 0, qRound((percent - 1) * inner.width()), 0);
    if (m_error) {
        QColor red(255, 60, 0, 210);
        c = red;
        // avoid too small red bar
        if (inner.width() < 10)
            inner.adjust(0, 0, 10 - inner.width(), 0);
    } else if (value() == maximum()) {
        c = QColor(120, 245, 90, 180);
    }

    QLinearGradient grad(inner.topLeft(), inner.bottomLeft());
    grad.setColorAt(0, c.lighter(114));
    grad.setColorAt(0.5, c.lighter(104));
    grad.setColorAt(0.51, c.darker(108));
    grad.setColorAt(1, c.darker(120));

    p.setBrush(grad);
    p.drawRect(inner);

    if (value() < maximum() && !m_error) {
        QColor cancelOutline = StyleHelper::panelTextColor();
        p.setPen(cancelOutline);
        QRect cancelRect(rect.right() - m_progressHeight + 2, rect.top(), m_progressHeight-1, rect.height());
        if (cancelRect.contains(mapFromGlobal(QCursor::pos())))
            p.setBrush(QColor(230, 90, 40, 190));
        else
            p.setBrush(Qt::NoBrush);

        p.drawRect(cancelRect);

        p.setPen(QPen(QColor(0, 0, 0, 70), 3));
        p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
        p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));

        p.setPen(StyleHelper::panelTextColor());
        p.drawLine(cancelRect.center()+QPoint(-1,-1), cancelRect.center()+QPoint(+3,+3));
        p.drawLine(cancelRect.center()+QPoint(+3,-1), cancelRect.center()+QPoint(-1,+3));
    }
}
<|endoftext|>


<commit_before>#include "planet.h"

QColor Planet::nextSelectionColor = QColor(1,1,1);

Planet::Planet() : position(0.0f,0.0f,0.0f) {
    mass = 1000.0f;

    selectionColor = nextSelectionColor;

    nextSelectionColor.setRed(nextSelectionColor.red()+1);
    if(nextSelectionColor.red() == 0) {
        nextSelectionColor.setRed(1);
        nextSelectionColor.setGreen(nextSelectionColor.green()+1);
        if(nextSelectionColor.green() == 0){
            nextSelectionColor.setGreen(1);
            nextSelectionColor.setBlue(nextSelectionColor.blue()+1);
        }
    }
    lastpathrecorddelta = 0;
}

Planet::~Planet(){

}

void Planet::draw(){
    glPushMatrix();
    glTranslatef(position.x,position.y,position.z);

    GLUquadric *sphere = gluNewQuadric();
    gluQuadricTexture(sphere, GL_TRUE);
    gluQuadricOrientation(sphere, GLU_OUTSIDE);
    gluSphere(sphere,this->getRadius(),64,32);

    glPopMatrix();
}

void Planet::drawPath(){
    if(path.size() < 1 || glm::distance(path.back(), this->position) > 0.05f){
        path.push_back(this->position);
    }

    // doing this even if it hasn't been recorded allows it to get shorter.
    if(path.size() > pathLength){
        path.erase(path.begin());
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, &path[0]);
    glDrawArrays(GL_LINE_STRIP, 0, path.size());
}

float Planet::getRadius(){
    return pow(3.0f * mass / 4.0f * M_PI, 1.0f / 3.0f) / 10.0f;
}

void Planet::drawBounds(GLenum drawmode, bool selectioncolor){
    bool texturing = glIsEnabled(GL_TEXTURE_2D);
    if(texturing){
        glDisable(GL_TEXTURE_2D);
    }

    if(selectioncolor){
        glColor3f(selectionColor.redF(), selectionColor.greenF(), selectionColor.blueF());
    }
    else{
        glColor3f(0.0f, 1.0f, 0.0f);
    }

    glPushMatrix();
    glTranslatef(position.x,position.y,position.z);

    GLUquadric *sphere = gluNewQuadric();
    gluQuadricOrientation(sphere, GLU_OUTSIDE);
    gluQuadricDrawStyle(sphere, drawmode);
    gluSphere(sphere,this->getRadius()*1.02f,32,16);

    glColor3f(1.0f,1.0f,1.0f);

    if(texturing){
        glEnable(GL_TEXTURE_2D);
    }

    glPopMatrix();
}

unsigned int Planet::pathLength = 200;
<commit_msg>missed line last commit.<commit_after>#include "planet.h"

QColor Planet::nextSelectionColor = QColor(1,1,1);

Planet::Planet() : position(0.0f,0.0f,0.0f) {
    mass = 1000.0f;

    selectionColor = nextSelectionColor;

    nextSelectionColor.setRed(nextSelectionColor.red()+1);
    if(nextSelectionColor.red() == 0) {
        nextSelectionColor.setRed(1);
        nextSelectionColor.setGreen(nextSelectionColor.green()+1);
        if(nextSelectionColor.green() == 0){
            nextSelectionColor.setGreen(1);
            nextSelectionColor.setBlue(nextSelectionColor.blue()+1);
        }
    }
}

Planet::~Planet(){

}

void Planet::draw(){
    glPushMatrix();
    glTranslatef(position.x,position.y,position.z);

    GLUquadric *sphere = gluNewQuadric();
    gluQuadricTexture(sphere, GL_TRUE);
    gluQuadricOrientation(sphere, GLU_OUTSIDE);
    gluSphere(sphere,this->getRadius(),64,32);

    glPopMatrix();
}

void Planet::drawPath(){
    if(path.size() < 1 || glm::distance(path.back(), this->position) > 0.05f){
        path.push_back(this->position);
    }

    // doing this even if it hasn't been recorded allows it to get shorter.
    if(path.size() > pathLength){
        path.erase(path.begin());
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, &path[0]);
    glDrawArrays(GL_LINE_STRIP, 0, path.size());
}

float Planet::getRadius(){
    return pow(3.0f * mass / 4.0f * M_PI, 1.0f / 3.0f) / 10.0f;
}

void Planet::drawBounds(GLenum drawmode, bool selectioncolor){
    bool texturing = glIsEnabled(GL_TEXTURE_2D);
    if(texturing){
        glDisable(GL_TEXTURE_2D);
    }

    if(selectioncolor){
        glColor3f(selectionColor.redF(), selectionColor.greenF(), selectionColor.blueF());
    }
    else{
        glColor3f(0.0f, 1.0f, 0.0f);
    }

    glPushMatrix();
    glTranslatef(position.x,position.y,position.z);

    GLUquadric *sphere = gluNewQuadric();
    gluQuadricOrientation(sphere, GLU_OUTSIDE);
    gluQuadricDrawStyle(sphere, drawmode);
    gluSphere(sphere,this->getRadius()*1.02f,32,16);

    glColor3f(1.0f,1.0f,1.0f);

    if(texturing){
        glEnable(GL_TEXTURE_2D);
    }

    glPopMatrix();
}

unsigned int Planet::pathLength = 200;
<|endoftext|>


<commit_before>/***************************************
** Tsunagari Tile Engine              **
** player.cpp                         **
** Copyright 2011-2013 PariahSoft LLC **
***************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

#include <boost/foreach.hpp>
#include <Gosu/Audio.hpp>
#include <Gosu/Input.hpp>
#include <Gosu/Math.hpp>

#include "area.h"
#include "client-conf.h"
#include "entity.h"
#include "log.h"
#include "player.h"
#include "world.h"
#include "window.h"

#define ASSERT(x)  if (!(x)) { return false; }

template<class Cont, class ValueType>
void removeValue(Cont* c, ValueType v)
{
	typename Cont::iterator it;
	for (it = c->begin(); it != c->end(); ++it) {
		if (*it == v) {
			c->erase(it);
			return;
		}
	}
}

Player::Player()
	: Character(), velocity(0, 0)
{
	nowalkFlags = TILE_NOWALK | TILE_NOWALK_PLAYER;
	nowalkExempt = TILE_NOWALK_EXIT;
}

bool Player::init(const std::string& descriptor, const std::string& initialPhase)
{
	ASSERT(Entity::init(descriptor));
	setPhase(initialPhase);
	return true;
}

void Player::destroy()
{
	// Assuming this is being called from Python code, where this function
	// is bound to the name "delete()".
	Log::err("Player", "delete(): Player cannot be destroyed");
}

void Player::startMovement(ivec2 delta)
{
	switch (conf.moveMode) {
	case TURN:
		moveByTile(delta);
		break;
	case TILE:
		movements.push_back(delta);
		velocity = delta;
		moveByTile(velocity);
		break;
	case NOTILE:
		// TODO
		break;
	}
	stillMoving = velocity;
}

void Player::stopMovement(ivec2 delta)
{
	switch (conf.moveMode) {
	case TURN:
		break;
	case TILE:
		removeValue(&movements, delta);
		velocity = movements.size() ?
		           movements.back() :
			   ivec2(0, 0);
		if (velocity)
			moveByTile(velocity);
		break;
	case NOTILE:
		// TODO
		break;
	}
	stillMoving = velocity;
}

void Player::moveByTile(ivec2 delta)
{
	if (frozen)
		return;
	if (moving)
		return;

	setFacing(delta);

	// Left CTRL allows changing facing, but disallows movement.
	const GameWindow& window = GameWindow::instance();
	if (window.input().down(Gosu::kbLeftControl)) {
		setPhase(directionStr(facing));
		redraw = true;
		return;
	}

	Entity::moveByTile(delta);

	World* world = World::instance();
	world->turn();
}

void Player::useTile()
{
	Tile* t = area->getTile(moveDest(facing));
	if (t)
		t->runUseScript(this);
}

void Player::setFrozen(bool b)
{
	World* world = World::instance();

	b ?  world->storeKeys() : world->restoreKeys();
	Entity::setFrozen(b);
	if (!frozen && velocity)
		moveByTile(velocity);
}

void Player::postMove()
{
	Entity::postMove();

	// Normal exit.
	if (destTile) {
		Exit* exit = destTile->exits[EXIT_NORMAL];
		if (exit)
			takeExit(exit);
	}

	// Side exit.
	if (fromTile) {
		ivec2 dxy(deltaCoord.x, deltaCoord.y);
		Exit* exit = fromTile->exitAt(dxy);
		if (exit)
			takeExit(exit);
	}

	// If we have a velocity, keep moving.
	if (conf.moveMode == TILE && velocity)
		moveByTile(velocity);
}

void Player::takeExit(Exit* exit)
{
	World* world = World::instance();
	Area* newArea = world->getArea(exit->area);
	if (newArea) {
		world->focusArea(newArea, exit->coords);
	}
	else {
		// Roll back movement if exit failed to open.
		setTileCoords(fromCoord);
		Log::err("Exit", exit->area + ": failed to load properly");
	}
}

<commit_msg>c++11: player.cpp<commit_after>/***************************************
** Tsunagari Tile Engine              **
** player.cpp                         **
** Copyright 2011-2013 PariahSoft LLC **
***************************************/

// **********
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// **********

#include <Gosu/Audio.hpp>
#include <Gosu/Input.hpp>
#include <Gosu/Math.hpp>

#include "area.h"
#include "client-conf.h"
#include "entity.h"
#include "log.h"
#include "player.h"
#include "world.h"
#include "window.h"

#define ASSERT(x)  if (!(x)) { return false; }

template<class Cont, class ValueType>
void removeValue(Cont* c, ValueType v)
{
	typename Cont::iterator it;
	for (it = c->begin(); it != c->end(); ++it) {
		if (*it == v) {
			c->erase(it);
			return;
		}
	}
}

Player::Player()
	: Character(), velocity(0, 0)
{
	nowalkFlags = TILE_NOWALK | TILE_NOWALK_PLAYER;
	nowalkExempt = TILE_NOWALK_EXIT;
}

bool Player::init(const std::string& descriptor, const std::string& initialPhase)
{
	ASSERT(Entity::init(descriptor));
	setPhase(initialPhase);
	return true;
}

void Player::destroy()
{
	// Assuming this is being called from Python code, where this function
	// is bound to the name "delete()".
	Log::err("Player", "delete(): Player cannot be destroyed");
}

void Player::startMovement(ivec2 delta)
{
	switch (conf.moveMode) {
	case TURN:
		moveByTile(delta);
		break;
	case TILE:
		movements.push_back(delta);
		velocity = delta;
		moveByTile(velocity);
		break;
	case NOTILE:
		// TODO
		break;
	}
	stillMoving = velocity;
}

void Player::stopMovement(ivec2 delta)
{
	switch (conf.moveMode) {
	case TURN:
		break;
	case TILE:
		removeValue(&movements, delta);
		velocity = movements.size() ?
		           movements.back() :
			   ivec2(0, 0);
		if (velocity)
			moveByTile(velocity);
		break;
	case NOTILE:
		// TODO
		break;
	}
	stillMoving = velocity;
}

void Player::moveByTile(ivec2 delta)
{
	if (frozen)
		return;
	if (moving)
		return;

	setFacing(delta);

	// Left CTRL allows changing facing, but disallows movement.
	const GameWindow& window = GameWindow::instance();
	if (window.input().down(Gosu::kbLeftControl)) {
		setPhase(directionStr(facing));
		redraw = true;
		return;
	}

	Entity::moveByTile(delta);

	World* world = World::instance();
	world->turn();
}

void Player::useTile()
{
	Tile* t = area->getTile(moveDest(facing));
	if (t)
		t->runUseScript(this);
}

void Player::setFrozen(bool b)
{
	World* world = World::instance();

	b ?  world->storeKeys() : world->restoreKeys();
	Entity::setFrozen(b);
	if (!frozen && velocity)
		moveByTile(velocity);
}

void Player::postMove()
{
	Entity::postMove();

	// Normal exit.
	if (destTile) {
		Exit* exit = destTile->exits[EXIT_NORMAL];
		if (exit)
			takeExit(exit);
	}

	// Side exit.
	if (fromTile) {
		ivec2 dxy(deltaCoord.x, deltaCoord.y);
		Exit* exit = fromTile->exitAt(dxy);
		if (exit)
			takeExit(exit);
	}

	// If we have a velocity, keep moving.
	if (conf.moveMode == TILE && velocity)
		moveByTile(velocity);
}

void Player::takeExit(Exit* exit)
{
	World* world = World::instance();
	Area* newArea = world->getArea(exit->area);
	if (newArea) {
		world->focusArea(newArea, exit->coords);
	}
	else {
		// Roll back movement if exit failed to open.
		setTileCoords(fromCoord);
		Log::err("Exit", exit->area + ": failed to load properly");
	}
}

<|endoftext|>


<commit_before>#include <QSettings>

#ifdef Q_OS_WIN32
    #include <winsparkle.h>
#else
    #include "mac-sparkle-support.h"
#endif

#include "api/requests.h"
#include "seafile-applet.h"
#include "utils/utils.h"

#include "auto-update-service.h"

SINGLETON_IMPL(AutoUpdateService)

namespace
{
#ifdef Q_OS_WIN32
    const char *kSparkleAppcastURI = "https://seafile.com/api/client-updates/seafile-client-windows/appcast.xml";
    const char *kWinSparkleRegistryPath = "SOFTWARE\\Seafile\\Seafile Client\\WinSparkle";
#else
    const char *kSparkleAppcastURI = "https://seafile.com/api/client-updates/seafile-client-mac/appcast.xml";
#endif
    const char *kSparkleAlreadyEnableUpdateByDefault = "SparkleAlreadyEnableUpdateByDefault";

QString getAppcastURI() {
    QString url_from_env = qgetenv("SEAFILE_CLIENT_APPCAST_URI");
    if (!url_from_env.isEmpty()) {
        qWarning(
            "winsparkle: using app cast url from SEAFILE_CLIENT_APPCAST_URI: "
            "%s",
            url_from_env.toUtf8().data());
        return url_from_env;
    }
    return kSparkleAppcastURI;
}

} // namespace

// Virtual base class for windows/mac
class AutoUpdateAdapter {
public:
    virtual void prepare() = 0;
    virtual void start() = 0;
    virtual void stop() = 0;
    virtual void checkNow() = 0;
    virtual bool autoUpdateEnabled() = 0;
    virtual void setAutoUpdateEnabled(bool enabled) = 0;
};

#ifdef Q_OS_WIN32
class WindowsAutoUpdateAdapter: public AutoUpdateAdapter {
public:
    void prepare() {
        // Note that @param path is relative to HKCU/HKLM root
        // and the root is not part of it. For example:
        // @code
        //     win_sparkle_set_registry_path("Software\\My App\\Updates");
        // @endcode
        win_sparkle_set_registry_path(kWinSparkleRegistryPath);
        win_sparkle_set_appcast_url(getAppcastURI().toUtf8().data());
        win_sparkle_set_app_details(
            L"Seafile",
            L"Seafile Client",
            QString(STRINGIZE(SEAFILE_CLIENT_VERSION)).toStdWString().c_str());
    }

    void start() {
        win_sparkle_init();
    }

    void stop() {
        win_sparkle_cleanup();
    }

    void checkNow() {
        win_sparkle_check_update_with_ui();
    }

    bool autoUpdateEnabled() {
        // qWarning() << "autoUpdateEnabled =" << win_sparkle_get_automatic_check_for_updates();
        win_sparkle_get_automatic_check_for_updates();
    }

    void setAutoUpdateEnabled(bool enabled) {
        win_sparkle_set_automatic_check_for_updates(enabled ? 1 : 0);
    }
};
#elif defined(Q_OS_MAC)
class MacAutoUpdateAdapter: public AutoUpdateAdapter {
public:
    void prepare() {
        SparkleHelper::setFeedURL(getAppcastURI().toUtf8().data());
    }

    void start() {
    }

    void stop() {
    }

    void checkNow() {
        SparkleHelper::checkForUpdate();
    }

    bool autoUpdateEnabled() {
        return SparkleHelper::autoUpdateEnabled();
    }

    void setAutoUpdateEnabled(bool enabled) {
        SparkleHelper::setAutoUpdateEnabled(enabled);
    }
};
#endif

AutoUpdateService::AutoUpdateService(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_WIN32
    adapter_ = new WindowsAutoUpdateAdapter;
#else
    adapter_ = new MacAutoUpdateAdapter;
#endif
}

void AutoUpdateService::start()
{
    adapter_->prepare();
    enableUpdateByDefault();
    adapter_->start();
}

void AutoUpdateService::enableUpdateByDefault() {
    // Enable auto update check by default.
    QSettings settings;
    settings.beginGroup("Misc");
    bool already_enable_update_by_default = settings.value(kSparkleAlreadyEnableUpdateByDefault, false).toBool();

    if (!already_enable_update_by_default) {
        settings.setValue(kSparkleAlreadyEnableUpdateByDefault, true);
        setAutoUpdateEnabled(true);
    }

    settings.endGroup();
}

void AutoUpdateService::stop()
{
    adapter_->stop();
}

void AutoUpdateService::checkUpdate()
{
    adapter_->checkNow();
}

bool AutoUpdateService::shouldSupportAutoUpdate() const {
    // qWarning() << "shouldSupportAutoUpdate =" << (QString(getBrand()) == "Seafile");
    return QString(getBrand()) == "Seafile";
}

bool AutoUpdateService::autoUpdateEnabled() const {
    return adapter_->autoUpdateEnabled();
}

void AutoUpdateService::setAutoUpdateEnabled(bool enabled) {
    // qWarning() << "setAutoUpdateEnabled:" << enabled;
    adapter_->setAutoUpdateEnabled(enabled);
}
<commit_msg>Fixed a typo in auto update service.<commit_after>#include <QSettings>

#ifdef Q_OS_WIN32
    #include <winsparkle.h>
#else
    #include "mac-sparkle-support.h"
#endif

#include "api/requests.h"
#include "seafile-applet.h"
#include "utils/utils.h"

#include "auto-update-service.h"

SINGLETON_IMPL(AutoUpdateService)

namespace
{
#ifdef Q_OS_WIN32
    const char *kSparkleAppcastURI = "https://seafile.com/api/client-updates/seafile-client-windows/appcast.xml";
    const char *kWinSparkleRegistryPath = "SOFTWARE\\Seafile\\Seafile Client\\WinSparkle";
#else
    const char *kSparkleAppcastURI = "https://seafile.com/api/client-updates/seafile-client-mac/appcast.xml";
#endif
    const char *kSparkleAlreadyEnableUpdateByDefault = "SparkleAlreadyEnableUpdateByDefault";

QString getAppcastURI() {
    QString url_from_env = qgetenv("SEAFILE_CLIENT_APPCAST_URI");
    if (!url_from_env.isEmpty()) {
        qWarning(
            "winsparkle: using app cast url from SEAFILE_CLIENT_APPCAST_URI: "
            "%s",
            url_from_env.toUtf8().data());
        return url_from_env;
    }
    return kSparkleAppcastURI;
}

} // namespace

// Virtual base class for windows/mac
class AutoUpdateAdapter {
public:
    virtual void prepare() = 0;
    virtual void start() = 0;
    virtual void stop() = 0;
    virtual void checkNow() = 0;
    virtual bool autoUpdateEnabled() = 0;
    virtual void setAutoUpdateEnabled(bool enabled) = 0;
};

#ifdef Q_OS_WIN32
class WindowsAutoUpdateAdapter: public AutoUpdateAdapter {
public:
    void prepare() {
        // Note that @param path is relative to HKCU/HKLM root
        // and the root is not part of it. For example:
        // @code
        //     win_sparkle_set_registry_path("Software\\My App\\Updates");
        // @endcode
        win_sparkle_set_registry_path(kWinSparkleRegistryPath);
        win_sparkle_set_appcast_url(getAppcastURI().toUtf8().data());
        win_sparkle_set_app_details(
            L"Seafile",
            L"Seafile Client",
            QString(STRINGIZE(SEAFILE_CLIENT_VERSION)).toStdWString().c_str());
    }

    void start() {
        win_sparkle_init();
    }

    void stop() {
        win_sparkle_cleanup();
    }

    void checkNow() {
        win_sparkle_check_update_with_ui();
    }

    bool autoUpdateEnabled() {
        // qWarning() << "autoUpdateEnabled =" << win_sparkle_get_automatic_check_for_updates();
        return win_sparkle_get_automatic_check_for_updates();
    }

    void setAutoUpdateEnabled(bool enabled) {
        win_sparkle_set_automatic_check_for_updates(enabled ? 1 : 0);
    }
};
#elif defined(Q_OS_MAC)
class MacAutoUpdateAdapter: public AutoUpdateAdapter {
public:
    void prepare() {
        SparkleHelper::setFeedURL(getAppcastURI().toUtf8().data());
    }

    void start() {
    }

    void stop() {
    }

    void checkNow() {
        SparkleHelper::checkForUpdate();
    }

    bool autoUpdateEnabled() {
        return SparkleHelper::autoUpdateEnabled();
    }

    void setAutoUpdateEnabled(bool enabled) {
        SparkleHelper::setAutoUpdateEnabled(enabled);
    }
};
#endif

AutoUpdateService::AutoUpdateService(QObject *parent) : QObject(parent)
{
#ifdef Q_OS_WIN32
    adapter_ = new WindowsAutoUpdateAdapter;
#else
    adapter_ = new MacAutoUpdateAdapter;
#endif
}

void AutoUpdateService::start()
{
    adapter_->prepare();
    enableUpdateByDefault();
    adapter_->start();
}

void AutoUpdateService::enableUpdateByDefault() {
    // Enable auto update check by default.
    QSettings settings;
    settings.beginGroup("Misc");
    bool already_enable_update_by_default = settings.value(kSparkleAlreadyEnableUpdateByDefault, false).toBool();

    if (!already_enable_update_by_default) {
        settings.setValue(kSparkleAlreadyEnableUpdateByDefault, true);
        setAutoUpdateEnabled(true);
    }

    settings.endGroup();
}

void AutoUpdateService::stop()
{
    adapter_->stop();
}

void AutoUpdateService::checkUpdate()
{
    adapter_->checkNow();
}

bool AutoUpdateService::shouldSupportAutoUpdate() const {
    // qWarning() << "shouldSupportAutoUpdate =" << (QString(getBrand()) == "Seafile");
    return QString(getBrand()) == "Seafile";
}

bool AutoUpdateService::autoUpdateEnabled() const {
    return adapter_->autoUpdateEnabled();
}

void AutoUpdateService::setAutoUpdateEnabled(bool enabled) {
    // qWarning() << "setAutoUpdateEnabled:" << enabled;
    adapter_->setAutoUpdateEnabled(enabled);
}
<|endoftext|>


<commit_before>#include "Format.h"
#include <iostream>

int main()
{
    fmtxx::Format(std::cout, "{1} {} {0} {}\n", 1, 2);
        // "2 1 1 2"
    fmtxx::Format(std::cout, "{0:d} {0:x} {0:o} {0:b}\n", 42);
        // "42 2a 52 101010"
    fmtxx::Format(std::cout, "{:<<16}\n", "left");
        // "left<<<<<<<<<<<<"
    fmtxx::Format(std::cout, "{:.^16}\n", "center");
        // ".....center....."
    fmtxx::Format(std::cout, "{:>>16}\n", "right");
        // ">>>>>>>>>>>right"
    fmtxx::Format(std::cout, "{:s}\n", 3.1415927);
        // "3.1415927"
        // Uses fast binary-to-decimal conversions (Grisu2)
        // and an output format similar to printf("%g")
}
<commit_msg>Update examples<commit_after>#if 1

#include "Format.h"
#include <iostream>

int main()
{
    fmtxx::Format(std::cout, "{1} {} {0} {}\n", 1, 2);
        // "2 1 1 2"
    fmtxx::Format(std::cout, "{0:d} {0:x} {0:o} {0:b}\n", 42);
        // "42 2a 52 101010"
    fmtxx::Format(std::cout, "{:-<16}\n", "left");
        // "left------------"
    fmtxx::Format(std::cout, "{:.^16}\n", "center");
        // ".....center....."
    fmtxx::Format(std::cout, "{:~>16}\n", "right");
        // "~~~~~~~~~~~right"
    fmtxx::Format(std::cout, "{:s}\n", 3.1415927);
        // "3.1415927"
        // Uses fast binary-to-decimal conversions (double-conversion)
        // and an output format similar to printf("%g")
}

#endif

#if 0

#include "Format.h"
#include <cmath>

struct Vector2D {
    float x;
    float y;
};

template <>
struct fmtxx::FormatValue<Vector2D>
{
    errc operator()(FormatBuffer& os, FormatSpec const& spec, Vector2D const& value) const
    {
        if (spec.conv == 'p' || spec.conv == 'P')
        {
            auto r   = std::hypot(value.x, value.y);
            auto phi = std::atan2(value.y, value.x);

            return Format(os, "(r={:.3g}, phi={:.3g})", r, phi);
        }

        return Format(os, "({}, {})", value.x, value.y);
    }
};

int main()
{
    Vector2D vec { 3.0, 4.0 };

    fmtxx::Format(stdout, "{}\n", vec);
        // "(3, 4)"
    fmtxx::Format(stdout, "{:p}\n", vec);
        // "(r=5, phi=0.927)"
}

#endif

#if 0

#include "Format.h"
#include <vector>

struct VectorBuffer : public fmtxx::FormatBuffer
{
    std::vector<char>& os;
    explicit VectorBuffer(std::vector<char>& v) : os(v) {}

    bool Put(char c) override {
        os.push_back(c);
        return true;
    }
    bool Write(char const* str, size_t len) override {
        os.insert(os.end(), str, str + len);
        return true;
    }
    bool Pad(char c, size_t count) override {
        os.resize(os.size() + count, c);
        return true;
    }
};

template <>
struct fmtxx::FormatValue<std::vector<char>>
{
    errc operator()(FormatBuffer& fb, FormatSpec const& spec, std::vector<char> const& vec) const
    {
        // The "{*}" means:
        // The formatting specification is given as an argument ('spec' here).
        return fmtxx::Format(fb, "{*}", spec, std::string_view(vec.data(), vec.size()));
    }
};

int main()
{
    std::vector<char> vec;
    fmtxx::FormatTo(VectorBuffer{vec}, "{:5}", -123);
        // out = {' ', '-', '1', '2', '3'}

    fmtxx::Format(stdout, "{}\n", vec);
        // " -123"
}

#endif
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_network.h"
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_attributes.h"

#include "MyString.h"

#include "condor_commands.h"
#include "condor_io.h"
#include "daemon.h"
#include "condor_distribution.h"
#define NUM_ELEMENTS(_ary)   (sizeof(_ary) / sizeof((_ary)[0]))

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

static int CalcTime(int,int,int);
static int TimeLine(const MyString& Name,int FromDate, int ToDate, int Res);

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

static void Usage(char* name)
{
  fprintf(stderr, "Usage: %s [-f filename] [-orgformat] [-pool hostname] [-lastday | -lastweek | -lastmonth | -lasthours h | -from m d y [-to m d y]] {-resourcequery <name> | -resourcelist | -resgroupquery <name> | -resgrouplist | -userquery <name> | -userlist | -usergroupquery <name> | -usergrouplist | -ckptquery | -ckptlist}\n",name);
  exit(1);
}

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

const int MinuteSec=60;
const int HourSec=MinuteSec*60;
const int DaySec=HourSec*24;
const int WeekSec=DaySec*7;
const int MonthSec=DaySec*30;
const int YearSec=DaySec*365;

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

/*
int GrpConvStr(char* InpStr, char* OutStr)
{
  float T,Unclaimed, Matched, Claimed,Preempting,Owner;
  if (sscanf(InpStr," %f %f %f %f %f %f",&T,&Unclaimed,&Matched,&Claimed,&Preempting,&Owner)!=6) return -1;
  sprintf(OutStr,"%f\t%f\t%f\t%f\t%f\t%f\n",T,Unclaimed,Matched,Claimed,Preempting,Owner);
  return 0;
}
*/

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

int ResConvStr(char* InpStr, char* OutStr)
{
  float T,LoadAvg;
  int KbdIdle;
  int State;
  if (sscanf(InpStr," %f %d %f %d",&T,&KbdIdle,&LoadAvg,&State)!=4) return -1;
  const char *stateStr;
  // Note: This should be kept in sync with condor_state.h, and with
  // StartdScanFunc() of view_server.C, and with
  // typedef enum ViewStates of view_server.h
  const char* StateName[] = {
	  "UNCLAIMED",
	  "MATCHED",
	  "CLAIMED",
	  "PRE-EMPTING",
	  "OWNER",
	  "SHUTDOWN",
	  "DELETE",
	  "BACKFILL",
  };
  if (State <= NUM_ELEMENTS(StateName) ) {
	stateStr = StateName[State-1];
  } else {
	stateStr = "UNKNOWN";
  }
  sprintf(OutStr,"%f\t%d\t%f\t%s\n",T,KbdIdle,LoadAvg,stateStr);
  return 0;
}

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

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

int main(int argc, char* argv[])
{
  int Now=time(0);
  int ToDate=Now;
  int FromDate=ToDate-DaySec;
  int Options=0;

  int QueryType=-1;
  MyString QueryArg;

  MyString FileName;
  MyString TimeFileName;
  char* pool = NULL;

  myDistro->Init( argc, argv );

  for(int i=1; i<argc; i++) {

    // Analyze date specifiers

    if (strcmp(argv[i],"-lastday")==0) {
      ToDate=Now;
      FromDate=ToDate-DaySec;
    }
    else if (strcmp(argv[i],"-lastweek")==0) {
      ToDate=Now;
      FromDate=ToDate-WeekSec;
    }
    else if (strcmp(argv[i],"-lastmonth")==0) {
      ToDate=Now;
      FromDate=ToDate-MonthSec;
    }
    else if (strcmp(argv[i],"-lasthours")==0) {
      if (argc-i<=1) Usage(argv[0]);
      int hours=atoi(argv[i+1]);
      ToDate=Now;
      FromDate=ToDate-HourSec*hours;
      i++;
    }
    else if (strcmp(argv[i],"-from")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      FromDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,FromDate);
      i+=3;
    }
    else if (strcmp(argv[i],"-to")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      ToDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,ToDate);
      i+=3;
    }

    // Query type

    else if (strcmp(argv[i],"-resourcelist")==0) {
      QueryType=QUERY_HIST_STARTD_LIST;
    }
    else if (strcmp(argv[i],"-resourcequery")==0) {
      QueryType=QUERY_HIST_STARTD;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-resgrouplist")==0) {
      QueryType=QUERY_HIST_GROUPS_LIST;
    }
    else if (strcmp(argv[i],"-resgroupquery")==0) {
      QueryType=QUERY_HIST_GROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-userlist")==0) {
      QueryType=QUERY_HIST_SUBMITTOR_LIST;
    }
    else if (strcmp(argv[i],"-userquery")==0) {
      QueryType=QUERY_HIST_SUBMITTOR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-usergrouplist")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS_LIST;
    }
    else if (strcmp(argv[i],"-usergroupquery")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-ckptlist")==0) {
      QueryType=QUERY_HIST_CKPTSRVR_LIST;
    }
    else if (strcmp(argv[i],"-ckptquery")==0) {
      QueryType=QUERY_HIST_CKPTSRVR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }

    // miscaleneous

    else if (strcmp(argv[i],"-f")==0) {
      if (argc-i<=1) Usage(argv[0]);
      FileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-timedat")==0) {
      if (argc-i<=1) Usage(argv[0]);
      TimeFileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-orgformat")==0) {
      Options=1;
	}
    else if (strcmp(argv[i],"-pool")==0) {
      if (argc-i<=1) Usage(argv[0]);
	  pool=argv[i+1];
      i++;
    }
    else {
      Usage(argv[0]);
    }
  }

  // Check validity or arguments
  if (QueryType==-1 || FromDate<0 || FromDate>Now || ToDate<FromDate) Usage(argv[0]);
  // if (ToDate>Now) ToDate=Now;

  config();

  Daemon view_host( DT_VIEW_COLLECTOR, 0, pool );
  if( ! view_host.locate() ) {
	  fprintf( stderr, "%s: %s\n", argv[0], view_host.error() );
	  exit(1);
  }

  const int MaxLen=200;
  char Line[MaxLen+1];
  char* LinePtr=Line;

  if (QueryArg.Length()>MaxLen) {
    fprintf(stderr, "Command line argument is too long\n");
    exit(1);
  }
  strcpy(LinePtr, QueryArg.Value());

  if (TimeFileName.Length()>0) TimeLine(TimeFileName,FromDate,ToDate,10);

  // Open the output file
  FILE* outfile=stdout;
  if (FileName.Length()>0) outfile=safe_fopen_wrapper_follow(FileName.Value(),"w");

  if (outfile == NULL) {
	fprintf( stderr, "Failed to open file %s\n", FileName.Value() );
	exit( 1 );
  }

  int LineCount=0;

  ReliSock sock;
  bool connect_error = true;
  do {
    if (sock.connect((char*) view_host.addr(), 0)) {
      connect_error = false;
      break;
    }
  } while (view_host.nextValidCm() == true);

  if (connect_error == true) {
      fprintf( stderr, "failed to connect to the CondorView server (%s)\n",
			 view_host.fullHostname() );
      fputs("No Data.\n",outfile);
      exit(1);
  }

  view_host.startCommand(QueryType, &sock);

  sock.encode();
  if (!sock.code(FromDate) ||
      !sock.code(ToDate) ||
      !sock.code(Options) ||
      !sock.code(LinePtr) ||
      !sock.end_of_message()) {
    fprintf( stderr, "failed to send query to the CondorView server %s\n",
			 view_host.fullHostname() );
    fputs("No Data.\n",outfile);
    exit(1);
  }

  char NewStr[200];

  sock.decode();
  while(1) {
    if (!sock.get(LinePtr,MaxLen)) {
      fprintf(stderr, "failed to receive data from the CondorView server %s\n",
			view_host.fullHostname());
      if (LineCount==0) fputs("No Data.\n",outfile);
      exit(1);
    }
    if (strlen(LinePtr)==0) break;
    LineCount++;
    if (Options==0 && QueryType==QUERY_HIST_STARTD) {
      ResConvStr(LinePtr,NewStr);
      fputs(NewStr,outfile);
    }
    else {
      fputs(LinePtr,outfile);
    }
  }
  if (!sock.end_of_message()) {
    fprintf(stderr, "failed to receive data from the CondorView server\n");
  }

  if (LineCount==0) fputs("No Data.\n",outfile);
  if (FileName.Length()>0) fclose(outfile);

  return 0;
}

int CalcTime(int month, int day, int year) {
  struct tm time_str;
  if (year<50) year+= 100; // If I ask for 1 1 00, I want 1 1 2000
  if (year>1900) year-=1900;
  time_str.tm_year=year;
  time_str.tm_mon=month-1;
  time_str.tm_mday=day;
  time_str.tm_hour=0;
  time_str.tm_min=0;
  time_str.tm_sec=0;
  time_str.tm_isdst=-1;
  return mktime(&time_str);
}

int TimeLine(const MyString& TimeFileName,int FromDate, int ToDate, int Res)
{
  double Interval=double(ToDate-FromDate)/double(Res);
  float RelT;
  time_t T;
  FILE* TimeFile=safe_fopen_wrapper_follow(TimeFileName.Value(),"w");
  if (!TimeFile) return -1;
  for (int i=0; i<=Res; i++) {
    T=(time_t)FromDate+((int)Interval*i);
    RelT=float(100.0/Res)*i;
	fprintf(TimeFile,"%.2f\t%s",RelT,asctime(localtime(&T)));
  }
  fclose(TimeFile);
  return 0;
}
<commit_msg>ResConvStr now avoids a compiler warning by making State unsigned<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_network.h"
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_attributes.h"

#include "MyString.h"

#include "condor_commands.h"
#include "condor_io.h"
#include "daemon.h"
#include "condor_distribution.h"
#define NUM_ELEMENTS(_ary)   (sizeof(_ary) / sizeof((_ary)[0]))

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

static int CalcTime(int,int,int);
static int TimeLine(const MyString& Name,int FromDate, int ToDate, int Res);

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

static void Usage(char* name)
{
  fprintf(stderr, "Usage: %s [-f filename] [-orgformat] [-pool hostname] [-lastday | -lastweek | -lastmonth | -lasthours h | -from m d y [-to m d y]] {-resourcequery <name> | -resourcelist | -resgroupquery <name> | -resgrouplist | -userquery <name> | -userlist | -usergroupquery <name> | -usergrouplist | -ckptquery | -ckptlist}\n",name);
  exit(1);
}

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

const int MinuteSec=60;
const int HourSec=MinuteSec*60;
const int DaySec=HourSec*24;
const int WeekSec=DaySec*7;
const int MonthSec=DaySec*30;
const int YearSec=DaySec*365;

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

/*
int GrpConvStr(char* InpStr, char* OutStr)
{
  float T,Unclaimed, Matched, Claimed,Preempting,Owner;
  if (sscanf(InpStr," %f %f %f %f %f %f",&T,&Unclaimed,&Matched,&Claimed,&Preempting,&Owner)!=6) return -1;
  sprintf(OutStr,"%f\t%f\t%f\t%f\t%f\t%f\n",T,Unclaimed,Matched,Claimed,Preempting,Owner);
  return 0;
}
*/

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

int ResConvStr(char* InpStr, char* OutStr)
{
  float T,LoadAvg;
  int KbdIdle;
  unsigned int State;
  if (sscanf(InpStr," %f %d %f %d",&T,&KbdIdle,&LoadAvg,&State)!=4) return -1;
  const char *stateStr;
  // Note: This should be kept in sync with condor_state.h, and with
  // StartdScanFunc() of view_server.C, and with
  // typedef enum ViewStates of view_server.h
  const char* StateName[] = {
	  "UNCLAIMED",
	  "MATCHED",
	  "CLAIMED",
	  "PRE-EMPTING",
	  "OWNER",
	  "SHUTDOWN",
	  "DELETE",
	  "BACKFILL",
  };
  if (State <= NUM_ELEMENTS(StateName) ) {
	stateStr = StateName[State-1];
  } else {
	stateStr = "UNKNOWN";
  }
  sprintf(OutStr,"%f\t%d\t%f\t%s\n",T,KbdIdle,LoadAvg,stateStr);
  return 0;
}

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

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

int main(int argc, char* argv[])
{
  int Now=time(0);
  int ToDate=Now;
  int FromDate=ToDate-DaySec;
  int Options=0;

  int QueryType=-1;
  MyString QueryArg;

  MyString FileName;
  MyString TimeFileName;
  char* pool = NULL;

  myDistro->Init( argc, argv );

  for(int i=1; i<argc; i++) {

    // Analyze date specifiers

    if (strcmp(argv[i],"-lastday")==0) {
      ToDate=Now;
      FromDate=ToDate-DaySec;
    }
    else if (strcmp(argv[i],"-lastweek")==0) {
      ToDate=Now;
      FromDate=ToDate-WeekSec;
    }
    else if (strcmp(argv[i],"-lastmonth")==0) {
      ToDate=Now;
      FromDate=ToDate-MonthSec;
    }
    else if (strcmp(argv[i],"-lasthours")==0) {
      if (argc-i<=1) Usage(argv[0]);
      int hours=atoi(argv[i+1]);
      ToDate=Now;
      FromDate=ToDate-HourSec*hours;
      i++;
    }
    else if (strcmp(argv[i],"-from")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      FromDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,FromDate);
      i+=3;
    }
    else if (strcmp(argv[i],"-to")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      ToDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,ToDate);
      i+=3;
    }

    // Query type

    else if (strcmp(argv[i],"-resourcelist")==0) {
      QueryType=QUERY_HIST_STARTD_LIST;
    }
    else if (strcmp(argv[i],"-resourcequery")==0) {
      QueryType=QUERY_HIST_STARTD;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-resgrouplist")==0) {
      QueryType=QUERY_HIST_GROUPS_LIST;
    }
    else if (strcmp(argv[i],"-resgroupquery")==0) {
      QueryType=QUERY_HIST_GROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-userlist")==0) {
      QueryType=QUERY_HIST_SUBMITTOR_LIST;
    }
    else if (strcmp(argv[i],"-userquery")==0) {
      QueryType=QUERY_HIST_SUBMITTOR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-usergrouplist")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS_LIST;
    }
    else if (strcmp(argv[i],"-usergroupquery")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-ckptlist")==0) {
      QueryType=QUERY_HIST_CKPTSRVR_LIST;
    }
    else if (strcmp(argv[i],"-ckptquery")==0) {
      QueryType=QUERY_HIST_CKPTSRVR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }

    // miscaleneous

    else if (strcmp(argv[i],"-f")==0) {
      if (argc-i<=1) Usage(argv[0]);
      FileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-timedat")==0) {
      if (argc-i<=1) Usage(argv[0]);
      TimeFileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-orgformat")==0) {
      Options=1;
	}
    else if (strcmp(argv[i],"-pool")==0) {
      if (argc-i<=1) Usage(argv[0]);
	  pool=argv[i+1];
      i++;
    }
    else {
      Usage(argv[0]);
    }
  }

  // Check validity or arguments
  if (QueryType==-1 || FromDate<0 || FromDate>Now || ToDate<FromDate) Usage(argv[0]);
  // if (ToDate>Now) ToDate=Now;

  config();

  Daemon view_host( DT_VIEW_COLLECTOR, 0, pool );
  if( ! view_host.locate() ) {
	  fprintf( stderr, "%s: %s\n", argv[0], view_host.error() );
	  exit(1);
  }

  const int MaxLen=200;
  char Line[MaxLen+1];
  char* LinePtr=Line;

  if (QueryArg.Length()>MaxLen) {
    fprintf(stderr, "Command line argument is too long\n");
    exit(1);
  }
  strcpy(LinePtr, QueryArg.Value());

  if (TimeFileName.Length()>0) TimeLine(TimeFileName,FromDate,ToDate,10);

  // Open the output file
  FILE* outfile=stdout;
  if (FileName.Length()>0) outfile=safe_fopen_wrapper_follow(FileName.Value(),"w");

  if (outfile == NULL) {
	fprintf( stderr, "Failed to open file %s\n", FileName.Value() );
	exit( 1 );
  }

  int LineCount=0;

  ReliSock sock;
  bool connect_error = true;
  do {
    if (sock.connect((char*) view_host.addr(), 0)) {
      connect_error = false;
      break;
    }
  } while (view_host.nextValidCm() == true);

  if (connect_error == true) {
      fprintf( stderr, "failed to connect to the CondorView server (%s)\n",
			 view_host.fullHostname() );
      fputs("No Data.\n",outfile);
      exit(1);
  }

  view_host.startCommand(QueryType, &sock);

  sock.encode();
  if (!sock.code(FromDate) ||
      !sock.code(ToDate) ||
      !sock.code(Options) ||
      !sock.code(LinePtr) ||
      !sock.end_of_message()) {
    fprintf( stderr, "failed to send query to the CondorView server %s\n",
			 view_host.fullHostname() );
    fputs("No Data.\n",outfile);
    exit(1);
  }

  char NewStr[200];

  sock.decode();
  while(1) {
    if (!sock.get(LinePtr,MaxLen)) {
      fprintf(stderr, "failed to receive data from the CondorView server %s\n",
			view_host.fullHostname());
      if (LineCount==0) fputs("No Data.\n",outfile);
      exit(1);
    }
    if (strlen(LinePtr)==0) break;
    LineCount++;
    if (Options==0 && QueryType==QUERY_HIST_STARTD) {
      ResConvStr(LinePtr,NewStr);
      fputs(NewStr,outfile);
    }
    else {
      fputs(LinePtr,outfile);
    }
  }
  if (!sock.end_of_message()) {
    fprintf(stderr, "failed to receive data from the CondorView server\n");
  }

  if (LineCount==0) fputs("No Data.\n",outfile);
  if (FileName.Length()>0) fclose(outfile);

  return 0;
}

int CalcTime(int month, int day, int year) {
  struct tm time_str;
  if (year<50) year+= 100; // If I ask for 1 1 00, I want 1 1 2000
  if (year>1900) year-=1900;
  time_str.tm_year=year;
  time_str.tm_mon=month-1;
  time_str.tm_mday=day;
  time_str.tm_hour=0;
  time_str.tm_min=0;
  time_str.tm_sec=0;
  time_str.tm_isdst=-1;
  return mktime(&time_str);
}

int TimeLine(const MyString& TimeFileName,int FromDate, int ToDate, int Res)
{
  double Interval=double(ToDate-FromDate)/double(Res);
  float RelT;
  time_t T;
  FILE* TimeFile=safe_fopen_wrapper_follow(TimeFileName.Value(),"w");
  if (!TimeFile) return -1;
  for (int i=0; i<=Res; i++) {
    T=(time_t)FromDate+((int)Interval*i);
    RelT=float(100.0/Res)*i;
	fprintf(TimeFile,"%.2f\t%s",RelT,asctime(localtime(&T)));
  }
  fclose(TimeFile);
  return 0;
}
<|endoftext|>


<commit_before>#ifndef _TBLIS_CONFIGS_KNL_CONFIG_HPP_
#define _TBLIS_CONFIGS_KNL_CONFIG_HPP_

#include "configs/config_builder.hpp"

extern "C"
{

EXTERN_GEMM_UKR( float, bli_sgemm_opt_30x16_knc);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_30x8_knc);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_30x8);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_24x8);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_8x24);

}

namespace tblis
{

EXTERN_PACK_NN_UKR(double, knl_packm_30xk);
EXTERN_PACK_NN_UKR(double, knl_packm_24xk);
EXTERN_PACK_NN_UKR(double, knl_packm_8xk);

extern int knl_check();

TBLIS_BEGIN_CONFIG(knl_d30x8_knc)

    TBLIS_CONFIG_GEMM_MR_EXTENT(   30,    30, _, _,
                                   32,    32, _, _)
    TBLIS_CONFIG_GEMM_NR       (   16,     8, _, _)
    TBLIS_CONFIG_GEMM_KR       (   16,     8, _, _)
    TBLIS_CONFIG_GEMM_MC_MAX   (  240,   120, _, _,
                                  300,   150, _, _)
    TBLIS_CONFIG_GEMM_NC       (14400, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX   (  240,   240, _, _,
                                  300,   300, _, _)

    TBLIS_CONFIG_GEMM_UKR(bli_sgemm_opt_30x16_knc,
                          bli_dgemm_opt_30x8_knc,
                          _,
                          _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(true, true, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d30x8)

    TBLIS_CONFIG_GEMM_MR_EXTENT(_,    30, _, _,
                                _,    32, _, _)
    TBLIS_CONFIG_GEMM_NR       (_,     8, _, _)
    TBLIS_CONFIG_GEMM_KR       (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC_MAX   (_,   120, _, _,
                                _,   150, _, _)
    TBLIS_CONFIG_GEMM_NC       (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX   (_,   240, _, _,
                                _,   300, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_30x8, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_30xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_8xk , _, _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(_, true, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d24x8)

    TBLIS_CONFIG_GEMM_MR    (_,    24, _, _)
    TBLIS_CONFIG_GEMM_NR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_KR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC    (_,   120, _, _)
    //TBLIS_CONFIG_GEMM_MC_MAX(_,   120, _, _,
    //                         _,   144, _, _)
    TBLIS_CONFIG_GEMM_NC    (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX(_,   336, _, _,
                             _,   408, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_24x8, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_24xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_8xk , _, _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(_, true, _, _)

    TBLIS_CONFIG_M_THREAD_RATIO(_, 4, _, _)
    TBLIS_CONFIG_NR_MAX_THREAD(_, 1, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d8x24)

    TBLIS_CONFIG_GEMM_MR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_NR    (_,    24, _, _)
    TBLIS_CONFIG_GEMM_KR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC    (_,   120, _, _)
    //TBLIS_CONFIG_GEMM_MC_MAX(_,   120, _, _,
    //                         _,   144, _, _)
    TBLIS_CONFIG_GEMM_NC    (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX(_,   336, _, _,
                             _,   408, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_8x24, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_8xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_24xk , _, _)

    TBLIS_CONFIG_M_THREAD_RATIO(_, 4, _, _)
    TBLIS_CONFIG_NR_MAX_THREAD(_, 1, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

typedef knl_d24x8_config knl_config;

}

#endif
<commit_msg>Update thread ratio for 8x24 knl kernel.<commit_after>#ifndef _TBLIS_CONFIGS_KNL_CONFIG_HPP_
#define _TBLIS_CONFIGS_KNL_CONFIG_HPP_

#include "configs/config_builder.hpp"

extern "C"
{

EXTERN_GEMM_UKR( float, bli_sgemm_opt_30x16_knc);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_30x8_knc);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_30x8);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_24x8);
EXTERN_GEMM_UKR(double, bli_dgemm_opt_8x24);

}

namespace tblis
{

EXTERN_PACK_NN_UKR(double, knl_packm_30xk);
EXTERN_PACK_NN_UKR(double, knl_packm_24xk);
EXTERN_PACK_NN_UKR(double, knl_packm_8xk);

extern int knl_check();

TBLIS_BEGIN_CONFIG(knl_d30x8_knc)

    TBLIS_CONFIG_GEMM_MR_EXTENT(   30,    30, _, _,
                                   32,    32, _, _)
    TBLIS_CONFIG_GEMM_NR       (   16,     8, _, _)
    TBLIS_CONFIG_GEMM_KR       (   16,     8, _, _)
    TBLIS_CONFIG_GEMM_MC_MAX   (  240,   120, _, _,
                                  300,   150, _, _)
    TBLIS_CONFIG_GEMM_NC       (14400, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX   (  240,   240, _, _,
                                  300,   300, _, _)

    TBLIS_CONFIG_GEMM_UKR(bli_sgemm_opt_30x16_knc,
                          bli_dgemm_opt_30x8_knc,
                          _,
                          _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(true, true, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d30x8)

    TBLIS_CONFIG_GEMM_MR_EXTENT(_,    30, _, _,
                                _,    32, _, _)
    TBLIS_CONFIG_GEMM_NR       (_,     8, _, _)
    TBLIS_CONFIG_GEMM_KR       (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC_MAX   (_,   120, _, _,
                                _,   150, _, _)
    TBLIS_CONFIG_GEMM_NC       (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX   (_,   240, _, _,
                                _,   300, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_30x8, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_30xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_8xk , _, _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(_, true, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d24x8)

    TBLIS_CONFIG_GEMM_MR    (_,    24, _, _)
    TBLIS_CONFIG_GEMM_NR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_KR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC    (_,   120, _, _)
    //TBLIS_CONFIG_GEMM_MC_MAX(_,   120, _, _,
    //                         _,   144, _, _)
    TBLIS_CONFIG_GEMM_NC    (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX(_,   336, _, _,
                             _,   408, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_24x8, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_24xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_8xk , _, _)

    TBLIS_CONFIG_GEMM_ROW_MAJOR(_, true, _, _)

    TBLIS_CONFIG_M_THREAD_RATIO(_, 4, _, _)
    TBLIS_CONFIG_NR_MAX_THREAD(_, 1, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

TBLIS_BEGIN_CONFIG(knl_d8x24)

    TBLIS_CONFIG_GEMM_MR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_NR    (_,    24, _, _)
    TBLIS_CONFIG_GEMM_KR    (_,     8, _, _)
    TBLIS_CONFIG_GEMM_MC    (_,   120, _, _)
    //TBLIS_CONFIG_GEMM_MC_MAX(_,   120, _, _,
    //                         _,   144, _, _)
    TBLIS_CONFIG_GEMM_NC    (_, 14400, _, _)
    TBLIS_CONFIG_GEMM_KC_MAX(_,   336, _, _,
                             _,   408, _, _)

    TBLIS_CONFIG_GEMM_UKR(_, bli_dgemm_opt_8x24, _, _)

    TBLIS_CONFIG_PACK_NN_MR_UKR(_, knl_packm_8xk, _, _)
    TBLIS_CONFIG_PACK_NN_NR_UKR(_, knl_packm_24xk , _, _)

    TBLIS_CONFIG_M_THREAD_RATIO(_, 16, _, _)
    TBLIS_CONFIG_NR_MAX_THREAD(_, 1, _, _)

    TBLIS_CONFIG_CHECK(knl_check)

TBLIS_END_CONFIG

typedef knl_d24x8_config knl_config;

}

#endif
<|endoftext|>