<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is added by mcw.
 */

#include <sal/config.h>
#include <unotest/filters-test.hxx>
#include <test/bootstrapfixture.hxx>
#include <rtl/strbuf.hxx>
#include <osl/file.hxx>

#include "scdll.hxx"
#include <sfx2/app.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/sfxmodelfactory.hxx>
#include <svl/stritem.hxx>

#define TEST_BUG_FILES 0

#include "helper/qahelper.hxx"

#include "calcconfig.hxx"
#include "interpre.hxx"

#include "docsh.hxx"
#include "postit.hxx"
#include "patattr.hxx"
#include "scitems.hxx"
#include "document.hxx"
#include "cellform.hxx"
#include "drwlayer.hxx"
#include "userdat.hxx"
#include "formulacell.hxx"

#include <svx/svdpage.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

/* Implementation of Filters test */

class ScOpenclTest
    : public test::FiltersTest
    , public ScBootstrapFixture
{
public:
    ScOpenclTest();
    void enableOpenCL(ScDocShell* pShell);
    void SetEnv();
    virtual void setUp();
    virtual void tearDown();

    virtual bool load( const OUString &rFilter, const OUString &rURL,
            const OUString &rUserData, unsigned int nFilterFlags,
            unsigned int nClipboardID, unsigned int nFilterVersion);
    void testSharedFormulaXLS();
    void testSharedFormulaXLSGroundWater();
    void testSharedFormulaXLSStockHistory();
    void testFinacialFormula();

    CPPUNIT_TEST_SUITE(ScOpenclTest);
    CPPUNIT_TEST(testSharedFormulaXLS);
    CPPUNIT_TEST(testSharedFormulaXLSGroundWater);
    CPPUNIT_TEST(testSharedFormulaXLSStockHistory);
    CPPUNIT_TEST(testFinacialFormula);
    CPPUNIT_TEST_SUITE_END();

private:
    uno::Reference<uno::XInterface> m_xCalcComponent;
};

bool ScOpenclTest::load(const OUString &rFilter, const OUString &rURL,
    const OUString &rUserData, unsigned int nFilterFlags,
        unsigned int nClipboardID, unsigned int nFilterVersion)
{
    ScDocShellRef xDocShRef = ScBootstrapFixture::load(rURL, rFilter, rUserData,
        OUString(), nFilterFlags, nClipboardID, nFilterVersion );
    bool bLoaded = xDocShRef.Is();
    //reference counting of ScDocShellRef is very confused.
    if (bLoaded)
        xDocShRef->DoClose();
    return bLoaded;
}
void ScOpenclTest::SetEnv()
{
    #ifdef WIN32
        char *newpathfull  = (char *)malloc(1024);
        newpathfull= "PATH=;C:\\Program Files (x86)\\AMD APP\\bin\\x86_64;";
        putenv(newpathfull);
    #else
        return;
    #endif
}
void ScOpenclTest::enableOpenCL(ScDocShell* pShell)
{
    ScModule* pScMod = SC_MOD();
    ScFormulaOptions rOpt = pScMod->GetFormulaOptions();
    ScCalcConfig maSavedConfig = rOpt.GetCalcConfig();
    maSavedConfig.mbOpenCLEnabled = true;
    rOpt.SetCalcConfig(maSavedConfig);
    pShell->SetFormulaOptions(rOpt);
}

void ScOpenclTest::testSharedFormulaXLSStockHistory()
{
#if 1
    ScDocShellRef xDocSh = loadDoc("stock-history.", XLS);

    enableOpenCL(xDocSh);

    ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);

    ScDocShellRef xDocShRes = loadDoc("stock-history.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 33; i < 44; ++i)
    {   // Cell H34:H44 in S&P 500 (tab 1)
        double fLibre = pDoc->GetValue(ScAddress(7, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(7, i, 1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, 0.0001*fExcel);
    }

    for (SCROW i = 33; i < 44; ++i)
    {   // Cell J34:J44 in S&P 500 (tab 1)
        double fLibre = pDoc->GetValue(ScAddress(9, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(9, i, 1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, 0.0001*fExcel);
    }

    xDocSh->DoClose();
    xDocShRes->DoClose();
#endif
}

void ScOpenclTest::testSharedFormulaXLSGroundWater()
{
    ScDocShellRef xDocSh = loadDoc("ground-water-daily.", XLS);

    enableOpenCL(xDocSh);

    ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);

    ScDocShellRef xDocShRes = loadDoc("ground-water-daily.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 5; i <= 77; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(11,i,1));
        double fExcel = pDocRes->GetValue(ScAddress(11,i,1));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}

void ScOpenclTest::testSharedFormulaXLS()
{
    ScDocShellRef xDocSh = loadDoc("sum_ex.", XLS);
    enableOpenCL(xDocSh);
    ScDocument *pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);
    ScDocShellRef xDocShRes = loadDoc("sum_ex.", XLS);
    ScDocument *pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    // AMLOEXT-5
    for (SCROW i = 0; i < 5; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-6
    for (SCROW i = 6; i < 14; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-8
    for (SCROW i = 15; i < 18; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-10
    for (SCROW i = 19; i < 22; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-9
    for (SCROW i = 23; i < 25; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        //double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        // There seems to be a bug in LibreOffice beta
        CPPUNIT_ASSERT_EQUAL(/*fExcel*/ 60.0, fLibre);
    }

    // AMLOEXT-9
    for (SCROW i = 25; i < 27; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-11
    for (SCROW i = 28; i < 35; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-11; workaround for a Calc beta bug
    CPPUNIT_ASSERT_EQUAL(25.0, pDoc->GetValue(ScAddress(2, 35, 0)));
    CPPUNIT_ASSERT_EQUAL(24.0, pDoc->GetValue(ScAddress(2, 36, 0)));

    // AMLOEXT-12
    for (SCROW i = 38; i < 43; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-14
    for (SCROW i = 5; i < 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(5, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(5, i, 1));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-15, AMLOEXT-16, and AMLOEXT-17
    for (SCROW i = 5; i < 10; ++i)
    {
        for (SCCOL j = 6; j < 11; ++j)
        {
            double fLibre = pDoc->GetValue(ScAddress(j, i, 1));
            double fExcel = pDocRes->GetValue(ScAddress(j, i, 1));
            CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre,
                fabs(fExcel*0.0001));
        }
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}
void ScOpenclTest::testFinacialFormula()
{
    ScDocShellRef xDocSh = loadDoc("FinancialFormulaTest.", XLS);
    enableOpenCL(xDocSh);   ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);   xDocSh->DoHardRecalc(true);
    ScDocShellRef xDocShRes = loadDoc("FinancialFormulaTest.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 1; i <= 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2,i,0));
        double fExcel = pDocRes->GetValue(ScAddress(2,i,0));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
    }
    // AMLOEXT-22
    for (SCROW i = 1; i <= 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(6,i,1));
        double fExcel = pDocRes->GetValue(ScAddress(6,i,1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}

ScOpenclTest::ScOpenclTest()
      : ScBootstrapFixture( "/sc/qa/unit/data" )
{
}

void ScOpenclTest::setUp()
{
    test::BootstrapFixture::setUp();
    SetEnv();
    // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
    // which is a private symbol to us, gets called
    m_xCalcComponent =
        getMultiServiceFactory()->
            createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
    CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
}

void ScOpenclTest::tearDown()
{
    uno::Reference< lang::XComponent >
        ( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
    test::BootstrapFixture::tearDown();
}

CPPUNIT_TEST_SUITE_REGISTRATION(ScOpenclTest);

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Testcase for Norminal<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is added by mcw.
 */

#include <sal/config.h>
#include <unotest/filters-test.hxx>
#include <test/bootstrapfixture.hxx>
#include <rtl/strbuf.hxx>
#include <osl/file.hxx>

#include "scdll.hxx"
#include <sfx2/app.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/sfxmodelfactory.hxx>
#include <svl/stritem.hxx>

#define TEST_BUG_FILES 0

#include "helper/qahelper.hxx"

#include "calcconfig.hxx"
#include "interpre.hxx"

#include "docsh.hxx"
#include "postit.hxx"
#include "patattr.hxx"
#include "scitems.hxx"
#include "document.hxx"
#include "cellform.hxx"
#include "drwlayer.hxx"
#include "userdat.hxx"
#include "formulacell.hxx"

#include <svx/svdpage.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

/* Implementation of Filters test */

class ScOpenclTest
    : public test::FiltersTest
    , public ScBootstrapFixture
{
public:
    ScOpenclTest();
    void enableOpenCL(ScDocShell* pShell);
    void SetEnv();
    virtual void setUp();
    virtual void tearDown();

    virtual bool load( const OUString &rFilter, const OUString &rURL,
            const OUString &rUserData, unsigned int nFilterFlags,
            unsigned int nClipboardID, unsigned int nFilterVersion);
    void testSharedFormulaXLS();
    void testSharedFormulaXLSGroundWater();
    void testSharedFormulaXLSStockHistory();
    void testFinacialFormula();

    CPPUNIT_TEST_SUITE(ScOpenclTest);
    CPPUNIT_TEST(testSharedFormulaXLS);
    CPPUNIT_TEST(testSharedFormulaXLSGroundWater);
    CPPUNIT_TEST(testSharedFormulaXLSStockHistory);
    CPPUNIT_TEST(testFinacialFormula);
    CPPUNIT_TEST_SUITE_END();

private:
    uno::Reference<uno::XInterface> m_xCalcComponent;
};

bool ScOpenclTest::load(const OUString &rFilter, const OUString &rURL,
    const OUString &rUserData, unsigned int nFilterFlags,
        unsigned int nClipboardID, unsigned int nFilterVersion)
{
    ScDocShellRef xDocShRef = ScBootstrapFixture::load(rURL, rFilter, rUserData,
        OUString(), nFilterFlags, nClipboardID, nFilterVersion );
    bool bLoaded = xDocShRef.Is();
    //reference counting of ScDocShellRef is very confused.
    if (bLoaded)
        xDocShRef->DoClose();
    return bLoaded;
}
void ScOpenclTest::SetEnv()
{
    #ifdef WIN32
        char *newpathfull  = (char *)malloc(1024);
        newpathfull= "PATH=;C:\\Program Files (x86)\\AMD APP\\bin\\x86_64;";
        putenv(newpathfull);
    #else
        return;
    #endif
}
void ScOpenclTest::enableOpenCL(ScDocShell* pShell)
{
    ScModule* pScMod = SC_MOD();
    ScFormulaOptions rOpt = pScMod->GetFormulaOptions();
    ScCalcConfig maSavedConfig = rOpt.GetCalcConfig();
    maSavedConfig.mbOpenCLEnabled = true;
    rOpt.SetCalcConfig(maSavedConfig);
    pShell->SetFormulaOptions(rOpt);
}

void ScOpenclTest::testSharedFormulaXLSStockHistory()
{
#if 1
    ScDocShellRef xDocSh = loadDoc("stock-history.", XLS);

    enableOpenCL(xDocSh);

    ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);

    ScDocShellRef xDocShRes = loadDoc("stock-history.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 33; i < 44; ++i)
    {   // Cell H34:H44 in S&P 500 (tab 1)
        double fLibre = pDoc->GetValue(ScAddress(7, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(7, i, 1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, 0.0001*fExcel);
    }

    for (SCROW i = 33; i < 44; ++i)
    {   // Cell J34:J44 in S&P 500 (tab 1)
        double fLibre = pDoc->GetValue(ScAddress(9, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(9, i, 1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, 0.0001*fExcel);
    }

    xDocSh->DoClose();
    xDocShRes->DoClose();
#endif
}

void ScOpenclTest::testSharedFormulaXLSGroundWater()
{
    ScDocShellRef xDocSh = loadDoc("ground-water-daily.", XLS);

    enableOpenCL(xDocSh);

    ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);

    ScDocShellRef xDocShRes = loadDoc("ground-water-daily.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 5; i <= 77; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(11,i,1));
        double fExcel = pDocRes->GetValue(ScAddress(11,i,1));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}

void ScOpenclTest::testSharedFormulaXLS()
{
    ScDocShellRef xDocSh = loadDoc("sum_ex.", XLS);
    enableOpenCL(xDocSh);
    ScDocument *pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);
    xDocSh->DoHardRecalc(true);
    ScDocShellRef xDocShRes = loadDoc("sum_ex.", XLS);
    ScDocument *pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    // AMLOEXT-5
    for (SCROW i = 0; i < 5; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-6
    for (SCROW i = 6; i < 14; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-8
    for (SCROW i = 15; i < 18; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-10
    for (SCROW i = 19; i < 22; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-9
    for (SCROW i = 23; i < 25; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        //double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        // There seems to be a bug in LibreOffice beta
        CPPUNIT_ASSERT_EQUAL(/*fExcel*/ 60.0, fLibre);
    }

    // AMLOEXT-9
    for (SCROW i = 25; i < 27; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-11
    for (SCROW i = 28; i < 35; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }
    // AMLOEXT-11; workaround for a Calc beta bug
    CPPUNIT_ASSERT_EQUAL(25.0, pDoc->GetValue(ScAddress(2, 35, 0)));
    CPPUNIT_ASSERT_EQUAL(24.0, pDoc->GetValue(ScAddress(2, 36, 0)));

    // AMLOEXT-12
    for (SCROW i = 38; i < 43; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2, i, 0));
        double fExcel = pDocRes->GetValue(ScAddress(2, i, 0));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-14
    for (SCROW i = 5; i < 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(5, i, 1));
        double fExcel = pDocRes->GetValue(ScAddress(5, i, 1));
        CPPUNIT_ASSERT_EQUAL(fExcel, fLibre);
    }

    // AMLOEXT-15, AMLOEXT-16, and AMLOEXT-17
    for (SCROW i = 5; i < 10; ++i)
    {
        for (SCCOL j = 6; j < 11; ++j)
        {
            double fLibre = pDoc->GetValue(ScAddress(j, i, 1));
            double fExcel = pDocRes->GetValue(ScAddress(j, i, 1));
            CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre,
                fabs(fExcel*0.0001));
        }
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}
void ScOpenclTest::testFinacialFormula()
{
    ScDocShellRef xDocSh = loadDoc("FinancialFormulaTest.", XLS);
    enableOpenCL(xDocSh);   ScDocument* pDoc = xDocSh->GetDocument();
    CPPUNIT_ASSERT(pDoc);   xDocSh->DoHardRecalc(true);
    ScDocShellRef xDocShRes = loadDoc("FinancialFormulaTest.", XLS);
    ScDocument* pDocRes = xDocShRes->GetDocument();
    CPPUNIT_ASSERT(pDocRes);
    // Check the results of formula cells in the shared formula range.
    for (SCROW i = 1; i <= 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2,i,0));
        double fExcel = pDocRes->GetValue(ScAddress(2,i,0));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
    }
    // AMLOEXT-22
    for (SCROW i = 1; i <= 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(6,i,1));
        double fExcel = pDocRes->GetValue(ScAddress(6,i,1));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
    }
        //[AMLOEXT-23]
    for (SCROW i = 1; i <= 10; ++i)
    {
        double fLibre = pDoc->GetValue(ScAddress(2,i,2));
        double fExcel = pDocRes->GetValue(ScAddress(2,i,2));
        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
    }
    xDocSh->DoClose();
    xDocShRes->DoClose();
}

ScOpenclTest::ScOpenclTest()
      : ScBootstrapFixture( "/sc/qa/unit/data" )
{
}

void ScOpenclTest::setUp()
{
    test::BootstrapFixture::setUp();
    SetEnv();
    // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
    // which is a private symbol to us, gets called
    m_xCalcComponent =
        getMultiServiceFactory()->
            createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
    CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
}

void ScOpenclTest::tearDown()
{
    uno::Reference< lang::XComponent >
        ( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
    test::BootstrapFixture::tearDown();
}

CPPUNIT_TEST_SUITE_REGISTRATION(ScOpenclTest);

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>create one fewer arrays<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2016 ScyllaDB
 */

/*
 * 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/>.
 */

namespace gms {
enum class application_state:int {STATUS = 0,
        LOAD,
        SCHEMA,
        DC,
        RACK,
        RELEASE_VERSION,
        REMOVAL_COORDINATOR,
        INTERNAL_IP,
        RPC_ADDRESS,
        SEVERITY,
        NET_VERSION,
        HOST_ID,
        TOKENS
};

class inet_address final {
  uint32_t raw_addr();
};

class versioned_value {
    sstring value;
    int version;
};

class heart_beat_state {
    int32_t get_generation();
    int32_t get_heart_beat_version();
};

class endpoint_state {
    gms::heart_beat_state get_heart_beat_state();
    std::map<gms::application_state, gms::versioned_value> get_application_state_map();
};

class gossip_digest {
    gms::inet_address get_endpoint();
    int32_t get_generation();
    int32_t get_max_version();
};

class gossip_digest_ack {
    std::vector<gms::gossip_digest> get_gossip_digest_list();
    std::map<gms::inet_address, gms::endpoint_state> get_endpoint_state_map();
};
}
<commit_msg>idl: Add gossip_digest_ack2<commit_after>/*
 * Copyright 2016 ScyllaDB
 */

/*
 * 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/>.
 */

namespace gms {
enum class application_state:int {STATUS = 0,
        LOAD,
        SCHEMA,
        DC,
        RACK,
        RELEASE_VERSION,
        REMOVAL_COORDINATOR,
        INTERNAL_IP,
        RPC_ADDRESS,
        SEVERITY,
        NET_VERSION,
        HOST_ID,
        TOKENS
};

class inet_address final {
  uint32_t raw_addr();
};

class versioned_value {
    sstring value;
    int version;
};

class heart_beat_state {
    int32_t get_generation();
    int32_t get_heart_beat_version();
};

class endpoint_state {
    gms::heart_beat_state get_heart_beat_state();
    std::map<gms::application_state, gms::versioned_value> get_application_state_map();
};

class gossip_digest {
    gms::inet_address get_endpoint();
    int32_t get_generation();
    int32_t get_max_version();
};

class gossip_digest_ack {
    std::vector<gms::gossip_digest> get_gossip_digest_list();
    std::map<gms::inet_address, gms::endpoint_state> get_endpoint_state_map();
};

class gossip_digest_ack2 {
    std::map<gms::inet_address, gms::endpoint_state> get_endpoint_state_map();
};

}
<|endoftext|>


<commit_before>#include "../../include/base/ErrorInfo.hpp"

namespace cutehmi {
namespace base {

QString ErrorInfo::toString() const
{
	QString result = str;
	result += "\n[error class: ";
	result += errClass;
	result += " code: ";
	result += code;
	result += "]";
	return result;
}

}
}

//(c)MP: Copyright © 2017, Michal Policht. All rights reserved.
//(c)MP: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
<commit_msg>Fix code to string conversion.<commit_after>#include "../../include/base/ErrorInfo.hpp"

namespace cutehmi {
namespace base {

QString ErrorInfo::toString() const
{
	QString result = str;
	result += "\n[error class: ";
	result += errClass;
	result += " code: ";
	result += QString::number(code);
	result += "]";
	return result;
}

}
}

//(c)MP: Copyright © 2017, Michal Policht. All rights reserved.
//(c)MP: This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: aststack.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 03:47:52 $
 *
 *  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 _RTL_ALLOC_H_
#include <rtl/alloc.h>
#endif
#ifndef _IDLC_ASTSTACK_HXX_
#include <idlc/aststack.hxx>
#endif
#ifndef _IDLC_ASTSCOPE_HXX_
#include <idlc/astscope.hxx>
#endif

#define STACKSIZE_INCREMENT 64

AstStack::AstStack()
    : m_stack((AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * STACKSIZE_INCREMENT))
    , m_size(STACKSIZE_INCREMENT)
    , m_top(0)
{
}

AstStack::~AstStack()
{
    for(sal_uInt32 i=0; i < m_top; i++)
    {
        if (m_stack[i])
            delete(m_stack[i]);
    }

    rtl_freeMemory(m_stack);
}

sal_uInt32 AstStack::depth()
{
    return m_top;
}

AstScope* AstStack::top()
{
    if (m_top < 1)
        return NULL;
    return m_stack[m_top - 1];
}

AstScope* AstStack::bottom()
{
    if (m_top == 0)
        return NULL;
    return m_stack[0];
}

AstScope* AstStack::nextToTop()
{
    AstScope *tmp, *retval;

    if (depth() < 2)
        return NULL;

    tmp = top();        // Save top
    (void) pop();       // Pop it
    retval = top();     // Get next one down
    (void) push(tmp);   // Push top back
    return retval;      // Return next one down
}

AstScope* AstStack::topNonNull()
{
    for (sal_uInt32 i = m_top; i > 0; i--)
    {
        if ( m_stack[i - 1] )
            return m_stack[i - 1];
      }
    return NULL;
}

AstStack* AstStack::push(AstScope* pScope)
{
    AstScope        **tmp;
//  AstDeclaration  *pDecl = ScopeAsDecl(pScope);
    sal_uInt32  newSize;
    sal_uInt32  i;

    // Make sure there's space for one more
    if (m_size == m_top)
    {
        newSize = m_size;
        newSize += STACKSIZE_INCREMENT;
        tmp = (AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * newSize);

        for(i=0; i < m_size; i++)
            tmp[i] = m_stack[i];

        rtl_freeMemory(m_stack);
        m_stack = tmp;
    }

    // Insert new scope
    m_stack[m_top++] = pScope;

    return this;
}

void AstStack::pop()
{
    AstScope *pScope;

    if (m_top < 1)
        return;
    pScope = m_stack[--m_top];
}

void AstStack::clear()
{
    m_top = 0;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.3.8); FILE MERGED 2006/09/01 17:31:13 kaib 1.3.8.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: aststack.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 08:13:00 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_idlc.hxx"
#ifndef _RTL_ALLOC_H_
#include <rtl/alloc.h>
#endif
#ifndef _IDLC_ASTSTACK_HXX_
#include <idlc/aststack.hxx>
#endif
#ifndef _IDLC_ASTSCOPE_HXX_
#include <idlc/astscope.hxx>
#endif

#define STACKSIZE_INCREMENT 64

AstStack::AstStack()
    : m_stack((AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * STACKSIZE_INCREMENT))
    , m_size(STACKSIZE_INCREMENT)
    , m_top(0)
{
}

AstStack::~AstStack()
{
    for(sal_uInt32 i=0; i < m_top; i++)
    {
        if (m_stack[i])
            delete(m_stack[i]);
    }

    rtl_freeMemory(m_stack);
}

sal_uInt32 AstStack::depth()
{
    return m_top;
}

AstScope* AstStack::top()
{
    if (m_top < 1)
        return NULL;
    return m_stack[m_top - 1];
}

AstScope* AstStack::bottom()
{
    if (m_top == 0)
        return NULL;
    return m_stack[0];
}

AstScope* AstStack::nextToTop()
{
    AstScope *tmp, *retval;

    if (depth() < 2)
        return NULL;

    tmp = top();        // Save top
    (void) pop();       // Pop it
    retval = top();     // Get next one down
    (void) push(tmp);   // Push top back
    return retval;      // Return next one down
}

AstScope* AstStack::topNonNull()
{
    for (sal_uInt32 i = m_top; i > 0; i--)
    {
        if ( m_stack[i - 1] )
            return m_stack[i - 1];
      }
    return NULL;
}

AstStack* AstStack::push(AstScope* pScope)
{
    AstScope        **tmp;
//  AstDeclaration  *pDecl = ScopeAsDecl(pScope);
    sal_uInt32  newSize;
    sal_uInt32  i;

    // Make sure there's space for one more
    if (m_size == m_top)
    {
        newSize = m_size;
        newSize += STACKSIZE_INCREMENT;
        tmp = (AstScope**)rtl_allocateZeroMemory(sizeof(AstScope*) * newSize);

        for(i=0; i < m_size; i++)
            tmp[i] = m_stack[i];

        rtl_freeMemory(m_stack);
        m_stack = tmp;
    }

    // Insert new scope
    m_stack[m_top++] = pScope;

    return this;
}

void AstStack::pop()
{
    AstScope *pScope;

    if (m_top < 1)
        return;
    pScope = m_stack[--m_top];
}

void AstStack::clear()
{
    m_top = 0;
}

<|endoftext|>


<commit_before>#include <rtosc/automations.h>
#include <cmath>

using namespace rtosc;

AutomationMgr::AutomationMgr(int slots, int per_slot, int control_points)
    :nslots(slots), per_slot(per_slot), active_slot(0), p(NULL), learn_queue_len(0), damaged(0)
{
    this->slots = new AutomationSlot[slots];
    memset(this->slots, 0, sizeof(AutomationSlot)*slots);
    for(int i=0; i<slots; ++i) {
        auto &s = this->slots[i];
        sprintf(s.name, "Slot %d", i);
        s.midi_cc  = -1;
        s.learning = -1;

        s.automations = new Automation[per_slot];
        memset(s.automations, 0, sizeof(Automation)*per_slot);
        for(int j=0; j<per_slot; ++j) {
            s.automations[j].map.control_points = new float[control_points];
            s.automations[j].map.npoints = control_points;
            s.automations[j].map.gain   = 100.0;
            s.automations[j].map.offset = 0.0;
        }
    }

}
AutomationMgr::~AutomationMgr(void)
{
}

void AutomationMgr::createBinding(int slot, const char *path, bool start_midi_learn)
{
    assert(p);
    const Port *port = p->apropos(path);
    if(!port) {
        fprintf(stderr, "[Zyn:Error] port '%s' does not exist\n", path);
        return;
    }
    auto meta = port->meta();
    if(!(meta.find("min") && meta.find("max"))) {
        fprintf(stderr, "No bounds for '%s' known\n", path);
        return;
    }
    int ind = -1;
    for(int i=0; i<per_slot; ++i) {
        if(slots[slot].automations[i].used == false) {
            ind = i;
            break;
        }
    }

    if(ind == -1)
        return;

    slots[slot].used = true;

    auto &au = slots[slot].automations[ind];

    au.used   = true;
    au.active = true;
    au.param_min = atof(meta["min"]);
    au.param_max = atof(meta["max"]);
    au.param_type = 'i';
    if(strstr(port->name, ":f"))
        au.param_type = 'f';
    strncpy(au.param_path, path, sizeof(au.param_path));

    au.map.gain   = 100.0;
    au.map.offset = 0;
    updateMapping(slot, ind);

    if(start_midi_learn && slots[slot].learning == -1 && slots[slot].midi_cc == -1)
        slots[slot].learning = ++learn_queue_len;

    damaged = true;

};

void AutomationMgr::updateMapping(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;

    auto &au = slots[slot_id].automations[sub];

    float mn = au.param_min;
    float mx = au.param_max;
    float center = (mn+mx)*(0.5 + au.map.offset/100.0);
    float range  = (mx-mn)*au.map.gain/100.0;

    au.map.upoints = 2;
    au.map.control_points[0] = 0;
    au.map.control_points[1] = center-range/2.0;
    au.map.control_points[2] = 1;
    au.map.control_points[3] = center+range/2.0;
}

void AutomationMgr::setSlot(int slot_id, float value)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    for(int i=0; i<per_slot; ++i)
        setSlotSub(slot_id, i, value);

    slots[slot_id].current_state = value;
}

void AutomationMgr::setSlotSub(int slot_id, int par, float value)
{
    if(slot_id >= nslots || slot_id < 0 || par >= per_slot || par < 0)
        return;
    auto &au = slots[slot_id].automations[par];
    if(au.used == false)
        return;
    const char *path = au.param_path;
    float mn = au.param_min;
    float mx = au.param_max;

    float a  = au.map.control_points[1];
    float b  = au.map.control_points[3];

    char type = au.param_type;

    char msg[256] = {0};
    if(type == 'i') {
        float v = value*(b-a) + a;
        if(v > mx)
            v = mx;
        else if(v < mn)
            v = mn;

        rtosc_message(msg, 256, path, "i", (int)roundf(v));
    } else if(type == 'f') {
        float v = value*(b-a) + a;
        if(v > mx)
            v = mx;
        else if(v < mn)
            v = mn;

        rtosc_message(msg, 256, path, "f", v);
    } else if(type == 'T' || type == 'F') {
        float v = value*(b-a) + a;
        if(v > 0.5)
            v = 1.0;
        else
            v = 0.0;

        rtosc_message(msg, 256, path, v == 1.0 ? "T" : "F");
    } else
        return;

    if(backend)
        backend(msg);
}

float AutomationMgr::getSlot(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return 0.0;
    return slots[slot_id].current_state;
}

void AutomationMgr::clearSlot(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    auto &s = slots[slot_id];
    s.active = false;
    s.used   = false;
    if(s.learning)
        learn_queue_len--;
    for(int i=0; i<nslots; ++i)
        if(slots[i].learning > s.learning)
            slots[i].learning--;
    s.learning = -1;
    s.midi_cc  = -1;
    s.current_state = 0;
    memset(s.name, 0, sizeof(s.name));
    sprintf(s.name, "Slot %d", slot_id);
    for(int i=0; i<per_slot; ++i)
        clearSlotSub(slot_id, i);
    damaged = true;
}

void AutomationMgr::clearSlotSub(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &a = slots[slot_id].automations[sub];
    a.used    = false;
    a.active  = false;
    a.relative = false;
    a.param_base_value = false;
    memset(a.param_path, 0, sizeof(a.param_path));
    a.param_type = 0;
    a.param_min  = 0;
    a.param_max  = 0;
    a.param_step = 0;
    a.map.gain   = 100;
    a.map.offset = 0;

    damaged = true;
}

void  AutomationMgr::setSlotSubGain(int slot_id, int sub, float f)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &m = slots[slot_id].automations[sub].map;
    m.gain = f;
}
float AutomationMgr::getSlotSubGain(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return 0.0;
    auto &m = slots[slot_id].automations[sub].map;
    return m.gain;
}
void  AutomationMgr::setSlotSubOffset(int slot_id, int sub, float f)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &m = slots[slot_id].automations[sub].map;
    m.offset = f;
}
float AutomationMgr::getSlotSubOffset(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return 0.0;
    auto &m = slots[slot_id].automations[sub].map;
    return m.offset;
}

void AutomationMgr::setName(int slot_id, const char *msg)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    strncpy(slots[slot_id].name, msg, sizeof(slots[slot_id].name));
    damaged = 1;
}
const char *AutomationMgr::getName(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return "";
    return slots[slot_id].name;
}
bool AutomationMgr::handleMidi(int channel, int cc, int val)
{
    int ccid = channel*128 + cc;

    bool bound_cc = false;
    for(int i=0; i<nslots; ++i) {
        if(slots[i].midi_cc == ccid) {
            bound_cc = true;
            setSlot(i, val/127.0);
        }
    }

    if(bound_cc)
        return 1;

    //No bound CC, now to see if there's something to learn
    for(int i=0; i<nslots; ++i) {
        if(slots[i].learning == 1) {
            slots[i].learning = -1;
            slots[i].midi_cc = ccid;
            for(int j=0; j<nslots; ++j)
                if(slots[j].learning > 1)
                    slots[j].learning -= 1;
            learn_queue_len--;
            setSlot(i, val/127.0);
            damaged = 1;
            break;
        }
    }
    return 0;
}

void AutomationMgr::set_ports(const class Ports &p_) {
    p = &p_;
};
//
//        AutomationSlot *slots;
//        struct AutomationMgrImpl *impl;
//};
void AutomationMgr::set_instance(void *v)
{
    this->instance = v;
}

void AutomationMgr::simpleSlope(int slot_id, int par, float slope, float offset)
{
    if(slot_id >= nslots || slot_id < 0 || par >= per_slot || par < 0)
        return;
    auto &map = slots[slot_id].automations[par].map;
    map.upoints = 2;
    map.control_points[0] = 0;
    map.control_points[1] = -(slope/2)+offset;
    map.control_points[2] =  1;
    map.control_points[3] =  slope/2+offset;

}

int AutomationMgr::free_slot(void) const
{
    for(int i=0; i<nslots; ++i)
        if(!slots[i].used)
            return i;
    return -1;
}
<commit_msg>Automations: Add Meta. Check For Blacklisted Ports<commit_after>#include <rtosc/automations.h>
#include <cmath>

using namespace rtosc;

AutomationMgr::AutomationMgr(int slots, int per_slot, int control_points)
    :nslots(slots), per_slot(per_slot), active_slot(0), p(NULL), learn_queue_len(0), damaged(0)
{
    this->slots = new AutomationSlot[slots];
    memset(this->slots, 0, sizeof(AutomationSlot)*slots);
    for(int i=0; i<slots; ++i) {
        auto &s = this->slots[i];
        sprintf(s.name, "Slot %d", i);
        s.midi_cc  = -1;
        s.learning = -1;

        s.automations = new Automation[per_slot];
        memset(s.automations, 0, sizeof(Automation)*per_slot);
        for(int j=0; j<per_slot; ++j) {
            s.automations[j].map.control_points = new float[control_points];
            s.automations[j].map.npoints = control_points;
            s.automations[j].map.gain   = 100.0;
            s.automations[j].map.offset = 0.0;
        }
    }

}
AutomationMgr::~AutomationMgr(void)
{
}

void AutomationMgr::createBinding(int slot, const char *path, bool start_midi_learn)
{
    assert(p);
    const Port *port = p->apropos(path);
    if(!port) {
        fprintf(stderr, "[Zyn:Error] port '%s' does not exist\n", path);
        return;
    }
    auto meta = port->meta();
    if(!(meta.find("min") && meta.find("max"))) {
        fprintf(stderr, "No bounds for '%s' known\n", path);
        return;
    }
    if(meta.find("internal") || meta.find("no learn")) {
        fprintf(stderr, "[Warning] port '%s' is unlearnable\n", path);
        return;
    }
    int ind = -1;
    for(int i=0; i<per_slot; ++i) {
        if(slots[slot].automations[i].used == false) {
            ind = i;
            break;
        }
    }

    if(ind == -1)
        return;

    slots[slot].used = true;

    auto &au = slots[slot].automations[ind];

    au.used   = true;
    au.active = true;
    au.param_min = atof(meta["min"]);
    au.param_max = atof(meta["max"]);
    au.param_type = 'i';
    if(strstr(port->name, ":f"))
        au.param_type = 'f';
    strncpy(au.param_path, path, sizeof(au.param_path));

    au.map.gain   = 100.0;
    au.map.offset = 0;
    updateMapping(slot, ind);

    if(start_midi_learn && slots[slot].learning == -1 && slots[slot].midi_cc == -1)
        slots[slot].learning = ++learn_queue_len;

    damaged = true;

};

void AutomationMgr::updateMapping(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;

    auto &au = slots[slot_id].automations[sub];

    float mn = au.param_min;
    float mx = au.param_max;
    float center = (mn+mx)*(0.5 + au.map.offset/100.0);
    float range  = (mx-mn)*au.map.gain/100.0;

    au.map.upoints = 2;
    au.map.control_points[0] = 0;
    au.map.control_points[1] = center-range/2.0;
    au.map.control_points[2] = 1;
    au.map.control_points[3] = center+range/2.0;
}

void AutomationMgr::setSlot(int slot_id, float value)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    for(int i=0; i<per_slot; ++i)
        setSlotSub(slot_id, i, value);

    slots[slot_id].current_state = value;
}

void AutomationMgr::setSlotSub(int slot_id, int par, float value)
{
    if(slot_id >= nslots || slot_id < 0 || par >= per_slot || par < 0)
        return;
    auto &au = slots[slot_id].automations[par];
    if(au.used == false)
        return;
    const char *path = au.param_path;
    float mn = au.param_min;
    float mx = au.param_max;

    float a  = au.map.control_points[1];
    float b  = au.map.control_points[3];

    char type = au.param_type;

    char msg[256] = {0};
    if(type == 'i') {
        float v = value*(b-a) + a;
        if(v > mx)
            v = mx;
        else if(v < mn)
            v = mn;

        rtosc_message(msg, 256, path, "i", (int)roundf(v));
    } else if(type == 'f') {
        float v = value*(b-a) + a;
        if(v > mx)
            v = mx;
        else if(v < mn)
            v = mn;

        rtosc_message(msg, 256, path, "f", v);
    } else if(type == 'T' || type == 'F') {
        float v = value*(b-a) + a;
        if(v > 0.5)
            v = 1.0;
        else
            v = 0.0;

        rtosc_message(msg, 256, path, v == 1.0 ? "T" : "F");
    } else
        return;

    if(backend)
        backend(msg);
}

float AutomationMgr::getSlot(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return 0.0;
    return slots[slot_id].current_state;
}

void AutomationMgr::clearSlot(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    auto &s = slots[slot_id];
    s.active = false;
    s.used   = false;
    if(s.learning)
        learn_queue_len--;
    for(int i=0; i<nslots; ++i)
        if(slots[i].learning > s.learning)
            slots[i].learning--;
    s.learning = -1;
    s.midi_cc  = -1;
    s.current_state = 0;
    memset(s.name, 0, sizeof(s.name));
    sprintf(s.name, "Slot %d", slot_id);
    for(int i=0; i<per_slot; ++i)
        clearSlotSub(slot_id, i);
    damaged = true;
}

void AutomationMgr::clearSlotSub(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &a = slots[slot_id].automations[sub];
    a.used    = false;
    a.active  = false;
    a.relative = false;
    a.param_base_value = false;
    memset(a.param_path, 0, sizeof(a.param_path));
    a.param_type = 0;
    a.param_min  = 0;
    a.param_max  = 0;
    a.param_step = 0;
    a.map.gain   = 100;
    a.map.offset = 0;

    damaged = true;
}

void  AutomationMgr::setSlotSubGain(int slot_id, int sub, float f)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &m = slots[slot_id].automations[sub].map;
    m.gain = f;
}
float AutomationMgr::getSlotSubGain(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return 0.0;
    auto &m = slots[slot_id].automations[sub].map;
    return m.gain;
}
void  AutomationMgr::setSlotSubOffset(int slot_id, int sub, float f)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return;
    auto &m = slots[slot_id].automations[sub].map;
    m.offset = f;
}
float AutomationMgr::getSlotSubOffset(int slot_id, int sub)
{
    if(slot_id >= nslots || slot_id < 0 || sub >= per_slot || sub < 0)
        return 0.0;
    auto &m = slots[slot_id].automations[sub].map;
    return m.offset;
}

void AutomationMgr::setName(int slot_id, const char *msg)
{
    if(slot_id >= nslots || slot_id < 0)
        return;
    strncpy(slots[slot_id].name, msg, sizeof(slots[slot_id].name));
    damaged = 1;
}
const char *AutomationMgr::getName(int slot_id)
{
    if(slot_id >= nslots || slot_id < 0)
        return "";
    return slots[slot_id].name;
}
bool AutomationMgr::handleMidi(int channel, int cc, int val)
{
    int ccid = channel*128 + cc;

    bool bound_cc = false;
    for(int i=0; i<nslots; ++i) {
        if(slots[i].midi_cc == ccid) {
            bound_cc = true;
            setSlot(i, val/127.0);
        }
    }

    if(bound_cc)
        return 1;

    //No bound CC, now to see if there's something to learn
    for(int i=0; i<nslots; ++i) {
        if(slots[i].learning == 1) {
            slots[i].learning = -1;
            slots[i].midi_cc = ccid;
            for(int j=0; j<nslots; ++j)
                if(slots[j].learning > 1)
                    slots[j].learning -= 1;
            learn_queue_len--;
            setSlot(i, val/127.0);
            damaged = 1;
            break;
        }
    }
    return 0;
}

void AutomationMgr::set_ports(const class Ports &p_) {
    p = &p_;
};
//
//        AutomationSlot *slots;
//        struct AutomationMgrImpl *impl;
//};
void AutomationMgr::set_instance(void *v)
{
    this->instance = v;
}

void AutomationMgr::simpleSlope(int slot_id, int par, float slope, float offset)
{
    if(slot_id >= nslots || slot_id < 0 || par >= per_slot || par < 0)
        return;
    auto &map = slots[slot_id].automations[par].map;
    map.upoints = 2;
    map.control_points[0] = 0;
    map.control_points[1] = -(slope/2)+offset;
    map.control_points[2] =  1;
    map.control_points[3] =  slope/2+offset;

}

int AutomationMgr::free_slot(void) const
{
    for(int i=0; i<nslots; ++i)
        if(!slots[i].used)
            return i;
    return -1;
}
<|endoftext|>


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

#include "syzygy/common/unittest_util.h"

namespace testing {

ApplicationTestBase* ApplicationTestBase::self_ = NULL;

void ApplicationTestBase::InitStreams(const base::FilePath& in_path,
                                      const base::FilePath& out_path,
                                      const base::FilePath& err_path) {
  ASSERT_FALSE(in_path.empty());
  ASSERT_FALSE(out_path.empty());
  ASSERT_FALSE(err_path.empty());

  in_.reset(file_util::OpenFile(in_path, "r"));
  out_.reset(file_util::OpenFile(out_path, "w"));
  err_.reset(file_util::OpenFile(err_path, "w"));

  ASSERT_TRUE(in_.get() != NULL);
  ASSERT_TRUE(out_.get() != NULL);
  ASSERT_TRUE(err_.get() != NULL);

  // Intercept logging.
  ASSERT_TRUE(self_ == NULL);
  ASSERT_TRUE(log_handler_ == NULL);
  self_ = this;
  log_handler_ = logging::GetLogMessageHandler();
  logging::SetLogMessageHandler(&HandleLogMessage);
}

void ApplicationTestBase::TearDownStreams() {
  if (self_ != NULL) {
    logging::SetLogMessageHandler(log_handler_);
    log_handler_ = NULL;
    self_ = NULL;
  }

  ASSERT_NO_FATAL_FAILURE(TearDownStream(&in_));
  ASSERT_NO_FATAL_FAILURE(TearDownStream(&out_));
  ASSERT_NO_FATAL_FAILURE(TearDownStream(&err_));
}

void ApplicationTestBase::SetUp() {
  Super::SetUp();

  // Save the log level so that we can restore it in TearDown.
  log_level_ = logging::GetMinLogLevel();

  // By default we don't log to console.
  log_to_console_ = false;
}

void ApplicationTestBase::TearDown() {
  logging::SetMinLogLevel(log_level_);

  // These need to be shut down before we can delete the temporary
  // directories.
  EXPECT_NO_FATAL_FAILURE(TearDownStreams());

  DirList::const_iterator iter;
  for (iter = temp_dirs_.begin(); iter != temp_dirs_.end(); ++iter) {
    EXPECT_TRUE(file_util::Delete(*iter, true));
  }

  Super::TearDown();
}

bool ApplicationTestBase::HandleLogMessage(int severity, const char* file,
    int line, size_t message_start, const std::string& str) {
  DCHECK(self_ != NULL);
  if (severity < logging::GetMinLogLevel())
    return true;
  fprintf(self_->err(), "%s", str.c_str());
  fflush(self_->err());

  // If we're logging to console then repeat the message there.
  if (self_->log_to_console_) {
    fprintf(stdout, "%s", str.c_str());
    fflush(stdout);
  }

  return true;
}

void ApplicationTestBase::TearDownStream(file_util::ScopedFILE* stream) {
  ASSERT_TRUE(stream != NULL);
  if (stream->get() == NULL)
    return;
  ASSERT_EQ(0, ::fclose(stream->get()));
  stream->reset();
}

FILE* ApplicationTestBase::GetOrInitFile(file_util::ScopedFILE* f,
                                         const char* mode) {
  DCHECK(f != NULL);
  DCHECK(mode != NULL);
  if (f->get() == NULL)
    f->reset(file_util::OpenFile(base::FilePath(L"NUL"), mode));
  return f->get();
}

}  // namespace testing
<commit_msg>Fix unittests so that they don't fail while under the VS2013 debugger.<commit_after>// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "syzygy/common/unittest_util.h"

namespace testing {

ApplicationTestBase* ApplicationTestBase::self_ = NULL;

void ApplicationTestBase::InitStreams(const base::FilePath& in_path,
                                      const base::FilePath& out_path,
                                      const base::FilePath& err_path) {
  ASSERT_FALSE(in_path.empty());
  ASSERT_FALSE(out_path.empty());
  ASSERT_FALSE(err_path.empty());

  in_.reset(file_util::OpenFile(in_path, "r"));
  out_.reset(file_util::OpenFile(out_path, "w"));
  err_.reset(file_util::OpenFile(err_path, "w"));

  ASSERT_TRUE(in_.get() != NULL);
  ASSERT_TRUE(out_.get() != NULL);
  ASSERT_TRUE(err_.get() != NULL);

  // Intercept logging.
  ASSERT_TRUE(self_ == NULL);
  ASSERT_TRUE(log_handler_ == NULL);
  self_ = this;
  log_handler_ = logging::GetLogMessageHandler();
  logging::SetLogMessageHandler(&HandleLogMessage);
}

void ApplicationTestBase::TearDownStreams() {
  if (self_ != NULL) {
    logging::SetLogMessageHandler(log_handler_);
    log_handler_ = NULL;
    self_ = NULL;
  }

  ASSERT_NO_FATAL_FAILURE(TearDownStream(&in_));
  ASSERT_NO_FATAL_FAILURE(TearDownStream(&out_));
  ASSERT_NO_FATAL_FAILURE(TearDownStream(&err_));
}

void ApplicationTestBase::SetUp() {
  Super::SetUp();

  // Save the log level so that we can restore it in TearDown.
  log_level_ = logging::GetMinLogLevel();

  // By default we don't log to console.
  log_to_console_ = false;
}

void ApplicationTestBase::TearDown() {
  logging::SetMinLogLevel(log_level_);

  // These need to be shut down before we can delete the temporary
  // directories.
  EXPECT_NO_FATAL_FAILURE(TearDownStreams());

  DirList::const_iterator iter;
  for (iter = temp_dirs_.begin(); iter != temp_dirs_.end(); ++iter) {
    bool success = file_util::Delete(*iter, true);
    // VS2013 holds open handles to any PDB file that has been loaded while
    // the debugger is active. This often prevents our unittests from
    // cleaning up after themselves.
    EXPECT_TRUE(success || ::IsDebuggerPresent());
  }

  Super::TearDown();
}

bool ApplicationTestBase::HandleLogMessage(int severity, const char* file,
    int line, size_t message_start, const std::string& str) {
  DCHECK(self_ != NULL);
  if (severity < logging::GetMinLogLevel())
    return true;
  fprintf(self_->err(), "%s", str.c_str());
  fflush(self_->err());

  // If we're logging to console then repeat the message there.
  if (self_->log_to_console_) {
    fprintf(stdout, "%s", str.c_str());
    fflush(stdout);
  }

  return true;
}

void ApplicationTestBase::TearDownStream(file_util::ScopedFILE* stream) {
  ASSERT_TRUE(stream != NULL);
  if (stream->get() == NULL)
    return;
  ASSERT_EQ(0, ::fclose(stream->get()));
  stream->reset();
}

FILE* ApplicationTestBase::GetOrInitFile(file_util::ScopedFILE* f,
                                         const char* mode) {
  DCHECK(f != NULL);
  DCHECK(mode != NULL);
  if (f->get() == NULL)
    f->reset(file_util::OpenFile(base::FilePath(L"NUL"), mode));
  return f->get();
}

}  // namespace testing
<|endoftext|>


<commit_before>//===-- HostThreadPosix.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Error.h"
#include "lldb/Host/posix/HostThreadPosix.h"

#include <errno.h>
#include <pthread.h>

using namespace lldb;
using namespace lldb_private;

HostThreadPosix::HostThreadPosix()
{
}

HostThreadPosix::HostThreadPosix(lldb::thread_t thread)
    : HostNativeThreadBase(thread)
{
}

HostThreadPosix::~HostThreadPosix()
{
}

Error
HostThreadPosix::Join(lldb::thread_result_t *result)
{
    Error error;
    if (IsJoinable())
    {
        int err = ::pthread_join(m_thread, result);
        error.SetError(err, lldb::eErrorTypePOSIX);
    }
    else
    {
        if (result)
            *result = NULL;
        error.SetError(EINVAL, eErrorTypePOSIX);
    }

    Reset();
    return error;
}

Error
HostThreadPosix::Cancel()
{
    Error error;
    if (IsJoinable())
    {
#ifndef __ANDROID__
        assert(false && "someone is calling HostThread::Cancel()");
        int err = ::pthread_cancel(m_thread);
        error.SetError(err, eErrorTypePOSIX);
#else
        error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
    }
    return error;
}

Error
HostThreadPosix::Detach()
{
    Error error;
    if (IsJoinable())
    {
        int err = ::pthread_detach(m_thread);
        error.SetError(err, eErrorTypePOSIX);
    }
    Reset();
    return error;
}
<commit_msg>Disable HostThread::Cancel assertion on FreeBSD<commit_after>//===-- HostThreadPosix.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/Error.h"
#include "lldb/Host/posix/HostThreadPosix.h"

#include <errno.h>
#include <pthread.h>

using namespace lldb;
using namespace lldb_private;

HostThreadPosix::HostThreadPosix()
{
}

HostThreadPosix::HostThreadPosix(lldb::thread_t thread)
    : HostNativeThreadBase(thread)
{
}

HostThreadPosix::~HostThreadPosix()
{
}

Error
HostThreadPosix::Join(lldb::thread_result_t *result)
{
    Error error;
    if (IsJoinable())
    {
        int err = ::pthread_join(m_thread, result);
        error.SetError(err, lldb::eErrorTypePOSIX);
    }
    else
    {
        if (result)
            *result = NULL;
        error.SetError(EINVAL, eErrorTypePOSIX);
    }

    Reset();
    return error;
}

Error
HostThreadPosix::Cancel()
{
    Error error;
    if (IsJoinable())
    {
#ifndef __ANDROID__
#ifndef __FreeBSD__
        assert(false && "someone is calling HostThread::Cancel()");
#endif
        int err = ::pthread_cancel(m_thread);
        error.SetError(err, eErrorTypePOSIX);
#else
        error.SetErrorString("HostThreadPosix::Cancel() not supported on Android");
#endif
    }
    return error;
}

Error
HostThreadPosix::Detach()
{
    Error error;
    if (IsJoinable())
    {
        int err = ::pthread_detach(m_thread);
        error.SetError(err, eErrorTypePOSIX);
    }
    Reset();
    return error;
}
<|endoftext|>


<commit_before>#include "webconfig/WebConfig.h"
#include "StaticFileServing.h"

WebConfig::WebConfig(QObject * parent)
	:  QObject(parent)
	, _port(WEBCONFIG_DEFAULT_PORT)
	, _server(nullptr)
{
	_hyperion = Hyperion::getInstance();
	const Json::Value &config = _hyperion->getJsonConfig();
	_baseUrl = QString::fromStdString(WEBCONFIG_DEFAULT_PATH);

	bool webconfigEnable = true;

	if (config.isMember("webConfig"))
	{
		const Json::Value & webconfigConfig = config["webConfig"];
		webconfigEnable = webconfigConfig.get("enable", true).asBool();
		_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
		_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", WEBCONFIG_DEFAULT_PATH).asString() );
	}

	if ( webconfigEnable )
		start();
}

WebConfig::~WebConfig()
{
	stop();
}

void WebConfig::start()
{
	if ( _server == nullptr )
		_server = new StaticFileServing (_hyperion, _baseUrl, _port, this);
}

void WebConfig::stop()
{
	if ( _server != nullptr )
	{
		delete _server;
		_server = nullptr;
	}
}

<commit_msg>Fixed random http port due to uninitialized _port (#29)<commit_after>#include "webconfig/WebConfig.h"
#include "StaticFileServing.h"

WebConfig::WebConfig(QObject * parent)
	:  QObject(parent)
	, _port(WEBCONFIG_DEFAULT_PORT)
	, _server(nullptr)
{
	_hyperion = Hyperion::getInstance();
	const Json::Value &config = _hyperion->getJsonConfig();
	_baseUrl = QString::fromStdString(WEBCONFIG_DEFAULT_PATH);
	_port = WEBCONFIG_DEFAULT_PORT;

	bool webconfigEnable = true;

	if (config.isMember("webConfig"))
	{
		const Json::Value & webconfigConfig = config["webConfig"];
		webconfigEnable = webconfigConfig.get("enable", true).asBool();
		_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
		_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", WEBCONFIG_DEFAULT_PATH).asString() );
	}

	if ( webconfigEnable )
		start();
}

WebConfig::~WebConfig()
{
	stop();
}

void WebConfig::start()
{
	if ( _server == nullptr )
		_server = new StaticFileServing (_hyperion, _baseUrl, _port, this);
}

void WebConfig::stop()
{
	if ( _server != nullptr )
	{
		delete _server;
		_server = nullptr;
	}
}

<|endoftext|>


<commit_before>#include <fcntl.h>
#include <unistd.h>
#include "ssr_priv.hpp"

#define PROCSTAT_PATH "/proc/stat"
#define MEMINFO_PATH "/proc/meminfo"

SysStatsMonitor::SysStatsMonitor()
{
	mProcStatFd = -1;
	mRawProcStats.mPending = false;

	mMeminfoFd = -1;
	mRawMemInfo.mPending = false;
}

SysStatsMonitor::~SysStatsMonitor()
{
	if (mProcStatFd != -1)
		close(mProcStatFd);

	if (mMeminfoFd != -1)
		close(mMeminfoFd);
}

int SysStatsMonitor::readRawStats()
{
	int ret;

	if (mProcStatFd == -1 || mMeminfoFd == -1)
		return 0;

	ret = pfstools::readRawStats(mProcStatFd, &mRawProcStats);
	if (ret < 0)
		return 0;

	ret = pfstools::readRawStats(mMeminfoFd, &mRawMemInfo);
	if (ret < 0)
		return 0;

	return 0;
}

int SysStatsMonitor::checkStatFile(
		int *fd,
		const char *path,
		pfstools::RawStats *rawStats)
{
	int ret;

	if (*fd == -1) {
		ret = open(path, O_RDONLY|O_CLOEXEC);
		if (ret == -1) {
			ret = -errno;
			LOGE("Fail to open %s : %d(%m)", path, errno);
			return ret;
		}

		*fd = ret;

		return -EAGAIN;
	} else if (!rawStats->mPending) {
		return -EAGAIN;
	}

	return 0;
}

int SysStatsMonitor::processRawStats(const SystemMonitor::Callbacks &cb)
{
	SystemMonitor::SystemStats stats;
	bool dataPending = false;
	int ret;

	// Check /proc/stat status
	ret = checkStatFile(&mProcStatFd, PROCSTAT_PATH, &mRawProcStats);
	if (ret != -EAGAIN) {
		LOGI("Read /proc/stat");
		if (ret < 0) {
			LOGI("%s:%d", __FILE__, __LINE__);
			return ret;
		}

		ret = pfstools::readSystemStats(mRawProcStats.mContent, &stats);
		if (ret < 0) {
			close(mProcStatFd);
			mProcStatFd = -1;
			return ret;
		}
	} else {
		dataPending = true;
	}

	// Check /proc/meminfo
	ret = checkStatFile(&mMeminfoFd, MEMINFO_PATH, &mRawMemInfo);
	if (ret != -EAGAIN) {
		LOGI("Read /proc/meminfo");
		if (ret < 0) {
			LOGI("%s:%d", __FILE__, __LINE__);
			return ret;
		}

		ret = pfstools::readMeminfoStats(mRawMemInfo.mContent, &stats);
		if (ret < 0) {
			close(mMeminfoFd);
			mMeminfoFd = -1;
			return ret;
		}
	} else {
		dataPending = true;
	}

	// Notify
	if (!dataPending && cb.mSystemStats) {
		stats.mTs = mRawProcStats.mTs;
		stats.mAcqEnd = mRawProcStats.mAcqEnd;
		cb.mSystemStats(stats, cb.mUserdata);
	}

	return 0;
}
<commit_msg>Remove useless logs<commit_after>#include <fcntl.h>
#include <unistd.h>
#include "ssr_priv.hpp"

#define PROCSTAT_PATH "/proc/stat"
#define MEMINFO_PATH "/proc/meminfo"

SysStatsMonitor::SysStatsMonitor()
{
	mProcStatFd = -1;
	mRawProcStats.mPending = false;

	mMeminfoFd = -1;
	mRawMemInfo.mPending = false;
}

SysStatsMonitor::~SysStatsMonitor()
{
	if (mProcStatFd != -1)
		close(mProcStatFd);

	if (mMeminfoFd != -1)
		close(mMeminfoFd);
}

int SysStatsMonitor::readRawStats()
{
	int ret;

	if (mProcStatFd == -1 || mMeminfoFd == -1)
		return 0;

	ret = pfstools::readRawStats(mProcStatFd, &mRawProcStats);
	if (ret < 0)
		return 0;

	ret = pfstools::readRawStats(mMeminfoFd, &mRawMemInfo);
	if (ret < 0)
		return 0;

	return 0;
}

int SysStatsMonitor::checkStatFile(
		int *fd,
		const char *path,
		pfstools::RawStats *rawStats)
{
	int ret;

	if (*fd == -1) {
		ret = open(path, O_RDONLY|O_CLOEXEC);
		if (ret == -1) {
			ret = -errno;
			LOGE("Fail to open %s : %d(%m)", path, errno);
			return ret;
		}

		*fd = ret;

		return -EAGAIN;
	} else if (!rawStats->mPending) {
		return -EAGAIN;
	}

	return 0;
}

int SysStatsMonitor::processRawStats(const SystemMonitor::Callbacks &cb)
{
	SystemMonitor::SystemStats stats;
	bool dataPending = false;
	int ret;

	// Check /proc/stat status
	ret = checkStatFile(&mProcStatFd, PROCSTAT_PATH, &mRawProcStats);
	if (ret != -EAGAIN) {
		if (ret < 0) {
			LOGI("%s:%d", __FILE__, __LINE__);
			return ret;
		}

		ret = pfstools::readSystemStats(mRawProcStats.mContent, &stats);
		if (ret < 0) {
			close(mProcStatFd);
			mProcStatFd = -1;
			return ret;
		}
	} else {
		dataPending = true;
	}

	// Check /proc/meminfo
	ret = checkStatFile(&mMeminfoFd, MEMINFO_PATH, &mRawMemInfo);
	if (ret != -EAGAIN) {
		if (ret < 0) {
			LOGI("%s:%d", __FILE__, __LINE__);
			return ret;
		}

		ret = pfstools::readMeminfoStats(mRawMemInfo.mContent, &stats);
		if (ret < 0) {
			close(mMeminfoFd);
			mMeminfoFd = -1;
			return ret;
		}
	} else {
		dataPending = true;
	}

	// Notify
	if (!dataPending && cb.mSystemStats) {
		stats.mTs = mRawProcStats.mTs;
		stats.mAcqEnd = mRawProcStats.mAcqEnd;
		cb.mSystemStats(stats, cb.mUserdata);
	}

	return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include <algorithm>

#include <caf/config_value.hpp>

#include "vast/event.hpp"
#include "vast/expected.hpp"
#include "vast/logger.hpp"
#include "vast/segment_store.hpp"
#include "vast/store.hpp"
#include "vast/table_slice.hpp"
#include "vast/to_events.hpp"

#include "vast/concept/printable/stream.hpp"

#include "vast/system/archive.hpp"

#include "vast/detail/assert.hpp"
#include "vast/detail/fill_status_map.hpp"

using std::chrono::steady_clock;
using std::chrono::duration_cast;
using std::chrono::microseconds;
using namespace caf;

namespace vast::system {

archive_type::behavior_type
archive(archive_type::stateful_pointer<archive_state> self,
        path dir, size_t capacity, size_t max_segment_size) {
  // TODO: make the choice of store configurable. For most flexibility, it
  // probably makes sense to pass a unique_ptr<stor> directory to the spawn
  // arguments of the actor. This way, users can provide their own store
  // implementation conveniently.
  VAST_INFO(self, "spawned:", VAST_ARG(capacity), VAST_ARG(max_segment_size));
  self->state.store = segment_store::make(
    self->system(), dir, max_segment_size, capacity);
  VAST_ASSERT(self->state.store != nullptr);
  self->set_exit_handler(
    [=](const exit_msg& msg) {
      self->state.store->flush();
      self->state.store.reset();
      self->quit(msg.reason);
    }
  );
  self->set_down_handler(
    [=](const down_msg& msg) {
      VAST_DEBUG(self, "received DOWN from", msg.source);
      self->state.active_exporters.erase(msg.source);
    }
  );
  return {
    [=](const ids& xs) -> caf::result<std::vector<event>> {
      VAST_ASSERT(rank(xs) > 0);
      VAST_DEBUG(self, "got query for", rank(xs), "events in range ["
                 << select(xs, 1) << ',' << (select(xs, -1) + 1) << ')');
      if (self->state.active_exporters.count(self->current_sender()->address())
          == 0) {
        VAST_DEBUG(self, "dismissing query for inactive sender");
        return make_error(ec::no_error);
      }
      std::vector<event> result;
      auto slices = self->state.store->get(xs);
      if (!slices)
        VAST_DEBUG(self, "failed to lookup IDs in store:",
                   self->system().render(slices.error()));
      else
        for (auto& slice : *slices)
          to_events(result, *slice, xs);
      return result;
    },
    [=](stream<table_slice_ptr> in) {
      self->make_sink(
        in,
        [](unit_t&) {
          // nop
        },
        [=](unit_t&, std::vector<table_slice_ptr>& batch) {
          VAST_DEBUG(self, "got", batch.size(), "table slices");
          for (auto& slice : batch) {
            if (auto error = self->state.store->put(slice)) {
              VAST_ERROR(self, "failed to add table slice to store",
                         self->system().render(error));
              self->quit(error);
              break;
            }
          }
        },
        [=](unit_t&, const error& err) {
          if (err) {
            VAST_ERROR(self, "got a stream error:", self->system().render(err));
          }
        }
      );
    },
    [=](exporter_atom, const actor& exporter) {
      auto sender_addr = self->current_sender()->address();
      self->state.active_exporters.insert(sender_addr);
      self->monitor<caf::message_priority::high>(exporter);
    },
    [=](status_atom) {
      caf::dictionary<caf::config_value> result;
      detail::fill_status_map(result, self);
      self->state.store->inspect_status(put_dictionary(result, "store"));
      return result;
    }
  };
}

} // namespace vast::system
<commit_msg>Fix log statement grammar<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include <algorithm>

#include <caf/config_value.hpp>

#include "vast/event.hpp"
#include "vast/expected.hpp"
#include "vast/logger.hpp"
#include "vast/segment_store.hpp"
#include "vast/store.hpp"
#include "vast/table_slice.hpp"
#include "vast/to_events.hpp"

#include "vast/concept/printable/stream.hpp"

#include "vast/system/archive.hpp"

#include "vast/detail/assert.hpp"
#include "vast/detail/fill_status_map.hpp"

using std::chrono::steady_clock;
using std::chrono::duration_cast;
using std::chrono::microseconds;
using namespace caf;

namespace vast::system {

archive_type::behavior_type
archive(archive_type::stateful_pointer<archive_state> self,
        path dir, size_t capacity, size_t max_segment_size) {
  // TODO: make the choice of store configurable. For most flexibility, it
  // probably makes sense to pass a unique_ptr<stor> directory to the spawn
  // arguments of the actor. This way, users can provide their own store
  // implementation conveniently.
  VAST_INFO(self, "spawned:", VAST_ARG(capacity), VAST_ARG(max_segment_size));
  self->state.store = segment_store::make(
    self->system(), dir, max_segment_size, capacity);
  VAST_ASSERT(self->state.store != nullptr);
  self->set_exit_handler(
    [=](const exit_msg& msg) {
      self->state.store->flush();
      self->state.store.reset();
      self->quit(msg.reason);
    }
  );
  self->set_down_handler(
    [=](const down_msg& msg) {
      VAST_DEBUG(self, "received DOWN from", msg.source);
      self->state.active_exporters.erase(msg.source);
    }
  );
  return {
    [=](const ids& xs) -> caf::result<std::vector<event>> {
      VAST_ASSERT(rank(xs) > 0);
      VAST_DEBUG(self, "got query for", rank(xs), "events in range ["
                 << select(xs, 1) << ',' << (select(xs, -1) + 1) << ')');
      if (self->state.active_exporters.count(self->current_sender()->address())
          == 0) {
        VAST_DEBUG(self, "dismisses query for inactive sender");
        return make_error(ec::no_error);
      }
      std::vector<event> result;
      auto slices = self->state.store->get(xs);
      if (!slices)
        VAST_DEBUG(self, "failed to lookup IDs in store:",
                   self->system().render(slices.error()));
      else
        for (auto& slice : *slices)
          to_events(result, *slice, xs);
      return result;
    },
    [=](stream<table_slice_ptr> in) {
      self->make_sink(
        in,
        [](unit_t&) {
          // nop
        },
        [=](unit_t&, std::vector<table_slice_ptr>& batch) {
          VAST_DEBUG(self, "got", batch.size(), "table slices");
          for (auto& slice : batch) {
            if (auto error = self->state.store->put(slice)) {
              VAST_ERROR(self, "failed to add table slice to store",
                         self->system().render(error));
              self->quit(error);
              break;
            }
          }
        },
        [=](unit_t&, const error& err) {
          if (err) {
            VAST_ERROR(self, "got a stream error:", self->system().render(err));
          }
        }
      );
    },
    [=](exporter_atom, const actor& exporter) {
      auto sender_addr = self->current_sender()->address();
      self->state.active_exporters.insert(sender_addr);
      self->monitor<caf::message_priority::high>(exporter);
    },
    [=](status_atom) {
      caf::dictionary<caf::config_value> result;
      detail::fill_status_map(result, self);
      self->state.store->inspect_status(put_dictionary(result, "store"));
      return result;
    }
  };
}

} // namespace vast::system
<|endoftext|>


<commit_before>/** ==========================================================================
 * 2013 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
 * with no warranties. This code is yours to share, use and modify with no
 * strings attached and no restrictions or obligations.
 *
 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
 * ============================================================================*/

#include "g3log/filesink.hpp"
#include "filesinkhelper.ipp"
#include <cassert>

namespace g3 {
   using namespace internal;

   FileSink::FileSink(const std::string &log_prefix, const std::string &log_directory)
      : _log_file_with_path(log_directory)
      , _log_prefix_backup(log_prefix)
      , _outptr(new std::ofstream)
   {
      _log_prefix_backup = prefixSanityFix(log_prefix);
      if (!isValidFilename(_log_prefix_backup)) {
         std::cerr << "g3log: forced abort due to illegal log prefix [" << log_prefix << "]" << std::endl;
         abort();
      }

      std::string file_name = createLogFileName(_log_prefix_backup);
      _log_file_with_path = pathSanityFix(_log_file_with_path, file_name);
      _outptr = createLogFile(_log_file_with_path);

      if (!_outptr) {
         std::cerr << "Cannot write log file to location, attempting current directory" << std::endl;
         _log_file_with_path = "./" + file_name;
         _outptr = createLogFile(_log_file_with_path);
      }
      assert(_outptr && "cannot open log file at startup");
      addLogFileHeader();
   }

   FileSink::~FileSink() {
      std::string exit_msg {"\ng3log g3FileSink shutdown at: "};
      exit_msg.append(localtime_formatted(systemtime_now(), internal::time_formatted));
      filestream() << exit_msg << std::flush;

      exit_msg.append({"\nLog file at: ["}).append(_log_file_with_path).append({"]\n\n"});
      std::cerr << exit_msg << std::flush;
   }

   // The actual log receiving function
   void FileSink::fileWrite(LogMessageMover message) {
      std::ofstream &out(filestream());
      out << message.get().toString();
   }

   std::string FileSink::changeLogFile(const std::string &directory) {

      auto now = g3::systemtime_now();
      auto now_formatted = g3::localtime_formatted(now, {internal::date_formatted + " " + internal::time_formatted});

      std::string file_name = createLogFileName(_log_prefix_backup);
      std::string prospect_log = directory + file_name;
      std::unique_ptr<std::ofstream> log_stream = createLogFile(prospect_log);
      if (nullptr == log_stream) {
         filestream() << "\n" << now_formatted << " Unable to change log file. Illegal filename or busy? Unsuccessful log name was: " << prospect_log;
         return {}; // no success
      }

      addLogFileHeader();
      std::ostringstream ss_change;
      ss_change << "\n\tChanging log file from : " << _log_file_with_path;
      ss_change << "\n\tto new location: " << prospect_log << "\n";
      filestream() << now_formatted << ss_change.str();
      ss_change.str("");

      std::string old_log = _log_file_with_path;
      _log_file_with_path = prospect_log;
      _outptr = std::move(log_stream);
      ss_change << "\n\tNew log file. The previous log file was at: ";
      ss_change << old_log;
      filestream() << now_formatted << ss_change.str();
      return _log_file_with_path;
   }
   std::string FileSink::fileName() {
      return _log_file_with_path;
   }
   void FileSink::addLogFileHeader() {
      filestream() << header();
   }

} // g3
<commit_msg>flush after every write: https://github.com/KjellKod/g3log/issues/57<commit_after>/** ==========================================================================
 * 2013 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
 * with no warranties. This code is yours to share, use and modify with no
 * strings attached and no restrictions or obligations.
 *
 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
 * ============================================================================*/

#include "g3log/filesink.hpp"
#include "filesinkhelper.ipp"
#include <cassert>

namespace g3 {
   using namespace internal;

   FileSink::FileSink(const std::string &log_prefix, const std::string &log_directory)
      : _log_file_with_path(log_directory)
      , _log_prefix_backup(log_prefix)
      , _outptr(new std::ofstream)
   {
      _log_prefix_backup = prefixSanityFix(log_prefix);
      if (!isValidFilename(_log_prefix_backup)) {
         std::cerr << "g3log: forced abort due to illegal log prefix [" << log_prefix << "]" << std::endl;
         abort();
      }

      std::string file_name = createLogFileName(_log_prefix_backup);
      _log_file_with_path = pathSanityFix(_log_file_with_path, file_name);
      _outptr = createLogFile(_log_file_with_path);

      if (!_outptr) {
         std::cerr << "Cannot write log file to location, attempting current directory" << std::endl;
         _log_file_with_path = "./" + file_name;
         _outptr = createLogFile(_log_file_with_path);
      }
      assert(_outptr && "cannot open log file at startup");
      addLogFileHeader();
   }

   FileSink::~FileSink() {
      std::string exit_msg {"\ng3log g3FileSink shutdown at: "};
      exit_msg.append(localtime_formatted(systemtime_now(), internal::time_formatted));
      filestream() << exit_msg << std::flush;

      exit_msg.append({"\nLog file at: ["}).append(_log_file_with_path).append({"]\n\n"});
      std::cerr << exit_msg << std::flush;
   }

   // The actual log receiving function
   void FileSink::fileWrite(LogMessageMover message) {
      std::ofstream &out(filestream());
      out << message.get().toString() << std::flush;
   }

   std::string FileSink::changeLogFile(const std::string &directory) {

      auto now = g3::systemtime_now();
      auto now_formatted = g3::localtime_formatted(now, {internal::date_formatted + " " + internal::time_formatted});

      std::string file_name = createLogFileName(_log_prefix_backup);
      std::string prospect_log = directory + file_name;
      std::unique_ptr<std::ofstream> log_stream = createLogFile(prospect_log);
      if (nullptr == log_stream) {
         filestream() << "\n" << now_formatted << " Unable to change log file. Illegal filename or busy? Unsuccessful log name was: " << prospect_log;
         return {}; // no success
      }

      addLogFileHeader();
      std::ostringstream ss_change;
      ss_change << "\n\tChanging log file from : " << _log_file_with_path;
      ss_change << "\n\tto new location: " << prospect_log << "\n";
      filestream() << now_formatted << ss_change.str();
      ss_change.str("");

      std::string old_log = _log_file_with_path;
      _log_file_with_path = prospect_log;
      _outptr = std::move(log_stream);
      ss_change << "\n\tNew log file. The previous log file was at: ";
      ss_change << old_log;
      filestream() << now_formatted << ss_change.str();
      return _log_file_with_path;
   }
   std::string FileSink::fileName() {
      return _log_file_with_path;
   }
   void FileSink::addLogFileHeader() {
      filestream() << header();
   }

} // g3
<|endoftext|>


<commit_before>/*
FPF - Frame Processing Framework
See the file COPYING for copying permission.
*/
/*
fpf_main.c - main(),  generic chain driver executable for FPF
History:
    created: 2015-11 - A.Shumilin.
*/
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
//
#include <ini.h>
#include <fpf.h>
#include "class_factory.h"
//
using namespace std;

//
#define INI_MAIN_SECTION "_main_"
#define INI_MAIN_FRAMESOURCE  "frame_source"
//common substitutes
#define  PARAM_INPUT_FILE   "INPUTFILE"
#define  PARAM_OUTPUT_FILE  "OUTPUTFILE"

//exit codes
#define EXIT_ERR_CONFIG_INCOMPLETE      -1
#define EXIT_ERR_INITIALIZATION_FAILED  -2
#define EXIT_ERR_FPF_ASSERT_FAILED      EXIT_FPF_ASSERT
#define EXIT_ERR_INVALID_ARG             -4

// Globals
t_ini g_ini;
ostream stream_null(NULL);

int main(int argc, char* argv[])
{
    cerr<< "*** Frame Processing Framework engine. v 0.6. build: " << __DATE__ <<" *** "<<endl;
    int exit_code = 0;
    string ini_fn;
    IFrameSource* frame_source;
    map<string,string> map_parameters;
    string s_fs_class;
    string s_root_framer;
    //------- get command line options ----------------
    int carg;
    size_t eqpos;string sx;
    while ((carg = getopt (argc, argv, "o:D:i:tcs")) != -1)
    switch (carg)
      {
      case 'i': // config ini file
        ini_fn = optarg;
        break;
      case 'o' : //output file
        map_parameters[PARAM_OUTPUT_FILE] = optarg;
      case 'D': // definition of custom parameters
        sx = optarg;
        eqpos = sx.find_first_of("=");
        if (string::npos != eqpos) // P=V line
            {
                map_parameters[sx.substr(0,eqpos)] = sx.substr(eqpos+1,sx.length()-eqpos);
            }
        else {  map_parameters[sx] = "yes"; } //take it a s a simple flag
        break;
      case '?':
        if (optopt == 'i')
          *fpf_error<<"ERROR: Option -"<<optopt<<" requires an argument.\n";
        else if (isprint (optopt))
          *fpf_error<<"ERROR: Unknown Option -"<<optopt<<"\n";
        else
          *fpf_error<<"ERROR: Unknown option character -"<<optopt<<"\n";
        return EXIT_ERR_INVALID_ARG;
      default:
         break;
      }// switch (c)
    // further arguments are taken as INPUT_FILE
    //  for (index = optind; index < argc; index++)
    if (optind < argc)
    {
        map_parameters[PARAM_INPUT_FILE] = (char*)  argv[optind];
    }

    //----------------------------------------------
    // init fpf
    fpf_last_error.clear();
    // default ini file, look by executable file name
    if (ini_fn.empty())
    {
       ini_fn = argv[0]; //take an  exe file name
        string::size_type dot = ini_fn.find_last_of("./\\"); //find the dot or slash, what is the rightmost
        if ((dot != string::npos) && (ini_fn[dot] == '.'))
        { ini_fn.erase(dot, string::npos); }
        ini_fn += ".ini";
    }
    *fpf_info<< "* Using INI config from: "<<ini_fn<<endl;

    //* read config file *
    read_config_file(ini_fn,g_ini,&map_parameters);
    ///dump_map_of_maps(g_ini,cout);
    //check _main_ ini section and accept generic settings
    if (g_ini.find(INI_MAIN_SECTION) == g_ini.end())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_SECTION << "] section in the ini file\n";
        //TO DO - fill dummy main section to work further!
        // if no default here, terminate the programm
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }//
    //Construct the root framer
    s_root_framer = g_ini[INI_MAIN_SECTION][INI_MAIN_FRAMESOURCE];
    if (s_root_framer.empty())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_FRAMESOURCE << "] set in main section to define root framer\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    if (g_ini.find(s_root_framer) == g_ini.end())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_FRAMESOURCE << "] section to be taken as a root framer\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    s_fs_class = g_ini[s_root_framer][INI_COMMON_CLASS];
    *fpf_info<<"* Using ["<<s_fs_class<<"] as a root frame source\n";
    frame_source = new_frame_source(s_fs_class);
    if (NULL == frame_source)
    {
        *fpf_error<<"\n#ERROR: failed to instantiate frame souce.\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    // run it
    if (frame_source->init(g_ini,s_root_framer))
    {
        cout << "\n===>\n";
        frame_source->start();
        // close it after termination
        cout << "\n<===\n\n";
        frame_source->close();
        //and kill
        delete frame_source; frame_source = NULL;
    }else
    {
        *fpf_error << "\n#ERROR: framer initialization failed.\n";
        exit_code = EXIT_ERR_INITIALIZATION_FAILED;
        goto THEEND;
    }

    //OK, bye-bye
    *fpf_info<<"* OK, normal termination.\n";
THEEND:
    return exit_code;
}
<commit_msg>0.7 version<commit_after>/*
FPF - Frame Processing Framework
See the file COPYING for copying permission.
*/
/*
fpf_main.c - main(),  generic chain driver executable for FPF
History:
    created: 2015-11 - A.Shumilin.
*/
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
//
#include <ini.h>
#include <fpf.h>
#include "class_factory.h"
//
using namespace std;

//
#define INI_MAIN_SECTION "_main_"
#define INI_MAIN_FRAMESOURCE  "frame_source"
//common substitutes
#define  PARAM_INPUT_FILE   "INPUTFILE"
#define  PARAM_OUTPUT_FILE  "OUTPUTFILE"

//exit codes
#define EXIT_ERR_CONFIG_INCOMPLETE      -1
#define EXIT_ERR_INITIALIZATION_FAILED  -2
#define EXIT_ERR_FPF_ASSERT_FAILED      EXIT_FPF_ASSERT
#define EXIT_ERR_INVALID_ARG             -4

// Globals
t_ini g_ini;
ostream stream_null(NULL);

int main(int argc, char* argv[])
{
    cerr<< "*** Frame Processing Framework engine. v 0.7. build: " << __DATE__ <<" *** "<<endl;
    int exit_code = 0;
    string ini_fn;
    IFrameSource* frame_source;
    map<string,string> map_parameters;
    string s_fs_class;
    string s_root_framer;
    //------- get command line options ----------------
    int carg;
    size_t eqpos;string sx;
    while ((carg = getopt (argc, argv, "o:D:i:tcs")) != -1)
    switch (carg)
      {
      case 'i': // config ini file
        ini_fn = optarg;
        break;
      case 'o' : //output file
        map_parameters[PARAM_OUTPUT_FILE] = optarg;
      case 'D': // definition of custom parameters
        sx = optarg;
        eqpos = sx.find_first_of("=");
        if (string::npos != eqpos) // P=V line
            {
                map_parameters[sx.substr(0,eqpos)] = sx.substr(eqpos+1,sx.length()-eqpos);
            }
        else {  map_parameters[sx] = "yes"; } //take it a s a simple flag
        break;
      case '?':
        if (optopt == 'i')
          *fpf_error<<"ERROR: Option -"<<optopt<<" requires an argument.\n";
        else if (isprint (optopt))
          *fpf_error<<"ERROR: Unknown Option -"<<optopt<<"\n";
        else
          *fpf_error<<"ERROR: Unknown option character -"<<optopt<<"\n";
        return EXIT_ERR_INVALID_ARG;
      default:
         break;
      }// switch (c)
    // further arguments are taken as INPUT_FILE
    //  for (index = optind; index < argc; index++)
    if (optind < argc)
    {
        map_parameters[PARAM_INPUT_FILE] = (char*)  argv[optind];
    }

    //----------------------------------------------
    // init fpf
    fpf_last_error.clear();
    // default ini file, look by executable file name
    if (ini_fn.empty())
    {
       ini_fn = argv[0]; //take an  exe file name
        string::size_type dot = ini_fn.find_last_of("./\\"); //find the dot or slash, what is the rightmost
        if ((dot != string::npos) && (ini_fn[dot] == '.'))
        { ini_fn.erase(dot, string::npos); }
        ini_fn += ".ini";
    }
    *fpf_info<< "* Using INI config from: "<<ini_fn<<endl;

    //* read config file *
    read_config_file(ini_fn,g_ini,&map_parameters);
    ///dump_map_of_maps(g_ini,cout);
    //check _main_ ini section and accept generic settings
    if (g_ini.find(INI_MAIN_SECTION) == g_ini.end())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_SECTION << "] section in the ini file\n";
        //TO DO - fill dummy main section to work further!
        // if no default here, terminate the programm
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }//
    //Construct the root framer
    s_root_framer = g_ini[INI_MAIN_SECTION][INI_MAIN_FRAMESOURCE];
    if (s_root_framer.empty())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_FRAMESOURCE << "] set in main section to define root framer\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    if (g_ini.find(s_root_framer) == g_ini.end())
    {
        *fpf_error << "\n#ERROR: no [" << INI_MAIN_FRAMESOURCE << "] section to be taken as a root framer\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    s_fs_class = g_ini[s_root_framer][INI_COMMON_CLASS];
    *fpf_info<<"* Using ["<<s_fs_class<<"] as a root frame source\n";
    frame_source = new_frame_source(s_fs_class);
    if (NULL == frame_source)
    {
        *fpf_error<<"\n#ERROR: failed to instantiate frame souce.\n";
        exit_code = EXIT_ERR_CONFIG_INCOMPLETE;
        goto THEEND;
    }
    // run it
    if (frame_source->init(g_ini,s_root_framer))
    {
        cout << "\n===>\n";
        frame_source->start();
        // close it after termination
        cout << "\n<===\n\n";
        frame_source->close();
        //and kill
        delete frame_source; frame_source = NULL;
    }else
    {
        *fpf_error << "\n#ERROR: framer initialization failed.\n";
        exit_code = EXIT_ERR_INITIALIZATION_FAILED;
        goto THEEND;
    }

    //OK, bye-bye
    *fpf_info<<"* OK, normal termination.\n";
THEEND:
    return exit_code;
}
<|endoftext|>