<commit_before>#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>
#include <ClickEncoder.h>

#include "ad5541.h"
#include "adc.h"
#include "button.h"
#include "fan.h"
#include "setter.h"
#include "lm35.h"

// Hardware Configuration
#define LCD_IIC_ADDRESS      0x20
#define LCD_IIC_COLS         16
#define LCD_IIC_ROWS         2

#define ENCODER_PIN_1        A0
#define ENCODER_PIN_2        A1
#define ENCODER_SW_PIN       2
#define ENCODER_UPDATE_RATE  4

#define ADC_CS_PIN           8
#define DAC_CS_PIN           9

#define BUTTON_1_PIN         3
#define BUTTON_2_PIN         4
#define BUTTON_3_PIN         6
#define BUTTON_4_PIN         5

#define FAN_SW_PIN           7
#define LM35_PIN             A3

#define MAX_BUTTON           4

#define ADC_CURRENT_CHN      AD7190_CH_AIN2P_AINCOM
#define ADC_VOLTAGE_CHN      AD7190_CH_AIN1P_AINCOM

// Constants
const double VREF_VOLTAGE = 5000.0;  // mV

///////////////////////
// Devices
///////////////////////

// DAC
AD5541 ad5541(DAC_CS_PIN);

// ADC
ADConverter adc(ADC_CS_PIN,
                ADC_VOLTAGE_CHN,
                ADC_CURRENT_CHN,
                VREF_VOLTAGE);

// LCD
LiquidCrystal_I2C lcd(LCD_IIC_ADDRESS,
                      LCD_IIC_COLS,
                      LCD_IIC_ROWS);

// encoder
ClickEncoder encoder(ENCODER_PIN_1,
                     ENCODER_PIN_2,
                     ENCODER_SW_PIN,
                     ENCODER_UPDATE_RATE);

// Buttons
Button buttons[MAX_BUTTON] {
    BUTTON_1_PIN,
    BUTTON_2_PIN,
    BUTTON_3_PIN,
    BUTTON_4_PIN,
};

// FAN
FanController fan(FAN_SW_PIN);

// temperature sensor
LM35 lm35(LM35_PIN, VREF_VOLTAGE);

// Setter (max 15000mA)
Setter<15000> current_set_point;

//////////////////////////////
// Operations
//////////////////////////////

enum OPTERATION_STATE
{
    STATE_IDLE = 1,
    STATE_RUNNING = 2,
    STATE_CALIBRATION = 10,

    STATE_UNDEF = 99,
};

// Global Data
struct {

    // status
    OPTERATION_STATE state;
    uint32_t state_time;

    // page
    int page;

} g_cb { STATE_IDLE, 0, 0 };

// timer service
void timer_one_isr()
{
    encoder.service();
}

void UpdateButtons()
{
    for (int i = MAX_BUTTON; i > 0; i--) {
        buttons[i - 1].update();
    }
}

void UpdateCurrentVoltage()
{
    // update current data, no need for idle
    if (g_cb.state != STATE_IDLE) {
        adc.updateCurrent();
    }
    // update voltage
    adc.updateVoltage();
}

void UpdateTemperature()
{
    lm35.update();
}

void UpdateSensors()
{
    // update inputs
    UpdateButtons();

    // sensors
    UpdateCurrentVoltage();
    UpdateTemperature();
}

/// Display a double with Fixed length
void DisplayFixedDouble(double value, int width, int prec)
{
    char line[20];
    dtostrf(value, width, prec, line);
    int len = strlen(line);
    if (len > width) {
        // if we have longger value, truncate it
        line[width] = '\0';
    } else {
        // if the first one is space then we have leading spaces
        if (line[0] == ' ') {
            for (char* p = strchr(line, ' '); p; p = strchr(line, ' ')) {
                *p = '0';
            }
        }
    }
    lcd.print(line);
}

void UpdateDisplay()
{
    lcd.noCursor();

    // Display
    // Line 1 - Current Set Point, temperature:
    //   aa.aaaA ttt.ttC X
    lcd.setCursor(0, 0);
    DisplayFixedDouble(current_set_point.as_double(), 6, 3);
    lcd.print("A ");
    DisplayFixedDouble(lm35.getTemperature(), 5, 2);
    lcd.print("C ");
    // FIXME: print out status
    switch (g_cb.state) {
        case STATE_IDLE:
            lcd.print(" ");
            break;
        case STATE_RUNNING:
            lcd.print("R");
        default:
            lcd.print("?");
    }

    // Line 2 - Current Sensing, Voltage Sensing:
    //   ss.ssssA vvv.vvvV
    lcd.setCursor(0, 1);

    if (g_cb.page == 0) {
        DisplayFixedDouble(adc.readCurrent(), 6, 3);
        lcd.print("A ");
        DisplayFixedDouble(adc.readVoltage(), 6, 3);
        lcd.print("V ");
    } else if (g_cb.page == 1) {
        double wattage = adc.readVoltage() * adc.readCurrent();
        DisplayFixedDouble(wattage, 8, 4);
        lcd.print("W ");
        lcd.print(ad5541.getValue(), HEX);
        lcd.print("     ");
    }

    uint8_t bit = 5 - current_set_point.current_bit();
    if (bit < 3) {
        bit -= 1;
    }
    lcd.setCursor(bit, 0);
    lcd.cursor();

}

void ProcessControl()
{
    uint32_t now = millis();

    // temperature control
    if (lm35.getTemperature() > 40.0 && !fan.isOn()) {
        fan.turn_on();
    } else if (lm35.getTemperature() < 35.0 && fan.isOn()) {
        fan.turn_off();
    }

    if (buttons[1].isRaisingEdge()) {
        current_set_point.move_left();
    } else if (buttons[2].isRaisingEdge()) {
        current_set_point.move_right();
    }
    current_set_point.increase(encoder.getValue());

    if (buttons[3].isRaisingEdge()) {
        g_cb.page = (g_cb.page + 1) % 2;
    }

    // FIXME: change this to PID
    static uint32_t last;
    double e = current_set_point.as_double() - adc.readCurrent();
    if (e > -0.0007 && e < 0.0007) {
        e = 0.0; // dead band
    }
    double p_term = e * 300; // _kP
    // double i_term = e * (now - last) * 10;
    // double d_term = e / (now - last) * 20;
    // double pid_sum = p_term + i_term + d_term;
    last = now;
    double pid_sum = p_term * 10.0;

    if (buttons[0].isRaisingEdge()) {
        lcd.clear();
        lcd.home();
        lcd.print(current_set_point.as_double());
        lcd.print(" ");
        lcd.print(adc.readCurrent());
        lcd.print(" ");
        lcd.print(pid_sum);
        lcd.setCursor(0, 1);
        lcd.print(ad5541.getValue(), HEX);
        delay(2000);
    }

    int32_t set_point = ad5541.getValue();
    set_point += (int32_t)pid_sum;
    set_point = constrain(set_point, AD5541_CODE_LOW, AD5541_CODE_HIGH);

    // State change event
    ClickEncoder::Button encoder_btn = encoder.getButton();
    if (g_cb.state == STATE_IDLE &&
        encoder_btn == ClickEncoder::Held &&
        g_cb.state_time + 3000.0 < now)
    {
        // IDLE -> RUNNING
        g_cb.state = STATE_RUNNING;
        g_cb.state_time = now;
        ad5541.setValue(set_point);
    }
    else if (g_cb.state == STATE_RUNNING)
    {
        if (encoder_btn == ClickEncoder::Clicked)
        {
            g_cb.state = STATE_IDLE;
            ad5541.setValue(0);
        }
        else if (ad5541.getValue() != set_point)
        {
            ad5541.setValue(set_point);
        }
    }
}

void setup()
{
    // initialize state to idle
    g_cb.state = STATE_IDLE;

    // LCD
    lcd.init();
    lcd.home();
    lcd.print("@DC Active Load@");
    lcd.setCursor(0, 1);
    lcd.print("       20170926");
    lcd.home();

    // SPI
    SPI.begin();

    // DAC
    ad5541.begin();
    ad5541.setValue(0);

    // Timer
    Timer1.initialize(1000);
    Timer1.attachInterrupt(timer_one_isr);

    // temperature
    lm35.init();

    // ADC
    adc.begin();
    while (!adc.detectDevice()) {
        lcd.clear();
        lcd.print("ADC ERROR");
        delay(300);
    }
    delay(10);
    adc.init();
    // FIXME: Calibration data should be gotten from EEPROM
    adc.setCalibData(AD7190_CONF_GAIN_1, 1.00080, 4.0);
    adc.setCalibData(AD7190_CONF_GAIN_8, 1.00243, -0.60);

    // Buttons
    buttons[0].init();
    buttons[1].init();
    buttons[2].init();
    buttons[3].init();

    // FAN
    fan.init();

    // get lcd ready for using information
    delay(2000);
    lcd.clear();
}

void loop()
{
    // Read Information
    UpdateSensors();
    // TODO: Controller logic
    ProcessControl();
    // Output:
    UpdateDisplay();
}

<commit_msg>Tuned a bit<commit_after>#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>
#include <ClickEncoder.h>

#include "ad5541.h"
#include "adc.h"
#include "button.h"
#include "fan.h"
#include "setter.h"
#include "lm35.h"

// Hardware Configuration
#define LCD_IIC_ADDRESS      0x20
#define LCD_IIC_COLS         16
#define LCD_IIC_ROWS         2

#define ENCODER_PIN_1        A0
#define ENCODER_PIN_2        A1
#define ENCODER_SW_PIN       2
#define ENCODER_UPDATE_RATE  4

#define ADC_CS_PIN           8
#define DAC_CS_PIN           9

#define BUTTON_1_PIN         3
#define BUTTON_2_PIN         4
#define BUTTON_3_PIN         6
#define BUTTON_4_PIN         5

#define FAN_SW_PIN           7
#define LM35_PIN             A3

#define MAX_BUTTON           4

#define ADC_CURRENT_CHN      AD7190_CH_AIN2P_AINCOM
#define ADC_VOLTAGE_CHN      AD7190_CH_AIN1P_AINCOM

// Constants
const double VREF_VOLTAGE = 5000.0;  // mV

///////////////////////
// Devices
///////////////////////

// DAC
AD5541 ad5541(DAC_CS_PIN);

// ADC
ADConverter adc(ADC_CS_PIN,
                ADC_VOLTAGE_CHN,
                ADC_CURRENT_CHN,
                VREF_VOLTAGE);

// LCD
LiquidCrystal_I2C lcd(LCD_IIC_ADDRESS,
                      LCD_IIC_COLS,
                      LCD_IIC_ROWS);

// encoder
ClickEncoder encoder(ENCODER_PIN_1,
                     ENCODER_PIN_2,
                     ENCODER_SW_PIN,
                     ENCODER_UPDATE_RATE);

// Buttons
Button buttons[MAX_BUTTON] {
    BUTTON_1_PIN,
    BUTTON_2_PIN,
    BUTTON_3_PIN,
    BUTTON_4_PIN,
};

// FAN
FanController fan(FAN_SW_PIN);

// temperature sensor
LM35 lm35(LM35_PIN, VREF_VOLTAGE);

// Setter (max 15000mA)
Setter<15000> current_set_point;

//////////////////////////////
// Operations
//////////////////////////////

enum OPTERATION_STATE
{
    STATE_IDLE = 1,
    STATE_RUNNING = 2,
    STATE_CALIBRATION = 10,

    STATE_UNDEF = 99,
};

// Global Data
struct {

    // status
    OPTERATION_STATE state;
    uint32_t state_time;

    // page
    int page;

} g_cb { STATE_IDLE, 0, 0 };

// timer service
void timer_one_isr()
{
    encoder.service();
}

void UpdateButtons()
{
    for (int i = MAX_BUTTON; i > 0; i--) {
        buttons[i - 1].update();
    }
}

void UpdateCurrentVoltage()
{
    // update current data, no need for idle
    if (g_cb.state != STATE_IDLE) {
        adc.updateCurrent();
    }
    // update voltage
    adc.updateVoltage();
}

void UpdateTemperature()
{
    lm35.update();
}

void UpdateSensors()
{
    // update inputs
    UpdateButtons();

    // sensors
    UpdateCurrentVoltage();
    UpdateTemperature();
}

/// Display a double with Fixed length
void DisplayFixedDouble(double value, int width, int prec)
{
    char line[20];
    dtostrf(value, width, prec, line);
    int len = strlen(line);
    if (len > width) {
        // if we have longger value, truncate it
        line[width] = '\0';
    } else {
        // if the first one is space then we have leading spaces
        if (line[0] == ' ') {
            for (char* p = strchr(line, ' '); p; p = strchr(line, ' ')) {
                *p = '0';
            }
        }
    }
    lcd.print(line);
}

void UpdateDisplay()
{
    lcd.noCursor();

    // Display
    // Line 1 - Current Set Point, temperature:
    //   aa.aaaA ttt.ttC X
    lcd.setCursor(0, 0);
    DisplayFixedDouble(current_set_point.as_double(), 6, 3);
    lcd.print("A ");
    DisplayFixedDouble(lm35.getTemperature(), 5, 2);
    lcd.print("C ");
    // FIXME: print out status
    switch (g_cb.state) {
        case STATE_IDLE:
            lcd.print(" ");
            break;
        case STATE_RUNNING:
            lcd.print("R");
        default:
            lcd.print("?");
    }

    // Line 2 - Current Sensing, Voltage Sensing:
    //   ss.ssssA vvv.vvvV
    lcd.setCursor(0, 1);

    if (g_cb.page == 0) {
        DisplayFixedDouble(adc.readCurrent(), 6, 3);
        lcd.print("A ");
        DisplayFixedDouble(adc.readVoltage(), 6, 3);
        lcd.print("V ");
    } else if (g_cb.page == 1) {
        double wattage = adc.readVoltage() * adc.readCurrent();
        DisplayFixedDouble(wattage, 8, 4);
        lcd.print("W ");
        lcd.print(ad5541.getValue(), HEX);
        lcd.print("     ");
    }

    uint8_t bit = 5 - current_set_point.current_bit();
    if (bit < 3) {
        bit -= 1;
    }
    lcd.setCursor(bit, 0);
    lcd.cursor();

}

void ProcessControl()
{
    uint32_t now = millis();

    // temperature control
    if (lm35.getTemperature() > 40.0 && !fan.isOn()) {
        fan.turn_on();
    } else if (lm35.getTemperature() < 35.0 && fan.isOn()) {
        fan.turn_off();
    }

    if (buttons[1].isRaisingEdge()) {
        current_set_point.move_left();
    } else if (buttons[2].isRaisingEdge()) {
        current_set_point.move_right();
    }
    current_set_point.increase(encoder.getValue());

    if (buttons[3].isRaisingEdge()) {
        g_cb.page = (g_cb.page + 1) % 2;
    }

    // FIXME: change this to PID
    static uint32_t last;
    double e = current_set_point.as_double() - adc.readCurrent();
    if (e > -0.0007 && e < 0.0007) {
        e = 0.0; // dead band
    }
    double p_term = e * 300; // _kP
    double i_term = e * (now - last) * 0.1;
    double d_term = e / (now - last) * 10;
    double pid_sum = p_term + i_term + d_term;
    pid_sum *= 10.0;
    last = now;

    if (buttons[0].isRaisingEdge()) {
        lcd.clear();
        lcd.home();
        lcd.print(current_set_point.as_double());
        lcd.print(" ");
        lcd.print(adc.readCurrent());
        lcd.print(" ");
        lcd.print(pid_sum);
        lcd.setCursor(0, 1);
        lcd.print(ad5541.getValue(), HEX);
        delay(2000);
    }

    int32_t set_point = ad5541.getValue();
    set_point += (int32_t)pid_sum;
    set_point = constrain(set_point, AD5541_CODE_LOW, AD5541_CODE_HIGH);

    // State change event
    ClickEncoder::Button encoder_btn = encoder.getButton();
    if (g_cb.state == STATE_IDLE &&
        encoder_btn == ClickEncoder::Held &&
        g_cb.state_time + 3000.0 < now)
    {
        // IDLE -> RUNNING
        g_cb.state = STATE_RUNNING;
        g_cb.state_time = now;
        ad5541.setValue(set_point);
    }
    else if (g_cb.state == STATE_RUNNING)
    {
        if (encoder_btn == ClickEncoder::Clicked)
        {
            g_cb.state = STATE_IDLE;
            ad5541.setValue(0);
        }
        else if (ad5541.getValue() != set_point)
        {
            ad5541.setValue(set_point);
        }
    }
}

void setup()
{
    // initialize state to idle
    g_cb.state = STATE_IDLE;

    // LCD
    lcd.init();
    lcd.home();
    lcd.print("@DC Active Load@");
    lcd.setCursor(0, 1);
    lcd.print("       20170926");
    lcd.home();

    // SPI
    SPI.begin();

    // DAC
    ad5541.begin();
    ad5541.setValue(0);

    // Timer
    Timer1.initialize(1000);
    Timer1.attachInterrupt(timer_one_isr);

    // temperature
    lm35.init();

    // ADC
    adc.begin();
    while (!adc.detectDevice()) {
        lcd.clear();
        lcd.print("ADC ERROR");
        delay(300);
    }
    delay(10);
    adc.init();
    // FIXME: Calibration data should be gotten from EEPROM
    adc.setCalibData(AD7190_CONF_GAIN_1, 1.00080, 4.0);
    adc.setCalibData(AD7190_CONF_GAIN_8, 1.00243, -0.60);

    // Buttons
    buttons[0].init();
    buttons[1].init();
    buttons[2].init();
    buttons[3].init();

    // FAN
    fan.init();

    // get lcd ready for using information
    delay(2000);
    lcd.clear();
}

void loop()
{
    // Read Information
    UpdateSensors();
    // TODO: Controller logic
    ProcessControl();
    // Output:
    UpdateDisplay();
}

<|endoftext|>


<commit_before><commit_msg>compile<commit_after><|endoftext|>


<commit_before>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): Deniz Erbilgin 2015
*/

#include "OTRadioLink_OTNullRadioLink.h"

namespace OTRadioLink {

OTNullRadioLink::OTNullRadioLink() {}

void OTNullRadioLink::getCapacity(uint8_t &queueRXMsgsMin, uint8_t &maxRXMsgLen, uint8_t &maxTXMsgLen) const
{
	queueRXMsgsMin = 0;
	maxRXMsgLen = 0;
	maxTXMsgLen = 0;
}

uint8_t OTNullRadioLink::getRXMsgsQueued() const
{
	return 0;
}

const volatile uint8_t *OTNullRadioLink::peekRXMsg(uint8_t &len) const
{
	len = 0;
	return NULL;
}
void OTNullRadioLink::removeRXMsg()
{

}

/**
 * @brief	If debug enabled, prints a string to serial
 * @param	buf		Pointer to a buffer
 */
bool OTNullRadioLink::sendRaw(const uint8_t *buf, uint8_t buflen, int8_t , TXpower , bool )
{
	// add zero termination
	uint8_t buffer[buflen+1];
	memcpy(buffer, buf, buflen);
	buffer[buflen] = '\0';
	// print if in debug mode
	DEBUG_SERIAL_PRINT_FLASHSTRING("Radio: ");
	DEBUG_SERIAL_PRINT((char *)buf);
	DEBUG_SERIAL_PRINTLN(); //FIXME Breaks unit tests
	return true;
}

} // OTNullRadioLink
<commit_msg>Removed DEBUG_SERIAL macros from OTNullRadioLink<commit_after>/*
The OpenTRV project licenses this file to you
under the Apache Licence, Version 2.0 (the "Licence");
you may not use this file except in compliance
with the Licence. You may obtain a copy of the Licence at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the Licence is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the Licence for the
specific language governing permissions and limitations
under the Licence.

Author(s) / Copyright (s): Deniz Erbilgin 2015
*/

#include "OTRadioLink_OTNullRadioLink.h"

namespace OTRadioLink {

OTNullRadioLink::OTNullRadioLink() {}

void OTNullRadioLink::getCapacity(uint8_t &queueRXMsgsMin, uint8_t &maxRXMsgLen, uint8_t &maxTXMsgLen) const
{
	queueRXMsgsMin = 0;
	maxRXMsgLen = 0;
	maxTXMsgLen = 0;
}

uint8_t OTNullRadioLink::getRXMsgsQueued() const
{
	return 0;
}

const volatile uint8_t *OTNullRadioLink::peekRXMsg(uint8_t &len) const
{
	len = 0;
	return NULL;
}
void OTNullRadioLink::removeRXMsg()
{

}

/**
 * @brief	If debug enabled, prints a string to serial
 * @param	buf		Pointer to a buffer
 */
bool OTNullRadioLink::sendRaw(const uint8_t *buf, uint8_t buflen, int8_t , TXpower , bool )
{
	// add zero termination
	uint8_t buffer[buflen+1];
	memcpy(buffer, buf, buflen);
	buffer[buflen] = '\0';
//	// print if in debug mode
//	DEBUG_SERIAL_PRINT_FLASHSTRING("Radio: ");
//	DEBUG_SERIAL_PRINT((char *)buf);
//	DEBUG_SERIAL_PRINTLN(); //FIXME Breaks unit tests
	return true;
}

} // OTNullRadioLink
<|endoftext|>


<commit_before>#pragma once

// ----------------------------------------------------------------------
// std::vector<std::string> split(const std::string& s, const std::string& delim, bool keep_empty = Split::KeepEmpty)
// Split string by delimiter into array of substrings
// std::vector<std::string> split(const std::string& s, const std::string& delim, bool keep_empty = Split::KeepEmpty)

// std::string strip(std::string source)
// Removes leading and trailing spaces from string
//
// ----------------------------------------------------------------------

#include <string>
#include <vector>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <iterator>
#include <utility>
#include <initializer_list>
#include <numeric>
#include <sstream>
#include <iomanip>

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

namespace string
{

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

    enum class Split { RemoveEmpty, KeepEmpty };

      // http://stackoverflow.com/questions/236129/split-a-string-in-c
    inline std::vector<std::string> split(std::string s, std::string delim, Split keep_empty = Split::KeepEmpty)
    {
        std::vector<std::string> result;
        if (! delim.empty()) {
            for (std::string::iterator substart = s.begin(), subend = substart; substart <= s.end(); substart = subend + static_cast<std::string::difference_type>(delim.size())) {
                subend = std::search(substart, s.end(), delim.begin(), delim.end());
                if (substart != subend || keep_empty == Split::KeepEmpty) {
                    result.push_back(std::string(substart, subend));
                }
            }
        }
        else {
            result.push_back(s);
        }
        return result;
    }

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

    inline std::string first_letter_of_words(std::string s)
    {
        std::string result;
        bool add = true;
        for (char c: s) {
            if (c == ' ') {
                add = true;
            }
            else if (add) {
                result.push_back(c);
                add = false;
            }
        }
        return result;
    }

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

    namespace _internal {
        template <typename InputIterator, typename Source> inline std::pair<InputIterator, InputIterator> strip_begin_end(Source& source)
        {
            auto predicate = [](auto c) { return std::isspace(c); }; // have to use lambda, other compiler cannot infer Predicate type from isspace
            auto e = std::find_if_not(source.rbegin(), source.rend(), predicate);
            auto b = std::find_if_not(source.begin(), e.base(), predicate);
            return std::make_pair(b, e.base());
        }
    } // namespace _internal

    // inline std::string& strip(std::string& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    // inline std::string strip(std::string&& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    inline std::string strip(std::string source)
    {
        auto be = _internal::strip_begin_end<std::string::const_iterator>(source);
        return std::string(be.first, be.second);
    }

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

    inline std::string replace(std::string source, std::string look_for, std::string replace_with)
    {
        std::string result;
        std::string::size_type start = 0;
        while (true) {
            const auto pos = source.find(look_for, start);
            if (pos != std::string::npos) {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.begin() + static_cast<std::string::difference_type>(pos));
                result.append(replace_with);
                start = pos + look_for.size();
            }
            else {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.end());
                break;
            }
        }
        return result;
    }

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

    // inline std::string& lower(std::string& source)
    // {
    //     std::transform(source.begin(), source.end(), source.begin(), ::tolower);
    //     return source;
    // }

    inline std::string lower(std::string source)
    {
        std::string result;
        std::transform(source.begin(), source.end(), std::back_inserter(result), ::tolower);
        return result;
    }

    // inline std::string& upper(std::string& source)
    // {
    //     std::transform(source.begin(), source.end(), source.begin(), ::toupper);
    //     return source;
    // }

    inline std::string upper(std::string source)
    {
        std::string result;
        std::transform(source.begin(), source.end(), std::back_inserter(result), ::toupper);
        return result;
    }

    // inline std::string& capitalize(std::string& source)
    // {
    //     if (!source.empty()) {
    //         std::transform(source.begin(), source.begin() + 1, source.begin(), ::toupper);
    //         std::transform(source.begin() + 1, source.end(), source.begin() + 1, ::tolower);
    //     }
    //     return source;
    // }

    inline std::string capitalize(std::string source)
    {
        std::string result;
        if (!source.empty()) {
            std::transform(source.begin(), source.begin() + 1, std::back_inserter(result), ::toupper);
            std::transform(source.begin() + 1, source.end(), std::back_inserter(result), ::tolower);
        }
        return result;
    }

    template <typename Iterator> inline std::string join(std::string separator, Iterator first, Iterator last)
    {
        std::string result;
        if (first != last) {
              // Note last - first below does not supported for std::set
              // const size_t resulting_size = std::accumulate(first, last, separator.size() * static_cast<size_t>(last - first - 1), [](size_t acc, const std::string& n) -> size_t { return acc + n.size(); });
              // result.reserve(resulting_size);
            for ( ; first != last; ++first) {
                if (!first->empty()) {
                    if (!result.empty())
                        result.append(separator);
                    result.append(*first);
                }
            }
        }
        return result;
    }

    template <typename Collection> inline std::string join(std::string separator, const Collection& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::initializer_list<std::string>&& parts)
    {
        std::vector<std::string> p{parts};
        return join(" ", std::begin(p), std::remove(std::begin(p), std::end(p), std::string()));
    }

    template <typename T> inline std::string to_hex_string(const T* aPtr)
    {
        std::stringstream stream;
        const void* value = reinterpret_cast<const void*>(aPtr);
        stream << value; // std::setfill('0') << std::setw(sizeof(value)*2) << std::hex << value;
        return stream.str();
    }

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

} // namespace string

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>to_hex_string for integral types<commit_after>#pragma once

// ----------------------------------------------------------------------
// std::vector<std::string> split(const std::string& s, const std::string& delim, bool keep_empty = Split::KeepEmpty)
// Split string by delimiter into array of substrings
// std::vector<std::string> split(const std::string& s, const std::string& delim, bool keep_empty = Split::KeepEmpty)

// std::string strip(std::string source)
// Removes leading and trailing spaces from string
//
// ----------------------------------------------------------------------

#include <string>
#include <vector>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <iterator>
#include <utility>
#include <initializer_list>
#include <numeric>
#include <sstream>
#include <iomanip>

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

namespace string
{

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

    enum class Split { RemoveEmpty, KeepEmpty };

      // http://stackoverflow.com/questions/236129/split-a-string-in-c
    inline std::vector<std::string> split(std::string s, std::string delim, Split keep_empty = Split::KeepEmpty)
    {
        std::vector<std::string> result;
        if (! delim.empty()) {
            for (std::string::iterator substart = s.begin(), subend = substart; substart <= s.end(); substart = subend + static_cast<std::string::difference_type>(delim.size())) {
                subend = std::search(substart, s.end(), delim.begin(), delim.end());
                if (substart != subend || keep_empty == Split::KeepEmpty) {
                    result.push_back(std::string(substart, subend));
                }
            }
        }
        else {
            result.push_back(s);
        }
        return result;
    }

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

    inline std::string first_letter_of_words(std::string s)
    {
        std::string result;
        bool add = true;
        for (char c: s) {
            if (c == ' ') {
                add = true;
            }
            else if (add) {
                result.push_back(c);
                add = false;
            }
        }
        return result;
    }

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

    namespace _internal {
        template <typename InputIterator, typename Source> inline std::pair<InputIterator, InputIterator> strip_begin_end(Source& source)
        {
            auto predicate = [](auto c) { return std::isspace(c); }; // have to use lambda, other compiler cannot infer Predicate type from isspace
            auto e = std::find_if_not(source.rbegin(), source.rend(), predicate);
            auto b = std::find_if_not(source.begin(), e.base(), predicate);
            return std::make_pair(b, e.base());
        }
    } // namespace _internal

    // inline std::string& strip(std::string& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    // inline std::string strip(std::string&& source)
    // {
    //     auto be = _internal::strip_begin_end<std::string::iterator>(source);
    //     source.erase(be.second, source.end()); // erase at the end first
    //     source.erase(source.begin(), be.first); // invalidates be.second!
    //     return source;
    // }

    inline std::string strip(std::string source)
    {
        auto be = _internal::strip_begin_end<std::string::const_iterator>(source);
        return std::string(be.first, be.second);
    }

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

    inline std::string replace(std::string source, std::string look_for, std::string replace_with)
    {
        std::string result;
        std::string::size_type start = 0;
        while (true) {
            const auto pos = source.find(look_for, start);
            if (pos != std::string::npos) {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.begin() + static_cast<std::string::difference_type>(pos));
                result.append(replace_with);
                start = pos + look_for.size();
            }
            else {
                result.append(source.begin() + static_cast<std::string::difference_type>(start), source.end());
                break;
            }
        }
        return result;
    }

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

    // inline std::string& lower(std::string& source)
    // {
    //     std::transform(source.begin(), source.end(), source.begin(), ::tolower);
    //     return source;
    // }

    inline std::string lower(std::string source)
    {
        std::string result;
        std::transform(source.begin(), source.end(), std::back_inserter(result), ::tolower);
        return result;
    }

    // inline std::string& upper(std::string& source)
    // {
    //     std::transform(source.begin(), source.end(), source.begin(), ::toupper);
    //     return source;
    // }

    inline std::string upper(std::string source)
    {
        std::string result;
        std::transform(source.begin(), source.end(), std::back_inserter(result), ::toupper);
        return result;
    }

    // inline std::string& capitalize(std::string& source)
    // {
    //     if (!source.empty()) {
    //         std::transform(source.begin(), source.begin() + 1, source.begin(), ::toupper);
    //         std::transform(source.begin() + 1, source.end(), source.begin() + 1, ::tolower);
    //     }
    //     return source;
    // }

    inline std::string capitalize(std::string source)
    {
        std::string result;
        if (!source.empty()) {
            std::transform(source.begin(), source.begin() + 1, std::back_inserter(result), ::toupper);
            std::transform(source.begin() + 1, source.end(), std::back_inserter(result), ::tolower);
        }
        return result;
    }

    template <typename Iterator> inline std::string join(std::string separator, Iterator first, Iterator last)
    {
        std::string result;
        if (first != last) {
              // Note last - first below does not supported for std::set
              // const size_t resulting_size = std::accumulate(first, last, separator.size() * static_cast<size_t>(last - first - 1), [](size_t acc, const std::string& n) -> size_t { return acc + n.size(); });
              // result.reserve(resulting_size);
            for ( ; first != last; ++first) {
                if (!first->empty()) {
                    if (!result.empty())
                        result.append(separator);
                    result.append(*first);
                }
            }
        }
        return result;
    }

    template <typename Collection> inline std::string join(std::string separator, const Collection& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::string separator, std::initializer_list<std::string>&& values)
    {
        return join(separator, std::begin(values), std::end(values));
    }

    inline std::string join(std::initializer_list<std::string>&& parts)
    {
        std::vector<std::string> p{parts};
        return join(" ", std::begin(p), std::remove(std::begin(p), std::end(p), std::string()));
    }

    template <typename T, typename = std::enable_if<std::is_integral<T>::value>> inline std::string to_hex_string(T aValue, bool aShowBase, bool aUppercase = true)
    {
        std::stringstream stream;
        stream << std::setfill('0') << std::setw(sizeof(aValue)*2) << std::hex;
        stream << (aShowBase ? std::showbase : std::noshowbase);
        stream << (aUppercase ? std::uppercase : std::nouppercase);
        stream << aValue;
        return stream.str();
    }

    template <typename T> inline std::string to_hex_string(const T* aPtr)
    {
        std::stringstream stream;
        const void* value = reinterpret_cast<const void*>(aPtr);
        stream << value; // std::setfill('0') << std::setw(sizeof(value)*2) << std::hex << value;
        return stream.str();
    }

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

} // namespace string

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before><commit_msg>Misc fixes to lengthfixer<commit_after><|endoftext|>


<commit_before>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.

#include "../precomp.hpp"

#include "../graph_simplifier.hpp"
#include "onnx_graph_simplifier.hpp"

#include <queue>

namespace cv { namespace dnn {
CV__DNN_EXPERIMENTAL_NS_BEGIN

// This wrapper can behave differently for fake input nodes and real graph nodes.
class ONNXNodeWrapper : public ImportNodeWrapper
{
public:
    ONNXNodeWrapper(opencv_onnx::NodeProto* _node = 0) : node(_node) {}

    virtual int getNumInputs() const CV_OVERRIDE
    {
        return node ? node->input_size() : 0;
    }

    virtual std::string getInputName(int idx) const CV_OVERRIDE
    {
        CV_Assert_N(node, idx < node->input_size());
        return node->input(idx);
    }

    virtual std::string getType() const CV_OVERRIDE
    {
        return node ? node->op_type() : "";
    }

    virtual void setType(const std::string& type) CV_OVERRIDE
    {
        CV_Assert(node);
        node->set_op_type(type);
    }

    virtual void setInputNames(const std::vector<std::string>& inputs) CV_OVERRIDE
    {
        CV_Assert(node);
        node->clear_input();
        for (int i = 0; i < inputs.size(); ++i)
            node->add_input(inputs[i]);
    }

    opencv_onnx::NodeProto* node;
};

// ONNX graph's inputs are separate from nodes so we index them before the rest of nodes.
class ONNXGraphWrapper : public ImportGraphWrapper
{
public:
    ONNXGraphWrapper(opencv_onnx::GraphProto& _net) : net(_net)
    {
        numInputs = net.input_size();
    }

    virtual Ptr<ImportNodeWrapper> getNode(int idx) const CV_OVERRIDE
    {
        opencv_onnx::NodeProto* node = 0;
        if (idx >= numInputs)
            node = net.mutable_node(idx - numInputs);
        return makePtr<ONNXNodeWrapper>(node);
    }

    virtual int getNumNodes() const CV_OVERRIDE
    {
        return numInputs + net.node_size();
    }

    virtual std::string getNodeName(int idx) const CV_OVERRIDE
    {
        if (idx < numInputs)
            return net.input(idx).name();
        else
            return net.node(idx - numInputs).output(0);
    }

    virtual void removeNode(int idx) CV_OVERRIDE
    {
        CV_Assert(idx >= numInputs);
        net.mutable_node()->DeleteSubrange(idx - numInputs, 1);
    }

private:
    int numInputs;
    opencv_onnx::GraphProto& net;
};

class SoftMaxSubgraph : public Subgraph
{
public:
    SoftMaxSubgraph()
    {
        int input = addNodeToMatch("");
        int inpExp = addNodeToMatch("Exp", input);
        int sum = addNodeToMatch("ReduceSum", inpExp);
        addNodeToMatch("Div", inpExp, sum);
        setFusedNode("Softmax", input);
    }

    virtual bool match(const Ptr<ImportGraphWrapper>& net, int nodeId,
                       std::vector<int>& matchedNodesIds,
                       std::vector<int>& targetNodesIds) CV_OVERRIDE
    {
        if (Subgraph::match(net, nodeId, matchedNodesIds, targetNodesIds))
        {
            Ptr<ImportNodeWrapper> sum = net->getNode(matchedNodesIds[1]);
            opencv_onnx::NodeProto* node = sum.dynamicCast<ONNXNodeWrapper>()->node;

            for (int i = 0; i < node->attribute_size(); i++)
            {
                opencv_onnx::AttributeProto attr = node->attribute(i);
                if (attr.name() != "axes")
                    continue;
                if (attr.ints_size() != 1)
                    CV_Error(Error::StsNotImplemented, format("Unexpected number of axes: %d", attr.ints_size()));
                axis = attr.ints(0);
                return true;
            }
            CV_Error(Error::StsNotImplemented, "Missed axes attribute");
        }
        return false;
    }

    virtual void finalize(const Ptr<ImportGraphWrapper>&,
                          const Ptr<ImportNodeWrapper>& fusedNode,
                          std::vector<Ptr<ImportNodeWrapper> >&) CV_OVERRIDE
    {
        opencv_onnx::NodeProto* node = fusedNode.dynamicCast<ONNXNodeWrapper>()->node;
        opencv_onnx::AttributeProto* attr = node->add_attribute();
        attr->set_name("axis");
        attr->set_i(axis);
    }

private:
    int axis;
};

void simplifySubgraphs(opencv_onnx::GraphProto& net)
{
    std::vector<Ptr<Subgraph> > subgraphs;
    subgraphs.push_back(makePtr<SoftMaxSubgraph>());

    simplifySubgraphs(Ptr<ImportGraphWrapper>(new ONNXGraphWrapper(net)), subgraphs);
}

CV__DNN_EXPERIMENTAL_NS_END
}}  // namespace cv::dnn
<commit_msg>Fix uninitialized value<commit_after>// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2020, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.

#include "../precomp.hpp"

#include "../graph_simplifier.hpp"
#include "onnx_graph_simplifier.hpp"

#include <queue>

namespace cv { namespace dnn {
CV__DNN_EXPERIMENTAL_NS_BEGIN

// This wrapper can behave differently for fake input nodes and real graph nodes.
class ONNXNodeWrapper : public ImportNodeWrapper
{
public:
    ONNXNodeWrapper(opencv_onnx::NodeProto* _node = 0) : node(_node) {}

    virtual int getNumInputs() const CV_OVERRIDE
    {
        return node ? node->input_size() : 0;
    }

    virtual std::string getInputName(int idx) const CV_OVERRIDE
    {
        CV_Assert_N(node, idx < node->input_size());
        return node->input(idx);
    }

    virtual std::string getType() const CV_OVERRIDE
    {
        return node ? node->op_type() : "";
    }

    virtual void setType(const std::string& type) CV_OVERRIDE
    {
        CV_Assert(node);
        node->set_op_type(type);
    }

    virtual void setInputNames(const std::vector<std::string>& inputs) CV_OVERRIDE
    {
        CV_Assert(node);
        node->clear_input();
        for (int i = 0; i < inputs.size(); ++i)
            node->add_input(inputs[i]);
    }

    opencv_onnx::NodeProto* node;
};

// ONNX graph's inputs are separate from nodes so we index them before the rest of nodes.
class ONNXGraphWrapper : public ImportGraphWrapper
{
public:
    ONNXGraphWrapper(opencv_onnx::GraphProto& _net) : net(_net)
    {
        numInputs = net.input_size();
    }

    virtual Ptr<ImportNodeWrapper> getNode(int idx) const CV_OVERRIDE
    {
        opencv_onnx::NodeProto* node = 0;
        if (idx >= numInputs)
            node = net.mutable_node(idx - numInputs);
        return makePtr<ONNXNodeWrapper>(node);
    }

    virtual int getNumNodes() const CV_OVERRIDE
    {
        return numInputs + net.node_size();
    }

    virtual std::string getNodeName(int idx) const CV_OVERRIDE
    {
        if (idx < numInputs)
            return net.input(idx).name();
        else
            return net.node(idx - numInputs).output(0);
    }

    virtual void removeNode(int idx) CV_OVERRIDE
    {
        CV_Assert(idx >= numInputs);
        net.mutable_node()->DeleteSubrange(idx - numInputs, 1);
    }

private:
    int numInputs;
    opencv_onnx::GraphProto& net;
};

class SoftMaxSubgraph : public Subgraph
{
public:
    SoftMaxSubgraph() : axis(1)
    {
        int input = addNodeToMatch("");
        int inpExp = addNodeToMatch("Exp", input);
        int sum = addNodeToMatch("ReduceSum", inpExp);
        addNodeToMatch("Div", inpExp, sum);
        setFusedNode("Softmax", input);
    }

    virtual bool match(const Ptr<ImportGraphWrapper>& net, int nodeId,
                       std::vector<int>& matchedNodesIds,
                       std::vector<int>& targetNodesIds) CV_OVERRIDE
    {
        if (Subgraph::match(net, nodeId, matchedNodesIds, targetNodesIds))
        {
            Ptr<ImportNodeWrapper> sum = net->getNode(matchedNodesIds[1]);
            opencv_onnx::NodeProto* node = sum.dynamicCast<ONNXNodeWrapper>()->node;

            for (int i = 0; i < node->attribute_size(); i++)
            {
                opencv_onnx::AttributeProto attr = node->attribute(i);
                if (attr.name() != "axes")
                    continue;
                if (attr.ints_size() != 1)
                    CV_Error(Error::StsNotImplemented, format("Unexpected number of axes: %d", attr.ints_size()));
                axis = attr.ints(0);
                return true;
            }
            CV_Error(Error::StsNotImplemented, "Missed axes attribute");
        }
        return false;
    }

    virtual void finalize(const Ptr<ImportGraphWrapper>&,
                          const Ptr<ImportNodeWrapper>& fusedNode,
                          std::vector<Ptr<ImportNodeWrapper> >&) CV_OVERRIDE
    {
        opencv_onnx::NodeProto* node = fusedNode.dynamicCast<ONNXNodeWrapper>()->node;
        opencv_onnx::AttributeProto* attr = node->add_attribute();
        attr->set_name("axis");
        attr->set_i(axis);
    }

private:
    int axis;
};

void simplifySubgraphs(opencv_onnx::GraphProto& net)
{
    std::vector<Ptr<Subgraph> > subgraphs;
    subgraphs.push_back(makePtr<SoftMaxSubgraph>());

    simplifySubgraphs(Ptr<ImportGraphWrapper>(new ONNXGraphWrapper(net)), subgraphs);
}

CV__DNN_EXPERIMENTAL_NS_END
}}  // namespace cv::dnn
<|endoftext|>


<commit_before>#include "find-hotspot.h"
using namespace tern;

#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Analysis/Dominators.h"
#include "common/IDAssigner.h"
#include "common/util.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Instructions.h"
using namespace llvm;

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

static RegisterPass<FindHotspot> X(
		"find-hotspot",
		"Find Hotspot",
		false,
		true); // is analysis

char FindHotspot::ID = 0;

FindHotspot::FindHotspot(): ModulePass(&ID) {
}

FindHotspot::~FindHotspot() {
}

void FindHotspot::print(raw_ostream &O, const Module *M) const {
}

void FindHotspot::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<IDAssigner>();
  ModulePass::getAnalysisUsage(AU);
}

void FindHotspot::init(Module &M) {
  int_type = IntegerType::get(M.getContext(), 32);
  vector<const Type *> params;
  params.push_back(int_type);
  FunctionType *switch_fty = FunctionType::get(int_type, params, false);
  backedge_stat = M.getOrInsertFunction("backedge_stat", switch_fty);
  assert(backedge_stat);
}

bool FindHotspot::runOnModule(Module &M) {
  init(M);

  SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> edges;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Function *f = I;
    if (f->isDeclaration())
      continue;
    FindFunctionBackedges(*f, edges);
  }

  SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32>::iterator itr = edges.begin();
  for (; itr != edges.end(); itr++) {
    fprintf(stderr, "Back edge from function %s: bb %s to bb %s\n",
      itr->first->getParent()->getNameStr().c_str(),
      itr->first->getNameStr().c_str(),
      itr->second->getNameStr().c_str()
    );
  }

  if (edges.size() > 0) {
    addBackEdgeStat(edges);
    return true;
  }

  return false;
}

void FindHotspot::addBackEdgeStat(SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> &back_edges) {
for (size_t i = 0; i < back_edges.size(); ++i) {
				BasicBlock *x = (BasicBlock *)((long)back_edges[i].first);
                BasicBlock *y = (BasicBlock *)((long)back_edges[i].second);
                Function *f = x->getParent();
				BasicBlock *bb = BasicBlock::Create(f->getContext(), "", f);
				bb->setName("xtern_backedge_to_" + y->getNameStr());

                // Add the instrumented function.
                Value *patched = CallInst::Create(backedge_stat, ConstantInt::get(int_type, (int)i), "", bb);
                assert(patched);

                // Set its sucessor to y
				BranchInst::Create(y, bb);

				// Modify new_x's successor
				TerminatorInst *ti = x->getTerminator();
				assert(ti);
                unsigned idx = 0;
                for (succ_iterator it = succ_begin(x); it != succ_end(x); ++it, ++idx) {
                  BasicBlock *z = *it;
                  if (z == y)
                    ti->setSuccessor(idx, bb);
                }

				// Modify PHI nodes of y;
				// For y, replace the incoming edge from x with from the back-edge BB
				for (BasicBlock::iterator ii = y->begin(); PHINode *phi = dyn_cast<PHINode>(ii); ++ii) {
					// Only replace the first one, because there may be multiple edges
					for (unsigned j = 0; j < phi->getNumIncomingValues(); ++j) {
						if (phi->getIncomingBlock(j) == x) {
							phi->setIncomingBlock(j, bb);
							break;
						}
					}
				}
			}
}

<commit_msg>Added find-hotspot pass to identify performance bottleneck in applications<commit_after>#include "find-hotspot.h"
using namespace tern;

#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Analysis/Dominators.h"
#include "common/IDAssigner.h"
#include "common/util.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Instructions.h"
using namespace llvm;

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

static RegisterPass<FindHotspot> X(
		"find-hotspot",
		"Find Hotspot",
		false,
		true); // is analysis

char FindHotspot::ID = 0;

FindHotspot::FindHotspot(): ModulePass(&ID) {
}

FindHotspot::~FindHotspot() {
}

void FindHotspot::print(raw_ostream &O, const Module *M) const {
}

void FindHotspot::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<IDAssigner>();
  ModulePass::getAnalysisUsage(AU);
}

void FindHotspot::init(Module &M) {
  int_type = IntegerType::get(M.getContext(), 32);
  vector<const Type *> params;
  params.push_back(int_type);
  FunctionType *switch_fty = FunctionType::get(int_type, params, false);
  backedge_stat = M.getOrInsertFunction("backedge_stat", switch_fty);
  assert(backedge_stat);
}

bool FindHotspot::runOnModule(Module &M) {
  init(M);

  SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> edges;
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    Function *f = I;
    if (f->isDeclaration())
      continue;
    FindFunctionBackedges(*f, edges);
  }

  SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32>::iterator itr = edges.begin();
  for (; itr != edges.end(); itr++) {
    fprintf(stderr, "Back edge from function %s: bb %s to bb %s\n",
      itr->first->getParent()->getNameStr().c_str(),
      itr->first->getNameStr().c_str(),
      itr->second->getNameStr().c_str()
    );
  }

  if (edges.size() > 0) {
    addBackEdgeStat(edges);
    return true;
  }

  return false;
}

void FindHotspot::addBackEdgeStat(SmallVector<std::pair<const BasicBlock*,const BasicBlock*>, 32> &back_edges) {
  for (size_t i = 0; i < back_edges.size(); ++i) {
    BasicBlock *x = (BasicBlock *)((long)back_edges[i].first);
    BasicBlock *y = (BasicBlock *)((long)back_edges[i].second);
    Function *f = x->getParent();
    BasicBlock *bb = BasicBlock::Create(f->getContext(), "", f);
    bb->setName("xtern_backedge_to_" + y->getNameStr());

    // Add the instrumented function.
    Value *patched = CallInst::Create(backedge_stat, ConstantInt::get(int_type, (int)i), "", bb);
    assert(patched);

    // Set its sucessor to y
    BranchInst::Create(y, bb);

    // Modify new_x's successor
    TerminatorInst *ti = x->getTerminator();
    assert(ti);
    unsigned idx = 0;
    for (succ_iterator it = succ_begin(x); it != succ_end(x); ++it, ++idx) {
      BasicBlock *z = *it;
      if (z == y)
        ti->setSuccessor(idx, bb);
    }

    // Modify PHI nodes of y;
    // For y, replace the incoming edge from x with from the back-edge BB
    for (BasicBlock::iterator ii = y->begin(); PHINode *phi = dyn_cast<PHINode>(ii); ++ii) {
      // Only replace the first one, because there may be multiple edges
      for (unsigned j = 0; j < phi->getNumIncomingValues(); ++j) {
        if (phi->getIncomingBlock(j) == x) {
            phi->setIncomingBlock(j, bb);
          break;
        }
      }
    }
  }
}

<|endoftext|>


<commit_before>#include <glib-object.h>

#include "utils/utils.h"
#include "seafile-applet.h"
#include "local-repo.h"

LocalRepo LocalRepo::fromGObject(GObject *obj)
{
    char *id = NULL;
    char *name = NULL;
    char *desc = NULL;
    char *worktree = NULL;
    char *relay_id = NULL;

    gboolean encrypted;
    gboolean auto_sync;
    gboolean worktree_invalid;
    gint64 last_sync_time;
    int version;

    g_object_get (obj,
                  "id", &id,
                  "name", &name,
                  "desc", &desc,
                  "encrypted", &encrypted,
                  "worktree", &worktree,
                  "auto-sync", &auto_sync,
                  "last-sync-time", &last_sync_time,
                  "worktree-invalid", &worktree_invalid,
                  "relay-id", &relay_id,
                  "version", &version,
                  NULL);

    LocalRepo repo;
    repo.id = QString::fromUtf8(id);
    repo.name = QString::fromUtf8(name);
    repo.description = QString::fromUtf8(desc);
    repo.worktree = QString::fromUtf8(worktree);
    repo.encrypted = encrypted;
    repo.auto_sync = auto_sync;
    repo.last_sync_time = last_sync_time;
    repo.worktree_invalid = worktree_invalid;
    repo.relay_id = relay_id;
    repo.version = version;

    g_free (id);
    g_free (name);
    g_free (desc);
    g_free (worktree);
    g_free (relay_id);

    return repo;
}

void LocalRepo::setSyncInfo(const QString &state, const QString &error, const QString &err_detail)
{
    // qWarning("error: %s\n", toCStr(error));
    // qWarning("state: %s\n", toCStr(state));
    if (error.length() > 0) {
        translateSyncError(error);
        if (err_detail.length() > 0)
            translateSyncErrDetail(err_detail);
    } else {
        translateSyncState(state);
    }
}

void LocalRepo::translateSyncState(const QString &status)
{
    if (status == "synchronized") {
        sync_state_str = QObject::tr("synchronized");
        sync_state = SYNC_STATE_DONE;

    } else if (status == "committing") {
        sync_state_str = QObject::tr("indexing files");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = false;

    } else if (status == "initializing") {
        sync_state_str = QObject::tr("sync initializing");
        sync_state = SYNC_STATE_INIT;

    } else if (status == "downloading") {
        sync_state_str = QObject::tr("downloading");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = true;

    } else if (status == "uploading") {
        sync_state_str = QObject::tr("uploading");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = true;

    } else if (status == "merging") {
        sync_state_str = QObject::tr("sync merging");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = false;

    } else if (status == "waiting for sync") {
        sync_state_str = QObject::tr("waiting for sync");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "relay not connected") {
        sync_state_str = QObject::tr("server not connected");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "relay authenticating") {
        sync_state_str = QObject::tr("server authenticating");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "auto sync is turned off") {
        sync_state_str = QObject::tr("auto sync is turned off");
        sync_state = SYNC_STATE_DISABLED;

    } else if (status == "cancel pending") {
        sync_state_str = QObject::tr("sync initializing");
        sync_state = SYNC_STATE_INIT;

    } else {
        qWarning("unknown sync status: %s\n", toCStr(status));
        sync_state_str = QObject::tr("unknown");
        sync_state = SYNC_STATE_UNKNOWN;
    }

    if (!auto_sync && sync_state != SYNC_STATE_ING) {
        sync_state_str = QObject::tr("auto sync is turned off");
        sync_state = SYNC_STATE_DISABLED;
        return;
    }
}

void LocalRepo::translateSyncError(const QString &error)
{
    sync_state = SYNC_STATE_ERROR;

    if (error == "relay not connected") {
        sync_error_str = QObject::tr("server not connected");

    } else if (error == "Server has been removed") {
        sync_error_str = QObject::tr("Server has been removed");

    } else if (error == "You have not login to the server") {
        sync_error_str = QObject::tr("You have not logged in to the server");

    } else if (error == "You do not have permission to access this repo") {
        sync_error_str = QObject::tr("You do not have permission to access this library");

    } else if (error == "The storage space of the repo owner has been used up") {
        sync_error_str = QObject::tr("The storage space of the library owner has been used up");

    } else if (error == "Remote service is not available") {
        sync_error_str = QObject::tr("Remote service is not available");

    } else if (error == "Access denied to service. Please check your registration on relay.") {
        sync_error_str = QObject::tr("Access denied to service");

    } else if (error == "Internal data corrupted.") {
        sync_error_str = QObject::tr("Internal data corrupted");

    } else if (error == "Failed to start upload.") {
        sync_error_str = QObject::tr("Failed to start upload");

    } else if (error == "Error occured in upload.") {
        sync_error_str = QObject::tr("Error occured in upload");

    } else if (error == "Failed to start download.") {
        sync_error_str = QObject::tr("Failed to start download");

    } else if (error == "Error occured in download.") {
        sync_error_str = QObject::tr("Error occured in download");

    } else if (error == "No such repo on relay.") {
        sync_error_str = QObject::tr("Library is deleted on server");

    } else if (error == "Repo is damaged on relay.") {
        sync_error_str = QObject::tr("Library is damaged on server");

    } else if (error == "Conflict in merge.") {
        sync_error_str = QObject::tr("Conflict in merge");

    } else if (error == "Server version is too old.") {
        sync_error_str = QObject::tr("Server version is too old");

    } else if (error == "invalid worktree") {
        sync_error_str = QObject::tr("Error when accessing the local folder");

    } else if (error == "Unknown error." || error == "Unknown error") {
        sync_error_str = QObject::tr("Unknown error");

    } else if (error == "Storage quota full") {
        sync_error_str = QObject::tr("The storage quota has been used up");

    } else if (error == "Service on remote server is not available") {
        sync_error_str = QObject::tr("Internal server error");

    } else if (error == "Access denied to service. Please check your registration on server.") {
        sync_error_str = QObject::tr("Access denied to service");

    } else if (error == "Transfer protocol outdated. You need to upgrade seafile.") {
        sync_error_str = QObject::tr("Your %1 client is too old").arg(getBrand());

    } else if (error == "Internal error when preparing upload") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Internal error when preparing download") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "No permission to access remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Library doesn't exist on the remote end") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Internal error when starting to send revision information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to get revision information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload revision information to remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get revision information from remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to send file information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to get file information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Incomplete file information in the local library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload file information to remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get file information from remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to update remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Others have concurrent updates to the remote library. You need to sync again.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Server failed to check storage quota") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Incomplete revision information in the local library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to compare data to server.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get block server list.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to start block transfer client.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload blocks.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to download blocks.") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Files are locked by other application") {
        sync_error_str = QObject::tr("Files are locked by other application");
    } else {
        sync_error_str = error;
    }
}

void LocalRepo::translateSyncErrDetail(const QString &err_detail)
{
    if (err_detail == "Permission denied on server") {
        sync_error_detail = QObject::tr("Permission denied on server. Please try resync the library");
    } else if (err_detail == "Network error") {
        sync_error_detail = QObject::tr("Network error");
    } else if (err_detail == "Cannot resolve proxy address") {
        sync_error_detail = QObject::tr("Cannot resolve proxy address");
    } else if (err_detail == "Cannot resolve server address") {
        sync_error_detail = QObject::tr("Cannot resolve server address");
    } else if (err_detail == "Cannot connect to server") {
        sync_error_detail = QObject::tr("Cannot connect to server");
    } else if (err_detail == "Failed to establish secure connection") {
        sync_error_detail = QObject::tr("Failed to establish secure connection. Please check server SSL certificate");
    } else if (err_detail == "Data transfer was interrupted") {
        sync_error_detail = QObject::tr("Data transfer was interrupted. Please check network or firewall");
    } else if (err_detail == "Data transfer timed out") {
        sync_error_detail = QObject::tr("Data transfer timed out. Please check network or firewall");
    } else if (err_detail == "Unhandled http redirect from server") {
        sync_error_detail = QObject::tr("Unhandled http redirect from server. Please check server cofiguration");
    } else if (err_detail == "Server error") {
        sync_error_detail = QObject::tr("Server error");
    } else if (err_detail == "Bad request") {
        sync_error_detail = QObject::tr("Bad request");
    } else if (err_detail == "Internal data corrupt on the client") {
        sync_error_detail = QObject::tr("Internal data corrupt on the client. Please try resync the library");
    } else if (err_detail == "Not enough memory") {
        sync_error_detail = QObject::tr("Not enough memory");
    } else if (err_detail == "Failed to write data on the client") {
        sync_error_detail = QObject::tr("Failed to write data on the client. Please check disk space or folder permissions");
    } else if (err_detail == "Storage quota full") {
        sync_error_detail = QObject::tr("Storage quota full");
    } else if (err_detail == "Files are locked by other application") {
        sync_error_detail = QObject::tr("Files are locked by other application");
    } else if (err_detail == "Library deleted on server") {
        sync_error_detail = QObject::tr("Library deleted on server");
    } else if (err_detail == "Library damaged on server") {
        sync_error_detail = QObject::tr("Library damaged on server");
    } else if (err_detail == "File is locked by another user") {
        sync_error_detail = QObject::tr("File is locked by another user");
    } else {
        sync_error_detail = err_detail;
    }

    // printf ("sync error detail set to '%s'\n", sync_error_detail.toUtf8().data());
}

QString LocalRepo::getErrorString() const
{
    return sync_error_detail.isEmpty() ? sync_error_str : sync_error_detail;
}
<commit_msg>Fixed typo (#1092)<commit_after>#include <glib-object.h>

#include "utils/utils.h"
#include "seafile-applet.h"
#include "local-repo.h"

LocalRepo LocalRepo::fromGObject(GObject *obj)
{
    char *id = NULL;
    char *name = NULL;
    char *desc = NULL;
    char *worktree = NULL;
    char *relay_id = NULL;

    gboolean encrypted;
    gboolean auto_sync;
    gboolean worktree_invalid;
    gint64 last_sync_time;
    int version;

    g_object_get (obj,
                  "id", &id,
                  "name", &name,
                  "desc", &desc,
                  "encrypted", &encrypted,
                  "worktree", &worktree,
                  "auto-sync", &auto_sync,
                  "last-sync-time", &last_sync_time,
                  "worktree-invalid", &worktree_invalid,
                  "relay-id", &relay_id,
                  "version", &version,
                  NULL);

    LocalRepo repo;
    repo.id = QString::fromUtf8(id);
    repo.name = QString::fromUtf8(name);
    repo.description = QString::fromUtf8(desc);
    repo.worktree = QString::fromUtf8(worktree);
    repo.encrypted = encrypted;
    repo.auto_sync = auto_sync;
    repo.last_sync_time = last_sync_time;
    repo.worktree_invalid = worktree_invalid;
    repo.relay_id = relay_id;
    repo.version = version;

    g_free (id);
    g_free (name);
    g_free (desc);
    g_free (worktree);
    g_free (relay_id);

    return repo;
}

void LocalRepo::setSyncInfo(const QString &state, const QString &error, const QString &err_detail)
{
    // qWarning("error: %s\n", toCStr(error));
    // qWarning("state: %s\n", toCStr(state));
    if (error.length() > 0) {
        translateSyncError(error);
        if (err_detail.length() > 0)
            translateSyncErrDetail(err_detail);
    } else {
        translateSyncState(state);
    }
}

void LocalRepo::translateSyncState(const QString &status)
{
    if (status == "synchronized") {
        sync_state_str = QObject::tr("synchronized");
        sync_state = SYNC_STATE_DONE;

    } else if (status == "committing") {
        sync_state_str = QObject::tr("indexing files");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = false;

    } else if (status == "initializing") {
        sync_state_str = QObject::tr("sync initializing");
        sync_state = SYNC_STATE_INIT;

    } else if (status == "downloading") {
        sync_state_str = QObject::tr("downloading");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = true;

    } else if (status == "uploading") {
        sync_state_str = QObject::tr("uploading");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = true;

    } else if (status == "merging") {
        sync_state_str = QObject::tr("sync merging");
        sync_state = SYNC_STATE_ING;
        has_data_transfer = false;

    } else if (status == "waiting for sync") {
        sync_state_str = QObject::tr("waiting for sync");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "relay not connected") {
        sync_state_str = QObject::tr("server not connected");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "relay authenticating") {
        sync_state_str = QObject::tr("server authenticating");
        sync_state = SYNC_STATE_WAITING;

    } else if (status == "auto sync is turned off") {
        sync_state_str = QObject::tr("auto sync is turned off");
        sync_state = SYNC_STATE_DISABLED;

    } else if (status == "cancel pending") {
        sync_state_str = QObject::tr("sync initializing");
        sync_state = SYNC_STATE_INIT;

    } else {
        qWarning("unknown sync status: %s\n", toCStr(status));
        sync_state_str = QObject::tr("unknown");
        sync_state = SYNC_STATE_UNKNOWN;
    }

    if (!auto_sync && sync_state != SYNC_STATE_ING) {
        sync_state_str = QObject::tr("auto sync is turned off");
        sync_state = SYNC_STATE_DISABLED;
        return;
    }
}

void LocalRepo::translateSyncError(const QString &error)
{
    sync_state = SYNC_STATE_ERROR;

    if (error == "relay not connected") {
        sync_error_str = QObject::tr("server not connected");

    } else if (error == "Server has been removed") {
        sync_error_str = QObject::tr("Server has been removed");

    } else if (error == "You have not login to the server") {
        sync_error_str = QObject::tr("You have not logged in to the server");

    } else if (error == "You do not have permission to access this repo") {
        sync_error_str = QObject::tr("You do not have permission to access this library");

    } else if (error == "The storage space of the repo owner has been used up") {
        sync_error_str = QObject::tr("The storage space of the library owner has been used up");

    } else if (error == "Remote service is not available") {
        sync_error_str = QObject::tr("Remote service is not available");

    } else if (error == "Access denied to service. Please check your registration on relay.") {
        sync_error_str = QObject::tr("Access denied to service");

    } else if (error == "Internal data corrupted.") {
        sync_error_str = QObject::tr("Internal data corrupted");

    } else if (error == "Failed to start upload.") {
        sync_error_str = QObject::tr("Failed to start upload");

    } else if (error == "Error occurred in upload.") {
        sync_error_str = QObject::tr("Error occurred in upload");

    } else if (error == "Failed to start download.") {
        sync_error_str = QObject::tr("Failed to start download");

    } else if (error == "Error occurred in download.") {
        sync_error_str = QObject::tr("Error occurred in download");

    } else if (error == "No such repo on relay.") {
        sync_error_str = QObject::tr("Library is deleted on server");

    } else if (error == "Repo is damaged on relay.") {
        sync_error_str = QObject::tr("Library is damaged on server");

    } else if (error == "Conflict in merge.") {
        sync_error_str = QObject::tr("Conflict in merge");

    } else if (error == "Server version is too old.") {
        sync_error_str = QObject::tr("Server version is too old");

    } else if (error == "invalid worktree") {
        sync_error_str = QObject::tr("Error when accessing the local folder");

    } else if (error == "Unknown error." || error == "Unknown error") {
        sync_error_str = QObject::tr("Unknown error");

    } else if (error == "Storage quota full") {
        sync_error_str = QObject::tr("The storage quota has been used up");

    } else if (error == "Service on remote server is not available") {
        sync_error_str = QObject::tr("Internal server error");

    } else if (error == "Access denied to service. Please check your registration on server.") {
        sync_error_str = QObject::tr("Access denied to service");

    } else if (error == "Transfer protocol outdated. You need to upgrade seafile.") {
        sync_error_str = QObject::tr("Your %1 client is too old").arg(getBrand());

    } else if (error == "Internal error when preparing upload") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Internal error when preparing download") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "No permission to access remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Library doesn't exist on the remote end") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Internal error when starting to send revision information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to get revision information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload revision information to remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get revision information from remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to send file information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to get file information") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Incomplete file information in the local library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload file information to remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get file information from remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Internal error when starting to update remote library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Others have concurrent updates to the remote library. You need to sync again.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Server failed to check storage quota") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Incomplete revision information in the local library") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to compare data to server.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to get block server list.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to start block transfer client.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to upload blocks.") {
        sync_error_str = QObject::tr("Failed to sync this library");
    } else if (error == "Failed to download blocks.") {
        sync_error_str = QObject::tr("Failed to sync this library");

    } else if (error == "Files are locked by other application") {
        sync_error_str = QObject::tr("Files are locked by other application");
    } else {
        sync_error_str = error;
    }
}

void LocalRepo::translateSyncErrDetail(const QString &err_detail)
{
    if (err_detail == "Permission denied on server") {
        sync_error_detail = QObject::tr("Permission denied on server. Please try resync the library");
    } else if (err_detail == "Network error") {
        sync_error_detail = QObject::tr("Network error");
    } else if (err_detail == "Cannot resolve proxy address") {
        sync_error_detail = QObject::tr("Cannot resolve proxy address");
    } else if (err_detail == "Cannot resolve server address") {
        sync_error_detail = QObject::tr("Cannot resolve server address");
    } else if (err_detail == "Cannot connect to server") {
        sync_error_detail = QObject::tr("Cannot connect to server");
    } else if (err_detail == "Failed to establish secure connection") {
        sync_error_detail = QObject::tr("Failed to establish secure connection. Please check server SSL certificate");
    } else if (err_detail == "Data transfer was interrupted") {
        sync_error_detail = QObject::tr("Data transfer was interrupted. Please check network or firewall");
    } else if (err_detail == "Data transfer timed out") {
        sync_error_detail = QObject::tr("Data transfer timed out. Please check network or firewall");
    } else if (err_detail == "Unhandled http redirect from server") {
        sync_error_detail = QObject::tr("Unhandled http redirect from server. Please check server cofiguration");
    } else if (err_detail == "Server error") {
        sync_error_detail = QObject::tr("Server error");
    } else if (err_detail == "Bad request") {
        sync_error_detail = QObject::tr("Bad request");
    } else if (err_detail == "Internal data corrupt on the client") {
        sync_error_detail = QObject::tr("Internal data corrupt on the client. Please try resync the library");
    } else if (err_detail == "Not enough memory") {
        sync_error_detail = QObject::tr("Not enough memory");
    } else if (err_detail == "Failed to write data on the client") {
        sync_error_detail = QObject::tr("Failed to write data on the client. Please check disk space or folder permissions");
    } else if (err_detail == "Storage quota full") {
        sync_error_detail = QObject::tr("Storage quota full");
    } else if (err_detail == "Files are locked by other application") {
        sync_error_detail = QObject::tr("Files are locked by other application");
    } else if (err_detail == "Library deleted on server") {
        sync_error_detail = QObject::tr("Library deleted on server");
    } else if (err_detail == "Library damaged on server") {
        sync_error_detail = QObject::tr("Library damaged on server");
    } else if (err_detail == "File is locked by another user") {
        sync_error_detail = QObject::tr("File is locked by another user");
    } else {
        sync_error_detail = err_detail;
    }

    // printf ("sync error detail set to '%s'\n", sync_error_detail.toUtf8().data());
}

QString LocalRepo::getErrorString() const
{
    return sync_error_detail.isEmpty() ? sync_error_str : sync_error_detail;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/buffer_traits.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file buffer_traits.H
 * @brief trait definitions for fapi2 buffer base class
 */

#ifndef __FAPI2_BUFFER_TRAITS__
#define __FAPI2_BUFFER_TRAITS__

#include <stdint.h>
#include <vector>
#include <algorithm>
#include <buffer_parameters.H>

// for debug printing ... can be removed for flight
#include <iostream>
#include <iterator>

namespace fapi2
{
    /// @cond
    /// Types representing a container of bits. Used to create
    /// variable_buffer. container_unit must remain 32-bits
    /// for now - there will be a lot of code to change if it
    /// changes. There are assertions helping to enforce this
    /// in places in the code.
    typedef uint32_t container_unit;
    typedef std::vector<container_unit> bits_container;

    /// @brief Traits of buffers
    // In general, we try to give buffers traits reflecting integral types. If
    // this fails, the compiler will let someone know.
    ///
    /// @tparam T is the type of iv_data (std::vector, etc)
    /// @tparam B is the type of the bit-specifier, typically uint32_t
    template<typename T, typename B = uint32_t>
    class bufferTraits
    {
    public:
#ifndef DOXYGEN
        ///
        /// @brief Print a container of bits
        /// @param[in] i_data the container of bits
        ///
        static inline void print(const T& i_data)
        {
            // convert to uint64_t to prevent uint8_t from being
            // printed as a char.
            std::cout << "\tdata is "
                      << std::hex
                      << static_cast<uint64_t>(i_data)
                      << std::dec << std::endl;
        }
#endif

        ///
        /// @brief Return the size of the buffer in E units
        /// @tparam E, the element size.
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in E's rounded up
        ///
        template<typename E>
        constexpr static B size(const T& i_buffer)
            {
                return (bit_length(i_buffer) +
                        (parameterTraits<E>::bit_length - 1)) /
                    parameterTraits<E>::bit_length;
            }

        ///
        /// @brief Return the size of the buffer itself
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in bits (not units)
        ///
        constexpr static B bit_length(const T&)
            { return sizeof(T) * 8; }

        ///
        /// @brief Clear the buffer
        /// @param[in,out] io_buffer the buffer which to clear
        ///
        static inline void clear(T& io_buffer)
            { io_buffer = static_cast<T>(0); }

        ///
        /// @brief Set the buffer
        /// @param[in,out] io_buffer the buffer which to set
        ///
        static inline void set(T& io_buffer)
            { io_buffer = static_cast<T>(~0); }

        ///
        /// @brief Invert the buffer
        /// @param[in,out] io_buffer the buffer which to invert
        ///
        static inline void invert(T& io_buffer)
            { io_buffer = ~io_buffer; }

        ///
        /// @brief Reverse the buffer
        /// @param[in,out] io_buffer the buffer which to reverse
        ///
        static inline void reverse(T& io_buffer)
            {
                io_buffer =
                    ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) |
                    ((io_buffer & 0x5555555555555555) << 1);
            }

        ///
        /// @brief Get the address of the buffer as an array
        /// @param[in] i_buffer the buffer which to invert
        /// @return The address of the first element of the buffer
        ///
        static inline void* get_address(T& i_buffer)
            { return (void*)&i_buffer; }

        typedef B bits_type;
        typedef T unit_type;
        constexpr static uint32_t bits_per_unit(void)
            { return sizeof(unit_type) * 8; }
    };

    //
    //
    /// @brief Traits for buffers which are a container of bits
    //
    //
    template<>
    class bufferTraits<bits_container, uint32_t>
    {
    public:
#ifndef DOXYGEN
        ///
        /// @brief Print a container of bits
        /// @param[in] i_data the container of bits
        ///
        static inline void print(const bits_container& i_data)
        {
            std::cout << "\tdata is " << std::hex;
            std::copy(i_data.begin(), i_data.end(),
                      std::ostream_iterator<container_unit>(std::cout, " "));
            std::cout << std::dec << std::endl;
        }
#endif

        ///
        /// @brief Return the size of the buffer in E units
        /// @tparam E, the element size.
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in E's rounded up
        ///
        template<typename E>
        constexpr static uint32_t size(const bits_container& i_buffer)
            {
                return (bit_length(i_buffer) +
                        (parameterTraits<E>::bit_length - 1)) /
                    parameterTraits<E>::bit_length;
            }

        ///
        /// @brief Return the size of the buffer itself
        /// @param[in,out] io_buffer the buffer which to size
        /// @return The size of the buffer in bits (not units)
        ///
        static inline uint32_t bit_length(const bits_container& i_buffer)
            { return i_buffer.size() * sizeof(container_unit) * 8; }

        ///
        /// @brief Clear the buffer
        /// @param[in,out] io_buffer the buffer which to clear
        ///
        static inline void clear(bits_container& io_buffer)
            { io_buffer.assign(io_buffer.size(), 0); }

        ///
        /// @brief Set the buffer
        /// @param[in,out] io_buffer the buffer which to set
        ///
        static inline void set(bits_container& io_buffer)
            { io_buffer.assign(io_buffer.size(), ~0); }

        ///
        /// @brief Invert the buffer
        /// @param[in,out] io_buffer the buffer which to invert
        ///
        static inline void invert(bits_container& io_buffer)
            {
                std::transform(io_buffer.begin(), io_buffer.end(),
                               io_buffer.begin(),
                               [](container_unit u) { return ~u; });
            }

        ///
        /// @brief Get the address of the buffer as an array
        /// @param[in] i_buffer the buffer which to invert
        /// @return The address of the first element of the buffer
        ///
        static inline void* get_address(bits_container& i_buffer)
            {
                return (void*)&(i_buffer[0]);
            }

        typedef uint32_t bits_type;
        typedef container_unit unit_type;
        constexpr static uint32_t bits_per_unit(void)
            { return sizeof(unit_type) * 8; }
    };
    /// @endcond
}

#endif
<commit_msg>FFDC class generation changes for caps, errors<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/buffer_traits.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file buffer_traits.H
 * @brief trait definitions for fapi2 buffer base class
 */

#ifndef __FAPI2_BUFFER_TRAITS__
#define __FAPI2_BUFFER_TRAITS__

#include <stdint.h>
#include <vector>
#include <algorithm>
#include <buffer_parameters.H>

// for debug printing ... can be removed for flight
#include <iostream>
#include <iterator>

namespace fapi2
{
    /// @cond
    /// Types representing a container of bits. Used to create
    /// variable_buffer. container_unit must remain 32-bits
    /// for now - there will be a lot of code to change if it
    /// changes. There are assertions helping to enforce this
    /// in places in the code.
    typedef uint32_t container_unit;
    typedef std::vector<container_unit> bits_container;

    /// @brief Traits of buffers
    // In general, we try to give buffers traits reflecting integral types. If
    // this fails, the compiler will let someone know.
    ///
    /// @tparam T is the type of iv_data (std::vector, etc)
    /// @tparam B is the type of the bit-specifier, typically uint32_t
    template<typename T, typename B = uint32_t>
    class bufferTraits
    {
    public:
#ifndef DOXYGEN
        ///
        /// @brief Print a container of bits
        /// @param[in] i_data the container of bits
        ///
        static inline void print(const T& i_data)
        {
            // convert to uint64_t to prevent uint8_t from being
            // printed as a char.
            std::cout << "\tdata is "
                      << std::hex
                      << static_cast<uint64_t>(i_data)
                      << std::dec << std::endl;
        }
#endif

        ///
        /// @brief Return the size of the buffer in E units
        /// @tparam E, the element size.
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in E's rounded up
        ///
        template<typename E>
        constexpr static B size(const T& i_buffer)
            {
                return (bit_length(i_buffer) +
                        (parameterTraits<E>::bit_length() - 1)) /
                    parameterTraits<E>::bit_length();
            }

        ///
        /// @brief Return the size of the buffer itself
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in bits (not units)
        ///
        constexpr static B bit_length(const T&)
            { return sizeof(T) * 8; }

        ///
        /// @brief Clear the buffer
        /// @param[in,out] io_buffer the buffer which to clear
        ///
        static inline void clear(T& io_buffer)
            { io_buffer = static_cast<T>(0); }

        ///
        /// @brief Set the buffer
        /// @param[in,out] io_buffer the buffer which to set
        ///
        static inline void set(T& io_buffer)
            { io_buffer = static_cast<T>(~0); }

        ///
        /// @brief Invert the buffer
        /// @param[in,out] io_buffer the buffer which to invert
        ///
        static inline void invert(T& io_buffer)
            { io_buffer = ~io_buffer; }

        ///
        /// @brief Reverse the buffer
        /// @param[in,out] io_buffer the buffer which to reverse
        ///
        static inline void reverse(T& io_buffer)
            {
                io_buffer =
                    ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) |
                    ((io_buffer & 0x5555555555555555) << 1);
            }

        ///
        /// @brief Get the address of the buffer as an array
        /// @param[in] i_buffer the buffer which to invert
        /// @return The address of the first element of the buffer
        ///
        static inline void* get_address(T& i_buffer)
            { return (void*)&i_buffer; }

        typedef B bits_type;
        typedef T unit_type;
        constexpr static uint32_t bits_per_unit(void)
            { return sizeof(unit_type) * 8; }
    };

    //
    //
    /// @brief Traits for buffers which are a container of bits
    //
    //
    template<>
    class bufferTraits<bits_container, uint32_t>
    {
    public:
#ifndef DOXYGEN
        ///
        /// @brief Print a container of bits
        /// @param[in] i_data the container of bits
        ///
        static inline void print(const bits_container& i_data)
        {
            std::cout << "\tdata is " << std::hex;
            std::copy(i_data.begin(), i_data.end(),
                      std::ostream_iterator<container_unit>(std::cout, " "));
            std::cout << std::dec << std::endl;
        }
#endif

        ///
        /// @brief Return the size of the buffer in E units
        /// @tparam E, the element size.
        /// @param[in] io_buffer the buffer which to size
        /// @return The size of the buffer in E's rounded up
        ///
        template<typename E>
        constexpr static uint32_t size(const bits_container& i_buffer)
            {
                return (bit_length(i_buffer) +
                        (parameterTraits<E>::bit_length - 1)) /
                    parameterTraits<E>::bit_length;
            }

        ///
        /// @brief Return the size of the buffer itself
        /// @param[in,out] io_buffer the buffer which to size
        /// @return The size of the buffer in bits (not units)
        ///
        static inline uint32_t bit_length(const bits_container& i_buffer)
            { return i_buffer.size() * sizeof(container_unit) * 8; }

        ///
        /// @brief Clear the buffer
        /// @param[in,out] io_buffer the buffer which to clear
        ///
        static inline void clear(bits_container& io_buffer)
            { io_buffer.assign(io_buffer.size(), 0); }

        ///
        /// @brief Set the buffer
        /// @param[in,out] io_buffer the buffer which to set
        ///
        static inline void set(bits_container& io_buffer)
            { io_buffer.assign(io_buffer.size(), ~0); }

        ///
        /// @brief Invert the buffer
        /// @param[in,out] io_buffer the buffer which to invert
        ///
        static inline void invert(bits_container& io_buffer)
            {
                std::transform(io_buffer.begin(), io_buffer.end(),
                               io_buffer.begin(),
                               [](container_unit u) { return ~u; });
            }

        ///
        /// @brief Get the address of the buffer as an array
        /// @param[in] i_buffer the buffer which to invert
        /// @return The address of the first element of the buffer
        ///
        static inline void* get_address(bits_container& i_buffer)
            {
                return (void*)&(i_buffer[0]);
            }

        typedef uint32_t bits_type;
        typedef container_unit unit_type;
        constexpr static uint32_t bits_per_unit(void)
            { return sizeof(unit_type) * 8; }
    };
    /// @endcond
}

#endif
<|endoftext|>


<commit_before><commit_msg>planning: fixed a bug in ScenarioDispatcher<commit_after><|endoftext|>