<commit_before>// Copyright (C) 2012, Chris J. Foster and the other authors and contributors
// 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.
// * Neither the name of the software's owners nor the names of its
//   contributors may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
//
// (This is the BSD 3-clause license)

#include "mainwindow.h"
#include "ptview.h"
#include "shadereditor.h"
#include "shader.h"

#include <QtCore/QSignalMapper>
#include <QtGui/QApplication>
#include <QtGui/QColorDialog>
#include <QtGui/QDockWidget>
#include <QtGui/QFileDialog>
#include <QtGui/QGridLayout>
#include <QtGui/QMenuBar>
#include <QtGui/QMessageBox>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QSplitter>
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QDesktopWidget>

//------------------------------------------------------------------------------
// Unbuffered std::streambuf implementation for output to a text edit widget
class StreamBufTextEditSink : public std::streambuf
{
    public:
        StreamBufTextEditSink(QPlainTextEdit* textEdit) : m_textEdit(textEdit) {}

    protected:
        int overflow(int c)
        {
            m_textEdit->moveCursor(QTextCursor::End);
            m_textEdit->insertPlainText(QString((char)c));
            m_textEdit->ensureCursorVisible();
            return 0;
        }

    private:
        QPlainTextEdit* m_textEdit;
};

//------------------------------------------------------------------------------
// PointViewerMainWindow implementation

PointViewerMainWindow::PointViewerMainWindow(
        const QStringList& initialPointFileNames)
    : m_pointView(0),
    m_logTextView(0),
    m_shaderParamsUI(0),
    m_oldBuf(0)
{
    setWindowTitle("Displaz");

    //--------------------------------------------------
    // Menus
    // File menu
    QMenu* fileMenu = menuBar()->addMenu(tr("&File"));
    QAction* openAct = fileMenu->addAction(tr("&Open"));
    openAct->setToolTip(tr("Open a point cloud file"));
    openAct->setShortcuts(QKeySequence::Open);
    connect(openAct, SIGNAL(triggered()), this, SLOT(openFiles()));
    QAction* reloadAct = fileMenu->addAction(tr("&Reload"));
    reloadAct->setStatusTip(tr("Reload point files from disk"));
    reloadAct->setShortcut(Qt::Key_F5);
    connect(reloadAct, SIGNAL(triggered()), this, SLOT(reloadFiles()));
    QAction* quitAct = fileMenu->addAction(tr("&Quit"));
    quitAct->setStatusTip(tr("Exit the application"));
    quitAct->setShortcuts(QKeySequence::Quit);
    connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));

    // View menu
    QMenu* viewMenu = menuBar()->addMenu(tr("&View"));
    QAction* drawBoundingBoxes = viewMenu->addAction(tr("Draw &Bounding boxes"));
    drawBoundingBoxes->setCheckable(true);
    drawBoundingBoxes->setChecked(true);
    QAction* trackballMode = viewMenu->addAction(tr("Use &Trackball camera"));
    trackballMode->setCheckable(true);
    trackballMode->setChecked(false);
    // Background sub-menu
    QMenu* backMenu = viewMenu->addMenu(tr("Set &Background"));
    QSignalMapper* mapper = new QSignalMapper(this);
    // Selectable backgrounds (svg_names from SVG standard - see QColor docs)
    const char* backgroundNames[] = {/* "Display Name", "svg_name", */
                                        "&Black",        "black",
                                        "&Dark Grey",    "dimgrey",
                                        "&Light Grey",   "lightgrey",
                                        "&White",        "white" };
    for(size_t i = 0; i < sizeof(backgroundNames)/sizeof(const char*); i+=2)
    {
        QAction* backgroundAct = backMenu->addAction(tr(backgroundNames[i]));
        mapper->setMapping(backgroundAct, backgroundNames[i+1]);
        connect(backgroundAct, SIGNAL(triggered()), mapper, SLOT(map()));
    }
    connect(mapper, SIGNAL(mapped(QString)),
            this, SLOT(setBackground(QString)));
    backMenu->addSeparator();
    QAction* backgroundCustom = backMenu->addAction(tr("&Custom"));
    connect(backgroundCustom, SIGNAL(triggered()),
            this, SLOT(chooseBackground()));

    // Help menu
    QMenu* helpMenu = menuBar()->addMenu(tr("&Help"));
    QAction* helpAct = helpMenu->addAction(tr("&Controls"));
    connect(helpAct, SIGNAL(triggered()), this, SLOT(helpDialog()));
    helpMenu->addSeparator();
    QAction* aboutAct = helpMenu->addAction(tr("&About"));
    connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutDialog()));

    //--------------------------------------------------
    // Point viewer
    m_pointView = new PointView(this);
    setCentralWidget(m_pointView);
    connect(drawBoundingBoxes, SIGNAL(triggered()),
            m_pointView, SLOT(toggleDrawBoundingBoxes()));
    connect(trackballMode, SIGNAL(triggered()),
            m_pointView, SLOT(toggleCameraMode()));
    connect(m_pointView, SIGNAL(pointFilesLoaded(QStringList)),
            this, SLOT(setLoadedFileNames(QStringList)));
    connect(&m_pointView->shaderProgram(), SIGNAL(paramsChanged()),
            this, SLOT(setupShaderParamUI()));

    //--------------------------------------------------
    // Docked widgets
    // Shader parameters UI
    QDockWidget* shaderParamsDock = new QDockWidget(tr("Shader Parameters"), this);
    shaderParamsDock->setFeatures(QDockWidget::DockWidgetMovable |
                                  QDockWidget::DockWidgetClosable);
    shaderParamsDock->setAllowedAreas(Qt::LeftDockWidgetArea |
                                      Qt::RightDockWidgetArea);
    m_shaderParamsUI = new QWidget(shaderParamsDock);
    shaderParamsDock->setWidget(m_shaderParamsUI);

    // Shader editor UI
    QDockWidget* shaderEditorDock = new QDockWidget(tr("Shader Editor"), this);
    shaderEditorDock->setFeatures(QDockWidget::DockWidgetMovable |
                                  QDockWidget::DockWidgetClosable);
    shaderEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea |
                                      Qt::RightDockWidgetArea);
    QWidget* shaderEditorUI = new QWidget(shaderEditorDock);
    QGridLayout* shaderEditorLayout = new QGridLayout(shaderEditorUI);
    shaderEditorLayout->setContentsMargins(2,2,2,2);
    QTabWidget* shaderTabs = new QTabWidget(shaderEditorUI);
    shaderEditorLayout->addWidget(shaderTabs, 0, 0);
    // vertex shader
    ShaderEditor* vertexShaderEditor = new ShaderEditor(shaderTabs);
    shaderTabs->addTab(vertexShaderEditor, tr("Vertex Shader"));
    connect(vertexShaderEditor, SIGNAL(sendShader(QString)),
            &m_pointView->shaderProgram(), SLOT(setVertexShader(QString)));
    // fragment shader
    ShaderEditor* fragmentShaderEditor = new ShaderEditor(shaderTabs);
    shaderTabs->addTab(fragmentShaderEditor, tr("Fragment Shader"));
    connect(fragmentShaderEditor, SIGNAL(sendShader(QString)),
            &m_pointView->shaderProgram(), SLOT(setFragmentShader(QString)));
    shaderEditorDock->setWidget(shaderEditorUI);

    // Log viewer UI
    QDockWidget* logDock = new QDockWidget(tr("Log"), this);
    logDock->setFeatures(QDockWidget::DockWidgetMovable |
                         QDockWidget::DockWidgetClosable);
    logDock->setAllowedAreas(Qt::AllDockWidgetAreas);
    m_logTextView = new QPlainTextEdit(logDock);
    m_logTextView->setReadOnly(true);
    m_logTextView->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
    //m_logTextView->setLineWrapMode(QPlainTextEdit::NoWrap);
    logDock->setWidget(m_logTextView);

    // Set up docked widgets
    addDockWidget(Qt::RightDockWidgetArea, shaderParamsDock);
    addDockWidget(Qt::RightDockWidgetArea, shaderEditorDock);
    addDockWidget(Qt::RightDockWidgetArea, logDock);
    tabifyDockWidget(shaderParamsDock, shaderEditorDock);
    shaderEditorDock->setVisible(false);

    // Add dock widget toggles to view menu
    viewMenu->addSeparator();
    viewMenu->addAction(shaderParamsDock->toggleViewAction());
    viewMenu->addAction(shaderEditorDock->toggleViewAction());
    viewMenu->addAction(logDock->toggleViewAction());

    // Set shaders
    QFile vertexShaderFile(":/points_v.glsl");
    if (vertexShaderFile.open(QIODevice::ReadOnly))
        m_pointView->shaderProgram().setVertexShader(vertexShaderFile.readAll());
    QFile fragmentShaderFile(":/points_f.glsl");
    if (fragmentShaderFile.open(QIODevice::ReadOnly))
        m_pointView->shaderProgram().setFragmentShader(fragmentShaderFile.readAll());
    vertexShaderEditor->setPlainText(m_pointView->shaderProgram().vertexShader());
    fragmentShaderEditor->setPlainText(m_pointView->shaderProgram().fragmentShader());

    if(!initialPointFileNames.empty())
        m_pointView->loadPointFiles(initialPointFileNames);
}

PointViewerMainWindow::~PointViewerMainWindow()
{
    if (m_oldBuf)
        std::cout.rdbuf(m_oldBuf);
}

void PointViewerMainWindow::setupShaderParamUI()
{
    while (QWidget* child = m_shaderParamsUI->findChild<QWidget*>())
        delete child;
    delete m_shaderParamsUI->layout();
    m_pointView->shaderProgram().setupParameterUI(m_shaderParamsUI);
}

QSize PointViewerMainWindow::sizeHint() const
{
    return QSize(800,600);
}

void PointViewerMainWindow::captureStdout()
{
    m_oldBuf = std::cout.rdbuf();
    m_guiStdoutBuf.reset(new StreamBufTextEditSink(m_logTextView));
    std::cout.rdbuf(m_guiStdoutBuf.get());
}

void PointViewerMainWindow::keyReleaseEvent(QKeyEvent* event)
{
    if(event->key() == Qt::Key_Escape)
        close();
}

void PointViewerMainWindow::openFiles()
{
    QFileDialog dialog(this, tr("Select one or more point clouds to open"));
    dialog.setNameFilter(tr("Point cloud files (*.las *.laz)"));
    dialog.setFileMode(QFileDialog::ExistingFiles);
    dialog.setDirectory(m_currFileDir);
    if(dialog.exec())
    {
        QStringList files = dialog.selectedFiles();
        m_pointView->loadPointFiles(files);
    }
    m_currFileDir = dialog.directory();
}

void PointViewerMainWindow::reloadFiles()
{
    m_pointView->reloadPointFiles();
}

void PointViewerMainWindow::helpDialog()
{
    QString message = tr(
        "

Displaz 3D window controls

"
        "<list>"
        "
LMB+drag = rotate camera
"
        "
RMB+drag = zoom camera
"
        "
Ctrl+LMB+drag = move 3D cursor
"
        "
Ctrl+RMB+drag = zoom 3D cursor along view direction
"
        "
'c' = center camera on 3D cursor
"
        "
's' = snap 3D cursor to nearest point
"
        "</list>"
        "
(LMB, RMB = left & right mouse buttons)
"
    );
    QMessageBox::information(this, tr("Displaz control summary"), message);
}

void PointViewerMainWindow::aboutDialog()
{
    QString message = tr("Displaz - a qt-based las viewer\nversion 0.0.1");
    QMessageBox::information(this, tr("About displaz"), message);
}

void PointViewerMainWindow::setBackground(const QString& name)
{
    m_pointView->setBackground(QColor(name));
}

void PointViewerMainWindow::chooseBackground()
{
    m_pointView->setBackground(
        QColorDialog::getColor(QColor(255,255,255), this, "background color"));
}

void PointViewerMainWindow::setLoadedFileNames(const QStringList& fileNames)
{
    setWindowTitle(tr("Displaz - %1").arg(fileNames.join(", ")));
}

<commit_msg>Improve default shader editor location<commit_after>// Copyright (C) 2012, Chris J. Foster and the other authors and contributors
// 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.
// * Neither the name of the software's owners nor the names of its
//   contributors may be used to endorse or promote products derived from this
//   software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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.
//
// (This is the BSD 3-clause license)

#include "mainwindow.h"
#include "ptview.h"
#include "shadereditor.h"
#include "shader.h"

#include <QtCore/QSignalMapper>
#include <QtGui/QApplication>
#include <QtGui/QColorDialog>
#include <QtGui/QDockWidget>
#include <QtGui/QFileDialog>
#include <QtGui/QGridLayout>
#include <QtGui/QMenuBar>
#include <QtGui/QMessageBox>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QSplitter>
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QDesktopWidget>

//------------------------------------------------------------------------------
// Unbuffered std::streambuf implementation for output to a text edit widget
class StreamBufTextEditSink : public std::streambuf
{
    public:
        StreamBufTextEditSink(QPlainTextEdit* textEdit) : m_textEdit(textEdit) {}

    protected:
        int overflow(int c)
        {
            m_textEdit->moveCursor(QTextCursor::End);
            m_textEdit->insertPlainText(QString((char)c));
            m_textEdit->ensureCursorVisible();
            return 0;
        }

    private:
        QPlainTextEdit* m_textEdit;
};

//------------------------------------------------------------------------------
// PointViewerMainWindow implementation

PointViewerMainWindow::PointViewerMainWindow(
        const QStringList& initialPointFileNames)
    : m_pointView(0),
    m_logTextView(0),
    m_shaderParamsUI(0),
    m_oldBuf(0)
{
    setWindowTitle("Displaz");

    //--------------------------------------------------
    // Menus
    // File menu
    QMenu* fileMenu = menuBar()->addMenu(tr("&File"));
    QAction* openAct = fileMenu->addAction(tr("&Open"));
    openAct->setToolTip(tr("Open a point cloud file"));
    openAct->setShortcuts(QKeySequence::Open);
    connect(openAct, SIGNAL(triggered()), this, SLOT(openFiles()));
    QAction* reloadAct = fileMenu->addAction(tr("&Reload"));
    reloadAct->setStatusTip(tr("Reload point files from disk"));
    reloadAct->setShortcut(Qt::Key_F5);
    connect(reloadAct, SIGNAL(triggered()), this, SLOT(reloadFiles()));
    QAction* quitAct = fileMenu->addAction(tr("&Quit"));
    quitAct->setStatusTip(tr("Exit the application"));
    quitAct->setShortcuts(QKeySequence::Quit);
    connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));

    // View menu
    QMenu* viewMenu = menuBar()->addMenu(tr("&View"));
    QAction* drawBoundingBoxes = viewMenu->addAction(tr("Draw &Bounding boxes"));
    drawBoundingBoxes->setCheckable(true);
    drawBoundingBoxes->setChecked(true);
    QAction* trackballMode = viewMenu->addAction(tr("Use &Trackball camera"));
    trackballMode->setCheckable(true);
    trackballMode->setChecked(false);
    // Background sub-menu
    QMenu* backMenu = viewMenu->addMenu(tr("Set &Background"));
    QSignalMapper* mapper = new QSignalMapper(this);
    // Selectable backgrounds (svg_names from SVG standard - see QColor docs)
    const char* backgroundNames[] = {/* "Display Name", "svg_name", */
                                        "&Black",        "black",
                                        "&Dark Grey",    "dimgrey",
                                        "&Light Grey",   "lightgrey",
                                        "&White",        "white" };
    for(size_t i = 0; i < sizeof(backgroundNames)/sizeof(const char*); i+=2)
    {
        QAction* backgroundAct = backMenu->addAction(tr(backgroundNames[i]));
        mapper->setMapping(backgroundAct, backgroundNames[i+1]);
        connect(backgroundAct, SIGNAL(triggered()), mapper, SLOT(map()));
    }
    connect(mapper, SIGNAL(mapped(QString)),
            this, SLOT(setBackground(QString)));
    backMenu->addSeparator();
    QAction* backgroundCustom = backMenu->addAction(tr("&Custom"));
    connect(backgroundCustom, SIGNAL(triggered()),
            this, SLOT(chooseBackground()));

    // Help menu
    QMenu* helpMenu = menuBar()->addMenu(tr("&Help"));
    QAction* helpAct = helpMenu->addAction(tr("&Controls"));
    connect(helpAct, SIGNAL(triggered()), this, SLOT(helpDialog()));
    helpMenu->addSeparator();
    QAction* aboutAct = helpMenu->addAction(tr("&About"));
    connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutDialog()));

    //--------------------------------------------------
    // Point viewer
    m_pointView = new PointView(this);
    setCentralWidget(m_pointView);
    connect(drawBoundingBoxes, SIGNAL(triggered()),
            m_pointView, SLOT(toggleDrawBoundingBoxes()));
    connect(trackballMode, SIGNAL(triggered()),
            m_pointView, SLOT(toggleCameraMode()));
    connect(m_pointView, SIGNAL(pointFilesLoaded(QStringList)),
            this, SLOT(setLoadedFileNames(QStringList)));
    connect(&m_pointView->shaderProgram(), SIGNAL(paramsChanged()),
            this, SLOT(setupShaderParamUI()));

    //--------------------------------------------------
    // Docked widgets
    // Shader parameters UI
    QDockWidget* shaderParamsDock = new QDockWidget(tr("Shader Parameters"), this);
    shaderParamsDock->setFeatures(QDockWidget::DockWidgetMovable |
                                  QDockWidget::DockWidgetClosable);
    shaderParamsDock->setAllowedAreas(Qt::LeftDockWidgetArea |
                                      Qt::RightDockWidgetArea);
    m_shaderParamsUI = new QWidget(shaderParamsDock);
    shaderParamsDock->setWidget(m_shaderParamsUI);

    // Shader editor UI
    QDockWidget* shaderEditorDock = new QDockWidget(tr("Shader Editor"), this);
    shaderEditorDock->setFeatures(QDockWidget::DockWidgetMovable |
                                  QDockWidget::DockWidgetClosable);
    shaderEditorDock->setAllowedAreas(Qt::LeftDockWidgetArea |
                                      Qt::RightDockWidgetArea);
    QWidget* shaderEditorUI = new QWidget(shaderEditorDock);
    QGridLayout* shaderEditorLayout = new QGridLayout(shaderEditorUI);
    shaderEditorLayout->setContentsMargins(2,2,2,2);
    QTabWidget* shaderTabs = new QTabWidget(shaderEditorUI);
    shaderEditorLayout->addWidget(shaderTabs, 0, 0);
    // vertex shader
    ShaderEditor* vertexShaderEditor = new ShaderEditor(shaderTabs);
    shaderTabs->addTab(vertexShaderEditor, tr("Vertex Shader"));
    connect(vertexShaderEditor, SIGNAL(sendShader(QString)),
            &m_pointView->shaderProgram(), SLOT(setVertexShader(QString)));
    // fragment shader
    ShaderEditor* fragmentShaderEditor = new ShaderEditor(shaderTabs);
    shaderTabs->addTab(fragmentShaderEditor, tr("Fragment Shader"));
    connect(fragmentShaderEditor, SIGNAL(sendShader(QString)),
            &m_pointView->shaderProgram(), SLOT(setFragmentShader(QString)));
    shaderEditorDock->setWidget(shaderEditorUI);

    // Log viewer UI
    QDockWidget* logDock = new QDockWidget(tr("Log"), this);
    logDock->setFeatures(QDockWidget::DockWidgetMovable |
                         QDockWidget::DockWidgetClosable);
    logDock->setAllowedAreas(Qt::AllDockWidgetAreas);
    m_logTextView = new QPlainTextEdit(logDock);
    m_logTextView->setReadOnly(true);
    m_logTextView->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
    //m_logTextView->setLineWrapMode(QPlainTextEdit::NoWrap);
    logDock->setWidget(m_logTextView);

    // Set up docked widgets
    addDockWidget(Qt::RightDockWidgetArea, shaderParamsDock);
    addDockWidget(Qt::RightDockWidgetArea, shaderEditorDock);
    addDockWidget(Qt::RightDockWidgetArea, logDock);
    //tabifyDockWidget(shaderParamsDock, shaderEditorDock);
    shaderEditorDock->setVisible(false);

    // Add dock widget toggles to view menu
    viewMenu->addSeparator();
    viewMenu->addAction(shaderParamsDock->toggleViewAction());
    viewMenu->addAction(shaderEditorDock->toggleViewAction());
    viewMenu->addAction(logDock->toggleViewAction());

    // Set shaders
    QFile vertexShaderFile(":/points_v.glsl");
    if (vertexShaderFile.open(QIODevice::ReadOnly))
        m_pointView->shaderProgram().setVertexShader(vertexShaderFile.readAll());
    QFile fragmentShaderFile(":/points_f.glsl");
    if (fragmentShaderFile.open(QIODevice::ReadOnly))
        m_pointView->shaderProgram().setFragmentShader(fragmentShaderFile.readAll());
    vertexShaderEditor->setPlainText(m_pointView->shaderProgram().vertexShader());
    fragmentShaderEditor->setPlainText(m_pointView->shaderProgram().fragmentShader());

    if(!initialPointFileNames.empty())
        m_pointView->loadPointFiles(initialPointFileNames);
}

PointViewerMainWindow::~PointViewerMainWindow()
{
    if (m_oldBuf)
        std::cout.rdbuf(m_oldBuf);
}

void PointViewerMainWindow::setupShaderParamUI()
{
    while (QWidget* child = m_shaderParamsUI->findChild<QWidget*>())
        delete child;
    delete m_shaderParamsUI->layout();
    m_pointView->shaderProgram().setupParameterUI(m_shaderParamsUI);
}

QSize PointViewerMainWindow::sizeHint() const
{
    return QSize(800,600);
}

void PointViewerMainWindow::captureStdout()
{
    m_oldBuf = std::cout.rdbuf();
    m_guiStdoutBuf.reset(new StreamBufTextEditSink(m_logTextView));
    std::cout.rdbuf(m_guiStdoutBuf.get());
}

void PointViewerMainWindow::keyReleaseEvent(QKeyEvent* event)
{
    if(event->key() == Qt::Key_Escape)
        close();
}

void PointViewerMainWindow::openFiles()
{
    QFileDialog dialog(this, tr("Select one or more point clouds to open"));
    dialog.setNameFilter(tr("Point cloud files (*.las *.laz)"));
    dialog.setFileMode(QFileDialog::ExistingFiles);
    dialog.setDirectory(m_currFileDir);
    if(dialog.exec())
    {
        QStringList files = dialog.selectedFiles();
        m_pointView->loadPointFiles(files);
    }
    m_currFileDir = dialog.directory();
}

void PointViewerMainWindow::reloadFiles()
{
    m_pointView->reloadPointFiles();
}

void PointViewerMainWindow::helpDialog()
{
    QString message = tr(
        "

Displaz 3D window controls

"
        "<list>"
        "
LMB+drag = rotate camera
"
        "
RMB+drag = zoom camera
"
        "
Ctrl+LMB+drag = move 3D cursor
"
        "
Ctrl+RMB+drag = zoom 3D cursor along view direction
"
        "
'c' = center camera on 3D cursor
"
        "
's' = snap 3D cursor to nearest point
"
        "</list>"
        "
(LMB, RMB = left & right mouse buttons)
"
    );
    QMessageBox::information(this, tr("Displaz control summary"), message);
}

void PointViewerMainWindow::aboutDialog()
{
    QString message = tr("Displaz - a qt-based las viewer\nversion 0.0.1");
    QMessageBox::information(this, tr("About displaz"), message);
}

void PointViewerMainWindow::setBackground(const QString& name)
{
    m_pointView->setBackground(QColor(name));
}

void PointViewerMainWindow::chooseBackground()
{
    m_pointView->setBackground(
        QColorDialog::getColor(QColor(255,255,255), this, "background color"));
}

void PointViewerMainWindow::setLoadedFileNames(const QStringList& fileNames)
{
    setWindowTitle(tr("Displaz - %1").arg(fileNames.join(", ")));
}

<|endoftext|>


<commit_before>#include "general.hpp"
#include "course.hpp"
#include "student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses(string filename) {
	ifstream infile(filename.c_str());
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
}

void readData() {
	loadCourses("data/2012-13-s2.csv");
	loadCourses("data/2012-13-interim.csv");
	loadCourses("data/2012-13-s1.csv");

	loadCourses("data/2011-12-s2.csv");
	loadCourses("data/2011-12-interim.csv");
	loadCourses("data/2011-12-s1.csv");

	loadCourses("data/2010-11-s2.csv");
	loadCourses("data/2010-11-interim.csv");
	loadCourses("data/2010-11-s1.csv");
}

vector<string> parseArguments(int argc, const char* argv[]) {
//	cout << argc << endl;
	vector<string> arguments;
	for (int i = 1; i < argc; i++) {
//		cout << argv[i] << endl;
		arguments.push_back(argv[i]);
	}
	return arguments;
}

int main(int argc, const char *argv[]) {
	vector<string> arguments = parseArguments(argc, argv);
	readData();

	if (arguments.size() > 0) {
		string arg0 = arguments.at(0);
		if (arg0 == "--find" || arg0 == "-f") {
			if (arguments.size() == 2) {
				Course c = Course(arguments.at(1));
				c.display();
			}
		}

		else if (arg0 == "--load" || arg0 == "-l") {
			if (arguments.size() == 2) {
				user = Student(arguments.at(1));
				user.display();
			}
		}

		else if (arg0 == "--demo") {
			user = Student("data/example.txt");
			user.display();
		}

		else if (arg0 == "--stress") {
			user = Student("data/stress.txt");
			user.display();
		}

		else if (arg0 == "--debug") {
			for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c) {
				if (c->getProfessor()[1] == ' ')
					if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
						cout << *c << endl;
				if (c->getDepartment(0) == NONE)
					cout << *c << endl;
			}
		}

		else if (arg0 == "--interactive" || arg0 == "-i") {
			string name, yearS = "", yearE = "", majors;
			cout << "Welcome!" << endl;
			cout << "What is your name? ";
			getline(cin, name);
			cout << "What year do you graduate? ";
			getline(cin, yearE);
			cout << "What are your majors (ex. CSCI, ASIAN) ";
			getline(cin, majors);
			user = Student(name, yearS, yearE, majors);

			string courses;
			cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
			getline(cin, courses);
			user.addCourses(courses);

			user.display();
		}
	}
	else {
		cout << "This program works best if you give it some data ;)" << endl;
		cout << "However, we have some example stuff to show you anyway." << endl;
		user = Student("data/example.txt");
		user.display();
	}

	return 0;
}
<commit_msg>Acknowledge that the users have moved in test-data<commit_after>#include "general.hpp"
#include "course.hpp"
#include "student.hpp"
using namespace std;

vector<Course> all_courses;
Student user;

void loadCourses(string filename) {
	ifstream infile(filename.c_str());
	string str; // read in the header line
	getline(infile, str);
	while (infile.peek() != -1){
		Course incourse(infile);
		all_courses.push_back(incourse);
		// cout << incourse << endl;
	}
}

void readData() {
	loadCourses("data/2012-13-s2.csv");
	loadCourses("data/2012-13-interim.csv");
	loadCourses("data/2012-13-s1.csv");

	loadCourses("data/2011-12-s2.csv");
	loadCourses("data/2011-12-interim.csv");
	loadCourses("data/2011-12-s1.csv");

	loadCourses("data/2010-11-s2.csv");
	loadCourses("data/2010-11-interim.csv");
	loadCourses("data/2010-11-s1.csv");
}

vector<string> parseArguments(int argc, const char* argv[]) {
//	cout << argc << endl;
	vector<string> arguments;
	for (int i = 1; i < argc; i++) {
//		cout << argv[i] << endl;
		arguments.push_back(argv[i]);
	}
	return arguments;
}

int main(int argc, const char *argv[]) {
	vector<string> arguments = parseArguments(argc, argv);
	readData();

	if (arguments.size() > 0) {
		string arg0 = arguments.at(0);
		if (arg0 == "--find" || arg0 == "-f") {
			if (arguments.size() == 2) {
				Course c = Course(arguments.at(1));
				c.display();
			}
		}

		else if (arg0 == "--load" || arg0 == "-l") {
			if (arguments.size() == 2) {
				user = Student(arguments.at(1));
				user.display();
			}
		}

		else if (arg0 == "--demo") {
			user = Student("data/example.txt");
			user.display();
		}

		else if (arg0 == "--stress") {
			user = Student("data/stress.txt");
			user.display();
		}

		else if (arg0 == "--debug") {
			for (vector<Course>::iterator c = all_courses.begin(); c != all_courses.end(); ++c) {
				if (c->getProfessor()[1] == ' ')
					if (c->getProfessor()[2] == '0' || c->getProfessor()[2] == '1')
						cout << *c << endl;
				if (c->getDepartment(0) == NONE)
					cout << *c << endl;
			}
		}

		else if (arg0 == "--interactive" || arg0 == "-i") {
			string name, yearS = "", yearE = "", majors;
			cout << "Welcome!" << endl;
			cout << "What is your name? ";
			getline(cin, name);
			cout << "What year do you graduate? ";
			getline(cin, yearE);
			cout << "What are your majors (ex. CSCI, ASIAN) ";
			getline(cin, majors);
			user = Student(name, yearS, yearE, majors);

			string courses;
			cout << "What are some courses that you have taken? (ex. CSCI125, STAT 110)" << endl;
			getline(cin, courses);
			user.addCourses(courses);

			user.display();
		}
	}
	else {
		cout << "This program works best if you give it some data ;)" << endl;
		cout << "However, we have some example stuff to show you anyway." << endl;
		user = Student("users/example.txt");
		user.display();
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <string.h>
#include <sys/time.h>

#include "API.h"

using namespace java::lang;
using namespace java::io;
using namespace java::util;

int main(int,char**)
{
	JavaVM* vm;
    void* envPtr;
    JavaVMInitArgs vm_args;
    memset(&vm_args, 0, sizeof(vm_args));

    char classPath[] = {"-Djava.class.path=../build"};

    JavaVMOption options[1];
    options[0].optionString = classPath;

    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.version = JNI_VERSION_1_6;
	JNI_CreateJavaVM(&vm, &envPtr, &vm_args);

	JNIEnv* env = (JNIEnv*)envPtr;

	jni::Initialize(*vm);

	// ------------------------------------------------------------------------
	// System.out.println("Hello world");
	// ------------------------------------------------------------------------

	// pure JNI
	{
		jstring   helloWorldString             = env->NewStringUTF("RAW");
		jclass    javaLangSystem               = env->FindClass("java/lang/System");
		jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
		jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
		jobject   javaLangSystem_out           = env->GetStaticObjectField(javaLangSystem, javaLangSystem_outFID);
		jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
		env->CallVoidMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
	}

	// JNI.h
	jni::Errno error;
	{
		jni::Initialize(*vm);
		if ((env = jni::AttachCurrentThread()))
		{
			jni::LocalFrame frame;
			jstring   helloWorldString             = env->NewStringUTF("JNI");
			jclass    javaLangSystem               = env->FindClass("java/lang/System");
			jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
			jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
			jobject   javaLangSystem_out           = env->GetStaticObjectField(javaLangSystem, javaLangSystem_outFID);
			jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
			env->CallVoidMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
			if ((error = jni::CheckError()))
				printf("JNI %s\n", jni::GetErrorMessage());
		}
	}

	// Ops.h
	{
		jni::LocalFrame frame;
		jstring   helloWorldString             = env->NewStringUTF("Ops");
		jclass    javaLangSystem               = env->FindClass("java/lang/System");
		jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
		jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
		jobject   javaLangSystem_out           = jni::Op<jobject>::GetStaticField(javaLangSystem, javaLangSystem_outFID);
		jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
		jni::Op<jvoid>::CallMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
		if ((error = jni::CheckError()))
			printf("Ops %d:%s\n", error, jni::GetErrorMessage());
	}

	{
		System::fOut().Println("Api");
	}

	// ------------------------------------------------------------------------
	// import java.io.PrintStream;
	// import java.util.Properties;
	// import java.util.Enumerator;
	//
	// PrintStream out       = System.out;
	// Properties properties = System.getPropertes();
	// Enumerator keys       = properties.keys();
	// while (keys.hasMoreElements())
	//     out.println(properties.getProperty((String)keys.next()));
	// ------------------------------------------------------------------------
	timeval start, stop;

	// Optimized version
	gettimeofday(&start, NULL);
	{
		jni::LocalFrame frame;
		PrintStream out       = System::fOut();
		Properties properties = System::GetProperties();
		Enumeration keys       = properties.Keys();
		while (keys.HasMoreElements())
			out.Println(properties.GetProperty(jni::Cast<String>(keys.NextElement())));
	}
	gettimeofday(&stop, NULL);
    printf("%f ms.\n", (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

    // -------------------------------------------------------------
    // Proxy test
    // -------------------------------------------------------------
    if (!jni::Proxy::__Register())
    	printf("%s\n", jni::GetErrorMessage());

	struct PretendRunnable : Runnable::Proxy
	{
		virtual void Run() {printf("%s\n", "hello world!!!!"); }
	};

    PretendRunnable pretendRunnable;
    Runnable runnable = pretendRunnable;

    Thread     thread(pretendRunnable);
    thread.Start();
    thread.Join();

    runnable.Run();

    // Make sure we don't get crashes from deleting the native object.
    PretendRunnable* pretendRunnable2 = new PretendRunnable;
    Runnable runnable2 = *pretendRunnable2;
    runnable2.Run();
    delete pretendRunnable2;
    runnable2.Run(); // <-- should not log anything

    // -------------------------------------------------------------
    // Performance
    // -------------------------------------------------------------
	struct PerformanceRunnable : Runnable::Proxy
	{
		int i;
		PerformanceRunnable() : i(0) {}
		virtual void Run() {  ++i; }
	};
	PerformanceRunnable* perfRunner = new PerformanceRunnable;
	Runnable perfRunnable = *perfRunner;
	gettimeofday(&start, NULL);
	for (int i = 0; i < 1024; ++i)
		perfRunnable.Run();
	gettimeofday(&stop, NULL);
    printf("count: %d, time: %f ms.\n", perfRunner->i, (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

    delete perfRunner;
	gettimeofday(&start, NULL);
	for (int i = 0; i < 1024; ++i)
		perfRunnable.Run();
	gettimeofday(&stop, NULL);
    printf("count: %d, time: %f ms.\n", 1024, (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

	struct KillMePleazeRunnable : Runnable::Proxy
	{
		KillMePleazeRunnable() : Runnable::Proxy(jni::kProxyWeaklyReferenced) { }
		virtual ~KillMePleazeRunnable() { printf("%s\n", "KillMePleazeRunnable");}
		virtual void Run() { }
	};

	{
		jni::LocalFrame frame;
		KillMePleazeRunnable* killMeRunnable = new KillMePleazeRunnable;
	}
	for (int i = 0; i < 32; ++i) // Do a couple of loops to massage the GC
	{
		jni::LocalFrame frame;
		jni::Array<int> array(1024*1024);
		System::Gc();
	}

	java::lang::CharSequence string = "hello world";
	printf("%s\n", static_cast<const char*>(string));

    printf("%s\n", "EOP");

    // print resolution of clock()
	jni::DetachCurrentThread();

	vm->DestroyJavaVM();
	return 0;
}
<commit_msg>fixed indentation in Test.cpp and added makefile<commit_after>#include <stdlib.h>
#include <string.h>
#include <sys/time.h>

#include "API.h"

using namespace java::lang;
using namespace java::io;
using namespace java::util;

int main(int,char**)
{
	JavaVM* vm;
	void* envPtr;
	JavaVMInitArgs vm_args;
	memset(&vm_args, 0, sizeof(vm_args));

	char classPath[] = {"-Djava.class.path=../build"};

	JavaVMOption options[1];
	options[0].optionString = classPath;

	vm_args.options = options;
	vm_args.nOptions = 1;
	vm_args.version = JNI_VERSION_1_6;
	JNI_CreateJavaVM(&vm, &envPtr, &vm_args);

	JNIEnv* env = (JNIEnv*)envPtr;

	jni::Initialize(*vm);

	// ------------------------------------------------------------------------
	// System.out.println("Hello world");
	// ------------------------------------------------------------------------

	// pure JNI
	{
		jstring   helloWorldString             = env->NewStringUTF("RAW");
		jclass    javaLangSystem               = env->FindClass("java/lang/System");
		jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
		jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
		jobject   javaLangSystem_out           = env->GetStaticObjectField(javaLangSystem, javaLangSystem_outFID);
		jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
		env->CallVoidMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
	}

	// JNI.h
	jni::Errno error;
	{
		jni::Initialize(*vm);
		if ((env = jni::AttachCurrentThread()))
		{
			jni::LocalFrame frame;
			jstring   helloWorldString             = env->NewStringUTF("JNI");
			jclass    javaLangSystem               = env->FindClass("java/lang/System");
			jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
			jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
			jobject   javaLangSystem_out           = env->GetStaticObjectField(javaLangSystem, javaLangSystem_outFID);
			jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
			env->CallVoidMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
			if ((error = jni::CheckError()))
				printf("JNI %s\n", jni::GetErrorMessage());
		}
	}

	// Ops.h
	{
		jni::LocalFrame frame;
		jstring   helloWorldString             = env->NewStringUTF("Ops");
		jclass    javaLangSystem               = env->FindClass("java/lang/System");
		jclass    javaIoPrintStream            = env->FindClass("java/io/PrintStream");
		jfieldID  javaLangSystem_outFID        = env->GetStaticFieldID(javaLangSystem, "out", "Ljava/io/PrintStream;");
		jobject   javaLangSystem_out           = jni::Op<jobject>::GetStaticField(javaLangSystem, javaLangSystem_outFID);
		jmethodID javaIoPrintStream_printlnMID = env->GetMethodID(javaIoPrintStream, "println", "(Ljava/lang/String;)V");
		jni::Op<jvoid>::CallMethod(javaLangSystem_out, javaIoPrintStream_printlnMID, helloWorldString);
		if ((error = jni::CheckError()))
			printf("Ops %d:%s\n", error, jni::GetErrorMessage());
	}

	{
		System::fOut().Println("Api");
	}

	// ------------------------------------------------------------------------
	// import java.io.PrintStream;
	// import java.util.Properties;
	// import java.util.Enumerator;
	//
	// PrintStream out       = System.out;
	// Properties properties = System.getPropertes();
	// Enumerator keys       = properties.keys();
	// while (keys.hasMoreElements())
	//     out.println(properties.getProperty((String)keys.next()));
	// ------------------------------------------------------------------------
	timeval start, stop;

	// Optimized version
	gettimeofday(&start, NULL);
	{
		jni::LocalFrame frame;
		PrintStream out       = System::fOut();
		Properties properties = System::GetProperties();
		Enumeration keys       = properties.Keys();
		while (keys.HasMoreElements())
			out.Println(properties.GetProperty(jni::Cast<String>(keys.NextElement())));
	}
	gettimeofday(&stop, NULL);
	printf("%f ms.\n", (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

	// -------------------------------------------------------------
	// Proxy test
	// -------------------------------------------------------------
	if (!jni::Proxy::__Register())
		printf("%s\n", jni::GetErrorMessage());

	struct PretendRunnable : Runnable::Proxy
	{
		virtual void Run() {printf("%s\n", "hello world!!!!"); }
	};

	PretendRunnable pretendRunnable;
	Runnable runnable = pretendRunnable;

	Thread     thread(pretendRunnable);
	thread.Start();
	thread.Join();

	runnable.Run();

	// Make sure we don't get crashes from deleting the native object.
	PretendRunnable* pretendRunnable2 = new PretendRunnable;
	Runnable runnable2 = *pretendRunnable2;
	runnable2.Run();
	delete pretendRunnable2;
	runnable2.Run(); // <-- should not log anything

	// -------------------------------------------------------------
	// Performance
	// -------------------------------------------------------------
	struct PerformanceRunnable : Runnable::Proxy
	{
		int i;
		PerformanceRunnable() : i(0) {}
		virtual void Run() {  ++i; }
	};
	PerformanceRunnable* perfRunner = new PerformanceRunnable;
	Runnable perfRunnable = *perfRunner;
	gettimeofday(&start, NULL);
	for (int i = 0; i < 1024; ++i)
		perfRunnable.Run();
	gettimeofday(&stop, NULL);
	printf("count: %d, time: %f ms.\n", perfRunner->i, (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

	delete perfRunner;
	gettimeofday(&start, NULL);
	for (int i = 0; i < 1024; ++i)
		perfRunnable.Run();
	gettimeofday(&stop, NULL);
	printf("count: %d, time: %f ms.\n", 1024, (stop.tv_sec - start.tv_sec) * 1000.0 + (stop.tv_usec - start.tv_usec) / 1000.0);

	struct KillMePleazeRunnable : Runnable::Proxy
	{
		KillMePleazeRunnable() : Runnable::Proxy(jni::kProxyWeaklyReferenced) { }
		virtual ~KillMePleazeRunnable() { printf("%s\n", "KillMePleazeRunnable");}
		virtual void Run() { }
	};

	{
		jni::LocalFrame frame;
		KillMePleazeRunnable* killMeRunnable = new KillMePleazeRunnable;
	}
	for (int i = 0; i < 32; ++i) // Do a couple of loops to massage the GC
	{
		jni::LocalFrame frame;
		jni::Array<int> array(1024*1024);
		System::Gc();
	}

	java::lang::CharSequence string = "hello world";
	printf("%s\n", static_cast<const char*>(string));

	printf("%s\n", "EOP");

	// print resolution of clock()
	jni::DetachCurrentThread();

	vm->DestroyJavaVM();
	return 0;
}
<|endoftext|>


<commit_before>/* Rapicorn
 * Copyright (C) 2008 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "testutils.hh"

#include <glib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

#define VERBOSE_TAG     100

namespace Rapicorn {
namespace Test {

static clockid_t bench_time_clockid = CLOCK_REALTIME;
static double    bench_time_resolution = 0.000001;      // 1µs resolution assumed for gettimeofday

Timer::Timer (double deadline_in_secs) :
  m_deadline (deadline_in_secs), m_test_duration (0), m_n_runs (0)
{
#if defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
  static bool initialized = false;
  if (once_enter (&initialized))
    {
      struct timespec tp = { 0, 0 };
      // CLOCK_MONOTONIC_RAW cannot slew, but doesn't measure SI seconds accurately
      // CLOCK_MONOTONIC may slew, but attempts to accurately measure SI seconds
#ifdef CLOCK_MONOTONIC
      if (bench_time_clockid == CLOCK_REALTIME && clock_getres (CLOCK_MONOTONIC, &tp) >= 0)
        bench_time_resolution = tp.tv_sec + tp.tv_nsec / 1000000000.0, bench_time_clockid = CLOCK_MONOTONIC;
#endif
      // CLOCK_REALTIME may slew and jump
      if (bench_time_clockid == CLOCK_REALTIME && clock_getres (bench_time_clockid, &tp) >= 0)
        bench_time_resolution = tp.tv_sec + tp.tv_nsec / 1000000000.0, bench_time_clockid = CLOCK_REALTIME;
      once_leave (&initialized, true);
    }
#endif // _POSIX_C_SOURCE
}

Timer::~Timer ()
{}

double
Timer::bench_time ()
{
#if defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
  struct timespec tp = { 0, 0 };
  if (ISLIKELY (clock_gettime (bench_time_clockid, &tp) >= 0))
    {
      double stamp = tp.tv_sec;
      stamp += tp.tv_nsec / 1000000000.0;
      return stamp;
    }
#endif // _POSIX_C_SOURCE
  uint64 ustamp = timestamp_now();
  return ustamp / 1000000.0;
}

int64
Timer::loops_needed () const
{
  if (m_samples.size() < 7)
    return m_n_runs + 1;        // force significant number of test runs
  const double deadline = MAX (m_deadline == 0.0 ? 0.005 : m_deadline, bench_time_resolution * 10000.0);
  if (m_test_duration > deadline * 0.5)
    return 0;                   // time for testing exceeded
  // we double the number of tests per run, to gain more accuracy: 0+1, 1+1, 3+1, 7+1, ...
  return m_n_runs + 1;
}

void
Timer::reset()
{
  m_samples.resize (0);
  m_test_duration = 0;
  m_n_runs = 0;
}

void
Timer::submit (double elapsed,
               int64  repetitions)
{
  m_test_duration += elapsed;
  m_n_runs += repetitions;
  if (elapsed >= bench_time_resolution * 100.0) // force error below 1%
    m_samples.push_back (elapsed / repetitions);
}

double
Timer::min_elapsed () const
{
  double m = DBL_MAX;
  for (size_t i = 0; i < m_samples.size(); i++)
    m = MIN (m, m_samples[i]);
  return m;
}

double
Timer::max_elapsed () const
{
  double m = 0;
  for (size_t i = 0; i < m_samples.size(); i++)
    m = MAX (m, m_samples[i]);
  return m;
}

static String
ensure_newline (const String &s)
{
  if (s.size() && s[s.size()-1] != '\n')
    return s + "\n";
  return s;
}

static __thread char *test_warning = NULL;
static __thread char *test_start = NULL;

void
test_output (int kind, const char *format, ...)
{
  va_list args;
  va_start (args, format);
  String msg = string_vprintf (format, args);
  va_end (args);
  String sout, bar;
  switch (verbose() ? VERBOSE_TAG + kind : kind)
    {
    case 1:                     // test message
    case 1 + VERBOSE_TAG:       // test message
      sout = ensure_newline (msg);
      break;
    case 2:                     // conditional test info
      break;
    case 2 + VERBOSE_TAG:       // conditional test info
      sout = ensure_newline (msg);
      break;
    case 3:                     // test program title
      sout = "RUN:  " + ensure_newline (msg);
      break;
    case 3 + VERBOSE_TAG:       // test program title
      bar = "### ** +--" + String (msg.size(), '-') + "--+ ** ###";
      msg = "### ** +  " + msg + "  + ** ###";
      sout = "\n" + bar + "\n" + msg + "\n" + bar + "\n";
      break;
    case 4:                     // test start
      sout = "  TEST   " + msg + ":" + String (63 - MIN (63, msg.size()), ' ');
      if (!test_start)
        {
          test_start = strdup (sout.c_str());
          sout = "";
        }
      break;
    case 4 + VERBOSE_TAG:       // test start
      sout = "\n## Testing: " + msg + "...\n";
      break;
    case 5:                     // test done
      if (test_start)
        {
          sout = test_start;
          free (test_start);
          test_start = NULL;
        }
      else
        sout = "";
      if (test_warning)
        {
          String w (test_warning);
          free (test_warning);
          test_warning = NULL;
          sout += "WARN\n" + ensure_newline (w);
        }
      else
        sout += "OK\n";
      break;
    case 5 + VERBOSE_TAG:       // test done
      break;
    case 6:                     // test warning
      {
        String w;
        if (test_warning)
          {
            w = test_warning;
            free (test_warning);
          }
        test_warning = strdup ((w + ensure_newline (msg)).c_str());
      }
      break;
    case 6 + VERBOSE_TAG:       // test warning
      sout = "WARNING: " + ensure_newline (msg);
      break;
    default:
    case 0 + VERBOSE_TAG:       // regular msg
    case 0:                     // regular msg
      sout = msg;
      break;
    }
  fflush (stdout);
  fputs (sout.c_str(), stderr);
  fflush (stderr);
}

static vector<void(*)(void*)> testfuncs;
static vector<void*>          testdatas;
static vector<String>         testnames;

void
add_internal (const String &testname,
              void        (*test_func) (void*),
              void         *data)
{
  testnames.push_back (testname);
  testfuncs.push_back ((void(*)(void*)) test_func);
  testdatas.push_back ((void*) data);
}

void
add (const String &testname,
     void        (*test_func) (void))
{
  add (testname, (void(*)(void*)) test_func, (void*) 0);
}

int
run (void)
{
  for (uint i = 0; i < testfuncs.size(); i++)
    {
      TSTART ("%s", testnames[i].c_str());
      testfuncs[i] (testdatas[i]);
      TDONE();
    }
  return 0;
}

bool
verbose (void)
{
  return init_settings().test_verbose;
}

bool
quick (void)
{
  return init_settings().test_quick;
}

bool
slow (void)
{
  return init_settings().test_slow;
}

bool
thorough (void)
{
  return init_settings().test_slow;
}

bool
perf (void)
{
  return init_settings().test_perf;
}

char
rand_bit (void)
{
  return 0 != (rand_int() & (1 << 15));
}

int32
rand_int (void)
{
  return g_random_int(); // g_test_rand_int();
}

int32
rand_int_range (int32 begin,
                int32 end)
{
  return g_random_int_range (begin, end); // g_test_rand_int_range()
}

double
test_rand_double (void)
{
  return g_random_double(); // g_test_rand_double()
}

double
test_rand_double_range (double range_start,
                        double range_end)
{
  return g_random_double_range (range_start, range_end); // g_test_rand_double_range()
}

} // Test
} // Rapicorn

namespace Rapicorn {
static bool verbose_init = false;

void
rapicorn_init_logtest (int *argc, char **argv)
{
  verbose_init = true;
  rapicorn_init_test (argc, argv);
}

void
rapicorn_init_test (int   *argc,
                    char **argv)
{
  /* check that NULL is defined to __null in C++ on 64bit */
  RAPICORN_ASSERT (sizeof (NULL) == sizeof (void*));
  /* normal initialization */
  RapicornInitValue ivalues[] = {
    { "stand-alone", "true" },
    { "test-verbose", verbose_init ? "true" : "false" },
    { "rapicorn-test-parse-args", "true" },
    { NULL }
  };
  rapicorn_init_core (argc, argv, NULL, ivalues); // FIXME: argv
  unsigned int flags = g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
  g_log_set_always_fatal ((GLogLevelFlags) (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
  Logging::override_config ("fatal-warnings");
  CPUInfo ci = cpu_info();
  if (init_settings().test_perf)
    g_printerr ("PERF: %s\n", g_get_prgname());
  else
    TTITLE ("%s", argv[0]);
}
} // Rapicorn
<commit_msg>RCORE: minor rewording upon test start<commit_after>/* Rapicorn
 * Copyright (C) 2008 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * A copy of the GNU Lesser General Public License should ship along
 * with this library; if not, see http://www.gnu.org/copyleft/.
 */
#include "testutils.hh"

#include <glib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

#define VERBOSE_TAG     100

namespace Rapicorn {
namespace Test {

static clockid_t bench_time_clockid = CLOCK_REALTIME;
static double    bench_time_resolution = 0.000001;      // 1µs resolution assumed for gettimeofday

Timer::Timer (double deadline_in_secs) :
  m_deadline (deadline_in_secs), m_test_duration (0), m_n_runs (0)
{
#if defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
  static bool initialized = false;
  if (once_enter (&initialized))
    {
      struct timespec tp = { 0, 0 };
      // CLOCK_MONOTONIC_RAW cannot slew, but doesn't measure SI seconds accurately
      // CLOCK_MONOTONIC may slew, but attempts to accurately measure SI seconds
#ifdef CLOCK_MONOTONIC
      if (bench_time_clockid == CLOCK_REALTIME && clock_getres (CLOCK_MONOTONIC, &tp) >= 0)
        bench_time_resolution = tp.tv_sec + tp.tv_nsec / 1000000000.0, bench_time_clockid = CLOCK_MONOTONIC;
#endif
      // CLOCK_REALTIME may slew and jump
      if (bench_time_clockid == CLOCK_REALTIME && clock_getres (bench_time_clockid, &tp) >= 0)
        bench_time_resolution = tp.tv_sec + tp.tv_nsec / 1000000000.0, bench_time_clockid = CLOCK_REALTIME;
      once_leave (&initialized, true);
    }
#endif // _POSIX_C_SOURCE
}

Timer::~Timer ()
{}

double
Timer::bench_time ()
{
#if defined (_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
  struct timespec tp = { 0, 0 };
  if (ISLIKELY (clock_gettime (bench_time_clockid, &tp) >= 0))
    {
      double stamp = tp.tv_sec;
      stamp += tp.tv_nsec / 1000000000.0;
      return stamp;
    }
#endif // _POSIX_C_SOURCE
  uint64 ustamp = timestamp_now();
  return ustamp / 1000000.0;
}

int64
Timer::loops_needed () const
{
  if (m_samples.size() < 7)
    return m_n_runs + 1;        // force significant number of test runs
  const double deadline = MAX (m_deadline == 0.0 ? 0.005 : m_deadline, bench_time_resolution * 10000.0);
  if (m_test_duration > deadline * 0.5)
    return 0;                   // time for testing exceeded
  // we double the number of tests per run, to gain more accuracy: 0+1, 1+1, 3+1, 7+1, ...
  return m_n_runs + 1;
}

void
Timer::reset()
{
  m_samples.resize (0);
  m_test_duration = 0;
  m_n_runs = 0;
}

void
Timer::submit (double elapsed,
               int64  repetitions)
{
  m_test_duration += elapsed;
  m_n_runs += repetitions;
  if (elapsed >= bench_time_resolution * 100.0) // force error below 1%
    m_samples.push_back (elapsed / repetitions);
}

double
Timer::min_elapsed () const
{
  double m = DBL_MAX;
  for (size_t i = 0; i < m_samples.size(); i++)
    m = MIN (m, m_samples[i]);
  return m;
}

double
Timer::max_elapsed () const
{
  double m = 0;
  for (size_t i = 0; i < m_samples.size(); i++)
    m = MAX (m, m_samples[i]);
  return m;
}

static String
ensure_newline (const String &s)
{
  if (s.size() && s[s.size()-1] != '\n')
    return s + "\n";
  return s;
}

static __thread char *test_warning = NULL;
static __thread char *test_start = NULL;

void
test_output (int kind, const char *format, ...)
{
  va_list args;
  va_start (args, format);
  String msg = string_vprintf (format, args);
  va_end (args);
  String sout, bar;
  switch (verbose() ? VERBOSE_TAG + kind : kind)
    {
    case 1:                     // test message
    case 1 + VERBOSE_TAG:       // test message
      sout = ensure_newline (msg);
      break;
    case 2:                     // conditional test info
      break;
    case 2 + VERBOSE_TAG:       // conditional test info
      sout = ensure_newline (msg);
      break;
    case 3:                     // test program title
      sout = "START:   " + ensure_newline (msg);
      break;
    case 3 + VERBOSE_TAG:       // test program title
      bar = "### ** +--" + String (msg.size(), '-') + "--+ ** ###";
      msg = "### ** +  " + msg + "  + ** ###";
      sout = "\n" + bar + "\n" + msg + "\n" + bar + "\n";
      break;
    case 4:                     // test start
      sout = "  TEST   " + msg + ":" + String (63 - MIN (63, msg.size()), ' ');
      if (!test_start)
        {
          test_start = strdup (sout.c_str());
          sout = "";
        }
      break;
    case 4 + VERBOSE_TAG:       // test start
      sout = "\n## Testing: " + msg + "...\n";
      break;
    case 5:                     // test done
      if (test_start)
        {
          sout = test_start;
          free (test_start);
          test_start = NULL;
        }
      else
        sout = "";
      if (test_warning)
        {
          String w (test_warning);
          free (test_warning);
          test_warning = NULL;
          sout += "WARN\n" + ensure_newline (w);
        }
      else
        sout += "OK\n";
      break;
    case 5 + VERBOSE_TAG:       // test done
      break;
    case 6:                     // test warning
      {
        String w;
        if (test_warning)
          {
            w = test_warning;
            free (test_warning);
          }
        test_warning = strdup ((w + ensure_newline (msg)).c_str());
      }
      break;
    case 6 + VERBOSE_TAG:       // test warning
      sout = "WARNING: " + ensure_newline (msg);
      break;
    default:
    case 0 + VERBOSE_TAG:       // regular msg
    case 0:                     // regular msg
      sout = msg;
      break;
    }
  fflush (stdout);
  fputs (sout.c_str(), stderr);
  fflush (stderr);
}

static vector<void(*)(void*)> testfuncs;
static vector<void*>          testdatas;
static vector<String>         testnames;

void
add_internal (const String &testname,
              void        (*test_func) (void*),
              void         *data)
{
  testnames.push_back (testname);
  testfuncs.push_back ((void(*)(void*)) test_func);
  testdatas.push_back ((void*) data);
}

void
add (const String &testname,
     void        (*test_func) (void))
{
  add (testname, (void(*)(void*)) test_func, (void*) 0);
}

int
run (void)
{
  for (uint i = 0; i < testfuncs.size(); i++)
    {
      TSTART ("%s", testnames[i].c_str());
      testfuncs[i] (testdatas[i]);
      TDONE();
    }
  return 0;
}

bool
verbose (void)
{
  return init_settings().test_verbose;
}

bool
quick (void)
{
  return init_settings().test_quick;
}

bool
slow (void)
{
  return init_settings().test_slow;
}

bool
thorough (void)
{
  return init_settings().test_slow;
}

bool
perf (void)
{
  return init_settings().test_perf;
}

char
rand_bit (void)
{
  return 0 != (rand_int() & (1 << 15));
}

int32
rand_int (void)
{
  return g_random_int(); // g_test_rand_int();
}

int32
rand_int_range (int32 begin,
                int32 end)
{
  return g_random_int_range (begin, end); // g_test_rand_int_range()
}

double
test_rand_double (void)
{
  return g_random_double(); // g_test_rand_double()
}

double
test_rand_double_range (double range_start,
                        double range_end)
{
  return g_random_double_range (range_start, range_end); // g_test_rand_double_range()
}

} // Test
} // Rapicorn

namespace Rapicorn {
static bool verbose_init = false;

void
rapicorn_init_logtest (int *argc, char **argv)
{
  verbose_init = true;
  rapicorn_init_test (argc, argv);
}

void
rapicorn_init_test (int   *argc,
                    char **argv)
{
  /* check that NULL is defined to __null in C++ on 64bit */
  RAPICORN_ASSERT (sizeof (NULL) == sizeof (void*));
  /* normal initialization */
  RapicornInitValue ivalues[] = {
    { "stand-alone", "true" },
    { "test-verbose", verbose_init ? "true" : "false" },
    { "rapicorn-test-parse-args", "true" },
    { NULL }
  };
  rapicorn_init_core (argc, argv, NULL, ivalues); // FIXME: argv
  unsigned int flags = g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
  g_log_set_always_fatal ((GLogLevelFlags) (flags | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL));
  Logging::override_config ("fatal-warnings");
  CPUInfo ci = cpu_info();
  if (init_settings().test_perf)
    g_printerr ("PERF: %s\n", g_get_prgname());
  else
    TTITLE ("%s", argv[0]);
}
} // Rapicorn
<|endoftext|>


<commit_before>#ifndef STAN_MATH_OPENCL_OPENCL
#define STAN_MATH_OPENCL_OPENCL
#ifdef STAN_OPENCL

#include <stan/math/opencl/opencl_context.hpp>
#include <stan/math/opencl/matrix_cl.hpp>
#include <stan/math/opencl/add.hpp>
#include <stan/math/opencl/copy.hpp>
#include <stan/math/opencl/copy_triangular.hpp>
#include <stan/math/opencl/cholesky_decompose.hpp>
#include <stan/math/opencl/diagonal_multiply.hpp>
#include <stan/math/opencl/identity.hpp>
#include <stan/math/opencl/tri_inverse.hpp>
#include <stan/math/opencl/multiply.hpp>
#include <stan/math/opencl/multiply_transpose.hpp>
#include <stan/math/opencl/sub_block.hpp>
#include <stan/math/opencl/subtract.hpp>
#include <stan/math/opencl/triangular_transpose.hpp>
#include <stan/math/opencl/transpose.hpp>
#include <stan/math/opencl/zeros.hpp>

#endif
#endif
<commit_msg>Fix headers<commit_after>#ifndef STAN_MATH_OPENCL_OPENCL
#define STAN_MATH_OPENCL_OPENCL
#ifdef STAN_OPENCL

#include <stan/math/opencl/opencl_context.hpp>
#include <stan/math/opencl/matrix_cl.hpp>
#include <stan/math/opencl/add.hpp>
#include <stan/math/opencl/copy.hpp>
#include <stan/math/opencl/copy_triangular.hpp>
#include <stan/math/opencl/cholesky_decompose.hpp>
#include <stan/math/opencl/diagonal_multiply.hpp>
#include <stan/math/opencl/identity.hpp>
#include <stan/math/opencl/tri_inverse.hpp>
#include <stan/math/opencl/multiply.hpp>
#include <stan/math/opencl/multiply_transpose.hpp>
#include <stan/math/opencl/sub_block.hpp>
#include <stan/math/opencl/subtract.hpp>
#include <stan/math/opencl/triangular_transpose.hpp>
#include <stan/math/opencl/transpose.hpp>
#include <stan/math/opencl/zeros.hpp>

#include <stan/math/opencl/err/check_diagonal_zeros.hpp>
#include <stan/math/opencl/err/check_matching_dims.hpp>
#include <stan/math/opencl/err/check_nan.hpp>
#include <stan/math/opencl/err/check_opencl.hpp>
#include <stan/math/opencl/err/check_square.hpp>
#include <stan/math/opencl/err/check_symmetric.hpp>
#endif
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation;
 * either version 2 of the License, or (at your option) any later
 * version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "kio_adb.h"

#include "kio_adb_debug.h"

#include <QUrl>
#include <QString>
#include <QDateTime>
#include <QByteArray>
#include <QProcess>
#include <QRegularExpression>

using namespace KIO;

extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
{
    if (argc != 4) {
        fprintf(stderr, "Usage: kio_adb protocol domain-socket1 domain-socket2\n");
        exit(-1);
    }

    AdbProtocol slave(argv[2], argv[3]);
    slave.dispatchLoop();

    return 0;
}

AdbProtocol::AdbProtocol(const QByteArray &pool, const QByteArray &app) :
    KIO::SlaveBase(QByteArrayLiteral("adb"), pool, app)
{

}

AdbProtocol::~AdbProtocol()
{

}

void AdbProtocol::stat(const QUrl &url)
{
    qCDebug(KIO_ADB) << "stat:" << url;

    finished();
}

void AdbProtocol::get(const QUrl &url)
{
    qCDebug(KIO_ADB) << "get:" << url;

    finished();
}

void AdbProtocol::put(const QUrl &url, int mode, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "put:" << url << mode << flags;

    finished();
}

void AdbProtocol::copy(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "copy:" << src << dest << mode << flags;

    finished();
}

void AdbProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "rename:" << src << dest << flags;

    finished();
}

void AdbProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "symlink:" << target << dest << flags;

    finished();
}

void AdbProtocol::chmod(const QUrl &url, int permissions)
{
    qCDebug(KIO_ADB) << "chmod:" << url << permissions;

    finished();
}

void AdbProtocol::chown(const QUrl &url, const QString &owner, const QString &group)
{
    qCDebug(KIO_ADB) << "chown:" << url << owner << group;

    finished();
}

void AdbProtocol::setModificationTime(const QUrl &url, const QDateTime &mtime)
{
    qCDebug(KIO_ADB) << "setModificationTime:" << url << mtime;

    finished();
}

void AdbProtocol::del(const QUrl &url, bool isfile)
{
    qCDebug(KIO_ADB) << "del:" << url << isfile;

    finished();
}

void AdbProtocol::listDir(const QUrl &url)
{
    qCDebug(KIO_ADB) << "listDir:" << url;

    const QString device = url.authority();
    const QString path = url.path();

    if (device.isEmpty()) {
        listDevices();
    } else if (path.isEmpty()) {
        QUrl targetUrl = url;
        targetUrl.setPath("/");
        redirection(targetUrl);

        finished();
    } else {
        // TODO list files/folders

        finished();
    }
}

void AdbProtocol::mkdir(const QUrl &url, int permissions)
{
    qCDebug(KIO_ADB) << "mkdir:" << url << permissions;

    finished();
}

void AdbProtocol::virtual_hook(int id, void *data)
{
    switch(id) {
        case SlaveBase::GetFileSystemFreeSpace: {
            QUrl *url = static_cast<QUrl *>(data);
            fileSystemFreeSpace(*url);
        }   break;
        default:
            SlaveBase::virtual_hook(id, data);
    }
}

void AdbProtocol::fileSystemFreeSpace(const QUrl &url)
{
    qCDebug(KIO_ADB) << "fileSystemFreeSpace:" << url;

    finished();
}

void AdbProtocol::listDevices()
{
    qCDebug(KIO_ADB) << "listDevices";

    QProcess process;
    process.setProgram(QLatin1String("adb"));
    process.setArguments({"devices", "-l"});
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.start();

    process.waitForFinished();
    const QString data = process.readAll();
    const QStringList lines = data.split(QLatin1Char('\n'), QString::SkipEmptyParts);

    static QRegularExpression re("^(?<id>\\S+)\\s+"
                                 "device\\s+"
                                 "(usb:(?<usb>\\S+)\\s+)?"
                                 "product:(?<product>\\w+)\\s+"
                                 "model:(?<model>\\w+)\\s+"
                                 "device:(?<device>\\w+)$",
                                 QRegularExpression::OptimizeOnFirstUsageOption);

    foreach (const QString &line, lines) {
        const auto match = re.match(line); // TODO try to use globalMatch instead
        if (!match.hasMatch()) {
            continue;
        }

        QUrl url;
        url.setScheme(QLatin1String("adb"));
        url.setAuthority(match.captured("id"));
        url.setPath("/");

        UDSEntry entry;
        entry.insert(UDSEntry::UDS_URL, url.url());
        entry.insert(UDSEntry::UDS_NAME, match.captured("model"));
        entry.insert(UDSEntry::UDS_ICON_NAME, QLatin1String("smartphone"));
        entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR);
        entry.insert(UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH);
        entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));

        listEntry(entry);
    }

    finished();
}
<commit_msg>List files and folders<commit_after>/*
 * Copyright (C) 2015 by Emmanuel Pescosta <emmanuelpescosta099@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation;
 * either version 2 of the License, or (at your option) any later
 * version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "kio_adb.h"

#include "kio_adb_debug.h"

#include <QUrl>
#include <QString>
#include <QDateTime>
#include <QByteArray>
#include <QProcess>
#include <QRegularExpression>

using namespace KIO;

extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
{
    if (argc != 4) {
        fprintf(stderr, "Usage: kio_adb protocol domain-socket1 domain-socket2\n");
        exit(-1);
    }

    AdbProtocol slave(argv[2], argv[3]);
    slave.dispatchLoop();

    return 0;
}

AdbProtocol::AdbProtocol(const QByteArray &pool, const QByteArray &app) :
    KIO::SlaveBase(QByteArrayLiteral("adb"), pool, app)
{

}

AdbProtocol::~AdbProtocol()
{

}

void AdbProtocol::stat(const QUrl &url)
{
    qCDebug(KIO_ADB) << "stat:" << url;

    finished();
}

void AdbProtocol::get(const QUrl &url)
{
    qCDebug(KIO_ADB) << "get:" << url;

    finished();
}

void AdbProtocol::put(const QUrl &url, int mode, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "put:" << url << mode << flags;

    finished();
}

void AdbProtocol::copy(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "copy:" << src << dest << mode << flags;

    finished();
}

void AdbProtocol::rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "rename:" << src << dest << flags;

    finished();
}

void AdbProtocol::symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags)
{
    qCDebug(KIO_ADB) << "symlink:" << target << dest << flags;

    finished();
}

void AdbProtocol::chmod(const QUrl &url, int permissions)
{
    qCDebug(KIO_ADB) << "chmod:" << url << permissions;

    finished();
}

void AdbProtocol::chown(const QUrl &url, const QString &owner, const QString &group)
{
    qCDebug(KIO_ADB) << "chown:" << url << owner << group;

    finished();
}

void AdbProtocol::setModificationTime(const QUrl &url, const QDateTime &mtime)
{
    qCDebug(KIO_ADB) << "setModificationTime:" << url << mtime;

    finished();
}

void AdbProtocol::del(const QUrl &url, bool isfile)
{
    qCDebug(KIO_ADB) << "del:" << url << isfile;

    finished();
}

void AdbProtocol::listDir(const QUrl &url)
{
    qCDebug(KIO_ADB) << "listDir:" << url;

    const QString device = url.authority();
    const QString path = url.path();

    if (device.isEmpty()) {
        listDevices();
    } else if (path.isEmpty()) {
        QUrl targetUrl = url;
        targetUrl.setPath("/");
        redirection(targetUrl);

        finished();
    } else {
        QProcess process;
        process.setProgram(QLatin1String("adb"));
        process.setArguments({"-s", device, "shell", "ls", "-l", "-a", path});
        process.setProcessChannelMode(QProcess::MergedChannels);
        process.start();

        process.waitForFinished();
        const QString data = process.readAll();
        const QStringList lines = data.split(QLatin1Char('\n'), QString::SkipEmptyParts);

        static QRegularExpression re("^(?<type>[\\-dlcbps])"
                                     "(?<permission>[\\-rwxsStT]{9})\\s+"
                                     "(?<owner>\\w+)\\s+"
                                     "(?<group>\\w+)\\s+"
                                     "((?<size>\\d+)\\s+)?"
                                     "(?<datetime>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2})\\s+"
                                     "(?<name>.+)\\s$",
                                     QRegularExpression::OptimizeOnFirstUsageOption);

        foreach (const QString &line, lines) {
            const auto match = re.match(line); // TODO try to use globalMatch instead
            if (!match.hasMatch()) {
                continue;
            }

            const auto parsePermission = [](const QString &permissionStr) -> int {
                if (permissionStr.size() != 9) {
                    return 0;
                }

                const auto parsePermissionChar = [](char c, int r, int w, int x, int s) -> int {
                    switch (c) {
                        case 'r':
                            return r;
                        case 'w':
                            return w;
                        case 'x':
                            return x;
                        case 't':
                            return x | S_ISVTX;
                        case 'T':
                            return S_ISVTX;
                        case 's':
                            return x | s;
                        case 'S':
                            return s;
                        case '-':
                        default:
                            return 0;
                    }
                };

                int permissions = 0;

                permissions |= parsePermissionChar(permissionStr[0].toLatin1(), S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID);
                permissions |= parsePermissionChar(permissionStr[1].toLatin1(), S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID);
                permissions |= parsePermissionChar(permissionStr[2].toLatin1(), S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID);

                permissions |= parsePermissionChar(permissionStr[3].toLatin1(), S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID);
                permissions |= parsePermissionChar(permissionStr[4].toLatin1(), S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID);
                permissions |= parsePermissionChar(permissionStr[5].toLatin1(), S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID);

                permissions |= parsePermissionChar(permissionStr[6].toLatin1(), S_IROTH, S_IWOTH, S_IXOTH, 0);
                permissions |= parsePermissionChar(permissionStr[7].toLatin1(), S_IROTH, S_IWOTH, S_IXOTH, 0);
                permissions |= parsePermissionChar(permissionStr[8].toLatin1(), S_IROTH, S_IWOTH, S_IXOTH, 0);

                return permissions;
            };

            UDSEntry entry;

            const QDateTime modificationTime = QDateTime::fromString(match.captured("datetime"), "yyyy-MM-dd HH:mm");
            entry.insert(UDSEntry::UDS_MODIFICATION_TIME, modificationTime.toTime_t());

            entry.insert(UDSEntry::UDS_USER, match.captured("owner"));
            entry.insert(UDSEntry::UDS_GROUP, match.captured("group"));
            entry.insert(UDSEntry::UDS_SIZE, match.captured("size").toULongLong());
            entry.insert(UDSEntry::UDS_ACCESS, parsePermission(match.captured("permission")));
            entry.insert(UDSEntry::UDS_NAME, match.captured("name"));

            const QChar type = match.captured("type")[0];
            if (type == QLatin1Char('-')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFREG);
            } else if (type == QLatin1Char('d')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR);
                entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));
            } else if (type == QLatin1Char('l')) {
                const QStringList nameParts = match.captured("name").split(QLatin1String(" -> "));
                const auto name = nameParts[0];
                const auto linkDest = nameParts[1];

                QUrl targetUrl = url;
                targetUrl.setPath(linkDest);

                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR); // S_IFLNK
                entry.insert(UDSEntry::UDS_URL, targetUrl.url());
                entry.insert(UDSEntry::UDS_LINK_DEST, linkDest);
                entry.insert(UDSEntry::UDS_NAME, name);
            } else if (type == QLatin1Char('c')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFCHR);
            } else if (type == QLatin1Char('b')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFBLK);
            } else if (type == QLatin1Char('p')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFIFO);
            } else if (type == QLatin1Char('s')) {
                entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFSOCK);
            }

            listEntry(entry);
        }

        finished();
    }
}

void AdbProtocol::mkdir(const QUrl &url, int permissions)
{
    qCDebug(KIO_ADB) << "mkdir:" << url << permissions;

    finished();
}

void AdbProtocol::virtual_hook(int id, void *data)
{
    switch(id) {
        case SlaveBase::GetFileSystemFreeSpace: {
            QUrl *url = static_cast<QUrl *>(data);
            fileSystemFreeSpace(*url);
        }   break;
        default:
            SlaveBase::virtual_hook(id, data);
    }
}

void AdbProtocol::fileSystemFreeSpace(const QUrl &url)
{
    qCDebug(KIO_ADB) << "fileSystemFreeSpace:" << url;

    finished();
}

void AdbProtocol::listDevices()
{
    qCDebug(KIO_ADB) << "listDevices";

    QProcess process;
    process.setProgram(QLatin1String("adb"));
    process.setArguments({"devices", "-l"});
    process.setProcessChannelMode(QProcess::MergedChannels);
    process.start();

    process.waitForFinished();
    const QString data = process.readAll();
    const QStringList lines = data.split(QLatin1Char('\n'), QString::SkipEmptyParts);

    static QRegularExpression re("^(?<id>\\S+)\\s+"
                                 "device\\s+"
                                 "(usb:(?<usb>\\S+)\\s+)?"
                                 "product:(?<product>\\w+)\\s+"
                                 "model:(?<model>\\w+)\\s+"
                                 "device:(?<device>\\w+)$",
                                 QRegularExpression::OptimizeOnFirstUsageOption);

    foreach (const QString &line, lines) {
        const auto match = re.match(line); // TODO try to use globalMatch instead
        if (!match.hasMatch()) {
            continue;
        }

        QUrl url;
        url.setScheme(QLatin1String("adb"));
        url.setAuthority(match.captured("id"));
        url.setPath("/");

        UDSEntry entry;
        entry.insert(UDSEntry::UDS_URL, url.url());
        entry.insert(UDSEntry::UDS_NAME, match.captured("model"));
        entry.insert(UDSEntry::UDS_ICON_NAME, QLatin1String("smartphone"));
        entry.insert(UDSEntry::UDS_FILE_TYPE, S_IFDIR);
        entry.insert(UDSEntry::UDS_ACCESS, S_IRUSR | S_IRGRP | S_IROTH);
        entry.insert(UDSEntry::UDS_MIME_TYPE, QLatin1String("inode/directory"));

        listEntry(entry);
    }

    finished();
}
<|endoftext|>


<commit_before>//===- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp -------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Atoms.h"
#include "GroupedSectionsPass.h"
#include "IdataPass.h"
#include "LinkerGeneratedSymbolFile.h"

#include "lld/Core/PassManager.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Path.h"

#include <bitset>
#include <set>

namespace lld {

namespace {} // anonymous namespace

bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
  if (_stackReserve < _stackCommit) {
    diagnostics << "Invalid stack size: reserve size must be equal to or "
                << "greater than commit size, but got " << _stackCommit
                << " and " << _stackReserve << ".\n";
    return false;
  }

  if (_heapReserve < _heapCommit) {
    diagnostics << "Invalid heap size: reserve size must be equal to or "
                << "greater than commit size, but got " << _heapCommit
                << " and " << _heapReserve << ".\n";
    return false;
  }

  // It's an error if the base address is not multiple of 64K.
  if (_baseAddress & 0xffff) {
    diagnostics << "Base address have to be multiple of 64K, but got "
                << _baseAddress << "\n";
    return false;
  }

  std::bitset<64> alignment(_sectionDefaultAlignment);
  if (alignment.count() != 1) {
    diagnostics << "Section alignment must be a power of 2, but got "
                << _sectionDefaultAlignment << "\n";
    return false;
  }

  // Architectures other than i386 is not supported yet.
  if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) {
    diagnostics << "Machine type other than x86 is not supported.\n";
    return false;
  }

  _reader = createReaderPECOFF(*this);
  _writer = createWriterPECOFF(*this);
  return true;
}

std::unique_ptr<File> PECOFFLinkingContext::createEntrySymbolFile() const {
  if (entrySymbolName().empty())
    return nullptr;
  std::unique_ptr<SimpleFile> entryFile(
      new SimpleFile(*this, "command line option /entry"));
  entryFile->addAtom(
      *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
  return std::move(entryFile);
}

std::unique_ptr<File> PECOFFLinkingContext::createUndefinedSymbolFile() const {
  if (_initialUndefinedSymbols.empty())
    return nullptr;
  std::unique_ptr<SimpleFile> undefinedSymFile(
      new SimpleFile(*this, "command line option /c (or) /include"));
  for (auto undefSymStr : _initialUndefinedSymbols)
    undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
                                   *undefinedSymFile, undefSymStr)));
  return std::move(undefinedSymFile);
}

bool PECOFFLinkingContext::createImplicitFiles(
    std::vector<std::unique_ptr<File> > &) const {
  std::unique_ptr<SimpleFileNode> fileNode(
      new SimpleFileNode("Implicit Files"));
  std::unique_ptr<File> linkerGeneratedSymFile(
      new coff::LinkerGeneratedSymbolFile(*this));
  fileNode->appendInputFile(std::move(linkerGeneratedSymFile));
  inputGraph().insertOneElementAt(std::move(fileNode),
                                  InputGraph::Position::END);
  return true;
}

/// Returns the section name in the resulting executable.
///
/// Sections in object files are usually output to the executable with the same
/// name, but you can rename by command line option. /merge:from=to makes the
/// linker to combine "from" section contents to "to" section in the
/// executable. We have a mapping for the renaming. This method looks up the
/// table and returns a new section name if renamed.
StringRef
PECOFFLinkingContext::getFinalSectionName(StringRef sectionName) const {
  auto it = _renamedSections.find(sectionName);
  if (it == _renamedSections.end())
    return sectionName;
  return getFinalSectionName(it->second);
}

/// Adds a mapping to the section renaming table. This method will be used for
/// /merge command line option.
bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics,
                                              StringRef from, StringRef to) {
  auto it = _renamedSections.find(from);
  if (it != _renamedSections.end()) {
    if (it->second == to)
      // There's already the same mapping.
      return true;
    diagnostics << "Section \"" << from << "\" is already mapped to \""
                << it->second << ", so it cannot be mapped to \"" << to << "\".";
    return true;
  }

  // Add a mapping, and check if there's no cycle in the renaming mapping. The
  // cycle detection algorithm we use here is naive, but that's OK because the
  // number of mapping is usually less than 10.
  _renamedSections[from] = to;
  for (auto elem : _renamedSections) {
    StringRef sectionName = elem.first;
    std::set<StringRef> visited;
    visited.insert(sectionName);
    for (;;) {
      auto pos = _renamedSections.find(sectionName);
      if (pos == _renamedSections.end())
        break;
      if (visited.count(pos->second)) {
        diagnostics << "/merge:" << from << "=" << to << " makes a cycle";
        return false;
      }
      sectionName = pos->second;
      visited.insert(sectionName);
    }
  }
  return true;
}

/// Try to find the input library file from the search paths and append it to
/// the input file list. Returns true if the library file is found.
StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const {
  // Current directory always takes precedence over the search paths.
  if (llvm::sys::path::is_absolute(filename) || llvm::sys::fs::exists(filename))
    return filename;
  // Iterate over the search paths.
  for (StringRef dir : _inputSearchPaths) {
    SmallString<128> path = dir;
    llvm::sys::path::append(path, filename);
    if (llvm::sys::fs::exists(path.str()))
      return allocateString(path.str());
  }
  return filename;
}

Writer &PECOFFLinkingContext::writer() const { return *_writer; }

ErrorOr<Reference::Kind>
PECOFFLinkingContext::relocKindFromString(StringRef str) const {
#define LLD_CASE(name) .Case(#name, llvm::COFF::name)
  int32_t ret = llvm::StringSwitch<int32_t>(str)
        LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
        LLD_CASE(IMAGE_REL_I386_DIR32)
        LLD_CASE(IMAGE_REL_I386_DIR32NB)
        LLD_CASE(IMAGE_REL_I386_REL32)
        .Default(-1);
#undef LLD_CASE
  if (ret == -1)
    return make_error_code(YamlReaderError::illegal_value);
  return ret;
}

ErrorOr<std::string>
PECOFFLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
  switch (kind) {
#define LLD_CASE(name)                          \
    case llvm::COFF::name:                      \
      return std::string(#name);

    LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
    LLD_CASE(IMAGE_REL_I386_DIR32)
    LLD_CASE(IMAGE_REL_I386_DIR32NB)
    LLD_CASE(IMAGE_REL_I386_REL32)
#undef LLD_CASE
  }
  return make_error_code(YamlReaderError::illegal_value);
}

void PECOFFLinkingContext::addPasses(PassManager &pm) {
  pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
  pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
  pm.add(std::unique_ptr<Pass>(new LayoutPass()));
}
} // end namespace lld
<commit_msg>Remove empty namespace.<commit_after>//===- lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp -------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Atoms.h"
#include "GroupedSectionsPass.h"
#include "IdataPass.h"
#include "LinkerGeneratedSymbolFile.h"

#include "lld/Core/PassManager.h"
#include "lld/Passes/LayoutPass.h"
#include "lld/Passes/RoundTripNativePass.h"
#include "lld/Passes/RoundTripYAMLPass.h"
#include "lld/ReaderWriter/PECOFFLinkingContext.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Simple.h"
#include "lld/ReaderWriter/Writer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Path.h"

#include <bitset>
#include <set>

namespace lld {

bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
  if (_stackReserve < _stackCommit) {
    diagnostics << "Invalid stack size: reserve size must be equal to or "
                << "greater than commit size, but got " << _stackCommit
                << " and " << _stackReserve << ".\n";
    return false;
  }

  if (_heapReserve < _heapCommit) {
    diagnostics << "Invalid heap size: reserve size must be equal to or "
                << "greater than commit size, but got " << _heapCommit
                << " and " << _heapReserve << ".\n";
    return false;
  }

  // It's an error if the base address is not multiple of 64K.
  if (_baseAddress & 0xffff) {
    diagnostics << "Base address have to be multiple of 64K, but got "
                << _baseAddress << "\n";
    return false;
  }

  std::bitset<64> alignment(_sectionDefaultAlignment);
  if (alignment.count() != 1) {
    diagnostics << "Section alignment must be a power of 2, but got "
                << _sectionDefaultAlignment << "\n";
    return false;
  }

  // Architectures other than i386 is not supported yet.
  if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) {
    diagnostics << "Machine type other than x86 is not supported.\n";
    return false;
  }

  _reader = createReaderPECOFF(*this);
  _writer = createWriterPECOFF(*this);
  return true;
}

std::unique_ptr<File> PECOFFLinkingContext::createEntrySymbolFile() const {
  if (entrySymbolName().empty())
    return nullptr;
  std::unique_ptr<SimpleFile> entryFile(
      new SimpleFile(*this, "command line option /entry"));
  entryFile->addAtom(
      *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
  return std::move(entryFile);
}

std::unique_ptr<File> PECOFFLinkingContext::createUndefinedSymbolFile() const {
  if (_initialUndefinedSymbols.empty())
    return nullptr;
  std::unique_ptr<SimpleFile> undefinedSymFile(
      new SimpleFile(*this, "command line option /c (or) /include"));
  for (auto undefSymStr : _initialUndefinedSymbols)
    undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
                                   *undefinedSymFile, undefSymStr)));
  return std::move(undefinedSymFile);
}

bool PECOFFLinkingContext::createImplicitFiles(
    std::vector<std::unique_ptr<File> > &) const {
  std::unique_ptr<SimpleFileNode> fileNode(
      new SimpleFileNode("Implicit Files"));
  std::unique_ptr<File> linkerGeneratedSymFile(
      new coff::LinkerGeneratedSymbolFile(*this));
  fileNode->appendInputFile(std::move(linkerGeneratedSymFile));
  inputGraph().insertOneElementAt(std::move(fileNode),
                                  InputGraph::Position::END);
  return true;
}

/// Returns the section name in the resulting executable.
///
/// Sections in object files are usually output to the executable with the same
/// name, but you can rename by command line option. /merge:from=to makes the
/// linker to combine "from" section contents to "to" section in the
/// executable. We have a mapping for the renaming. This method looks up the
/// table and returns a new section name if renamed.
StringRef
PECOFFLinkingContext::getFinalSectionName(StringRef sectionName) const {
  auto it = _renamedSections.find(sectionName);
  if (it == _renamedSections.end())
    return sectionName;
  return getFinalSectionName(it->second);
}

/// Adds a mapping to the section renaming table. This method will be used for
/// /merge command line option.
bool PECOFFLinkingContext::addSectionRenaming(raw_ostream &diagnostics,
                                              StringRef from, StringRef to) {
  auto it = _renamedSections.find(from);
  if (it != _renamedSections.end()) {
    if (it->second == to)
      // There's already the same mapping.
      return true;
    diagnostics << "Section \"" << from << "\" is already mapped to \""
                << it->second << ", so it cannot be mapped to \"" << to << "\".";
    return true;
  }

  // Add a mapping, and check if there's no cycle in the renaming mapping. The
  // cycle detection algorithm we use here is naive, but that's OK because the
  // number of mapping is usually less than 10.
  _renamedSections[from] = to;
  for (auto elem : _renamedSections) {
    StringRef sectionName = elem.first;
    std::set<StringRef> visited;
    visited.insert(sectionName);
    for (;;) {
      auto pos = _renamedSections.find(sectionName);
      if (pos == _renamedSections.end())
        break;
      if (visited.count(pos->second)) {
        diagnostics << "/merge:" << from << "=" << to << " makes a cycle";
        return false;
      }
      sectionName = pos->second;
      visited.insert(sectionName);
    }
  }
  return true;
}

/// Try to find the input library file from the search paths and append it to
/// the input file list. Returns true if the library file is found.
StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const {
  // Current directory always takes precedence over the search paths.
  if (llvm::sys::path::is_absolute(filename) || llvm::sys::fs::exists(filename))
    return filename;
  // Iterate over the search paths.
  for (StringRef dir : _inputSearchPaths) {
    SmallString<128> path = dir;
    llvm::sys::path::append(path, filename);
    if (llvm::sys::fs::exists(path.str()))
      return allocateString(path.str());
  }
  return filename;
}

Writer &PECOFFLinkingContext::writer() const { return *_writer; }

ErrorOr<Reference::Kind>
PECOFFLinkingContext::relocKindFromString(StringRef str) const {
#define LLD_CASE(name) .Case(#name, llvm::COFF::name)
  int32_t ret = llvm::StringSwitch<int32_t>(str)
        LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
        LLD_CASE(IMAGE_REL_I386_DIR32)
        LLD_CASE(IMAGE_REL_I386_DIR32NB)
        LLD_CASE(IMAGE_REL_I386_REL32)
        .Default(-1);
#undef LLD_CASE
  if (ret == -1)
    return make_error_code(YamlReaderError::illegal_value);
  return ret;
}

ErrorOr<std::string>
PECOFFLinkingContext::stringFromRelocKind(Reference::Kind kind) const {
  switch (kind) {
#define LLD_CASE(name)                          \
    case llvm::COFF::name:                      \
      return std::string(#name);

    LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
    LLD_CASE(IMAGE_REL_I386_DIR32)
    LLD_CASE(IMAGE_REL_I386_DIR32NB)
    LLD_CASE(IMAGE_REL_I386_REL32)
#undef LLD_CASE
  }
  return make_error_code(YamlReaderError::illegal_value);
}

void PECOFFLinkingContext::addPasses(PassManager &pm) {
  pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
  pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
  pm.add(std::unique_ptr<Pass>(new LayoutPass()));
}
} // end namespace lld
<|endoftext|>


<commit_before>//===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the MCAsmInfoDarwin properties.
//
//===----------------------------------------------------------------------===//

#include "PPCMCAsmInfo.h"
using namespace llvm;

void PPCMCAsmInfoDarwin::anchor() { }

PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
  if (is64Bit)
    PointerSize = 8;
  IsLittleEndian = false;

  PCSymbol = ".";
  CommentString = ";";
  ExceptionsType = ExceptionHandling::DwarfCFI;

  if (!is64Bit)
    Data64bitsDirective = 0;      // We can't emit a 64-bit unit in PPC32 mode.

  AssemblerDialect = 1;           // New-Style mnemonics.
  SupportsDebugInformation= true; // Debug information.
}

void PPCLinuxMCAsmInfo::anchor() { }

PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
  if (is64Bit)
    PointerSize = 8;
  IsLittleEndian = false;

  // ".comm align is in bytes but .align is pow-2."
  AlignmentIsInBytes = false;

  CommentString = "#";
  GlobalPrefix = "";
  PrivateGlobalPrefix = ".L";
  WeakRefDirective = "\t.weak\t";

  // Uses '.section' before '.bss' directive
  UsesELFSectionDirectiveForBSS = true;

  // Debug Information
  SupportsDebugInformation = true;

  PCSymbol = ".";

  // Set up DWARF directives
  HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)

  // Exceptions handling
  if (!is64Bit)
    ExceptionsType = ExceptionHandling::DwarfCFI;

  ZeroDirective = "\t.space\t";
  Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
  AssemblerDialect = 0;           // Old-Style mnemonics.
}

<commit_msg>Enable exceptions handling on PPC64 now that cr misaligned spilling was fixed in r163713.<commit_after>//===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the MCAsmInfoDarwin properties.
//
//===----------------------------------------------------------------------===//

#include "PPCMCAsmInfo.h"
using namespace llvm;

void PPCMCAsmInfoDarwin::anchor() { }

PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
  if (is64Bit)
    PointerSize = 8;
  IsLittleEndian = false;

  PCSymbol = ".";
  CommentString = ";";
  ExceptionsType = ExceptionHandling::DwarfCFI;

  if (!is64Bit)
    Data64bitsDirective = 0;      // We can't emit a 64-bit unit in PPC32 mode.

  AssemblerDialect = 1;           // New-Style mnemonics.
  SupportsDebugInformation= true; // Debug information.
}

void PPCLinuxMCAsmInfo::anchor() { }

PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
  if (is64Bit)
    PointerSize = 8;
  IsLittleEndian = false;

  // ".comm align is in bytes but .align is pow-2."
  AlignmentIsInBytes = false;

  CommentString = "#";
  GlobalPrefix = "";
  PrivateGlobalPrefix = ".L";
  WeakRefDirective = "\t.weak\t";

  // Uses '.section' before '.bss' directive
  UsesELFSectionDirectiveForBSS = true;

  // Debug Information
  SupportsDebugInformation = true;

  PCSymbol = ".";

  // Set up DWARF directives
  HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)

  // Exceptions handling
  ExceptionsType = ExceptionHandling::DwarfCFI;

  ZeroDirective = "\t.space\t";
  Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
  AssemblerDialect = 0;           // Old-Style mnemonics.
}

<|endoftext|>