<commit_before>#include "ouroboros_server.h"
#include <server/data/data_store.hpp>
#include <server/device_tree.hpp>
#include <mongoose/mongoose.h>
#include <server/rest.h>
#include <sstream>
#include <cassert>
#include <slre/slre.h>

namespace ouroboros
{
	namespace detail
	{
		std::string bad_JSON(mg_connection* aConn)
		{
			mg_send_status(aConn, 400);
			return std::string("{ \"status\" : \"Bad JSON request.\"}");
		}

		std::string good_JSON()
		{
			return std::string("{ \"status\" : \"OK.\"}");
		}
	}

	std::string url_regex("(.+://)?(.+)");

	ouroboros_server::ouroboros_server()
	:mpServer(NULL),
		mStore(device_tree<var_field>::get_device_tree().get_data_store())
	{
		//The following line is a hack workaround to trying to avoid using
		//functional support in c++03
		if (!mpSendServer)
		{
			//HACK
			mpSendServer = this;
		}
		mpServer = mg_create_server(this, ouroboros_server::event_handler);
		mg_set_option(mpServer, "document_root", ".");      // Serve current directory
		mg_set_option(mpServer, "listening_port", "8080");  // Open port 8080
	}

	ouroboros_server::~ouroboros_server()
	{
		mg_destroy_server(&mpServer);
	}

	const var_field *ouroboros_server::get(const std::string& aGroup, const std::string& aField) const
	{
		return mStore.get(normalize_group(aGroup), aField);
	}

	var_field *ouroboros_server::get(const std::string& aGroup, const std::string& aField)
	{
		return const_cast<var_field *>(static_cast<const ouroboros_server&>(*this).get(aGroup, aField));
	}

	const group<var_field> *ouroboros_server::get(const std::string& aGroup) const
	{
		return mStore.get(normalize_group(aGroup));
	}

	group<var_field> *ouroboros_server::get(const std::string& aGroup)
	{
		return const_cast<group<var_field> *>(static_cast<const ouroboros_server&>(*this).get(aGroup));
	}

	bool ouroboros_server::set(const std::string& aGroup, const std::string& aField, const var_field& aFieldData)
	{
		var_field *result = mStore.get(normalize_group(aGroup), aField);
		if (!result)
		{
			return false;
		}
		result->setJSON(aFieldData.getJSON());

		handle_notification(aGroup, aField);
		return true;
	}

	bool ouroboros_server::set(const std::string& , const group<var_field>& )
	{
		return false;
	}

	void ouroboros_server::run()
	{
		mg_poll_server(mpServer, 1000);
	}

	mg_result ouroboros_server::handle_rest(const rest_request& aRequest)
	{
		switch (aRequest.getRestRequestType())
		{
			case FIELDS:
				handle_name_rest(aRequest);
				break;

			case GROUPS:
				handle_group_rest(aRequest);
				break;

			case CALLBACK:
				handle_callback_rest(aRequest);
				break;

			case NONE:
				break;
			default:
				return MG_FALSE;
		}
		return MG_TRUE;
	}

	void ouroboros_server::handle_name_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields());

		std::string sjson;
		mg_connection *conn = aRequest.getConnection();
		if (named)
		{
			switch (aRequest.getHttpRequestType())
			{
				case PUT:
				{
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					if (named->setJSON(json))
					{
						handle_notification(aRequest.getGroups(), aRequest.getFields());
						sjson = detail::good_JSON();
					}
					else
					{
						sjson = detail::bad_JSON(conn);
					}
				}
					break;

				case GET:
					//Send JSON describing named item
					sjson = named->getJSON();
					break;

				default:
					sjson = detail::bad_JSON(conn);
			}
		}
		else
		{
			sjson = detail::bad_JSON(conn);
		}

		mg_send_data(conn, sjson.c_str(), sjson.length());
	}

	void ouroboros_server::handle_group_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		group<var_field> *pgroup = mStore.get(normalize_group(aRequest.getGroups()));

		std::string sjson;
		mg_connection *conn = aRequest.getConnection();
		if (pgroup)
		{
			switch (aRequest.getHttpRequestType())
			{
				case GET:
					//Send JSON describing named item
					sjson = pgroup->getJSON();
					break;

				default:
					sjson = detail::bad_JSON(conn);
			}
		}
		else
		{
			sjson = detail::bad_JSON(conn);
		}

		mg_send_data(conn, sjson.c_str(), sjson.length());
	}

	void ouroboros_server::handle_callback_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		std::string resource = normalize_group(aRequest.getGroups()) + '/' + aRequest.getFields();
		var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields());

		std::string response;
		mg_connection *conn = aRequest.getConnection();
		if (named)
		{
			switch (aRequest.getHttpRequestType())
			{
				case POST:
				{
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					std::string response_url = json.get("callback");

					//create callback

					//Due to a limitation of C++03, use a semi-global map
					//to track response URLs
					mResponseUrls[named] = response_url;
					std::string callback_id = register_callback(aRequest.getGroups(), aRequest.getFields(), establish_connection);

					std::stringstream ss;
					ss << "{ \"id\" : \"" << callback_id << "\" }";
					mg_send_status(aConn, 201);
					response = ss.str();
				}
					break;

				case DELETE:
				{
					//Send JSON describing named item
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					std::string id = json.get("id");
					unregister_callback(id);
					response = detail::good_JSON();
				}
					break;

				default:
					response = detail::bad_JSON(conn);
			}
		}
		else
		{
			response = detail::bad_JSON(conn);
		}

		mg_send_data(conn, response.c_str(), response.length());
	}

	void ouroboros_server::establish_connection(var_field* aResponse)
	{
		if (mpSendServer->mResponseUrls.count(aResponse))
		{
			std::string url = mpSendServer->mResponseUrls[aResponse];
			mg_connection *client;
			client = mg_connect(mpSendServer->mpServer, url.c_str());
			client->connection_param = aResponse;
		}
	}

	void ouroboros_server::send_response(mg_connection *aConn)
	{
		var_field *aResponse = reinterpret_cast<var_field*>(aConn->connection_param);
		if (mResponseUrls.count(aResponse))
		{
			std::string url = mResponseUrls[aResponse];

			size_t delim = url.find("://");
			if (delim != std::string::npos)
			{
				url = url.substr(delim + 3);
			}

			delim = url.find("/");

			std::string host = url.substr(0, delim);
			std::string res;
			if (delim != std::string::npos)
			{
				res = url.substr(delim);
			}
			else
			{
				res = "/";
			}

			mg_printf(aConn, "PUT %s HTTP/1.1\r\nHost: %s\r\n"
				"Content-Type: application/json\r\n\r\n%s",
				res.c_str(),
				host.c_str(),
				aResponse->getJSON().c_str());

		}
	}

	std::string ouroboros_server::normalize_group(const std::string& aGroup)
	{
		std::string result = "server";
		if(!aGroup.empty())
		{
			result += group_delimiter + aGroup;
		}

		return result;
	}

	void ouroboros_server::handle_notification(const std::string& aGroup, const std::string& aField)
	{
		std::string key(aGroup+'/'+aField);
		if (mCallbackSubjects.count(key))
		{
			mCallbackSubjects[key].notify();
		}
	}

	mg_result ouroboros_server::handle_uri(mg_connection *conn, const std::string& uri)
	{
		rest_request request(conn, uri);
		if (request.getRestRequestType() != NONE)
		{
			std::string output;

			return handle_rest(request);
		}
		return MG_FALSE;
	}

	int ouroboros_server::event_handler(mg_connection *conn, mg_event ev)
	{
		ouroboros_server *this_server = reinterpret_cast<ouroboros_server*>(conn->server_param);
		switch (ev)
		{
			case MG_AUTH:
				return MG_TRUE;
				break;

			case MG_REQUEST:
				return this_server->handle_uri(conn, conn->uri);
				break;
			case MG_CONNECT:
				this_server->send_response(conn);
				return MG_TRUE;
			default:
				return MG_FALSE;
		}
	}

	std::string ouroboros_server::register_callback(
		const std::string& aGroup,
		const std::string& aField,
		callback_function aCallback)
	{
		std::string result;
		var_field *named = mStore.get(normalize_group(aGroup), aField);
		if (named)
		{
			std::string key(aGroup + "/" + aField);
			result = mCallbackManager.register_callback(key);
			if (!mCallbackSubjects.count(key))
			{
				mCallbackSubjects[key] = subject<id_callback<var_field*, callback_function> >();
			}

			id_callback<var_field*, callback_function> cb(result, named, aCallback);
			mCallbackSubjects[key].registerObserver(cb);
		}
		return result;
	}

	void ouroboros_server::unregister_callback(const std::string& aID)
	{
		//TODO
	}

	const std::string ouroboros_server::group_delimiter(data_store<var_field>::group_delimiter);
	ouroboros_server *ouroboros_server::mpSendServer = NULL;
}

<commit_msg>Update ouroboros_server.cpp<commit_after>#include "ouroboros_server.h"
#include <server/data/data_store.hpp>
#include <server/device_tree.hpp>
#include <mongoose/mongoose.h>
#include <server/rest.h>
#include <sstream>
#include <cassert>
#include <slre/slre.h>

namespace ouroboros
{
	namespace detail
	{
		std::string bad_JSON(mg_connection* aConn)
		{
			mg_send_status(aConn, 400);
			return std::string("{ \"status\" : \"Bad JSON request.\"}");
		}

		std::string good_JSON()
		{
			return std::string("{ \"status\" : \"OK.\"}");
		}
	}

	std::string url_regex("(.+://)?(.+)");

	ouroboros_server::ouroboros_server()
	:mpServer(NULL),
		mStore(device_tree<var_field>::get_device_tree().get_data_store())
	{
		//The following line is a hack workaround to trying to avoid using
		//functional support in c++03
		if (!mpSendServer)
		{
			//HACK
			mpSendServer = this;
		}
		mpServer = mg_create_server(this, ouroboros_server::event_handler);
		mg_set_option(mpServer, "document_root", ".");      // Serve current directory
		mg_set_option(mpServer, "listening_port", "8080");  // Open port 8080
	}

	ouroboros_server::~ouroboros_server()
	{
		mg_destroy_server(&mpServer);
	}

	const var_field *ouroboros_server::get(const std::string& aGroup, const std::string& aField) const
	{
		return mStore.get(normalize_group(aGroup), aField);
	}

	var_field *ouroboros_server::get(const std::string& aGroup, const std::string& aField)
	{
		return const_cast<var_field *>(static_cast<const ouroboros_server&>(*this).get(aGroup, aField));
	}

	const group<var_field> *ouroboros_server::get(const std::string& aGroup) const
	{
		return mStore.get(normalize_group(aGroup));
	}

	group<var_field> *ouroboros_server::get(const std::string& aGroup)
	{
		return const_cast<group<var_field> *>(static_cast<const ouroboros_server&>(*this).get(aGroup));
	}

	bool ouroboros_server::set(const std::string& aGroup, const std::string& aField, const var_field& aFieldData)
	{
		var_field *result = mStore.get(normalize_group(aGroup), aField);
		if (!result)
		{
			return false;
		}
		result->setJSON(aFieldData.getJSON());

		handle_notification(aGroup, aField);
		return true;
	}

	bool ouroboros_server::set(const std::string& , const group<var_field>& )
	{
		return false;
	}

	void ouroboros_server::run()
	{
		mg_poll_server(mpServer, 1000);
	}

	mg_result ouroboros_server::handle_rest(const rest_request& aRequest)
	{
		switch (aRequest.getRestRequestType())
		{
			case FIELDS:
				handle_name_rest(aRequest);
				break;

			case GROUPS:
				handle_group_rest(aRequest);
				break;

			case CALLBACK:
				handle_callback_rest(aRequest);
				break;

			case NONE:
				break;
			default:
				return MG_FALSE;
		}
		return MG_TRUE;
	}

	void ouroboros_server::handle_name_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields());

		std::string sjson;
		mg_connection *conn = aRequest.getConnection();
		if (named)
		{
			switch (aRequest.getHttpRequestType())
			{
				case PUT:
				{
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					if (named->setJSON(json))
					{
						handle_notification(aRequest.getGroups(), aRequest.getFields());
						sjson = detail::good_JSON();
					}
					else
					{
						sjson = detail::bad_JSON(conn);
					}
				}
					break;

				case GET:
					//Send JSON describing named item
					sjson = named->getJSON();
					break;

				default:
					sjson = detail::bad_JSON(conn);
			}
		}
		else
		{
			sjson = detail::bad_JSON(conn);
		}

		mg_send_data(conn, sjson.c_str(), sjson.length());
	}

	void ouroboros_server::handle_group_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		group<var_field> *pgroup = mStore.get(normalize_group(aRequest.getGroups()));

		std::string sjson;
		mg_connection *conn = aRequest.getConnection();
		if (pgroup)
		{
			switch (aRequest.getHttpRequestType())
			{
				case GET:
					//Send JSON describing named item
					sjson = pgroup->getJSON();
					break;

				default:
					sjson = detail::bad_JSON(conn);
			}
		}
		else
		{
			sjson = detail::bad_JSON(conn);
		}

		mg_send_data(conn, sjson.c_str(), sjson.length());
	}

	void ouroboros_server::handle_callback_rest(const rest_request& aRequest)
	{
		//get reference to named thing
		std::string resource = normalize_group(aRequest.getGroups()) + '/' + aRequest.getFields();
		var_field *named = mStore.get(normalize_group(aRequest.getGroups()), aRequest.getFields());

		std::string response;
		mg_connection *conn = aRequest.getConnection();
		if (named)
		{
			switch (aRequest.getHttpRequestType())
			{
				case POST:
				{
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					std::string response_url = json.get("callback");

					//create callback

					//Due to a limitation of C++03, use a semi-global map
					//to track response URLs
					mResponseUrls[named] = response_url;
					std::string callback_id = register_callback(aRequest.getGroups(), aRequest.getFields(), establish_connection);

					std::stringstream ss;
					ss << "{ \"id\" : \"" << callback_id << "\" }";
					mg_send_status(conn, 201);
					response = ss.str();
				}
					break;

				case DELETE:
				{
					//Send JSON describing named item
					std::string data(conn->content, conn->content_len);
					JSON json(data);

					std::string id = json.get("id");
					unregister_callback(id);
					response = detail::good_JSON();
				}
					break;

				default:
					response = detail::bad_JSON(conn);
			}
		}
		else
		{
			response = detail::bad_JSON(conn);
		}

		mg_send_data(conn, response.c_str(), response.length());
	}

	void ouroboros_server::establish_connection(var_field* aResponse)
	{
		if (mpSendServer->mResponseUrls.count(aResponse))
		{
			std::string url = mpSendServer->mResponseUrls[aResponse];
			mg_connection *client;
			client = mg_connect(mpSendServer->mpServer, url.c_str());
			client->connection_param = aResponse;
		}
	}

	void ouroboros_server::send_response(mg_connection *aConn)
	{
		var_field *aResponse = reinterpret_cast<var_field*>(aConn->connection_param);
		if (mResponseUrls.count(aResponse))
		{
			std::string url = mResponseUrls[aResponse];

			size_t delim = url.find("://");
			if (delim != std::string::npos)
			{
				url = url.substr(delim + 3);
			}

			delim = url.find("/");

			std::string host = url.substr(0, delim);
			std::string res;
			if (delim != std::string::npos)
			{
				res = url.substr(delim);
			}
			else
			{
				res = "/";
			}

			mg_printf(aConn, "PUT %s HTTP/1.1\r\nHost: %s\r\n"
				"Content-Type: application/json\r\n\r\n%s",
				res.c_str(),
				host.c_str(),
				aResponse->getJSON().c_str());

		}
	}

	std::string ouroboros_server::normalize_group(const std::string& aGroup)
	{
		std::string result = "server";
		if(!aGroup.empty())
		{
			result += group_delimiter + aGroup;
		}

		return result;
	}

	void ouroboros_server::handle_notification(const std::string& aGroup, const std::string& aField)
	{
		std::string key(aGroup+'/'+aField);
		if (mCallbackSubjects.count(key))
		{
			mCallbackSubjects[key].notify();
		}
	}

	mg_result ouroboros_server::handle_uri(mg_connection *conn, const std::string& uri)
	{
		rest_request request(conn, uri);
		if (request.getRestRequestType() != NONE)
		{
			std::string output;

			return handle_rest(request);
		}
		return MG_FALSE;
	}

	int ouroboros_server::event_handler(mg_connection *conn, mg_event ev)
	{
		ouroboros_server *this_server = reinterpret_cast<ouroboros_server*>(conn->server_param);
		switch (ev)
		{
			case MG_AUTH:
				return MG_TRUE;
				break;

			case MG_REQUEST:
				return this_server->handle_uri(conn, conn->uri);
				break;
			case MG_CONNECT:
				this_server->send_response(conn);
				return MG_TRUE;
			default:
				return MG_FALSE;
		}
	}

	std::string ouroboros_server::register_callback(
		const std::string& aGroup,
		const std::string& aField,
		callback_function aCallback)
	{
		std::string result;
		var_field *named = mStore.get(normalize_group(aGroup), aField);
		if (named)
		{
			std::string key(aGroup + "/" + aField);
			result = mCallbackManager.register_callback(key);
			if (!mCallbackSubjects.count(key))
			{
				mCallbackSubjects[key] = subject<id_callback<var_field*, callback_function> >();
			}

			id_callback<var_field*, callback_function> cb(result, named, aCallback);
			mCallbackSubjects[key].registerObserver(cb);
		}
		return result;
	}

	void ouroboros_server::unregister_callback(const std::string& aID)
	{
		//TODO
	}

	const std::string ouroboros_server::group_delimiter(data_store<var_field>::group_delimiter);
	ouroboros_server *ouroboros_server::mpSendServer = NULL;
}

<|endoftext|>


<commit_before>//===- MapFile.cpp --------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the -Map option. It shows lists in order and
// hierarchically the output sections, input sections, input files and
// symbol:
//
//   Address  Size     Align Out     In      Symbol
//   00201000 00000015     4 .text
//   00201000 0000000e     4         test.o:(.text)
//   0020100e 00000000     0                 local
//   00201005 00000000     0                 f(int)
//
//===----------------------------------------------------------------------===//

#include "MapFile.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "Strings.h"
#include "SymbolTable.h"
#include "SyntheticSections.h"
#include "lld/Common/Threads.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;

using namespace lld;
using namespace lld::elf;

typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy;

// Print out the first three columns of a line.
static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
                        uint64_t Align) {
  int W = Config->Is64 ? 16 : 8;
  OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align);
}

static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }

// Returns a list of all symbols that we want to print out.
static std::vector<Defined *> getSymbols() {
  std::vector<Defined *> V;
  for (InputFile *File : ObjectFiles)
    for (Symbol *B : File->getSymbols())
      if (auto *DR = dyn_cast<Defined>(B))
        if (DR->getFile() == File && !DR->isSection() && DR->Section &&
            DR->Section->Live)
          V.push_back(DR);
  return V;
}

// Returns a map from sections to their symbols.
static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
  SymbolMapTy Ret;
  for (Defined *S : Syms)
    if (auto *DR = dyn_cast<Defined>(S))
      Ret[DR->Section].push_back(S);

  // Sort symbols by address. We want to print out symbols in the
  // order in the output file rather than the order they appeared
  // in the input files.
  for (auto &It : Ret) {
    SmallVectorImpl<Defined *> &V = It.second;
    std::sort(V.begin(), V.end(),
              [](Defined *A, Defined *B) { return A->getVA() < B->getVA(); });
  }
  return Ret;
}

// Construct a map from symbols to their stringified representations.
// Demangling symbols (which is what toString() does) is slow, so
// we do that in batch using parallel-for.
static DenseMap<Defined *, std::string>
getSymbolStrings(ArrayRef<Defined *> Syms) {
  std::vector<std::string> Str(Syms.size());
  parallelForEachN(0, Syms.size(), [&](size_t I) {
    raw_string_ostream OS(Str[I]);
    writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0);
    OS << indent(2) << toString(*Syms[I]);
  });

  DenseMap<Defined *, std::string> Ret;
  for (size_t I = 0, E = Syms.size(); I < E; ++I)
    Ret[Syms[I]] = std::move(Str[I]);
  return Ret;
}

void elf::writeMapFile() {
  if (Config->MapFile.empty())
    return;

  // Open a map file for writing.
  std::error_code EC;
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
  if (EC) {
    error("cannot open " + Config->MapFile + ": " + EC.message());
    return;
  }

  // Collect symbol info that we want to print out.
  std::vector<Defined *> Syms = getSymbols();
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings(Syms);

  // Print out the header line.
  int W = Config->Is64 ? 16 : 8;
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
     << " Align Out     In      Symbol\n";

  // Print out file contents.
  for (OutputSection *OSec : OutputSections) {
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
    OS << OSec->Name << '\n';

    // Dump symbols for each input section.
    for (BaseCommand *Base : OSec->SectionCommands) {
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
      if (!ISD)
        continue;
      for (InputSection *IS : ISD->Sections) {
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
                    IS->Alignment);
        OS << indent(1) << toString(IS) << '\n';
        for (Defined *Sym : SectionSyms[IS])
          OS << SymStr[Sym] << '\n';
      }
    }
  }
}
<commit_msg>Simplify. NFC.<commit_after>//===- MapFile.cpp --------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the -Map option. It shows lists in order and
// hierarchically the output sections, input sections, input files and
// symbol:
//
//   Address  Size     Align Out     In      Symbol
//   00201000 00000015     4 .text
//   00201000 0000000e     4         test.o:(.text)
//   0020100e 00000000     0                 local
//   00201005 00000000     0                 f(int)
//
//===----------------------------------------------------------------------===//

#include "MapFile.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "OutputSections.h"
#include "Strings.h"
#include "SymbolTable.h"
#include "SyntheticSections.h"
#include "lld/Common/Threads.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace llvm::object;

using namespace lld;
using namespace lld::elf;

typedef DenseMap<const SectionBase *, SmallVector<Defined *, 4>> SymbolMapTy;

// Print out the first three columns of a line.
static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
                        uint64_t Align) {
  int W = Config->Is64 ? 16 : 8;
  OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align);
}

static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }

// Returns a list of all symbols that we want to print out.
static std::vector<Defined *> getSymbols() {
  std::vector<Defined *> V;
  for (InputFile *File : ObjectFiles)
    for (Symbol *B : File->getSymbols())
      if (auto *DR = dyn_cast<Defined>(B))
        if (DR->getFile() == File && !DR->isSection() && DR->Section &&
            DR->Section->Live)
          V.push_back(DR);
  return V;
}

// Returns a map from sections to their symbols.
static SymbolMapTy getSectionSyms(ArrayRef<Defined *> Syms) {
  SymbolMapTy Ret;
  for (Defined *S : Syms)
    Ret[S->Section].push_back(S);

  // Sort symbols by address. We want to print out symbols in the
  // order in the output file rather than the order they appeared
  // in the input files.
  for (auto &It : Ret) {
    SmallVectorImpl<Defined *> &V = It.second;
    std::sort(V.begin(), V.end(),
              [](Defined *A, Defined *B) { return A->getVA() < B->getVA(); });
  }
  return Ret;
}

// Construct a map from symbols to their stringified representations.
// Demangling symbols (which is what toString() does) is slow, so
// we do that in batch using parallel-for.
static DenseMap<Defined *, std::string>
getSymbolStrings(ArrayRef<Defined *> Syms) {
  std::vector<std::string> Str(Syms.size());
  parallelForEachN(0, Syms.size(), [&](size_t I) {
    raw_string_ostream OS(Str[I]);
    writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0);
    OS << indent(2) << toString(*Syms[I]);
  });

  DenseMap<Defined *, std::string> Ret;
  for (size_t I = 0, E = Syms.size(); I < E; ++I)
    Ret[Syms[I]] = std::move(Str[I]);
  return Ret;
}

void elf::writeMapFile() {
  if (Config->MapFile.empty())
    return;

  // Open a map file for writing.
  std::error_code EC;
  raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
  if (EC) {
    error("cannot open " + Config->MapFile + ": " + EC.message());
    return;
  }

  // Collect symbol info that we want to print out.
  std::vector<Defined *> Syms = getSymbols();
  SymbolMapTy SectionSyms = getSectionSyms(Syms);
  DenseMap<Defined *, std::string> SymStr = getSymbolStrings(Syms);

  // Print out the header line.
  int W = Config->Is64 ? 16 : 8;
  OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
     << " Align Out     In      Symbol\n";

  // Print out file contents.
  for (OutputSection *OSec : OutputSections) {
    writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment);
    OS << OSec->Name << '\n';

    // Dump symbols for each input section.
    for (BaseCommand *Base : OSec->SectionCommands) {
      auto *ISD = dyn_cast<InputSectionDescription>(Base);
      if (!ISD)
        continue;
      for (InputSection *IS : ISD->Sections) {
        writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
                    IS->Alignment);
        OS << indent(1) << toString(IS) << '\n';
        for (Defined *Sym : SectionSyms[IS])
          OS << SymStr[Sym] << '\n';
      }
    }
  }
}
<|endoftext|>


<commit_before>/*  cbr
 *  main.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Timer.hpp"
#include "TimeSync.hpp"
#include "TimeProfiler.hpp"

#include "Network.hpp"

#include "Forwarder.hpp"

#include "LocationService.hpp"

#include "Proximity.hpp"
#include "Server.hpp"

#include "Options.hpp"
#include "Statistics.hpp"
#include "StandardLocationService.hpp"
#include "Test.hpp"
#include "SSTNetwork.hpp"
#include "TCPNetwork.hpp"
#include "FIFOServerMessageQueue.hpp"
#include "FairServerMessageQueue.hpp"
#include "TabularServerIDMap.hpp"
#include "ExpIntegral.hpp"
#include "SqrIntegral.hpp"
#include "UniformCoordinateSegmentation.hpp"
#include "CoordinateSegmentationClient.hpp"
#include "LoadMonitor.hpp"
#include "CraqObjectSegmentation.hpp"

#include "ServerWeightCalculator.hpp"
#include "SpaceContext.hpp"

namespace {
CBR::Network* gNetwork = NULL;
CBR::Trace* gTrace = NULL;
CBR::SpaceContext* gSpaceContext = NULL;
CBR::Time g_start_time( CBR::Time::null() );
}

void *main_loop(void *);

int main(int argc, char** argv) {

    using namespace CBR;

    InitOptions();
    ParseOptions(argc, argv);

    std::string time_server=GetOption("time-server")->as<String>();
    TimeSync sync;

    sync.start(time_server);

    ServerID server_id = GetOption("id")->as<ServerID>();
    String trace_file = GetPerServerFile(STATS_TRACE_FILE, server_id);
    gTrace = new Trace(trace_file);

    // Compute the starting date/time
    String start_time_str = GetOption("wait-until")->as<String>();
    g_start_time = start_time_str.empty() ? Timer::now() : Timer::getSpecifiedDate( start_time_str );
    Time start_time = g_start_time;
    start_time += GetOption("wait-additional")->as<Duration>();

    Duration duration = GetOption("duration")->as<Duration>();

    IOService* ios = IOServiceFactory::makeIOService();
    IOStrand* mainStrand = ios->createStrand();

    Time init_space_ctx_time = Time::null() + (Timer::now() - start_time);

    SpaceContext* space_context = new SpaceContext(server_id, ios, mainStrand, start_time, init_space_ctx_time, gTrace, duration);

    gSpaceContext = space_context;

    String network_type = GetOption(NETWORK_TYPE)->as<String>();
    if (network_type == "sst")
        gNetwork = new SSTNetwork(space_context);
    else if (network_type == "tcp")
      gNetwork = new TCPNetwork(space_context,GetOption("space-to-space-receive-buffer")->as<size_t>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>(),GetOption(SEND_BANDWIDTH)->as<uint32>());

    gNetwork->init(&main_loop);

    sync.stop();

    return 0;
}
void *main_loop(void *) {
    using namespace CBR;

    ServerID server_id = GetOption("id")->as<ServerID>();

    String test_mode = GetOption("test")->as<String>();
    if (test_mode != "none") {
        String server_port = GetOption("server-port")->as<String>();
        String client_port = GetOption("client-port")->as<String>();
        String host = GetOption("host")->as<String>();
        if (test_mode == "server")
            CBR::testServer(server_port.c_str(), host.c_str(), client_port.c_str());
        else if (test_mode == "client")
            CBR::testClient(client_port.c_str(), host.c_str(), server_port.c_str());
        return 0;
    }

    BoundingBox3f region = GetOption("region")->as<BoundingBox3f>();
    Vector3ui32 layout = GetOption("layout")->as<Vector3ui32>();

    uint32 max_space_servers = GetOption("max-servers")->as<uint32>();
    if (max_space_servers == 0)
      max_space_servers = layout.x * layout.y * layout.z;
    uint32 num_oh_servers = GetOption("num-oh")->as<uint32>();
    uint32 nservers = max_space_servers + num_oh_servers;

    Duration duration = GetOption("duration")->as<Duration>();

    srand( GetOption("rand-seed")->as<uint32>() );

    SpaceContext* space_context = gSpaceContext;
    Forwarder* forwarder = new Forwarder(space_context);

    LocationService* loc_service = NULL;
    String loc_service_type = GetOption(LOC)->as<String>();
    if (loc_service_type == "standard")
        loc_service = new StandardLocationService(space_context);
    else
        assert(false);

    String filehandle = GetOption("serverips")->as<String>();
    std::ifstream ipConfigFileHandle(filehandle.c_str());
    ServerIDMap * server_id_map = new TabularServerIDMap(ipConfigFileHandle);
    gTrace->setServerIDMap(server_id_map);
    gNetwork->setServerIDMap(server_id_map);

    ServerMessageQueue* sq = NULL;
    String server_queue_type = GetOption(SERVER_QUEUE)->as<String>();
    if (server_queue_type == "fifo")
        sq = new FIFOServerMessageQueue(space_context, gNetwork, server_id_map, GetOption(SEND_BANDWIDTH)->as<uint32>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>());
    else if (server_queue_type == "fair")
        sq = new FairServerMessageQueue(space_context, gNetwork, server_id_map, GetOption(SEND_BANDWIDTH)->as<uint32>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>());
    else {
        assert(false);
        exit(-1);
    }

    String cseg_type = GetOption(CSEG)->as<String>();
    CoordinateSegmentation* cseg = NULL;
    if (cseg_type == "uniform")
        cseg = new UniformCoordinateSegmentation(space_context, region, layout);
    else if (cseg_type == "client") {
      cseg = new CoordinateSegmentationClient(space_context, region, layout, server_id_map);
    }
    else {
        assert(false);
        exit(-1);
    }

    LoadMonitor* loadMonitor = new LoadMonitor(space_context, sq, cseg);

    //Create OSeg
    std::string oseg_type=GetOption(OSEG)->as<String>();
    IOStrand* osegStrand = space_context->ioService->createStrand();
    ObjectSegmentation* oseg = NULL;
    if (oseg_type == OSEG_OPTION_CRAQ)
    {
      //using craq approach
      std::vector<UUID> initServObjVec;

      std::vector<CraqInitializeArgs> craqArgsGet;
      CraqInitializeArgs cInitArgs1;

      cInitArgs1.ipAdd = "localhost";
      cInitArgs1.port  =     "10298";
      craqArgsGet.push_back(cInitArgs1);

      std::vector<CraqInitializeArgs> craqArgsSet;
      CraqInitializeArgs cInitArgs2;
      cInitArgs2.ipAdd = "localhost";
      cInitArgs2.port  =     "10299";
      craqArgsSet.push_back(cInitArgs2);

      std::string oseg_craq_prefix=GetOption(OSEG_UNIQUE_CRAQ_PREFIX)->as<String>();

      if (oseg_type.size() ==0)
      {
        std::cout<<"\n\nERROR: Incorrect craq prefix for oseg.  String must be at least one letter long.  (And be between G and Z.)  Please try again.\n\n";
        assert(false);
      }

      std::cout<<"\n\nUniquely appending  "<<oseg_craq_prefix[0]<<"\n\n";
      oseg = new CraqObjectSegmentation (space_context, cseg, initServObjVec, craqArgsGet, craqArgsSet, oseg_craq_prefix[0],osegStrand,space_context->mainStrand);

    }      //end craq approach

    //end create oseg

    ServerWeightCalculator* weight_calc = NULL;
    if (GetOption("gaussian")->as<bool>()) {
        weight_calc =
            new ServerWeightCalculator(
                server_id,
                cseg,

                std::tr1::bind(&integralExpFunction,GetOption("flatness")->as<double>(),
                    std::tr1::placeholders::_1,
                    std::tr1::placeholders::_2,
                    std::tr1::placeholders::_3,
                    std::tr1::placeholders::_4),
                sq
            );
    }else {
        weight_calc =
            new ServerWeightCalculator(
                server_id,
                cseg,
                std::tr1::bind(SqrIntegral(false),GetOption("const-cutoff")->as<double>(),GetOption("flatness")->as<double>(),
                    std::tr1::placeholders::_1,
                    std::tr1::placeholders::_2,
                    std::tr1::placeholders::_3,
                    std::tr1::placeholders::_4),
                sq);
    }

    // We have all the info to initialize the forwarder now
    forwarder->initialize(oseg, sq);

    Proximity* prox = new Proximity(space_context, loc_service);

    Server* server = new Server(space_context, forwarder, loc_service, cseg, prox, oseg, server_id_map->lookupExternal(space_context->id()));

      prox->initialize(cseg);

      Time start_time = g_start_time;
    // If we're one of the initial nodes, we'll have to wait until we hit the start time
    {
        Time now_time = Timer::now();
        if (start_time > now_time) {
            Duration sleep_time = start_time - now_time;
            printf("Waiting %f seconds\n", sleep_time.toSeconds() ); fflush(stdout);
            usleep( sleep_time.toMicroseconds() );
        }
    }

    ///////////Go go go!! start of simulation/////////////////////

    gNetwork->begin();

    space_context->add(space_context);
    space_context->add(gNetwork);
    space_context->add(cseg);
    space_context->add(loc_service);
    space_context->add(prox);
    space_context->add(server);
    space_context->add(oseg);
    space_context->add(forwarder);
    space_context->add(loadMonitor);

    space_context->run(2);

    if (GetOption(PROFILE)->as<bool>()) {
        space_context->profiler->report();
    }

    gTrace->prepareShutdown();

    prox->shutdown();

    delete server;
    delete sq;
    delete prox;
    delete server_id_map;
    if (weight_calc != NULL)
      delete weight_calc;
    delete cseg;
    delete oseg;

    delete loc_service;
    delete forwarder;

    delete gNetwork;
    gNetwork=NULL;

    gTrace->shutdown();
    delete gTrace;
    gTrace = NULL;

    IOStrand* mainStrand = space_context->mainStrand;
    IOService* ios = space_context->ioService;

    delete osegStrand;

    delete space_context;
    space_context = NULL;

    delete mainStrand;
    delete osegStrand;

    IOServiceFactory::destroyIOService(ios);

    return 0;
}
<commit_msg>Oooops.  Deleting somethign twice.<commit_after>/*  cbr
 *  main.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of cbr nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "Timer.hpp"
#include "TimeSync.hpp"
#include "TimeProfiler.hpp"

#include "Network.hpp"

#include "Forwarder.hpp"

#include "LocationService.hpp"

#include "Proximity.hpp"
#include "Server.hpp"

#include "Options.hpp"
#include "Statistics.hpp"
#include "StandardLocationService.hpp"
#include "Test.hpp"
#include "SSTNetwork.hpp"
#include "TCPNetwork.hpp"
#include "FIFOServerMessageQueue.hpp"
#include "FairServerMessageQueue.hpp"
#include "TabularServerIDMap.hpp"
#include "ExpIntegral.hpp"
#include "SqrIntegral.hpp"
#include "UniformCoordinateSegmentation.hpp"
#include "CoordinateSegmentationClient.hpp"
#include "LoadMonitor.hpp"
#include "CraqObjectSegmentation.hpp"

#include "ServerWeightCalculator.hpp"
#include "SpaceContext.hpp"

namespace {
CBR::Network* gNetwork = NULL;
CBR::Trace* gTrace = NULL;
CBR::SpaceContext* gSpaceContext = NULL;
CBR::Time g_start_time( CBR::Time::null() );
}

void *main_loop(void *);

int main(int argc, char** argv) {

    using namespace CBR;

    InitOptions();
    ParseOptions(argc, argv);

    std::string time_server=GetOption("time-server")->as<String>();
    TimeSync sync;

    sync.start(time_server);

    ServerID server_id = GetOption("id")->as<ServerID>();
    String trace_file = GetPerServerFile(STATS_TRACE_FILE, server_id);
    gTrace = new Trace(trace_file);

    // Compute the starting date/time
    String start_time_str = GetOption("wait-until")->as<String>();
    g_start_time = start_time_str.empty() ? Timer::now() : Timer::getSpecifiedDate( start_time_str );
    Time start_time = g_start_time;
    start_time += GetOption("wait-additional")->as<Duration>();

    Duration duration = GetOption("duration")->as<Duration>();

    IOService* ios = IOServiceFactory::makeIOService();
    IOStrand* mainStrand = ios->createStrand();

    Time init_space_ctx_time = Time::null() + (Timer::now() - start_time);

    SpaceContext* space_context = new SpaceContext(server_id, ios, mainStrand, start_time, init_space_ctx_time, gTrace, duration);

    gSpaceContext = space_context;

    String network_type = GetOption(NETWORK_TYPE)->as<String>();
    if (network_type == "sst")
        gNetwork = new SSTNetwork(space_context);
    else if (network_type == "tcp")
      gNetwork = new TCPNetwork(space_context,GetOption("space-to-space-receive-buffer")->as<size_t>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>(),GetOption(SEND_BANDWIDTH)->as<uint32>());

    gNetwork->init(&main_loop);

    sync.stop();

    return 0;
}
void *main_loop(void *) {
    using namespace CBR;

    ServerID server_id = GetOption("id")->as<ServerID>();

    String test_mode = GetOption("test")->as<String>();
    if (test_mode != "none") {
        String server_port = GetOption("server-port")->as<String>();
        String client_port = GetOption("client-port")->as<String>();
        String host = GetOption("host")->as<String>();
        if (test_mode == "server")
            CBR::testServer(server_port.c_str(), host.c_str(), client_port.c_str());
        else if (test_mode == "client")
            CBR::testClient(client_port.c_str(), host.c_str(), server_port.c_str());
        return 0;
    }

    BoundingBox3f region = GetOption("region")->as<BoundingBox3f>();
    Vector3ui32 layout = GetOption("layout")->as<Vector3ui32>();

    uint32 max_space_servers = GetOption("max-servers")->as<uint32>();
    if (max_space_servers == 0)
      max_space_servers = layout.x * layout.y * layout.z;
    uint32 num_oh_servers = GetOption("num-oh")->as<uint32>();
    uint32 nservers = max_space_servers + num_oh_servers;

    Duration duration = GetOption("duration")->as<Duration>();

    srand( GetOption("rand-seed")->as<uint32>() );

    SpaceContext* space_context = gSpaceContext;
    Forwarder* forwarder = new Forwarder(space_context);

    LocationService* loc_service = NULL;
    String loc_service_type = GetOption(LOC)->as<String>();
    if (loc_service_type == "standard")
        loc_service = new StandardLocationService(space_context);
    else
        assert(false);

    String filehandle = GetOption("serverips")->as<String>();
    std::ifstream ipConfigFileHandle(filehandle.c_str());
    ServerIDMap * server_id_map = new TabularServerIDMap(ipConfigFileHandle);
    gTrace->setServerIDMap(server_id_map);
    gNetwork->setServerIDMap(server_id_map);

    ServerMessageQueue* sq = NULL;
    String server_queue_type = GetOption(SERVER_QUEUE)->as<String>();
    if (server_queue_type == "fifo")
        sq = new FIFOServerMessageQueue(space_context, gNetwork, server_id_map, GetOption(SEND_BANDWIDTH)->as<uint32>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>());
    else if (server_queue_type == "fair")
        sq = new FairServerMessageQueue(space_context, gNetwork, server_id_map, GetOption(SEND_BANDWIDTH)->as<uint32>(),GetOption(RECEIVE_BANDWIDTH)->as<uint32>());
    else {
        assert(false);
        exit(-1);
    }

    String cseg_type = GetOption(CSEG)->as<String>();
    CoordinateSegmentation* cseg = NULL;
    if (cseg_type == "uniform")
        cseg = new UniformCoordinateSegmentation(space_context, region, layout);
    else if (cseg_type == "client") {
      cseg = new CoordinateSegmentationClient(space_context, region, layout, server_id_map);
    }
    else {
        assert(false);
        exit(-1);
    }

    LoadMonitor* loadMonitor = new LoadMonitor(space_context, sq, cseg);

    //Create OSeg
    std::string oseg_type=GetOption(OSEG)->as<String>();
    IOStrand* osegStrand = space_context->ioService->createStrand();
    ObjectSegmentation* oseg = NULL;
    if (oseg_type == OSEG_OPTION_CRAQ)
    {
      //using craq approach
      std::vector<UUID> initServObjVec;

      std::vector<CraqInitializeArgs> craqArgsGet;
      CraqInitializeArgs cInitArgs1;

      cInitArgs1.ipAdd = "localhost";
      cInitArgs1.port  =     "10298";
      craqArgsGet.push_back(cInitArgs1);

      std::vector<CraqInitializeArgs> craqArgsSet;
      CraqInitializeArgs cInitArgs2;
      cInitArgs2.ipAdd = "localhost";
      cInitArgs2.port  =     "10299";
      craqArgsSet.push_back(cInitArgs2);

      std::string oseg_craq_prefix=GetOption(OSEG_UNIQUE_CRAQ_PREFIX)->as<String>();

      if (oseg_type.size() ==0)
      {
        std::cout<<"\n\nERROR: Incorrect craq prefix for oseg.  String must be at least one letter long.  (And be between G and Z.)  Please try again.\n\n";
        assert(false);
      }

      std::cout<<"\n\nUniquely appending  "<<oseg_craq_prefix[0]<<"\n\n";
      oseg = new CraqObjectSegmentation (space_context, cseg, initServObjVec, craqArgsGet, craqArgsSet, oseg_craq_prefix[0],osegStrand,space_context->mainStrand);

    }      //end craq approach

    //end create oseg

    ServerWeightCalculator* weight_calc = NULL;
    if (GetOption("gaussian")->as<bool>()) {
        weight_calc =
            new ServerWeightCalculator(
                server_id,
                cseg,

                std::tr1::bind(&integralExpFunction,GetOption("flatness")->as<double>(),
                    std::tr1::placeholders::_1,
                    std::tr1::placeholders::_2,
                    std::tr1::placeholders::_3,
                    std::tr1::placeholders::_4),
                sq
            );
    }else {
        weight_calc =
            new ServerWeightCalculator(
                server_id,
                cseg,
                std::tr1::bind(SqrIntegral(false),GetOption("const-cutoff")->as<double>(),GetOption("flatness")->as<double>(),
                    std::tr1::placeholders::_1,
                    std::tr1::placeholders::_2,
                    std::tr1::placeholders::_3,
                    std::tr1::placeholders::_4),
                sq);
    }

    // We have all the info to initialize the forwarder now
    forwarder->initialize(oseg, sq);

    Proximity* prox = new Proximity(space_context, loc_service);

    Server* server = new Server(space_context, forwarder, loc_service, cseg, prox, oseg, server_id_map->lookupExternal(space_context->id()));

      prox->initialize(cseg);

      Time start_time = g_start_time;
    // If we're one of the initial nodes, we'll have to wait until we hit the start time
    {
        Time now_time = Timer::now();
        if (start_time > now_time) {
            Duration sleep_time = start_time - now_time;
            printf("Waiting %f seconds\n", sleep_time.toSeconds() ); fflush(stdout);
            usleep( sleep_time.toMicroseconds() );
        }
    }

    ///////////Go go go!! start of simulation/////////////////////

    gNetwork->begin();

    space_context->add(space_context);
    space_context->add(gNetwork);
    space_context->add(cseg);
    space_context->add(loc_service);
    space_context->add(prox);
    space_context->add(server);
    space_context->add(oseg);
    space_context->add(forwarder);
    space_context->add(loadMonitor);

    space_context->run(2);

    if (GetOption(PROFILE)->as<bool>()) {
        space_context->profiler->report();
    }

    gTrace->prepareShutdown();

    prox->shutdown();

    delete server;
    delete sq;
    delete prox;
    delete server_id_map;
    if (weight_calc != NULL)
      delete weight_calc;
    delete cseg;
    delete oseg;

    delete loc_service;
    delete forwarder;

    delete gNetwork;
    gNetwork=NULL;

    gTrace->shutdown();
    delete gTrace;
    gTrace = NULL;

    IOStrand* mainStrand = space_context->mainStrand;
    IOService* ios = space_context->ioService;

    delete space_context;
    space_context = NULL;

    delete mainStrand;
    delete osegStrand;

    IOServiceFactory::destroyIOService(ios);

    return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"

// #define INOTIFY_THREAD_SAFE
#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

static CUBE_STATE_T _state, *state=&_state;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            state->shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            state->shader.build(fragSource,vertSource);
            *fragHasChanged = false;
            std::cout << "Parent: reloading shader" << std::endl;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    state->shader.use();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

void drawThread() {
    while (1) {
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
}

void watchThread(const std::string& file) {
    Inotify notify;

    InotifyWatch watch(file, IN_MODIFY);//IN_ALL_EVENTS);
    notify.Add(watch);

    for (;;) {

        if(!(*fragHasChanged)){
            std::cout << "Child: Watching again" << std::endl;
            notify.WaitForEvents();

            size_t count = notify.GetEventCount();
            while(count-- > 0) {
                InotifyEvent event;
                bool got_event = notify.GetEvent(&event);

                if(got_event){
                    std::string mask_str;
                    event.DumpTypes(mask_str);
                    *fragHasChanged = true;
                    std::cout << "Child: Something have change " << mask_str << std::endl;
                }
            }
        }

    }
}

void init(const std::string& fragFile) {
    GLfloat cx, cy;
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){

    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);

    pid_t pid = fork();

    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            init(fragFile);
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);

    return 0;
}

<commit_msg>watching folder<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"

#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

static CUBE_STATE_T _state, *state=&_state;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            state->shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            state->shader.build(fragSource,vertSource);
            *fragHasChanged = false;
            std::cout << "Parent: reloading shader" << std::endl;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    state->shader.use();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

void drawThread() {
    while (1) {
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
}

void watchThread(const std::string& _file) {
    Inotify notify;

    InotifyWatch watch(".", IN_MODIFY);//IN_ALL_EVENTS);
    notify.Add(watch);

    for (;;) {

        if(!(*fragHasChanged)){
            notify.WaitForEvents();

            size_t count = notify.GetEventCount();
            while(count-- > 0) {
                InotifyEvent event;
                bool got_event = notify.GetEvent(&event);

                if(got_event){
                    std::string mask_str;
                    event.DumpTypes(mask_str);
                    std::string filename = event.GetName();
                    std::cout << "Child: " << filename << " have change " << mask_str << std::endl;
                    if (filename == _file){
                        *fragHasChanged = true;
                    }
                }
            }
        }
    }
}

void init(const std::string& fragFile) {
    GLfloat cx, cy;
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){

    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);

    pid_t pid = fork();

    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            init(fragFile);
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);

    return 0;
}

<|endoftext|>


<commit_before>#pragma once

#include "macro.hpp"

#include <utility>

namespace bh
{

namespace impl
{

template<typename ... T> class ScopeFuncImpl;
template<> class ScopeFuncImpl<> {};
template<typename First_T, typename ... Rest_T>
class ScopeFuncImpl<First_T, Rest_T...>
    : private ScopeFuncImpl<Rest_T...>
{
private:
    using BaseType = ScopeFuncImpl<Rest_T...>;

    First_T m_Functor;

public:
    ScopeFuncImpl(First_T && p_Functor, Rest_T && ... p_Functors)
        : BaseType(std::forward<Rest_T>(p_Functors)...), m_Functor(p_Functor) {}

    ~ScopeFuncImpl(void) { m_Functor(); }
}; // ScopeFuncImpl

} // impl ns

/**
 * \class ScopeFunc
 * A RAII class that takes an arbitrary number of functor objects, executing the objects' operator()
 * in the ScopeFunc object's destructor when the ScopeFunc object is destroyed.
*/
template<typename ... Functor_T>
class ScopeFunc
    : private impl::ScopeFuncImpl<Functor_T...>
{
private:
    using BaseType = impl::ScopeFuncImpl<Functor_T...>;

public:
    ScopeFunc(Functor_T && ... p_Functors)
        : BaseType(std::forward<Functor_T>(p_Functors)...) {}
};

template<typename ... Functor_T>
ScopeFunc<Functor_T...> makeScopeFunc(Functor_T && ... p_rrFunctor)
{
    return ScopeFunc<Functor_T...>(std::forward<Functor_T>(p_rrFunctor) ... );
}

} // BH ns

/**
 * Create a named ScopeFunc object.
 */
#define MakeNamedScopeFunc(...) auto MAKE_UNIQUE_NAME() = bh::makeScopeFunc(__VA_ARGS__);
/**
 * Create a named ScopeFunc object.
 * \see MakeNamedScopeFunc.
 */
#define BH_MakeNamedScopeFunc(...) MakeNamedScopeFunc(__VA_ARGS__);
<commit_msg>Update ScopeFunc.hpp<commit_after>#pragma once

#include "macro.hpp"

#include <utility>

namespace bh
{

namespace impl
{

/** @brief ScopeFunc implementation impl. */
template<typename ... T> class ScopeFuncImpl;
/** @brief ScopeFunc implementation impl. */
template<> class ScopeFuncImpl<> {};
/** @brief ScopeFunc implementation impl. */
template<typename First_T, typename ... Rest_T>
class ScopeFuncImpl<First_T, Rest_T...>
    : private ScopeFuncImpl<Rest_T...>
{
private:
    using BaseType = ScopeFuncImpl<Rest_T...>;

    First_T m_Functor;

public:
    ScopeFuncImpl(First_T && p_Functor, Rest_T && ... p_Functors)
        : BaseType(std::forward<Rest_T>(p_Functors)...), m_Functor(p_Functor) {}

    ~ScopeFuncImpl(void) { m_Functor(); }
}; // ScopeFuncImpl

} // impl ns

/**
 * @class ScopeFunc
 * @brief A RAII class that takes a single functor object, executing the object's operator()
 * in the ScopeFunc object's destructor when the ScopeFunc object is destroyed.
*/
template<typename ... Functor_T>
class ScopeFunc
    : private impl::ScopeFuncImpl<Functor_T...>
{
private:
    using BaseType = impl::ScopeFuncImpl<Functor_T...>;

public:
    ScopeFunc(Functor_T && ... p_Functors)
        : BaseType(std::forward<Functor_T>(p_Functors)...) {}
};

/**
 * Utility function for creating a ScopeFunc object with an arbitrary amount of functors.
 *
 * Sample usuage:
 * @code
 *      auto scope_func = makeScopeFunc([](void){ std::cout << "end of scope" << std::endl; });
 * @endcode
 * @return a ScopeFunc object.
*/
template<typename ... Functor_T>
ScopeFunc<Functor_T...> makeScopeFunc(Functor_T && ... p_rrFunctor)
{
    return ScopeFunc<Functor_T...>(std::forward<Functor_T>(p_rrFunctor) ... );
}

} // bh ns

/**
 * Utility macro function for creating a ScopeFunc object with an arbitrary amount of functors.
 * This function takes care of creating the ScopeFunc object for you so you don't declare one.
 * makeScopeFunc is used internally.
 *
 * Sample usuage:
 * @code
 *      MakeScopeFunc([](void){ std::cout << "end of scope" << std::endl; });
 * @endcode
 * @return a ScopeFunc object.
*/
#define MakeScopeFunc(...) auto MAKE_UNIQUE_NAME() = bh::makeScopeFunc(__VA_ARGS__);
#define BH_MakeScopeFunc(...) auto BH_MAKE_UNIQUE_NAME() = bh::makeScopeFunc(__VA_ARGS__);
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <string.h>

#include "../include/Suffix.h"
#include "../include/Constants.h"
#include "../include/Functions.h"

using std::cout;
using std::cin;
using std::cerr;
using std::setw;
using std::flush;
using std::endl;

int main() {
    cout << "Enter sample string: " << flush;
    cin.getline(T, MAX_LENGTH - 1);
    N = (int) (strlen(T) - 1);

    Suffix active(0, 0, -1);
    for (int i = 0; i <= N; i++) {
        AddPrefix(active, i);
    }
    dump_edges(N);
    cout << "Would you like to validate the tree?" << flush;
    std::string s;
    getline(cin, s);
    if (s.size() > 0 && s[0] == 'Y' || s[0] == 'y') {
        validate();
    }
    return 1;
}<commit_msg>Fixed main program namespaces.<commit_after>#include <iostream>
#include <iomanip>
#include <string.h>

#include "../include/Suffix.h"
#include "../include/Constants.h"
#include "../include/Functions.h"

using std::cout;
using std::cin;
using std::flush;

int main() {
    cout << "Enter sample string: " << flush;
    cin.getline(T, MAX_LENGTH - 1);
    N = (int) (strlen(T) - 1);

    Suffix active(0, 0, -1);
    for (int i = 0; i <= N; i++) {
        AddPrefix(active, i);
    }
    dump_edges(N);
    cout << "Would you like to validate the tree?" << flush;
    std::string s;
    getline(cin, s);
    if (s.size() > 0 && s[0] == 'Y' || s[0] == 'y') {
        validate();
    }
    return 1;
}<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <string>

#include "args.hpp"
#include "code.hpp"
#include "error.hpp"
#include "parser.hpp"

#ifndef VERSION
#error No version was defined during the compilation process
#endif

int main(int argc, char **argv)
{
	// @TODO: Make it possible through a flag to one day be able to generate a binary file.

	if (argc == 1) {
		// @TODO Print out proper usage information
		std::cerr << Error() << "Invalid number of arguments" << std::endl;
		return 1;
	} else {
		// Before anything, check if this is a version invocation
		// @TODO Also add license when there is a license
		if (std::string(argv[1]) == "version") {
			std::cout << "DTVM version " << VERSION << "\n" <<
				"by Victhor S. Sartório" << std::endl;
			return 0;
		}

		// Parse possible flags
		// @TODO Pass over the handling of flags to the `args` translation unit
		for (int i = 3; i < argc; i++) {
			std::string arg(argv[i]);

			if (arg == "-no-ansi-color-codes" || arg == "-no-acc")
				dtvm_args::no_ansi_color_codes = true;
			else if (arg == "-parse-and-print")
				dtvm_args::parse_and_print = true;
			else
				std::cout << Warn() << "Unknown option '" << argv[i] << "'" << std::endl;
		}

		// Attempt to open file
		std::string file_path(argv[2]);
		std::ifstream file(file_path);
		if (!file.is_open()) {
			std::cerr << Error() << "Could not open file '" << file_path << "'" << std::endl;
			return 1;
		}

		// Parse code
		auto code = parse(file, file_path);
		if (code.curr_index == 0) {
			std::cerr << Error() << "Got invalid code from parser" << std::endl;
			return 1;
		}

		// If the program was called with -parse-and-print, just pretty print the parsed bytecode.
		if (dtvm_args::parse_and_print) {
			code.display();
			return 0;
		}

		// Run the code in the VM.
		std::cout << Error() << "The VM is not yet implemented" << std::endl;
	}

	return 0;
}
<commit_msg>Fixed bug where you'd still need the 'c' in invocation<commit_after>#include <fstream>
#include <iostream>
#include <string>

#include "args.hpp"
#include "code.hpp"
#include "error.hpp"
#include "parser.hpp"

#ifndef VERSION
#error No version was defined during the compilation process
#endif

int main(int argc, char **argv)
{
	// @TODO: Make it possible through a flag to one day be able to generate a binary file.

	if (argc == 1) {
		// @TODO Print out proper usage information
		std::cerr << Error() << "Invalid number of arguments" << std::endl;
		return 1;
	} else {
		// Before anything, check if this is a version invocation
		// @TODO Also add license when there is a license
		if (std::string(argv[1]) == "version") {
			std::cout << "DTVM version " << VERSION << "\n" <<
				"by Victhor S. Sartório" << std::endl;
			return 0;
		}

		// Parse possible flags
		// @TODO Pass over the handling of flags to the `args` translation unit
		for (int i = 2; i < argc; i++) {
			std::string arg(argv[i]);

			if (arg == "-no-ansi-color-codes" || arg == "-no-acc")
				dtvm_args::no_ansi_color_codes = true;
			else if (arg == "-parse-and-print")
				dtvm_args::parse_and_print = true;
			else
				std::cout << Warn() << "Unknown option '" << argv[i] << "'" << std::endl;
		}

		// Attempt to open file
		std::string file_path(argv[1]);
		std::ifstream file(file_path);
		if (!file.is_open()) {
			std::cerr << Error() << "Could not open file '" << file_path << "'" << std::endl;
			return 1;
		}

		// Parse code
		auto code = parse(file, file_path);
		if (code.curr_index == 0) {
			std::cerr << Error() << "Got invalid code from parser" << std::endl;
			return 1;
		}

		// If the program was called with -parse-and-print, just pretty print the parsed bytecode.
		if (dtvm_args::parse_and_print) {
			code.display();
			return 0;
		}

		// Run the code in the VM.
		std::cout << Error() << "The VM is not yet implemented" << std::endl;
	}

	return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
  main.cpp
  -------------------
  A brewing recipe calculator
  -------------------
  Copyright (c) 1999-2007 David Johnson <david@usermode.org>
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/

#include <cstdlib>

#include <QApplication>
#include <QLibraryInfo>
#include <QLocale>
#include <QMainWindow>
#include <QStringList>
#include <QTextStream>
#include <QTranslator>

#if defined(Q_WS_MACX)
extern void qt_mac_set_menubar_icons(bool enable);
#endif

#include "qbrew.h"
#include "resource.h"

using namespace std;
using namespace Resource;

//////////////////////////////////////////////////////////////////////////////
// doversion()
// -----------
// Print out copyright and version info to stdout

void doversion(QTextStream &stream)
{
    stream << PACKAGE << ' ' << VERSION << '\n';
    stream << QObject::tr(DESCRIPTION) << '\n';
    stream << QObject::tr(COPYRIGHT);
    stream << ' ' << AUTHOR;
    stream << " <" << AUTHOR_EMAIL << ">";
    stream << endl;
}

//////////////////////////////////////////////////////////////////////////////
// dohelp()
// --------
// Print out help info to stdout

void dohelp(QTextStream &stream)
{
    stream << QObject::tr("Usage: %1 [options] [file]\n").arg(PACKAGE);
    stream << QObject::tr(DESCRIPTION) << "\n\n";

    // arguments
    stream << QObject::tr("Arguments\n");
    stream << QObject::tr("    file                  File to open") << "\n\n";

    // general options
    stream << QObject::tr("Options\n");
    stream << QObject::tr("    --help                Print the command line options.\n");
    stream << QObject::tr("    --version             Print the application version.\n");
    stream << endl;
}

//////////////////////////////////////////////////////////////////////////////
// doargs()
// --------
// Process the arguments that QApplication doesn't take care of

QString doargs(QStringList arguments, QTextStream &stream)
{
    QString arg;
    for (int n=1; n<arguments.count(); ++n) {
        arg = arguments.at(n);
        if ((arg == "-h")  || (arg == "-help") ||
            (arg == "--help")) {
            dohelp(stream);
            exit(0);
        } else if ((arg == "-v") || (arg == "-version") ||
                   (arg == "--version")) {
            doversion(stream);
            exit(0);
        } else if (arg[0] == '-') {
            // no other valid options
            stream << QObject::tr("Invalid parameter \"%1\"\n") .arg(arg);
            dohelp(stream);
            exit(1);
        } else {
            // it must be a filename
            return arg;
        }
    }
    return (QObject::tr(DEFAULT_FILE));
}

//////////////////////////////////////////////////////////////////////////////
// main()
// ------
// Entry point of application

int main(int argc, char **argv)
{
    Q_INIT_RESOURCE(qbrew);

    QApplication app(argc, argv);

#if defined(Q_WS_MACX)
    // disable icons on Mac menus (as is customary)
    qt_mac_set_menubar_icons(false);
#endif

    // load qbrew translations
    QString transdir = QBrew::instance()->dataBase() + "translations";
    QTranslator translator;
    translator.load("qbrew_" + QLocale::system().name(), transdir);
    app.installTranslator(&translator);
    // load qt translations
    QString qttransdir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
    QTranslator qttranslator;
    qttranslator.load("qt_" + QLocale::system().name(), qttransdir);
    app.installTranslator(&qttranslator);

    // check for additional command line arguments
    QTextStream stream(stdout);
    QString filename = doargs(app.arguments(), stream);

    QBrew* mainwindow = QBrew::instance();
    mainwindow->initialize(filename);
    mainwindow->show();

    app.installEventFilter(mainwindow); // for handling file open events

    return app.exec();
}
<commit_msg>check loading of translations<commit_after>/***************************************************************************
  main.cpp
  -------------------
  A brewing recipe calculator
  -------------------
  Copyright (c) 1999-2007 David Johnson <david@usermode.org>
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/

#include <cstdlib>

#include <QApplication>
#include <QLibraryInfo>
#include <QLocale>
#include <QMainWindow>
#include <QStringList>
#include <QTextStream>
#include <QTranslator>

#if defined(Q_WS_MACX)
extern void qt_mac_set_menubar_icons(bool enable);
#endif

#include "qbrew.h"
#include "resource.h"

using namespace std;
using namespace Resource;

//////////////////////////////////////////////////////////////////////////////
// doversion()
// -----------
// Print out copyright and version info to stdout

void doversion(QTextStream &stream)
{
    stream << PACKAGE << ' ' << VERSION << '\n';
    stream << QObject::tr(DESCRIPTION) << '\n';
    stream << QObject::tr(COPYRIGHT);
    stream << ' ' << AUTHOR;
    stream << " <" << AUTHOR_EMAIL << ">";
    stream << endl;
}

//////////////////////////////////////////////////////////////////////////////
// dohelp()
// --------
// Print out help info to stdout

void dohelp(QTextStream &stream)
{
    stream << QObject::tr("Usage: %1 [options] [file]\n").arg(PACKAGE);
    stream << QObject::tr(DESCRIPTION) << "\n\n";

    // arguments
    stream << QObject::tr("Arguments\n");
    stream << QObject::tr("    file                  File to open") << "\n\n";

    // general options
    stream << QObject::tr("Options\n");
    stream << QObject::tr("    --help                Print the command line options.\n");
    stream << QObject::tr("    --version             Print the application version.\n");
    stream << endl;
}

//////////////////////////////////////////////////////////////////////////////
// doargs()
// --------
// Process the arguments that QApplication doesn't take care of

QString doargs(QStringList arguments, QTextStream &stream)
{
    QString arg;
    for (int n=1; n<arguments.count(); ++n) {
        arg = arguments.at(n);
        if ((arg == "-h")  || (arg == "-help") ||
            (arg == "--help")) {
            dohelp(stream);
            exit(0);
        } else if ((arg == "-v") || (arg == "-version") ||
                   (arg == "--version")) {
            doversion(stream);
            exit(0);
        } else if (arg[0] == '-') {
            // no other valid options
            stream << QObject::tr("Invalid parameter \"%1\"\n") .arg(arg);
            dohelp(stream);
            exit(1);
        } else {
            // it must be a filename
            return arg;
        }
    }
    return (QObject::tr(DEFAULT_FILE));
}

//////////////////////////////////////////////////////////////////////////////
// main()
// ------
// Entry point of application

int main(int argc, char **argv)
{
    Q_INIT_RESOURCE(qbrew);

    QApplication app(argc, argv);

#if defined(Q_WS_MACX)
    // disable icons on Mac menus (as is customary)
    qt_mac_set_menubar_icons(false);
#endif

    // load qbrew translations
    QString transdir = QBrew::instance()->dataBase() + "translations";
    QTranslator translator;
    if (translator.load("qbrew_" + QLocale::system().name(), transdir)) {
        app.installTranslator(&translator);
    }
    // load qt translations
    QString qttransdir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
    QTranslator qttranslator;
    if (qttranslator.load("qt_" + QLocale::system().name(), qttransdir)) {
        app.installTranslator(&qttranslator);
    }

    // check for additional command line arguments
    QTextStream stream(stdout);
    QString filename = doargs(app.arguments(), stream);

    QBrew* mainwindow = QBrew::instance();
    mainwindow->initialize(filename);
    mainwindow->show();

    app.installEventFilter(mainwindow); // for handling file open events

    return app.exec();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
 * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
 * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
 *
 * This file is part of SuperKaramba.
 *
 *  SuperKaramba is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  SuperKaramba is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with SuperKaramba; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ****************************************************************************/

#include <karambaapp.h>
#include <qobject.h>

#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kconfig.h>
#include <kmainwindow.h>
#include <qfileinfo.h>
#include <qstringlist.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kdeversion.h>

#include "karamba.h"
#include "karambasessionmanaged.h"
#include "karambainterface.h"
#include "karamba_python.h"

static const char *description =
    I18N_NOOP("A KDE Eye-candy Application");

static const char *version = "0.38";

static KCmdLineOptions options[] =
{
  // { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
  // { "!nosystray", I18N_NOOP("Disable systray icon"), 0 },
  { "+file", I18N_NOOP("A required argument 'file'"), 0 },
  { 0, 0, 0 }
};

// This is for redirecting all qWarning, qDebug,... messages to file.
// Usefull when testing session management issues etc.
// #define KARAMBA_LOG 1

#ifdef KARAMBA_LOG

void karambaMessageOutput(QtMsgType type, const char *msg)
{
  FILE* fp = fopen("/tmp/karamba.log", "a");
  if(fp)
  {
    pid_t pid = getpid();

    switch ( type )
    {
        case QtDebugMsg:
            fprintf( fp, "Debug (%d): %s\n", pid, msg );
            break;
        case QtWarningMsg:
            if (strncmp(msg, "X Error", 7) != 0)
              fprintf( fp, "Warning (%d): %s\n", pid, msg );
            break;
        case QtFatalMsg:
            fprintf( fp, "Fatal (%d): %s\n", pid, msg );
            abort();                    // deliberately core dump
    }
    fclose(fp);
  }
}

#endif

int main(int argc, char **argv)
{
#ifdef KARAMBA_LOG
    qInstallMsgHandler(karambaMessageOutput);
#endif
    KAboutData about("superkaramba", I18N_NOOP("SuperKaramba"),
                     version, description,
                     KAboutData::License_GPL,
                     "(c) 2003-2006 The SuperKaramba developers");
    about.addAuthor("Adam Geitgey", 0, "adam@rootnode.org");
    about.addAuthor("Hans Karlsson", 0, "karlsson.h@home.se");
    about.addAuthor("Ryan Nickell", 0, "p0z3r@earthlink.net");
    about.addAuthor("Petri Damstén", 0, "petri.damsten@iki.fi");
    about.addAuthor("Alexander Wiedenbruch", 0, "mail@wiedenbruch.de");
    about.addAuthor("Luke Kenneth Casson Leighton", 0, "lkcl@lkcl.net");
    KCmdLineArgs::init(argc, argv, &about);
    KCmdLineArgs::addCmdLineOptions(options);
    KSessionManaged ksm;
    //karamba *mainWin = 0;
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    QStringList lst;
    int ret = 0;

    // Create ~/.superkaramba if necessary
    KarambaApplication::checkSuperKarambaDir();

    KarambaApplication::lockKaramba();

    KarambaApplication app;

    QString mainAppId = app.getMainKaramba();
    if(!mainAppId.isEmpty())
    {
      app.initDcopStub(mainAppId.ascii());
    }
    else
    {
      //Set up systray icon
      app.setUpSysTray(&about);
      app.initDcopStub();
    }

    KarambaApplication::unlockKaramba();

    app.connect(qApp,SIGNAL(lastWindowClosed()),qApp,SLOT(quit()));

    // Try to restore a previous session if applicable.
    app.checkPreviousSession(app, lst);
    if( (lst.size() == 0) && !app.isRestored() )
    {
      //Not a saved session - check for themes given on command line
      app.checkCommandLine(args, lst);

      if(lst.size() == 0)
      {
        //No themes given on command line and no saved session.
        //Show welcome dialog.
        app.globalShowThemeDialog();
      }
    }

    args->clear();

    KarambaPython::initPython();
    //qDebug("startThemes");
    if(app.startThemes(lst) || mainAppId.isEmpty())
      ret = app.exec();
    KarambaPython::shutdownPython();
    return ret;
}
<commit_msg>Bump up the version to 0.39 before the 3.5.2 tagging occurs.<commit_after>/*
 * Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
 * Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
 * Copyright (c) 2005 Ryan Nickell <p0z3r@earthlink.net>
 *
 * This file is part of SuperKaramba.
 *
 *  SuperKaramba is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  SuperKaramba is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with SuperKaramba; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 ****************************************************************************/

#include <karambaapp.h>
#include <qobject.h>

#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kconfig.h>
#include <kmainwindow.h>
#include <qfileinfo.h>
#include <qstringlist.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kdeversion.h>

#include "karamba.h"
#include "karambasessionmanaged.h"
#include "karambainterface.h"
#include "karamba_python.h"

static const char *description =
    I18N_NOOP("A KDE Eye-candy Application");

static const char *version = "0.39";

static KCmdLineOptions options[] =
{
  // { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
  // { "!nosystray", I18N_NOOP("Disable systray icon"), 0 },
  { "+file", I18N_NOOP("A required argument 'file'"), 0 },
  { 0, 0, 0 }
};

// This is for redirecting all qWarning, qDebug,... messages to file.
// Usefull when testing session management issues etc.
// #define KARAMBA_LOG 1

#ifdef KARAMBA_LOG

void karambaMessageOutput(QtMsgType type, const char *msg)
{
  FILE* fp = fopen("/tmp/karamba.log", "a");
  if(fp)
  {
    pid_t pid = getpid();

    switch ( type )
    {
        case QtDebugMsg:
            fprintf( fp, "Debug (%d): %s\n", pid, msg );
            break;
        case QtWarningMsg:
            if (strncmp(msg, "X Error", 7) != 0)
              fprintf( fp, "Warning (%d): %s\n", pid, msg );
            break;
        case QtFatalMsg:
            fprintf( fp, "Fatal (%d): %s\n", pid, msg );
            abort();                    // deliberately core dump
    }
    fclose(fp);
  }
}

#endif

int main(int argc, char **argv)
{
#ifdef KARAMBA_LOG
    qInstallMsgHandler(karambaMessageOutput);
#endif
    KAboutData about("superkaramba", I18N_NOOP("SuperKaramba"),
                     version, description,
                     KAboutData::License_GPL,
                     "(c) 2003-2006 The SuperKaramba developers");
    about.addAuthor("Adam Geitgey", 0, "adam@rootnode.org");
    about.addAuthor("Hans Karlsson", 0, "karlsson.h@home.se");
    about.addAuthor("Ryan Nickell", 0, "p0z3r@earthlink.net");
    about.addAuthor("Petri Damstén", 0, "petri.damsten@iki.fi");
    about.addAuthor("Alexander Wiedenbruch", 0, "mail@wiedenbruch.de");
    about.addAuthor("Luke Kenneth Casson Leighton", 0, "lkcl@lkcl.net");
    KCmdLineArgs::init(argc, argv, &about);
    KCmdLineArgs::addCmdLineOptions(options);
    KSessionManaged ksm;
    //karamba *mainWin = 0;
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    QStringList lst;
    int ret = 0;

    // Create ~/.superkaramba if necessary
    KarambaApplication::checkSuperKarambaDir();

    KarambaApplication::lockKaramba();

    KarambaApplication app;

    QString mainAppId = app.getMainKaramba();
    if(!mainAppId.isEmpty())
    {
      app.initDcopStub(mainAppId.ascii());
    }
    else
    {
      //Set up systray icon
      app.setUpSysTray(&about);
      app.initDcopStub();
    }

    KarambaApplication::unlockKaramba();

    app.connect(qApp,SIGNAL(lastWindowClosed()),qApp,SLOT(quit()));

    // Try to restore a previous session if applicable.
    app.checkPreviousSession(app, lst);
    if( (lst.size() == 0) && !app.isRestored() )
    {
      //Not a saved session - check for themes given on command line
      app.checkCommandLine(args, lst);

      if(lst.size() == 0)
      {
        //No themes given on command line and no saved session.
        //Show welcome dialog.
        app.globalShowThemeDialog();
      }
    }

    args->clear();

    KarambaPython::initPython();
    //qDebug("startThemes");
    if(app.startThemes(lst) || mainAppId.isEmpty())
      ret = app.exec();
    KarambaPython::shutdownPython();
    return ret;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include "logger.hpp"
#include "server.hpp"
#include "parser.hpp"
#include "config.hpp"
#include "requestHandler.hpp"

void handler(int sig)
{
	RequestHandler::stop();
	exit(0);
}

int main(int argc, char **argv)
{
	std::ios_base::sync_with_stdio(false);
	signal(SIGINT, handler);
	signal(SIGTERM, handler);

	std::string configFile = "liquid.conf";
	unsigned int logLevel = Logger::Level::INFO;
	int opt;

	while ((opt = getopt(argc, argv, "c:v:")) != -1) {
		switch (opt) {
			case 'c':
				configFile = optarg;
				break;
			case 'v':
				try {
					logLevel = std::stoul(optarg);
					if (logLevel <= Logger::Level::ERROR)
						break;
				}
				catch (const std::exception& e) {}
			default:
				std::cerr << "Usage: " << argv0 << " [-c configFile] [-v <0,1,2>]\n";
				return 1;
		}
	}

	try {
		LOG_INIT(static_cast<Logger::Level>(logLevel));
		Config::load("liquid.conf");
		int port = Config::getInt("port");
		Server server(port);
		Parser::init();
		if (Config::get("type") == "private")
			RequestHandler::init();
		LOG_INFO("Starting " + Config::get("type") + " server on port " + std::to_string(port));
		server.run();
	}
	catch (const std::exception& e) {
		LOG_ERROR(e.what());
	}

	return 0;
}
<commit_msg>fix build error<commit_after>#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include "logger.hpp"
#include "server.hpp"
#include "parser.hpp"
#include "config.hpp"
#include "requestHandler.hpp"

void handler(int sig)
{
	RequestHandler::stop();
	exit(0);
}

int main(int argc, char **argv)
{
	std::ios_base::sync_with_stdio(false);
	signal(SIGINT, handler);
	signal(SIGTERM, handler);

	std::string configFile = "liquid.conf";
	unsigned int logLevel = Logger::Level::INFO;
	int opt;

	while ((opt = getopt(argc, argv, "c:v:")) != -1) {
		switch (opt) {
			case 'c':
				configFile = optarg;
				break;
			case 'v':
				try {
					logLevel = std::stoul(optarg);
					if (logLevel <= Logger::Level::ERROR)
						break;
				}
				catch (const std::exception& e) {}
			default:
				std::cerr << "Usage: " << argv[0] << " [-c configFile] [-v <0,1,2>]\n";
				return 1;
		}
	}

	try {
		LOG_INIT(static_cast<Logger::Level>(logLevel));
		Config::load("liquid.conf");
		int port = Config::getInt("port");
		Server server(port);
		Parser::init();
		if (Config::get("type") == "private")
			RequestHandler::init();
		LOG_INFO("Starting " + Config::get("type") + " server on port " + std::to_string(port));
		server.run();
	}
	catch (const std::exception& e) {
		LOG_ERROR(e.what());
	}

	return 0;
}
<|endoftext|>