<commit_before>// Copyright (C) 2014 sails Authors.
// All rights reserved.
//
// Filename: saf.cc
//
// Author: sailsxu <sailsxu@gmail.com>
// Created: 2014-10-13 17:10:36

#include <sails/net/epoll_server.h>
#include <sails/net/connector.h>
#include <signal.h>
//#include <gperftools/profiler.h>
#include "src/monitor.h"
#include "src/server.h"

sails::Config config;
bool isRun = true;
sails::Server server;
sails::Monitor* monitor;

void sails_signal_handle(int signo, siginfo_t *, void *) {
  switch (signo) {
    case SIGINT:
      {
        server.Stop();
        isRun = false;

        delete monitor;
        break;
      }
  }
}

void sails_init(int, char **) {
  // signal kill
  struct sigaction act;
  act.sa_sigaction = sails_signal_handle;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  if (sigaction(SIGINT, &act, NULL) == -1) {
    perror("sigaction error");
    exit(EXIT_FAILURE);
  }

  // 初始化server
  server.Init(config.get_listen_port(), 3, 10,
              config.get_handle_thread(), true);

  monitor = new sails::Monitor(&server, config.get_monitor_port());
  monitor->Run();
}

int main(int argc, char *argv[]) {
  sails_init(argc, argv);
  //  ProfilerStart("saf.prof");
  while (isRun) {
    sleep(2);
  }
  //  ProfilerStop();
  char msg[100] = {'\0'};
  snprintf(msg, sizeof(msg), "total send:%lld\n", server.send_data);
  perror(msg);
  sleep(2);
  return 0;
}
<commit_msg>update<commit_after>// Copyright (C) 2014 sails Authors.
// All rights reserved.
//
// Filename: saf.cc
//
// Author: sailsxu <sailsxu@gmail.com>
// Created: 2014-10-13 17:10:36

#include <sails/net/epoll_server.h>
#include <sails/net/connector.h>
#include <signal.h>
//#include <gperftools/profiler.h>
#include "src/monitor.h"
#include "src/server.h"

sails::Config config;
bool isRun = true;
sails::Server server;
sails::Monitor* monitor;

void sails_signal_handle(int signo, siginfo_t *, void *) {
  switch (signo) {
    case SIGINT:
      {
        server.Stop();
        isRun = false;

        delete monitor;
        break;
      }
  }
}

void sails_init(int, char **) {
  // signal kill
  struct sigaction act;
  act.sa_sigaction = sails_signal_handle;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  if (sigaction(SIGINT, &act, NULL) == -1) {
    perror("sigaction error");
    exit(EXIT_FAILURE);
  }

  // 初始化server
  server.Init(config.get_listen_port(), 3, 10,
              config.get_handle_thread(), true);

  monitor = new sails::Monitor(&server, config.get_monitor_port());
  monitor->Run();
}

int main(int argc, char *argv[]) {
  sails_init(argc, argv);
  //  ProfilerStart("saf.prof");
  while (isRun) {
    sleep(2);
  }
  //  ProfilerStop();
  return 0;
}
<|endoftext|>


<commit_before>#include "vogleditor_qsettingsdialog.h"
#include "ui_vogleditor_qsettingsdialog.h"

#include "vogleditor_qsettings.h"

vogleditor_QSettingsDialog::vogleditor_QSettingsDialog(QWidget *parent)
    : QDialog(parent),
      ui(new Ui::vogleditor_QSettingsDialog)
{
    ui->setupUi(this);

    // tab parent
    ui->tabWidget->setCurrentIndex(g_settings.tab_page());

    connect(ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(tabCB(int)));

    connect(ui->buttonBox, SIGNAL(accepted()), SLOT(acceptCB()));
    connect(ui->buttonBox, SIGNAL(rejected()), SLOT(cancelCB()));

    connect(this, &vogleditor_QSettingsDialog::settingsChanged, &g_settings, &vogleditor_qsettings::update_group_active_lists);

    // Startup settings tab
    QString strSettings = g_settings.to_string();

    ui->textEdit->setText(strSettings);

    // Group settings tab

    // State Render
    ui->checkboxStateRender->setText(g_settings.group_state_render_name());
    ui->checkboxStateRender->setChecked(g_settings.group_state_render_stat());
    ui->checkboxStateRender->setEnabled(g_settings.group_state_render_used());

    connect(ui->checkboxStateRender, SIGNAL(stateChanged(int)),
            SLOT(checkboxStateRenderCB(int)));

    // Debug markers
    QVector<QCheckBox *> checkboxList;

    QStringList group_debug_marker_names = g_settings.group_debug_marker_names();
    QVector<bool> debug_marker_stat = g_settings.group_debug_marker_stat();
    QVector<bool> debug_marker_used = g_settings.group_debug_marker_used();
    int debug_marker_cnt = group_debug_marker_names.size();
    for (int i = 0; i < debug_marker_cnt; i++)
    {
        checkboxList << new QCheckBox(group_debug_marker_names[i], ui->groupboxDebugMarker);
        checkboxList[i]->setChecked(debug_marker_stat[i]);
        checkboxList[i]->setEnabled(debug_marker_used[i]);
        ui->vLayout_groupboxDebugMarker->insertWidget(i, checkboxList[i]);
    }

    for (int i = 0; i < debug_marker_cnt; i++)
    {
        connect(checkboxList[i], SIGNAL(stateChanged(int)),
                SLOT(checkboxCB(int)));
    }

    // Debug marker options
    ui->radiobuttonDebugMarkerNameOption->setText(g_settings.group_debug_marker_option_name_label());
    ui->radiobuttonDebugMarkerNameOption->setChecked(g_settings.group_debug_marker_option_name_stat());

    ui->radiobuttonDebugMarkerOmitOption->setText(g_settings.group_debug_marker_option_omit_label());
    ui->radiobuttonDebugMarkerOmitOption->setChecked(g_settings.group_debug_marker_option_omit_stat());

    setEnableDebugMarkerOptions();

    connect(ui->radiobuttonDebugMarkerNameOption, SIGNAL(toggled(bool)),
            SLOT(radiobuttonNameCB(bool)));
    connect(ui->radiobuttonDebugMarkerOmitOption, SIGNAL(toggled(bool)),
            SLOT(radiobuttonOmitCB(bool)));

    // Nest options
    checkboxList.clear();

    // Groupbox
    ui->groupboxNestOptions->setTitle(g_settings.groupbox_nest_options_name());
    ui->groupboxNestOptions->setChecked(g_settings.groupbox_nest_options_stat());
    ui->groupboxNestOptions->setEnabled(g_settings.groupbox_nest_options_used());
    if (g_settings.groupbox_nest_options_stat())
    {
        // For now, toggle State/Render groups and Nest options
        checkboxStateRenderCB(false);
    }

    // Checkboxes
    QStringList group_nest_options_names = g_settings.group_nest_options_names();
    QVector<bool> nest_options_stat = g_settings.group_nest_options_stat();
    QVector<bool> nest_options_used = g_settings.group_nest_options_used();
    int nest_options_cnt = group_nest_options_names.size();
    for (int i = 0; i < nest_options_cnt; i++)
    {
        checkboxList << new QCheckBox(group_nest_options_names[i], ui->groupboxNestOptions);
        checkboxList[i]->setChecked(nest_options_stat[i]);
        checkboxList[i]->setEnabled(nest_options_used[i]);
        ui->vLayout_groupboxNestOptionsScrollarea->addWidget(checkboxList[i]);
    }

    connect(ui->groupboxNestOptions, SIGNAL(toggled(bool)), // groupbox
            SLOT(groupboxNestOptionsCB(bool)));

    for (int i = 0; i < nest_options_cnt; i++) // checkboxes in groupbox
    {
        connect(checkboxList[i], SIGNAL(stateChanged(int)),
                SLOT(checkboxCB(int)));
    }

    // Save initial state
    m_bGroupInitialState = groupState();

} // constructor

vogleditor_QSettingsDialog::~vogleditor_QSettingsDialog()
{
    delete ui;
    clearLayout(ui->verticalLayout_tabGroups);

} // destructor

void vogleditor_QSettingsDialog::clearLayout(QLayout *layout)
{
    // taken from
    // http://stackoverflow.com/questions/4272196/qt-remove-all-widgets-from-layout
    // ... didn't seem to make any difference using valgrind Memcheck...

    while (QLayoutItem *item = layout->takeAt(0))
    {
        delete item->widget();
        if (QLayout *childLayout = item->layout())
            clearLayout(childLayout);
        delete item;
    }
} // clearLayout

void vogleditor_QSettingsDialog::tabCB(int page)
{
    g_settings.set_tab_page(page);
}

void vogleditor_QSettingsDialog::checkboxStateRenderCB(int val)
{
    bool bVal = bool(val);
    if (bVal)
    {
        ui->groupboxNestOptions->setChecked(!bVal);
        g_settings.set_groupbox_nest_options_stat(!bVal);
    }
    // Update
    g_settings.set_group_state_render_stat(bVal);
    updateTextTab();

} // checkboxStateRenderCB

void vogleditor_QSettingsDialog::groupboxNestOptionsCB(bool bVal)
{
    if (bVal)
    {
        ui->checkboxStateRender->setChecked(!bVal);
        g_settings.set_group_state_render_stat(!bVal);
    }
    // Update
    g_settings.set_groupbox_nest_options_stat(bVal);
    updateTextTab();

} // groupboxNestOptionsCB

void vogleditor_QSettingsDialog::checkboxCB(int state)
{
    g_settings.set_group_state_render_stat(ui->checkboxStateRender->isChecked());
    g_settings.set_group_debug_marker_stat(checkboxValues(ui->groupboxDebugMarker));
    g_settings.set_group_nest_options_stat(checkboxValues(ui->groupboxNestOptions));

    setEnableDebugMarkerOptions();

    updateTextTab();

} // checkboxCB

void vogleditor_QSettingsDialog::setEnableDebugMarkerOptions()
{
    //  Disable options if no Debug marker groups are checked
    QVector<bool> bCurrentState = checkboxValues(ui->groupboxDebugMarker);

    bool bVal;
    foreach(bVal, bCurrentState)
    {
        if (bVal)
            break;
    }
    enableDebugMarkerOptions(bVal);
}
void vogleditor_QSettingsDialog::enableDebugMarkerOptions(bool bVal)
{
    ui->radiobuttonDebugMarkerNameOption->setEnabled(bVal);
    ui->radiobuttonDebugMarkerOmitOption->setEnabled(bVal);

    // Notify g_settings
    g_settings.set_group_debug_marker_option_name_used(bVal);
    g_settings.set_group_debug_marker_option_omit_used(bVal);
}

void vogleditor_QSettingsDialog::radiobuttonNameCB(bool state)
{
    g_settings.set_group_debug_marker_option_name_stat(state);
    updateTextTab();
}

void vogleditor_QSettingsDialog::radiobuttonOmitCB(bool state)
{
    g_settings.set_group_debug_marker_option_omit_stat(state);
    updateTextTab();
}

void vogleditor_QSettingsDialog::updateTextTab()
{
    //update json tab settings page
    QString strSettings = g_settings.to_string();
    ui->textEdit->setText(strSettings);
}

QVector<bool> vogleditor_QSettingsDialog::checkboxValues(QObject *widget)
{
    // Note: This function is intended to only return checkbox values of
    //       API call names, so for the Debug marker API call list parent
    //       radiobuttons were used for the options.
    QList<QCheckBox *> groupCheckBoxes = widget->findChildren<QCheckBox *>();

    QVector<bool> bQVector;
    QList<QCheckBox *>::const_iterator iter = groupCheckBoxes.begin();

    while (iter != groupCheckBoxes.end())
    {
        bQVector << (*iter)->isChecked();
        iter++;
    }
    return bQVector;

} // checkboxValues()

QVector<bool> vogleditor_QSettingsDialog::groupState()
{
    QVector<bool> bCurrentState;

    bCurrentState << ui->checkboxStateRender->isChecked();
    bCurrentState << ui->groupboxNestOptions->isChecked();

    bCurrentState << checkboxValues(ui->groupboxDebugMarker);
    bCurrentState << checkboxValues(ui->groupboxNestOptions);

    bCurrentState << ui->radiobuttonDebugMarkerNameOption->isChecked();
    bCurrentState << ui->radiobuttonDebugMarkerOmitOption->isChecked();

    return bCurrentState;

} // groupState

void vogleditor_QSettingsDialog::reset()
{
    if (groupOptionsChanged())
    {
        // Set in same order as saved (from ::groupState())
        //
        // TODO: QMap these, widget key to value, in constructor
        //       so order won't matter
        int i = 0;
        ui->checkboxStateRender->setChecked(m_bGroupInitialState[i++]);
        ui->groupboxNestOptions->setChecked(m_bGroupInitialState[i++]);

        QList<QCheckBox *> checkboxes = ui->groupboxDebugMarker->findChildren<QCheckBox *>();
        for (int indx = 0; indx < checkboxes.count(); indx++)
        {
            checkboxes[indx]->setChecked(m_bGroupInitialState[i++]);
        }
        checkboxes = ui->groupboxNestOptions->findChildren<QCheckBox *>();
        for (int indx = 0; indx < checkboxes.count(); indx++)
        {
            checkboxes[indx]->setChecked(m_bGroupInitialState[i++]);
        }

        ui->radiobuttonDebugMarkerNameOption->setChecked(m_bGroupInitialState[i++]);
        ui->radiobuttonDebugMarkerOmitOption->setChecked(m_bGroupInitialState[i++]);
    }
} // reset

bool vogleditor_QSettingsDialog::groupOptionsChanged()
{
    return m_bGroupInitialState != groupState();
}

void vogleditor_QSettingsDialog::acceptCB()
{
    save();

    if (groupOptionsChanged())
    {
        emit settingsChanged();
    }
}

void vogleditor_QSettingsDialog::cancelCB()
{
    reset();
}

void vogleditor_QSettingsDialog::save()
{
    g_settings.from_string(ui->textEdit->toPlainText().toStdString().c_str());
    g_settings.save();
}
<commit_msg>vogleditor: Fix crash when closing settings dialog due to accessing a deleted object.<commit_after>#include "vogleditor_qsettingsdialog.h"
#include "ui_vogleditor_qsettingsdialog.h"

#include "vogleditor_qsettings.h"

vogleditor_QSettingsDialog::vogleditor_QSettingsDialog(QWidget *parent)
    : QDialog(parent),
      ui(new Ui::vogleditor_QSettingsDialog)
{
    ui->setupUi(this);

    // tab parent
    ui->tabWidget->setCurrentIndex(g_settings.tab_page());

    connect(ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(tabCB(int)));

    connect(ui->buttonBox, SIGNAL(accepted()), SLOT(acceptCB()));
    connect(ui->buttonBox, SIGNAL(rejected()), SLOT(cancelCB()));

    connect(this, &vogleditor_QSettingsDialog::settingsChanged, &g_settings, &vogleditor_qsettings::update_group_active_lists);

    // Startup settings tab
    QString strSettings = g_settings.to_string();

    ui->textEdit->setText(strSettings);

    // Group settings tab

    // State Render
    ui->checkboxStateRender->setText(g_settings.group_state_render_name());
    ui->checkboxStateRender->setChecked(g_settings.group_state_render_stat());
    ui->checkboxStateRender->setEnabled(g_settings.group_state_render_used());

    connect(ui->checkboxStateRender, SIGNAL(stateChanged(int)),
            SLOT(checkboxStateRenderCB(int)));

    // Debug markers
    QVector<QCheckBox *> checkboxList;

    QStringList group_debug_marker_names = g_settings.group_debug_marker_names();
    QVector<bool> debug_marker_stat = g_settings.group_debug_marker_stat();
    QVector<bool> debug_marker_used = g_settings.group_debug_marker_used();
    int debug_marker_cnt = group_debug_marker_names.size();
    for (int i = 0; i < debug_marker_cnt; i++)
    {
        checkboxList << new QCheckBox(group_debug_marker_names[i], ui->groupboxDebugMarker);
        checkboxList[i]->setChecked(debug_marker_stat[i]);
        checkboxList[i]->setEnabled(debug_marker_used[i]);
        ui->vLayout_groupboxDebugMarker->insertWidget(i, checkboxList[i]);
    }

    for (int i = 0; i < debug_marker_cnt; i++)
    {
        connect(checkboxList[i], SIGNAL(stateChanged(int)),
                SLOT(checkboxCB(int)));
    }

    // Debug marker options
    ui->radiobuttonDebugMarkerNameOption->setText(g_settings.group_debug_marker_option_name_label());
    ui->radiobuttonDebugMarkerNameOption->setChecked(g_settings.group_debug_marker_option_name_stat());

    ui->radiobuttonDebugMarkerOmitOption->setText(g_settings.group_debug_marker_option_omit_label());
    ui->radiobuttonDebugMarkerOmitOption->setChecked(g_settings.group_debug_marker_option_omit_stat());

    setEnableDebugMarkerOptions();

    connect(ui->radiobuttonDebugMarkerNameOption, SIGNAL(toggled(bool)),
            SLOT(radiobuttonNameCB(bool)));
    connect(ui->radiobuttonDebugMarkerOmitOption, SIGNAL(toggled(bool)),
            SLOT(radiobuttonOmitCB(bool)));

    // Nest options
    checkboxList.clear();

    // Groupbox
    ui->groupboxNestOptions->setTitle(g_settings.groupbox_nest_options_name());
    ui->groupboxNestOptions->setChecked(g_settings.groupbox_nest_options_stat());
    ui->groupboxNestOptions->setEnabled(g_settings.groupbox_nest_options_used());
    if (g_settings.groupbox_nest_options_stat())
    {
        // For now, toggle State/Render groups and Nest options
        checkboxStateRenderCB(false);
    }

    // Checkboxes
    QStringList group_nest_options_names = g_settings.group_nest_options_names();
    QVector<bool> nest_options_stat = g_settings.group_nest_options_stat();
    QVector<bool> nest_options_used = g_settings.group_nest_options_used();
    int nest_options_cnt = group_nest_options_names.size();
    for (int i = 0; i < nest_options_cnt; i++)
    {
        checkboxList << new QCheckBox(group_nest_options_names[i], ui->groupboxNestOptions);
        checkboxList[i]->setChecked(nest_options_stat[i]);
        checkboxList[i]->setEnabled(nest_options_used[i]);
        ui->vLayout_groupboxNestOptionsScrollarea->addWidget(checkboxList[i]);
    }

    connect(ui->groupboxNestOptions, SIGNAL(toggled(bool)), // groupbox
            SLOT(groupboxNestOptionsCB(bool)));

    for (int i = 0; i < nest_options_cnt; i++) // checkboxes in groupbox
    {
        connect(checkboxList[i], SIGNAL(stateChanged(int)),
                SLOT(checkboxCB(int)));
    }

    // Save initial state
    m_bGroupInitialState = groupState();

} // constructor

vogleditor_QSettingsDialog::~vogleditor_QSettingsDialog()
{
    clearLayout(ui->verticalLayout_tabGroups);
    delete ui;
} // destructor

void vogleditor_QSettingsDialog::clearLayout(QLayout *layout)
{
    // taken from
    // http://stackoverflow.com/questions/4272196/qt-remove-all-widgets-from-layout
    // ... didn't seem to make any difference using valgrind Memcheck...

    while (QLayoutItem *item = layout->takeAt(0))
    {
        delete item->widget();
        if (QLayout *childLayout = item->layout())
            clearLayout(childLayout);
        delete item;
    }
} // clearLayout

void vogleditor_QSettingsDialog::tabCB(int page)
{
    g_settings.set_tab_page(page);
}

void vogleditor_QSettingsDialog::checkboxStateRenderCB(int val)
{
    bool bVal = bool(val);
    if (bVal)
    {
        ui->groupboxNestOptions->setChecked(!bVal);
        g_settings.set_groupbox_nest_options_stat(!bVal);
    }
    // Update
    g_settings.set_group_state_render_stat(bVal);
    updateTextTab();

} // checkboxStateRenderCB

void vogleditor_QSettingsDialog::groupboxNestOptionsCB(bool bVal)
{
    if (bVal)
    {
        ui->checkboxStateRender->setChecked(!bVal);
        g_settings.set_group_state_render_stat(!bVal);
    }
    // Update
    g_settings.set_groupbox_nest_options_stat(bVal);
    updateTextTab();

} // groupboxNestOptionsCB

void vogleditor_QSettingsDialog::checkboxCB(int state)
{
    g_settings.set_group_state_render_stat(ui->checkboxStateRender->isChecked());
    g_settings.set_group_debug_marker_stat(checkboxValues(ui->groupboxDebugMarker));
    g_settings.set_group_nest_options_stat(checkboxValues(ui->groupboxNestOptions));

    setEnableDebugMarkerOptions();

    updateTextTab();

} // checkboxCB

void vogleditor_QSettingsDialog::setEnableDebugMarkerOptions()
{
    //  Disable options if no Debug marker groups are checked
    QVector<bool> bCurrentState = checkboxValues(ui->groupboxDebugMarker);

    bool bVal;
    foreach(bVal, bCurrentState)
    {
        if (bVal)
            break;
    }
    enableDebugMarkerOptions(bVal);
}
void vogleditor_QSettingsDialog::enableDebugMarkerOptions(bool bVal)
{
    ui->radiobuttonDebugMarkerNameOption->setEnabled(bVal);
    ui->radiobuttonDebugMarkerOmitOption->setEnabled(bVal);

    // Notify g_settings
    g_settings.set_group_debug_marker_option_name_used(bVal);
    g_settings.set_group_debug_marker_option_omit_used(bVal);
}

void vogleditor_QSettingsDialog::radiobuttonNameCB(bool state)
{
    g_settings.set_group_debug_marker_option_name_stat(state);
    updateTextTab();
}

void vogleditor_QSettingsDialog::radiobuttonOmitCB(bool state)
{
    g_settings.set_group_debug_marker_option_omit_stat(state);
    updateTextTab();
}

void vogleditor_QSettingsDialog::updateTextTab()
{
    //update json tab settings page
    QString strSettings = g_settings.to_string();
    ui->textEdit->setText(strSettings);
}

QVector<bool> vogleditor_QSettingsDialog::checkboxValues(QObject *widget)
{
    // Note: This function is intended to only return checkbox values of
    //       API call names, so for the Debug marker API call list parent
    //       radiobuttons were used for the options.
    QList<QCheckBox *> groupCheckBoxes = widget->findChildren<QCheckBox *>();

    QVector<bool> bQVector;
    QList<QCheckBox *>::const_iterator iter = groupCheckBoxes.begin();

    while (iter != groupCheckBoxes.end())
    {
        bQVector << (*iter)->isChecked();
        iter++;
    }
    return bQVector;

} // checkboxValues()

QVector<bool> vogleditor_QSettingsDialog::groupState()
{
    QVector<bool> bCurrentState;

    bCurrentState << ui->checkboxStateRender->isChecked();
    bCurrentState << ui->groupboxNestOptions->isChecked();

    bCurrentState << checkboxValues(ui->groupboxDebugMarker);
    bCurrentState << checkboxValues(ui->groupboxNestOptions);

    bCurrentState << ui->radiobuttonDebugMarkerNameOption->isChecked();
    bCurrentState << ui->radiobuttonDebugMarkerOmitOption->isChecked();

    return bCurrentState;

} // groupState

void vogleditor_QSettingsDialog::reset()
{
    if (groupOptionsChanged())
    {
        // Set in same order as saved (from ::groupState())
        //
        // TODO: QMap these, widget key to value, in constructor
        //       so order won't matter
        int i = 0;
        ui->checkboxStateRender->setChecked(m_bGroupInitialState[i++]);
        ui->groupboxNestOptions->setChecked(m_bGroupInitialState[i++]);

        QList<QCheckBox *> checkboxes = ui->groupboxDebugMarker->findChildren<QCheckBox *>();
        for (int indx = 0; indx < checkboxes.count(); indx++)
        {
            checkboxes[indx]->setChecked(m_bGroupInitialState[i++]);
        }
        checkboxes = ui->groupboxNestOptions->findChildren<QCheckBox *>();
        for (int indx = 0; indx < checkboxes.count(); indx++)
        {
            checkboxes[indx]->setChecked(m_bGroupInitialState[i++]);
        }

        ui->radiobuttonDebugMarkerNameOption->setChecked(m_bGroupInitialState[i++]);
        ui->radiobuttonDebugMarkerOmitOption->setChecked(m_bGroupInitialState[i++]);
    }
} // reset

bool vogleditor_QSettingsDialog::groupOptionsChanged()
{
    return m_bGroupInitialState != groupState();
}

void vogleditor_QSettingsDialog::acceptCB()
{
    save();

    if (groupOptionsChanged())
    {
        emit settingsChanged();
    }
}

void vogleditor_QSettingsDialog::cancelCB()
{
    reset();
}

void vogleditor_QSettingsDialog::save()
{
    g_settings.from_string(ui->textEdit->toPlainText().toStdString().c_str());
    g_settings.save();
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "gflags/gflags.h"
#include "opencv2/opencv.hpp"

#include "cyber/common/log.h"
#include "modules/perception/inference/inference.h"
#include "modules/perception/inference/inference_factory.h"
#include "modules/perception/inference/tensorrt/batch_stream.h"
#include "modules/perception/inference/tensorrt/entropy_calibrator.h"
#include "modules/perception/inference/tensorrt/rt_net.h"
#include "modules/perception/inference/utils/util.h"

DEFINE_bool(int8, false, "use int8");
DEFINE_string(names_file, "./lane_parser/blob_names.txt",
              "path of output blob");
DEFINE_string(test_list, "image_list.txt", "path of image list");
DEFINE_string(image_root, "./images/", "path of image dir");
DEFINE_string(image_ext, ".jpg", "path of image ext");
DEFINE_string(res_dir, "./result.dat", "path of result");

int main(int argc, char **argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  std::vector<float> output_data_vec1;
  std::vector<cv::Scalar> color_table;
  color_table.push_back(cv::Scalar(0, 97, 255));    // for other >0 mask values
  color_table.push_back(cv::Scalar(0, 0, 255));     // for mask value = 1
  color_table.push_back(cv::Scalar(0, 255, 0));     // for mask value = 2
  color_table.push_back(cv::Scalar(255, 0, 0));     // for mask value = 3
  color_table.push_back(cv::Scalar(240, 32, 160));  // for mask value = 4

  const std::string proto_file = "./lane_parser/caffe.pt";
  const std::string weight_file = "./lane_parser/caffe.caffemodel";
  const std::string model_root = "./lane_parser/";

  cudaDeviceProp prop;
  cudaGetDeviceProperties(&prop, 0);
  AINFO << prop.name;

  apollo::perception::inference::Inference *rt_net;
  const std::string input_blob_name = "data";
  std::vector<std::string> inputs{"data"};

  std::vector<std::string> outputs{"loc_pred", "obj_pred", "cls_pred",
                                   "ori_pred", "dim_pred", "lof_pred",
                                   "lor_pred", "conv4_3"};

  apollo::perception::inference::load_data<std::string>(FLAGS_names_file,
                                                        &outputs);
  for (auto name : outputs) {
    ADEBUG << name;
  }

  if (FLAGS_int8) {
    apollo::perception::inference::BatchStream stream(2, 50, "./batches/");
    nvinfer1::Int8EntropyCalibrator calibrator(stream, 0, true, "./");
    std::cout << "int8" << std::endl;
    rt_net = apollo::perception::inference::CreateInferenceByName(
        "RTNetInt8", proto_file, weight_file, outputs, inputs, model_root);
  } else {
    std::cout << "fp32" << std::endl;
    rt_net = apollo::perception::inference::CreateInferenceByName(
        "RTNet", proto_file, weight_file, outputs, inputs);
  }
  const int height = 608;
  const int width = 1024;
  const int offset_y = 0;
  std::vector<int> shape = {1, 3, height, width};
  std::map<std::string, std::vector<int>> shape_map{{input_blob_name, shape}};

  rt_net->Init(shape_map);

  auto input_blob = rt_net->get_blob("data");
  std::vector<std::string> image_lists;
  apollo::perception::inference::load_data<std::string>(FLAGS_test_list,
                                                        &image_lists);
  std::vector<float> output_data_vec;

  for (auto image_file : image_lists) {
    cv::Mat img =
        cv::imread(FLAGS_image_root + image_file + FLAGS_image_ext, CV_8UC1);
    ADEBUG << img.channels();
    cv::Rect roi(0, offset_y, img.cols, img.rows - offset_y);
    cv::Mat img_roi = img(roi);
    img_roi.copyTo(img);
    cv::resize(img, img, cv::Size(width, height));

    const int count = 1 * width * height;
    std::vector<float> input(count);
    for (int i = 0; i < count; i++) {
      input[i] = static_cast<float>(img.data[i] - 128) * 0.0078125f;
    }
    cudaMemcpy(input_blob->mutable_gpu_data(), &input[0], count * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaDeviceSynchronize();
    rt_net->Infer();
    cudaDeviceSynchronize();

    for (auto output_name : outputs) {
      auto blob = rt_net->get_blob(output_name);
      std::vector<float> tmp_vec(blob->cpu_data(),
                                 blob->cpu_data() + blob->count());
      if (output_name == "output") {
        const float *output_data = blob->cpu_data();
        for (int h = 0; h < img.rows; h++) {
          for (int w = 0; w < img.cols; w++) {
            int offset = blob->offset(0, 0, h, w);
            if (output_data[offset] > 0) {
              img.at<cv::Vec3b>(h, w)[0] = static_cast<unsigned char>(
                  img.at<cv::Vec3b>(w, h)[0] * 0.7 + color_table[0][0] * 0.3);
            }
          }
        }
        cv::imwrite("res.jpg", img);
      }
      output_data_vec.insert(output_data_vec.end(), tmp_vec.begin(),
                             tmp_vec.end());
    }
  }

  apollo::perception::inference::write_result(FLAGS_res_dir, output_data_vec);
  delete rt_net;

  return 0;
}
<commit_msg>Perception: consolidate lane_sample<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "gflags/gflags.h"
#include "opencv2/opencv.hpp"

#include "cyber/common/log.h"
#include "modules/perception/inference/inference.h"
#include "modules/perception/inference/inference_factory.h"
#include "modules/perception/inference/tensorrt/batch_stream.h"
#include "modules/perception/inference/tensorrt/entropy_calibrator.h"
#include "modules/perception/inference/tensorrt/rt_net.h"
#include "modules/perception/inference/utils/util.h"

DEFINE_bool(int8, false, "use int8");
DEFINE_string(names_file, "./lane_parser/blob_names.txt",
              "path of output blob");
DEFINE_string(test_list, "image_list.txt", "path of image list");
DEFINE_string(image_root, "./images/", "path of image dir");
DEFINE_string(image_ext, ".jpg", "path of image ext");
DEFINE_string(res_dir, "./result.dat", "path of result");

int main(int argc, char **argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  std::vector<cv::Scalar> color_table;
  color_table.push_back(cv::Scalar(0, 97, 255));    // for other >0 mask values
  color_table.push_back(cv::Scalar(0, 0, 255));     // for mask value = 1
  color_table.push_back(cv::Scalar(0, 255, 0));     // for mask value = 2
  color_table.push_back(cv::Scalar(255, 0, 0));     // for mask value = 3
  color_table.push_back(cv::Scalar(240, 32, 160));  // for mask value = 4

  const std::string proto_file = "./lane_parser/caffe.pt";
  const std::string weight_file = "./lane_parser/caffe.caffemodel";
  const std::string model_root = "./lane_parser/";

  cudaDeviceProp prop;
  cudaGetDeviceProperties(&prop, 0);
  AINFO << prop.name;

  apollo::perception::inference::Inference *rt_net;
  const std::string input_blob_name = "data";
  std::vector<std::string> inputs{"data"};

  std::vector<std::string> outputs{"loc_pred", "obj_pred", "cls_pred",
                                   "ori_pred", "dim_pred", "lof_pred",
                                   "lor_pred", "conv4_3"};

  apollo::perception::inference::load_data<std::string>(FLAGS_names_file,
                                                        &outputs);
  for (auto &name : outputs) {
    ADEBUG << name;
  }

  if (FLAGS_int8) {
    apollo::perception::inference::BatchStream stream(2, 50, "./batches/");
    nvinfer1::Int8EntropyCalibrator calibrator(stream, 0, true, "./");
    std::cout << "int8" << std::endl;
    rt_net = apollo::perception::inference::CreateInferenceByName(
        "RTNetInt8", proto_file, weight_file, outputs, inputs, model_root);
  } else {
    std::cout << "fp32" << std::endl;
    rt_net = apollo::perception::inference::CreateInferenceByName(
        "RTNet", proto_file, weight_file, outputs, inputs);
  }
  const int height = 608;
  const int width = 1024;
  const int offset_y = 0;
  std::vector<int> shape = {1, 3, height, width};
  std::map<std::string, std::vector<int>> shape_map{{input_blob_name, shape}};

  rt_net->Init(shape_map);

  auto input_blob = rt_net->get_blob("data");
  std::vector<std::string> image_lists;
  apollo::perception::inference::load_data<std::string>(FLAGS_test_list,
                                                        &image_lists);
  std::vector<float> output_data_vec;

  const int count = width * height;
  for (auto &image_file : image_lists) {
    cv::Mat img =
        cv::imread(FLAGS_image_root + image_file + FLAGS_image_ext, CV_8UC1);
    ADEBUG << img.channels();
    cv::Rect roi(0, offset_y, img.cols, img.rows - offset_y);
    cv::Mat img_roi = img(roi);
    img_roi.copyTo(img);
    cv::resize(img, img, cv::Size(width, height));

    std::vector<float> input(count);
    for (int i = 0; i < count; ++i) {
      input[i] = static_cast<float>(img.data[i] - 128) * 0.0078125f;
    }
    cudaMemcpy(input_blob->mutable_gpu_data(), &input[0], count * sizeof(float),
               cudaMemcpyHostToDevice);
    cudaDeviceSynchronize();
    rt_net->Infer();
    cudaDeviceSynchronize();

    for (auto &output_name : outputs) {
      auto blob = rt_net->get_blob(output_name);
      std::vector<float> tmp_vec(blob->cpu_data(),
                                 blob->cpu_data() + blob->count());
      if (output_name == "output") {
        const float *output_data = blob->cpu_data();
        for (int h = 0; h < img.rows; h++) {
          for (int w = 0; w < img.cols; w++) {
            int offset = blob->offset(0, 0, h, w);
            if (output_data[offset] > 0) {
              img.at<cv::Vec3b>(h, w)[0] = static_cast<unsigned char>(
                  img.at<cv::Vec3b>(w, h)[0] * 0.7 + color_table[0][0] * 0.3);
            }
          }
        }
        cv::imwrite("res.jpg", img);
      }
      output_data_vec.insert(output_data_vec.end(), tmp_vec.begin(),
                             tmp_vec.end());
    }
  }

  apollo::perception::inference::write_result(FLAGS_res_dir, output_data_vec);
  delete rt_net;

  return 0;
}
<|endoftext|>


<commit_before>#include "dglcontroller.h"
#include "dglgui.h"

DGLResourceListener::DGLResourceListener(uint listenerId, uint objectId, DGLResource::ObjectType type, DGLResourceManager* manager):
m_ListenerId(listenerId), m_ObjectId(objectId), m_ObjectType(type), m_Manager(manager), m_RefCount(0) {
    m_Manager->registerListener(this);
}

DGLResourceListener::~DGLResourceListener() {
    m_Manager->unregisterListener(this);
}

DGLResourceManager::DGLResourceManager(DglController* controller):m_MaxListenerId(0), m_Controller(controller) {}

void DGLResourceManager::emitQueries() {
    dglnet::QueryResourceMessage queries;
    for (std::multimap<uint, DGLResourceListener*>::iterator i = m_Listeners.begin(); i != m_Listeners.end(); i++) {
        dglnet::QueryResourceMessage::ResourceQuery query;
        query.m_ListenerId = i->first;
        query.m_ObjectId = i->second->m_ObjectId;
        query.m_Type = i->second->m_ObjectType;
        queries.m_ResourceQueries.push_back(query);
    }
    if (queries.m_ResourceQueries.size())
        m_Controller->sendMessage(&queries);
}

void DGLResourceManager::handleResourceMessage(const dglnet::ResourceMessage& msg) {

    int  idx = 0;
    bool end = false;

    //this strange method of iteration is to allow modification of m_Listeners

    for (int idx = 0; !end; idx++) {
        std::pair<std::multimap<uint, DGLResourceListener*>::iterator, std::multimap<uint, DGLResourceListener*>::iterator> range = m_Listeners.equal_range(msg.m_ListenerId);
        std::multimap<uint, DGLResourceListener*>::iterator i  = range.first;
        for (int j = 0; j < idx && i != range.second ; j++) {
            i++;
        }
        if (i == range.second) {
            end = true;
        } else {
            std::string errorMessage;
            if (msg.isOk(errorMessage)) {
                i->second->update(*msg.m_Resource);
            } else {
                i->second->error(errorMessage);
            }
        }
    }
}

DGLResourceListener* DGLResourceManager::createListener(uint objectId, DGLResource::ObjectType type) {
    for (std::multimap<uint, DGLResourceListener*>::iterator i = m_Listeners.begin(); i != m_Listeners.end(); i++) {
        if (i->second->m_ObjectId == objectId && i->second->m_ObjectType == type) {
            return new DGLResourceListener(i->second->m_ListenerId, objectId, type, this);
        }
    }
    return new DGLResourceListener(m_MaxListenerId++, objectId, type, this);
}

void DGLResourceManager::registerListener(DGLResourceListener* listener) {
    m_Listeners.insert(std::pair<uint, DGLResourceListener*>(listener->m_ListenerId, listener));

    dglnet::QueryResourceMessage queries;
    dglnet::QueryResourceMessage::ResourceQuery query;
    query.m_ListenerId = listener->m_ListenerId;
    query.m_ObjectId = listener->m_ObjectId;
    query.m_Type = listener->m_ObjectType;
    queries.m_ResourceQueries.push_back(query);
    m_Controller->sendMessage(&queries);
}

void DGLResourceManager::unregisterListener(DGLResourceListener* listener) {
    std::pair<std::multimap<uint, DGLResourceListener*>::iterator, std::multimap<uint, DGLResourceListener*>::iterator> range = m_Listeners.equal_range(listener->m_ListenerId);
    for (std::multimap<uint, DGLResourceListener*>::iterator i = range.first; i != range.second; i++) {
        if (i->second == listener) {
            m_Listeners.erase(i);
            break;
        }
    }
}

void DGLViewRouter::show(uint name, DGLResource::ObjectType type, uint target) {
    switch (type) {
        case DGLResource::ObjectTypeBuffer:
            emit showBuffer(name);
            break;
        case DGLResource::ObjectTypeFramebuffer:
            emit showFramebuffer(name);
            break;
        case DGLResource::ObjectTypeFBO:
            emit showFBO(name);
            break;
        case DGLResource::ObjectTypeTexture:
            emit showTexture(name);
            break;
        case DGLResource::ObjectTypeShader:
            assert(target);
            emit showShader(name, target);
            break;
        case DGLResource::ObjectTypeProgram:
            emit showProgram(name);
            break;
    }
}

DglController::DglController():m_Disconnected(true), m_Connected(false), m_ConfiguredAndBkpointsSet(false), m_BreakPointController(this), m_ResourceManager(this) {
    m_Timer.setInterval(10);
    CONNASSERT(connect(&m_Timer, SIGNAL(timeout()), this, SLOT(poll())));
}

void DglController::connectServer(const std::string& host, const std::string& port) {
    if (m_DglClient) {
        disconnectServer();
    }

    //we are not disconnected, but not yet connected - so we do not set m_Connected
    m_Disconnected = false;

    m_DglClient = boost::make_shared<dglnet::Client>(this, this);
    m_DglClient->connectServer(host, port);
    m_Timer.start();
}

void DglController::onSocket() {
    //m_Timer.stop();
    m_NotifierRead = boost::make_shared<QSocketNotifier>(m_DglClient->getSocketFD(), QSocketNotifier::Read);
    m_NotifierWrite = boost::make_shared<QSocketNotifier>(m_DglClient->getSocketFD(), QSocketNotifier::Write);
    CONNASSERT(connect(&*m_NotifierRead, SIGNAL(activated(int)), this, SLOT(poll())));
    CONNASSERT(connect(&*m_NotifierWrite, SIGNAL(activated(int)), this, SLOT(poll())));
}

void DglController::disconnectServer() {
    if (m_DglClient) {
        m_DglClient->abort();
        m_DglClient.reset();
        m_ConfiguredAndBkpointsSet = false;
        setConnected(false);
        setDisconnected(true);
        debugeeInfo("");
    }
    m_Connected = false;
    m_NotifierRead.reset();
    m_NotifierWrite.reset();
}

bool DglController::isConnected() {
    return m_Connected;
}

void DglController::poll() {
    if (m_DglClient) {
        m_DglClient->poll();

        if (m_Disconnected)  {
            //one of asio handlers requested disconnection
            disconnectServer();
            error(tr("Connection error"), m_DglClientDeadInfo.c_str());
        }
    }
}

void DglController::debugContinue() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(false);
    m_DglClient->sendMessage(&message);
}

void DglController::debugInterrupt() {
    assert(isConnected());
    dglnet::ContinueBreakMessage message(true);
    m_DglClient->sendMessage(&message);
}

void DglController::debugStep() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_CALL);
    m_DglClient->sendMessage(&message);
}

void DglController::debugStepDrawCall() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_DRAW_CALL);
    m_DglClient->sendMessage(&message);
}

void DglController::debugStepFrame() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_FRAME);
    m_DglClient->sendMessage(&message);
}

void DglController::onSetStatus(std::string str) {
    newStatus(str.c_str());
}

void DglController::queryCallTrace(uint startOffset, uint endOffset) {
    dglnet::QueryCallTraceMessage message(startOffset, endOffset);
    m_DglClient->sendMessage(&message);
}

void DglController::doHandle(const dglnet::HelloMessage & msg) {
    //we are connected now
    m_Connected = true;
    debugeeInfo(msg.m_ProcessName);
    setConnected(true);
    setDisconnected(false);
}

void DglController::doHandle(const dglnet::BreakedCallMessage & msg) {
    if (!m_ConfiguredAndBkpointsSet) {
        //this is the first time debugee was stopped, before any execution
        //we must upload some configuration to it
        m_ConfiguredAndBkpointsSet = true;

        sendConfig();
        getBreakPoints()->sendCurrent();
    }

    setBreaked(true);
    setRunning(false);

    breaked(msg.m_entryp, msg.m_TraceSize);
    breakedWithStateReports(msg.m_CurrentCtx, msg.m_CtxReports);

    m_ResourceManager.emitQueries();

}

void DglController::doHandle(const dglnet::CallTraceMessage& msg) {
    gotCallTraceChunkChunk(msg.m_StartOffset, msg.m_Trace);
}

void DglController::doHandle(const dglnet::ResourceMessage& msg) {
    m_ResourceManager.handleResourceMessage(msg);
}

void DglController::doHandleDisconnect(const std::string& msg) {
    m_DglClientDeadInfo = msg;
    m_Disconnected = true;
    m_Connected = !m_Disconnected;
}

void DglController::sendMessage(dglnet::Message* msg) {
    assert(isConnected());
    m_DglClient->sendMessage(msg);
}

DGLBreakPointController* DglController::getBreakPoints() {
    return &m_BreakPointController;
}

DGLResourceManager* DglController::getResourceManager() {
    return &m_ResourceManager;
}

DGLViewRouter* DglController::getViewRouter() {
    return &m_ViewRouter;
}

void DglController::configure(const DGLConfiguration& config) {
    m_Config = config;
    sendConfig();
}

void DglController::sendConfig() {
    if (isConnected()) {
        dglnet::ConfigurationMessage message(m_Config);
        m_DglClient->sendMessage(&message);
    }
}

const DGLConfiguration& DglController::getConfig() {
    return m_Config;
}

DGLBreakPointController::DGLBreakPointController(DglController* controller):m_Controller(controller) {}

std::set<Entrypoint> DGLBreakPointController::getCurrent() {
    return m_Current;
}

void DGLBreakPointController::setCurrent(const std::set<Entrypoint>& newCurrent) {
    if (m_Current != newCurrent) {
        m_Current = newCurrent;
        sendCurrent();
    }
}

void DGLBreakPointController::sendCurrent() {
    if (m_Controller->isConnected()) {
        dglnet::SetBreakPointsMessage msg(m_Current);
        m_Controller->sendMessage(&msg);
    }
}<commit_msg>More status-es in qstatusbar<commit_after>#include "dglcontroller.h"
#include "dglgui.h"

DGLResourceListener::DGLResourceListener(uint listenerId, uint objectId, DGLResource::ObjectType type, DGLResourceManager* manager):
m_ListenerId(listenerId), m_ObjectId(objectId), m_ObjectType(type), m_Manager(manager), m_RefCount(0) {
    m_Manager->registerListener(this);
}

DGLResourceListener::~DGLResourceListener() {
    m_Manager->unregisterListener(this);
}

DGLResourceManager::DGLResourceManager(DglController* controller):m_MaxListenerId(0), m_Controller(controller) {}

void DGLResourceManager::emitQueries() {
    dglnet::QueryResourceMessage queries;
    for (std::multimap<uint, DGLResourceListener*>::iterator i = m_Listeners.begin(); i != m_Listeners.end(); i++) {
        dglnet::QueryResourceMessage::ResourceQuery query;
        query.m_ListenerId = i->first;
        query.m_ObjectId = i->second->m_ObjectId;
        query.m_Type = i->second->m_ObjectType;
        queries.m_ResourceQueries.push_back(query);
    }
    if (queries.m_ResourceQueries.size())
        m_Controller->sendMessage(&queries);
}

void DGLResourceManager::handleResourceMessage(const dglnet::ResourceMessage& msg) {

    int  idx = 0;
    bool end = false;

    //this strange method of iteration is to allow modification of m_Listeners

    for (int idx = 0; !end; idx++) {
        std::pair<std::multimap<uint, DGLResourceListener*>::iterator, std::multimap<uint, DGLResourceListener*>::iterator> range = m_Listeners.equal_range(msg.m_ListenerId);
        std::multimap<uint, DGLResourceListener*>::iterator i  = range.first;
        for (int j = 0; j < idx && i != range.second ; j++) {
            i++;
        }
        if (i == range.second) {
            end = true;
        } else {
            std::string errorMessage;
            if (msg.isOk(errorMessage)) {
                i->second->update(*msg.m_Resource);
            } else {
                i->second->error(errorMessage);
            }
        }
    }
}

DGLResourceListener* DGLResourceManager::createListener(uint objectId, DGLResource::ObjectType type) {
    for (std::multimap<uint, DGLResourceListener*>::iterator i = m_Listeners.begin(); i != m_Listeners.end(); i++) {
        if (i->second->m_ObjectId == objectId && i->second->m_ObjectType == type) {
            return new DGLResourceListener(i->second->m_ListenerId, objectId, type, this);
        }
    }
    return new DGLResourceListener(m_MaxListenerId++, objectId, type, this);
}

void DGLResourceManager::registerListener(DGLResourceListener* listener) {
    m_Listeners.insert(std::pair<uint, DGLResourceListener*>(listener->m_ListenerId, listener));

    dglnet::QueryResourceMessage queries;
    dglnet::QueryResourceMessage::ResourceQuery query;
    query.m_ListenerId = listener->m_ListenerId;
    query.m_ObjectId = listener->m_ObjectId;
    query.m_Type = listener->m_ObjectType;
    queries.m_ResourceQueries.push_back(query);
    m_Controller->sendMessage(&queries);
}

void DGLResourceManager::unregisterListener(DGLResourceListener* listener) {
    std::pair<std::multimap<uint, DGLResourceListener*>::iterator, std::multimap<uint, DGLResourceListener*>::iterator> range = m_Listeners.equal_range(listener->m_ListenerId);
    for (std::multimap<uint, DGLResourceListener*>::iterator i = range.first; i != range.second; i++) {
        if (i->second == listener) {
            m_Listeners.erase(i);
            break;
        }
    }
}

void DGLViewRouter::show(uint name, DGLResource::ObjectType type, uint target) {
    switch (type) {
        case DGLResource::ObjectTypeBuffer:
            emit showBuffer(name);
            break;
        case DGLResource::ObjectTypeFramebuffer:
            emit showFramebuffer(name);
            break;
        case DGLResource::ObjectTypeFBO:
            emit showFBO(name);
            break;
        case DGLResource::ObjectTypeTexture:
            emit showTexture(name);
            break;
        case DGLResource::ObjectTypeShader:
            assert(target);
            emit showShader(name, target);
            break;
        case DGLResource::ObjectTypeProgram:
            emit showProgram(name);
            break;
    }
}

DglController::DglController():m_Disconnected(true), m_Connected(false), m_ConfiguredAndBkpointsSet(false), m_BreakPointController(this), m_ResourceManager(this) {
    m_Timer.setInterval(10);
    CONNASSERT(connect(&m_Timer, SIGNAL(timeout()), this, SLOT(poll())));
}

void DglController::connectServer(const std::string& host, const std::string& port) {
    if (m_DglClient) {
        disconnectServer();
    }

    //we are not disconnected, but not yet connected - so we do not set m_Connected
    m_Disconnected = false;

    m_DglClient = boost::make_shared<dglnet::Client>(this, this);
    m_DglClient->connectServer(host, port);
    m_Timer.start();
}

void DglController::onSocket() {
    //m_Timer.stop();
    m_NotifierRead = boost::make_shared<QSocketNotifier>(m_DglClient->getSocketFD(), QSocketNotifier::Read);
    m_NotifierWrite = boost::make_shared<QSocketNotifier>(m_DglClient->getSocketFD(), QSocketNotifier::Write);
    CONNASSERT(connect(&*m_NotifierRead, SIGNAL(activated(int)), this, SLOT(poll())));
    CONNASSERT(connect(&*m_NotifierWrite, SIGNAL(activated(int)), this, SLOT(poll())));
}

void DglController::disconnectServer() {
    if (m_DglClient) {
        m_DglClient->abort();
        m_DglClient.reset();
        m_ConfiguredAndBkpointsSet = false;
        setConnected(false);
        setDisconnected(true);
        debugeeInfo("");
    }
    m_Connected = false;
    m_NotifierRead.reset();
    m_NotifierWrite.reset();
    newStatus("Disconnected.");
}

bool DglController::isConnected() {
    return m_Connected;
}

void DglController::poll() {
    if (m_DglClient) {
        m_DglClient->poll();

        if (m_Disconnected)  {
            //one of asio handlers requested disconnection
            disconnectServer();
            error(tr("Connection error"), m_DglClientDeadInfo.c_str());
        }
    }
}

void DglController::debugContinue() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(false);
    m_DglClient->sendMessage(&message);
}

void DglController::debugInterrupt() {
    assert(isConnected());
    dglnet::ContinueBreakMessage message(true);
    m_DglClient->sendMessage(&message);
    newStatus("Interrupting...");
}

void DglController::debugStep() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_CALL);
    m_DglClient->sendMessage(&message);
    newStatus("Running...");
}

void DglController::debugStepDrawCall() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_DRAW_CALL);
    m_DglClient->sendMessage(&message);
    newStatus("Running...");
}

void DglController::debugStepFrame() {
    setBreaked(false);
    setRunning(true);
    assert(isConnected());
    dglnet::ContinueBreakMessage message(dglnet::ContinueBreakMessage::STEP_FRAME);
    m_DglClient->sendMessage(&message);
    newStatus("Running...");
}

void DglController::onSetStatus(std::string str) {
    newStatus(str.c_str());
}

void DglController::queryCallTrace(uint startOffset, uint endOffset) {
    dglnet::QueryCallTraceMessage message(startOffset, endOffset);
    m_DglClient->sendMessage(&message);
}

void DglController::doHandle(const dglnet::HelloMessage & msg) {
    //we are connected now
    m_Connected = true;
    debugeeInfo(msg.m_ProcessName);
    setConnected(true);
    setDisconnected(false);
}

void DglController::doHandle(const dglnet::BreakedCallMessage & msg) {
    if (!m_ConfiguredAndBkpointsSet) {
        //this is the first time debugee was stopped, before any execution
        //we must upload some configuration to it
        m_ConfiguredAndBkpointsSet = true;

        sendConfig();
        getBreakPoints()->sendCurrent();
    }

    setBreaked(true);
    setRunning(false);

    breaked(msg.m_entryp, msg.m_TraceSize);
    breakedWithStateReports(msg.m_CurrentCtx, msg.m_CtxReports);

    m_ResourceManager.emitQueries();

    newStatus("Breaked execution.");
}

void DglController::doHandle(const dglnet::CallTraceMessage& msg) {
    gotCallTraceChunkChunk(msg.m_StartOffset, msg.m_Trace);
}

void DglController::doHandle(const dglnet::ResourceMessage& msg) {
    m_ResourceManager.handleResourceMessage(msg);
}

void DglController::doHandleDisconnect(const std::string& msg) {
    m_DglClientDeadInfo = msg;
    m_Disconnected = true;
    m_Connected = !m_Disconnected;
}

void DglController::sendMessage(dglnet::Message* msg) {
    assert(isConnected());
    m_DglClient->sendMessage(msg);
}

DGLBreakPointController* DglController::getBreakPoints() {
    return &m_BreakPointController;
}

DGLResourceManager* DglController::getResourceManager() {
    return &m_ResourceManager;
}

DGLViewRouter* DglController::getViewRouter() {
    return &m_ViewRouter;
}

void DglController::configure(const DGLConfiguration& config) {
    m_Config = config;
    sendConfig();
}

void DglController::sendConfig() {
    if (isConnected()) {
        dglnet::ConfigurationMessage message(m_Config);
        m_DglClient->sendMessage(&message);
    }
}

const DGLConfiguration& DglController::getConfig() {
    return m_Config;
}

DGLBreakPointController::DGLBreakPointController(DglController* controller):m_Controller(controller) {}

std::set<Entrypoint> DGLBreakPointController::getCurrent() {
    return m_Current;
}

void DGLBreakPointController::setCurrent(const std::set<Entrypoint>& newCurrent) {
    if (m_Current != newCurrent) {
        m_Current = newCurrent;
        sendCurrent();
    }
}

void DGLBreakPointController::sendCurrent() {
    if (m_Controller->isConnected()) {
        dglnet::SetBreakPointsMessage msg(m_Current);
        m_Controller->sendMessage(&msg);
    }
}<|endoftext|>


<commit_before>/*
 * Part of tivars_lib_cpp
 * (C) 2015-2018 Adrien "Adriweb" Bertrand
 * https://github.com/adriweb/tivars_lib_cpp
 * License: MIT
 */

#include "TypeHandlers.h"
#include "../utils.h"
#include <unordered_map>
#include <iostream>
#include <iterator>
#include <regex>
#include <fstream>

namespace tivars
{
    namespace TH_Tokenized
    {
        std::unordered_map<uint, std::vector<std::string>> tokens_BytesToName;
        std::unordered_map<std::string, uint> tokens_NameToBytes;
        uchar lengthOfLongestTokenName;
        std::vector<uchar> firstByteOfTwoByteTokens;
        const uint16_t squishedASMTokens[] = { 0xBB6D, 0xEF69, 0xEF7B }; // 83+/84+, 84+CSE, CE
    }

    /* TODO: handle TI-Innovator Send( exception for in-strings tokenization (=> not shortest tokens) */
    data_t TH_Tokenized::makeDataFromString(const std::string& str, const options_t& options)
    {
        (void)options;
        data_t data;

        // two bytes reserved for the size. Filled later
        data.push_back(0); data.push_back(0);

        const uchar maxTokSearchLen = std::min((uchar)str.length(), lengthOfLongestTokenName);

        bool isWithinString = false;

        for (uint strCursorPos = 0; strCursorPos < str.length(); strCursorPos++)
        {
            const std::string currChar = str.substr(strCursorPos, 1);
            if (currChar == "\"")
            {
                isWithinString = !isWithinString;
            } else if (currChar == "\n" || currChar == "→")
            {
                isWithinString = false;
            }
            /* isWithinString => minimum token length, otherwise maximal munch */
            for (uint currentLength = isWithinString ? 1 : maxTokSearchLen;
                 isWithinString ? (currentLength <= maxTokSearchLen) : (currentLength > 0);
                 currentLength += (isWithinString ? 1 : -1))
            {
                std::string currentSubString = str.substr(strCursorPos, currentLength);
                if (tokens_NameToBytes.count(currentSubString))
                {
                    uint tokenValue = tokens_NameToBytes[currentSubString];
                    if (tokenValue > 0xFF)
                    {
                        data.push_back((uchar)(tokenValue >> 8));
                    }
                    data.push_back((uchar)(tokenValue & 0xFF));
                    strCursorPos += currentLength - 1;
                    break;
                }
            }
        }

        uint actualDataLen = (uint) (data.size() - 2);
        data[0] = (uchar)(actualDataLen & 0xFF);
        data[1] = (uchar)((actualDataLen >> 8) & 0xFF);
        return data;
    }

    std::string TH_Tokenized::makeStringFromData(const data_t& data, const options_t& options)
    {
        if (data.size() < 2)
        {
            throw std::invalid_argument("Invalid data array. Needs to contain at least 2 bytes (size fields)");
        }

        uint langIdx = (uint)((has_option(options, "lang") && options.at("lang") == LANG_FR) ? LANG_FR : LANG_EN);

        const int howManyBytes = (data[0] & 0xFF) + ((data[1] & 0xFF) << 8);
        if (howManyBytes != (int)data.size() - 2)
        {
            std::cerr << "[Warning] Byte count (" << (data.size() - 2) << ") and size field (" << howManyBytes  << ") mismatch!";
        }

        if (howManyBytes >= 2)
        {
            const uint16_t twoFirstBytes = (uint16_t) ((data[3] & 0xFF) + ((data[2] & 0xFF) << 8));
            if (std::find(std::begin(squishedASMTokens), std::end(squishedASMTokens), twoFirstBytes) != std::end(squishedASMTokens))
            {
                return "[Error] This is a squished ASM program - cannnot preview it!";
            }
        }

        uint errCount = 0;
        std::string str;
        const size_t dataSize = data.size();
        for (uint i = 2; i < (uint)howManyBytes + 2; i++)
        {
            uint currentToken = data[i];
            uint nextToken = (i < dataSize-1) ? data[i+1] : (uint)-1;
            uint bytesKey = currentToken;
            if (is_in_vector(firstByteOfTwoByteTokens, (uchar)currentToken))
            {
                if (nextToken == (uint)-1)
                {
                    std::cerr << "[Warning] Encountered an unfinished two-byte token! Setting the second byte to 0x00";
                    nextToken = 0x00;
                }
                bytesKey = nextToken + (currentToken << 8);
                i++;
            }
            if (tokens_BytesToName.find(bytesKey) != tokens_BytesToName.end())
            {
                str += tokens_BytesToName[bytesKey][langIdx];
            } else {
                str += " [???] ";
                errCount++;
            }
        }

        if (errCount > 0)
        {
            std::cerr << "[Warning] " << errCount << " token(s) could not be detokenized (' [???] ' was used)!";
        }

        if (has_option(options, "prettify") && options.at("prettify") == 1)
        {
            str = std::regex_replace(str, std::regex(R"(\[?\|?([a-z]+)\]?)"), "$1");
        }

        if (has_option(options, "reindent") && options.at("reindent") == 1)
        {
            str = reindentCodeString(str);
        }

        return str;
    }

    std::string TH_Tokenized::reindentCodeString(const std::string& str_orig, const options_t& options)
    {
        int lang;
        if (has_option(options, "lang"))
        {
            lang = options.at("lang");
        } else {
            lang = (str_orig.size() > 1 && str_orig[0] == '.' && (str_orig[1] == '.' || ::isalpha(str_orig[1]))) ? PRGMLANG_AXE : PRGMLANG_BASIC;
        }

        std::string str(str_orig);

        str = std::regex_replace(str, std::regex("([^\\s])(Del|Eff)Var "), "$1\n$2Var ");

        std::vector<std::string> lines_tmp = explode(str, '\n');

        // Inplace-replace the appropriate ":" by new-line chars (ie, by inserting the split string in the lines_tmp array)
        for (uint16_t idx = 0; idx < (uint16_t)lines_tmp.size(); idx++)
        {
            const auto line = lines_tmp[idx];
            bool isWithinString = false;
            for (uint16_t strIdx = 0; strIdx < (uint16_t)line.size(); strIdx++)
            {
                const auto currChar = line.substr(strIdx, 1);
                if (currChar == ":" && !isWithinString)
                {
                    lines_tmp[idx] = line.substr(0, strIdx); // replace "old" line by lhs
                    lines_tmp.insert(lines_tmp.begin() + idx + 1, line.substr(strIdx + 1)); // inserting rhs
                    break;
                } else if (currChar == "\"") {
                    isWithinString = !isWithinString;
                } else if (currChar == "\n" || currChar == "→") {
                    isWithinString = false;
                }
            }
        }

        std::vector<std::pair<uint, std::string>> lines(lines_tmp.size()); // indent, text
        for (const auto& line : lines_tmp)
        {
            lines.emplace_back(0, line);
        }

        std::vector<std::string> increaseIndentAfter   = { "If", "For", "While", "Repeat" };
        std::vector<std::string> decreaseIndentOfToken = { "Then", "Else", "End", "ElseIf", "EndIf", "End!If" };
        std::vector<std::string> closingTokens         = { "End", "EndIf", "End!If" };
        uint nextIndent = 0;
        std::string oldFirstCommand, firstCommand;
        for (auto& line : lines)
        {
            oldFirstCommand = firstCommand;

            std::string trimmedLine = trim(line.second);
            if (trimmedLine.length() > 0) {
                char* trimmedLine_c = (char*) trimmedLine.c_str();
                firstCommand = strtok(trimmedLine_c, " ");
                firstCommand = trim(firstCommand);
                trimmedLine = std::string(trimmedLine_c);
                trimmedLine_c = (char*) trimmedLine.c_str();
                if (firstCommand == trimmedLine)
                {
                    firstCommand = strtok(trimmedLine_c, "(");
                    firstCommand = trim(firstCommand);
                }
            } else {
                firstCommand = "";
            }

            line.first = nextIndent;

            if (is_in_vector(increaseIndentAfter, firstCommand))
            {
                nextIndent++;
            }
            if (line.first > 0 && is_in_vector(decreaseIndentOfToken, firstCommand))
            {
                line.first--;
            }
            if (nextIndent > 0 && (is_in_vector(closingTokens, firstCommand) || (oldFirstCommand == "If" && firstCommand != "Then" && lang != PRGMLANG_AXE)))
            {
                nextIndent--;
            }
        }

        str = "";
        for (const auto& line : lines)
        {
            str += str_repeat(" ", line.first * 3) + line.second + '\n';
        }

        return ltrim(rtrim(str, "\t\n\r\f\v"));
    }

    void TH_Tokenized::initTokens()
    {
        std::ifstream t("programs_tokens.csv");
        std::string csvFileStr((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());

        if (csvFileStr.length() > 0)
        {
            std::vector<std::vector<std::string>> lines;
            ParseCSV(csvFileStr, lines);

            for (const auto& tokenInfo : lines)
            {
                uint bytes;
                if (tokenInfo[6] == "2") // number of bytes for the token
                {
                    if (!is_in_vector(firstByteOfTwoByteTokens, hexdec(tokenInfo[7])))
                    {
                        firstByteOfTwoByteTokens.push_back(hexdec(tokenInfo[7]));
                    }
                    bytes = hexdec(tokenInfo[8]) + (hexdec(tokenInfo[7]) << 8);
                } else {
                    bytes = hexdec(tokenInfo[7]);
                }
                tokens_BytesToName[bytes] = { tokenInfo[4], tokenInfo[5] }; // EN, FR
                tokens_NameToBytes[tokenInfo[4]] = bytes; // EN
                tokens_NameToBytes[tokenInfo[5]] = bytes; // FR
                uchar maxLenName = (uchar) std::max(tokenInfo[4].length(), tokenInfo[5].length());
                if (maxLenName > lengthOfLongestTokenName)
                {
                    lengthOfLongestTokenName = maxLenName;
                }
            }
        } else {
            throw std::runtime_error("Could not open the tokens csv file");
        }
    }

}
<commit_msg>Detect ICE header, handle ICE-style If statements<commit_after>/*
 * Part of tivars_lib_cpp
 * (C) 2015-2018 Adrien "Adriweb" Bertrand
 * https://github.com/adriweb/tivars_lib_cpp
 * License: MIT
 */

#include "TypeHandlers.h"
#include "../utils.h"
#include <unordered_map>
#include <iostream>
#include <iterator>
#include <regex>
#include <fstream>

namespace tivars
{
    namespace TH_Tokenized
    {
        std::unordered_map<uint, std::vector<std::string>> tokens_BytesToName;
        std::unordered_map<std::string, uint> tokens_NameToBytes;
        uchar lengthOfLongestTokenName;
        std::vector<uchar> firstByteOfTwoByteTokens;
        const uint16_t squishedASMTokens[] = { 0xBB6D, 0xEF69, 0xEF7B }; // 83+/84+, 84+CSE, CE
    }

    /* TODO: handle TI-Innovator Send( exception for in-strings tokenization (=> not shortest tokens) */
    data_t TH_Tokenized::makeDataFromString(const std::string& str, const options_t& options)
    {
        (void)options;
        data_t data;

        // two bytes reserved for the size. Filled later
        data.push_back(0); data.push_back(0);

        const uchar maxTokSearchLen = std::min((uchar)str.length(), lengthOfLongestTokenName);

        bool isWithinString = false;

        for (uint strCursorPos = 0; strCursorPos < str.length(); strCursorPos++)
        {
            const std::string currChar = str.substr(strCursorPos, 1);
            if (currChar == "\"")
            {
                isWithinString = !isWithinString;
            } else if (currChar == "\n" || currChar == "→")
            {
                isWithinString = false;
            }
            /* isWithinString => minimum token length, otherwise maximal munch */
            for (uint currentLength = isWithinString ? 1 : maxTokSearchLen;
                 isWithinString ? (currentLength <= maxTokSearchLen) : (currentLength > 0);
                 currentLength += (isWithinString ? 1 : -1))
            {
                std::string currentSubString = str.substr(strCursorPos, currentLength);
                if (tokens_NameToBytes.count(currentSubString))
                {
                    uint tokenValue = tokens_NameToBytes[currentSubString];
                    if (tokenValue > 0xFF)
                    {
                        data.push_back((uchar)(tokenValue >> 8));
                    }
                    data.push_back((uchar)(tokenValue & 0xFF));
                    strCursorPos += currentLength - 1;
                    break;
                }
            }
        }

        uint actualDataLen = (uint) (data.size() - 2);
        data[0] = (uchar)(actualDataLen & 0xFF);
        data[1] = (uchar)((actualDataLen >> 8) & 0xFF);
        return data;
    }

    std::string TH_Tokenized::makeStringFromData(const data_t& data, const options_t& options)
    {
        if (data.size() < 2)
        {
            throw std::invalid_argument("Invalid data array. Needs to contain at least 2 bytes (size fields)");
        }

        uint langIdx = (uint)((has_option(options, "lang") && options.at("lang") == LANG_FR) ? LANG_FR : LANG_EN);

        const int howManyBytes = (data[0] & 0xFF) + ((data[1] & 0xFF) << 8);
        if (howManyBytes != (int)data.size() - 2)
        {
            std::cerr << "[Warning] Byte count (" << (data.size() - 2) << ") and size field (" << howManyBytes  << ") mismatch!";
        }

        if (howManyBytes >= 2)
        {
            const uint16_t twoFirstBytes = (uint16_t) ((data[3] & 0xFF) + ((data[2] & 0xFF) << 8));
            if (std::find(std::begin(squishedASMTokens), std::end(squishedASMTokens), twoFirstBytes) != std::end(squishedASMTokens))
            {
                return "[Error] This is a squished ASM program - cannnot preview it!";
            }
        }

        uint errCount = 0;
        std::string str;
        const size_t dataSize = data.size();
        for (uint i = 2; i < (uint)howManyBytes + 2; i++)
        {
            uint currentToken = data[i];
            uint nextToken = (i < dataSize-1) ? data[i+1] : (uint)-1;
            uint bytesKey = currentToken;
            if (is_in_vector(firstByteOfTwoByteTokens, (uchar)currentToken))
            {
                if (nextToken == (uint)-1)
                {
                    std::cerr << "[Warning] Encountered an unfinished two-byte token! Setting the second byte to 0x00";
                    nextToken = 0x00;
                }
                bytesKey = nextToken + (currentToken << 8);
                i++;
            }
            if (tokens_BytesToName.find(bytesKey) != tokens_BytesToName.end())
            {
                str += tokens_BytesToName[bytesKey][langIdx];
            } else {
                str += " [???] ";
                errCount++;
            }
        }

        if (errCount > 0)
        {
            std::cerr << "[Warning] " << errCount << " token(s) could not be detokenized (' [???] ' was used)!";
        }

        if (has_option(options, "prettify") && options.at("prettify") == 1)
        {
            str = std::regex_replace(str, std::regex(R"(\[?\|?([a-z]+)\]?)"), "$1");
        }

        if (has_option(options, "reindent") && options.at("reindent") == 1)
        {
            str = reindentCodeString(str);
        }

        return str;
    }

    std::string TH_Tokenized::reindentCodeString(const std::string& str_orig, const options_t& options)
    {
        int lang;
        if (has_option(options, "lang"))
        {
            lang = options.at("lang");
        } else if (str_orig.size() > 1 && str_orig[0] == '.' && (str_orig[1] == '.' || ::isalpha(str_orig[1]))) {
            lang = PRGMLANG_AXE;
        } else if (str_orig.size() > 0 && str_orig[0] == '\uf02f') {
            lang = PRGMLANG_ICE;
        } else {
            lang = PRGMLANG_BASIC;
        }

        std::string str(str_orig);

        str = std::regex_replace(str, std::regex("([^\\s])(Del|Eff)Var "), "$1\n$2Var ");

        std::vector<std::string> lines_tmp = explode(str, '\n');

        // Inplace-replace the appropriate ":" by new-line chars (ie, by inserting the split string in the lines_tmp array)
        for (uint16_t idx = 0; idx < (uint16_t)lines_tmp.size(); idx++)
        {
            const auto line = lines_tmp[idx];
            bool isWithinString = false;
            for (uint16_t strIdx = 0; strIdx < (uint16_t)line.size(); strIdx++)
            {
                const auto currChar = line.substr(strIdx, 1);
                if (currChar == ":" && !isWithinString)
                {
                    lines_tmp[idx] = line.substr(0, strIdx); // replace "old" line by lhs
                    lines_tmp.insert(lines_tmp.begin() + idx + 1, line.substr(strIdx + 1)); // inserting rhs
                    break;
                } else if (currChar == "\"") {
                    isWithinString = !isWithinString;
                } else if (currChar == "\n" || currChar == "→") {
                    isWithinString = false;
                }
            }
        }

        std::vector<std::pair<uint, std::string>> lines(lines_tmp.size()); // indent, text
        for (const auto& line : lines_tmp)
        {
            lines.emplace_back(0, line);
        }

        std::vector<std::string> increaseIndentAfter   = { "If", "For", "While", "Repeat" };
        std::vector<std::string> decreaseIndentOfToken = { "Then", "Else", "End", "ElseIf", "EndIf", "End!If" };
        std::vector<std::string> closingTokens         = { "End", "EndIf", "End!If" };
        uint nextIndent = 0;
        std::string oldFirstCommand, firstCommand;
        for (auto& line : lines)
        {
            oldFirstCommand = firstCommand;

            std::string trimmedLine = trim(line.second);
            if (trimmedLine.length() > 0) {
                char* trimmedLine_c = (char*) trimmedLine.c_str();
                firstCommand = strtok(trimmedLine_c, " ");
                firstCommand = trim(firstCommand);
                trimmedLine = std::string(trimmedLine_c);
                trimmedLine_c = (char*) trimmedLine.c_str();
                if (firstCommand == trimmedLine)
                {
                    firstCommand = strtok(trimmedLine_c, "(");
                    firstCommand = trim(firstCommand);
                }
            } else {
                firstCommand = "";
            }

            line.first = nextIndent;

            if (is_in_vector(increaseIndentAfter, firstCommand))
            {
                nextIndent++;
            }
            if (line.first > 0 && is_in_vector(decreaseIndentOfToken, firstCommand))
            {
                line.first--;
            }
            if (nextIndent > 0 && (is_in_vector(closingTokens, firstCommand) || (oldFirstCommand == "If" && firstCommand != "Then" && lang != PRGMLANG_AXE && lang != PRGMLANG_ICE)))
            {
                nextIndent--;
            }
        }

        str = "";
        for (const auto& line : lines)
        {
            str += str_repeat(" ", line.first * 3) + line.second + '\n';
        }

        return ltrim(rtrim(str, "\t\n\r\f\v"));
    }

    void TH_Tokenized::initTokens()
    {
        std::ifstream t("programs_tokens.csv");
        std::string csvFileStr((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());

        if (csvFileStr.length() > 0)
        {
            std::vector<std::vector<std::string>> lines;
            ParseCSV(csvFileStr, lines);

            for (const auto& tokenInfo : lines)
            {
                uint bytes;
                if (tokenInfo[6] == "2") // number of bytes for the token
                {
                    if (!is_in_vector(firstByteOfTwoByteTokens, hexdec(tokenInfo[7])))
                    {
                        firstByteOfTwoByteTokens.push_back(hexdec(tokenInfo[7]));
                    }
                    bytes = hexdec(tokenInfo[8]) + (hexdec(tokenInfo[7]) << 8);
                } else {
                    bytes = hexdec(tokenInfo[7]);
                }
                tokens_BytesToName[bytes] = { tokenInfo[4], tokenInfo[5] }; // EN, FR
                tokens_NameToBytes[tokenInfo[4]] = bytes; // EN
                tokens_NameToBytes[tokenInfo[5]] = bytes; // FR
                uchar maxLenName = (uchar) std::max(tokenInfo[4].length(), tokenInfo[5].length());
                if (maxLenName > lengthOfLongestTokenName)
                {
                    lengthOfLongestTokenName = maxLenName;
                }
            }
        } else {
            throw std::runtime_error("Could not open the tokens csv file");
        }
    }

}
<|endoftext|>


<commit_before>#include "ppk_modules.h"
#include "tokenizer.h"
#include "vparam.h"

#include <sys/types.h>
#include <dirent.h>

#include <iostream>
#include <cstring>

//portability functions
void* openLibrary(std::string lib_path);
void* loadSymbol(void* dlhandle, const char* symbolName);
const char* libraryError();

void PPK_Modules::debug(std::string msg)
{
	#ifdef DEBUG_MSG
		std::cout << msg;
	#endif
}

#if defined(WIN32) || defined(WIN64)
	#include <windows.h>
	void* openLibrary(std::string lib_path){return LoadLibraryA(lib_path.c_str());}
	void* loadSymbol(void* dlhandle, const char* symbolName){return (void*)GetProcAddress((HINSTANCE__*)dlhandle, symbolName);}
	const char* libraryError(){return "";}

	static const char* baseKey="Software\\PPassKeeper\\";
	size_t getRegistryValue(const char* key, char* ret, size_t max_size)
	{
		HKEY hk;
		char tmpBuf[512];
		if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, baseKey, 0, KEY_QUERY_VALUE, &hk))
		{
			DWORD size=sizeof(tmpBuf);
			RegQueryValueEx(hk, key, 0, 0, (BYTE*)tmpBuf, &size);
			RegCloseKey(hk);

			strncpy(ret, tmpBuf, max_size-1);

			return size;
		}
		else
			return 0;
	}

	void PPK_Modules::reload(void)
	{
		WIN32_FIND_DATA File;
		HANDLE hSearch;

		modules.clear();

		//char dir_path[2048];
		//unsigned int len=GetEnvironmentVariableA("ppasskeeperMods", dir_path, (DWORD)sizeof(dir_path));
		char dir_path[512];
		getRegistryValue("mods_path", tmpBuf, sizeof(tmpBuf));
		std::string dirpath=dir_path;

		debug("--------------- <PPassKeeper> ---------------\nIf you don't want to see theses messages, recompile ppasskeeper with the cmake switch '-DPPK_DEBUG=OFF'\n")

		hSearch = FindFirstFile((dirpath+"\\*.dll").c_str(), &File);
		if (hSearch != INVALID_HANDLE_VALUE)
		{
			do
			{
				loadPlugin(dirpath, File.cFileName);
			}while (FindNextFile(hSearch, &File));

			FindClose(hSearch);
		}
		else
			debug("Could not open plugins directory : "+dirpath);

		debug("--------------- </PPassKeeper> ---------------\n\n");
	}
#else
	#include <dlfcn.h>
	void* openLibrary(std::string lib_path){return dlopen(lib_path.c_str(), RTLD_LAZY);}
	void* loadSymbol(void* dlhandle, const char* symbolName){return dlsym(dlhandle, symbolName);}
	const char* libraryError(){return dlerror();}

	void PPK_Modules::reload(void)
	{
		DIR * plugindir;
		struct dirent * mydirent;

		modules.clear();

		debug("--------------- <PPassKeeper> ---------------\nIf you don't want to see theses messages, recompile ppasskeeper with the cmake switch '-DPPK_DEBUG=OFF'\n");

		//Open Plugin's directory
		plugindir = opendir(DIRECTORY_PATH);
		if(plugindir!=NULL)
		{
			while ((mydirent = readdir(plugindir))!=NULL)
			{
				int i = strlen(mydirent->d_name) - 3;

				//suffix check: don't load libtool (.la) files
				if (i >= 0 && strcmp(mydirent->d_name + i, ".la")!=0)
					loadPlugin(DIRECTORY_PATH, mydirent->d_name);
			}

			closedir(plugindir);
		}
		else
			debug("Could not open plugins directory : "DIRECTORY_PATH);

		debug("--------------- </PPassKeeper> ---------------\n\n");
	}
#endif

//Private functions
void PPK_Modules::loadPlugin(std::string dirpath, std::string filename)
{
	//if the filename doesn't have the right prefix then try to load it as a shared object
	if(filename.size()>7 && filename.substr(0,7)=="libppk_")
	{
		//debug
		debug("Load the plugin '"+dirpath+"/"+filename+"': ");

		//Load the shared object
		void* dlhandle = openLibrary(dirpath+"/"+filename);
		if (dlhandle!=NULL)
		{
			_module tm; //Temporary module

			//Try to fill the module structure with the symbols
			tm.dlhandle=dlhandle;

			tm.getModuleID=(_getModuleID)loadSymbol(dlhandle, "getModuleID");
			tm.getModuleName=(_getModuleName)loadSymbol(dlhandle, "getModuleName");
			tm.getABIVersion=(_getABIVersion)loadSymbol(dlhandle, "getABIVersion");
			tm.readFlagsAvailable=(_readFlagsAvailable)loadSymbol(dlhandle, "readFlagsAvailable");
			tm.writeFlagsAvailable=(_writeFlagsAvailable)loadSymbol(dlhandle, "writeFlagsAvailable");
			tm.listingFlagsAvailable=(_listingFlagsAvailable)loadSymbol(dlhandle, "listingFlagsAvailable");

			//

			tm.entryExists=(_entryExists)loadSymbol(dlhandle, "entryExists");
			tm.maxDataSize=(_maxDataSize)loadSymbol(dlhandle, "maxDataSize");
			tm.getEntry=(_getEntry)loadSymbol(dlhandle, "getEntry");
			tm.setEntry=(_setEntry)loadSymbol(dlhandle, "setEntry");
			tm.removeEntry=(_removeEntry)loadSymbol(dlhandle, "removeEntry");

			tm.isWritable=(_isWritable)loadSymbol(dlhandle, "isWritable");
			tm.securityLevel=(_securityLevel)loadSymbol(dlhandle, "securityLevel");

			tm.getEntryListCount=(_getEntryListCount)loadSymbol(dlhandle, "getEntryListCount");
			tm.getEntryList=(_getEntryList)loadSymbol(dlhandle, "getEntryList");

			//errors
			tm.getLastError=(_getLastError)loadSymbol(dlhandle, "getLastError");

			//optionnal
			tm.setCustomPromptMessage=(_setCustomPromptMessage)loadSymbol(dlhandle, "setCustomPromptMessage");
			tm.constructor=(_constructor)loadSymbol(dlhandle, "constructor");
			tm.destructor=(_destructor)loadSymbol(dlhandle, "destructor");
			tm.availableParameters=(_availableParameters)loadSymbol(dlhandle, "availableParameters");
			tm.setParam=(_setParam)loadSymbol(dlhandle, "setParam");

		#ifdef DEBUG_MSG
			if(tm.getModuleID==NULL)std::cerr << "missing : getModuleID();";
			if(tm.getModuleName==NULL)std::cerr << "missing : getModuleName();";
			if(tm.getABIVersion==NULL)std::cerr << "missing : getABIVersion();";
			if(tm.readFlagsAvailable==NULL)std::cerr << "missing : readFlagsAvailable();";
			if(tm.writeFlagsAvailable==NULL)std::cerr << "missing : writeFlagsAvailable();";
			if(tm.listingFlagsAvailable==NULL)std::cerr << "missing : listingFlagsAvailable();";
			if(tm.maxDataSize==NULL)std::cerr << "missing : maxDataSize();";
			if(tm.entryExists==NULL)std::cerr << "missing : entryExists();";
			if(tm.getEntry==NULL)std::cerr << "missing : getEntry();";
			if(tm.setEntry==NULL)std::cerr << "missing : setEntry();";
			if(tm.removeEntry==NULL)std::cerr << "missing : removeEntry();";
			if(tm.isWritable==NULL)std::cerr << "missing : isWritable();";
			if(tm.securityLevel==NULL)std::cerr << "missing : securityLevel();";
			if(tm.getEntryListCount==NULL)std::cerr << "missing : getEntryListCount();";
			if(tm.getEntryList==NULL)std::cerr << "missing : getEntryList();";
			if(tm.getLastError==NULL)std::cerr << "missing : getLastError();";
		#endif

			//if minimal functions are here, add the lib to available modules
			if(tm.getModuleID!=NULL && tm.getModuleName!=NULL && tm.getABIVersion!=NULL && tm.readFlagsAvailable!=NULL && tm.writeFlagsAvailable!=NULL && tm.listingFlagsAvailable!=NULL && tm.entryExists!=NULL && tm.maxDataSize!=NULL && tm.getEntry!=NULL && tm.setEntry!=NULL && tm.removeEntry!=NULL && tm.getLastError!=NULL && tm.isWritable!=NULL && tm.securityLevel!=NULL && tm.getEntryListCount!=NULL && tm.getEntryList!=NULL)
			{
				//Get the ID of the library
				tm.id=tm.getModuleID();
				tm.display_name=tm.getModuleName();

				//Call its constructor
				if(tm.constructor)
					tm.constructor();

				//Send the parameters
				if(tm.setParam!=NULL)
					sendParameters(tm);

				//Copy it into the modules list if it doesn't already exist
				if(getModuleByID(tm.id)==NULL)
				{
					modules[tm.id]=tm;
					debug((std::string("OK (ID=")+tm.id)+")\n");
				}
				else
					debug((std::string("FAILED (ID=") + tm.id) + " already exist in modules list)\n");
			}
			else
				debug("FAILED (not all symbols are present, check version numbers)\n");
		}
		else
			debug((std::string("FAILED (") + libraryError()) + ")\n");
	}
}

void PPK_Modules::sendParameters(_module m)
{
	VParam& param = VParam::instance();

	if(m.setParam!=NULL)
	{
		std::vector<std::string> listParams = param.listParams(m.id);
		for(int i=0;i<listParams.size();i++)
		{
			cvariant cv = param.getParam(m.id, listParams[i].c_str());
			m.setParam(listParams[i].c_str(), cv);
		}
	}
}

//Public functions
PPK_Modules::PPK_Modules()
{
	reload();

}

PPK_Modules::~PPK_Modules()
{
	//Call the destructor on every module
	std::map<std::string, _module>::iterator iter;
	for( iter = modules.begin(); iter != modules.end(); iter++ )
	{
		if(iter->second.destructor)
			iter->second.destructor();
	}
}

unsigned int PPK_Modules::size()
{
	return modules.size()+1;
}

unsigned int PPK_Modules::getModulesList(ppk_module* pmodules, unsigned int ModulesCount)
{
	if(modules.size()>0)
	{
		//Automatic module
		pmodules[0].id=LIBPPK_DEFAULT_MODULE;
		pmodules[0].display_name=LIBPPK_DEFAULT_MODULE_DESC;

		std::map<std::string,_module>::iterator iter;
		unsigned int i;
		for(i=1,iter=modules.begin(); i<ModulesCount && iter!=modules.end(); i++,iter++)
		{
			pmodules[i].id=iter->second.id;
			pmodules[i].display_name=iter->second.display_name;
		}

		return i;
	}
	else
		return false;
}

const _module* PPK_Modules::getModuleByID(const char* module_id) //return the corresponding module or NULL if the module is not referenced
{
	//Get the real module name
	if(strcmp(module_id, LIBPPK_DEFAULT_MODULE)==0)
		module_id=autoModule();

	//Does the module exist ?
	std::map<std::string,_module>::iterator fter = modules.find(module_id);
	if(fter!=modules.end())
		return &(fter->second);
	else
		return NULL;
}

const char* PPK_Modules::autoModule()
{
	if(getenv("GNOME_KEYRING_PID")!=NULL && \
	   getenv("GNOME_DESKTOP_SESSION_ID")!=NULL && \
	   ppk_module_is_available("GKeyring")
	  )
	{
		return "GKeyring";
	}
	else if(getenv("KDE_FULL_SESSION")!=NULL && \
	   strcmp(getenv("KDE_SESSION_VERSION"), "4")==0 && \
	   ppk_module_is_available("KWallet4")
	  )
	{
		return "KWallet4";
	}
	else if(ppk_module_is_available("SaveToFile_Enc"))
		return "SaveToFile_Enc";
	else if(ppk_module_is_available("SaveToFile_PT"))
		return "SaveToFile_PT";
	else if(ppk_module_count()>1)
	{
		ppk_module mods[2];
		ppk_module_list(mods, sizeof(mods));
		return mods[1].id;
	}
	else
		return "";

}

<commit_msg>Windows: build fix<commit_after>#include "ppk_modules.h"
#include "tokenizer.h"
#include "vparam.h"

#include <sys/types.h>
#include <dirent.h>

#include <iostream>
#include <cstring>

//portability functions
void* openLibrary(std::string lib_path);
void* loadSymbol(void* dlhandle, const char* symbolName);
const char* libraryError();

void PPK_Modules::debug(std::string msg)
{
	#ifdef DEBUG_MSG
		std::cout << msg;
	#endif
}

#if defined(WIN32) || defined(WIN64)
	#include <windows.h>
	void* openLibrary(std::string lib_path){return LoadLibraryA(lib_path.c_str());}
	void* loadSymbol(void* dlhandle, const char* symbolName){return (void*)GetProcAddress((HINSTANCE__*)dlhandle, symbolName);}
	const char* libraryError(){return "";}

	static const char* baseKey="Software\\PPassKeeper\\";
	size_t getRegistryValue(const char* key, char* ret, size_t max_size)
	{
		HKEY hk;
		char tmpBuf[512];
		if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, baseKey, 0, KEY_QUERY_VALUE, &hk))
		{
			DWORD size=sizeof(tmpBuf);
			RegQueryValueEx(hk, key, 0, 0, (BYTE*)tmpBuf, &size);
			RegCloseKey(hk);

			strncpy(ret, tmpBuf, max_size-1);

			return size;
		}
		else
			return 0;
	}

	void PPK_Modules::reload(void)
	{
		WIN32_FIND_DATA File;
		HANDLE hSearch;

		modules.clear();

		//char dir_path[2048];
		//unsigned int len=GetEnvironmentVariableA("ppasskeeperMods", dir_path, (DWORD)sizeof(dir_path));
		char dir_path[512];
		getRegistryValue("mods_path", dir_path, sizeof(dir_path));
		std::string dirpath=dir_path;

		debug("--------------- <PPassKeeper> ---------------\nIf you don't want to see theses messages, recompile ppasskeeper with the cmake switch '-DPPK_DEBUG=OFF'\n");

		hSearch = FindFirstFile((dirpath+"\\*.dll").c_str(), &File);
		if (hSearch != INVALID_HANDLE_VALUE)
		{
			do
			{
				loadPlugin(dirpath, File.cFileName);
			}while (FindNextFile(hSearch, &File));

			FindClose(hSearch);
		}
		else
			debug("Could not open plugins directory : "+dirpath);

		debug("--------------- </PPassKeeper> ---------------\n\n");
	}
#else
	#include <dlfcn.h>
	void* openLibrary(std::string lib_path){return dlopen(lib_path.c_str(), RTLD_LAZY);}
	void* loadSymbol(void* dlhandle, const char* symbolName){return dlsym(dlhandle, symbolName);}
	const char* libraryError(){return dlerror();}

	void PPK_Modules::reload(void)
	{
		DIR * plugindir;
		struct dirent * mydirent;

		modules.clear();

		debug("--------------- <PPassKeeper> ---------------\nIf you don't want to see theses messages, recompile ppasskeeper with the cmake switch '-DPPK_DEBUG=OFF'\n");

		//Open Plugin's directory
		plugindir = opendir(DIRECTORY_PATH);
		if(plugindir!=NULL)
		{
			while ((mydirent = readdir(plugindir))!=NULL)
			{
				int i = strlen(mydirent->d_name) - 3;

				//suffix check: don't load libtool (.la) files
				if (i >= 0 && strcmp(mydirent->d_name + i, ".la")!=0)
					loadPlugin(DIRECTORY_PATH, mydirent->d_name);
			}

			closedir(plugindir);
		}
		else
			debug("Could not open plugins directory : "DIRECTORY_PATH);

		debug("--------------- </PPassKeeper> ---------------\n\n");
	}
#endif

//Private functions
void PPK_Modules::loadPlugin(std::string dirpath, std::string filename)
{
	//if the filename doesn't have the right prefix then try to load it as a shared object
	if(filename.size()>7 && filename.substr(0,7)=="libppk_")
	{
		//debug
		debug("Load the plugin '"+dirpath+"/"+filename+"': ");

		//Load the shared object
		void* dlhandle = openLibrary(dirpath+"/"+filename);
		if (dlhandle!=NULL)
		{
			_module tm; //Temporary module

			//Try to fill the module structure with the symbols
			tm.dlhandle=dlhandle;

			tm.getModuleID=(_getModuleID)loadSymbol(dlhandle, "getModuleID");
			tm.getModuleName=(_getModuleName)loadSymbol(dlhandle, "getModuleName");
			tm.getABIVersion=(_getABIVersion)loadSymbol(dlhandle, "getABIVersion");
			tm.readFlagsAvailable=(_readFlagsAvailable)loadSymbol(dlhandle, "readFlagsAvailable");
			tm.writeFlagsAvailable=(_writeFlagsAvailable)loadSymbol(dlhandle, "writeFlagsAvailable");
			tm.listingFlagsAvailable=(_listingFlagsAvailable)loadSymbol(dlhandle, "listingFlagsAvailable");

			//

			tm.entryExists=(_entryExists)loadSymbol(dlhandle, "entryExists");
			tm.maxDataSize=(_maxDataSize)loadSymbol(dlhandle, "maxDataSize");
			tm.getEntry=(_getEntry)loadSymbol(dlhandle, "getEntry");
			tm.setEntry=(_setEntry)loadSymbol(dlhandle, "setEntry");
			tm.removeEntry=(_removeEntry)loadSymbol(dlhandle, "removeEntry");

			tm.isWritable=(_isWritable)loadSymbol(dlhandle, "isWritable");
			tm.securityLevel=(_securityLevel)loadSymbol(dlhandle, "securityLevel");

			tm.getEntryListCount=(_getEntryListCount)loadSymbol(dlhandle, "getEntryListCount");
			tm.getEntryList=(_getEntryList)loadSymbol(dlhandle, "getEntryList");

			//errors
			tm.getLastError=(_getLastError)loadSymbol(dlhandle, "getLastError");

			//optionnal
			tm.setCustomPromptMessage=(_setCustomPromptMessage)loadSymbol(dlhandle, "setCustomPromptMessage");
			tm.constructor=(_constructor)loadSymbol(dlhandle, "constructor");
			tm.destructor=(_destructor)loadSymbol(dlhandle, "destructor");
			tm.availableParameters=(_availableParameters)loadSymbol(dlhandle, "availableParameters");
			tm.setParam=(_setParam)loadSymbol(dlhandle, "setParam");

		#ifdef DEBUG_MSG
			if(tm.getModuleID==NULL)std::cerr << "missing : getModuleID();";
			if(tm.getModuleName==NULL)std::cerr << "missing : getModuleName();";
			if(tm.getABIVersion==NULL)std::cerr << "missing : getABIVersion();";
			if(tm.readFlagsAvailable==NULL)std::cerr << "missing : readFlagsAvailable();";
			if(tm.writeFlagsAvailable==NULL)std::cerr << "missing : writeFlagsAvailable();";
			if(tm.listingFlagsAvailable==NULL)std::cerr << "missing : listingFlagsAvailable();";
			if(tm.maxDataSize==NULL)std::cerr << "missing : maxDataSize();";
			if(tm.entryExists==NULL)std::cerr << "missing : entryExists();";
			if(tm.getEntry==NULL)std::cerr << "missing : getEntry();";
			if(tm.setEntry==NULL)std::cerr << "missing : setEntry();";
			if(tm.removeEntry==NULL)std::cerr << "missing : removeEntry();";
			if(tm.isWritable==NULL)std::cerr << "missing : isWritable();";
			if(tm.securityLevel==NULL)std::cerr << "missing : securityLevel();";
			if(tm.getEntryListCount==NULL)std::cerr << "missing : getEntryListCount();";
			if(tm.getEntryList==NULL)std::cerr << "missing : getEntryList();";
			if(tm.getLastError==NULL)std::cerr << "missing : getLastError();";
		#endif

			//if minimal functions are here, add the lib to available modules
			if(tm.getModuleID!=NULL && tm.getModuleName!=NULL && tm.getABIVersion!=NULL && tm.readFlagsAvailable!=NULL && tm.writeFlagsAvailable!=NULL && tm.listingFlagsAvailable!=NULL && tm.entryExists!=NULL && tm.maxDataSize!=NULL && tm.getEntry!=NULL && tm.setEntry!=NULL && tm.removeEntry!=NULL && tm.getLastError!=NULL && tm.isWritable!=NULL && tm.securityLevel!=NULL && tm.getEntryListCount!=NULL && tm.getEntryList!=NULL)
			{
				//Get the ID of the library
				tm.id=tm.getModuleID();
				tm.display_name=tm.getModuleName();

				//Call its constructor
				if(tm.constructor)
					tm.constructor();

				//Send the parameters
				if(tm.setParam!=NULL)
					sendParameters(tm);

				//Copy it into the modules list if it doesn't already exist
				if(getModuleByID(tm.id)==NULL)
				{
					modules[tm.id]=tm;
					debug((std::string("OK (ID=")+tm.id)+")\n");
				}
				else
					debug((std::string("FAILED (ID=") + tm.id) + " already exist in modules list)\n");
			}
			else
				debug("FAILED (not all symbols are present, check version numbers)\n");
		}
		else
			debug((std::string("FAILED (") + libraryError()) + ")\n");
	}
}

void PPK_Modules::sendParameters(_module m)
{
	VParam& param = VParam::instance();

	if(m.setParam!=NULL)
	{
		std::vector<std::string> listParams = param.listParams(m.id);
		for(int i=0;i<listParams.size();i++)
		{
			cvariant cv = param.getParam(m.id, listParams[i].c_str());
			m.setParam(listParams[i].c_str(), cv);
		}
	}
}

//Public functions
PPK_Modules::PPK_Modules()
{
	reload();

}

PPK_Modules::~PPK_Modules()
{
	//Call the destructor on every module
	std::map<std::string, _module>::iterator iter;
	for( iter = modules.begin(); iter != modules.end(); iter++ )
	{
		if(iter->second.destructor)
			iter->second.destructor();
	}
}

unsigned int PPK_Modules::size()
{
	return modules.size()+1;
}

unsigned int PPK_Modules::getModulesList(ppk_module* pmodules, unsigned int ModulesCount)
{
	if(modules.size()>0)
	{
		//Automatic module
		pmodules[0].id=LIBPPK_DEFAULT_MODULE;
		pmodules[0].display_name=LIBPPK_DEFAULT_MODULE_DESC;

		std::map<std::string,_module>::iterator iter;
		unsigned int i;
		for(i=1,iter=modules.begin(); i<ModulesCount && iter!=modules.end(); i++,iter++)
		{
			pmodules[i].id=iter->second.id;
			pmodules[i].display_name=iter->second.display_name;
		}

		return i;
	}
	else
		return false;
}

const _module* PPK_Modules::getModuleByID(const char* module_id) //return the corresponding module or NULL if the module is not referenced
{
	//Get the real module name
	if(strcmp(module_id, LIBPPK_DEFAULT_MODULE)==0)
		module_id=autoModule();

	//Does the module exist ?
	std::map<std::string,_module>::iterator fter = modules.find(module_id);
	if(fter!=modules.end())
		return &(fter->second);
	else
		return NULL;
}

const char* PPK_Modules::autoModule()
{
	if(getenv("GNOME_KEYRING_PID")!=NULL && \
	   getenv("GNOME_DESKTOP_SESSION_ID")!=NULL && \
	   ppk_module_is_available("GKeyring")
	  )
	{
		return "GKeyring";
	}
	else if(getenv("KDE_FULL_SESSION")!=NULL && \
	   strcmp(getenv("KDE_SESSION_VERSION"), "4")==0 && \
	   ppk_module_is_available("KWallet4")
	  )
	{
		return "KWallet4";
	}
	else if(ppk_module_is_available("SaveToFile_Enc"))
		return "SaveToFile_Enc";
	else if(ppk_module_is_available("SaveToFile_PT"))
		return "SaveToFile_PT";
	else if(ppk_module_count()>1)
	{
		ppk_module mods[2];
		ppk_module_list(mods, sizeof(mods));
		return mods[1].id;
	}
	else
		return "";

}

<|endoftext|>