<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcserver.h"
#include "rpcclient.h"
#include "init.h"
#include <boost/algorithm/string/predicate.hpp>

void WaitForShutdown(boost::thread_group* threadGroup)
{
    bool fShutdown = ShutdownRequested();
    // Tell the main threads to shutdown.
    while (!fShutdown)
    {
        MilliSleep(200);
        fShutdown = ShutdownRequested();
    }
    if (threadGroup)
    {
        threadGroup->interrupt_all();
        threadGroup->join_all();
    }
}

//////////////////////////////////////////////////////////////////////////////
//
// Start
//
bool AppInit(int argc, char* argv[])
{
    boost::thread_group threadGroup;

    bool fRet = false;
    try
    {
        //
        // Parameters
        //
        // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
        ParseParameters(argc, argv);
        if (!boost::filesystem::is_directory(GetDataDir(false)))
        {
            fprintf(stderr, "Error: Specified directory does not exist\n");
            Shutdown();
        }
        ReadConfigFile(mapArgs, mapMultiArgs);

        if (mapArgs.count("-?") || mapArgs.count("--help"))
        {
            // First part of help message is specific to bitcoind / RPC client
            std::string strUsage = _("eMark version") + " " + FormatFullVersion() + "\n\n" +
                _("Usage:") + "\n" +
                  "  eMarkd [options]                     " + "\n" +
                  "  eMarkd [options] <command> [params]  " + _("Send command to -server or eMarkd") + "\n" +
                  "  eMarkd [options] help                " + _("List commands") + "\n" +
                  "  eMarkd [options] help <command>      " + _("Get help for a command") + "\n";

            strUsage += "\n" + HelpMessage();

            fprintf(stdout, "%s", strUsage.c_str());
            return false;
        }

        // Command-line RPC
        for (int i = 1; i < argc; i++)
            if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "eMark:"))
                fCommandLine = true;

        if (fCommandLine)
        {
            if (!SelectParamsFromCommandLine()) {
                fprintf(stderr, "Error: invalid combination of -regtest and -testnet.\n");
                return false;
            }
            int ret = CommandLineRPC(argc, argv);
            exit(ret);
        }
#if !defined(WIN32)
        fDaemon = GetBoolArg("-daemon", false);
        if (fDaemon)
        {
            // Daemonize
            pid_t pid = fork();
            if (pid < 0)
            {
                fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
                return false;
            }
            if (pid > 0) // Parent process, pid is child process id
            {
                CreatePidFile(GetPidFile(), pid);
                return true;
            }
            // Child process falls through to rest of initialization

            pid_t sid = setsid();
            if (sid < 0)
                fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
        }
#endif

        fRet = AppInit2(threadGroup);
    }
    catch (std::exception& e) {
        PrintException(&e, "AppInit()");
    } catch (...) {
        PrintException(NULL, "AppInit()");
    }

    if (!fRet)
    {

        threadGroup.interrupt_all();
        // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
        // the startup-failure cases to make sure they don't result in a hang due to some
        // thread-blocking-waiting-for-another-thread-during-startup case
    } else {
        WaitForShutdown(&threadGroup);
    }
    Shutdown();

    return fRet;
}

extern void noui_connect();
int main(int argc, char* argv[])
{
    bool fRet = false;
    fHaveGUI = false;

    // Connect bitcoind signal handlers
    noui_connect();

    fRet = AppInit(argc, argv);

    if (fRet && fDaemon)
        return 0;

    return (fRet ? 0 : 1);
}
<commit_msg>Add support for reporting version number from command line:  "eMarkd --version"<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "rpcserver.h"
#include "rpcclient.h"
#include "init.h"
#include <boost/algorithm/string/predicate.hpp>

void WaitForShutdown(boost::thread_group* threadGroup)
{
    bool fShutdown = ShutdownRequested();
    // Tell the main threads to shutdown.
    while (!fShutdown)
    {
        MilliSleep(200);
        fShutdown = ShutdownRequested();
    }
    if (threadGroup)
    {
        threadGroup->interrupt_all();
        threadGroup->join_all();
    }
}

//////////////////////////////////////////////////////////////////////////////
//
// Start
//
bool AppInit(int argc, char* argv[])
{
    boost::thread_group threadGroup;

    bool fRet = false;
    try
    {
        //
        // Parameters
        //
        // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
        ParseParameters(argc, argv);
        if (!boost::filesystem::is_directory(GetDataDir(false)))
        {
            fprintf(stderr, "Error: Specified directory does not exist\n");
            Shutdown();
        }
        ReadConfigFile(mapArgs, mapMultiArgs);

        if (mapArgs.count("-?") || mapArgs.count("--help"))
        {
            // First part of help message is specific to bitcoind / RPC client
            std::string strUsage = _("eMark version") + " " + FormatFullVersion() + "\n\n" +
                _("Usage:") + "\n" +
                  "  eMarkd [options]                     " + "\n" +
                  "  eMarkd [options] <command> [params]  " + _("Send command to -server or eMarkd") + "\n" +
                  "  eMarkd [options] help                " + _("List commands") + "\n" +
                  "  eMarkd [options] help <command>      " + _("Get help for a command") + "\n";

            strUsage += "\n" + HelpMessage();

            fprintf(stdout, "%s", strUsage.c_str());
            return false;
        }

  	if (mapArgs.count("-v") || mapArgs.count("--version"))
          {
            std::string strUsage = _("eMark Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n";
            fprintf(stdout, "%s", strUsage.c_str());
            return false;
          }

        // Command-line RPC
        for (int i = 1; i < argc; i++)
            if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "eMark:"))
                fCommandLine = true;

        if (fCommandLine)
        {
            if (!SelectParamsFromCommandLine()) {
                fprintf(stderr, "Error: invalid combination of -regtest and -testnet.\n");
                return false;
            }
            int ret = CommandLineRPC(argc, argv);
            exit(ret);
        }
#if !defined(WIN32)
        fDaemon = GetBoolArg("-daemon", false);
        if (fDaemon)
        {
            // Daemonize
            pid_t pid = fork();
            if (pid < 0)
            {
                fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
                return false;
            }
            if (pid > 0) // Parent process, pid is child process id
            {
                CreatePidFile(GetPidFile(), pid);
                return true;
            }
            // Child process falls through to rest of initialization

            pid_t sid = setsid();
            if (sid < 0)
                fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
        }
#endif

        fRet = AppInit2(threadGroup);
    }
    catch (std::exception& e) {
        PrintException(&e, "AppInit()");
    } catch (...) {
        PrintException(NULL, "AppInit()");
    }

    if (!fRet)
    {

        threadGroup.interrupt_all();
        // threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
        // the startup-failure cases to make sure they don't result in a hang due to some
        // thread-blocking-waiting-for-another-thread-during-startup case
    } else {
        WaitForShutdown(&threadGroup);
    }
    Shutdown();

    return fRet;
}

extern void noui_connect();
int main(int argc, char* argv[])
{
    bool fRet = false;
    fHaveGUI = false;

    // Connect bitcoind signal handlers
    noui_connect();

    fRet = AppInit(argc, argv);

    if (fRet && fDaemon)
        return 0;

    return (fRet ? 0 : 1);
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 *  $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/***
 *   The PlatformUtils::initialize() would set fLocale
 *   to either a user-provided string or 0
 *
 ***/
char* XMLMsgLoader::fLocale = 0;

char* XMLMsgLoader::fPath = 0;

XMLCh XMLMsgLoader::fLanguage[] = {chLatin_e, chLatin_n, chNull};

/***
 *  if localeToAdopt is 0, that is to release memory for
 *  the user defined locale string
 *
 ***/
void  XMLMsgLoader::setLocale(const char* const localeToAdopt)
{
    /***
     * Release the current setting's memory, if any
     ***/
    if (fLocale)
    {
        XMLPlatformUtils::fgMemoryManager->deallocate(fLocale);//delete [] fLocale;
        fLocale = 0;
    }

    /***
     *
     *  REVISIT: later we may do locale format checking
     *
     *           refer to phttp://oss.software.ibm.com/icu/userguide/locale.html
     *           for details.
     */
    if (localeToAdopt && (strlen(localeToAdopt) == 2 || (strlen(localeToAdopt) > 3 && localeToAdopt[2]=='_')))
    {
        fLocale   = XMLString::replicate(localeToAdopt, XMLPlatformUtils::fgMemoryManager);
    }

}

const char* XMLMsgLoader::getLocale()
{
    return fLocale;
}

/***
 *  if nlsHomeToAdopt is 0, that is to release memory for
 *  the user defined NLSHome string
 *
 ***/
void  XMLMsgLoader::setNLSHome(const char* const nlsHomeToAdopt)
{
    /***
     * Release the current setting's memory, if any
     ***/
    if (fPath)
    {
        XMLPlatformUtils::fgMemoryManager->deallocate(fPath);//delete [] fPath;
        fPath = 0;
    }

    if (nlsHomeToAdopt)
    {
        fPath = XMLString::replicate(nlsHomeToAdopt, XMLPlatformUtils::fgMemoryManager);
    }

}

const char* XMLMsgLoader::getNLSHome()
{
    return fPath;
}

XERCES_CPP_NAMESPACE_END
<commit_msg>Removed data member definition that was previously removed from the header file.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

/*
 *  $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLMsgLoader.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/***
 *   The PlatformUtils::initialize() would set fLocale
 *   to either a user-provided string or 0
 *
 ***/
char* XMLMsgLoader::fLocale = 0;

char* XMLMsgLoader::fPath = 0;

/***
 *  if localeToAdopt is 0, that is to release memory for
 *  the user defined locale string
 *
 ***/
void  XMLMsgLoader::setLocale(const char* const localeToAdopt)
{
    /***
     * Release the current setting's memory, if any
     ***/
    if (fLocale)
    {
        XMLPlatformUtils::fgMemoryManager->deallocate(fLocale);//delete [] fLocale;
        fLocale = 0;
    }

    /***
     *
     *  REVISIT: later we may do locale format checking
     *
     *           refer to phttp://oss.software.ibm.com/icu/userguide/locale.html
     *           for details.
     */
    if (localeToAdopt && (strlen(localeToAdopt) == 2 || (strlen(localeToAdopt) > 3 && localeToAdopt[2]=='_')))
    {
        fLocale   = XMLString::replicate(localeToAdopt, XMLPlatformUtils::fgMemoryManager);
    }

}

const char* XMLMsgLoader::getLocale()
{
    return fLocale;
}

/***
 *  if nlsHomeToAdopt is 0, that is to release memory for
 *  the user defined NLSHome string
 *
 ***/
void  XMLMsgLoader::setNLSHome(const char* const nlsHomeToAdopt)
{
    /***
     * Release the current setting's memory, if any
     ***/
    if (fPath)
    {
        XMLPlatformUtils::fgMemoryManager->deallocate(fPath);//delete [] fPath;
        fPath = 0;
    }

    if (nlsHomeToAdopt)
    {
        fPath = XMLString::replicate(nlsHomeToAdopt, XMLPlatformUtils::fgMemoryManager);
    }

}

const char* XMLMsgLoader::getNLSHome()
{
    return fPath;
}

XERCES_CPP_NAMESPACE_END
<|endoftext|>


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#ifdef HAVE_CONFIG_H
 #include "config.h"
#endif

#include "strigiconfig.h"
#include "fileinputstream.h"
#include "bz2inputstream.h"
#include "indexer.h"
#include "analyzerconfiguration.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "streamlineanalyzer.h"
#include "streamsaxanalyzer.h"
#include "streameventanalyzer.h"

#include <cstdio>
#include <cstring>
#ifdef HAVE_UNISTD_H
 #include <unistd.h>
#endif
#ifdef HAVE_DIRECT_H
 #include <direct.h>
#endif

#include <sstream>
#include <fstream>
#include <set>
using namespace Strigi;
using namespace std;

class SelectedAnalyzerConfiguration : public Strigi::AnalyzerConfiguration {
public:
    const set<string> requiredAnalyzers;
    mutable set<string> usedAnalyzers;
    mutable set<string> availableAnalyzers;

    explicit SelectedAnalyzerConfiguration(const set<string> an)
        : requiredAnalyzers(an) {}

    bool valid() const {
        return requiredAnalyzers.size() == usedAnalyzers.size()
            || requiredAnalyzers.size() == 0;
    }
    bool useFactory(const string& name) const {
        bool use = requiredAnalyzers.find(name) != requiredAnalyzers.end()
            || requiredAnalyzers.size() == 0;
        if (use) {
            usedAnalyzers.insert(name);
        }
        availableAnalyzers.insert(name);
        return use;
    }
    bool useFactory(StreamEndAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamThroughAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamSaxAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamEventAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamLineAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
};

void
printUsage(char** argv) {
    fprintf(stderr, "Usage: %s [OPTIONS] SOURCE\n"
        "Analyze the given file and output the result as XML.\n"
        " -c   configuration file\n"
        " -a   comma-separated list of analyzers\n"
        " -r   reference output, when specified, the reference output is \n"
        "      compared to the given output and the first difference is \n"
        "      reported.\n",
        argv[0]);
}
bool
containsHelp(int argc, char **argv) {
    for (int i=1; i<argc; ++i) {
         if (strcmp(argv[i], "--help") == 0
             || strcmp(argv[i], "-h") == 0) return true;
    }
    return false;
}
set<string>
parseAnalyzerNames(const char* names) {
    set<string> n;
    string ns(names);
    string::size_type start = 0, p = ns.find(',');
    while (p != string::npos) {
        n.insert(ns.substr(start, p-start));
        start  = p + 1;
        p = ns.find(',', start);
    }
    n.insert(ns.substr(start));
    return n;
}
set<string>
parseConfig(const char* config) {
    set<string> n;
    return n;
}
/**
 * Usage: $0 [OPTIONS] SOURCE
 **/
int
main(int argc, char** argv) {
    // there are 2 optional options that both require an argument.
    // one can specify 1 source, so the number of arguments must be
    // 2, 4 or 6
    if (containsHelp(argc, argv) || (argc != 2 && argc != 4 && argc != 6)) {
        printUsage(argv);
        return -1;
    }

    set<string> analyzers;
    const char* targetFile;
    const char* referenceFile = 0;
    if (argc == 4) {
        if (strcmp(argv[1],"-a") == 0) {
            analyzers = parseAnalyzerNames(argv[2]);
        } else if (strcmp(argv[1], "-r") == 0) {
            referenceFile = argv[2];
        } else if (strcmp(argv[1], "-c") == 0) {
            analyzers = parseConfig(argv[1]);
        } else {
            printUsage(argv);
            return -1;
        }
        targetFile = argv[3];
    } else if (argc == 6) {
        if (strcmp(argv[1], "-a") == 0) {
            analyzers = parseAnalyzerNames(argv[2]);
            if (strcmp(argv[3], "-r") == 0) {
                referenceFile = argv[4];
            }
        } else if (strcmp(argv[1], "-c") == 0) {
            analyzers = parseConfig(argv[2]);
            if (strcmp(argv[3], "-r") == 0) {
                referenceFile = argv[4];
            }
        } else if (strcmp(argv[1], "-r") == 0) {
            referenceFile = argv[2];
            if (strcmp(argv[3], "-a") == 0) {
                analyzers = parseAnalyzerNames(argv[4]);
            }
        } else {
            printUsage(argv);
            return -1;
        }
        targetFile = argv[5];
    } else {
        targetFile = argv[1];
    }

    const char* mappingFile = 0;

    // check that the target file exists
    {
        ifstream filetest(targetFile);
        if (!filetest.good()) {
            cerr << "The file '" << targetFile << "' cannot be read." << endl;
            return 1;
        }
    }
    // check that the result file is ok
    FileInputStream f(referenceFile);
    BZ2InputStream bz2(&f);
    if (referenceFile != 0 && bz2.status() != Ok) {
        cerr << "The file '" << referenceFile << "' cannot be read." << endl;
        return 1;
    }

    ostringstream s;
    SelectedAnalyzerConfiguration ic(analyzers);
    Indexer indexer(s, ic, mappingFile);
    if (!ic.valid()) {
        set<string>::const_iterator i;
        set<string> missing;
        set_difference(analyzers.begin(), analyzers.end(),
            ic.availableAnalyzers.begin(), ic.availableAnalyzers.end(),
            insert_iterator<set<string> >(missing, missing.begin()));
        if (missing.size() == 1) {
            fprintf(stderr, "No analyzer with name %s was found.\n",
               missing.begin()->c_str());
        } else {
            cerr << "The analyzers";
            for (i = missing.begin(); i != missing.end(); ++i) {
                cerr << ", " << *i;
            }
            cerr << " were not found." << endl;
        }
        fprintf(stderr, "Choose from:\n");
        for (i = ic.availableAnalyzers.begin(); i != ic.availableAnalyzers.end(); ++i) {
            cerr << " " << *i << endl;
        }
        return 1;
    }

    // change to the directory of the file to analyze
    // this ensures a consistent naming of the file uris, regardless of cwd
    string targetPath(targetFile);
    string::size_type slashpos = targetPath.rfind('/');
    if (slashpos == string::npos) {
         indexer.index(targetFile);
    } else {
         chdir(targetPath.substr(0,slashpos).c_str());
         indexer.index(targetPath.substr(slashpos+1).c_str());
    }
    string str = s.str();
    int32_t n = 2*str.length();

    // if no reference file was specified, we output the analysis
    if (referenceFile == 0) {
        cout << str;
        return 0;
    }

    // load the file to compare with
    const char* c;
    n = bz2.read(c, n, n);
    if (n < 0) {
        fprintf(stderr, "Error: %s\n", bz2.error());
        return -1;
    }
    if (n != (int32_t)s.str().length()) {
        printf("output length differs %i instead of %i\n", n, s.str().length());
    }

    const char* p1 = c;
    const char* p2 = str.c_str();
    int32_t n1 = n;
    int32_t n2 = str.length();
    while (n1-- && n2-- && *p1 == *p2) {
        p1++;
        p2++;
    }
    if (n1 ==0 && (*p1 || *p2)) {
         printf("difference at position %i\n", p1-c);

         int32_t m = (80 > str.length())?str.length():80;
         printf("%i %.*s\n", m, m, str.c_str());

         m = (80 > n)?n:80;
         printf("%i %.*s\n", m, m, c);

         return -1;
    }

    return 0;
}
<commit_msg>code that makes the new tests work<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#ifdef HAVE_CONFIG_H
 #include "config.h"
#endif

#include "strigiconfig.h"
#include "fileinputstream.h"
#include "bz2inputstream.h"
#include "indexer.h"
#include "analyzerconfiguration.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "streamlineanalyzer.h"
#include "streamsaxanalyzer.h"
#include "streameventanalyzer.h"

#include <cstdio>
#include <cstring>
#ifdef HAVE_UNISTD_H
 #include <unistd.h>
#endif
#ifdef HAVE_DIRECT_H
 #include <direct.h>
#endif

#include <sstream>
#include <fstream>
#include <set>
using namespace Strigi;
using namespace std;

class SelectedAnalyzerConfiguration : public Strigi::AnalyzerConfiguration {
public:
    const set<string> requiredAnalyzers;
    mutable set<string> usedAnalyzers;
    mutable set<string> availableAnalyzers;

    explicit SelectedAnalyzerConfiguration(const set<string> an)
        : requiredAnalyzers(an) {}

    bool valid() const {
        return requiredAnalyzers.size() == usedAnalyzers.size()
            || requiredAnalyzers.size() == 0;
    }
    bool useFactory(const string& name) const {
        bool use = requiredAnalyzers.find(name) != requiredAnalyzers.end()
            || requiredAnalyzers.size() == 0;
        if (use) {
            usedAnalyzers.insert(name);
        }
        availableAnalyzers.insert(name);
        return use;
    }
    bool useFactory(StreamEndAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamThroughAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamSaxAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamEventAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
    bool useFactory(StreamLineAnalyzerFactory* f) const {
        return useFactory(f->name());
    }
};

void
printUsage(char** argv) {
    fprintf(stderr, "Usage: %s [OPTIONS] SOURCE\n"
        "Analyze the given file and output the result as XML.\n"
        " -c   configuration file\n"
        " -a   comma-separated list of analyzers\n"
        " -r   reference output, when specified, the reference output is \n"
        "      compared to the given output and the first difference is \n"
        "      reported.\n",
        argv[0]);
}
bool
containsHelp(int argc, char **argv) {
    for (int i=1; i<argc; ++i) {
         if (strcmp(argv[i], "--help") == 0
             || strcmp(argv[i], "-h") == 0) return true;
    }
    return false;
}
set<string>
parseAnalyzerNames(const char* names) {
    set<string> n;
    string ns(names);
    string::size_type start = 0, p = ns.find(',');
    while (p != string::npos) {
        n.insert(ns.substr(start, p-start));
        start  = p + 1;
        p = ns.find(',', start);
    }
    n.insert(ns.substr(start));
    return n;
}
set<string>
parseConfig(const char* config) {
    set<string> n;
    ifstream f(config);
    string line;
    while (f.good()) {
        getline(f, line);
        if (strncmp("analyzer=", line.c_str(), 9) == 0) {
            n.insert(line.substr(9));
        }
    }

    return n;
}
/**
 * Usage: $0 [OPTIONS] SOURCE
 **/
int
main(int argc, char** argv) {
    // there are 2 optional options that both require an argument.
    // one can specify 1 source, so the number of arguments must be
    // 2, 4 or 6
    if (containsHelp(argc, argv) || (argc != 2 && argc != 4 && argc != 6)) {
        printUsage(argv);
        return -1;
    }

    set<string> analyzers;
    const char* targetFile;
    const char* referenceFile = 0;
    if (argc == 4) {
        if (strcmp(argv[1],"-a") == 0) {
            analyzers = parseAnalyzerNames(argv[2]);
        } else if (strcmp(argv[1], "-r") == 0) {
            referenceFile = argv[2];
        } else if (strcmp(argv[1], "-c") == 0) {
            analyzers = parseConfig(argv[2]);
        } else {
            printUsage(argv);
            return -1;
        }
        targetFile = argv[3];
    } else if (argc == 6) {
        if (strcmp(argv[1], "-a") == 0) {
            analyzers = parseAnalyzerNames(argv[2]);
            if (strcmp(argv[3], "-r") == 0) {
                referenceFile = argv[4];
            }
        } else if (strcmp(argv[1], "-c") == 0) {
            analyzers = parseConfig(argv[2]);
            if (strcmp(argv[3], "-r") == 0) {
                referenceFile = argv[4];
            }
        } else if (strcmp(argv[1], "-r") == 0) {
            referenceFile = argv[2];
            if (strcmp(argv[3], "-a") == 0) {
                analyzers = parseAnalyzerNames(argv[4]);
            } else if (strcmp(argv[3], "-c") == 0) {
                analyzers = parseConfig(argv[4]);
            }
        } else {
            printUsage(argv);
            return -1;
        }
        targetFile = argv[5];
    } else {
        targetFile = argv[1];
    }

    const char* mappingFile = 0;

    // check that the target file exists
    {
        ifstream filetest(targetFile);
        if (!filetest.good()) {
            cerr << "The file '" << targetFile << "' cannot be read." << endl;
            return 1;
        }
    }
    // check that the result file is ok
    FileInputStream f(referenceFile);
    BZ2InputStream bz2(&f);
    if (referenceFile != 0 && bz2.status() != Ok) {
        cerr << "The file '" << referenceFile << "' cannot be read." << endl;
        return 1;
    }

    ostringstream s;
    SelectedAnalyzerConfiguration ic(analyzers);
    Indexer indexer(s, ic, mappingFile);
    if (!ic.valid()) {
        set<string>::const_iterator i;
        set<string> missing;
        set_difference(analyzers.begin(), analyzers.end(),
            ic.availableAnalyzers.begin(), ic.availableAnalyzers.end(),
            insert_iterator<set<string> >(missing, missing.begin()));
        if (missing.size() == 1) {
            fprintf(stderr, "No analyzer with name %s was found.\n",
               missing.begin()->c_str());
        } else {
            cerr << "The analyzers";
            for (i = missing.begin(); i != missing.end(); ++i) {
                cerr << ", " << *i;
            }
            cerr << " were not found." << endl;
        }
        fprintf(stderr, "Choose from:\n");
        for (i = ic.availableAnalyzers.begin(); i != ic.availableAnalyzers.end(); ++i) {
            cerr << " " << *i << endl;
        }
        return 1;
    }

    // change to the directory of the file to analyze
    // this ensures a consistent naming of the file uris, regardless of cwd
    string targetPath(targetFile);
    string::size_type slashpos = targetPath.rfind('/');
    if (slashpos == string::npos) {
         indexer.index(targetFile);
    } else {
         chdir(targetPath.substr(0,slashpos).c_str());
         indexer.index(targetPath.substr(slashpos+1).c_str());
    }
    string str = s.str();
    int32_t n = 2*str.length();

    // if no reference file was specified, we output the analysis
    if (referenceFile == 0) {
        cout << str;
        return 0;
    }

    // load the file to compare with
    const char* c;
    n = bz2.read(c, n, n);
    if (n < 0) {
        fprintf(stderr, "Error: %s\n", bz2.error());
        return -1;
    }
    if (n != (int32_t)s.str().length()) {
        printf("output length differs %i instead of %i\n", n, s.str().length());
    }

    const char* p1 = c;
    const char* p2 = str.c_str();
    int32_t n1 = n;
    int32_t n2 = str.length();
    while (n1-- && n2-- && *p1 == *p2) {
        p1++;
        p2++;
    }
    if (n1 ==0 && (*p1 || *p2)) {
         printf("difference at position %i\n", p1-c);

         int32_t m = (80 > str.length())?str.length():80;
         printf("%i %.*s\n", m, m, str.c_str());

         m = (80 > n)?n:80;
         printf("%i %.*s\n", m, m, c);

         return -1;
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
    SWARM

    Copyright (C) 2012-2022 Torbjorn Rognes and Frederic Mahe

    This program 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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

/*
  Blocked bloom filter with precomputed bit patterns
  as described in

  Putze F, Sanders P, Singler J (2009)
  Cache-, Hash- and Space-Efficient Bloom Filters
  Journal of Experimental Algorithmics, 14, 4
  https://doi.org/10.1145/1498698.1594230
*/

#include "swarm.h"
#include "bloomflex.h"
#include "pseudo_rng.h"
#include "util.h"

void bloomflex_patterns_generate(struct bloomflex_s * b);

void bloomflex_patterns_generate(struct bloomflex_s * b)
{
  constexpr unsigned int max_range {63};  // i & max_range = cap values to 63 max
#if 0
  printf("Generating %" PRIu64 " patterns with %" PRIu64 " bits set.\n",
         b->pattern_count,
         b->pattern_k);
#endif
  for(auto i = 0U; i < b->pattern_count; i++)
    {
      uint64_t pattern {0};
      for(auto j = 0U; j < b->pattern_k; j++)
        {
          uint64_t onebit {0};
          onebit = 1ULL << (rand_64() & max_range);  // 0 <= shift <= 63
          while ((pattern & onebit) != 0U) {
            onebit = 1ULL << (rand_64() & max_range);
          }
          pattern |= onebit;
        }
      b->patterns[i] = pattern;
    }
}

auto bloomflex_init(uint64_t size, unsigned int k) -> struct bloomflex_s *
{
  /* Input size is in bytes for full bitmap */

  constexpr unsigned int multiplier {16};  // multiply by 65,536
  constexpr unsigned int divider {3};  // divide by 8

  auto * b {new struct bloomflex_s};
  b->size = size >> divider;

  b->pattern_shift = multiplier;
  b->pattern_count = 1 << b->pattern_shift;
  b->pattern_mask = b->pattern_count - 1;
  b->pattern_k = k;

  b->patterns = new uint64_t[b->pattern_count];
  bloomflex_patterns_generate(b);

  b->bitmap = new uint64_t[size];
  memset(b->bitmap, UINT8_MAX, size);

  return b;
}

void bloomflex_exit(struct bloomflex_s * b)
{
  delete [] b->bitmap;
  b->bitmap = nullptr;
  delete [] b->patterns;
  b->patterns = nullptr;
  delete b;
  b = nullptr;
}
<commit_msg>eliminate dependencies<commit_after>/*
    SWARM

    Copyright (C) 2012-2022 Torbjorn Rognes and Frederic Mahe

    This program 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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

/*
  Blocked bloom filter with precomputed bit patterns
  as described in

  Putze F, Sanders P, Singler J (2009)
  Cache-, Hash- and Space-Efficient Bloom Filters
  Journal of Experimental Algorithmics, 14, 4
  https://doi.org/10.1145/1498698.1594230
*/

#include <cstdint>
#include <cstring>
#include "bloomflex.h"
#include "pseudo_rng.h"

auto bloomflex_patterns_generate(struct bloomflex_s * b) -> void
{
  constexpr unsigned int max_range {63};  // i & max_range = cap values to 63 max
  for(auto i = 0U; i < b->pattern_count; i++)
    {
      uint64_t pattern {0};
      for(auto j = 0U; j < b->pattern_k; j++)
        {
          uint64_t onebit {0};
          onebit = 1ULL << (rand_64() & max_range);  // 0 <= shift <= 63
          while ((pattern & onebit) != 0U) {
            onebit = 1ULL << (rand_64() & max_range);
          }
          pattern |= onebit;
        }
      b->patterns[i] = pattern;
    }
}

auto bloomflex_init(uint64_t size, unsigned int k) -> struct bloomflex_s *
{
  /* Input size is in bytes for full bitmap */

  constexpr unsigned int multiplier {16};  // multiply by 65,536
  constexpr unsigned int divider {3};  // divide by 8

  auto * b {new struct bloomflex_s};
  b->size = size >> divider;

  b->pattern_shift = multiplier;
  b->pattern_count = 1 << b->pattern_shift;
  b->pattern_mask = b->pattern_count - 1;
  b->pattern_k = k;

  b->patterns = new uint64_t[b->pattern_count];
  bloomflex_patterns_generate(b);

  b->bitmap = new uint64_t[size];
  memset(b->bitmap, UINT8_MAX, size);

  return b;
}

auto bloomflex_exit(struct bloomflex_s * b) -> void
{
  delete [] b->bitmap;
  b->bitmap = nullptr;
  delete [] b->patterns;
  b->patterns = nullptr;
  delete b;
  b = nullptr;
}
<|endoftext|>


<commit_before><commit_msg>Valgrind: Fix leak in PluginList by actually calling Shutdown().<commit_after><|endoftext|>


<commit_before><commit_msg>Disallow setting the rate to values that would cause busy loops (< 1/16x) or rendering issues (> 16x) BUG=18362 TEST=none Review URL: http://codereview.chromium.org/164032<commit_after><|endoftext|>


<commit_before>//
//  XorLinkedList.h
//  FunnyCoding
//
//  Created by Xplorld on 2016/3/27.
//  Copyright © 2016年 xplorld. All rights reserved.
//

#ifndef XorLinkedList_hpp
#define XorLinkedList_hpp

#include <utility>
#include <iterator>
#include <cstdint>
#include <cassert>
#include <initializer_list>

template <typename T>
class XorLinkedList {
public:
    class Iterator;
private:
    class Node {
        friend XorLinkedList;
        friend Iterator;
        uintptr_t xorptr;
        T value;

        Node(T &&v);
        Node(const T &v);

        template < typename inputIterator>
        Node(const inputIterator v);

        Node* join(T &&v);
        Node* join(const T& v);

        template < typename inputIterator>
        Node* join(const inputIterator v);

        template < typename inputIterator>
        static std::pair<Node *, Node *> newList(inputIterator begin,inputIterator end);

        template < typename inputIterator>
        static std::pair<Node *, Node *> newList(std::move_iterator<inputIterator> begin,std::move_iterator<inputIterator> end);

        //do not declare as method, since `curr` may be nullptr
        static Node *another(Node* curr, Node* one); //->another

        ~Node() ;
    };

    //Wrapper so that List can put on the stack
    //and befriend RAII
    Node *head;
    //last `Node` that is not nullptr
    Node *tail;
public:
    class Iterator {
        Node *prev;
        Node *curr;
    public:
        Iterator(Node *prev,Node *curr);
        T &value()      ;
        T &operator*()  ;
        T *operator->() ;
        Iterator &operator++() ;      //++i
        Iterator operator++ ( int );  //i++
        Iterator &operator--() ;      //--i
        Iterator operator-- ( int );  //i--

        friend bool operator!=(Iterator lhs, Iterator rhs) {return lhs.curr != rhs.curr;}
        explicit operator bool() const ;
    };
    XorLinkedList();
    XorLinkedList(const T* v) ;
    XorLinkedList(const T& v) ;
    XorLinkedList(T&& v) ;
    XorLinkedList(std::initializer_list<T> array);
    XorLinkedList(T *array,size_t count);
    template < typename inputIterator>
    XorLinkedList(inputIterator begin,inputIterator end);
    //move constructor
    XorLinkedList(XorLinkedList&& another);

    void append(const T &v);

    ~XorLinkedList() ;
    XorLinkedList::Iterator begin();
    XorLinkedList::Iterator end();
};

//template <typename T>
//bool operator!=(typename XorLinkedList<T>::Iterator &one, typename XorLinkedList<T>::Iterator &another);

#include <algorithm>
#define PtrToInt(p) reinterpret_cast<uintptr_t>((void *)(p))
#define IntToPtr(i) reinterpret_cast<Node *>((i))

//template <typename T>
//XorLinkedList<T>::Node::Node(const T *v) : xorptr(0),value(*v){}
template <typename T>
template <typename inputIterator>
XorLinkedList<T>::Node::Node(const inputIterator v) : xorptr(0),value(*v){} //copy, not move

template <typename T>
XorLinkedList<T>::Node::Node(const T &v) : xorptr(0),value(v){} //copy

template <typename T>
XorLinkedList<T>::Node::Node(T &&v) : xorptr(0),value(std::move(v)){}

template <typename T>
template <typename inputIterator>
typename std::pair< typename XorLinkedList<T>::Node *, typename XorLinkedList<T>::Node *>
XorLinkedList<T>::Node::newList(inputIterator begin,inputIterator end) {
    Node *list,*tail;
    try {
        assert(begin != end && "input feed is empty");
        list = new Node(&*begin); //cast iter to pointer
        ++begin;
        tail = list;
        while (begin != end){

            tail = tail->join(&*begin);
            ++begin;
        }
    } catch(...) {
        delete list;
        throw;
    }

    return std::make_pair(list, tail);
}

template <typename T>
template < typename inputIterator>
typename std::pair< typename XorLinkedList<T>::Node *, typename XorLinkedList<T>::Node *>
XorLinkedList<T>::Node::newList(std::move_iterator<inputIterator> begin,std::move_iterator<inputIterator> end) {
    Node *list,*tail;
    try {
        assert(begin != end && "input feed is empty");
         list = new Node(std::move(begin));
        ++begin;
         tail = list;
        while (begin != end){

            tail = tail->join(std::move(begin));
            ++begin;
        }
    } catch(...) {
        delete list;
        throw;
    }

    return std::make_pair(list, tail);
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::another(Node*curr, Node* one) {
    if (curr == nullptr) {
        return nullptr;
    }
    return IntToPtr(PtrToInt(one) ^ curr->xorptr);
}

template <typename T>
XorLinkedList<T>::Node::~Node() {
    printf("deallocating, I am %p\n",&value);

    auto B = another(this,nullptr);
    if (B) {
        //A -> B -> C
        //I am head A!
        auto C = another(B,this);
        B->xorptr = PtrToInt(C);
        delete B;
    }
    //        else {
    //I am tail
    //do nothing
    //        }
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(const T &v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(std::move(v));
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

template <typename T>
template < typename inputIterator>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(const inputIterator v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(v);
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(T&& v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(std::move(v));
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

#undef PtrToInt
#undef IntToPtr

template <typename T>
XorLinkedList<T>::Iterator::Iterator(Node *prev,Node *curr) : prev(prev),curr(curr) {}

template <typename T>
T & XorLinkedList<T>::Iterator::value()      { return curr->value; }

template <typename T>
T & XorLinkedList<T>::Iterator::operator*()  { return curr->value; }

template <typename T>
T * XorLinkedList<T>::Iterator::operator->() { return &curr->value; }

template <typename T>
typename XorLinkedList<T>::Iterator & XorLinkedList<T>::Iterator::operator++() {
    Node *nextNode = Node::another(curr,prev);
    prev = curr;
    curr = nextNode;
    return *this;
}

template <typename T>
typename XorLinkedList<T>::Iterator  XorLinkedList<T>::Iterator::operator++ ( int )
{
    Iterator nowIter = Iterator(curr);
    nowIter.prev = prev;

    ++(*this);
    return nowIter;
}

template <typename T>
typename XorLinkedList<T>::Iterator & XorLinkedList<T>::Iterator::operator--() {
    Node *prevNode = Node::another(prev,curr);
    curr = prev;
    prev = prevNode;
    return *this;
}

template <typename T>
typename XorLinkedList<T>::Iterator  XorLinkedList<T>::Iterator::operator-- ( int )
{
    Iterator nowIter = Iterator(curr);
    nowIter.prev = prev;

    --(*this);
    return nowIter;
}

template <typename T>
XorLinkedList<T>::Iterator::operator bool() const {   return curr;    }

template <typename T>
XorLinkedList<T>::XorLinkedList() : head(nullptr), tail(nullptr) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(const T& v) : head(new Node(v)), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(T &&v) : head(new Node(std::move(v))), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(const T *v) : head(new Node(v)), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(std::initializer_list<T> array) {
    auto pair = Node::newList(array.begin(),array.end());
    head = pair.first;
    tail = pair.second;
}

template <typename T>
XorLinkedList<T>::XorLinkedList(T *array,size_t count) {
    auto pair = Node::newList(array,array+count);
    head = pair.first;
    tail = pair.second;
}

template <typename T>
template <typename inputIterator>
XorLinkedList<T>::XorLinkedList(inputIterator begin,inputIterator end) {
    auto pair = Node::newList(begin,end);
    head = pair.first;
    tail = pair.second;
}

template <typename T>
XorLinkedList<T>::~XorLinkedList() {
    printf("deleting linked list\n");
    if (head) delete head;
    //no need to delete tail, it will be deleted by Node deconstructer recursively
}

template <typename T>
XorLinkedList<T>::XorLinkedList(XorLinkedList&& another) {
    head = another.head;
    tail = another.tail;
    another.head = nullptr;
    another.tail = nullptr;
}

template <typename T>
void XorLinkedList<T>::append(const T &v){
        if (tail) {
            tail = tail->join(&v);
        } else {
            //empty linked list
            head = new Node(&v);
            tail = head;
        }
}

template <typename T>
typename XorLinkedList<T>::Iterator XorLinkedList<T>::begin() {
    if (head) return Iterator(nullptr,head);
    return Iterator(nullptr,nullptr);
}

template <typename T>
typename XorLinkedList<T>::Iterator XorLinkedList<T>::end() {
    if (tail) return Iterator(tail,nullptr);
    return Iterator(nullptr,nullptr);
}

#endif /* XorLinkedList_hpp */
<commit_msg>init pointers with nullptr<commit_after>//
//  XorLinkedList.h
//  FunnyCoding
//
//  Created by Xplorld on 2016/3/27.
//  Copyright © 2016年 xplorld. All rights reserved.
//

#ifndef XorLinkedList_hpp
#define XorLinkedList_hpp

#include <utility>
#include <iterator>
#include <cstdint>
#include <cassert>
#include <initializer_list>

template <typename T>
class XorLinkedList {
public:
    class Iterator;
private:
    class Node {
        friend XorLinkedList;
        friend Iterator;
        uintptr_t xorptr;
        T value;

        Node(T &&v);
        Node(const T &v);

        template < typename inputIterator>
        Node(const inputIterator v);

        Node* join(T &&v);
        Node* join(const T& v);

        template < typename inputIterator>
        Node* join(const inputIterator v);

        template < typename inputIterator>
        static std::pair<Node *, Node *> newList(inputIterator begin,inputIterator end);

        template < typename inputIterator>
        static std::pair<Node *, Node *> newList(std::move_iterator<inputIterator> begin,std::move_iterator<inputIterator> end);

        //do not declare as method, since `curr` may be nullptr
        static Node *another(Node* curr, Node* one); //->another

        ~Node() ;
    };

    //Wrapper so that List can put on the stack
    //and befriend RAII
    Node *head;
    //last `Node` that is not nullptr
    Node *tail;
public:
    class Iterator {
        Node *prev;
        Node *curr;
    public:
        Iterator(Node *prev,Node *curr);
        T &value()      ;
        T &operator*()  ;
        T *operator->() ;
        Iterator &operator++() ;      //++i
        Iterator operator++ ( int );  //i++
        Iterator &operator--() ;      //--i
        Iterator operator-- ( int );  //i--

        friend bool operator!=(Iterator lhs, Iterator rhs) {return lhs.curr != rhs.curr;}
        explicit operator bool() const ;
    };
    XorLinkedList();
    XorLinkedList(const T* v) ;
    XorLinkedList(const T& v) ;
    XorLinkedList(T&& v) ;
    XorLinkedList(std::initializer_list<T> array);
    XorLinkedList(T *array,size_t count);
    template < typename inputIterator>
    XorLinkedList(inputIterator begin,inputIterator end);
    //move constructor
    XorLinkedList(XorLinkedList&& another);

    void append(const T &v);

    ~XorLinkedList() ;
    XorLinkedList::Iterator begin();
    XorLinkedList::Iterator end();
};

//template <typename T>
//bool operator!=(typename XorLinkedList<T>::Iterator &one, typename XorLinkedList<T>::Iterator &another);

#include <algorithm>
#define PtrToInt(p) reinterpret_cast<uintptr_t>((void *)(p))
#define IntToPtr(i) reinterpret_cast<Node *>((i))

//template <typename T>
//XorLinkedList<T>::Node::Node(const T *v) : xorptr(0),value(*v){}
template <typename T>
template <typename inputIterator>
XorLinkedList<T>::Node::Node(const inputIterator v) : xorptr(0),value(*v){} //copy, not move

template <typename T>
XorLinkedList<T>::Node::Node(const T &v) : xorptr(0),value(v){} //copy

template <typename T>
XorLinkedList<T>::Node::Node(T &&v) : xorptr(0),value(std::move(v)){}

template <typename T>
template <typename inputIterator>
typename std::pair< typename XorLinkedList<T>::Node *, typename XorLinkedList<T>::Node *>
XorLinkedList<T>::Node::newList(inputIterator begin,inputIterator end) {
    Node *list = nullptr,*tail = nullptr;
    try {
        assert(begin != end && "input feed is empty");
        list = new Node(&*begin); //cast iter to pointer
        ++begin;
        tail = list;
        while (begin != end){

            tail = tail->join(&*begin);
            ++begin;
        }
    } catch(...) {
        delete list;
        throw;
    }

    return std::make_pair(list, tail);
}

template <typename T>
template < typename inputIterator>
typename std::pair< typename XorLinkedList<T>::Node *, typename XorLinkedList<T>::Node *>
XorLinkedList<T>::Node::newList(std::move_iterator<inputIterator> begin,std::move_iterator<inputIterator> end) {
    Node *list = nullptr,*tail = nullptr;
    try {
        assert(begin != end && "input feed is empty");
         list = new Node(std::move(begin));
        ++begin;
         tail = list;
        while (begin != end){

            tail = tail->join(std::move(begin));
            ++begin;
        }
    } catch(...) {
        delete list;
        throw;
    }

    return std::make_pair(list, tail);
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::another(Node*curr, Node* one) {
    if (curr == nullptr) {
        return nullptr;
    }
    return IntToPtr(PtrToInt(one) ^ curr->xorptr);
}

template <typename T>
XorLinkedList<T>::Node::~Node() {
    printf("deallocating, I am %p\n",&value);

    auto B = another(this,nullptr);
    if (B) {
        //A -> B -> C
        //I am head A!
        auto C = another(B,this);
        B->xorptr = PtrToInt(C);
        delete B;
    }
    //        else {
    //I am tail
    //do nothing
    //        }
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(const T &v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(std::move(v));
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

template <typename T>
template < typename inputIterator>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(const inputIterator v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(v);
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

template <typename T>
typename XorLinkedList<T>::Node * XorLinkedList<T>::Node::join(T&& v) {
    //A->B, C.
    //B.p = A, C.p = 0

    Node *endNode = this;
    Node *newNode = new Node(std::move(v));
    endNode->xorptr = endNode->xorptr ^ PtrToInt((void *)newNode);
    newNode->xorptr = PtrToInt((void *)endNode);
    //A->B->C
    //B.p = A^C, C.p = B^0 = B
    return newNode;
}

#undef PtrToInt
#undef IntToPtr

template <typename T>
XorLinkedList<T>::Iterator::Iterator(Node *prev,Node *curr) : prev(prev),curr(curr) {}

template <typename T>
T & XorLinkedList<T>::Iterator::value()      { return curr->value; }

template <typename T>
T & XorLinkedList<T>::Iterator::operator*()  { return curr->value; }

template <typename T>
T * XorLinkedList<T>::Iterator::operator->() { return &curr->value; }

template <typename T>
typename XorLinkedList<T>::Iterator & XorLinkedList<T>::Iterator::operator++() {
    Node *nextNode = Node::another(curr,prev);
    prev = curr;
    curr = nextNode;
    return *this;
}

template <typename T>
typename XorLinkedList<T>::Iterator  XorLinkedList<T>::Iterator::operator++ ( int )
{
    Iterator nowIter = Iterator(curr);
    nowIter.prev = prev;

    ++(*this);
    return nowIter;
}

template <typename T>
typename XorLinkedList<T>::Iterator & XorLinkedList<T>::Iterator::operator--() {
    Node *prevNode = Node::another(prev,curr);
    curr = prev;
    prev = prevNode;
    return *this;
}

template <typename T>
typename XorLinkedList<T>::Iterator  XorLinkedList<T>::Iterator::operator-- ( int )
{
    Iterator nowIter = Iterator(curr);
    nowIter.prev = prev;

    --(*this);
    return nowIter;
}

template <typename T>
XorLinkedList<T>::Iterator::operator bool() const {   return curr;    }

template <typename T>
XorLinkedList<T>::XorLinkedList() : head(nullptr), tail(nullptr) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(const T& v) : head(new Node(v)), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(T &&v) : head(new Node(std::move(v))), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(const T *v) : head(new Node(v)), tail(head) {}

template <typename T>
XorLinkedList<T>::XorLinkedList(std::initializer_list<T> array) {
    auto pair = Node::newList(array.begin(),array.end());
    head = pair.first;
    tail = pair.second;
}

template <typename T>
XorLinkedList<T>::XorLinkedList(T *array,size_t count) {
    auto pair = Node::newList(array,array+count);
    head = pair.first;
    tail = pair.second;
}

template <typename T>
template <typename inputIterator>
XorLinkedList<T>::XorLinkedList(inputIterator begin,inputIterator end) {
    auto pair = Node::newList(begin,end);
    head = pair.first;
    tail = pair.second;
}

template <typename T>
XorLinkedList<T>::~XorLinkedList() {
    printf("deleting linked list\n");
    if (head) delete head;
    //no need to delete tail, it will be deleted by Node deconstructer recursively
}

template <typename T>
XorLinkedList<T>::XorLinkedList(XorLinkedList&& another) {
    head = another.head;
    tail = another.tail;
    another.head = nullptr;
    another.tail = nullptr;
}

template <typename T>
void XorLinkedList<T>::append(const T &v){
        if (tail) {
            tail = tail->join(&v);
        } else {
            //empty linked list
            head = new Node(&v);
            tail = head;
        }
}

template <typename T>
typename XorLinkedList<T>::Iterator XorLinkedList<T>::begin() {
    if (head) return Iterator(nullptr,head);
    return Iterator(nullptr,nullptr);
}

template <typename T>
typename XorLinkedList<T>::Iterator XorLinkedList<T>::end() {
    if (tail) return Iterator(tail,nullptr);
    return Iterator(nullptr,nullptr);
}

#endif /* XorLinkedList_hpp */
<|endoftext|>


<commit_before>#include "main.h"

/// Filename of input file.
std::string filename = "";

std::string dot_filename = "";
std::ostream * dot_output = &std::cout;

/// The Petri Net
PetriNet *TheNet = new PetriNet();

// different modes controlled by command line

/// print the Petri Net
bool mode_petri_net = false;
/// simplify Petri Net
bool mode_simplify_petri_net = false;
/// paint Petri Net with dot
bool mode_dot_petri_net = false;
/// paint Petri Net with dot and output to file
bool mode_dot_2_file = false;
/// pretty printer
bool mode_pretty_printer = false;
/// print AST
bool mode_ast = false;

void print_help()
{
  trace("\n");
  trace("BPEL2oWFN\n");
  trace("---------\n");
  trace("Options: \n");
  trace("   -f | --file <filename>    - read input from <filename>,\n");
  trace("                               if this parameter is omitted, input is read from STDIN\n");
  trace("   -d | -dd | -ddd | -dddd | - set debug level\n");
  trace("        --debug [1..4]         ... some more information soon\n");
  trace("   -h | --help               - print this screen\n");
  trace("\n");
  trace("\n");
  trace("output modes (choose at maximum one, default is just parsing):\n");
  trace("\n");
  trace("   -a  | --ast               - output the AST\n");
  trace("   -x  | --xml               - output simple XML w/o any unnecessary informtion\n");
  trace("   -pn | --petri-net         - output the Petri Net (in LoLA style?)\n");
  trace("\n");
  trace("special Petri Net modes:\n");
  trace("\n");
  trace("   -s  | --simplify          - outout a structural simplified Petri Net\n");
  trace("                               (implies option -pn)\n");
  trace("   -D  | --dot               - output dot input\n");
  trace("                               (implies option -pn)\n");
  trace("\n");
  trace("For more information see:\n");
  trace("  http://www.informatik.hu-berlin.de/top/forschung/projekte/tools4bpel/\n");
  trace("\n");

}

int main( int argc, char *argv[])
{
  /***
   * Reading command line arguments and triggering appropriate behaviour.
   * In case of false parameters call command line help function and exit.
   */

  if (argc > 1)
  {
    int argument_counter = 1;
    while (argument_counter < argc)
    {
      char * argument_string = argv[argument_counter++];

      // check for input other than stdin
      if (! strcmp(argument_string, "-f") || ! strcmp(argument_string, "--file"))
      {
        if (argument_counter < argc)
	{
          filename = (std::string) argv[argument_counter++];
          if (!(yyin = fopen(filename.c_str(), "r")))
	  {
            // fprintf(stderr, "  File '%s' not found.\n", filename);
            trace("  File '");
	    trace(filename);
	    trace("' not found.\n");
            exit(2);
          }
	}
	else
	{
          print_help();
	  exit(1);
	}
      }

      // select output, default is just parsing
      else if (! strcmp(argument_string, "-pn") || ! strcmp(argument_string, "--petri-net")) {
	// output a Petri Net
        mode_petri_net = true;
      }
      else if (! strcmp(argument_string, "-x") || ! strcmp(argument_string, "--xml")) {
	// output a pretty xml
        mode_pretty_printer = true;
      }
      else if (! strcmp(argument_string, "-a") || ! strcmp(argument_string, "--ast")) {
	// output the AST, but why anyone should want to?
        mode_ast = true;
      }

      // simplyfy?
      else if (! strcmp(argument_string, "-s") || ! strcmp(argument_string, "--simplify"))
      {
        mode_simplify_petri_net = true;
	mode_petri_net = true;
      }

      // generate dot output
      else if (! strcmp(argument_string, "-D") || ! strcmp(argument_string, "--dot"))
      {
        mode_dot_petri_net = true;
	mode_petri_net = true;
      }

      // generate dot output and write it into a file
      else if (! strcmp(argument_string, "-D2F") || ! strcmp(argument_string, "--dot2file"))
      {
        mode_dot_petri_net = true;
	mode_dot_2_file = true;
	mode_petri_net = true;
      }

      // debug
      else if (! strcmp(argument_string, "-d"))
      {
        debug_level = TRACE_WARNINGS;
      }
      else if (! strcmp(argument_string, "-dd"))
      {
        debug_level = TRACE_INFORMATION;
      }
      else if (! strcmp(argument_string, "-ddd"))
      {
        debug_level = TRACE_DEBUG;
      }
      else if (! strcmp(argument_string, "-dddd"))
      {
        debug_level = TRACE_VERY_DEBUG;
      }
      else if (! strcmp(argument_string, "--debug"))
      {
        if (argument_counter < argc)
	{
          argument_string = argv[argument_counter++];
	  // instead of atoi we may use the stringstream class?
          debug_level = atoi(argument_string);
	  if (debug_level < 1 || debug_level > 4) {
            print_help();
	    exit(1);
	  }
	}
	else
	{
          print_help();
	  exit(1);
	}
      }

      // help
      else if (! strcmp(argument_string, "-h") || ! strcmp(argument_string, "--help"))
      {
        print_help();
        exit(1);
      }
      else
      {
	trace("Unknown option: " + ((std::string) argument_string) + "\n");
	print_help();
	exit(1);
      }

    }
    // take care of the output modes
    if ((mode_petri_net && mode_ast) || (mode_petri_net && mode_pretty_printer) || (mode_ast && mode_pretty_printer))
    {
      print_help();
      exit(1);
    }
  }

  if ( filename != "")
  {
    trace(TRACE_INFORMATION, "Reading BPEL from file ");
    trace(TRACE_INFORMATION, (filename));
    trace(TRACE_INFORMATION, "\n");

    // if wanted, create a dot output file
    if ( mode_dot_2_file )
    {
      trace(TRACE_INFORMATION, "Creating file for dot output\n");
      std::string dotti_file = filename;
      if ( dotti_file.rfind(".bpel", 0) >= (dotti_file.length() - 8) )
      {
        dotti_file = dotti_file.replace( (dotti_file.length() - 5), 5, ".dot");
      }
      else
      {
        dotti_file += ".dot";
      }

      dot_filename = dotti_file.c_str();
      dot_output = new std::ofstream(dotti_file.c_str(), std::ofstream::out | std::ofstream::trunc);
    }
  }

  // don't show debug messages from flex and Bison, unless highest debug mode is requested
  if (debug_level == TRACE_VERY_DEBUG)
  {
    yydebug = 1;
    yy_flex_debug = 1;
  }
  else
  {
    yydebug = 0;
    yy_flex_debug = 0;
  }

  trace(TRACE_INFORMATION, "Parsing ...\n");

  // invoke Bison parser
  int error = yyparse();

  if (!error)
  {
    trace(TRACE_INFORMATION, "Parsing complete.\n");
    if (mode_ast)
    {
      TheProcess->print();
    }

    trace(TRACE_INFORMATION, "Rewriting BPEL...\n");
    TheProcess = TheProcess->rewrite(kc::implicit);
    trace(TRACE_INFORMATION, "Rewriting complete.\n");

    if (mode_pretty_printer)
    {
      TheProcess->unparse(kc::printer, kc::xml);
    }
    if (mode_petri_net)
    {
      TheProcess->unparse(kc::pseudoPrinter, kc::petrinet);
    }
  }

  if (mode_simplify_petri_net)
  {
    TheNet->simplify();
  }
  if (mode_dot_petri_net)
  {
    TheNet->drawDot();
  }

  //std::cout << std::endl;

  //TheNet->information();

  if (dot_filename != "")
  {
    trace(TRACE_INFORMATION,"Closing dot output file: " + dot_filename + "\n");
    (*dot_output) << std::flush;
    ((std::ofstream*)dot_output)->close();
  }

  return error;
}
<commit_msg>+ minor changes:   - new command line argument "-?"   - help is at maximum 80 chars per line<commit_after>#include "main.h"

/// Filename of input file.
std::string filename = "";

std::string dot_filename = "";
std::ostream * dot_output = &std::cout;

/// The Petri Net
PetriNet *TheNet = new PetriNet();

// different modes controlled by command line

/// print the Petri Net
bool mode_petri_net = false;
/// simplify Petri Net
bool mode_simplify_petri_net = false;
/// paint Petri Net with dot
bool mode_dot_petri_net = false;
/// paint Petri Net with dot and output to file
bool mode_dot_2_file = false;
/// pretty printer
bool mode_pretty_printer = false;
/// print AST
bool mode_ast = false;

void print_help()
{
  // 80 chars
  //    "--------------------------------------------------------------------------------"
  trace("\n");
  trace("BPEL2oWFN\n");
  trace("---------\n");
  trace("Options: \n");
  trace("   -f | --file <filename>    - read input from <filename>,\n");
  trace("                               if this parameter is omitted, input is read from\n");
  trace("                               STDIN\n");
  trace("   -d | -dd | -ddd | -dddd | - set debug level\n");
  trace("        --debug [1..4]         ... some more information soon\n");
  trace("   -h | --help               - print this screen\n");
  trace("\n");
  trace("\n");
  trace("output modes (choose at maximum one, default is just parsing):\n");
  trace("\n");
  trace("   -a  | --ast               - output the AST\n");
  trace("   -x  | --xml               - output simple XML w/o any unnecessary\n");
  trace("                               informtion\n");
  trace("   -pn | --petri-net         - output the Petri Net (in LoLA style?)\n");
  trace("\n");
  trace("special Petri Net modes:\n");
  trace("\n");
  trace("   -s   | --simplify         - outout a structural simplified Petri Net\n");
  trace("                               (implies option -pn)\n");
  trace("   -D   | --dot              - output dot input\n");
  trace("                               (implies option -pn)\n");
  trace("   -D2F | --dot2file         - output dot input into file (same name as\n");
  trace("                               input file\n");
  trace("                               (implies option -D)\n");
  trace("\n");
  trace("For more information see:\n");
  trace("  http://www.informatik.hu-berlin.de/top/forschung/projekte/tools4bpel/\n");
  trace("\n");

}

int main( int argc, char *argv[])
{
  /***
   * Reading command line arguments and triggering appropriate behaviour.
   * In case of false parameters call command line help function and exit.
   */

  if (argc > 1)
  {
    int argument_counter = 1;
    while (argument_counter < argc)
    {
      char * argument_string = argv[argument_counter++];

      // check for input other than stdin
      if (! strcmp(argument_string, "-f") || ! strcmp(argument_string, "--file"))
      {
        if (argument_counter < argc)
	{
          filename = (std::string) argv[argument_counter++];
          if (!(yyin = fopen(filename.c_str(), "r")))
	  {
            // fprintf(stderr, "  File '%s' not found.\n", filename);
            trace("  File '");
	    trace(filename);
	    trace("' not found.\n");
            exit(2);
          }
	}
	else
	{
          print_help();
	  exit(1);
	}
      }

      // select output, default is just parsing
      else if (! strcmp(argument_string, "-pn") || ! strcmp(argument_string, "--petri-net")) {
	// output a Petri Net
        mode_petri_net = true;
      }
      else if (! strcmp(argument_string, "-x") || ! strcmp(argument_string, "--xml")) {
	// output a pretty xml
        mode_pretty_printer = true;
      }
      else if (! strcmp(argument_string, "-a") || ! strcmp(argument_string, "--ast")) {
	// output the AST, but why anyone should want to?
        mode_ast = true;
      }

      // simplyfy?
      else if (! strcmp(argument_string, "-s") || ! strcmp(argument_string, "--simplify"))
      {
        mode_simplify_petri_net = true;
	mode_petri_net = true;
      }

      // generate dot output
      else if (! strcmp(argument_string, "-D") || ! strcmp(argument_string, "--dot"))
      {
        mode_dot_petri_net = true;
	mode_petri_net = true;
      }

      // generate dot output and write it into a file
      else if (! strcmp(argument_string, "-D2F") || ! strcmp(argument_string, "--dot2file"))
      {
        mode_dot_petri_net = true;
	mode_dot_2_file = true;
	mode_petri_net = true;
      }

      // debug
      else if (! strcmp(argument_string, "-d"))
      {
        debug_level = TRACE_WARNINGS;
      }
      else if (! strcmp(argument_string, "-dd"))
      {
        debug_level = TRACE_INFORMATION;
      }
      else if (! strcmp(argument_string, "-ddd"))
      {
        debug_level = TRACE_DEBUG;
      }
      else if (! strcmp(argument_string, "-dddd"))
      {
        debug_level = TRACE_VERY_DEBUG;
      }
      else if (! strcmp(argument_string, "--debug"))
      {
        if (argument_counter < argc)
	{
          argument_string = argv[argument_counter++];
	  // instead of atoi we may use the stringstream class?
          debug_level = atoi(argument_string);
	  if (debug_level < 1 || debug_level > 4) {
            print_help();
	    exit(1);
	  }
	}
	else
	{
          print_help();
	  exit(1);
	}
      }

      // help
      else if (! strcmp(argument_string, "-h") || ! strcmp(argument_string, "-?") || ! strcmp(argument_string, "--help"))
      {
        print_help();
        exit(1);
      }
      else
      {
	trace("Unknown option: " + ((std::string) argument_string) + "\n");
	print_help();
	exit(1);
      }

    }
    // take care of the output modes
    if ((mode_petri_net && mode_ast) || (mode_petri_net && mode_pretty_printer) || (mode_ast && mode_pretty_printer))
    {
      print_help();
      exit(1);
    }
  }

  if ( filename != "")
  {
    trace(TRACE_INFORMATION, "Reading BPEL from file ");
    trace(TRACE_INFORMATION, (filename));
    trace(TRACE_INFORMATION, "\n");

    // if wanted, create a dot output file
    if ( mode_dot_2_file )
    {
      trace(TRACE_INFORMATION, "Creating file for dot output\n");
      std::string dotti_file = filename;
      if ( dotti_file.rfind(".bpel", 0) >= (dotti_file.length() - 8) )
      {
        dotti_file = dotti_file.replace( (dotti_file.length() - 5), 5, ".dot");
      }
      else
      {
        dotti_file += ".dot";
      }

      dot_filename = dotti_file.c_str();
      dot_output = new std::ofstream(dotti_file.c_str(), std::ofstream::out | std::ofstream::trunc);
    }
  }

  // don't show debug messages from flex and Bison, unless highest debug mode is requested
  if (debug_level == TRACE_VERY_DEBUG)
  {
    yydebug = 1;
    yy_flex_debug = 1;
  }
  else
  {
    yydebug = 0;
    yy_flex_debug = 0;
  }

  trace(TRACE_INFORMATION, "Parsing ...\n");

  // invoke Bison parser
  int error = yyparse();

  if (!error)
  {
    trace(TRACE_INFORMATION, "Parsing complete.\n");
    if (mode_ast)
    {
      TheProcess->print();
    }

    trace(TRACE_INFORMATION, "Rewriting BPEL...\n");
    TheProcess = TheProcess->rewrite(kc::implicit);
    trace(TRACE_INFORMATION, "Rewriting complete.\n");

    if (mode_pretty_printer)
    {
      TheProcess->unparse(kc::printer, kc::xml);
    }
    if (mode_petri_net)
    {
      TheProcess->unparse(kc::pseudoPrinter, kc::petrinet);
    }
  }

  if (mode_simplify_petri_net)
  {
    TheNet->simplify();
  }
  if (mode_dot_petri_net)
  {
    TheNet->drawDot();
  }

  //std::cout << std::endl;

  //TheNet->information();

  if (dot_filename != "")
  {
    trace(TRACE_INFORMATION,"Closing dot output file: " + dot_filename + "\n");
    (*dot_output) << std::flush;
    ((std::ofstream*)dot_output)->close();
  }

  return error;
}
<|endoftext|>


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

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "mvdLayerStackWidget.h"
#include "ui_mvdLayerStackWidget.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)
#include <cassert>

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "Gui/mvdLayerStackItemModel.h"

namespace mvd
{

/*
  TRANSLATOR mvd::LayerStackWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
LayerStackWidget
::LayerStackWidget( QWidget* parent, Qt::WindowFlags flags  ):
  QWidget( parent, flags ),
  m_UI( new mvd::Ui::LayerStackWidget() )
{
  m_UI->setupUi( this );

  {
  QItemSelectionModel * ism = m_UI->treeView->selectionModel();

  m_UI->treeView->setModel( new LayerStackItemModel( m_UI->treeView ) );

  delete ism;
  ism = NULL;
  }

  QObject::connect(
    m_UI->treeView->selectionModel(),
    SIGNAL( currentRowChanged( const QModelIndex &,  const QModelIndex & ) ),
    // to:
    this,
    SLOT( OnCurrentRowChanged( const QModelIndex &, const QModelIndex & ) )
    );

  QObject::connect(
    m_UI->treeView->selectionModel(),
    SIGNAL( selectionChanged( const QItemSelection &,  const QItemSelection & ) ),
    // to:
    this,
    SLOT( OnSelectionChanged( const QItemSelection &, const QItemSelection & ) )
    );
}

/*******************************************************************************/
LayerStackWidget
::~LayerStackWidget()
{
  delete m_UI;
  m_UI = NULL;
}

/*******************************************************************************/
const LayerStackItemModel *
LayerStackWidget
::GetItemModel() const
{
  return const_cast< LayerStackWidget * >( this )->GetItemModel();
}

/*******************************************************************************/
LayerStackItemModel *
LayerStackWidget
::GetItemModel()
{
  assert(
    m_UI->treeView->model()==
    qobject_cast< LayerStackItemModel * >( m_UI->treeView->model() )
    );

  return qobject_cast< LayerStackItemModel * >( m_UI->treeView->model() );
}

/*******************************************************************************/
// void
// LayerStackWidget
// ::SetModel( LayerStackItemModel * itemModel )
// {
//   // See http://qt-project.org/doc/qt-4.8/qabstractitemview.html#setModel .
//   QItemSelectionModel * itemSelectionModel = m_UI->treeView->selectionModel();

//   m_UI->treeView->setModel( itemModel );

//   itemModel->setParent( m_UI->treeView );

//   delete itemSelectionModel;
//   itemSelectionModel = NULL;
// }

/*******************************************************************************/
void
LayerStackWidget
::SetCurrent( int row )
{
  assert( m_UI->treeView->selectionModel()!=NULL );

  // if( m_UI->treeView->selectionModel()->currentIndex().row()==row )
  //   return;

  if( row<0 )
    m_UI->treeView->selectionModel()->clearSelection();

  else
    m_UI->treeView->selectionModel()->select(
      m_UI->treeView->model()->index( row, 1 ),
      QItemSelectionModel::ClearAndSelect |
      QItemSelectionModel::Rows
  );

  /*
  m_UI->treeView->selectionModel()->setCurrentIndex(
    m_UI->treeView->model()->index( row, 1 ),
    QItemSelectionModel::ClearAndSelect |
    // QItemSelectionModel::Current |
    QItemSelectionModel::Rows
  );
  */
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
LayerStackWidget
::OnCurrentRowChanged( const QModelIndex & current,
                       const QModelIndex & previous )
{
  qDebug()
    << this
    << "::OnCurrentRowChange(" << current.row() << "," << previous.row() << ")";

  emit CurrentChanged( current.row() );
}

/*******************************************************************************/
void
LayerStackWidget
::OnSelectionChanged( const QItemSelection & selected,
                      const QItemSelection & deselected )
{
  qDebug()
    << this
    << "::OnSelectionChanged(" << selected << "," << deselected << ")";

  QModelIndexList indexes( selected.indexes() );
  // assert( indexes.empty() || indexes.size()==1 );

  emit SelectionChanged(
    indexes.empty()
    ? -1
    : indexes.front().row()
  );
}

} // end namespace 'mvd'
<commit_msg>REFAC: Removed debug traces.<commit_after>/*=========================================================================

  Program:   Monteverdi2
  Language:  C++

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See Copyright.txt for details.

  Monteverdi2 is distributed under the CeCILL licence version 2. See
  Licence_CeCILL_V2-en.txt or
  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt for more details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "mvdLayerStackWidget.h"
#include "ui_mvdLayerStackWidget.h"

/*****************************************************************************/
/* INCLUDE SECTION                                                           */

//
// Qt includes (sorted by alphabetic order)
//// Must be included before system/custom includes.

//
// System includes (sorted by alphabetic order)
#include <cassert>

//
// ITK includes (sorted by alphabetic order)

//
// OTB includes (sorted by alphabetic order)

//
// Monteverdi includes (sorted by alphabetic order)
#include "Gui/mvdLayerStackItemModel.h"

namespace mvd
{

/*
  TRANSLATOR mvd::LayerStackWidget

  Necessary for lupdate to be aware of C++ namespaces.

  Context comment for translator.
*/

/*****************************************************************************/
/* CONSTANTS                                                                 */

/*****************************************************************************/
/* STATIC IMPLEMENTATION SECTION                                             */

/*****************************************************************************/
/* CLASS IMPLEMENTATION SECTION                                              */

/*******************************************************************************/
LayerStackWidget
::LayerStackWidget( QWidget* parent, Qt::WindowFlags flags  ):
  QWidget( parent, flags ),
  m_UI( new mvd::Ui::LayerStackWidget() )
{
  m_UI->setupUi( this );

  {
  QItemSelectionModel * ism = m_UI->treeView->selectionModel();

  m_UI->treeView->setModel( new LayerStackItemModel( m_UI->treeView ) );

  delete ism;
  ism = NULL;
  }

  QObject::connect(
    m_UI->treeView->selectionModel(),
    SIGNAL( currentRowChanged( const QModelIndex &,  const QModelIndex & ) ),
    // to:
    this,
    SLOT( OnCurrentRowChanged( const QModelIndex &, const QModelIndex & ) )
    );

  QObject::connect(
    m_UI->treeView->selectionModel(),
    SIGNAL( selectionChanged( const QItemSelection &,  const QItemSelection & ) ),
    // to:
    this,
    SLOT( OnSelectionChanged( const QItemSelection &, const QItemSelection & ) )
    );
}

/*******************************************************************************/
LayerStackWidget
::~LayerStackWidget()
{
  delete m_UI;
  m_UI = NULL;
}

/*******************************************************************************/
const LayerStackItemModel *
LayerStackWidget
::GetItemModel() const
{
  return const_cast< LayerStackWidget * >( this )->GetItemModel();
}

/*******************************************************************************/
LayerStackItemModel *
LayerStackWidget
::GetItemModel()
{
  assert(
    m_UI->treeView->model()==
    qobject_cast< LayerStackItemModel * >( m_UI->treeView->model() )
    );

  return qobject_cast< LayerStackItemModel * >( m_UI->treeView->model() );
}

/*******************************************************************************/
// void
// LayerStackWidget
// ::SetModel( LayerStackItemModel * itemModel )
// {
//   // See http://qt-project.org/doc/qt-4.8/qabstractitemview.html#setModel .
//   QItemSelectionModel * itemSelectionModel = m_UI->treeView->selectionModel();

//   m_UI->treeView->setModel( itemModel );

//   itemModel->setParent( m_UI->treeView );

//   delete itemSelectionModel;
//   itemSelectionModel = NULL;
// }

/*******************************************************************************/
void
LayerStackWidget
::SetCurrent( int row )
{
  assert( m_UI->treeView->selectionModel()!=NULL );

  // if( m_UI->treeView->selectionModel()->currentIndex().row()==row )
  //   return;

  if( row<0 )
    m_UI->treeView->selectionModel()->clearSelection();

  else
    m_UI->treeView->selectionModel()->select(
      m_UI->treeView->model()->index( row, 1 ),
      QItemSelectionModel::ClearAndSelect |
      QItemSelectionModel::Rows
  );

  /*
  m_UI->treeView->selectionModel()->setCurrentIndex(
    m_UI->treeView->model()->index( row, 1 ),
    QItemSelectionModel::ClearAndSelect |
    // QItemSelectionModel::Current |
    QItemSelectionModel::Rows
  );
  */
}

/*******************************************************************************/
/* SLOTS                                                                       */
/*******************************************************************************/
void
LayerStackWidget
::OnCurrentRowChanged( const QModelIndex & current,
                       const QModelIndex & previous )
{
  // qDebug()
  //   << this
  //   << "::OnCurrentRowChange(" << current.row() << "," << previous.row() << ")";

  emit CurrentChanged( current.row() );
}

/*******************************************************************************/
void
LayerStackWidget
::OnSelectionChanged( const QItemSelection & selected,
                      const QItemSelection & deselected )
{
  // qDebug()
  //   << this
  //   << "::OnSelectionChanged(" << selected << "," << deselected << ")";

  QModelIndexList indexes( selected.indexes() );
  // assert( indexes.empty() || indexes.size()==1 );

  emit SelectionChanged(
    indexes.empty()
    ? -1
    : indexes.front().row()
  );
}

} // end namespace 'mvd'
<|endoftext|>


<commit_before>#ifndef WIGWAG_SIGNAL_HPP
#define WIGWAG_SIGNAL_HPP

// Copyright (c) 2016, Dmitry Koplyarov <koplyarov.da@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
// provided that the above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include <wigwag/life_token.hpp>
#include <wigwag/signal_policies.hpp>
#include <wigwag/token.hpp>

#include <list>

namespace wigwag
{

	template < typename Signature_, typename ThreadingPolicy_, typename HandlersStoragePolicy_, typename LifeAssurancePolicy_ >
	class basic_signal
	{
	public:
		using handler_type = std::function<Signature_>;
		using populator_type = std::function<void(const std::function<Signature_>&)>;

		using lock_primitive = typename ThreadingPolicy_::lock_primitive;

		using life_assurance = typename LifeAssurancePolicy_::life_assurance;
		using life_checker = typename LifeAssurancePolicy_::life_checker;
		using execution_guard = typename LifeAssurancePolicy_::execution_guard;

		using handlers_stack_container = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>::handlers_stack_container;
		using handler_id = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>::handler_id;
		using storage = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>;
		using storage_ref = typename HandlersStoragePolicy_::template storage_ref<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>;

	private:
		class lock_guard
		{
			const lock_primitive& _lp;

		public:
			lock_guard(const lock_primitive& lp) : _lp(lp) { _lp.lock(); }
			~lock_guard() { _lp.unlock(); }
		};

		struct connection : public token::implementation, public life_assurance
		{
			storage_ref		_storage_ref;
			handler_id		_id;

		public:
			connection(life_assurance&& la, storage_ref sr, handler_id id)
				: life_assurance(std::move(la)), _storage_ref(sr), _id(id)
			{ }

			~connection()
			{ _storage_ref.erase_handler(_id); }
		};

	private:
		storage		_storage;

	public:
		token connect(const handler_type& handler)
		{
			lock_guard(_storage.get_lock_primitive());

			life_assurance la;
			auto id = _storage.add_handler(handler, la.get_life_checker());
			return token::create<connection>(std::move(la), storage_ref(_storage), id);
		}

		template < typename... Args >
		void operator() (Args&&... args) const
		{
			handlers_stack_container handlers_copy;

			{
				lock_guard(_storage.get_lock_primitive());
				handlers_copy.assign(_storage.get_handlers().begin(), _storage.get_handlers().end());
			}

			for (const auto& h : handlers_copy)
			{
				execution_guard g(h.get_life_checker());
				if (g.is_alive())
					h.get_handler()(std::forward<Args>(args)...);
			}
		}
	};

	template < typename Signature_ >
	using signal = basic_signal<Signature_, signal_policies::threading::own_mutex<std::mutex>, signal_policies::handlers_storage::shared_list, signal_policies::life_assurance::life_tokens>;

}

#endif
<commit_msg>Fixed locks in signal<commit_after>#ifndef WIGWAG_SIGNAL_HPP
#define WIGWAG_SIGNAL_HPP

// Copyright (c) 2016, Dmitry Koplyarov <koplyarov.da@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
// provided that the above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include <wigwag/life_token.hpp>
#include <wigwag/signal_policies.hpp>
#include <wigwag/token.hpp>

#include <list>

namespace wigwag
{

	template < typename Signature_, typename ThreadingPolicy_, typename HandlersStoragePolicy_, typename LifeAssurancePolicy_ >
	class basic_signal
	{
	public:
		using handler_type = std::function<Signature_>;
		using populator_type = std::function<void(const std::function<Signature_>&)>;

		using lock_primitive = typename ThreadingPolicy_::lock_primitive;

		using life_assurance = typename LifeAssurancePolicy_::life_assurance;
		using life_checker = typename LifeAssurancePolicy_::life_checker;
		using execution_guard = typename LifeAssurancePolicy_::execution_guard;

		using handlers_stack_container = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>::handlers_stack_container;
		using handler_id = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>::handler_id;
		using storage = typename HandlersStoragePolicy_::template storage<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>;
		using storage_ref = typename HandlersStoragePolicy_::template storage_ref<Signature_, ThreadingPolicy_, LifeAssurancePolicy_>;

	private:
		class lock_guard
		{
			const lock_primitive& _lp;

		public:
			lock_guard(const lock_primitive& lp) : _lp(lp) { _lp.lock(); }
			~lock_guard() { _lp.unlock(); }
		};

		struct connection : public token::implementation, public life_assurance
		{
			storage_ref		_storage_ref;
			handler_id		_id;

		public:
			connection(life_assurance&& la, storage_ref sr, handler_id id)
				: life_assurance(std::move(la)), _storage_ref(sr), _id(id)
			{ }

			~connection()
			{
				lock_guard lg(_storage_ref.get_lock_primitive());
				_storage_ref.erase_handler(_id);
			}
		};

	private:
		storage		_storage;

	public:
		token connect(const handler_type& handler)
		{
			lock_guard lg(_storage.get_lock_primitive());

			life_assurance la;
			auto id = _storage.add_handler(handler, la.get_life_checker());
			return token::create<connection>(std::move(la), storage_ref(_storage), id);
		}

		template < typename... Args >
		void operator() (Args&&... args) const
		{
			handlers_stack_container handlers_copy;

			{
				lock_guard lg(_storage.get_lock_primitive());
				handlers_copy.assign(_storage.get_handlers().begin(), _storage.get_handlers().end());
			}

			for (const auto& h : handlers_copy)
			{
				execution_guard g(h.get_life_checker());
				if (g.is_alive())
					h.get_handler()(std::forward<Args>(args)...);
			}
		}
	};

	template < typename Signature_ >
	using signal = basic_signal<Signature_, signal_policies::threading::own_mutex<std::mutex>, signal_policies::handlers_storage::shared_list, signal_policies::life_assurance::life_tokens>;

}

#endif
<|endoftext|>