<commit_before>/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * 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 "mbed.h"
#include "nRF51822n.h"
#include "TMP102.h"

nRF51822n   nrf;                /* BLE radio driver */

DigitalOut  led1(LED1);
DigitalOut  led2(LED2);
Serial      pc(USBTX,USBRX);
TMP102      healthThemometer(p22, p20, 0x90);

/* Device Information service */
uint8_t            manufacturerName[4] = { 'm', 'b', 'e', 'd' };
GattService        deviceInformationService ( GattService::UUID_DEVICE_INFORMATION_SERVICE );
GattCharacteristic deviceManufacturer ( GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR,
                                        sizeof(manufacturerName), sizeof(manufacturerName),
                                        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);

/* Battery Level Service */
uint8_t            batt = 100;     /* Battery level */
uint8_t            read_batt = 0; /* Variable to hold battery level reads */
GattService        battService ( GattService::UUID_BATTERY_SERVICE );
GattCharacteristic battLevel   ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 1, 1,
                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);

/* Health Thermometer Service */
uint8_t             thermTempPayload[5] = { 0, 0, 0, 0, 0 };
GattService         thermService (GattService::UUID_HEALTH_THERMOMETER_SERVICE);
GattCharacteristic  thermTemp (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
                               5, 5, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);

/* Advertising data and parameters */
GapAdvertisingData   advData;
GapAdvertisingData   scanResponse;
GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );
uint16_t             uuid16_list[] = { GattService::UUID_BATTERY_SERVICE,
                                       GattService::UUID_DEVICE_INFORMATION_SERVICE,
                                       GattService::UUID_HEALTH_THERMOMETER_SERVICE };

uint32_t quick_ieee11073_from_float(float temperature);
void updateServiceValues(void);

/**************************************************************************/
/*!
    @brief  This custom class can be used to override any GapEvents
            that you are interested in handling on an application level.
*/
/**************************************************************************/
class GapEventHandler : public GapEvents
{
    virtual void onTimeout(void)
    {
        pc.printf("Advertising Timeout!\n\r");
        // Restart the advertising process with a much slower interval,
        // only start advertising again after a button press, etc.
    }

    virtual void onConnected(void)
    {
        pc.printf("Connected!\n\r");
    }

    virtual void onDisconnected(void)
    {
        pc.printf("Disconnected!\n\r");
        pc.printf("Restarting the advertising process\n\r");
        nrf.getGap().startAdvertising(advParams);
    }
};

/**************************************************************************/
/*!
    @brief  This custom class can be used to override any GattServerEvents
            that you are interested in handling on an application level.
*/
/**************************************************************************/
class GattServerEventHandler : public GattServerEvents
{
    //virtual void onDataSent(void) {}
    //virtual void onDataWritten(void) {}

    virtual void onUpdatesEnabled(uint16_t charHandle)
    {
        if (charHandle == thermTemp.handle)
        {
            pc.printf("Temperature indication enabled\n\r");
        }
    }

    virtual void onUpdatesDisabled(uint16_t charHandle)
    {
        if (charHandle == thermTemp.handle)
        {
            pc.printf("Temperature indication disabled\n\r");
        }
    }

    virtual void onConfirmationReceived(uint16_t charHandle)
    {
        if (charHandle == thermTemp.handle)
        {
            pc.printf("Temperature indication received\n\r");
        }
    }
};

/**************************************************************************/
/*!
    @brief  Program entry point
*/
/**************************************************************************/
int main(void)
{
    pc.baud(115200);

    /* Setup blinky: led1 is toggled in main, led2 is toggled via Ticker */
    led1=1;
    led2=1;

    /* Setup the local GAP/GATT event handlers */
    nrf.getGap().setEventHandler(new GapEventHandler());
    nrf.getGattServer().setEventHandler(new GattServerEventHandler());

    /* Initialise the nRF51822 */
    pc.printf("Initialising the nRF51822\n\r");
    nrf.init();

    /* Make sure we get a clean start */
    nrf.reset();

    /* Add BLE-Only flag and complete service list to the advertising data */
    advData.addFlags(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    advData.addData(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
                   (uint8_t*)uuid16_list, sizeof(uuid16_list));
    advData.addAppearance(GapAdvertisingData::GENERIC_THERMOMETER);
    nrf.getGap().setAdvertisingData(advData, scanResponse);

    /* Add the Battery Level service */
    battService.addCharacteristic(battLevel);
    nrf.getGattServer().addService(battService);

    /* Add the Device Information service */
    deviceInformationService.addCharacteristic(deviceManufacturer);
    nrf.getGattServer().addService(deviceInformationService);

    /* Health Thermometer Service */
    thermService.addCharacteristic(thermTemp);
    nrf.getGattServer().addService(thermService);

    /* Start advertising (make sure you've added all your data first) */
    nrf.getGap().startAdvertising(advParams);

    /* Now that we're live, update the battery level characteristic, and */
    /* change the device manufacturer characteristic to 'mbed' */
    nrf.getGattServer().updateValue(battLevel.handle, (uint8_t*)&batt, sizeof(batt));
    nrf.getGattServer().updateValue(deviceManufacturer.handle, manufacturerName, sizeof(manufacturerName));
    nrf.getGattServer().updateValue(thermTemp.handle, thermTempPayload, sizeof(thermTempPayload));

    for (;;)
    {
        wait(1);
        updateServiceValues();
    }
}

/**************************************************************************/
/*!
    @brief  Ticker callback to switch led2 state
*/
/**************************************************************************/
void updateServiceValues(void)
{
      /* Toggle the LED */
      led1 = !led1;

      /* Update battery level */
      nrf.getGattServer().updateValue(battLevel.handle, (uint8_t*)&batt, sizeof(batt));

      /* Update the temperature */
      float temperature = healthThemometer.read();
      uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
      memcpy(thermTempPayload+1, &temp_ieee11073, 4);
      nrf.getGattServer().updateValue(thermTemp.handle, thermTempPayload, sizeof(thermTempPayload));
      printf("Temperature: %f Celsius\r\n", temperature);
}

/**
 * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
 * @param temperature The temperature as a float.
 * @return The temperature in 11073-20601 FLOAT-Type format.
 */
uint32_t quick_ieee11073_from_float(float temperature)
{
    uint8_t  exponent = 0xFF; //exponent is -1
    uint32_t mantissa = (uint32_t)(temperature*10);

    return ( ((uint32_t)exponent) << 24) | mantissa;
}
<commit_msg>Update Health_Thermometer example to latest revision<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2006-2014 ARM Limited
 *
 * 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 "mbed.h"
#include "TMP102.h"
#include "nRF51822n.h"

nRF51822n   nrf;                               /* BLE radio driver */
TMP102      healthThemometer(p22, p20, 0x90);  /* The TMP102 connected to our board */

/* LEDs for indication: */
DigitalOut  oneSecondLed(LED1);        /* LED1 is toggled every second. */
DigitalOut  advertisingStateLed(LED2); /* LED2 is on when we are advertising, otherwise off. */

/* Health Thermometer Service */
uint8_t             thermTempPayload[5] = { 0, 0, 0, 0, 0 };
GattService         thermService (GattService::UUID_HEALTH_THERMOMETER_SERVICE);
GattCharacteristic  thermTemp (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR,
                               5, 5, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE);

/* Battery Level Service */
uint8_t            batt = 100;     /* Battery level */
uint8_t            read_batt = 0; /* Variable to hold battery level reads */
GattService        battService ( GattService::UUID_BATTERY_SERVICE );
GattCharacteristic battLevel   ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, 1, 1,
                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);

/* Advertising data and parameters */
GapAdvertisingData   advData;
GapAdvertisingData   scanResponse;
GapAdvertisingParams advParams ( GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED );

uint16_t             uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE,
                                      GattService::UUID_BATTERY_SERVICE};

uint32_t quick_ieee11073_from_float(float temperature);
void updateServiceValues(void);

/**************************************************************************/
/*!
    @brief  This custom class can be used to override any GapEvents
            that you are interested in handling on an application level.
*/
/**************************************************************************/
class GapEventHandler : public GapEvents
{
    //virtual void onTimeout(void) {}

    virtual void onConnected(void)
    {
        advertisingStateLed = 0;
    }

    /* When a client device disconnects we need to start advertising again. */
    virtual void onDisconnected(void)
    {
        nrf.getGap().startAdvertising(advParams);
        advertisingStateLed = 1;
    }
};

/**************************************************************************/
/*!
    @brief  Program entry point
*/
/**************************************************************************/
int main(void)
{

    /* Setup blinky led */
    oneSecondLed=1;

    /* Setup an event handler for GAP events i.e. Client/Server connection events. */
    nrf.getGap().setEventHandler(new GapEventHandler());

    /* Initialise the nRF51822 */
    nrf.init();

    /* Make sure we get a clean start */
    nrf.reset();

    /* Add BLE-Only flag and complete service list to the advertising data */
    advData.addFlags(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    advData.addData(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
                   (uint8_t*)uuid16_list, sizeof(uuid16_list));
    advData.addAppearance(GapAdvertisingData::GENERIC_THERMOMETER);
    nrf.getGap().setAdvertisingData(advData, scanResponse);

    /* Health Thermometer Service */
    thermService.addCharacteristic(thermTemp);
    nrf.getGattServer().addService(thermService);

    /* Add the Battery Level service */
    battService.addCharacteristic(battLevel);
    nrf.getGattServer().addService(battService);

    /* Start advertising (make sure you've added all your data first) */
    nrf.getGap().startAdvertising(advParams);
    advertisingStateLed = 1;

    for (;;)
    {
        /* Now that we're live, update the battery level & temperature characteristics */
        updateServiceValues();
        wait(1);
    }
}

/**************************************************************************/
/*!
    @brief  Ticker callback to switch advertisingStateLed state
*/
/**************************************************************************/
void updateServiceValues(void)
{
      /* Toggle the one second LEDs */
      oneSecondLed = !oneSecondLed;

      /* Update battery level */
      nrf.getGattServer().updateValue(battLevel.handle, (uint8_t*)&batt, sizeof(batt));
      /* Decrement the battery level. */
      batt <=50 ? batt=100 : batt--;;

      /* Update the temperature. Note that we need to convert to an ieee11073 format float. */
      float temperature = healthThemometer.read();
      uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperature);
      memcpy(thermTempPayload+1, &temp_ieee11073, 4);
      nrf.getGattServer().updateValue(thermTemp.handle, thermTempPayload, sizeof(thermTempPayload));
}

/**
 * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
 * @param temperature The temperature as a float.
 * @return The temperature in 11073-20601 FLOAT-Type format.
 */
uint32_t quick_ieee11073_from_float(float temperature)
{
    uint8_t  exponent = 0xFF; //exponent is -1
    uint32_t mantissa = (uint32_t)(temperature*10);

    return ( ((uint32_t)exponent) << 24) | mantissa;
}

<|endoftext|>


<commit_before>
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;

Logger log_1 =  Logger::getInstance("test.log_1");
Logger log_2 =  Logger::getInstance("test.log_2");
Logger log_3 =  Logger::getInstance("test.log_3");

void
printMsgs(Logger& logger)
{
    LOG4CPLUS_TRACE_METHOD(logger, "printMsgs()");
    LOG4CPLUS_DEBUG(logger, "printMsgs()");
    LOG4CPLUS_INFO(logger, "printMsgs()");
    LOG4CPLUS_WARN(logger, "printMsgs()");
    LOG4CPLUS_ERROR(logger, "printMsgs()");
}

int
main()
{
    cout << "Entering main()..." << endl;
    LogLog::getLogLog()->setInternalDebugging(true);
    Logger root = Logger::getRoot();
    try {
        ConfigureAndWatchThread configureThread("log4cplus.properties", 5 * 1000);

	LOG4CPLUS_WARN(root, "Testing....")

        for(int i=0; i<100; ++i) {
            printMsgs(log_1);
            printMsgs(log_2);
            printMsgs(log_3);
	    sleep(1);
        }
    }
    catch(...) {
        cout << "Exception..." << endl;
	LOG4CPLUS_FATAL(root, "Exception occured...")
    }

    cout << "Exiting main()..." << endl;
    return 0;
}

<commit_msg>Now specify the sleep() method to use.<commit_after>
#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/stringhelper.h>

using namespace std;
using namespace log4cplus;
using namespace log4cplus::helpers;

Logger log_1 =  Logger::getInstance("test.log_1");
Logger log_2 =  Logger::getInstance("test.log_2");
Logger log_3 =  Logger::getInstance("test.log_3");

void
printMsgs(Logger& logger)
{
    LOG4CPLUS_TRACE_METHOD(logger, "printMsgs()");
    LOG4CPLUS_DEBUG(logger, "printMsgs()");
    LOG4CPLUS_INFO(logger, "printMsgs()");
    LOG4CPLUS_WARN(logger, "printMsgs()");
    LOG4CPLUS_ERROR(logger, "printMsgs()");
}

int
main()
{
    cout << "Entering main()..." << endl;
    LogLog::getLogLog()->setInternalDebugging(true);
    Logger root = Logger::getRoot();
    try {
        ConfigureAndWatchThread configureThread("log4cplus.properties", 5 * 1000);

	    LOG4CPLUS_WARN(root, "Testing....")

        for(int i=0; i<100; ++i) {
            printMsgs(log_1);
            printMsgs(log_2);
            printMsgs(log_3);
	        log4cplus::helpers::sleep(1);
        }
    }
    catch(...) {
        cout << "Exception..." << endl;
	LOG4CPLUS_FATAL(root, "Exception occured...")
    }

    cout << "Exiting main()..." << endl;
    return 0;
}

<|endoftext|>


<commit_before>#include "slave.hpp"
#include <stdint.h>
#include "net_structs.hpp"
#include "arch/linux/coroutines.hpp"

namespace replication {

// TODO unit test offsets

slave_t::slave_t(store_t *internal_store, replication_config_t replication_config, failover_config_t failover_config)
    : internal_store(internal_store),
      replication_config(replication_config),
      failover_config(failover_config),
      conn(NULL),
      shutting_down(false),
      failover_script(failover_config.failover_script_path),
      timeout(INITIAL_TIMEOUT),
      timer_token(NULL),
      failover_reset_control(std::string("failover reset"), this),
      new_master_control(std::string("new master"), this)
{
    coro_t::spawn(&run, this);
}

slave_t::~slave_t() {
    shutting_down = true;
    coro_t::move_to_thread(home_thread);
    kill_conn();

    /* cancel the timer */
    if(timer_token) cancel_timer(timer_token);
}

void slave_t::kill_conn() {
    struct : public message_parser_t::message_parser_shutdown_callback_t, public cond_t {
            void on_parser_shutdown() { pulse(); }
    } parser_shutdown_cb;

    {
        on_thread_t thread_switch(home_thread);

        if (!parser.shutdown(&parser_shutdown_cb))
            parser_shutdown_cb.wait();
    }

    { //on_thread_t scope
        on_thread_t thread_switch(get_num_threads() - 2);
        if (conn) {
            delete conn;
            conn = NULL;
        }
    }
}

store_t::get_result_t slave_t::get(store_key_t *key)
{
    return internal_store->get(key);
}

store_t::get_result_t slave_t::get_cas(store_key_t *key, cas_t proposed_cas)
{
    // TODO: ask joe why this used get(key) before (back when we did not have proposed_cas).
    return internal_store->get_cas(key, proposed_cas);
}

store_t::set_result_t slave_t::set(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas) {
    if (respond_to_queries)
        return internal_store->set(key, data, flags, exptime, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::set_result_t slave_t::add(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas)
{
    return internal_store->add(key, data,  flags,  exptime, proposed_cas);
}

store_t::set_result_t slave_t::replace(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->replace(key, data, flags, exptime, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::set_result_t slave_t::cas(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t unique, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->cas(key, data, flags, exptime, unique, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::incr_decr_result_t slave_t::incr(store_key_t *key, unsigned long long amount, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->incr(key, amount, proposed_cas);
    else
        return store_t::incr_decr_result_t::idr_not_allowed;
}

store_t::incr_decr_result_t slave_t::decr(store_key_t *key, unsigned long long amount, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->decr(key, amount, proposed_cas);
    else
        return store_t::incr_decr_result_t::idr_not_allowed;
}

store_t::append_prepend_result_t slave_t::append(store_key_t *key, data_provider_t *data, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->append(key, data, proposed_cas);
    else
        return store_t::apr_not_allowed;
}

store_t::append_prepend_result_t slave_t::prepend(store_key_t *key, data_provider_t *data, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->prepend(key, data, proposed_cas);
    else
        return store_t::apr_not_allowed;
}

store_t::delete_result_t slave_t::delete_key(store_key_t *key)
{
    if (respond_to_queries)
        return internal_store->delete_key(key);
    else
        return dr_not_allowed;
}

std::string slave_t::failover_reset() {
    on_thread_t thread_switch(get_num_threads() - 2);
    give_up.reset();
    timeout = INITIAL_TIMEOUT;

    if (timer_token) {
        cancel_timer(timer_token);
        timer_token = NULL;
    }

    if (conn) kill_conn(); //this will cause a notify
    else coro->notify();

    return std::string("Reseting failover\n");
}

 /* message_callback_t interface */
void slave_t::hello(boost::scoped_ptr<hello_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<backfill_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<announce_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<set_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<append_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<prepend_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<nop_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<ack_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<shutting_down_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<goodbye_message_t>& message)
{}
void slave_t::conn_closed()
{
    coro->notify();
}

/* failover driving functions */
void slave_t::reconnect_timer_callback(void *ctx) {
    slave_t *self = static_cast<slave_t*>(ctx);
    self->coro->notify();
}

/* give_up_t interface: the give_up_t struct keeps track of the last N times
 * the server failed. If it's failing to frequently then it will tell us to
 * give up on the server and stop trying to reconnect */
void slave_t::give_up_t::on_reconnect() {
    succesful_reconnects.push(ticks_to_secs(get_ticks()));
    limit_to(MAX_RECONNECTS_PER_N_SECONDS);
}

bool slave_t::give_up_t::give_up() {
    limit_to(MAX_RECONNECTS_PER_N_SECONDS);

    return (succesful_reconnects.size() == MAX_RECONNECTS_PER_N_SECONDS && (succesful_reconnects.back() - ticks_to_secs(get_ticks())) < N_SECONDS);
}

void slave_t::give_up_t::reset() {
    limit_to(0);
}

void slave_t::give_up_t::limit_to(unsigned int limit) {
    while (succesful_reconnects.size() > limit)
        succesful_reconnects.pop();
}

/* failover callback */
void slave_t::on_failure() {
    respond_to_queries = true;
}

void slave_t::on_resume() {
    respond_to_queries = false;
}

void run(slave_t *slave) {
    slave->coro = coro_t::self();
    slave->failover.add_callback(slave);
    slave->respond_to_queries = false;
    bool first_connect = true;
    while (!slave->shutting_down) {
        try {
            if (slave->conn) {
                delete slave->conn;
                slave->conn = NULL;
            }
            coro_t::move_to_thread(get_num_threads() - 2);
            logINF("Attempting to connect as slave to: %s:%d\n", slave->replication_config.hostname, slave->replication_config.port);
            slave->conn = new tcp_conn_t(slave->replication_config.hostname, slave->replication_config.port);
            slave->timeout = INITIAL_TIMEOUT;
            slave->give_up.on_reconnect();

            slave->parser.parse_messages(slave->conn, slave);
            if (!first_connect) //UGLY :( but it's either this or code duplication
                slave->failover.on_resume(); //Call on_resume if we've failed before
            first_connect = false;
            logINF("Connected as slave to: %s:%d\n", slave->replication_config.hostname, slave->replication_config.port);

            coro_t::wait(); //wait for things to fail
            slave->failover.on_failure();
            if (slave->shutting_down) break;

        } catch (tcp_conn_t::connect_failed_exc_t& e) {
            //Presumably if the master doesn't even accept an initial
            //connection then this is a user error rather than some sort of
            //failure
            if (first_connect)
                crash("Master at %s:%d is not responding :(. Perhaps you haven't brought it up yet. But what do I know I'm just a database\n", slave->replication_config.hostname, slave->replication_config.port);
        }

        /* The connection has failed. Let's see what se should do */
        if (!slave->give_up.give_up()) {
            slave->timer_token = fire_timer_once(slave->timeout, &slave->reconnect_timer_callback, slave);
            slave->timeout *= TIMEOUT_GROWTH_FACTOR;
            coro_t::wait(); //waiting on a timer
            slave->timer_token = NULL;
        } else {
            logINF("Master at %s:%d has failed %d times in the last %d seconds," \
                    "going rogue. To resume slave behavior send the command" \
                    "\"rethinkdb failover reset\" (over telnet)\n",
                    slave->replication_config.hostname, slave->replication_config.port,
                    MAX_RECONNECTS_PER_N_SECONDS, N_SECONDS);
            coro_t::wait(); //the only thing that can save us now is a reset
        }
    }
}

std::string slave_t::new_master(std::string args) {
    std::string host = args.substr(0, args.find(' '));
    if (host.length() >  MAX_HOSTNAME_LEN - 1)
        return std::string("That hostname is soo long, use a shorter one\n");

    /* redo the replication_config info */
    strcpy(replication_config.hostname, host.c_str());
    replication_config.port = atoi(strip_spaces(args.substr(args.find(' ') + 1)).c_str()); //TODO this is ugly

    failover_reset();

    return std::string("New master set\n");
}

std::string slave_t::failover_reset_control_t::call(std::string) {
    return slave->failover_reset();
}

std::string slave_t::new_master_control_t::call(std::string args) {
    return slave->new_master(args);
}

}  // namespace replication
<commit_msg>Fixed compilation error with slave.cc when MOCK_CACHE_CHECK=1 DEBUG=1.<commit_after>#include "slave.hpp"

#include <stdint.h>

#include "arch/linux/coroutines.hpp"
#include "logger.hpp"
#include "net_structs.hpp"

namespace replication {

// TODO unit test offsets

slave_t::slave_t(store_t *internal_store, replication_config_t replication_config, failover_config_t failover_config)
    : internal_store(internal_store),
      replication_config(replication_config),
      failover_config(failover_config),
      conn(NULL),
      shutting_down(false),
      failover_script(failover_config.failover_script_path),
      timeout(INITIAL_TIMEOUT),
      timer_token(NULL),
      failover_reset_control(std::string("failover reset"), this),
      new_master_control(std::string("new master"), this)
{
    coro_t::spawn(&run, this);
}

slave_t::~slave_t() {
    shutting_down = true;
    coro_t::move_to_thread(home_thread);
    kill_conn();

    /* cancel the timer */
    if(timer_token) cancel_timer(timer_token);
}

void slave_t::kill_conn() {
    struct : public message_parser_t::message_parser_shutdown_callback_t, public cond_t {
            void on_parser_shutdown() { pulse(); }
    } parser_shutdown_cb;

    {
        on_thread_t thread_switch(home_thread);

        if (!parser.shutdown(&parser_shutdown_cb))
            parser_shutdown_cb.wait();
    }

    { //on_thread_t scope
        on_thread_t thread_switch(get_num_threads() - 2);
        if (conn) {
            delete conn;
            conn = NULL;
        }
    }
}

store_t::get_result_t slave_t::get(store_key_t *key)
{
    return internal_store->get(key);
}

store_t::get_result_t slave_t::get_cas(store_key_t *key, cas_t proposed_cas)
{
    // TODO: ask joe why this used get(key) before (back when we did not have proposed_cas).
    return internal_store->get_cas(key, proposed_cas);
}

store_t::set_result_t slave_t::set(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas) {
    if (respond_to_queries)
        return internal_store->set(key, data, flags, exptime, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::set_result_t slave_t::add(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas)
{
    return internal_store->add(key, data,  flags,  exptime, proposed_cas);
}

store_t::set_result_t slave_t::replace(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->replace(key, data, flags, exptime, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::set_result_t slave_t::cas(store_key_t *key, data_provider_t *data, mcflags_t flags, exptime_t exptime, cas_t unique, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->cas(key, data, flags, exptime, unique, proposed_cas);
    else
        return store_t::sr_not_allowed;
}

store_t::incr_decr_result_t slave_t::incr(store_key_t *key, unsigned long long amount, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->incr(key, amount, proposed_cas);
    else
        return store_t::incr_decr_result_t::idr_not_allowed;
}

store_t::incr_decr_result_t slave_t::decr(store_key_t *key, unsigned long long amount, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->decr(key, amount, proposed_cas);
    else
        return store_t::incr_decr_result_t::idr_not_allowed;
}

store_t::append_prepend_result_t slave_t::append(store_key_t *key, data_provider_t *data, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->append(key, data, proposed_cas);
    else
        return store_t::apr_not_allowed;
}

store_t::append_prepend_result_t slave_t::prepend(store_key_t *key, data_provider_t *data, cas_t proposed_cas)
{
    if (respond_to_queries)
        return internal_store->prepend(key, data, proposed_cas);
    else
        return store_t::apr_not_allowed;
}

store_t::delete_result_t slave_t::delete_key(store_key_t *key)
{
    if (respond_to_queries)
        return internal_store->delete_key(key);
    else
        return dr_not_allowed;
}

std::string slave_t::failover_reset() {
    on_thread_t thread_switch(get_num_threads() - 2);
    give_up.reset();
    timeout = INITIAL_TIMEOUT;

    if (timer_token) {
        cancel_timer(timer_token);
        timer_token = NULL;
    }

    if (conn) kill_conn(); //this will cause a notify
    else coro->notify();

    return std::string("Reseting failover\n");
}

 /* message_callback_t interface */
void slave_t::hello(boost::scoped_ptr<hello_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<backfill_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<announce_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<set_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<append_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<prepend_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<nop_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<ack_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<shutting_down_message_t>& message)
{}
void slave_t::send(boost::scoped_ptr<goodbye_message_t>& message)
{}
void slave_t::conn_closed()
{
    coro->notify();
}

/* failover driving functions */
void slave_t::reconnect_timer_callback(void *ctx) {
    slave_t *self = static_cast<slave_t*>(ctx);
    self->coro->notify();
}

/* give_up_t interface: the give_up_t struct keeps track of the last N times
 * the server failed. If it's failing to frequently then it will tell us to
 * give up on the server and stop trying to reconnect */
void slave_t::give_up_t::on_reconnect() {
    succesful_reconnects.push(ticks_to_secs(get_ticks()));
    limit_to(MAX_RECONNECTS_PER_N_SECONDS);
}

bool slave_t::give_up_t::give_up() {
    limit_to(MAX_RECONNECTS_PER_N_SECONDS);

    return (succesful_reconnects.size() == MAX_RECONNECTS_PER_N_SECONDS && (succesful_reconnects.back() - ticks_to_secs(get_ticks())) < N_SECONDS);
}

void slave_t::give_up_t::reset() {
    limit_to(0);
}

void slave_t::give_up_t::limit_to(unsigned int limit) {
    while (succesful_reconnects.size() > limit)
        succesful_reconnects.pop();
}

/* failover callback */
void slave_t::on_failure() {
    respond_to_queries = true;
}

void slave_t::on_resume() {
    respond_to_queries = false;
}

void run(slave_t *slave) {
    slave->coro = coro_t::self();
    slave->failover.add_callback(slave);
    slave->respond_to_queries = false;
    bool first_connect = true;
    while (!slave->shutting_down) {
        try {
            if (slave->conn) {
                delete slave->conn;
                slave->conn = NULL;
            }
            coro_t::move_to_thread(get_num_threads() - 2);
            logINF("Attempting to connect as slave to: %s:%d\n", slave->replication_config.hostname, slave->replication_config.port);
            slave->conn = new tcp_conn_t(slave->replication_config.hostname, slave->replication_config.port);
            slave->timeout = INITIAL_TIMEOUT;
            slave->give_up.on_reconnect();

            slave->parser.parse_messages(slave->conn, slave);
            if (!first_connect) //UGLY :( but it's either this or code duplication
                slave->failover.on_resume(); //Call on_resume if we've failed before
            first_connect = false;
            logINF("Connected as slave to: %s:%d\n", slave->replication_config.hostname, slave->replication_config.port);

            coro_t::wait(); //wait for things to fail
            slave->failover.on_failure();
            if (slave->shutting_down) break;

        } catch (tcp_conn_t::connect_failed_exc_t& e) {
            //Presumably if the master doesn't even accept an initial
            //connection then this is a user error rather than some sort of
            //failure
            if (first_connect)
                crash("Master at %s:%d is not responding :(. Perhaps you haven't brought it up yet. But what do I know I'm just a database\n", slave->replication_config.hostname, slave->replication_config.port);
        }

        /* The connection has failed. Let's see what se should do */
        if (!slave->give_up.give_up()) {
            slave->timer_token = fire_timer_once(slave->timeout, &slave->reconnect_timer_callback, slave);
            slave->timeout *= TIMEOUT_GROWTH_FACTOR;
            coro_t::wait(); //waiting on a timer
            slave->timer_token = NULL;
        } else {
            logINF("Master at %s:%d has failed %d times in the last %d seconds," \
                    "going rogue. To resume slave behavior send the command" \
                    "\"rethinkdb failover reset\" (over telnet)\n",
                    slave->replication_config.hostname, slave->replication_config.port,
                    MAX_RECONNECTS_PER_N_SECONDS, N_SECONDS);
            coro_t::wait(); //the only thing that can save us now is a reset
        }
    }
}

std::string slave_t::new_master(std::string args) {
    std::string host = args.substr(0, args.find(' '));
    if (host.length() >  MAX_HOSTNAME_LEN - 1)
        return std::string("That hostname is soo long, use a shorter one\n");

    /* redo the replication_config info */
    strcpy(replication_config.hostname, host.c_str());
    replication_config.port = atoi(strip_spaces(args.substr(args.find(' ') + 1)).c_str()); //TODO this is ugly

    failover_reset();

    return std::string("New master set\n");
}

std::string slave_t::failover_reset_control_t::call(std::string) {
    return slave->failover_reset();
}

std::string slave_t::new_master_control_t::call(std::string args) {
    return slave->new_master(args);
}

}  // namespace replication
<|endoftext|>


<commit_before>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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 "resembla_with_id.hpp"

#include <fstream>
#include <algorithm>

namespace resembla {

ResemblaWithId::ResemblaWithId(const std::shared_ptr<ResemblaInterface> resembla,
        std::string corpus_path, size_t id_col, size_t text_col):
    resembla(resembla)
{
    loadCorpus(corpus_path, id_col, text_col);
}

std::vector<ResemblaWithId::output_type> ResemblaWithId::find(const string_type& query,
        double threshold, size_t max_response) const
{
    std::vector<output_type> results;
    for(auto raw_result: resembla->find(query, threshold, max_response)){
        results.push_back({raw_result, ids.at(raw_result.text)});
    }
    return results;
}

std::vector<ResemblaWithId::output_type> ResemblaWithId::eval(const string_type& query,
        const std::vector<string_type>& targets, double threshold, size_t max_response) const
{
    std::vector<output_type> results;
    for(auto raw_result: resembla->eval(query, targets, threshold, max_response)){
        auto i = ids.find(raw_result.text);
        results.push_back({raw_result, i != ids.end() ? i->second : id_type{0}});
    }
    return results;
}

void ResemblaWithId::loadCorpus(const std::string& corpus_path, size_t id_col, size_t text_col)
{
    id_type max_id = 0;
    std::ifstream ifs(corpus_path);
    if(ifs.fail()){
        throw std::runtime_error("input file is not available: " + corpus_path);
    }

    while(ifs.good()){
        std::string line;
        std::getline(ifs, line);
        if(ifs.eof() || line.length() == 0){
            break;
        }

        auto columns = split(line, column_delimiter<>());
        if(text_col - 1 < columns.size()){
            auto text = cast_string<string_type>(columns[text_col - 1]);
            auto i = ids.find(text);
            if(i == std::end(ids)){
                id_type id;
                if(id_col == 0 || id_col > columns.size()){
                    id = ++max_id;
                }
                else{
                    id = std::stoi(columns[id_col - 1]);
                    max_id = std::max(id, max_id);
                }
                ids[text] = id;
            }
        }
    }
}

}
<commit_msg>use csv_reader in resembla_with_id<commit_after>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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 "resembla_with_id.hpp"

#include <algorithm>

#include "csv_reader.hpp"

namespace resembla {

ResemblaWithId::ResemblaWithId(const std::shared_ptr<ResemblaInterface> resembla,
        std::string corpus_path, size_t id_col, size_t text_col):
    resembla(resembla)
{
    loadCorpus(corpus_path, id_col, text_col);
}

std::vector<ResemblaWithId::output_type> ResemblaWithId::find(const string_type& query,
        double threshold, size_t max_response) const
{
    std::vector<output_type> results;
    for(auto raw_result: resembla->find(query, threshold, max_response)){
        results.push_back({raw_result, ids.at(raw_result.text)});
    }
    return results;
}

std::vector<ResemblaWithId::output_type> ResemblaWithId::eval(const string_type& query,
        const std::vector<string_type>& targets, double threshold, size_t max_response) const
{
    std::vector<output_type> results;
    for(auto raw_result: resembla->eval(query, targets, threshold, max_response)){
        auto i = ids.find(raw_result.text);
        results.push_back({raw_result, i != ids.end() ? i->second : id_type{0}});
    }
    return results;
}

void ResemblaWithId::loadCorpus(const std::string& corpus_path, size_t id_col, size_t text_col)
{
    id_type max_id{0};
    for(const auto& columns: CsvReader<string_type>(corpus_path, text_col)){
        const auto& text = cast_string<string_type>(columns[text_col - 1]);

        auto i = ids.find(text);
        if(i == std::end(ids)){
            id_type id;
            if(id_col == 0 || id_col > columns.size()){
                id = ++max_id;
            }
            else{
                id = std::stoi(columns[id_col - 1]);
                max_id = std::max(id, max_id);
            }
            ids[text] = id;
        }
    }
}

}
<|endoftext|>


<commit_before>#include <os.h>
#include <x86.h>

/* Stack pointer */
extern u32 *		stack_ptr;

/* Current cpu name */
static char cpu_name[512] = "x86-noname";

/* Detect the type of processor */
char* Architecture::detect(){
	cpu_vendor_name(cpu_name);
	return cpu_name;
}

/* Start and initialize the architecture */
void Architecture::init(){
	 io.print("Architecture x86, cpu=%s \n", detect());

	 io.print("Loading GDT \n");
		 init_gdt();
		 asm("	movw $0x18, %%ax \n \
			movw %%ax, %%ss \n \
			movl %0, %%esp"::"i" (KERN_STACK));

	 io.print("Loading IDT \n");
		 init_idt();

	 io.print("Configure PIC \n");
		 init_pic();

	 io.print("Loading Task Register \n");
		 asm("	movw $0x38, %ax; ltr %ax");
}

/* Initialise the list of processus */
void Architecture::initProc(){
	firstProc= new Process("kernel");
	firstProc->setState(ZOMBIE);
	firstProc->addFile(fsm.path("/dev/tty"),0);
	firstProc->addFile(fsm.path("/dev/tty"),0);
	firstProc->addFile(fsm.path("/dev/tty"),0);

	plist=firstProc;
	pcurrent=firstProc;
	pcurrent->setPNext(NULL);
	process_st* current=pcurrent->getPInfo();
	current->regs.cr3 = (u32) pd0;
}

/* Reboot the computer */
void Architecture::reboot(){
    u8 good = 0x02;
    while ((good & 0x02) != 0)
        good = io.inb(0x64);
    io.outb(0x64, 0xFE);
}

/* Shutdown the computer */
void Architecture::shutdown(){
	// todo
}

/* Install a interruption handler */
void Architecture::install_irq(int_handler h){
	// todo
}

/* Add a process to the scheduler */
void Architecture::addProcess(Process* p){
	p->setPNext(plist);
	plist=p;
}

/* Fork a process */
int Architecture::fork(process_st* info,process_st* father){
	memcpy((char*)info,(char*)father,sizeof(process_st));
	info->pd = pd_copy(father->pd);
}

/* Initialise a new process */
int Architecture::createProc(process_st* info, char* file, int argc, char** argv){
	page *kstack;
	process_st *previous;
	process_st *current;

	char **param, **uparam;
	u32 stackp;
	u32 e_entry;

	int pid;
	int i;

	pid = 1;

	info->pid = pid;

	if (argc) {
		param = (char**) kmalloc(sizeof(char*) * (argc+1));
		for (i=0 ; i<argc ; i++) {
			param[i] = (char*) kmalloc(strlen(argv[i]) + 1);
			strcpy(param[i], argv[i]);
		}
		param[i] = 0;
	}

	info->pd = pd_create();

	INIT_LIST_HEAD(&(info->pglist));

	previous = arch.pcurrent->getPInfo();
	current=info;

	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"((info->pd)->base->p_addr));

	e_entry = (u32) load_elf(file,info);

	if (e_entry == 0) {
		for (i=0 ; i<argc ; i++)
			kfree(param[i]);
		kfree(param);
		arch.pcurrent = (Process*) previous->vinfo;
		current=arch.pcurrent->getPInfo();
		asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (current->regs.cr3));
		pd_destroy(info->pd);
		return -1;
	}

	stackp = USER_STACK - 16;

	if (argc) {
		uparam = (char**) kmalloc(sizeof(char*) * argc);

		for (i=0 ; i<argc ; i++) {
			stackp -= (strlen(param[i]) + 1);
			strcpy((char*) stackp, param[i]);
			uparam[i] = (char*) stackp;
		}

		stackp &= 0xFFFFFFF0;

		// Creation des arguments de main() : argc, argv[]...
		stackp -= sizeof(char*);
		*((char**) stackp) = 0;

		for (i=argc-1 ; i>=0 ; i--) {
			stackp -= sizeof(char*);
			*((char**) stackp) = uparam[i];
		}

		stackp -= sizeof(char*);
		*((char**) stackp) = (char*) (stackp + 4);

		stackp -= sizeof(char*);
		*((int*) stackp) = argc;

		stackp -= sizeof(char*);

		for (i=0 ; i<argc ; i++)
			kfree(param[i]);

		kfree(param);
		kfree(uparam);
	}

	kstack = get_page_from_heap();

	// Initialise le reste des registres et des attributs
	info->regs.ss = 0x33;
	info->regs.esp = stackp;
	info->regs.eflags = 0x0;
	info->regs.cs = 0x23;
	info->regs.eip = e_entry;
	info->regs.ds = 0x2B;
	info->regs.es = 0x2B;
	info->regs.fs = 0x2B;
	info->regs.gs = 0x2B;
	info->regs.cr3 = (u32) info->pd->base->p_addr;

	info->kstack.ss0 = 0x18;
	info->kstack.esp0 = (u32) kstack->v_addr + PAGESIZE - 16;

	info->regs.eax = 0;
	info->regs.ecx = 0;
	info->regs.edx = 0;
	info->regs.ebx = 0;

	info->regs.ebp = 0;
	info->regs.esi = 0;
	info->regs.edi = 0;

	info->b_heap = (char*) ((u32) info->e_bss & 0xFFFFF000) + PAGESIZE;
	info->e_heap = info->b_heap;

	info->signal = 0;
	for(i=0 ; i<32 ; i++)
		info->sigfn[i] = (char*) SIG_DFL;

	arch.pcurrent = (Process*) previous->vinfo;
	current=arch.pcurrent->getPInfo();
	asm("mov %0, %%eax ;mov %%eax, %%cr3":: "m"(current->regs.cr3));

	return 1;
}

// Destroy a process
void Architecture::destroy_process(Process* pp){
	disable_interrupt();

	u16 kss;
	u32 kesp;
	u32 accr3;
	list_head *p, *n;
	page *pg;
	process_st *proccurrent=(arch.pcurrent)->getPInfo();
	process_st *pidproc=pp->getPInfo();

	// Switch page to the process to destroy
	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (pidproc->regs.cr3));

	// Free process memory:
	//  - pages used by the executable code
	//  - user stack
	//  - kernel stack
	//  - pages directory

	// Free process memory
	list_for_each_safe(p, n, &pidproc->pglist) {
		pg = list_entry(p, struct page, list);
		release_page_frame(pg->p_addr);
		list_del(p);
		kfree(pg);
	}

	release_page_from_heap((char *) ((u32)pidproc->kstack.esp0 & 0xFFFFF000));

	// Free pages directory
	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(pd0));

	pd_destroy(pidproc->pd);

	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (proccurrent->regs.cr3));

	// Remove from the list
	if (plist==pp){
		plist=pp->getPNext();
	}
	else{
		Process* l=plist;
		Process*ol=plist;
		while (l!=NULL){

			if (l==pp){
				ol->setPNext(pp->getPNext());
			}

			ol=l;
			l=l->getPNext();
		}
	}

	enable_interrupt();
}

void Architecture::change_process_father(Process* pe, Process* pere){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getPParent()==pe){
			p->setPParent(pere);
		}

		p=pn;
	}
}

void Architecture::destroy_all_zombie(){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getState()==ZOMBIE && p->getPid()!=1){
			destroy_process(p);
			delete p;
		}

		p=pn;
	}
}

/* Set the syscall arguments */
void Architecture::setParam(u32 ret, u32 ret1, u32 ret2, u32 ret3,u32 ret4){
	ret_reg[0]=ret;
	ret_reg[1]=ret1;
	ret_reg[2]=ret2;
	ret_reg[3]=ret3;
	ret_reg[4]=ret4;
}

/* Enable the interruption */
void Architecture::enable_interrupt(){
	asm ("sti");
}

/* Disable the interruption */
void Architecture::disable_interrupt(){
	asm ("cli");
}

/* Get a syscall argument */
u32	Architecture::getArg(u32 n){
	if (n<5)
		return ret_reg[n];
	else
		return 0;
}

/* Set the return value of syscall */
void Architecture::setRet(u32 ret){
	stack_ptr[14] = ret;
}
<commit_msg>Update architecture.cc<commit_after>#include <os.h>
#include <x86.h>

/* Stack pointer */
extern u32 *		stack_ptr;

/* Current cpu name */
static char cpu_name[512] = "x86-noname";

/* Detect the type of processor */
char* Architecture::detect(){
	cpu_vendor_name(cpu_name);
	return cpu_name;
}

/* Start and initialize the architecture */
void Architecture::init(){
	 io.print("Architecture x86, cpu=%s \n", detect());

	 io.print("Loading GDT \n");
		 init_gdt();
		 asm("	movw $0x18, %%ax \n \
			movw %%ax, %%ss \n \
			movl %0, %%esp"::"i" (KERN_STACK));

	 io.print("Loading IDT \n");
		 init_idt();

	 io.print("Configure PIC \n");
		 init_pic();

	 io.print("Loading Task Register \n");
		 asm("	movw $0x38, %ax; ltr %ax");
}

/* Initialise the list of processus */
void Architecture::initProc(){
	firstProc= new Process("kernel");
	firstProc->setState(ZOMBIE);
	firstProc->addFile(fsm.path("/suriyaa/tty"),0);
	firstProc->addFile(fsm.path("/suriyaa/tty"),0);
	firstProc->addFile(fsm.path("/suriyaa/tty"),0);

	plist=firstProc;
	pcurrent=firstProc;
	pcurrent->setPNext(NULL);
	process_st* current=pcurrent->getPInfo();
	current->regs.cr3 = (u32) pd0;
}

/* Reboot the computer */
void Architecture::reboot(){
    u8 good = 0x02;
    while ((good & 0x02) != 0)
        good = io.inb(0x64);
    io.outb(0x64, 0xFE);
}

/* Shutdown the computer */
void Architecture::shutdown(){
	// todo
}

/* Install a interruption handler */
void Architecture::install_irq(int_handler h){
	// todo
}

/* Add a process to the scheduler */
void Architecture::addProcess(Process* p){
	p->setPNext(plist);
	plist=p;
}

/* Fork a process */
int Architecture::fork(process_st* info,process_st* father){
	memcpy((char*)info,(char*)father,sizeof(process_st));
	info->pd = pd_copy(father->pd);
}

/* Initialise a new process */
int Architecture::createProc(process_st* info, char* file, int argc, char** argv){
	page *kstack;
	process_st *previous;
	process_st *current;

	char **param, **uparam;
	u32 stackp;
	u32 e_entry;

	int pid;
	int i;

	pid = 1;

	info->pid = pid;

	if (argc) {
		param = (char**) kmalloc(sizeof(char*) * (argc+1));
		for (i=0 ; i<argc ; i++) {
			param[i] = (char*) kmalloc(strlen(argv[i]) + 1);
			strcpy(param[i], argv[i]);
		}
		param[i] = 0;
	}

	info->pd = pd_create();

	INIT_LIST_HEAD(&(info->pglist));

	previous = arch.pcurrent->getPInfo();
	current=info;

	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"((info->pd)->base->p_addr));

	e_entry = (u32) load_elf(file,info);

	if (e_entry == 0) {
		for (i=0 ; i<argc ; i++)
			kfree(param[i]);
		kfree(param);
		arch.pcurrent = (Process*) previous->vinfo;
		current=arch.pcurrent->getPInfo();
		asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (current->regs.cr3));
		pd_destroy(info->pd);
		return -1;
	}

	stackp = USER_STACK - 16;

	if (argc) {
		uparam = (char**) kmalloc(sizeof(char*) * argc);

		for (i=0 ; i<argc ; i++) {
			stackp -= (strlen(param[i]) + 1);
			strcpy((char*) stackp, param[i]);
			uparam[i] = (char*) stackp;
		}

		stackp &= 0xFFFFFFF0;

		// Creation des arguments de main() : argc, argv[]...
		stackp -= sizeof(char*);
		*((char**) stackp) = 0;

		for (i=argc-1 ; i>=0 ; i--) {
			stackp -= sizeof(char*);
			*((char**) stackp) = uparam[i];
		}

		stackp -= sizeof(char*);
		*((char**) stackp) = (char*) (stackp + 4);

		stackp -= sizeof(char*);
		*((int*) stackp) = argc;

		stackp -= sizeof(char*);

		for (i=0 ; i<argc ; i++)
			kfree(param[i]);

		kfree(param);
		kfree(uparam);
	}

	kstack = get_page_from_heap();

	// Initialise le reste des registres et des attributs
	info->regs.ss = 0x33;
	info->regs.esp = stackp;
	info->regs.eflags = 0x0;
	info->regs.cs = 0x23;
	info->regs.eip = e_entry;
	info->regs.ds = 0x2B;
	info->regs.es = 0x2B;
	info->regs.fs = 0x2B;
	info->regs.gs = 0x2B;
	info->regs.cr3 = (u32) info->pd->base->p_addr;

	info->kstack.ss0 = 0x18;
	info->kstack.esp0 = (u32) kstack->v_addr + PAGESIZE - 16;

	info->regs.eax = 0;
	info->regs.ecx = 0;
	info->regs.edx = 0;
	info->regs.ebx = 0;

	info->regs.ebp = 0;
	info->regs.esi = 0;
	info->regs.edi = 0;

	info->b_heap = (char*) ((u32) info->e_bss & 0xFFFFF000) + PAGESIZE;
	info->e_heap = info->b_heap;

	info->signal = 0;
	for(i=0 ; i<32 ; i++)
		info->sigfn[i] = (char*) SIG_DFL;

	arch.pcurrent = (Process*) previous->vinfo;
	current=arch.pcurrent->getPInfo();
	asm("mov %0, %%eax ;mov %%eax, %%cr3":: "m"(current->regs.cr3));

	return 1;
}

// Destroy a process
void Architecture::destroy_process(Process* pp){
	disable_interrupt();

	u16 kss;
	u32 kesp;
	u32 accr3;
	list_head *p, *n;
	page *pg;
	process_st *proccurrent=(arch.pcurrent)->getPInfo();
	process_st *pidproc=pp->getPInfo();

	// Switch page to the process to destroy
	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (pidproc->regs.cr3));

	// Free process memory:
	//  - pages used by the executable code
	//  - user stack
	//  - kernel stack
	//  - pages directory

	// Free process memory
	list_for_each_safe(p, n, &pidproc->pglist) {
		pg = list_entry(p, struct page, list);
		release_page_frame(pg->p_addr);
		list_del(p);
		kfree(pg);
	}

	release_page_from_heap((char *) ((u32)pidproc->kstack.esp0 & 0xFFFFF000));

	// Free pages directory
	asm("mov %0, %%eax; mov %%eax, %%cr3"::"m"(pd0));

	pd_destroy(pidproc->pd);

	asm("mov %0, %%eax ;mov %%eax, %%cr3"::"m" (proccurrent->regs.cr3));

	// Remove from the list
	if (plist==pp){
		plist=pp->getPNext();
	}
	else{
		Process* l=plist;
		Process*ol=plist;
		while (l!=NULL){

			if (l==pp){
				ol->setPNext(pp->getPNext());
			}

			ol=l;
			l=l->getPNext();
		}
	}

	enable_interrupt();
}

void Architecture::change_process_father(Process* pe, Process* pere){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getPParent()==pe){
			p->setPParent(pere);
		}

		p=pn;
	}
}

void Architecture::destroy_all_zombie(){
	Process* p=plist;
	Process* pn=NULL;
	while (p!=NULL){
		pn=p->getPNext();
		if (p->getState()==ZOMBIE && p->getPid()!=1){
			destroy_process(p);
			delete p;
		}

		p=pn;
	}
}

/* Set the syscall arguments */
void Architecture::setParam(u32 ret, u32 ret1, u32 ret2, u32 ret3,u32 ret4){
	ret_reg[0]=ret;
	ret_reg[1]=ret1;
	ret_reg[2]=ret2;
	ret_reg[3]=ret3;
	ret_reg[4]=ret4;
}

/* Enable the interruption */
void Architecture::enable_interrupt(){
	asm ("sti");
}

/* Disable the interruption */
void Architecture::disable_interrupt(){
	asm ("cli");
}

/* Get a syscall argument */
u32	Architecture::getArg(u32 n){
	if (n<5)
		return ret_reg[n];
	else
		return 0;
}

/* Set the return value of syscall */
void Architecture::setRet(u32 ret){
	stack_ptr[14] = ret;
}
<|endoftext|>


<commit_before>// This file is part of BlueSky
//
// BlueSky is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "py_bs_log.h"
#include "py_bs_exports.h"
#include "py_bs_object_base.h"
#include "bs_kernel.h"

#include <bs_exception.h>
#include <boost/python/call_method.hpp>
#include <boost/python/enum.hpp>

using namespace boost::python;

namespace blue_sky {
namespace python {

BS_API const sp_channel &bs_end2(const sp_channel &r) {
		//r.lock()->set_can_output(true);
		//r.lock()->send_to_subscribers();
		return r;
}

py_bs_log::py_bs_log()
	: //py_bs_messaging(sp_log(new bs_log(give_log::Instance())))
	l(BS_KERNEL.get_log ())
{}

//py_bs_channel *py_bs_log::get(const std::string &name_) const {
//	return new py_bs_channel(l[name_]);
//}
//
//const sp_channel& py_bs_log::operator[](const std::string &name_) const {
//	return l[name_];
//}

py_bs_channel py_bs_log::add_channel(const py_bs_channel &ch) {
	return py_bs_channel(l.add_channel(ch.c));
}

bool py_bs_log::rem_channel(const std::string &ch_name) {
	return l.rem_channel(ch_name);
}

void stream_wrapper::write(const std::string &str) const {
	boost::python::call_method<void>(obj.ptr(), "write", str);
}

// void py_stream::write(const std::string &str) const {
// 	try {
// 		if (override f = this->get_override("write"))
// 			f(str);
// 		else
// 			BSERROR << "Function write does not exists, or is not correct!" << bs_end;
// 	}
// 	catch(...) {
// 		throw bs_exception("py_stream","May be member function \"void write(const std::string&) const\" is not overriden!");
// 	}
// }

py_bs_channel::py_bs_channel(const std::string &a) : c(new bs_channel(a)),auto_newline(true) {}
py_bs_channel::py_bs_channel(const sp_channel &s) : c(s),auto_newline(true) {}

void py_bs_channel::write(const char *str) const {
	//if (auto_newline)
	//	*c.lock() << str << bs_end;
	//else
	//	bs_end2(*c.lock() << str);
}

bool py_bs_channel::attach(const py_stream &s) const {
	return c.lock()->attach(s.spstream);
}

bool py_bs_channel::detach(const py_stream &s) const {
	return c.lock()->detach(s.spstream);
}

std::string py_bs_channel::get_name() const {
	return c.lock()->get_name();
}

void py_bs_channel::set_output_time() const {
	c.lock()->set_output_time();
}

void py_bs_channel::set_wait_end() const {
	//c.lock()->set_wait_end();
}

void py_bs_channel::set_auto_newline(bool nl = false) {
	auto_newline = nl;
}

py_thread_log::py_thread_log() : l(BS_KERNEL.get_tlog ()) {}

py_bs_channel py_thread_log::add_log_channel(const std::string &name) {
	return py_bs_channel(l.add_log_channel(name));
}

bool py_thread_log::add_log_stream(const std::string &ch_name, const py_stream &pstream) {
	return l.add_log_stream(ch_name,pstream.spstream);
}

bool py_thread_log::rem_log_channel(const std::string &ch_name) {
	return l.rem_log_channel(ch_name);
}

bool py_thread_log::rem_log_stream(const std::string &ch_name, const py_stream &pstream) {
	return l.rem_log_stream(ch_name,pstream.spstream);
}

//const py_bs_channel *py_thread_log::get(const std::string &ch_name) const {
//	return new py_bs_channel(l[ch_name]);
//}

//const sp_channel &py_thread_log::operator[](const std::string &ch_name) const {
//	return l[ch_name];
//}

bool py_bs_log::subscribe(int signal_code, const python_slot& slot) const {
	return l.subscribe(signal_code,slot.spslot);
}

bool py_bs_log::unsubscribe(int signal_code, const python_slot& slot) const {
	return l.unsubscribe(signal_code,slot.spslot);
}

ulong py_bs_log::num_slots(int signal_code) const {
	return l.num_slots(signal_code);
}

bool py_bs_log::fire_signal(int signal_code, const py_objbase* param) const {
	return l.fire_signal(signal_code,param->sp);
}

std::vector< int > py_bs_log::get_signal_list() const {
	return l.get_signal_list();
}

//std::list< std::string > py_bs_log::get_ch_list() const {
//	return l.channel_list();
//}

void py_export_log() {
	class_<py_bs_log, /*bases<py_bs_messaging>,*/ noncopyable>("log")
		.def("add_channel",&py_bs_log::add_channel)
		.def("rem_channel",&py_bs_log::rem_channel)
		//.def("get",&py_bs_log::get, return_value_policy<manage_new_object>())
		.def("subscribe",&py_bs_log::subscribe)
		.def("unsubscribe",&py_bs_log::unsubscribe)
		.def("num_slots",&py_bs_log::num_slots)
		.def("fire_signal",&py_bs_log::fire_signal)
		.def("get_signal_list",&py_bs_log::get_signal_list)
		//.def("get_ch_list",&py_bs_log::get_ch_list)
	;

	class_<py_thread_log, noncopyable>("thread_log")
		.def("add_log_channel",&py_thread_log::add_log_channel)
		.def("rem_log_channel",&py_thread_log::rem_log_channel)
		.def("add_log_stream",&py_thread_log::add_log_stream)
		.def("rem_log_stream",&py_thread_log::rem_log_stream)
		//.def("get",&py_thread_log::get, return_value_policy<manage_new_object>())
    ;

	//class_<py_stream, noncopyable>("stream")
		//.def("write",pure_virtual(&bs_stream::write));

	class_<stream_wrapper, noncopyable>("stream", init<const std::string &, const boost::python::object&>())
		.def("write", &stream_wrapper::write);

	class_<py_stream, noncopyable>("wstream", init<const std::string &, const boost::python::object&>());

	class_<py_bs_channel>("channel", init <const std::string &> ())
		.def(init<std::string>())
		.def("attach",&py_bs_channel::attach)
		.def("detach",&py_bs_channel::detach)
		.def("get_name",&py_bs_channel::get_name)
		.def("write",&py_bs_channel::write)
		.def("set_output_time",&py_bs_channel::set_output_time)
		.def("set_wait_end",&py_bs_channel::set_wait_end)
		.def("set_auto_newline",&py_bs_channel::set_auto_newline);

	enum_<bs_log::signal_codes>("log_signal_codes")
		.value("log_channel_added",bs_log::log_channel_added)
		.value("log_channel_removed",bs_log::log_channel_removed)
		.export_values();
}

}	//namespace blue_sky::python
}	//namespace blue_sky
<commit_msg>Fix: Output in log in python was broken<commit_after>// This file is part of BlueSky
//
// BlueSky is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// BlueSky is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with BlueSky; if not, see <http://www.gnu.org/licenses/>.

#include "py_bs_log.h"
#include "py_bs_exports.h"
#include "py_bs_object_base.h"
#include "bs_kernel.h"

#include <bs_exception.h>
#include <boost/python/call_method.hpp>
#include <boost/python/enum.hpp>

using namespace boost::python;

namespace blue_sky {
namespace python {

py_bs_log::py_bs_log()
	: //py_bs_messaging(sp_log(new bs_log(give_log::Instance())))
	l(BS_KERNEL.get_log ())
{}

//py_bs_channel *py_bs_log::get(const std::string &name_) const {
//	return new py_bs_channel(l[name_]);
//}
//
//const sp_channel& py_bs_log::operator[](const std::string &name_) const {
//	return l[name_];
//}

py_bs_channel py_bs_log::add_channel(const py_bs_channel &ch) {
	return py_bs_channel(l.add_channel(ch.c));
}

bool py_bs_log::rem_channel(const std::string &ch_name) {
	return l.rem_channel(ch_name);
}

void stream_wrapper::write(const std::string &str) const {
	boost::python::call_method<void>(obj.ptr(), "write", str);
}

// void py_stream::write(const std::string &str) const {
// 	try {
// 		if (override f = this->get_override("write"))
// 			f(str);
// 		else
// 			BSERROR << "Function write does not exists, or is not correct!" << bs_end;
// 	}
// 	catch(...) {
// 		throw bs_exception("py_stream","May be member function \"void write(const std::string&) const\" is not overriden!");
// 	}
// }

py_bs_channel::py_bs_channel(const std::string &a) : c(new bs_channel(a)),auto_newline(true) {}
py_bs_channel::py_bs_channel(const sp_channel &s) : c(s),auto_newline(true) {}

void py_bs_channel::write(const char *str) const {
  locked_channel (c, __FILE__, __LINE__) << str << bs_end;
}

bool py_bs_channel::attach(const py_stream &s) const {
	return c.lock()->attach(s.spstream);
}

bool py_bs_channel::detach(const py_stream &s) const {
	return c.lock()->detach(s.spstream);
}

std::string py_bs_channel::get_name() const {
	return c.lock()->get_name();
}

void py_bs_channel::set_output_time() const {
	c.lock()->set_output_time();
}

py_thread_log::py_thread_log() : l(BS_KERNEL.get_tlog ()) {}

py_bs_channel py_thread_log::add_log_channel(const std::string &name) {
	return py_bs_channel(l.add_log_channel(name));
}

bool py_thread_log::add_log_stream(const std::string &ch_name, const py_stream &pstream) {
	return l.add_log_stream(ch_name,pstream.spstream);
}

bool py_thread_log::rem_log_channel(const std::string &ch_name) {
	return l.rem_log_channel(ch_name);
}

bool py_thread_log::rem_log_stream(const std::string &ch_name, const py_stream &pstream) {
	return l.rem_log_stream(ch_name,pstream.spstream);
}

//const py_bs_channel *py_thread_log::get(const std::string &ch_name) const {
//	return new py_bs_channel(l[ch_name]);
//}

//const sp_channel &py_thread_log::operator[](const std::string &ch_name) const {
//	return l[ch_name];
//}

bool py_bs_log::subscribe(int signal_code, const python_slot& slot) const {
	return l.subscribe(signal_code,slot.spslot);
}

bool py_bs_log::unsubscribe(int signal_code, const python_slot& slot) const {
	return l.unsubscribe(signal_code,slot.spslot);
}

ulong py_bs_log::num_slots(int signal_code) const {
	return l.num_slots(signal_code);
}

bool py_bs_log::fire_signal(int signal_code, const py_objbase* param) const {
	return l.fire_signal(signal_code,param->sp);
}

std::vector< int > py_bs_log::get_signal_list() const {
	return l.get_signal_list();
}

//std::list< std::string > py_bs_log::get_ch_list() const {
//	return l.channel_list();
//}

void py_export_log() {
	class_<py_bs_log, /*bases<py_bs_messaging>,*/ noncopyable>("log")
		.def("add_channel",&py_bs_log::add_channel)
		.def("rem_channel",&py_bs_log::rem_channel)
		//.def("get",&py_bs_log::get, return_value_policy<manage_new_object>())
		.def("subscribe",&py_bs_log::subscribe)
		.def("unsubscribe",&py_bs_log::unsubscribe)
		.def("num_slots",&py_bs_log::num_slots)
		.def("fire_signal",&py_bs_log::fire_signal)
		.def("get_signal_list",&py_bs_log::get_signal_list)
		//.def("get_ch_list",&py_bs_log::get_ch_list)
	;

	class_<py_thread_log, noncopyable>("thread_log")
		.def("add_log_channel",&py_thread_log::add_log_channel)
		.def("rem_log_channel",&py_thread_log::rem_log_channel)
		.def("add_log_stream",&py_thread_log::add_log_stream)
		.def("rem_log_stream",&py_thread_log::rem_log_stream)
		//.def("get",&py_thread_log::get, return_value_policy<manage_new_object>())
    ;

	//class_<py_stream, noncopyable>("stream")
		//.def("write",pure_virtual(&bs_stream::write));

	class_<stream_wrapper, noncopyable>("stream", init<const std::string &, const boost::python::object&>())
		.def("write", &stream_wrapper::write);

	class_<py_stream, noncopyable>("wstream", init<const std::string &, const boost::python::object&>());

	class_<py_bs_channel>("channel", init <const std::string &> ())
		.def(init<std::string>())
		.def("attach",&py_bs_channel::attach)
		.def("detach",&py_bs_channel::detach)
		.def("get_name",&py_bs_channel::get_name)
		.def("write",&py_bs_channel::write)
		.def("set_output_time",&py_bs_channel::set_output_time)
    ;

	enum_<bs_log::signal_codes>("log_signal_codes")
		.value("log_channel_added",bs_log::log_channel_added)
		.value("log_channel_removed",bs_log::log_channel_removed)
		.export_values();
}

}	//namespace blue_sky::python
}	//namespace blue_sky
<|endoftext|>


<commit_before>
#include "numerics/quadrature.hpp"

#include <limits>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/elementary_functions.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/is_near.hpp"
#include "testing_utilities/numerics_matchers.hpp"

namespace principia {
namespace numerics {
namespace quadrature {

using quantities::Angle;
using quantities::Cos;
using quantities::Sin;
using quantities::si::Radian;
using testing_utilities::AlmostEquals;
using testing_utilities::IsNear;
using testing_utilities::RelativeErrorFrom;
using testing_utilities::operator""_⑴;
using ::testing::AnyOf;
using ::testing::Eq;

class QuadratureTest : public ::testing::Test {};

TEST_F(QuadratureTest, Sin) {
  int evaluations = 0;
  auto const f = [&evaluations](Angle const x) {
    ++evaluations;
    return Sin(x);
  };
  auto const ʃf = (Cos(2.0 * Radian) - Cos(5.0 * Radian)) * Radian;
  EXPECT_THAT(GaussLegendre<1>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(10_⑴)));
  EXPECT_THAT(GaussLegendre<2>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.3_⑴)));
  EXPECT_THAT(GaussLegendre<3>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.0e-1_⑴)));
  EXPECT_THAT(GaussLegendre<4>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.4e-2_⑴)));
  EXPECT_THAT(GaussLegendre<5>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.6e-4_⑴)));
  EXPECT_THAT(GaussLegendre<6>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.1e-5_⑴)));
  EXPECT_THAT(GaussLegendre<7>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.6e-7_⑴)));
  EXPECT_THAT(GaussLegendre<8>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.7e-9_⑴)));
  EXPECT_THAT(GaussLegendre<9>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.8e-11_⑴)));
  EXPECT_THAT(GaussLegendre<10>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 2495, 2498));
  EXPECT_THAT(GaussLegendre<11>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 20));
  EXPECT_THAT(GaussLegendre<12>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 6, 7));
  EXPECT_THAT(GaussLegendre<13>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 0, 1));
  EXPECT_THAT(GaussLegendre<14>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 1, 2));
  EXPECT_THAT(GaussLegendre<15>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 3, 4));

  evaluations = 0;
  EXPECT_THAT(AutomaticClenshawCurtis(
                  f,
                  -2.0 * Radian,
                  5.0 * Radian,
                  /*max_relative_error=*/std::numeric_limits<double>::epsilon(),
                  /*max_points=*/std::nullopt),
              AlmostEquals(ʃf, 3, 4));
  EXPECT_THAT(evaluations, Eq(65));
}

TEST_F(QuadratureTest, Sin2) {
  auto const f = [](Angle const x) { return Sin(2 * x); };
  auto const ʃf = (Cos(4 * Radian) - Cos(10 * Radian)) / 2 * Radian;
  EXPECT_THAT(GaussLegendre<1>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(9.7_⑴)));
  EXPECT_THAT(GaussLegendre<2>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(7.6_⑴)));
  EXPECT_THAT(GaussLegendre<3>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(7.6_⑴)));
  EXPECT_THAT(GaussLegendre<4>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.4_⑴)));
  EXPECT_THAT(GaussLegendre<5>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.2e-1_⑴)));
  EXPECT_THAT(GaussLegendre<6>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.6e-2_⑴)));
  EXPECT_THAT(GaussLegendre<7>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.5e-3_⑴)));
  EXPECT_THAT(GaussLegendre<8>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.0e-4_⑴)));
  EXPECT_THAT(GaussLegendre<9>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.5e-6_⑴)));
  EXPECT_THAT(GaussLegendre<10>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.9e-7_⑴)));;
  EXPECT_THAT(GaussLegendre<11>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.1e-9_⑴)));
  EXPECT_THAT(GaussLegendre<12>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(1.9e-10_⑴)));
  EXPECT_THAT(GaussLegendre<13>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.7e-12_⑴)));
  EXPECT_THAT(GaussLegendre<14>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 422, 425));
  EXPECT_THAT(GaussLegendre<15>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 36, 50));
  EXPECT_THAT(GaussLegendre<16>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 152, 159));
}

TEST_F(QuadratureTest, Sin10) {
  int evaluations = 0;
  auto const f = [&evaluations](Angle const x) {
    ++evaluations;
    return Sin(10 * x);
  };
  auto const ʃf = (Cos(20 * Radian) - Cos(50 * Radian)) / 10 * Radian;
  EXPECT_THAT(AutomaticClenshawCurtis(
                  f,
                  -2.0 * Radian,
                  5.0 * Radian,
                  /*max_relative_error=*/std::numeric_limits<double>::epsilon(),
                  /*max_points=*/std::nullopt),
              AlmostEquals(ʃf, 2, 20));
  EXPECT_THAT(evaluations, AnyOf(Eq(65537), Eq(262145)));
}

}  // namespace quadrature
}  // namespace numerics
}  // namespace principia
<commit_msg>Adjust number of iterations for Linux and macOS.<commit_after>
#include "numerics/quadrature.hpp"

#include <limits>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "quantities/elementary_functions.hpp"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/is_near.hpp"
#include "testing_utilities/numerics_matchers.hpp"

namespace principia {
namespace numerics {
namespace quadrature {

using quantities::Angle;
using quantities::Cos;
using quantities::Sin;
using quantities::si::Radian;
using testing_utilities::AlmostEquals;
using testing_utilities::IsNear;
using testing_utilities::RelativeErrorFrom;
using testing_utilities::operator""_⑴;
using ::testing::AnyOf;
using ::testing::Eq;

class QuadratureTest : public ::testing::Test {};

TEST_F(QuadratureTest, Sin) {
  int evaluations = 0;
  auto const f = [&evaluations](Angle const x) {
    ++evaluations;
    return Sin(x);
  };
  auto const ʃf = (Cos(2.0 * Radian) - Cos(5.0 * Radian)) * Radian;
  EXPECT_THAT(GaussLegendre<1>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(10_⑴)));
  EXPECT_THAT(GaussLegendre<2>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.3_⑴)));
  EXPECT_THAT(GaussLegendre<3>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.0e-1_⑴)));
  EXPECT_THAT(GaussLegendre<4>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.4e-2_⑴)));
  EXPECT_THAT(GaussLegendre<5>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.6e-4_⑴)));
  EXPECT_THAT(GaussLegendre<6>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.1e-5_⑴)));
  EXPECT_THAT(GaussLegendre<7>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.6e-7_⑴)));
  EXPECT_THAT(GaussLegendre<8>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.7e-9_⑴)));
  EXPECT_THAT(GaussLegendre<9>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.8e-11_⑴)));
  EXPECT_THAT(GaussLegendre<10>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 2495, 2498));
  EXPECT_THAT(GaussLegendre<11>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 20));
  EXPECT_THAT(GaussLegendre<12>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 6, 7));
  EXPECT_THAT(GaussLegendre<13>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 0, 1));
  EXPECT_THAT(GaussLegendre<14>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 1, 2));
  EXPECT_THAT(GaussLegendre<15>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 3, 4));

  evaluations = 0;
  EXPECT_THAT(AutomaticClenshawCurtis(
                  f,
                  -2.0 * Radian,
                  5.0 * Radian,
                  /*max_relative_error=*/std::numeric_limits<double>::epsilon(),
                  /*max_points=*/std::nullopt),
              AlmostEquals(ʃf, 3, 4));
  EXPECT_THAT(evaluations, Eq(65));
}

TEST_F(QuadratureTest, Sin2) {
  auto const f = [](Angle const x) { return Sin(2 * x); };
  auto const ʃf = (Cos(4 * Radian) - Cos(10 * Radian)) / 2 * Radian;
  EXPECT_THAT(GaussLegendre<1>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(9.7_⑴)));
  EXPECT_THAT(GaussLegendre<2>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(7.6_⑴)));
  EXPECT_THAT(GaussLegendre<3>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(7.6_⑴)));
  EXPECT_THAT(GaussLegendre<4>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.4_⑴)));
  EXPECT_THAT(GaussLegendre<5>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.2e-1_⑴)));
  EXPECT_THAT(GaussLegendre<6>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(4.6e-2_⑴)));
  EXPECT_THAT(GaussLegendre<7>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.5e-3_⑴)));
  EXPECT_THAT(GaussLegendre<8>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.0e-4_⑴)));
  EXPECT_THAT(GaussLegendre<9>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.5e-6_⑴)));
  EXPECT_THAT(GaussLegendre<10>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(2.9e-7_⑴)));;
  EXPECT_THAT(GaussLegendre<11>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(8.1e-9_⑴)));
  EXPECT_THAT(GaussLegendre<12>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(1.9e-10_⑴)));
  EXPECT_THAT(GaussLegendre<13>(f, -2.0 * Radian, 5.0 * Radian),
              RelativeErrorFrom(ʃf, IsNear(3.7e-12_⑴)));
  EXPECT_THAT(GaussLegendre<14>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 422, 425));
  EXPECT_THAT(GaussLegendre<15>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 36, 50));
  EXPECT_THAT(GaussLegendre<16>(f, -2.0 * Radian, 5.0 * Radian),
              AlmostEquals(ʃf, 152, 159));
}

TEST_F(QuadratureTest, Sin10) {
  int evaluations = 0;
  auto const f = [&evaluations](Angle const x) {
    ++evaluations;
    return Sin(10 * x);
  };
  auto const ʃf = (Cos(20 * Radian) - Cos(50 * Radian)) / 10 * Radian;
  EXPECT_THAT(AutomaticClenshawCurtis(
                  f,
                  -2.0 * Radian,
                  5.0 * Radian,
                  /*max_relative_error=*/std::numeric_limits<double>::epsilon(),
                  /*max_points=*/std::nullopt),
              AlmostEquals(ʃf, 2, 20));
  EXPECT_THAT(evaluations, AnyOf(Eq(32769), Eq(65537), Eq(262145), Eq(524289)));
}

}  // namespace quadrature
}  // namespace numerics
}  // namespace principia
<|endoftext|>


<commit_before>#include "HalideRuntime.h"

// Structs are annoying to deal with from within Halide Stmts. These
// utility functions are for dealing with buffer_t in that
// context. They are not intended for use outside of Halide code, and
// not exposed in HalideRuntime.h. The symbols are private to the
// module and should be inlined and then stripped. Definitions here
// are repeated in CodeGen_C.cpp, so changes here should be reflected
// there too.

extern "C" {

__attribute__((always_inline, weak))
uint8_t *_halide_buffer_get_host(const buffer_t *buf) {
    return buf->host;
}

__attribute__((always_inline, weak))
uint64_t _halide_buffer_get_dev(const buffer_t *buf) {
    return buf->dev;
}

__attribute__((always_inline, weak))
int _halide_buffer_get_min(const buffer_t *buf, int d) {
    return buf->min[d];
}

__attribute__((always_inline, weak))
int _halide_buffer_get_max(const buffer_t *buf, int d) {
    return buf->min[d] + buf->extent[d] - 1;
}

__attribute__((always_inline, weak))
bool _halide_buffer_get_host_dirty(buffer_t *buf) {
    return buf->host_dirty;
}

__attribute__((always_inline, weak))
bool _halide_buffer_get_dev_dirty(buffer_t *buf) {
    return buf->dev_dirty;
}

__attribute__((always_inline, weak))
int _halide_buffer_set_host_dirty(buffer_t *buf, bool val) {
    buf->host_dirty = val;
    return 0;
}

__attribute__((always_inline, weak))
int _halide_buffer_set_dev_dirty(buffer_t *buf, bool val) {
    buf->dev_dirty = val;
    return 0;
}

__attribute__((always_inline, weak))
buffer_t *_halide_buffer_init(buffer_t *dst, uint8_t *host, uint64_t dev, int /*type_code*/, int type_bits, int dimensions,
                              const int *min, const int *extent, const int *stride, bool host_dirty, bool dev_dirty) {
    dst->host = host;
    dst->dev = dev;
    dst->elem_size = (type_bits + 7) / 8;
    dst->host_dirty = host_dirty;
    dst->dev_dirty = dev_dirty;
    for (int i = 0; i < dimensions; i++) {
        dst->min[i] = min[i];
        dst->extent[i] = extent[i];
        dst->stride[i] = stride[i];
    }
    for (int i = dimensions; i < 4; i++) {
        dst->min[i] = 0;
        dst->extent[i] = 0;
        dst->stride[i] = 0;
    }
    return dst;
}

}
<commit_msg>Making arguments const for new buffer_get_*<commit_after>#include "HalideRuntime.h"

// Structs are annoying to deal with from within Halide Stmts. These
// utility functions are for dealing with buffer_t in that
// context. They are not intended for use outside of Halide code, and
// not exposed in HalideRuntime.h. The symbols are private to the
// module and should be inlined and then stripped. Definitions here
// are repeated in CodeGen_C.cpp, so changes here should be reflected
// there too.

extern "C" {

__attribute__((always_inline, weak))
uint8_t *_halide_buffer_get_host(const buffer_t *buf) {
    return buf->host;
}

__attribute__((always_inline, weak))
uint64_t _halide_buffer_get_dev(const buffer_t *buf) {
    return buf->dev;
}

__attribute__((always_inline, weak))
int _halide_buffer_get_min(const buffer_t *buf, int d) {
    return buf->min[d];
}

__attribute__((always_inline, weak))
int _halide_buffer_get_max(const buffer_t *buf, int d) {
    return buf->min[d] + buf->extent[d] - 1;
}

__attribute__((always_inline, weak))
bool _halide_buffer_get_host_dirty(const buffer_t *buf) {
    return buf->host_dirty;
}

__attribute__((always_inline, weak))
bool _halide_buffer_get_dev_dirty(const buffer_t *buf) {
    return buf->dev_dirty;
}

__attribute__((always_inline, weak))
int _halide_buffer_set_host_dirty(buffer_t *buf, bool val) {
    buf->host_dirty = val;
    return 0;
}

__attribute__((always_inline, weak))
int _halide_buffer_set_dev_dirty(buffer_t *buf, bool val) {
    buf->dev_dirty = val;
    return 0;
}

__attribute__((always_inline, weak))
buffer_t *_halide_buffer_init(buffer_t *dst, uint8_t *host, uint64_t dev, int /*type_code*/, int type_bits, int dimensions,
                              const int *min, const int *extent, const int *stride, bool host_dirty, bool dev_dirty) {
    dst->host = host;
    dst->dev = dev;
    dst->elem_size = (type_bits + 7) / 8;
    dst->host_dirty = host_dirty;
    dst->dev_dirty = dev_dirty;
    for (int i = 0; i < dimensions; i++) {
        dst->min[i] = min[i];
        dst->extent[i] = extent[i];
        dst->stride[i] = stride[i];
    }
    for (int i = dimensions; i < 4; i++) {
        dst->min[i] = 0;
        dst->extent[i] = 0;
        dst->stride[i] = 0;
    }
    return dst;
}

}
<|endoftext|>


<commit_before>#include <locale>
#include <scope_macro.h>
#include <str_util.h>
#include <shl_exception.h>

namespace shl {

string expand_macro(const string& token, const string& text, const Match& match) {
    if (token[0] != '$') return token;

    if (token[1] == '{') {
        if (token.back() != '}') throw InvalidSourceException("scope macro not properly closed");
        string num_command = token.substr(2, token.size() - 3);
        vector<string> num_command_pair = strtok(num_command, [](char c) { return c == ':';});

        int group_num = atoi(num_command_pair[0].c_str());
        if (group_num >= match.size()) throw InvalidSourceException("capture group number in scope name out of range");

        string expanded = match[group_num].substr(text);

        std::locale loc;
        if (num_command_pair[1] == "/downcase") {
            return tolower(expanded, loc);
        } else if (num_command_pair[1] == "/upcase") {
            return std::toupper(expanded, loc);
        } else {
            throw InvalidSourceException("unknown expansion function " + num_command_pair[1]);
        }

    } else {
        int group_num = atoi(token.c_str() + 1);
        if (group_num >= match.size()) throw InvalidSourceException("capture group number in scope name out of range");
        return match[group_num].substr(text);
    }
}

}
<commit_msg>fix bugs<commit_after>#include <scope_macro.h>
#include <str_util.h>
#include <shl_exception.h>

namespace shl {

static string lower(const string& str) {
   string tmp = str;
   for(size_t pos = 0; pos < tmp.size(); ++pos) tmp[pos] = tolower(tmp[pos]);

   return tmp;
}

static string upper(const string& str) {
   string tmp = str;
   for(size_t pos = 0; pos < tmp.size(); ++pos) tmp[pos] = toupper(tmp[pos]);

   return tmp;
}

string expand_macro(const string& token, const string& text, const Match& match) {
    if (token[0] != '$') return token;

    if (token[1] == '{') {
        if (token.back() != '}') throw InvalidSourceException("scope macro not properly closed");
        string num_command = token.substr(2, token.size() - 3);
        vector<string> num_command_pair = strtok(num_command, [](char c) { return c == ':';});

        int group_num = atoi(num_command_pair[0].c_str());
        if (group_num >= match.size()) throw InvalidSourceException("capture group number in scope name out of range");

        string expanded = match[group_num].substr(text);
        if (num_command_pair.size() == 1) return expanded;

        if (num_command_pair[1] == "/downcase") {
            return lower(expanded);
        } else if (num_command_pair[1] == "/upcase") {
            return upper(expanded);
        } else {
            throw InvalidSourceException("unknown expansion function " + num_command_pair[1]);
        }

    } else {
        int group_num = atoi(token.c_str() + 1);
        if (group_num >= match.size()) throw InvalidSourceException("capture group number in scope name out of range");
        return match[group_num].substr(text);
    }
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: brwhead.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 21:08:04 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that 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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <svtools/brwhead.hxx>
#include <svtools/brwbox.hxx>

#ifndef GCC
#endif

//===================================================================

BrowserHeader::BrowserHeader( BrowseBox* pParent, WinBits nWinBits )
 :HeaderBar( pParent, nWinBits )
 ,_pBrowseBox( pParent )
{
    long nHeight = pParent->IsZoom() ? pParent->CalcZoom(pParent->GetTitleHeight()) : pParent->GetTitleHeight();

    SetPosSizePixel( Point( 0, 0),
                     Size( pParent->GetOutputSizePixel().Width(),
                           nHeight ) );
    Show();
}

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

void BrowserHeader::Command( const CommandEvent& rCEvt )
{
    if ( !GetCurItemId() && COMMAND_CONTEXTMENU == rCEvt.GetCommand() )
    {
        Point aPos( rCEvt.GetMousePosPixel() );
        if ( _pBrowseBox->IsFrozen(0) )
            aPos.X() += _pBrowseBox->GetColumnWidth(0);
        _pBrowseBox->GetDataWindow().Command( CommandEvent(
                Point( aPos.X(), aPos.Y() - GetSizePixel().Height() ),
                COMMAND_CONTEXTMENU, rCEvt.IsMouseEvent() ) );
    }
}

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

void BrowserHeader::Select()
{
    HeaderBar::Select();
}

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

void BrowserHeader::EndDrag()
{
    // call before other actions, it looks more nice in most cases
    HeaderBar::EndDrag();
    Update();

    // not aborted?
    USHORT nId = GetCurItemId();
    if ( nId )
    {
        // Handle-Column?
        if ( nId == USHRT_MAX-1 )
            nId = 0;

        if ( !IsItemMode() )
        {
            // column resize
            _pBrowseBox->SetColumnWidth( nId, GetItemSize( nId ) );
            _pBrowseBox->ColumnResized( nId );
            SetItemSize( nId, _pBrowseBox->GetColumnWidth( nId ) );
        }
        else
        {
            // column drag
            // Hat sich die Position eigentlich veraendert
            // Handlecolumn beruecksichtigen
            USHORT nOldPos = _pBrowseBox->GetColumnPos(nId),
                nNewPos = GetItemPos( nId );

            if (!_pBrowseBox->GetColumnId(0))   // Handle
                nNewPos++;

            if (nOldPos != nNewPos)
            {
                _pBrowseBox->SetColumnPos( nId, nNewPos );
                _pBrowseBox->ColumnMoved( nId );
            }
        }
    }
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS changefileheader (1.7.246); FILE MERGED 2008/03/31 13:01:20 rt 1.7.246.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: brwhead.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <svtools/brwhead.hxx>
#include <svtools/brwbox.hxx>

#ifndef GCC
#endif

//===================================================================

BrowserHeader::BrowserHeader( BrowseBox* pParent, WinBits nWinBits )
 :HeaderBar( pParent, nWinBits )
 ,_pBrowseBox( pParent )
{
    long nHeight = pParent->IsZoom() ? pParent->CalcZoom(pParent->GetTitleHeight()) : pParent->GetTitleHeight();

    SetPosSizePixel( Point( 0, 0),
                     Size( pParent->GetOutputSizePixel().Width(),
                           nHeight ) );
    Show();
}

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

void BrowserHeader::Command( const CommandEvent& rCEvt )
{
    if ( !GetCurItemId() && COMMAND_CONTEXTMENU == rCEvt.GetCommand() )
    {
        Point aPos( rCEvt.GetMousePosPixel() );
        if ( _pBrowseBox->IsFrozen(0) )
            aPos.X() += _pBrowseBox->GetColumnWidth(0);
        _pBrowseBox->GetDataWindow().Command( CommandEvent(
                Point( aPos.X(), aPos.Y() - GetSizePixel().Height() ),
                COMMAND_CONTEXTMENU, rCEvt.IsMouseEvent() ) );
    }
}

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

void BrowserHeader::Select()
{
    HeaderBar::Select();
}

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

void BrowserHeader::EndDrag()
{
    // call before other actions, it looks more nice in most cases
    HeaderBar::EndDrag();
    Update();

    // not aborted?
    USHORT nId = GetCurItemId();
    if ( nId )
    {
        // Handle-Column?
        if ( nId == USHRT_MAX-1 )
            nId = 0;

        if ( !IsItemMode() )
        {
            // column resize
            _pBrowseBox->SetColumnWidth( nId, GetItemSize( nId ) );
            _pBrowseBox->ColumnResized( nId );
            SetItemSize( nId, _pBrowseBox->GetColumnWidth( nId ) );
        }
        else
        {
            // column drag
            // Hat sich die Position eigentlich veraendert
            // Handlecolumn beruecksichtigen
            USHORT nOldPos = _pBrowseBox->GetColumnPos(nId),
                nNewPos = GetItemPos( nId );

            if (!_pBrowseBox->GetColumnId(0))   // Handle
                nNewPos++;

            if (nOldPos != nNewPos)
            {
                _pBrowseBox->SetColumnPos( nId, nNewPos );
                _pBrowseBox->ColumnMoved( nId );
            }
        }
    }
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before><commit_msg>sw: Prefix LinesAndTable member variables.<commit_after><|endoftext|>


<commit_before><commit_msg>coverity#705921 Dereference before null check<commit_after><|endoftext|>