<commit_before>#include <cstdlib>
#include <string>
#include <node.h>
#include <node_buffer.h>
#include <v8.h>
#include <qrencode.h>
#include <png.h>

using namespace v8;

const unsigned int QRC_MAX_SIZE[] = { 2938, 2319, 1655, 1268 };
const int WHITE = 16777216;

struct Qrc_Params {
  const char* data;
  QRecLevel ec_level;
  int dot_size;
  int margin;
  int foreground_color;
  int background_color;
  int version;

  Qrc_Params(std::string p_data, QRecLevel p_ec_level = QR_ECLEVEL_L,
          int p_version = 0,
          int p_dot_size = 3, int p_margin = 4,
          int p_foreground_color = 0x0, int p_background_color = 0xffffff) {
    data = new char[p_data.length() + 1];
    strcpy((char*)data, p_data.c_str());
    ec_level = p_ec_level;
    version = p_version;
    dot_size = p_dot_size;
    margin = p_margin;
    foreground_color = p_foreground_color;
    background_color = p_background_color;
  }

  ~Qrc_Params() {
    delete data;
  }
};

struct Qrc_Png_Buffer {
  char *data;
  size_t size;
  Qrc_Png_Buffer() {
    data = NULL;
    size = 0;
  }
  ~Qrc_Png_Buffer() {
    if (data) {
      free(data);
    }
  }
};

Qrc_Params* ValidateArgs(const Arguments& args) {
  struct Qrc_Params* params;

  if (args.Length() < 1 || !args[0]->IsString()) {
    ThrowException(Exception::TypeError(String::New("No source string given")));
    return NULL;
  }
  std::string data(*v8::String::Utf8Value(args[0]));
  if (data.length() < 1 || data.length() > QRC_MAX_SIZE[0]) {
    ThrowException(Exception::RangeError(String::New("Source string length out of range")));
    return NULL;
  }
  params = new Qrc_Params(data);

  if (args.Length() > 1) {
    if (!args[1]->IsObject()) {
      ThrowException(Exception::TypeError(String::New("Second argument must be an object")));
      delete params;
      return NULL;
    }
    Local<Object> paramsObj = Local<Object>::Cast(args[1]);
    Local<Value> paramsEcLevel = paramsObj->Get(String::New("ecLevel"));
    if (!paramsEcLevel->IsUndefined()) {
      if (!paramsEcLevel->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for ec level")));
        delete params;
        return NULL;
      } else if (paramsEcLevel->IntegerValue() < QR_ECLEVEL_L || paramsEcLevel->IntegerValue() > QR_ECLEVEL_H) {
        ThrowException(Exception::RangeError(String::New("EC level value out of range")));
        delete params;
        return NULL;
      } else {
        params->ec_level = (QRecLevel) paramsEcLevel->IntegerValue();
        if (data.length() > QRC_MAX_SIZE[params->ec_level]) {
          ThrowException(Exception::RangeError(String::New("Source string length out of range")));
          delete params;
          return NULL;
        }
      }
    }
    Local<Value> paramsDotSize = paramsObj->Get(String::New("dotSize"));
    if (!paramsDotSize->IsUndefined()) {
      if (!paramsDotSize->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for dot size")));
        delete params;
        return NULL;
      } else if (paramsDotSize->IntegerValue() < 1 || paramsDotSize->IntegerValue() > 50) {
        ThrowException(Exception::RangeError(String::New("Dot size out of range")));
        delete params;
        return NULL;
      } else {
        params->dot_size = paramsDotSize->IntegerValue();
      }
    }
    Local<Value> paramsMargin = paramsObj->Get(String::New("margin"));
    if (!paramsMargin->IsUndefined()) {
      if (!paramsMargin->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for margin")));
        delete params;
        return NULL;
      } else if (paramsMargin->IntegerValue() < 0 || paramsMargin->IntegerValue() > 10) {
        ThrowException(Exception::RangeError(String::New("Margin size out of range")));
        delete params;
        return NULL;
      } else {
        params->margin = paramsMargin->IntegerValue();
      }
    }
    Local<Value> paramsFgColor = paramsObj->Get(String::New("foregroundColor"));
    if (!paramsFgColor->IsUndefined()) {
      if (!paramsFgColor->IsUint32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for foreground color")));
        delete params;
        return NULL;
      } else if (paramsFgColor->IntegerValue() < 0 || paramsFgColor->IntegerValue() >= WHITE) {
        ThrowException(Exception::RangeError(String::New("Foreground color out of range")));
        delete params;
        return NULL;
      } else {
        params->foreground_color = paramsFgColor->IntegerValue();
      }
    }
    Local<Value> paramsBgColor = paramsObj->Get(String::New("backgroundColor"));
    if (!paramsBgColor->IsUndefined()) {
      if (!paramsBgColor->IsUint32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for background color")));
        delete params;
        return NULL;
      } else if (paramsBgColor->IntegerValue() < 0 || paramsBgColor->IntegerValue() >= WHITE) {
        ThrowException(Exception::RangeError(String::New("Background color out of range")));
        delete params;
        return NULL;
      } else {
        params->background_color = paramsBgColor->IntegerValue();
      }
    }
    Local<Value> paramsVersion = paramsObj->Get(String::New("version"));
    if (!paramsVersion->IsUndefined()) {
      if (!paramsVersion->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for version")));
        delete params;
        return NULL;
      } else if (paramsVersion->IntegerValue() < 1 || paramsVersion->IntegerValue() > QRSPEC_VERSION_MAX) {
        ThrowException(Exception::RangeError(String::New("Version number out of range")));
        delete params;
        return NULL;
      } else {
        params->version = paramsVersion->IntegerValue();
      }
    }
  }

  return params;
}

QRcode* Encode(Qrc_Params* params) {
  QRcode* code;
  code = QRcode_encodeString8bit((const char*)params->data, params->version, params->ec_level);
  return code;
}

Handle<Value> EncodeBuf(const Arguments& args) {
  HandleScope scope;
  Local<Object> codeObj = Object::New();

  Qrc_Params* params = ValidateArgs(args);
  if (!params) {
    return scope.Close(codeObj);
  }

  QRcode* code = Encode(params);
  delete params;
  if (code != NULL) {
    Local<node::Buffer> buffer = node::Buffer::New((const char*)code->data, code->width * code->width);
    codeObj->Set(String::NewSymbol("width"), Integer::New(code->width));
    codeObj->Set(String::NewSymbol("version"), Integer::New(code->version));
    codeObj->Set(String::NewSymbol("data"), buffer->handle_);
    QRcode_free(code);
  }
  return scope.Close(codeObj);
}

void Qrc_png_write_buffer(png_structp png_ptr, png_bytep data, png_size_t length) {
  Qrc_Png_Buffer* b = (Qrc_Png_Buffer *)png_get_io_ptr(png_ptr);
  size_t nsize = b->size + length;

  if (b->data) {
    b->data = (char *)realloc(b->data, nsize);
  } else {
    b->data = (char *)malloc(nsize);
  }

  if (!b->data) {
    png_error(png_ptr, "Write Error");
  }

  memcpy(b->data + b->size, data, length);
  b->size += length;
}

Handle<Value> EncodePNG(const Arguments& args) {
  HandleScope scope;
  Local<Object> obj = Object::New();

  Qrc_Params* params = ValidateArgs(args);
  if (!params) {
    return scope.Close(obj);
  }

  QRcode* code = Encode(params);

  if (code != NULL) {
    Qrc_Png_Buffer* bp = new Qrc_Png_Buffer();

    png_structp png_ptr;
    png_infop info_ptr;
    png_colorp png_plte;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
        NULL, NULL, NULL);
    if (!png_ptr) {
      delete params;
      return scope.Close(obj);
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
      png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
      delete params;
      return scope.Close(obj);
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
      png_destroy_write_struct(&png_ptr, &info_ptr);
      delete params;
      return scope.Close(obj);
    }

    png_set_write_fn(png_ptr, bp, Qrc_png_write_buffer, NULL);

    png_plte = (png_colorp) malloc(sizeof(png_color) * 2);
    png_plte[0].red = params->background_color >> 16 & 0xFF;
    png_plte[0].green = params->background_color >> 8 & 0xFF;
    png_plte[0].blue = params->background_color & 0xFF;
    png_plte[1].red = params->foreground_color >> 16 & 0xFF;
    png_plte[1].green = params->foreground_color >> 8 & 0xFF;
    png_plte[1].blue = params->foreground_color & 0xFF;

    png_set_PLTE(png_ptr, info_ptr, png_plte, 2);

    png_set_IHDR(png_ptr, info_ptr, (code->width + params->margin * 2) * params->dot_size, (code->width + params->margin * 2) * params->dot_size, 1,
        PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT);

    png_write_info(png_ptr, info_ptr);

    png_set_packing(png_ptr);

    unsigned char* row = new unsigned char[(code->width + params->margin * 2) * params->dot_size];

    for (int y = -(params->margin); y < code->width + params->margin; y++) {
      for (int x = -(params->margin * params->dot_size); x < (code->width + params->margin) * params->dot_size; x += params->dot_size) {
        for (int d = 0; d < params->dot_size; d++) {
          if (y < 0 || y > code->width - 1 || x < 0 || x > ((code->width - 1) * params->dot_size)) {
            row[x + params->margin * params->dot_size + d] = 0;
          } else {
            row[x + params->margin * params->dot_size + d] = code->data[y * code->width + x/params->dot_size] << 7;
          }
        }
      }
      for (int d = 0; d < params->dot_size; d++) {
        png_write_row(png_ptr, row);
      }
    }

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    delete[] row;
    free(png_plte);

    Local<node::Buffer> buffer = node::Buffer::New(bp->data, bp->size);
    obj->Set(String::NewSymbol("width"), Integer::New(code->width));
    obj->Set(String::NewSymbol("version"), Integer::New(code->version));
    obj->Set(String::NewSymbol("data"), buffer->handle_);
    QRcode_free(code);
    delete bp;
  }
  delete params;
  return scope.Close(obj);
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("encode"),
      FunctionTemplate::New(EncodeBuf)->GetFunction());
  exports->Set(String::NewSymbol("encodePng"),
      FunctionTemplate::New(EncodePNG)->GetFunction());
}

NODE_MODULE(qrc, init)
<commit_msg>Fix exception wordings<commit_after>#include <cstdlib>
#include <string>
#include <node.h>
#include <node_buffer.h>
#include <v8.h>
#include <qrencode.h>
#include <png.h>

using namespace v8;

const unsigned int QRC_MAX_SIZE[] = { 2938, 2319, 1655, 1268 };
const int WHITE = 16777216;

struct Qrc_Params {
  const char* data;
  QRecLevel ec_level;
  int dot_size;
  int margin;
  int foreground_color;
  int background_color;
  int version;

  Qrc_Params(std::string p_data, QRecLevel p_ec_level = QR_ECLEVEL_L,
          int p_version = 0,
          int p_dot_size = 3, int p_margin = 4,
          int p_foreground_color = 0x0, int p_background_color = 0xffffff) {
    data = new char[p_data.length() + 1];
    strcpy((char*)data, p_data.c_str());
    ec_level = p_ec_level;
    version = p_version;
    dot_size = p_dot_size;
    margin = p_margin;
    foreground_color = p_foreground_color;
    background_color = p_background_color;
  }

  ~Qrc_Params() {
    delete data;
  }
};

struct Qrc_Png_Buffer {
  char *data;
  size_t size;
  Qrc_Png_Buffer() {
    data = NULL;
    size = 0;
  }
  ~Qrc_Png_Buffer() {
    if (data) {
      free(data);
    }
  }
};

Qrc_Params* ValidateArgs(const Arguments& args) {
  struct Qrc_Params* params;

  if (args.Length() < 1 || !args[0]->IsString()) {
    ThrowException(Exception::TypeError(String::New("No source string given")));
    return NULL;
  }
  std::string data(*v8::String::Utf8Value(args[0]));
  if (data.length() < 1 || data.length() > QRC_MAX_SIZE[0]) {
    ThrowException(Exception::RangeError(String::New("Source string length out of range")));
    return NULL;
  }
  params = new Qrc_Params(data);

  if (args.Length() > 1) {
    if (!args[1]->IsObject()) {
      ThrowException(Exception::TypeError(String::New("Second argument must be an object")));
      delete params;
      return NULL;
    }
    Local<Object> paramsObj = Local<Object>::Cast(args[1]);
    Local<Value> paramsEcLevel = paramsObj->Get(String::New("ecLevel"));
    if (!paramsEcLevel->IsUndefined()) {
      if (!paramsEcLevel->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for EC level")));
        delete params;
        return NULL;
      } else if (paramsEcLevel->IntegerValue() < QR_ECLEVEL_L || paramsEcLevel->IntegerValue() > QR_ECLEVEL_H) {
        ThrowException(Exception::RangeError(String::New("EC level out of range")));
        delete params;
        return NULL;
      } else {
        params->ec_level = (QRecLevel) paramsEcLevel->IntegerValue();
        if (data.length() > QRC_MAX_SIZE[params->ec_level]) {
          ThrowException(Exception::RangeError(String::New("Source string length out of range")));
          delete params;
          return NULL;
        }
      }
    }
    Local<Value> paramsDotSize = paramsObj->Get(String::New("dotSize"));
    if (!paramsDotSize->IsUndefined()) {
      if (!paramsDotSize->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for dot size")));
        delete params;
        return NULL;
      } else if (paramsDotSize->IntegerValue() < 1 || paramsDotSize->IntegerValue() > 50) {
        ThrowException(Exception::RangeError(String::New("Dot size out of range")));
        delete params;
        return NULL;
      } else {
        params->dot_size = paramsDotSize->IntegerValue();
      }
    }
    Local<Value> paramsMargin = paramsObj->Get(String::New("margin"));
    if (!paramsMargin->IsUndefined()) {
      if (!paramsMargin->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for margin size")));
        delete params;
        return NULL;
      } else if (paramsMargin->IntegerValue() < 0 || paramsMargin->IntegerValue() > 10) {
        ThrowException(Exception::RangeError(String::New("Margin size out of range")));
        delete params;
        return NULL;
      } else {
        params->margin = paramsMargin->IntegerValue();
      }
    }
    Local<Value> paramsFgColor = paramsObj->Get(String::New("foregroundColor"));
    if (!paramsFgColor->IsUndefined()) {
      if (!paramsFgColor->IsUint32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for foreground color")));
        delete params;
        return NULL;
      } else if (paramsFgColor->IntegerValue() < 0 || paramsFgColor->IntegerValue() >= WHITE) {
        ThrowException(Exception::RangeError(String::New("Foreground color out of range")));
        delete params;
        return NULL;
      } else {
        params->foreground_color = paramsFgColor->IntegerValue();
      }
    }
    Local<Value> paramsBgColor = paramsObj->Get(String::New("backgroundColor"));
    if (!paramsBgColor->IsUndefined()) {
      if (!paramsBgColor->IsUint32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for background color")));
        delete params;
        return NULL;
      } else if (paramsBgColor->IntegerValue() < 0 || paramsBgColor->IntegerValue() >= WHITE) {
        ThrowException(Exception::RangeError(String::New("Background color out of range")));
        delete params;
        return NULL;
      } else {
        params->background_color = paramsBgColor->IntegerValue();
      }
    }
    Local<Value> paramsVersion = paramsObj->Get(String::New("version"));
    if (!paramsVersion->IsUndefined()) {
      if (!paramsVersion->IsInt32()) {
        ThrowException(Exception::TypeError(String::New("Wrong type for version")));
        delete params;
        return NULL;
      } else if (paramsVersion->IntegerValue() < 1 || paramsVersion->IntegerValue() > QRSPEC_VERSION_MAX) {
        ThrowException(Exception::RangeError(String::New("Version out of range")));
        delete params;
        return NULL;
      } else {
        params->version = paramsVersion->IntegerValue();
      }
    }
  }

  return params;
}

QRcode* Encode(Qrc_Params* params) {
  QRcode* code;
  code = QRcode_encodeString8bit((const char*)params->data, params->version, params->ec_level);
  return code;
}

Handle<Value> EncodeBuf(const Arguments& args) {
  HandleScope scope;
  Local<Object> codeObj = Object::New();

  Qrc_Params* params = ValidateArgs(args);
  if (!params) {
    return scope.Close(codeObj);
  }

  QRcode* code = Encode(params);
  delete params;
  if (code != NULL) {
    Local<node::Buffer> buffer = node::Buffer::New((const char*)code->data, code->width * code->width);
    codeObj->Set(String::NewSymbol("width"), Integer::New(code->width));
    codeObj->Set(String::NewSymbol("version"), Integer::New(code->version));
    codeObj->Set(String::NewSymbol("data"), buffer->handle_);
    QRcode_free(code);
  }
  return scope.Close(codeObj);
}

void Qrc_png_write_buffer(png_structp png_ptr, png_bytep data, png_size_t length) {
  Qrc_Png_Buffer* b = (Qrc_Png_Buffer *)png_get_io_ptr(png_ptr);
  size_t nsize = b->size + length;

  if (b->data) {
    b->data = (char *)realloc(b->data, nsize);
  } else {
    b->data = (char *)malloc(nsize);
  }

  if (!b->data) {
    png_error(png_ptr, "Write Error");
  }

  memcpy(b->data + b->size, data, length);
  b->size += length;
}

Handle<Value> EncodePNG(const Arguments& args) {
  HandleScope scope;
  Local<Object> obj = Object::New();

  Qrc_Params* params = ValidateArgs(args);
  if (!params) {
    return scope.Close(obj);
  }

  QRcode* code = Encode(params);

  if (code != NULL) {
    Qrc_Png_Buffer* bp = new Qrc_Png_Buffer();

    png_structp png_ptr;
    png_infop info_ptr;
    png_colorp png_plte;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
        NULL, NULL, NULL);
    if (!png_ptr) {
      delete params;
      return scope.Close(obj);
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
      png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
      delete params;
      return scope.Close(obj);
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
      png_destroy_write_struct(&png_ptr, &info_ptr);
      delete params;
      return scope.Close(obj);
    }

    png_set_write_fn(png_ptr, bp, Qrc_png_write_buffer, NULL);

    png_plte = (png_colorp) malloc(sizeof(png_color) * 2);
    png_plte[0].red = params->background_color >> 16 & 0xFF;
    png_plte[0].green = params->background_color >> 8 & 0xFF;
    png_plte[0].blue = params->background_color & 0xFF;
    png_plte[1].red = params->foreground_color >> 16 & 0xFF;
    png_plte[1].green = params->foreground_color >> 8 & 0xFF;
    png_plte[1].blue = params->foreground_color & 0xFF;

    png_set_PLTE(png_ptr, info_ptr, png_plte, 2);

    png_set_IHDR(png_ptr, info_ptr, (code->width + params->margin * 2) * params->dot_size, (code->width + params->margin * 2) * params->dot_size, 1,
        PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT);

    png_write_info(png_ptr, info_ptr);

    png_set_packing(png_ptr);

    unsigned char* row = new unsigned char[(code->width + params->margin * 2) * params->dot_size];

    for (int y = -(params->margin); y < code->width + params->margin; y++) {
      for (int x = -(params->margin * params->dot_size); x < (code->width + params->margin) * params->dot_size; x += params->dot_size) {
        for (int d = 0; d < params->dot_size; d++) {
          if (y < 0 || y > code->width - 1 || x < 0 || x > ((code->width - 1) * params->dot_size)) {
            row[x + params->margin * params->dot_size + d] = 0;
          } else {
            row[x + params->margin * params->dot_size + d] = code->data[y * code->width + x/params->dot_size] << 7;
          }
        }
      }
      for (int d = 0; d < params->dot_size; d++) {
        png_write_row(png_ptr, row);
      }
    }

    png_write_end(png_ptr, info_ptr);
    png_destroy_write_struct(&png_ptr, &info_ptr);

    delete[] row;
    free(png_plte);

    Local<node::Buffer> buffer = node::Buffer::New(bp->data, bp->size);
    obj->Set(String::NewSymbol("width"), Integer::New(code->width));
    obj->Set(String::NewSymbol("version"), Integer::New(code->version));
    obj->Set(String::NewSymbol("data"), buffer->handle_);
    QRcode_free(code);
    delete bp;
  }
  delete params;
  return scope.Close(obj);
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("encode"),
      FunctionTemplate::New(EncodeBuf)->GetFunction());
  exports->Set(String::NewSymbol("encodePng"),
      FunctionTemplate::New(EncodePNG)->GetFunction());
}

NODE_MODULE(qrc, init)
<|endoftext|>


<commit_before>#include <arduino.h>
#include "servomover.h"

unsigned long PERIOD = 20;  // Fixed, a servo can be steered every 20ms.

LinearServoMover::LinearServoMover(int pin,
                                   int min_position,
                                   int max_position,
                                   int duration){
  pin = pin;
  min_position = min_position;
  max_position = max_position;
  duration = duration;

  current_position = min_position;
  next_update = 0;
  to_min = true;
  done = true;

  servo.attach(pin);
  move_servo();
  movement_per_period = (max_position - min_position) / duration * PERIOD;
}

void LinearServoMover::move_servo(){
  if (current_position < min_position) {
    current_position = min_position;
    done = true;
  }
  if (current_position > max_position) {
    current_position = max_position;
    done = true;
  }
  servo.writeMicroseconds(current_position);
}

void LinearServoMover::move_to_min(){
  to_min = true;
  done = false;
}

void LinearServoMover::move_to_max(){
  to_min = false;
  done = false;
}

void LinearServoMover::perhaps_update(){
  unsigned long now = millis();
  if (!done && next_update < now) {
    next_update = now + PERIOD;
    if (to_min) {
      current_position -= movement_per_period;
    }
    else {
      current_position += movement_per_period;
    }
    move_servo();
  }
}
<commit_msg>Added detach/attach after and before movement<commit_after>#include <arduino.h>
#include "servomover.h"

unsigned long PERIOD = 20;  // Fixed, a servo can be steered every 20ms.

LinearServoMover::LinearServoMover(int pin,
                                   int min_position,
                                   int max_position,
                                   int duration){
  pin = pin;
  min_position = min_position;
  max_position = max_position;
  duration = duration;

  current_position = min_position;
  next_update = 0;
  to_min = true;
  done = true;

  servo.attach(pin);
  move_servo();
  movement_per_period = (max_position - min_position) / duration * PERIOD;
}

void LinearServoMover::move_servo(){
  if (current_position < min_position) {
    current_position = min_position;
    done = true;
  }
  if (current_position > max_position) {
    current_position = max_position;
    done = true;
  }
  servo.writeMicroseconds(current_position);
  if (done) {
    servo.detach();
  }
}

void LinearServoMover::move_to_min(){
  to_min = true;
  done = false;
  servo.attach(pin);
}

void LinearServoMover::move_to_max(){
  to_min = false;
  done = false;
  servo.attach(pin);
}

void LinearServoMover::perhaps_update(){
  unsigned long now = millis();
  if (!done && next_update < now) {
    next_update = now + PERIOD;
    if (to_min) {
      current_position -= movement_per_period;
    }
    else {
      current_position += movement_per_period;
    }
    move_servo();
  }
}
<|endoftext|>


<commit_before>#include <cmath>
#include <iostream>
#include "gtest/gtest.h"
#include "numgrind.h"
#include "utils.h"

#include "testhelpers.h"

using namespace NumGrind;

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad01) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(1);
    auto b = manager.variable(2);
    auto c = a + b;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 1.0);
    ASSERT_FLOAT_EQ(vars[1], 2.0);

    c.node()->forwardPass(vars);
    c.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 1.0);
    ASSERT_FLOAT_EQ(grad[1], 1.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad02) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(7);
    auto b = manager.variable(12);
    auto c = a - b;
    auto d = a*c;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 7.0);
    ASSERT_FLOAT_EQ(vars[1], 12.0);

    d.node()->forwardPass(vars);
    d.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], -7.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad03) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(3);
    auto b = manager.variable(2);
    auto c = manager.variable(12);
    auto d = a + b;
    auto e = a * b;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 3.0);
    ASSERT_FLOAT_EQ(vars[1], 2.0);
    ASSERT_FLOAT_EQ(vars[2], 12.0);

    e.node()->forwardPass(vars);
    e.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], 3.0);
    ASSERT_FLOAT_EQ(grad[2], 0.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad04) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = 2.0f*manager.variable(3);
    auto b = a + manager.variable(10);

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 3.0);
    ASSERT_FLOAT_EQ(vars[1], 10.0);

    b.node()->forwardPass(vars);
    b.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], 1.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad05) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto f = 2*manager.variable(13) * manager.variable(16) - 10 + manager.variable(2)/3.0;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[2], 13.0);
    ASSERT_FLOAT_EQ(vars[1], 16.0);
    ASSERT_FLOAT_EQ(vars[0], 2.0);

    f.node()->forwardPass(vars);
    f.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[2], 2*16.0);
    ASSERT_FLOAT_EQ(grad[1], 2*13.0);
    ASSERT_FLOAT_EQ(grad[0], 1.0/3.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGradMat01) {

    using namespace SymbolicGraph;
    GraphManager manager;
    Eigen::VectorXf val1(3);
    val1 << 4, 6, 1;
    Eigen::MatrixXf val2(2, 3);
    val2 << 2, 4, 6,
            8, 10, 12;
    auto a = manager.variable(val1);
    auto b = manager.variable(val2);
    auto c = manager.variable(1, 4, 13);

    auto vars = manager.initializeVariables();

    ASSERT_EQ(vars.size(), 3 + 6 + 4);

    ASSERT_FLOAT_EQ(vars[0], 4.0);
    ASSERT_FLOAT_EQ(vars[1], 6.0);
    ASSERT_FLOAT_EQ(vars[2], 1.0);

    ASSERT_FLOAT_EQ(vars[3], 2.0);
    ASSERT_FLOAT_EQ(vars[4], 4.0);
    ASSERT_FLOAT_EQ(vars[5], 6.0);
    ASSERT_FLOAT_EQ(vars[6], 8.0);
    ASSERT_FLOAT_EQ(vars[7], 10.0);
    ASSERT_FLOAT_EQ(vars[8], 12.0);

    ASSERT_FLOAT_EQ(vars[9],  13.0);
    ASSERT_FLOAT_EQ(vars[10], 13.0);
    ASSERT_FLOAT_EQ(vars[11], 13.0);
}

TEST(NumGrindGraphManagerSuit, testMatSum01) {

    using namespace SymbolicGraph;
    GraphManager gm;

    Eigen::MatrixXf aMat(3, 2);
    aMat << 1, 2,
            3, 4,
            5, 6;
    Eigen::MatrixXf bMat(1, 2);
    bMat << 10, 20;
    auto a = gm.variable(aMat);
    auto b = gm.variable(bMat);
    auto c = a + b;
    auto d = apply<testhelpers::square, testhelpers::squareDer>(c);
    auto e = reduceSum(d);
    auto vars = gm.initializeVariables();
    auto grad = gm.initializeGradient(vars);
    c.node()->forwardPass(vars);
    auto res1 = c.value();

    ASSERT_FLOAT_EQ(res1(0, 0), 11);
    ASSERT_FLOAT_EQ(res1(0, 1), 22);
    ASSERT_FLOAT_EQ(res1(1, 0), 13);
    ASSERT_FLOAT_EQ(res1(1, 1), 24);
    ASSERT_FLOAT_EQ(res1(2, 0), 15);
    ASSERT_FLOAT_EQ(res1(2, 1), 26);

    e.node()->forwardPass(vars);
    e.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2*11);
    ASSERT_FLOAT_EQ(grad[1], 2*22);
    ASSERT_FLOAT_EQ(grad[2], 2*13);
    ASSERT_FLOAT_EQ(grad[3], 2*24);
    ASSERT_FLOAT_EQ(grad[4], 2*15);
    ASSERT_FLOAT_EQ(grad[5], 2*26);

    ASSERT_FLOAT_EQ(grad[6], 2*11 + 2*13 + 2*15);
    ASSERT_FLOAT_EQ(grad[7], 2*22 + 2*24 + 2*26);

}

TEST(NumGrindGraphManagerSuit, testSeriesOfCalls01) {
    using namespace SymbolicGraph;
    GraphManager gm;

    Eigen::MatrixXf targets(3, 1);
    targets << 1, 2, 3;

    Eigen::MatrixXf varsInit(3, 1);
    varsInit << 0, 0, 0;
    //varsInit << 1, 1, 1;

    auto a = gm.variable(varsInit);
    auto b = gm.constant(targets);
    auto residuals = a - b;
    auto err  = dot(residuals, residuals);//reduceSum(residuals*residuals);
    auto vars = gm.initializeVariables();
    auto grad = gm.initializeGradient(vars);

    auto func  = gm.funcFromNode(&err);
    auto gradF = gm.gradFromNode(&err);

    ASSERT_FLOAT_EQ(func(vars), 1 + 4 + 9);
    gradF(vars, grad);

    ASSERT_FLOAT_EQ(grad[0], -2*1);
    ASSERT_FLOAT_EQ(grad[1], -2*2);
    ASSERT_FLOAT_EQ(grad[2], -2*3);

    vars[0] = 1;
    vars[1] = 1;
    vars[2] = 1;

    gradF(vars, grad);
    ASSERT_FLOAT_EQ(func(vars), 0 + 1 + 4);

    ASSERT_FLOAT_EQ(grad[0],  2*0);
    ASSERT_FLOAT_EQ(grad[1], -2*1);
    ASSERT_FLOAT_EQ(grad[2], -2*2);

    vars[0] = 2;
    vars[1] = 2;
    vars[2] = 1;

    ASSERT_FLOAT_EQ(func(vars), 1 + 0 + 4);
    gradF(vars, grad);

    ASSERT_FLOAT_EQ(grad[0],  2*1);
    ASSERT_FLOAT_EQ(grad[1], -2*0);
    ASSERT_FLOAT_EQ(grad[2], -2*2);

    vars[0] = 1;
    vars[1] = 2;
    vars[2] = 3;

    gradF(vars, grad);
    ASSERT_FLOAT_EQ(func(vars), 0 + 0 + 0);

    ASSERT_FLOAT_EQ(grad[0],  2*0);
    ASSERT_FLOAT_EQ(grad[1], -2*0);
    ASSERT_FLOAT_EQ(grad[2], -2*0);

}
<commit_msg>small changes in tests<commit_after>#include <cmath>
#include <iostream>
#include "gtest/gtest.h"
#include "numgrind.h"
#include "utils.h"

#include "testhelpers.h"

using namespace NumGrind;

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad01) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(1);
    auto b = manager.variable(2);
    auto c = a + b;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 1.0);
    ASSERT_FLOAT_EQ(vars[1], 2.0);

    c.node()->forwardPass(vars);
    c.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 1.0);
    ASSERT_FLOAT_EQ(grad[1], 1.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad02) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(7);
    auto b = manager.variable(12);
    auto c = a - b;
    auto d = a*c;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 7.0);
    ASSERT_FLOAT_EQ(vars[1], 12.0);

    d.node()->forwardPass(vars);
    d.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], -7.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad03) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = manager.variable(3);
    auto b = manager.variable(2);
    auto c = manager.variable(12);
    auto d = a + b;
    auto e = a * b;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 3.0);
    ASSERT_FLOAT_EQ(vars[1], 2.0);
    ASSERT_FLOAT_EQ(vars[2], 12.0);

    e.node()->forwardPass(vars);
    e.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], 3.0);
    ASSERT_FLOAT_EQ(grad[2], 0.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad04) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto a = 2.0f*manager.variable(3);
    auto b = a + manager.variable(10);

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[0], 3.0);
    ASSERT_FLOAT_EQ(vars[1], 10.0);

    b.node()->forwardPass(vars);
    b.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2.0);
    ASSERT_FLOAT_EQ(grad[1], 1.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGrad05) {

    using namespace SymbolicGraph;
    GraphManager manager;
    auto f = 2*manager.variable(13) * manager.variable(16) - 10 + manager.variable(2)/3.0;

    auto vars = manager.initializeVariables();
    auto grad = manager.initializeGradient(vars);

    ASSERT_FLOAT_EQ(vars[2], 13.0);
    ASSERT_FLOAT_EQ(vars[1], 16.0);
    ASSERT_FLOAT_EQ(vars[0], 2.0);

    f.node()->forwardPass(vars);
    f.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[2], 2*16.0);
    ASSERT_FLOAT_EQ(grad[1], 2*13.0);
    ASSERT_FLOAT_EQ(grad[0], 1.0/3.0);
}

TEST(NumGrindGraphManagerSuit, testInitializeVarsAndGradMat01) {

    using namespace SymbolicGraph;
    GraphManager manager;
    Eigen::VectorXf val1(3);
    val1 << 4, 6, 1;
    Eigen::MatrixXf val2(2, 3);
    val2 << 2, 4, 6,
            8, 10, 12;
    auto a = manager.variable(val1);
    auto b = manager.variable(val2);
    auto c = manager.variable(1, 4, 13);

    auto vars = manager.initializeVariables();

    ASSERT_EQ(vars.size(), 3 + 6 + 4);

    ASSERT_FLOAT_EQ(vars[0], 4.0);
    ASSERT_FLOAT_EQ(vars[1], 6.0);
    ASSERT_FLOAT_EQ(vars[2], 1.0);

    ASSERT_FLOAT_EQ(vars[3], 2.0);
    ASSERT_FLOAT_EQ(vars[4], 4.0);
    ASSERT_FLOAT_EQ(vars[5], 6.0);
    ASSERT_FLOAT_EQ(vars[6], 8.0);
    ASSERT_FLOAT_EQ(vars[7], 10.0);
    ASSERT_FLOAT_EQ(vars[8], 12.0);

    ASSERT_FLOAT_EQ(vars[9],  13.0);
    ASSERT_FLOAT_EQ(vars[10], 13.0);
    ASSERT_FLOAT_EQ(vars[11], 13.0);
}

TEST(NumGrindGraphManagerSuit, testMatSum01) {

    using namespace SymbolicGraph;
    GraphManager gm;

    Eigen::MatrixXf aMat(3, 2);
    aMat << 1, 2,
            3, 4,
            5, 6;
    Eigen::MatrixXf bMat(1, 2);
    bMat << 10, 20;
    auto a = gm.variable(aMat);
    auto b = gm.variable(bMat);
    auto c = a + b;
    auto d = apply<testhelpers::square, testhelpers::squareDer>(c);
    auto e = reduceSum(d);
    auto vars = gm.initializeVariables();
    auto grad = gm.initializeGradient(vars);
    c.node()->forwardPass(vars);
    auto res1 = c.value();

    ASSERT_FLOAT_EQ(res1(0, 0), 11);
    ASSERT_FLOAT_EQ(res1(0, 1), 22);
    ASSERT_FLOAT_EQ(res1(1, 0), 13);
    ASSERT_FLOAT_EQ(res1(1, 1), 24);
    ASSERT_FLOAT_EQ(res1(2, 0), 15);
    ASSERT_FLOAT_EQ(res1(2, 1), 26);

    e.node()->forwardPass(vars);
    e.node()->backwardPass(1.0, grad);

    ASSERT_FLOAT_EQ(grad[0], 2*11);
    ASSERT_FLOAT_EQ(grad[1], 2*22);
    ASSERT_FLOAT_EQ(grad[2], 2*13);
    ASSERT_FLOAT_EQ(grad[3], 2*24);
    ASSERT_FLOAT_EQ(grad[4], 2*15);
    ASSERT_FLOAT_EQ(grad[5], 2*26);

    ASSERT_FLOAT_EQ(grad[6], 2*11 + 2*13 + 2*15);
    ASSERT_FLOAT_EQ(grad[7], 2*22 + 2*24 + 2*26);

}

TEST(NumGrindGraphManagerSuit, testSeriesOfCalls01) {
    using namespace SymbolicGraph;
    GraphManager gm;

    Eigen::MatrixXf targets(3, 1);
    targets << 1, 2, 3;

    Eigen::MatrixXf varsInit(3, 1);
    varsInit << 0, 0, 0;
    //varsInit << 1, 1, 1;

    auto a = gm.variable(varsInit);
    auto b = gm.constant(targets);
    auto err  = sumOfSquares(a - b);
    auto vars = gm.initializeVariables();
    auto grad = gm.initializeGradient(vars);

    auto func  = gm.funcFromNode(&err);
    auto gradF = gm.gradFromNode(&err);

    ASSERT_FLOAT_EQ(func(vars), 1 + 4 + 9);
    gradF(vars, grad);

    ASSERT_FLOAT_EQ(grad[0], -2*1);
    ASSERT_FLOAT_EQ(grad[1], -2*2);
    ASSERT_FLOAT_EQ(grad[2], -2*3);

    vars[0] = 1;
    vars[1] = 1;
    vars[2] = 1;

    gradF(vars, grad);
    ASSERT_FLOAT_EQ(func(vars), 0 + 1 + 4);

    ASSERT_FLOAT_EQ(grad[0],  2*0);
    ASSERT_FLOAT_EQ(grad[1], -2*1);
    ASSERT_FLOAT_EQ(grad[2], -2*2);

    vars[0] = 2;
    vars[1] = 2;
    vars[2] = 1;

    ASSERT_FLOAT_EQ(func(vars), 1 + 0 + 4);
    gradF(vars, grad);

    ASSERT_FLOAT_EQ(grad[0],  2*1);
    ASSERT_FLOAT_EQ(grad[1], -2*0);
    ASSERT_FLOAT_EQ(grad[2], -2*2);

    vars[0] = 1;
    vars[1] = 2;
    vars[2] = 3;

    gradF(vars, grad);
    ASSERT_FLOAT_EQ(func(vars), 0 + 0 + 0);

    ASSERT_FLOAT_EQ(grad[0],  2*0);
    ASSERT_FLOAT_EQ(grad[1], -2*0);
    ASSERT_FLOAT_EQ(grad[2], -2*0);

}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <string>
#include "../src/options.hpp"

namespace {

class CmdLineOptionsTest : public ::testing::Test {
protected:
CmdLineOptions opts;
};

TEST_F(CmdLineOptionsTest, DefaultConstructor) {
EXPECT_EQ(false, opts.getHelp());
EXPECT_EQ(false, opts.getTemplate());
EXPECT_EQ(false, opts.getDebug());
EXPECT_EQ(false, opts.getQuiet());
EXPECT_EQ("", opts.getInputPath());
}

TEST_F(CmdLineOptionsTest, ExplicitConstructor) {
CmdLineOptions helpSet(true,false,false,false,"");
EXPECT_EQ(true, helpSet.getHelp());
EXPECT_EQ(false, helpSet.getTemplate());
EXPECT_EQ(false, helpSet.getDebug());
EXPECT_EQ(false, helpSet.getQuiet());
EXPECT_EQ("", helpSet.getInputPath());

CmdLineOptions tempSet(false,true,false,false,"");
EXPECT_EQ(false, tempSet.getHelp());
EXPECT_EQ(true, tempSet.getTemplate());
EXPECT_EQ(false, tempSet.getDebug());
EXPECT_EQ(false, tempSet.getQuiet());
EXPECT_EQ("", tempSet.getInputPath());

CmdLineOptions debugSet(false,false,true,false,"");
EXPECT_EQ(false, debugSet.getHelp());
EXPECT_EQ(false, debugSet.getTemplate());
EXPECT_EQ(true, debugSet.getDebug());
EXPECT_EQ(false, debugSet.getQuiet());
EXPECT_EQ("", debugSet.getInputPath());

CmdLineOptions quietSet(false,false,false,true,"");
EXPECT_EQ(false, quietSet.getHelp());
EXPECT_EQ(false, quietSet.getTemplate());
EXPECT_EQ(false, quietSet.getDebug());
EXPECT_EQ(true, quietSet.getQuiet());
EXPECT_EQ("", quietSet.getInputPath());

CmdLineOptions pathSet(false,false,false,false,"ExplicitConstructorPath");
EXPECT_EQ(false, pathSet.getHelp());
EXPECT_EQ(false, pathSet.getTemplate());
EXPECT_EQ(false, pathSet.getDebug());
EXPECT_EQ(false, pathSet.getQuiet());
EXPECT_EQ("ExplicitConstructorPath", pathSet.getInputPath());
}
} // end namespace

int main(int argc, char * argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
<commit_msg>Use EXPECT_TRUE/FALSE( instead of EXPECT_EQ(true/false,<commit_after>#include <gtest/gtest.h>
#include <string>
#include "../src/options.hpp"

namespace {

class CmdLineOptionsTest : public ::testing::Test {
protected:
CmdLineOptions opts;
};

TEST_F(CmdLineOptionsTest, DefaultConstructor) {
EXPECT_FALSE(opts.getHelp());
EXPECT_FALSE(opts.getTemplate());
EXPECT_FALSE(opts.getDebug());
EXPECT_FALSE(opts.getQuiet());
EXPECT_EQ("", opts.getInputPath());
}

TEST_F(CmdLineOptionsTest, ExplicitConstructor) {
CmdLineOptions helpSet(true,false,false,false,"");
EXPECT_TRUE(helpSet.getHelp());
EXPECT_FALSE(helpSet.getTemplate());
EXPECT_FALSE(helpSet.getDebug());
EXPECT_FALSE(helpSet.getQuiet());
EXPECT_EQ("", helpSet.getInputPath());

CmdLineOptions tempSet(false,true,false,false,"");
EXPECT_FALSE(tempSet.getHelp());
EXPECT_TRUE(tempSet.getTemplate());
EXPECT_FALSE(tempSet.getDebug());
EXPECT_FALSE(tempSet.getQuiet());
EXPECT_EQ("", tempSet.getInputPath());

CmdLineOptions debugSet(false,false,true,false,"");
EXPECT_FALSE(debugSet.getHelp());
EXPECT_FALSE(debugSet.getTemplate());
EXPECT_TRUE(debugSet.getDebug());
EXPECT_FALSE(debugSet.getQuiet());
EXPECT_EQ("", debugSet.getInputPath());

CmdLineOptions quietSet(false,false,false,true,"");
EXPECT_FALSE(quietSet.getHelp());
EXPECT_FALSE(quietSet.getTemplate());
EXPECT_FALSE(quietSet.getDebug());
EXPECT_TRUE(quietSet.getQuiet());
EXPECT_EQ("", quietSet.getInputPath());

CmdLineOptions pathSet(false,false,false,false,"ExplicitConstructorPath");
EXPECT_FALSE(pathSet.getHelp());
EXPECT_FALSE(pathSet.getTemplate());
EXPECT_FALSE(pathSet.getDebug());
EXPECT_FALSE(pathSet.getQuiet());
EXPECT_EQ("ExplicitConstructorPath", pathSet.getInputPath());
}

} // end namespace

int main(int argc, char * argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE "test_parse_unicode"
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif
#include <toml.hpp>
#include <iostream>
#include <fstream>

BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
{
    const auto data = toml::parse("toml/tests/hard_example_unicode.toml");

    const auto the = toml::get<toml::Table>(data.at("the"));
    BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
                      std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #"));

    const auto hard = toml::get<toml::Table>(the.at("hard"));
    const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
    BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
                expected_the_hard_test_array);
    const std::vector<std::string> expected_the_hard_test_array2{
            std::string(u8"Tèƨƭ #11 ]ƥřôƲèδ ƭλáƭ"),
            std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
    BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
                expected_the_hard_test_array2);
    BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
                      std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
    BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
                      std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));

    const auto bit = toml::get<toml::Table>(hard.at(std::string(u8"βïƭ#")));
    BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))),
                      std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
    const std::vector<std::string> expected_multi_line_array{"]"};
    BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
                expected_multi_line_array);

}
<commit_msg>change literal string to sequence of codepoint<commit_after>#define BOOST_TEST_MODULE "test_parse_unicode"
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif
#include <toml.hpp>
#include <iostream>
#include <fstream>

#ifdef _MSC_VER
BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
{
    const auto data = toml::parse("toml/tests/hard_example_unicode.toml");

    const auto the = toml::get<toml::Table>(data.at("the"));
    BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
                      std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x27\xE2\x84\x93\xE2\x84\x93\x20\xCE\xBB\xC3\xA1\xC6\xAD\xC3\xA8\x20\xE2\x82\xA5\xC3\xA8\x20\xC3\xA1\xC6\x92\xC6\xAD\xC3\xA8\xC5\x99\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC6\xA8\x20\x2D\x20\x23"));

//     const auto hard = toml::get<toml::Table>(the.at("hard"));
//     const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
//     BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
//                 expected_the_hard_test_array);
//     const std::vector<std::string> expected_the_hard_test_array2{
//             std::string(u8"Tèƨƭ #11 ]ƥřôƲèδ ƭλáƭ"),
//             std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
//     BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
//                 expected_the_hard_test_array2);
//     BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
//                       std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
//     BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
//                       std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));
//
//     const auto bit = toml::get<toml::Table>(hard.at(std::string(u8"βïƭ#")));
//     BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))),
//                       std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
//     const std::vector<std::string> expected_multi_line_array{"]"};
//     BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
//                 expected_multi_line_array);
}
#else
BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
{
    const auto data = toml::parse("toml/tests/hard_example_unicode.toml");

    const auto the = toml::get<toml::Table>(data.at("the"));
    BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
                      std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #"));

    const auto hard = toml::get<toml::Table>(the.at("hard"));
    const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
    BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
                expected_the_hard_test_array);
    const std::vector<std::string> expected_the_hard_test_array2{
            std::string(u8"Tèƨƭ #11 ]ƥřôƲèδ ƭλáƭ"),
            std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
    BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
                expected_the_hard_test_array2);
    BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
                      std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
    BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
                      std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));

    const auto bit = toml::get<toml::Table>(hard.at(std::string(u8"βïƭ#")));
    BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))),
                      std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
    const std::vector<std::string> expected_multi_line_array{"]"};
    BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
                expected_multi_line_array);

}
#endif
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32OpenGLTextMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 REGENTS 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.

=========================================================================*/
#include "vtkWin32OpenGLTextMapper.h"
#include <GL/gl.h>
#include "vtkObjectFactory.h"
#include "vtkgluPickMatrix.h"

//------------------------------------------------------------------------------
vtkWin32OpenGLTextMapper* vtkWin32OpenGLTextMapper::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkWin32OpenGLTextMapper");
  if(ret)
    {
    return (vtkWin32OpenGLTextMapper*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkWin32OpenGLTextMapper;
}

struct vtkFontStruct
{
  vtkWindow *Window;
  int   Italic;
  int   Bold;
  int   FontSize;
  int   FontFamily;
  int   ListBase;
};

static vtkFontStruct *cache[10] = {NULL,NULL,NULL,NULL,NULL,
                                   NULL,NULL,NULL,NULL,NULL};
static numCached = 0;

int vtkWin32OpenGLTextMapper::GetListBaseForFont(vtkTextMapper *tm,
                                                 vtkViewport *vp)
{
  int i, j;
  vtkWindow *win = vp->GetVTKWindow();

  // has the font been cached ?
  for (i = 0; i < numCached; i++)
    {
    if (cache[i]->Window == win &&
        cache[i]->Italic == tm->GetItalic() &&
        cache[i]->Bold == tm->GetBold() &&
        cache[i]->FontSize == tm->GetFontSize() &&
        cache[i]->FontFamily == tm->GetFontFamily())
      {
      // make this the most recently used
      if (i != 0)
        {
        vtkFontStruct *tmp = cache[i];
        for (j = i-1; j >= 0; j--)
          {
          cache[j+1] = cache[j];
          }
        cache[0] = tmp;
        }
      return cache[0]->ListBase;
      }
    }

  HDC hdc = (HDC) win->GetGenericContext();

  // OK the font is not cached
  // so we need to make room for a new font
  if (numCached == 10)
    {
    wglMakeCurrent((HDC)cache[9]->Window->GetGenericContext(),
                   (HGLRC)cache[9]->Window->GetGenericDisplayId());
    glDeleteLists(cache[9]->ListBase,255);
    wglMakeCurrent(hdc, (HGLRC)win->GetGenericDisplayId());
    numCached = 9;
    }

  // add the new font
  if (!cache[numCached])
    {
    cache[numCached] = new vtkFontStruct;
    int done = 0;
    cache[numCached]->ListBase = 1000;
    do
      {
      done = 1;
      cache[numCached]->ListBase += 260;
      for (i = 0; i < numCached; i++)
        {
        if (cache[i]->ListBase == cache[numCached]->ListBase)
          {
          done = 0;
          }
        }
      }
    while (!done);
    }

  // set the other info and build the font
  cache[numCached]->Window = win;
  cache[numCached]->Italic = tm->GetItalic();
  cache[numCached]->Bold = tm->GetBold();
  cache[numCached]->FontSize = tm->GetFontSize();
  cache[numCached]->FontFamily = tm->GetFontFamily();
  wglUseFontBitmaps(hdc, 0, 255, cache[numCached]->ListBase);

  // now resort the list
  vtkFontStruct *tmp = cache[numCached];
  for (i = numCached-1; i >= 0; i--)
    {
    cache[i+1] = cache[i];
    }
  cache[0] = tmp;
  numCached++;
  return cache[0]->ListBase;
}

void vtkWin32OpenGLTextMapper::ReleaseGraphicsResources(vtkWindow *win)
{
  int i,j;

  // free up any cached font associated with this window
  // has the font been cached ?
  for (i = 0; i < numCached; i++)
    {
    if (cache[i]->Window == win)
      {
      glDeleteLists(cache[i]->ListBase,255);
      delete cache[i];
      // resort them
      numCached--;
      for (j = i; j < numCached; j++)
        {
        cache[j] = cache[j+1];
        }
      cache[numCached] = NULL;
      }
    }

  if ( this->Font )
    {
    DeleteObject( this->Font );
    this->Font = 0;
    }

  this->LastWindow = NULL;

  // very important
  // the release of graphics resources indicates that significant changes have
  // occurred. Old fonts, cached sizes etc are all no longer valid, so we send
  // ourselves a general modified message.
  this->Modified();
}

vtkWin32OpenGLTextMapper::vtkWin32OpenGLTextMapper()
{
}

vtkWin32OpenGLTextMapper::~vtkWin32OpenGLTextMapper()
{
  if (this->LastWindow)
    {
    this->ReleaseGraphicsResources(this->LastWindow);
    }
}

void vtkWin32OpenGLTextMapper::RenderOpaqueGeometry(vtkViewport* viewport,
                                                    vtkActor2D* actor)
{
  vtkDebugMacro (<< "RenderOpaqueGeometry");

  // turn off texturing in case it is on
  glDisable( GL_TEXTURE_2D );

  // Get the window information for display
  vtkWindow*  window = viewport->GetVTKWindow();
  if (this->LastWindow && this->LastWindow != window)
    {
    this->ReleaseGraphicsResources(this->LastWindow);
    }
  this->LastWindow = window;

  // Check for input
  if ( this->NumberOfLines > 1 )
    {
    this->RenderOpaqueGeometryMultipleLines(viewport, actor);
    return;
    }

  if ( this->Input == NULL )
    {
    vtkErrorMacro (<<"Render - No input");
    return;
    }

  int size[2];
  this->GetSize(viewport, size);

  // Get the device context from the window
  HDC hdc = (HDC) window->GetGenericContext();

  // Select the font
  HFONT hOldFont = (HFONT) SelectObject(hdc, this->Font);

  // Get the position of the text actor
  POINT ptDestOff;
  int* actorPos =
    actor->GetPositionCoordinate()->GetComputedViewportValue(viewport);
  ptDestOff.x = actorPos[0];
  ptDestOff.y = actorPos[1] - this->LineOffset;

  // Set up the font color from the text actor
  unsigned char red = 0;
  unsigned char green = 0;
  unsigned char blue = 0;
  float*  actorColor = actor->GetProperty()->GetColor();
  red = (unsigned char) (actorColor[0] * 255.0);
  green = (unsigned char) (actorColor[1] * 255.0);
  blue = (unsigned char) (actorColor[2] * 255.0);

  // Set up the shadow color
  float intensity;
  intensity = (red + green + blue)/3.0;

  unsigned char shadowRed, shadowGreen, shadowBlue;
  if (intensity > 128)
    {
    shadowRed = shadowBlue = shadowGreen = 0;
    }
  else
    {
    shadowRed = shadowBlue = shadowGreen = 255;
    }

  // Define bounding rectangle
  RECT rect;
  rect.left = ptDestOff.x;
  rect.top = ptDestOff.y;
  rect.bottom = ptDestOff.y;
  rect.right = ptDestOff.x;

  rect.right = rect.left + size[0];
  rect.top = rect.bottom + size[1];

  int winJust;
  switch (this->Justification)
    {
    int tmp;
    case VTK_TEXT_LEFT: winJust = DT_LEFT; break;
    case VTK_TEXT_CENTERED:
      winJust = DT_CENTER;
      tmp = rect.right - rect.left + 1;
      rect.left = rect.left - tmp/2;
      rect.right = rect.left + tmp;
      break;
    case VTK_TEXT_RIGHT:
      winJust = DT_RIGHT;
      tmp = rect.right - rect.left + 1;
      rect.right = rect.left;
      rect.left = rect.left - tmp;
    }
  switch (this->VerticalJustification)
    {
    case VTK_TEXT_TOP:
      rect.top = rect.bottom;
      rect.bottom = rect.bottom - size[1];
      break;
    case VTK_TEXT_CENTERED:
      rect.bottom = rect.bottom - size[1]/2;
      rect.top = rect.bottom + size[1];
      break;
    case VTK_TEXT_BOTTOM:
      break;
    }

  // push a 2D matrix on the stack
  int *vsize = viewport->GetSize();
  glMatrixMode( GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  if(viewport->GetIsPicking())
    {
    GLint glviewport[4];
    glGetIntegerv( GL_VIEWPORT, glviewport);
    vtkgluPickMatrix(viewport->GetPickX(), viewport->GetPickY(),
		     1, 1, glviewport);
    }

  glMatrixMode( GL_MODELVIEW );
  glPushMatrix();
  glLoadIdentity();
  glDisable( GL_LIGHTING);

  int front =
    (actor->GetProperty()->GetDisplayLocation() == VTK_FOREGROUND_LOCATION);

  // When picking draw the bounds of the text as a rectangle,
  // as text only picks when the pick point is exactly on the
  // origin of the text
  if(viewport->GetIsPicking())
    {
    glRectf(rect.left, rect.bottom, rect.right, rect.top);
    // Clean up and return after drawing the rectangle
    glMatrixMode( GL_PROJECTION);
    glPopMatrix();
    glMatrixMode( GL_MODELVIEW);
    glPopMatrix();
    glEnable( GL_LIGHTING);

    // Restore the state
    SelectObject(hdc, hOldFont);
    return;
    }

  glListBase(vtkWin32OpenGLTextMapper::GetListBaseForFont(this,viewport));

  // Set the colors for the shadow
  if (this->Shadow)
    {
    rect.left++; rect.bottom--;
    // set the colors for the foreground
    glColor3ub(shadowRed, shadowGreen, shadowBlue);
    glRasterPos3f((2.0 * (GLfloat)(rect.left) / vsize[0] - 1),
		  (2.0 * (GLfloat)(rect.bottom) / vsize[1] - 1),
		  (front)?(-1):(.9999));

    // Draw the shadow text
    glCallLists (strlen(this->Input), GL_UNSIGNED_BYTE, this->Input);
    rect.left--;  rect.bottom++;
    }

  // set the colors for the foreground
  glColor3ub(red, green, blue);
  glRasterPos3f((2.0 * (GLfloat)(rect.left) / vsize[0] - 1),
		(2.0 * (GLfloat)(rect.bottom) / vsize[1] - 1),
		(front)?(-1):(.9999));

  // display a string: // indicate start of glyph display lists
  glCallLists (strlen(this->Input), GL_UNSIGNED_BYTE, this->Input);

  glFlush();
  GdiFlush();

  glMatrixMode( GL_PROJECTION);
  glPopMatrix();
  glMatrixMode( GL_MODELVIEW);
  glPopMatrix();
  glEnable( GL_LIGHTING);

  // Restore the state
  SelectObject(hdc, hOldFont);
}

<commit_msg>ERR:Didn't modify picking to reflect coordinate system changes<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWin32OpenGLTextMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 REGENTS 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.

=========================================================================*/
#include "vtkWin32OpenGLTextMapper.h"
#include <GL/gl.h>
#include "vtkObjectFactory.h"
#include "vtkgluPickMatrix.h"

//------------------------------------------------------------------------------
vtkWin32OpenGLTextMapper* vtkWin32OpenGLTextMapper::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkWin32OpenGLTextMapper");
  if(ret)
    {
    return (vtkWin32OpenGLTextMapper*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkWin32OpenGLTextMapper;
}

struct vtkFontStruct
{
  vtkWindow *Window;
  int   Italic;
  int   Bold;
  int   FontSize;
  int   FontFamily;
  int   ListBase;
};

static vtkFontStruct *cache[10] = {NULL,NULL,NULL,NULL,NULL,
                                   NULL,NULL,NULL,NULL,NULL};
static numCached = 0;

int vtkWin32OpenGLTextMapper::GetListBaseForFont(vtkTextMapper *tm,
                                                 vtkViewport *vp)
{
  int i, j;
  vtkWindow *win = vp->GetVTKWindow();

  // has the font been cached ?
  for (i = 0; i < numCached; i++)
    {
    if (cache[i]->Window == win &&
        cache[i]->Italic == tm->GetItalic() &&
        cache[i]->Bold == tm->GetBold() &&
        cache[i]->FontSize == tm->GetFontSize() &&
        cache[i]->FontFamily == tm->GetFontFamily())
      {
      // make this the most recently used
      if (i != 0)
        {
        vtkFontStruct *tmp = cache[i];
        for (j = i-1; j >= 0; j--)
          {
          cache[j+1] = cache[j];
          }
        cache[0] = tmp;
        }
      return cache[0]->ListBase;
      }
    }

  HDC hdc = (HDC) win->GetGenericContext();

  // OK the font is not cached
  // so we need to make room for a new font
  if (numCached == 10)
    {
    wglMakeCurrent((HDC)cache[9]->Window->GetGenericContext(),
                   (HGLRC)cache[9]->Window->GetGenericDisplayId());
    glDeleteLists(cache[9]->ListBase,255);
    wglMakeCurrent(hdc, (HGLRC)win->GetGenericDisplayId());
    numCached = 9;
    }

  // add the new font
  if (!cache[numCached])
    {
    cache[numCached] = new vtkFontStruct;
    int done = 0;
    cache[numCached]->ListBase = 1000;
    do
      {
      done = 1;
      cache[numCached]->ListBase += 260;
      for (i = 0; i < numCached; i++)
        {
        if (cache[i]->ListBase == cache[numCached]->ListBase)
          {
          done = 0;
          }
        }
      }
    while (!done);
    }

  // set the other info and build the font
  cache[numCached]->Window = win;
  cache[numCached]->Italic = tm->GetItalic();
  cache[numCached]->Bold = tm->GetBold();
  cache[numCached]->FontSize = tm->GetFontSize();
  cache[numCached]->FontFamily = tm->GetFontFamily();
  wglUseFontBitmaps(hdc, 0, 255, cache[numCached]->ListBase);

  // now resort the list
  vtkFontStruct *tmp = cache[numCached];
  for (i = numCached-1; i >= 0; i--)
    {
    cache[i+1] = cache[i];
    }
  cache[0] = tmp;
  numCached++;
  return cache[0]->ListBase;
}

void vtkWin32OpenGLTextMapper::ReleaseGraphicsResources(vtkWindow *win)
{
  int i,j;

  // free up any cached font associated with this window
  // has the font been cached ?
  for (i = 0; i < numCached; i++)
    {
    if (cache[i]->Window == win)
      {
      glDeleteLists(cache[i]->ListBase,255);
      delete cache[i];
      // resort them
      numCached--;
      for (j = i; j < numCached; j++)
        {
        cache[j] = cache[j+1];
        }
      cache[numCached] = NULL;
      }
    }

  if ( this->Font )
    {
    DeleteObject( this->Font );
    this->Font = 0;
    }

  this->LastWindow = NULL;

  // very important
  // the release of graphics resources indicates that significant changes have
  // occurred. Old fonts, cached sizes etc are all no longer valid, so we send
  // ourselves a general modified message.
  this->Modified();
}

vtkWin32OpenGLTextMapper::vtkWin32OpenGLTextMapper()
{
}

vtkWin32OpenGLTextMapper::~vtkWin32OpenGLTextMapper()
{
  if (this->LastWindow)
    {
    this->ReleaseGraphicsResources(this->LastWindow);
    }
}

void vtkWin32OpenGLTextMapper::RenderOpaqueGeometry(vtkViewport* viewport,
                                                    vtkActor2D* actor)
{
  vtkDebugMacro (<< "RenderOpaqueGeometry");

  // turn off texturing in case it is on
  glDisable( GL_TEXTURE_2D );

  // Get the window information for display
  vtkWindow*  window = viewport->GetVTKWindow();
  if (this->LastWindow && this->LastWindow != window)
    {
    this->ReleaseGraphicsResources(this->LastWindow);
    }
  this->LastWindow = window;

  // Check for input
  if ( this->NumberOfLines > 1 )
    {
    this->RenderOpaqueGeometryMultipleLines(viewport, actor);
    return;
    }

  if ( this->Input == NULL )
    {
    vtkErrorMacro (<<"Render - No input");
    return;
    }

  int size[2];
  this->GetSize(viewport, size);

  // Get the device context from the window
  HDC hdc = (HDC) window->GetGenericContext();

  // Select the font
  HFONT hOldFont = (HFONT) SelectObject(hdc, this->Font);

  // Get the position of the text actor
  POINT ptDestOff;
  int* actorPos =
    actor->GetPositionCoordinate()->GetComputedViewportValue(viewport);
  ptDestOff.x = actorPos[0];
  ptDestOff.y = actorPos[1] - this->LineOffset;

  // Set up the font color from the text actor
  unsigned char red = 0;
  unsigned char green = 0;
  unsigned char blue = 0;
  float*  actorColor = actor->GetProperty()->GetColor();
  red = (unsigned char) (actorColor[0] * 255.0);
  green = (unsigned char) (actorColor[1] * 255.0);
  blue = (unsigned char) (actorColor[2] * 255.0);

  // Set up the shadow color
  float intensity;
  intensity = (red + green + blue)/3.0;

  unsigned char shadowRed, shadowGreen, shadowBlue;
  if (intensity > 128)
    {
    shadowRed = shadowBlue = shadowGreen = 0;
    }
  else
    {
    shadowRed = shadowBlue = shadowGreen = 255;
    }

  // Define bounding rectangle
  RECT rect;
  rect.left = ptDestOff.x;
  rect.top = ptDestOff.y;
  rect.bottom = ptDestOff.y;
  rect.right = ptDestOff.x;

  rect.right = rect.left + size[0];
  rect.top = rect.bottom + size[1];

  int winJust;
  switch (this->Justification)
    {
    int tmp;
    case VTK_TEXT_LEFT: winJust = DT_LEFT; break;
    case VTK_TEXT_CENTERED:
      winJust = DT_CENTER;
      tmp = rect.right - rect.left + 1;
      rect.left = rect.left - tmp/2;
      rect.right = rect.left + tmp;
      break;
    case VTK_TEXT_RIGHT:
      winJust = DT_RIGHT;
      tmp = rect.right - rect.left + 1;
      rect.right = rect.left;
      rect.left = rect.left - tmp;
    }
  switch (this->VerticalJustification)
    {
    case VTK_TEXT_TOP:
      rect.top = rect.bottom;
      rect.bottom = rect.bottom - size[1];
      break;
    case VTK_TEXT_CENTERED:
      rect.bottom = rect.bottom - size[1]/2;
      rect.top = rect.bottom + size[1];
      break;
    case VTK_TEXT_BOTTOM:
      break;
    }

  // push a 2D matrix on the stack
  int *vsize = viewport->GetSize();
  glMatrixMode( GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  if(viewport->GetIsPicking())
    {
    GLint glviewport[4];
    glGetIntegerv( GL_VIEWPORT, glviewport);
    vtkgluPickMatrix(viewport->GetPickX(), viewport->GetPickY(),
		     1, 1, glviewport);
    }

  glMatrixMode( GL_MODELVIEW );
  glPushMatrix();
  glLoadIdentity();
  glDisable( GL_LIGHTING);

  int front =
    (actor->GetProperty()->GetDisplayLocation() == VTK_FOREGROUND_LOCATION);

  // When picking draw the bounds of the text as a rectangle,
  // as text only picks when the pick point is exactly on the
  // origin of the text
  if(viewport->GetIsPicking())
    {
    float width = 2.0 * ((float)rect.right - rect.left) / vsize[0];
    float height = 2.0 * ((float)rect.top - rect.bottom) / vsize[1];
    float x1 = (2.0 * (GLfloat)(rect.left) / vsize[0] - 1);
    float y1 = (2.0 * (GLfloat)(rect.bottom) / vsize[1] - 1);
    glRectf(x1, y1, x1+width, y1+height);

    // Clean up and return after drawing the rectangle
    glMatrixMode( GL_PROJECTION);
    glPopMatrix();
    glMatrixMode( GL_MODELVIEW);
    glPopMatrix();
    glEnable( GL_LIGHTING);

    // Restore the state
    SelectObject(hdc, hOldFont);
    return;
    }

  glListBase(vtkWin32OpenGLTextMapper::GetListBaseForFont(this,viewport));

  // Set the colors for the shadow
  if (this->Shadow)
    {
    rect.left++; rect.bottom--;
    // set the colors for the foreground
    glColor3ub(shadowRed, shadowGreen, shadowBlue);
    glRasterPos3f((2.0 * (GLfloat)(rect.left) / vsize[0] - 1),
		  (2.0 * (GLfloat)(rect.bottom) / vsize[1] - 1),
		  (front)?(-1):(.9999));

    // Draw the shadow text
    glCallLists (strlen(this->Input), GL_UNSIGNED_BYTE, this->Input);
    rect.left--;  rect.bottom++;
    }

  // set the colors for the foreground
  glColor3ub(red, green, blue);
  glRasterPos3f((2.0 * (GLfloat)(rect.left) / vsize[0] - 1),
		(2.0 * (GLfloat)(rect.bottom) / vsize[1] - 1),
		(front)?(-1):(.9999));

  // display a string: // indicate start of glyph display lists
  glCallLists (strlen(this->Input), GL_UNSIGNED_BYTE, this->Input);

  glFlush();
  GdiFlush();

  glMatrixMode( GL_PROJECTION);
  glPopMatrix();
  glMatrixMode( GL_MODELVIEW);
  glPopMatrix();
  glEnable( GL_LIGHTING);

  // Restore the state
  SelectObject(hdc, hOldFont);
}

<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TAtt3D.cxx,v 1.1.1.1 2000/05/16 17:00:38 rdm Exp $
// Author: Fons Rademakers   08/09/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TAtt3D                                                               //
//                                                                      //
// Use this attribute class when an object should have 3D capabilities. //
//
// VisualTimestamp can be used by 3D viewers to determine if an object  //
// has  changed between two scene paints.                               //
// ResetVisualTimestamp must be called to activate the mechanism.       //
//////////////////////////////////////////////////////////////////////////

#include "TAtt3D.h"

ClassImp(TAtt3D)

//______________________________________________________________________________
void TAtt3D::Sizeof3D() const
{
   // Set total size of this 3D object (used by X3D interface).

   return;
}
<commit_msg>From Matevz: Removed comment left by negligence.<commit_after>// @(#)root/base:$Name:  $:$Id: TAtt3D.cxx,v 1.2 2006/04/07 08:43:59 brun Exp $
// Author: Fons Rademakers   08/09/99

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TAtt3D                                                               //
//                                                                      //
// Use this attribute class when an object should have 3D capabilities. //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TAtt3D.h"

ClassImp(TAtt3D)

//______________________________________________________________________________
void TAtt3D::Sizeof3D() const
{
   // Set total size of this 3D object (used by X3D interface).

   return;
}
<|endoftext|>


<commit_before><commit_msg>added many new tests, still not finished<commit_after><|endoftext|>


<commit_before>#ifndef PYTHONIC_INCLUDE_UTILS_ITERATOR_HPP
#define PYTHONIC_INCLUDE_UTILS_ITERATOR_HPP

namespace pythonic
{

  namespace utils
  {

    template <class T>
    struct comparable_iterator : T {
      comparable_iterator();
      comparable_iterator(T const &t);
      bool operator<(comparable_iterator<T> other);
    };

    // Utility class to remind sequence we are iterating on to avoid dangling
    // reference
    template <bool as_tuple, class T, class... Others>
    struct iterator_reminder;

    template <class T, class... Others>
    struct iterator_reminder<true, T, Others...> {
      std::tuple<T, Others...> value;
      iterator_reminder(T const &v, Others const &... o);
    };

    template <class T>
    struct iterator_reminder<false, T> {
      T value;
      iterator_reminder(T const &v);
    };

    template <class T>
    struct iterator_reminder<true, T> {
      std::tuple<T> value;
      iterator_reminder(T const &v);
    };

    /* Get the "minimum" of all iterators :
       - only random => random
       - at least one forward => forward
       */
    template <typename... Iters>
    struct iterator_min;

    template <typename T>
    struct iterator_min<T> {
      using type = typename std::iterator_traits<T>::iterator_category;
    };

    template <typename T, typename... Iters>
    struct iterator_min<T, Iters...> {
      using type = typename std::conditional<
          std::is_same<typename std::iterator_traits<T>::iterator_category,
                       std::forward_iterator_tag>::value,
          std::forward_iterator_tag,
          typename iterator_min<Iters...>::type>::type;
    };
  }
}

#endif
<commit_msg>Fix default constructor for itertools iterators<commit_after>#ifndef PYTHONIC_INCLUDE_UTILS_ITERATOR_HPP
#define PYTHONIC_INCLUDE_UTILS_ITERATOR_HPP

namespace pythonic
{

  namespace utils
  {

    template <class T>
    struct comparable_iterator : T {
      comparable_iterator();
      comparable_iterator(T const &t);
      bool operator<(comparable_iterator<T> other);
    };

    // Utility class to remind sequence we are iterating on to avoid dangling
    // reference
    template <bool as_tuple, class T, class... Others>
    struct iterator_reminder;

    template <class T, class... Others>
    struct iterator_reminder<true, T, Others...> {
      std::tuple<T, Others...> value;
      // FIXME : It works only because template arguments are not references
      // so it trigger a copy.
      iterator_reminder() = default;
      iterator_reminder(T const &v, Others const &... o);
    };

    template <class T>
    struct iterator_reminder<false, T> {
      T value;
      iterator_reminder() = default;
      iterator_reminder(T const &v);
    };

    template <class T>
    struct iterator_reminder<true, T> {
      std::tuple<T> value;
      iterator_reminder() = default;
      iterator_reminder(T const &v);
    };

    /* Get the "minimum" of all iterators :
       - only random => random
       - at least one forward => forward
       */
    template <typename... Iters>
    struct iterator_min;

    template <typename T>
    struct iterator_min<T> {
      using type = typename std::iterator_traits<T>::iterator_category;
    };

    template <typename T, typename... Iters>
    struct iterator_min<T, Iters...> {
      using type = typename std::conditional<
          std::is_same<typename std::iterator_traits<T>::iterator_category,
                       std::forward_iterator_tag>::value,
          std::forward_iterator_tag,
          typename iterator_min<Iters...>::type>::type;
    };
  }
}

#endif
<|endoftext|>


<commit_before>#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "AnalogAccel.h"
#include "Timer.h"
#include "USART.h"
#include "Memory.h"
#include "DataCollector.h"

enum State {WAIT, ERASE, COLLECT, DUMP};

void readState(USART& usart, State& state)
{
	if(!usart.hasRxData())
		return;

	uint8_t cmd = usart.readbyte();

	switch(cmd)
	{
		case 'W':
			state = WAIT;
			break;
		case 'E':
			state = ERASE;
			break;
		case 'C':
			state = COLLECT;
			break;
		case 'D':
			state = DUMP;
			break;
	};
}

int main()
{
	sei();

	AnalogAccel analogAccel;
	Timer timer(1000); //1000Hz count frequency
	USART usart(57600); //Give or take 0.2% rounding error
	Memory memory(&PORTB, PORTB2, timer);
	uint32_t address = 0;
	DataCollector dataCollector(analogAccel, timer);

	State currentState = WAIT;

	char eraseSuccess[] = "Chip erased\n";
	char eraseFail[] = "Erase failed\n";

	while(true)
	{
		switch(currentState)
		{
			case WAIT: //Just loop until USART switches state
				break;
			case ERASE:
				address = 0;
				if(memory.eraseChip())
					usart.write((uint8_t*)eraseSuccess,
						sizeof(eraseSuccess));
				else
					usart.write((uint8_t*)eraseFail,
						sizeof(eraseFail));
				break;
			case COLLECT:
				dataCollector.collectPage();
				if(memory.writePage(dataCollector.getPagePtr(), address))
					address += PAGELEN;
				else //Memory full or not responsive
					currentState = WAIT;
				break;
			case DUMP:
				break;
		};

		readState(usart, currentState);
	}

	return 0;
}
<commit_msg>Bugfix: erasing chip would cause infinite loop condition<commit_after>#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "AnalogAccel.h"
#include "Timer.h"
#include "USART.h"
#include "Memory.h"
#include "DataCollector.h"

enum State {WAIT, ERASE, COLLECT, DUMP};

void readState(USART& usart, State& state)
{
	if(!usart.hasRxData())
		return;

	uint8_t cmd = usart.readbyte();

	switch(cmd)
	{
		case 'W':
			state = WAIT;
			break;
		case 'E':
			state = ERASE;
			break;
		case 'C':
			state = COLLECT;
			break;
		case 'D':
			state = DUMP;
			break;
	};
}

int main()
{
	sei();

	AnalogAccel analogAccel;
	Timer timer(1000); //1000Hz count frequency
	USART usart(57600); //Give or take 0.2% rounding error
	Memory memory(&PORTB, PORTB2, timer);
	uint32_t address = 0;
	DataCollector dataCollector(analogAccel, timer);

	State currentState = WAIT;

	char eraseSuccess[] = "Chip erased\n";
	char eraseFail[] = "Erase failed\n";

	while(true)
	{
		switch(currentState)
		{
			case WAIT: //Just loop until USART switches state
				break;
			case ERASE:
				address = 0;
				if(memory.eraseChip())
					usart.write((uint8_t*)eraseSuccess,
						sizeof(eraseSuccess));
				else
					usart.write((uint8_t*)eraseFail,
						sizeof(eraseFail));

				currentState = WAIT;
				break;
			case COLLECT:
				dataCollector.collectPage();
				if(memory.writePage(dataCollector.getPagePtr(), address))
					address += PAGELEN;
				else //Memory full or not responsive
					currentState = WAIT;
				break;
			case DUMP:
				break;
		};

		readState(usart, currentState);
	}

	return 0;
}
<|endoftext|>


<commit_before><commit_msg>P4 to Git Change 1467094 by johtaylo@johtaylo-jtincrementor-increment on 2017/10/06 03:00:04<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "unit_tests.hpp"

using namespace mfem;

TEST_CASE("VTU XML Reader", "[Mesh][VTU][XML]")
{
   auto mesh_filename = GENERATE("quad_append_b64.vtu", "quad_append_raw.vtu",
                                 "quad_ascii.vtu", "quad_binary.vtu"
#ifdef MFEM_USE_ZLIB
                                 ,
                                 "quad_append_b64_compress.vtu",
                                 "quad_append_raw_compress.vtu",
                                 "quad_binary_compress.vtu"
#endif
                                );
   Mesh mesh = Mesh::LoadFromFile(("data/"+std::string(mesh_filename)).c_str());

   REQUIRE(mesh.Dimension() == 2);
   REQUIRE(mesh.GetNE() == 9);
   REQUIRE(mesh.GetNV() == 16);
   REQUIRE(mesh.HasGeometry(Geometry::POINT));
   REQUIRE(mesh.HasGeometry(Geometry::SEGMENT));
   REQUIRE(mesh.HasGeometry(Geometry::SQUARE));
   REQUIRE(mesh.GetNumGeometries(2) == 1);
}
<commit_msg>Don't use #ifdef inside macro (not portable)<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "mfem.hpp"
#include "unit_tests.hpp"

using namespace mfem;

TEST_CASE("VTU XML Reader", "[Mesh][VTU][XML]")
{
   std::vector<std::string> mesh_filenames = {
      "quad_append_b64.vtu", "quad_append_raw.vtu",
      "quad_ascii.vtu", "quad_binary.vtu"
   };
#ifdef MFEM_USE_ZLIB
   // Test VTU meshes with binary compression only if compiled with zlib enabled
   mesh_filenames.insert(mesh_filenames.end(), {
      "quad_append_b64_compress.vtu", "quad_append_raw_compress.vtu",
      "quad_binary_compress.vtu"
   });
#endif
   for (const std::string &fname : mesh_filenames)
   {
      Mesh mesh = Mesh::LoadFromFile(("data/" + fname).c_str());
      REQUIRE(mesh.Dimension() == 2);
      REQUIRE(mesh.GetNE() == 9);
      REQUIRE(mesh.GetNV() == 16);
      REQUIRE(mesh.HasGeometry(Geometry::POINT));
      REQUIRE(mesh.HasGeometry(Geometry::SEGMENT));
      REQUIRE(mesh.HasGeometry(Geometry::SQUARE));
      REQUIRE(mesh.GetNumGeometries(2) == 1);
   }
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Gábor Pankotay (mrpanky@gmail.com)

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 <nan.h>
#include <semaphore.h>

#include "sem.h"
#include "sem_acquireworker.h"

using std::string;
using v8::Local;
using v8::Value;
using v8::String;
using v8::Function;
using v8::FunctionTemplate;
using Nan::New;
using Nan::Set;
using Nan::To;
using Nan::ObjectWrap;
using Nan::ThrowError;
using Nan::ErrnoException;
using Nan::Callback;
using Nan::Persistent;
using Nan::NewInstance;
using Nan::GetFunction;
using Nan::SetPrototypeMethod;

NAN_MODULE_INIT(SemaphoreFactory::Init)
{
    Local<FunctionTemplate> tpl = New<FunctionTemplate>(SemaphoreFactory::Instance);
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    SetPrototypeMethod(tpl, "acquire", SemaphoreFactory::Acquire);
    SetPrototypeMethod(tpl, "release", SemaphoreFactory::Release);

    constructor().Reset(GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(SemaphoreFactory::CreateInstance)
{
    Local<Function> ctor = New<Function>(SemaphoreFactory::constructor());

    String::Utf8Value utf8(info[0]->ToString());
    string name(*utf8);
    name = SEM_NAME(name);

    const int argc = 1;

    Local<Value> argv[1] = {New(name).ToLocalChecked()};
    info.GetReturnValue().Set(NewInstance(ctor, argc, argv).ToLocalChecked());
}

NAN_METHOD(SemaphoreFactory::Instance)
{
    String::Utf8Value utf8(info[0]->ToString());
    string name(*utf8);

    if (info.IsConstructCall())
    {
        SemaphoreFactory *obj = new SemaphoreFactory(name);
        obj->Wrap(info.This());
        info.GetReturnValue().Set(info.This());
    }
    else
    {
        const int argc = 1;

        Local<Value> argv[argc] = {New(name).ToLocalChecked()};
        Local<Function> ctor = New(SemaphoreFactory::constructor());
        info.GetReturnValue().Set(NewInstance(ctor, argc, argv).ToLocalChecked());
    }
}

inline Persistent<Function> &SemaphoreFactory::constructor()
{
    static Persistent<Function> ctor;
    return ctor;
}

NAN_METHOD(SemaphoreFactory::Acquire)
{
    long timeout_millisec = -1;

    if (info.Length() == 0 && !info[info.Length() - 1]->IsFunction())
    {
        ThrowError("Callback function missing.");
    }

    if (info.Length() > 1)
    {
        timeout_millisec = (long)info[0]->NumberValue();
    }

    Callback *callback = new Callback(info[info.Length() - 1].As<Function>());

    SemaphoreFactory *obj = ObjectWrap::Unwrap<SemaphoreFactory>(info.Holder());

#ifdef _WIN32
    //todo win
#else
    obj->mutex = sem_open(obj->semaphore_name.c_str(), O_CREAT, S_IRUSR | S_IWUSR, 1);
#endif

    if (obj->mutex == SEM_FAILED)
    {
        ThrowError(ErrnoException(
            errno,
            "sem_open",
            strerror(errno)));
    }

    auto acquire_worker = new AcquireWorker(callback, obj->mutex, timeout_millisec);
    AsyncQueueWorker(acquire_worker);
}

NAN_METHOD(SemaphoreFactory::Release)
{
    SemaphoreFactory *obj = ObjectWrap::Unwrap<SemaphoreFactory>(info.Holder());

#ifdef _WIN32

#else
    int result = sem_post(obj->mutex);
#endif

    if (result < 0)
    {
        ThrowError(ErrnoException(
            errno,
            "sem_post",
            strerror(errno)));
        return;
    }
}

NAN_METHOD(SemaphoreFactory::Unlink)
{
    if (info[0]->IsString())
    {
        String::Utf8Value utf8(info[0]->ToString());
        string name(*utf8);

#ifdef _WIN32
        //todo win
#else
        sem_unlink(name.c_str());
#endif
    }
}

NAN_MODULE_INIT(Init)
{
    SemaphoreFactory::Init(target);
    Set(target,
        New<String>("create").ToLocalChecked(),
        GetFunction(New<FunctionTemplate>(SemaphoreFactory::CreateInstance)).ToLocalChecked());
    Set(target,
        New<String>("unlink").ToLocalChecked(),
        GetFunction(New<FunctionTemplate>(SemaphoreFactory::Unlink)).ToLocalChecked());
}

NODE_MODULE(sem, Init)
<commit_msg>close semaphore after post<commit_after>/*
Copyright 2017 Gábor Pankotay (mrpanky@gmail.com)

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 <nan.h>
#include <semaphore.h>

#include "sem.h"
#include "sem_acquireworker.h"

using std::string;
using v8::Local;
using v8::Value;
using v8::String;
using v8::Function;
using v8::FunctionTemplate;
using Nan::New;
using Nan::Set;
using Nan::To;
using Nan::ObjectWrap;
using Nan::ThrowError;
using Nan::ErrnoException;
using Nan::Callback;
using Nan::Persistent;
using Nan::NewInstance;
using Nan::GetFunction;
using Nan::SetPrototypeMethod;

NAN_MODULE_INIT(SemaphoreFactory::Init)
{
    Local<FunctionTemplate> tpl = New<FunctionTemplate>(SemaphoreFactory::Instance);
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    SetPrototypeMethod(tpl, "acquire", SemaphoreFactory::Acquire);
    SetPrototypeMethod(tpl, "release", SemaphoreFactory::Release);

    constructor().Reset(GetFunction(tpl).ToLocalChecked());
}

NAN_METHOD(SemaphoreFactory::CreateInstance)
{
    Local<Function> ctor = New<Function>(SemaphoreFactory::constructor());

    String::Utf8Value utf8(info[0]->ToString());
    string name(*utf8);
    name = SEM_NAME(name);

    const int argc = 1;

    Local<Value> argv[1] = {New(name).ToLocalChecked()};
    info.GetReturnValue().Set(NewInstance(ctor, argc, argv).ToLocalChecked());
}

NAN_METHOD(SemaphoreFactory::Instance)
{
    String::Utf8Value utf8(info[0]->ToString());
    string name(*utf8);

    if (info.IsConstructCall())
    {
        SemaphoreFactory *obj = new SemaphoreFactory(name);
        obj->Wrap(info.This());
        info.GetReturnValue().Set(info.This());
    }
    else
    {
        const int argc = 1;

        Local<Value> argv[argc] = {New(name).ToLocalChecked()};
        Local<Function> ctor = New(SemaphoreFactory::constructor());
        info.GetReturnValue().Set(NewInstance(ctor, argc, argv).ToLocalChecked());
    }
}

inline Persistent<Function> &SemaphoreFactory::constructor()
{
    static Persistent<Function> ctor;
    return ctor;
}

NAN_METHOD(SemaphoreFactory::Acquire)
{
    long timeout_millisec = -1;

    if (info.Length() == 0 && !info[info.Length() - 1]->IsFunction())
    {
        ThrowError("Callback function missing.");
    }

    if (info.Length() > 1)
    {
        timeout_millisec = (long)info[0]->NumberValue();
    }

    Callback *callback = new Callback(info[info.Length() - 1].As<Function>());

    SemaphoreFactory *obj = ObjectWrap::Unwrap<SemaphoreFactory>(info.Holder());

#ifdef _WIN32
    //todo win
#else
    obj->mutex = sem_open(obj->semaphore_name.c_str(), O_CREAT, S_IRUSR | S_IWUSR, 1);
#endif

    if (obj->mutex == SEM_FAILED)
    {
        ThrowError(ErrnoException(
            errno,
            "sem_open",
            strerror(errno)));
    }

    auto acquire_worker = new AcquireWorker(callback, obj->mutex, timeout_millisec);
    AsyncQueueWorker(acquire_worker);
}

NAN_METHOD(SemaphoreFactory::Release)
{
    SemaphoreFactory *obj = ObjectWrap::Unwrap<SemaphoreFactory>(info.Holder());

#ifdef _WIN32

#else
    int result = sem_post(obj->mutex);
    sem_close(obj->mutex);
#endif

    if (result < 0)
    {
        ThrowError(ErrnoException(
            errno,
            "sem_post",
            strerror(errno)));
        return;
    }
}

NAN_METHOD(SemaphoreFactory::Unlink)
{
    if (info[0]->IsString())
    {
        String::Utf8Value utf8(info[0]->ToString());
        string name(*utf8);

#ifdef _WIN32
        //todo win
#else
        sem_unlink(name.c_str());
#endif
    }
}

NAN_MODULE_INIT(Init)
{
    SemaphoreFactory::Init(target);
    Set(target,
        New<String>("create").ToLocalChecked(),
        GetFunction(New<FunctionTemplate>(SemaphoreFactory::CreateInstance)).ToLocalChecked());
    Set(target,
        New<String>("unlink").ToLocalChecked(),
        GetFunction(New<FunctionTemplate>(SemaphoreFactory::Unlink)).ToLocalChecked());
}

NODE_MODULE(sem, Init)
<|endoftext|>


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

#include "lcds.h"
#include "bitop.h"

#include <util/delay.h>
#include <avr/pgmspace.h>

avr_cpp_lib::LCDS::LCDS(OutputPin rs, OutputPin e, OutputPin d4, OutputPin d5, OutputPin d6, OutputPin d7)
	: rs(rs), e(e), d4(d4), d5(d5), d6(d6), d7(d7) {
	d7.clear();
	d6.clear();
	d5.set();
	d4.set();
	rs.clear();

	// one (8 bit mode)
	enableToggle();

	// two (8 bit mode)
	enableToggle();

	// three (4 bit mode)
	d4.clear();
	enableToggle();

	// dual line, 4 bit mode
	command(0b00101000);

	// turn display on, cursor off
	command(DISPLAY_ON);
}

void avr_cpp_lib::LCDS::enableToggle() {
	e.set();
	_delay_ms(1);
	e.clear();
	_delay_ms(1);
}

void avr_cpp_lib::LCDS::command(uint8_t c) {
	rs.clear();
	send(c);
}

void avr_cpp_lib::LCDS::character(uint8_t c) {
	rs.set();
	send(c);
}

void avr_cpp_lib::LCDS::send(uint8_t c) {
	if (BITSET(c, 7)) {
		d7.set();
	} else {
		d7.clear();
	}
	if (BITSET(c, 6)) {
		d6.set();
	} else {
		d6.clear();
	}
	if (BITSET(c, 5)) {
		d5.set();
	} else {
		d5.clear();
	}
	if (BITSET(c, 4)) {
		d4.set();
	} else {
		d4.clear();
	}
	enableToggle();
	if (BITSET(c, 3)) {
		d7.set();
	} else {
		d7.clear();
	}
	if (BITSET(c, 2)) {
		d6.set();
	} else {
		d6.clear();
	}
	if (BITSET(c, 1)) {
		d5.set();
	} else {
		d5.clear();
	}
	if (BITSET(c, 0)) {
		d4.set();
	} else {
		d4.clear();
	}
	enableToggle();
}

void avr_cpp_lib::LCDS::gotoXY(uint8_t x, uint8_t y) {
	uint8_t tmp;
	switch (y) {
	case 0:
		tmp = x;
		break;
	case 1:
		tmp = 0x40 + x;
		break;
	case 2:
		tmp = 0x14 + x;
		break;
	default:
		tmp = 0x54 + x;
	}
	command(1<<7 | tmp);
}

void avr_cpp_lib::LCDS::write(uint32_t i, uint8_t l, uint8_t m) {
	char buf[l + 1];
	buf[l] = '\0';
	for (; l > 0; l--) {
		uint8_t c = i % m;
		if (c < 10) {
			buf[l-1] = 0x30 + c;
		} else {
			buf[l-1] = 0x41 + c - 10;
		}
		i = i / m;
	}
	write(buf);
}

void avr_cpp_lib::LCDS::write(const char * s) {
	while (*s != '\0') {
		character(*s);
		s++;
	}
}

void avr_cpp_lib::LCDS::writeFlash(const char * s) {
	uint8_t c = pgm_read_byte(s);
	while (c != '\0') {
		character(c);
		s++;
		c = pgm_read_byte(s);
	}
}
<commit_msg>Some commands take some time, added delay<commit_after>/* File: lcds.cpp
 * Synchronous lcd hd44780 interface.
 */
/* Copyright (c) 2012-2013 Domen Ipavec (domen.ipavec@z-v.si)
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "lcds.h"
#include "bitop.h"

#include <util/delay.h>
#include <avr/pgmspace.h>

avr_cpp_lib::LCDS::LCDS(OutputPin rs, OutputPin e, OutputPin d4, OutputPin d5, OutputPin d6, OutputPin d7)
	: rs(rs), e(e), d4(d4), d5(d5), d6(d6), d7(d7) {
	d7.clear();
	d6.clear();
	d5.set();
	d4.set();
	rs.clear();

	// one (8 bit mode)
	enableToggle();

	// two (8 bit mode)
	enableToggle();

	// three (4 bit mode)
	d4.clear();
	enableToggle();

	// dual line, 4 bit mode
	command(0b00101000);

	// turn display on, cursor off
	command(DISPLAY_ON);
}

void avr_cpp_lib::LCDS::enableToggle() {
	e.set();
	_delay_ms(1);
	e.clear();
	_delay_ms(1);
}

void avr_cpp_lib::LCDS::command(uint8_t c) {
	rs.clear();
	send(c);
	_delay_ms(2);
}

void avr_cpp_lib::LCDS::character(uint8_t c) {
	rs.set();
	send(c);
}

void avr_cpp_lib::LCDS::send(uint8_t c) {
	if (BITSET(c, 7)) {
		d7.set();
	} else {
		d7.clear();
	}
	if (BITSET(c, 6)) {
		d6.set();
	} else {
		d6.clear();
	}
	if (BITSET(c, 5)) {
		d5.set();
	} else {
		d5.clear();
	}
	if (BITSET(c, 4)) {
		d4.set();
	} else {
		d4.clear();
	}
	enableToggle();
	if (BITSET(c, 3)) {
		d7.set();
	} else {
		d7.clear();
	}
	if (BITSET(c, 2)) {
		d6.set();
	} else {
		d6.clear();
	}
	if (BITSET(c, 1)) {
		d5.set();
	} else {
		d5.clear();
	}
	if (BITSET(c, 0)) {
		d4.set();
	} else {
		d4.clear();
	}
	enableToggle();
}

void avr_cpp_lib::LCDS::gotoXY(uint8_t x, uint8_t y) {
	uint8_t tmp;
	switch (y) {
	case 0:
		tmp = x;
		break;
	case 1:
		tmp = 0x40 + x;
		break;
	case 2:
		tmp = 0x14 + x;
		break;
	default:
		tmp = 0x54 + x;
	}
	command(1<<7 | tmp);
}

void avr_cpp_lib::LCDS::write(uint32_t i, uint8_t l, uint8_t m) {
	char buf[l + 1];
	buf[l] = '\0';
	for (; l > 0; l--) {
		uint8_t c = i % m;
		if (c < 10) {
			buf[l-1] = 0x30 + c;
		} else {
			buf[l-1] = 0x41 + c - 10;
		}
		i = i / m;
	}
	write(buf);
}

void avr_cpp_lib::LCDS::write(const char * s) {
	while (*s != '\0') {
		character(*s);
		s++;
	}
}

void avr_cpp_lib::LCDS::writeFlash(const char * s) {
	uint8_t c = pgm_read_byte(s);
	while (c != '\0') {
		character(c);
		s++;
		c = pgm_read_byte(s);
	}
}
<|endoftext|>