<commit_before>#include <algorithm>
#include <cstring>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include <curl/curl.h>

#include "command.h"
#include "config.h"
#include "dbo_project.h"
#include "flags.h"
#include "main.h"
#include "store_file.h"
#include "util.h"

static const std::string VERSION = "0.2.0-SNAPSHOT";

static const int INSTALL_DIALOG_LINE_LENGTH = 80;
static const int HELP_INDENT_SIZE = 10;

Command* const CMD_STORE = new Command("store", "[location]",
        "Gets or sets the current store location.", &handleStoreCmd);
Command* const CMD_INSTALL = new Command("install", "<projects>...",
        "Installs or upgrades the specified projects to the current store.", &handleInstallCmd);
Command* const CMD_UPGRADE = new Command("upgrade", "",
        "Attempts to upgrade all projects installed to the current store.", &handleUpgradeCmd);
Command* const CMD_REMOVE = new Command("remove", "<projects>...",
        "Removes the specified projects from the current store.", &handleRemoveCmd);
Command* const CMD_HELP = new Command("help", "[command]",
        "Displays help for one or all commands.", &handleHelpCmd);
Command* const CMD_MOO = new Command("moo", "",
        "Have you mooed today?", &handleMooCmd, false);
Command* const CMDS[] = {CMD_STORE, CMD_INSTALL, CMD_REMOVE, CMD_UPGRADE, CMD_HELP, CMD_MOO};

static std::vector<RemoteProject*>* const EMPTY_RPP_VEC = new std::vector<RemoteProject*>(0);

static std::vector<std::string>* params;

int main(int argc, char* argv[]) {
    if (argc < 2) {
        err("Too few args!");
		print("    Usage: dbo_get <command>");
        return 1;
    }

	parseParamsAndFlags(argc, argv);

    char* cmd = argv[1];
    for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
        if (matchCmd(cmd, (*it)->getLabel())) {
            return (*it)->getHandler()(argc, argv);
        }
    }
    err("Invalid command, try `dbo-get help`.");
    return 1;
}

void parseParamsAndFlags(int argc, char* argv[]) {
	int paramCount = 0;
	int flagCount = 0;
	for (int i = 2; i < argc; i++) {
		if (argv[i][0] == '-') {
			flagCount += argv[i][1] == '-' ? 1 : std::strlen(argv[i]) - 1;
		} else {
			paramCount++;
		}
	}

    params = new std::vector<std::string>(paramCount);
	std::vector<Flag>* flags = new std::vector<Flag>(flagCount);
    int p = 0;
	int f = 0;
    for (int i = 2; i < argc; i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == '-') {
				std::string name = std::string(argv[i] + 2);
				const Flag* flag = matchFlag(name);
				if (flag == NULL) {
					invalidFlag(name);
					exit(1);
				} else {
					(*flags)[f++] = *flag;
				}
			} else {
				for (size_t j = 1; j < std::strlen(argv[i]); j++) {
					const Flag* flag = matchFlag(argv[i][j]);
					if (flag == NULL) {
						invalidFlag(argv[i][j]);
						exit(1);
					} else {
						(*flags)[f++] = *flag;
					}
				}
			}
		} else {
            (*params)[p++] = argv[i];
        }
    }

	setFlags(flags);

	if (testFlag(Flag::kQuiet) && testFlag(Flag::kVerbose)) {
		err("Quiet and verbose flags cannot be used in conjunction.");
		exit(1);
	}
}

int handleStoreCmd(int argc, char* argv[]) {
    if (argc < 3) {
        std::string* loc = Config::getInstance().get(Config::KEY_STORE);
		printQ("Current store location: " + (loc == NULL ? "NOT SET" : *loc));
        return 0;
    }

    std::string path = "";
    for (size_t i = 0; i < params->size(); i++) {
        path += (*params)[i];
        if (i < params->size() - 1) {
            path += " ";
        }
    }
    delete(params);
    std::replace(path.begin(), path.end(), '\\', '/');
    Config::getInstance().set(Config::KEY_STORE, path);
    makePath(path);
	printQ("Successfully set store location as \"" + path + "\".");

    return 0;
}

std::vector<RemoteProject*>* resolve(std::vector<std::string>* projects, bool ignoreFail) {
    printQ("Resolving projects...");

    std::vector<RemoteProject*>* vec = new std::vector<RemoteProject*>(projects->size());
    bool fail = false;
    bool empty = true;
    curl_global_init(CURL_GLOBAL_ALL);
	bool forceUpdate = testFlag(Flag::kUpdate);
    for (size_t i = 0; i < projects->size(); i++) {
        std::string id = (*projects)[i];
        print("Resolving project " + id + "...");
        RemoteProject* remote = new RemoteProject(id);

        if (!remote->resolve() && !ignoreFail) {
            err("Failed to resolve " + id + ".");
            fail = true;
            return NULL;
        }

        LocalProject* local = StoreFile::getInstance().getProject(id);

        if (local == NULL || forceUpdate || remote->getVersion() > local->getVersion()) {
            (*vec)[i] = remote;
            empty = false;
        }

        print("Done resolving " + id + ".");
    }
    curl_global_cleanup();
    return fail ? NULL : (!empty ? vec : EMPTY_RPP_VEC);
}

static void printDialogListing(std::vector<std::string> projects) {
    std::string line = "  ";
    for (size_t i = 0; i < projects.size(); i++) {
        if (projects[i] == "") {
            break;
        }
        std::string newLine = line + projects[i];
        if (line.length() + 1 > INSTALL_DIALOG_LINE_LENGTH) {
			printQ(line);
            line = "  " + projects[i];
        } else {
            line = newLine + " ";
        }
    }
	printQ(line);
}

int handleInstallCmd(int argc, char* argv[]) {
    if (argc < 3) {
        tooFewArgs(CMD_INSTALL->getLabel(), CMD_INSTALL->getUsage());
        return 1;
    }
    return install(params, false);
}

int handleUpgradeCmd(int argc, char* argv[]) {
    if (argc >= 3) {
        tooFewArgs(CMD_UPGRADE->getLabel(), CMD_UPGRADE->getUsage());
        return 1;
    }
    std::vector<std::string>* projects = StoreFile::getInstance().getProjectIds();
    return install(projects, true);
}

int handleRemoveCmd(int argc, char* argv[]) {
    if (argc < 3) {
        tooFewArgs(CMD_REMOVE->getLabel(), CMD_REMOVE->getUsage());
        return 1;
    }
    return remove(params);
}

int handleHelpCmd(int argc, char* argv[]) {
    if (argc == 2) {
        printInfoHeader();
        for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
            if ((*it)->isDocumented()) {
                printHelp(*it);
            }
        }
        return 0;
    } else if (argc == 3) {
        for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
            if (matchCmd(argv[2], (*it)->getLabel())) {
                if (!(*it)->isDocumented()) {
                    break;
                }
                printHelp(*it);
                return 0;
            }
        }
        err("Cannot display help: invalid command specified.");
        return 1;
    } else {
        tooManyArgs(CMD_HELP->getLabel(), CMD_HELP->getUsage());
        return 1;
    }
}

void printInfoHeader() {
	printQ("dbo-get v" + VERSION + ".");
	printQ("Copyright (c) 2016 Max Roncace.");
	printQ("");
	printQ("dbo-get is a utility for installing and managing projects hosted by BukkitDev,");
	printQ("the premier hosting service for Bukkit software.");
	printQ("");
	printQ("Commands:");
}

void printHelp(Command* cmd) {
    std::string indent = "";
    for (int i = cmd->getLabel().length(); i < HELP_INDENT_SIZE; i++) {
        indent += " ";
    }
	printQ("  " + cmd->getLabel() + indent + cmd->getDescription());
    std::string indent2 = indent;
    for (size_t i = 0; i < cmd->getLabel().length() + 4; i++) {
        indent2 += " ";
    }
    printQ(indent2 + "Usage: dbo-get " + cmd->getLabel() + " " + cmd->getUsage());
}

int handleMooCmd(int argc, char* argv[]) {
	int vs = testFlagi(Flag::kVerbose);
	switch (vs) {
	case 0:
		printQ("Yes, you're very clever.");
		break;
	case 1:
		printQ("Hey, what are you doing?");
		break;
	case 2:
		printQ("Mhm, I get it, haha. Funny.");
		break;
	case 3:
		printQ("You really want this, don't you?");
		break;
	case 4:
		printQ("Alright, very well.");
		break;
	case 5:
		printArt();
		break;
	case 50:
		printQ("Someone's been rummaging through the source, mm?");
		break;
	default:
		printQ("Happy?");
		break;
	}
    return 0;
}

int install(std::vector<std::string>* projects, bool ignoreFail) {
    std::string* loc = Config::getInstance().get(Config::KEY_STORE);
    if (loc == NULL) {
        err("Store location is not set; please run store command first.");
        return 1;
    }
    makePath(*loc);

    std::vector<RemoteProject*>* resolved = resolve(projects, ignoreFail);

    delete(projects);

    if (resolved == NULL) {
        err("No projects specified for installation.");
        return 1;
    }

    if (resolved->empty()) {
        printQ("Already up-to-date.");
        return 0;
    }

    printInstallDialog(resolved);

	printQ("Installing projects...");
    for (size_t i = 0; i < resolved->size(); i++) {
        RemoteProject* proj = (*resolved)[i];
        if (proj == NULL) {
            continue;
        }

        LocalProject* local = StoreFile::getInstance().getProject(proj->getId());
        if (local != NULL) {
            print("Upgrading project " + proj->getId() + " (#" + std::to_string(local->getVersion()) + " -> #" + std::to_string(proj->getVersion()) + ").");
            if (!local->remove() || !proj->install()) {
                //TODO: this shit ain't atomic
                return 1;
            }
        } else {
            print("Installing project " + proj->getId() + "...");
            if (!proj->install()) {
                return 1;
            }
        }
        print("Done installing " + proj->getId() + ".");
    }
	printQ("Done.");

    StoreFile::getInstance().save();

    return 0;
}

int remove(std::vector<std::string>* projects) {
    std::string* loc = Config::getInstance().get(Config::KEY_STORE);
    if (loc == NULL) {
        err("Store location is not set; please run store command first.");
        return 1;
    }
    makePath(*loc);

	printQ("Resolving projects...");
    bool fail = false;
    std::vector<LocalProject> resolved = std::vector<LocalProject>(projects->size());
    for (size_t i = 0; i < projects->size(); i++) {
        std::string id = (*projects)[i];
        print("Resolving project " + id + "...");
        LocalProject* proj = StoreFile::getInstance().getProject(id);
        if (proj != NULL) {
            if (!fail) {
                resolved[i] = *proj;
				print("Done resolving " + id + ".");
            }
        } else {
            err("No project with ID " + id + " is currently installed.");
            fail = true;
        }
    }

    delete(projects);

    if (fail) {
        err("No projects specified for removal.");
        return 1;
    }

    printRemoveDialog(&resolved);

	printQ("Removing projects...");
    for (size_t i = 0; i < resolved.size(); i++) {
        LocalProject proj = resolved[i];
        print("Removing project " + proj.getId() + "...");
        proj.remove();
        print("Done removing " + proj.getId() + ".");
    }
	printQ("Done.");

    StoreFile::getInstance().save();

    return 0;
}

static void printInstallDialog(std::vector<RemoteProject*>* projects) {
    std::vector<std::string> upgradeList = std::vector<std::string>(projects->size());
    std::vector<std::string> installList = std::vector<std::string>(projects->size());
    int ui = 0;
    int ii = 0;
    int nu = 0;
    for (size_t i = 0; i < projects->size(); i++) {
        RemoteProject* remote = (*projects)[i];
        if (remote == NULL) {
            nu++;
            continue;
        }
        LocalProject* local = StoreFile::getInstance().getProject(remote->getId());
        if (local != NULL) {
            upgradeList[ui++] = remote->getId();
        } else {
            installList[ii++] = remote->getId();
        }
    }

    if (ui > 0) {
		printQ("The following projects will be upgraded:");
        printDialogListing(upgradeList);
    }

    if (ii > 0) {
		printQ("The following projects will be newly installed:");
        printDialogListing(installList);
    }

	printQ(std::to_string(ui) + " upgraded, " + std::to_string(ii) + " newly installed, 0 to remove, "
        + std::to_string(nu) + " not upgraded.");
}

static void printRemoveDialog(std::vector<LocalProject>* projects) {
    std::vector<std::string> removeList = std::vector<std::string>(projects->size());
    for (size_t i = 0; i < projects->size(); i++) {
        removeList[i] = (*projects)[i].getId();
    }
    printDialogListing(removeList);

	printQ("0 upgraded, 0 newly installed, " + std::to_string(projects->size()) + " to remove, 0 not upgraded.");
}
<commit_msg>Add flags to help dialog<commit_after>#include <algorithm>
#include <cstring>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

#include <curl/curl.h>

#include "command.h"
#include "config.h"
#include "dbo_project.h"
#include "flags.h"
#include "main.h"
#include "store_file.h"
#include "util.h"

static const std::string VERSION = "0.2.0-SNAPSHOT";

static const int INSTALL_DIALOG_LINE_LENGTH = 80;
static const int HELP_CMD_INDENT_SIZE = 10;
static const int HELP_FLAG_INDENT_SIZE = 18;

Command* const CMD_STORE = new Command("store", "[location]",
        "Gets or sets the current store location.", &handleStoreCmd);
Command* const CMD_INSTALL = new Command("install", "<projects>...",
        "Installs or upgrades the specified projects to the current store.", &handleInstallCmd);
Command* const CMD_UPGRADE = new Command("upgrade", "",
        "Attempts to upgrade all projects installed to the current store.", &handleUpgradeCmd);
Command* const CMD_REMOVE = new Command("remove", "<projects>...",
        "Removes the specified projects from the current store.", &handleRemoveCmd);
Command* const CMD_HELP = new Command("help", "[command]",
        "Displays help for one or all commands.", &handleHelpCmd);
Command* const CMD_MOO = new Command("moo", "",
        "Have you mooed today?", &handleMooCmd, false);
Command* const CMDS[] = {CMD_STORE, CMD_INSTALL, CMD_REMOVE, CMD_UPGRADE, CMD_HELP, CMD_MOO};

static std::vector<RemoteProject*>* const EMPTY_RPP_VEC = new std::vector<RemoteProject*>(0);

static std::vector<std::string>* params;

int main(int argc, char* argv[]) {
    if (argc < 2) {
        err("Too few args!");
		print("    Usage: dbo_get <command>");
        return 1;
    }

	parseParamsAndFlags(argc, argv);

    char* cmd = argv[1];
    for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
        if (matchCmd(cmd, (*it)->getLabel())) {
            return (*it)->getHandler()(argc, argv);
        }
    }
    err("Invalid command, try `dbo-get help`.");
    return 1;
}

void parseParamsAndFlags(int argc, char* argv[]) {
	int paramCount = 0;
	int flagCount = 0;
	for (int i = 2; i < argc; i++) {
		if (argv[i][0] == '-') {
			flagCount += argv[i][1] == '-' ? 1 : std::strlen(argv[i]) - 1;
		} else {
			paramCount++;
		}
	}

    params = new std::vector<std::string>(paramCount);
	std::vector<Flag>* flags = new std::vector<Flag>(flagCount);
    int p = 0;
	int f = 0;
    for (int i = 2; i < argc; i++) {
		if (argv[i][0] == '-') {
			if (argv[i][1] == '-') {
				std::string name = std::string(argv[i] + 2);
				const Flag* flag = matchFlag(name);
				if (flag == NULL) {
					invalidFlag(name);
					exit(1);
				} else {
					(*flags)[f++] = *flag;
				}
			} else {
				for (size_t j = 1; j < std::strlen(argv[i]); j++) {
					const Flag* flag = matchFlag(argv[i][j]);
					if (flag == NULL) {
						invalidFlag(argv[i][j]);
						exit(1);
					} else {
						(*flags)[f++] = *flag;
					}
				}
			}
		} else {
            (*params)[p++] = argv[i];
        }
    }

	setFlags(flags);

	if (testFlag(Flag::kQuiet) && testFlag(Flag::kVerbose)) {
		err("Quiet and verbose flags cannot be used in conjunction.");
		exit(1);
	}
}

int handleStoreCmd(int argc, char* argv[]) {
    if (argc < 3) {
        std::string* loc = Config::getInstance().get(Config::KEY_STORE);
		printQ("Current store location: " + (loc == NULL ? "NOT SET" : *loc));
        return 0;
    }

    std::string path = "";
    for (size_t i = 0; i < params->size(); i++) {
        path += (*params)[i];
        if (i < params->size() - 1) {
            path += " ";
        }
    }
    delete(params);
    std::replace(path.begin(), path.end(), '\\', '/');
    Config::getInstance().set(Config::KEY_STORE, path);
    makePath(path);
	printQ("Successfully set store location as \"" + path + "\".");

    return 0;
}

std::vector<RemoteProject*>* resolve(std::vector<std::string>* projects, bool ignoreFail) {
    printQ("Resolving projects...");

    std::vector<RemoteProject*>* vec = new std::vector<RemoteProject*>(projects->size());
    bool fail = false;
    bool empty = true;
    curl_global_init(CURL_GLOBAL_ALL);
	bool forceUpdate = testFlag(Flag::kUpdate);
    for (size_t i = 0; i < projects->size(); i++) {
        std::string id = (*projects)[i];
        print("Resolving project " + id + "...");
        RemoteProject* remote = new RemoteProject(id);

        if (!remote->resolve() && !ignoreFail) {
            err("Failed to resolve " + id + ".");
            fail = true;
            return NULL;
        }

        LocalProject* local = StoreFile::getInstance().getProject(id);

        if (local == NULL || forceUpdate || remote->getVersion() > local->getVersion()) {
            (*vec)[i] = remote;
            empty = false;
        }

        print("Done resolving " + id + ".");
    }
    curl_global_cleanup();
    return fail ? NULL : (!empty ? vec : EMPTY_RPP_VEC);
}

static void printDialogListing(std::vector<std::string> projects) {
    std::string line = "  ";
    for (size_t i = 0; i < projects.size(); i++) {
        if (projects[i] == "") {
            break;
        }
        std::string newLine = line + projects[i];
        if (line.length() + 1 > INSTALL_DIALOG_LINE_LENGTH) {
			printQ(line);
            line = "  " + projects[i];
        } else {
            line = newLine + " ";
        }
    }
	printQ(line);
}

int handleInstallCmd(int argc, char* argv[]) {
    if (argc < 3) {
        tooFewArgs(CMD_INSTALL->getLabel(), CMD_INSTALL->getUsage());
        return 1;
    }
    return install(params, false);
}

int handleUpgradeCmd(int argc, char* argv[]) {
    if (argc >= 3) {
        tooFewArgs(CMD_UPGRADE->getLabel(), CMD_UPGRADE->getUsage());
        return 1;
    }
    std::vector<std::string>* projects = StoreFile::getInstance().getProjectIds();
    return install(projects, true);
}

int handleRemoveCmd(int argc, char* argv[]) {
    if (argc < 3) {
        tooFewArgs(CMD_REMOVE->getLabel(), CMD_REMOVE->getUsage());
        return 1;
    }
    return remove(params);
}

void printFlag(std::string name, char shorthand, std::string description) {
	std::string start = "  -" + std::string(&shorthand, 1) + ", --" + name;
	std::string indent = "";
	for (int i = start.length(); i < HELP_FLAG_INDENT_SIZE; i++) {
		indent += " ";
	}
	printQ(start + indent + description);
}

int handleHelpCmd(int argc, char* argv[]) {
    if (argc == 2) {
        printInfoHeader();
		printQ("Flags:");
		printFlag("force", 'f', "Forces dbo-get to upgrade packages without comparing versions at all.");
		printFlag("quiet", 'q', "Enables quiet logging and suppresses much of the normal output.");
		printFlag("verbose", 'v', "Enables verbose logging.");
		printQ("Commands:");
        for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
            if ((*it)->isDocumented()) {
                printHelp(*it);
            }
        }
        return 0;
    } else if (argc == 3) {
        for (auto it = std::begin(CMDS); it != std::end(CMDS); ++it) {
            if (matchCmd(argv[2], (*it)->getLabel())) {
                if (!(*it)->isDocumented()) {
                    break;
                }
                printHelp(*it);
                return 0;
            }
        }
        err("Cannot display help: invalid command specified.");
        return 1;
    } else {
        tooManyArgs(CMD_HELP->getLabel(), CMD_HELP->getUsage());
        return 1;
    }
}

void printInfoHeader() {
	printQ("dbo-get v" + VERSION + ".");
	printQ("Copyright (c) 2016 Max Roncace.");
	printQ("");
	printQ("dbo-get is a utility for installing and managing projects hosted by BukkitDev,");
	printQ("the premier hosting service for Bukkit software.");
	printQ("");
}

void printHelp(Command* cmd) {
    std::string indent = "";
    for (int i = cmd->getLabel().length(); i < HELP_CMD_INDENT_SIZE; i++) {
        indent += " ";
    }
	printQ("  " + cmd->getLabel() + indent + cmd->getDescription());
    std::string indent2 = indent;
    for (size_t i = 0; i < cmd->getLabel().length() + 4; i++) {
        indent2 += " ";
    }
    printQ(indent2 + "Usage: dbo-get " + cmd->getLabel() + " " + cmd->getUsage());
}

int handleMooCmd(int argc, char* argv[]) {
	int vs = testFlagi(Flag::kVerbose);
	switch (vs) {
	case 0:
		printQ("Yes, you're very clever.");
		break;
	case 1:
		printQ("Hey, what are you doing?");
		break;
	case 2:
		printQ("Mhm, I get it, haha. Funny.");
		break;
	case 3:
		printQ("You really want this, don't you?");
		break;
	case 4:
		printQ("Alright, very well.");
		break;
	case 5:
		printArt();
		break;
	case 50:
		printQ("Someone's been rummaging through the source, mm?");
		break;
	default:
		printQ("Happy?");
		break;
	}
    return 0;
}

int install(std::vector<std::string>* projects, bool ignoreFail) {
    std::string* loc = Config::getInstance().get(Config::KEY_STORE);
    if (loc == NULL) {
        err("Store location is not set; please run store command first.");
        return 1;
    }
    makePath(*loc);

    std::vector<RemoteProject*>* resolved = resolve(projects, ignoreFail);

    delete(projects);

    if (resolved == NULL) {
        err("No projects specified for installation.");
        return 1;
    }

    if (resolved->empty()) {
        printQ("Already up-to-date.");
        return 0;
    }

    printInstallDialog(resolved);

	printQ("Installing projects...");
    for (size_t i = 0; i < resolved->size(); i++) {
        RemoteProject* proj = (*resolved)[i];
        if (proj == NULL) {
            continue;
        }

        LocalProject* local = StoreFile::getInstance().getProject(proj->getId());
        if (local != NULL) {
            print("Upgrading project " + proj->getId() + " (#" + std::to_string(local->getVersion()) + " -> #" + std::to_string(proj->getVersion()) + ").");
            if (!local->remove() || !proj->install()) {
                //TODO: this shit ain't atomic
                return 1;
            }
        } else {
            print("Installing project " + proj->getId() + "...");
            if (!proj->install()) {
                return 1;
            }
        }
        print("Done installing " + proj->getId() + ".");
    }
	printQ("Done.");

    StoreFile::getInstance().save();

    return 0;
}

int remove(std::vector<std::string>* projects) {
    std::string* loc = Config::getInstance().get(Config::KEY_STORE);
    if (loc == NULL) {
        err("Store location is not set; please run store command first.");
        return 1;
    }
    makePath(*loc);

	printQ("Resolving projects...");
    bool fail = false;
    std::vector<LocalProject> resolved = std::vector<LocalProject>(projects->size());
    for (size_t i = 0; i < projects->size(); i++) {
        std::string id = (*projects)[i];
        print("Resolving project " + id + "...");
        LocalProject* proj = StoreFile::getInstance().getProject(id);
        if (proj != NULL) {
            if (!fail) {
                resolved[i] = *proj;
				print("Done resolving " + id + ".");
            }
        } else {
            err("No project with ID " + id + " is currently installed.");
            fail = true;
        }
    }

    delete(projects);

    if (fail) {
        err("No projects specified for removal.");
        return 1;
    }

    printRemoveDialog(&resolved);

	printQ("Removing projects...");
    for (size_t i = 0; i < resolved.size(); i++) {
        LocalProject proj = resolved[i];
        print("Removing project " + proj.getId() + "...");
        proj.remove();
        print("Done removing " + proj.getId() + ".");
    }
	printQ("Done.");

    StoreFile::getInstance().save();

    return 0;
}

static void printInstallDialog(std::vector<RemoteProject*>* projects) {
    std::vector<std::string> upgradeList = std::vector<std::string>(projects->size());
    std::vector<std::string> installList = std::vector<std::string>(projects->size());
    int ui = 0;
    int ii = 0;
    int nu = 0;
    for (size_t i = 0; i < projects->size(); i++) {
        RemoteProject* remote = (*projects)[i];
        if (remote == NULL) {
            nu++;
            continue;
        }
        LocalProject* local = StoreFile::getInstance().getProject(remote->getId());
        if (local != NULL) {
            upgradeList[ui++] = remote->getId();
        } else {
            installList[ii++] = remote->getId();
        }
    }

    if (ui > 0) {
		printQ("The following projects will be upgraded:");
        printDialogListing(upgradeList);
    }

    if (ii > 0) {
		printQ("The following projects will be newly installed:");
        printDialogListing(installList);
    }

	printQ(std::to_string(ui) + " upgraded, " + std::to_string(ii) + " newly installed, 0 to remove, "
        + std::to_string(nu) + " not upgraded.");
}

static void printRemoveDialog(std::vector<LocalProject>* projects) {
    std::vector<std::string> removeList = std::vector<std::string>(projects->size());
    for (size_t i = 0; i < projects->size(); i++) {
        removeList[i] = (*projects)[i].getId();
    }
    printDialogListing(removeList);

	printQ("0 upgraded, 0 newly installed, " + std::to_string(projects->size()) + " to remove, 0 not upgraded.");
}
<|endoftext|>


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

using namespace std;

bool isKlinker(const char a){
	bool res = false;

	if(a == 'a'){
		res = true;
	} else if(a == 'e'){
		res = true;
	} else if(a == 'i'){
		res = true;
	} else if(a == 'o'){
		res = true;
	} else if(a == 'u'){
		res = true;
	}

	return res;
}

class Generator {
	private:
		string s;
	public:
		void setString(string str);
		string getPPConversion();
		string getPPConversion(string str);
};

void Generator::setString(string str){
	s = str;
}

string Generator::getPPConversion(){
	string res = "";

	for(int i = 0; i< s.length(); i++){
		if(isKlinker(s[i])){
			res += s[i];
			res += 'p';
		}
		res += s[i];
	}

	return res;
}

string Generator::getPPConversion(string str){
	setString(str);
	return getPPConversion();
}

int main(){

	string input;
	Generator gen;

	cout << "Schrijf een woord: ";
	cin >> input;
	gen.setString(input);

	cout << "'" << input << "' " << "in pepekestaal is: '"
		<< gen.getPPConversion() << "'" <<endl;

	return 0;
}<commit_msg>added function to generator class<commit_after>#include <iostream>
#include <string>

using namespace std;

class Generator {
	private:
		string s;
		bool isKlinker(const char a);
	public:
		void setString(string str);
		string getPPConversion();
		string getPPConversion(string str);
};

bool Generator::isKlinker(const char a){
	bool res = false;

	if(a == 'a'){
		res = true;
	} else if(a == 'e'){
		res = true;
	} else if(a == 'i'){
		res = true;
	} else if(a == 'o'){
		res = true;
	} else if(a == 'u'){
		res = true;
	}

	return res;
}

void Generator::setString(string str){
	s = str;
}

string Generator::getPPConversion(){
	string res = "";

	for(int i = 0; i< s.length(); i++){
		if(isKlinker(s[i])){
			res += s[i];
			res += 'p';
		}
		res += s[i];
	}

	return res;
}

string Generator::getPPConversion(string str){
	setString(str);
	return getPPConversion();
}

int main(){

	string input;
	Generator gen;

	cout << "Schrijf een woord: ";
	cin >> input;
	gen.setString(input);

	cout << "'" << input << "' " << "in pepekestaal is: '"
		<< gen.getPPConversion() << "'" <<endl;

	return 0;
}<|endoftext|>


<commit_before>#include <bits/stdc++.h>
using namespace std;

#define MAXN    100005
#define clip(X) min(X,10000)

// IMPLEMENTACAO/TESTES
// procurar formulas menores nas maiores, mais ou menos R² * d(phi) (melhoria1)
// dp para otimizar o renaming limitando o nro maximo de literais   (melhoria2)
// procurar um benchmark e adaptar a entrada para ele
// adaptar a saida para algum provador, colocando em CNF

// MONOGRAFIA
// colocar exemplo 3.2

// formula
enum {CONJ=0,DISJ,IMPL,EQUI,NEGA,ATOM};
struct Vertex {
  char type;
  int literal;
  int up;
  vector<int> down;
  int p;
  Vertex() : p(1) {}
} G[MAXN];
int V = 0;

// create tree parsing formula from string
// first: tree
// second: number of literals
pair<vector<Vertex>,int> parse(string phi) {
  // tells if a character is valid for a variable name
  auto isvarsym = [](char c) {
    return
      ('0' <= c && c <= '9') ||
      ('a' <= c && c <= 'z') ||
      ('A' <= c && c <= 'Z')
    ;
  };

  vector<Vertex> ret(1);
  ret.back().type = CONJ;
  ret.back().up = 0;
  stack<int> S;
  S.push(0);
  map<string,int> id;
  int nextlit = 1;
  for (int i = 0; i < phi.size(); i++) {
    char c = phi[i];
    if (c == ' ' || c == '\t') continue;
    else if (c == '&') ret[S.top()].type = CONJ;
    else if (c == '|') ret[S.top()].type = DISJ;
    else if (c == '=') { ret[S.top()].type = IMPL; i++; }
    else if (c == '<') { ret[S.top()].type = EQUI; i += 2; }
    else if (c == '(' || c == '~') { // push
      S.push(ret.size());
      ret.emplace_back();
      ret.back().type = (c == '(' ? CONJ : NEGA);
    }
    else if (c == ')') { // pop
      int u = S.top();
      S.pop();
      ret[u].up = S.top();
      ret[S.top()].down.push_back(u);
      // removing multiple parentheses
      if (ret[u].type != NEGA && ret[u].down.size() == 1) {
        int u1 = ret[u].down.front();
        ret[u].type = ret[u1].type;
        ret[u].down = ret[u1].down;
        for (int v : ret[u].down) ret[v].up = u;
      }
    }
    else { // literal
      string tmp = {phi[i]};
      while (i+1 < phi.size() && isvarsym(phi[i+1])) tmp += phi[++i];
      int& lit = id[tmp];
      if (!lit) lit = nextlit++;
      ret[S.top()].down.push_back(ret.size());
      ret.emplace_back();
      ret.back().type = ATOM;
      ret.back().literal = lit;
      ret.back().up = S.top();
      if (ret[S.top()].type == NEGA) { phi[i] = ')'; i--; }
    }
  }
  // removing multiple parentheses
  if (ret[0].down.size() == 1) {
    int u = ret[0].down.front();
    ret[0].type = ret[u].type;
    ret[0].down = ret[u].down;
    for (int v : ret[0].down) ret[v].up = 0;
  }
  return make_pair(ret,id.size());
}

void nnf(vector<Vertex>& T) {
  // copy tree rooted at u
  function<int(int)> copy = [&](int u) {
    int nu = T.size(); T.emplace_back();
    T[nu].type = T[u].type;
    T[nu].literal = T[u].literal;
    for (int v : T[u].down) {
      int tmp = copy(v);
      T[tmp].up = nu;
      T[nu].down.push_back(tmp);
    }
    return nu;
  };

  // remove implications and equivalences
  function<void(int)> dfs1 = [&](int u) {
    if (T[u].type == IMPL) {
      T[u].type = DISJ;
      int v = T[u].down.front();
      int negi = T.size(); T.emplace_back();
      T[negi].type = NEGA;
      T[u].down.front() = negi;
      T[negi].up = u;
      T[negi].down.push_back(v);
      T[v].up = negi;
    }
    else if (T[u].type == EQUI) {
      auto f = [&](int a, int b) {
        int impi = T.size(); T.emplace_back();
        T[impi].type = IMPL;
        T[u].down.push_back(impi);
        T[impi].up = u;
        T[impi].down.push_back(a), T[impi].down.push_back(b);
        T[a].up = impi, T[b].up = impi;
      };
      T[u].type = CONJ;
      int a = T[u].down.front(),  b = T[u].down.back();
      int c = copy(b),            d = copy(a);
      T[u].down.clear();
      f(a,b);
      f(c,d);
    }
    for (int v : T[u].down) dfs1(v);
  };
  dfs1(0);

  // remove negations
  function<void(int,bool)> dfs2 = [&](int u, bool neg) {
    if (!neg) {
      if (T[u].type == NEGA) {
        auto& phi1 = T[T[u].down.front()];
        if (phi1.type == NEGA) {
          auto& phi2 = T[phi1.down.front()];
          T[u].type = phi2.type;
          T[u].literal = phi2.literal;
          T[u].down = phi2.down;
          for (int v : T[u].down) T[v].up = u;
          phi1.type = CONJ, phi2.type = CONJ; // removing phi1 and phi2
        }
        else if (phi1.type != ATOM) { // CONJ or DISJ
          T[u].type = (phi1.type == CONJ ? DISJ : CONJ);
          T[u].down = phi1.down;
          for (int v : T[u].down) T[v].up = u;
          phi1.type = CONJ; // removing phi1
          neg = true;
        }
      }
    }
    else {
      if (T[u].type == NEGA) {
        auto& phi1 = T[T[u].down.front()];
        T[u].type = phi1.type;
        T[u].literal = phi1.literal;
        T[u].down = phi1.down;
        for (int v : T[u].down) T[v].up = u;
        phi1.type = CONJ; // removing phi1
        neg = false;
      }
      else if (T[u].type != ATOM) { // CONJ or DISJ
        T[u].type = (T[u].type == CONJ ? DISJ : CONJ);
      }
      else { // ATOM
        int atmi = copy(u);
        T[u].type = NEGA;
        T[u].down.push_back(atmi);
        T[atmi].up = u;
        neg = false;
      }
    }
    for (int v : T[u].down) dfs2(v,neg);
  };
  dfs2(0,false);
}

// build DAG from tree T
void build(const vector<Vertex>& T) {
  map<int,int> lit_newu;
  map<int,multiset<int>> oldp_newc;
  V = 1;

  // create vertices for literals
  for (int i = 0; i < T.size(); i++) if (T[i].type == ATOM) {
    auto& phi = T[i];
    int& u = lit_newu[phi.literal];
    if (!u) {
      u = ++V;
      G[u].type = ATOM;
      G[u].literal = phi.literal;
    }
    oldp_newc[phi.up].insert(u);
  }

  // search tree bottom-up to create vertices for subformulas
  for (map<multiset<int>,int> newc_newp; !oldp_newc.empty();) {
    list<pair<int,int>> tmp;
    for (auto kv = oldp_newc.begin(); kv != oldp_newc.end();) {
      auto& phi = T[kv->first];
      if (kv->second.size() < phi.down.size()) { kv++; continue; }
      int& u = newc_newp[kv->second];
      if (!u) {
        u = (phi.up != kv->first) ? ++V : 1;
        G[u].type = phi.type;
        for (int v : kv->second) G[u].down.push_back(v);
      }
      if (phi.up != kv->first) tmp.emplace_back(phi.up,u);
      oldp_newc.erase(kv++);
    }
    for (auto& kv : tmp) oldp_newc[kv.first].insert(kv.second);
  }
}

// position of u in a reverse toposort
int pos(int u) {
  static int next = 1, dp[MAXN] = {};
  int& ans = dp[u];
  if (ans) return ans;
  for (int v : G[u].down) pos(v);
  return ans = next++;
}

// p(phi(u))
int p(int u) {
  static int dp[MAXN] = {};
  int& ans = dp[u];
  if (ans) return ans;
  switch (G[u].type) {
    case CONJ: ans = 0; for (int v : G[u].down) ans = clip(ans+p(v)); break;
    case DISJ: ans = 1; for (int v : G[u].down) ans = clip(ans*p(v)); break;
    default:   ans = 1; break;
  }
  return ans;
}

// Boy de la Tour's top-down renaming
vector<int> R;
int nextR;
void R_rec(int u, int a) {
  auto& phi = G[u];
  if (phi.p == 1) return;

  // check renaming condition
  bool renamed = false;
  if (a > 1) {
    a = 1;
    renamed = true;
  }

  // search children
  if (phi.type == CONJ) {
    for (int v : phi.down) R_rec(v,a);
    phi.p = 0; for (int v : phi.down) phi.p = clip(phi.p+G[v].p);
  }
  else { // phi.type == DISJ
    int n = phi.down.size();

    vector<int> dp(n,1); // dp[i] = prod(phi_j.p), i < j < n
    for (int i = n-2; 0 <= i; i--) dp[i] = clip(G[phi.down[i+1]].p*dp[i+1]);

    int ai = a; // ai = a*prod(phi_j.p), 0 <= j < i
    for (int i = 0; i < n; i++) {
      R_rec(phi.down[i],clip(ai*dp[i]));
      ai = clip(ai*G[phi.down[i]].p);
    }
    phi.p = 1; for (int v : phi.down) phi.p = clip(phi.p*G[v].p);
  }

  if (renamed) {
    R.push_back(u);
    phi.type |= (1<<7);
    phi.literal = nextR++;
    phi.p = 1;
  }
}

// pretty print a formula
string array2str(Vertex formula[], int root) {
  stringstream ss;
  function<void(int)> dfs = [&](int u) {
    auto& phi = formula[u];
    if (phi.type == ATOM || phi.type&(1<<7)) {
      ss << "p" << phi.literal;
      return;
    }
    if (phi.type == NEGA) {
      ss << "~";
      dfs(phi.down.front());
      return;
    }
    ss << "(";
    char op = phi.type == CONJ ? '&' : '|';
    bool printed = false;
    for (int u : phi.down) {
      if (printed) ss << " " << op << " ";
      printed = true;
      dfs(u);
    }
    ss << ")";
  };
  auto& phi = formula[root];
  char op = phi.type == CONJ ? '&' : '|';
  bool printed = false;
  for (int u : phi.down) {
    if (printed) ss << " " << op << " ";
    printed = true;
    dfs(u);
  }
  return ss.str();
}

int main() {

  // input
  string phi;
  getline(cin,phi);

  // preprocess
  auto tree = parse(phi);
  nnf(tree.first);
  build(tree.first);
  auto toposort = [](int u, int v){ return pos(u) < pos(v); };
  for (int u = 1; u <= V; u++) {
    auto& phi = G[u];
    sort(phi.down.begin(),phi.down.end(),toposort);
    phi.p = p(u);
  }
  cout << array2str(G,1) << endl;

  // renaming
  nextR = tree.second+1;
  R_rec(1,1);

  // output
  cout << "(" << array2str(G,1) << ")";
  for (int u : R) {
    auto& phi = G[u];
    phi.type &= ~(1<<7);
    cout << " & (~p" << phi.literal << " | (" << array2str(G,u) << "))";
    phi.type |=  (1<<7);
  }
  cout << endl;

  return 0;
}
<commit_msg>Improving comments<commit_after>#include <bits/stdc++.h>
using namespace std;

#define MAXN    100005
#define clip(X) min(X,10000)

// IMPLEMENTACAO/TESTES
// procurar formulas menores nas maiores, mais ou menos R² * d(phi) (melhoria1)
// dp para otimizar o renaming limitando o nro maximo de literais   (melhoria2)
// procurar um benchmark e adaptar a entrada para ele
// adaptar a saida para algum provador, colocando em CNF

// MONOGRAFIA
// colocar exemplo 3.2

// formula
enum {CONJ=0,DISJ,IMPL,EQUI,NEGA,ATOM};
struct Vertex {
  char type;
  int literal;
  int up;
  vector<int> down;
  int p;
  Vertex() : p(1) {}
} G[MAXN];
int V = 0;

// parse string to create tree
// first: tree
// second: number of literals
pair<vector<Vertex>,int> parse(string phi) {
  // tells if a character is valid for a variable name
  auto isvarsym = [](char c) {
    return
      ('0' <= c && c <= '9') ||
      ('a' <= c && c <= 'z') ||
      ('A' <= c && c <= 'Z')
    ;
  };

  vector<Vertex> ret(1);
  ret.back().type = CONJ;
  ret.back().up = 0;
  stack<int> S;
  S.push(0);
  map<string,int> id;
  int nextlit = 1;
  for (int i = 0; i < phi.size(); i++) {
    char c = phi[i];
    if (c == ' ' || c == '\t') continue;
    else if (c == '&') ret[S.top()].type = CONJ;
    else if (c == '|') ret[S.top()].type = DISJ;
    else if (c == '=') { ret[S.top()].type = IMPL; i++; }
    else if (c == '<') { ret[S.top()].type = EQUI; i += 2; }
    else if (c == '(' || c == '~') { // push
      S.push(ret.size());
      ret.emplace_back();
      ret.back().type = (c == '(' ? CONJ : NEGA);
    }
    else if (c == ')') { // pop
      int u = S.top();
      S.pop();
      ret[u].up = S.top();
      ret[S.top()].down.push_back(u);
      // removing multiple parentheses
      if (ret[u].type != NEGA && ret[u].down.size() == 1) {
        int u1 = ret[u].down.front();
        ret[u].type = ret[u1].type;
        ret[u].down = ret[u1].down;
        for (int v : ret[u].down) ret[v].up = u;
      }
    }
    else { // literal
      string tmp = {phi[i]};
      while (i+1 < phi.size() && isvarsym(phi[i+1])) tmp += phi[++i];
      int& lit = id[tmp];
      if (!lit) lit = nextlit++;
      ret[S.top()].down.push_back(ret.size());
      ret.emplace_back();
      ret.back().type = ATOM;
      ret.back().literal = lit;
      ret.back().up = S.top();
      if (ret[S.top()].type == NEGA) { phi[i] = ')'; i--; }
    }
  }
  // removing multiple parentheses
  if (ret[0].down.size() == 1) {
    int u = ret[0].down.front();
    ret[0].type = ret[u].type;
    ret[0].down = ret[u].down;
    for (int v : ret[0].down) ret[v].up = 0;
  }
  return make_pair(ret,id.size());
}

void nnf(vector<Vertex>& T) {
  // copy tree rooted at u
  function<int(int)> copy = [&](int u) {
    int nu = T.size(); T.emplace_back();
    T[nu].type = T[u].type;
    T[nu].literal = T[u].literal;
    for (int v : T[u].down) {
      int tmp = copy(v);
      T[tmp].up = nu;
      T[nu].down.push_back(tmp);
    }
    return nu;
  };

  // remove implications and equivalences
  function<void(int)> dfs1 = [&](int u) {
    if (T[u].type == IMPL) {
      T[u].type = DISJ;
      int v = T[u].down.front();
      int negi = T.size(); T.emplace_back();
      T[negi].type = NEGA;
      T[u].down.front() = negi;
      T[negi].up = u;
      T[negi].down.push_back(v);
      T[v].up = negi;
    }
    else if (T[u].type == EQUI) {
      auto f = [&](int a, int b) {
        int impi = T.size(); T.emplace_back();
        T[impi].type = IMPL;
        T[u].down.push_back(impi);
        T[impi].up = u;
        T[impi].down.push_back(a), T[impi].down.push_back(b);
        T[a].up = impi, T[b].up = impi;
      };
      T[u].type = CONJ;
      int a = T[u].down.front(),  b = T[u].down.back();
      int c = copy(b),            d = copy(a);
      T[u].down.clear();
      f(a,b);
      f(c,d);
    }
    for (int v : T[u].down) dfs1(v);
  };
  dfs1(0);

  // remove negations
  function<void(int,bool)> dfs2 = [&](int u, bool neg) {
    if (!neg) {
      if (T[u].type == NEGA) {
        auto& phi1 = T[T[u].down.front()];
        if (phi1.type == NEGA) {
          auto& phi2 = T[phi1.down.front()];
          T[u].type = phi2.type;
          T[u].literal = phi2.literal;
          T[u].down = phi2.down;
          for (int v : T[u].down) T[v].up = u;
          phi1.type = CONJ, phi2.type = CONJ; // removing phi1 and phi2
        }
        else if (phi1.type != ATOM) { // CONJ or DISJ
          T[u].type = (phi1.type == CONJ ? DISJ : CONJ);
          T[u].down = phi1.down;
          for (int v : T[u].down) T[v].up = u;
          phi1.type = CONJ; // removing phi1
          neg = true;
        }
      }
    }
    else {
      if (T[u].type == NEGA) {
        auto& phi1 = T[T[u].down.front()];
        T[u].type = phi1.type;
        T[u].literal = phi1.literal;
        T[u].down = phi1.down;
        for (int v : T[u].down) T[v].up = u;
        phi1.type = CONJ; // removing phi1
        neg = false;
      }
      else if (T[u].type != ATOM) { // CONJ or DISJ
        T[u].type = (T[u].type == CONJ ? DISJ : CONJ);
      }
      else { // ATOM
        int atmi = copy(u);
        T[u].type = NEGA;
        T[u].down.push_back(atmi);
        T[atmi].up = u;
        neg = false;
      }
    }
    for (int v : T[u].down) dfs2(v,neg);
  };
  dfs2(0,false);
}

// build DAG from tree T
void build(const vector<Vertex>& T) {
  map<int,int> lit_newu;
  map<int,multiset<int>> oldp_newc;
  V = 1;

  // create vertices for literals
  for (int i = 0; i < T.size(); i++) if (T[i].type == ATOM) {
    auto& phi = T[i];
    int& u = lit_newu[phi.literal];
    if (!u) {
      u = ++V;
      G[u].type = ATOM;
      G[u].literal = phi.literal;
    }
    oldp_newc[phi.up].insert(u);
  }

  // search tree bottom-up to create vertices for subformulas
  for (map<multiset<int>,int> newc_newp; !oldp_newc.empty();) {
    list<pair<int,int>> tmp;
    for (auto kv = oldp_newc.begin(); kv != oldp_newc.end();) {
      auto& phi = T[kv->first];
      if (kv->second.size() < phi.down.size()) { kv++; continue; }
      int& u = newc_newp[kv->second];
      if (!u) {
        u = (phi.up != kv->first) ? ++V : 1;
        G[u].type = phi.type;
        for (int v : kv->second) G[u].down.push_back(v);
      }
      if (phi.up != kv->first) tmp.emplace_back(phi.up,u);
      oldp_newc.erase(kv++);
    }
    for (auto& kv : tmp) oldp_newc[kv.first].insert(kv.second);
  }
}

// position of u in a reverse toposort
int pos(int u) {
  static int next = 1, dp[MAXN] = {};
  int& ans = dp[u];
  if (ans) return ans;
  for (int v : G[u].down) pos(v);
  return ans = next++;
}

// p(phi(u))
int p(int u) {
  static int dp[MAXN] = {};
  int& ans = dp[u];
  if (ans) return ans;
  switch (G[u].type) {
    case CONJ: ans = 0; for (int v : G[u].down) ans = clip(ans+p(v)); break;
    case DISJ: ans = 1; for (int v : G[u].down) ans = clip(ans*p(v)); break;
    default:   ans = 1; break;
  }
  return ans;
}

// Boy de la Tour's top-down renaming
vector<int> R;
int nextR;
void R_rec(int u, int a) {
  auto& phi = G[u];
  if (phi.p == 1) return;

  // check renaming condition
  bool renamed = false;
  if (a > 1) {
    a = 1;
    renamed = true;
  }

  // search children
  if (phi.type == CONJ) {
    for (int v : phi.down) R_rec(v,a);
    phi.p = 0; for (int v : phi.down) phi.p = clip(phi.p+G[v].p);
  }
  else { // phi.type == DISJ
    int n = phi.down.size();

    vector<int> dp(n,1); // dp[i] = prod(phi_j.p), i < j < n
    for (int i = n-2; 0 <= i; i--) dp[i] = clip(G[phi.down[i+1]].p*dp[i+1]);

    int ai = a; // ai = a*prod(phi_j.p), 0 <= j < i
    for (int i = 0; i < n; i++) {
      R_rec(phi.down[i],clip(ai*dp[i]));
      ai = clip(ai*G[phi.down[i]].p);
    }
    phi.p = 1; for (int v : phi.down) phi.p = clip(phi.p*G[v].p);
  }

  if (renamed) {
    R.push_back(u);
    phi.type |= (1<<7);
    phi.literal = nextR++;
    phi.p = 1;
  }
}

// pretty print a formula
string array2str(Vertex formula[], int root) {
  stringstream ss;
  function<void(int)> dfs = [&](int u) {
    auto& phi = formula[u];
    if (phi.type == ATOM || phi.type&(1<<7)) {
      ss << "p" << phi.literal;
      return;
    }
    if (phi.type == NEGA) {
      ss << "~";
      dfs(phi.down.front());
      return;
    }
    ss << "(";
    char op = phi.type == CONJ ? '&' : '|';
    bool printed = false;
    for (int u : phi.down) {
      if (printed) ss << " " << op << " ";
      printed = true;
      dfs(u);
    }
    ss << ")";
  };
  auto& phi = formula[root];
  char op = phi.type == CONJ ? '&' : '|';
  bool printed = false;
  for (int u : phi.down) {
    if (printed) ss << " " << op << " ";
    printed = true;
    dfs(u);
  }
  return ss.str();
}

int main() {

  // input
  string phi;
  getline(cin,phi);

  // preprocess
  auto tree = parse(phi);
  nnf(tree.first);
  build(tree.first);
  auto toposort = [](int u, int v){ return pos(u) < pos(v); };
  for (int u = 1; u <= V; u++) {
    auto& phi = G[u];
    sort(phi.down.begin(),phi.down.end(),toposort);
    phi.p = p(u);
  }
  cout << array2str(G,1) << endl;

  // renaming
  nextR = tree.second+1;
  R_rec(1,1);

  // output
  cout << "(" << array2str(G,1) << ")";
  for (int u : R) {
    auto& phi = G[u];
    phi.type &= ~(1<<7);
    cout << " & (~p" << phi.literal << " | (" << array2str(G,u) << "))";
    phi.type |=  (1<<7);
  }
  cout << endl;

  return 0;
}
<|endoftext|>


<commit_before>bb6daf11-2747-11e6-b81a-e0f84713e7b8<commit_msg>Did ANOTHER thing<commit_after>bb87afa1-2747-11e6-a3dd-e0f84713e7b8<|endoftext|>


<commit_before>#include "mainwindow.h"
#include <QWebView>
#include <QtWidgets>
#include <QWebFrame>
#include <QDir>
#include <QApplication>
#include <QDebug>
#include <QWebPage>
#include <QObject>

/*
 *  Utility:
 *  ./exectuable pageAddress width height decoration
 *
 *   - pageAddress: the html file path or url
 *   - width:       integer that represent the width of the window
 *   - height:      integer that represent the height of the window
 *   - decoration:  if it is "UNDECORATED" the window will be undecorated (it will not have
 *                  borders and the window buttons
 *
 * */

QWebView *webView;

/*
 *  Javascript functions (Public API)
 * */
class MyJavaScriptOperations : public QObject {
    Q_OBJECT
public:
    /*
     *  Close window
     *  $API.closeWindow();
     *
     **/
    Q_INVOKABLE void closeWindow () {
        webView->close();
    }

    /*
     *  Resize
     *  $API.resize(width, height);
     *
     **/
    Q_INVOKABLE void resize (int width, int height) {
        webView->resize(width, height);
    }

    /*
     *  Set window flags
     *  $API.setWindowFlags (type)
     *      - UNDECORATED
     *
     * */
    Q_INVOKABLE void setWindowFlags (QString type) {

        QStringList options;
        options << "UNDECORATED";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowFlags(Qt::FramelessWindowHint);
                webView->show();
                break;
            // TODO Other cases
        }
    }

    /*
     *  Set window state
     *  $API.setWindowState (value)
     *      - MAXIMIZED
     *      - MINIMIZED
     *      - FULLSCREEN
     *      - ACTIVE
     * */
    Q_INVOKABLE void setWindowState (QString type) {

        QStringList options;
        options << "MAXIMIZED" << "MINIMIZED" << "FULLSCREEN" << "ACTIVATE";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowState(Qt::WindowMaximized);
                break;
            case 1:
                webView->setWindowState(Qt::WindowMinimized);
                break;
            case 2:
                webView->setWindowState(Qt::WindowFullScreen);
                break;
            case 3:
                webView->setWindowState(Qt::WindowActive);
                break;
        }
    }

    /*
     *  Get window size
     *  $API.getWindowSize ()
     * */
    Q_INVOKABLE QObject *getWindowSize () {

        QObject *size = new QObject();
        QSize winSize = webView->size();

        size->setProperty("width", winSize.width());
        size->setProperty("height", winSize.height());

        return size;
    }

    /*
     *  Set window position
     *  $API.setWindowPosition (left, top)
     * */
    Q_INVOKABLE void setWindowPosition (int left, int top) {
        webView->move(left, top);
    }

    /*
     *  Get window position
     *  $API.getWindowPosition (left, top)
     * */
    Q_INVOKABLE QObject *getWindowPosition () {
        QObject *position = new QObject();
        QPoint point = webView->pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Debug
     *  $API.debug(message)
     *
     * */
    Q_INVOKABLE void debug (QString message) {
        qDebug() << message;
    }
};

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

    QApplication app(argc, argv);

    // build the web view
    QWebView *view = new QWebView();

    webView = view;

    // get the html path
    QString HTML_PATH       = QString(argv[1]);

    // the path is NOT a web site url
    if (!HTML_PATH.startsWith("htt"))
    {
        // get it from the local machine
        HTML_PATH = "file://" + QDir::current().absolutePath() + QDir::separator() + HTML_PATH;
    }

    // set window width and height
    int     WINDOW_WIDTH    = QString(argv[2]).toInt();
    int     WINDOW_HEIGHT   = QString(argv[3]).toInt();

    // handle "UNDECORATED" flag
    if (QString(argv[4]) == "UNDECORATED") {
        view->setWindowFlags(Qt::FramelessWindowHint);
    }

    // add the public api functions
    view->page()->mainFrame()->addToJavaScriptWindowObject("$API", new MyJavaScriptOperations);

    // resize the window
    view->resize(WINDOW_WIDTH, WINDOW_HEIGHT);

    // load that HTML file or website
    view->load(QUrl(HTML_PATH));

    // show the web view
    view->show();

    return app.exec();
}

#include "main.moc"
<commit_msg>Added getMousePosition function. Trying to set transparent background for web view.<commit_after>#include "mainwindow.h"
#include <QWebView>
#include <QtWidgets>
#include <QWebFrame>
#include <QDir>
#include <QApplication>
#include <QDebug>
#include <QWebPage>
#include <QObject>

/*
 *  Utility:
 *  ./exectuable pageAddress width height decoration
 *
 *   - pageAddress: the html file path or url
 *   - width:       integer that represent the width of the window
 *   - height:      integer that represent the height of the window
 *   - decoration:  if it is "UNDECORATED" the window will be undecorated (it will not have
 *                  borders and the window buttons
 *
 * */

QWebView *webView;

/*
 *  Javascript functions (Public API)
 * */
class MyJavaScriptOperations : public QObject {
    Q_OBJECT
public:
    /*
     *  Close window
     *  $API.closeWindow();
     *
     **/
    Q_INVOKABLE void closeWindow () {
        webView->close();
    }

    /*
     *  Resize
     *  $API.resize(width, height);
     *
     **/
    Q_INVOKABLE void resize (int width, int height) {
        webView->resize(width, height);
    }

    /*
     *  Set window flags
     *  $API.setWindowFlags (type)
     *      - UNDECORATED
     *
     * */
    Q_INVOKABLE void setWindowFlags (QString type) {

        QStringList options;
        options << "UNDECORATED";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowFlags(Qt::FramelessWindowHint);
                webView->show();
                break;
            // TODO Other cases
        }
    }

    /*
     *  Set window state
     *  $API.setWindowState (value)
     *      - MAXIMIZED
     *      - MINIMIZED
     *      - FULLSCREEN
     *      - ACTIVE
     * */
    Q_INVOKABLE void setWindowState (QString type) {

        QStringList options;
        options << "MAXIMIZED" << "MINIMIZED" << "FULLSCREEN" << "ACTIVATE";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowState(Qt::WindowMaximized);
                break;
            case 1:
                webView->setWindowState(Qt::WindowMinimized);
                break;
            case 2:
                webView->setWindowState(Qt::WindowFullScreen);
                break;
            case 3:
                webView->setWindowState(Qt::WindowActive);
                break;
        }
    }

    /*
     *  Get window size
     *  $API.getWindowSize ()
     * */
    Q_INVOKABLE QObject *getWindowSize () {

        QObject *size = new QObject();
        QSize winSize = webView->size();

        size->setProperty("width", winSize.width());
        size->setProperty("height", winSize.height());

        return size;
    }

    /*
     *  Set window position
     *  $API.setWindowPosition (left, top)
     * */
    Q_INVOKABLE void setWindowPosition (int left, int top) {
        webView->move(left, top);
    }

    /*
     *  Get window position
     *  $API.getWindowPosition (left, top)
     * */
    Q_INVOKABLE QObject *getWindowPosition () {
        QObject *position = new QObject();
        QPoint point = webView->pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Get mouse position
     *  $API.getMousePosition()
     *
     * */
    Q_INVOKABLE QObject *getMousePosition () {
        QObject *position = new QObject();
        QPoint point = QCursor::pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Debug
     *  $API.debug(message)
     *
     * */
    Q_INVOKABLE void debug (QString message) {
        qDebug() << message;
    }

};

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

    QApplication app(argc, argv);

    // build the web view
    QWebView *view = new QWebView();

    webView = view;

    // get the html path
    QString HTML_PATH       = QString(argv[1]);

    // the path is NOT a web site url
    if (!HTML_PATH.startsWith("htt"))
    {
        // get it from the local machine
        HTML_PATH = "file://" + QDir::current().absolutePath() + QDir::separator() + HTML_PATH;
    }

    // set window width and height
    int     WINDOW_WIDTH    = QString(argv[2]).toInt();
    int     WINDOW_HEIGHT   = QString(argv[3]).toInt();

    // handle "UNDECORATED" flag
    if (QString(argv[4]) == "UNDECORATED") {
        view->setWindowFlags(Qt::FramelessWindowHint);
        QPalette palette = view->palette();
        palette.setBrush(QPalette::Base, Qt::transparent);
        view->page()->setPalette(palette);
        view->setAttribute(Qt::WA_OpaquePaintEvent, false);
    }

    // add the public api functions
    view->page()->mainFrame()->addToJavaScriptWindowObject("$API", new MyJavaScriptOperations);

    // resize the window
    view->resize(WINDOW_WIDTH, WINDOW_HEIGHT);

    // load that HTML file or website
    view->load(QUrl(HTML_PATH));

    // show the web view
    view->show();

    return app.exec();
}

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


<commit_before>e96b89f0-2747-11e6-baa5-e0f84713e7b8<commit_msg>Initial commit.13<commit_after>e974fee1-2747-11e6-aa12-e0f84713e7b8<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <windows.h>
#include <sstream>
#include <ctype.h>

using namespace std;

int main()
{
    string url, cont, format, selection;
    stringstream update;

    //Welcome message
    system("color A");
    cout << "Welcome to Youtube-dl helper\n\n " << endl;
    cout << "This little 'tool' was written by Aljaz Gros" << endl;
    cout << "Youtube-dl and FFmpeg belong to their respective owners and are not owned by me" << endl;
    cout << "I wrote this just to make downloading/conversion easier for windows users" << endl << endl;
    cout << "If you haven't got youtube-dl and/or FFMpeg get them now as they are required for this 'tool' to work properly" << endl;
    cout << "If you experiance any ffprobe errors please read README.txt\n\n" << endl;
    system("pause");
    system("cls");
    system("color F"); //Clears text and sets color to bright white after user presses any key

    //Selection menu
    select:
    cout << "What would you like to do?" << endl;
    cout << "1) Update" << endl;
    cout << "2) Download (no convertion)" << endl;
    cout << "2) Download & convert video" << endl;
    cout << "Your input: ";
    cin >> selection;
    string keep_file="";

    //If for selection
    if(selection == "1")
    {
        update << "youtube-dl -U";
        system(update.str().c_str());
        system("pause");
        goto select;
    }
    else if (selection == "2")
    {
        goto input_noformat;
    }
    else if (selection == "3")
    {
        goto input_format;
    }
    else
    {
        goto select;
        cout << "Wrong input!" << endl;
    }

    //URL input /w.o converting
    input_noformat:
    cout << "Input video URL: ";
    cin >> url;
    system("cls");
    goto no_format_skip;

    //URL Input /w converting
    input_format:
    cout << "Input video URL: ";
    cin >> url;
    system("cls");

    //Formats
    cout << "Here are recommended formats:"<<endl;
    cout << "best (1)" << endl;
    cout << "aac (2)" << endl;
    cout << "vorbis (3)" << endl;
    cout << "mp3 (4)" << endl;
    cout << "m4a (5)" << endl;
    cout << "opus (6)" << endl;
    cout << "wav (7)" << endl;
    cout << "Either write in number or input format name on your own" << endl;
    cout << "Input format: ";
    cin >> format;

    //Formats by number
    if(format == "1")
    {
        format="best";
    }
    else if(format == "2")
    {
        format="aac";
    }
    else if(format == "3")
    {
        format="vorbis";
    }
    else if(format == "4")
    {
        format="mp3";
    }
    else if(format == "5")
    {
        format="m4a";
    }
    else if(format == "6")
    {
        format="opus";
    }
    else if(format == "7")
    {
        format="wav";
    }

    //Keeping original file Y/N
    keepfile:
    cout << "Would you like to keep original file?(Y/N) ";
    cin >> keep_file;
    Sleep(1000);
    system("cls");

    //String for system()
    no_format_skip:
    stringstream call_line;
    if (keep_file == "Y" || keep_file == "y" )
    {
    call_line << "youtube-dl --output /output/%(title)s.%(ext)s --console-title --k --ignore-errors --extract-audio --audio-quality 0 --audio-format " << format << " " << url;
    }
    else if (keep_file == "N" || keep_file == "n")
    {
    call_line << "youtube-dl --output /output/%(title)s.%(ext)s --console-title --ignore-errors --extract-audio --audio-quality 0 --audio-format " << format << " " << url;
    }
    else if (selection == "2")
    {
    call_line << "youtube-dl --output /output/%(title)s.%(ext)s --console-title --ignore-errors --audio-quality 0 " << url;
    }
    else //If input is not Y/y or N/n
    {
    cout<<"Wrong input";
    goto keepfile;
    }
    system(call_line.str().c_str());
    contini:
    cout << endl << "To continue write Y to end write N." << endl;

    //Returns to start if User inputs Y
    cin >> cont;
    if(cont=="Y" || cont=="y")
    {
        goto select;
        system("cls");
    }
    else if(cont=="N" || cont=="n")
    {

    //Ends program if anything else is input by User than Y or y.
    cout << endl << "Ending program" << endl;
    Sleep(1000);
    return 0;
    }
    else
    {
        cout << "Invalid input." <<endl;
        goto contini;
    }
}
<commit_msg>Update main.cpp<commit_after>#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <windows.h>
#include <sstream>
#include <ctype.h>

using namespace std;

//Funckija za posodobitev youtube-dl
void posodobitev()
{
    stringstream posodobitev_string;
    posodobitev_string << "youtube-dl.exe -U"; //String za posodobitev
    system(posodobitev_string.str().c_str());
}

//Funkcija za pretvorbo prenesenega videa
void pretvorba_prenesenega() //Trenutno v testni fazi
{
    system("cls");
    system("cd output & dir /b *.mp4"); //Prikaže vse .mp4 datoteke v mapi output.
    cout << "\n" << endl;
    cout << "Vnesite naslov videa:" << endl;
    cout << "OPOMBA: Naslov vnesi v narekovajih drugace ne bo delovalo!" << endl;
    cout << "Naslov: ";
    string naslov_videa ="";
    cin.ignore();
    getline(cin, naslov_videa); //Uporaba getline namesto navadnega cin da zazna celoten vnos z narekovaji.
    izbris_prompt:
    int izbris;
    cout << "\nZelite obdrzati .mp4 datoteko? (1[da]/0[ne]): ";
    cin >> izbris;
    stringstream premakni_mp4, konvertiraj, premakni_mp3, zbris_mp4, obdrzi_mp4;
    cout << naslov_videa;
    premakni_mp4 << "cd output & move " << naslov_videa << " .."; //Premakne .mp4 datoteko iz output mape v mapo kjer se nahaja program
    konvertiraj << "ffmpeg -i " << naslov_videa << " -c:v lib264 " << naslov_videa << ".mp3"; //Pretvori premaknjeno .mp4 datoteko
    premakni_mp3  << "move " << naslov_videa << ".mp3 output"; //Premakne novo .mp3 datoteko katera je bila pretvorjena v mapo output
    zbris_mp4 << "del /q /f " << naslov_videa; //Zbrise .mp4 datoteko po pretvorbi
    obdrzi_mp4 << "move " << naslov_videa << " output"; //Premakne .mp4 datoteko v primeru da je ne zelimo izbrisati

    if(izbris == 1)
    {
        system(premakni_mp4.str().c_str());
        system(konvertiraj.str().c_str());
        system(premakni_mp3.str().c_str());
        system(obdrzi_mp4.str().c_str());
    }
    else if (izbris == 0)
    {
        system(premakni_mp4.str().c_str());
        system(konvertiraj.str().c_str());
        system(premakni_mp3.str().c_str());
        system(zbris_mp4.str().c_str());
    }
    else
        goto izbris_prompt;

}

//Funkcija poslje informacije za formate
void format_info()
{
    cout << "\"Hitri\" formati:" << endl;
    cout << "1. mp3" << endl;
    cout << "2. aac" << endl;
    cout << "3. wav" << endl;
    cout << "4. vorbis" << endl;
    cout << "5. opus" << endl;
    cout << "6. m4a" << endl;
    cout << "Vpisi stevilko za hitri format ali vpisi ime formata v katerega zelis pretvoriti" << endl;
}

//Funkcija za pretvorbo stevilk hitrih formatov(int) v string
string formati(string vhodni_format)
{
    //Program preveri ce je uporabnik uporabil številko za hitri format, ce ne uporabi vpisan format
    if(vhodni_format == "1")
    {
        vhodni_format = "mp3";
    }
    else if(vhodni_format == "2")
    {
        vhodni_format = "aac";
    }
    else if(vhodni_format == "3")
    {
        vhodni_format = "wav";
    }
    else if(vhodni_format == "4")
    {
        vhodni_format = "vorbis";
    }
    else if(vhodni_format == "5")
    {
        vhodni_format = "opus";
    }
    else if(vhodni_format == "6")
    {
        vhodni_format = "m4a";
    }
    return vhodni_format;
}

//Funkcija samo za prenos videa
void prenos_videa()
{
    string url;
    system("cls");
    cout << "URL Naslov videa: ";
    cin >> url;
    stringstream vnos_podatkov;
    vnos_podatkov << "youtube-dl.exe --output /output/%(title)s.%(ext)s --console-title --keep-video --ignore-errors -f best " << url; //String za prenos videa v mp4 formatu
    system(vnos_podatkov.str().c_str());
}

//Funkcija za prenos in pretvorbo videa
void prenos_in_pretvorba()
{
    pip_vnos:  //Zaèetek za vnosa; V primeru da uporanbik ne vpiše èesar pravilno ga vrne na zaèetek vpisa za prenos in pretvorbo
    string url, format;
    int obdrzi;
    stringstream obdrzi_datoteko_string, zbrisi_datoteko_string;
    system("cls");
    cout << "Vnesi URL videa: ";
    cin >> url;
    format_info();
    cout << "Vnesi format: ";
    cin >> format;
    format=formati(format); //Poklice funkcijo s formati in vrne string v primeru da smo vnesli stevilko.
    cout << "Zelite obdrzati izvorno datoteko? (DA [1]/NE [0]) " << endl;
    cout << "Vasa izbira: ";
    cin >> obdrzi;

    switch(obdrzi)
    {
        //Pretvori izvorno datoteko in jo obdrzi
        case 1:
        obdrzi_datoteko_string << "youtube-dl.exe --output /output/%(title)s.%(ext)s --console-title --keep-video --ignore-errors --extract-audio --audio-quality 0 --audio-format " << format << " " << url;
        system(obdrzi_datoteko_string.str().c_str());
        break;

        //Izbris izvorne datoteke po pretvorbi
        case 0:
        zbrisi_datoteko_string << "youtube-dl.exe --output /output/%(title)s.%(ext)s --console-title --ignore-errors --extract-audio --audio-quality 0 --audio-format " << format << " " << url;
        system(zbrisi_datoteko_string.str().c_str());
        break;

        //Povrne uporabnika nazaj na vpis v primeru, da ni vpisal 1(da) ali 0 (ne).
        default:
            goto pip_vnos;
    }

}

int main()
{
    int zacetna_izbira;
    //Program nastavi pisavo na zeleno  barvo in prikaze zagonsko sporocilo
    system("color A");
    cout << "Dobrodosli v uporabniskem vmesniku za Youtube-dl \n" << endl;
    cout << "Program Youtube-dl in ffmpeg sta tuja programa in pripadata svojim lastnikom" << endl;
    cout << "Ta program je samo uporabniski vmesnik kateri je namenjen lazji uporabi teh programov" << endl;

    //Program pocaka uporabnika, da pritisne tipko za nadaljevanje, pobirse sporocilo in nastavi pisavo nazaj na belo
    system("pause");
    system("cls");
    system("color F");

    //Zacetna izbira
    zacetek:
    cout << "1. Posodobitev" << endl;
    cout << "2. Prenos videa" << endl;
    cout << "3. Prenos in pretvorba videa" << endl;
    cout << "4. Pretvorba prenesenega videa v mp3" << endl;
    cout << "0. Izhod iz programa" << endl;
    cout << "Vasa izbira: ";
    cin >> zacetna_izbira;

    //Switch za zacetno izbiro glede na uporabnikov vnos
    switch(zacetna_izbira)
    {

    //Izhod iz programa
    case 0:
        return 0;
        break;

    //Program gre na funkcijo za posodobitev
    case 1:
        posodobitev();
        break;

    //Funkcija za samo prenos videa
    case 2:
        prenos_videa();
        break;

    //Funkcija za prenos in pretvorbo videa
    case 3:
        prenos_in_pretvorba();
        break;

    //Funkcija za pretvorbo prenesenih videev
    case 4:
        pretvorba_prenesenega();
        break;

    //Vrne uporabnika na zacetek ce je vnesel napacno stevilko
    default:
        goto zacetek;
        cout << "Napacna izbira! Poskusi znova." << endl;
        system("pause");
        system("cls");
        break;
    }

    //Se izvede po pretvorbi, prenosu ali kater koli drugi funkciji
    nadaljevanje:
    int nadaljuj;
    system("cls");
    cout << "Zelite nadaljevati? (DA [1]/NE [0]): " ;
    cin >> nadaljuj;

    switch(nadaljuj)
    {
        //Vrne se na zacetek za izbiro funkcij
        case 1:
            goto zacetek;
            break;

        //Konca program
        case 0:
            return 0;
            break;

        //Pozove uporabnika za ponoven vnos v primeru napacnega vnosa.
        default:
            cout << "Napacen vnos! Poskusi znova.";
            break;
    }

}
<|endoftext|>


<commit_before>7b27fc94-2749-11e6-a4d7-e0f84713e7b8<commit_msg>lets try again<commit_after>7b338a00-2749-11e6-9ab3-e0f84713e7b8<|endoftext|>


<commit_before>#include "main.h"
#include <chrono>

int num_rows;
int num_cols;
int num_nonzeros;

std::chrono::duration<double> blaze_time;
std::chrono::duration<double> vcl_time;
std::chrono::duration<double> vexcl_time;
std::chrono::duration<double> elapsed;
std::chrono::time_point<std::chrono::system_clock> start, end;

#include "utils.h"

void ReadSparse(COO& data, const std::string filename) {
  std::cout << "Reading: " << filename << std::endl;
  std::stringstream ss(ReadFileAsString(filename));
  size_t i, j;
  double v;

  while (true) {
    ss >> i;
    // Make sure that after reading things are still valid
    // If so then the line is good and continue
    if (ss.fail() == true) {
      break;
    }
    ss >> j >> v;
    data.row.push_back(i);
    data.col.push_back(j);
    data.val.push_back(v);
  }
  data.update();
}

void ReadVector(std::vector<double>& data, const std::string filename) {
  std::cout << "Reading: " << filename << std::endl;
  std::stringstream ss(ReadFileAsString(filename));
  double v;

  while (true) {
    ss >> v;
    // Make sure that after reading things are still valid
    // If so then the line is good and continue
    if (ss.fail() == true) {
      break;
    }
    data.push_back(v);
  }
}

int main(int argc, char* argv[]) {
  COO D_T, M_invD;
  std::vector<double> gamma;
  std::cout << "Read in data to sparse COO structure: \n";
  start = std::chrono::system_clock::now();
  ReadSparse(D_T, "D_T_" + std::string(argv[1]) + ".mat");
  ReadSparse(M_invD, "M_invD_" + std::string(argv[1]) + ".mat");
  ReadVector(gamma, "gamma_" + std::string(argv[1]) + ".mat");
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to read data from file: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  blaze::CompressedMatrix<double> D_T_blaze = BlazeTest::ConvertMatrix(D_T);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Blaze: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  blaze::CompressedMatrix<double> M_invD_blaze = BlazeTest::ConvertMatrix(M_invD);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load M_invD Blaze: " << elapsed.count() << std::endl;

  blaze::DynamicVector<double> gamma_blaze = BlazeTest::ConvertVector(gamma);

  {
    std::cout << "Blaze Test:\n";
    BlazeTest blaze_test;
    start = std::chrono::system_clock::now();
    blaze_test.RunSPMV(D_T_blaze, M_invD_blaze, gamma_blaze);
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Blaze Time: " << elapsed.count() / RUNS << std::endl;
  }

  std::cout << "Eigen Triplet:\n";
  // Convert the COO into Eigen triplets
  // Timing this part isn't important, in practice you would not need to do this
  std::vector<Eigen::Triplet<double> > D_T_triplet = EigenTest::ConvertCOO(D_T);
  std::vector<Eigen::Triplet<double> > M_invD_triplet = EigenTest::ConvertCOO(M_invD);
  std::cout << "Eigen Convert:\n";

  Eigen::SparseMatrix<double> D_T_eigen(D_T.num_rows, D_T.num_cols);
  D_T_eigen.reserve(Eigen::VectorXi::Constant(D_T.num_cols, 12));
  Eigen::SparseMatrix<double> M_invD_eigen(M_invD.num_rows, M_invD.num_cols);

  start = std::chrono::system_clock::now();
  EigenTest::ConvertMatrix(D_T_triplet, D_T, D_T_eigen);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Eigen: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  EigenTest::ConvertMatrix(M_invD_triplet, M_invD, M_invD_eigen);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Eigen: " << elapsed.count() << std::endl;

  Eigen::VectorXd gamma_eigen = EigenTest::ConvertVector(gamma);

  {
    std::cout << "Eigen Test:\n";
    start = std::chrono::system_clock::now();
    EigenTest::RunSPMV(D_T_eigen, M_invD_eigen, gamma_eigen);
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Eigen Time: " << elapsed.count() / RUNS << std::endl;
  }

  //
  //  {
  //    VexCLTest vexcl_test;
  //    vexcl_test.CreateContext();
  //    vexcl_test.WarmUp();
  //    CSR D_T_csr = BlazeTest::ConvertSparse(D_T_blaze);
  //    CSR M_invD_csr = BlazeTest::ConvertSparse(M_invD_blaze);
  //    vex::SpMat<double> D_T_vex = vexcl_test.ConvertMatrix(D_T_csr);
  //    vex::SpMat<double> M_invD_vex = vexcl_test.ConvertMatrix(M_invD_csr);
  //    vex::vector<double> gamma_vex = vexcl_test.ConvertVector(gamma);
  //
  //    start = std::chrono::system_clock::now();
  //    vexcl_test.RunSPMV(D_T_vex, M_invD_vex, gamma_vex);
  //    end = std::chrono::system_clock::now();
  //    vexcl_time = end - start;
  //  }

  //
  //  // Compute some metrics and print them out
  //  num_rows = D_T_blaze.rows();
  //  num_cols = D_T_blaze.columns();
  //  num_nonzeros = D_T_blaze.nonZeros();
  //  printf("D_T: rows:, columns:, non zeros:,M_invD: rows:, columns:, non zeros:, gamma: size:, b: size: Memory\n");
  //  printf("%d, %d, %d, %d, %d, %d, %d, %d %f\n", num_rows, num_cols, num_nonzeros, M_invD_blaze.rows(), M_invD_blaze.columns(), M_invD_blaze.nonZeros(), gamma_blaze.size(), rhs_blaze.size(),
  //         ((num_nonzeros + M_invD_blaze.nonZeros() + gamma_blaze.size() + rhs_blaze.size()) / double(GFLOP)) * sizeof(double) );
  //
  //  //  printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T_blaze.rows(), D_T_blaze.columns(), D_T_blaze.nonZeros());
  //  //  printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD_blaze.rows(), M_invD_blaze.columns(), M_invD_blaze.nonZeros());
  //  //  printf("gamma: size: %d\n", gamma_blaze.size());
  //  //  printf("b: size: %d\n", rhs_blaze.size());

  //
  //  {
  //    ViennaCLTest viennacl_test;
  //    viennacl_test.WarmUp();
  //
  //    viennacl::compressed_matrix<double> D_T_vcl = viennacl_test.ConvertMatrix(D_T_csr);
  //    viennacl::compressed_matrix<double> M_invD_vcl = viennacl_test.ConvertMatrix(M_invD_csr);
  //    viennacl::vector<double> gamma_vcl = viennacl_test.ConvertVector(gamma_blaze);
  //
  //    start = std::chrono::system_clock::now();
  //    viennacl_test.RunSPMV(D_T_vcl, M_invD_vcl, gamma_vcl);
  //    end = std::chrono::system_clock::now();
  //    vcl_time = end - start;
  //  }
  //

  //
  //  // Two Spmv each with 2*nnz operations
  //  uint operations = 2 * 2 * num_nonzeros;
  //  uint moved = 2 * (num_nonzeros + 2 * num_rows) * sizeof(double);
  //
  //  double blaze_single = blaze_time.count() / RUNS;
  //  double vex_single = vexcl_time.count() / RUNS;
  //  double vcl_single = vcl_time.count() / RUNS;
  //  // double eig_single = eigen_time.count() / RUNS;
  //
  //  printf("Blaze: %f %f %f", blaze_single, operations / blaze_single / GFLOP, moved / blaze_single / GFLOP);
  //  printf("VexCL: %f %f %f", vex_single, operations / vex_single / GFLOP, moved / vex_single / GFLOP);
  //  printf("VCL: %f %f %f", vcl_single, operations / vcl_single / GFLOP, moved / vcl_single / GFLOP);
  //
  //  //  printf("Blaze sec, VexCL sec, Speedup, Blaze Flops, VexCL Flops, Bandwidth Blaze, Bandwidth VexCL \n");
  //  //  printf("%f, %f, %f, %f, %f, %f, %f\n", blaze_single, vex_single, blaze_single / vex_single, operations / blaze_single / GFLOP, operations / vex_single / GFLOP, moved / blaze_single / GFLOP,
  //  //         moved / vex_single / GFLOP);
  //  //  //
  //  //  printf("Blaze %f sec. Eigen %f sec. VexCL %f sec.\n", blaze_single, eig_single, vex_single);
  //  //  printf("Speedup: Blaze vs Eigen %f\n", blaze_single / eig_single);
  //  //  printf("Speedup: Blaze vs VexCL %f\n", blaze_single / vex_single);
  //  //  printf("Speedup: Eigen vs VexCL %f\n", eig_single / vex_single);
  //  //
  //  //  printf("Flops: Blaze %f Eigen %f VexCL %f\n", operations / blaze_single / GFLOP, operations / eig_single / GFLOP, operations / vex_single / GFLOP);
  //  //  printf("Bandwidth: Blaze %f Eigen %f VexCL %f\n", moved / blaze_single / GFLOP, moved / eig_single / GFLOP, moved / vex_single / GFLOP);

  return 0;
}
<commit_msg>Output timing for transposing a matrix<commit_after>#include "main.h"
#include <chrono>

int num_rows;
int num_cols;
int num_nonzeros;

std::chrono::duration<double> blaze_time;
std::chrono::duration<double> vcl_time;
std::chrono::duration<double> vexcl_time;
std::chrono::duration<double> elapsed;
std::chrono::time_point<std::chrono::system_clock> start, end;

#include "utils.h"

void ReadSparse(COO& data, const std::string filename) {
  std::cout << "Reading: " << filename << std::endl;
  std::stringstream ss(ReadFileAsString(filename));
  size_t i, j;
  double v;

  while (true) {
    ss >> i;
    // Make sure that after reading things are still valid
    // If so then the line is good and continue
    if (ss.fail() == true) {
      break;
    }
    ss >> j >> v;
    data.row.push_back(i);
    data.col.push_back(j);
    data.val.push_back(v);
  }
  data.update();
}

void ReadVector(std::vector<double>& data, const std::string filename) {
  std::cout << "Reading: " << filename << std::endl;
  std::stringstream ss(ReadFileAsString(filename));
  double v;

  while (true) {
    ss >> v;
    // Make sure that after reading things are still valid
    // If so then the line is good and continue
    if (ss.fail() == true) {
      break;
    }
    data.push_back(v);
  }
}

int main(int argc, char* argv[]) {
  COO D_T, M_invD;
  std::vector<double> gamma;
  std::cout << "Read in data to sparse COO structure: \n";
  start = std::chrono::system_clock::now();
  ReadSparse(D_T, "D_T_" + std::string(argv[1]) + ".mat");
  ReadSparse(M_invD, "M_invD_" + std::string(argv[1]) + ".mat");
  ReadVector(gamma, "gamma_" + std::string(argv[1]) + ".mat");
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to read data from file: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  blaze::CompressedMatrix<double> D_T_blaze = BlazeTest::ConvertMatrix(D_T);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Blaze: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  blaze::CompressedMatrix<double> M_invD_blaze = BlazeTest::ConvertMatrix(M_invD);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load M_invD Blaze: " << elapsed.count() << std::endl;

  blaze::DynamicVector<double> gamma_blaze = BlazeTest::ConvertVector(gamma);

  {
    std::cout << "Blaze Test:\n";
    BlazeTest blaze_test;
    start = std::chrono::system_clock::now();
    blaze_test.RunSPMV(D_T_blaze, M_invD_blaze, gamma_blaze);
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Blaze Time: " << elapsed.count() / RUNS << std::endl;

    start = std::chrono::system_clock::now();
    blaze::CompressedMatrix<double> Transposed = blaze::trans(D_T_blaze);
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Blaze Transpose Time: " << elapsed.count() / RUNS << std::endl;
  }

  std::cout << "Eigen Triplet:\n";
  // Convert the COO into Eigen triplets
  // Timing this part isn't important, in practice you would not need to do this
  std::vector<Eigen::Triplet<double> > D_T_triplet = EigenTest::ConvertCOO(D_T);
  std::vector<Eigen::Triplet<double> > M_invD_triplet = EigenTest::ConvertCOO(M_invD);
  std::cout << "Eigen Convert:\n";

  Eigen::SparseMatrix<double> D_T_eigen(D_T.num_rows, D_T.num_cols);
  D_T_eigen.reserve(Eigen::VectorXi::Constant(D_T.num_cols, 12));
  Eigen::SparseMatrix<double> M_invD_eigen(M_invD.num_rows, M_invD.num_cols);

  start = std::chrono::system_clock::now();
  EigenTest::ConvertMatrix(D_T_triplet, D_T, D_T_eigen);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Eigen: " << elapsed.count() << std::endl;

  start = std::chrono::system_clock::now();
  EigenTest::ConvertMatrix(M_invD_triplet, M_invD, M_invD_eigen);
  end = std::chrono::system_clock::now();
  elapsed = end - start;
  std::cout << "Time to load D_T Eigen: " << elapsed.count() << std::endl;

  Eigen::VectorXd gamma_eigen = EigenTest::ConvertVector(gamma);

  {
    std::cout << "Eigen Test:\n";
    start = std::chrono::system_clock::now();
    EigenTest::RunSPMV(D_T_eigen, M_invD_eigen, gamma_eigen);
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Eigen Time: " << elapsed.count() / RUNS << std::endl;

    start = std::chrono::system_clock::now();
    Eigen::SparseMatrix<double> Transposed(D_T_eigen.transpose());
    end = std::chrono::system_clock::now();
    elapsed = end - start;
    std::cout << "Eigen Transpose Time: " << elapsed.count() / RUNS << std::endl;
  }

  //
  //  {
  //    VexCLTest vexcl_test;
  //    vexcl_test.CreateContext();
  //    vexcl_test.WarmUp();
  //    CSR D_T_csr = BlazeTest::ConvertSparse(D_T_blaze);
  //    CSR M_invD_csr = BlazeTest::ConvertSparse(M_invD_blaze);
  //    vex::SpMat<double> D_T_vex = vexcl_test.ConvertMatrix(D_T_csr);
  //    vex::SpMat<double> M_invD_vex = vexcl_test.ConvertMatrix(M_invD_csr);
  //    vex::vector<double> gamma_vex = vexcl_test.ConvertVector(gamma);
  //
  //    start = std::chrono::system_clock::now();
  //    vexcl_test.RunSPMV(D_T_vex, M_invD_vex, gamma_vex);
  //    end = std::chrono::system_clock::now();
  //    vexcl_time = end - start;
  //  }

  //
  //  // Compute some metrics and print them out
  //  num_rows = D_T_blaze.rows();
  //  num_cols = D_T_blaze.columns();
  //  num_nonzeros = D_T_blaze.nonZeros();
  //  printf("D_T: rows:, columns:, non zeros:,M_invD: rows:, columns:, non zeros:, gamma: size:, b: size: Memory\n");
  //  printf("%d, %d, %d, %d, %d, %d, %d, %d %f\n", num_rows, num_cols, num_nonzeros, M_invD_blaze.rows(), M_invD_blaze.columns(), M_invD_blaze.nonZeros(), gamma_blaze.size(), rhs_blaze.size(),
  //         ((num_nonzeros + M_invD_blaze.nonZeros() + gamma_blaze.size() + rhs_blaze.size()) / double(GFLOP)) * sizeof(double) );
  //
  //  //  printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T_blaze.rows(), D_T_blaze.columns(), D_T_blaze.nonZeros());
  //  //  printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD_blaze.rows(), M_invD_blaze.columns(), M_invD_blaze.nonZeros());
  //  //  printf("gamma: size: %d\n", gamma_blaze.size());
  //  //  printf("b: size: %d\n", rhs_blaze.size());

  //
  //  {
  //    ViennaCLTest viennacl_test;
  //    viennacl_test.WarmUp();
  //
  //    viennacl::compressed_matrix<double> D_T_vcl = viennacl_test.ConvertMatrix(D_T_csr);
  //    viennacl::compressed_matrix<double> M_invD_vcl = viennacl_test.ConvertMatrix(M_invD_csr);
  //    viennacl::vector<double> gamma_vcl = viennacl_test.ConvertVector(gamma_blaze);
  //
  //    start = std::chrono::system_clock::now();
  //    viennacl_test.RunSPMV(D_T_vcl, M_invD_vcl, gamma_vcl);
  //    end = std::chrono::system_clock::now();
  //    vcl_time = end - start;
  //  }
  //

  //
  //  // Two Spmv each with 2*nnz operations
  //  uint operations = 2 * 2 * num_nonzeros;
  //  uint moved = 2 * (num_nonzeros + 2 * num_rows) * sizeof(double);
  //
  //  double blaze_single = blaze_time.count() / RUNS;
  //  double vex_single = vexcl_time.count() / RUNS;
  //  double vcl_single = vcl_time.count() / RUNS;
  //  // double eig_single = eigen_time.count() / RUNS;
  //
  //  printf("Blaze: %f %f %f", blaze_single, operations / blaze_single / GFLOP, moved / blaze_single / GFLOP);
  //  printf("VexCL: %f %f %f", vex_single, operations / vex_single / GFLOP, moved / vex_single / GFLOP);
  //  printf("VCL: %f %f %f", vcl_single, operations / vcl_single / GFLOP, moved / vcl_single / GFLOP);
  //
  //  //  printf("Blaze sec, VexCL sec, Speedup, Blaze Flops, VexCL Flops, Bandwidth Blaze, Bandwidth VexCL \n");
  //  //  printf("%f, %f, %f, %f, %f, %f, %f\n", blaze_single, vex_single, blaze_single / vex_single, operations / blaze_single / GFLOP, operations / vex_single / GFLOP, moved / blaze_single / GFLOP,
  //  //         moved / vex_single / GFLOP);
  //  //  //
  //  //  printf("Blaze %f sec. Eigen %f sec. VexCL %f sec.\n", blaze_single, eig_single, vex_single);
  //  //  printf("Speedup: Blaze vs Eigen %f\n", blaze_single / eig_single);
  //  //  printf("Speedup: Blaze vs VexCL %f\n", blaze_single / vex_single);
  //  //  printf("Speedup: Eigen vs VexCL %f\n", eig_single / vex_single);
  //  //
  //  //  printf("Flops: Blaze %f Eigen %f VexCL %f\n", operations / blaze_single / GFLOP, operations / eig_single / GFLOP, operations / vex_single / GFLOP);
  //  //  printf("Bandwidth: Blaze %f Eigen %f VexCL %f\n", moved / blaze_single / GFLOP, moved / eig_single / GFLOP, moved / vex_single / GFLOP);

  return 0;
}
<|endoftext|>