<commit_before>/**
 * @file
 *
 * @brief
 *
 * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 */

#include <cmdline.hpp>

#include <kdb.hpp>
#include <keysetio.hpp>
#include <kdbconfig.h>

#include <iostream>
#include <vector>
#include <cstdio>
#include <set>

#include <getopt.h>

#include <command.hpp>
#include <external.hpp>

using namespace std;

Cmdline::Cmdline (int argc,
		  char** argv,
		  Command *command
		 ) :
	helpText(),
	invalidOpt(false),

	/*XXX: Step 2: initialise your option here.*/
	debug(),
	force(),
	load(),
	humanReadable(),
	help(),
	interactive(),
	noNewline(),
	test(),
	recursive(),
	resolver(KDB_DEFAULT_RESOLVER),
	strategy("preserve"),
	verbose(),
	version(),
	withoutElektra(),
	null(),
	first(true),
	second(true),
	third(true),
	all(),
	format("dump"),
	plugins("sync"),
	pluginsConfig(""),
	ns("user"),
	editor(),

	executable(),
	commandName()
{
	extern int optind;
	extern char *optarg;

	int index = 0;
	int opt;

	size_t optionPos;

	synopsis = command->getSynopsis();

	helpText += command->getShortHelpText();
	helpText += "\n";
	helpText += command->getLongHelpText();
	helpText += "\n";

	string allOptions = command->getShortOptions();
	allOptions += "HV";

	std::set<string::value_type> unique_sorted_chars (allOptions.begin(), allOptions.end());
	string acceptedOptions (unique_sorted_chars.begin(), unique_sorted_chars.end());

	vector<option> long_options;
	/*XXX: Step 3: give it a long name.*/
	if (acceptedOptions.find('a')!=string::npos)
	{
		option o = {"all", no_argument, nullptr, 'a'};
		long_options.push_back(o);
		helpText += "-a --all                 Consider all of the keys.\n";
	}
	if (acceptedOptions.find('d')!=string::npos)
	{
		option o = {"debug", no_argument, nullptr, 'd'};
		long_options.push_back(o);
		helpText += "-d --debug               Give debug information or ask debug questions (in interactive mode).\n";
	}
	if (acceptedOptions.find('f')!=string::npos)
	{
		option o = {"force", no_argument, nullptr, 'f'};
		long_options.push_back(o);
		helpText += "-f --force               Force the action to be done.\n";
	}
	if (acceptedOptions.find('l')!=string::npos)
	{
		option o = {"load", no_argument, nullptr, 'f'};
		long_options.push_back(o);
		helpText += "-l --load                Load plugin even if system/elektra is available\n";
	}
	if (acceptedOptions.find('h')!=string::npos)
	{
		option o = {"human-readable", no_argument, nullptr, 'h'};
		long_options.push_back(o);
		helpText += "-h --human-readable      Print numbers in an human readable way\n";
	}
	if (acceptedOptions.find('H')!=string::npos)
	{
		option o = {"help", no_argument, nullptr, 'H'};
		long_options.push_back(o);
		helpText += "-H --help                Show the man page.\n";
	}
	if (acceptedOptions.find('i')!=string::npos)
	{
		option o = {"interactive", no_argument, nullptr, 'i'};
		long_options.push_back(o);
		helpText += "-i --interactive         Instead of passing all information by parameters\n";
		helpText += "                         ask the user interactively.\n";
	}
	if (acceptedOptions.find('n')!=string::npos)
	{
		option o = {"no-newline", no_argument, nullptr, 'n'};
		long_options.push_back(o);
		helpText += "-n --no-newline          Suppress the newline at the end of the output.\n";
	}
	if (acceptedOptions.find('t')!=string::npos)
	{
		option o = {"test", no_argument, nullptr, 't'};
		long_options.push_back(o);
		helpText += "-t --test                Test.\n";
	}
	if (acceptedOptions.find('r')!=string::npos)
	{
		option o = {"recursive", no_argument, nullptr, 'r'};
		long_options.push_back(o);
		helpText += "-r --recursive           Work in a recursive mode.\n";
	}
	optionPos = acceptedOptions.find('R');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"resolver", required_argument, nullptr, 'R'};
		long_options.push_back (o);
		helpText +=
				"-R --resolver <name>     Specify the resolver plugin to use\n"
				"                         if no resolver is given, the default resolver is used.\n"
				"";
	}
	optionPos = acceptedOptions.find('s');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"strategy", required_argument, nullptr, 's'};
		long_options.push_back(o);
		helpText +=
			"-s --strategy <name>     Specify which strategy should be used to resolve conflicts.\n";
	}
	if (acceptedOptions.find('v')!=string::npos)
	{
		option o = {"verbose", no_argument, nullptr, 'v'};
		long_options.push_back(o);
		helpText += "-v --verbose             Explain what is happening.\n";
	}
	if (acceptedOptions.find('V')!=string::npos)
	{
		option o = {"version", no_argument, nullptr, 'V'};
		long_options.push_back(o);
		helpText += "-V --version             Print version info.\n";
	}
	if (acceptedOptions.find('E')!=string::npos)
	{
		option o = {"without-elektra", no_argument, nullptr, 'E'};
		long_options.push_back(o);
		helpText += "-E --without-elektra     Omit the `system/elektra` directory.\n";
	}
	optionPos = acceptedOptions.find('e');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"editor", required_argument, 0, 'e'};
		long_options.push_back(o);
		helpText += "-e --editor              Which external editor to use.\n";
	}
	if (acceptedOptions.find('0')!=string::npos)
	{
		option o = {"null", no_argument, nullptr, '0'};
		long_options.push_back(o);
		helpText += "-0 --null                Use binary 0 termination.\n";
	}
	if (acceptedOptions.find('1')!=string::npos)
	{
		option o = {"first", no_argument, nullptr, '1'};
		long_options.push_back(o);
		helpText += "-1 --first               Suppress the first column.\n";
	}
	if (acceptedOptions.find('2')!=string::npos)
	{
		option o = {"second", no_argument, nullptr, '2'};
		long_options.push_back(o);
		helpText += "-2 --second              Suppress the second column.\n";
	}
	if (acceptedOptions.find('3')!=string::npos)
	{
		option o = {"third", no_argument, nullptr, '3'};
		long_options.push_back(o);
		helpText += "-3 --third               Suppress the third column.\n";
	}
	optionPos = acceptedOptions.find('N');
	if (acceptedOptions.find('N')!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"namespace", required_argument, nullptr, 'N'};
		long_options.push_back(o);
		helpText += "-N --namespace ns        Specify the namespace to use when writing cascading keys\n"
			    "                         Default: value of /sw/kdb/current/namespace or user.\n";
	}
	optionPos = acceptedOptions.find('c');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"plugins-config", no_argument, nullptr, 'c'};
		long_options.push_back(o);
		helpText += "-c --plugins-config      Add a plugin configuration.\n";
	}

	{
		using namespace kdb;
		/*XXX: Step 4: use default from KDB, if available.*/
		std::string dirname = "/sw/kdb/current/";
		KDB kdb;
		KeySet conf;
		kdb.get(conf, dirname);

		Key k;

		k = conf.lookup(dirname+"resolver");
		if (k) resolver = k.get<string>();

		k = conf.lookup(dirname+"format");
		if (k) format = k.get<string>();

		k = conf.lookup(dirname+"plugins");
		if (k) plugins = k.get<string>();

		k = conf.lookup(dirname+"namespace");
		if (k) ns = k.get<string>();

		k = conf.lookup(dirname+"editor");
		if (k) editor = k.get<string>();
	}

	option o = {nullptr, 0, nullptr, 0};
	long_options.push_back(o);

	executable = argv[0];
	commandName = argv[1];

	if (dynamic_cast<ExternalCommand*>(command))
	{
		// do not print to stderr for external commands,
		// we do not know which options they have and
		// otherwise maybe wrong "invalid/unrecognized option"
		// are reported to stderr.
		opterr = 0;
	}

	while ((opt = getopt_long (argc, argv,
					acceptedOptions.c_str(),
					&long_options[0], &index)) != EOF)
	{
		switch (opt)
		{
		/*XXX: Step 5: and now process the option.*/
		case 'a': all = true; break;
		case 'd': debug = true; break;
		case 'e': editor = optarg; break;
		case 'f': force = true; break;
		case 'h': humanReadable = true; break;
		case 'l': load= true; break;
		case 'H': help = true; break;
		case 'i': interactive = true; break;
		case 'n': noNewline = true; break;
		case 't': test = true; break;
		case 'r': recursive = true; break;
		case 'R': resolver = optarg; break;
		case 's': strategy = optarg; break;
		case 'v': verbose = true; break;
		case 'V': version = true; break;
		case 'E': withoutElektra= true; break;
		case '0': null= true; break;
		case '1': first= false; break;
		case '2': second= false; break;
		case '3': third= false; break;
		case 'N': ns = optarg; break;
		case 'c': pluginsConfig = optarg; break;

		default: invalidOpt = true; break;
		}
	}

	optind++; // skip the command name
	while (optind < argc)
	{
		arguments.push_back(argv[optind++]);
	}
}

kdb::KeySet Cmdline::getPluginsConfig(string basepath) const
{
	using namespace kdb;

	string keyName;
	string value;
	KeySet ret;
	istringstream sstream(pluginsConfig);

	// read until the next '=', this will be the keyname
	while (std::getline (sstream, keyName, '='))
	{
		// read until a ',' or the end of line
		// if nothing is read because the '=' is the last character
		// in the config string, consider the value empty
		if (!std::getline (sstream, value, ',')) value = "";

		Key configKey = Key (basepath + keyName, KEY_END);
		configKey.setString (value);
		ret.append (configKey);
	}
	return ret;
}

std::ostream & operator<< (std::ostream & os, Cmdline & cl)
{
	if (cl.invalidOpt)
	{
		os << "Invalid option given\n" << endl;
	}

	os << "Usage: " << cl.executable << " " << cl.commandName << " " << cl.synopsis;
	os << "\n\n" << cl.helpText;
	return os;
}
<commit_msg>kdb: new KDB names for internal conf<commit_after>/**
 * @file
 *
 * @brief
 *
 * @copyright BSD License (see doc/COPYING or http://www.libelektra.org)
 */

#include <cmdline.hpp>

#include <kdb.hpp>
#include <keysetio.hpp>
#include <kdbconfig.h>

#include <iostream>
#include <vector>
#include <cstdio>
#include <set>

#include <getopt.h>

#include <command.hpp>
#include <external.hpp>

using namespace std;

Cmdline::Cmdline (int argc,
		  char** argv,
		  Command *command
		 ) :
	helpText(),
	invalidOpt(false),

	/*XXX: Step 2: initialise your option here.*/
	debug(),
	force(),
	load(),
	humanReadable(),
	help(),
	interactive(),
	noNewline(),
	test(),
	recursive(),
	resolver(KDB_DEFAULT_RESOLVER),
	strategy("preserve"),
	verbose(),
	version(),
	withoutElektra(),
	null(),
	first(true),
	second(true),
	third(true),
	all(),
	format("dump"),
	plugins("sync"),
	pluginsConfig(""),
	ns("user"),
	editor(),

	executable(),
	commandName()
{
	extern int optind;
	extern char *optarg;

	int index = 0;
	int opt;

	size_t optionPos;

	synopsis = command->getSynopsis();

	helpText += command->getShortHelpText();
	helpText += "\n";
	helpText += command->getLongHelpText();
	helpText += "\n";

	string allOptions = command->getShortOptions();
	allOptions += "HV";

	std::set<string::value_type> unique_sorted_chars (allOptions.begin(), allOptions.end());
	string acceptedOptions (unique_sorted_chars.begin(), unique_sorted_chars.end());

	vector<option> long_options;
	/*XXX: Step 3: give it a long name.*/
	if (acceptedOptions.find('a')!=string::npos)
	{
		option o = {"all", no_argument, nullptr, 'a'};
		long_options.push_back(o);
		helpText += "-a --all                 Consider all of the keys.\n";
	}
	if (acceptedOptions.find('d')!=string::npos)
	{
		option o = {"debug", no_argument, nullptr, 'd'};
		long_options.push_back(o);
		helpText += "-d --debug               Give debug information or ask debug questions (in interactive mode).\n";
	}
	if (acceptedOptions.find('f')!=string::npos)
	{
		option o = {"force", no_argument, nullptr, 'f'};
		long_options.push_back(o);
		helpText += "-f --force               Force the action to be done.\n";
	}
	if (acceptedOptions.find('l')!=string::npos)
	{
		option o = {"load", no_argument, nullptr, 'f'};
		long_options.push_back(o);
		helpText += "-l --load                Load plugin even if system/elektra is available\n";
	}
	if (acceptedOptions.find('h')!=string::npos)
	{
		option o = {"human-readable", no_argument, nullptr, 'h'};
		long_options.push_back(o);
		helpText += "-h --human-readable      Print numbers in an human readable way\n";
	}
	if (acceptedOptions.find('H')!=string::npos)
	{
		option o = {"help", no_argument, nullptr, 'H'};
		long_options.push_back(o);
		helpText += "-H --help                Show the man page.\n";
	}
	if (acceptedOptions.find('i')!=string::npos)
	{
		option o = {"interactive", no_argument, nullptr, 'i'};
		long_options.push_back(o);
		helpText += "-i --interactive         Instead of passing all information by parameters\n";
		helpText += "                         ask the user interactively.\n";
	}
	if (acceptedOptions.find('n')!=string::npos)
	{
		option o = {"no-newline", no_argument, nullptr, 'n'};
		long_options.push_back(o);
		helpText += "-n --no-newline          Suppress the newline at the end of the output.\n";
	}
	if (acceptedOptions.find('t')!=string::npos)
	{
		option o = {"test", no_argument, nullptr, 't'};
		long_options.push_back(o);
		helpText += "-t --test                Test.\n";
	}
	if (acceptedOptions.find('r')!=string::npos)
	{
		option o = {"recursive", no_argument, nullptr, 'r'};
		long_options.push_back(o);
		helpText += "-r --recursive           Work in a recursive mode.\n";
	}
	optionPos = acceptedOptions.find('R');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"resolver", required_argument, nullptr, 'R'};
		long_options.push_back (o);
		helpText +=
				"-R --resolver <name>     Specify the resolver plugin to use\n"
				"                         if no resolver is given, the default resolver is used.\n"
				"";
	}
	optionPos = acceptedOptions.find('s');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"strategy", required_argument, nullptr, 's'};
		long_options.push_back(o);
		helpText +=
			"-s --strategy <name>     Specify which strategy should be used to resolve conflicts.\n";
	}
	if (acceptedOptions.find('v')!=string::npos)
	{
		option o = {"verbose", no_argument, nullptr, 'v'};
		long_options.push_back(o);
		helpText += "-v --verbose             Explain what is happening.\n";
	}
	if (acceptedOptions.find('V')!=string::npos)
	{
		option o = {"version", no_argument, nullptr, 'V'};
		long_options.push_back(o);
		helpText += "-V --version             Print version info.\n";
	}
	if (acceptedOptions.find('E')!=string::npos)
	{
		option o = {"without-elektra", no_argument, nullptr, 'E'};
		long_options.push_back(o);
		helpText += "-E --without-elektra     Omit the `system/elektra` directory.\n";
	}
	optionPos = acceptedOptions.find('e');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"editor", required_argument, 0, 'e'};
		long_options.push_back(o);
		helpText += "-e --editor              Which external editor to use.\n";
	}
	if (acceptedOptions.find('0')!=string::npos)
	{
		option o = {"null", no_argument, nullptr, '0'};
		long_options.push_back(o);
		helpText += "-0 --null                Use binary 0 termination.\n";
	}
	if (acceptedOptions.find('1')!=string::npos)
	{
		option o = {"first", no_argument, nullptr, '1'};
		long_options.push_back(o);
		helpText += "-1 --first               Suppress the first column.\n";
	}
	if (acceptedOptions.find('2')!=string::npos)
	{
		option o = {"second", no_argument, nullptr, '2'};
		long_options.push_back(o);
		helpText += "-2 --second              Suppress the second column.\n";
	}
	if (acceptedOptions.find('3')!=string::npos)
	{
		option o = {"third", no_argument, nullptr, '3'};
		long_options.push_back(o);
		helpText += "-3 --third               Suppress the third column.\n";
	}
	optionPos = acceptedOptions.find('N');
	if (acceptedOptions.find('N')!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"namespace", required_argument, nullptr, 'N'};
		long_options.push_back(o);
		helpText += "-N --namespace ns        Specify the namespace to use when writing cascading keys\n"
			    "                         Default: value of /sw/kdb/current/namespace or user.\n";
	}
	optionPos = acceptedOptions.find('c');
	if (optionPos!=string::npos)
	{
		acceptedOptions.insert(optionPos+1, ":");
		option o = {"plugins-config", no_argument, nullptr, 'c'};
		long_options.push_back(o);
		helpText += "-c --plugins-config      Add a plugin configuration.\n";
	}

	{
		using namespace kdb;
		/*XXX: Step 4: use default from KDB, if available.*/
		KDB kdb;
		KeySet conf;

		for (int i=0; i<=2; ++i)
		{
			std::string dirname;
			switch (i)
			{
			// prefer later dirnames (will override)
			case 0: dirname = "/sw/kdb/current/"; break; // legacy
			case 1: dirname = "/sw/elektra/kdb/#0/%/"; break; // no profile
			case 2: dirname = "/sw/elektra/kdb/#0/current/"; break; // current profile
			}

			kdb.get(conf, dirname);

			Key k = conf.lookup(dirname+"resolver");
			if (k) resolver = k.get<string>();

			k = conf.lookup(dirname+"format");
			if (k) format = k.get<string>();

			k = conf.lookup(dirname+"plugins");
			if (k) plugins = k.get<string>();

			k = conf.lookup(dirname+"namespace");
			if (k) ns = k.get<string>();

			k = conf.lookup(dirname+"editor");
			if (k) editor = k.get<string>();
		}

	}

	option o = {nullptr, 0, nullptr, 0};
	long_options.push_back(o);

	executable = argv[0];
	commandName = argv[1];

	if (dynamic_cast<ExternalCommand*>(command))
	{
		// do not print to stderr for external commands,
		// we do not know which options they have and
		// otherwise maybe wrong "invalid/unrecognized option"
		// are reported to stderr.
		opterr = 0;
	}

	while ((opt = getopt_long (argc, argv,
					acceptedOptions.c_str(),
					&long_options[0], &index)) != EOF)
	{
		switch (opt)
		{
		/*XXX: Step 5: and now process the option.*/
		case 'a': all = true; break;
		case 'd': debug = true; break;
		case 'e': editor = optarg; break;
		case 'f': force = true; break;
		case 'h': humanReadable = true; break;
		case 'l': load= true; break;
		case 'H': help = true; break;
		case 'i': interactive = true; break;
		case 'n': noNewline = true; break;
		case 't': test = true; break;
		case 'r': recursive = true; break;
		case 'R': resolver = optarg; break;
		case 's': strategy = optarg; break;
		case 'v': verbose = true; break;
		case 'V': version = true; break;
		case 'E': withoutElektra= true; break;
		case '0': null= true; break;
		case '1': first= false; break;
		case '2': second= false; break;
		case '3': third= false; break;
		case 'N': ns = optarg; break;
		case 'c': pluginsConfig = optarg; break;

		default: invalidOpt = true; break;
		}
	}

	optind++; // skip the command name
	while (optind < argc)
	{
		arguments.push_back(argv[optind++]);
	}
}

kdb::KeySet Cmdline::getPluginsConfig(string basepath) const
{
	using namespace kdb;

	string keyName;
	string value;
	KeySet ret;
	istringstream sstream(pluginsConfig);

	// read until the next '=', this will be the keyname
	while (std::getline (sstream, keyName, '='))
	{
		// read until a ',' or the end of line
		// if nothing is read because the '=' is the last character
		// in the config string, consider the value empty
		if (!std::getline (sstream, value, ',')) value = "";

		Key configKey = Key (basepath + keyName, KEY_END);
		configKey.setString (value);
		ret.append (configKey);
	}
	return ret;
}

std::ostream & operator<< (std::ostream & os, Cmdline & cl)
{
	if (cl.invalidOpt)
	{
		os << "Invalid option given\n" << endl;
	}

	os << "Usage: " << cl.executable << " " << cl.commandName << " " << cl.synopsis;
	os << "\n\n" << cl.helpText;
	return os;
}
<|endoftext|>


<commit_before>/***********************************************************************
  Moses - factored phrase-based language decoder
  Copyright (C) 2011 University of Edinburgh

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

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

  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ***********************************************************************/

#include "ChartRuleLookupManagerOnDisk.h"

#include <algorithm>

#include "PhraseDictionaryOnDisk.h"
#include "StaticData.h"
#include "DotChartOnDisk.h"
#include "ChartTranslationOptionList.h"
#include "../../OnDiskPt/src/TargetPhraseCollection.h"

using namespace std;

namespace Moses
{

ChartRuleLookupManagerOnDisk::ChartRuleLookupManagerOnDisk(
  const InputType &sentence,
  const ChartCellCollection &cellColl,
  const PhraseDictionaryOnDisk &dictionary,
  OnDiskPt::OnDiskWrapper &dbWrapper,
  const LMList *languageModels,
  const WordPenaltyProducer *wpProducer,
  const std::vector<FactorType> &inputFactorsVec,
  const std::vector<FactorType> &outputFactorsVec,
  const std::vector<float> &weight,
  const std::string &filePath)
  : ChartRuleLookupManager(sentence, cellColl)
  , m_dictionary(dictionary)
  , m_dbWrapper(dbWrapper)
  , m_languageModels(languageModels)
  , m_wpProducer(wpProducer)
  , m_inputFactorsVec(inputFactorsVec)
  , m_outputFactorsVec(outputFactorsVec)
  , m_weight(weight)
  , m_filePath(filePath)
{
  assert(m_expandableDottedRuleListVec.size() == 0);
  size_t sourceSize = sentence.GetSize();
  m_expandableDottedRuleListVec.resize(sourceSize);

  for (size_t ind = 0; ind < m_expandableDottedRuleListVec.size(); ++ind) {
    DottedRuleOnDisk *initDottedRule = new DottedRuleOnDisk(m_dbWrapper.GetRootSourceNode());

    DottedRuleStackOnDisk *processedStack = new DottedRuleStackOnDisk(sourceSize - ind + 1);
    processedStack->Add(0, initDottedRule); // init rule. stores the top node in tree

    m_expandableDottedRuleListVec[ind] = processedStack;
  }
}

ChartRuleLookupManagerOnDisk::~ChartRuleLookupManagerOnDisk()
{
  std::map<UINT64, const TargetPhraseCollection*>::const_iterator iterCache;
  for (iterCache = m_cache.begin(); iterCache != m_cache.end(); ++iterCache) {
    delete iterCache->second;
  }
  m_cache.clear();

  RemoveAllInColl(m_expandableDottedRuleListVec);
  RemoveAllInColl(m_sourcePhraseNode);
}

void ChartRuleLookupManagerOnDisk::GetChartRuleCollection(
  const WordsRange &range,
  bool adhereTableLimit,
  ChartTranslationOptionList &outColl)
{
  const StaticData &staticData = StaticData::Instance();
  size_t rulesLimit = StaticData::Instance().GetRuleLimit();

  size_t relEndPos = range.GetEndPos() - range.GetStartPos();
  size_t absEndPos = range.GetEndPos();

  // MAIN LOOP. create list of nodes of target phrases
  DottedRuleStackOnDisk &expandableDottedRuleList = *m_expandableDottedRuleListVec[range.GetStartPos()];

  // sort save nodes so only do nodes with most counts
  expandableDottedRuleList.SortSavedNodes();
  size_t numDerivations = 0
                          ,maxDerivations = 999999; // staticData.GetMaxDerivations();
  bool overThreshold = true;

  const DottedRuleStackOnDisk::SavedNodeColl &savedNodeColl = expandableDottedRuleList.GetSavedNodeColl();
  //cerr << "savedNodeColl=" << savedNodeColl.size() << " ";

  for (size_t ind = 0; ind < (savedNodeColl.size()) && ((numDerivations < maxDerivations) || overThreshold) ; ++ind) {
    const SavedNodeOnDisk &savedNode = *savedNodeColl[ind];

    const DottedRuleOnDisk &prevDottedRule = savedNode.GetDottedRule();
    const OnDiskPt::PhraseNode &prevNode = prevDottedRule.GetLastNode();
    const CoveredChartSpan *prevCoveredChartSpan = prevDottedRule.GetLastCoveredChartSpan();
    size_t startPos = (prevCoveredChartSpan == NULL) ? range.GetStartPos() : prevCoveredChartSpan->GetWordsRange().GetEndPos() + 1;

    // search for terminal symbol
    if (startPos == absEndPos) {
      const Word &sourceWord = GetSentence().GetWord(absEndPos);
      OnDiskPt::Word *sourceWordBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceWord);

      if (sourceWordBerkeleyDb != NULL) {
        const OnDiskPt::PhraseNode *node = prevNode.GetChild(*sourceWordBerkeleyDb, m_dbWrapper);
        if (node != NULL) {
          // TODO figure out why source word is needed from node, not from sentence
          // prob to do with factors or non-term
          //const Word &sourceWord = node->GetSourceWord();
          CoveredChartSpan *newCoveredChartSpan = new CoveredChartSpan(absEndPos, absEndPos
              , sourceWord
              , prevCoveredChartSpan);
          DottedRuleOnDisk *dottedRule = new DottedRuleOnDisk(*node, newCoveredChartSpan);
          expandableDottedRuleList.Add(relEndPos+1, dottedRule);

          // cache for cleanup
          m_sourcePhraseNode.push_back(node);
        }

        delete sourceWordBerkeleyDb;
      }
    }

    // search for non-terminals
    size_t endPos, stackInd;
    if (startPos > absEndPos)
      continue;
    else if (startPos == range.GetStartPos() && range.GetEndPos() > range.GetStartPos()) {
      // start.
      endPos = absEndPos - 1;
      stackInd = relEndPos;
    } else {
      endPos = absEndPos;
      stackInd = relEndPos + 1;
    }

    // size_t nonTermNumWordsCovered = endPos - startPos + 1;

    // get target nonterminals in this span from chart
    const NonTerminalSet &chartNonTermSet = GetCellCollection().GetConstituentLabelSet(WordsRange(startPos, endPos));

    //const Word &defaultSourceNonTerm = staticData.GetInputDefaultNonTerminal()
    //                                   ,&defaultTargetNonTerm = staticData.GetOutputDefaultNonTerminal();

    // go through each SOURCE lhs
    const NonTerminalSet &sourceLHSSet = GetSentence().GetLabelSet(startPos, endPos);

    NonTerminalSet::const_iterator iterSourceLHS;
    for (iterSourceLHS = sourceLHSSet.begin(); iterSourceLHS != sourceLHSSet.end(); ++iterSourceLHS) {
      const Word &sourceLHS = *iterSourceLHS;

      OnDiskPt::Word *sourceLHSBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceLHS);

      if (sourceLHSBerkeleyDb == NULL) {
        delete sourceLHSBerkeleyDb;
        continue; // vocab not in pt. node definately won't be in there
      }

      const OnDiskPt::PhraseNode *sourceNode = prevNode.GetChild(*sourceLHSBerkeleyDb, m_dbWrapper);
      delete sourceLHSBerkeleyDb;

      if (sourceNode == NULL)
        continue; // didn't find source node

      // go through each TARGET lhs
      NonTerminalSet::const_iterator iterChartNonTerm;
      for (iterChartNonTerm = chartNonTermSet.begin(); iterChartNonTerm != chartNonTermSet.end(); ++iterChartNonTerm) {
        const Word &chartNonTerm = *iterChartNonTerm;

        //cerr << sourceLHS << " " << defaultSourceNonTerm << " " << chartNonTerm << " " << defaultTargetNonTerm << endl;

        //bool isSyntaxNonTerm = (sourceLHS != defaultSourceNonTerm) || (chartNonTerm != defaultTargetNonTerm);
        bool doSearch = true; //isSyntaxNonTerm ? nonTermNumWordsCovered <=  maxSyntaxSpan :
        //						nonTermNumWordsCovered <= maxDefaultSpan;

        if (doSearch) {

          OnDiskPt::Word *chartNonTermBerkeleyDb = m_dbWrapper.ConvertFromMoses(Output, m_outputFactorsVec, chartNonTerm);

          if (chartNonTermBerkeleyDb == NULL)
            continue;

          const OnDiskPt::PhraseNode *node = sourceNode->GetChild(*chartNonTermBerkeleyDb, m_dbWrapper);
          delete chartNonTermBerkeleyDb;

          if (node == NULL)
            continue;

          // found matching entry
          //const Word &sourceWord = node->GetSourceWord();
          CoveredChartSpan *newCoveredChartSpan = new CoveredChartSpan(startPos, endPos
              , chartNonTerm
              , prevCoveredChartSpan);

          DottedRuleOnDisk *dottedRule = new DottedRuleOnDisk(*node, newCoveredChartSpan);
          expandableDottedRuleList.Add(stackInd, dottedRule);

          m_sourcePhraseNode.push_back(node);
        }
      } // for (iterChartNonTerm

      delete sourceNode;

    } // for (iterLabelListf

    // return list of target phrases
    DottedRuleCollOnDisk &nodes = expandableDottedRuleList.Get(relEndPos + 1);

    // source LHS
    DottedRuleCollOnDisk::const_iterator iterDottedRuleColl;
    for (iterDottedRuleColl = nodes.begin(); iterDottedRuleColl != nodes.end(); ++iterDottedRuleColl) {
      // node of last source word
      const DottedRuleOnDisk &prevDottedRule = **iterDottedRuleColl;
      if (prevDottedRule.Done())
        continue;
      prevDottedRule.Done(true);

      const CoveredChartSpan *coveredChartSpan = prevDottedRule.GetLastCoveredChartSpan();
      assert(coveredChartSpan);

      const OnDiskPt::PhraseNode &prevNode = prevDottedRule.GetLastNode();

      //get node for each source LHS
      const NonTerminalSet &lhsSet = GetSentence().GetLabelSet(range.GetStartPos(), range.GetEndPos());
      NonTerminalSet::const_iterator iterLabelSet;
      for (iterLabelSet = lhsSet.begin(); iterLabelSet != lhsSet.end(); ++iterLabelSet) {
        const Word &sourceLHS = *iterLabelSet;

        OnDiskPt::Word *sourceLHSBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceLHS);
        if (sourceLHSBerkeleyDb == NULL)
          continue;

        const TargetPhraseCollection *targetPhraseCollection = NULL;
        const OnDiskPt::PhraseNode *node = prevNode.GetChild(*sourceLHSBerkeleyDb, m_dbWrapper);
        if (node) {
          UINT64 tpCollFilePos = node->GetValue();
          std::map<UINT64, const TargetPhraseCollection*>::const_iterator iterCache = m_cache.find(tpCollFilePos);
          if (iterCache == m_cache.end()) {
            // not in case
            overThreshold = node->GetCount(0) > staticData.GetRuleCountThreshold();
            //cerr << node->GetCount(0) << " ";

            const OnDiskPt::TargetPhraseCollection *tpcollBerkeleyDb = node->GetTargetPhraseCollection(m_dictionary.GetTableLimit(), m_dbWrapper);

            targetPhraseCollection
            = tpcollBerkeleyDb->ConvertToMoses(m_inputFactorsVec
                                               ,m_outputFactorsVec
                                               ,m_dictionary
                                               ,m_weight
                                               ,m_wpProducer
                                               ,*m_languageModels
                                               ,m_filePath
                                               , m_dbWrapper.GetVocab());

            delete tpcollBerkeleyDb;
            m_cache[tpCollFilePos] = targetPhraseCollection;
          } else {
            // jsut get out of cache
            targetPhraseCollection = iterCache->second;
          }

          assert(targetPhraseCollection);
          outColl.Add(*targetPhraseCollection, *coveredChartSpan,
                      GetCellCollection(), adhereTableLimit, rulesLimit);

          numDerivations++;

        } // if (node)

        delete node;
        delete sourceLHSBerkeleyDb;
      }
    }
  } // for (size_t ind = 0; ind < savedNodeColl.size(); ++ind)

  outColl.CreateChartRules(rulesLimit);

  //cerr << numDerivations << " ";
}

} // namespace Moses
<commit_msg>don't use counts for desperation pruning<commit_after>/***********************************************************************
  Moses - factored phrase-based language decoder
  Copyright (C) 2011 University of Edinburgh

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

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

  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ***********************************************************************/

#include "ChartRuleLookupManagerOnDisk.h"

#include <algorithm>

#include "PhraseDictionaryOnDisk.h"
#include "StaticData.h"
#include "DotChartOnDisk.h"
#include "ChartTranslationOptionList.h"
#include "../../OnDiskPt/src/TargetPhraseCollection.h"

using namespace std;

namespace Moses
{

ChartRuleLookupManagerOnDisk::ChartRuleLookupManagerOnDisk(
  const InputType &sentence,
  const ChartCellCollection &cellColl,
  const PhraseDictionaryOnDisk &dictionary,
  OnDiskPt::OnDiskWrapper &dbWrapper,
  const LMList *languageModels,
  const WordPenaltyProducer *wpProducer,
  const std::vector<FactorType> &inputFactorsVec,
  const std::vector<FactorType> &outputFactorsVec,
  const std::vector<float> &weight,
  const std::string &filePath)
  : ChartRuleLookupManager(sentence, cellColl)
  , m_dictionary(dictionary)
  , m_dbWrapper(dbWrapper)
  , m_languageModels(languageModels)
  , m_wpProducer(wpProducer)
  , m_inputFactorsVec(inputFactorsVec)
  , m_outputFactorsVec(outputFactorsVec)
  , m_weight(weight)
  , m_filePath(filePath)
{
  assert(m_expandableDottedRuleListVec.size() == 0);
  size_t sourceSize = sentence.GetSize();
  m_expandableDottedRuleListVec.resize(sourceSize);

  for (size_t ind = 0; ind < m_expandableDottedRuleListVec.size(); ++ind) {
    DottedRuleOnDisk *initDottedRule = new DottedRuleOnDisk(m_dbWrapper.GetRootSourceNode());

    DottedRuleStackOnDisk *processedStack = new DottedRuleStackOnDisk(sourceSize - ind + 1);
    processedStack->Add(0, initDottedRule); // init rule. stores the top node in tree

    m_expandableDottedRuleListVec[ind] = processedStack;
  }
}

ChartRuleLookupManagerOnDisk::~ChartRuleLookupManagerOnDisk()
{
  std::map<UINT64, const TargetPhraseCollection*>::const_iterator iterCache;
  for (iterCache = m_cache.begin(); iterCache != m_cache.end(); ++iterCache) {
    delete iterCache->second;
  }
  m_cache.clear();

  RemoveAllInColl(m_expandableDottedRuleListVec);
  RemoveAllInColl(m_sourcePhraseNode);
}

void ChartRuleLookupManagerOnDisk::GetChartRuleCollection(
  const WordsRange &range,
  bool adhereTableLimit,
  ChartTranslationOptionList &outColl)
{
  const StaticData &staticData = StaticData::Instance();
  size_t rulesLimit = staticData.GetRuleLimit();

  size_t relEndPos = range.GetEndPos() - range.GetStartPos();
  size_t absEndPos = range.GetEndPos();

  // MAIN LOOP. create list of nodes of target phrases
  DottedRuleStackOnDisk &expandableDottedRuleList = *m_expandableDottedRuleListVec[range.GetStartPos()];

  // sort save nodes so only do nodes with most counts
  expandableDottedRuleList.SortSavedNodes();

  const DottedRuleStackOnDisk::SavedNodeColl &savedNodeColl = expandableDottedRuleList.GetSavedNodeColl();
  //cerr << "savedNodeColl=" << savedNodeColl.size() << " ";

  for (size_t ind = 0; ind < (savedNodeColl.size()) ; ++ind) {
    const SavedNodeOnDisk &savedNode = *savedNodeColl[ind];

    const DottedRuleOnDisk &prevDottedRule = savedNode.GetDottedRule();
    const OnDiskPt::PhraseNode &prevNode = prevDottedRule.GetLastNode();
    const CoveredChartSpan *prevCoveredChartSpan = prevDottedRule.GetLastCoveredChartSpan();
    size_t startPos = (prevCoveredChartSpan == NULL) ? range.GetStartPos() : prevCoveredChartSpan->GetWordsRange().GetEndPos() + 1;

    // search for terminal symbol
    if (startPos == absEndPos) {
      const Word &sourceWord = GetSentence().GetWord(absEndPos);
      OnDiskPt::Word *sourceWordBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceWord);

      if (sourceWordBerkeleyDb != NULL) {
        const OnDiskPt::PhraseNode *node = prevNode.GetChild(*sourceWordBerkeleyDb, m_dbWrapper);
        if (node != NULL) {
          // TODO figure out why source word is needed from node, not from sentence
          // prob to do with factors or non-term
          //const Word &sourceWord = node->GetSourceWord();
          CoveredChartSpan *newCoveredChartSpan = new CoveredChartSpan(absEndPos, absEndPos
              , sourceWord
              , prevCoveredChartSpan);
          DottedRuleOnDisk *dottedRule = new DottedRuleOnDisk(*node, newCoveredChartSpan);
          expandableDottedRuleList.Add(relEndPos+1, dottedRule);

          // cache for cleanup
          m_sourcePhraseNode.push_back(node);
        }

        delete sourceWordBerkeleyDb;
      }
    }

    // search for non-terminals
    size_t endPos, stackInd;
    if (startPos > absEndPos)
      continue;
    else if (startPos == range.GetStartPos() && range.GetEndPos() > range.GetStartPos()) {
      // start.
      endPos = absEndPos - 1;
      stackInd = relEndPos;
    } else {
      endPos = absEndPos;
      stackInd = relEndPos + 1;
    }

    // size_t nonTermNumWordsCovered = endPos - startPos + 1;

    // get target nonterminals in this span from chart
    const NonTerminalSet &chartNonTermSet = GetCellCollection().GetConstituentLabelSet(WordsRange(startPos, endPos));

    //const Word &defaultSourceNonTerm = staticData.GetInputDefaultNonTerminal()
    //                                   ,&defaultTargetNonTerm = staticData.GetOutputDefaultNonTerminal();

    // go through each SOURCE lhs
    const NonTerminalSet &sourceLHSSet = GetSentence().GetLabelSet(startPos, endPos);

    NonTerminalSet::const_iterator iterSourceLHS;
    for (iterSourceLHS = sourceLHSSet.begin(); iterSourceLHS != sourceLHSSet.end(); ++iterSourceLHS) {
      const Word &sourceLHS = *iterSourceLHS;

      OnDiskPt::Word *sourceLHSBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceLHS);

      if (sourceLHSBerkeleyDb == NULL) {
        delete sourceLHSBerkeleyDb;
        continue; // vocab not in pt. node definately won't be in there
      }

      const OnDiskPt::PhraseNode *sourceNode = prevNode.GetChild(*sourceLHSBerkeleyDb, m_dbWrapper);
      delete sourceLHSBerkeleyDb;

      if (sourceNode == NULL)
        continue; // didn't find source node

      // go through each TARGET lhs
      NonTerminalSet::const_iterator iterChartNonTerm;
      for (iterChartNonTerm = chartNonTermSet.begin(); iterChartNonTerm != chartNonTermSet.end(); ++iterChartNonTerm) {
        const Word &chartNonTerm = *iterChartNonTerm;

        //cerr << sourceLHS << " " << defaultSourceNonTerm << " " << chartNonTerm << " " << defaultTargetNonTerm << endl;

        //bool isSyntaxNonTerm = (sourceLHS != defaultSourceNonTerm) || (chartNonTerm != defaultTargetNonTerm);
        bool doSearch = true; //isSyntaxNonTerm ? nonTermNumWordsCovered <=  maxSyntaxSpan :
        //						nonTermNumWordsCovered <= maxDefaultSpan;

        if (doSearch) {

          OnDiskPt::Word *chartNonTermBerkeleyDb = m_dbWrapper.ConvertFromMoses(Output, m_outputFactorsVec, chartNonTerm);

          if (chartNonTermBerkeleyDb == NULL)
            continue;

          const OnDiskPt::PhraseNode *node = sourceNode->GetChild(*chartNonTermBerkeleyDb, m_dbWrapper);
          delete chartNonTermBerkeleyDb;

          if (node == NULL)
            continue;

          // found matching entry
          //const Word &sourceWord = node->GetSourceWord();
          CoveredChartSpan *newCoveredChartSpan = new CoveredChartSpan(startPos, endPos
              , chartNonTerm
              , prevCoveredChartSpan);

          DottedRuleOnDisk *dottedRule = new DottedRuleOnDisk(*node, newCoveredChartSpan);
          expandableDottedRuleList.Add(stackInd, dottedRule);

          m_sourcePhraseNode.push_back(node);
        }
      } // for (iterChartNonTerm

      delete sourceNode;

    } // for (iterLabelListf

    // return list of target phrases
    DottedRuleCollOnDisk &nodes = expandableDottedRuleList.Get(relEndPos + 1);

    // source LHS
    DottedRuleCollOnDisk::const_iterator iterDottedRuleColl;
    for (iterDottedRuleColl = nodes.begin(); iterDottedRuleColl != nodes.end(); ++iterDottedRuleColl) {
      // node of last source word
      const DottedRuleOnDisk &prevDottedRule = **iterDottedRuleColl;
      if (prevDottedRule.Done())
        continue;
      prevDottedRule.Done(true);

      const CoveredChartSpan *coveredChartSpan = prevDottedRule.GetLastCoveredChartSpan();
      assert(coveredChartSpan);

      const OnDiskPt::PhraseNode &prevNode = prevDottedRule.GetLastNode();

      //get node for each source LHS
      const NonTerminalSet &lhsSet = GetSentence().GetLabelSet(range.GetStartPos(), range.GetEndPos());
      NonTerminalSet::const_iterator iterLabelSet;
      for (iterLabelSet = lhsSet.begin(); iterLabelSet != lhsSet.end(); ++iterLabelSet) {
        const Word &sourceLHS = *iterLabelSet;

        OnDiskPt::Word *sourceLHSBerkeleyDb = m_dbWrapper.ConvertFromMoses(Input, m_inputFactorsVec, sourceLHS);
        if (sourceLHSBerkeleyDb == NULL)
          continue;

        const TargetPhraseCollection *targetPhraseCollection = NULL;
        const OnDiskPt::PhraseNode *node = prevNode.GetChild(*sourceLHSBerkeleyDb, m_dbWrapper);
        if (node) {
          UINT64 tpCollFilePos = node->GetValue();
          std::map<UINT64, const TargetPhraseCollection*>::const_iterator iterCache = m_cache.find(tpCollFilePos);
          if (iterCache == m_cache.end()) {

            const OnDiskPt::TargetPhraseCollection *tpcollBerkeleyDb = node->GetTargetPhraseCollection(m_dictionary.GetTableLimit(), m_dbWrapper);

            targetPhraseCollection
            = tpcollBerkeleyDb->ConvertToMoses(m_inputFactorsVec
                                               ,m_outputFactorsVec
                                               ,m_dictionary
                                               ,m_weight
                                               ,m_wpProducer
                                               ,*m_languageModels
                                               ,m_filePath
                                               , m_dbWrapper.GetVocab());

            delete tpcollBerkeleyDb;
            m_cache[tpCollFilePos] = targetPhraseCollection;
          } else {
            // jsut get out of cache
            targetPhraseCollection = iterCache->second;
          }

          assert(targetPhraseCollection);
          outColl.Add(*targetPhraseCollection, *coveredChartSpan,
                      GetCellCollection(), adhereTableLimit, rulesLimit);

        } // if (node)

        delete node;
        delete sourceLHSBerkeleyDb;
      }
    }
  } // for (size_t ind = 0; ind < savedNodeColl.size(); ++ind)

  outColl.CreateChartRules(rulesLimit);

  //cerr << numDerivations << " ";
}

} // namespace Moses
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline_util/export_dot.h>
#include <vistk/pipeline_util/load_pipe.h>
#include <vistk/pipeline_util/pipe_bakery.h>
#include <vistk/pipeline_util/pipe_declaration_types.h>

#include <vistk/utilities/path.h>

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/types.h>

#include <vistk/config.h>

#include <tools/helpers/typed_value_desc.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include <cstddef>
#include <cstdlib>

namespace po = boost::program_options;

static std::string const split_str = "=";

static po::options_description make_options();
static void VISTK_NO_RETURN usage(po::options_description const& options);

int main(int argc, char* argv[])
{
  vistk::load_known_modules();

  po::options_description const desc = make_options();

  po::variables_map vm;
  try
  {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  }
  catch (po::unknown_option& e)
  {
    std::cerr << "Error: unknown option " << e.get_option_name() << std::endl;

    usage(desc);
  }
  po::notify(vm);

  if (vm.count("help"))
  {
    usage(desc);
  }

  if (!vm.count("input"))
  {
    std::cerr << "Error: input not set" << std::endl;

    usage(desc);
  }

  vistk::pipeline_t pipe;

  {
    std::istream* pistr;
    std::ifstream fin;

    vistk::path_t const ipath = vm["input"].as<vistk::path_t>();

    if (ipath.native() == vistk::path_t("-"))
    {
      pistr = &std::cin;
    }
    else
    {
      fin.open(ipath.native().c_str());

      if (!fin.good())
      {
        std::cerr << "Error: Unable to open input file" << std::endl;

        return EXIT_FAILURE;
      }

      pistr = &fin;
    }

    std::istream& istr = *pistr;

    /// \todo Include paths?

    vistk::pipe_blocks blocks = vistk::load_pipe_blocks(istr, boost::filesystem::current_path());

    // Load supplemental configuration files.
    if (vm.count("config"))
    {
      vistk::paths_t const configs = vm["config"].as<vistk::paths_t>();

      BOOST_FOREACH (vistk::path_t const& config, configs)
      {
        vistk::pipe_blocks const config_blocks = vistk::load_pipe_blocks_from_file(config);

        blocks.insert(blocks.end(), config_blocks.begin(), config_blocks.end());
      }
    }

    // Insert lone setting variables from the command line.
    if (vm.count("setting"))
    {
      std::vector<std::string> const settings = vm["setting"].as<std::vector<std::string> >();

      BOOST_FOREACH (std::string const& setting, settings)
      {
        vistk::config_pipe_block block;

        vistk::config_value_t value;

        size_t const split_pos = setting.find(split_str);

        if (split_pos == std::string::npos)
        {
          std::cerr << "Error: The setting on the command line "
                       "\'" << setting << "\' does not contain "
                       "the \'" << split_str << "\' string which "
                       "separates the key from the value" << std::endl;

          return EXIT_FAILURE;
        }

        vistk::config::key_t setting_key = setting.substr(0, split_pos);
        vistk::config::value_t setting_value = setting.substr(split_pos + split_str.size());

        vistk::config::keys_t keys;

        if (vistk::config::block_sep.size() != 1)
        {
          std::cerr << "Error: The block separator is longer than "
                       "one character and does not work here" << std::endl;

          return EXIT_FAILURE;
        }

        /// \bug Does not work if (vistk::config::block_sep.size() != 1).
        boost::split(keys, setting_key, boost::is_any_of(vistk::config::block_sep));

        if (keys.size() < 2)
        {
          std::cerr << "Error: The key in the command line setting "
                       "\'" << setting << "\' does not contain "
                       "at least two keys in its keypath which is "
                       "invalid" << std::endl;

          return EXIT_FAILURE;
        }

        value.key.key_path.push_back(keys.back());
        value.value = setting_value;

        keys.pop_back();

        block.key = keys;
        block.values.push_back(value);

        blocks.push_back(block);
      }
    }

    pipe = vistk::bake_pipe_blocks(blocks);
  }

  if (!pipe)
  {
    std::cerr << "Error: Unable to bake pipeline" << std::endl;

    return EXIT_FAILURE;
  }

  std::ostream* postr;
  std::ofstream fout;

  vistk::path_t const opath = vm["output"].as<vistk::path_t>();

  if (opath.native() == vistk::path_t("-"))
  {
    postr = &std::cout;
  }
  else
  {
    fout.open(opath.native().c_str());

    if (fout.bad())
    {
      std::cerr << "Error: Unable to open output file" << std::endl;

      return EXIT_FAILURE;
    }

    postr = &fout;
  }

  std::ostream& ostr = *postr;

  std::string const graph_name = vm["name"].as<std::string>();

  vistk::export_dot(ostr, pipe, graph_name);

  return EXIT_SUCCESS;
}

po::options_description
make_options()
{
  po::options_description desc;

  desc.add_options()
    ("help,h", "output help message and quit")
    ("input,i", po::value_desc<vistk::path_t>()->metavar("FILE"), "input path")
    ("output,o", po::value_desc<vistk::path_t>()->metavar("FILE")->default_value("-"), "output path")
    ("config,c", po::value_desc<vistk::paths_t>()->metavar("FILE"), "supplemental configuration file")
    ("setting,s", po::value_desc<std::vector<std::string> >()->metavar("VAR=VALUE"), "additional configuration")
    ("include,I", po::value_desc<vistk::paths_t>()->metavar("DIR"), "configuration include path")
    ("name,n", po::value_desc<std::string>()->metavar("NAME")->default_value("unnamed"), "name of the graph")
  ;

  return desc;
}

void
usage(po::options_description const& options)
{
  std::cerr << options << std::endl;

  exit(EXIT_FAILURE);
}
<commit_msg>Add an option to pipe_to_dot to setup the pipeline<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline_util/export_dot.h>
#include <vistk/pipeline_util/load_pipe.h>
#include <vistk/pipeline_util/pipe_bakery.h>
#include <vistk/pipeline_util/pipe_declaration_types.h>

#include <vistk/utilities/path.h>

#include <vistk/pipeline/config.h>
#include <vistk/pipeline/modules.h>
#include <vistk/pipeline/pipeline.h>
#include <vistk/pipeline/types.h>

#include <vistk/config.h>

#include <tools/helpers/typed_value_desc.h>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include <cstddef>
#include <cstdlib>

namespace po = boost::program_options;

static std::string const split_str = "=";

static po::options_description make_options();
static void VISTK_NO_RETURN usage(po::options_description const& options);

int main(int argc, char* argv[])
{
  vistk::load_known_modules();

  po::options_description const desc = make_options();

  po::variables_map vm;
  try
  {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  }
  catch (po::unknown_option& e)
  {
    std::cerr << "Error: unknown option " << e.get_option_name() << std::endl;

    usage(desc);
  }
  po::notify(vm);

  if (vm.count("help"))
  {
    usage(desc);
  }

  if (!vm.count("input"))
  {
    std::cerr << "Error: input not set" << std::endl;

    usage(desc);
  }

  vistk::pipeline_t pipe;

  {
    std::istream* pistr;
    std::ifstream fin;

    vistk::path_t const ipath = vm["input"].as<vistk::path_t>();

    if (ipath.native() == vistk::path_t("-"))
    {
      pistr = &std::cin;
    }
    else
    {
      fin.open(ipath.native().c_str());

      if (!fin.good())
      {
        std::cerr << "Error: Unable to open input file" << std::endl;

        return EXIT_FAILURE;
      }

      pistr = &fin;
    }

    std::istream& istr = *pistr;

    /// \todo Include paths?

    vistk::pipe_blocks blocks = vistk::load_pipe_blocks(istr, boost::filesystem::current_path());

    // Load supplemental configuration files.
    if (vm.count("config"))
    {
      vistk::paths_t const configs = vm["config"].as<vistk::paths_t>();

      BOOST_FOREACH (vistk::path_t const& config, configs)
      {
        vistk::pipe_blocks const config_blocks = vistk::load_pipe_blocks_from_file(config);

        blocks.insert(blocks.end(), config_blocks.begin(), config_blocks.end());
      }
    }

    // Insert lone setting variables from the command line.
    if (vm.count("setting"))
    {
      std::vector<std::string> const settings = vm["setting"].as<std::vector<std::string> >();

      BOOST_FOREACH (std::string const& setting, settings)
      {
        vistk::config_pipe_block block;

        vistk::config_value_t value;

        size_t const split_pos = setting.find(split_str);

        if (split_pos == std::string::npos)
        {
          std::cerr << "Error: The setting on the command line "
                       "\'" << setting << "\' does not contain "
                       "the \'" << split_str << "\' string which "
                       "separates the key from the value" << std::endl;

          return EXIT_FAILURE;
        }

        vistk::config::key_t setting_key = setting.substr(0, split_pos);
        vistk::config::value_t setting_value = setting.substr(split_pos + split_str.size());

        vistk::config::keys_t keys;

        if (vistk::config::block_sep.size() != 1)
        {
          std::cerr << "Error: The block separator is longer than "
                       "one character and does not work here" << std::endl;

          return EXIT_FAILURE;
        }

        /// \bug Does not work if (vistk::config::block_sep.size() != 1).
        boost::split(keys, setting_key, boost::is_any_of(vistk::config::block_sep));

        if (keys.size() < 2)
        {
          std::cerr << "Error: The key in the command line setting "
                       "\'" << setting << "\' does not contain "
                       "at least two keys in its keypath which is "
                       "invalid" << std::endl;

          return EXIT_FAILURE;
        }

        value.key.key_path.push_back(keys.back());
        value.value = setting_value;

        keys.pop_back();

        block.key = keys;
        block.values.push_back(value);

        blocks.push_back(block);
      }
    }

    pipe = vistk::bake_pipe_blocks(blocks);
  }

  if (!pipe)
  {
    std::cerr << "Error: Unable to bake pipeline" << std::endl;

    return EXIT_FAILURE;
  }

  std::ostream* postr;
  std::ofstream fout;

  vistk::path_t const opath = vm["output"].as<vistk::path_t>();

  if (opath.native() == vistk::path_t("-"))
  {
    postr = &std::cout;
  }
  else
  {
    fout.open(opath.native().c_str());

    if (fout.bad())
    {
      std::cerr << "Error: Unable to open output file" << std::endl;

      return EXIT_FAILURE;
    }

    postr = &fout;
  }

  std::ostream& ostr = *postr;

  std::string const graph_name = vm["name"].as<std::string>();

  if (vm.count("setup"))
  {
    pipe->setup_pipeline();

    vistk::export_dot_setup(ostr, pipe, graph_name);
  }
  else
  {
    vistk::export_dot(ostr, pipe, graph_name);
  }

  return EXIT_SUCCESS;
}

po::options_description
make_options()
{
  po::options_description desc;

  desc.add_options()
    ("help,h", "output help message and quit")
    ("input,i", po::value_desc<vistk::path_t>()->metavar("FILE"), "input path")
    ("output,o", po::value_desc<vistk::path_t>()->metavar("FILE")->default_value("-"), "output path")
    ("config,c", po::value_desc<vistk::paths_t>()->metavar("FILE"), "supplemental configuration file")
    ("setting,s", po::value_desc<std::vector<std::string> >()->metavar("VAR=VALUE"), "additional configuration")
    ("setup,S", "setup the pipeline before exporting")
    ("include,I", po::value_desc<vistk::paths_t>()->metavar("DIR"), "configuration include path")
    ("name,n", po::value_desc<std::string>()->metavar("NAME")->default_value("unnamed"), "name of the graph")
  ;

  return desc;
}

void
usage(po::options_description const& options)
{
  std::cerr << options << std::endl;

  exit(EXIT_FAILURE);
}
<|endoftext|>


<commit_before>#include "FileProgress.h"
#include "MainForm.h"
#include "../AppCore.h"
#include "../Utils/Utils.h"

FileProgress::FileProgress(AppCore& c) : core(c)
{

}

void FileProgress::update()
{
	refreshing = true;
	selectionChanged = false;
	updatePiecesChart();
	updateFilesProgress();
	refreshing = false;
}

void FileProgress::fileSelectionChanged(int rowIndex)
{
	if (refreshing)
		return;

	auto row = GuiLite::MainForm::instance->filesProgressGridView->Rows[rowIndex];

	mtBI::TorrentFileSelectionRequest request;
	request.index = (uint32_t)System::Convert::ToInt32(row->Cells[0]->Value->ToString());
	request.selected = System::Convert::ToBoolean(row->Cells[1]->Value->ToString());
	memcpy(request.hash, core.firstSelectedHash, 20);

	core.IoctlFunc(mtBI::MessageId::SetTorrentFileSelection, &request, nullptr);
}

void FileProgress::initPiecesChart()
{
	if (lastBitfield.size() != progress.bitfield.size() || core.selectionChanged)
	{
		System::GC::Collect();
		lastBitfield.clear(progress.bitfield.size());

		auto chart = GuiLite::MainForm::instance->pieceChart;
		chart->Visible = true;

		chart->Series["HasSeries"]->Points->Clear();
		chart->Series["Request"]->Points->Clear();
		ProgressChartIntervalSize = min(progress.piecesCount, MaxProgressChartIntervalSize);
		chart->ChartAreas[0]->AxisX->Interval = ProgressChartIntervalSize;

		for (uint32_t i = 0; i < ProgressChartIntervalSize; i++)
		{
			chart->Series["HasSeries"]->Points->AddXY(i, 0);
			chart->Series["HasSeries"]->Points[i]->IsEmpty = true;
		}

		selectionChanged = true;
	}
}

uint32_t FileProgress::getProgressChartIndex(uint32_t pieceIdx)
{
	if (ProgressChartIntervalSize < MaxProgressChartIntervalSize)
		return pieceIdx;

	float coef = ProgressChartIntervalSize / (float)progress.piecesCount;

	return (uint32_t)(pieceIdx * coef);
}

void FileProgress::updatePiecesChart()
{
	auto chart = GuiLite::MainForm::instance->pieceChart;
	progress.bitfield.clear(progress.bitfield.size());
	activePieces.clear();

	if (core.IoctlFunc(mtBI::MessageId::GetPiecesInfo, &core.firstSelectedHash, &progress) == mtt::Status::Success && !progress.bitfield.empty())
	{
		initPiecesChart();

		chart->Titles[0]->Text = int(progress.receivedCount).ToString() + "/" + int(progress.piecesCount).ToString();

		for (uint32_t i = 0; i < progress.piecesCount; i++)
		{
			size_t idx = static_cast<size_t>(i / 8.0f);
			unsigned char bitmask = 128 >> i % 8;

			bool value = (progress.bitfield[idx] & bitmask) != 0;
			bool lastValue = (lastBitfield[idx] & bitmask) != 0;

			if (value && !lastValue)
			{
				chart->Series["HasSeries"]->Points[getProgressChartIndex(i)]->IsEmpty = false;
			}
		}

		chart->Series["Request"]->Points->Clear();
		for (size_t i = 0; i < progress.requests.size(); i++)
		{
			chart->Series["Request"]->Points->AddXY(getProgressChartIndex(progress.requests[i]), 0);
		}

		activePieces.assign(progress.requests.data(), progress.requests.data() + progress.requests.size());

		std::swap(progress.bitfield, lastBitfield);
	}
	else
		chart->Visible = false;
}

void FileProgress::updateFilesProgress()
{
	auto filesGrid = GuiLite::MainForm::instance->filesProgressGridView;

	if (selectionChanged)
	{
		mtBI::TorrentInfo info;
		if (core.IoctlFunc(mtBI::MessageId::GetTorrentInfo, &core.firstSelectedHash, &info) == mtt::Status::Success)
		{
			adjustGridRowsCount(filesGrid, (int)info.files.size());

			for (uint32_t i = 0; i < info.files.size(); i++)
			{
				auto& file = info.files[i];
				auto row = gcnew cli::array< System::String^ >(9) {
					int(i).ToString(), file.selected ? "true" : "false",
						gcnew System::String(file.name.data, 0, (int)file.name.length, System::Text::Encoding::UTF8),
						"", formatBytes(file.size), int(file.size).ToString(), "", "", ""
				};

				filesGrid->Rows[i]->SetValues(row);
			}

			//filesGrid->Sort(filesGrid->Columns[1], System::ComponentModel::ListSortDirection::Ascending);
			filesGrid->ClearSelection();
		}
	}

	mtBI::TorrentFilesProgress progressInfo;
	if (core.IoctlFunc(mtBI::MessageId::GetTorrentFilesProgress, &core.firstSelectedHash, &progressInfo) == mtt::Status::Success)
	{
		if (selectionChanged)
		{
			fileFinishedPieces.clear();
			fileFinishedPieces.resize(progressInfo.files.size(), -1);
		}

		for (int i = 0; i < filesGrid->Rows->Count; i++)
		{
			int idx = System::Convert::ToInt32(filesGrid->Rows[i]->Cells[0]->Value->ToString());

			if (idx < (int)progressInfo.files.size())
			{
				const auto& file = progressInfo.files[idx];
				uint32_t piecesCount = 1 + file.pieceEnd - file.pieceStart;

				//percentage column
				filesGrid->Rows[i]->Cells[3]->Value = float(file.progress).ToString("P");

				//pieces size column
				if (selectionChanged)
					filesGrid->Rows[i]->Cells[6]->Value = int(piecesCount).ToString();

				//remaining pieces column
				if (fileFinishedPieces[idx] != file.receivedPieces)
				{
					fileFinishedPieces[idx] = file.receivedPieces;
					filesGrid->Rows[i]->Cells[7]->Value = int(piecesCount - file.receivedPieces).ToString();
				}

				//active pieces column
				size_t active = 0;
				for (auto pIdx : activePieces)
				{
					if (pIdx >= file.pieceStart && pIdx <= file.pieceEnd)
						active++;
				}
				filesGrid->Rows[i]->Cells[8]->Value = int(active).ToString();
			}
		}

		if (filesGrid->SelectedRows->Count > 0)
		{
			int idx = System::Convert::ToInt32(filesGrid->SelectedRows[0]->Cells[0]->Value->ToString());
			if (!selectionChanged)
			{
				auto chart = GuiLite::MainForm::instance->pieceChart;
				chart->Series["Request"]->Points->Clear();

				for (uint32_t i = progressInfo.files[idx].pieceStart; i <= progressInfo.files[idx].pieceEnd; i++)
				{
					chart->Series["Request"]->Points->AddXY(getProgressChartIndex(i), 0);
				}

				filesGrid->ClearSelection();
			}
		}
	}
}
<commit_msg>Gui: refresh progress chart after progress reset<commit_after>#include "FileProgress.h"
#include "MainForm.h"
#include "../AppCore.h"
#include "../Utils/Utils.h"

FileProgress::FileProgress(AppCore& c) : core(c)
{
}

void FileProgress::update()
{
	refreshing = true;
	selectionChanged = false;
	updatePiecesChart();
	updateFilesProgress();
	refreshing = false;
}

void FileProgress::fileSelectionChanged(int rowIndex)
{
	if (refreshing)
		return;

	auto row = GuiLite::MainForm::instance->filesProgressGridView->Rows[rowIndex];

	mtBI::TorrentFileSelectionRequest request;
	request.index = (uint32_t)System::Convert::ToInt32(row->Cells[0]->Value->ToString());
	request.selected = System::Convert::ToBoolean(row->Cells[1]->Value->ToString());
	memcpy(request.hash, core.firstSelectedHash, 20);

	core.IoctlFunc(mtBI::MessageId::SetTorrentFileSelection, &request, nullptr);
}

void FileProgress::initPiecesChart()
{
	if (lastBitfield.size() != progress.bitfield.size() || core.selectionChanged)
	{
		System::GC::Collect();
		lastBitfield.clear(progress.bitfield.size());

		auto chart = GuiLite::MainForm::instance->pieceChart;
		chart->Visible = true;

		chart->Series["HasSeries"]->Points->Clear();
		chart->Series["Request"]->Points->Clear();
		ProgressChartIntervalSize = min(progress.piecesCount, MaxProgressChartIntervalSize);
		chart->ChartAreas[0]->AxisX->Interval = ProgressChartIntervalSize;

		for (uint32_t i = 0; i < ProgressChartIntervalSize; i++)
		{
			chart->Series["HasSeries"]->Points->AddXY(i, 0);
			chart->Series["HasSeries"]->Points[i]->IsEmpty = true;
		}

		selectionChanged = true;
	}
}

uint32_t FileProgress::getProgressChartIndex(uint32_t pieceIdx)
{
	if (ProgressChartIntervalSize < MaxProgressChartIntervalSize)
		return pieceIdx;

	float coef = ProgressChartIntervalSize / (float)progress.piecesCount;

	return (uint32_t)(pieceIdx * coef);
}

void FileProgress::updatePiecesChart()
{
	auto chart = GuiLite::MainForm::instance->pieceChart;
	progress.bitfield.clear(progress.bitfield.size());
	activePieces.clear();

	if (core.IoctlFunc(mtBI::MessageId::GetPiecesInfo, &core.firstSelectedHash, &progress) == mtt::Status::Success && !progress.bitfield.empty())
	{
		static uint32_t lastReceivedCount = progress.receivedCount;
		if (progress.receivedCount < lastReceivedCount)
			lastBitfield.clear(0);

		initPiecesChart();

		chart->Titles[0]->Text = int(progress.receivedCount).ToString() + "/" + int(progress.piecesCount).ToString();

		for (uint32_t i = 0; i < progress.piecesCount; i++)
		{
			size_t idx = static_cast<size_t>(i / 8.0f);
			unsigned char bitmask = 128 >> i % 8;

			bool value = (progress.bitfield[idx] & bitmask) != 0;
			bool lastValue = (lastBitfield[idx] & bitmask) != 0;

			if (value && !lastValue)
			{
				chart->Series["HasSeries"]->Points[getProgressChartIndex(i)]->IsEmpty = false;
			}
		}

		chart->Series["Request"]->Points->Clear();
		for (size_t i = 0; i < progress.requests.size(); i++)
		{
			chart->Series["Request"]->Points->AddXY(getProgressChartIndex(progress.requests[i]), 0);
		}

		activePieces.assign(progress.requests.data(), progress.requests.data() + progress.requests.size());

		std::swap(progress.bitfield, lastBitfield);
		lastReceivedCount = progress.receivedCount;
	}
	else
		chart->Visible = false;
}

void FileProgress::updateFilesProgress()
{
	auto filesGrid = GuiLite::MainForm::instance->filesProgressGridView;

	if (selectionChanged)
	{
		mtBI::TorrentInfo info;
		if (core.IoctlFunc(mtBI::MessageId::GetTorrentInfo, &core.firstSelectedHash, &info) == mtt::Status::Success)
		{
			adjustGridRowsCount(filesGrid, (int)info.files.size());

			for (uint32_t i = 0; i < info.files.size(); i++)
			{
				auto& file = info.files[i];
				auto row = gcnew cli::array< System::String^ >(9) {
					int(i).ToString(), file.selected ? "true" : "false",
						gcnew System::String(file.name.data, 0, (int)file.name.length, System::Text::Encoding::UTF8),
						"", formatBytes(file.size), int(file.size).ToString(), "", "", ""
				};

				filesGrid->Rows[i]->SetValues(row);
			}

			//filesGrid->Sort(filesGrid->Columns[1], System::ComponentModel::ListSortDirection::Ascending);
			filesGrid->ClearSelection();
		}
	}

	mtBI::TorrentFilesProgress progressInfo;
	if (core.IoctlFunc(mtBI::MessageId::GetTorrentFilesProgress, &core.firstSelectedHash, &progressInfo) == mtt::Status::Success)
	{
		if (selectionChanged)
		{
			fileFinishedPieces.clear();
			fileFinishedPieces.resize(progressInfo.files.size(), -1);
		}

		for (int i = 0; i < filesGrid->Rows->Count; i++)
		{
			int idx = System::Convert::ToInt32(filesGrid->Rows[i]->Cells[0]->Value->ToString());

			if (idx < (int)progressInfo.files.size())
			{
				const auto& file = progressInfo.files[idx];
				uint32_t piecesCount = 1 + file.pieceEnd - file.pieceStart;

				//percentage column
				filesGrid->Rows[i]->Cells[3]->Value = float(file.progress).ToString("P");

				//pieces size column
				if (selectionChanged)
					filesGrid->Rows[i]->Cells[6]->Value = int(piecesCount).ToString();

				//remaining pieces column
				if (fileFinishedPieces[idx] != file.receivedPieces)
				{
					fileFinishedPieces[idx] = file.receivedPieces;
					filesGrid->Rows[i]->Cells[7]->Value = int(piecesCount - file.receivedPieces).ToString();
				}

				//active pieces column
				size_t active = 0;
				for (auto pIdx : activePieces)
				{
					if (pIdx >= file.pieceStart && pIdx <= file.pieceEnd)
						active++;
				}
				filesGrid->Rows[i]->Cells[8]->Value = int(active).ToString();
			}
		}

		if (filesGrid->SelectedRows->Count > 0)
		{
			int idx = System::Convert::ToInt32(filesGrid->SelectedRows[0]->Cells[0]->Value->ToString());
			if (!selectionChanged)
			{
				auto chart = GuiLite::MainForm::instance->pieceChart;
				chart->Series["Request"]->Points->Clear();

				for (uint32_t i = progressInfo.files[idx].pieceStart; i <= progressInfo.files[idx].pieceEnd; i++)
				{
					chart->Series["Request"]->Points->AddXY(getProgressChartIndex(i), 0);
				}

				filesGrid->ClearSelection();
			}
		}
	}
}
<|endoftext|>


<commit_before>/******************************************************************
*
* uHTTP for C++
*
* Copyright (C) Satoshi Konno 2002
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <uhttp/util/Thread.h>

#include <stdio.h>

using namespace uHTTP;

#undef UHTTP_THREAD_DETACHED

////////////////////////////////////////////////
// Thread Func
////////////////////////////////////////////////

#if defined(WIN32) && !defined(ITRON)
static DWORD WINAPI Win32ThreadProc(LPVOID lpParam) {
  Thread *thread = (Thread *)lpParam;
  thread->run();
  return 0;
}
#elif defined(BTRON)
static VOID BTronTaskProc(W param) {
  Thread *thread = (Thread *)param;
  thread->run();
  ext_tsk();
}
#elif defined(ITRON)
static TASK ITronTaskProc(int param) {
  T_RTSK rtsk;
  if (ref_tsk(TSK_SELF, &rtsk) != E_OK)
    return;
  Thread *thread = (Thread *)rtsk.exinf;
  thread->run();
  exd_tsk();
}
#elif defined(TENGINE) && !defined(PROCESS_BASE)
static VOID TEngineTaskProc(INT stacd, VP param) {
  Thread *thread = (Thread *)param;
  thread->run();
  tk_exd_tsk();
}
#elif defined(TENGINE) && defined(PROCESS_BASE)
static VOID TEngineProcessBasedTaskProc(W param) {
  Thread *thread = (Thread *)param;
  thread->run();
  b_ext_tsk();
}
#else
static void *PosixThreadProc(void *param) {
  Thread *thread = (Thread *)param;
  thread->run();
  return 0;
}
#endif

////////////////////////////////////////////////
// Thread
////////////////////////////////////////////////

Thread::Thread() {
  setRunnableFlag(false);
  setObject(NULL);
}

bool Thread::start() {
  this->mutex.lock();

#if defined(WIN32) && !defined(ITRON)
  hThread = CreateThread(NULL, 0, Win32ThreadProc, (LPVOID)this, 0, &threadID);
#elif defined(BTRON)
  P_STATE pstate;
  prc_sts(0, &pstate, NULL);
  taskID = cre_tsk(BTronTaskProc, pstate.priority, (W)this);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
  if (wup_tsk(taskID) != 0) {
    this->mutex.unlock();
    return false;
  }
#elif defined(ITRON)
  T_CTSK ctsk = {TA_HLNG,  (VP_INT)this, (FP)ITronTaskProc, 6, 512, NULL, NULL};
  taskID = acre_tsk(&ctsk);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
  if (sta_tsk(taskID, 0) != E_OK) {
    this->mutex.unlock();
    del_tsk(taskID);
    return FALSE;
  }
#elif defined(TENGINE) && !defined(PROCESS_BASE)
  T_CTSK ctsk = {(VP)this, TA_HLNG, TEngineTaskProc,10, 2048};
  taskID = tk_cre_tsk(&ctsk);
  if (taskID < E_OK) {
    this->mutex.unlock();
    return false;
  }
  if (tk_sta_tsk(taskID, 0) < E_OK) {
    tk_del_tsk(thread->taskID);
    this->mutex.unlock();
    return false;
  }
#elif defined(TENGINE) && defined(PROCESS_BASE)
  P_STATE pstate;
  b_prc_sts(0, &pstate, NULL);
  taskID = b_cre_tsk(TEngineProcessBasedTaskProc, pstate.priority, (W)this);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
#else
  pthread_attr_t thread_attr;
  if (pthread_attr_init(&thread_attr) != 0) {
    this->mutex.unlock();
    return false;
  }
#if defined(UHTTP_THREAD_DETACHED)
  if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
    pthread_attr_destroy(&thread_attr);
    this->mutex.unlock();
    return false;
  }
#endif
  if (pthread_create(&thread, &thread_attr, PosixThreadProc, this) != 0) {
    pthread_attr_destroy(&thread_attr);
    this->mutex.unlock();
    return false;
  }
  pthread_attr_destroy(&thread_attr);
#endif

  setRunnableFlag(true);

  this->mutex.unlock();

  return true;
}

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

bool Thread::stop() {
  this->mutex.lock();

  if (isRunnable() == true) {
    setRunnableFlag(false);
#if defined(WIN32) && !defined(ITRON)
    TerminateThread(hThread, 0);
    WaitForSingleObject(hThread, INFINITE);
#elif defined(BTRON)
    ter_tsk(taskID);
#elif defined(ITRON)
    ter_tsk(taskID);
    del_tsk(taskID);
#elif defined(TENGINE) && !defined(PROCESS_BASE)
    tk_ter_tsk(taskID);
    tk_del_tsk(taskID);
#elif defined(TENGINE) && defined(PROCESS_BASE)
    b_ter_tsk(taskID);
#else
    if (pthread_cancel(thread) == 0) {
#if defined(UHTTP_THREAD_DETACHED)
      pthread_detach(thread);
#else
      pthread_join(thread, NULL);
    }
#endif
#endif
  }

  this->mutex.unlock();

  return true;
}

void Thread::setRunnableFlag(bool flag) {
  runnableFlag = flag;
}

bool Thread::isRunnable() {
#if !defined(WIN32) && !defined(ITRON) && !defined(BTRON) && !defined(TENGINE) && !defined(PROCESS_BASE)
  pthread_testcancel();
#endif
  return runnableFlag;
}

<commit_msg>* Changed Thead class to enable 'detached'.<commit_after>/******************************************************************
*
* uHTTP for C++
*
* Copyright (C) Satoshi Konno 2002
*
* This is licensed under BSD-style license, see file COPYING.
*
******************************************************************/

#include <uhttp/util/Thread.h>

#include <stdio.h>

using namespace uHTTP;

#define UHTTP_THREAD_DETACHED 1

////////////////////////////////////////////////
// Thread Func
////////////////////////////////////////////////

#if defined(WIN32) && !defined(ITRON)
static DWORD WINAPI Win32ThreadProc(LPVOID lpParam) {
  Thread *thread = (Thread *)lpParam;
  thread->run();
  return 0;
}
#elif defined(BTRON)
static VOID BTronTaskProc(W param) {
  Thread *thread = (Thread *)param;
  thread->run();
  ext_tsk();
}
#elif defined(ITRON)
static TASK ITronTaskProc(int param) {
  T_RTSK rtsk;
  if (ref_tsk(TSK_SELF, &rtsk) != E_OK)
    return;
  Thread *thread = (Thread *)rtsk.exinf;
  thread->run();
  exd_tsk();
}
#elif defined(TENGINE) && !defined(PROCESS_BASE)
static VOID TEngineTaskProc(INT stacd, VP param) {
  Thread *thread = (Thread *)param;
  thread->run();
  tk_exd_tsk();
}
#elif defined(TENGINE) && defined(PROCESS_BASE)
static VOID TEngineProcessBasedTaskProc(W param) {
  Thread *thread = (Thread *)param;
  thread->run();
  b_ext_tsk();
}
#else
static void *PosixThreadProc(void *param) {
  Thread *thread = (Thread *)param;
  thread->run();
  return 0;
}
#endif

////////////////////////////////////////////////
// Thread
////////////////////////////////////////////////

Thread::Thread() {
  setRunnableFlag(false);
  setObject(NULL);
}

bool Thread::start() {
  this->mutex.lock();

#if defined(WIN32) && !defined(ITRON)
  hThread = CreateThread(NULL, 0, Win32ThreadProc, (LPVOID)this, 0, &threadID);
#elif defined(BTRON)
  P_STATE pstate;
  prc_sts(0, &pstate, NULL);
  taskID = cre_tsk(BTronTaskProc, pstate.priority, (W)this);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
  if (wup_tsk(taskID) != 0) {
    this->mutex.unlock();
    return false;
  }
#elif defined(ITRON)
  T_CTSK ctsk = {TA_HLNG,  (VP_INT)this, (FP)ITronTaskProc, 6, 512, NULL, NULL};
  taskID = acre_tsk(&ctsk);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
  if (sta_tsk(taskID, 0) != E_OK) {
    this->mutex.unlock();
    del_tsk(taskID);
    return FALSE;
  }
#elif defined(TENGINE) && !defined(PROCESS_BASE)
  T_CTSK ctsk = {(VP)this, TA_HLNG, TEngineTaskProc,10, 2048};
  taskID = tk_cre_tsk(&ctsk);
  if (taskID < E_OK) {
    this->mutex.unlock();
    return false;
  }
  if (tk_sta_tsk(taskID, 0) < E_OK) {
    tk_del_tsk(thread->taskID);
    this->mutex.unlock();
    return false;
  }
#elif defined(TENGINE) && defined(PROCESS_BASE)
  P_STATE pstate;
  b_prc_sts(0, &pstate, NULL);
  taskID = b_cre_tsk(TEngineProcessBasedTaskProc, pstate.priority, (W)this);
  if (taskID < 0) {
    this->mutex.unlock();
    return false;
  }
#else
  pthread_attr_t thread_attr;
  if (pthread_attr_init(&thread_attr) != 0) {
    this->mutex.unlock();
    return false;
  }
#if defined(UHTTP_THREAD_DETACHED)
  if (pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) != 0) {
    pthread_attr_destroy(&thread_attr);
    this->mutex.unlock();
    return false;
  }
#endif
  if (pthread_create(&thread, &thread_attr, PosixThreadProc, this) != 0) {
    pthread_attr_destroy(&thread_attr);
    this->mutex.unlock();
    return false;
  }
  pthread_attr_destroy(&thread_attr);
#endif

  setRunnableFlag(true);

  this->mutex.unlock();

  return true;
}

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

bool Thread::stop() {
  this->mutex.lock();

  if (isRunnable() == true) {
    setRunnableFlag(false);
#if defined(WIN32) && !defined(ITRON)
    TerminateThread(hThread, 0);
    WaitForSingleObject(hThread, INFINITE);
#elif defined(BTRON)
    ter_tsk(taskID);
#elif defined(ITRON)
    ter_tsk(taskID);
    del_tsk(taskID);
#elif defined(TENGINE) && !defined(PROCESS_BASE)
    tk_ter_tsk(taskID);
    tk_del_tsk(taskID);
#elif defined(TENGINE) && defined(PROCESS_BASE)
    b_ter_tsk(taskID);
#else
    if (pthread_cancel(thread) == 0) {
#if defined(UHTTP_THREAD_DETACHED)
      pthread_detach(thread);
#else
      pthread_join(thread, NULL);
    }
#endif
#endif
  }

  this->mutex.unlock();

  return true;
}

void Thread::setRunnableFlag(bool flag) {
  runnableFlag = flag;
}

bool Thread::isRunnable() {
#if !defined(WIN32) && !defined(ITRON) && !defined(BTRON) && !defined(TENGINE) && !defined(PROCESS_BASE)
  pthread_testcancel();
#endif
  return runnableFlag;
}

<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.11 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/03/20 04:31:43 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"

int main(int argc, char *argv[])
{
  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }

      return 1;
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;

      return 1;
    }

  // Create the root container.
  CCopasiContainer::init();

  // Create the global data model.
  CCopasiDataModel::Global = new CCopasiDataModel;

  const COptions::nonOptionType & Files = COptions::getNonOptions();

  if (!COptions::compareValue("ImportSBML", std::string("")))
    {
      // Import the SBML File
      std::string ImportSBML;
      COptions::getValue("ImportSBML", ImportSBML);
      CCopasiDataModel::Global->importSBML(ImportSBML);

      // Save the COPASI File, which is the only thing to do.
      std::string Save;
      COptions::getValue("Save", Save);
      CCopasiDataModel::Global->saveModel(Save);
    }

  COptions::nonOptionType::const_iterator it = Files.begin();
  COptions::nonOptionType::const_iterator end = Files.end();

  for (; it != end; ++it)
    {
      CCopasiDataModel::Global->loadModel(*it);

      // Check whether exporting to SBML is requested.
      if (!COptions::compareValue("ExportSBML", std::string("")))
        {
          // Export the SBML File
          std::string ExportSBML;
          COptions::getValue("ExportSBML", ExportSBML);
          CCopasiDataModel::Global->exportSBML(ExportSBML);

          // Since only one export file name can be specified we
          // stop execution.
          return 0;
        }

      CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
      unsigned C_INT32 i, imax = TaskList.size();

      for (i = 0; i < imax; i++)
        if (TaskList[i]->isScheduled())
          {
            TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

            TaskList[i]->initialize();
            TaskList[i]->process();
            TaskList[i]->restore();
          }

      // Check whether a file for saving the resulting model is given
      if (!COptions::compareValue("Save", std::string("")))
        {
          std::string Save;
          COptions::getValue("Save", Save);
          CCopasiDataModel::Global->saveModel(Save);

          // Since only one save file name can be specified we
          // stop execution.
          return 0;
        }

      //      CCopasiDataModel::Global->saveModel("");
    }

  //  catch (CCopasiException Exception)
  //    {
  //      std::cout << Exception.getMessage().getText() << std::endl;
  //}

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  std::cout << "Leaving main program." << std::endl;
  return 0;
}
<commit_msg>Fixed call to CCopasiTask::process to have a CallBackhandler as a parameter.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/CopasiSE/CopasiSE.cpp,v $
   $Revision: 1.12 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/04/08 03:05:26 $
   End CVS Header */

// Main
//
// (C) Stefan Hoops 2002
//

#include <stdlib.h>
#include <sstream>
#include <string>
#include <iostream>

#define COPASI_MAIN
#define COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "CopasiDataModel/CCopasiDataModel.h"
#include "utilities/CCopasiMessage.h"
#include "utilities/CCopasiException.h"
#include "utilities/CCopasiTask.h"
#include "utilities/CCopasiProblem.h"
#include "commandline/COptionParser.h"
#include "commandline/COptions.h"
#include "function/CFunctionDB.h"

int main(int argc, char *argv[])
{
  try
    {
      // Parse the commandline options
      COptions::init(argc, argv);
    }

  catch (copasi::autoexcept &e)
    {
      switch (e.get_autothrow_id())
        {
        case copasi::autothrow_help:
          std::cout << "Usage: " << argv[0] << " [options]\n";
          std::cout << e.what();
        }

      return 1;
    }

  catch (copasi::option_error &e)
    {
      std::cerr << argv[0] << ": " << e.what() << "\n";
      std::cerr << e.get_help_comment() << std::endl;

      return 1;
    }

  // Create the root container.
  CCopasiContainer::init();

  // Create the global data model.
  CCopasiDataModel::Global = new CCopasiDataModel;

  const COptions::nonOptionType & Files = COptions::getNonOptions();

  if (!COptions::compareValue("ImportSBML", std::string("")))
    {
      // Import the SBML File
      std::string ImportSBML;
      COptions::getValue("ImportSBML", ImportSBML);
      CCopasiDataModel::Global->importSBML(ImportSBML);

      // Save the COPASI File, which is the only thing to do.
      std::string Save;
      COptions::getValue("Save", Save);
      CCopasiDataModel::Global->saveModel(Save);
    }

  COptions::nonOptionType::const_iterator it = Files.begin();
  COptions::nonOptionType::const_iterator end = Files.end();

  for (; it != end; ++it)
    {
      CCopasiDataModel::Global->loadModel(*it);

      // Check whether exporting to SBML is requested.
      if (!COptions::compareValue("ExportSBML", std::string("")))
        {
          // Export the SBML File
          std::string ExportSBML;
          COptions::getValue("ExportSBML", ExportSBML);
          CCopasiDataModel::Global->exportSBML(ExportSBML);

          // Since only one export file name can be specified we
          // stop execution.
          return 0;
        }

      CCopasiVectorN< CCopasiTask > & TaskList = * CCopasiDataModel::Global->getTaskList();
      unsigned C_INT32 i, imax = TaskList.size();

      for (i = 0; i < imax; i++)
        if (TaskList[i]->isScheduled())
          {
            TaskList[i]->getProblem()->setModel(CCopasiDataModel::Global->getModel());

            TaskList[i]->initialize();
            TaskList[i]->process(NULL);
            TaskList[i]->restore();
          }

      // Check whether a file for saving the resulting model is given
      if (!COptions::compareValue("Save", std::string("")))
        {
          std::string Save;
          COptions::getValue("Save", Save);
          CCopasiDataModel::Global->saveModel(Save);

          // Since only one save file name can be specified we
          // stop execution.
          return 0;
        }

      //      CCopasiDataModel::Global->saveModel("");
    }

  //  catch (CCopasiException Exception)
  //    {
  //      std::cout << Exception.getMessage().getText() << std::endl;
  //}

  pdelete(CCopasiDataModel::Global);
  pdelete(CCopasiContainer::Root);

  std::cout << "Leaving main program." << std::endl;
  return 0;
}
<|endoftext|>