<commit_before>/*
The MIT License (MIT)

Copyright (c) 2014-2017 Oleg Linkin <maledictusdemagog@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "linksbagmanager.h"

#include <QDir>
#include <QSettings>
#include <QStandardPaths>

#include "src/enumsproxy.h"
#include "src/bookmarksmodel.h"
#include "src/filterproxymodel.h"
#include "src/getpocketapi.h"
#include "src/settings/applicationsettings.h"

namespace LinksBag
{
LinksBagManager::LinksBagManager(QObject *parent)
: QObject(parent)
, m_Api(new GetPocketApi(this))
, m_IsBusy(false)
, m_IsLogged(false)
, m_BookmarksModel(new BookmarksModel(this))
, m_FilterProxyModel(new FilterProxyModel(this))
{
    MakeConnections();

    m_FilterProxyModel->setSourceModel(m_BookmarksModel);

    SetLogged(!ApplicationSettings::Instance(this)->value("access_token").isNull() &&
              !ApplicationSettings::Instance(this)->value("user_name").isNull());
    if (m_IsLogged)
    {
        loadBookmarksFromCache();
    }
}

LinksBagManager* LinksBagManager::Instance(QObject *parent)
{
    static LinksBagManager *linksBagManager = nullptr;
    if (!linksBagManager)
    {
        linksBagManager = new LinksBagManager(parent);
    }
    return linksBagManager;
}

bool LinksBagManager::GetBusy() const
{
    return m_IsBusy;
}

bool LinksBagManager::GetLogged() const
{
    return m_IsLogged;
}

void LinksBagManager::MakeConnections()
{
    connect(m_Api.get(),
            &GetPocketApi::requestFinished,
            this,
            [=](bool success, const QString& errorMsg)
            {
                SetBusy(false);
                if (!success && !errorMsg.isEmpty())
                {
                    emit error(errorMsg, ETGeneral);
                }
            });
    connect(m_Api.get(),
            &GetPocketApi::error,
            this,
            [=](const QString& msg, int code, ErrorType type)
            {
                SetBusy(false);
                const QString errorMessage = (type == ETGetPocket?
                        (tr("GetPocket error (%1): ").arg(code) + msg) :
                        msg);
                emit error(errorMessage, type);
            });

    connect(m_Api.get(),
            &GetPocketApi::requestTokenChanged,
            this,
            &LinksBagManager::requestTokenChanged);

    connect(m_Api.get(),
            &GetPocketApi::logged,
            this,
            [=](bool logged, const QString& accessToken, const QString& userName)
            {
                ApplicationSettings::Instance(this)->
                        setValue("access_token", accessToken);
                ApplicationSettings::Instance(this)->
                        setValue("user_name", userName);
                SetLogged(logged);
            });

    connect(m_Api.get(),
            &GetPocketApi::gotBookmarks,
            this,
            [this](const Bookmarks_t& bookmarks, quint64 since)
            {
                m_BookmarksModel->AddBookmarks(bookmarks);
                m_FilterProxyModel->sort(0, Qt::DescendingOrder);
                ApplicationSettings::Instance(this)->setValue("last_update", since);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkRemoved,
            this,
            [this](const QString& id)
            {
                m_BookmarksModel->RemoveBookmark(id);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkMarkedAsFavorite,
            [this](const QString& id, bool favorite)
            {
                m_BookmarksModel->MarkBookmarkAsFavorite(id, favorite);
                emit bookmarkFavoriteStateChanged(id, favorite);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkMarkedAsRead,
            [this](const QString& id, bool read)
            {
                m_BookmarksModel->MarkBookmarkAsRead(id, read);
                emit bookmarkReadStateChanged(id, read);
            });

    connect(m_Api.get(),
            &GetPocketApi::tagsUpdated,
            [this](const QString& id, const QString& tags)
            {
                m_BookmarksModel->UpdateTags(id, tags);
            });
}

void LinksBagManager::SetBusy(const bool busy)
{
    m_IsBusy = busy;
    emit busyChanged();
}

void LinksBagManager::SetLogged(const bool logged)
{
    m_IsLogged = logged;
    emit loggedChanged();
}

void LinksBagManager::saveBookmarks()
{
    const auto& bookmarks = m_BookmarksModel->GetBookmarks();
    if (bookmarks.isEmpty())
        return;

    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    settings.beginWriteArray("Bookmarks");
    for (int i = 0, size = bookmarks.size(); i < size; ++i)
    {
        settings.setArrayIndex(i);
        settings.setValue("SerializedData", bookmarks.at(i).Serialize());
    }
    settings.endArray();
    settings.sync();
}

BookmarksModel* LinksBagManager::GetBookmarksModel() const
{
    return m_BookmarksModel;
}

FilterProxyModel*LinksBagManager::GetFilterModel() const
{
    return m_FilterProxyModel;
}

void LinksBagManager::obtainRequestToken()
{
    SetBusy(true);
    m_Api->ObtainRequestToken();
}

void LinksBagManager::requestAccessToken()
{
    SetBusy(true);
    m_Api->RequestAccessToken();
}

void LinksBagManager::filterBookmarks(const QString &text)
{
    m_FilterProxyModel->setFilterRegExp(text);
}

void LinksBagManager::loadBookmarksFromCache()
{
    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    const int size = settings.beginReadArray("Bookmarks");
    Bookmarks_t bookmarks;
    for (int i = 0; i < size; ++i)
    {
        settings.setArrayIndex(i);
        QByteArray data = settings.value("SerializedData").toByteArray();
        Bookmark bm = Bookmark::Deserialize(data);
        qDebug() << "no nie" << bm.GetContent() << "czemu to nie dziala";
        if (!bm.IsValid())
        {
            qWarning() << Q_FUNC_INFO
                    << "unserializable entry"
                    << i;
            continue;
        }
        bookmarks << bm;
    }
    settings.endArray();

    m_BookmarksModel->SetBookmarks(bookmarks);
    m_FilterProxyModel->sort(0, Qt::DescendingOrder);
}

void LinksBagManager::refreshBookmarks()
{
    SetBusy(true);
    m_Api->LoadBookmarks(ApplicationSettings::Instance(this)->
            value("last_update", 0).toLongLong());
}

void LinksBagManager::removeBookmark(const QString& id)
{
    SetBusy(true);
    m_Api->RemoveBookmark(id);
}

void LinksBagManager::markAsFavorite(const QString& id, bool favorite)
{
    SetBusy(true);
    m_Api->MarkBookmarkAsFavorite(id, favorite);
}

void LinksBagManager::markAsRead(const QString& id, bool read)
{
    SetBusy(true);
    m_Api->MarkBookmarkAsRead(id, read);
}

void LinksBagManager::updateTags(const QString& id, const QString& tags)
{
    SetBusy(true);
    m_Api->UpdateTags(id, tags);
}

void LinksBagManager::updateContent(const QString &id, const QString &content)
{
    m_BookmarksModel->UpdateContent(id, content);
}

void LinksBagManager::resetAccount()
{
    ApplicationSettings::Instance(this)->remove("access_token");
    ApplicationSettings::Instance(this)->remove("user_name");
    ApplicationSettings::Instance(this)->remove("last_update");
    ApplicationSettings::Instance(this)->remove("bookmarks_filter");
    ApplicationSettings::Instance(this)->remove("search_field_visibility");

    m_Api->ResetAccount();

    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    settings.remove("Bookmarks");
    settings.sync();

    m_BookmarksModel->Clear();

    QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
    if (dir.exists())
    {
        dir.removeRecursively();
    }

    SetLogged(false);
}
} // namespace LinskBag
<commit_msg>remove unnecessary debug message note to self: don't commit code on Christmas<commit_after>/*
The MIT License (MIT)

Copyright (c) 2014-2017 Oleg Linkin <maledictusdemagog@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "linksbagmanager.h"

#include <QDir>
#include <QSettings>
#include <QStandardPaths>

#include "src/enumsproxy.h"
#include "src/bookmarksmodel.h"
#include "src/filterproxymodel.h"
#include "src/getpocketapi.h"
#include "src/settings/applicationsettings.h"

namespace LinksBag
{
LinksBagManager::LinksBagManager(QObject *parent)
: QObject(parent)
, m_Api(new GetPocketApi(this))
, m_IsBusy(false)
, m_IsLogged(false)
, m_BookmarksModel(new BookmarksModel(this))
, m_FilterProxyModel(new FilterProxyModel(this))
{
    MakeConnections();

    m_FilterProxyModel->setSourceModel(m_BookmarksModel);

    SetLogged(!ApplicationSettings::Instance(this)->value("access_token").isNull() &&
              !ApplicationSettings::Instance(this)->value("user_name").isNull());
    if (m_IsLogged)
    {
        loadBookmarksFromCache();
    }
}

LinksBagManager* LinksBagManager::Instance(QObject *parent)
{
    static LinksBagManager *linksBagManager = nullptr;
    if (!linksBagManager)
    {
        linksBagManager = new LinksBagManager(parent);
    }
    return linksBagManager;
}

bool LinksBagManager::GetBusy() const
{
    return m_IsBusy;
}

bool LinksBagManager::GetLogged() const
{
    return m_IsLogged;
}

void LinksBagManager::MakeConnections()
{
    connect(m_Api.get(),
            &GetPocketApi::requestFinished,
            this,
            [=](bool success, const QString& errorMsg)
            {
                SetBusy(false);
                if (!success && !errorMsg.isEmpty())
                {
                    emit error(errorMsg, ETGeneral);
                }
            });
    connect(m_Api.get(),
            &GetPocketApi::error,
            this,
            [=](const QString& msg, int code, ErrorType type)
            {
                SetBusy(false);
                const QString errorMessage = (type == ETGetPocket?
                        (tr("GetPocket error (%1): ").arg(code) + msg) :
                        msg);
                emit error(errorMessage, type);
            });

    connect(m_Api.get(),
            &GetPocketApi::requestTokenChanged,
            this,
            &LinksBagManager::requestTokenChanged);

    connect(m_Api.get(),
            &GetPocketApi::logged,
            this,
            [=](bool logged, const QString& accessToken, const QString& userName)
            {
                ApplicationSettings::Instance(this)->
                        setValue("access_token", accessToken);
                ApplicationSettings::Instance(this)->
                        setValue("user_name", userName);
                SetLogged(logged);
            });

    connect(m_Api.get(),
            &GetPocketApi::gotBookmarks,
            this,
            [this](const Bookmarks_t& bookmarks, quint64 since)
            {
                m_BookmarksModel->AddBookmarks(bookmarks);
                m_FilterProxyModel->sort(0, Qt::DescendingOrder);
                ApplicationSettings::Instance(this)->setValue("last_update", since);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkRemoved,
            this,
            [this](const QString& id)
            {
                m_BookmarksModel->RemoveBookmark(id);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkMarkedAsFavorite,
            [this](const QString& id, bool favorite)
            {
                m_BookmarksModel->MarkBookmarkAsFavorite(id, favorite);
                emit bookmarkFavoriteStateChanged(id, favorite);
            });

    connect(m_Api.get(),
            &GetPocketApi::bookmarkMarkedAsRead,
            [this](const QString& id, bool read)
            {
                m_BookmarksModel->MarkBookmarkAsRead(id, read);
                emit bookmarkReadStateChanged(id, read);
            });

    connect(m_Api.get(),
            &GetPocketApi::tagsUpdated,
            [this](const QString& id, const QString& tags)
            {
                m_BookmarksModel->UpdateTags(id, tags);
            });
}

void LinksBagManager::SetBusy(const bool busy)
{
    m_IsBusy = busy;
    emit busyChanged();
}

void LinksBagManager::SetLogged(const bool logged)
{
    m_IsLogged = logged;
    emit loggedChanged();
}

void LinksBagManager::saveBookmarks()
{
    const auto& bookmarks = m_BookmarksModel->GetBookmarks();
    if (bookmarks.isEmpty())
        return;

    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    settings.beginWriteArray("Bookmarks");
    for (int i = 0, size = bookmarks.size(); i < size; ++i)
    {
        settings.setArrayIndex(i);
        settings.setValue("SerializedData", bookmarks.at(i).Serialize());
    }
    settings.endArray();
    settings.sync();
}

BookmarksModel* LinksBagManager::GetBookmarksModel() const
{
    return m_BookmarksModel;
}

FilterProxyModel*LinksBagManager::GetFilterModel() const
{
    return m_FilterProxyModel;
}

void LinksBagManager::obtainRequestToken()
{
    SetBusy(true);
    m_Api->ObtainRequestToken();
}

void LinksBagManager::requestAccessToken()
{
    SetBusy(true);
    m_Api->RequestAccessToken();
}

void LinksBagManager::filterBookmarks(const QString &text)
{
    m_FilterProxyModel->setFilterRegExp(text);
}

void LinksBagManager::loadBookmarksFromCache()
{
    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    const int size = settings.beginReadArray("Bookmarks");
    Bookmarks_t bookmarks;
    for (int i = 0; i < size; ++i)
    {
        settings.setArrayIndex(i);
        QByteArray data = settings.value("SerializedData").toByteArray();
        Bookmark bm = Bookmark::Deserialize(data);
        if (!bm.IsValid())
        {
            qWarning() << Q_FUNC_INFO
                    << "unserializable entry"
                    << i;
            continue;
        }
        bookmarks << bm;
    }
    settings.endArray();

    m_BookmarksModel->SetBookmarks(bookmarks);
    m_FilterProxyModel->sort(0, Qt::DescendingOrder);
}

void LinksBagManager::refreshBookmarks()
{
    SetBusy(true);
    m_Api->LoadBookmarks(ApplicationSettings::Instance(this)->
            value("last_update", 0).toLongLong());
}

void LinksBagManager::removeBookmark(const QString& id)
{
    SetBusy(true);
    m_Api->RemoveBookmark(id);
}

void LinksBagManager::markAsFavorite(const QString& id, bool favorite)
{
    SetBusy(true);
    m_Api->MarkBookmarkAsFavorite(id, favorite);
}

void LinksBagManager::markAsRead(const QString& id, bool read)
{
    SetBusy(true);
    m_Api->MarkBookmarkAsRead(id, read);
}

void LinksBagManager::updateTags(const QString& id, const QString& tags)
{
    SetBusy(true);
    m_Api->UpdateTags(id, tags);
}

void LinksBagManager::updateContent(const QString &id, const QString &content)
{
    m_BookmarksModel->UpdateContent(id, content);
}

void LinksBagManager::resetAccount()
{
    ApplicationSettings::Instance(this)->remove("access_token");
    ApplicationSettings::Instance(this)->remove("user_name");
    ApplicationSettings::Instance(this)->remove("last_update");
    ApplicationSettings::Instance(this)->remove("bookmarks_filter");
    ApplicationSettings::Instance(this)->remove("search_field_visibility");

    m_Api->ResetAccount();

    QSettings settings(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) +
            "/linksbag_cache", QSettings::IniFormat);
    settings.remove("Bookmarks");
    settings.sync();

    m_BookmarksModel->Clear();

    QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
    if (dir.exists())
    {
        dir.removeRecursively();
    }

    SetLogged(false);
}
} // namespace LinskBag
<|endoftext|>


<commit_before>#include "app.h"
#include "log.h"
#include "file.h"
#include "config.h"
#include "daemon.h"
#include "strings.h"
#include <stdio.h>

namespace sim{

volatile bool quit = false;

void signal_handler(int sig){
	switch(sig){
		case SIGTERM:
		case SIGINT:{
			quit = true;
			break;
		}
	}
}

bool Application::running(){
	return !quit;
}

int Application::main(int argc, char **argv){
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);

	conf = NULL;

	welcome();
	parse_args(argc, argv);
	init();

	log_info("config : %s", this->app_args.conf_file.c_str());
	log_info("pidfile: %s, pid: %d", app_args.pidfile.c_str(), (int)getpid());
	log_info("logger");
	log_info("    level : %s", Logger::shared()->level_name().c_str());
	log_info("    output: %s", Logger::shared()->output_name().c_str());
	log_info("    rotate: %" PRId64, Logger::shared()->rotate_size());

	write_pid();
	run();
	remove_pidfile();

	delete conf;
	return 0;
}

void Application::welcome(){
}

void Application::usage(int argc, char **argv){
	printf("Usage:\n");
	printf("    %s [-d] /path/to/app.conf [-s start|stop|restart]\n", argv[0]);
	printf("Options:\n");
	printf("    -d    run as daemon\n");
	printf("    -s    option to start|stop|restart the server\n");
	printf("    -h    show this message\n");
}

void Application::parse_args(int argc, char **argv){
	for(int i=1; i<argc; i++){
		std::string arg = argv[i];
		if(arg == "-d"){
			app_args.is_daemon = true;
		}else if(arg == "-v"){
			exit(0);
		}else if(arg == "-h"){
			usage(argc, argv);
			exit(0);
		}else if(arg == "-s"){
			if(argc > i + 1){
				i ++;
				app_args.start_opt = argv[i];
			}else{
				usage(argc, argv);
				exit(1);
			}
			if(app_args.start_opt != "start" && app_args.start_opt != "stop" && app_args.start_opt != "restart"){
				usage(argc, argv);
				fprintf(stderr, "Error: bad argument: '%s'\n", app_args.start_opt.c_str());
				exit(1);
			}
		}else{
			app_args.conf_file = argv[i];
		}
	}

	if(app_args.conf_file.empty()){
		usage(argc, argv);
		exit(1);
	}
}

void Application::init(){
	if(!is_file(app_args.conf_file.c_str())){
		fprintf(stderr, "'%s' is not a file or not exists!\n", app_args.conf_file.c_str());
		exit(1);
	}
	conf = Config::load(app_args.conf_file.c_str());
	if(!conf){
		fprintf(stderr, "error loading conf file: '%s'\n", app_args.conf_file.c_str());
		exit(1);
	}
	{
		std::string conf_dir = real_dirname(app_args.conf_file.c_str());
		if(chdir(conf_dir.c_str()) == -1){
			fprintf(stderr, "error chdir: %s\n", conf_dir.c_str());
			exit(1);
		}
	}

	app_args.pidfile = conf->get_str("pidfile");

	if(app_args.start_opt == "stop"){
		kill_process();
		exit(0);
	}
	if(app_args.start_opt == "restart"){
		if(file_exists(app_args.pidfile)){
			kill_process();
		}
	}

	check_pidfile();

	{ // logger
		std::string log_output;
		std::string log_level_;
		int64_t log_rotate_size;

		log_level_ = conf->get_str("logger.level");
		strtolower(&log_level_);
		if(log_level_.empty()){
			log_level_ = "debug";
		}
		int level = Logger::get_level(log_level_.c_str());
		log_rotate_size = conf->get_int64("logger.rotate.size");
		log_output = conf->get_str("logger.output");
		if(log_output == ""){
			log_output = "stdout";
		}
		if(log_open(log_output.c_str(), level, true, log_rotate_size) == -1){
			fprintf(stderr, "error opening log file: %s\n", log_output.c_str());
			exit(1);
		}
	}

	app_args.work_dir = conf->get_str("work_dir");
	if(app_args.work_dir.empty()){
		app_args.work_dir = ".";
	}
	if(!is_dir(app_args.work_dir.c_str())){
		fprintf(stderr, "'%s' is not a directory or not exists!\n", app_args.work_dir.c_str());
		exit(1);
	}

	// WARN!!!
	// deamonize() MUST be called before any thread is created!
	if(app_args.is_daemon){
		daemonize();
	}
}

int Application::read_pid(){
	if(app_args.pidfile.empty()){
		return -1;
	}
	std::string s;
	file_get_contents(app_args.pidfile, &s);
	if(s.empty()){
		return -1;
	}
	return str_to_int(s);
}

void Application::write_pid(){
	if(app_args.pidfile.empty()){
		return;
	}
	int pid = (int)getpid();
	std::string s = str(pid);
	int ret = file_put_contents(app_args.pidfile, s);
	if(ret == -1){
		log_error("Failed to write pidfile '%s'(%s)", app_args.pidfile.c_str(), strerror(errno));
		exit(1);
	}
}

void Application::check_pidfile(){
	if(app_args.pidfile.size()){
		if(access(app_args.pidfile.c_str(), F_OK) == 0){
			fprintf(stderr, "Fatal error!\nPidfile %s already exists!\n"
				"Kill the running process before you run this command,\n"
				"or use '-s restart' option to restart the server.\n",
				app_args.pidfile.c_str());
			exit(1);
		}
	}
}

void Application::remove_pidfile(){
	if(app_args.pidfile.size()){
		remove(app_args.pidfile.c_str());
	}
}

void Application::kill_process(){
	int pid = read_pid();
	if(pid == -1){
		fprintf(stderr, "could not read pidfile: %s(%s)\n", app_args.pidfile.c_str(), strerror(errno));
		exit(1);
	}
	if(kill(pid, 0) == -1 && errno == ESRCH){
		fprintf(stderr, "process: %d not running\n", pid);
		remove_pidfile();
		return;
	}
	int ret = kill(pid, SIGTERM);
	if(ret == -1){
		fprintf(stderr, "could not kill process: %d(%s)\n", pid, strerror(errno));
		exit(1);
	}

	while(file_exists(app_args.pidfile)){
		usleep(100 * 1000);
	}
}

}; // namespace sim
<commit_msg>update<commit_after>#include "app.h"
#include "log.h"
#include "file.h"
#include "config.h"
#include "daemon.h"
#include "strings.h"
#include <stdio.h>

namespace sim{

volatile bool quit = false;

void signal_handler(int sig){
	switch(sig){
		case SIGTERM:
		case SIGINT:{
			quit = true;
			break;
		}
	}
}

bool Application::running(){
	return !quit;
}

int Application::main(int argc, char **argv){
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);

	conf = NULL;

	welcome();
	parse_args(argc, argv);
	init();

	log_info("config    : %s", this->app_args.conf_file.c_str());
	log_info("pidfile   : %s, pid: %d", app_args.pidfile.c_str(), (int)getpid());
	log_info("log_level : %s", Logger::shared()->level_name().c_str());
	log_info("log_output: %s", Logger::shared()->output_name().c_str());
	log_info("log_rotate: %" PRId64, Logger::shared()->rotate_size());

	write_pid();
	run();
	remove_pidfile();

	delete conf;
	return 0;
}

void Application::welcome(){
}

void Application::usage(int argc, char **argv){
	printf("Usage:\n");
	printf("    %s [-d] /path/to/app.conf [-s start|stop|restart]\n", argv[0]);
	printf("Options:\n");
	printf("    -d    run as daemon\n");
	printf("    -s    option to start|stop|restart the server\n");
	printf("    -h    show this message\n");
}

void Application::parse_args(int argc, char **argv){
	for(int i=1; i<argc; i++){
		std::string arg = argv[i];
		if(arg == "-d"){
			app_args.is_daemon = true;
		}else if(arg == "-v"){
			exit(0);
		}else if(arg == "-h"){
			usage(argc, argv);
			exit(0);
		}else if(arg == "-s"){
			if(argc > i + 1){
				i ++;
				app_args.start_opt = argv[i];
			}else{
				usage(argc, argv);
				exit(1);
			}
			if(app_args.start_opt != "start" && app_args.start_opt != "stop" && app_args.start_opt != "restart"){
				usage(argc, argv);
				fprintf(stderr, "Error: bad argument: '%s'\n", app_args.start_opt.c_str());
				exit(1);
			}
		}else{
			app_args.conf_file = argv[i];
		}
	}

	if(app_args.conf_file.empty()){
		usage(argc, argv);
		exit(1);
	}
}

void Application::init(){
	if(!is_file(app_args.conf_file.c_str())){
		fprintf(stderr, "'%s' is not a file or not exists!\n", app_args.conf_file.c_str());
		exit(1);
	}
	conf = Config::load(app_args.conf_file.c_str());
	if(!conf){
		fprintf(stderr, "error loading conf file: '%s'\n", app_args.conf_file.c_str());
		exit(1);
	}
	{
		std::string conf_dir = real_dirname(app_args.conf_file.c_str());
		if(chdir(conf_dir.c_str()) == -1){
			fprintf(stderr, "error chdir: %s\n", conf_dir.c_str());
			exit(1);
		}
	}

	app_args.pidfile = conf->get_str("pidfile");

	if(app_args.start_opt == "stop"){
		kill_process();
		exit(0);
	}
	if(app_args.start_opt == "restart"){
		if(file_exists(app_args.pidfile)){
			kill_process();
		}
	}

	check_pidfile();

	{ // logger
		std::string log_output;
		std::string log_level_;
		int64_t log_rotate_size;

		log_level_ = conf->get_str("logger.level");
		strtolower(&log_level_);
		if(log_level_.empty()){
			log_level_ = "debug";
		}
		int level = Logger::get_level(log_level_.c_str());
		log_rotate_size = conf->get_int64("logger.rotate.size");
		log_output = conf->get_str("logger.output");
		if(log_output == ""){
			log_output = "stdout";
		}
		if(log_open(log_output.c_str(), level, true, log_rotate_size) == -1){
			fprintf(stderr, "error opening log file: %s\n", log_output.c_str());
			exit(1);
		}
	}

	app_args.work_dir = conf->get_str("work_dir");
	if(app_args.work_dir.empty()){
		app_args.work_dir = ".";
	}
	if(!is_dir(app_args.work_dir.c_str())){
		fprintf(stderr, "'%s' is not a directory or not exists!\n", app_args.work_dir.c_str());
		exit(1);
	}

	// WARN!!!
	// deamonize() MUST be called before any thread is created!
	if(app_args.is_daemon){
		daemonize();
	}
}

int Application::read_pid(){
	if(app_args.pidfile.empty()){
		return -1;
	}
	std::string s;
	file_get_contents(app_args.pidfile, &s);
	if(s.empty()){
		return -1;
	}
	return str_to_int(s);
}

void Application::write_pid(){
	if(app_args.pidfile.empty()){
		return;
	}
	int pid = (int)getpid();
	std::string s = str(pid);
	int ret = file_put_contents(app_args.pidfile, s);
	if(ret == -1){
		log_error("Failed to write pidfile '%s'(%s)", app_args.pidfile.c_str(), strerror(errno));
		exit(1);
	}
}

void Application::check_pidfile(){
	if(app_args.pidfile.size()){
		if(access(app_args.pidfile.c_str(), F_OK) == 0){
			fprintf(stderr, "Fatal error!\nPidfile %s already exists!\n"
				"Kill the running process before you run this command,\n"
				"or use '-s restart' option to restart the server.\n",
				app_args.pidfile.c_str());
			exit(1);
		}
	}
}

void Application::remove_pidfile(){
	if(app_args.pidfile.size()){
		remove(app_args.pidfile.c_str());
	}
}

void Application::kill_process(){
	int pid = read_pid();
	if(pid == -1){
		fprintf(stderr, "could not read pidfile: %s(%s)\n", app_args.pidfile.c_str(), strerror(errno));
		exit(1);
	}
	if(kill(pid, 0) == -1 && errno == ESRCH){
		fprintf(stderr, "process: %d not running\n", pid);
		remove_pidfile();
		return;
	}
	int ret = kill(pid, SIGTERM);
	if(ret == -1){
		fprintf(stderr, "could not kill process: %d(%s)\n", pid, strerror(errno));
		exit(1);
	}

	while(file_exists(app_args.pidfile)){
		usleep(100 * 1000);
	}
}

}; // namespace sim
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qplace.h"
#include "qplace_p.h"

#ifdef QPLACE_DEBUG
#include <QDebug>
#endif

#include <QStringList>

QT_BEGIN_NAMESPACE

/*!
    \class QPlace
    \inmodule QtLocation
    \ingroup QtLocation-places
    \since QtLocation 5.0

    \brief The QPlace class represents basic information about a place.
*/

/*!
    Constructs an empty place object.
*/
QPlace::QPlace()
        : d_ptr(new QPlacePrivate())
{
}

/*!
    Constructs a copy of \a other.
*/
QPlace::QPlace(const QPlace &other)
        : d_ptr(other.d_ptr)
{
}

/*!
    Destroys this place.
*/
QPlace::~QPlace()
{
}

/*!
    Assigns \a other to this place and returns a reference
    to this place.
*/
QPlace &QPlace::operator= (const QPlace & other)
{
    d_ptr = other.d_ptr;
    return *this;
}

inline QPlacePrivate* QPlace::d_func()
{
    return static_cast<QPlacePrivate *>(d_ptr.data());
}

inline const QPlacePrivate* QPlace::d_func() const
{
    return static_cast<const QPlacePrivate *>(d_ptr.constData());
}

/*!
    Returns true if \a other is equal to this place,
    otherwise returns false.
*/
bool QPlace::operator== (const QPlace &other) const
{
    Q_D(const QPlace);
    return *d == *other.d_func();
}

/*!
    Returns true if \a other is not equal to this place,
    otherwise returns false.
*/
bool QPlace::operator!= (const QPlace &other) const
{
    Q_D(const QPlace);
    return !(*d == *other.d_func());
}

/*!
    Returns categories.
*/
QList<QPlaceCategory> QPlace::categories() const
{
    Q_D(const QPlace);
    return d->categories;
}

/*!
    Sets categories.
*/
void QPlace::setCategories(const QList<QPlaceCategory> &categories)
{
    Q_D(QPlace);
    d->categories = categories;
}

/*!
    Returns location.
*/
QGeoLocation QPlace::location() const
{
    Q_D(const QPlace);
    return d->location;
}

/*!
    Sets location.
*/
void QPlace::setLocation(const QGeoLocation &location)
{
    Q_D(QPlace);
    d->location = location;
}

/*!
    Returns rating.
*/
QPlaceRating QPlace::rating() const
{
    Q_D(const QPlace);
    return d->rating;
}

/*!
    Sets rating.
*/
void QPlace::setRating(const QPlaceRating &rating)
{
    Q_D(QPlace);
    d->rating = rating;
}

/*!
    Returns the supplier of this place data.
*/
QPlaceSupplier QPlace::supplier() const
{
    Q_D(const QPlace);
    return d->supplier;
}

/*!
    Sets the supplier of this place data to \a supplier.
*/
void QPlace::setSupplier(const QPlaceSupplier &supplier)
{
    Q_D(QPlace);
    d->supplier = supplier;
}

/*!
    Returns a collection of content associated with a place.
    This collection is a map with the key being the index of the content object
    and value being the content object itself.

    The \a type specifies which kind of content is to be retrieved.
*/
QPlaceContent::Collection QPlace::content(QPlaceContent::Type type) const
{
    Q_D(const QPlace);
    return d->contentCollections.value(type);
}

/*!
    Sets a collection of \a content for the given \a type.
*/
void QPlace::setContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
{
    Q_D(QPlace);
    d->contentCollections.insert(type, content);
}

/*!
    Adds a collection of \a content of the given \a type to the place.  Any index in \a content
    that already exists is overwritten.
*/
void QPlace::insertContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
{
    Q_D(QPlace);
    QMapIterator<int, QPlaceContent> iter(content);
    while (iter.hasNext()) {
        iter.next();
        d->contentCollections[type].insert(iter.key(), iter.value());
    }
}

/*!
    Returns the total count of content objects of the given \a type.
    This total count indicates how many the manager should have available.
    (As opposed to how many objects this place instance is currently assigned).
    A negative count indicates that the total number of items is unknown.
*/
int QPlace::totalContentCount(QPlaceContent::Type type) const
{
    Q_D(const QPlace);
    return d->contentCounts.value(type, 0);
}

/*!
    Sets the \a totalCount of content objects of the given \a type.
*/
void QPlace::setTotalContentCount(QPlaceContent::Type type, int totalCount)
{
    Q_D(QPlace);
    d->contentCounts.insert(type, totalCount);
}

/*!
    Returns name.
*/
QString QPlace::name() const
{
    Q_D(const QPlace);
    return d->name;
}

/*!
    Sets name.
*/
void QPlace::setName(const QString &name)
{
    Q_D(QPlace);
    d->name = name;
}

/*!
    Returns placeId.
*/
QString QPlace::placeId() const
{
    Q_D(const QPlace);
    return d->placeId;
}

/*!
    Sets placeId.
*/
void QPlace::setPlaceId(const QString &placeId)
{
    Q_D(QPlace);
    d->placeId = placeId;
}

/*!
    Returns a rich text attribution string of the place.  Note, some providers may have a
    requirement where the attribution must be shown whenever a place is displayed to an end user.
*/
QString QPlace::attribution() const
{
    Q_D(const QPlace);
    return d->attribution;
}

/*!
    Sets the attribution string of the place.
*/
void QPlace::setAttribution(const QString &attribution)
{
    Q_D(QPlace);
    d->attribution = attribution;
}

/*!
    Returns the icon of the place.
*/
QPlaceIcon QPlace::icon() const
{
    Q_D(const QPlace);
    return d->icon;
}

/*!
    Sets the icon of the place.
*/
void QPlace::setIcon(const QPlaceIcon &icon)
{
    Q_D(QPlace);
    d->icon = icon;
}

/*!
    Returns the primary phone number for this place.
*/
QString QPlace::primaryPhone() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> phoneNumbers = d->contacts.value(QPlaceContactDetail::Phone);
    if (!phoneNumbers.isEmpty())
        return phoneNumbers.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary fax number for this place.
*/
QString QPlace::primaryFax() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> faxNumbers = d->contacts.value(QPlaceContactDetail::Fax);
    if (!faxNumbers.isEmpty())
        return faxNumbers.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary email address for this place.
*/
QString QPlace::primaryEmail() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> emailAddresses = d->contacts.value(QPlaceContactDetail::Email);
    if (!emailAddresses.isEmpty())
        return emailAddresses.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary URL of this place.
*/
QUrl QPlace::primaryWebsite() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> websites = d->contacts.value(QPlaceContactDetail::Website);
    if (!websites.isEmpty())
        return QUrl(websites.at(0).value().toAscii());
    else
        return QString();
}

/*!
    Returns whether the details of this place have been fetched or not.
*/
bool QPlace::detailsFetched() const
{
    Q_D(const QPlace);
    return d->detailsFetched;
}

/*!
    Sets whether the details of this place have been \a fetched or not.
*/
void QPlace::setDetailsFetched(bool fetched)
{
    Q_D(QPlace);
    d->detailsFetched = fetched;
}

/*!
    Returns the extended attributes of the place
*/
QPlace::ExtendedAttributes QPlace::extendedAttributes() const
{
    Q_D(const QPlace);
    return d->extendedAttributes;
}

/*!
    Sets the extended attributes of the place.
*/
void QPlace::setExtendedAttributes(const ExtendedAttributes &attributes)
{
    Q_D(QPlace);
    d->extendedAttributes = attributes;
}

/*!
    Returns the type of contact details this place has.
*/
QStringList QPlace::contactTypes() const
{
    Q_D(const QPlace);
    return d->contacts.keys();
}

/*!
    Returns a list of contact details of the specified \a contactType
*/
QList<QPlaceContactDetail> QPlace::contactDetails(const QString &contactType)
{
    Q_D(const QPlace);
    return d->contacts.value(contactType);
}

/*!
    Sets the contact \a details of a specified \a contactType.
*/
void QPlace::setContactDetails(const QString &contactType, QList<QPlaceContactDetail> details)
{
    Q_D(QPlace);
    if (details.isEmpty())
        d->contacts.remove(contactType);
    else
        d->contacts.insert(contactType, details);
}

/*!
    Appends a contact \a detail of a specified \a contactType.
*/
void QPlace::appendContactDetail(const QString &contactType, const QPlaceContactDetail &detail)
{
    Q_D(QPlace);
    QList<QPlaceContactDetail> details = d->contacts.value(contactType);
    details.append(detail);
    d->contacts.insert(contactType, details);
}

/*!
    Adds a single attribute to the place.  If the attribute already
    exists then the old value is overwritten.
*/
void QPlace::insertExtendedAttribute(const QString &key, const QPlaceAttribute &value)
{
    Q_D(QPlace);
    d->extendedAttributes.insert(key, value);
}

/*!
    Sets the visibility of the place to \a visibility.
*/
void QPlace::setVisibility(QtLocation::Visibility visibility)
{
    Q_D(QPlace);
    d->visibility = visibility;
}

/*!
    Returns the visibility of the place.
*/
QtLocation::Visibility QPlace::visibility() const
{
    Q_D(const QPlace);
    return d->visibility;
}

/*******************************************************************************
*******************************************************************************/

QPlacePrivate::QPlacePrivate()
:   QSharedData(), visibility(QtLocation::UnspecifiedVisibility), detailsFetched(false)
{
}

QPlacePrivate::QPlacePrivate(const QPlacePrivate &other)
        : QSharedData(other),
        categories(other.categories),
        location(other.location),
        rating(other.rating),
        supplier(other.supplier),
        name(other.name),
        placeId(other.placeId),
        attribution(other.attribution),
        contentCollections(other.contentCollections),
        contentCounts(other.contentCounts),
        contacts(other.contacts),
        extendedAttributes(other.extendedAttributes),
        visibility(other.visibility),
        detailsFetched(other.detailsFetched)
{
}

QPlacePrivate::~QPlacePrivate() {}

QPlacePrivate& QPlacePrivate::operator= (const QPlacePrivate & other)
{
    categories = other.categories;
    location = other.location;
    rating = other.rating;
    supplier = other.supplier;
    name = other.name;
    placeId = other.placeId;
    attribution = other.attribution;
    contentCollections = other.contentCollections;
    contentCounts = other.contentCounts;
    contacts = other.contacts;
    extendedAttributes = other.extendedAttributes;
    visibility = other.visibility;
    detailsFetched = other.detailsFetched;

    return *this;
}

bool QPlacePrivate::operator== (const QPlacePrivate &other) const
{
#ifdef QPLACE_DEBUG
    qDebug() << "categories: " << (categories == other.categories);
    qDebug() << "location:" << (location == other.location);
    qDebug() << "rating" << (rating == other.rating);
    qDebug() << "suppliers" << (suppliers == other.suppliers);
    qDebug() << "contentCollections " << (contentCollections == other.contentCollections);
    qDebug() << "contentCounts " << (contentCounts == other.contentCounts);
    qDebug() << "name " << (name == other.name);
    qDebug() << "placeId" << (placeId == other.placeId);
    qDebug() << "attribution" << (attribution == other.attribution);
    qDebug() << "contacts" << (contacts == other.contacts);
    qDebug() << "extendedAttributes" << (extendedAttributes == other.extendedAttributes);
    qDebug() << "visibility" << (visibility == other.visibility);
#endif

    return (categories == other.categories
            && location == other.location
            && rating == other.rating
            && supplier == other.supplier
            && contentCollections == other.contentCollections
            && contentCounts == other.contentCounts
            && name == other.name
            && placeId == other.placeId
            && attribution == other.attribution
            && contacts == other.contacts
            && extendedAttributes == other.extendedAttributes
            && visibility == other.visibility
            );
}

QT_END_NAMESPACE
<commit_msg>Fix icon not being properly copied and compared in QPlace<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qplace.h"
#include "qplace_p.h"

#ifdef QPLACE_DEBUG
#include <QDebug>
#endif

#include <QStringList>

QT_BEGIN_NAMESPACE

/*!
    \class QPlace
    \inmodule QtLocation
    \ingroup QtLocation-places
    \since QtLocation 5.0

    \brief The QPlace class represents basic information about a place.
*/

/*!
    Constructs an empty place object.
*/
QPlace::QPlace()
        : d_ptr(new QPlacePrivate())
{
}

/*!
    Constructs a copy of \a other.
*/
QPlace::QPlace(const QPlace &other)
        : d_ptr(other.d_ptr)
{
}

/*!
    Destroys this place.
*/
QPlace::~QPlace()
{
}

/*!
    Assigns \a other to this place and returns a reference
    to this place.
*/
QPlace &QPlace::operator= (const QPlace & other)
{
    d_ptr = other.d_ptr;
    return *this;
}

inline QPlacePrivate* QPlace::d_func()
{
    return static_cast<QPlacePrivate *>(d_ptr.data());
}

inline const QPlacePrivate* QPlace::d_func() const
{
    return static_cast<const QPlacePrivate *>(d_ptr.constData());
}

/*!
    Returns true if \a other is equal to this place,
    otherwise returns false.
*/
bool QPlace::operator== (const QPlace &other) const
{
    Q_D(const QPlace);
    return *d == *other.d_func();
}

/*!
    Returns true if \a other is not equal to this place,
    otherwise returns false.
*/
bool QPlace::operator!= (const QPlace &other) const
{
    Q_D(const QPlace);
    return !(*d == *other.d_func());
}

/*!
    Returns categories.
*/
QList<QPlaceCategory> QPlace::categories() const
{
    Q_D(const QPlace);
    return d->categories;
}

/*!
    Sets categories.
*/
void QPlace::setCategories(const QList<QPlaceCategory> &categories)
{
    Q_D(QPlace);
    d->categories = categories;
}

/*!
    Returns location.
*/
QGeoLocation QPlace::location() const
{
    Q_D(const QPlace);
    return d->location;
}

/*!
    Sets location.
*/
void QPlace::setLocation(const QGeoLocation &location)
{
    Q_D(QPlace);
    d->location = location;
}

/*!
    Returns rating.
*/
QPlaceRating QPlace::rating() const
{
    Q_D(const QPlace);
    return d->rating;
}

/*!
    Sets rating.
*/
void QPlace::setRating(const QPlaceRating &rating)
{
    Q_D(QPlace);
    d->rating = rating;
}

/*!
    Returns the supplier of this place data.
*/
QPlaceSupplier QPlace::supplier() const
{
    Q_D(const QPlace);
    return d->supplier;
}

/*!
    Sets the supplier of this place data to \a supplier.
*/
void QPlace::setSupplier(const QPlaceSupplier &supplier)
{
    Q_D(QPlace);
    d->supplier = supplier;
}

/*!
    Returns a collection of content associated with a place.
    This collection is a map with the key being the index of the content object
    and value being the content object itself.

    The \a type specifies which kind of content is to be retrieved.
*/
QPlaceContent::Collection QPlace::content(QPlaceContent::Type type) const
{
    Q_D(const QPlace);
    return d->contentCollections.value(type);
}

/*!
    Sets a collection of \a content for the given \a type.
*/
void QPlace::setContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
{
    Q_D(QPlace);
    d->contentCollections.insert(type, content);
}

/*!
    Adds a collection of \a content of the given \a type to the place.  Any index in \a content
    that already exists is overwritten.
*/
void QPlace::insertContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
{
    Q_D(QPlace);
    QMapIterator<int, QPlaceContent> iter(content);
    while (iter.hasNext()) {
        iter.next();
        d->contentCollections[type].insert(iter.key(), iter.value());
    }
}

/*!
    Returns the total count of content objects of the given \a type.
    This total count indicates how many the manager should have available.
    (As opposed to how many objects this place instance is currently assigned).
    A negative count indicates that the total number of items is unknown.
*/
int QPlace::totalContentCount(QPlaceContent::Type type) const
{
    Q_D(const QPlace);
    return d->contentCounts.value(type, 0);
}

/*!
    Sets the \a totalCount of content objects of the given \a type.
*/
void QPlace::setTotalContentCount(QPlaceContent::Type type, int totalCount)
{
    Q_D(QPlace);
    d->contentCounts.insert(type, totalCount);
}

/*!
    Returns name.
*/
QString QPlace::name() const
{
    Q_D(const QPlace);
    return d->name;
}

/*!
    Sets name.
*/
void QPlace::setName(const QString &name)
{
    Q_D(QPlace);
    d->name = name;
}

/*!
    Returns placeId.
*/
QString QPlace::placeId() const
{
    Q_D(const QPlace);
    return d->placeId;
}

/*!
    Sets placeId.
*/
void QPlace::setPlaceId(const QString &placeId)
{
    Q_D(QPlace);
    d->placeId = placeId;
}

/*!
    Returns a rich text attribution string of the place.  Note, some providers may have a
    requirement where the attribution must be shown whenever a place is displayed to an end user.
*/
QString QPlace::attribution() const
{
    Q_D(const QPlace);
    return d->attribution;
}

/*!
    Sets the attribution string of the place.
*/
void QPlace::setAttribution(const QString &attribution)
{
    Q_D(QPlace);
    d->attribution = attribution;
}

/*!
    Returns the icon of the place.
*/
QPlaceIcon QPlace::icon() const
{
    Q_D(const QPlace);
    return d->icon;
}

/*!
    Sets the icon of the place.
*/
void QPlace::setIcon(const QPlaceIcon &icon)
{
    Q_D(QPlace);
    d->icon = icon;
}

/*!
    Returns the primary phone number for this place.
*/
QString QPlace::primaryPhone() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> phoneNumbers = d->contacts.value(QPlaceContactDetail::Phone);
    if (!phoneNumbers.isEmpty())
        return phoneNumbers.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary fax number for this place.
*/
QString QPlace::primaryFax() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> faxNumbers = d->contacts.value(QPlaceContactDetail::Fax);
    if (!faxNumbers.isEmpty())
        return faxNumbers.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary email address for this place.
*/
QString QPlace::primaryEmail() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> emailAddresses = d->contacts.value(QPlaceContactDetail::Email);
    if (!emailAddresses.isEmpty())
        return emailAddresses.at(0).value();
    else
        return QString();
}

/*!
    Returns the primary URL of this place.
*/
QUrl QPlace::primaryWebsite() const
{
    Q_D(const QPlace);
    QList<QPlaceContactDetail> websites = d->contacts.value(QPlaceContactDetail::Website);
    if (!websites.isEmpty())
        return QUrl(websites.at(0).value().toAscii());
    else
        return QString();
}

/*!
    Returns whether the details of this place have been fetched or not.
*/
bool QPlace::detailsFetched() const
{
    Q_D(const QPlace);
    return d->detailsFetched;
}

/*!
    Sets whether the details of this place have been \a fetched or not.
*/
void QPlace::setDetailsFetched(bool fetched)
{
    Q_D(QPlace);
    d->detailsFetched = fetched;
}

/*!
    Returns the extended attributes of the place
*/
QPlace::ExtendedAttributes QPlace::extendedAttributes() const
{
    Q_D(const QPlace);
    return d->extendedAttributes;
}

/*!
    Sets the extended attributes of the place.
*/
void QPlace::setExtendedAttributes(const ExtendedAttributes &attributes)
{
    Q_D(QPlace);
    d->extendedAttributes = attributes;
}

/*!
    Returns the type of contact details this place has.
*/
QStringList QPlace::contactTypes() const
{
    Q_D(const QPlace);
    return d->contacts.keys();
}

/*!
    Returns a list of contact details of the specified \a contactType
*/
QList<QPlaceContactDetail> QPlace::contactDetails(const QString &contactType)
{
    Q_D(const QPlace);
    return d->contacts.value(contactType);
}

/*!
    Sets the contact \a details of a specified \a contactType.
*/
void QPlace::setContactDetails(const QString &contactType, QList<QPlaceContactDetail> details)
{
    Q_D(QPlace);
    if (details.isEmpty())
        d->contacts.remove(contactType);
    else
        d->contacts.insert(contactType, details);
}

/*!
    Appends a contact \a detail of a specified \a contactType.
*/
void QPlace::appendContactDetail(const QString &contactType, const QPlaceContactDetail &detail)
{
    Q_D(QPlace);
    QList<QPlaceContactDetail> details = d->contacts.value(contactType);
    details.append(detail);
    d->contacts.insert(contactType, details);
}

/*!
    Adds a single attribute to the place.  If the attribute already
    exists then the old value is overwritten.
*/
void QPlace::insertExtendedAttribute(const QString &key, const QPlaceAttribute &value)
{
    Q_D(QPlace);
    d->extendedAttributes.insert(key, value);
}

/*!
    Sets the visibility of the place to \a visibility.
*/
void QPlace::setVisibility(QtLocation::Visibility visibility)
{
    Q_D(QPlace);
    d->visibility = visibility;
}

/*!
    Returns the visibility of the place.
*/
QtLocation::Visibility QPlace::visibility() const
{
    Q_D(const QPlace);
    return d->visibility;
}

/*******************************************************************************
*******************************************************************************/

QPlacePrivate::QPlacePrivate()
:   QSharedData(), visibility(QtLocation::UnspecifiedVisibility), detailsFetched(false)
{
}

QPlacePrivate::QPlacePrivate(const QPlacePrivate &other)
        : QSharedData(other),
        categories(other.categories),
        location(other.location),
        rating(other.rating),
        supplier(other.supplier),
        name(other.name),
        placeId(other.placeId),
        attribution(other.attribution),
        contentCollections(other.contentCollections),
        contentCounts(other.contentCounts),
        contacts(other.contacts),
        extendedAttributes(other.extendedAttributes),
        visibility(other.visibility),
        detailsFetched(other.detailsFetched),
        icon(other.icon)
{
}

QPlacePrivate::~QPlacePrivate() {}

QPlacePrivate& QPlacePrivate::operator= (const QPlacePrivate & other)
{
    categories = other.categories;
    location = other.location;
    rating = other.rating;
    supplier = other.supplier;
    name = other.name;
    placeId = other.placeId;
    attribution = other.attribution;
    contentCollections = other.contentCollections;
    contentCounts = other.contentCounts;
    contacts = other.contacts;
    extendedAttributes = other.extendedAttributes;
    visibility = other.visibility;
    detailsFetched = other.detailsFetched;
    icon = other.icon;

    return *this;
}

bool QPlacePrivate::operator== (const QPlacePrivate &other) const
{
#ifdef QPLACE_DEBUG
    qDebug() << "categories: " << (categories == other.categories);
    qDebug() << "location:" << (location == other.location);
    qDebug() << "rating" << (rating == other.rating);
    qDebug() << "suppliers" << (suppliers == other.suppliers);
    qDebug() << "contentCollections " << (contentCollections == other.contentCollections);
    qDebug() << "contentCounts " << (contentCounts == other.contentCounts);
    qDebug() << "name " << (name == other.name);
    qDebug() << "placeId" << (placeId == other.placeId);
    qDebug() << "attribution" << (attribution == other.attribution);
    qDebug() << "contacts" << (contacts == other.contacts);
    qDebug() << "extendedAttributes" << (extendedAttributes == other.extendedAttributes);
    qDebug() << "visibility" << (visibility == other.visibility);
    qDebug() << "icon" << (icon == other.icon);
#endif

    return (categories == other.categories
            && location == other.location
            && rating == other.rating
            && supplier == other.supplier
            && contentCollections == other.contentCollections
            && contentCounts == other.contentCounts
            && name == other.name
            && placeId == other.placeId
            && attribution == other.attribution
            && contacts == other.contacts
            && extendedAttributes == other.extendedAttributes
            && visibility == other.visibility
            && icon == other.icon
            );
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>///
/// @file   api.cpp
/// @brief  primesieve C++ API.
///         Contains the implementations of the functions declared
///         in the primesieve.hpp header file.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve.hpp>
#include <primesieve/CpuInfo.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/ParallelSieve.hpp>

#include <stdint.h>
#include <cstddef>
#include <limits>
#include <string>

namespace {

int sieve_size = 0;

int num_threads = 0;

}

namespace primesieve {

uint64_t nth_prime(int64_t n, uint64_t start)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  return ps.nthPrime(n, start);
}

uint64_t count_primes(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_PRIMES);
  return ps.getCount(0);
}

uint64_t count_twins(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_TWINS);
  return ps.getCount(1);
}

uint64_t count_triplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_TRIPLETS);
  return ps.getCount(2);
}

uint64_t count_quadruplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_QUADRUPLETS);
  return ps.getCount(3);
}

uint64_t count_quintuplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_QUINTUPLETS);
  return ps.getCount(4);
}

uint64_t count_sextuplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_SEXTUPLETS);
  return ps.getCount(5);
}

void print_primes(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_PRIMES);
}

void print_twins(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_TWINS);
}

void print_triplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_TRIPLETS);
}

void print_quadruplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_QUADRUPLETS);
}

void print_quintuplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_QUINTUPLETS);
}

void print_sextuplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_SEXTUPLETS);
}

int get_num_threads()
{
  if (num_threads)
    return num_threads;
  else
    return ParallelSieve::getMaxThreads();
}

void set_num_threads(int threads)
{
  num_threads = inBetween(1, threads, ParallelSieve::getMaxThreads());
}

uint64_t get_max_stop()
{
  return std::numeric_limits<uint64_t>::max();
}

std::string primesieve_version()
{
  return PRIMESIEVE_VERSION;
}

void set_sieve_size(int size)
{
  sieve_size = inBetween(8, size, 4096);
  sieve_size = floorPow2(sieve_size);
}

int get_sieve_size()
{
  // user specified sieve size
  if (sieve_size)
    return sieve_size;

  // We use the L2 cache size as sieve size only if the L2
  // cache is not shared by multiple physical CPU cores.
  // Also we use a sieve size that is slightly smaller than
  // the L2 cache size because we want to reduce the number
  // of L2 cache misses (because the L3 cache is slow).
  if (cpuInfo.hasPrivateL2Cache())
  {
    // convert bytes to KiB
    size_t size = cpuInfo.l2CacheSize() >> 10;
    size = size - 1;
    size = inBetween(32, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
  else if (cpuInfo.hasL1Cache())
  {
    // convert bytes to KiB
    size_t size = cpuInfo.l1CacheSize() >> 10;
    size = inBetween(8, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
  else
  {
    // default sieve size in KiB
    size_t size = 32;
    size = inBetween(8, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
}

} // namespace
<commit_msg>Update L2 cache comment<commit_after>///
/// @file   api.cpp
/// @brief  primesieve C++ API.
///         Contains the implementations of the functions declared
///         in the primesieve.hpp header file.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve.hpp>
#include <primesieve/CpuInfo.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/ParallelSieve.hpp>

#include <stdint.h>
#include <cstddef>
#include <limits>
#include <string>

namespace {

int sieve_size = 0;

int num_threads = 0;

}

namespace primesieve {

uint64_t nth_prime(int64_t n, uint64_t start)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  return ps.nthPrime(n, start);
}

uint64_t count_primes(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_PRIMES);
  return ps.getCount(0);
}

uint64_t count_twins(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_TWINS);
  return ps.getCount(1);
}

uint64_t count_triplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_TRIPLETS);
  return ps.getCount(2);
}

uint64_t count_quadruplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_QUADRUPLETS);
  return ps.getCount(3);
}

uint64_t count_quintuplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_QUINTUPLETS);
  return ps.getCount(4);
}

uint64_t count_sextuplets(uint64_t start, uint64_t stop)
{
  ParallelSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.setNumThreads(get_num_threads());
  ps.sieve(start, stop, COUNT_SEXTUPLETS);
  return ps.getCount(5);
}

void print_primes(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_PRIMES);
}

void print_twins(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_TWINS);
}

void print_triplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_TRIPLETS);
}

void print_quadruplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_QUADRUPLETS);
}

void print_quintuplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_QUINTUPLETS);
}

void print_sextuplets(uint64_t start, uint64_t stop)
{
  PrimeSieve ps;
  ps.setSieveSize(get_sieve_size());
  ps.sieve(start, stop, PRINT_SEXTUPLETS);
}

int get_num_threads()
{
  if (num_threads)
    return num_threads;
  else
    return ParallelSieve::getMaxThreads();
}

void set_num_threads(int threads)
{
  num_threads = inBetween(1, threads, ParallelSieve::getMaxThreads());
}

uint64_t get_max_stop()
{
  return std::numeric_limits<uint64_t>::max();
}

std::string primesieve_version()
{
  return PRIMESIEVE_VERSION;
}

void set_sieve_size(int size)
{
  sieve_size = inBetween(8, size, 4096);
  sieve_size = floorPow2(sieve_size);
}

int get_sieve_size()
{
  // user specified sieve size
  if (sieve_size)
    return sieve_size;

  // We use the L2 cache for sieving only if we can assume
  // that it is fast. There are two rules that help us
  // identify whether the L2 cache is fast or not.
  // Rule 1: Shared CPU caches are slow.
  // Rule 2: The last level CPU cache is slow.
  // Also we use a sieve size that is slightly smaller than
  // the L2 cache size because we want to reduce the number
  // of L2 cache misses (because the L3 cache is slow).
  if (cpuInfo.hasPrivateL2Cache() &&
      cpuInfo.hasL3Cache())
  {
    // convert bytes to KiB
    size_t size = cpuInfo.l2CacheSize() >> 10;
    size = size - 1;
    size = inBetween(32, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
  else if (cpuInfo.hasL1Cache())
  {
    // convert bytes to KiB
    size_t size = cpuInfo.l1CacheSize() >> 10;
    size = inBetween(8, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
  else
  {
    // default sieve size in KiB
    size_t size = 32;
    size = inBetween(8, size, 4096);
    size = floorPow2(size);
    return (int) size;
  }
}

} // namespace
<|endoftext|>


<commit_before>/**
   @file ast.cpp
   @brief Implementation file for AST-related classes
   @copyright 2014 Assured Information Security, Inc.
   @author Jacob Torrey <torreyj@ainfosec.com>

   Stores the implementations for the AST classes. Includes pretty-printing logic
   and some operator overloads for AST manipulation and analysis.
*/
#include "ast.h"
#include "parser.h"

/**
   Overload for the == operator to allow for simple comparison of two NIdentifiers.
   The NIdentifier values being compared are of type string, which represent the names of
   variables, lists, structs, struct members, etc.

   @param i1 First NIdentifier to compare
   @param i2 Second NIdentifier to compare
   @return true if the Identifiers resolve to the same value, false otherwise
*/
bool operator==(const NIdentifier & i1, const NIdentifier & i2)
{
  return i1.value == i2.value;
}

/**
   Overload for the << operator to allow pretty printing of AST objects and AST as a whole

   @param os Output stream to print to
   @param node Node to pretty-print
   @return Output stream passed in
*/
std::ostream & operator<<(std::ostream & os, const Node & node)
{
  node.print(os);
  return os;
}

/**
   Print function for NBlock objects in the AST. Each block is composed of a vector of
   statements. This function iterators over the typedef std::vector<NStatement*> StatementList,
   printing each each statement in a given block, and returning the output stream.

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NBlock::print(std::ostream & os) const
{
    os << "Block: {" << std::endl;

    for (StatementList::const_iterator it = statements.begin(); it != statements.end(); ++it)
      os << *(*it) << std::endl;

    os << "}" << std::endl;
    return os;
}

/**
   Print function for NVariableDeclaration objects. There are three members of the
   NVariableDeclaration object that are printed:

   1) Type
   2) NIdentifier (Variable name)
   3) Associated value or RHS (optional)

   The initializationExpression is the RHS in variable assignments (e.g. the 4 in int a = 4).
   If initializationExpression is NULL, then the no value was assigned to variable (e.g. int a).

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NVariableDeclaration::print(std::ostream & os) const
{
  if (!type.isList)
  {
      os << "Variable declared --- (" << type << " " << ident << ")";
  }
  else
  {
      os << "List declared --- (" << type << " " << ident << "[])";
  }
  if (initializationExpression != NULL)
  {
      os << " = " << *initializationExpression;
  }
  os << std::endl;
  return os;
}

/**
   Print function for NFunctionDeclaration objects. It first prints the return type
   and name of the function followed by the arguments contained within the
   typedef std::vector<NVariableDeclaration *> VariableList. Then, the NBlock body
   of the function is printed.

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NFunctionDeclaration::print(std::ostream & os) const
{
  os << "Function declared --- (" << type << " " << ident << "(";

  for (VariableList::const_iterator it = variables.begin(); it != variables.end(); ++it)
      os << *(*it) << ") ";

  os << *body << ")";
  os << std::endl;

  return os;
}

std::ostream & NStructureDeclaration::print(std::ostream & os) const
{
  os << "Struct declared --- (" << ident << " {";
  for (int i = 0; i < members.size(); i++)
    {
      os << *(members[i]) << " ";
    }
  os << "})";
  os << std::endl;

  return os;
}

std::ostream & NAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << ident << " = " << expr << ")" << std::endl;
  return os;
}

std::ostream & NListAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << list << " = " << expr << "<" << std::endl;
  return os;
}

std::ostream & NStructureAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << structure << " = " << expr << ")" << std::endl;
  return os;
}

std::ostream & NBinaryOperator::print(std::ostream & os) const
{
  std::string symbol;
  switch(op)
  {
  case TMUL:
      symbol = "*";
      break;
  case TADD:
      symbol = "+";
      break;
  case TDIV:
      symbol = "/";
      break;
  case TSUB:
      symbol = "-";
      break;
  case TMOD:
      symbol = "%";
      break;
  case TBAND:
      symbol = "&";
      break;
  case TBXOR:
      symbol = "^";
      break;
  case TBOR:
      symbol = "|";
      break;
  case TLNOT:
      symbol = "!";
      break;
  case TLOR:
      symbol = "||";
      break;
  case TLAND:
      symbol = "&&";
      break;
  default:
      symbol = "UNKNOWN OP";
      break;

  }
  os << "(BINOP: " << lhs << " " << symbol << " " << rhs << ")" << std::endl;
  return os;
}

std::ostream & NIdentifier::print(std::ostream & os) const
{
  os << "Identifier: " << value;
  return os;
}

std::ostream & NListAccess::print(std::ostream & os) const
{
  os << "(List access: " << ident << "[" << index << "])";
  return os;
}

std::ostream & NVariableAccess::print(std::ostream & os) const
{
  os << "(Variable access: " << ident << ")";
  return os;
}

std::ostream & NStructureAccess::print(std::ostream & os) const
{
  os << "(Struct access: " << ident << "." << member << ")";
  return os;
}

std::ostream & NReturn::print(std::ostream & os) const
{
  os << "(Return: " << retExpr << ")";
  os << std::endl;
  return os;
}

std::ostream & NDouble::print(std::ostream & os) const
{
  os << "DOUBLE:" << value;
  return os;
}

std::ostream & NBool::print(std::ostream & os) const
{
  os << "BOOL:" << value;
  return os;
}

std::ostream & NInt::print(std::ostream & os) const
{
  os << "INT:" << value;
  return os;
}

std::ostream & NValue::print(std::ostream & os) const
{
  os << "(Generic NValue)" << std::endl;
  return os;
}

std::ostream & NUInt::print(std::ostream & os) const
{
  os << "UINT:" << value;
  return os;
}

std::ostream & NString::print(std::ostream & os) const
{
  os << "STRING:" << value;
  return os;
}

std::ostream & NLoopStatement::print(std::ostream & os) const
{
  os << "Loop: " << list << " as " << asVar << std::endl;
  os << "{" << loopBlock << "}" << std::endl;
  return os;
}

std::ostream & NIfStatement::print(std::ostream & os) const
{
  if (elseblock == NULL && elseif == NULL)
    os << "If: (" << condition << ") then " << thenblock << std::endl;
  if (elseblock != NULL && elseif == NULL)
    os << "If: (" << condition << ") then: " << thenblock << " else: " << *(elseblock) << std::endl;
  if (elseblock == NULL && elseif != NULL)
    {
      os << "If: (" << condition << ") then " << thenblock << std::endl;
      os << "Else if: " << *(elseif) << std::endl;
    }
  if (elseblock != NULL && elseif != NULL)
    {
      os << "If: (" << condition << ") then " << thenblock << std::endl;
      os << "Else if: " << *(elseif) << " else: " << *(elseblock) << std::endl;
    }
  return os;
}

std::ostream & NFunctionCall::print(std::ostream & os) const
{
  os << "Function Call: " << ident << std::endl;
  for (int i = 0; i < args.size(); i++)
    {
      os << args[i] << std::endl;
    }
  return os;
}

std::ostream & NList::print(std::ostream & os) const
{
    os << "List: [";
    for (int i = 0; i < value.size(); i++)
    {
	os << *(value[i]) << " ";
    }
    os << "]" << std::endl;
    return os;
}
<commit_msg>Adding more comments and improving print functions in ast.cpp<commit_after>/**
   @file ast.cpp
   @brief Implementation file for AST-related classes
   @copyright 2014 Assured Information Security, Inc.
   @author Jacob Torrey <torreyj@ainfosec.com>

   Stores the implementations for the AST classes. Includes pretty-printing logic
   and some operator overloads for AST manipulation and analysis.
*/
#include "ast.h"
#include "parser.h"

/**
   Overload for the == operator to allow for simple comparison of two NIdentifiers.
   The NIdentifier values being compared are of type string, which represent the names of
   variables, lists, structs, struct members, etc.

   @param i1 First NIdentifier to compare
   @param i2 Second NIdentifier to compare
   @return true if the Identifiers resolve to the same value, false otherwise
*/
bool operator==(const NIdentifier & i1, const NIdentifier & i2)
{
  return i1.value == i2.value;
}

/**
   Overload for the << operator to allow pretty printing of AST objects and AST as a whole

   @param os Output stream to print to
   @param node Node to pretty-print
   @return Output stream passed in
*/
std::ostream & operator<<(std::ostream & os, const Node & node)
{
  node.print(os);
  return os;
}

/**
   Print function for NBlock objects in the AST. Each block is composed of a vector of
   statements. This function iterators over the typedef std::vector<NStatement*> StatementList,
   printing each each statement in a given block, and returning the output stream.

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NBlock::print(std::ostream & os) const
{
    os << "Block: {" << std::endl;

    for (StatementList::const_iterator it = statements.begin(); it != statements.end(); ++it)
      os << *(*it) << std::endl;

    os << "}" << std::endl;
    return os;
}

/**
   Print function for NVariableDeclaration objects. There are three members of the
   NVariableDeclaration object that are printed:

   1) Type
   2) NIdentifier (Variable name)
   3) Associated value or RHS (optional)

   The initializationExpression is the RHS in variable assignments (e.g. the 4 in int a = 4).
   If initializationExpression is NULL, then the no value was assigned to variable (e.g. int a).

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NVariableDeclaration::print(std::ostream & os) const
{
  if (!type.isList)
  {
      os << "Variable declared --- (" << type << " " << ident << ")";
  }
  else
  {
      os << "List declared --- (" << type << " " << ident << "[])";
  }
  if (initializationExpression != NULL)
  {
      os << " = " << *initializationExpression;
  }
  os << std::endl;
  return os;
}

/**
   Print function for NFunctionDeclaration objects. It first prints the return type
   and name of the function followed by the arguments contained within the
   typedef std::vector<NVariableDeclaration *> VariableList. Then, the NBlock body
   of the function is printed.

   @param os Output stream to print to
   @return Output stream passed in
*/
std::ostream & NFunctionDeclaration::print(std::ostream & os) const
{
  os << "Function declared --- (" << type << " " << ident << "(";

  for (VariableList::const_iterator it = variables.begin(); it != variables.end(); ++it)
      os << *(*it) << ") ";

  os << *body << ")";
  os << std::endl;

  return os;
}

/**
   Print function for NStructureDeclaration objects. It first prints the name of the
   struct followed by its typedef std::vector<NVariableDeclaration *> VariableList
   members.

   @params os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NStructureDeclaration::print(std::ostream & os) const
{
  os << "Struct declared --- (" << ident << " {";

  for (VariableList::const_iterator it = members.begin(); it != members.end(); ++it)
      os << *(*it) << " ";

  os << "})";
  os << std::endl;

  return os;
}

/**
   Print function for NAssignmentStatement objects, which are inherited from the
   NStatement class. Similar to the NVariableDeclaration, this object is used
   after a variable has been declared, but is subsequently given a value in
   another statement. For example, the second statement in,
      int a
      a = 4
   is the assignment statement.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << ident << " = " << expr << ")" << std::endl;
  return os;
}

/**
   Print function for NListAssignmentStatement objects, which are inherited from the
   NAssignmentStatement class. The NListAccess &list variable that is printed contains the
   name (NIdentifier &ident) and the index (NExpression &index) of each element in
   the list. The expr value is the RHS of the expression in the assignment statement.
   (Not to be confused with a declaration statement.)

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NListAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << list << " = " << expr << "<" << std::endl;
  return os;
}

/**
   Print function for NStructureAssignmentStatement objects, which are inherited from
   the NAssignmentStatement class. The NStructure &structure variable that is printed
   contains the structure name (NIdentifier &ident) and its members (NIdentifier &member).
   The expr value is the RHS of the expression in the assignment statement. (Not to be
   confused with a declaration statement.)

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NStructureAssignmentStatement::print(std::ostream & os) const
{
  os << "(Assignment: " << structure << " = " << expr << ")" << std::endl;
  return os;
}

/**
   Print function for NBinaryOperator objects, which are inherited from the NExpression
   class. This function prints the LHS, the binary operator symbol, followed by the RHS
   of the expression.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NBinaryOperator::print(std::ostream & os) const
{
  std::string symbol;
  switch(op)
  {
  case TMUL:
      symbol = "*";
      break;
  case TADD:
      symbol = "+";
      break;
  case TDIV:
      symbol = "/";
      break;
  case TSUB:
      symbol = "-";
      break;
  case TMOD:
      symbol = "%";
      break;
  case TBAND:
      symbol = "&";
      break;
  case TBXOR:
      symbol = "^";
      break;
  case TBOR:
      symbol = "|";
      break;
  case TLNOT:
      symbol = "!";
      break;
  case TLOR:
      symbol = "||";
      break;
  case TLAND:
      symbol = "&&";
      break;
  case TCEQ:
      symbol = "==";
      break;
  default:
      symbol = "UNKNOWN OP";
      break;

  }
  os << "(BINOP: " << lhs << " " << symbol << " " << rhs << ")" << std::endl;
  return os;
}

/**
   Prints the name of a given NIdentifier object. (Note: the variable 'value'
   is a string.)

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NIdentifier::print(std::ostream & os) const
{
  os << "Identifier: " << value;
  return os;
}

/**
   Prints an NListAccess object, which is a list element containing an NIdentifier &ident
   and an NExpression &index. (Note: an index may be more than just an integer, like a[1+2]
   would be the third element in a list.)

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NListAccess::print(std::ostream & os) const
{
  os << "(List access: " << ident << "[" << index << "])";
  return os;
}

/**
   Prints an NVariableAccess object, which is inherited from NExpression and contains an
   NIdentifier &ident member. The ident variable is the name of the variable being accessed.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NVariableAccess::print(std::ostream & os) const
{
  os << "(Variable access: " << ident << ")";
  return os;
}

/**
   Prints an NStructureAccess object, which is inherited from the NExpression class and contains both
   an NIdentifier &ident member (the struct name) and an NIdentifier &member member (the
   struct's member name being accessed).

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NStructureAccess::print(std::ostream & os) const
{
  os << "(Struct access: " << ident << "." << member << ")";
  return os;
}

/**
   Prints an NReturn object, which is inherited from the NStatement class. The retExpr variable
   is of type NExpression.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NReturn::print(std::ostream & os) const
{
  os << "(Return: " << retExpr << ")";
  os << std::endl;
  return os;
}

/**
   Prints an NDouble object, which is inherited from the NValue class. The variable 'value'
   that is printed is the number itself, not the string name of the identifier.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NDouble::print(std::ostream & os) const
{
  os << "DOUBLE:" << value;
  return os;
}

/**
   Prints an NBool object, which is inherited from the NValue class. The variable 'value'
   that is printed is 'true (1)' or 'false (0)', not the string name of the identifier.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NBool::print(std::ostream & os) const
{
  os << "BOOL:" << value;
  return os;
}

/**
   Prints an NInt object, which is inherited from the NValue class. The variable 'value'
   that is printed is the number itself, not the string name of the identifier.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NInt::print(std::ostream & os) const
{
  os << "INT:" << value;
  return os;
}

/**
   Print function that allows for the genertic printing of an NValue object. The NValue
   class does not contain any variables, thus there are not any variables printed to the
   output stream in this function.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NValue::print(std::ostream & os) const
{
  os << "(Generic NValue)" << std::endl;
  return os;
}

/**
   Prints an NUInt object, which is inherited from the NValue class. The variable 'value'
   that is printed is the number itself, not the string name of the identifier.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NUInt::print(std::ostream & os) const
{
  os << "UINT:" << value;
  return os;
}

/**
   Prints an NString object, which is inherited from the NValue class. The variable 'value'
   that is printed is the string itself, not the string name of the identifier.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NString::print(std::ostream & os) const
{
  os << "STRING:" << value;
  return os;
}

/**
   Prints NLoopStatement objects, which are inherited from the NStatement class. The variable
   NIdentifer &list is the list variable name that is being looped through. NIdentifier &asVar
   is the temporary name inside of the loop block to reference the current list element. And
   the NBlock &loopBlock are the statements contained with in the braces of the loop statement.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NLoopStatement::print(std::ostream & os) const
{
  os << "Loop: " << list << " as " << asVar << std::endl;
  os << "{" << loopBlock << "}" << std::endl;
  return os;
}

/**
   Prints NIfStatement objects, which are inherited from the NStatement class. There are four
   possible members that may be printed:
    1) NExpression &condition, the 'if' condition in parentheses
    2) NBlock &thenblock, the series of statements that follow the 'if' condition
    3) NBlock *elseblock, a pointer to a statement or series of statements for 'else' conditions
    4) NStatement *elseif, a pointer to one statement completing the 'if' statement

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NIfStatement::print(std::ostream & os) const
{
  if (elseblock == NULL && elseif == NULL)
    os << "If: (" << condition << ") then " << thenblock << std::endl;
  if (elseblock != NULL && elseif == NULL)
    os << "If: (" << condition << ") then: " << thenblock << " else: " << *(elseblock) << std::endl;
  if (elseblock == NULL && elseif != NULL)
    {
      os << "If: (" << condition << ") then " << thenblock << std::endl;
      os << "Else if: " << *(elseif) << std::endl;
    }
  if (elseblock != NULL && elseif != NULL)
    {
      os << "If: (" << condition << ") then " << thenblock << std::endl;
      os << "Else if: " << *(elseif) << " else: " << *(elseblock) << std::endl;
    }
  return os;
}

/**
   Prints FunctionCall objects, which are inherited from the NExpression class. The 'args'
   variable is a typedef std::vector<NExpression *> ExpressionList and contains the arguments
   passed to the function.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NFunctionCall::print(std::ostream & os) const
{
  os << "Function Call: " << ident << std::endl;

  for(ExpressionList::const_iterator it = args.begin(); it != args.end(); ++it)
      os << *(*it) << std::endl;

  return os;
}

/**
   Prints NList objects, which are inherited from the NValue class. The 'value' variable
   is a typedef std::vector<NExpression *> ExpressionList and contains the values of the
   list items, not the names of the items.

   @param os Output stream to print to
   @return Output stream passed on
*/
std::ostream & NList::print(std::ostream & os) const
{
    os << "List: [";

    for (ExpressionList::const_iterator it = value.begin(); it != value.end(); ++it)
        os << *(*it) << " ";

    os << "]" << std::endl;
    return os;
}
<|endoftext|>


<commit_before>#include <boost/program_options.hpp>

#include <boost/graph/use_mpi.hpp>
#include <boost/graph/distributed/graphviz.hpp>
#include <boost/graph/distributed/page_rank.hpp>

#include <iostream>
#include <iterator>
#include <vector>

#include "social_graph.hpp"
#include "degree_centrality.hpp"
#include "node_strength.hpp"
#include "graph_loaders.hpp"
#include "benchmark.hpp"

namespace po = boost::program_options;

void usage(char *execname, po::options_description &desc)
{
    std::cout << "Usage: " << execname << " [options] <filename>" << std::endl << desc;
}

int main(int argc, char *argv[])
{
    mpi::environment env(argc, argv);

    Graph g;

    bool is_root_proc = (process_id(g.process_group()) == 0);

    // Option definition
    po::options_description generic_opts("Generic options");
    bool verbose;
    generic_opts.add_options()
    ("help,h", "print this message")
    ("verbose,v", po::bool_switch(&verbose), "print some info while processing")
    ;

    po::options_description io_opts("Input/Output options");
    std::string ofile, iformat;
    io_opts.add_options()
    ("output,o", po::value(&ofile), "save output to file 'arg'")
    ("input-format,f", po::value(&iformat), "treat input as [csv]")
    ;

    po::options_description hidden_opts("Hidden options");
    std::string ifile;
    hidden_opts.add_options()
    ("input-file", po::value(&ifile), "input file");

    // first command line token with no name: input-file
    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description cmdline_opts;
    cmdline_opts.add(generic_opts).add(io_opts).add(hidden_opts);

    po::options_description visible_opts;
    visible_opts.add(generic_opts).add(io_opts);
    // end of option definition

    std::istream *input;
    std::ostream *output;

    try {
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(cmdline_opts).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("help")) {
            if (is_root_proc) {
                usage(argv[0], visible_opts);
            }

            return 0;
        }

        if (vm.count("output")) {
            output = new std::ofstream(ofile.c_str());

        } else {
            output = &std::cout;
        }

        if (is_root_proc) {
            if (vm.count("input-file")) {
                input = new std::ifstream(ifile.c_str());

            } else {
                input = &std::cin;
            }

            BENCHMARK(sigsna::load_graph_from_csv(*input, g));
        }

    } catch (std::exception& e) {
        if (is_root_proc) {
            std::cout << "Error: " << e.what() << std::endl;
            usage(argv[0], visible_opts);
        }

        return 1;
    }

    synchronize(g.process_group());

    VertexUIntMap in_degree_map = get(&Person::in_degree, g);
    BENCHMARK(all_in_degree_values(g, in_degree_map));

    VertexUIntMap out_degree_map = get(&Person::out_degree, g);
    BENCHMARK(all_out_degree_values(g, out_degree_map));

    EdgeUIntMap edge_weight_map = get(&Relationship::weight, g);
    VertexUIntMap in_strength_map = get(&Person::in_strength, g);
    BENCHMARK(all_in_strength_values(g, in_strength_map, edge_weight_map));

    VertexUIntMap out_strength_map = get(&Person::out_strength, g);
    BENCHMARK(all_out_strength_values(g, out_strength_map, edge_weight_map));

    VertexFloatMap pagerank_map = get(&Person::pagerank, g);
    BENCHMARK(page_rank(g, pagerank_map));

    VertexNameMap name_map = get(&Person::name, g);
    BENCHMARK(write_graphviz(*output, g, make_all_measures_writer(name_map, in_degree_map, out_degree_map, in_strength_map, out_strength_map, pagerank_map)));

    if (verbose) {
        std::ostringstream oss;
        mpi::communicator world;

        oss << "Process " << world.rank() << ":" << std::endl;
        benchmark::write_log(oss);

        // Gather and print
        std::vector<std::string> thelog;

        if (is_root_proc) {
            mpi::gather(world, oss.str(), thelog, 0);

            for (std::vector<std::string>::iterator i = thelog.begin(); i != thelog.end(); ++i) {
                std::cerr << *i;
            }
        } else {
            mpi::gather(world, oss.str(), 0);
        }
    }

    return 0;
}<commit_msg>Removed BENCHMARK macros from cli.cpp<commit_after>#include <boost/program_options.hpp>

#include <boost/graph/use_mpi.hpp>
#include <boost/graph/distributed/graphviz.hpp>
#include <boost/graph/distributed/page_rank.hpp>

#include <iostream>
#include <iterator>
#include <vector>

#include "social_graph.hpp"
#include "degree_centrality.hpp"
#include "node_strength.hpp"
#include "graph_loaders.hpp"
#include "benchmark.hpp"

namespace po = boost::program_options;

void usage(char *execname, po::options_description &desc)
{
    std::cout << "Usage: " << execname << " [options] <filename>" << std::endl << desc;
}

int main(int argc, char *argv[])
{
    mpi::environment env(argc, argv);

    Graph g;

    bool is_root_proc = (process_id(g.process_group()) == 0);

    // Option definition
    po::options_description generic_opts("Generic options");
    bool verbose;
    generic_opts.add_options()
    ("help,h", "print this message")
    ("verbose,v", po::bool_switch(&verbose), "print some info while processing")
    ;

    po::options_description io_opts("Input/Output options");
    std::string ofile, iformat;
    io_opts.add_options()
    ("output,o", po::value(&ofile), "save output to file 'arg'")
    ("input-format,f", po::value(&iformat), "treat input as [csv]")
    ;

    po::options_description hidden_opts("Hidden options");
    std::string ifile;
    hidden_opts.add_options()
    ("input-file", po::value(&ifile), "input file");

    // first command line token with no name: input-file
    po::positional_options_description p;
    p.add("input-file", -1);

    po::options_description cmdline_opts;
    cmdline_opts.add(generic_opts).add(io_opts).add(hidden_opts);

    po::options_description visible_opts;
    visible_opts.add(generic_opts).add(io_opts);
    // end of option definition

    std::istream *input;
    std::ostream *output;

    try {
        po::variables_map vm;
        po::store(po::command_line_parser(argc, argv).options(cmdline_opts).positional(p).run(), vm);
        po::notify(vm);

        if (vm.count("help")) {
            if (is_root_proc) {
                usage(argv[0], visible_opts);
            }

            return 0;
        }

        if (vm.count("output")) {
            output = new std::ofstream(ofile.c_str());

        } else {
            output = &std::cout;
        }

        if (is_root_proc) {
            if (vm.count("input-file")) {
                input = new std::ifstream(ifile.c_str());

            } else {
                input = &std::cin;
            }

            sigsna::load_graph_from_csv(*input, g);
        }

    } catch (std::exception& e) {
        if (is_root_proc) {
            std::cout << "Error: " << e.what() << std::endl;
            usage(argv[0], visible_opts);
        }

        return 1;
    }

    synchronize(g.process_group());

    VertexUIntMap in_degree_map = get(&Person::in_degree, g);
    all_in_degree_values(g, in_degree_map);

    VertexUIntMap out_degree_map = get(&Person::out_degree, g);
    all_out_degree_values(g, out_degree_map);

    EdgeUIntMap edge_weight_map = get(&Relationship::weight, g);
    VertexUIntMap in_strength_map = get(&Person::in_strength, g);
    all_in_strength_values(g, in_strength_map, edge_weight_map);

    VertexUIntMap out_strength_map = get(&Person::out_strength, g);
    all_out_strength_values(g, out_strength_map, edge_weight_map);

    VertexFloatMap pagerank_map = get(&Person::pagerank, g);
    page_rank(g, pagerank_map);

    VertexNameMap name_map = get(&Person::name, g);
    write_graphviz(*output, g, make_all_measures_writer(name_map, in_degree_map, out_degree_map, in_strength_map, out_strength_map, pagerank_map));

    return 0;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2011, Tim Branyen @tbranyen <tim@tabdeveloper.com>
*/

#include <v8.h>
#include <node.h>

#include "../vendor/libgit2/include/git2.h"

#include "../include/reference.h"
#include "../include/sig.h"
#include "../include/error.h"
#include "../include/blob.h"
#include "../include/repo.h"
#include "../include/oid.h"
#include "../include/object.h"
#include "../include/commit.h"
#include "../include/revwalk.h"
#include "../include/tree.h"
#include "../include/tree_entry.h"
#include "../include/diff_list.h"
#include "../include/threads.h"

extern "C" void init(Handle<v8::Object> target) {
  HandleScope scope;

  GitError::Initialize(target);

  GitReference::Initialize(target);
  GitSig::Initialize(target);
  GitBlob::Initialize(target);
  GitOid::Initialize(target);
  GitObject::Initialize(target);
  GitRepo::Initialize(target);
  GitCommit::Initialize(target);
  GitRevWalk::Initialize(target);

  GitTree::Initialize(target);
  GitTreeEntry::Initialize(target);

  GitDiffList::Initialize(target);

  GitThreads::Initialize(target);
}
<commit_msg>Updated base.cc to export module for node 0.10.0<commit_after>/*
Copyright (c) 2011, Tim Branyen @tbranyen <tim@tabdeveloper.com>
*/

#include <v8.h>
#include <node.h>

#include "../vendor/libgit2/include/git2.h"

#include "../include/reference.h"
#include "../include/sig.h"
#include "../include/error.h"
#include "../include/blob.h"
#include "../include/repo.h"
#include "../include/oid.h"
#include "../include/object.h"
#include "../include/commit.h"
#include "../include/revwalk.h"
#include "../include/tree.h"
#include "../include/tree_entry.h"
#include "../include/diff_list.h"
#include "../include/threads.h"

extern "C" void init(Handle<v8::Object> target) {
  HandleScope scope;

  GitError::Initialize(target);

  GitReference::Initialize(target);
  GitSig::Initialize(target);
  GitBlob::Initialize(target);
  GitOid::Initialize(target);
  GitObject::Initialize(target);
  GitRepo::Initialize(target);
  GitCommit::Initialize(target);
  GitRevWalk::Initialize(target);

  GitTree::Initialize(target);
  GitTreeEntry::Initialize(target);

  GitDiffList::Initialize(target);

  GitThreads::Initialize(target);

}

NODE_MODULE(nodegit, init)
<|endoftext|>