<commit_before>/******************************************************************************

  This source file is part of the MoleQueue project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

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

******************************************************************************/

#include "localsocketconnection.h"

#include <QtCore/QDateTime>
#include <QtCore/QTimer>
#include <QtCore/QDataStream>
#include <QtNetwork/QLocalSocket>

namespace MoleQueue
{

LocalSocketConnection::LocalSocketConnection(QObject *parentObject,
                                             QLocalSocket *socket)
  : Connection(parentObject),
    m_connectionString(socket->serverName()),
    m_socket(NULL),
    m_dataStream(new QDataStream),
    m_holdRequests(true)
{
  setSocket(socket);
}

LocalSocketConnection::LocalSocketConnection(QObject *parentObject,
                                             const QString &serverName)
  : Connection(parentObject),
    m_connectionString(serverName),
    m_socket(NULL),
    m_dataStream(new QDataStream),
    m_holdRequests(true)
{
  setSocket(new QLocalSocket);
}

LocalSocketConnection::~LocalSocketConnection()
{
  // Make sure we are closed
  close();

  delete m_socket;
  m_socket = NULL;

  delete m_dataStream;
  m_dataStream = NULL;

}

void LocalSocketConnection::setSocket(QLocalSocket *socket)
{
  if (m_socket != NULL) {
    m_socket->abort();
    m_socket->disconnect(this);
    disconnect(m_socket);
    m_socket->deleteLater();
  }
  if (socket != NULL) {
    connect(socket, SIGNAL(readyRead()),
            this, SLOT(readSocket()));
    connect(socket, SIGNAL(disconnected()),
            this, SIGNAL(disconnected()));
    connect(socket, SIGNAL(destroyed()),
            this, SLOT(socketDestroyed()));
  }
  m_dataStream->setDevice(socket);
  m_dataStream->setVersion(QDataStream::Qt_4_8);
  m_socket = socket;
}

void LocalSocketConnection::readSocket()
{
  if(!m_socket->isValid())
    return;

  if (m_holdRequests)
    return;

  if (m_socket->bytesAvailable() == 0)
    return;

  PacketType packet;
  (*m_dataStream) >> packet;

  emit packetReceived(packet, EndpointIdType());

  // Check again in 50 ms if no more data is available, or immediately if there
  // is. This helps ensure that burst traffic is handled robustly.
  QTimer::singleShot(m_socket->bytesAvailable() > 0 ? 0 : 50,
                     this, SLOT(readSocket()));
}

void LocalSocketConnection::open()
{
  if (m_socket) {
    if(isOpen()) {
      qWarning() << "Socket already connected to" << m_connectionString;
      return;
    }

    m_socket->connectToServer(m_connectionString);
  }
  else {
    qWarning() << "No socket set, connection not opened.";
  }
}

void LocalSocketConnection::start()
{
  if (m_socket) {
    m_holdRequests = false;
    while (m_socket->bytesAvailable() != 0)
      readSocket();
  }
}

void LocalSocketConnection::close()
{
  if(m_socket) {
    if(m_socket->isOpen()) {
      m_socket->disconnectFromServer();
      m_socket->close();
    }
  }
}

bool  LocalSocketConnection::isOpen()
{
  return m_socket != NULL && m_socket->isOpen();
}

QString LocalSocketConnection::connectionString() const
{
  return m_connectionString;
}

bool LocalSocketConnection::send(const PacketType &packet,
                                 const EndpointIdType &endpoint)
{
  Q_UNUSED(endpoint);
  (*m_dataStream) << packet;

  return true;
}

void LocalSocketConnection::flush()
{
  m_socket->flush();
}

void LocalSocketConnection::socketDestroyed()
{
  // Set to NULL so we know we don't need to clean up
  m_socket = NULL;
  // Tell anyone listening we have been disconnected.
  emit disconnected();
}

} /* namespace MoleQueue */
<commit_msg>Fixed an rpc sending bug for Windows and Qt 5.8<commit_after>/******************************************************************************

  This source file is part of the MoleQueue project.

  Copyright 2012 Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

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

******************************************************************************/

#include "localsocketconnection.h"

#include <QtCore/QDateTime>
#include <QtCore/QTimer>
#include <QtCore/QDataStream>
#include <QtNetwork/QLocalSocket>

namespace MoleQueue
{

LocalSocketConnection::LocalSocketConnection(QObject *parentObject,
                                             QLocalSocket *socket)
  : Connection(parentObject),
    m_connectionString(socket->serverName()),
    m_socket(NULL),
    m_dataStream(new QDataStream),
    m_holdRequests(true)
{
  setSocket(socket);
}

LocalSocketConnection::LocalSocketConnection(QObject *parentObject,
                                             const QString &serverName)
  : Connection(parentObject),
    m_connectionString(serverName),
    m_socket(NULL),
    m_dataStream(new QDataStream),
    m_holdRequests(true)
{
  setSocket(new QLocalSocket);
}

LocalSocketConnection::~LocalSocketConnection()
{
  // Make sure we are closed
  close();

  delete m_socket;
  m_socket = NULL;

  delete m_dataStream;
  m_dataStream = NULL;

}

void LocalSocketConnection::setSocket(QLocalSocket *socket)
{
  if (m_socket != NULL) {
    m_socket->abort();
    m_socket->disconnect(this);
    disconnect(m_socket);
    m_socket->deleteLater();
  }
  if (socket != NULL) {
    connect(socket, SIGNAL(readyRead()),
            this, SLOT(readSocket()));
    connect(socket, SIGNAL(disconnected()),
            this, SIGNAL(disconnected()));
    connect(socket, SIGNAL(destroyed()),
            this, SLOT(socketDestroyed()));
  }
  m_dataStream->setDevice(socket);
  m_dataStream->setVersion(QDataStream::Qt_4_8);
  m_socket = socket;
}

void LocalSocketConnection::readSocket()
{
  if(!m_socket->isValid())
    return;

  if (m_holdRequests)
    return;

  if (m_socket->bytesAvailable() == 0)
    return;

  PacketType packet;
  (*m_dataStream) >> packet;

  emit packetReceived(packet, EndpointIdType());

  // Check again in 50 ms if no more data is available, or immediately if there
  // is. This helps ensure that burst traffic is handled robustly.
  QTimer::singleShot(m_socket->bytesAvailable() > 0 ? 0 : 50,
                     this, SLOT(readSocket()));
}

void LocalSocketConnection::open()
{
  if (m_socket) {
    if(isOpen()) {
      qWarning() << "Socket already connected to" << m_connectionString;
      return;
    }

    m_socket->connectToServer(m_connectionString);
  }
  else {
    qWarning() << "No socket set, connection not opened.";
  }
}

void LocalSocketConnection::start()
{
  if (m_socket) {
    m_holdRequests = false;
    while (m_socket->bytesAvailable() != 0)
      readSocket();
  }
}

void LocalSocketConnection::close()
{
  if(m_socket) {
    if(m_socket->isOpen()) {
      m_socket->disconnectFromServer();
      m_socket->close();
    }
  }
}

bool  LocalSocketConnection::isOpen()
{
  return m_socket != NULL && m_socket->isOpen();
}

QString LocalSocketConnection::connectionString() const
{
  return m_connectionString;
}

bool LocalSocketConnection::send(const PacketType &packet,
                                 const EndpointIdType &endpoint)
{
  Q_UNUSED(endpoint);

  // Because of a possible bug with Qt 5.8 and 5.9 on Windows,
  // (*m_dataStream) << packet
  // sends two packets instead of one. The packets will fail to get read
  // correctly on the other side of the message. To fix this, we write the
  // message to a byte array and send it in all together as a single raw data
  // packet. If this bug gets fixed in the future, we will not need the
  // Windows section...
  // See https://bugreports.qt.io/browse/QTBUG-61097 for the bug report.
#ifdef _WIN32
  PacketType byteArray;
  QDataStream tmpStream(&byteArray, QIODevice::WriteOnly);
  tmpStream << packet;
  m_dataStream->writeRawData(byteArray, byteArray.size());
#else
  (*m_dataStream) << packet;
#endif

  return true;
}

void LocalSocketConnection::flush()
{
  m_socket->flush();
}

void LocalSocketConnection::socketDestroyed()
{
  // Set to NULL so we know we don't need to clean up
  m_socket = NULL;
  // Tell anyone listening we have been disconnected.
  emit disconnected();
}

} /* namespace MoleQueue */
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

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

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>

#include "frozen_mutation.hh"
#include "schema_builder.hh"
#include "tests/mutation_assertions.hh"

static schema_builder new_table() {
    return { "some_keyspace", "some_table" };
}

static api::timestamp_type new_timestamp() {
    static api::timestamp_type t = 0;
    return t++;
};

static tombstone new_tombstone() {
    return { new_timestamp(), gc_clock::now() };
};

BOOST_AUTO_TEST_CASE(test_writing_and_reading) {
    schema_ptr s = new_table()
        .with_column("pk_col", bytes_type, column_kind::partition_key)
        .with_column("ck_col_1", bytes_type, column_kind::clustering_key)
        .with_column("ck_col_2", bytes_type, column_kind::clustering_key)
        .with_column("regular_col_1", bytes_type)
        .with_column("regular_col_2", bytes_type)
        .with_column("static_col_1", bytes_type, column_kind::static_column)
        .with_column("static_col_2", bytes_type, column_kind::static_column)
        .build();

    partition_key key = partition_key::from_single_value(*s, bytes("key"));
    clustering_key ck1 = clustering_key::from_deeply_exploded(*s, {data_value(bytes("ck1_0")), data_value(bytes("ck1_1"))});
    clustering_key ck2 = clustering_key::from_deeply_exploded(*s, {data_value(bytes("ck2_0")), data_value(bytes("ck2_1"))});
    auto ttl = gc_clock::duration(1);

    auto test_freezing = [] (const mutation& m) {
        assert_that(freeze(m).unfreeze(m.schema())).is_equal_to(m);
    };

    mutation m(key, s);
    m.partition().apply(new_tombstone());

    test_freezing(m);

    m.partition().apply_delete(*s, ck2, new_tombstone());

    test_freezing(m);

    m.partition().apply_row_tombstone(*s, clustering_key_prefix::from_deeply_exploded(*s, {data_value(bytes("ck2_0"))}), new_tombstone());

    test_freezing(m);

    m.set_clustered_cell(ck1, "regular_col_1", data_value(bytes("regular_col_value")), new_timestamp(), ttl);

    test_freezing(m);

    m.set_clustered_cell(ck1, "regular_col_2", data_value(bytes("regular_col_value")), new_timestamp(), ttl);

    test_freezing(m);

    m.partition().apply_insert(*s, ck2, new_timestamp());

    test_freezing(m);

    m.set_clustered_cell(ck2, "regular_col_1", data_value(bytes("ck2_regular_col_1_value")), new_timestamp());

    test_freezing(m);

    m.set_static_cell("static_col_1", data_value(bytes("static_col_value")), new_timestamp(), ttl);

    test_freezing(m);

    m.set_static_cell("static_col_2", data_value(bytes("static_col_value")), new_timestamp());

    test_freezing(m);

    {
        auto fm = freeze(m);
        auto dk = fm.decorated_key(*s);
        BOOST_REQUIRE(dk.equal(*s, m.decorated_key()));
    }
}

BOOST_AUTO_TEST_CASE(test_application_of_partition_view_has_the_same_effect_as_applying_regular_mutation) {
    schema_ptr s = new_table()
        .with_column("pk_col", bytes_type, column_kind::partition_key)
        .with_column("ck_1", bytes_type, column_kind::clustering_key)
        .with_column("reg_1", bytes_type)
        .with_column("reg_2", bytes_type)
        .with_column("static_1", bytes_type, column_kind::static_column)
        .build();

    partition_key key = partition_key::from_single_value(*s, bytes("key"));
    clustering_key ck = clustering_key::from_deeply_exploded(*s, {data_value(bytes("ck"))});

    mutation m1(key, s);
    m1.partition().apply(new_tombstone());
    m1.set_clustered_cell(ck, "reg_1", data_value(bytes("val1")), new_timestamp());
    m1.set_clustered_cell(ck, "reg_2", data_value(bytes("val2")), new_timestamp());
    m1.partition().apply_insert(*s, ck, new_timestamp());
    m1.set_static_cell("static_1", data_value(bytes("val3")), new_timestamp());

    mutation m2(key, s);
    m2.set_clustered_cell(ck, "reg_1", data_value(bytes("val4")), new_timestamp());
    m2.partition().apply_insert(*s, ck, new_timestamp());
    m2.set_static_cell("static_1", data_value(bytes("val5")), new_timestamp());

    mutation m_frozen(key, s);
    m_frozen.partition().apply(*s, freeze(m1).partition());
    m_frozen.partition().apply(*s, freeze(m2).partition());

    mutation m_unfrozen(key, s);
    m_unfrozen.partition().apply(*s, m1.partition());
    m_unfrozen.partition().apply(*s, m2.partition());

    mutation m_refrozen(key, s);
    m_refrozen.partition().apply(*s, freeze(m1).unfreeze(s).partition());
    m_refrozen.partition().apply(*s, freeze(m2).unfreeze(s).partition());

    assert_that(m_unfrozen).is_equal_to(m_refrozen);
    assert_that(m_unfrozen).is_equal_to(m_frozen);
}
<commit_msg>tests: Use mutation generators in frozen_mutation_test<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

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

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE core

#include <boost/test/unit_test.hpp>

#include "frozen_mutation.hh"
#include "schema_builder.hh"
#include "tests/mutation_assertions.hh"
#include "tests/mutation_source_test.hh"

static schema_builder new_table() {
    return { "some_keyspace", "some_table" };
}

static api::timestamp_type new_timestamp() {
    static api::timestamp_type t = 0;
    return t++;
};

static tombstone new_tombstone() {
    return { new_timestamp(), gc_clock::now() };
};

BOOST_AUTO_TEST_CASE(test_writing_and_reading) {
    for_each_mutation([] (const mutation& m) {
        auto frozen = freeze(m);
        BOOST_REQUIRE_EQUAL(frozen.schema_version(), m.schema()->version());
        assert_that(frozen.unfreeze(m.schema())).is_equal_to(m);
        BOOST_REQUIRE(frozen.decorated_key(*m.schema()).equal(*m.schema(), m.decorated_key()));
    });
}

BOOST_AUTO_TEST_CASE(test_application_of_partition_view_has_the_same_effect_as_applying_regular_mutation) {
    schema_ptr s = new_table()
        .with_column("pk_col", bytes_type, column_kind::partition_key)
        .with_column("ck_1", bytes_type, column_kind::clustering_key)
        .with_column("reg_1", bytes_type)
        .with_column("reg_2", bytes_type)
        .with_column("static_1", bytes_type, column_kind::static_column)
        .build();

    partition_key key = partition_key::from_single_value(*s, bytes("key"));
    clustering_key ck = clustering_key::from_deeply_exploded(*s, {data_value(bytes("ck"))});

    mutation m1(key, s);
    m1.partition().apply(new_tombstone());
    m1.set_clustered_cell(ck, "reg_1", data_value(bytes("val1")), new_timestamp());
    m1.set_clustered_cell(ck, "reg_2", data_value(bytes("val2")), new_timestamp());
    m1.partition().apply_insert(*s, ck, new_timestamp());
    m1.set_static_cell("static_1", data_value(bytes("val3")), new_timestamp());

    mutation m2(key, s);
    m2.set_clustered_cell(ck, "reg_1", data_value(bytes("val4")), new_timestamp());
    m2.partition().apply_insert(*s, ck, new_timestamp());
    m2.set_static_cell("static_1", data_value(bytes("val5")), new_timestamp());

    mutation m_frozen(key, s);
    m_frozen.partition().apply(*s, freeze(m1).partition());
    m_frozen.partition().apply(*s, freeze(m2).partition());

    mutation m_unfrozen(key, s);
    m_unfrozen.partition().apply(*s, m1.partition());
    m_unfrozen.partition().apply(*s, m2.partition());

    mutation m_refrozen(key, s);
    m_refrozen.partition().apply(*s, freeze(m1).unfreeze(s).partition());
    m_refrozen.partition().apply(*s, freeze(m2).unfreeze(s).partition());

    assert_that(m_unfrozen).is_equal_to(m_refrozen);
    assert_that(m_unfrozen).is_equal_to(m_frozen);
}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     test_forward_solution.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     December, 2016
*
* @section  LICENSE
*
* Copyright (C) 2016, Christoph Dinh and Matti Hamalainen. 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 MNE-CPP authors 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 OWNER 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.
*
*
* @brief    The forward solution test implementation
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fwd/computeFwd/compute_fwd_settings.h>
#include <fwd/computeFwd/compute_fwd.h>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FWDLIB;

//=============================================================================================================
/**
* DECLARE CLASS TestForwardSolution
*
* @brief The TestForwardSolution class provides dipole fit tests
*
*/
class TestForwardSolution : public QObject
{
    Q_OBJECT

public:
    TestForwardSolution();

private slots:
    void initTestCase();
    void computeForward();
    void cleanupTestCase();

private:
    void compareForward();

    double epsilon;

};

//*************************************************************************************************************

TestForwardSolution::TestForwardSolution()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestForwardSolution::initTestCase()
{

}

//*************************************************************************************************************

void TestForwardSolution::computeForward()
{
    QString refFileName(QDir::currentPath()+"/mne-cpp-test-data/Result/ref_dip_fit.dat");
    QFile testFile;

    //*********************************************************************************************************
    // Forward Solution Settings
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Forward Solution Settings >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    //Following is equivalent to: --meg --accurate --src ./MNE-sample-data/subjects/sample/bem/sample-oct-6-src.fif
    // --meas ./MNE-sample-data/MEG/sample/sample_audvis_raw.fif
    // --mri ./MNE-sample-data/subjects/sample/mri/brain-neuromag/sets/COR.fif
    // --bem ./MNE-sample-data/subjects/sample/bem/sample-5120-5120-5120-bem.fif
    // --mindist 5 --fwd ./MNE-sample-data/Result/sample_audvis-meg-oct-6-fwd.fif
    ComputeFwdSettings settings;

    settings.include_meg = true;
    settings.accurate = true;
    settings.srcname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/bem/sample-oct-6-src.fif";
    settings.measname = QDir::currentPath()+"./MNE-sample-data/MEG/sample/sample_audvis_raw.fif";
    settings.mriname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/mri/brain-neuromag/sets/COR.fif";
    settings.mri_head_ident = false;
    settings.transname.clear();
    settings.bemname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/bem/sample-5120-5120-5120-bem.fif";
    settings.mindist = 5.0f/1000.0f;
    settings.solname = QDir::currentPath()+"./mne-cpp-test-data/Result/sample_audvis-meg-oct-6-fwd.fif";

    settings.checkIntegrity();

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Forward Solution Settings Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");

    //*********************************************************************************************************
    // Compute Forward Solution
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compute Forward Solution >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    ComputeFwd cmpFwd(&settings);
    cmpFwd.calculateFwd();

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compute Forward Solution Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");

    //*********************************************************************************************************
    // Write Forward Solution
    //*********************************************************************************************************

    //*********************************************************************************************************
    // Load reference Dipole Set
    //*********************************************************************************************************

    //*********************************************************************************************************
    // Compare Fit
    //*********************************************************************************************************

    compareForward();
}

//*************************************************************************************************************

void TestForwardSolution::compareForward()
{
    //*********************************************************************************************************
    // Write Read Forward Solution
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compare Forward Solution >>>>>>>>>>>>>>>>>>>>>>>>>\n");

//    QVERIFY( m_refECDSet.size() == m_ECDSet.size() );

//    for (int i = 0; i < m_refECDSet.size(); ++i)
//    {
//        printf("Compare orig Dipole %d: %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.1f\n", i,
//                1000*m_ECDSet[i].time,1000*m_ECDSet[i].time,
//                1000*m_ECDSet[i].rd[0],1000*m_ECDSet[i].rd[1],1000*m_ECDSet[i].rd[2],
//                1e9*m_ECDSet[i].Q.norm(),1e9*m_ECDSet[i].Q[0],1e9*m_ECDSet[i].Q[1],1e9*m_ECDSet[i].Q[2],100.0*m_ECDSet[i].good);
//        printf("         ref Dipole %d: %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.1f\n", i,
//                1000*m_refECDSet[i].time,1000*m_refECDSet[i].time,
//                1000*m_refECDSet[i].rd[0],1000*m_refECDSet[i].rd[1],1000*m_refECDSet[i].rd[2],
//                1e9*m_refECDSet[i].Q.norm(),1e9*m_refECDSet[i].Q[0],1e9*m_refECDSet[i].Q[1],1e9*m_refECDSet[i].Q[2],100.0*m_refECDSet[i].good);

//        QVERIFY( m_ECDSet[i].valid == m_refECDSet[i].valid );
//        QVERIFY( m_ECDSet[i].time - m_refECDSet[i].time < epsilon );
//        QVERIFY( m_ECDSet[i].rd == m_refECDSet[i].rd );
//        QVERIFY( m_ECDSet[i].Q == m_refECDSet[i].Q );
//        QVERIFY( m_ECDSet[i].good - m_refECDSet[i].good < epsilon );
//        QVERIFY( m_ECDSet[i].khi2 - m_refECDSet[i].khi2 < epsilon );
//        QVERIFY( m_ECDSet[i].nfree == m_refECDSet[i].nfree );
//        QVERIFY( m_ECDSet[i].neval == m_refECDSet[i].neval );
//    }

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compare Forward Solution Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");
}

//*************************************************************************************************************

void TestForwardSolution::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestForwardSolution)
#include "test_forward_solution.moc"
<commit_msg>Adjusting Fwd test<commit_after>//=============================================================================================================
/**
* @file     test_forward_solution.cpp
* @author   Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     December, 2016
*
* @section  LICENSE
*
* Copyright (C) 2016, Christoph Dinh and Matti Hamalainen. 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 MNE-CPP authors 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 OWNER 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.
*
*
* @brief    The forward solution test implementation
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <fwd/computeFwd/compute_fwd_settings.h>
#include <fwd/computeFwd/compute_fwd.h>
#include <mne/mne.h>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtTest>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace FWDLIB;
using namespace MNELIB;

//=============================================================================================================
/**
* DECLARE CLASS TestForwardSolution
*
* @brief The TestForwardSolution class provides dipole fit tests
*
*/
class TestForwardSolution : public QObject
{
    Q_OBJECT

public:
    TestForwardSolution();

private slots:
    void initTestCase();
    void computeForward();
    void cleanupTestCase();

private:
    void compareForward();

    double epsilon;

};

//*************************************************************************************************************

TestForwardSolution::TestForwardSolution()
: epsilon(0.000001)
{
}

//*************************************************************************************************************

void TestForwardSolution::initTestCase()
{

}

//*************************************************************************************************************

void TestForwardSolution::computeForward()
{
    //*********************************************************************************************************
    // Forward Solution Settings
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Forward Solution Settings >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    //Following is equivalent to: --meg --accurate --src ./MNE-sample-data/subjects/sample/bem/sample-oct-6-src.fif
    // --meas ./MNE-sample-data/MEG/sample/sample_audvis_raw.fif
    // --mri ./MNE-sample-data/subjects/sample/mri/brain-neuromag/sets/COR.fif
    // --bem ./MNE-sample-data/subjects/sample/bem/sample-5120-5120-5120-bem.fif
    // --mindist 5 --fwd ./MNE-sample-data/Result/sample_audvis-meg-oct-6-fwd.fif
    ComputeFwdSettings settings;

    settings.include_meg = true;
    settings.accurate = true;
    settings.srcname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/bem/sample-oct-6-src.fif";
    settings.measname = QDir::currentPath()+"./MNE-sample-data/MEG/sample/sample_audvis_raw.fif";
    settings.mriname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/mri/brain-neuromag/sets/COR.fif";
    settings.mri_head_ident = false;
    settings.transname.clear();
    settings.bemname = QDir::currentPath()+"./MNE-sample-data/subjects/sample/bem/sample-5120-5120-5120-bem.fif";
    settings.mindist = 5.0f/1000.0f;
    settings.solname = QDir::currentPath()+"./mne-cpp-test-data/Result/sample_audvis-meg-oct-6-fwd.fif";

    settings.checkIntegrity();

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Forward Solution Settings Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");

    //*********************************************************************************************************
    // Compute Forward Solution
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compute Forward Solution >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    ComputeFwd cmpFwd(&settings);
    cmpFwd.calculateFwd();

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compute Forward Solution Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");

    //*********************************************************************************************************
    // Write Forward Solution
    //*********************************************************************************************************

    //*********************************************************************************************************
    // Load reference Dipole Set
    //*********************************************************************************************************

    //*********************************************************************************************************
    // Compare Fit
    //*********************************************************************************************************

    compareForward();
}

//*************************************************************************************************************

void TestForwardSolution::compareForward()
{
    //*********************************************************************************************************
    // Write Read Forward Solution
    //*********************************************************************************************************

    printf(">>>>>>>>>>>>>>>>>>>>>>>>> Compare Forward Solution >>>>>>>>>>>>>>>>>>>>>>>>>\n");

    QString refFwdFileName(QDir::currentPath()+"./mne-cpp-test-data/Result/sample_audvis-meg-oct-6-fwd.fif");

    //Load data
    MNEForwardSolution t_Fwd(refFwdFileName);

//    QVERIFY( m_refECDSet.size() == m_ECDSet.size() );

//    for (int i = 0; i < m_refECDSet.size(); ++i)
//    {
//        printf("Compare orig Dipole %d: %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.1f\n", i,
//                1000*m_ECDSet[i].time,1000*m_ECDSet[i].time,
//                1000*m_ECDSet[i].rd[0],1000*m_ECDSet[i].rd[1],1000*m_ECDSet[i].rd[2],
//                1e9*m_ECDSet[i].Q.norm(),1e9*m_ECDSet[i].Q[0],1e9*m_ECDSet[i].Q[1],1e9*m_ECDSet[i].Q[2],100.0*m_ECDSet[i].good);
//        printf("         ref Dipole %d: %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.1f\n", i,
//                1000*m_refECDSet[i].time,1000*m_refECDSet[i].time,
//                1000*m_refECDSet[i].rd[0],1000*m_refECDSet[i].rd[1],1000*m_refECDSet[i].rd[2],
//                1e9*m_refECDSet[i].Q.norm(),1e9*m_refECDSet[i].Q[0],1e9*m_refECDSet[i].Q[1],1e9*m_refECDSet[i].Q[2],100.0*m_refECDSet[i].good);

//        QVERIFY( m_ECDSet[i].valid == m_refECDSet[i].valid );
//        QVERIFY( m_ECDSet[i].time - m_refECDSet[i].time < epsilon );
//        QVERIFY( m_ECDSet[i].rd == m_refECDSet[i].rd );
//        QVERIFY( m_ECDSet[i].Q == m_refECDSet[i].Q );
//        QVERIFY( m_ECDSet[i].good - m_refECDSet[i].good < epsilon );
//        QVERIFY( m_ECDSet[i].khi2 - m_refECDSet[i].khi2 < epsilon );
//        QVERIFY( m_ECDSet[i].nfree == m_refECDSet[i].nfree );
//        QVERIFY( m_ECDSet[i].neval == m_refECDSet[i].neval );
//    }

    printf("<<<<<<<<<<<<<<<<<<<<<<<<< Compare Forward Solution Finished <<<<<<<<<<<<<<<<<<<<<<<<<\n");
}

//*************************************************************************************************************

void TestForwardSolution::cleanupTestCase()
{
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

QTEST_APPLESS_MAIN(TestForwardSolution)
#include "test_forward_solution.moc"
<|endoftext|>


<commit_before>#include "aerial_autonomy/controllers/rpyt_based_position_controller.h"
#include <aerial_autonomy/tests/test_utils.h>

#include <gtest/gtest.h>
#include <tf/transform_datatypes.h>

class RPYTBasedPositionControllerTests : public ::testing::Test {
public:
  RPYTBasedPositionControllerTests()
      : config_(RPYTBasedPositionControllerConfig()) {
    // Set tolerances
    auto velocity_tolerance =
        config_.mutable_rpyt_based_velocity_controller_config()
            ->mutable_velocity_controller_config()
            ->mutable_goal_velocity_tolerance();
    velocity_tolerance->set_vx(0.01);
    velocity_tolerance->set_vy(0.01);
    velocity_tolerance->set_vz(0.01);
    auto position_tolerance =
        config_.mutable_velocity_based_position_controller_config()
            ->mutable_position_controller_config()
            ->mutable_goal_position_tolerance();
    position_tolerance->set_x(0.05);
    position_tolerance->set_y(0.05);
    position_tolerance->set_z(0.05);
  }

  void runUntilConvergence(PositionYaw goal) {
    std::chrono::duration<double> dt = std::chrono::milliseconds(20);

    RPYTBasedPositionController controller(config_, dt);
    auto sensor_data =
        std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(0, 0, 0, 0));
    auto &velocity_yaw_rate = std::get<0>(sensor_data);
    auto &position_yaw = std::get<1>(sensor_data);
    auto convergence = [&]() {
      RollPitchYawRateThrust controls;

      controller.run(sensor_data, controls);
      tf::Transform tf;
      tf.setOrigin(tf::Vector3(0, 0, 0));
      tf.setRotation(
          tf::createQuaternionFromRPY(controls.r, controls.p, controls.y));

      double ext_z_acc = 0.1;
      tf::Vector3 body_acc(
          0, 0,
          controls.t * config_.rpyt_based_velocity_controller_config().kt() +
              ext_z_acc);
      tf::Vector3 global_acc = tf * body_acc;

      velocity_yaw_rate.x = velocity_yaw_rate.x + global_acc[0] * dt.count();
      velocity_yaw_rate.y = velocity_yaw_rate.y + global_acc[1] * dt.count();
      velocity_yaw_rate.z =
          velocity_yaw_rate.z + (global_acc[2] - 9.81) * dt.count();
      velocity_yaw_rate.yaw_rate = controls.y;
      position_yaw.x = velocity_yaw_rate.x * dt.count();
      position_yaw.y = velocity_yaw_rate.y * dt.count();
      position_yaw.z = velocity_yaw_rate.z * dt.count();
      position_yaw.yaw = position_yaw.yaw + controls.y * dt.count();

      return bool(controller.isConverged(sensor_data));

    };

    ASSERT_TRUE(test_utils::waitUntilTrue()(
        convergence, std::chrono::seconds(1), std::chrono::milliseconds(0)));
  }

  RPYTBasedPositionControllerConfig config_;
};

TEST_F(RPYTBasedPositionControllerTests, SetGetGoal) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(1, -2, 3, 0.1);
  controller.setGoal(goal);
  PositionYaw expected_goal = controller.getGoal();
  ASSERT_EQ(goal, expected_goal);
}

TEST_F(RPYTBasedPositionControllerTests, Converged) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(0, 0, 0, 0);
  controller.setGoal(goal);

  ASSERT_TRUE(controller.isConverged(
      std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(0, 0, 0, 0))));
}

TEST_F(RPYTBasedPositionControllerTests, NotConverged) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(0, 0, 0, 0);
  controller.setGoal(goal);

  // Not converged for non-zero position
  ASSERT_FALSE(controller.isConverged(
      std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(1, 0, 0, 0))));
  // Not converged for non-zero velocity
  ASSERT_FALSE(controller.isConverged(
      std::make_tuple(VelocityYawRate(1, 0, 0, 0), PositionYaw(0, 0, 0, 0))));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceAlreadyConverged) {
  runUntilConvergence(PositionYaw(0, 0, 0, 0));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceNoYaw) {
  runUntilConvergence(PositionYaw(2.0, 3.0, -1.0, 0));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceYaw) {
  runUntilConvergence(PositionYaw(-1.0, -1.0, 1.0, M_PI / 2.));
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Add neg yaw test<commit_after>#include "aerial_autonomy/controllers/rpyt_based_position_controller.h"
#include <aerial_autonomy/tests/test_utils.h>

#include <gtest/gtest.h>
#include <tf/transform_datatypes.h>

class RPYTBasedPositionControllerTests : public ::testing::Test {
public:
  RPYTBasedPositionControllerTests()
      : config_(RPYTBasedPositionControllerConfig()) {
    // Set tolerances
    auto velocity_tolerance =
        config_.mutable_rpyt_based_velocity_controller_config()
            ->mutable_velocity_controller_config()
            ->mutable_goal_velocity_tolerance();
    velocity_tolerance->set_vx(0.01);
    velocity_tolerance->set_vy(0.01);
    velocity_tolerance->set_vz(0.01);
    auto position_tolerance =
        config_.mutable_velocity_based_position_controller_config()
            ->mutable_position_controller_config()
            ->mutable_goal_position_tolerance();
    position_tolerance->set_x(0.05);
    position_tolerance->set_y(0.05);
    position_tolerance->set_z(0.05);
  }

  void runUntilConvergence(PositionYaw goal) {
    std::chrono::duration<double> dt = std::chrono::milliseconds(20);

    RPYTBasedPositionController controller(config_, dt);
    auto sensor_data =
        std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(0, 0, 0, 0));
    auto &velocity_yaw_rate = std::get<0>(sensor_data);
    auto &position_yaw = std::get<1>(sensor_data);
    auto convergence = [&]() {
      RollPitchYawRateThrust controls;

      controller.run(sensor_data, controls);
      tf::Transform tf;
      tf.setOrigin(tf::Vector3(0, 0, 0));
      tf.setRotation(
          tf::createQuaternionFromRPY(controls.r, controls.p, controls.y));

      double ext_z_acc = 0.1;
      tf::Vector3 body_acc(
          0, 0,
          controls.t * config_.rpyt_based_velocity_controller_config().kt() +
              ext_z_acc);
      tf::Vector3 global_acc = tf * body_acc;

      velocity_yaw_rate.x = velocity_yaw_rate.x + global_acc[0] * dt.count();
      velocity_yaw_rate.y = velocity_yaw_rate.y + global_acc[1] * dt.count();
      velocity_yaw_rate.z =
          velocity_yaw_rate.z + (global_acc[2] - 9.81) * dt.count();
      velocity_yaw_rate.yaw_rate = controls.y;
      position_yaw.x = velocity_yaw_rate.x * dt.count();
      position_yaw.y = velocity_yaw_rate.y * dt.count();
      position_yaw.z = velocity_yaw_rate.z * dt.count();
      position_yaw.yaw = position_yaw.yaw + controls.y * dt.count();

      return bool(controller.isConverged(sensor_data));

    };

    ASSERT_TRUE(test_utils::waitUntilTrue()(
        convergence, std::chrono::seconds(1), std::chrono::milliseconds(0)));
  }

  RPYTBasedPositionControllerConfig config_;
};

TEST_F(RPYTBasedPositionControllerTests, SetGetGoal) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(1, -2, 3, 0.1);
  controller.setGoal(goal);
  PositionYaw expected_goal = controller.getGoal();
  ASSERT_EQ(goal, expected_goal);
}

TEST_F(RPYTBasedPositionControllerTests, Converged) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(0, 0, 0, 0);
  controller.setGoal(goal);

  ASSERT_TRUE(controller.isConverged(
      std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(0, 0, 0, 0))));
}

TEST_F(RPYTBasedPositionControllerTests, NotConverged) {
  RPYTBasedPositionController controller(config_,
                                         std::chrono::milliseconds(20));

  PositionYaw goal(0, 0, 0, 0);
  controller.setGoal(goal);

  // Not converged for non-zero position
  ASSERT_FALSE(controller.isConverged(
      std::make_tuple(VelocityYawRate(0, 0, 0, 0), PositionYaw(1, 0, 0, 0))));
  // Not converged for non-zero velocity
  ASSERT_FALSE(controller.isConverged(
      std::make_tuple(VelocityYawRate(1, 0, 0, 0), PositionYaw(0, 0, 0, 0))));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceAlreadyConverged) {
  runUntilConvergence(PositionYaw(0, 0, 0, 0));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceNoYaw) {
  runUntilConvergence(PositionYaw(2.0, 3.0, -1.0, 0));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceYaw) {
  runUntilConvergence(PositionYaw(-1.0, -1.0, 1.0, M_PI / 2.));
}

TEST_F(RPYTBasedPositionControllerTests, RunUntilConvergenceNegYaw) {
  runUntilConvergence(PositionYaw(-1.0, -1.0, 1.0, -M_PI / 2.));
}

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>
#include "expirypropertiesdialog.h"
#include "folderrequester.h"
#include "kmfoldertree.h"
#include "kmglobal.h"

#include <qvariant.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qspinbox.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <klocale.h>
#include <kmessagebox.h>

using namespace KMail;

/*
 *  Constructs a ExpiryPropertiesDialog as a child of 'parent', with the
 *  name 'name'.
 *
 */
ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* folder )
    : KDialogBase( tree, "expiry_properties", false, i18n( "Mail Expiry Properties" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  QWidget* privateLayoutWidget = new QWidget( this, "globalVBox" );
  setMainWidget( privateLayoutWidget );
  privateLayoutWidget->setGeometry( QRect( 10, 20, 270, 138 ) );
  globalVBox = new QVBoxLayout( privateLayoutWidget, 11, 6, "globalVBox");
  globalVBox->setSpacing( 20 );

  readHBox = new QHBoxLayout( 0, 0, 6, "readHBox");

  expireReadMailCB = new QCheckBox( privateLayoutWidget, "expireReadMailCB" );
  expireReadMailCB->setText( i18n( "Expire read mails after" ) );
  connect( expireReadMailCB, SIGNAL( toggled( bool )),
           this, SLOT( slotUpdateControls() ) );
  readHBox->addWidget( expireReadMailCB );

  expireReadMailSB = new QSpinBox( privateLayoutWidget, "expireReadMailSB" );
  expireReadMailSB->setMaxValue( 999999 );
  expireReadMailSB->setValue( 30 );
  readHBox->addWidget( expireReadMailSB );

  labelDays = new QLabel( privateLayoutWidget, "labelDays" );
  labelDays->setText( i18n( "days" ) );
  readHBox->addWidget( labelDays );
  globalVBox->addLayout( readHBox );

  unreadHBox = new QHBoxLayout( 0, 0, 6, "unreadHBox");

  expireUnreadMailCB = new QCheckBox( privateLayoutWidget, "expireUnreadMailCB" );
  expireUnreadMailCB->setText( i18n( "Expire unread mails after" ) );
  connect( expireUnreadMailCB, SIGNAL( toggled( bool )),
           this, SLOT( slotUpdateControls() ) );
  unreadHBox->addWidget( expireUnreadMailCB );

  expireUnreadMailSB = new QSpinBox( privateLayoutWidget, "expireUnreadMailSB" );
  expireUnreadMailSB->setMaxValue( 99999 );
  expireUnreadMailSB->setValue( 30 );
  unreadHBox->addWidget( expireUnreadMailSB );

  labelDays2 = new QLabel( privateLayoutWidget, "labelDays2" );
  labelDays2->setText( i18n( "days" ) );
  labelDays2->setAlignment( int( QLabel::AlignTop ) );
  unreadHBox->addWidget( labelDays2 );
  globalVBox->addLayout( unreadHBox );

  expiryActionHBox = new QHBoxLayout( 0, 0, 6, "expiryActionHBox");

  expiryActionLabel = new QLabel( privateLayoutWidget, "expiryActionLabel" );
  expiryActionLabel->setText( i18n( "Expiry action:" ) );
  expiryActionLabel->setAlignment( int( QLabel::AlignVCenter ) );
  expiryActionHBox->addWidget( expiryActionLabel );

  actionsHBox = new QVBoxLayout( 0, 0, 6, "actionsHBox");
  actionsGroup = new QButtonGroup( this );
  actionsGroup->hide(); // for mutual exclusion of the radio buttons

  moveToHBox = new QHBoxLayout( 0, 0, 6, "moveToHBox");

  moveToRB = new QRadioButton( privateLayoutWidget, "moveToRB" );
  actionsGroup->insert( moveToRB );
  connect( moveToRB, SIGNAL( toggled( bool ) ),
           this, SLOT( slotUpdateControls() ) );
  moveToRB->setText( i18n( "Move to:" ) );
  moveToHBox->addWidget( moveToRB );

  folderSelector = new KMail::FolderRequester( privateLayoutWidget, tree );
  folderSelector->setMustBeReadWrite( true );
  moveToHBox->addWidget( folderSelector );
  actionsHBox->addLayout( moveToHBox );

  deletePermanentlyRB = new QRadioButton( privateLayoutWidget, "deletePermanentlyRB" );
  actionsGroup->insert( deletePermanentlyRB );
  deletePermanentlyRB->setText( i18n( "Delete permanently" ) );
  actionsHBox->addWidget( deletePermanentlyRB );
  expiryActionHBox->addLayout( actionsHBox );
  globalVBox->addLayout( expiryActionHBox );

  note = new QLabel( privateLayoutWidget, "note" );
  note->setText( i18n( "Note: Expiry action will be applied immediately after confirming settings." ) );
  note->setAlignment( int( QLabel::WordBreak | QLabel::AlignVCenter ) );
  globalVBox->addWidget( note );

  // Load the values from the folder
  bool expiryGloballyOn = mFolder->isAutoExpire();
  int daysToExpireRead, daysToExpireUnread;
  mFolder->daysToExpire( daysToExpireRead, daysToExpireUnread );

  if ( expiryGloballyOn && daysToExpireRead > 0 ) {
    expireReadMailCB->setChecked( true );
    expireReadMailSB->setValue( daysToExpireRead );
  }
  if ( expiryGloballyOn && daysToExpireUnread > 0 ) {
    expireUnreadMailCB->setChecked( true );
    expireUnreadMailSB->setValue( daysToExpireUnread );
  }

  if ( mFolder->expireAction() == KMFolder::ExpireDelete )
    deletePermanentlyRB->setChecked( true );
  else
    moveToRB->setChecked( true );

  QString destFolderID = mFolder->expireToFolderId();
  if ( !destFolderID.isEmpty() ) {
    KMFolder* destFolder = kmkernel->findFolderById( destFolderID );
    if ( destFolder )
      folderSelector->setFolder( destFolder );
  }
  slotUpdateControls();
  resize( QSize(295, 204).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
}

/*
 *  Destroys the object and frees any allocated resources
 */
ExpiryPropertiesDialog::~ExpiryPropertiesDialog()
{
    // no need to delete child widgets, Qt does it all for us
}

void ExpiryPropertiesDialog::slotOk()
{
  bool enableGlobally = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
  if ( enableGlobally && moveToRB->isChecked() && !folderSelector->folder() ) {
    KMessageBox::error( this, i18n("Please select a folder to expire messages into."),
        i18n( "No Folder Selected" ) );
    return;
  }
  mFolder->setAutoExpire( enableGlobally );
  // we always write out days now
  mFolder->setReadExpireAge( expireReadMailSB->value() );
  mFolder->setUnreadExpireAge( expireUnreadMailSB->value() );
  mFolder->setReadExpireUnits( expireDays );
  mFolder->setUnreadExpireUnits( expireDays );

  if ( deletePermanentlyRB->isChecked() )
    mFolder->setExpireAction( KMFolder::ExpireDelete );
  else
    mFolder->setExpireAction( KMFolder::ExpireMove );
  KMFolder* expireToFolder = folderSelector->folder();
  if ( expireToFolder )
    mFolder->setExpireToFolderId( expireToFolder->idString() );

  // trigger immediate expiry if there is something to do
  if ( enableGlobally )
    mFolder->expireOldMessages( true /*immediate*/);
  KDialogBase::slotOk();
}

void ExpiryPropertiesDialog::slotUpdateControls()
{
  bool showExpiryActions = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
  moveToRB->setEnabled( showExpiryActions );
  folderSelector->setEnabled( showExpiryActions && moveToRB->isChecked() );
  deletePermanentlyRB->setEnabled( showExpiryActions );
}

#include "expirypropertiesdialog.moc"
<commit_msg>Make sure the unread and read expiry settings are toggled individually.<commit_after>
#include "expirypropertiesdialog.h"
#include "folderrequester.h"
#include "kmfoldertree.h"
#include "kmglobal.h"

#include <qvariant.h>
#include <qpushbutton.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qspinbox.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>

#include <klocale.h>
#include <kmessagebox.h>

using namespace KMail;

/*
 *  Constructs a ExpiryPropertiesDialog as a child of 'parent', with the
 *  name 'name'.
 *
 */
ExpiryPropertiesDialog::ExpiryPropertiesDialog( KMFolderTree* tree, KMFolder* folder )
    : KDialogBase( tree, "expiry_properties", false, i18n( "Mail Expiry Properties" ),
                   KDialogBase::Ok|KDialogBase::Cancel,
                   KDialogBase::Ok, true ),
      mFolder( folder )
{
  setWFlags( getWFlags() | WDestructiveClose );
  QWidget* privateLayoutWidget = new QWidget( this, "globalVBox" );
  setMainWidget( privateLayoutWidget );
  privateLayoutWidget->setGeometry( QRect( 10, 20, 270, 138 ) );
  globalVBox = new QVBoxLayout( privateLayoutWidget, 11, 6, "globalVBox");
  globalVBox->setSpacing( 20 );

  readHBox = new QHBoxLayout( 0, 0, 6, "readHBox");

  expireReadMailCB = new QCheckBox( privateLayoutWidget, "expireReadMailCB" );
  expireReadMailCB->setText( i18n( "Expire read mails after" ) );
  connect( expireReadMailCB, SIGNAL( toggled( bool )),
           this, SLOT( slotUpdateControls() ) );
  readHBox->addWidget( expireReadMailCB );

  expireReadMailSB = new QSpinBox( privateLayoutWidget, "expireReadMailSB" );
  expireReadMailSB->setMaxValue( 999999 );
  expireReadMailSB->setValue( 30 );
  readHBox->addWidget( expireReadMailSB );

  labelDays = new QLabel( privateLayoutWidget, "labelDays" );
  labelDays->setText( i18n( "days" ) );
  readHBox->addWidget( labelDays );
  globalVBox->addLayout( readHBox );

  unreadHBox = new QHBoxLayout( 0, 0, 6, "unreadHBox");

  expireUnreadMailCB = new QCheckBox( privateLayoutWidget, "expireUnreadMailCB" );
  expireUnreadMailCB->setText( i18n( "Expire unread mails after" ) );
  connect( expireUnreadMailCB, SIGNAL( toggled( bool )),
           this, SLOT( slotUpdateControls() ) );
  unreadHBox->addWidget( expireUnreadMailCB );

  expireUnreadMailSB = new QSpinBox( privateLayoutWidget, "expireUnreadMailSB" );
  expireUnreadMailSB->setMaxValue( 99999 );
  expireUnreadMailSB->setValue( 30 );
  unreadHBox->addWidget( expireUnreadMailSB );

  labelDays2 = new QLabel( privateLayoutWidget, "labelDays2" );
  labelDays2->setText( i18n( "days" ) );
  labelDays2->setAlignment( int( QLabel::AlignTop ) );
  unreadHBox->addWidget( labelDays2 );
  globalVBox->addLayout( unreadHBox );

  expiryActionHBox = new QHBoxLayout( 0, 0, 6, "expiryActionHBox");

  expiryActionLabel = new QLabel( privateLayoutWidget, "expiryActionLabel" );
  expiryActionLabel->setText( i18n( "Expiry action:" ) );
  expiryActionLabel->setAlignment( int( QLabel::AlignVCenter ) );
  expiryActionHBox->addWidget( expiryActionLabel );

  actionsHBox = new QVBoxLayout( 0, 0, 6, "actionsHBox");
  actionsGroup = new QButtonGroup( this );
  actionsGroup->hide(); // for mutual exclusion of the radio buttons

  moveToHBox = new QHBoxLayout( 0, 0, 6, "moveToHBox");

  moveToRB = new QRadioButton( privateLayoutWidget, "moveToRB" );
  actionsGroup->insert( moveToRB );
  connect( moveToRB, SIGNAL( toggled( bool ) ),
           this, SLOT( slotUpdateControls() ) );
  moveToRB->setText( i18n( "Move to:" ) );
  moveToHBox->addWidget( moveToRB );

  folderSelector = new KMail::FolderRequester( privateLayoutWidget, tree );
  folderSelector->setMustBeReadWrite( true );
  moveToHBox->addWidget( folderSelector );
  actionsHBox->addLayout( moveToHBox );

  deletePermanentlyRB = new QRadioButton( privateLayoutWidget, "deletePermanentlyRB" );
  actionsGroup->insert( deletePermanentlyRB );
  deletePermanentlyRB->setText( i18n( "Delete permanently" ) );
  actionsHBox->addWidget( deletePermanentlyRB );
  expiryActionHBox->addLayout( actionsHBox );
  globalVBox->addLayout( expiryActionHBox );

  note = new QLabel( privateLayoutWidget, "note" );
  note->setText( i18n( "Note: Expiry action will be applied immediately after confirming settings." ) );
  note->setAlignment( int( QLabel::WordBreak | QLabel::AlignVCenter ) );
  globalVBox->addWidget( note );

  // Load the values from the folder
  bool expiryGloballyOn = mFolder->isAutoExpire();
  int daysToExpireRead, daysToExpireUnread;
  mFolder->daysToExpire( daysToExpireRead, daysToExpireUnread );

  if ( expiryGloballyOn
      && mFolder->getReadExpireUnits() != expireNever
      && daysToExpireRead >= 0 ) {
    expireReadMailCB->setChecked( true );
    expireReadMailSB->setValue( daysToExpireRead );
  }
  if ( expiryGloballyOn
      && mFolder->getUnreadExpireUnits() != expireNever
      && daysToExpireUnread >= 0 ) {
    expireUnreadMailCB->setChecked( true );
    expireUnreadMailSB->setValue( daysToExpireUnread );
  }

  if ( mFolder->expireAction() == KMFolder::ExpireDelete )
    deletePermanentlyRB->setChecked( true );
  else
    moveToRB->setChecked( true );

  QString destFolderID = mFolder->expireToFolderId();
  if ( !destFolderID.isEmpty() ) {
    KMFolder* destFolder = kmkernel->findFolderById( destFolderID );
    if ( destFolder )
      folderSelector->setFolder( destFolder );
  }
  slotUpdateControls();
  resize( QSize(295, 204).expandedTo(minimumSizeHint()) );
  clearWState( WState_Polished );
}

/*
 *  Destroys the object and frees any allocated resources
 */
ExpiryPropertiesDialog::~ExpiryPropertiesDialog()
{
    // no need to delete child widgets, Qt does it all for us
}

void ExpiryPropertiesDialog::slotOk()
{
  bool enableGlobally = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
  if ( enableGlobally && moveToRB->isChecked() && !folderSelector->folder() ) {
    KMessageBox::error( this, i18n("Please select a folder to expire messages into."),
        i18n( "No Folder Selected" ) );
    return;
  }
  mFolder->setAutoExpire( enableGlobally );
  // we always write out days now
  mFolder->setReadExpireAge( expireReadMailSB->value() );
  mFolder->setUnreadExpireAge( expireUnreadMailSB->value() );
  mFolder->setReadExpireUnits( expireReadMailCB->isChecked()? expireDays : expireNever );
  mFolder->setUnreadExpireUnits( expireUnreadMailCB->isChecked()? expireDays : expireNever );

  if ( deletePermanentlyRB->isChecked() )
    mFolder->setExpireAction( KMFolder::ExpireDelete );
  else
    mFolder->setExpireAction( KMFolder::ExpireMove );
  KMFolder* expireToFolder = folderSelector->folder();
  if ( expireToFolder )
    mFolder->setExpireToFolderId( expireToFolder->idString() );

  // trigger immediate expiry if there is something to do
  if ( enableGlobally )
    mFolder->expireOldMessages( true /*immediate*/);
  KDialogBase::slotOk();
}

void ExpiryPropertiesDialog::slotUpdateControls()
{
  bool showExpiryActions = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
  moveToRB->setEnabled( showExpiryActions );
  folderSelector->setEnabled( showExpiryActions && moveToRB->isChecked() );
  deletePermanentlyRB->setEnabled( showExpiryActions );
}

#include "expirypropertiesdialog.moc"
<|endoftext|>


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

#include "base/process_util.h"

#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <time.h>
#include <unistd.h>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/threading/thread_restrictions.h"

namespace base {

ProcessId GetParentProcessId(ProcessHandle process) {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return info.p_ppid;
}

FilePath GetProcessExecutablePath(ProcessHandle process) {
  struct kinfo_proc kp;
  size_t len;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) == -1)
    return FilePath();
  mib[5] = (len / sizeof(struct kinfo_proc));
  if (sysctl(mib, arraysize(mib), &kp, &len, NULL, 0) < 0)
    return FilePath();
  if ((kp.p_flag & P_SYSTEM) != 0)
    return FilePath();
  if (strcmp(kp.p_comm, "chrome") == 0)
    return FilePath(kp.p_comm);

  return FilePath();
}

ProcessIterator::ProcessIterator(const ProcessFilter* filter)
    : index_of_kinfo_proc_(),
      filter_(filter) {

  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(),
                sizeof(struct kinfo_proc), 0 };

  bool done = false;
  int try_num = 1;
  const int max_tries = 10;

  do {
    size_t len = 0;
    if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) {
      DLOG(ERROR) << "failed to get the size needed for the process list";
      kinfo_procs_.resize(0);
      done = true;
    } else {
      size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
      // Leave some spare room for process table growth (more could show up
      // between when we check and now)
      num_of_kinfo_proc += 16;
      kinfo_procs_.resize(num_of_kinfo_proc);
      len = num_of_kinfo_proc * sizeof(struct kinfo_proc);
      if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) {
        // If we get a mem error, it just means we need a bigger buffer, so
        // loop around again.  Anything else is a real error and give up.
        if (errno != ENOMEM) {
          DLOG(ERROR) << "failed to get the process list";
          kinfo_procs_.resize(0);
          done = true;
        }
      } else {
        // Got the list, just make sure we're sized exactly right
        size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
        kinfo_procs_.resize(num_of_kinfo_proc);
        done = true;
      }
    }
  } while (!done && (try_num++ < max_tries));

  if (!done) {
    DDLOG(ERROR) << "failed to collect the process list in a few tries";
    kinfo_procs_.resize(0);
  }
}

ProcessIterator::~ProcessIterator() {
}

bool ProcessIterator::CheckForNextProcess() {
  std::string data;
  for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) {
    kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_];

    // Skip processes just awaiting collection
    if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB))
      continue;

    int mib[] = { CTL_KERN, KERN_PROC_ARGS, kinfo.p_pid };

    // Find out what size buffer we need.
    size_t data_len = 0;
    if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) {
      DVPLOG(1) << "failed to figure out the buffer size for a commandline";
      continue;
    }

    data.resize(data_len);
    if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) {
      DVPLOG(1) << "failed to fetch a commandline";
      continue;
    }

    // |data| contains all the command line parameters of the process, separated
    // by blocks of one or more null characters. We tokenize |data| into a
    // vector of strings using '\0' as a delimiter and populate
    // |entry_.cmd_line_args_|.
    std::string delimiters;
    delimiters.push_back('\0');
    Tokenize(data, delimiters, &entry_.cmd_line_args_);

    // |data| starts with the full executable path followed by a null character.
    // We search for the first instance of '\0' and extract everything before it
    // to populate |entry_.exe_file_|.
    size_t exec_name_end = data.find('\0');
    if (exec_name_end == std::string::npos) {
      DLOG(ERROR) << "command line data didn't match expected format";
      continue;
    }

    entry_.pid_ = kinfo.p_pid;
    entry_.ppid_ = kinfo.p_ppid;
    entry_.gid_ = kinfo.p__pgid;
    size_t last_slash = data.rfind('/', exec_name_end);
    if (last_slash == std::string::npos)
      entry_.exe_file_.assign(data, 0, exec_name_end);
    else
      entry_.exe_file_.assign(data, last_slash + 1,
                              exec_name_end - last_slash - 1);
    // Start w/ the next entry next time through
    ++index_of_kinfo_proc_;
    // Done
    return true;
  }
  return false;
}

bool NamedProcessIterator::IncludeEntry() {
  return (executable_name_ == entry().exe_file() &&
          ProcessIterator::IncludeEntry());
}

ProcessMetrics::ProcessMetrics(ProcessHandle process)
    : process_(process),
      last_time_(0),
      last_system_time_(0),
      last_cpu_(0) {

  processor_count_ = base::SysInfo::NumberOfProcessors();
}

// static
ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
  return new ProcessMetrics(process);
}

size_t ProcessMetrics::GetPagefileUsage() const {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
}

size_t ProcessMetrics::GetPeakPagefileUsage() const {

  return 0;
}

size_t ProcessMetrics::GetWorkingSetSize() const {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return info.p_vm_rssize * getpagesize();
}

size_t ProcessMetrics::GetPeakWorkingSetSize() const {

  return 0;
}

bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
                                    size_t* shared_bytes) {
  WorkingSetKBytes ws_usage;

  if (!GetWorkingSetKBytes(&ws_usage))
    return false;

  if (private_bytes)
    *private_bytes = ws_usage.priv << 10;

  if (shared_bytes)
    *shared_bytes = ws_usage.shared * 1024;

  return true;
}

bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
// TODO(bapt) be sure we can't be precise
  size_t priv = GetWorkingSetSize();
  if (!priv)
    return false;
  ws_usage->priv = priv / 1024;
  ws_usage->shareable = 0;
  ws_usage->shared = 0;

  return true;
}

bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
  return false;
}

static int GetProcessCPU(pid_t pid) {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return 0;

  return info.p_pctcpu;
}

double ProcessMetrics::GetCPUUsage() {
  struct timeval now;

  int retval = gettimeofday(&now, NULL);
  if (retval)
    return 0;

  int64 time = TimeValToMicroseconds(now);

  if (last_time_ == 0) {
    // First call, just set the last values.
    last_time_ = time;
    last_cpu_ = GetProcessCPU(process_);
    return 0;
  }

  int64 time_delta = time - last_time_;
  DCHECK_NE(time_delta, 0);

  if (time_delta == 0)
    return 0;

  int cpu = GetProcessCPU(process_);

  last_time_ = time;
  last_cpu_ = cpu;

  double percentage = static_cast<double>((cpu * 100.0) / FSCALE);

  return percentage;
}

size_t GetSystemCommitCharge() {
  int mib[] = { CTL_VM, VM_METER };
  int pagesize;
  struct vmtotal vmtotal;
  unsigned long mem_total, mem_free, mem_inactive;
  size_t len = sizeof(vmtotal);

  if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
    return 0;

  mem_total = vmtotal.t_vm;
  mem_free = vmtotal.t_free;
  mem_inactive = vmtotal.t_vm - vmtotal.t_avm;

  pagesize = getpagesize();

  return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
}

void EnableTerminationOnOutOfMemory() {
}

void EnableTerminationOnHeapCorruption() {
}

}  // namespace base
<commit_msg>fix typo introduced in CR# 8341026<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process_util.h"

#include <ctype.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <time.h>
#include <unistd.h>

#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_split.h"
#include "base/string_tokenizer.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/threading/thread_restrictions.h"

namespace base {

ProcessId GetParentProcessId(ProcessHandle process) {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return info.p_ppid;
}

FilePath GetProcessExecutablePath(ProcessHandle process) {
  struct kinfo_proc kp;
  size_t len;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) == -1)
    return FilePath();
  mib[5] = (len / sizeof(struct kinfo_proc));
  if (sysctl(mib, arraysize(mib), &kp, &len, NULL, 0) < 0)
    return FilePath();
  if ((kp.p_flag & P_SYSTEM) != 0)
    return FilePath();
  if (strcmp(kp.p_comm, "chrome") == 0)
    return FilePath(kp.p_comm);

  return FilePath();
}

ProcessIterator::ProcessIterator(const ProcessFilter* filter)
    : index_of_kinfo_proc_(),
      filter_(filter) {

  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(),
                sizeof(struct kinfo_proc), 0 };

  bool done = false;
  int try_num = 1;
  const int max_tries = 10;

  do {
    size_t len = 0;
    if (sysctl(mib, arraysize(mib), NULL, &len, NULL, 0) < 0) {
      DLOG(ERROR) << "failed to get the size needed for the process list";
      kinfo_procs_.resize(0);
      done = true;
    } else {
      size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
      // Leave some spare room for process table growth (more could show up
      // between when we check and now)
      num_of_kinfo_proc += 16;
      kinfo_procs_.resize(num_of_kinfo_proc);
      len = num_of_kinfo_proc * sizeof(struct kinfo_proc);
      if (sysctl(mib, arraysize(mib), &kinfo_procs_[0], &len, NULL, 0) < 0) {
        // If we get a mem error, it just means we need a bigger buffer, so
        // loop around again.  Anything else is a real error and give up.
        if (errno != ENOMEM) {
          DLOG(ERROR) << "failed to get the process list";
          kinfo_procs_.resize(0);
          done = true;
        }
      } else {
        // Got the list, just make sure we're sized exactly right
        size_t num_of_kinfo_proc = len / sizeof(struct kinfo_proc);
        kinfo_procs_.resize(num_of_kinfo_proc);
        done = true;
      }
    }
  } while (!done && (try_num++ < max_tries));

  if (!done) {
    DLOG(ERROR) << "failed to collect the process list in a few tries";
    kinfo_procs_.resize(0);
  }
}

ProcessIterator::~ProcessIterator() {
}

bool ProcessIterator::CheckForNextProcess() {
  std::string data;
  for (; index_of_kinfo_proc_ < kinfo_procs_.size(); ++index_of_kinfo_proc_) {
    kinfo_proc& kinfo = kinfo_procs_[index_of_kinfo_proc_];

    // Skip processes just awaiting collection
    if ((kinfo.p_pid > 0) && (kinfo.p_stat == SZOMB))
      continue;

    int mib[] = { CTL_KERN, KERN_PROC_ARGS, kinfo.p_pid };

    // Find out what size buffer we need.
    size_t data_len = 0;
    if (sysctl(mib, arraysize(mib), NULL, &data_len, NULL, 0) < 0) {
      DVPLOG(1) << "failed to figure out the buffer size for a commandline";
      continue;
    }

    data.resize(data_len);
    if (sysctl(mib, arraysize(mib), &data[0], &data_len, NULL, 0) < 0) {
      DVPLOG(1) << "failed to fetch a commandline";
      continue;
    }

    // |data| contains all the command line parameters of the process, separated
    // by blocks of one or more null characters. We tokenize |data| into a
    // vector of strings using '\0' as a delimiter and populate
    // |entry_.cmd_line_args_|.
    std::string delimiters;
    delimiters.push_back('\0');
    Tokenize(data, delimiters, &entry_.cmd_line_args_);

    // |data| starts with the full executable path followed by a null character.
    // We search for the first instance of '\0' and extract everything before it
    // to populate |entry_.exe_file_|.
    size_t exec_name_end = data.find('\0');
    if (exec_name_end == std::string::npos) {
      DLOG(ERROR) << "command line data didn't match expected format";
      continue;
    }

    entry_.pid_ = kinfo.p_pid;
    entry_.ppid_ = kinfo.p_ppid;
    entry_.gid_ = kinfo.p__pgid;
    size_t last_slash = data.rfind('/', exec_name_end);
    if (last_slash == std::string::npos)
      entry_.exe_file_.assign(data, 0, exec_name_end);
    else
      entry_.exe_file_.assign(data, last_slash + 1,
                              exec_name_end - last_slash - 1);
    // Start w/ the next entry next time through
    ++index_of_kinfo_proc_;
    // Done
    return true;
  }
  return false;
}

bool NamedProcessIterator::IncludeEntry() {
  return (executable_name_ == entry().exe_file() &&
          ProcessIterator::IncludeEntry());
}

ProcessMetrics::ProcessMetrics(ProcessHandle process)
    : process_(process),
      last_time_(0),
      last_system_time_(0),
      last_cpu_(0) {

  processor_count_ = base::SysInfo::NumberOfProcessors();
}

// static
ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
  return new ProcessMetrics(process);
}

size_t ProcessMetrics::GetPagefileUsage() const {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
}

size_t ProcessMetrics::GetPeakPagefileUsage() const {

  return 0;
}

size_t ProcessMetrics::GetWorkingSetSize() const {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return -1;

  return info.p_vm_rssize * getpagesize();
}

size_t ProcessMetrics::GetPeakWorkingSetSize() const {

  return 0;
}

bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
                                    size_t* shared_bytes) {
  WorkingSetKBytes ws_usage;

  if (!GetWorkingSetKBytes(&ws_usage))
    return false;

  if (private_bytes)
    *private_bytes = ws_usage.priv << 10;

  if (shared_bytes)
    *shared_bytes = ws_usage.shared * 1024;

  return true;
}

bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
// TODO(bapt) be sure we can't be precise
  size_t priv = GetWorkingSetSize();
  if (!priv)
    return false;
  ws_usage->priv = priv / 1024;
  ws_usage->shareable = 0;
  ws_usage->shared = 0;

  return true;
}

bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
  return false;
}

static int GetProcessCPU(pid_t pid) {
  struct kinfo_proc info;
  size_t length;
  int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid,
                sizeof(struct kinfo_proc), 0 };

  if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
    return -1;

  mib[5] = (length / sizeof(struct kinfo_proc));

  if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
    return 0;

  return info.p_pctcpu;
}

double ProcessMetrics::GetCPUUsage() {
  struct timeval now;

  int retval = gettimeofday(&now, NULL);
  if (retval)
    return 0;

  int64 time = TimeValToMicroseconds(now);

  if (last_time_ == 0) {
    // First call, just set the last values.
    last_time_ = time;
    last_cpu_ = GetProcessCPU(process_);
    return 0;
  }

  int64 time_delta = time - last_time_;
  DCHECK_NE(time_delta, 0);

  if (time_delta == 0)
    return 0;

  int cpu = GetProcessCPU(process_);

  last_time_ = time;
  last_cpu_ = cpu;

  double percentage = static_cast<double>((cpu * 100.0) / FSCALE);

  return percentage;
}

size_t GetSystemCommitCharge() {
  int mib[] = { CTL_VM, VM_METER };
  int pagesize;
  struct vmtotal vmtotal;
  unsigned long mem_total, mem_free, mem_inactive;
  size_t len = sizeof(vmtotal);

  if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
    return 0;

  mem_total = vmtotal.t_vm;
  mem_free = vmtotal.t_free;
  mem_inactive = vmtotal.t_vm - vmtotal.t_avm;

  pagesize = getpagesize();

  return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
}

void EnableTerminationOnOutOfMemory() {
}

void EnableTerminationOnHeapCorruption() {
}

}  // namespace base
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: opcodes.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 21:34:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OPCODES_HXX
#define _OPCODES_HXX

#include "sbintern.hxx"

#ifdef MTW
#undef _NUMBER
#endif

// Ein Opcode ist entweder 1, 3 oder 5 Bytes lang, je nach numerischen
// Wert des Opcodes (s.u.).

enum SbiOpcode {
    // Alle Opcodes ohne Operanden
    _NOP = 0,

    SbOP0_START = _NOP,

    // Operatoren
    // die folgenden Operatoren sind genauso angeordnet
    // wie der enum SbxVarOp
    _EXP, _MUL, _DIV, _MOD, _PLUS, _MINUS, _NEG,
    _EQ,  _NE,  _LT,  _GT, _LE, _GE,
    _IDIV, _AND, _OR, _XOR, _EQV, _IMP, _NOT,
    _CAT,
    // Ende enum SbxVarOp
    _LIKE, _IS,
    // Laden/speichern
    _ARGC,              // neuen Argv einrichten
    _ARGV,              // TOS ==> aktueller Argv
    _INPUT,             // Input ==> TOS
    _LINPUT,            // Line Input ==> TOS
    _GET,               // TOS anfassen
    _SET,               // Speichern Objekt TOS ==> TOS-1
    _PUT,               // TOS ==> TOS-1
    _PUTC,              // TOS ==> TOS-1, dann ReadOnly
    _DIM,               // DIM
    _REDIM,             // REDIM
    _REDIMP,            // REDIM PRESERVE
    _ERASE,             // TOS loeschen
    // Verzweigen
    _STOP,              // Programmende
    _INITFOR,           // FOR-Variable initialisieren
    _NEXT,              // FOR-Variable inkrementieren
    _CASE,              // Anfang CASE
    _ENDCASE,           // Ende CASE
    _STDERROR,          // Standard-Fehlerbehandlung
    _NOERROR,           // keine Fehlerbehandlung
    _LEAVE,             // UP verlassen
    // E/A
    _CHANNEL,           // TOS = Kanalnummer
    _BPRINT,            // print TOS
    _PRINTF,            // print TOS in field
    _BWRITE,            // write TOS
    _RENAME,            // Rename Tos+1 to Tos
    _PROMPT,            // TOS = Prompt for Input
    _RESTART,           // Restartpunkt definieren
    _CHAN0,             // I/O-Kanal 0
    // Sonstiges
    _EMPTY,             // Leeren Ausdruck auf Stack
    _ERROR,             // TOS = Fehlercode
    _LSET,              // Speichern Objekt TOS ==> TOS-1
    _RSET,              // Speichern Objekt TOS ==> TOS-1
    _REDIMP_ERASE,      // Copies array to be later used by REDIM PRESERVE before erasing it
    _INITFOREACH,
    SbOP0_END,

    // Alle Opcodes mit einem Operanden

    _NUMBER = 0x40,     // Laden einer numerischen Konstanten (+ID)

    SbOP1_START = _NUMBER,

    _SCONST,            // Laden einer Stringkonstanten (+ID)
    _CONST,             // Immediate Load (+Wert)
    _ARGN,              // Speichern eines named Args in Argv (+StringID)
    _PAD,               // String auf feste Laenge bringen (+Laenge)
    // Verzweigungen
    _JUMP,              // Sprung (+Target)
    _JUMPT,             // TOS auswerten, bedingter Sprung (+Target)
    _JUMPF,             // TOS auswerten, bedingter Sprung (+Target)
    _ONJUMP,            // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
    _GOSUB,             // UP-Aufruf (+Target)
    _RETURN,            // UP-Return (+0 oder Target)
    _TESTFOR,           // FOR-Variable testen, inkrementieren (+Endlabel)
    _CASETO,            // Tos+1 <= Case <= Tos, 2xremove (+Target)
    _ERRHDL,            // Fehler-Handler (+Offset)
    _RESUME,            // Resume nach Fehlern (+0 or 1 or Label)
    // E/A
    _CLOSE,             // (+Kanal/0)
    _PRCHAR,            // (+char)
    // Verwaltung
    _SETCLASS,          // Set + Klassennamen testen (+StringId)
    _TESTCLASS,         // Check TOS class (+StringId)
    _LIB,               // Libnamen fuer Declare-Procs setzen (+StringId)
    _BASED,             // TOS wird um BASE erhoeht, BASE davor gepusht (+base)
    // Typanpassung im Argv
    _ARGTYP,            // Letzten Parameter in Argv konvertieren (+Typ)

    SbOP1_END,

    // Alle Opcodes mit zwei Operanden

    _RTL = 0x80,        // Laden aus RTL (+StringID+Typ)

    SbOP2_START = _RTL,

    _FIND,              // Laden (+StringID+Typ)
    _ELEM,              // Laden Element (+StringID+Typ)
    _PARAM,             // Parameter (+Offset+Typ)
    // Verzweigen
    _CALL,              // DECLARE-Methode rufen (+StringID+Typ)
    _CALLC,             // Cdecl-DECLARE-Methode rufen (+StringID+Typ)
    _CASEIS,            // Case-Test (+Test-Opcode+True-Target)
    // Verwaltung
    _STMNT,             // Beginn eines Statements (+Line+Col)
    // E/A
    _OPEN,              // (+SvStreamFlags+Flags)
    // Objekte
    _LOCAL,             // Lokale Variable definieren (+StringID+Typ)
    _PUBLIC,            // Modulglobale Variable (+StringID+Typ)
    _GLOBAL,            // Globale Variable definieren, public-Anweisung (+StringID+Typ)
    _CREATE,            // Objekt kreieren (+StringId+StringID)
    _STATIC,            // Statische Variabl (+StringID+Typ) JSM
    _TCREATE,           // User Defined Objekt kreieren
    _DCREATE,           // Objekt-Array kreieren (+StringId+StringID)
    _GLOBAL_P,          // Globale Variable definieren, die beim Neustart von Basic
                        // nicht ueberschrieben wird, P=PERSIST (+StringID+Typ)
    _FIND_G,            // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
    _DCREATE_REDIMP,    // Objekt-Array redimensionieren (+StringId+StringID)
    _FIND_CM,           // Search inside a class module (CM) to enable global search in time
    SbOP2_END

};

#endif
<commit_msg>INTEGRATION: CWS ab17fixes (1.7.10); FILE MERGED<commit_after>/*************************************************************************
 *
 *  $RCSfile: opcodes.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-29 13:00:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OPCODES_HXX
#define _OPCODES_HXX

#include "sbintern.hxx"

#ifdef MTW
#undef _NUMBER
#endif

// Ein Opcode ist entweder 1, 3 oder 5 Bytes lang, je nach numerischen
// Wert des Opcodes (s.u.).

enum SbiOpcode {
    // Alle Opcodes ohne Operanden
    _NOP = 0,

    SbOP0_START = _NOP,

    // Operatoren
    // die folgenden Operatoren sind genauso angeordnet
    // wie der enum SbxVarOp
    _EXP, _MUL, _DIV, _MOD, _PLUS, _MINUS, _NEG,
    _EQ,  _NE,  _LT,  _GT, _LE, _GE,
    _IDIV, _AND, _OR, _XOR, _EQV, _IMP, _NOT,
    _CAT,
    // Ende enum SbxVarOp
    _LIKE, _IS,
    // Laden/speichern
    _ARGC,              // neuen Argv einrichten
    _ARGV,              // TOS ==> aktueller Argv
    _INPUT,             // Input ==> TOS
    _LINPUT,            // Line Input ==> TOS
    _GET,               // TOS anfassen
    _SET,               // Speichern Objekt TOS ==> TOS-1
    _PUT,               // TOS ==> TOS-1
    _PUTC,              // TOS ==> TOS-1, dann ReadOnly
    _DIM,               // DIM
    _REDIM,             // REDIM
    _REDIMP,            // REDIM PRESERVE
    _ERASE,             // TOS loeschen
    // Verzweigen
    _STOP,              // Programmende
    _INITFOR,           // FOR-Variable initialisieren
    _NEXT,              // FOR-Variable inkrementieren
    _CASE,              // Anfang CASE
    _ENDCASE,           // Ende CASE
    _STDERROR,          // Standard-Fehlerbehandlung
    _NOERROR,           // keine Fehlerbehandlung
    _LEAVE,             // UP verlassen
    // E/A
    _CHANNEL,           // TOS = Kanalnummer
    _BPRINT,            // print TOS
    _PRINTF,            // print TOS in field
    _BWRITE,            // write TOS
    _RENAME,            // Rename Tos+1 to Tos
    _PROMPT,            // TOS = Prompt for Input
    _RESTART,           // Restartpunkt definieren
    _CHAN0,             // I/O-Kanal 0
    // Sonstiges
    _EMPTY,             // Leeren Ausdruck auf Stack
    _ERROR,             // TOS = Fehlercode
    _LSET,              // Speichern Objekt TOS ==> TOS-1
    _RSET,              // Speichern Objekt TOS ==> TOS-1
    _REDIMP_ERASE,      // Copies array to be later used by REDIM PRESERVE before erasing it
    _INITFOREACH,
    SbOP0_END,

    // Alle Opcodes mit einem Operanden

    _NUMBER = 0x40,     // Laden einer numerischen Konstanten (+ID)

    SbOP1_START = _NUMBER,

    _SCONST,            // Laden einer Stringkonstanten (+ID)
    _CONST,             // Immediate Load (+Wert)
    _ARGN,              // Speichern eines named Args in Argv (+StringID)
    _PAD,               // String auf feste Laenge bringen (+Laenge)
    // Verzweigungen
    _JUMP,              // Sprung (+Target)
    _JUMPT,             // TOS auswerten, bedingter Sprung (+Target)
    _JUMPF,             // TOS auswerten, bedingter Sprung (+Target)
    _ONJUMP,            // TOS auswerten, Sprung in JUMP-Tabelle (+MaxVal)
    _GOSUB,             // UP-Aufruf (+Target)
    _RETURN,            // UP-Return (+0 oder Target)
    _TESTFOR,           // FOR-Variable testen, inkrementieren (+Endlabel)
    _CASETO,            // Tos+1 <= Case <= Tos, 2xremove (+Target)
    _ERRHDL,            // Fehler-Handler (+Offset)
    _RESUME,            // Resume nach Fehlern (+0 or 1 or Label)
    // E/A
    _CLOSE,             // (+Kanal/0)
    _PRCHAR,            // (+char)
    // Verwaltung
    _SETCLASS,          // Set + Klassennamen testen (+StringId)
    _TESTCLASS,         // Check TOS class (+StringId)
    _LIB,               // Libnamen fuer Declare-Procs setzen (+StringId)
    _BASED,             // TOS wird um BASE erhoeht, BASE davor gepusht (+base)
    // Typanpassung im Argv
    _ARGTYP,            // Letzten Parameter in Argv konvertieren (+Typ)

    SbOP1_END,

    // Alle Opcodes mit zwei Operanden

    _RTL = 0x80,        // Laden aus RTL (+StringID+Typ)

    SbOP2_START = _RTL,

    _FIND,              // Laden (+StringID+Typ)
    _ELEM,              // Laden Element (+StringID+Typ)
    _PARAM,             // Parameter (+Offset+Typ)
    // Verzweigen
    _CALL,              // DECLARE-Methode rufen (+StringID+Typ)
    _CALLC,             // Cdecl-DECLARE-Methode rufen (+StringID+Typ)
    _CASEIS,            // Case-Test (+Test-Opcode+True-Target)
    // Verwaltung
    _STMNT,             // Beginn eines Statements (+Line+Col)
    // E/A
    _OPEN,              // (+SvStreamFlags+Flags)
    // Objekte
    _LOCAL,             // Lokale Variable definieren (+StringID+Typ)
    _PUBLIC,            // Modulglobale Variable (+StringID+Typ)
    _GLOBAL,            // Globale Variable definieren, public-Anweisung (+StringID+Typ)
    _CREATE,            // Objekt kreieren (+StringId+StringID)
    _STATIC,            // Statische Variabl (+StringID+Typ) JSM
    _TCREATE,           // User Defined Objekt kreieren
    _DCREATE,           // Objekt-Array kreieren (+StringId+StringID)
    _GLOBAL_P,          // Globale Variable definieren, die beim Neustart von Basic
                        // nicht ueberschrieben wird, P=PERSIST (+StringID+Typ)
    _FIND_G,            // Sucht globale Variable mit Spezialbehandlung wegen _GLOBAL_P
    _DCREATE_REDIMP,    // Objekt-Array redimensionieren (+StringId+StringID)
    _FIND_CM,           // Search inside a class module (CM) to enable global search in time
    SbOP2_END

};

#endif
<|endoftext|>


<commit_before><commit_msg>coverity#984078 Uninitialized scalar field<commit_after><|endoftext|>