<commit_before>// hack, see http://stackoverflow.com/questions/12523122/what-is-glibcxx-use-nanosleep-all-about
#define _GLIBCXX_USE_NANOSLEEP 1
#include <chrono>
#include <thread>
#include <linux/i2c-dev.h>
//#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "NodeDb.h"
#include "NodeDCMotor.h"

using namespace std;
using namespace Arro;
using namespace arro;

// To stub out
#ifndef RPI
typedef signed char s8;
typedef unsigned char u8;

typedef signed short s16;
typedef unsigned short u16;

typedef signed int s32;
typedef unsigned int u32;

typedef signed long long s64;

s32 i2c_smbus_read_byte(int /*client*/){
    return 0;
}
s32 i2c_smbus_write_byte(int/*client*/, u8 /*value*/){
    return 0;
}
s32 i2c_smbus_read_byte_data(int/*client*/, u8 /*command*/){
    return 0;
}
s32 i2c_smbus_write_byte_data(int/*client*/, u8 /*command*/, u8 /*value*/){
    return 0;
}
s32 i2c_smbus_read_word_data(int/*client*/, u8 /*command*/){
    return 0;
}
s32 i2c_smbus_write_word_data(int/*client*/,  u8 /*command*/, u16 /*value*/){
    return 0;
}

#endif

// Registers/etc.
#define  __MODE1               0x00
#define  __MODE2               0x01
#define  __SUBADR1             0x02
#define  __SUBADR2             0x03
#define  __SUBADR3             0x04
#define  __PRESCALE            0xFE
#define  __LED0_ON_L           0x06
#define  __LED0_ON_H           0x07
#define  __LED0_OFF_L          0x08
#define  __LED0_OFF_H          0x09
#define  __ALL_LED_ON_L        0xFA
#define  __ALL_LED_ON_H        0xFB
#define  __ALL_LED_OFF_L       0xFC
#define  __ALL_LED_OFF_H       0xFD

// Bits
#define __RESTART              0x80
#define __SLEEP                0x10
#define __ALLCALL              0x01
#define __INVRT                0x10
#define __OUTDRV               0x04

static RegisterMe<NodeDCMotor> registerMe("DCMotor");

unsigned char
NodeDCMotor::MotorHAT::i2c_readU8(unsigned char command) {
    // Using I2C Read, equivalent of i2c_smbus_read_byte(file)
    // if (read(file, buf, 1) != 1) {
    __s32 ret  = i2c_smbus_read_byte_data(m_file, command);
    m_trace.println("---- i2c_read returned ", ret);
    if (ret == -1) {
        m_trace.fatal("Failed i2c_read errno", errno);
    } else {
        // buf[0] contains the read byte
    }
    return ret;
}

void
NodeDCMotor::MotorHAT::i2c_write8(unsigned char command, unsigned short value) {
    // Using I2C Write, equivalent of
    // i2c_smbus_write_word_data(file, register, 0x6543)

    // unsigned char buf[10];
    // buf[0] = register;
    // buf[1] = value & 0x000000FF; // 0x43;
    // value = value >> 8;
    // buf[2] = value & 0x000000FF; // 0x65;
    // if (write(file, buf, 3) !=3) {

    __s32 ret = i2c_smbus_write_byte_data(m_file, command, value);
    m_trace.println("---- i2c_write8 Wrote", value);
    m_trace.println("to ", (int)command);
    if (ret == -1) {
        m_trace.fatal("Failed i2c_write8 errno", errno);
    }
}

void
NodeDCMotor::MotorHAT::setAllPWM(int on, int off) {
    i2c_write8(__ALL_LED_ON_L, on & 0xFF);
    i2c_write8(__ALL_LED_ON_H, on >> 8);
    i2c_write8(__ALL_LED_OFF_L, off & 0xFF);
    i2c_write8(__ALL_LED_OFF_H, off >> 8);
}

void
NodeDCMotor::MotorHAT::setPWM(int channel, int on, int off) {
    i2c_write8(__LED0_ON_L+4*channel, on & 0xFF);
    i2c_write8(__LED0_ON_H+4*channel, on >> 8);
    i2c_write8(__LED0_OFF_L+4*channel, off & 0xFF);
    i2c_write8(__LED0_OFF_H+4*channel, off >> 8);
}

void
NodeDCMotor::MotorHAT::setPWMFreq(double freq) {
    m_prescaleval = 25000000.0;   // 25MHz
    m_prescaleval /= 4096.0;      // 12-bit
    m_prescaleval /= float(freq);
    m_prescaleval -= 1.0;

    m_trace.println("Setting PWM frequency to %d Hz", freq);
    m_trace.println("Estimated pre-scale: %d", m_prescaleval);

    int prescale = (int)(m_prescaleval + 0.5);
    m_trace.println("Final pre-scale", prescale);

    int oldmode = i2c_readU8(__MODE1);
    int newmode = (oldmode & 0x7F) | __SLEEP;  // sleep
    i2c_write8(__MODE1, newmode);           // go to sleep
    i2c_write8(__PRESCALE, prescale);
    i2c_write8(__MODE1, oldmode);
    //time.sleep(0.005)
    std::chrono::milliseconds timespan(5);
    std::this_thread::sleep_for(timespan);
    i2c_write8(__MODE1, oldmode | 0x80);
}

NodeDCMotor::MotorHAT::MotorHAT(int address, const char* filename, int freq):
    m_trace("DCMotor", false),
    m_prescaleval(0),
    m_i2caddr(address),
    m_frequency(freq) {
    m_trace.println("NodeDCMotor::MotorHAT::MotorHAT");

#ifdef RPI
    if ((m_file = open(filename,O_RDWR)) < 0) {
        m_trace.fatal("Failed to open the bus errno", errno);
    }

    if (ioctl(m_file, I2C_SLAVE, m_i2caddr) < 0) {
        m_trace.fatal("Failed to acquire bus access and/or talk to slave");
    }
#else
    m_trace.println(string("Not opening") + filename);
#endif

    /* Reseting PCA9685 */
    setAllPWM(0, 0);
    i2c_smbus_write_byte_data(m_file, __MODE2, __OUTDRV);
    i2c_smbus_write_byte_data(m_file, __MODE1, __ALLCALL);
    std::chrono::milliseconds timespan(5);
    std::this_thread::sleep_for(timespan);

    int oldmode = i2c_readU8(__MODE1);
    int newmode = oldmode & ~(__SLEEP);  // reset sleep
    i2c_write8(__MODE1, newmode);
    std::this_thread::sleep_for(timespan);

    //    self.motors = [ Adafruit_DCMotor(self, m) for m in range(4) ]
    //    self.steppers = [ Adafruit_StepperMotor(self, 1), Adafruit_StepperMotor(self, 2) ]
    //    self._pwm =  PWM(addr, debug=False)

}

void
NodeDCMotor::MotorHAT::setPin(int pin, int value) {
    m_trace.println("NodeDCMotor::MotorHAT::setPin");

    if ((pin < 0) or (pin > 15)) {
        throw std::runtime_error("PWM pin must be between 0 and 15 inclusive");
    }
    if ((value != 0) and (value != 1)) {
        throw std::runtime_error("Pin value must be 0 or 1!");
    }
    if (value == 0) {
        setPWM(pin, 0, 4096);
    }
    if (value == 1) {
        setPWM(pin, 4096, 0);
    }
}

NodeDCMotor::MotorHAT* NodeDCMotor::m_pMotorHAT = nullptr;

NodeDCMotor::NodeDCMotor(Process* d, const string& /*name*/, ConfigReader::StringMap& params, TiXmlElement*):
    m_trace("NodeDCMotor", true),
    m_device(d),
    m_Ch(0),
    m_running(true) {

    if(!m_pMotorHAT) {
        m_pMotorHAT = new MotorHAT();
    }

    try {
        m_Ch = stod(params.at("Motor"));
    }
    catch (std::out_of_range) {
        m_trace.println("### param not found Ch ");
        m_Ch = 0;
    }
    int pwm;
    int in1;
    int in2;

    m_trace.println(string("Init motor ") + std::to_string(m_Ch));
    if (m_Ch == 0) {
        pwm = 8;
        in2 = 9;
        in1 = 10;
    }
    else if (m_Ch == 1) {
        pwm = 13;
        in2 = 12;
        in1 = 11;
    }
    else if (m_Ch == 2) {
        pwm = 2;
        in2 = 3;
        in1 = 4;
    }
    else if (m_Ch == 3) {
        pwm = 7;
        in2 = 6;
        in1 = 5;
    }
    else
    {
        throw std::runtime_error("MotorHAT Motor must be between 1 and 4 inclusive");
    }

    m_PWMpin = pwm;
    m_IN1pin = in1;
    m_IN2pin = in2;

}

void
NodeDCMotor::run(NodeDCMotor::MotorHAT::dir command) {
    m_trace.println("NodeDCMotor::run");
    if(m_pMotorHAT) {
        if (command == MotorHAT::FORWARD) {
            m_pMotorHAT->setPin(m_IN2pin, 0);
            m_pMotorHAT->setPin(m_IN1pin, 1);
        }
        if (command == MotorHAT::BACKWARD) {
            m_pMotorHAT->setPin(m_IN1pin, 0);
            m_pMotorHAT->setPin(m_IN2pin, 1);
        }
        if (command == MotorHAT::RELEASE) {
            m_pMotorHAT->setPin(m_IN1pin, 0);
            m_pMotorHAT->setPin(m_IN2pin, 0);
        }
    }
}

void
NodeDCMotor::setSpeed(int speed) {
    m_trace.println("NodeDCMotor::setSpeed");
    if (speed < 0) {
        speed = 0;
    }
    if (speed > 255) {
        speed = 255;
    }
    m_pMotorHAT->setPWM(m_Ch, 0, speed * 16);
}

void
NodeDCMotor::handleMessage(MessageBuf* m, const std::string& padName) {
    m_trace.println("NodeDCMotor::handleMessage");
    m_trace.println(padName);
    if(m_running && padName == "speed") {
        auto msg = new Value();
        msg->ParseFromString(m->c_str());

        assert(msg->GetTypeName() == "arro.Value");

        setSpeed(((Value*)msg)->value());
        run(MotorHAT::FORWARD);

    } else if(m_running && padName == "direction") {
        auto msg = new Value();
        msg->ParseFromString(m->c_str());

        int dir = ((Value*)msg)->value();
        if(dir >= 0 && dir <= 4) {
            run((MotorHAT::dir)dir);
        }

        assert(msg->GetTypeName() == "arro.Value");

    } else if(padName == "_action") {
        auto msg = new Action();
        msg->ParseFromString(m->c_str());

        string a = msg->action();

        if(a == "_terminated") {
            m_trace.println("Received _terminated");
            m_running = false;
            // Switch off the motor
            run(MotorHAT::RELEASE);
        }

        assert(msg->GetTypeName() == "arro.Action");

    } else {
        m_trace.println(string("Message received from ") + padName);
    }
}

void
NodeDCMotor::runCycle() {
    m_trace.println("NodeDCMotor::runCycle");

}
<commit_msg>DC Motor fix<commit_after>// hack, see http://stackoverflow.com/questions/12523122/what-is-glibcxx-use-nanosleep-all-about
#define _GLIBCXX_USE_NANOSLEEP 1
#include <chrono>
#include <thread>
#include <linux/i2c-dev.h>
//#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "NodeDb.h"
#include "NodeDCMotor.h"

using namespace std;
using namespace Arro;
using namespace arro;

// To stub out
#ifndef RPI
typedef signed char s8;
typedef unsigned char u8;

typedef signed short s16;
typedef unsigned short u16;

typedef signed int s32;
typedef unsigned int u32;

typedef signed long long s64;

s32 i2c_smbus_read_byte(int /*client*/){
    return 0;
}
s32 i2c_smbus_write_byte(int/*client*/, u8 /*value*/){
    return 0;
}
s32 i2c_smbus_read_byte_data(int/*client*/, u8 /*command*/){
    return 0;
}
s32 i2c_smbus_write_byte_data(int/*client*/, u8 /*command*/, u8 /*value*/){
    return 0;
}
s32 i2c_smbus_read_word_data(int/*client*/, u8 /*command*/){
    return 0;
}
s32 i2c_smbus_write_word_data(int/*client*/,  u8 /*command*/, u16 /*value*/){
    return 0;
}

#endif

// Registers/etc.
#define  __MODE1               0x00
#define  __MODE2               0x01
#define  __SUBADR1             0x02
#define  __SUBADR2             0x03
#define  __SUBADR3             0x04
#define  __PRESCALE            0xFE
#define  __LED0_ON_L           0x06
#define  __LED0_ON_H           0x07
#define  __LED0_OFF_L          0x08
#define  __LED0_OFF_H          0x09
#define  __ALL_LED_ON_L        0xFA
#define  __ALL_LED_ON_H        0xFB
#define  __ALL_LED_OFF_L       0xFC
#define  __ALL_LED_OFF_H       0xFD

// Bits
#define __RESTART              0x80
#define __SLEEP                0x10
#define __ALLCALL              0x01
#define __INVRT                0x10
#define __OUTDRV               0x04

static RegisterMe<NodeDCMotor> registerMe("DCMotor");

unsigned char
NodeDCMotor::MotorHAT::i2c_readU8(unsigned char command) {
    // Using I2C Read, equivalent of i2c_smbus_read_byte(file)
    // if (read(file, buf, 1) != 1) {
    __s32 ret  = i2c_smbus_read_byte_data(m_file, command);
    m_trace.println("---- i2c_read returned ", ret);
    if (ret == -1) {
        m_trace.fatal("Failed i2c_read errno", errno);
    } else {
        // buf[0] contains the read byte
    }
    return ret;
}

void
NodeDCMotor::MotorHAT::i2c_write8(unsigned char command, unsigned short value) {
    // Using I2C Write, equivalent of
    // i2c_smbus_write_word_data(file, register, 0x6543)

    // unsigned char buf[10];
    // buf[0] = register;
    // buf[1] = value & 0x000000FF; // 0x43;
    // value = value >> 8;
    // buf[2] = value & 0x000000FF; // 0x65;
    // if (write(file, buf, 3) !=3) {

    __s32 ret = i2c_smbus_write_byte_data(m_file, command, value);
    m_trace.println("---- i2c_write8 Wrote", value);
    m_trace.println("to ", (int)command);
    if (ret == -1) {
        m_trace.fatal("Failed i2c_write8 errno", errno);
    }
}

void
NodeDCMotor::MotorHAT::setAllPWM(int on, int off) {
    i2c_write8(__ALL_LED_ON_L, on & 0xFF);
    i2c_write8(__ALL_LED_ON_H, on >> 8);
    i2c_write8(__ALL_LED_OFF_L, off & 0xFF);
    i2c_write8(__ALL_LED_OFF_H, off >> 8);
}

void
NodeDCMotor::MotorHAT::setPWM(int channel, int on, int off) {
    i2c_write8(__LED0_ON_L+4*channel, on & 0xFF);
    i2c_write8(__LED0_ON_H+4*channel, on >> 8);
    i2c_write8(__LED0_OFF_L+4*channel, off & 0xFF);
    i2c_write8(__LED0_OFF_H+4*channel, off >> 8);
}

void
NodeDCMotor::MotorHAT::setPWMFreq(double freq) {
    m_prescaleval = 25000000.0;   // 25MHz
    m_prescaleval /= 4096.0;      // 12-bit
    m_prescaleval /= float(freq);
    m_prescaleval -= 1.0;

    m_trace.println("Setting PWM frequency to %d Hz", freq);
    m_trace.println("Estimated pre-scale: %d", m_prescaleval);

    int prescale = (int)(m_prescaleval + 0.5);
    m_trace.println("Final pre-scale", prescale);

    int oldmode = i2c_readU8(__MODE1);
    int newmode = (oldmode & 0x7F) | __SLEEP;  // sleep
    i2c_write8(__MODE1, newmode);           // go to sleep
    i2c_write8(__PRESCALE, prescale);
    i2c_write8(__MODE1, oldmode);
    //time.sleep(0.005)
    std::chrono::milliseconds timespan(5);
    std::this_thread::sleep_for(timespan);
    i2c_write8(__MODE1, oldmode | 0x80);
}

NodeDCMotor::MotorHAT::MotorHAT(int address, const char* filename, int freq):
    m_trace("DCMotor", false),
    m_prescaleval(0),
    m_i2caddr(address),
    m_frequency(freq) {
    m_trace.println("NodeDCMotor::MotorHAT::MotorHAT");

#ifdef RPI
    if ((m_file = open(filename,O_RDWR)) < 0) {
        m_trace.fatal("Failed to open the bus errno", errno);
    }

    if (ioctl(m_file, I2C_SLAVE, m_i2caddr) < 0) {
        m_trace.fatal("Failed to acquire bus access and/or talk to slave");
    }
#else
    m_trace.println(string("Not opening") + filename);
#endif

    /* Reseting PCA9685 */
    setAllPWM(0, 0);
    i2c_smbus_write_byte_data(m_file, __MODE2, __OUTDRV);
    i2c_smbus_write_byte_data(m_file, __MODE1, __ALLCALL);
    std::chrono::milliseconds timespan(5);
    std::this_thread::sleep_for(timespan);

    int oldmode = i2c_readU8(__MODE1);
    int newmode = oldmode & ~(__SLEEP);  // reset sleep
    i2c_write8(__MODE1, newmode);
    std::this_thread::sleep_for(timespan);

    //    self.motors = [ Adafruit_DCMotor(self, m) for m in range(4) ]
    //    self.steppers = [ Adafruit_StepperMotor(self, 1), Adafruit_StepperMotor(self, 2) ]
    //    self._pwm =  PWM(addr, debug=False)

}

void
NodeDCMotor::MotorHAT::setPin(int pin, int value) {
    m_trace.println("NodeDCMotor::MotorHAT::setPin");

    if ((pin < 0) or (pin > 15)) {
        throw std::runtime_error("PWM pin must be between 0 and 15 inclusive");
    }
    if ((value != 0) and (value != 1)) {
        throw std::runtime_error("Pin value must be 0 or 1!");
    }
    if (value == 0) {
        setPWM(pin, 0, 4096);
    }
    if (value == 1) {
        setPWM(pin, 4096, 0);
    }
}

NodeDCMotor::MotorHAT* NodeDCMotor::m_pMotorHAT = nullptr;

NodeDCMotor::NodeDCMotor(Process* d, const string& /*name*/, ConfigReader::StringMap& params, TiXmlElement*):
    m_trace("NodeDCMotor", true),
    m_device(d),
    m_Ch(0),
    m_running(true) {

    if(!m_pMotorHAT) {
        m_pMotorHAT = new MotorHAT();
    }

    try {
        m_Ch = stod(params.at("Motor"));
    }
    catch (std::out_of_range) {
        m_trace.println("### param not found Ch ");
        m_Ch = 0;
    }
    int pwm;
    int in1;
    int in2;

    m_trace.println(string("Init motor ") + std::to_string(m_Ch));
    if (m_Ch == 0) {
        pwm = 8;
        in2 = 9;
        in1 = 10;
    }
    else if (m_Ch == 1) {
        pwm = 13;
        in2 = 12;
        in1 = 11;
    }
    else if (m_Ch == 2) {
        pwm = 2;
        in2 = 3;
        in1 = 4;
    }
    else if (m_Ch == 3) {
        pwm = 7;
        in2 = 6;
        in1 = 5;
    }
    else
    {
        throw std::runtime_error("MotorHAT Motor must be between 1 and 4 inclusive");
    }

    m_PWMpin = pwm;
    m_IN1pin = in1;
    m_IN2pin = in2;

}

void
NodeDCMotor::run(NodeDCMotor::MotorHAT::dir command) {
    m_trace.println("NodeDCMotor::run");
    if(m_pMotorHAT) {
        if (command == MotorHAT::FORWARD) {
            m_pMotorHAT->setPin(m_IN2pin, 0);
            m_pMotorHAT->setPin(m_IN1pin, 1);
        }
        if (command == MotorHAT::BACKWARD) {
            m_pMotorHAT->setPin(m_IN1pin, 0);
            m_pMotorHAT->setPin(m_IN2pin, 1);
        }
        if (command == MotorHAT::RELEASE) {
            m_pMotorHAT->setPin(m_IN1pin, 0);
            m_pMotorHAT->setPin(m_IN2pin, 0);
        }
    }
}

void
NodeDCMotor::setSpeed(int speed) {
    m_trace.println("NodeDCMotor::setSpeed");
    if (speed < 0) {
        speed = 0;
    }
    if (speed > 255) {
        speed = 255;
    }
    m_pMotorHAT->setPWM(m_Ch, 0, speed * 16);
}

void
NodeDCMotor::handleMessage(MessageBuf* m, const std::string& padName) {
    m_trace.println("NodeDCMotor::handleMessage");
    m_trace.println(padName);
    if(m_running && padName == "speed") {
        auto msg = new Value();
        msg->ParseFromString(m->c_str());

        assert(msg->GetTypeName() == "arro.Value");

        setSpeed(((Value*)msg)->value());

    } else if(m_running && padName == "direction") {
        auto msg = new Value();
        msg->ParseFromString(m->c_str());

        int dir = ((Value*)msg)->value();
        if(dir >= 0 && dir <= 4) {
            run((MotorHAT::dir)dir);
        }

        assert(msg->GetTypeName() == "arro.Value");

    } else if(padName == "_action") {
        auto msg = new Action();
        msg->ParseFromString(m->c_str());

        string a = msg->action();

        if(a == "_terminated") {
            m_trace.println("Received _terminated");
            m_running = false;
            // Switch off the motor
            run(MotorHAT::RELEASE);
        }

        assert(msg->GetTypeName() == "arro.Action");

    } else {
        m_trace.println(string("Message received from ") + padName);
    }
}

void
NodeDCMotor::runCycle() {
    m_trace.println("NodeDCMotor::runCycle");

}
<|endoftext|>


<commit_before>#include <v8.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <common.h>
#include <dirent.h>
#include <string.h>

v8::Handle<v8::Value> _directory(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1 || args.This()->InternalFieldCount() == 0) {
	return v8::ThrowException(v8::String::New("Invalid call format. Use 'new Directory(name)'"));
    }

    args.This()->SetInternalField(0, args[0]);
    return args.This();
}

v8::Handle<v8::Value> _create(const v8::Arguments& args) {
    v8::HandleScope handle_scope;

    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    int mode;
    if (args.Length() == 0) {
	mode = 0777;
    } else {
	mode = args[0]->Int32Value();
    }

    int result = mkdir(*name, mode);
    if (result != 0) {
	return v8::ThrowException(v8::String::New("Cannot create directory'"));
    }

    return args.This();
}

v8::Handle<v8::Value> _listfiles(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));

    DIR * dp;
    struct dirent * ep;

    v8::Handle<v8::Array> result = v8::Array::New();

    dp = opendir(*name);
    if (dp == NULL) { return v8::ThrowException(v8::String::New("Directory cannot be opened")); }
    int cnt = 0;
    while ((ep = readdir(dp))) {
	if (ep->d_type == DT_REG) {
	    result->Set(v8::Integer::New(cnt++), v8::String::New(ep->d_name));
	}
    }
    closedir(dp);
    return result;
}

v8::Handle<v8::Value> _listdirectories(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));

    DIR * dp;
    struct dirent * ep;

    v8::Handle<v8::Array> result = v8::Array::New();

    dp = opendir(*name);
    if (dp == NULL) { return v8::ThrowException(v8::String::New("Directory cannot be opened")); }
    int cnt = 0;
    while ((ep = readdir(dp))) {
	if (ep->d_type == DT_DIR) {
	    if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) {
		result->Set(v8::Integer::New(cnt++), v8::String::New(ep->d_name));
	    }
	}
    }
    closedir(dp);
    return result;
}

v8::Handle<v8::Value> _file(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1 || args.This()->InternalFieldCount() == 0) {
	return v8::ThrowException(v8::String::New("Invalid call format. Use 'new File(name)'"));
    }

    args.This()->SetInternalField(0, args[0]);
    args.This()->SetInternalField(1, v8::Boolean::New(false));
    return args.This();
}

v8::Handle<v8::Value> _open(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1) {
	return v8::ThrowException(v8::String::New("Bad argument count. Use 'file.open(mode)'"));
    }
    v8::String::Utf8Value mode(args[0]);
    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);
    if (!file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File already opened"));
    }

    FILE * f;
    f = fopen(*name, *mode);

    if (!f) {
	return v8::ThrowException(v8::String::New("Cannot open file"));
    }

    struct stat st;
    if (stat(*name, &st) == 0) {
	args.This()->SetInternalField(2, v8::Integer::New(st.st_size));
    }
    args.This()->SetInternalField(1, v8::External::New((void *)f));
    args.This()->SetInternalField(3, v8::Integer::New(0));

    return args.This();
}

v8::Handle<v8::Value> _close(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("Cannot close non-opened file"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());
    fclose(f);
    args.This()->SetInternalField(1, v8::Boolean::New(false));
    return args.This();
}

v8::Handle<v8::Value> _read(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before reading"));
    }

    long size = args.This()->GetInternalField(2)->IntegerValue();
    long pos = args.This()->GetInternalField(3)->IntegerValue();

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());

    long avail = size-pos;
    if (!avail) { return v8::Boolean::New(false); }

    if (args.Length() && args[0]->IsNumber()) {
        int len = args[0]->IntegerValue();
	if (len < avail) { avail = len; }
    }
    char buf[avail];
    fread(buf, sizeof(char), avail, f);
    pos += avail;

    args.This()->SetInternalField(3, v8::Integer::New(pos));

   if (args.Length() > 1 && args[1]->IsTrue()) {
       return char2array(buf, avail);
   } else {
       return char2string(buf, avail);
    }
}

v8::Handle<v8::Value> _rewind(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);
    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before rewinding"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());
    rewind(f);

    args.This()->SetInternalField(3, v8::Integer::New(0));
    return args.This();
}

v8::Handle<v8::Value> _write(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before writing"));
    }

    if (args.Length() < 1) {
	return v8::ThrowException(v8::String::New("Bad argument count. Use 'file.write(data)'"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());

    if (args[0]->IsArray()) {
	v8::Handle<v8::Array> arr = v8::Handle<v8::Array>::Cast(args[0]);
	int len = arr->Length();

	int max = 4096;
	int current = 0;
	char buf[max];
	for (int i=0;i<len;i++) {
    	    v8::Handle<v8::Integer> a = v8::Integer::New(arr->Get(v8::Integer::New(i))->IntegerValue());
	    buf[current++] = (char) a->Int32Value();
	    if (current == max) {
    		fwrite(buf, sizeof(char), current, f);
		current = 0;
	    }
	}
	if (current) { fwrite(buf, sizeof(char), current, f); }

    } else {
	v8::String::Utf8Value data(args[0]);

	fwrite(*data, sizeof(char), args[0]->ToString()->Utf8Length(), f);
    }

    return args.This();
}

v8::Handle<v8::Value> _remove(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (!file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be closed before deleting"));
    }

    if (!remove(*name)) {
	return v8::ThrowException(v8::String::New("Cannot remove file"));
    }

    return args.This();
}

v8::Handle<v8::Value> _getsize(const v8::Arguments& args) {
    v8::HandleScope handle_scope;

    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    struct stat st;
    if (stat(*name, &st) == 0) {
	return v8::Integer::New(st.st_size);
    } else {
	return v8::Boolean::New(false);
    }
}

v8::Handle<v8::Value> _tostring(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    return args.This()->GetInternalField(0);

}

void SetupIo(v8::Handle<v8::Object> target) {
  v8::HandleScope handle_scope;

  v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(_file);
  ft->SetClassName(v8::String::New("File"));
  v8::Handle<v8::ObjectTemplate> ot = ft->InstanceTemplate();
  ot->SetInternalFieldCount(4); /* filename, handle, size, position */

  v8::Handle<v8::ObjectTemplate> pt = ft->PrototypeTemplate();
  pt->Set("open", v8::FunctionTemplate::New(_open));
  pt->Set("read", v8::FunctionTemplate::New(_read));
  pt->Set("rewind", v8::FunctionTemplate::New(_rewind));
  pt->Set("close", v8::FunctionTemplate::New(_close));
  pt->Set("write", v8::FunctionTemplate::New(_write));
  pt->Set("remove", v8::FunctionTemplate::New(_remove));
  pt->Set("getSize", v8::FunctionTemplate::New(_getsize));
  pt->Set("toString", v8::FunctionTemplate::New(_tostring));

  target->Set(v8::String::New("File"), ft->GetFunction());

  ft = v8::FunctionTemplate::New(_directory);
  ft->SetClassName(v8::String::New("Directory"));
  ot = ft->InstanceTemplate();
  ot->SetInternalFieldCount(1); /* dirname */

  pt = ft->PrototypeTemplate();
  pt->Set("create", v8::FunctionTemplate::New(_create));
  pt->Set("listFiles", v8::FunctionTemplate::New(_listfiles));
  pt->Set("listDirectories", v8::FunctionTemplate::New(_listdirectories));
  pt->Set("toString", v8::FunctionTemplate::New(_tostring));

  target->Set(v8::String::New("Directory"), ft->GetFunction());

}
<commit_msg>File/directory removing and existance test<commit_after>#include <v8.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <common.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>

v8::Handle<v8::Value> _directory(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1 || args.This()->InternalFieldCount() == 0) {
	return v8::ThrowException(v8::String::New("Invalid call format. Use 'new Directory(name)'"));
    }

    args.This()->SetInternalField(0, args[0]);
    return args.This();
}

v8::Handle<v8::Value> _create(const v8::Arguments& args) {
    v8::HandleScope handle_scope;

    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    int mode;
    if (args.Length() == 0) {
	mode = 0777;
    } else {
	mode = args[0]->Int32Value();
    }

    int result = mkdir(*name, mode);
    if (result != 0) {
	return v8::ThrowException(v8::String::New("Cannot create directory'"));
    }

    return args.This();
}

v8::Handle<v8::Value> _listfiles(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));

    DIR * dp;
    struct dirent * ep;

    v8::Handle<v8::Array> result = v8::Array::New();

    dp = opendir(*name);
    if (dp == NULL) { return v8::ThrowException(v8::String::New("Directory cannot be opened")); }
    int cnt = 0;
    while ((ep = readdir(dp))) {
	if (ep->d_type == DT_REG) {
	    result->Set(v8::Integer::New(cnt++), v8::String::New(ep->d_name));
	}
    }
    closedir(dp);
    return result;
}

v8::Handle<v8::Value> _listdirectories(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));

    DIR * dp;
    struct dirent * ep;

    v8::Handle<v8::Array> result = v8::Array::New();

    dp = opendir(*name);
    if (dp == NULL) { return v8::ThrowException(v8::String::New("Directory cannot be opened")); }
    int cnt = 0;
    while ((ep = readdir(dp))) {
	if (ep->d_type == DT_DIR) {
	    if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) {
		result->Set(v8::Integer::New(cnt++), v8::String::New(ep->d_name));
	    }
	}
    }
    closedir(dp);
    return result;
}

v8::Handle<v8::Value> _file(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1 || args.This()->InternalFieldCount() == 0) {
	return v8::ThrowException(v8::String::New("Invalid call format. Use 'new File(name)'"));
    }

    args.This()->SetInternalField(0, args[0]);
    args.This()->SetInternalField(1, v8::Boolean::New(false));
    return args.This();
}

v8::Handle<v8::Value> _open(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    if (args.Length() < 1) {
	return v8::ThrowException(v8::String::New("Bad argument count. Use 'file.open(mode)'"));
    }
    v8::String::Utf8Value mode(args[0]);
    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);
    if (!file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File already opened"));
    }

    FILE * f;
    f = fopen(*name, *mode);

    if (!f) {
	return v8::ThrowException(v8::String::New("Cannot open file"));
    }

    struct stat st;
    if (stat(*name, &st) == 0) {
	args.This()->SetInternalField(2, v8::Integer::New(st.st_size));
    }
    args.This()->SetInternalField(1, v8::External::New((void *)f));
    args.This()->SetInternalField(3, v8::Integer::New(0));

    return args.This();
}

v8::Handle<v8::Value> _close(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("Cannot close non-opened file"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());
    fclose(f);
    args.This()->SetInternalField(1, v8::Boolean::New(false));
    return args.This();
}

v8::Handle<v8::Value> _read(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before reading"));
    }

    long size = args.This()->GetInternalField(2)->IntegerValue();
    long pos = args.This()->GetInternalField(3)->IntegerValue();

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());

    long avail = size-pos;
    if (!avail) { return v8::Boolean::New(false); }

    if (args.Length() && args[0]->IsNumber()) {
        int len = args[0]->IntegerValue();
	if (len < avail) { avail = len; }
    }
    char buf[avail];
    fread(buf, sizeof(char), avail, f);
    pos += avail;

    args.This()->SetInternalField(3, v8::Integer::New(pos));

   if (args.Length() > 1 && args[1]->IsTrue()) {
       return char2array(buf, avail);
   } else {
       return char2string(buf, avail);
    }
}

v8::Handle<v8::Value> _rewind(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);
    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before rewinding"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());
    rewind(f);

    args.This()->SetInternalField(3, v8::Integer::New(0));
    return args.This();
}

v8::Handle<v8::Value> _write(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::Handle<v8::Value> file = args.This()->GetInternalField(1);

    if (file->IsFalse()) {
	return v8::ThrowException(v8::String::New("File must be opened before writing"));
    }

    if (args.Length() < 1) {
	return v8::ThrowException(v8::String::New("Bad argument count. Use 'file.write(data)'"));
    }

    FILE * f = reinterpret_cast<FILE *>(v8::Handle<v8::External>::Cast(file)->Value());

    if (args[0]->IsArray()) {
	v8::Handle<v8::Array> arr = v8::Handle<v8::Array>::Cast(args[0]);
	int len = arr->Length();

	int max = 4096;
	int current = 0;
	char buf[max];
	for (int i=0;i<len;i++) {
    	    v8::Handle<v8::Integer> a = v8::Integer::New(arr->Get(v8::Integer::New(i))->IntegerValue());
	    buf[current++] = (char) a->Int32Value();
	    if (current == max) {
    		fwrite(buf, sizeof(char), current, f);
		current = 0;
	    }
	}
	if (current) { fwrite(buf, sizeof(char), current, f); }

    } else {
	v8::String::Utf8Value data(args[0]);

	fwrite(*data, sizeof(char), args[0]->ToString()->Utf8Length(), f);
    }

    return args.This();
}

v8::Handle<v8::Value> _remove(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));

    if (remove(*name) != 0) {
	return v8::ThrowException(v8::String::New("Cannot remove file/dir"));
    }

    return args.This();
}

v8::Handle<v8::Value> _getsize(const v8::Arguments& args) {
    v8::HandleScope handle_scope;

    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    struct stat st;
    if (stat(*name, &st) == 0) {
	return v8::Integer::New(st.st_size);
    } else {
	return v8::Boolean::New(false);
    }
}

v8::Handle<v8::Value> _tostring(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    return args.This()->GetInternalField(0);
}

v8::Handle<v8::Value> _exists(const v8::Arguments& args) {
    v8::HandleScope handle_scope;
    v8::String::Utf8Value name(args.This()->GetInternalField(0));
    int result = access(*name, F_OK);
    return v8::Boolean::New(result == 0);
}

void SetupIo(v8::Handle<v8::Object> target) {
  v8::HandleScope handle_scope;

  v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(_file);
  ft->SetClassName(v8::String::New("File"));
  v8::Handle<v8::ObjectTemplate> ot = ft->InstanceTemplate();
  ot->SetInternalFieldCount(4); /* filename, handle, size, position */

  v8::Handle<v8::ObjectTemplate> pt = ft->PrototypeTemplate();
  pt->Set("open", v8::FunctionTemplate::New(_open));
  pt->Set("read", v8::FunctionTemplate::New(_read));
  pt->Set("rewind", v8::FunctionTemplate::New(_rewind));
  pt->Set("close", v8::FunctionTemplate::New(_close));
  pt->Set("write", v8::FunctionTemplate::New(_write));
  pt->Set("remove", v8::FunctionTemplate::New(_remove));
  pt->Set("getSize", v8::FunctionTemplate::New(_getsize));
  pt->Set("toString", v8::FunctionTemplate::New(_tostring));
  pt->Set("exists", v8::FunctionTemplate::New(_exists));

  target->Set(v8::String::New("File"), ft->GetFunction());

  ft = v8::FunctionTemplate::New(_directory);
  ft->SetClassName(v8::String::New("Directory"));
  ot = ft->InstanceTemplate();
  ot->SetInternalFieldCount(1); /* dirname */

  pt = ft->PrototypeTemplate();
  pt->Set("create", v8::FunctionTemplate::New(_create));
  pt->Set("listFiles", v8::FunctionTemplate::New(_listfiles));
  pt->Set("listDirectories", v8::FunctionTemplate::New(_listdirectories));
  pt->Set("toString", v8::FunctionTemplate::New(_tostring));
  pt->Set("exists", v8::FunctionTemplate::New(_exists));
  pt->Set("remove", v8::FunctionTemplate::New(_remove));

  target->Set(v8::String::New("Directory"), ft->GetFunction());

}
<|endoftext|>


<commit_before>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "of.hh"

#undef FACTORY_CREATE_PARAMS
#undef FACTORY_CREATOR_PARAMS
#undef FACTORY_CREATOR_PARAMS2

#define FACTORY_CREATE_PARAMS std::string name, std::string params
#define FACTORY_CREATOR_PARAMS std::string params
#define FACTORY_CREATOR_PARAMS2 params

FACTORY_IMPLEMENTATION(OutputFormat)

#undef FACTORY_CREATE_PARAMS
#undef FACTORY_CREATOR_PARAMS
#undef FACTORY_CREATOR_PARAMS2
#undef __factory_h__

#include "conf.hh"
#include "log.hh"
#include "helper.hh"
#include "history_log.hh"
#include "coverage_of.hh"

OutputFormat::~OutputFormat() {}

void OutputFormat::set_model(std::string m)
{
  if (status) {
    std::string model_name;
    std::string model_param;

    split(m, model_name, model_param);

    printf("load model %s %s\n",model_name.c_str(),model_param.c_str());

    if ((model=Model::create(l,model_name,model_param)) == NULL)
      {
	errormsg="Can't create model \""+m+"\"";
	status=false;
	return;
      } else {
      if (model->status) {
	set_model(model);
      } else {
	status=false;
	errormsg="Model error "+model->errormsg;
      }
    }
  }
}

void OutputFormat::add_uc(std::string& name,
			  Coverage* c)
{
  if (status) {
    covnames.push_back(name);
    covs.push_back(c);
    c->set_model(model);
  }
}

std::string OutputFormat::handle_history(Log&l,std::string& h)
{
  if (status) {
    History* history = new History_log(l,h);
    std::vector<Coverage*> c;
    c.resize(rcovs.size());
    std::copy(rcovs.begin(),rcovs.end(),c.begin());
    Coverage_of* cov=new Coverage_of(l,c);

    testnames.push_back(h);

    history->set_coverage(cov,model);
    return format_covs();
  } else {
    return "";
  }
}

void OutputFormat::add_uc(std::string& name,
			  std::string& c)
{
  if (status) {
    std::string coverage_name;
    std::string coverage_param;
    split(c, coverage_name, coverage_param);

    Coverage* coverage = CoverageFactory::create(l,coverage_name,coverage_param);
    if (coverage == NULL) {
      errormsg="Can't create coverage";
      status=false;
    } else {
      add_uc(name,coverage);
    }
  }
}

void OutputFormat::add_report(std::string& name,
			      std::vector<std::string*>& from,
			      std::vector<std::string*>& to,
			      std::vector<std::string*>& drop)
{
  if (status) {
    reportnames.push_back(name);
    Coverage_report* c=new Coverage_report(l,from,to,drop);
    c->set_model(model);
    rcovs.push_back(c);
  }
}

void OutputFormat::add_testrun(std::string& name,
			       std::string& _model)
{
  if (status) {
    std::string model_name,model_param;
    split(_model, model_name, model_param);

    Model* model;
    if ((model=Model::create(l, model_name, model_param)) == NULL) {
      errormsg="Can't create model \""+_model+"\"";
      status=false;
    } else {
      if (model->status) {
	add_testrun(name,model);
      } else {
	status=false;
	errormsg="Model error "+model->errormsg;
      }
    }
  }
}

void OutputFormat::add_testrun(std::string& name,
			       Model* _model)
{
  if (status) {
    testruns.push_back(_model);
    testnames.push_back(name);
  }
}
<commit_msg>Fix regression in of.<commit_after>/*
 * fMBT, free Model Based Testing tool
 * Copyright (c) 2011,2012 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU Lesser General Public License,
 * version 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "of.hh"

#undef FACTORY_CREATE_PARAMS
#undef FACTORY_CREATOR_PARAMS
#undef FACTORY_CREATOR_PARAMS2

#define FACTORY_CREATE_PARAMS std::string name, std::string params
#define FACTORY_CREATOR_PARAMS std::string params
#define FACTORY_CREATOR_PARAMS2 params

FACTORY_IMPLEMENTATION(OutputFormat)

#undef FACTORY_CREATE_PARAMS
#undef FACTORY_CREATOR_PARAMS
#undef FACTORY_CREATOR_PARAMS2
#undef __factory_h__

#include "conf.hh"
#include "log.hh"
#include "helper.hh"
#include "history_log.hh"
#include "coverage_of.hh"

OutputFormat::~OutputFormat() {}

void OutputFormat::set_model(std::string m)
{
  if (status) {
    std::string model_name;
    std::string model_param;

    split(m, model_name, model_param);

    printf("load model %s %s\n",model_name.c_str(),model_param.c_str());

    if ((model=Model::create(l,model_name,model_param)) == NULL)
      {
	errormsg="Can't create model \""+m+"\"";
	status=false;
	return;
      } else {
      if (model->status) {
	set_model(model);
      } else {
	status=false;
	errormsg="Model error "+model->errormsg;
      }
    }
  }
}

void OutputFormat::add_uc(std::string& name,
			  Coverage* c)
{
  if (status) {
    covnames.push_back(name);
    covs.push_back(c);
    c->set_model(model);
  }
}

std::string OutputFormat::handle_history(Log&l,std::string& h)
{
  if (status) {
    History* history = new History_log(l,h);
    std::vector<Coverage*> c;
    c.insert(c.end(),rcovs.begin(),rcovs.end());
    c.insert(c.end(),covs.begin(),covs.end());
    Coverage_of* cov=new Coverage_of(l,c);

    testnames.push_back(h);

    history->set_coverage(cov,model);
    return format_covs();
  } else {
    return "";
  }
}

void OutputFormat::add_uc(std::string& name,
			  std::string& c)
{
  if (status) {
    std::string coverage_name;
    std::string coverage_param;
    split(c, coverage_name, coverage_param);

    Coverage* coverage = CoverageFactory::create(l,coverage_name,coverage_param);
    if (coverage == NULL) {
      errormsg="Can't create coverage";
      status=false;
    } else {
      add_uc(name,coverage);
    }
  }
}

void OutputFormat::add_report(std::string& name,
			      std::vector<std::string*>& from,
			      std::vector<std::string*>& to,
			      std::vector<std::string*>& drop)
{
  if (status) {
    reportnames.push_back(name);
    Coverage_report* c=new Coverage_report(l,from,to,drop);
    c->set_model(model);
    rcovs.push_back(c);
  }
}

void OutputFormat::add_testrun(std::string& name,
			       std::string& _model)
{
  if (status) {
    std::string model_name,model_param;
    split(_model, model_name, model_param);

    Model* model;
    if ((model=Model::create(l, model_name, model_param)) == NULL) {
      errormsg="Can't create model \""+_model+"\"";
      status=false;
    } else {
      if (model->status) {
	add_testrun(name,model);
      } else {
	status=false;
	errormsg="Model error "+model->errormsg;
      }
    }
  }
}

void OutputFormat::add_testrun(std::string& name,
			       Model* _model)
{
  if (status) {
    testruns.push_back(_model);
    testnames.push_back(name);
  }
}
<|endoftext|>


<commit_before>#include "directmessage.h"
#include "showdirectmessage.h"
#include "newdirectmessage.h"
#include "destroydirectmessage.h"

#include "../tools/datamanager.h"
#include "../users/user.h"

#include "../utils.h"

#include <QtCore/QMetaProperty>

class DirectMessage::Private : public QObject
{
    Q_OBJECT
public:
    Private(DirectMessage *parent);

    bool loading;
    QString createdAt;
    QVariantMap entities;
    QString idStr;
    QVariantMap recipient;
    QString recipientId;
    QString recipientScreenName;
    QVariantMap sender;
    QString senderId;
    QString senderScreenName;
    QString text;
    QString plainText;
    QString richText;
    QVariantList media;

    void create(const QVariantMap &parameters);
    void destroy();

private slots:
    void setLoading(bool loading);
    void idStrChanged(const QString &idStr);
    void dataChanged(const QVariant &data);

private:
    DirectMessage *q;
    QList<AbstractTwitterAction *> tasks;
};

DirectMessage::Private::Private(DirectMessage *parent)
    : QObject(parent)
    , loading(false)
    , q(parent)
{
    connect(q, SIGNAL(idStrChanged(QString)), this, SLOT(idStrChanged(QString)));
}

void DirectMessage::Private::setLoading(bool l)
{
    if (loading == l) return;
    loading = l;
    emit q->loadingChanged(l);
}

void DirectMessage::Private::idStrChanged(const QString &id)
{
    createdAt.clear();
    entities.clear();
    recipient.clear();
    recipientId.clear();
    recipientScreenName.clear();
    sender.clear();
    senderId.clear();
    senderScreenName.clear();
    text.clear();
    plainText.clear();
    richText.clear();
    media.clear();
    if (id.isEmpty()) {
    } else {
        ShowDirectMessage *action = new ShowDirectMessage(this);
        action->setId(id);
        connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
        if (loading) {
            tasks.append(action);
        } else {
            setLoading(true);
            action->exec();
        }
    }
}

void DirectMessage::Private::create(const QVariantMap &parameters)
{
    NewDirectMessage *action = new NewDirectMessage(this);
    action->setUserId(parameters.value("user_id").toString());
    action->setText(parameters.value("text").toString());
    connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
    if (loading) {
        tasks.append(action);
    } else {
       setLoading(true);
       action->exec();
    }
}

void DirectMessage::Private::destroy()
{
    DestroyDirectMessage *action = new DestroyDirectMessage(this);
    action->setId(idStr);
    action->setIncludeEntities(true);
    connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
    if (loading) {
        tasks.append(action);
    } else {
       setLoading(true);
       action->exec();
    }
}

void DirectMessage::Private::dataChanged(const QVariant &data)
{
    if (qobject_cast<DestroyDirectMessage *>(QObject::sender())) {
        DEBUG() << data;
        q->setIdStr(QString());
        emit q->dataChanged();
        qDeleteAll(tasks);
        tasks.clear();
        setLoading(false);
    }
    AbstractTwitterAction *action = qobject_cast<AbstractTwitterAction *>(QObject::sender());
    if (action) {
        QVariantMap directMessage = DirectMessage::parse(data.toMap());
        const QMetaObject *mo = q->metaObject();
        for (int i = 0; i < mo->propertyCount(); i++) {
            QMetaProperty prop = mo->property(i);
            if (!prop.isDesignable()) continue;
            const char *key = prop.name();
            if (directMessage.contains(key)) {
                q->setProperty(key, directMessage.value(key));
            } else {
                q->setProperty(key, QVariant());
            }
        }
        DataManager::instance()->addData(DataManager::DirectMessageData, q->idStr(), directMessage);
        emit q->dataChanged();
        action->deleteLater();
    }
    if (tasks.isEmpty()) {
        setLoading(false);
    } else {
        tasks.takeFirst()->exec();
    }
}

DirectMessage::DirectMessage(QObject *parent)
    : QObject(parent)
    , d(new Private(this))
{
}

void DirectMessage::newDirectMessage(QVariantMap parameters)
{
    d->create(parameters);
}

void DirectMessage::destroyDirectMessage()
{
    d->destroy();
}

bool DirectMessage::loading() const
{
    return d->loading;
}

const QString &DirectMessage::createdAt() const
{
    return d->createdAt;
}

void DirectMessage::setCreatedAt(const QString &createdAt)
{
    if (d->createdAt == createdAt) return;
    d->createdAt = createdAt;
    emit createdAtChanged(createdAt);
}

const QVariantMap &DirectMessage::entities() const
{
    return d->entities;
}

void DirectMessage::setEntities(const QVariantMap &entities)
{
    if (d->entities == entities) return;
    d->entities = entities;
    emit entitiesChanged(entities);
}

const QString &DirectMessage::idStr() const
{
    return d->idStr;
}

void DirectMessage::setIdStr(const QString &idStr)
{
    if (d->idStr == idStr) return;
    d->idStr = idStr;
    emit idStrChanged(idStr);
}

const QVariantMap &DirectMessage::recipient() const
{
    return d->recipient;
}

void DirectMessage::setRecipient(const QVariantMap &recipient)
{
    if (d->recipient == recipient) return;
    d->recipient = recipient;
    emit recipientChanged(recipient);
}

const QString &DirectMessage::recipientId() const
{
    return d->recipientId;
}

void DirectMessage::setRecipientId(const QString &recipientId)
{
    if (d->recipientId == recipientId) return;
    d->recipientId = recipientId;
    emit recipientIdChanged(recipientId);
}

const QString &DirectMessage::recipientScreenName() const
{
    return d->recipientScreenName;
}

void DirectMessage::setRecipientScreenName(const QString &recipientScreenName)
{
    if (d->recipientScreenName == recipientScreenName) return;
    d->recipientScreenName = recipientScreenName;
    emit recipientScreenNameChanged(recipientScreenName);
}

const QVariantMap &DirectMessage::sender() const
{
    return d->sender;
}

void DirectMessage::setSender(const QVariantMap &sender)
{
    if (d->sender == sender) return;
    d->sender = sender;
    emit senderChanged(sender);
}

const QString &DirectMessage::senderId() const
{
    return d->senderId;
}

void DirectMessage::setSenderId(const QString &senderId)
{
    if (d->senderId == senderId) return;
    d->senderId = senderId;
    emit senderIdChanged(senderId);
}

const QString &DirectMessage::senderScreenName() const
{
    return d->senderScreenName;
}

void DirectMessage::setSenderScreenName(const QString &senderScreenName)
{
    if (d->senderScreenName == senderScreenName) return;
    d->senderScreenName = senderScreenName;
    emit senderScreenNameChanged(senderScreenName);
}

const QString &DirectMessage::text() const
{
    return d->text;
}

void DirectMessage::setText(const QString &text)
{
    if (d->text == text) return;
    d->text = text;
    emit textChanged(text);
}

const QString &DirectMessage::plainText() const
{
    return d->plainText;
}

void DirectMessage::setPlainText(const QString &plainText)
{
    if (d->plainText == plainText) return;
    d->plainText = plainText;
    emit plainTextChanged(plainText);
}

const QString &DirectMessage::richText() const
{
    return d->richText;
}

void DirectMessage::setRichText(const QString &richText)
{
    if (d->richText == richText) return;
    d->richText = richText;
    emit richTextChanged(richText);
}

const QVariantList &DirectMessage::media() const
{
    return d->media;
}

void DirectMessage::setMedia(const QVariantList &media)
{
    if (d->media == media) return;
    d->media = media;
    emit mediaChanged(media);
}

QVariantMap DirectMessage::data() const
{
    QVariantMap ret;
    const QMetaObject *mo = metaObject();
    for (int i = 0; i < mo->propertyCount(); i++) {
        QMetaProperty prop = mo->property(i);
        if (!prop.isDesignable()) continue;
        const char *key = prop.name();
        ret.insert(key, property(key));
    }
    return ret;
}

bool DirectMessage::indicesGreaterThan(const QVariant &v1, const QVariant &v2)
{
    return v1.toMap().value("indices").toList().first().toInt() > v2.toMap().value("indices").toList().first().toInt();
}

void DirectMessage::debug() const
{
    const QMetaObject *mo = metaObject();
    for (int i = 0; i < mo->propertyCount(); i++) {
        QMetaProperty prop = mo->property(i);
        if (!prop.isDesignable()) continue;
        const char *key = prop.name();
        DEBUG() << key << property(key);
    }
}

QVariantMap DirectMessage::parse(const QVariantMap &directMessage)
{
    QVariantMap ret = directMessage;

    ret.insert("recipient", User::parse(ret.value("recipient").toMap()));
    ret.insert("sender", User::parse(ret.value("sender").toMap()));

    QString text = ret.value("text").toString();
    if (ret.contains("entities") && !ret.value("entities").isNull()) {
        QString plainText = text;
        QString richText = text.replace(" ", "\t");
        QVariantList entitiesSortedByIndices;
        QVariantMap entities = ret.value("entities").toMap();
        foreach (const QString &key, entities.keys()) {
            QVariant entity = entities.value(key);
            if (entity.type() == QVariant::List) {
                QVariantList e = entity.toList();
                foreach (const QVariant &ee, e) {
                    QVariantMap eee = ee.toMap();
                    eee.insert("type", key);
                    entitiesSortedByIndices.append(eee);
                }
            } else {
                DEBUG() << entity;
            }
        }
        qSort(entitiesSortedByIndices.begin(), entitiesSortedByIndices.end(), &DirectMessage::indicesGreaterThan);
        QVariantList media;
        foreach (const QVariant &item, entitiesSortedByIndices) {
            QVariantMap entity = item.toMap();
            QVariantList indices = entity.value("indices").toList();
            int start = indices.first().toInt();
            int end = indices.last().toInt();
            QString type = entity.value("type").toString();
            QString plainTextAfter;
            QString richTextAfter;
            if (type == "urls") {
                if (entity.contains("display_url")) {
                    plainTextAfter = entity.value("display_url").toString();
                    richTextAfter = QString("%3")
                            .arg(entity.value("expanded_url").toString())
                            .arg(entity.value("url").toString())
                            .arg(entity.value("display_url").toString());
                } else {
                    plainTextAfter = entity.value("url").toString();
                    richTextAfter = QString("%1")
                            .arg(entity.value("url").toString());
                }
            } else if (type == "user_mentions") {
                richTextAfter = QString("@%2")
                        .arg(entity.value("id_str").toString())
                        .arg(entity.value("screen_name").toString());
            } else if (type == "hashtags") {
                richTextAfter = QString("#%2")
                        .arg(entity.value("text").toString())
                        .arg(entity.value("text").toString());
            } else if (type == "media") {
                plainTextAfter = entity.value("display_url").toString();
                richTextAfter = QString("%3")
                        .arg(entity.value("media_url").toString())
                        .arg(entity.value("url").toString())
                        .arg(entity.value("display_url").toString());
                media.append(entity.value("media_url"));
            } else {
                DEBUG() << type << item;
            }
            if (!plainTextAfter.isNull())
                plainText.replace(start, end - start, plainTextAfter);
            if (!richTextAfter.isNull())
                richText.replace(start, end - start, richTextAfter);
        }
        ret.insert("plain_text", escapeHtml(plainText));
        ret.insert("rich_text", richText.replace("\n", "
").replace("\t", " ").replace(QString::fromUtf8("　"), "    "));
        ret.insert("media", media);
    } else {
        DEBUG() << text;
        if (!ret.contains("plain_text"))
            ret.insert("plain_text", escapeHtml(text));
        if (!ret.contains("rich_text"))
            ret.insert("rich_text", text.replace(" ", " ").replace("\n", "
").replace(QString::fromUtf8("　"), "    "));
    }
    return ret;
}

#include "directmessage.moc"
<commit_msg>typo: user handling in dm<commit_after>#include "directmessage.h"
#include "showdirectmessage.h"
#include "newdirectmessage.h"
#include "destroydirectmessage.h"

#include "../tools/datamanager.h"
#include "../users/user.h"

#include "../utils.h"

#include <QtCore/QMetaProperty>

class DirectMessage::Private : public QObject
{
    Q_OBJECT
public:
    Private(DirectMessage *parent);

    bool loading;
    QString createdAt;
    QVariantMap entities;
    QString idStr;
    QVariantMap recipient;
    QString recipientId;
    QString recipientScreenName;
    QVariantMap sender;
    QString senderId;
    QString senderScreenName;
    QString text;
    QString plainText;
    QString richText;
    QVariantList media;

    void create(const QVariantMap &parameters);
    void destroy();

private slots:
    void setLoading(bool loading);
    void idStrChanged(const QString &idStr);
    void dataChanged(const QVariant &data);

private:
    DirectMessage *q;
    QList<AbstractTwitterAction *> tasks;
};

DirectMessage::Private::Private(DirectMessage *parent)
    : QObject(parent)
    , loading(false)
    , q(parent)
{
    connect(q, SIGNAL(idStrChanged(QString)), this, SLOT(idStrChanged(QString)));
}

void DirectMessage::Private::setLoading(bool l)
{
    if (loading == l) return;
    loading = l;
    emit q->loadingChanged(l);
}

void DirectMessage::Private::idStrChanged(const QString &id)
{
    createdAt.clear();
    entities.clear();
    recipient.clear();
    recipientId.clear();
    recipientScreenName.clear();
    sender.clear();
    senderId.clear();
    senderScreenName.clear();
    text.clear();
    plainText.clear();
    richText.clear();
    media.clear();
    if (id.isEmpty()) {
    } else {
        ShowDirectMessage *action = new ShowDirectMessage(this);
        action->setId(id);
        connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
        if (loading) {
            tasks.append(action);
        } else {
            setLoading(true);
            action->exec();
        }
    }
}

void DirectMessage::Private::create(const QVariantMap &parameters)
{
    NewDirectMessage *action = new NewDirectMessage(this);
    action->setUserId(parameters.value("user_id").toString());
    action->setText(parameters.value("text").toString());
    connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
    if (loading) {
        tasks.append(action);
    } else {
       setLoading(true);
       action->exec();
    }
}

void DirectMessage::Private::destroy()
{
    DestroyDirectMessage *action = new DestroyDirectMessage(this);
    action->setId(idStr);
    action->setIncludeEntities(true);
    connect(action, SIGNAL(dataChanged(QVariant)), this, SLOT(dataChanged(QVariant)));
    if (loading) {
        tasks.append(action);
    } else {
       setLoading(true);
       action->exec();
    }
}

void DirectMessage::Private::dataChanged(const QVariant &data)
{
    if (qobject_cast<DestroyDirectMessage *>(QObject::sender())) {
        DEBUG() << data;
        q->setIdStr(QString());
        emit q->dataChanged();
        qDeleteAll(tasks);
        tasks.clear();
        setLoading(false);
    }
    AbstractTwitterAction *action = qobject_cast<AbstractTwitterAction *>(QObject::sender());
    if (action) {
        QVariantMap directMessage = DirectMessage::parse(data.toMap());
        const QMetaObject *mo = q->metaObject();
        for (int i = 0; i < mo->propertyCount(); i++) {
            QMetaProperty prop = mo->property(i);
            if (!prop.isDesignable()) continue;
            const char *key = prop.name();
            if (directMessage.contains(key)) {
                q->setProperty(key, directMessage.value(key));
            } else {
                q->setProperty(key, QVariant());
            }
        }
        DataManager::instance()->addData(DataManager::DirectMessageData, q->idStr(), directMessage);
        emit q->dataChanged();
        action->deleteLater();
    }
    if (tasks.isEmpty()) {
        setLoading(false);
    } else {
        tasks.takeFirst()->exec();
    }
}

DirectMessage::DirectMessage(QObject *parent)
    : QObject(parent)
    , d(new Private(this))
{
}

void DirectMessage::newDirectMessage(QVariantMap parameters)
{
    d->create(parameters);
}

void DirectMessage::destroyDirectMessage()
{
    d->destroy();
}

bool DirectMessage::loading() const
{
    return d->loading;
}

const QString &DirectMessage::createdAt() const
{
    return d->createdAt;
}

void DirectMessage::setCreatedAt(const QString &createdAt)
{
    if (d->createdAt == createdAt) return;
    d->createdAt = createdAt;
    emit createdAtChanged(createdAt);
}

const QVariantMap &DirectMessage::entities() const
{
    return d->entities;
}

void DirectMessage::setEntities(const QVariantMap &entities)
{
    if (d->entities == entities) return;
    d->entities = entities;
    emit entitiesChanged(entities);
}

const QString &DirectMessage::idStr() const
{
    return d->idStr;
}

void DirectMessage::setIdStr(const QString &idStr)
{
    if (d->idStr == idStr) return;
    d->idStr = idStr;
    emit idStrChanged(idStr);
}

const QVariantMap &DirectMessage::recipient() const
{
    return d->recipient;
}

void DirectMessage::setRecipient(const QVariantMap &recipient)
{
    if (d->recipient == recipient) return;
    d->recipient = recipient;
    emit recipientChanged(recipient);
}

const QString &DirectMessage::recipientId() const
{
    return d->recipientId;
}

void DirectMessage::setRecipientId(const QString &recipientId)
{
    if (d->recipientId == recipientId) return;
    d->recipientId = recipientId;
    emit recipientIdChanged(recipientId);
}

const QString &DirectMessage::recipientScreenName() const
{
    return d->recipientScreenName;
}

void DirectMessage::setRecipientScreenName(const QString &recipientScreenName)
{
    if (d->recipientScreenName == recipientScreenName) return;
    d->recipientScreenName = recipientScreenName;
    emit recipientScreenNameChanged(recipientScreenName);
}

const QVariantMap &DirectMessage::sender() const
{
    return d->sender;
}

void DirectMessage::setSender(const QVariantMap &sender)
{
    if (d->sender == sender) return;
    d->sender = sender;
    emit senderChanged(sender);
}

const QString &DirectMessage::senderId() const
{
    return d->senderId;
}

void DirectMessage::setSenderId(const QString &senderId)
{
    if (d->senderId == senderId) return;
    d->senderId = senderId;
    emit senderIdChanged(senderId);
}

const QString &DirectMessage::senderScreenName() const
{
    return d->senderScreenName;
}

void DirectMessage::setSenderScreenName(const QString &senderScreenName)
{
    if (d->senderScreenName == senderScreenName) return;
    d->senderScreenName = senderScreenName;
    emit senderScreenNameChanged(senderScreenName);
}

const QString &DirectMessage::text() const
{
    return d->text;
}

void DirectMessage::setText(const QString &text)
{
    if (d->text == text) return;
    d->text = text;
    emit textChanged(text);
}

const QString &DirectMessage::plainText() const
{
    return d->plainText;
}

void DirectMessage::setPlainText(const QString &plainText)
{
    if (d->plainText == plainText) return;
    d->plainText = plainText;
    emit plainTextChanged(plainText);
}

const QString &DirectMessage::richText() const
{
    return d->richText;
}

void DirectMessage::setRichText(const QString &richText)
{
    if (d->richText == richText) return;
    d->richText = richText;
    emit richTextChanged(richText);
}

const QVariantList &DirectMessage::media() const
{
    return d->media;
}

void DirectMessage::setMedia(const QVariantList &media)
{
    if (d->media == media) return;
    d->media = media;
    emit mediaChanged(media);
}

QVariantMap DirectMessage::data() const
{
    QVariantMap ret;
    const QMetaObject *mo = metaObject();
    for (int i = 0; i < mo->propertyCount(); i++) {
        QMetaProperty prop = mo->property(i);
        if (!prop.isDesignable()) continue;
        const char *key = prop.name();
        ret.insert(key, property(key));
    }
    return ret;
}

bool DirectMessage::indicesGreaterThan(const QVariant &v1, const QVariant &v2)
{
    return v1.toMap().value("indices").toList().first().toInt() > v2.toMap().value("indices").toList().first().toInt();
}

void DirectMessage::debug() const
{
    const QMetaObject *mo = metaObject();
    for (int i = 0; i < mo->propertyCount(); i++) {
        QMetaProperty prop = mo->property(i);
        if (!prop.isDesignable()) continue;
        const char *key = prop.name();
        DEBUG() << key << property(key);
    }
}

QVariantMap DirectMessage::parse(const QVariantMap &directMessage)
{
    QVariantMap ret = directMessage;

    ret.insert("recipient", User::parse(ret.value("recipient").toMap()));
    ret.insert("sender", User::parse(ret.value("sender").toMap()));

    QString text = ret.value("text").toString();
    if (ret.contains("entities") && !ret.value("entities").isNull()) {
        QString plainText = text;
        QString richText = text.replace(" ", "\t");
        QVariantList entitiesSortedByIndices;
        QVariantMap entities = ret.value("entities").toMap();
        foreach (const QString &key, entities.keys()) {
            QVariant entity = entities.value(key);
            if (entity.type() == QVariant::List) {
                QVariantList e = entity.toList();
                foreach (const QVariant &ee, e) {
                    QVariantMap eee = ee.toMap();
                    eee.insert("type", key);
                    entitiesSortedByIndices.append(eee);
                }
            } else {
                DEBUG() << entity;
            }
        }
        qSort(entitiesSortedByIndices.begin(), entitiesSortedByIndices.end(), &DirectMessage::indicesGreaterThan);
        QVariantList media;
        foreach (const QVariant &item, entitiesSortedByIndices) {
            QVariantMap entity = item.toMap();
            QVariantList indices = entity.value("indices").toList();
            int start = indices.first().toInt();
            int end = indices.last().toInt();
            QString type = entity.value("type").toString();
            QString plainTextAfter;
            QString richTextAfter;
            if (type == "urls") {
                if (entity.contains("display_url")) {
                    plainTextAfter = entity.value("display_url").toString();
                    richTextAfter = QString("%3")
                            .arg(entity.value("expanded_url").toString())
                            .arg(entity.value("url").toString())
                            .arg(entity.value("display_url").toString());
                } else {
                    plainTextAfter = entity.value("url").toString();
                    richTextAfter = QString("%1")
                            .arg(entity.value("url").toString());
                }
            } else if (type == "user_mentions") {
                richTextAfter = QString("@%2")
                        .arg(entity.value("id_str").toString())
                        .arg(entity.value("screen_name").toString());
            } else if (type == "hashtags") {
                richTextAfter = QString("#%2")
                        .arg(entity.value("text").toString())
                        .arg(entity.value("text").toString());
            } else if (type == "media") {
                plainTextAfter = entity.value("display_url").toString();
                richTextAfter = QString("%3")
                        .arg(entity.value("media_url").toString())
                        .arg(entity.value("url").toString())
                        .arg(entity.value("display_url").toString());
                media.append(entity.value("media_url"));
            } else {
                DEBUG() << type << item;
            }
            if (!plainTextAfter.isNull())
                plainText.replace(start, end - start, plainTextAfter);
            if (!richTextAfter.isNull())
                richText.replace(start, end - start, richTextAfter);
        }
        ret.insert("plain_text", escapeHtml(plainText));
        ret.insert("rich_text", richText.replace("\n", "
").replace("\t", " ").replace(QString::fromUtf8("　"), "    "));
        ret.insert("media", media);
    } else {
        DEBUG() << text;
        if (!ret.contains("plain_text"))
            ret.insert("plain_text", escapeHtml(text));
        if (!ret.contains("rich_text"))
            ret.insert("rich_text", text.replace(" ", " ").replace("\n", "
").replace(QString::fromUtf8("　"), "    "));
    }
    return ret;
}

#include "directmessage.moc"
<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2017 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file SDP3X.hpp
 *
 * Driver for Sensirion SDP3X Differential Pressure Sensor
 *
 * Datasheet: https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Sensirion_Differential_Pressure_Sensors_SDP3x_Digital_Datasheet_V0.8.pdf
 */

#ifndef DRIVERS_SDP3X_AIRSPEED_HPP_
#define DRIVERS_SDP3X_AIRSPEED_HPP_

#include <drivers/airspeed/airspeed.h>
#include <drivers/device/i2c.h>
#include <drivers/drv_airspeed.h>
#include <math.h>
#include <mathlib/math/filter/LowPassFilter2p.hpp>
#include <px4_config.h>
#include <sys/types.h>
#include <systemlib/airspeed.h>
#include <systemlib/perf_counter.h>
#include <uORB/topics/differential_pressure.h>
#include <uORB/uORB.h>

#define I2C_ADDRESS_1_SDP3X		0x21
#define I2C_ADDRESS_2_SDP3X		0x22
#define I2C_ADDRESS_3_SDP3X		0x23

#define SDP3X_SCALE_TEMPERATURE		200.0f
#define SDP3X_RESET_ADDR		0x00
#define SDP3X_RESET_CMD			0x06
#define SDP3X_CONT_MEAS_AVG_MODE	0x3615

#define SDP3X_SCALE_PRESSURE_SDP31	20
#define SDP3X_SCALE_PRESSURE_SDP32	5
#define SDP3X_SCALE_PRESSURE_SDP33	60

#define PATH_SDP3X "/dev/sdp3x"

// Measurement rate is 20Hz
#define SPD3X_MEAS_RATE 100
#define SDP3X_MEAS_DRIVER_FILTER_FREQ 3.0f
#define CONVERSION_INTERVAL	(1000000 / SPD3X_MEAS_RATE)	/* microseconds */

class SDP3X : public Airspeed
{
public:
	SDP3X(int bus, int address = I2C_ADDRESS_1_SDP3X, const char *path = PATH_SDP3X) :
		Airspeed(bus, address, CONVERSION_INTERVAL, path)
	{
	}

private:

	/**
	 * Perform a poll cycle; collect from the previous measurement
	 * and start a new one.
	 */
	void	cycle() override;
	int	measure() override { return 0; }
	int	collect() override;
	int	probe() override;

	math::LowPassFilter2p _filter{SPD3X_MEAS_RATE, SDP3X_MEAS_DRIVER_FILTER_FREQ};

	bool init_sdp3x();

	/**
	 * Calculate the CRC8 for the sensor payload data
	 */
	bool crc(const uint8_t data[], unsigned size, uint8_t checksum);

	/**
	 * Write a command in Sensirion specific logic
	 */
	int write_command(uint16_t command);

	uint16_t _scale{0};
};

#endif /* DRIVERS_SDP3X_AIRSPEED_HPP_ */
<commit_msg>define SDP3X_SCALE_PRESSURE_SDP3X corrected<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2017 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file SDP3X.hpp
 *
 * Driver for Sensirion SDP3X Differential Pressure Sensor
 *
 * Datasheet: https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Sensirion_Differential_Pressure_Sensors_SDP3x_Digital_Datasheet_V0.8.pdf
 */

#ifndef DRIVERS_SDP3X_AIRSPEED_HPP_
#define DRIVERS_SDP3X_AIRSPEED_HPP_

#include <drivers/airspeed/airspeed.h>
#include <drivers/device/i2c.h>
#include <drivers/drv_airspeed.h>
#include <math.h>
#include <mathlib/math/filter/LowPassFilter2p.hpp>
#include <px4_config.h>
#include <sys/types.h>
#include <systemlib/airspeed.h>
#include <systemlib/perf_counter.h>
#include <uORB/topics/differential_pressure.h>
#include <uORB/uORB.h>

#define I2C_ADDRESS_1_SDP3X		0x21
#define I2C_ADDRESS_2_SDP3X		0x22
#define I2C_ADDRESS_3_SDP3X		0x23

#define SDP3X_SCALE_TEMPERATURE		200.0f
#define SDP3X_RESET_ADDR		0x00
#define SDP3X_RESET_CMD			0x06
#define SDP3X_CONT_MEAS_AVG_MODE	0x3615

#define SDP3X_SCALE_PRESSURE_SDP31	60
#define SDP3X_SCALE_PRESSURE_SDP32	240
#define SDP3X_SCALE_PRESSURE_SDP33	20

#define PATH_SDP3X "/dev/sdp3x"

// Measurement rate is 20Hz
#define SPD3X_MEAS_RATE 100
#define SDP3X_MEAS_DRIVER_FILTER_FREQ 3.0f
#define CONVERSION_INTERVAL	(1000000 / SPD3X_MEAS_RATE)	/* microseconds */

class SDP3X : public Airspeed
{
public:
	SDP3X(int bus, int address = I2C_ADDRESS_1_SDP3X, const char *path = PATH_SDP3X) :
		Airspeed(bus, address, CONVERSION_INTERVAL, path)
	{
	}

private:

	/**
	 * Perform a poll cycle; collect from the previous measurement
	 * and start a new one.
	 */
	void	cycle() override;
	int	measure() override { return 0; }
	int	collect() override;
	int	probe() override;

	math::LowPassFilter2p _filter{SPD3X_MEAS_RATE, SDP3X_MEAS_DRIVER_FILTER_FREQ};

	bool init_sdp3x();

	/**
	 * Calculate the CRC8 for the sensor payload data
	 */
	bool crc(const uint8_t data[], unsigned size, uint8_t checksum);

	/**
	 * Write a command in Sensirion specific logic
	 */
	int write_command(uint16_t command);

	uint16_t _scale{0};
};

#endif /* DRIVERS_SDP3X_AIRSPEED_HPP_ */
<|endoftext|>


<commit_before>#ifndef __EXTENSION_FIXED_POINT_RECYCLING_HPP
#define __EXTENSION_FIXED_POINT_RECYCLING_HPP

#include "gr1context.hpp"

/**
 * Modifies the realizability checking part to recycle the innermost fixed points
 * whenever possible during the game solving process.
 *
 * The idea is from the paper "An improved algorithm for the evaluation of fixpoint expressions"
 * by A. Browne, E.M. Clarke, S. Jha, D.E. Long, and W. Marrerob
 *
 */
template<class T> class XFixedPointRecycling : public T {
protected:

    // Inherited stuff used
    using T::mgr;
    using T::strategyDumpingData;
    using T::livenessGuarantees;
    using T::livenessAssumptions;
    using T::varVectorPre;
    using T::varVectorPost;
    using T::varCubePostOutput;
    using T::varCubePostInput;
    using T::safetyEnv;
    using T::safetySys;
    using T::winningPositions;

    // Constructor
    XFixedPointRecycling<T>(std::list<std::string> &filenames) : T(filenames) {}

    // Modified synthesis function
    void computeWinningPositions() {

        // The greatest fixed point - called "Z" in the GR(1) synthesis paper
        BFFixedPoint nu2(mgr.constantTrue());

        BF recyclingInnermostFixedPoints[livenessGuarantees.size()][livenessAssumptions.size()];
        bool firstOutermost = true;

        // Iterate until we have found a fixed point
        for (;!nu2.isFixedPointReached();) {

            // To extract a strategy in case of realizability, we need to store a sequence of 'preferred' transitions in the
            // game structure. These preferred transitions only need to be computed during the last execution of the outermost
            // greatest fixed point. Since we don't know which one is the last one, we store them in every iteration,
            // so that after the last iteration, we obtained the necessary data. Before any new iteration, we need to
            // clear the old data, though.
            strategyDumpingData.clear();

            // Iterate over all of the liveness guarantees. Put the results into the variable 'nextContraintsForGoals' for every
            // goal. Then, after we have iterated over the goals, we can update nu2.
            BF nextContraintsForGoals = mgr.constantTrue();
            for (unsigned int j=0;j<livenessGuarantees.size();j++) {

                // Start computing the transitions that lead closer to the goal and lead to a position that is not yet known to be losing.
                // Start with the ones that actually represent reaching the goal (which is a transition in this implementation as we can have
                // nexts in the goal descriptions).
                BF livetransitions = livenessGuarantees[j] & (nu2.getValue().SwapVariables(varVectorPre,varVectorPost));

                // Compute the middle least-fixed point (called 'Y' in the GR(1) paper)
                BFFixedPoint mu1(mgr.constantFalse());

                bool firstMiddle = true;

                for (;!mu1.isFixedPointReached();) {

                    // Update the set of transitions that lead closer to the goal.
                    livetransitions |= mu1.getValue().SwapVariables(varVectorPre,varVectorPost);

                    // Iterate over the liveness assumptions. Store the positions that are found to be winning for *any*
                    // of them into the variable 'goodForAnyLivenessAssumption'.
                    BF goodForAnyLivenessAssumption = mu1.getValue();
                    for (unsigned int i=0;i<livenessAssumptions.size();i++) {

                        // Prepare the variable 'foundPaths' that contains the transitions that stay within the inner-most
                        // greatest fixed point or get closer to the goal. Only used for strategy extraction
                        BF foundPaths = mgr.constantTrue();

                        // Inner-most greatest fixed point. The corresponding variable in the paper would be 'X'.
                        BFFixedPoint nu0((firstMiddle && (!firstOutermost))?recyclingInnermostFixedPoints[j][i] & nu2.getValue():nu2.getValue());
                        for (;!nu0.isFixedPointReached();) {

                            // Compute a set of paths that are safe to take - used for the enforceable predecessor operator ('cox')
                            foundPaths = livetransitions | (nu0.getValue().SwapVariables(varVectorPre,varVectorPost) & !(livenessAssumptions[i]));
                            foundPaths &= safetySys;

                            // Update the inner-most fixed point with the result of applying the enforcable predecessor operator
                            nu0.update(safetyEnv.Implies(foundPaths).ExistAbstract(varCubePostOutput).UnivAbstract(varCubePostInput));
                        }

                        // Update the set of positions that are winning for some liveness assumption
                        goodForAnyLivenessAssumption |= nu0.getValue();

                        recyclingInnermostFixedPoints[j][i] = nu0.getValue();

                        // Dump the paths that we just wound into 'strategyDumpingData' - store the current goal long
                        // with the BDD
                        strategyDumpingData.push_back(std::pair<unsigned int,BF>(j,foundPaths));
                    }

                    // Update the moddle fixed point
                    mu1.update(goodForAnyLivenessAssumption);

                    firstMiddle = false;
                }

                // Update the set of positions that are winning for any goal for the outermost fixed point
                nextContraintsForGoals &= mu1.getValue();
            }

            // Update the outer-most fixed point
            nu2.update(nextContraintsForGoals);
            firstOutermost = false;

        }

        // We found the set of winning positions
        winningPositions = nu2.getValue();
    }

public:
    static GR1Context* makeInstance(std::list<std::string> &filenames) {
        return new XFixedPointRecycling<T>(filenames);
    }
};

#endif

<commit_msg>variable length arrays don't work with all gcc compilers, so changing these to vectors<commit_after>#ifndef __EXTENSION_FIXED_POINT_RECYCLING_HPP
#define __EXTENSION_FIXED_POINT_RECYCLING_HPP

#include "gr1context.hpp"

/**
 * Modifies the realizability checking part to recycle the innermost fixed points
 * whenever possible during the game solving process.
 *
 * The idea is from the paper "An improved algorithm for the evaluation of fixpoint expressions"
 * by A. Browne, E.M. Clarke, S. Jha, D.E. Long, and W. Marrerob
 *
 */
template<class T> class XFixedPointRecycling : public T {
protected:

    // Inherited stuff used
    using T::mgr;
    using T::strategyDumpingData;
    using T::livenessGuarantees;
    using T::livenessAssumptions;
    using T::varVectorPre;
    using T::varVectorPost;
    using T::varCubePostOutput;
    using T::varCubePostInput;
    using T::safetyEnv;
    using T::safetySys;
    using T::winningPositions;

    // Constructor
    XFixedPointRecycling<T>(std::list<std::string> &filenames) : T(filenames) {}

    // Modified synthesis function
    void computeWinningPositions() {

        // The greatest fixed point - called "Z" in the GR(1) synthesis paper
        BFFixedPoint nu2(mgr.constantTrue());

        //std::vector<std::vector<BF>> recyclingInnermostFixedPoints;
        //
        //std::vector<std::vector<BF>> recyclingInnermostFixedPoints[livenessGuarantees.size()][livenessAssumptions.size()];
        unsigned int m = livenessAssumptions.size();
        unsigned int n = livenessGuarantees.size();
        std::vector<std::vector<BF>> recyclingInnermostFixedPoints(n);
        for (unsigned int i = 0; i < n; i++) {
            recyclingInnermostFixedPoints[i].resize(m);
        }

        bool firstOutermost = true;

        // Iterate until we have found a fixed point
        for (;!nu2.isFixedPointReached();) {

            // To extract a strategy in case of realizability, we need to store a sequence of 'preferred' transitions in the
            // game structure. These preferred transitions only need to be computed during the last execution of the outermost
            // greatest fixed point. Since we don't know which one is the last one, we store them in every iteration,
            // so that after the last iteration, we obtained the necessary data. Before any new iteration, we need to
            // clear the old data, though.
            strategyDumpingData.clear();

            // Iterate over all of the liveness guarantees. Put the results into the variable 'nextContraintsForGoals' for every
            // goal. Then, after we have iterated over the goals, we can update nu2.
            BF nextContraintsForGoals = mgr.constantTrue();
            for (unsigned int j=0;j<livenessGuarantees.size();j++) {

                // Start computing the transitions that lead closer to the goal and lead to a position that is not yet known to be losing.
                // Start with the ones that actually represent reaching the goal (which is a transition in this implementation as we can have
                // nexts in the goal descriptions).
                BF livetransitions = livenessGuarantees[j] & (nu2.getValue().SwapVariables(varVectorPre,varVectorPost));

                // Compute the middle least-fixed point (called 'Y' in the GR(1) paper)
                BFFixedPoint mu1(mgr.constantFalse());

                bool firstMiddle = true;

                for (;!mu1.isFixedPointReached();) {

                    // Update the set of transitions that lead closer to the goal.
                    livetransitions |= mu1.getValue().SwapVariables(varVectorPre,varVectorPost);

                    // Iterate over the liveness assumptions. Store the positions that are found to be winning for *any*
                    // of them into the variable 'goodForAnyLivenessAssumption'.
                    BF goodForAnyLivenessAssumption = mu1.getValue();
                    for (unsigned int i=0;i<livenessAssumptions.size();i++) {

                        // Prepare the variable 'foundPaths' that contains the transitions that stay within the inner-most
                        // greatest fixed point or get closer to the goal. Only used for strategy extraction
                        BF foundPaths = mgr.constantTrue();

                        // Inner-most greatest fixed point. The corresponding variable in the paper would be 'X'.
                        BFFixedPoint nu0((firstMiddle && (!firstOutermost))?recyclingInnermostFixedPoints[j][i] & nu2.getValue():nu2.getValue());
                        for (;!nu0.isFixedPointReached();) {

                            // Compute a set of paths that are safe to take - used for the enforceable predecessor operator ('cox')
                            foundPaths = livetransitions | (nu0.getValue().SwapVariables(varVectorPre,varVectorPost) & !(livenessAssumptions[i]));
                            foundPaths &= safetySys;

                            // Update the inner-most fixed point with the result of applying the enforcable predecessor operator
                            nu0.update(safetyEnv.Implies(foundPaths).ExistAbstract(varCubePostOutput).UnivAbstract(varCubePostInput));
                        }

                        // Update the set of positions that are winning for some liveness assumption
                        goodForAnyLivenessAssumption |= nu0.getValue();

                        recyclingInnermostFixedPoints[j][i] = nu0.getValue();

                        // Dump the paths that we just wound into 'strategyDumpingData' - store the current goal long
                        // with the BDD
                        strategyDumpingData.push_back(std::pair<unsigned int,BF>(j,foundPaths));
                    }

                    // Update the moddle fixed point
                    mu1.update(goodForAnyLivenessAssumption);

                    firstMiddle = false;
                }

                // Update the set of positions that are winning for any goal for the outermost fixed point
                nextContraintsForGoals &= mu1.getValue();
            }

            // Update the outer-most fixed point
            nu2.update(nextContraintsForGoals);
            firstOutermost = false;

        }

        // We found the set of winning positions
        winningPositions = nu2.getValue();
    }

public:
    static GR1Context* makeInstance(std::list<std::string> &filenames) {
        return new XFixedPointRecycling<T>(filenames);
    }
};

#endif

<|endoftext|>