<commit_before>#include "parser.h"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <streambuf>

using namespace std;

namespace gpr {

  template<typename T>
  struct parse_stream {
    size_t i;
    vector<T> s;

    template<typename R>
    parse_stream<T>(R v) : s(v.begin(), v.end()) {
      i = 0;
    }

    T next() {
      return s[i];
    }

    int chars_left() const {
      return i < s.size();
    }

    parse_stream<T>& operator++(int) {
      i++;
      return *this;
    }

    parse_stream<T>& operator--(int) {
      i--;
      return *this;
    }

    typename vector<T>::iterator end() {
      return s.end();
    }

    typename vector<T>::iterator begin() {
      return s.end();
    }

    typename vector<T>::iterator remaining() {
      return s.begin() + i;
    }

  };

  typedef parse_stream<char> parse_state;

  void ignore_whitespace(parse_state& s) {
    while (s.chars_left() && (isspace(s.next()) || s.next() == '\r')) { s++; }
  }

  string string_remaining(parse_state& ps) {
    return string(ps.remaining(), ps.end());
  }

  void parse_char(char c, parse_state& s) {
    if (s.next() == c) {
      s++;
      return;
    }
    cout << "Cannot parse char " << c << " from string " << string_remaining(s) << endl;
    assert(false);
  }

  double parse_double(parse_state& s) {
    size_t j = s.i;
    double v = stod(string_remaining(s), &j);
    s.i += j;
    return v;
  }

  double parse_double(parse_stream<string>& s) {
    double v = stod(s.next());
    s++;
    return v;
  }

  int parse_int(parse_stream<string>& s) {
    int i = stoi(s.next());
    s++;
    return i;
  }

  int parse_int(parse_state& s) {
    size_t j = s.i;

    //cout << "Remaining = " << string_remaining(s) << endl;
    int v = stoi(string_remaining(s), &j);

    s.i += j;
    return v;
  }

  double parse_coordinate(char c, parse_state& s) {
    ignore_whitespace(s);
    assert(s.next() == c);
    s++;
    return parse_double(s);
  }

  double parse_option_coordinate(char c, parse_state& s, double def) {
    ignore_whitespace(s);
    if (s.next() == c) {
      s++;
      return parse_double(s);
    }
    return def;
  }

  addr parse_address(char c, parse_stream<string>& s) {
    switch(c) {
    case 'X':
    case 'Y':
    case 'Z':
    case 'I':
    case 'J':
    case 'K':
    case 'F':
    case 'R':
    case 'Q':
    case 'S':
    case 'x':
    case 'y':
    case 'z':
    case 'i':
    case 'j':
    case 'k':
    case 'f':
    case 'r':
    case 's':
    case 'q':
    case 'E':
      return make_double_address(parse_double(s));
    case 'G':
    case 'H':
    case 'M':
    case 'N':
    case 'O':
    case 'T':
    case 'P':
    case 'D':
    case 'L':
    case 'g':
    case 'h':
    case 'm':
    case 'n':
    case 'o':
    case 't':
    case 'p':
    case 'd':
    case 'l':
      return make_int_address(parse_int(s));
    default:
      cout << "Invalid c = " << c << endl;
      cout << "Inavlid c as int = " << ((int) c) << endl;
      cout << "Is EOF? " << (((int) c) == EOF) << endl;
      assert(false);
    }
  }

  string parse_line_comment_with_delimiter(char sc, parse_state& s) {
    string text = "";
    while (s.chars_left() && s.next() != '\n') {
      text += s.next();
      s++;
    }

    return text;
  }

  string parse_comment_with_delimiters(char sc, char ec, parse_state& s) {
    int depth = 0;
    string text = "";
    do {
      if (s.next() == sc) { depth++; }
      else if (s.next() == ec) { depth--; }
      else {
	text += s.next();
      }
      s++;
    } while (s.chars_left() && depth > 0);

    return text;
  }

  string parse_comment_with_delimiters(string sc,
				       string ec,
				       parse_stream<string>& s) {
    int depth = 0;
    string text = "";
    do {
      if (s.next() == sc) { depth++; }
      else if (s.next() == ec) { depth--; }
      else {
	text += s.next();
      }
      s++;
    } while (s.chars_left() && depth > 0);

    return text;
  }

  chunk parse_word_address(parse_stream<string>& s) {
    assert(s.chars_left());
    assert(s.next().size() == 1);

    char c = s.next()[0];
    s++;

    cout << "value to be parsed in parse address = " << s.next() << endl;

    addr a = parse_address(c, s);
    return chunk(c, a);
  }

  chunk parse_chunk(parse_stream<string>& s) {
    assert(s.chars_left());

    if (s.next() == "[") {
      string cs = parse_comment_with_delimiters("[", "]", s);
      return chunk('[', ']', cs);
    } else if (s.next() == "(") {
      string cs = parse_comment_with_delimiters("(", ")", s);

      cout << "Parsed comment = " << cs << endl;
      cout << "Chars left ? " << s.chars_left() << endl;
      cout << "Next s = " << s.next() << endl;

      return chunk('(', ')', cs);

    } else if (s.next() == ";") {
      // s++;
      // string cs = parse_line_comment_with_delimiter(';', s);
      // return chunk(';', ';', cs);
      assert(false);
    } else {
      return parse_word_address(s);
    }

  }

  bool parse_slash(parse_state& s) {
    if (s.next() == '/') {
      s++;
      return true;
    }

    return false;
  }

  bool is_slash(const string& s) {
    if (s.size() != 1) { return false; }

    return s[0] == '/';
  }

  bool parse_slash(parse_stream<string>& s) {
    if (is_slash(s.next())) {
      s++;
      return true;
    }

    return false;
  }

  std::pair<bool, int> parse_line_number(parse_state& s) {
    if (s.next() == 'N') {
      s++;

      int ln = parse_int(s);

      return std::make_pair(true, ln);
    }
    return std::make_pair(false, -1);
  }

  std::pair<bool, int> parse_line_number(parse_stream<string>& s) {
    if (s.next() == "N") {
      s++;

      int ln = parse_int(s);

      return std::make_pair(true, ln);
    }
    return std::make_pair(false, -1);
  }

  block parse_tokens(const std::vector<string>& tokens) {
    cout << "Parsing tokens: ";
    for (auto& t : tokens) {
      cout << t << " ";
    }
    cout << endl;

    parse_stream<string> s(tokens);
    vector<chunk> chunks;
    bool is_slashed = parse_slash(s);

    std::pair<bool, int> line_no =
      parse_line_number(s);

    while (s.chars_left()) {
      chunk ch = parse_chunk(s);
      chunks.push_back(ch);
    }

    if (line_no.first) {
      return block(line_no.second, is_slashed, chunks);
    } else {
      return block(is_slashed, chunks);
    }

  }

  // block lex_gprog_line(const string& str) {
  //   parse_state s(str);

  //   vector<chunk> chunks;

  //   ignore_whitespace(s);

  //   bool is_slashed = parse_slash(s);

  //   ignore_whitespace(s);

  //   std::pair<bool, int> line_no =
  //     parse_line_number(s);

  //   while (s.chars_left()) {
  //     ignore_whitespace(s);
  //     if (!s.chars_left()) { break; }

  //     chunk ch = parse_chunk(s);
  //     chunks.push_back(ch);

  //   }

  //   if (line_no.first) {
  //     return block(line_no.second, is_slashed, chunks);
  //   } else {
  //     return block(is_slashed, chunks);
  //   }
  // }

  // vector<block> lex_gprog(const string& str) {
  //   vector<block> blocks;
  //   string::const_iterator line_start = str.begin();
  //   string::const_iterator line_end;

  //   while (line_start < str.end()) {
  //     line_end = find(line_start, str.end(), '\n');
  //     string line(line_start, line_end);
  //     if (line.size() > 0) {
  // 	block b = lex_gprog_line(line);
  // 	//if (b.size() > 0) {
  // 	  blocks.push_back(b);
  // 	  //}
  //     }
  //     line_start += line.size() + 1;
  //   }
  //   return blocks;
  // }

  vector<block> lex_gprog(const string& str) {
    vector<block> blocks;
    string::const_iterator line_start = str.begin();
    string::const_iterator line_end;

    while (line_start < str.end()) {
      line_end = find(line_start, str.end(), '\n');
      string line(line_start, line_end);
      cout << "Line to parse = " << line << endl;

      if (line.size() > 0) {
	vector<string> line_tokens = lex_block(line);
	block b = parse_tokens(line_tokens);
	blocks.push_back(b);
      }

      line_start += line.size() + 1;
    }
    return blocks;
  }

  gcode_program parse_gcode(const std::string& program_text) {
    auto blocks = lex_gprog(program_text);
    return gcode_program(blocks);
  }

  gcode_program parse_gcode_saving_block_text(const std::string& program_text) {
    auto blocks = lex_gprog(program_text);
    for (auto& b : blocks) {
      b.set_debug_text();
    }
    return gcode_program(blocks);
  }

  bool is_num_char(const char c) {
    return (isdigit(c) ||
	    (c == '.') ||
	    (c == '-'));
  }

  std::string digit_string(parse_state& s) {
    string num_str = "";

    while (s.chars_left() && is_num_char(s.next())) {
      num_str += s.next();
      s++;
    }

    return num_str;
  }

  std::string lex_token(parse_state& s) {
    char c = s.next();
    string next_token = "";

    if (is_num_char(c)) {
      return digit_string(s);
    }

    switch(c) {
    case '%':
      s++;
      return "%";
    case '/':
      s++;
      return "/";

    case '(':
      s++;
      return "(";

    case ')':
      s++;
      return ")";

    case '[':
      s++;
      return "[";

    case ']':
      s++;
      return "]";

    // case 'X':
    // case 'Y':
    // case 'Z':
    // case 'I':
    // case 'J':
    // case 'K':
    // case 'F':
    // case 'R':
    // case 'Q':
    // case 'S':
    // case 'x':
    // case 'y':
    // case 'z':
    // case 'i':
    // case 'j':
    // case 'k':
    // case 'f':
    // case 'r':
    // case 's':
    // case 'q':
    // case 'E':
    // case 'G':
    // case 'H':
    // case 'M':
    // case 'N':
    // case 'O':
    // case 'T':
    // case 'P':
    // case 'D':
    // case 'L':
    // case 'g':
    // case 'h':
    // case 'm':
    // case 'n':
    // case 'o':
    // case 't':
    // case 'p':
    // case 'd':
    // case 'l':
    default:
      next_token += c;
      s++;
      return next_token;
      //    default:
      // cout << "Invalid c = " << c << endl;
      // cout << "Inavlid c as int = " << ((int) c) << endl;
      // cout << "Is EOF? " << (((int) c) == EOF) << endl;
      // assert(false);
    }

  }

  std::vector<std::string> lex_block(const std::string& block_text) {
    parse_state s(block_text);

    vector<string> tokens;

    ignore_whitespace(s);

    while (s.chars_left()) {
      ignore_whitespace(s);
      string token = lex_token(s);
      tokens.push_back(token);
    }

    return tokens;
  }

}
<commit_msg>Fixed bizarre old bug in parse_stream. end was begin, but that did not fix the segfault<commit_after>#include "parser.h"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <streambuf>

using namespace std;

namespace gpr {

  template<typename T>
  struct parse_stream {
    size_t i;
    vector<T> s;

    template<typename R>
    parse_stream<T>(R v) : s(v.begin(), v.end()) {
      i = 0;
    }

    T next() {
      return s[i];
    }

    int chars_left() const {
      return i < s.size();
    }

    parse_stream<T>& operator++(int) {
      i++;
      return *this;
    }

    parse_stream<T>& operator--(int) {
      i--;
      return *this;
    }

    typename vector<T>::iterator end() {
      return s.end();
    }

    typename vector<T>::iterator begin() {
      return s.begin();
    }

    typename vector<T>::iterator remaining() {
      return s.begin() + i;
    }

  };

  typedef parse_stream<char> parse_state;

  void ignore_whitespace(parse_state& s) {
    while (s.chars_left() && (isspace(s.next()) || s.next() == '\r')) { s++; }
  }

  string string_remaining(parse_state& ps) {
    return string(ps.remaining(), ps.end());
  }

  void parse_char(char c, parse_state& s) {
    if (s.next() == c) {
      s++;
      return;
    }
    cout << "Cannot parse char " << c << " from string " << string_remaining(s) << endl;
    assert(false);
  }

  double parse_double(parse_state& s) {
    size_t j = s.i;
    double v = stod(string_remaining(s), &j);
    s.i += j;
    return v;
  }

  double parse_double(parse_stream<string>& s) {
    double v = stod(s.next());
    s++;
    return v;
  }

  int parse_int(parse_stream<string>& s) {
    int i = stoi(s.next());
    s++;
    return i;
  }

  int parse_int(parse_state& s) {
    size_t j = s.i;

    //cout << "Remaining = " << string_remaining(s) << endl;
    int v = stoi(string_remaining(s), &j);

    s.i += j;
    return v;
  }

  double parse_coordinate(char c, parse_state& s) {
    ignore_whitespace(s);
    assert(s.next() == c);
    s++;
    return parse_double(s);
  }

  double parse_option_coordinate(char c, parse_state& s, double def) {
    ignore_whitespace(s);
    if (s.next() == c) {
      s++;
      return parse_double(s);
    }
    return def;
  }

  addr parse_address(char c, parse_stream<string>& s) {
    switch(c) {
    case 'X':
    case 'Y':
    case 'Z':
    case 'I':
    case 'J':
    case 'K':
    case 'F':
    case 'R':
    case 'Q':
    case 'S':
    case 'x':
    case 'y':
    case 'z':
    case 'i':
    case 'j':
    case 'k':
    case 'f':
    case 'r':
    case 's':
    case 'q':
    case 'E':
      return make_double_address(parse_double(s));
    case 'G':
    case 'H':
    case 'M':
    case 'N':
    case 'O':
    case 'T':
    case 'P':
    case 'D':
    case 'L':
    case 'g':
    case 'h':
    case 'm':
    case 'n':
    case 'o':
    case 't':
    case 'p':
    case 'd':
    case 'l':
      return make_int_address(parse_int(s));
    default:
      cout << "Invalid c = " << c << endl;
      cout << "Inavlid c as int = " << ((int) c) << endl;
      cout << "Is EOF? " << (((int) c) == EOF) << endl;
      assert(false);
    }
  }

  string parse_line_comment_with_delimiter(char sc, parse_state& s) {
    string text = "";
    while (s.chars_left() && s.next() != '\n') {
      text += s.next();
      s++;
    }

    return text;
  }

  string parse_comment_with_delimiters(char sc, char ec, parse_state& s) {
    int depth = 0;
    string text = "";
    do {
      if (s.next() == sc) { depth++; }
      else if (s.next() == ec) { depth--; }
      else {
	text += s.next();
      }
      s++;
    } while (s.chars_left() && depth > 0);

    return text;
  }

  string parse_comment_with_delimiters(string sc,
				       string ec,
				       parse_stream<string>& s) {
    int depth = 0;
    string text = "";
    do {
      if (s.next() == sc) { depth++; }
      else if (s.next() == ec) { depth--; }
      else {
	text += s.next();
      }
      s++;
    } while (s.chars_left() && depth > 0);

    return text;
  }

  chunk parse_word_address(parse_stream<string>& s) {
    assert(s.chars_left());
    assert(s.next().size() == 1);

    char c = s.next()[0];
    s++;

    cout << "value to be parsed in parse address = " << s.next() << endl;

    addr a = parse_address(c, s);
    return chunk(c, a);
  }

  chunk parse_chunk(parse_stream<string>& s) {
    assert(s.chars_left());

    if (s.next() == "[") {
      string cs = parse_comment_with_delimiters("[", "]", s);
      return chunk('[', ']', cs);
    } else if (s.next() == "(") {
      string cs = parse_comment_with_delimiters("(", ")", s);

      cout << "Parsed comment = " << cs << endl;
      cout << "Chars left ? " << s.chars_left() << endl;
      cout << "Next s = " << s.next() << endl;

      return chunk('(', ')', cs);

    } else if (s.next() == ";") {
      // s++;
      // string cs = parse_line_comment_with_delimiter(';', s);
      // return chunk(';', ';', cs);
      assert(false);
    } else {
      return parse_word_address(s);
    }

  }

  bool parse_slash(parse_state& s) {
    if (s.next() == '/') {
      s++;
      return true;
    }

    return false;
  }

  bool is_slash(const string& s) {
    if (s.size() != 1) { return false; }

    return s[0] == '/';
  }

  bool parse_slash(parse_stream<string>& s) {
    if (is_slash(s.next())) {
      s++;
      return true;
    }

    return false;
  }

  std::pair<bool, int> parse_line_number(parse_state& s) {
    if (s.next() == 'N') {
      s++;

      int ln = parse_int(s);

      return std::make_pair(true, ln);
    }
    return std::make_pair(false, -1);
  }

  std::pair<bool, int> parse_line_number(parse_stream<string>& s) {
    if (s.next() == "N") {
      s++;

      int ln = parse_int(s);

      return std::make_pair(true, ln);
    }
    return std::make_pair(false, -1);
  }

  block parse_tokens(const std::vector<string>& tokens) {
    cout << "Parsing tokens: ";
    for (auto& t : tokens) {
      cout << t << " ";
    }
    cout << endl;

    parse_stream<string> s(tokens);
    vector<chunk> chunks;
    bool is_slashed = parse_slash(s);

    std::pair<bool, int> line_no =
      parse_line_number(s);

    while (s.chars_left()) {
      chunk ch = parse_chunk(s);
      chunks.push_back(ch);
    }

    if (line_no.first) {
      return block(line_no.second, is_slashed, chunks);
    } else {
      return block(is_slashed, chunks);
    }

  }

  // block lex_gprog_line(const string& str) {
  //   parse_state s(str);

  //   vector<chunk> chunks;

  //   ignore_whitespace(s);

  //   bool is_slashed = parse_slash(s);

  //   ignore_whitespace(s);

  //   std::pair<bool, int> line_no =
  //     parse_line_number(s);

  //   while (s.chars_left()) {
  //     ignore_whitespace(s);
  //     if (!s.chars_left()) { break; }

  //     chunk ch = parse_chunk(s);
  //     chunks.push_back(ch);

  //   }

  //   if (line_no.first) {
  //     return block(line_no.second, is_slashed, chunks);
  //   } else {
  //     return block(is_slashed, chunks);
  //   }
  // }

  // vector<block> lex_gprog(const string& str) {
  //   vector<block> blocks;
  //   string::const_iterator line_start = str.begin();
  //   string::const_iterator line_end;

  //   while (line_start < str.end()) {
  //     line_end = find(line_start, str.end(), '\n');
  //     string line(line_start, line_end);
  //     if (line.size() > 0) {
  // 	block b = lex_gprog_line(line);
  // 	//if (b.size() > 0) {
  // 	  blocks.push_back(b);
  // 	  //}
  //     }
  //     line_start += line.size() + 1;
  //   }
  //   return blocks;
  // }

  vector<block> lex_gprog(const string& str) {
    vector<block> blocks;
    string::const_iterator line_start = str.begin();
    string::const_iterator line_end;

    while (line_start < str.end()) {
      line_end = find(line_start, str.end(), '\n');
      string line(line_start, line_end);
      cout << "Line to parse = " << line << endl;

      if (line.size() > 0) {
	vector<string> line_tokens = lex_block(line);
	block b = parse_tokens(line_tokens);
	blocks.push_back(b);
      }

      line_start += line.size() + 1;
    }
    return blocks;
  }

  gcode_program parse_gcode(const std::string& program_text) {
    auto blocks = lex_gprog(program_text);
    return gcode_program(blocks);
  }

  gcode_program parse_gcode_saving_block_text(const std::string& program_text) {
    auto blocks = lex_gprog(program_text);
    for (auto& b : blocks) {
      b.set_debug_text();
    }
    return gcode_program(blocks);
  }

  bool is_num_char(const char c) {
    return (isdigit(c) ||
	    (c == '.') ||
	    (c == '-'));
  }

  std::string digit_string(parse_state& s) {
    string num_str = "";

    while (s.chars_left() && is_num_char(s.next())) {
      num_str += s.next();
      s++;
    }

    return num_str;
  }

  std::string lex_token(parse_state& s) {
    char c = s.next();
    string next_token = "";

    if (is_num_char(c)) {
      return digit_string(s);
    }

    switch(c) {
    case '%':
      s++;
      return "%";
    case '/':
      s++;
      return "/";

    case '(':
      s++;
      return "(";

    case ')':
      s++;
      return ")";

    case '[':
      s++;
      return "[";

    case ']':
      s++;
      return "]";

    // case 'X':
    // case 'Y':
    // case 'Z':
    // case 'I':
    // case 'J':
    // case 'K':
    // case 'F':
    // case 'R':
    // case 'Q':
    // case 'S':
    // case 'x':
    // case 'y':
    // case 'z':
    // case 'i':
    // case 'j':
    // case 'k':
    // case 'f':
    // case 'r':
    // case 's':
    // case 'q':
    // case 'E':
    // case 'G':
    // case 'H':
    // case 'M':
    // case 'N':
    // case 'O':
    // case 'T':
    // case 'P':
    // case 'D':
    // case 'L':
    // case 'g':
    // case 'h':
    // case 'm':
    // case 'n':
    // case 'o':
    // case 't':
    // case 'p':
    // case 'd':
    // case 'l':
    default:
      next_token += c;
      s++;
      return next_token;
      //    default:
      // cout << "Invalid c = " << c << endl;
      // cout << "Inavlid c as int = " << ((int) c) << endl;
      // cout << "Is EOF? " << (((int) c) == EOF) << endl;
      // assert(false);
    }

  }

  std::vector<std::string> lex_block(const std::string& block_text) {
    parse_state s(block_text);

    vector<string> tokens;

    ignore_whitespace(s);

    while (s.chars_left()) {
      ignore_whitespace(s);
      string token = lex_token(s);
      tokens.push_back(token);
    }

    return tokens;
  }

}
<|endoftext|>


<commit_before>#include "stdio.h"
#include "unistd.h"
#include "sys/time.h"
#include "mpi.h"

#include "master.h"
#include "failure.h"
#include "protocol.h"
#include "log.h"
#include "tools.h"

Master::Master(const std::string &program, Engine &engine, DAG &dag,
               const std::string &dagfile, const std::string &outfile,
               const std::string &errfile) {
    this->program = program;
    this->dagfile = dagfile;
    this->outfile = dagfile + "." + outfile;
    this->errfile = dagfile + "." + errfile;
    this->engine = &engine;
    this->dag = &dag;

    total_count = 0;
    success_count = 0;
    failed_count = 0;
}

Master::~Master() {
}

void Master::submit_task(Task *task, int worker) {
    int rc;
    log_debug("Submitting task %s to worker %d", task->name.c_str(), worker);
    rc = send_request(task->name, task->command, task->extra_id, worker);
    if (rc != 0 ) {
        myfailure("Sending task failed");
    }

    this->total_count++;
}

void Master::wait_for_result() {
    log_trace("Waiting for task to finish");

    std::string name;
    int exitcode;
    double start_time;
    double end_time;
    int worker;
    recv_response(name, start_time, end_time, exitcode, worker);

    // Mark worker idle
    log_trace("Worker %d is idle", worker);
    this->mark_worker_idle(worker);

    // Mark task finished
    if (exitcode == 0) {
        log_debug("Task %s finished with exitcode %d", name.c_str(), exitcode);
        this->success_count++;
    } else {
        log_error("Task %s failed with exitcode %d", name.c_str(), exitcode);
        this->failed_count++;
    }
    Task *t = this->dag->get_task(name);
    this->engine->mark_task_finished(t, exitcode);
}

void Master::add_worker(int worker) {
    this->mark_worker_idle(worker);
}

bool Master::has_idle_worker() {
    return !this->idle.empty();
}

int Master::next_idle_worker() {
    if (!this->has_idle_worker()) {
        myfailure("No idle workers");
    }
    int worker = this->idle.front();
    this->idle.pop();
    return worker;
}

void Master::mark_worker_idle(int worker) {
    this->idle.push(worker);
}

void Master::merge_task_stdio(FILE *dest, const std::string &srcfile, const std::string &stream) {
    log_trace("Merging %s file: %s", stream.c_str(), srcfile.c_str());

    FILE *src = fopen(srcfile.c_str(), "r");
    if (src == NULL) {
        // The file may not exist if the worker didn't run any tasks, just print a warning
        if (errno == ENOENT) {
            log_warn("No %s file: %s", stream.c_str(), srcfile.c_str());
            return;
        } else {
            myfailures("Unable to open task %s file: %s", stream.c_str(), srcfile.c_str());
        }
    }

    char buf[BUFSIZ];
    while (1) {
        int r = fread(buf, 1, BUFSIZ, src);
        if (r < 0) {
            myfailures("Error reading source file: %s", srcfile.c_str());
        }
        if (r == 0) {
            break;
        }
        int w = fwrite(buf, 1, r, dest);
        if (w < r) {
            myfailures("Error writing to dest file");
        }
    }

    fclose(src);

    if (unlink(srcfile.c_str())) {
        myfailures("Unable to delete task %s file: %s", stream.c_str(), srcfile.c_str());
    }
}

int Master::run() {
    // Start time of workflow
    struct timeval start;
    gettimeofday(&start, NULL);

    int numprocs;
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    int numworkers = numprocs - 1;
    if (numworkers == 0) {
        myfailure("Need at least 1 worker");
    }

    log_info("Master starting with %d workers", numworkers);

    // First, send out the paths to the outfile/errfile
    send_stdio_paths(this->outfile, this->errfile);

    // Queue up the workers
    for (int i=1; i<=numworkers; i++) {
        this->add_worker(i);
    }

    // While DAG has tasks to run
    while (!this->engine->is_finished()) {

        // Submit as many tasks as we can
        while (this->engine->has_ready_task() && this->has_idle_worker()) {
            int worker = this->next_idle_worker();
            Task *task = this->engine->next_ready_task();
            this->submit_task(task, worker);
        }

        if (!this->engine->has_ready_task()) {
            log_debug("No ready tasks");
        }

        if (!this->has_idle_worker()) {
            log_debug("No idle workers");
        }

        this->wait_for_result();
    }

    log_info("Workflow finished");

    // Finish time of workflow
    struct timeval finish;
    gettimeofday(&finish, NULL);

    // Tell workers to exit
    // TODO Change this to MPI_Bcast
    log_trace("Sending workers shutdown messages");
    for (int i=1; i<=numworkers; i++) {
        send_shutdown(i);
    }

    log_trace("Waiting for workers to finish");

    double total_runtime = collect_total_runtimes();
    log_info("Total runtime of tasks: %f", total_runtime);

    double stime = start.tv_sec + (start.tv_usec/1000000.0);
    double ftime = finish.tv_sec + (finish.tv_usec/1000000.0);
    double walltime = ftime - stime;
    log_info("Wall time: %lf seconds", walltime);

    // Compute resource utilization
    if (total_runtime > 0) {
        double master_util = total_runtime / (walltime * numprocs);
        double worker_util = total_runtime / (walltime * numworkers);
        log_info("Resource utilization (with master): %lf", master_util);
        log_info("Resource utilization (without master): %lf", worker_util);
    }

    // Merge stdout/stderr from all tasks
    log_trace("Merging stdio from workers");
    FILE *outf = stdout;
    if (outfile != "stdout") {
        fopen(this->outfile.c_str(), "w");
        if (outf == NULL) {
            myfailures("Unable to open stdout file: %s\n", this->outfile.c_str());
        }
    }
    FILE *errf = stderr;
    if (errfile != "stderr") {
        fopen(this->errfile.c_str(), "w");
        if (errf == NULL) {
            myfailures("Unable to open stderr file: %s\n", this->outfile.c_str());
        }
    }

    // Collect all stdout/stderr
    char dotrank[25];
    for (int i=1; i<=numworkers; i++) {
        sprintf(dotrank, ".%d", i);

        std::string toutfile = this->outfile;
        toutfile += dotrank;
        this->merge_task_stdio(outf, toutfile, "stdout");

        std::string terrfile = this->errfile;
        terrfile += dotrank;
        this->merge_task_stdio(errf, terrfile, "stderr");
    }

    // pegasus cluster output - used for provenance
    char buf[BUFSIZ];
    char stat[10];
    char date[32];
    if (this->engine->is_failed()) {
        strcpy(stat, "failed");
    }
    else {
        strcpy(stat, "ok");
    }
    iso2date(stime, date, sizeof(date));
    sprintf(buf, "[cluster-summary stat=\"%s\" tasks=%ld, succeeded=%ld, failed=%ld, extra=%d,"
                 " start=\"%s\", duration=%.3f, pid=%d, app=\"%s\"]\n",
                 stat,
                 this->total_count,
                 this->success_count,
                 this->failed_count,
                 0,
                 date,
                 walltime,
                 getpid(),
                 this->program.c_str());
    fwrite(buf, 1, strlen(buf), outf);

    if (errfile != "stderr") {
        fclose(errf);
    }
    if (outfile != "stdout") {
        fclose(outf);
    }

    if (this->engine->max_failures_reached()) {
        log_error("Max myfailures reached: DAG prematurely aborted");
    }

    if (this->engine->is_failed()) {
        log_error("Workflow failed");
        return 1;
    } else {
        log_info("Workflow suceeded");
        return 0;
    }
}
<commit_msg>Fixed duration to be for all cores<commit_after>#include "stdio.h"
#include "unistd.h"
#include "sys/time.h"
#include "mpi.h"

#include "master.h"
#include "failure.h"
#include "protocol.h"
#include "log.h"
#include "tools.h"

Master::Master(const std::string &program, Engine &engine, DAG &dag,
               const std::string &dagfile, const std::string &outfile,
               const std::string &errfile) {
    this->program = program;
    this->dagfile = dagfile;
    this->outfile = dagfile + "." + outfile;
    this->errfile = dagfile + "." + errfile;
    this->engine = &engine;
    this->dag = &dag;

    total_count = 0;
    success_count = 0;
    failed_count = 0;
}

Master::~Master() {
}

void Master::submit_task(Task *task, int worker) {
    int rc;
    log_debug("Submitting task %s to worker %d", task->name.c_str(), worker);
    rc = send_request(task->name, task->command, task->extra_id, worker);
    if (rc != 0 ) {
        myfailure("Sending task failed");
    }

    this->total_count++;
}

void Master::wait_for_result() {
    log_trace("Waiting for task to finish");

    std::string name;
    int exitcode;
    double start_time;
    double end_time;
    int worker;
    recv_response(name, start_time, end_time, exitcode, worker);

    // Mark worker idle
    log_trace("Worker %d is idle", worker);
    this->mark_worker_idle(worker);

    // Mark task finished
    if (exitcode == 0) {
        log_debug("Task %s finished with exitcode %d", name.c_str(), exitcode);
        this->success_count++;
    } else {
        log_error("Task %s failed with exitcode %d", name.c_str(), exitcode);
        this->failed_count++;
    }
    Task *t = this->dag->get_task(name);
    this->engine->mark_task_finished(t, exitcode);
}

void Master::add_worker(int worker) {
    this->mark_worker_idle(worker);
}

bool Master::has_idle_worker() {
    return !this->idle.empty();
}

int Master::next_idle_worker() {
    if (!this->has_idle_worker()) {
        myfailure("No idle workers");
    }
    int worker = this->idle.front();
    this->idle.pop();
    return worker;
}

void Master::mark_worker_idle(int worker) {
    this->idle.push(worker);
}

void Master::merge_task_stdio(FILE *dest, const std::string &srcfile, const std::string &stream) {
    log_trace("Merging %s file: %s", stream.c_str(), srcfile.c_str());

    FILE *src = fopen(srcfile.c_str(), "r");
    if (src == NULL) {
        // The file may not exist if the worker didn't run any tasks, just print a warning
        if (errno == ENOENT) {
            log_warn("No %s file: %s", stream.c_str(), srcfile.c_str());
            return;
        } else {
            myfailures("Unable to open task %s file: %s", stream.c_str(), srcfile.c_str());
        }
    }

    char buf[BUFSIZ];
    while (1) {
        int r = fread(buf, 1, BUFSIZ, src);
        if (r < 0) {
            myfailures("Error reading source file: %s", srcfile.c_str());
        }
        if (r == 0) {
            break;
        }
        int w = fwrite(buf, 1, r, dest);
        if (w < r) {
            myfailures("Error writing to dest file");
        }
    }

    fclose(src);

    if (unlink(srcfile.c_str())) {
        myfailures("Unable to delete task %s file: %s", stream.c_str(), srcfile.c_str());
    }
}

int Master::run() {
    // Start time of workflow
    struct timeval start;
    gettimeofday(&start, NULL);

    int numprocs;
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

    int numworkers = numprocs - 1;
    if (numworkers == 0) {
        myfailure("Need at least 1 worker");
    }

    log_info("Master starting with %d workers", numworkers);

    // First, send out the paths to the outfile/errfile
    send_stdio_paths(this->outfile, this->errfile);

    // Queue up the workers
    for (int i=1; i<=numworkers; i++) {
        this->add_worker(i);
    }

    // While DAG has tasks to run
    while (!this->engine->is_finished()) {

        // Submit as many tasks as we can
        while (this->engine->has_ready_task() && this->has_idle_worker()) {
            int worker = this->next_idle_worker();
            Task *task = this->engine->next_ready_task();
            this->submit_task(task, worker);
        }

        if (!this->engine->has_ready_task()) {
            log_debug("No ready tasks");
        }

        if (!this->has_idle_worker()) {
            log_debug("No idle workers");
        }

        this->wait_for_result();
    }

    log_info("Workflow finished");

    // Finish time of workflow
    struct timeval finish;
    gettimeofday(&finish, NULL);

    // Tell workers to exit
    // TODO Change this to MPI_Bcast
    log_trace("Sending workers shutdown messages");
    for (int i=1; i<=numworkers; i++) {
        send_shutdown(i);
    }

    log_trace("Waiting for workers to finish");

    double total_runtime = collect_total_runtimes();
    log_info("Total runtime of tasks: %f", total_runtime);

    double stime = start.tv_sec + (start.tv_usec/1000000.0);
    double ftime = finish.tv_sec + (finish.tv_usec/1000000.0);
    double walltime = ftime - stime;
    log_info("Wall time: %lf seconds", walltime);

    // Compute resource utilization
    if (total_runtime > 0) {
        double master_util = total_runtime / (walltime * numprocs);
        double worker_util = total_runtime / (walltime * numworkers);
        log_info("Resource utilization (with master): %lf", master_util);
        log_info("Resource utilization (without master): %lf", worker_util);
    }

    // Merge stdout/stderr from all tasks
    log_trace("Merging stdio from workers");
    FILE *outf = stdout;
    if (outfile != "stdout") {
        fopen(this->outfile.c_str(), "w");
        if (outf == NULL) {
            myfailures("Unable to open stdout file: %s\n", this->outfile.c_str());
        }
    }
    FILE *errf = stderr;
    if (errfile != "stderr") {
        fopen(this->errfile.c_str(), "w");
        if (errf == NULL) {
            myfailures("Unable to open stderr file: %s\n", this->outfile.c_str());
        }
    }

    // Collect all stdout/stderr
    char dotrank[25];
    for (int i=1; i<=numworkers; i++) {
        sprintf(dotrank, ".%d", i);

        std::string toutfile = this->outfile;
        toutfile += dotrank;
        this->merge_task_stdio(outf, toutfile, "stdout");

        std::string terrfile = this->errfile;
        terrfile += dotrank;
        this->merge_task_stdio(errf, terrfile, "stderr");
    }

    // pegasus cluster output - used for provenance
    char buf[BUFSIZ];
    char stat[10];
    char date[32];
    if (this->engine->is_failed()) {
        strcpy(stat, "failed");
    }
    else {
        strcpy(stat, "ok");
    }
    iso2date(stime, date, sizeof(date));
    sprintf(buf, "[cluster-summary stat=\"%s\" tasks=%ld, succeeded=%ld, failed=%ld, extra=%d,"
                 " start=\"%s\", duration=%.3f, pid=%d, app=\"%s\"]\n",
                 stat,
                 this->total_count,
                 this->success_count,
                 this->failed_count,
                 0,
                 date,
                 walltime * numprocs, /* duration is for all cores */
                 getpid(),
                 this->program.c_str());
    fwrite(buf, 1, strlen(buf), outf);

    if (errfile != "stderr") {
        fclose(errf);
    }
    if (outfile != "stdout") {
        fclose(outf);
    }

    if (this->engine->max_failures_reached()) {
        log_error("Max myfailures reached: DAG prematurely aborted");
    }

    if (this->engine->is_failed()) {
        log_error("Workflow failed");
        return 1;
    } else {
        log_info("Workflow suceeded");
        return 0;
    }
}
<|endoftext|>


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

#include "Clocks.h"

namespace facebook {
namespace memcache {
namespace cycles {

uint64_t getCpuCycles() noexcept {
#if defined(__x86_64__)
  uint64_t hi;
  uint64_t lo;
  __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
  return (hi << 32) | lo;
#elif defined(__powerpc__) && \
    (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
  uint64_t val;
  val = __builtin_ppc_get_timebase();
  return val;
#elif defined(__aarch64__)
  uint64_t cval;
  asm volatile("mrs %0, cntvct_el0" : "=r"(cval));
  return cval;
#else
#error Unsupported CPU. Consider implementing your own Clock.
#endif
}

} // namespace cycles
} // namespace memcache
} // namespace facebook
<commit_msg>mcrouter: implement Clock for arm32 and i386<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "Clocks.h"
#include <sys/time.h>

namespace facebook {
namespace memcache {
namespace cycles {

uint64_t getCpuCycles() noexcept {
#if defined(__x86_64__)
  uint64_t hi;
  uint64_t lo;
  __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
  return (hi << 32) | lo;
#elif defined(__i386__)
  uint64_t val;
  __asm__ volatile("rdtsc" : "=A"(val));
  return val;
#elif defined(__powerpc__) && \
    (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
  uint64_t val;
  val = __builtin_ppc_get_timebase();
  return val;
#elif defined(__aarch64__)
  uint64_t cval;
  asm volatile("mrs %0, cntvct_el0" : "=r"(cval));
  return cval;
#elif defined(__ARM_ARCH)
#if (__ARM_ARCH >= 6)
  uint32_t pmccntr;
  uint32_t pmuseren;
  uint32_t pmcntenset;
  asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r"(pmuseren));
  if (pmuseren & 1) {
    asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(pmcntenset));
    if (pmcntenset & 0x80000000ul) {
      asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(pmccntr));
      return static_cast<uint64_t>(pmccntr) * 64;
    }
  }
#endif
  struct timeval tv;
  gettimeofday(&tv, nullptr);
  return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
#else
#error Unsupported CPU. Consider implementing your own Clock.
#endif
}

} // namespace cycles
} // namespace memcache
} // namespace facebook
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    // Decompose the group into individual cells and calculate them individually.

    ScAddress aTmpPos = rTopPos;
    SCROW nOffset = rTopPos.Row() - xGroup->mnStart;
    SCROW nLength = xGroup->mnLength - nOffset;
    std::vector<double> aResults;
    aResults.reserve(nLength);
    for (SCROW i = 0; i < nLength; ++i)
    {
        aTmpPos.SetRow(rTopPos.Row() + i);
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        for (size_t nRow = 0; nRow < nRowSize; ++nRow)
                        {
                            if (nRowStart + nRow < p2->GetArrayLength())
                            {
                                double fVal = pArray[nRowStart+nRow];
                                pMat->PutDouble(fVal, nCol, nRow);
                            }
                        }
                    }

                    ScMatrixToken aTok(pMat);
                    aCode2.AddToken(aTok);
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        ScCompiler aComp(&rDoc, aTmpPos, aCode2);
        aComp.SetGrammar(rDoc.GetGrammar());
        aComp.CompileTokenArray(); // Create RPN token array.
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(rTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}

FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Actually we need to reset the top row to be the top of the group.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    // Decompose the group into individual cells and calculate them individually.

    // Always set the top row to be the top of the group.  Grouped formula
    // cells are to be calculated for its full segment at all times.

    ScAddress aTopPos = rTopPos;
    aTopPos.SetRow(xGroup->mnStart);
    ScAddress aTmpPos = aTopPos;

    std::vector<double> aResults;
    aResults.reserve(xGroup->mnLength);
    for (SCROW i = 0; i < xGroup->mnLength; ++i)
    {
        aTmpPos.SetRow(aTopPos.Row() + i);
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        for (size_t nRow = 0; nRow < nRowSize; ++nRow)
                        {
                            if (nRowStart + nRow < p2->GetArrayLength())
                            {
                                double fVal = pArray[nRowStart+nRow];
                                pMat->PutDouble(fVal, nCol, nRow);
                            }
                        }
                    }

                    ScMatrixToken aTok(pMat);
                    aCode2.AddToken(aTok);
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        ScCompiler aComp(&rDoc, aTmpPos, aCode2);
        aComp.SetGrammar(rDoc.GetGrammar());
        aComp.CompileTokenArray(); // Create RPN token array.
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(aTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}

FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//
//  Copyright 2013 Uncodin, Inc.
//
//  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 "parser.h"

using namespace std;

static void rndr_blockcode(struct buf *ob, struct buf *text, void *opaque);
static void rndr_blockquote(struct buf *ob, struct buf *text, void *opaque);
static void rndr_header(struct buf *ob, struct buf *text, int level, void *opaque);
static void rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque);
static void rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque);
static void rndr_paragraph(struct buf *ob, struct buf *text, void *opaque);
static int rndr_codespan(struct buf *ob, struct buf *text, void *opaque);
static int rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_linebreak(struct buf *ob, void *opaque);
static int rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque);
static void rndr_normal_text(struct buf *ob, struct buf *text, void *opaque);

struct mkd_renderer mkd_callbacks = {
	/* document-level callbacks */
	NULL,                 // prolog
	NULL,                 // epilogue

	/* block-level callbacks */
	rndr_blockcode,       // block code
	rndr_blockquote,      // block quote
	NULL,                 // block html
	rndr_header,          // header
	NULL,                 // hrule
	rndr_list,            // list
	rndr_listitem,        // listitem
	rndr_paragraph,       // paragraph
	NULL,                 // table
	NULL,                 // table cell
	NULL,                 // table row

	/* span-level callbacks */
	NULL,                 // autolink
	rndr_codespan,        // codespan
	rndr_double_emphasis, // double emphasis
	rndr_emphasis,        // emphasis
	NULL,                 // image
	rndr_linebreak,       // line break
	rndr_link,            // link
	NULL,                 // raw html tag
	rndr_triple_emphasis, // triple emphasis

	/* low-level callbacks */
	NULL,                 // entity
	rndr_normal_text,     // normal text

	/* renderer data */
	64, // max stack
	"*_",
	NULL // opaque
};

namespace Bypass {

	const static std::string TWO_SPACES = "  ";
	const static std::string NEWLINE = "\n";

	Parser::Parser()
	: elementSoup()
	{
		elementCount = 1;
	}

	Parser::~Parser() {

	}

	Document Parser::parse(const char* mkd) {
		document = Document();

		if (mkd) {
			struct buf *ib, *ob;

			ib = bufnew(INPUT_UNIT);
			bufputs(ib, mkd);

			ob = bufnew(OUTPUT_UNIT);

			mkd_callbacks.opaque = this;

			//parse and assemble document
			markdown(ob, ib, &mkd_callbacks);

			for (std::map<int, Element>::iterator it = elementSoup.begin(); it != elementSoup.end(); ++it) {
				document.append(it->second);
			}

			bufrelease(ib);
			bufrelease(ob);
		}

		return document;
	}

	Document Parser::parse(const string& markdown) {
		return parse(markdown.c_str());
	}

	void Parser::eraseTrailingControlCharacters(const std::string& controlCharacters) {
		std::map<int, Element>::iterator it = elementSoup.find(elementCount);

		if ( it != elementSoup.end() ) {
			Element * element = &((*it).second);

			if (boost::ends_with(element->text, controlCharacters)) {
				boost::erase_tail(element->text, controlCharacters.size());
			}
		}
	}

	// Block Element Callbacks

	void Parser::handleBlock(Type type, struct buf *ob, struct buf *text, int extra) {
		Element block;
		block.setType(type);

		if (type == HEADER) {
			char levelStr[2];
			snprintf(levelStr, 2, "%d", extra);
			block.addAttribute("level", levelStr);
		}

		std::string textString(text->data, text->data + text->size);
		std::vector<std::string> strs;
		boost::split(strs, textString, boost::is_any_of("|"));

		for(vector<std::string>::iterator it = strs.begin(); it != strs.end(); it++) {
			int pos = atoi((*it).c_str());
			std::map<int, Element>::iterator elit = elementSoup.find(pos);

			if ( elit != elementSoup.end() ) {
				block.append((*elit).second);
				elementSoup.erase(pos);
			}
		}

		elementCount++;

		std::ostringstream oss;
		oss << elementCount;
		elementSoup[elementCount] = block;
		oss << '|';
		bufputs(ob, oss.str().c_str());
	}

	void Parser::parsedBlockCode(struct buf *ob, struct buf *text) {
		parsedNormalText(ob, text);
		eraseTrailingControlCharacters(NEWLINE);

		std::ostringstream oss;
		oss << elementCount << '|';
		bufreset(text);
		bufputs(text, oss.str().c_str());
		handleBlock(BLOCK_CODE, ob, text);
	}

	void Parser::parsedBlockQuote(struct buf *ob, struct buf *text) {
		handleBlock(BLOCK_QUOTE, ob, text);
	}

	void Parser::parsedHeader(struct buf *ob, struct buf *text, int level) {
		handleBlock(HEADER, ob, text, level);
	}

	void Parser::parsedList(struct buf *ob, struct buf *text, int flags) {
		handleBlock(LIST, ob, text);
	}

	void Parser::parsedListItem(struct buf *ob, struct buf *text, int flags) {
		handleBlock(LIST_ITEM, ob, text);
	}

	void Parser::parsedParagraph(struct buf *ob, struct buf *text) {
		handleBlock(PARAGRAPH, ob, text);
	}

	// Span Element Callbacks

	void Parser::handleSpan(Type type, struct buf *ob, struct buf *text, struct buf *extra, struct buf *extra2) {

		std::vector<std::string> strs;
		std::string textString;
		if (text) {
			textString = std::string(text->data, text->data + text->size);
			boost::split(strs, textString, boost::is_any_of("|"));
		}
		if (strs.size() > 0) {
			int pos = atoi(strs[0].c_str());
			std::map<int, Element>::iterator elit = elementSoup.find(pos);

			Element element = elit->second;
			element.setType(type);

			if (extra != NULL && extra->size) {
				if (element.getType() == LINK) {
					element.addAttribute("link", std::string(extra->data, extra->data + extra->size));
				}
			}

			if (extra2 != NULL && extra2->size) {
				if (element.getType() == LINK) {
					element.addAttribute("title", std::string(extra2->data, extra2->data + extra2->size));
				}
			}

			elementSoup.erase(pos);
			elementSoup[pos] = element;

			bufputs(ob, textString.c_str());
		}
		else {
			Element element;
			element.setType(type);

			createSpan(element, ob);
		}
	}

	void Parser::createSpan(const Element& element, struct buf *ob) {
		elementCount++;
		std::ostringstream oss;
		oss << elementCount;
		elementSoup[elementCount] = element;
		oss << '|';
		bufputs(ob, oss.str().c_str());
	}

	int Parser::parsedDoubleEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(DOUBLE_EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedTripleEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(TRIPLE_EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedLink(struct buf *ob, struct buf *link, struct buf *title, struct buf *content) {
		handleSpan(LINK, ob, content, link, title);
		return 1;
	}

	int Parser::parsedCodeSpan(struct buf *ob, struct buf *text) {
		if (text && text->size > 0) {
			Element codeSpan;
			codeSpan.setType(CODE_SPAN);
			codeSpan.text.assign(text->data, text->data + text->size);
			createSpan(codeSpan, ob);
		}
		return 1;
	}

	int Parser::parsedLinebreak(struct buf *ob) {
		eraseTrailingControlCharacters(TWO_SPACES);
		handleSpan(LINEBREAK, ob, NULL);
		return 1;
	}

	// Low Level Callbacks

	void Parser::parsedNormalText(struct buf *ob, struct buf *text) {
		// The parser will spuriously emit a text callback for an empty string
		// that butts up against a span-level element. This will ignore it.

		if (text && text->size > 0) {
			Element normalText;
			normalText.setType(TEXT);
			normalText.text.assign(text->data, text->data + text->size);
			createSpan(normalText, ob);
		}
	}

}

// Block Element callbacks

static void rndr_blockcode(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedBlockCode(ob, text);
}

static void rndr_blockquote(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedBlockQuote(ob, text);
}

static void rndr_header(struct buf *ob, struct buf *text, int level, void *opaque) {
	((Bypass::Parser*) opaque)->parsedHeader(ob, text, level);
}

static void rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque) {
	((Bypass::Parser*) opaque)->parsedList(ob, text, flags);
}

static void rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque) {
	((Bypass::Parser*) opaque)->parsedListItem(ob, text, flags);
}

static void rndr_paragraph(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedParagraph(ob, text);
}

// Span Element callbacks

static int rndr_codespan(struct buf *ob, struct buf *text, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedCodeSpan(ob, text);
}

static int rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedDoubleEmphasis(ob, text, c);
}

static int rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedEmphasis(ob, text, c);
}

static int rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedTripleEmphasis(ob, text, c);
}

static int rndr_linebreak(struct buf *ob, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedLinebreak(ob);
}

static int rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedLink(ob, link, title, content);
}

//	Low Level Callbacks

static void rndr_normal_text(struct buf *ob, struct buf *text, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedNormalText(ob, text);
}

<commit_msg>Fix minor Analyze warning<commit_after>//
//  Copyright 2013 Uncodin, Inc.
//
//  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 "parser.h"

using namespace std;

static void rndr_blockcode(struct buf *ob, struct buf *text, void *opaque);
static void rndr_blockquote(struct buf *ob, struct buf *text, void *opaque);
static void rndr_header(struct buf *ob, struct buf *text, int level, void *opaque);
static void rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque);
static void rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque);
static void rndr_paragraph(struct buf *ob, struct buf *text, void *opaque);
static int rndr_codespan(struct buf *ob, struct buf *text, void *opaque);
static int rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque);
static int rndr_linebreak(struct buf *ob, void *opaque);
static int rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque);
static void rndr_normal_text(struct buf *ob, struct buf *text, void *opaque);

struct mkd_renderer mkd_callbacks = {
	/* document-level callbacks */
	NULL,                 // prolog
	NULL,                 // epilogue

	/* block-level callbacks */
	rndr_blockcode,       // block code
	rndr_blockquote,      // block quote
	NULL,                 // block html
	rndr_header,          // header
	NULL,                 // hrule
	rndr_list,            // list
	rndr_listitem,        // listitem
	rndr_paragraph,       // paragraph
	NULL,                 // table
	NULL,                 // table cell
	NULL,                 // table row

	/* span-level callbacks */
	NULL,                 // autolink
	rndr_codespan,        // codespan
	rndr_double_emphasis, // double emphasis
	rndr_emphasis,        // emphasis
	NULL,                 // image
	rndr_linebreak,       // line break
	rndr_link,            // link
	NULL,                 // raw html tag
	rndr_triple_emphasis, // triple emphasis

	/* low-level callbacks */
	NULL,                 // entity
	rndr_normal_text,     // normal text

	/* renderer data */
	64, // max stack
	"*_",
	NULL // opaque
};

namespace Bypass {

	const static std::string TWO_SPACES = "  ";
	const static std::string NEWLINE = "\n";

	Parser::Parser()
	: elementSoup()
	{
		elementCount = 1;
	}

	Parser::~Parser() {

	}

	Document Parser::parse(const char* mkd) {
		document = Document();

		if (mkd) {
			struct buf *ib, *ob;

			ib = bufnew(INPUT_UNIT);
			bufputs(ib, mkd);

			ob = bufnew(OUTPUT_UNIT);

			mkd_callbacks.opaque = this;

			//parse and assemble document
			markdown(ob, ib, &mkd_callbacks);

			for (std::map<int, Element>::iterator it = elementSoup.begin(); it != elementSoup.end(); ++it) {
				document.append(it->second);
			}

			bufrelease(ib);
			bufrelease(ob);
		}

		return document;
	}

	Document Parser::parse(const string& markdown) {
		return parse(markdown.c_str());
	}

	void Parser::eraseTrailingControlCharacters(const std::string& controlCharacters) {
		std::map<int, Element>::iterator it = elementSoup.find(elementCount);

		if ( it != elementSoup.end() ) {
			Element * element = &((*it).second);

			if (boost::ends_with(element->text, controlCharacters)) {
				boost::erase_tail(element->text, controlCharacters.size());
			}
		}
	}

	// Block Element Callbacks

	void Parser::handleBlock(Type type, struct buf *ob, struct buf *text, int extra) {
		Element block;
		block.setType(type);

		if (type == HEADER) {
			char levelStr[2];
			snprintf(levelStr, 2, "%d", extra);
			block.addAttribute("level", levelStr);
		}

		std::string textString(text->data, text->data + text->size);
		std::vector<std::string> strs;
		boost::split(strs, textString, boost::is_any_of("|"));

		for(vector<std::string>::iterator it = strs.begin(); it != strs.end(); it++) {
			int pos = atoi((*it).c_str());
			std::map<int, Element>::iterator elit = elementSoup.find(pos);

			if ( elit != elementSoup.end() ) {
				block.append((*elit).second);
				elementSoup.erase(pos);
			}
		}

		elementCount++;

		std::ostringstream oss;
		oss << elementCount;
		elementSoup[elementCount] = block;
		oss << '|';
		bufputs(ob, oss.str().c_str());
	}

	void Parser::parsedBlockCode(struct buf *ob, struct buf *text) {
		if(!text) return; // Analyze seems to believe that text can be null here
		parsedNormalText(ob, text);
		eraseTrailingControlCharacters(NEWLINE);

		std::ostringstream oss;
		oss << elementCount << '|';
		bufreset(text);
		bufputs(text, oss.str().c_str());
		handleBlock(BLOCK_CODE, ob, text);
	}

	void Parser::parsedBlockQuote(struct buf *ob, struct buf *text) {
		handleBlock(BLOCK_QUOTE, ob, text);
	}

	void Parser::parsedHeader(struct buf *ob, struct buf *text, int level) {
		handleBlock(HEADER, ob, text, level);
	}

	void Parser::parsedList(struct buf *ob, struct buf *text, int flags) {
		handleBlock(LIST, ob, text);
	}

	void Parser::parsedListItem(struct buf *ob, struct buf *text, int flags) {
		handleBlock(LIST_ITEM, ob, text);
	}

	void Parser::parsedParagraph(struct buf *ob, struct buf *text) {
		handleBlock(PARAGRAPH, ob, text);
	}

	// Span Element Callbacks

	void Parser::handleSpan(Type type, struct buf *ob, struct buf *text, struct buf *extra, struct buf *extra2) {

		std::vector<std::string> strs;
		std::string textString;
		if (text) {
			textString = std::string(text->data, text->data + text->size);
			boost::split(strs, textString, boost::is_any_of("|"));
		}
		if (strs.size() > 0) {
			int pos = atoi(strs[0].c_str());
			std::map<int, Element>::iterator elit = elementSoup.find(pos);

			Element element = elit->second;
			element.setType(type);

			if (extra != NULL && extra->size) {
				if (element.getType() == LINK) {
					element.addAttribute("link", std::string(extra->data, extra->data + extra->size));
				}
			}

			if (extra2 != NULL && extra2->size) {
				if (element.getType() == LINK) {
					element.addAttribute("title", std::string(extra2->data, extra2->data + extra2->size));
				}
			}

			elementSoup.erase(pos);
			elementSoup[pos] = element;

			bufputs(ob, textString.c_str());
		}
		else {
			Element element;
			element.setType(type);

			createSpan(element, ob);
		}
	}

	void Parser::createSpan(const Element& element, struct buf *ob) {
		elementCount++;
		std::ostringstream oss;
		oss << elementCount;
		elementSoup[elementCount] = element;
		oss << '|';
		bufputs(ob, oss.str().c_str());
	}

	int Parser::parsedDoubleEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(DOUBLE_EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedTripleEmphasis(struct buf *ob, struct buf *text, char c) {
		handleSpan(TRIPLE_EMPHASIS, ob, text);
		return 1;
	}

	int Parser::parsedLink(struct buf *ob, struct buf *link, struct buf *title, struct buf *content) {
		handleSpan(LINK, ob, content, link, title);
		return 1;
	}

	int Parser::parsedCodeSpan(struct buf *ob, struct buf *text) {
		if (text && text->size > 0) {
			Element codeSpan;
			codeSpan.setType(CODE_SPAN);
			codeSpan.text.assign(text->data, text->data + text->size);
			createSpan(codeSpan, ob);
		}
		return 1;
	}

	int Parser::parsedLinebreak(struct buf *ob) {
		eraseTrailingControlCharacters(TWO_SPACES);
		handleSpan(LINEBREAK, ob, NULL);
		return 1;
	}

	// Low Level Callbacks

	void Parser::parsedNormalText(struct buf *ob, struct buf *text) {
		// The parser will spuriously emit a text callback for an empty string
		// that butts up against a span-level element. This will ignore it.

		if (text && text->size > 0) {
			Element normalText;
			normalText.setType(TEXT);
			normalText.text.assign(text->data, text->data + text->size);
			createSpan(normalText, ob);
		}
	}

}

// Block Element callbacks

static void rndr_blockcode(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedBlockCode(ob, text);
}

static void rndr_blockquote(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedBlockQuote(ob, text);
}

static void rndr_header(struct buf *ob, struct buf *text, int level, void *opaque) {
	((Bypass::Parser*) opaque)->parsedHeader(ob, text, level);
}

static void rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque) {
	((Bypass::Parser*) opaque)->parsedList(ob, text, flags);
}

static void rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque) {
	((Bypass::Parser*) opaque)->parsedListItem(ob, text, flags);
}

static void rndr_paragraph(struct buf *ob, struct buf *text, void *opaque) {
	((Bypass::Parser*) opaque)->parsedParagraph(ob, text);
}

// Span Element callbacks

static int rndr_codespan(struct buf *ob, struct buf *text, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedCodeSpan(ob, text);
}

static int rndr_double_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedDoubleEmphasis(ob, text, c);
}

static int rndr_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedEmphasis(ob, text, c);
}

static int rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedTripleEmphasis(ob, text, c);
}

static int rndr_linebreak(struct buf *ob, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedLinebreak(ob);
}

static int rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedLink(ob, link, title, content);
}

//	Low Level Callbacks

static void rndr_normal_text(struct buf *ob, struct buf *text, void *opaque) {
	return ((Bypass::Parser*) opaque)->parsedNormalText(ob, text);
}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#ifndef _Stroika_Foundation_Streams_InputStream_inl_
#define _Stroika_Foundation_Streams_InputStream_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Streams {

            /*
             ********************************************************************************
             **************************** InputStream<ELEMENT_TYPE> *************************
             ********************************************************************************
             */
            template    <typename ELEMENT_TYPE>
            inline  InputStream<ELEMENT_TYPE>::InputStream (const _SharedIRep& rep)
                : inherited (rep)
            {
            }
            template    <typename ELEMENT_TYPE>
            inline  InputStream<ELEMENT_TYPE>::InputStream (nullptr_t)
                : inherited (nullptr)
            {
            }
            template    <typename ELEMENT_TYPE>
            inline  auto    InputStream<ELEMENT_TYPE>::_GetRep () const -> _SharedIRep
            {
                return dynamic_pointer_cast<_IRep> (inherited::_GetRep ());
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType  InputStream<ELEMENT_TYPE>::GetOffset () const
            {
                return _GetRep ()->GetReadOffset ();
            }
            template    <typename ELEMENT_TYPE>
            SeekOffsetType  InputStream<ELEMENT_TYPE>::GetOffsetToEndOfStream () const
            {
                SeekOffsetType  savedReadFrom = GetOffset ();
                SeekOffsetType  size =  Seek (Whence::eFromEnd, 0);
                Seek (Whence::eFromStart, savedReadFrom);
                Assert (size >= savedReadFrom);
                size -= savedReadFrom;
                return size;
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType    InputStream<ELEMENT_TYPE>::Seek (SignedSeekOffsetType offset) const
            {
                return _GetRep ()->SeekRead (Whence::eFromStart, offset);
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType    InputStream<ELEMENT_TYPE>::Seek (Whence whence, SignedSeekOffsetType offset) const
            {
                return _GetRep ()->SeekRead (whence, offset);
            }
            template    <typename ELEMENT_TYPE>
            inline  auto  InputStream<ELEMENT_TYPE>::Read () const -> Memory::Optional<ElementType> {
                ElementType b {};
                RequireNotNull (_GetRep ().get ());
                if (_GetRep ()->Read (&b, &b + 1) == 0)
                {
                    return Memory::Optional<ElementType> ();
                }
                else {
                    return b;
                }
            }
            template    <typename ELEMENT_TYPE>
            inline  size_t  InputStream<ELEMENT_TYPE>::Read (ElementType* intoStart, ElementType* intoEnd) const
            {
                RequireNotNull (intoStart);
                Require ((intoEnd - intoStart) >= 1);
                RequireNotNull (_GetRep ().get ());
                return _GetRep ()->Read (nullptr, intoStart, intoEnd);
            }
            template    <typename ELEMENT_TYPE>
            size_t  InputStream<ELEMENT_TYPE>::Read (SeekOffsetType* offset, ElementType* intoStart, ElementType* intoEnd) const
            {
                RequireNotNull (offset);
                return _GetRep ()->Read (offset, intoStart, intoEnd);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Streams_InputStream_inl_*/
<commit_msg>fixed Streams/InputStreams regression<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#ifndef _Stroika_Foundation_Streams_InputStream_inl_
#define _Stroika_Foundation_Streams_InputStream_inl_  1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include    "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Streams {

            /*
             ********************************************************************************
             **************************** InputStream<ELEMENT_TYPE> *************************
             ********************************************************************************
             */
            template    <typename ELEMENT_TYPE>
            inline  InputStream<ELEMENT_TYPE>::InputStream (const _SharedIRep& rep)
                : inherited (rep)
            {
            }
            template    <typename ELEMENT_TYPE>
            inline  InputStream<ELEMENT_TYPE>::InputStream (nullptr_t)
                : inherited (nullptr)
            {
            }
            template    <typename ELEMENT_TYPE>
            inline  auto    InputStream<ELEMENT_TYPE>::_GetRep () const -> _SharedIRep
            {
                return dynamic_pointer_cast<_IRep> (inherited::_GetRep ());
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType  InputStream<ELEMENT_TYPE>::GetOffset () const
            {
                return _GetRep ()->GetReadOffset ();
            }
            template    <typename ELEMENT_TYPE>
            SeekOffsetType  InputStream<ELEMENT_TYPE>::GetOffsetToEndOfStream () const
            {
                SeekOffsetType  savedReadFrom = GetOffset ();
                SeekOffsetType  size =  Seek (Whence::eFromEnd, 0);
                Seek (Whence::eFromStart, savedReadFrom);
                Assert (size >= savedReadFrom);
                size -= savedReadFrom;
                return size;
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType    InputStream<ELEMENT_TYPE>::Seek (SignedSeekOffsetType offset) const
            {
                return _GetRep ()->SeekRead (Whence::eFromStart, offset);
            }
            template    <typename ELEMENT_TYPE>
            inline  SeekOffsetType    InputStream<ELEMENT_TYPE>::Seek (Whence whence, SignedSeekOffsetType offset) const
            {
                return _GetRep ()->SeekRead (whence, offset);
            }
            template    <typename ELEMENT_TYPE>
            inline  auto  InputStream<ELEMENT_TYPE>::Read () const -> Memory::Optional<ElementType> {
                ElementType b {};
                RequireNotNull (_GetRep ());
                return (_GetRep ()->Read (nullptr, &b, &b + 1) == 0)? Memory::Optional<ElementType> () : b;
            }
            template    <typename ELEMENT_TYPE>
            inline  size_t  InputStream<ELEMENT_TYPE>::Read (ElementType* intoStart, ElementType* intoEnd) const
            {
                RequireNotNull (intoStart);
                Require ((intoEnd - intoStart) >= 1);
                RequireNotNull (_GetRep ().get ());
                return _GetRep ()->Read (nullptr, intoStart, intoEnd);
            }
            template    <typename ELEMENT_TYPE>
            size_t  InputStream<ELEMENT_TYPE>::Read (SeekOffsetType* offset, ElementType* intoStart, ElementType* intoEnd) const
            {
                RequireNotNull (offset);
                return _GetRep ()->Read (offset, intoStart, intoEnd);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Streams_InputStream_inl_*/
<|endoftext|>


<commit_before>#if !defined(ASCII_TREE_GRAMMAR_H)
#define ASCII_TREE_GRAMMAR_H

#include <utility>
#include <cctype>
#include <string>
#include <vector>

#if 0

GRAMMAR
========

tokens:           token
                  tokens token

token:            node
                  horizontal-edge
                  edge-part

node:             root-node
                  named-node

root-node:        '[' '*' ']'

named-node:       '[' node-name ']'

node-name:        name-chars

name-chars:       name-char
                  name-chars name-char

name-char:        alnum
                  '_'

alnum:            one of: [A-Za-z0-9]

horizontal-edge:  edge-chars edge-name edge-chars

edge-chars:       '-'
                  edge-chars '-'

edge-name:        '(' name-chars ')'

edge-part:        '\'
                  '|'
                  '/'
                  edge-name

#endif

namespace ascii_tree
{
    struct ascii_tree_parse_exception
    {
        const std::string s;
        const size_t pos;

        ascii_tree_parse_exception(const std::string& s, size_t pos) : s(s), pos(pos) {}
    };

    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        std::string name;

        token(toktype type, std::string&& name) : type(type), name(std::move(name)) {}
    };

    inline token root_node() { return token(token::root_node, ""); }
    inline token named_node(std::string&& name) { return token(token::named_node, std::move(name)); }
    inline token edge_name(std::string&& name) { return token(token::edge_name, std::move(name)); }
    inline token horizontal_edge(std::string&& name) { return token(token::horizontal_edge, std::move(name)); }
    inline token ascending_edge_part() { return token(token::ascending_edge_part, ""); }
    inline token descending_edge_part() { return token(token::descending_edge_part, ""); }
    inline token vertical_edge_part() { return token(token::vertical_edge_part, ""); }

    inline bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    inline std::vector<token> tokenize(const std::string& s)
    {
        std::vector<token> tokens;
        enum {
            none, open_square_brace, close_square_brace, asterisk, dash,
            open_paren, close_paren, name_char, slash, backslash, pipe
        } prev_ch = none, prev_prev_ch = none;
        size_t marker = 0, marked_length = 0;

        for (size_t i = 0; i < s.size(); ++i)
        {
            auto ch = s[i];

            if (ch == '[')
            {
                if (prev_ch == open_square_brace)
                {
                    throw ascii_tree_parse_exception(s, i);
                }

                prev_ch = open_square_brace;
            }
            else if (ch == ']')
            {
                if (prev_ch == asterisk)
                {
                    tokens.emplace_back(root_node());
                }
                else if (prev_ch == open_square_brace)
                {
                    throw ascii_tree_parse_exception(s, i);
                }
                else
                {
                    tokens.emplace_back(named_node(s.substr(marker, marked_length)));
                }

                prev_ch = close_square_brace;
            }
            else if (ch == '*')
            {
                prev_ch = asterisk;
            }
            else if (ch == '-')
            {
                if (prev_ch == close_paren)
                {
                    tokens.emplace_back(horizontal_edge(s.substr(marker, marked_length)));
                }

                prev_ch = dash;
            }
            else if (ch == '/')
            {
                tokens.emplace_back(ascending_edge_part());
                prev_ch = slash;
            }
            else if (ch == '\\')
            {
                tokens.emplace_back(descending_edge_part());
                prev_ch = backslash;
            }
            else if (ch == '|')
            {
                tokens.emplace_back(vertical_edge_part());
                prev_ch = pipe;
            }
            else if (ch == '(')
            {
                if (prev_ch == dash) { prev_prev_ch = dash; }
                prev_ch = open_paren;
            }
            else if (ch == ')')
            {
                if (prev_prev_ch == none)
                {
                    tokens.emplace_back(edge_name(s.substr(marker, marked_length)));
                }

                prev_ch = close_paren;
            }
            else if (isalnum(ch) || ch == '_')
            {
                if (prev_ch != name_char)
                {
                    marker = i;
                    marked_length = 0;
                }

                prev_ch = name_char;
                ++marked_length;
            }
            else if (ch != ' ')
            {
                throw ascii_tree_parse_exception(s, i);
            }
        }

        return tokens;
    }
}

#endif // ASCII_TREE_GRAMMAR_H
<commit_msg>promote enum for terminal characters out of tokenize function<commit_after>#if !defined(ASCII_TREE_GRAMMAR_H)
#define ASCII_TREE_GRAMMAR_H

#include <utility>
#include <cctype>
#include <string>
#include <vector>

#if 0

GRAMMAR
========

tokens:           token
                  tokens token

token:            node
                  horizontal-edge
                  edge-part

node:             root-node
                  named-node

root-node:        '[' '*' ']'

named-node:       '[' node-name ']'

node-name:        name-chars

name-chars:       name-char
                  name-chars name-char

name-char:        alnum
                  '_'

alnum:            one of: [A-Za-z0-9]

horizontal-edge:  edge-chars edge-name edge-chars

edge-chars:       '-'
                  edge-chars '-'

edge-name:        '(' name-chars ')'

edge-part:        '\'
                  '|'
                  '/'
                  edge-name

#endif

namespace ascii_tree
{
    struct ascii_tree_parse_exception
    {
        const std::string s;
        const size_t pos;

        ascii_tree_parse_exception(const std::string& s, size_t pos) : s(s), pos(pos) {}
    };

    struct token
    {
        enum toktype { root_node, named_node, edge_name, horizontal_edge, ascending_edge_part, descending_edge_part, vertical_edge_part };
        toktype type;
        std::string name;

        token(toktype type, std::string&& name) : type(type), name(std::move(name)) {}
    };

    inline token root_node() { return token(token::root_node, ""); }
    inline token named_node(std::string&& name) { return token(token::named_node, std::move(name)); }
    inline token edge_name(std::string&& name) { return token(token::edge_name, std::move(name)); }
    inline token horizontal_edge(std::string&& name) { return token(token::horizontal_edge, std::move(name)); }
    inline token ascending_edge_part() { return token(token::ascending_edge_part, ""); }
    inline token descending_edge_part() { return token(token::descending_edge_part, ""); }
    inline token vertical_edge_part() { return token(token::vertical_edge_part, ""); }

    inline bool operator==(const token& lhs, const token& rhs)
    {
        return lhs.type == rhs.type
            && lhs.name == rhs.name;
    }

    enum Terminals
    {
        none, open_square_brace, close_square_brace, asterisk, dash,
        open_paren, close_paren, name_char, slash, backslash, pipe
    };

    inline std::vector<token> tokenize(const std::string& s)
    {
        std::vector<token> tokens;
        Terminals prev_ch = none, prev_prev_ch = none;
        size_t marker = 0, marked_length = 0;

        for (size_t i = 0; i < s.size(); ++i)
        {
            auto ch = s[i];

            if (ch == '[')
            {
                if (prev_ch == open_square_brace)
                {
                    throw ascii_tree_parse_exception(s, i);
                }

                prev_ch = open_square_brace;
            }
            else if (ch == ']')
            {
                if (prev_ch == asterisk)
                {
                    tokens.emplace_back(root_node());
                }
                else if (prev_ch == open_square_brace)
                {
                    throw ascii_tree_parse_exception(s, i);
                }
                else
                {
                    tokens.emplace_back(named_node(s.substr(marker, marked_length)));
                }

                prev_ch = close_square_brace;
            }
            else if (ch == '*')
            {
                prev_ch = asterisk;
            }
            else if (ch == '-')
            {
                if (prev_ch == close_paren)
                {
                    tokens.emplace_back(horizontal_edge(s.substr(marker, marked_length)));
                }

                prev_ch = dash;
            }
            else if (ch == '/')
            {
                tokens.emplace_back(ascending_edge_part());
                prev_ch = slash;
            }
            else if (ch == '\\')
            {
                tokens.emplace_back(descending_edge_part());
                prev_ch = backslash;
            }
            else if (ch == '|')
            {
                tokens.emplace_back(vertical_edge_part());
                prev_ch = pipe;
            }
            else if (ch == '(')
            {
                if (prev_ch == dash) { prev_prev_ch = dash; }
                prev_ch = open_paren;
            }
            else if (ch == ')')
            {
                if (prev_prev_ch == none)
                {
                    tokens.emplace_back(edge_name(s.substr(marker, marked_length)));
                }

                prev_ch = close_paren;
            }
            else if (isalnum(ch) || ch == '_')
            {
                if (prev_ch != name_char)
                {
                    marker = i;
                    marked_length = 0;
                }

                prev_ch = name_char;
                ++marked_length;
            }
            else if (ch != ' ')
            {
                throw ascii_tree_parse_exception(s, i);
            }
        }

        return tokens;
    }
}

#endif // ASCII_TREE_GRAMMAR_H
<|endoftext|>


<commit_before>#ifndef FORMATION_HPP
#define FORMATION_HPP 1

#include <QString>
#include <map>

#include "structures.hpp"
#include "singleton.hpp"
#include "manager.hpp"
#include "uvmanager.hpp"

#include <iostream>

class Formation;
typedef Singleton<Manager<Formation>> FormationManager;

#define CUM CategorieUVManager::getInstance()
#define UVM UvManager::getInstance()
#define FM FormationManager::getInstance()

//! Classe des Formations
class Formation : public BaseItem {

  public:

    Formation(const QString& abbr, const QString& n)
        : BaseItem(abbr), longName(n), parent(""), nbLignes(0), nbColonnes(0),
          minCredits(0), minNbUvRecommended(0) {}

    inline const QString& getLongName() const { return longName; }
    inline bool hasParent() const { return parent != ""; }

    //! Retourne le parent de la formation, lève une exception s’il n’existe pas
    inline const Formation& getParent() const { return FM->getItem(parent); }

    inline const std::map<CategorieUV, int>& getRequirements() const { return requirements; }
    inline unsigned int getLignesTSH() const { return nbLignes; }
    inline unsigned int getColonnesTSH() const { return nbColonnes; }

    inline bool hasChildren() const {
        std::vector<Formation> formations = FM->iterator();
        for(auto it=formations.begin(); it!=formations.end(); it++) {
            if (it->hasParent() && (it->getParent() == *this)) {
                return true;
            }
        }
        return false;
    }

    inline void setLongName(const QString &l) { longName = l; }
    inline void setRequirements(const QString &c, unsigned int n) {
        //Vérifie si la catégorie existe
        CategorieUV cat("", "");
        try {
            cat = CUM->getItem(c);
        } catch (Exception) {
            return;
        }

        requirements[cat] = n;
    }

    inline void setParent(const QString& p) {
        //On vérifie que le parent existe
        try {
            FM->getItem(p);
        } catch (Exception) {
            return;
        }

        parent = p;
    }
    inline void setLignesTSH(unsigned int l) { nbLignes = l; }
    inline void setColonnesTSH(unsigned int c) { nbColonnes = c; }

  protected:
    QString longName;

    //! Formation parente, vide si pas de parent
    QString parent;

    //! Minimums de crédits requis par catégories
    std::map<CategorieUV, int> requirements;

    //! UVs dont la validation est nécessaire
    std::vector<Uv> compulsory;

    //! UVs dont la validation est recommandée
    std::vector<Uv> recommended;

    //! Nombre de lignes présentes dans le tableau TSH
    unsigned int nbLignes;

    //! Nombre de colonnes présentes dans le tableau TSH
    unsigned int nbColonnes;

    //! Nombre minimum de crédits à valider toutes catégories confondues
    unsigned int minCredits;

    //! Nombre minimum d’UV à valider dans les UVs recommandées
    unsigned int minNbUvRecommended;

};

#endif // FORMATION_HPP
<commit_msg>Modification de la class Formation<commit_after>#ifndef FORMATION_HPP
#define FORMATION_HPP 1

#include <QString>
#include <map>

#include "structures.hpp"
#include "singleton.hpp"
#include "manager.hpp"
#include "uvmanager.hpp"

#include <iostream>

class Formation;
typedef Singleton<Manager<Formation>> FormationManager;

#define CUM CategorieUVManager::getInstance()
#define UVM UvManager::getInstance()
#define FM FormationManager::getInstance()

//! Classe des Formations
class Formation : public BaseItem {

  public:

    Formation(const QString& abbr, const QString& n)
        : BaseItem(abbr), longName(n), parent(""), nbLignes(0), nbColonnes(0),
          minCredits(0) {}

    inline const QString& getLongName() const { return longName; }
    inline bool hasParent() const { return parent != ""; }
    inline void addUv(const QString& u) { uvs.push_back(UVM->getItem(u)); }
    inline void addUv(Uv u) { uvs.push_back(u); }

    //! Retourne le parent de la formation, lève une exception s’il n’existe pas
    inline const Formation& getParent() const { return FM->getItem(parent); }

    inline const std::map<CategorieUV, int>& getRequirements() const { return requirements; }
    inline unsigned int getLignesTSH() const { return nbLignes; }
    inline unsigned int getColonnesTSH() const { return nbColonnes; }
    inline const std::vector<Uv>& getUvs() const { return uvs; }

    inline bool hasChildren() const {
        std::vector<Formation> formations = FM->iterator();
        for(auto it=formations.begin(); it!=formations.end(); it++) {
            if (it->hasParent() && (it->getParent() == *this)) {
                return true;
            }
        }
        return false;
    }

    inline void setLongName(const QString &l) { longName = l; }
    inline void setRequirements(const QString &c, unsigned int n) {
        //Vérifie si la catégorie existe
        CategorieUV cat("", "");
        try {
            cat = CUM->getItem(c);
        } catch (Exception) {
            return;
        }

        requirements[cat] = n;
    }

    inline void setParent(const QString& p) {
        //On vérifie que le parent existe
        try {
            FM->getItem(p);
        } catch (Exception) {
            return;
        }

        parent = p;
    }
    inline void setLignesTSH(unsigned int l) { nbLignes = l; }
    inline void setColonnesTSH(unsigned int c) { nbColonnes = c; }

  protected:
    QString longName;

    //! Formation parente, vide si pas de parent
    QString parent;

    //! Minimums de crédits requis par catégories
    std::map<CategorieUV, int> requirements;

    //! UVs de la formation
    std::vector<Uv> uvs;

    //! Nombre de lignes présentes dans le tableau TSH
    unsigned int nbLignes;

    //! Nombre de colonnes présentes dans le tableau TSH
    unsigned int nbColonnes;

    //! Nombre minimum de crédits à valider toutes catégories confondues
    unsigned int minCredits;

};

#endif // FORMATION_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 *          Gabe Black
 *          Kevin Lim
 */

#include "arch/alpha/floatregfile.hh"
#include "sim/serialize.hh"

namespace AlphaISA {
void
FloatRegFile::clear()
{
    std::memset(d, 0, sizeof(d));
}

void
FloatRegFile::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY(q, NumFloatRegs);
}

void
FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY(q, NumFloatRegs);
}

} // namespace AlphaISA
<commit_msg>alpha: Need to include cstring so that g++ 4.3 works.<commit_after>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Steve Reinhardt
 *          Gabe Black
 *          Kevin Lim
 */

#include <cstring>

#include "arch/alpha/floatregfile.hh"
#include "sim/serialize.hh"

namespace AlphaISA {
void
FloatRegFile::clear()
{
    std::memset(d, 0, sizeof(d));
}

void
FloatRegFile::serialize(std::ostream &os)
{
    SERIALIZE_ARRAY(q, NumFloatRegs);
}

void
FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
{
    UNSERIALIZE_ARRAY(q, NumFloatRegs);
}

} // namespace AlphaISA
<|endoftext|>