<commit_before>/// \file Debugger.cpp

#include "chi/Debugger.hpp"

#include <chi/Context.hpp>
#include <chi/LLVMVersion.hpp>
#include <chi/NameMangler.hpp>
#include <chi/NodeInstance.hpp>
#include <chi/Result.hpp>

#include <boost/filesystem.hpp>
#include <boost/uuid/uuid_io.hpp>

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeWriter.h>
#endif

#include <llvm/Support/FileSystem.h>
#include <llvm/Support/raw_ostream.h>

#include <lldb/API/SBListener.h>
#include <lldb/API/SBThread.h>

#include <stdlib.h>  // for setenv

namespace fs = boost::filesystem;

namespace chi {

Debugger::Debugger(const char* pathToChig, GraphModule& mod) : mModule{&mod} {
// point it to lldb-server
#if __linux__
	auto lldbServerPath = fs::path(pathToChig).parent_path() / "lldb-server";
	setenv("LLDB_DEBUGSERVER_PATH", lldbServerPath.c_str(), 1);
#endif

	lldb::SBDebugger::Initialize();
	mDebugger = lldb::SBDebugger::Create();

	// set the logger to stderr for testing
	mDebugger.SetLoggingCallback(
	    [](const char* msg, void* dbg) {
		    std::cerr << msg;
		    std::cerr.flush();
		},
	    this);

	const char* val[] = {"api", nullptr};
	mDebugger.EnableLog("lldb", val);

	// create target
	mTarget = mDebugger.CreateTarget(pathToChig);
}

Debugger::~Debugger() { lldb::SBDebugger::Terminate(); }

Result Debugger::terminate() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Kill();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to terminate process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}

Result Debugger::processContinue() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Continue();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to continue process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}
Result Debugger::pause() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Stop();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to pause process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}

Result Debugger::setBreakpoint(NodeInstance& node, lldb::SBBreakpoint* bp) {
	Result res;

	int linenum = lineNumberFromNode(node);

	// create the breakpoint
	auto breakpoint = mTarget.BreakpointCreateByLocation(
	    node.module().sourceFilePath().string().c_str(), linenum);

	// make sure that it's good
	if (!breakpoint.IsValid()) {
		res.addEntry("EUKN", "Could not set breakpoint on node",
		             {{"nodeid", node.stringId()},
		              {"File Name", node.module().sourceFilePath().string()},
		              {"Line  Number", linenum}});

		return res;
	}

	mBreakpoints[&node] = breakpoint;

	if (bp != nullptr) { *bp = breakpoint; }

	breakpoint.SetEnabled(true);

	return res;
}

bool Debugger::removeBreakpoint(NodeInstance& node) {
	auto iter = mBreakpoints.find(&node);
	if (iter == mBreakpoints.end()) { return false; }

	return mTarget.BreakpointDelete(iter->second.GetID());
}

Result Debugger::start(const char** argv, const char** envp,
                       const boost::filesystem::path& workingDirectory) {
	Expects(boost::filesystem::is_directory(workingDirectory));

	Result res;

	if (!mTarget.IsValid()) {
		res.addEntry("EUKN", "Cannot start a debugger process with an invalid target", {});
		return res;
	}

	// generate IR
	std::unique_ptr<llvm::Module> mod;
	{
		res = module().context().compileModule(module(), &mod);
		if (!res) { return res; }
	}

	// write it to a file
	fs::path tmpIRPath;
	{
		tmpIRPath = boost::filesystem::temp_directory_path() / fs::unique_path();
		std::error_code      ec;  // TODO: use ec
		llvm::raw_fd_ostream file{tmpIRPath.string(), ec, llvm::sys::fs::F_RW};
		llvm::WriteBitcodeToFile(mod.get(), file);
	}

	// create args
	std::vector<const char*> args;
	{
		args.push_back("interpret");
		args.push_back("-i");
		args.push_back(tmpIRPath.string().c_str());
		args.push_back("-O");
		args.push_back("0");

		if (argv != nullptr) {
			for (; *argv != nullptr; ++argv) { args.push_back(*argv); }
		}

		args.push_back(nullptr);
	}

	// start the process
	{
		lldb::SBError    err;
		lldb::SBListener invalidListener;
		mProcess =
		    mTarget.Launch(invalidListener, args.data(), envp, nullptr, nullptr, nullptr,
		                   workingDirectory.string().c_str(), lldb::eLaunchFlagDebug, false, err);

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to launch process", {{"Error Message", err.GetCString()}});
		}
	}

	return res;
}

std::vector<const NodeInstance*> Debugger::listBreakpoints() const {
	std::vector<const NodeInstance*> ret;
	ret.reserve(mBreakpoints.size());
	for (const auto& bpts : mBreakpoints) { ret.push_back(bpts.first); }
	return ret;
}

lldb::SBValue Debugger::inspectNodeOutput(const NodeInstance& inst, size_t id,
                                          lldb::SBFrame frame) {
	Expects(id < inst.outputDataConnections.size());

	// if frame isn't valid, use the default
	if (!frame.IsValid()) {
		auto thread = lldbProcess().GetSelectedThread();
		if (!thread.IsValid()) { return {}; }
		frame = thread.GetSelectedFrame();
	}

	if (!frame.IsValid()) { return {}; }

	// make sure it's in scope
	auto func = &nodeFromFrame(frame)->function();
	if (func != &inst.function()) { return {}; }

	auto variableName = inst.stringId() + "__" + std::to_string(id);
	return frame.FindVariable(variableName.c_str());
}

NodeInstance* Debugger::nodeFromFrame(lldb::SBFrame frame) {
	using namespace std::string_literals;

	// if frame isn't valid, use the default
	if (!frame.IsValid()) {
		auto thread = lldbProcess().GetSelectedThread();
		if (!thread.IsValid()) { return {}; }
		frame = thread.GetSelectedFrame();
	}

	if (!frame.IsValid()) { return {}; }

	auto mangledFunctionName = frame.GetFunctionName();
	// demangle that
	std::string moduleName, functionName;
	std::tie(moduleName, functionName) = unmangleFunctionName(mangledFunctionName);

	GraphFunction* func = nullptr;

	if (mangledFunctionName == "main"s) { func = module().functionFromName("main"); }

	if (func == nullptr) {
		auto mod = static_cast<GraphModule*>(module().context().moduleByFullName(moduleName));
		if (!mod) { return nullptr; }
		func = mod->functionFromName(functionName);
	}

	unsigned lineNo = frame.GetLineEntry().GetLine();

	// create assoc TODO: cache these
	auto assoc = func->module().createLineNumberAssoc();

	auto nodeIter = assoc.left.find(lineNo);
	if (nodeIter == assoc.left.end()) { return nullptr; }

	return nodeIter->second;
}

unsigned lineNumberFromNode(NodeInstance& inst) {
	// TODO: cache these, they're kinda expensive to make
	auto lineAssoc      = inst.module().createLineNumberAssoc();
	auto lineNumberIter = lineAssoc.right.find(&inst);
	if (lineNumberIter == lineAssoc.right.end()) { return -1; }

	return lineNumberIter->second;
}

}  // namespace chi
<commit_msg>Add another missing include for LLVM 3.5<commit_after>/// \file Debugger.cpp

#include "chi/Debugger.hpp"

#include <chi/Context.hpp>
#include <chi/LLVMVersion.hpp>
#include <chi/NameMangler.hpp>
#include <chi/NodeInstance.hpp>
#include <chi/Result.hpp>

#include <boost/filesystem.hpp>
#include <boost/uuid/uuid_io.hpp>

#if LLVM_VERSION_LESS_EQUAL(3, 9)
#include <llvm/Bitcode/ReaderWriter.h>
#else
#include <llvm/Bitcode/BitcodeWriter.h>
#endif

#include <llvm/Support/FileSystem.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/Module.h>

#include <lldb/API/SBListener.h>
#include <lldb/API/SBThread.h>

#include <stdlib.h>  // for setenv

namespace fs = boost::filesystem;

namespace chi {

Debugger::Debugger(const char* pathToChig, GraphModule& mod) : mModule{&mod} {
// point it to lldb-server
#if __linux__
	auto lldbServerPath = fs::path(pathToChig).parent_path() / "lldb-server";
	setenv("LLDB_DEBUGSERVER_PATH", lldbServerPath.c_str(), 1);
#endif

	lldb::SBDebugger::Initialize();
	mDebugger = lldb::SBDebugger::Create();

	// set the logger to stderr for testing
	mDebugger.SetLoggingCallback(
	    [](const char* msg, void* dbg) {
		    std::cerr << msg;
		    std::cerr.flush();
		},
	    this);

	const char* val[] = {"api", nullptr};
	mDebugger.EnableLog("lldb", val);

	// create target
	mTarget = mDebugger.CreateTarget(pathToChig);
}

Debugger::~Debugger() { lldb::SBDebugger::Terminate(); }

Result Debugger::terminate() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Kill();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to terminate process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}

Result Debugger::processContinue() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Continue();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to continue process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}
Result Debugger::pause() {
	Result res;

	if (isAttached()) {
		auto err = mProcess.Stop();

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to pause process",
			             {{"Error Code", err.GetError()}, {"Error String", err.GetCString()}});

			return res;
		}
	}

	return res;
}

Result Debugger::setBreakpoint(NodeInstance& node, lldb::SBBreakpoint* bp) {
	Result res;

	int linenum = lineNumberFromNode(node);

	// create the breakpoint
	auto breakpoint = mTarget.BreakpointCreateByLocation(
	    node.module().sourceFilePath().string().c_str(), linenum);

	// make sure that it's good
	if (!breakpoint.IsValid()) {
		res.addEntry("EUKN", "Could not set breakpoint on node",
		             {{"nodeid", node.stringId()},
		              {"File Name", node.module().sourceFilePath().string()},
		              {"Line  Number", linenum}});

		return res;
	}

	mBreakpoints[&node] = breakpoint;

	if (bp != nullptr) { *bp = breakpoint; }

	breakpoint.SetEnabled(true);

	return res;
}

bool Debugger::removeBreakpoint(NodeInstance& node) {
	auto iter = mBreakpoints.find(&node);
	if (iter == mBreakpoints.end()) { return false; }

	return mTarget.BreakpointDelete(iter->second.GetID());
}

Result Debugger::start(const char** argv, const char** envp,
                       const boost::filesystem::path& workingDirectory) {
	Expects(boost::filesystem::is_directory(workingDirectory));

	Result res;

	if (!mTarget.IsValid()) {
		res.addEntry("EUKN", "Cannot start a debugger process with an invalid target", {});
		return res;
	}

	// generate IR
	std::unique_ptr<llvm::Module> mod;
	{
		res = module().context().compileModule(module(), &mod);
		if (!res) { return res; }
	}

	// write it to a file
	fs::path tmpIRPath;
	{
		tmpIRPath = boost::filesystem::temp_directory_path() / fs::unique_path();
		std::error_code      ec;  // TODO: use ec
		llvm::raw_fd_ostream file{tmpIRPath.string(), ec, llvm::sys::fs::F_RW};
		llvm::WriteBitcodeToFile(mod.get(), file);
	}

	// create args
	std::vector<const char*> args;
	{
		args.push_back("interpret");
		args.push_back("-i");
		args.push_back(tmpIRPath.string().c_str());
		args.push_back("-O");
		args.push_back("0");

		if (argv != nullptr) {
			for (; *argv != nullptr; ++argv) { args.push_back(*argv); }
		}

		args.push_back(nullptr);
	}

	// start the process
	{
		lldb::SBError    err;
		lldb::SBListener invalidListener;
		mProcess =
		    mTarget.Launch(invalidListener, args.data(), envp, nullptr, nullptr, nullptr,
		                   workingDirectory.string().c_str(), lldb::eLaunchFlagDebug, false, err);

		if (err.Fail()) {
			res.addEntry("EUKN", "Failed to launch process", {{"Error Message", err.GetCString()}});
		}
	}

	return res;
}

std::vector<const NodeInstance*> Debugger::listBreakpoints() const {
	std::vector<const NodeInstance*> ret;
	ret.reserve(mBreakpoints.size());
	for (const auto& bpts : mBreakpoints) { ret.push_back(bpts.first); }
	return ret;
}

lldb::SBValue Debugger::inspectNodeOutput(const NodeInstance& inst, size_t id,
                                          lldb::SBFrame frame) {
	Expects(id < inst.outputDataConnections.size());

	// if frame isn't valid, use the default
	if (!frame.IsValid()) {
		auto thread = lldbProcess().GetSelectedThread();
		if (!thread.IsValid()) { return {}; }
		frame = thread.GetSelectedFrame();
	}

	if (!frame.IsValid()) { return {}; }

	// make sure it's in scope
	auto func = &nodeFromFrame(frame)->function();
	if (func != &inst.function()) { return {}; }

	auto variableName = inst.stringId() + "__" + std::to_string(id);
	return frame.FindVariable(variableName.c_str());
}

NodeInstance* Debugger::nodeFromFrame(lldb::SBFrame frame) {
	using namespace std::string_literals;

	// if frame isn't valid, use the default
	if (!frame.IsValid()) {
		auto thread = lldbProcess().GetSelectedThread();
		if (!thread.IsValid()) { return {}; }
		frame = thread.GetSelectedFrame();
	}

	if (!frame.IsValid()) { return {}; }

	auto mangledFunctionName = frame.GetFunctionName();
	// demangle that
	std::string moduleName, functionName;
	std::tie(moduleName, functionName) = unmangleFunctionName(mangledFunctionName);

	GraphFunction* func = nullptr;

	if (mangledFunctionName == "main"s) { func = module().functionFromName("main"); }

	if (func == nullptr) {
		auto mod = static_cast<GraphModule*>(module().context().moduleByFullName(moduleName));
		if (!mod) { return nullptr; }
		func = mod->functionFromName(functionName);
	}

	unsigned lineNo = frame.GetLineEntry().GetLine();

	// create assoc TODO: cache these
	auto assoc = func->module().createLineNumberAssoc();

	auto nodeIter = assoc.left.find(lineNo);
	if (nodeIter == assoc.left.end()) { return nullptr; }

	return nodeIter->second;
}

unsigned lineNumberFromNode(NodeInstance& inst) {
	// TODO: cache these, they're kinda expensive to make
	auto lineAssoc      = inst.module().createLineNumberAssoc();
	auto lineNumberIter = lineAssoc.right.find(&inst);
	if (lineNumberIter == lineAssoc.right.end()) { return -1; }

	return lineNumberIter->second;
}

}  // namespace chi
<|endoftext|>


<commit_before>#include <libdariadb/interfaces/icallbacks.h>
#include <thread>
using namespace dariadb;

IReadCallback::IReadCallback() {
  is_end_called = false;
  is_cancel = false;
}

IReadCallback::~IReadCallback() {}

void IReadCallback::is_end() {
  is_end_called = true;
}

void IReadCallback::wait() {
  // TODO make more smarter.
  while (!is_cancel && !is_end_called) {
    std::this_thread::sleep_for(std::chrono::milliseconds(300));
  }
  // mtx.unlock();
}

void IReadCallback::cancel() {
  is_cancel = true;
}

bool IReadCallback::is_canceled() const {
  return is_cancel;
}<commit_msg>rm TODO.<commit_after>#include <libdariadb/interfaces/icallbacks.h>
#include <thread>
using namespace dariadb;

IReadCallback::IReadCallback() {
  is_end_called = false;
  is_cancel = false;
}

IReadCallback::~IReadCallback() {}

void IReadCallback::is_end() {
  is_end_called = true;
}

void IReadCallback::wait() {
  while (!is_cancel && !is_end_called) {
    std::this_thread::sleep_for(std::chrono::milliseconds(300));
  }
}

void IReadCallback::cancel() {
  is_cancel = true;
}

bool IReadCallback::is_canceled() const {
  return is_cancel;
}<|endoftext|>


<commit_before><commit_msg>tableindex: Evaluate predicate once<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <ref/Class.hpp>
#include <ref/DescriptorsImpl.ipp>
#include <ref/utils/JsonSerializer.hpp>

using namespace ref;

struct Animal;

// Structural features (attributes)
struct Name    : String {};
struct Surname : String {};
struct Age     : UInt32 {};
struct Alive   : Bool {};
struct Emails  : Feature< std::vector< std::string > >{};
struct Pets    : Feature< std::vector< Animal > >{};

// Classes
struct Animal :
    Class< Animal, Features< Alive, Age > >
{
};

struct Person :
    Class< Person,
           Features< Name, Surname, Emails, Pets >,
           Animal >
{
};

int main(int argc, char **argv)
{
    Person me;
    Animal dog;

    // Direct access
    me.set< Name >("Andres");
    me.set< Surname >("Senac");
    me.set< Age >(29);
    const std::vector< std::string > emails = {"andres@senac.es", "asenac@senac.es"};
    me.set< Emails >(emails);
    me.get< Pets >().push_back(dog);

    std::cout << me.get< Name >() << " "
        << me.get< Surname >() << " "
        << me.get< Age >() << std::endl;

    // Descriptors
    const ClassDescriptor * classDesc = me.getClassDescriptor();
    const FeatureDescriptorVector features =
        classDesc->getAllFeatureDescriptors();

    for (size_t i = 0; i < features.size(); i++)
    {
        const FeatureDescriptor * featureDesc = features[i];

        Holder h = featureDesc->getValue(&me);
        const TypeDescriptor * typeDesc = h.descriptor();

        if (typeDesc->getKind() == TypeDescriptor::kPrimitive)
        {
            const PrimitiveTypeDescriptor * priTypeDesc =
                static_cast< const PrimitiveTypeDescriptor * >(typeDesc);
            std::cout << featureDesc->getName() << " = "
                << priTypeDesc->getString(h) << std::endl;
        }
        else
        {
            std::cout << featureDesc->getName() << " = non-printable type!" << std::endl;
        }
    }

    std::cout << std::endl;

    JsonSerializer js(std::cout);
    js.serialize(&me);

    std::cout << std::endl;

    return 0;
}
<commit_msg>use as method instead of static_cast<commit_after>#include <iostream>
#include <ref/Class.hpp>
#include <ref/DescriptorsImpl.ipp>
#include <ref/utils/JsonSerializer.hpp>

using namespace ref;

struct Animal;

// Structural features (attributes)
struct Name    : String {};
struct Surname : String {};
struct Age     : UInt32 {};
struct Alive   : Bool {};
struct Emails  : Feature< std::vector< std::string > >{};
struct Pets    : Feature< std::vector< Animal > >{};

// Classes
struct Animal :
    Class< Animal, Features< Alive, Age > >
{
};

struct Person :
    Class< Person,
           Features< Name, Surname, Emails, Pets >,
           Animal >
{
};

int main(int argc, char **argv)
{
    Person me;
    Animal dog;

    // Direct access
    me.set< Name >("Andres");
    me.set< Surname >("Senac");
    me.set< Age >(29);
    const std::vector< std::string > emails = {"andres@senac.es", "asenac@senac.es"};
    me.set< Emails >(emails);
    me.get< Pets >().push_back(dog);

    std::cout << me.get< Name >() << " "
        << me.get< Surname >() << " "
        << me.get< Age >() << std::endl;

    // Descriptors
    const ClassDescriptor * classDesc = me.getClassDescriptor();
    const FeatureDescriptorVector features =
        classDesc->getAllFeatureDescriptors();

    for (size_t i = 0; i < features.size(); i++)
    {
        const FeatureDescriptor * featureDesc = features[i];

        Holder h = featureDesc->getValue(&me);
        const TypeDescriptor * typeDesc = h.descriptor();

        if (typeDesc->getKind() == TypeDescriptor::kPrimitive)
        {
            const PrimitiveTypeDescriptor *priTypeDesc =
                typeDesc->as<PrimitiveTypeDescriptor>();
            std::cout << featureDesc->getName() << " = "
                << priTypeDesc->getString(h) << std::endl;
        }
        else
        {
            std::cout << featureDesc->getName() << " = non-printable type!" << std::endl;
        }
    }

    std::cout << std::endl;

    JsonSerializer js(std::cout);
    js.serialize(&me);

    std::cout << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/libmesh_config.h"
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES

#include "libmesh/elem.h"
#include "libmesh/fe.h"
#include "libmesh/fe_interface.h"

namespace {
static const libMesh::FEFamily _underlying_fe_family = libMesh::BERNSTEIN;
}

namespace libMesh
{

LIBMESH_DEFAULT_VECTORIZED_FE(2,RATIONAL_BERNSTEIN)

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const Elem * elem,
                                     const Order order,
                                     const unsigned int i,
                                     const Point & p,
                                     const bool add_p_level)
{
  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      weighted_sum += weighted_shape;
      if (sf == i)
        weighted_shape_i = weighted_shape;
    }

  return weighted_shape_i / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const ElemType,
                                     const Order,
                                     const unsigned int,
                                     const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const FEType fet,
                                     const Elem * elem,
                                     const unsigned int i,
                                     const Point & p,
                                     const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape
    (elem, fet.order, i, p, add_p_level);
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const Elem * elem,
                                           const Order order,
                                           const unsigned int i,
                                           const unsigned int j,
                                           const Point & p,
                                           const bool add_p_level)
{
  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0,
       weighted_grad_i = 0, weighted_grad_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      Real weighted_grad = node_weights[sf] *
        FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j, p);
      weighted_sum += weighted_shape;
      weighted_grad_sum += weighted_grad;
      if (sf == i)
        {
          weighted_shape_i = weighted_shape;
          weighted_grad_i = weighted_grad;
        }
    }

  return (weighted_sum * weighted_grad_i - weighted_shape_i * weighted_grad_sum) /
         weighted_sum / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const ElemType,
                                           const Order,
                                           const unsigned int,
                                           const unsigned int,
                                           const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const FEType fet,
                                           const Elem * elem,
                                           const unsigned int i,
                                           const unsigned int j,
                                           const Point & p,
                                           const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape_deriv
    (elem, fet.order, i, j, p, add_p_level);
}

#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const Elem * elem,
                                                  const Order order,
                                                  const unsigned int i,
                                                  const unsigned int j,
                                                  const Point & p,
                                                  const bool add_p_level)
{
  unsigned int j1, j2;
  switch (j)
    {
    case 0:
      // j = 0 ==> d^2 phi / dxi^2
      j1 = j2 = 0;
      break;
    case 1:
      // j = 1 ==> d^2 phi / dxi deta
      j1 = 0;
      j2 = 1;
      break;
    case 2:
      // j = 2 ==> d^2 phi / deta^2
      j1 = j2 = 1;
      break;
    default:
      libmesh_error();
    }

  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0,
       weighted_grada_i = 0, weighted_grada_sum = 0,
       weighted_gradb_i = 0, weighted_gradb_sum = 0,
       weighted_hess_i = 0, weighted_hess_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      Real weighted_grada = node_weights[sf] *
        FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j1, p);
      Real weighted_hess = node_weights[sf] *
        FEInterface::shape_second_deriv(fe_type, extra_order, elem, sf, j, p);
      weighted_sum += weighted_shape;
      weighted_grada_sum += weighted_grada;
      Real weighted_gradb = weighted_grada;
      if (j1 != j2)
        {
          weighted_gradb = (j1 == j2) ? weighted_grada :
            node_weights[sf] *
            FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j2, p);
          weighted_grada_sum += weighted_grada;
        }
      weighted_hess_sum += weighted_hess;
      if (sf == i)
        {
          weighted_shape_i = weighted_shape;
          weighted_grada_i = weighted_grada;
          weighted_gradb_i = weighted_gradb;
          weighted_hess_i = weighted_hess;
        }
    }

  if (j1 == j2)
    weighted_gradb_sum = weighted_grada_sum;

  return (weighted_sum * weighted_hess_i - weighted_grada_i * weighted_gradb_sum -
          weighted_shape_i * weighted_hess_sum - weighted_gradb_i * weighted_grada_sum +
          2 * weighted_grada_sum * weighted_shape_i * weighted_gradb_sum / weighted_sum) /
         weighted_sum / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const ElemType,
                                                  const Order,
                                                  const unsigned int,
                                                  const unsigned int,
                                                  const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const FEType fet,
                                                  const Elem * elem,
                                                  const unsigned int i,
                                                  const unsigned int j,
                                                  const Point & p,
                                                  const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv
    (elem, fet.order, i, j, p, add_p_level);
}

#endif

} // namespace libMesh

#endif// LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
<commit_msg>Override 2D RATIONAL_BERNSTEIN all_shapes<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2021 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/libmesh_config.h"
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES

#include "libmesh/elem.h"
#include "libmesh/fe.h"
#include "libmesh/fe_interface.h"

namespace {
using namespace libMesh;

static const FEFamily _underlying_fe_family = BERNSTEIN;

// shapes[i][j] is shape function phi_i at point p[j]
void weighted_shapes(const Elem * elem,
                     FEType fe_type,
                     std::vector<std::vector<Real>> & shapes,
                     const std::vector<Point> & p,
                     const bool add_p_level)
{
  const int extra_order = add_p_level * elem->p_level();

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  libmesh_assert_equal_to (n_sf, elem->n_nodes());

  std::vector<Real> node_weights(n_sf);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_sf; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  const std::size_t n_p = p.size();

  shapes.resize(n_sf);
  for (unsigned int i=0; i != n_sf; ++i)
    {
      auto & shapes_i = shapes[i];
      shapes_i.resize(n_p, 0);
      FEInterface::shapes(2, fe_type, elem, i, p, shapes_i, add_p_level);
      for (auto & s : shapes_i)
        s *= node_weights[i];
    }
}

} // anonymous namespace

namespace libMesh
{

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const Elem * elem,
                                     const Order order,
                                     const unsigned int i,
                                     const Point & p,
                                     const bool add_p_level)
{
  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      weighted_sum += weighted_shape;
      if (sf == i)
        weighted_shape_i = weighted_shape;
    }

  return weighted_shape_i / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const ElemType,
                                     const Order,
                                     const unsigned int,
                                     const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape(const FEType fet,
                                     const Elem * elem,
                                     const unsigned int i,
                                     const Point & p,
                                     const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape
    (elem, fet.order, i, p, add_p_level);
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const Elem * elem,
                                           const Order order,
                                           const unsigned int i,
                                           const unsigned int j,
                                           const Point & p,
                                           const bool add_p_level)
{
  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0,
       weighted_grad_i = 0, weighted_grad_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      Real weighted_grad = node_weights[sf] *
        FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j, p);
      weighted_sum += weighted_shape;
      weighted_grad_sum += weighted_grad;
      if (sf == i)
        {
          weighted_shape_i = weighted_shape;
          weighted_grad_i = weighted_grad;
        }
    }

  return (weighted_sum * weighted_grad_i - weighted_shape_i * weighted_grad_sum) /
         weighted_sum / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const ElemType,
                                           const Order,
                                           const unsigned int,
                                           const unsigned int,
                                           const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_deriv(const FEType fet,
                                           const Elem * elem,
                                           const unsigned int i,
                                           const unsigned int j,
                                           const Point & p,
                                           const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape_deriv
    (elem, fet.order, i, j, p, add_p_level);
}

#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const Elem * elem,
                                                  const Order order,
                                                  const unsigned int i,
                                                  const unsigned int j,
                                                  const Point & p,
                                                  const bool add_p_level)
{
  unsigned int j1, j2;
  switch (j)
    {
    case 0:
      // j = 0 ==> d^2 phi / dxi^2
      j1 = j2 = 0;
      break;
    case 1:
      // j = 1 ==> d^2 phi / dxi deta
      j1 = 0;
      j2 = 1;
      break;
    case 2:
      // j = 2 ==> d^2 phi / deta^2
      j1 = j2 = 1;
      break;
    default:
      libmesh_error();
    }

  libmesh_assert(elem);

  int extra_order = add_p_level * elem->p_level();

  // FEType object to be passed to various FEInterface functions below.
  FEType fe_type(order, _underlying_fe_family);

  const unsigned int n_sf =
    FEInterface::n_shape_functions(fe_type, extra_order, elem);

  const unsigned int n_nodes = elem->n_nodes();
  libmesh_assert_equal_to (n_sf, n_nodes);

  std::vector<Real> node_weights(n_nodes);

  const unsigned char datum_index = elem->mapping_data();
  for (unsigned int n=0; n<n_nodes; n++)
    node_weights[n] =
      elem->node_ref(n).get_extra_datum<Real>(datum_index);

  Real weighted_shape_i = 0, weighted_sum = 0,
       weighted_grada_i = 0, weighted_grada_sum = 0,
       weighted_gradb_i = 0, weighted_gradb_sum = 0,
       weighted_hess_i = 0, weighted_hess_sum = 0;

  for (unsigned int sf=0; sf<n_sf; sf++)
    {
      Real weighted_shape = node_weights[sf] *
        FEInterface::shape(fe_type, extra_order, elem, sf, p);
      Real weighted_grada = node_weights[sf] *
        FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j1, p);
      Real weighted_hess = node_weights[sf] *
        FEInterface::shape_second_deriv(fe_type, extra_order, elem, sf, j, p);
      weighted_sum += weighted_shape;
      weighted_grada_sum += weighted_grada;
      Real weighted_gradb = weighted_grada;
      if (j1 != j2)
        {
          weighted_gradb = (j1 == j2) ? weighted_grada :
            node_weights[sf] *
            FEInterface::shape_deriv(fe_type, extra_order, elem, sf, j2, p);
          weighted_grada_sum += weighted_grada;
        }
      weighted_hess_sum += weighted_hess;
      if (sf == i)
        {
          weighted_shape_i = weighted_shape;
          weighted_grada_i = weighted_grada;
          weighted_gradb_i = weighted_gradb;
          weighted_hess_i = weighted_hess;
        }
    }

  if (j1 == j2)
    weighted_gradb_sum = weighted_grada_sum;

  return (weighted_sum * weighted_hess_i - weighted_grada_i * weighted_gradb_sum -
          weighted_shape_i * weighted_hess_sum - weighted_gradb_i * weighted_grada_sum +
          2 * weighted_grada_sum * weighted_shape_i * weighted_gradb_sum / weighted_sum) /
         weighted_sum / weighted_sum;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const ElemType,
                                                  const Order,
                                                  const unsigned int,
                                                  const unsigned int,
                                                  const Point &)
{
  libmesh_error_msg("Rational bases require the real element \nto query nodal weighting.");
  return 0.;
}

template <>
Real FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv(const FEType fet,
                                                  const Elem * elem,
                                                  const unsigned int i,
                                                  const unsigned int j,
                                                  const Point & p,
                                                  const bool add_p_level)
{
  return FE<2,RATIONAL_BERNSTEIN>::shape_second_deriv
    (elem, fet.order, i, j, p, add_p_level);
}

#endif

// LIBMESH_DEFAULT_VECTORIZED_FE(2, RATIONAL_BERNSTEIN)

template<>
void FE<2,RATIONAL_BERNSTEIN>::shapes
  (const Elem * elem,
   const Order o,
   const unsigned int i,
   const std::vector<Point> & p,
   std::vector<OutputShape> & vi,
   const bool add_p_level)
{
//  FE<2,RATIONAL_BERNSTEIN>::default_shapes(elem,o,i,p,vi,add_p_level);
  libmesh_assert_equal_to(p.size(), vi.size());
  for (auto j : index_range(vi))
    vi[j] = FE<2,RATIONAL_BERNSTEIN>::shape (elem, o, i, p[j], add_p_level);
}

template<>
void FE<2,RATIONAL_BERNSTEIN>::all_shapes
  (const Elem * elem,
   const Order o,
   const std::vector<Point> & p,
   std::vector<std::vector<OutputShape>> & v,
   const bool add_p_level)
{
  std::vector<std::vector<Real>> shapes;

  FEType fe_type(o, _underlying_fe_family);

  weighted_shapes(elem, fe_type, shapes, p, add_p_level);

  std::vector<Real> shape_sums(p.size(), 0);

  for (auto i : index_range(v))
    {
      libmesh_assert_equal_to ( p.size(), shapes[i].size() );
      for (auto j : index_range(p))
        shape_sums[j] += shapes[i][j];
    }

  for (auto i : index_range(v))
    {
      libmesh_assert_equal_to ( p.size(), v[i].size() );
      for (auto j : index_range(v[i]))
        {
          v[i][j] = shapes[i][j] / shape_sums[j];

#ifdef DEBUG
          Real old_shape = FE<2,RATIONAL_BERNSTEIN>::shape (elem, o, i, p[j], add_p_level);
          libmesh_assert(std::abs(v[i][j] - old_shape) < TOLERANCE*TOLERANCE);
#endif
        }
    }
}

template<>
void FE<2,RATIONAL_BERNSTEIN>::shape_derivs
  (const Elem * elem,
   const Order o,
   const unsigned int i,
   const unsigned int j,
   const std::vector<Point> & p,
   std::vector<OutputShape> & v,
   const bool add_p_level)
{
  libmesh_assert_equal_to(p.size(), v.size());
  for (auto vi : index_range(v))
    v[vi] = FE<2,RATIONAL_BERNSTEIN>::shape_deriv (elem, o, i, j, p[vi], add_p_level);
}

} // namespace libMesh

#endif// LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
<|endoftext|>


<commit_before>
/* ****************************************************************************
 *
 * FILE            DelilahUtils.cpp
 *
 * AUTHOR          Andreu Urruela
 *
 * PROJECT         Samson
 *
 * DATE            8/31/11
 *
 * DESCRIPTION
 *
 *  Copyright 2011 Andreu Urruela. All rights reserved.
 *
 * ****************************************************************************/

#include <sstream>                  // std::ostringstream
#include <iomanip>                  // std::setw

#include "au/Descriptors.h"         // au::Descriptors

#include "DelilahUtils.h"			// Own interface

namespace samson {

    std::string getStreamOperationInfo( const pugi::xml_node& node )
    {
        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string description = pugi::get( node , "description" );

        std::ostringstream output;
        output << std::setw(15) << name << "  " << description;
        return output.str();

    }

    std::string getBLockListInfo( pugi::node node )
    {
        size_t size_total =  pugi::getUInt64( node , "size_total" );
        size_t size_on_memory =  pugi::getUInt64( node , "size_on_memory" );
        size_t size_on_disk =  pugi::getUInt64( node , "size_on_disk" );

        int num_blocks = pugi::getInt( node , "num_blocks" );
        size_t kvs = pugi::getUInt64( node , "kvs" );
        size_t size = pugi::getUInt64( node , "size" );

        if( ( kvs == 0 ) && (size == 0) )
            return "Empty";

        std::ostringstream output;
        output << num_blocks << " blocks with ";
        output << au::str( kvs , "kvs" ) << " in ";
        output << au::str( size , "bytes" )  ;
        output << " ";
        if( size_total > 0 )
        {
            double p_memory = (double) size_on_memory / (double) size_total;
            double p_disk = (double) size_on_disk / (double) size_total;

            output << au::Format::percentage_string( p_memory ) << " on memory & " << au::Format::percentage_string( p_disk ) << " on disk";
        }

        return output.str();
    }

    std::string getQueueInfo( const pugi::xml_node& queue )
    {

        // Get information for this state
        std::string name = pugi::get( queue , "name" );

        const pugi::node block_list = queue.first_element_by_path("block_list");

        std::ostringstream output;
        output << std::setw(15) << name << ": [ "  << getBLockListInfo (block_list ) << " ]";

        return output.str();
    }

    std::string getStateInfo( const pugi::xml_node& state )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( state, "name" );

        int num_state_items =  pugi::getInt( state , "num_state_items" );

        const pugi::node state_info = state.first_element_by_path("state_info").first_element_by_path("block_list");
        const pugi::node input_info = state.first_element_by_path("input_info").first_element_by_path("block_list");

        output << "State " << name << ": ( " << num_state_items << " state items ) ";
        output << " State: [ " << getBLockListInfo( state_info ) << " ] ";

        output << " Input: [ " << getBLockListInfo( input_info ) << " ] ";

        output << "\n";

        return output.str();

    }

    std::string getQueueTaskInfo( const pugi::xml_node& queue_task )
    {
        // Get information for this state
        std::string id              = pugi::get( queue_task , "id" );
        std::string description     = pugi::get( queue_task , "description" );

        const pugi::node block_list = queue_task.first_element_by_path("block_list");

        std::ostringstream output;
        output << "Task " << id << " : " << description << "\n";
        output << "            -> Input " << getBLockListInfo( block_list ) << "\n";
        return output.str();

    }

    std::string getFormatInfo( const pugi::xml_node& node )
    {
        // Get information for this state
        std::string key_format = pugi::get( node , "key_format" );
        std::string value_format = pugi::get( node , "value_format" );

        std::ostringstream output;
        output << "[" << key_format << "-" << value_format << "]";
        return output.str();
    }

    std::string getDataInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string help = pugi::get( node , "help" );

        output << "** " << std::left << std::setw(40) << name << " - " << help;

        return output.str();
    }

    std::string getOperationInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string type = pugi::get( node , "type" );
        std::string help = pugi::get( node , "help" );

        output << "** " << name << " ( " << type << " )\n";

        output << "\t\tInputs: ";
        pugi::xml_node input_formats = node.first_element_by_path("input_formats");
        for( pugi::xml_node_iterator n = input_formats.begin() ; n != input_formats.end() ; n++)
            output << getFormatInfo(*n) << " ";
        output << "\n";

        output << "\t\tOutputs: ";
        pugi::xml_node output_formats = node.first_element_by_path("output_formats");
        for( pugi::xml_node_iterator n = output_formats.begin() ; n != output_formats.end() ; n++)
            output << getFormatInfo(*n) << " ";
        output << "\n";
        output << "\t\tHelp: " << help << "\n";

        return output.str();

    }

    std::string getTaskInfo( const pugi::xml_node& node )
    {
        std::string id = pugi::get( node , "id" );
        std::string job_id = pugi::get( node , "job_id" );
        std::string name = pugi::get( node , "name" );
        std::string state = pugi::get( node , "state" );

        std::ostringstream output;
        output << "[ " << id << " ] [ Job " << job_id << " ] [ " << state << " ] " << name << " " ;

        if( state == "running" )
        {
            size_t total_info = pugi::getUInt64( node , "total_info" );
            size_t running_info = pugi::getUInt64( node , "running_info" );
            size_t processed_info = pugi::getUInt64( node , "processed_info" );

            output << "[ Progress: ";
            output << au::str( running_info , "bytes" ) << " / ";
            output << au::str( processed_info , "bytes" ) << " / ";
            output << au::str( total_info , "bytes" );
            output << "]";
        }

        return output.str();

    }

    std::string getWorkerTaskInfo( const pugi::xml_node& node )
    {
        std::string task_id = pugi::get( node , "task_id" );
        std::string operation = pugi::get( node , "operation" );
        std::string status = pugi::get( node , "status" );

        int num_workers = (int) pugi::getUInt64( node , "num_workers" );
        int num_finished_workers = (int) pugi::getUInt64( node , "num_finished_workers" );

        std::ostringstream output;
        output << "[ " << task_id << " ] [ " << status << " ] " << operation << " " ;

        if( num_finished_workers == num_workers )
            output << " All workers finised ";
        else
            output << " Completed workers " << num_finished_workers << " / " << num_workers;

        au::Descriptors descriptors;
        pugi::xml_node node_worker_subtasks = node.first_element_by_path("worker_subtasks");
        for( pugi::xml_node_iterator n = node_worker_subtasks.begin() ; n != node_worker_subtasks.end() ; n++)
        {
            std::string description = pugi::get(*n, "description" );
            std::string state = pugi::get(*n, "state" );
            descriptors.add( au::str( "[ %s : %s ]" , description.c_str() , state.c_str() ) );
        }

        output << "\n\t SubTasks: " << descriptors.str();

        return output.str();

    }

    std::string getJobInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string id = pugi::get( node , "id" );
        std::string command = pugi::get( node , "command" );
        std::string status = pugi::get( node , "status" );

        output << "  [ " << id << " ] [ " << std::setw(10) << std::left <<  status << " ] " << command;

        pugi::xml_node current_task = node.first_element_by_path("current_task").first_element_by_path("controller_task");

        if( pugi::get( current_task , "id" ) != "" )
            output << "\n\tCurrent task: " << getTaskInfo( current_task );

        return output.str();
    }

    std::string getModuleInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string name = pugi::get( node , "name" );
        std::string version = pugi::get( node , "version" );
        std::string author = pugi::get( node , "author" );

        int num_operations  = getNumChildrens( node.first_element_by_path("operations") , "operation" );
        int num_datas       = getNumChildrens( node.first_element_by_path("datas") , "dats" );

        output << "  Module " << std::left << std::setw(25) << name << " " << std::setw(10) << version;
        output << std::setw(15) << au::str("[ #ops: %3d #datas: %3d ]",num_operations, num_datas);
        output << " ( " << author << ")";

        return output.str();
    }

    std::string getNetworkInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string description = pugi::get( node , "description" );
        output << description << "\n";
        return output.str();
    }

    std::string getEngineSystemInfo( const pugi::xml_node& node )
    {

        pugi::xml_node node_memory_manager = node.first_element_by_path("memory_manager");
        pugi::xml_node node_disk_manager = node.first_element_by_path("disk_manager");
        pugi::xml_node node_process_manager = node.first_element_by_path("process_manager");

        std::ostringstream output;

        size_t memory       = pugi::getUInt64( node_memory_manager , "memory" );
        size_t used_memory  = pugi::getUInt64( node_memory_manager , "used_memory" );
        int num_buffers  = (int) pugi::getUInt64( node_memory_manager , "num_buffers" );

        output << "** Memory: " << au::str( used_memory , "bytes" ) << " / " << au::str( memory , "bytes" ) << " ( " << num_buffers << " buffers )\n";

        size_t num_pending_operations = pugi::getUInt64( node_disk_manager , "num_pending_operations" );
        size_t num_running_operations = pugi::getUInt64( node_disk_manager , "num_running_operations" );

        std::string t_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("total") , "description" );
        std::string r_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("read") , "description" );
        std::string w_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("write") , "description" );

        output << "\n";

        output << "** Disk: Running " << num_running_operations << " ops, waiting " << num_pending_operations << " ops\n";
        output << "      READ  [ " << r_statistics << " ]\n";
        output << "      WRITE [ " << w_statistics << " ]\n";
        output << "      TOTAL [ " << t_statistics << " ]\n";

        pugi::xml_node running = node_process_manager.first_element_by_path("running");
        pugi::xml_node queued = node_process_manager.first_element_by_path("queued");
        pugi::xml_node halted = node_process_manager.first_element_by_path("halted");

        au::Descriptors queued_elements;
        pugi::xml_node_iterator n;
        for( n = queued.begin() ; n != queued.end() ; n++)
            queued_elements.add( pugi::get(*n , "operation_name" ) );

        au::Descriptors halted_elements;
        for( n = halted.begin() ; n != halted.end() ; n++)
            halted_elements.add( pugi::get(*n , "operation_name" ) );

        output << "\n";

        output << "** Process manager:\n";
        output << "      QUEUED:  " << queued_elements.str() << "\n";
        output << "      HALTED:  " << halted_elements.str() << "\n";
        output << "      RUNNING:\n";

        for(  n = running.begin() ; n != running.end() ; n++)
        {
            output << "         ";
            output << "[ Priority " << pugi::get( *n , "priority") << " ] ";
            output << "[ Progress " << au::Format::percentage_string( pugi::getDouble( *n , "progress") ) << " ] ";
            output << pugi::get( *n , "operation_name");
            output << "\n";

        }

        return output.str();
    }

    std::string getSetInfo( const pugi::xml_node& queue )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( queue , "name" );

        size_t kvs = pugi::getUInt64( queue , "kvs" );
        size_t size = pugi::getUInt64( queue , "size" );

        size_t num_files = pugi::getUInt64( queue , "num_files" );

        pugi::xml_node format_node = queue.first_element_by_path("format");

        output << std::setw(30) << name;
        output << " ";
        output << au::str( kvs );
        output << " kvs in ";
        output << au::str( size ) << " bytes";
        output << " #File: " << num_files;
        output << " " << getFormatInfo( format_node );

        return output.str();
    }

}

<commit_msg>Fix bug about showing the number of datas in a particular module (ls_modules)<commit_after>
/* ****************************************************************************
 *
 * FILE            DelilahUtils.cpp
 *
 * AUTHOR          Andreu Urruela
 *
 * PROJECT         Samson
 *
 * DATE            8/31/11
 *
 * DESCRIPTION
 *
 *  Copyright 2011 Andreu Urruela. All rights reserved.
 *
 * ****************************************************************************/

#include <sstream>                  // std::ostringstream
#include <iomanip>                  // std::setw

#include "au/Descriptors.h"         // au::Descriptors

#include "DelilahUtils.h"			// Own interface

namespace samson {

    std::string getStreamOperationInfo( const pugi::xml_node& node )
    {
        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string description = pugi::get( node , "description" );

        std::ostringstream output;
        output << std::setw(15) << name << "  " << description;
        return output.str();

    }

    std::string getBLockListInfo( pugi::node node )
    {
        size_t size_total =  pugi::getUInt64( node , "size_total" );
        size_t size_on_memory =  pugi::getUInt64( node , "size_on_memory" );
        size_t size_on_disk =  pugi::getUInt64( node , "size_on_disk" );

        int num_blocks = pugi::getInt( node , "num_blocks" );
        size_t kvs = pugi::getUInt64( node , "kvs" );
        size_t size = pugi::getUInt64( node , "size" );

        if( ( kvs == 0 ) && (size == 0) )
            return "Empty";

        std::ostringstream output;
        output << num_blocks << " blocks with ";
        output << au::str( kvs , "kvs" ) << " in ";
        output << au::str( size , "bytes" )  ;
        output << " ";
        if( size_total > 0 )
        {
            double p_memory = (double) size_on_memory / (double) size_total;
            double p_disk = (double) size_on_disk / (double) size_total;

            output << au::Format::percentage_string( p_memory ) << " on memory & " << au::Format::percentage_string( p_disk ) << " on disk";
        }

        return output.str();
    }

    std::string getQueueInfo( const pugi::xml_node& queue )
    {

        // Get information for this state
        std::string name = pugi::get( queue , "name" );

        const pugi::node block_list = queue.first_element_by_path("block_list");

        std::ostringstream output;
        output << std::setw(15) << name << ": [ "  << getBLockListInfo (block_list ) << " ]";

        return output.str();
    }

    std::string getStateInfo( const pugi::xml_node& state )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( state, "name" );

        int num_state_items =  pugi::getInt( state , "num_state_items" );

        const pugi::node state_info = state.first_element_by_path("state_info").first_element_by_path("block_list");
        const pugi::node input_info = state.first_element_by_path("input_info").first_element_by_path("block_list");

        output << "State " << name << ": ( " << num_state_items << " state items ) ";
        output << " State: [ " << getBLockListInfo( state_info ) << " ] ";

        output << " Input: [ " << getBLockListInfo( input_info ) << " ] ";

        output << "\n";

        return output.str();

    }

    std::string getQueueTaskInfo( const pugi::xml_node& queue_task )
    {
        // Get information for this state
        std::string id              = pugi::get( queue_task , "id" );
        std::string description     = pugi::get( queue_task , "description" );

        const pugi::node block_list = queue_task.first_element_by_path("block_list");

        std::ostringstream output;
        output << "Task " << id << " : " << description << "\n";
        output << "            -> Input " << getBLockListInfo( block_list ) << "\n";
        return output.str();

    }

    std::string getFormatInfo( const pugi::xml_node& node )
    {
        // Get information for this state
        std::string key_format = pugi::get( node , "key_format" );
        std::string value_format = pugi::get( node , "value_format" );

        std::ostringstream output;
        output << "[" << key_format << "-" << value_format << "]";
        return output.str();
    }

    std::string getDataInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string help = pugi::get( node , "help" );

        output << "** " << std::left << std::setw(40) << name << " - " << help;

        return output.str();
    }

    std::string getOperationInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( node , "name" );
        std::string type = pugi::get( node , "type" );
        std::string help = pugi::get( node , "help" );

        output << "** " << name << " ( " << type << " )\n";

        output << "\t\tInputs: ";
        pugi::xml_node input_formats = node.first_element_by_path("input_formats");
        for( pugi::xml_node_iterator n = input_formats.begin() ; n != input_formats.end() ; n++)
            output << getFormatInfo(*n) << " ";
        output << "\n";

        output << "\t\tOutputs: ";
        pugi::xml_node output_formats = node.first_element_by_path("output_formats");
        for( pugi::xml_node_iterator n = output_formats.begin() ; n != output_formats.end() ; n++)
            output << getFormatInfo(*n) << " ";
        output << "\n";
        output << "\t\tHelp: " << help << "\n";

        return output.str();

    }

    std::string getTaskInfo( const pugi::xml_node& node )
    {
        std::string id = pugi::get( node , "id" );
        std::string job_id = pugi::get( node , "job_id" );
        std::string name = pugi::get( node , "name" );
        std::string state = pugi::get( node , "state" );

        std::ostringstream output;
        output << "[ " << id << " ] [ Job " << job_id << " ] [ " << state << " ] " << name << " " ;

        if( state == "running" )
        {
            size_t total_info = pugi::getUInt64( node , "total_info" );
            size_t running_info = pugi::getUInt64( node , "running_info" );
            size_t processed_info = pugi::getUInt64( node , "processed_info" );

            output << "[ Progress: ";
            output << au::str( running_info , "bytes" ) << " / ";
            output << au::str( processed_info , "bytes" ) << " / ";
            output << au::str( total_info , "bytes" );
            output << "]";
        }

        return output.str();

    }

    std::string getWorkerTaskInfo( const pugi::xml_node& node )
    {
        std::string task_id = pugi::get( node , "task_id" );
        std::string operation = pugi::get( node , "operation" );
        std::string status = pugi::get( node , "status" );

        int num_workers = (int) pugi::getUInt64( node , "num_workers" );
        int num_finished_workers = (int) pugi::getUInt64( node , "num_finished_workers" );

        std::ostringstream output;
        output << "[ " << task_id << " ] [ " << status << " ] " << operation << " " ;

        if( num_finished_workers == num_workers )
            output << " All workers finised ";
        else
            output << " Completed workers " << num_finished_workers << " / " << num_workers;

        au::Descriptors descriptors;
        pugi::xml_node node_worker_subtasks = node.first_element_by_path("worker_subtasks");
        for( pugi::xml_node_iterator n = node_worker_subtasks.begin() ; n != node_worker_subtasks.end() ; n++)
        {
            std::string description = pugi::get(*n, "description" );
            std::string state = pugi::get(*n, "state" );
            descriptors.add( au::str( "[ %s : %s ]" , description.c_str() , state.c_str() ) );
        }

        output << "\n\t SubTasks: " << descriptors.str();

        return output.str();

    }

    std::string getJobInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string id = pugi::get( node , "id" );
        std::string command = pugi::get( node , "command" );
        std::string status = pugi::get( node , "status" );

        output << "  [ " << id << " ] [ " << std::setw(10) << std::left <<  status << " ] " << command;

        pugi::xml_node current_task = node.first_element_by_path("current_task").first_element_by_path("controller_task");

        if( pugi::get( current_task , "id" ) != "" )
            output << "\n\tCurrent task: " << getTaskInfo( current_task );

        return output.str();
    }

    std::string getModuleInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string name = pugi::get( node , "name" );
        std::string version = pugi::get( node , "version" );
        std::string author = pugi::get( node , "author" );

        int num_operations  = getNumChildrens( node.first_element_by_path("operations") , "operation" );
        int num_datas       = getNumChildrens( node.first_element_by_path("datas") , "data" );

        output << "  Module " << std::left << std::setw(25) << name << " " << std::setw(10) << version;
        output << std::setw(15) << au::str("[ #ops: %3d #datas: %3d ]",num_operations, num_datas);
        output << " ( " << author << ")";

        return output.str();
    }

    std::string getNetworkInfo( const pugi::xml_node& node )
    {
        std::ostringstream output;

        std::string description = pugi::get( node , "description" );
        output << description << "\n";
        return output.str();
    }

    std::string getEngineSystemInfo( const pugi::xml_node& node )
    {

        pugi::xml_node node_memory_manager = node.first_element_by_path("memory_manager");
        pugi::xml_node node_disk_manager = node.first_element_by_path("disk_manager");
        pugi::xml_node node_process_manager = node.first_element_by_path("process_manager");

        std::ostringstream output;

        size_t memory       = pugi::getUInt64( node_memory_manager , "memory" );
        size_t used_memory  = pugi::getUInt64( node_memory_manager , "used_memory" );
        int num_buffers  = (int) pugi::getUInt64( node_memory_manager , "num_buffers" );

        output << "** Memory: " << au::str( used_memory , "bytes" ) << " / " << au::str( memory , "bytes" ) << " ( " << num_buffers << " buffers )\n";

        size_t num_pending_operations = pugi::getUInt64( node_disk_manager , "num_pending_operations" );
        size_t num_running_operations = pugi::getUInt64( node_disk_manager , "num_running_operations" );

        std::string t_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("total") , "description" );
        std::string r_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("read") , "description" );
        std::string w_statistics = pugi::get( node_disk_manager.first_element_by_path("statistics").first_element_by_path("write") , "description" );

        output << "\n";

        output << "** Disk: Running " << num_running_operations << " ops, waiting " << num_pending_operations << " ops\n";
        output << "      READ  [ " << r_statistics << " ]\n";
        output << "      WRITE [ " << w_statistics << " ]\n";
        output << "      TOTAL [ " << t_statistics << " ]\n";

        pugi::xml_node running = node_process_manager.first_element_by_path("running");
        pugi::xml_node queued = node_process_manager.first_element_by_path("queued");
        pugi::xml_node halted = node_process_manager.first_element_by_path("halted");

        au::Descriptors queued_elements;
        pugi::xml_node_iterator n;
        for( n = queued.begin() ; n != queued.end() ; n++)
            queued_elements.add( pugi::get(*n , "operation_name" ) );

        au::Descriptors halted_elements;
        for( n = halted.begin() ; n != halted.end() ; n++)
            halted_elements.add( pugi::get(*n , "operation_name" ) );

        output << "\n";

        output << "** Process manager:\n";
        output << "      QUEUED:  " << queued_elements.str() << "\n";
        output << "      HALTED:  " << halted_elements.str() << "\n";
        output << "      RUNNING:\n";

        for(  n = running.begin() ; n != running.end() ; n++)
        {
            output << "         ";
            output << "[ Priority " << pugi::get( *n , "priority") << " ] ";
            output << "[ Progress " << au::Format::percentage_string( pugi::getDouble( *n , "progress") ) << " ] ";
            output << pugi::get( *n , "operation_name");
            output << "\n";

        }

        return output.str();
    }

    std::string getSetInfo( const pugi::xml_node& queue )
    {
        std::ostringstream output;

        // Get information for this state
        std::string name = pugi::get( queue , "name" );

        size_t kvs = pugi::getUInt64( queue , "kvs" );
        size_t size = pugi::getUInt64( queue , "size" );

        size_t num_files = pugi::getUInt64( queue , "num_files" );

        pugi::xml_node format_node = queue.first_element_by_path("format");

        output << std::setw(30) << name;
        output << " ";
        output << au::str( kvs );
        output << " kvs in ";
        output << au::str( size ) << " bytes";
        output << " #File: " << num_files;
        output << " " << getFormatInfo( format_node );

        return output.str();
    }

}

<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CommandsStandard.h"

/* system implementation headers */
#include <stdio.h>
#include <ctype.h>
#include <string>

/* common implementation headers */
#include "CommandManager.h"
#include "StateDatabase.h"
#include "KeyManager.h"
#include "TextUtils.h"

static bool			quitFlag = false;

//
// command handlers
//

static std::string		cmdQuit(const std::string&,
					const CommandManager::ArgList&, bool*)
{
  CommandsStandard::quit();
  return std::string();
}

static void			onHelpCB(const std::string& name,
					 void* userData)
{
  std::string& result = *static_cast<std::string*>(userData);
  result += name;
  result += "\n";
}

static std::string		cmdHelp(const std::string&,
					const CommandManager::ArgList& args, bool*)
{
  switch (args.size()) {
    case 0: {
      std::string result;
      CMDMGR.iterate(&onHelpCB, &result);
      return result;
    }

    case 1:
      return CMDMGR.getHelp(args[0]);

    default:
      return "usage: help [<command-name>]";
  }
}

static std::string		cmdPrint(const std::string&,
					 const CommandManager::ArgList& args, bool*)
{
  // merge all arguments into one string
  std::string arg;
  const unsigned int n = (int)args.size();
  if (n > 0)
    arg = args[0];
  for (unsigned int i = 1; i < n; ++i) {
    arg += " ";
    arg += args[i];
  }

  // interpolate variables
  std::string result;
  const char* scan = arg.c_str();
  while (*scan != '\0') {
    if (*scan != '$') {
      result.append(scan, 1);
      ++scan;
    } else {
      // could be a variable
      ++scan;
      if (*scan == '$') {
	// no, it's just $$ which maps to $
	result += "$";
	++scan;
      } else if (*scan != '{') {
	// parse variable name
	const char* name = scan;
	while (*scan != '\0' && !isspace(*scan))
	  ++scan;

	// look up variable
	result += BZDB.get(std::string(name, scan - name));
      } else {
	// parse "quoted" variable name
	const char* name = ++scan;
	while (*scan != '\0' && *scan != '}')
	  ++scan;

	if (*scan != '\0') {
	  // look up variable
	  result += BZDB.get(std::string(name, scan - name));

	  // skip }
	  ++scan;
	}
      }
    }
  }

  std::cout << "printing \"" << result << "\"" << std::endl;
  return result;
}

static void			onSetCB(const std::string& name,
					void* userData)
{
  // don't show names starting with _
  std::string& result = *static_cast<std::string*>(userData);
  if (!name.empty() && name.c_str()[0] != '_') {
    result += name;
    result += " = ";
    result += BZDB.get(name);
    result += "\n";
  }
}

static std::string		cmdSet(const std::string&,
				       const CommandManager::ArgList& args, bool* error)
{
	if(error) *error = false;
  switch (args.size()) {

    case 0:
      {
	// print out all values that are set
	std::string result;
	BZDB.iterate(&onSetCB, &result);
	return result;
      }
    case 1:
      {
	// the string was set to nothing, so just print value
	if (BZDB.isSet(args[0])) {
	  return args[0] + " is " + BZDB.get(args[0]);
	} else {
	  if(error) *error = true;
	  return "variable " + args[0] + " does not exist";
	}
      }
    case 2:
      {
	// set variable to value
	BZDB.set(args[0], args[1], StateDatabase::User);
	return std::string();
      }
    default:
      {
    if(error) *error = true;
	return "usage: set <name> [<value>]";
      }
  }
}

static std::string		cmdUnset(const std::string&,
					 const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 1)
    return "usage: unset <name>";
  BZDB.unset(args[0], StateDatabase::User);
  return std::string();
}

static void			onBindCB(const std::string& name, bool press,
					 const std::string& cmd, void* userData)
{
  std::string& result = *static_cast<std::string*>(userData);
  result += name;
  result += (press ? " down " : " up ");
  result += cmd;
  result += "\n";
}

static std::string		cmdBind(const std::string&,
					const CommandManager::ArgList& args, bool*)
{
  if (args.size() == 0) {
    std::string result;
    KEYMGR.iterate(&onBindCB, &result);
    return result;
  } else if (args.size() < 3) {
    return "usage: bind <button-name> {up|down} <command> <args>...";
  }

  BzfKeyEvent key;
  if (!KEYMGR.stringToKeyEvent(args[0], key))
    return std::string("bind error: unknown button name \"") + args[0] + "\"";

  bool down;
  if (args[1] == "up")
    down = false;
  else if (args[1] == "down")
    down = true;
  else
    return std::string("bind error: illegal state \"") + args[1] + "\"";

  std::string cmd = args[2];
  for (unsigned int i = 3; i < args.size(); ++i) {
    cmd += " ";
    cmd += args[i];
  }

  // ignore attempts to modify Esc.  we reserve that for the menu
  if (key.ascii != 27)
    KEYMGR.bind(key, down, cmd);

  return std::string();
}

static std::string		cmdUnbind(const std::string&,
					  const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 2)
    return "usage: unbind <button-name> {up|down}";

  BzfKeyEvent key_event;
  if (!KEYMGR.stringToKeyEvent(args[0], key_event))
    return std::string("bind error: unknown button name \"") + args[0] + "\"";

  bool down;
  if (args[1] == "up")
    down = false;
  else if (args[1] == "down")
    down = true;
  else
    return std::string("bind error: illegal state \"") + args[1] + "\"";

  if (key_event.ascii != 27)
    KEYMGR.unbind(key_event, down);

  return std::string();
}

static std::string		cmdToggle(const std::string&,
					  const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 1)
    return "usage: toggle <name>";
  const std::string& name = args[0];
  if (BZDB.isTrue(name))
    BZDB.set(name, "0", StateDatabase::User);
  else
    BZDB.set(name, "1", StateDatabase::User);
  return std::string();
}

static std::string cmdMult(const std::string&, const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 2)
    return "usage: mult <name> <value>";
  float value;
  if (sscanf(BZDB.get(args[0]).c_str(), "%f", &value) != 1)
    value = 0.0;
  float amount;
  if (sscanf(args[1].c_str(), "%f", &amount) != 1)
    amount = 1.0;
  value *= amount;
  BZDB.set(args[0], TextUtils::format("%f", value), StateDatabase::User);
  return std::string();
}

//
// command name to function mapping
//

const struct CommandsItem commands[] = {
  { "quit",	&cmdQuit,	"quit:  quit the program" },
  { "help",	&cmdHelp,	"help [<command-name>]:  get help on a command or a list of commands" },
  { "print",	&cmdPrint,	"print ...:  print arguments; $name is replaced by value of variable \"name\"" },
  { "set",	&cmdSet,	"set [<name> <value>]:  set a variable or print all set variables" },
  { "unset",	&cmdUnset,	"unset <name>:  unset a variable" },
  { "bind",	&cmdBind,	"bind <button-name> {up|down} <command> <args>...: bind a key" },
  { "unbind",	&cmdUnbind,	"unbind <button-name> {up|down}:  unbind a key" },
  { "toggle",	&cmdToggle,	"toggle <name>:  toggle truth value of a variable" },
  { "mult",	&cmdMult,	"mult <name> <value>:  multiply a variable by an amount" }
};
// FIXME -- may want a cmd to cycle through a list

//
// CommandsStandard
//

void				CommandsStandard::add()
{
  unsigned int i;
  for (i = 0; i < countof(commands); ++i)
    CMDMGR.add(commands[i].name, commands[i].func, commands[i].help);
}

void				CommandsStandard::remove()
{
  unsigned int i;
  for (i = 0; i < countof(commands); ++i)
    CMDMGR.remove(commands[i].name);
}

void				CommandsStandard::quit()
{
  quitFlag = true;
}

bool				CommandsStandard::isQuit()
{
  return quitFlag;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>- added "add" command for key bindings - added ability to set values for the "toggle" key binding command<commit_after>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CommandsStandard.h"

/* system implementation headers */
#include <stdio.h>
#include <ctype.h>
#include <string>

/* common implementation headers */
#include "CommandManager.h"
#include "StateDatabase.h"
#include "KeyManager.h"
#include "TextUtils.h"

static bool			quitFlag = false;

//
// command handlers
//

static std::string		cmdQuit(const std::string&,
					const CommandManager::ArgList&, bool*)
{
  CommandsStandard::quit();
  return std::string();
}

static void			onHelpCB(const std::string& name,
					 void* userData)
{
  std::string& result = *static_cast<std::string*>(userData);
  result += name;
  result += "\n";
}

static std::string		cmdHelp(const std::string&,
					const CommandManager::ArgList& args, bool*)
{
  switch (args.size()) {
    case 0: {
      std::string result;
      CMDMGR.iterate(&onHelpCB, &result);
      return result;
    }

    case 1:
      return CMDMGR.getHelp(args[0]);

    default:
      return "usage: help [<command-name>]";
  }
}

static std::string		cmdPrint(const std::string&,
					 const CommandManager::ArgList& args, bool*)
{
  // merge all arguments into one string
  std::string arg;
  const unsigned int n = (int)args.size();
  if (n > 0)
    arg = args[0];
  for (unsigned int i = 1; i < n; ++i) {
    arg += " ";
    arg += args[i];
  }

  // interpolate variables
  std::string result;
  const char* scan = arg.c_str();
  while (*scan != '\0') {
    if (*scan != '$') {
      result.append(scan, 1);
      ++scan;
    } else {
      // could be a variable
      ++scan;
      if (*scan == '$') {
	// no, it's just $$ which maps to $
	result += "$";
	++scan;
      } else if (*scan != '{') {
	// parse variable name
	const char* name = scan;
	while (*scan != '\0' && !isspace(*scan))
	  ++scan;

	// look up variable
	result += BZDB.get(std::string(name, scan - name));
      } else {
	// parse "quoted" variable name
	const char* name = ++scan;
	while (*scan != '\0' && *scan != '}')
	  ++scan;

	if (*scan != '\0') {
	  // look up variable
	  result += BZDB.get(std::string(name, scan - name));

	  // skip }
	  ++scan;
	}
      }
    }
  }

  std::cout << "printing \"" << result << "\"" << std::endl;
  return result;
}

static void			onSetCB(const std::string& name,
					void* userData)
{
  // don't show names starting with _
  std::string& result = *static_cast<std::string*>(userData);
  if (!name.empty() && name.c_str()[0] != '_') {
    result += name;
    result += " = ";
    result += BZDB.get(name);
    result += "\n";
  }
}

static std::string		cmdSet(const std::string&,
				       const CommandManager::ArgList& args, bool* error)
{
	if(error) *error = false;
  switch (args.size()) {

    case 0:
      {
	// print out all values that are set
	std::string result;
	BZDB.iterate(&onSetCB, &result);
	return result;
      }
    case 1:
      {
	// the string was set to nothing, so just print value
	if (BZDB.isSet(args[0])) {
	  return args[0] + " is " + BZDB.get(args[0]);
	} else {
	  if(error) *error = true;
	  return "variable " + args[0] + " does not exist";
	}
      }
    case 2:
      {
	// set variable to value
	BZDB.set(args[0], args[1], StateDatabase::User);
	return std::string();
      }
    default:
      {
    if(error) *error = true;
	return "usage: set <name> [<value>]";
      }
  }
}

static std::string		cmdUnset(const std::string&,
					 const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 1)
    return "usage: unset <name>";
  BZDB.unset(args[0], StateDatabase::User);
  return std::string();
}

static void			onBindCB(const std::string& name, bool press,
					 const std::string& cmd, void* userData)
{
  std::string& result = *static_cast<std::string*>(userData);
  result += name;
  result += (press ? " down " : " up ");
  result += cmd;
  result += "\n";
}

static std::string		cmdBind(const std::string&,
					const CommandManager::ArgList& args, bool*)
{
  if (args.size() == 0) {
    std::string result;
    KEYMGR.iterate(&onBindCB, &result);
    return result;
  } else if (args.size() < 3) {
    return "usage: bind <button-name> {up|down} <command> <args>...";
  }

  BzfKeyEvent key;
  if (!KEYMGR.stringToKeyEvent(args[0], key))
    return std::string("bind error: unknown button name \"") + args[0] + "\"";

  bool down;
  if (args[1] == "up")
    down = false;
  else if (args[1] == "down")
    down = true;
  else
    return std::string("bind error: illegal state \"") + args[1] + "\"";

  std::string cmd = args[2];
  for (unsigned int i = 3; i < args.size(); ++i) {
    cmd += " ";
    cmd += args[i];
  }

  // ignore attempts to modify Esc.  we reserve that for the menu
  if (key.ascii != 27)
    KEYMGR.bind(key, down, cmd);

  return std::string();
}

static std::string		cmdUnbind(const std::string&,
					  const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 2)
    return "usage: unbind <button-name> {up|down}";

  BzfKeyEvent key_event;
  if (!KEYMGR.stringToKeyEvent(args[0], key_event))
    return std::string("bind error: unknown button name \"") + args[0] + "\"";

  bool down;
  if (args[1] == "up")
    down = false;
  else if (args[1] == "down")
    down = true;
  else
    return std::string("bind error: illegal state \"") + args[1] + "\"";

  if (key_event.ascii != 27)
    KEYMGR.unbind(key_event, down);

  return std::string();
}

static std::string		cmdToggle(const std::string&,
					  const CommandManager::ArgList& args, bool*)
{
  if ((args.size() < 1) || (args.size() > 3)) {
    return "usage: toggle <name> [first [second]]";
  }
  const std::string& name = args[0];
  if (args.size() == 1) {
    BZDB.set(name, BZDB.isTrue(name) ? "0" : "1");
  } else if (args.size() == 2) {
    BZDB.set(name, BZDB.isTrue(name) ? "0" : args[1]);
  } else {
    BZDB.set(name, (BZDB.get(name) == args[1]) ? args[2] : args[1]);
  }
  return std::string();
}

static std::string cmdMult(const std::string&, const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 2)
    return "usage: mult <name> <value>";
  float value;
  if (sscanf(BZDB.get(args[0]).c_str(), "%f", &value) != 1)
    value = 0.0;
  float amount;
  if (sscanf(args[1].c_str(), "%f", &amount) != 1)
    amount = 1.0;
  value *= amount;
  BZDB.set(args[0], TextUtils::format("%f", value), StateDatabase::User);
  return std::string();
}

static std::string cmdAdd(const std::string&, const CommandManager::ArgList& args, bool*)
{
  if (args.size() != 2) {
    return "usage: add <name> <value>";
  }
  float value;
  if (sscanf(BZDB.get(args[0]).c_str(), "%f", &value) != 1) {
    value = 0.0f;
  }
  float amount;
  if (sscanf(args[1].c_str(), "%f", &amount) != 1) {
    amount = 0.0f;
  }
  value += amount;
  BZDB.set(args[0], TextUtils::format("%f", value), StateDatabase::User);
  return std::string();
}

//
// command name to function mapping
//

const struct CommandsItem commands[] = {
  { "quit",	&cmdQuit,	"quit:  quit the program" },
  { "help",	&cmdHelp,	"help [<command-name>]:  get help on a command or a list of commands" },
  { "print",	&cmdPrint,	"print ...:  print arguments; $name is replaced by value of variable \"name\"" },
  { "set",	&cmdSet,	"set [<name> <value>]:  set a variable or print all set variables" },
  { "unset",	&cmdUnset,	"unset <name>:  unset a variable" },
  { "bind",	&cmdBind,	"bind <button-name> {up|down} <command> <args>...: bind a key" },
  { "unbind",	&cmdUnbind,	"unbind <button-name> {up|down}:  unbind a key" },
  { "toggle",	&cmdToggle,	"toggle <name> [first [second]]:  toggle value of a variable" },
  { "mult",	&cmdMult,	"mult <name> <value>:  multiply a variable by an amount" },
  { "add",	&cmdAdd,	"add <name> <value>:  add an amount to a variable" }
};
// FIXME -- may want a cmd to cycle through a list

//
// CommandsStandard
//

void				CommandsStandard::add()
{
  unsigned int i;
  for (i = 0; i < countof(commands); ++i)
    CMDMGR.add(commands[i].name, commands[i].func, commands[i].help);
}

void				CommandsStandard::remove()
{
  unsigned int i;
  for (i = 0; i < countof(commands); ++i)
    CMDMGR.remove(commands[i].name);
}

void				CommandsStandard::quit()
{
  quitFlag = true;
}

bool				CommandsStandard::isQuit()
{
  return quitFlag;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before><commit_msg>Start dynification tests<commit_after><|endoftext|>


<commit_before>#include <boost/thread/mutex.hpp>

#include "gt/model/common.hpp"

namespace GT {
namespace Model {

////////////////////////////////////////////////////////////////////////////////

boost::mutex nullFactoryMutex;

////////////////////////////////////////////////////////////////////////////////

// class NullFactory {
NullFactory* volatile NullFactory::instance = 0;

// public:
NullFactory& NullFactory::getInstance() {
    // Singleton implemented according to:
    // "C++ and the Perils of Double-Checked Locking"
    // but without executing constructor inside getInstance() method
    // since it's an eyesore.
    if (!instance) {
        boost::mutex::scoped_lock lock(nullFactoryMutex);
        if (!instance) {
            NullFactory* volatile tmp = new NullFactory();
            instance = tmp;
        }
    }
    return *instance;
}

IdentifierPtr NullFactory::createIdentifier() {
    return IdentifierPtr(new Identifier("NullIdentifier"));
}

MessagePtr NullFactory::createMessage() {
    return MessagePtr(new Identifier("NullMessage"));
}

NumberPtr NullFactory::createNumber() {
    return NumberPtr(new Number(0));
}

PlayerPtr NullFactory::createPlayer() {
    return PlayerPtr(new NullPlayer());
}

ResultPtr NullFactory::createResult() {
    return ResultPtr(new NullResult());
}

// private:
NullFactory::NullFactory() {}
// }

////////////////////////////////////////////////////////////////////////////////

} /* END namespace Model */
} /* END namespace GT */
<commit_msg>* Added lacking implementation of createIdentifiers() method.<commit_after>#include <boost/thread/mutex.hpp>

#include "gt/model/common.hpp"

namespace GT {
namespace Model {

////////////////////////////////////////////////////////////////////////////////

boost::mutex nullFactoryMutex;

////////////////////////////////////////////////////////////////////////////////

// class NullFactory {
NullFactory* volatile NullFactory::instance = 0;

// public:
NullFactory& NullFactory::getInstance() {
    // Singleton implemented according to:
    // "C++ and the Perils of Double-Checked Locking"
    // but without executing constructor inside getInstance() method
    // since it's an eyesore.
    if (!instance) {
        boost::mutex::scoped_lock lock(nullFactoryMutex);
        if (!instance) {
            NullFactory* volatile tmp = new NullFactory();
            instance = tmp;
        }
    }
    return *instance;
}

IdentifierPtr NullFactory::createIdentifier() {
    return IdentifierPtr(new Identifier("NullIdentifier"));
}

IdentifiersPtr NullFactory::createIdentifiers() {
    return IdentifiersPtr(new Identifiers());
}

MessagePtr NullFactory::createMessage() {
    return MessagePtr(new Identifier("NullMessage"));
}

NumberPtr NullFactory::createNumber() {
    return NumberPtr(new Number(0));
}

PlayerPtr NullFactory::createPlayer() {
    return PlayerPtr(new NullPlayer());
}

ResultPtr NullFactory::createResult() {
    return ResultPtr(new NullResult());
}

// private:
NullFactory::NullFactory() {}
// }

////////////////////////////////////////////////////////////////////////////////

} /* END namespace Model */
} /* END namespace GT */
<|endoftext|>


<commit_before>/*
    Copyright (c) 2008 Bertjan Broeksema <b.broeksema@kdemail.net>
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

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

#include "singlefileresourcebase.h"

#include <akonadi/changerecorder.h>
#include <akonadi/entitydisplayattribute.h>
#include <akonadi/itemfetchscope.h>

#include <kio/job.h>
#include <kio/jobuidelegate.h>
#include <KDebug>
#include <KDirWatch>
#include <KLocale>
#include <KStandardDirs>

#include <QtCore/QDir>

using namespace Akonadi;

SingleFileResourceBase::SingleFileResourceBase( const QString & id )
  : ResourceBase( id ), mDownloadJob( 0 ), mUploadJob( 0 )
{
  connect( &mDirtyTimer, SIGNAL( timeout() ), SLOT( writeFile() ) );
  mDirtyTimer.setSingleShot( true );

  connect( this, SIGNAL( reloadConfiguration() ), SLOT( reloadFile() ) );
  QTimer::singleShot( 0, this, SLOT( readFile() ) );

  changeRecorder()->itemFetchScope().fetchFullPayload();
  changeRecorder()->fetchCollection( true );

  connect( KDirWatch::self(), SIGNAL( dirty( QString ) ), SLOT( fileChanged( QString ) ) );
}

QString SingleFileResourceBase::cacheFile() const
{
  return KStandardDirs::locateLocal( "cache", "akonadi/" + identifier() );
}

void SingleFileResourceBase::setSupportedMimetypes( const QStringList & mimeTypes, const QString &icon )
{
  mSupportedMimetypes = mimeTypes;
  mCollectionIcon = icon;
}

void SingleFileResourceBase::collectionChanged( const Akonadi::Collection & collection )
{
  QString newName = collection.name();
  if ( collection.hasAttribute<EntityDisplayAttribute>() ) {
    EntityDisplayAttribute *attr = collection.attribute<EntityDisplayAttribute>();
    if ( !attr->displayName().isEmpty() )
      newName = attr->displayName();
  }

  if ( newName != name() )
    setName( newName );

  changeCommitted( collection );
}

void SingleFileResourceBase::reloadFile()
{
  // Update the network setting.
  setNeedsNetwork( !mCurrentUrl.isEmpty() && !mCurrentUrl.isLocalFile() );

  // if we have something loaded already, make sure we write that back in case
  // the settings changed
  if ( !mCurrentUrl.isEmpty() )
    writeFile();

  readFile();
  synchronize();
}

void SingleFileResourceBase::handleProgress( KJob *, unsigned long pct )
{
  emit percent( pct );
}

void SingleFileResourceBase::fileChanged( const QString & fileName )
{
  if ( fileName != mCurrentUrl.path() )
    return;

  // handle conflicts
  if ( mDirtyTimer.isActive() && !mCurrentUrl.isEmpty() ) {
    const KUrl prevUrl = mCurrentUrl;
    int i = 0;
    QString lostFoundFileName;
    do {
      lostFoundFileName = KStandardDirs::locateLocal( "data", identifier() + QDir::separator()
          + prevUrl.fileName() + "-" + QString::number( ++i ) );
    } while ( KStandardDirs::exists( lostFoundFileName ) );
    mCurrentUrl = KUrl( lostFoundFileName );
    writeFile();
    emit warning( i18n( "The file '%1' was changed on disk while there were still pending changes in Akonadi. "
        "To avoid dataloss, a backup of the internal changes has been created at '%2'.",
         prevUrl.prettyUrl(), mCurrentUrl.prettyUrl() ) );
    mCurrentUrl = prevUrl;
  }

  readFile();
  synchronize();
}

void SingleFileResourceBase::slotDownloadJobResult( KJob *job )
{
  if ( job->error() && job->error() != KIO::ERR_DOES_NOT_EXIST ) {
    emit status( Broken, i18n( "Could not load file '%1'.", mCurrentUrl.prettyUrl() ) );
  } else {
    readFromFile( KUrl( cacheFile() ).url() );
  }

  mDownloadJob = 0;
  KGlobal::deref();

  emit status( Idle, i18nc( "@info:status", "Ready" ) );
}

void SingleFileResourceBase::slotUploadJobResult( KJob *job )
{
  if ( job->error() ) {
    emit status( Broken, i18n( "Could not save file '%1'.", mCurrentUrl.prettyUrl() ) );
  }

  mUploadJob = 0;
  KGlobal::deref();

  emit status( Idle, i18nc( "@info:status", "Ready" ) );
}

#include "singlefileresourcebase.moc"
<commit_msg>Also watch "created" signals, since modifications using KSaveFile or similar techniques result in delete+create<commit_after>/*
    Copyright (c) 2008 Bertjan Broeksema <b.broeksema@kdemail.net>
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

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

#include "singlefileresourcebase.h"

#include <akonadi/changerecorder.h>
#include <akonadi/entitydisplayattribute.h>
#include <akonadi/itemfetchscope.h>

#include <kio/job.h>
#include <kio/jobuidelegate.h>
#include <KDebug>
#include <KDirWatch>
#include <KLocale>
#include <KStandardDirs>

#include <QtCore/QDir>

using namespace Akonadi;

SingleFileResourceBase::SingleFileResourceBase( const QString & id )
  : ResourceBase( id ), mDownloadJob( 0 ), mUploadJob( 0 )
{
  connect( &mDirtyTimer, SIGNAL( timeout() ), SLOT( writeFile() ) );
  mDirtyTimer.setSingleShot( true );

  connect( this, SIGNAL( reloadConfiguration() ), SLOT( reloadFile() ) );
  QTimer::singleShot( 0, this, SLOT( readFile() ) );

  changeRecorder()->itemFetchScope().fetchFullPayload();
  changeRecorder()->fetchCollection( true );

  connect( KDirWatch::self(), SIGNAL( dirty( QString ) ), SLOT( fileChanged( QString ) ) );
  connect( KDirWatch::self(), SIGNAL( created( QString ) ), SLOT( fileChanged( QString ) ) );
}

QString SingleFileResourceBase::cacheFile() const
{
  return KStandardDirs::locateLocal( "cache", "akonadi/" + identifier() );
}

void SingleFileResourceBase::setSupportedMimetypes( const QStringList & mimeTypes, const QString &icon )
{
  mSupportedMimetypes = mimeTypes;
  mCollectionIcon = icon;
}

void SingleFileResourceBase::collectionChanged( const Akonadi::Collection & collection )
{
  QString newName = collection.name();
  if ( collection.hasAttribute<EntityDisplayAttribute>() ) {
    EntityDisplayAttribute *attr = collection.attribute<EntityDisplayAttribute>();
    if ( !attr->displayName().isEmpty() )
      newName = attr->displayName();
  }

  if ( newName != name() )
    setName( newName );

  changeCommitted( collection );
}

void SingleFileResourceBase::reloadFile()
{
  // Update the network setting.
  setNeedsNetwork( !mCurrentUrl.isEmpty() && !mCurrentUrl.isLocalFile() );

  // if we have something loaded already, make sure we write that back in case
  // the settings changed
  if ( !mCurrentUrl.isEmpty() )
    writeFile();

  readFile();
  synchronize();
}

void SingleFileResourceBase::handleProgress( KJob *, unsigned long pct )
{
  emit percent( pct );
}

void SingleFileResourceBase::fileChanged( const QString & fileName )
{
  if ( fileName != mCurrentUrl.path() )
    return;

  // handle conflicts
  if ( mDirtyTimer.isActive() && !mCurrentUrl.isEmpty() ) {
    const KUrl prevUrl = mCurrentUrl;
    int i = 0;
    QString lostFoundFileName;
    do {
      lostFoundFileName = KStandardDirs::locateLocal( "data", identifier() + QDir::separator()
          + prevUrl.fileName() + "-" + QString::number( ++i ) );
    } while ( KStandardDirs::exists( lostFoundFileName ) );
    mCurrentUrl = KUrl( lostFoundFileName );
    writeFile();
    emit warning( i18n( "The file '%1' was changed on disk while there were still pending changes in Akonadi. "
        "To avoid dataloss, a backup of the internal changes has been created at '%2'.",
         prevUrl.prettyUrl(), mCurrentUrl.prettyUrl() ) );
    mCurrentUrl = prevUrl;
  }

  readFile();
  synchronize();
}

void SingleFileResourceBase::slotDownloadJobResult( KJob *job )
{
  if ( job->error() && job->error() != KIO::ERR_DOES_NOT_EXIST ) {
    emit status( Broken, i18n( "Could not load file '%1'.", mCurrentUrl.prettyUrl() ) );
  } else {
    readFromFile( KUrl( cacheFile() ).url() );
  }

  mDownloadJob = 0;
  KGlobal::deref();

  emit status( Idle, i18nc( "@info:status", "Ready" ) );
}

void SingleFileResourceBase::slotUploadJobResult( KJob *job )
{
  if ( job->error() ) {
    emit status( Broken, i18n( "Could not save file '%1'.", mCurrentUrl.prettyUrl() ) );
  }

  mUploadJob = 0;
  KGlobal::deref();

  emit status( Idle, i18nc( "@info:status", "Ready" ) );
}

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