<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "client/ui/statistics_dialog.h"

#include "base/desktop/screen_capturer.h"

#include <QTimer>

namespace client {

StatisticsDialog::StatisticsDialog(QWidget* parent)
    : QDialog(parent),
      duration_(0, 0)
{
    ui.setupUi(this);
    ui.tree->resizeColumnToContents(0);

    update_timer_ = new QTimer(this);
    connect(update_timer_, &QTimer::timeout, this, &StatisticsDialog::metricsRequired);
    update_timer_->start(std::chrono::seconds(1));
}

StatisticsDialog::~StatisticsDialog() = default;

void StatisticsDialog::setMetrics(const DesktopWindow::Metrics& metrics)
{
    for (int i = 0; i < ui.tree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* item = ui.tree->topLevelItem(i);

        switch (i)
        {
            case 0:
                item->setText(1, duration_.addSecs(
                    static_cast<int>(metrics.duration.count())).toString());
                break;

            case 1:
                item->setText(1, sizeToString(metrics.total_rx));
                break;

            case 2:
                item->setText(1, sizeToString(metrics.total_tx));
                break;

            case 3:
                item->setText(1, speedToString(metrics.speed_rx));
                break;

            case 4:
                item->setText(1, speedToString(metrics.speed_tx));
                break;

            case 5:
                item->setText(1, QString::number(metrics.video_packet_count));
                break;

            case 6:
                item->setText(1, sizeToString(metrics.min_video_packet));
                break;

            case 7:
                item->setText(1, sizeToString(metrics.max_video_packet));
                break;

            case 8:
                item->setText(1, sizeToString(metrics.avg_video_packet));
                break;

            case 9:
                item->setText(1, QString::number(metrics.audio_packet_count));
                break;

            case 10:
                item->setText(1, sizeToString(metrics.min_audio_packet));
                break;

            case 11:
                item->setText(1, sizeToString(metrics.max_audio_packet));
                break;

            case 12:
                item->setText(1, sizeToString(metrics.avg_audio_packet));
                break;

            case 13:
                item->setText(1, base::ScreenCapturer::typeToString(
                    static_cast<base::ScreenCapturer::Type>(metrics.video_capturer_type)));
                break;

            case 14:
                item->setText(1, QString::number(metrics.fps));
                break;

            case 15:
                item->setText(1, QString::number(metrics.send_mouse));
                break;

            case 16:
                item->setText(1, QString::number(metrics.drop_mouse));
                break;

            case 17:
                item->setText(1, QString::number(metrics.send_key));
                break;

            case 18:
                item->setText(1, QString::number(metrics.read_clipboard));
                break;

            case 19:
                item->setText(1, QString::number(metrics.send_clipboard));
                break;
        }
    }
}

// static
QString StatisticsDialog::sizeToString(int64_t size)
{
    static const int64_t kKB = 1024LL;
    static const int64_t kMB = kKB * 1024LL;
    static const int64_t kGB = kMB * 1024LL;
    static const int64_t kTB = kGB * 1024LL;

    QString units;
    int64_t divider;

    if (size >= kTB)
    {
        units = "TB";
        divider = kTB;
    }
    else if (size >= kGB)
    {
        units = "GB";
        divider = kGB;
    }
    else if (size >= kMB)
    {
        units = "MB";
        divider = kMB;
    }
    else if (size >= kKB)
    {
        units = "kB";
        divider = kKB;
    }
    else
    {
        units = "B";
        divider = 1;
    }

    return QString("%1 %2")
        .arg(static_cast<double>(size) / static_cast<double>(divider), 0, 'g', 4)
        .arg(units);
}

// static
QString StatisticsDialog::speedToString(int64_t speed)
{
    static const int64_t kKB = 1024LL;
    static const int64_t kMB = kKB * 1024LL;
    static const int64_t kGB = kMB * 1024LL;
    static const int64_t kTB = kGB * 1024LL;

    QString units;
    int64_t divider;

    if (speed >= kTB)
    {
        units = "TB/s";
        divider = kTB;
    }
    else if (speed >= kGB)
    {
        units = "GB/s";
        divider = kGB;
    }
    else if (speed >= kMB)
    {
        units = "MB/s";
        divider = kMB;
    }
    else if (speed >= kKB)
    {
        units = "kB/s";
        divider = kKB;
    }
    else
    {
        units = "B/s";
        divider = 1;
    }

    return QString("%1 %2")
        .arg(static_cast<double>(speed) / static_cast<double>(divider), 0, 'g', 4)
        .arg(units);
}

} // namespace client
<commit_msg>Calc percentage.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "client/ui/statistics_dialog.h"

#include "base/desktop/screen_capturer.h"

#include <QTimer>

namespace client {

StatisticsDialog::StatisticsDialog(QWidget* parent)
    : QDialog(parent),
      duration_(0, 0)
{
    ui.setupUi(this);
    ui.tree->resizeColumnToContents(0);

    update_timer_ = new QTimer(this);
    connect(update_timer_, &QTimer::timeout, this, &StatisticsDialog::metricsRequired);
    update_timer_->start(std::chrono::seconds(1));
}

StatisticsDialog::~StatisticsDialog() = default;

void StatisticsDialog::setMetrics(const DesktopWindow::Metrics& metrics)
{
    for (int i = 0; i < ui.tree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* item = ui.tree->topLevelItem(i);

        switch (i)
        {
            case 0:
                item->setText(1, duration_.addSecs(
                    static_cast<int>(metrics.duration.count())).toString());
                break;

            case 1:
                item->setText(1, sizeToString(metrics.total_rx));
                break;

            case 2:
                item->setText(1, sizeToString(metrics.total_tx));
                break;

            case 3:
                item->setText(1, speedToString(metrics.speed_rx));
                break;

            case 4:
                item->setText(1, speedToString(metrics.speed_tx));
                break;

            case 5:
                item->setText(1, QString::number(metrics.video_packet_count));
                break;

            case 6:
                item->setText(1, sizeToString(metrics.min_video_packet));
                break;

            case 7:
                item->setText(1, sizeToString(metrics.max_video_packet));
                break;

            case 8:
                item->setText(1, sizeToString(metrics.avg_video_packet));
                break;

            case 9:
                item->setText(1, QString::number(metrics.audio_packet_count));
                break;

            case 10:
                item->setText(1, sizeToString(metrics.min_audio_packet));
                break;

            case 11:
                item->setText(1, sizeToString(metrics.max_audio_packet));
                break;

            case 12:
                item->setText(1, sizeToString(metrics.avg_audio_packet));
                break;

            case 13:
                item->setText(1, base::ScreenCapturer::typeToString(
                    static_cast<base::ScreenCapturer::Type>(metrics.video_capturer_type)));
                break;

            case 14:
                item->setText(1, QString::number(metrics.fps));
                break;

            case 15:
                item->setText(1, QString::number(metrics.send_mouse));
                break;

            case 16:
            {
                int total_mouse = metrics.send_mouse + metrics.drop_mouse;
                int percentage = 0;

                if (total_mouse != 0)
                    percentage = (metrics.drop_mouse * 100) / total_mouse;

                item->setText(1, QString("%1 (%2 %)").arg(metrics.drop_mouse).arg(percentage));
            }
            break;

            case 17:
                item->setText(1, QString::number(metrics.send_key));
                break;

            case 18:
                item->setText(1, QString::number(metrics.read_clipboard));
                break;

            case 19:
                item->setText(1, QString::number(metrics.send_clipboard));
                break;
        }
    }
}

// static
QString StatisticsDialog::sizeToString(int64_t size)
{
    static const int64_t kKB = 1024LL;
    static const int64_t kMB = kKB * 1024LL;
    static const int64_t kGB = kMB * 1024LL;
    static const int64_t kTB = kGB * 1024LL;

    QString units;
    int64_t divider;

    if (size >= kTB)
    {
        units = "TB";
        divider = kTB;
    }
    else if (size >= kGB)
    {
        units = "GB";
        divider = kGB;
    }
    else if (size >= kMB)
    {
        units = "MB";
        divider = kMB;
    }
    else if (size >= kKB)
    {
        units = "kB";
        divider = kKB;
    }
    else
    {
        units = "B";
        divider = 1;
    }

    return QString("%1 %2")
        .arg(static_cast<double>(size) / static_cast<double>(divider), 0, 'g', 4)
        .arg(units);
}

// static
QString StatisticsDialog::speedToString(int64_t speed)
{
    static const int64_t kKB = 1024LL;
    static const int64_t kMB = kKB * 1024LL;
    static const int64_t kGB = kMB * 1024LL;
    static const int64_t kTB = kGB * 1024LL;

    QString units;
    int64_t divider;

    if (speed >= kTB)
    {
        units = "TB/s";
        divider = kTB;
    }
    else if (speed >= kGB)
    {
        units = "GB/s";
        divider = kGB;
    }
    else if (speed >= kMB)
    {
        units = "MB/s";
        divider = kMB;
    }
    else if (speed >= kKB)
    {
        units = "kB/s";
        divider = kKB;
    }
    else
    {
        units = "B/s";
        divider = 1;
    }

    return QString("%1 %2")
        .arg(static_cast<double>(speed) / static_cast<double>(divider), 0, 'g', 4)
        .arg(units);
}

} // namespace client
<|endoftext|>


<commit_before>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "console/computer_group_tree.h"
#include "console/computer_mime_data.h"

#include <QApplication>
#include <QDropEvent>
#include <QUuid>

namespace console {

ComputerGroupTree::ComputerGroupTree(QWidget* parent)
    : QTreeWidget(parent),
      computer_group_mime_type_(QString("application/%1").arg(QUuid::createUuid().toString()))
{
    QTreeWidgetItem* invisible_root = invisibleRootItem();
    invisible_root->setFlags(invisible_root->flags() ^ Qt::ItemIsDropEnabled);
    setAcceptDrops(true);
}

void ComputerGroupTree::setComputerMimeType(const QString& mime_type)
{
    computer_mime_type_ = mime_type;
}

bool ComputerGroupTree::dragging() const
{
    return dragging_;
}

void ComputerGroupTree::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
        start_pos_ = event->pos();

    QTreeWidget::mousePressEvent(event);
}

void ComputerGroupTree::mouseMoveEvent(QMouseEvent* event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        int distance = (event->pos() - start_pos_).manhattanLength();

        if (distance > QApplication::startDragDistance())
        {
            startDrag(Qt::MoveAction);
            return;
        }
    }

    QTreeWidget::mouseMoveEvent(event);
}

void ComputerGroupTree::dragEnterEvent(QDragEnterEvent* event)
{
    const QMimeData* mime_data = event->mimeData();

    if (mime_data->hasFormat(computer_group_mime_type_) ||
        mime_data->hasFormat(computer_mime_type_))
    {
        event->acceptProposedAction();
    }

    dragging_ = true;
}

void ComputerGroupTree::dragLeaveEvent(QDragLeaveEvent* event)
{
    dragging_ = false;
    QTreeWidget::dragLeaveEvent(event);
}

void ComputerGroupTree::dragMoveEvent(QDragMoveEvent* event)
{
    event->ignore();

    const QMimeData* mime_data = event->mimeData();

    if (mime_data->hasFormat(computer_group_mime_type_))
    {
        ComputerGroupItem* source_item = dynamic_cast<ComputerGroupItem*>(itemAt(start_pos_));
        ComputerGroupItem* target_item = dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));

        if (isAllowedDropTarget(target_item, source_item))
        {
            clearSelection();

            target_item->setSelected(true);
            event->acceptProposedAction();
        }
    }
    else if (mime_data->hasFormat(computer_mime_type_))
    {
        ComputerGroupItem* target_item = dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
        if (target_item)
        {
            const ComputerMimeData* computer_mime_data =
                dynamic_cast<const ComputerMimeData*>(mime_data);
            if (computer_mime_data)
            {
                ComputerItem* computer_item = computer_mime_data->computerItem();
                if (computer_item && computer_item->parentComputerGroupItem() != target_item)
                {
                    clearSelection();

                    target_item->setSelected(true);
                    event->acceptProposedAction();
                }
            }
        }
    }
    else
    {
        // Ignore other.
    }

    QWidget::dragMoveEvent(event);
}

void ComputerGroupTree::dropEvent(QDropEvent* event)
{
    const QMimeData* mime_data = event->mimeData();
    if (!mime_data)
        return;

    if (mime_data->hasFormat(computer_group_mime_type_))
    {
        const ComputerGroupMimeData* computer_group_mime_data =
            dynamic_cast<const ComputerGroupMimeData*>(event->mimeData());
        if (computer_group_mime_data)
        {
            ComputerGroupItem* target_group_item =
                dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
            if (!target_group_item)
                return;

            ComputerGroupItem* source_group_item =
                computer_group_mime_data->computerGroup();

            if (!isAllowedDropTarget(target_group_item, source_group_item))
                return;

            ComputerGroupItem* parent_group_item =
                dynamic_cast<ComputerGroupItem*>(source_group_item->parent());
            if (!parent_group_item)
                return;

            proto::address_book::ComputerGroup* computer_group =
                parent_group_item->takeChildComputerGroup(source_group_item);
            if (!computer_group)
                return;

            target_group_item->addChildComputerGroup(computer_group);
            target_group_item->setExpanded(true);

            setCurrentItem(source_group_item);

            emit itemDropped();
        }
    }
    else if (mime_data->hasFormat(computer_mime_type_))
    {
        const ComputerMimeData* computer_mime_data =
            dynamic_cast<const ComputerMimeData*>(event->mimeData());
        if (computer_mime_data)
        {
            ComputerItem* computer_item = computer_mime_data->computerItem();

            ComputerGroupItem* target_group_item =
                dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
            ComputerGroupItem* source_group_item =
                computer_item->parentComputerGroupItem();

            if (target_group_item && source_group_item)
            {
                setCurrentItem(source_group_item);

                proto::address_book::Computer* computer =
                    source_group_item->takeChildComputer(computer_item->computer());

                if (computer)
                {
                    target_group_item->addChildComputer(computer);
                    emit itemDropped();
                }
            }
        }
    }

    dragging_ = false;
}

bool ComputerGroupTree::isAllowedDropTarget(ComputerGroupItem* target, ComputerGroupItem* item)
{
    if (!target || !item)
        return false;

    if (target == invisibleRootItem() || target == item)
        return false;

    std::function<bool(ComputerGroupItem*, ComputerGroupItem*)> is_child_item =
        [&](ComputerGroupItem* parent_item, ComputerGroupItem* child_item)
    {
        int count = parent_item->childCount();
        for (int i = 0; i < count; ++i)
        {
            ComputerGroupItem* current = dynamic_cast<ComputerGroupItem*>(parent_item->child(i));
            if (current)
            {
                if (current == child_item)
                    return true;

                if (is_child_item(current, child_item))
                    return true;
            }
        }

        return false;
    };

    return !is_child_item(item, target);
}

void ComputerGroupTree::startDrag(Qt::DropActions supported_actions)
{
    ComputerGroupItem* computer_group = dynamic_cast<ComputerGroupItem*>(itemAt(start_pos_));
    if (computer_group)
    {
        ComputerGroupDrag* drag = new ComputerGroupDrag(this);

        drag->setComputerGroupItem(computer_group, computer_group_mime_type_);

        QIcon icon = computer_group->icon(0);
        drag->setPixmap(icon.pixmap(icon.actualSize(QSize(16, 16))));

        drag->exec(supported_actions);
    }
}

} // namespace console
<commit_msg>Fixed crash when dragging computer groups.<commit_after>//
// Aspia Project
// Copyright (C) 2020 Dmitry Chapyshev <dmitry@aspia.ru>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

#include "console/computer_group_tree.h"
#include "console/computer_mime_data.h"

#include <QApplication>
#include <QDropEvent>
#include <QUuid>

namespace console {

ComputerGroupTree::ComputerGroupTree(QWidget* parent)
    : QTreeWidget(parent),
      computer_group_mime_type_(QString("application/%1").arg(QUuid::createUuid().toString()))
{
    QTreeWidgetItem* invisible_root = invisibleRootItem();
    invisible_root->setFlags(invisible_root->flags() ^ Qt::ItemIsDropEnabled);
    setAcceptDrops(true);
}

void ComputerGroupTree::setComputerMimeType(const QString& mime_type)
{
    computer_mime_type_ = mime_type;
}

bool ComputerGroupTree::dragging() const
{
    return dragging_;
}

void ComputerGroupTree::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
        start_pos_ = event->pos();

    QTreeWidget::mousePressEvent(event);
}

void ComputerGroupTree::mouseMoveEvent(QMouseEvent* event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        int distance = (event->pos() - start_pos_).manhattanLength();

        if (distance > QApplication::startDragDistance())
        {
            startDrag(Qt::MoveAction);
            return;
        }
    }

    QTreeWidget::mouseMoveEvent(event);
}

void ComputerGroupTree::dragEnterEvent(QDragEnterEvent* event)
{
    const QMimeData* mime_data = event->mimeData();

    if (mime_data->hasFormat(computer_group_mime_type_) ||
        mime_data->hasFormat(computer_mime_type_))
    {
        event->acceptProposedAction();
    }

    dragging_ = true;
}

void ComputerGroupTree::dragLeaveEvent(QDragLeaveEvent* event)
{
    dragging_ = false;
    QTreeWidget::dragLeaveEvent(event);
}

void ComputerGroupTree::dragMoveEvent(QDragMoveEvent* event)
{
    event->ignore();

    const QMimeData* mime_data = event->mimeData();

    if (mime_data->hasFormat(computer_group_mime_type_))
    {
        ComputerGroupItem* source_item = dynamic_cast<ComputerGroupItem*>(itemAt(start_pos_));
        ComputerGroupItem* target_item = dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));

        if (isAllowedDropTarget(target_item, source_item))
        {
            clearSelection();

            target_item->setSelected(true);
            event->acceptProposedAction();
        }
    }
    else if (mime_data->hasFormat(computer_mime_type_))
    {
        ComputerGroupItem* target_item = dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
        if (target_item)
        {
            const ComputerMimeData* computer_mime_data =
                dynamic_cast<const ComputerMimeData*>(mime_data);
            if (computer_mime_data)
            {
                ComputerItem* computer_item = computer_mime_data->computerItem();
                if (computer_item && computer_item->parentComputerGroupItem() != target_item)
                {
                    clearSelection();

                    target_item->setSelected(true);
                    event->acceptProposedAction();
                }
            }
        }
    }
    else
    {
        // Ignore other.
    }

    QWidget::dragMoveEvent(event);
}

void ComputerGroupTree::dropEvent(QDropEvent* event)
{
    const QMimeData* mime_data = event->mimeData();
    if (!mime_data)
        return;

    if (mime_data->hasFormat(computer_group_mime_type_))
    {
        const ComputerGroupMimeData* computer_group_mime_data =
            dynamic_cast<const ComputerGroupMimeData*>(event->mimeData());
        if (computer_group_mime_data)
        {
            ComputerGroupItem* target_group_item =
                dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
            if (!target_group_item)
                return;

            ComputerGroupItem* source_group_item =
                computer_group_mime_data->computerGroup();

            if (!isAllowedDropTarget(target_group_item, source_group_item))
                return;

            ComputerGroupItem* parent_group_item =
                dynamic_cast<ComputerGroupItem*>(source_group_item->parent());
            if (!parent_group_item)
                return;

            proto::address_book::ComputerGroup* computer_group =
                parent_group_item->takeChildComputerGroup(source_group_item);
            if (!computer_group)
                return;

            // After calling takeChildComputerGroup, instance source_group_item is destroyed.
            // We create a new instance with the same data in a new location.
            source_group_item = target_group_item->addChildComputerGroup(computer_group);
            target_group_item->setExpanded(true);

            setCurrentItem(source_group_item);
            emit itemDropped();
        }
    }
    else if (mime_data->hasFormat(computer_mime_type_))
    {
        const ComputerMimeData* computer_mime_data =
            dynamic_cast<const ComputerMimeData*>(event->mimeData());
        if (computer_mime_data)
        {
            ComputerItem* computer_item = computer_mime_data->computerItem();

            ComputerGroupItem* target_group_item =
                dynamic_cast<ComputerGroupItem*>(itemAt(event->pos()));
            ComputerGroupItem* source_group_item =
                computer_item->parentComputerGroupItem();

            if (target_group_item && source_group_item)
            {
                setCurrentItem(source_group_item);

                proto::address_book::Computer* computer =
                    source_group_item->takeChildComputer(computer_item->computer());

                if (computer)
                {
                    target_group_item->addChildComputer(computer);
                    emit itemDropped();
                }
            }
        }
    }

    dragging_ = false;
}

bool ComputerGroupTree::isAllowedDropTarget(ComputerGroupItem* target, ComputerGroupItem* item)
{
    if (!target || !item)
        return false;

    if (target == invisibleRootItem() || target == item)
        return false;

    std::function<bool(ComputerGroupItem*, ComputerGroupItem*)> is_child_item =
        [&](ComputerGroupItem* parent_item, ComputerGroupItem* child_item)
    {
        int count = parent_item->childCount();
        for (int i = 0; i < count; ++i)
        {
            ComputerGroupItem* current = dynamic_cast<ComputerGroupItem*>(parent_item->child(i));
            if (current)
            {
                if (current == child_item)
                    return true;

                if (is_child_item(current, child_item))
                    return true;
            }
        }

        return false;
    };

    return !is_child_item(item, target);
}

void ComputerGroupTree::startDrag(Qt::DropActions supported_actions)
{
    ComputerGroupItem* computer_group = dynamic_cast<ComputerGroupItem*>(itemAt(start_pos_));
    if (computer_group)
    {
        ComputerGroupDrag* drag = new ComputerGroupDrag(this);

        drag->setComputerGroupItem(computer_group, computer_group_mime_type_);

        QIcon icon = computer_group->icon(0);
        drag->setPixmap(icon.pixmap(icon.actualSize(QSize(16, 16))));

        drag->exec(supported_actions);
    }
}

} // namespace console
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2014, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file RefreshLoop.hxx
 * Flow that performs periodic polling.
 *
 * @author Balazs Racz
 * @date 13 Jul 2014
 */

#ifndef _OPENLCB_REFRESHLOOP_HXX_
#define _OPENLCB_REFRESHLOOP_HXX_

#include <vector>

#include "executor/StateFlow.hxx"
#include "executor/Timer.hxx"
#include "openlcb/WriteHelper.hxx"

namespace openlcb
{

/// Abstract base class for components that need repeated execution (with a
/// specified frequency, i.e. not a busy loop).
class Polling
{
public:
    /** This function will be called approximately 33 times per second by the
     * refresh loop. It must notify done when it is finished using the
     * writehelper. */
    virtual void poll_33hz(WriteHelper *helper, Notifiable *done) = 0;
};

/// State flow that calls a set of @ref Polling objects at a regular interval.
///
/// Usage: Instantiate your objects from descendants of the Polling
/// class. Create a RefreshLoop object and pass in the list of Polling object
/// pointers to the constructor.
class RefreshLoop : public StateFlowBase
{
public:
    RefreshLoop(Node *node, const std::initializer_list<Polling *> &members)
        : StateFlowBase(node->iface())
//        , node_(node)
        , timer_(this)
        , lastTimeout_(os_get_time_monotonic())
        , members_(members)
    {
        start_flow(STATE(wait_for_tick));
    }

    /** Stops the refresh loop. If you call this funciton, then wait for the
     * executor, then it is safe to delete *this. */
    void stop()
    {
        set_terminated();
        timer_.ensure_triggered();
    }

    Action wait_for_tick()
    {
        lastTimeout_ += MSEC_TO_NSEC(30);
        nextMember_ = members_.begin();
        // If we have overflowed our timer, this call will happen immediately.
        return sleep_and_call(&timer_, lastTimeout_ - os_get_time_monotonic(),
                              STATE(call_members));
    }

    Action call_members()
    {
        if (nextMember_ == members_.end())
        {
            return call_immediately(STATE(wait_for_tick));
        }
        (*nextMember_)->poll_33hz(&helper_, this);
        ++nextMember_;
        return wait();
    }

private:
//    Node *node_;
    WriteHelper helper_;
    StateFlowTimer timer_;
    long long lastTimeout_;
    typedef vector<Polling*> members_type;
    members_type members_;
    members_type::iterator nextMember_;
};

} // namespace openlcb

#endif // _OPENLCB_REFRESHLOOP_HXX_
<commit_msg>Improves performance of RefreshLoop object (#270)<commit_after>/** \copyright
 * Copyright (c) 2014, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file RefreshLoop.hxx
 * Flow that performs periodic polling.
 *
 * @author Balazs Racz
 * @date 13 Jul 2014
 */

#ifndef _OPENLCB_REFRESHLOOP_HXX_
#define _OPENLCB_REFRESHLOOP_HXX_

#include <vector>

#include "executor/StateFlow.hxx"
#include "executor/Timer.hxx"
#include "openlcb/WriteHelper.hxx"

namespace openlcb
{

/// Abstract base class for components that need repeated execution (with a
/// specified frequency, i.e. not a busy loop).
class Polling
{
public:
    /** This function will be called approximately 33 times per second by the
     * refresh loop. It must notify done when it is finished using the
     * writehelper. */
    virtual void poll_33hz(WriteHelper *helper, Notifiable *done) = 0;
};

/// State flow that calls a set of @ref Polling objects at a regular interval.
///
/// Usage: Instantiate your objects from descendants of the Polling
/// class. Create a RefreshLoop object and pass in the list of Polling object
/// pointers to the constructor.
class RefreshLoop : public StateFlowBase
{
public:
    RefreshLoop(Node *node, const std::initializer_list<Polling *> &members)
        : StateFlowBase(node->iface())
        , timer_(this)
        , lastTimeout_(os_get_time_monotonic())
        , members_(members)
    {
        start_flow(STATE(wait_for_tick));
    }

    /** Stops the refresh loop. If you call this funciton, then wait for the
     * executor, then it is safe to delete *this. */
    void stop()
    {
        set_terminated();
        timer_.ensure_triggered();
    }

    Action wait_for_tick()
    {
        lastTimeout_ += MSEC_TO_NSEC(30);
        nextMember_ = members_.begin();
        // If we have overflowed our timer, this call will happen immediately.
        return sleep_and_call(&timer_, lastTimeout_ - os_get_time_monotonic(),
                              STATE(call_members));
    }

    Action call_members()
    {
        while (true)
        {
            if (nextMember_ == members_.end())
            {
                return call_immediately(STATE(wait_for_tick));
            }
            bn_.reset(this);
            (*nextMember_)->poll_33hz(&helper_, bn_.new_child());
            ++nextMember_;
            if (bn_.abort_if_almost_done())
            {
                // The polling member called done notifiable inline. Short
                // circuits the yield to the executor.
                continue;
            }
            bn_.maybe_done();
            return wait();
        }
    }

private:
    /// Message write buffer that is passed to each polling object.
    WriteHelper helper_;
    /// Helper object for sleeps.
    StateFlowTimer timer_;
    /// Rolling clock of when the next wakeup should happen.
    long long lastTimeout_;
    /// Controllable notifier to be passed into the polling objects.
    BarrierNotifiable bn_;
    /// Data structure type for storing the polling members.
    typedef vector<Polling*> members_type;
    /// The actual members.
    members_type members_;
    /// Iterator for going through the members list.
    members_type::iterator nextMember_;
};

} // namespace openlcb

#endif // _OPENLCB_REFRESHLOOP_HXX_
<|endoftext|>


<commit_before>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "parseArgs/parseArgs.h"
#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "au/CommandLine.h"                     // au::CommandLine
#include "au/Console.h"                         // au::Console

#include "samson/common/SamsonSetup.h"			// samson::SamsonSetup
#include "samson/common/coding.h"				// samson::FormatHeader
#include "samson/common/samsonVars.h"           // SAMSON_ARG_VARS SAMSON_ARGS
#include "samson/module/KVFormat.h"             // samson::KVFormat
#include "samson/module/ModulesManager.h"		// samson::ModulesManager
#include "samson/common/samsonVersion.h"

/* ****************************************************************************
 *
 * Option variables
 */

SAMSON_ARG_VARS;
bool check;

/* ****************************************************************************
 *
 * parse arguments
 */

PaArgument paArgs[] =
{
	SAMSON_ARGS,

	{ "-check",   &check,    "",     PaBool,    PaOpt,  false,  false,   true,  "Check if setup file is correct" },

	PA_END_OF_ARGS
};

int logFd = -1;
bool modified = false;  // Global variable to know if we have to save something before quiting..

std::string getHelpMessage()
{
    std::ostringstream output;

    output << "-------------------------------------\n";
    output << "Help for samsonSetup tool\n";
    output << "-------------------------------------\n";
    output << "\n";
    output << " show                     Show all setup outputs\n";
    output << " set property value       Set a particular value\n";
    output << " save                     Save modified values\n";
    output << " check                    Check if current values are coherent\n";
    output << " edit                     Edit all property values\n";
    output << " set_desktop              Set typical valies for desktop 2Gb & 2 cores\n";
    output << " quit                     Quit samsonSetup tool\n";

    return output.str();
}

class SamsonConfigConsole : public au::Console
{

public:

    std::string getPrompt()
    {
        return "SamsonConfig > ";
    }

    //!< function to process a command instroduced by user
    void evalCommand( std::string command )
    {

        au::CommandLine cmd;
        cmd.parse( command );

        if( cmd.get_num_arguments() == 0)
            return;

        std::string main_command = cmd.get_argument(0);

        if( main_command == "help" )
        {
            writeOnConsole( getHelpMessage() );
            return;
        }

        if( main_command == "set" )
        {
            if( cmd.get_num_arguments() < 3 )
                writeOnConsole("Usage: set property value");

            std::string property = cmd.get_argument(1);
            std::string value = cmd.get_argument(2);

            if( !samson::SamsonSetup::shared()->isParameterDefined( property ) )
            {
                writeErrorOnConsole(au::str("Paramter '%s' not defined" , property.c_str()) );
                return;
            }

            samson::SamsonSetup::shared()->setValueForParameter( property , value );
            modified = true;
            writeWarningOnConsole(au::str("Property '%s' set to '%s'", property.c_str() , value.c_str() ));

            return;

        }

        if( main_command == "set_desktop" )
        {
            samson::SamsonSetup::shared()->resetToDefaultValues();
            samson::SamsonSetup::shared()->setValueForParameter( "general.memory" , "2000000000" );
            samson::SamsonSetup::shared()->setValueForParameter( "general.num_processess" , "2" );
            samson::SamsonSetup::shared()->setValueForParameter( "general.shared_memory_size_per_buffer" , "64000000" );

            writeWarningOnConsole("Properties general.memory                        = 2Gb");
            writeWarningOnConsole("Properties general.num_processess                = 2");
            writeWarningOnConsole("Properties general.shared_memory_size_per_buffer = 64Mb");
            return;
        }

        if( main_command == "save" )
        {
            int res = samson::SamsonSetup::shared()->save();  // Save a new file with the current setup

            std::string fileName = samson::SamsonSetup::shared()->setupFileName();

            if( !res )
            {
                writeWarningOnConsole(  au::str("Saved file at %s", fileName.c_str() ) );
                modified = false;
            }
            else
            {
                writeErrorOnConsole(  au::str("Error saving file at %s", fileName.c_str() ) );
            }

            return;
        }

        if( main_command == "check" )
        {
            writeWarningOnConsole( "Checking setup..." );

            // Check everything looks ok
            au::ErrorManager errorManager;
            samson::SamsonSetup::shared()->check(&errorManager);

            if( errorManager.isActivated() )
                writeErrorOnConsole(errorManager.getMessage());
            else
                writeWarningOnConsole("OK\n");

            return;
        }

        if( main_command == "quit" )
        {
            if( modified )
            {
                std::cout << "Setup file modified.... save (y/n)? ";
                char line[1024];
                if (fgets(line, 1024, stdin)== NULL)
                {
                    writeWarningOnConsole("Read nothing");
                }
                if( strcmp(line, "y") || strcmp(line, "Y") )
                {
                    samson::SamsonSetup::shared()->save();  // Save a new file with the current setup
                    std::string fileName = samson::SamsonSetup::shared()->setupFileName();
                    writeWarningOnConsole(  au::str("Saved file at %s", fileName.c_str() ) );
                }

            }

            quitConsole();
            return;
        }

        if ( main_command == "show" )
        {
            std::cout << samson::SamsonSetup::shared()->str();
            return;
        }

        if ( main_command == "edit" )
        {
            modified = true;
            samson::SamsonSetup::shared()->edit();  // Enter in edit mode from command line
            return;
        }

        writeErrorOnConsole(au::str("Unknown command '%s'" , main_command.c_str() ));
        writeWarningOnConsole("Type help to get a list of valid commands ");

    }

};

/* ****************************************************************************
 *
 * man texts -
 */
static const char* manSynopsis         = " [OPTION]";
static const char* manShortDescription = "samsonSetup is a tool to define setup parameters in a SAMSON system.\n\n";
static const char* manDescription      =
"samsonSetup [-check] : Samson configuration tool.\n"
"\n"
"\t -check : Verify current setup\n"
"\n"
"\t samsonSetup is an interactive tool to specify all the setup values in a Samson deployment\n"
"\t Just type help inside samsonSetup to get a list of valid commands\n"
"\n";

static const char* manExitStatus    = "0      if OK\n 1-255  error\n";
static const char* manAuthor        = "Written by Andreu Urruela, Ken Zangelin and J.Gregorio Escalada.";
static const char* manReportingBugs = "bugs to samson-dev@tid.es\n";
static const char* manCopyright     = "Copyright (C) 2011 Telefonica Investigacion y Desarrollo";
static const char* manVersion       = SAMSON_VERSION;

/* ****************************************************************************
 *
 * main -
 */
int main(int argC, const char *argV[])
{
	paConfig("builtin prefix",                (void*) "SS_SETUP_");
	paConfig("usage and exit on any warning", (void*) true);
	paConfig("log to screen",                 (void*) "only errors");
	paConfig("log file line format",          (void*) "TYPE:DATE:EXEC-AUX/FILE[LINE](p.PID)(t.TID) FUNC: TEXT");
	paConfig("screen line format",            (void*) "TYPE@TIME  EXEC: TEXT");
	paConfig("log to file",                   (void*) true);

	paConfig("man synopsis",                  (void*) manSynopsis);
	paConfig("man shortdescription",          (void*) manShortDescription);
	paConfig("man description",               (void*) manDescription);
	paConfig("man exitstatus",                (void*) manExitStatus);
	paConfig("man author",                    (void*) manAuthor);
	paConfig("man reportingbugs",             (void*) manReportingBugs);
	paConfig("man copyright",                 (void*) manCopyright);
	paConfig("man version",                   (void*) manVersion);

	paParse(paArgs, argC, (char**) argV, 1, false);

    // SamsonSetup init
	samson::SamsonSetup::init( samsonHome , samsonWorking  );
    samson::SamsonSetup::shared()->createWorkingDirectories();      // Create working directories

    if( check )
    {
        std::cout << "Checking setup file ( " << samson::SamsonSetup::shared()->setupFileName() << " ) ...";

        // Check everything looks ok
        au::ErrorManager errorManager;
        samson::SamsonSetup::shared()->check(&errorManager);

        if( errorManager.isActivated() )
            std::cout << "Error checking setup: " << errorManager.getMessage();
        else
            std::cout << "OK!\n";

        return 0;
    }

    std::cout << "\nType help to get a list of valid command\n\n";
    SamsonConfigConsole console;
    console.runConsole();

    // Show samson setup
    //std::cout << samson::SamsonSetup::shared()->str();

}
<commit_msg>spelling correction<commit_after>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "parseArgs/parseArgs.h"
#include "logMsg/logMsg.h"
#include "logMsg/traceLevels.h"

#include "au/CommandLine.h"                     // au::CommandLine
#include "au/Console.h"                         // au::Console

#include "samson/common/SamsonSetup.h"			// samson::SamsonSetup
#include "samson/common/coding.h"				// samson::FormatHeader
#include "samson/common/samsonVars.h"           // SAMSON_ARG_VARS SAMSON_ARGS
#include "samson/module/KVFormat.h"             // samson::KVFormat
#include "samson/module/ModulesManager.h"		// samson::ModulesManager
#include "samson/common/samsonVersion.h"

/* ****************************************************************************
 *
 * Option variables
 */

SAMSON_ARG_VARS;
bool check;

/* ****************************************************************************
 *
 * parse arguments
 */

PaArgument paArgs[] =
{
	SAMSON_ARGS,

	{ "-check",   &check,    "",     PaBool,    PaOpt,  false,  false,   true,  "Check if setup file is correct" },

	PA_END_OF_ARGS
};

int logFd = -1;
bool modified = false;  // Global variable to know if we have to save something before quiting..

std::string getHelpMessage()
{
    std::ostringstream output;

    output << "-------------------------------------\n";
    output << "Help for samsonSetup tool\n";
    output << "-------------------------------------\n";
    output << "\n";
    output << " show                     Show all setup outputs\n";
    output << " set property value       Set a particular value\n";
    output << " save                     Save modified values\n";
    output << " check                    Check if current values are coherent\n";
    output << " edit                     Edit all property values\n";
    output << " set_desktop              Set typical values for desktop (2GB RAM & 2 cores)\n";
    output << " quit                     Quit samsonSetup tool\n";

    return output.str();
}

class SamsonConfigConsole : public au::Console
{

public:

    std::string getPrompt()
    {
        return "SamsonConfig > ";
    }

    //!< function to process a command instroduced by user
    void evalCommand( std::string command )
    {

        au::CommandLine cmd;
        cmd.parse( command );

        if( cmd.get_num_arguments() == 0)
            return;

        std::string main_command = cmd.get_argument(0);

        if( main_command == "help" )
        {
            writeOnConsole( getHelpMessage() );
            return;
        }

        if( main_command == "set" )
        {
            if( cmd.get_num_arguments() < 3 )
                writeOnConsole("Usage: set property value");

            std::string property = cmd.get_argument(1);
            std::string value = cmd.get_argument(2);

            if( !samson::SamsonSetup::shared()->isParameterDefined( property ) )
            {
                writeErrorOnConsole(au::str("Paramter '%s' not defined" , property.c_str()) );
                return;
            }

            samson::SamsonSetup::shared()->setValueForParameter( property , value );
            modified = true;
            writeWarningOnConsole(au::str("Property '%s' set to '%s'", property.c_str() , value.c_str() ));

            return;

        }

        if( main_command == "set_desktop" )
        {
            samson::SamsonSetup::shared()->resetToDefaultValues();
            samson::SamsonSetup::shared()->setValueForParameter( "general.memory" , "2000000000" );
            samson::SamsonSetup::shared()->setValueForParameter( "general.num_processess" , "2" );
            samson::SamsonSetup::shared()->setValueForParameter( "general.shared_memory_size_per_buffer" , "64000000" );

            writeWarningOnConsole("Properties general.memory                        = 2Gb");
            writeWarningOnConsole("Properties general.num_processess                = 2");
            writeWarningOnConsole("Properties general.shared_memory_size_per_buffer = 64Mb");
            return;
        }

        if( main_command == "save" )
        {
            int res = samson::SamsonSetup::shared()->save();  // Save a new file with the current setup

            std::string fileName = samson::SamsonSetup::shared()->setupFileName();

            if( !res )
            {
                writeWarningOnConsole(  au::str("Saved file at %s", fileName.c_str() ) );
                modified = false;
            }
            else
            {
                writeErrorOnConsole(  au::str("Error saving file at %s", fileName.c_str() ) );
            }

            return;
        }

        if( main_command == "check" )
        {
            writeWarningOnConsole( "Checking setup..." );

            // Check everything looks ok
            au::ErrorManager errorManager;
            samson::SamsonSetup::shared()->check(&errorManager);

            if( errorManager.isActivated() )
                writeErrorOnConsole(errorManager.getMessage());
            else
                writeWarningOnConsole("OK\n");

            return;
        }

        if( main_command == "quit" )
        {
            if( modified )
            {
                std::cout << "Setup file modified.... save (y/n)? ";
                char line[1024];
                if (fgets(line, 1024, stdin)== NULL)
                {
                    writeWarningOnConsole("Read nothing");
                }
                if( strcmp(line, "y") || strcmp(line, "Y") )
                {
                    samson::SamsonSetup::shared()->save();  // Save a new file with the current setup
                    std::string fileName = samson::SamsonSetup::shared()->setupFileName();
                    writeWarningOnConsole(  au::str("Saved file at %s", fileName.c_str() ) );
                }

            }

            quitConsole();
            return;
        }

        if ( main_command == "show" )
        {
            std::cout << samson::SamsonSetup::shared()->str();
            return;
        }

        if ( main_command == "edit" )
        {
            modified = true;
            samson::SamsonSetup::shared()->edit();  // Enter in edit mode from command line
            return;
        }

        writeErrorOnConsole(au::str("Unknown command '%s'" , main_command.c_str() ));
        writeWarningOnConsole("Type help to get a list of valid commands ");

    }

};

/* ****************************************************************************
 *
 * man texts -
 */
static const char* manSynopsis         = " [OPTION]";
static const char* manShortDescription = "samsonSetup is a tool to define setup parameters in a SAMSON system.\n\n";
static const char* manDescription      =
"samsonSetup [-check] : Samson configuration tool.\n"
"\n"
"\t -check : Verify current setup\n"
"\n"
"\t samsonSetup is an interactive tool to specify all the setup values in a Samson deployment\n"
"\t Just type help inside samsonSetup to get a list of valid commands\n"
"\n";

static const char* manExitStatus    = "0      if OK\n 1-255  error\n";
static const char* manAuthor        = "Written by Andreu Urruela, Ken Zangelin and J.Gregorio Escalada.";
static const char* manReportingBugs = "bugs to samson-dev@tid.es\n";
static const char* manCopyright     = "Copyright (C) 2011 Telefonica Investigacion y Desarrollo";
static const char* manVersion       = SAMSON_VERSION;

/* ****************************************************************************
 *
 * main -
 */
int main(int argC, const char *argV[])
{
	paConfig("builtin prefix",                (void*) "SS_SETUP_");
	paConfig("usage and exit on any warning", (void*) true);
	paConfig("log to screen",                 (void*) "only errors");
	paConfig("log file line format",          (void*) "TYPE:DATE:EXEC-AUX/FILE[LINE](p.PID)(t.TID) FUNC: TEXT");
	paConfig("screen line format",            (void*) "TYPE@TIME  EXEC: TEXT");
	paConfig("log to file",                   (void*) true);

	paConfig("man synopsis",                  (void*) manSynopsis);
	paConfig("man shortdescription",          (void*) manShortDescription);
	paConfig("man description",               (void*) manDescription);
	paConfig("man exitstatus",                (void*) manExitStatus);
	paConfig("man author",                    (void*) manAuthor);
	paConfig("man reportingbugs",             (void*) manReportingBugs);
	paConfig("man copyright",                 (void*) manCopyright);
	paConfig("man version",                   (void*) manVersion);

	paParse(paArgs, argC, (char**) argV, 1, false);

    // SamsonSetup init
	samson::SamsonSetup::init( samsonHome , samsonWorking  );
    samson::SamsonSetup::shared()->createWorkingDirectories();      // Create working directories

    if( check )
    {
        std::cout << "Checking setup file ( " << samson::SamsonSetup::shared()->setupFileName() << " ) ...";

        // Check everything looks ok
        au::ErrorManager errorManager;
        samson::SamsonSetup::shared()->check(&errorManager);

        if( errorManager.isActivated() )
            std::cout << "Error checking setup: " << errorManager.getMessage();
        else
            std::cout << "OK!\n";

        return 0;
    }

    std::cout << "\nType help to get a list of valid command\n\n";
    SamsonConfigConsole console;
    console.runConsole();

    // Show samson setup
    //std::cout << samson::SamsonSetup::shared()->str();

}
<|endoftext|>


<commit_before>#include "lapos_ascii_tokenizer.h"

#include <cstdlib>
#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <sstream>

using std::string;
using std::vector;
using std::istringstream;

namespace {

void replace(string& s, const string& s1, const string& s2, const char skip=0,
             bool left=true) {
    string::size_type pos = 0;
    while (1) {
        string::size_type i = s.find(s1, pos);
        if (i == string::npos) {
            break;
        }
        if (skip) {
            if (left && i > 0 && s[i - 1] == skip) {
                pos = i + 1;
                continue;
            } else if (i < s.size() - 1 && s[i + 1] == skip) {
                pos = i + 1;
                continue;
            }
        }
        s.replace(i, s1.size(), s2);
        pos = i + s2.size();
    }
}

void SeparateCommas(string& s) {
    const int n = s.size();

    string t;
    for (int i = 0; i < n; i++) {
        if (s[i] == ',') {
            if (!(i > 0 && isdigit(s[i - 1]) && i < n - 1 &&
                  isdigit(s[i + 1]))) {
                t += " , ";
                continue;
            }
        }
        t += string(1, s[i]);
    }

    s = t;
}

void ReallyTokenize(const string& input_text, vector<string>* out) {
    out->clear();

    if (input_text.size() == 0) {
        return;
    }

    string s = input_text;

    replace(s, "``", " `` ");
    if (s[0] == '"') {
        s.replace(0, 1, "`` ");
    }
    if (s.size() > 2 && s[0] == '`' && s[1] != '`') {
        s.replace(0, 1, "` ");
    }
    replace(s, " \"", "  `` ");
    replace(s, "(\"", "( `` ");
    replace(s, "[\"", "[ `` ");
    replace(s, "{\"", "{ `` ");
    replace(s, "<\"", "< `` ");
    replace(s, " `", "  ` ", '`', false);
    replace(s, "(`", "( ` ", '`', false);
    replace(s, "[`", "[ ` ", '`', false);
    replace(s, "{`", "{ ` ", '`', false);
    replace(s, "<`", "< ` ", '`', false);

    replace(s, "...", " ... ");

    SeparateCommas(s);
    replace(s, ";", " ; ");
    replace(s, ":", " : ");
    replace(s, "@", " @ ");
    replace(s, "#", " # ");
    replace(s, "$", " $ ");
    replace(s, "%", " % ");
    replace(s, "&", " & ");

    int pos = s.size() - 1;
    while (pos > 0 && s[pos] == ' ') {
        pos--;
    }
    while (pos > 0) {
        char c = s[pos];
        if (c == '[' || c == ']' || c == ')' || c == '}' || c == '>' ||
            c == '"' || c == '\'') {
            pos--;
            continue;
        }
        break;
    }
    if (s[pos] == '.' && !(pos > 0 && s[pos - 1] == '.')) {
        s.replace(pos, 1, " .");
    }

    replace(s, "?", " ? ");
    replace(s, "!", " ! ");
    replace(s, "[", " [ ");
    replace(s, "]", " ] ");
    replace(s, "(", " ( ");
    replace(s, ")", " ) ");
    replace(s, "{", " { ");
    replace(s, "}", " } ");
    replace(s, "<", " < ");
    replace(s, ">", " > ");

    replace(s, "--", " -- ");

    s.replace(string::size_type(0), 0, " ");
    s.replace(s.size(), 0, " ");

    replace(s, "''", " '' ");
    replace(s, "\"", " '' ");

    replace(s, "' ", " ' ", '\'');
    replace(s, "'s ", " 's ");
    replace(s, "'S ", " 'S ");
    replace(s, "'m ", " 'm ");
    replace(s, "'M ", " 'M ");
    replace(s, "'d ", " 'd ");
    replace(s, "'D ", " 'D ");
    replace(s, "'ll ", " 'll ");
    replace(s, "'re ", " 're ");
    replace(s, "'ve ", " 've ");
    replace(s, "n't ", " n't ");
    replace(s, "'LL ", " 'LL ");
    replace(s, "'RE ", " 'RE ");
    replace(s, "'VE ", " 'VE ");
    replace(s, "N'T ", " N'T ");

    replace(s, " Cannot ", " Can not ");
    replace(s, " cannot ", " can not ");
    replace(s, " D'ye ", " D' ye ");
    replace(s, " d'ye ", " d' ye ");
    replace(s, " Gimme ", " Gim me ");
    replace(s, " gimme ", " gim me ");
    replace(s, " Gonna ", " Gon na ");
    replace(s, " gonna ", " gon na ");
    replace(s, " Gotta ", " Got ta ");
    replace(s, " gotta ", " got ta ");
    replace(s, " Lemme ", " Lem me ");
    replace(s, " lemme ", " lem me ");
    replace(s, " More'n ", " More 'n ");
    replace(s, " more'n ", " more 'n ");
    replace(s, "'Tis ", " 'T is ");
    replace(s, "'tis ", " 't is ");
    replace(s, "'Twas ", " 'T was ");
    replace(s, "'twas ", " 't was ");
    replace(s, " Wanna ", " Wan na ");
    //  replace(s, " wanna ", " wanna ");
    replace(s, " wanna ", " wan na ");

    if (s[s.size() - 1] == '\'') {
        s.replace(s.size() - 1, 1, " ' ");
    }

    istringstream is(s);
    string t;
    while (is >> t) {
        out->emplace_back(t);
    }
}

size_t FindOneOf(const string& s, size_t search_from, const string& cc) {
    for (auto i = search_from; i < s.size(); ++i) {
        for (auto& c : cc) {
            if (s[i] == c) {
                return i;
            }
        }
    }
    return ~0ul;
}

size_t FindFirstNot(const string& s, size_t search_from, char c) {
    for (auto i = search_from; i < s.size(); ++i) {
        if (s[i] != c) {
            return i;
        }
    }
    return ~0ul;
}

bool GetSpans(const string& text, const vector<string>& tokens,
              vector<Span>* spans) {
    spans->reserve(tokens.size());
    size_t search_from = 0;
    for (auto& token : tokens) {
        Span span;
        if (token == "''") {
            size_t x = FindOneOf(text, search_from, "\"'");
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else if (text[span.begin] == '"') {
                span.end_excl = span.begin + 1;
            } else {
                span.end_excl = span.begin + 2;
            }
        } else if (token == "``") {
            size_t x = FindOneOf(text, search_from, "\"`");
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else if (text[span.begin] == '"') {
                span.end_excl = span.begin + 1;
            } else {
                span.end_excl = span.begin + 2;
            }
        } else {
            size_t x = FindFirstNot(text, search_from, ' ');
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else {
                span.end_excl =
                    span.begin + static_cast<uint16_t>(token.size());
            }
        }

        // Assume that the characters match (see asumptions list in Tokenize()).
        if (text.size() < span.end_excl) {
            return false;
        }

        spans->emplace_back(span);
        search_from = span.end_excl;
    }

    return true;
}

}  // namespace

bool LaposASCIITokenizer::Tokenize(
        const string& in, vector<string>* out, vector<Span>* spans) const {
    // Assumptions we can make in order to efficiently compute original spans:
    //
    // * The input string's size < UINT16_MAX.
    //
    // * Tokenization only inserts spacing.
    //   * Except for " -> `` or ''.
    //
    // * `` and '' may already exist in the input string (due to preprocessing).
    //
    // * The input string only contains printable ASCII (therefore the only
    //   possible whitespace character is space/0x20).

    // Tokenize.
    ReallyTokenize(in, out);

    // Map tokens to spans.
    if (!GetSpans(in, *out, spans)) {
        return false;
    }

    return true;
}
<commit_msg>replace -> Replace.<commit_after>#include "lapos_ascii_tokenizer.h"

#include <cstdlib>
#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <sstream>

using std::string;
using std::vector;
using std::istringstream;

namespace {

void Replace(string& s, const string& s1, const string& s2, const char skip=0,
             bool left=true) {
    string::size_type pos = 0;
    while (1) {
        string::size_type i = s.find(s1, pos);
        if (i == string::npos) {
            break;
        }
        if (skip) {
            if (left && i > 0 && s[i - 1] == skip) {
                pos = i + 1;
                continue;
            } else if (i < s.size() - 1 && s[i + 1] == skip) {
                pos = i + 1;
                continue;
            }
        }
        s.replace(i, s1.size(), s2);
        pos = i + s2.size();
    }
}

void SeparateCommas(string& s) {
    const int n = s.size();

    string t;
    for (int i = 0; i < n; i++) {
        if (s[i] == ',') {
            if (!(i > 0 && isdigit(s[i - 1]) && i < n - 1 &&
                  isdigit(s[i + 1]))) {
                t += " , ";
                continue;
            }
        }
        t += string(1, s[i]);
    }

    s = t;
}

void ReallyTokenize(const string& input_text, vector<string>* out) {
    out->clear();

    if (input_text.size() == 0) {
        return;
    }

    string s = input_text;

    Replace(s, "``", " `` ");
    if (s[0] == '"') {
        s.replace(0, 1, "`` ");
    }
    if (s.size() > 2 && s[0] == '`' && s[1] != '`') {
        s.replace(0, 1, "` ");
    }
    Replace(s, " \"", "  `` ");
    Replace(s, "(\"", "( `` ");
    Replace(s, "[\"", "[ `` ");
    Replace(s, "{\"", "{ `` ");
    Replace(s, "<\"", "< `` ");
    Replace(s, " `", "  ` ", '`', false);
    Replace(s, "(`", "( ` ", '`', false);
    Replace(s, "[`", "[ ` ", '`', false);
    Replace(s, "{`", "{ ` ", '`', false);
    Replace(s, "<`", "< ` ", '`', false);

    Replace(s, "...", " ... ");

    SeparateCommas(s);
    Replace(s, ";", " ; ");
    Replace(s, ":", " : ");
    Replace(s, "@", " @ ");
    Replace(s, "#", " # ");
    Replace(s, "$", " $ ");
    Replace(s, "%", " % ");
    Replace(s, "&", " & ");

    int pos = s.size() - 1;
    while (pos > 0 && s[pos] == ' ') {
        pos--;
    }
    while (pos > 0) {
        char c = s[pos];
        if (c == '[' || c == ']' || c == ')' || c == '}' || c == '>' ||
            c == '"' || c == '\'') {
            pos--;
            continue;
        }
        break;
    }
    if (s[pos] == '.' && !(pos > 0 && s[pos - 1] == '.')) {
        s.replace(pos, 1, " .");
    }

    Replace(s, "?", " ? ");
    Replace(s, "!", " ! ");
    Replace(s, "[", " [ ");
    Replace(s, "]", " ] ");
    Replace(s, "(", " ( ");
    Replace(s, ")", " ) ");
    Replace(s, "{", " { ");
    Replace(s, "}", " } ");
    Replace(s, "<", " < ");
    Replace(s, ">", " > ");

    Replace(s, "--", " -- ");

    s.replace(string::size_type(0), 0, " ");
    s.replace(s.size(), 0, " ");

    Replace(s, "''", " '' ");
    Replace(s, "\"", " '' ");

    Replace(s, "' ", " ' ", '\'');
    Replace(s, "'s ", " 's ");
    Replace(s, "'S ", " 'S ");
    Replace(s, "'m ", " 'm ");
    Replace(s, "'M ", " 'M ");
    Replace(s, "'d ", " 'd ");
    Replace(s, "'D ", " 'D ");
    Replace(s, "'ll ", " 'll ");
    Replace(s, "'re ", " 're ");
    Replace(s, "'ve ", " 've ");
    Replace(s, "n't ", " n't ");
    Replace(s, "'LL ", " 'LL ");
    Replace(s, "'RE ", " 'RE ");
    Replace(s, "'VE ", " 'VE ");
    Replace(s, "N'T ", " N'T ");

    Replace(s, " Cannot ", " Can not ");
    Replace(s, " cannot ", " can not ");
    Replace(s, " D'ye ", " D' ye ");
    Replace(s, " d'ye ", " d' ye ");
    Replace(s, " Gimme ", " Gim me ");
    Replace(s, " gimme ", " gim me ");
    Replace(s, " Gonna ", " Gon na ");
    Replace(s, " gonna ", " gon na ");
    Replace(s, " Gotta ", " Got ta ");
    Replace(s, " gotta ", " got ta ");
    Replace(s, " Lemme ", " Lem me ");
    Replace(s, " lemme ", " lem me ");
    Replace(s, " More'n ", " More 'n ");
    Replace(s, " more'n ", " more 'n ");
    Replace(s, "'Tis ", " 'T is ");
    Replace(s, "'tis ", " 't is ");
    Replace(s, "'Twas ", " 'T was ");
    Replace(s, "'twas ", " 't was ");
    Replace(s, " Wanna ", " Wan na ");
    Replace(s, " wanna ", " wan na ");

    if (s[s.size() - 1] == '\'') {
        s.replace(s.size() - 1, 1, " ' ");
    }

    istringstream is(s);
    string t;
    while (is >> t) {
        out->emplace_back(t);
    }
}

size_t FindOneOf(const string& s, size_t search_from, const string& cc) {
    for (auto i = search_from; i < s.size(); ++i) {
        for (auto& c : cc) {
            if (s[i] == c) {
                return i;
            }
        }
    }
    return ~0ul;
}

size_t FindFirstNot(const string& s, size_t search_from, char c) {
    for (auto i = search_from; i < s.size(); ++i) {
        if (s[i] != c) {
            return i;
        }
    }
    return ~0ul;
}

bool GetSpans(const string& text, const vector<string>& tokens,
              vector<Span>* spans) {
    spans->reserve(tokens.size());
    size_t search_from = 0;
    for (auto& token : tokens) {
        Span span;
        if (token == "''") {
            size_t x = FindOneOf(text, search_from, "\"'");
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else if (text[span.begin] == '"') {
                span.end_excl = span.begin + 1;
            } else {
                span.end_excl = span.begin + 2;
            }
        } else if (token == "``") {
            size_t x = FindOneOf(text, search_from, "\"`");
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else if (text[span.begin] == '"') {
                span.end_excl = span.begin + 1;
            } else {
                span.end_excl = span.begin + 2;
            }
        } else {
            size_t x = FindFirstNot(text, search_from, ' ');
            if (UINT16_MAX < x) {
                return false;
            }
            span.begin = static_cast<uint16_t>(x);
            if (text.size() < span.begin) {
                return false;
            } else {
                span.end_excl =
                    span.begin + static_cast<uint16_t>(token.size());
            }
        }

        // Assume that the characters match (see asumptions list in Tokenize()).
        if (text.size() < span.end_excl) {
            return false;
        }

        spans->emplace_back(span);
        search_from = span.end_excl;
    }

    return true;
}

}  // namespace

bool LaposASCIITokenizer::Tokenize(
        const string& in, vector<string>* out, vector<Span>* spans) const {
    // Assumptions we can make in order to efficiently compute original spans:
    //
    // * The input string's size < UINT16_MAX.
    //
    // * Tokenization only inserts spacing.
    //   * Except for " -> `` or ''.
    //
    // * `` and '' may already exist in the input string (due to preprocessing).
    //
    // * The input string only contains printable ASCII (therefore the only
    //   possible whitespace character is space/0x20).

    // Tokenize.
    ReallyTokenize(in, out);

    // Map tokens to spans.
    if (!GetSpans(in, *out, spans)) {
        return false;
    }

    return true;
}
<|endoftext|>


<commit_before>#ifndef __STOUT_NET_HPP__
#define __STOUT_NET_HPP__

#include <netdb.h>
#include <stdio.h>

#include <sys/param.h>
#include <sys/socket.h>

#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif

#include <string>

#include "os.hpp"
#include "try.hpp"

// Network utilities.
namespace net {

// Returns the return code resulting from attempting to download the
// specified HTTP or FTP URL into a file at the specified path.
inline Try<int> download(const std::string& url, const std::string& path)
{
#ifndef HAVE_LIBCURL
  return Try<int>::error("Downloading via HTTP/FTP is not supported");
#else
  Try<int> fd = os::open(path, O_CREAT | O_WRONLY,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);

  CHECK(!fd.isNone());

  if (fd.isError()) {
    return Try<int>::error(fd.error());
  }

  curl_global_init(CURL_GLOBAL_ALL);
  CURL* curl = curl_easy_init();

  if (curl == NULL) {
    curl_easy_cleanup(curl);
    os::close(fd.get());
    return Try<int>::error("Failed to initialize libcurl");
  }

  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);

  FILE* file = fdopen(fd.get(), "w");
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);

  CURLcode curlErrorCode = curl_easy_perform(curl);
  if (curlErrorCode != 0) {
    curl_easy_cleanup(curl);
    fclose(file);
    return Try<int>::error(curl_easy_strerror(curlErrorCode));
  }

  long code;
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
  curl_easy_cleanup(curl);

  if (!fclose(file)) {
    return Try<int>::error("Failed to close file handle");
  }

  return Try<int>::some(code);
#endif // HAVE_LIBCURL
}

// Returns a Try of the hostname for the provided IP. If the hostname cannot
// be resolved, then a string version of the IP address is returned.
inline Try<std::string> getHostname(uint32_t ip)
{
  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = ip;

  char hostname[MAXHOSTNAMELEN];
  if (getnameinfo(
      (sockaddr*)&addr,
      sizeof(addr),
      hostname,
      MAXHOSTNAMELEN,
      NULL,
      NULL,
      0) != 0) {
    return Try<std::string>::error(strerror(errno));
  }

  return std::string(hostname);
}

} // namespace net {

#endif // __STOUT_NET_HPP__
<commit_msg>Fix bug passing 'NULL' instead of 0.<commit_after>#ifndef __STOUT_NET_HPP__
#define __STOUT_NET_HPP__

#include <netdb.h>
#include <stdio.h>

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/types.h>

#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#endif

#include <string>

#include "os.hpp"
#include "try.hpp"

// Network utilities.
namespace net {

// Returns the return code resulting from attempting to download the
// specified HTTP or FTP URL into a file at the specified path.
inline Try<int> download(const std::string& url, const std::string& path)
{
#ifndef HAVE_LIBCURL
  return Try<int>::error("Downloading via HTTP/FTP is not supported");
#else
  Try<int> fd = os::open(path, O_CREAT | O_WRONLY,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);

  CHECK(!fd.isNone());

  if (fd.isError()) {
    return Try<int>::error(fd.error());
  }

  curl_global_init(CURL_GLOBAL_ALL);
  CURL* curl = curl_easy_init();

  if (curl == NULL) {
    curl_easy_cleanup(curl);
    os::close(fd.get());
    return Try<int>::error("Failed to initialize libcurl");
  }

  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);

  FILE* file = fdopen(fd.get(), "w");
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);

  CURLcode curlErrorCode = curl_easy_perform(curl);
  if (curlErrorCode != 0) {
    curl_easy_cleanup(curl);
    fclose(file);
    return Try<int>::error(curl_easy_strerror(curlErrorCode));
  }

  long code;
  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
  curl_easy_cleanup(curl);

  if (!fclose(file)) {
    return Try<int>::error("Failed to close file handle");
  }

  return Try<int>::some(code);
#endif // HAVE_LIBCURL
}

// Returns a Try of the hostname for the provided IP. If the hostname cannot
// be resolved, then a string version of the IP address is returned.
inline Try<std::string> getHostname(uint32_t ip)
{
  sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = ip;

  char hostname[MAXHOSTNAMELEN];
  if (getnameinfo(
      (sockaddr*)&addr,
      sizeof(addr),
      hostname,
      MAXHOSTNAMELEN,
      NULL,
      0,
      0) != 0) {
    return Try<std::string>::error(strerror(errno));
  }

  return std::string(hostname);
}

} // namespace net {

#endif // __STOUT_NET_HPP__
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/test/python_utils.h"

#include "base/base_paths.h"
#include "base/environment.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"

const char kPythonPathEnv[] = "PYTHONPATH";

void AppendToPythonPath(const FilePath& dir) {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  std::string old_path;
  std::string dir_path;
#if defined(OS_WIN)
  dir_path = WideToUTF8(dir.value());
#elif defined(OS_POSIX)
  dir_path = dir.value();
#endif
  if (!env->GetVar(kPythonPathEnv, &old_path)) {
    env->SetVar(kPythonPathEnv, dir_path.c_str());
  } else if (old_path.find(dir_path) == std::string::npos) {
    std::string new_path(old_path);
#if defined(OS_WIN)
    new_path.append(";");
#elif defined(OS_POSIX)
    new_path.append(":");
#endif
    new_path.append(dir_path.c_str());
    env->SetVar(kPythonPathEnv, new_path);
  }
}

bool GetPyProtoPath(FilePath* dir) {
  // Locate the Python code generated by the protocol buffers compiler.
  FilePath generated_code_dir;
  if (!PathService::Get(base::DIR_EXE, &generated_code_dir)) {
    return false;
  }

  const FilePath kPyProto(FILE_PATH_LITERAL("pyproto"));

#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
  // On Mac and Chrome OS, DIR_EXE might be pointing deep into the Release/
  // (or Debug/) directory and we can't depend on how far down it goes. So we
  // walk upwards from DIR_EXE until we find a likely looking spot.
  while (!file_util::DirectoryExists(generated_code_dir.Append(kPyProto))) {
    FilePath parent = generated_code_dir.DirName();
    if (parent == generated_code_dir) {
      // We hit the root directory. Maybe we didn't build any targets which
      // produced Python protocol buffers.
      PathService::Get(base::DIR_EXE, &generated_code_dir);
      return false;
    }
    generated_code_dir = parent;
  }
#endif
  *dir = generated_code_dir.Append(kPyProto);
  return true;
}

bool GetPythonRunTime(FilePath* dir) {
#if defined(OS_WIN)
  if (!PathService::Get(base::DIR_SOURCE_ROOT, dir))
    return false;
  *dir = dir->Append(FILE_PATH_LITERAL("third_party"))
      .Append(FILE_PATH_LITERAL("python_26"))
      .Append(FILE_PATH_LITERAL("python.exe"));
#elif defined(OS_POSIX)
  *dir = FilePath("python");
#endif
  return true;
}
<commit_msg>Set PYTHON_PATH at TestServer Init() instead of Start()<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/test/python_utils.h"

#include "base/base_paths.h"
#include "base/environment.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"

const char kPythonPathEnv[] = "PYTHONPATH";

void AppendToPythonPath(const FilePath& dir) {
  scoped_ptr<base::Environment> env(base::Environment::Create());
  std::string old_path;
  std::string dir_path;
#if defined(OS_WIN)
  dir_path = WideToUTF8(dir.value());
#elif defined(OS_POSIX)
  dir_path = dir.value();
#endif
  if (!env->GetVar(kPythonPathEnv, &old_path)) {
    env->SetVar(kPythonPathEnv, dir_path.c_str());
  } else if (old_path.find(dir_path) == std::string::npos) {
    std::string new_path(old_path);
#if defined(OS_WIN)
    new_path.append(";");
#elif defined(OS_POSIX)
    new_path.append(":");
#endif
    new_path.append(dir_path.c_str());
    env->SetVar(kPythonPathEnv, new_path);
  }
}

namespace {

// Search for |to_try|, rolling up the directory tree from
// |start_dir|.  If found, return true and put the path to |to_try| in
// |out_dir|.  If not, return false and leave |out_dir| untouched.
bool TryRelativeToDir(const FilePath& start_dir,
                      const FilePath& to_try,
                      FilePath* out_dir) {
  FilePath dir(start_dir);
  while (!file_util::DirectoryExists(dir.Append(to_try))) {
    FilePath parent = dir.DirName();
    if (parent == dir) {
      // We hit the root directory.
      return false;
    }
    dir = parent;
  }
  *out_dir = dir;
  return true;
}

}  // namespace

bool GetPyProtoPath(FilePath* dir) {
  // Locate the Python code generated by the protocol buffers compiler.
  FilePath generated_code_dir;
  if (!PathService::Get(base::DIR_EXE, &generated_code_dir)) {
    LOG(ERROR) << "Can't find " << generated_code_dir.value();
    return false;
  }

  const FilePath kPyProto(FILE_PATH_LITERAL("pyproto"));

#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
  FilePath source_dir;
  if (!PathService::Get(base::DIR_SOURCE_ROOT, &source_dir)) {
    LOG(ERROR) << "Can't find " << source_dir.value();
    return false;
  }
  // On Mac, and possibly Chrome OS, DIR_EXE might be pointing deep
  // into the Release/ (or Debug/) directory and we can't depend on
  // how far down it goes. So we walk upwards from DIR_EXE until we
  // find a likely looking spot.
  if (!TryRelativeToDir(generated_code_dir, kPyProto, dir)) {
    LOG(WARNING) << "Can't find " << kPyProto.value()
                 << " next to " << generated_code_dir.value();
    // On Chrome OS, we may have installed the test binaries and support tools
    // in a wholly separate location, relative to DIR_SOURCE_ROOT.  We'll want
    // to do a similar investigation from that point as well.
    generated_code_dir = source_dir
        .Append(FILE_PATH_LITERAL("out"))
        .Append(FILE_PATH_LITERAL("Release"));
    if (!TryRelativeToDir(generated_code_dir, kPyProto, dir)) {
      LOG(WARNING) << "Can't find " << kPyProto.value()
                   << " next to " << generated_code_dir.value();
      return false;
    }
  }
  generated_code_dir = *dir;
#endif
  *dir = generated_code_dir.Append(kPyProto);
  VLOG(2) << "Found " << kPyProto.value() << " in " << dir->value();
  return true;
}

bool GetPythonRunTime(FilePath* dir) {
#if defined(OS_WIN)
  if (!PathService::Get(base::DIR_SOURCE_ROOT, dir))
    return false;
  *dir = dir->Append(FILE_PATH_LITERAL("third_party"))
      .Append(FILE_PATH_LITERAL("python_26"))
      .Append(FILE_PATH_LITERAL("python.exe"));
#elif defined(OS_POSIX)
  *dir = FilePath("python");
#endif
  return true;
}
<|endoftext|>


<commit_before>#ifdef _WIN32

#include "lldb/Host/ProcessRunLock.h"
#include "lldb/Host/windows/windows.h"

namespace lldb_private {

    // Windows has slim read-writer lock support on Vista and higher, so we
    // will attempt to load the APIs.  If they exist, we will use them, and
    // if not, we will fall back on critical sections.  When we drop support
    // for XP, we can stop lazy-loading these APIs and just use them directly.
#if defined(__MINGW32__)
    // Taken from WinNT.h
    typedef struct _RTL_SRWLOCK {
        PVOID Ptr;
    } RTL_SRWLOCK, *PRTL_SRWLOCK;

    // Taken from WinBase.h
    typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
#endif

    typedef struct Win32RWLOCK
    {
        unsigned long int readlockcount;
        HANDLE writable;
        CRITICAL_SECTION writelock;
        unsigned long int writelocked;
    } Win32RWLOCK;

    typedef Win32RWLOCK* PWin32RWLOCK;

    static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
    static BOOL (WINAPI *fpTryAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static BOOL (WINAPI *fpTryAcquireSRWLockShared)(PSRWLOCK lock) = NULL;

    static bool sHasSRW = false;

    static bool loadSRW()
    {
        static bool sChecked = false;
        if (!sChecked)
        {
            sChecked = true;
            return false;

            HMODULE hLib = ::LoadLibrary(TEXT("Kernel32"));
            if (hLib)
            {
                fpInitializeSRWLock =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "InitializeSRWLock");
                fpAcquireSRWLockExclusive =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "AcquireSRWLockExclusive");
                fpAcquireSRWLockShared =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "AcquireSRWLockShared");
                fpReleaseSRWLockExclusive =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "ReleaseSRWLockExclusive");
                fpReleaseSRWLockShared =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "ReleaseSRWLockShared");
                fpTryAcquireSRWLockExclusive =
                    (BOOL (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "TryAcquireSRWLockExclusive");
                fpTryAcquireSRWLockShared =
                    (BOOL (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "TryAcquireSRWLockShared");

                ::FreeLibrary(hLib);

                if (fpInitializeSRWLock != NULL) {
                    sHasSRW = true;
                }
            }
        }
        return sHasSRW;
    }

    ProcessRunLock::ProcessRunLock ()
        : m_running(false)
    {
        if (loadSRW())
        {
            m_rwlock = calloc(1, sizeof(SRWLOCK));
            fpInitializeSRWLock(static_cast<PSRWLOCK>(m_rwlock));
        }
        else
        {
            m_rwlock = calloc(1, sizeof(Win32RWLOCK));
            static_cast<PWin32RWLOCK>(m_rwlock)->readlockcount = 0;
            static_cast<PWin32RWLOCK>(m_rwlock)->writable = CreateEvent(NULL, true, true, NULL);
            InitializeCriticalSection(&static_cast<PWin32RWLOCK>(m_rwlock)->writelock);
        }
    }

    ProcessRunLock::~ProcessRunLock ()
    {
        if (!sHasSRW)
        {
            CloseHandle(static_cast<PWin32RWLOCK>(m_rwlock)->writable);
            DeleteCriticalSection(&static_cast<PWin32RWLOCK>(m_rwlock)->writelock);
        }
        free(m_rwlock);
    }

    bool ReadLock (lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpAcquireSRWLockShared(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            EnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            InterlockedIncrement(&static_cast<PWin32RWLOCK>(rwlock)->readlockcount);
            ResetEvent(static_cast<PWin32RWLOCK>(rwlock)->writable);
            LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            return true;
        }
    }

    bool ProcessRunLock::ReadTryLock ()
    {
        ReadLock(m_rwlock);
        if (m_running == false)
            return true;
        ReadUnlock();
        return false;
    }

    bool ProcessRunLock::ReadUnlock ()
    {
        if (sHasSRW)
        {
            fpReleaseSRWLockShared(static_cast<PSRWLOCK>(m_rwlock));
            return true;
        }
        else
        {
            unsigned long int value = InterlockedDecrement(&static_cast<PWin32RWLOCK>(m_rwlock)->readlockcount);
            assert(((int)value) >= 0);
            if (value == 0)
                SetEvent(static_cast<PWin32RWLOCK>(m_rwlock)->writable);
            return true;
        }
    }

    bool WriteLock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            EnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            WaitForSingleObject(static_cast<PWin32RWLOCK>(rwlock)->writable, INFINITE);
            int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 1);
            assert(res == 0);
            return true;
        }
    }

    bool WriteTryLock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            return fpTryAcquireSRWLockExclusive(static_cast<PSRWLOCK>(rwlock)) != 0;
        }
        else
        {
            if (TryEnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock)) {
                if (WaitForSingleObject(static_cast<PWin32RWLOCK>(rwlock)->writable, 0)) {
                    LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
                    return false;
                }
                int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 1);
                assert(res == 0);
                return true;
            }
            return false;
        }
    }

    bool WriteUnlock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 0);
            if (res == 1) {
                LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
                return true;
            }
            return false;
        }
    }

    bool ProcessRunLock::SetRunning ()
    {
        WriteLock(m_rwlock);
        m_running = true;
        WriteUnlock(m_rwlock);
        return true;
    }

    bool ProcessRunLock::TrySetRunning ()
    {
        if (WriteTryLock(m_rwlock))
        {
            bool r = !m_running;
            m_running = true;
            WriteUnlock(m_rwlock);
            return r;
        }
        return false;
    }

    bool ProcessRunLock::SetStopped ()
    {
        WriteLock(m_rwlock);
        m_running = false;
        WriteUnlock(m_rwlock);
        return true;
    }
}

#endif
<commit_msg>Change type of a few members of a struct from unsigned to signed. They are used in Windows APIs which expect a signed argument and cause a build failure on Mingw.<commit_after>#ifdef _WIN32

#include "lldb/Host/ProcessRunLock.h"
#include "lldb/Host/windows/windows.h"

namespace lldb_private {

    // Windows has slim read-writer lock support on Vista and higher, so we
    // will attempt to load the APIs.  If they exist, we will use them, and
    // if not, we will fall back on critical sections.  When we drop support
    // for XP, we can stop lazy-loading these APIs and just use them directly.
#if defined(__MINGW32__)
    // Taken from WinNT.h
    typedef struct _RTL_SRWLOCK {
        PVOID Ptr;
    } RTL_SRWLOCK, *PRTL_SRWLOCK;

    // Taken from WinBase.h
    typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
#endif

    typedef struct Win32RWLOCK
    {
        long int readlockcount;
        HANDLE writable;
        CRITICAL_SECTION writelock;
        long int writelocked;
    } Win32RWLOCK;

    typedef Win32RWLOCK* PWin32RWLOCK;

    static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
    static BOOL (WINAPI *fpTryAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
    static BOOL (WINAPI *fpTryAcquireSRWLockShared)(PSRWLOCK lock) = NULL;

    static bool sHasSRW = false;

    static bool loadSRW()
    {
        static bool sChecked = false;
        if (!sChecked)
        {
            sChecked = true;
            return false;

            HMODULE hLib = ::LoadLibrary(TEXT("Kernel32"));
            if (hLib)
            {
                fpInitializeSRWLock =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "InitializeSRWLock");
                fpAcquireSRWLockExclusive =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "AcquireSRWLockExclusive");
                fpAcquireSRWLockShared =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "AcquireSRWLockShared");
                fpReleaseSRWLockExclusive =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "ReleaseSRWLockExclusive");
                fpReleaseSRWLockShared =
                    (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "ReleaseSRWLockShared");
                fpTryAcquireSRWLockExclusive =
                    (BOOL (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "TryAcquireSRWLockExclusive");
                fpTryAcquireSRWLockShared =
                    (BOOL (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
                    "TryAcquireSRWLockShared");

                ::FreeLibrary(hLib);

                if (fpInitializeSRWLock != NULL) {
                    sHasSRW = true;
                }
            }
        }
        return sHasSRW;
    }

    ProcessRunLock::ProcessRunLock ()
        : m_running(false)
    {
        if (loadSRW())
        {
            m_rwlock = calloc(1, sizeof(SRWLOCK));
            fpInitializeSRWLock(static_cast<PSRWLOCK>(m_rwlock));
        }
        else
        {
            m_rwlock = calloc(1, sizeof(Win32RWLOCK));
            static_cast<PWin32RWLOCK>(m_rwlock)->readlockcount = 0;
            static_cast<PWin32RWLOCK>(m_rwlock)->writable = CreateEvent(NULL, true, true, NULL);
            InitializeCriticalSection(&static_cast<PWin32RWLOCK>(m_rwlock)->writelock);
        }
    }

    ProcessRunLock::~ProcessRunLock ()
    {
        if (!sHasSRW)
        {
            CloseHandle(static_cast<PWin32RWLOCK>(m_rwlock)->writable);
            DeleteCriticalSection(&static_cast<PWin32RWLOCK>(m_rwlock)->writelock);
        }
        free(m_rwlock);
    }

    bool ReadLock (lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpAcquireSRWLockShared(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            EnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            InterlockedIncrement(&static_cast<PWin32RWLOCK>(rwlock)->readlockcount);
            ResetEvent(static_cast<PWin32RWLOCK>(rwlock)->writable);
            LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            return true;
        }
    }

    bool ProcessRunLock::ReadTryLock ()
    {
        ReadLock(m_rwlock);
        if (m_running == false)
            return true;
        ReadUnlock();
        return false;
    }

    bool ProcessRunLock::ReadUnlock ()
    {
        if (sHasSRW)
        {
            fpReleaseSRWLockShared(static_cast<PSRWLOCK>(m_rwlock));
            return true;
        }
        else
        {
            unsigned long int value = InterlockedDecrement(&static_cast<PWin32RWLOCK>(m_rwlock)->readlockcount);
            assert(((int)value) >= 0);
            if (value == 0)
                SetEvent(static_cast<PWin32RWLOCK>(m_rwlock)->writable);
            return true;
        }
    }

    bool WriteLock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            EnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
            WaitForSingleObject(static_cast<PWin32RWLOCK>(rwlock)->writable, INFINITE);
            int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 1);
            assert(res == 0);
            return true;
        }
    }

    bool WriteTryLock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            return fpTryAcquireSRWLockExclusive(static_cast<PSRWLOCK>(rwlock)) != 0;
        }
        else
        {
            if (TryEnterCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock)) {
                if (WaitForSingleObject(static_cast<PWin32RWLOCK>(rwlock)->writable, 0)) {
                    LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
                    return false;
                }
                int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 1);
                assert(res == 0);
                return true;
            }
            return false;
        }
    }

    bool WriteUnlock(lldb::rwlock_t rwlock)
    {
        if (sHasSRW)
        {
            fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(rwlock));
            return true;
        }
        else
        {
            int res = InterlockedExchange(&static_cast<PWin32RWLOCK>(rwlock)->writelocked, 0);
            if (res == 1) {
                LeaveCriticalSection(&static_cast<PWin32RWLOCK>(rwlock)->writelock);
                return true;
            }
            return false;
        }
    }

    bool ProcessRunLock::SetRunning ()
    {
        WriteLock(m_rwlock);
        m_running = true;
        WriteUnlock(m_rwlock);
        return true;
    }

    bool ProcessRunLock::TrySetRunning ()
    {
        if (WriteTryLock(m_rwlock))
        {
            bool r = !m_running;
            m_running = true;
            WriteUnlock(m_rwlock);
            return r;
        }
        return false;
    }

    bool ProcessRunLock::SetStopped ()
    {
        WriteLock(m_rwlock);
        m_running = false;
        WriteUnlock(m_rwlock);
        return true;
    }
}

#endif
<|endoftext|>