<commit_before>#include <iostream>
#include <fstream>
#include <getopt.h>
#include <algorithm>
#include <memory>

#include <zcm/zcm-cpp.hpp>

#include "zcm/json/json.h"

#include "zcm/util/TypeDb.hpp"

#include "IndexerPluginDb.hpp"

using namespace std;

struct Args
{
    string logfile     = "";
    string output      = "";
    string plugin_path = "";
    string type_path   = "";
    bool readable      = false;
    bool debug         = false;

    bool parse(int argc, char *argv[])
    {
        // set some defaults
        const char *optstring = "l:o:p:t:rdh";
        struct option long_opts[] = {
            { "log",         required_argument, 0, 'l' },
            { "output",      required_argument, 0, 'o' },
            { "plugin-path", required_argument, 0, 'p' },
            { "type-path",   required_argument, 0, 't' },
            { "readable",    no_argument,       0, 'r' },
            { "debug",       no_argument,       0, 'd' },
            { "help",        no_argument,       0, 'h' },
            { 0, 0, 0, 0 }
        };

        int c;
        while ((c = getopt_long (argc, argv, optstring, long_opts, 0)) >= 0) {
            switch (c) {
                case 'l': logfile     = string(optarg); break;
                case 'o': output      = string(optarg); break;
                case 'p': plugin_path = string(optarg); break;
                case 't': type_path   = string(optarg); break;
                case 'r': readable    = true;           break;
                case 'd': debug       = true;           break;
                case 'h': default: return false;
            };
        }

        if (logfile == "") {
            cerr << "Please specify logfile input" << endl;
            return false;
        }

        if (output  == "") {
            cerr << "Please specify index file output" << endl;
            return false;
        }

        const char* type_path_env = getenv("ZCM_LOG_INDEXER_ZCMTYPES_PATH");
        if (type_path == "" && type_path_env) type_path = type_path_env;
        if (type_path == "") {
            cerr << "Please specify a zcmtypes.so path either through -t TYPE_PATH "
                    "or through the env var ZCM_LOG_INDEXER_ZCMTYPES_PATH" << endl;
            return false;
        }

        const char* plugin_path_env = getenv("ZCM_LOG_INDEXER_PLUGINS_PATH");
        if (plugin_path == "" && plugin_path_env) plugin_path = plugin_path_env;
        if (plugin_path == "") cerr << "Running with default timestamp indexer plugin" << endl;

        return true;
    }

    void usage()
    {
        cerr << "usage: zcm-log-indexer [options]" << endl
             << "" << endl
             << "    Load in a log file and write an index json file that" << endl
             << "    allows for faster log indexing." << endl
             << "" << endl
             << "Example:" << endl
             << "    zcm-log-indexer -l zcm.log -o index.dbz -t path/to/zcmtypes.so" << endl
             << "" << endl
             << "Options:" << endl
             << "" << endl
             << "  -h, --help              Shows this help text and exits" << endl
             << "  -l, --log=logfile       Input log to index for fast querying" << endl
             << "  -o, --output=indexfile  Output index file to be used with log" << endl
             << "  -p, --plugin-path=path  Path to shared library containing indexer plugins" << endl
             << "                          Can also be specified via the environment variable" << endl
             << "                          ZCM_LOG_INDEXER_ZCMTYPES_PATH" << endl
             << "  -t, --type-path=path    Path to shared library containing the zcmtypes" << endl
             << "                          Can also be specified via the environment variable" << endl
             << "                          ZCM_LOG_INDEXER_PLUGINS_PATH" << endl
             << "  -r, --readable          Don't minify the output index file. " << endl
             << "                          Leave it human readable" << endl
             << "  -d, --debug             Run a dry run to ensure proper indexer setup" << endl
             << endl << endl;
    }
};

int main(int argc, char* argv[])
{
    Args args;
    if (!args.parse(argc, argv)) {
        args.usage();
        return 1;
    }

    zcm::LogFile log(args.logfile, "r");
    if (!log.good()) {
        cerr << "Unable to open logfile: " << args.logfile << endl;
        return 1;
    }
    fseeko(log.getFilePtr(), 0, SEEK_END);
    // XXX Look into handling large logfiles
    off_t logSize = ftello(log.getFilePtr());

    ofstream output;
    output.open(args.output);
    if (!output.is_open()) {
        cerr << "Unable to open output file: " << args.output << endl;
        log.close();
        return 1;
    }

    vector<zcm::IndexerPlugin*> plugins;

    bool defaultShouldBeIncluded = true;
    zcm::IndexerPlugin* defaultPlugin = new zcm::IndexerPlugin();

    IndexerPluginDb pluginDb(args.plugin_path, args.debug);
    // Load plugins from path if specified
    if (args.plugin_path != "") {
        bool dependsOnDefault = false;
        vector<const zcm::IndexerPlugin*> dbPlugins = pluginDb.getPlugins();
        // casting away constness. Don't mess up.
        for (auto dbp : dbPlugins) {
            plugins.push_back((zcm::IndexerPlugin*) dbp);
            defaultShouldBeIncluded = false;
            auto deps = dbp->dependsOn();
            for (auto dep : deps) {
                if (dep == defaultPlugin->name()) {
                    dependsOnDefault = true;
                    break;
                }
            }
        }

        if (dependsOnDefault)
            defaultShouldBeIncluded = true;
    }

    if (defaultShouldBeIncluded) plugins.push_back(defaultPlugin);

    for (size_t i = 0; i < plugins.size(); ++i) {
        for (size_t j = i + 1; j < plugins.size(); ++j) {
            if (args.debug)
                cout << plugins.data()[i] << "->name() == "
                     << plugins.data()[j] << "->name()" << endl;

            if (plugins[i]->name() == plugins[j]->name()) {
                cerr << "Plugins must have unique names. Collision: "
                     << plugins[i]->name() << endl;
                return 1;
            }
        }
    }

    TypeDb types(args.type_path, args.debug);

    if (args.debug) return 0;

    struct PluginRuntimeInfo {
        zcm::IndexerPlugin* plugin;
        bool runThroughLog;
    };

    auto buildPluginGroups = [] (vector<zcm::IndexerPlugin*> plugins) {
        vector<vector<PluginRuntimeInfo>> groups;
        vector<zcm::IndexerPlugin*> lastLoop = plugins;
        while (!plugins.empty()) {
            groups.resize(groups.size() + 1);
            for (auto p = plugins.begin(); p != plugins.end();) {
                auto deps = (*p)->dependsOn();

                bool skipUntilLater = false;
                for (auto* dep : plugins) {
                    if (find(deps.begin(), deps.end(), dep->name()) != deps.end()) {
                        skipUntilLater = true;
                        break;
                    }
                }
                for (auto dep : groups.back()) {
                    if (find(deps.begin(), deps.end(), dep.plugin->name()) != deps.end()) {
                        skipUntilLater = true;
                        break;
                    }
                }
                if (!skipUntilLater) {
                    groups.back().push_back({*p, false});
                    p = plugins.erase(p);
                } else {
                    ++p;
                }
            }

            // Check for dependency resolution failure
            if (plugins == lastLoop) {
                cerr << "Unable to resolve all plugin dependencies. "
                        "Plugins left to resolve:" << endl << endl;
                for (auto* p : plugins) {
                    cerr << p->name() << endl
                         << "  Depends on:" << endl;
                    for (auto d : p->dependsOn())
                         cerr << "    " << d << endl;
                    cerr << endl;
                }
                exit(1);
            }
            lastLoop = plugins;
        }
        return groups;
    };

    // We do not own all the memory in here. We only own the default prorgam
    vector<vector<PluginRuntimeInfo>> pluginGroups;
    pluginGroups = buildPluginGroups(plugins);
    if (pluginGroups.size() > 1) {
        cout << "Identified " << pluginGroups.size() << " indexer plugin groups" << endl
             << "Running through log " << pluginGroups.size()
             << " times to satisfy dependencies" << endl;
    }

    zcm::Json::Value index;

    size_t numEvents = 0;
    const zcm::LogEvent* evt;
    for (size_t i = 0; i < pluginGroups.size(); ++i) {
        if (pluginGroups.size() != 1) cout << "Plugin group " << (i + 1) << endl;
        off_t offset = 0;
        fseeko(log.getFilePtr(), 0, SEEK_SET);

        for (auto& p : pluginGroups[i])
            p.runThroughLog = p.plugin->setUp(index, index[p.plugin->name()], log);

        while (1) {
            offset = ftello(log.getFilePtr());

            static int lastPrintPercent = 0;
            int percent = (100.0 * offset / logSize) * 100;
            if (percent != lastPrintPercent) {
                cout << "\r" << "Percent Complete: " << (percent / 100) << flush;
                lastPrintPercent = percent;
            }

            evt = log.readNextEvent();
            if (evt == nullptr) break;

            int64_t msg_hash;
            __int64_t_decode_array(evt->data, 0, 8, &msg_hash, 1);
            const TypeMetadata* md = types.getByHash(msg_hash);
            if (!md) continue;

            for (auto& p : pluginGroups[i]) {
                assert(p.plugin);

                if (!p.runThroughLog) continue;

                p.plugin->indexEvent(index, index[p.plugin->name()],
                                     evt->channel, md->name,
                                     offset, evt->timestamp,
                                     (uint64_t) msg_hash,
                                     evt->data, evt->datalen);

                numEvents++;
            }
        }

        cout << endl;

        for (auto& p : pluginGroups[i])
            p.plugin->tearDown(index, index[p.plugin->name()], log);
    }

    delete defaultPlugin;
    defaultPlugin = nullptr;

    zcm::Json::StreamWriterBuilder builder;
    builder["indentation"] = args.readable ? "    " : "";
    std::unique_ptr<zcm::Json::StreamWriter> writer(builder.newStreamWriter());
    writer->write(index, &output);
    output << endl;
    output.close();

    cout << "Indexed " << numEvents << " events" << endl;
    return 0;
}
<commit_msg>Now can force running of default<commit_after>#include <iostream>
#include <fstream>
#include <getopt.h>
#include <algorithm>
#include <memory>

#include <zcm/zcm-cpp.hpp>

#include "zcm/json/json.h"

#include "zcm/util/TypeDb.hpp"

#include "IndexerPluginDb.hpp"

using namespace std;

struct Args
{
    string logfile     = "";
    string output      = "";
    string plugin_path = "";
    string type_path   = "";
    bool readable      = false;
    bool debug         = false;
    bool useDefault    = false;

    bool parse(int argc, char *argv[])
    {
        // set some defaults
        const char *optstring = "l:o:p:t:rdh";
        struct option long_opts[] = {
            { "log",         required_argument, 0, 'l' },
            { "output",      required_argument, 0, 'o' },
            { "plugin-path", required_argument, 0, 'p' },
            { "type-path",   required_argument, 0, 't' },
            { "readable",    no_argument,       0, 'r' },
            { "use-default", no_argument,       0, 'd' },
            { "debug",       no_argument,       0,  0  },
            { "help",        no_argument,       0, 'h' },
            { 0, 0, 0, 0 }
        };

        int c;
        while ((c = getopt_long (argc, argv, optstring, long_opts, 0)) >= 0) {
            switch (c) {
                case 'l': logfile     = string(optarg); break;
                case 'o': output      = string(optarg); break;
                case 'p': plugin_path = string(optarg); break;
                case 't': type_path   = string(optarg); break;
                case 'r': readable    = true;           break;
                case 'd': useDefault  = true;           break;
                case 'h':
                default:
                    if (string(argv[optind]) == "debug") {
                        debug = true;
                    } else return false;
            };
        }

        if (logfile == "") {
            cerr << "Please specify logfile input" << endl;
            return false;
        }

        if (output  == "") {
            cerr << "Please specify index file output" << endl;
            return false;
        }

        const char* type_path_env = getenv("ZCM_LOG_INDEXER_ZCMTYPES_PATH");
        if (type_path == "" && type_path_env) type_path = type_path_env;
        if (type_path == "") {
            cerr << "Please specify a zcmtypes.so path either through -t TYPE_PATH "
                    "or through the env var ZCM_LOG_INDEXER_ZCMTYPES_PATH" << endl;
            return false;
        }

        const char* plugin_path_env = getenv("ZCM_LOG_INDEXER_PLUGINS_PATH");
        if (plugin_path == "" && plugin_path_env) plugin_path = plugin_path_env;
        if (plugin_path == "") cerr << "Running with default timestamp indexer plugin" << endl;

        return true;
    }

    void usage()
    {
        cerr << "usage: zcm-log-indexer [options]" << endl
             << "" << endl
             << "    Load in a log file and write an index json file that" << endl
             << "    allows for faster log indexing." << endl
             << "" << endl
             << "Example:" << endl
             << "    zcm-log-indexer -l zcm.log -o index.dbz -t path/to/zcmtypes.so" << endl
             << "" << endl
             << "Options:" << endl
             << "" << endl
             << "  -h, --help              Shows this help text and exits" << endl
             << "  -l, --log=logfile       Input log to index for fast querying" << endl
             << "  -o, --output=indexfile  Output index file to be used with log" << endl
             << "  -p, --plugin-path=path  Path to shared library containing indexer plugins" << endl
             << "                          Can also be specified via the environment variable" << endl
             << "                          ZCM_LOG_INDEXER_ZCMTYPES_PATH" << endl
             << "  -t, --type-path=path    Path to shared library containing the zcmtypes" << endl
             << "                          Can also be specified via the environment variable" << endl
             << "                          ZCM_LOG_INDEXER_PLUGINS_PATH" << endl
             << "  -r, --readable          Don't minify the output index file. " << endl
             << "                          Leave it human readable" << endl
             << "  -d, --debug             Run a dry run to ensure proper indexer setup" << endl
             << endl << endl;
    }
};

int main(int argc, char* argv[])
{
    Args args;
    if (!args.parse(argc, argv)) {
        args.usage();
        return 1;
    }

    zcm::LogFile log(args.logfile, "r");
    if (!log.good()) {
        cerr << "Unable to open logfile: " << args.logfile << endl;
        return 1;
    }
    fseeko(log.getFilePtr(), 0, SEEK_END);
    // XXX Look into handling large logfiles
    off_t logSize = ftello(log.getFilePtr());

    ofstream output;
    output.open(args.output);
    if (!output.is_open()) {
        cerr << "Unable to open output file: " << args.output << endl;
        log.close();
        return 1;
    }

    vector<zcm::IndexerPlugin*> plugins;

    bool defaultShouldBeIncluded = true;
    zcm::IndexerPlugin* defaultPlugin = new zcm::IndexerPlugin();

    IndexerPluginDb pluginDb(args.plugin_path, args.debug);
    // Load plugins from path if specified
    if (args.plugin_path != "") {
        bool dependsOnDefault = false;
        vector<const zcm::IndexerPlugin*> dbPlugins = pluginDb.getPlugins();
        // casting away constness. Don't mess up.
        for (auto dbp : dbPlugins) {
            plugins.push_back((zcm::IndexerPlugin*) dbp);
            defaultShouldBeIncluded = false;
            auto deps = dbp->dependsOn();
            for (auto dep : deps) {
                if (dep == defaultPlugin->name()) {
                    dependsOnDefault = true;
                    break;
                }
            }
        }

        if (dependsOnDefault || args.useDefault)
            defaultShouldBeIncluded = true;
    }

    if (defaultShouldBeIncluded) plugins.push_back(defaultPlugin);

    for (size_t i = 0; i < plugins.size(); ++i) {
        for (size_t j = i + 1; j < plugins.size(); ++j) {
            if (args.debug)
                cout << plugins.data()[i] << "->name() == "
                     << plugins.data()[j] << "->name()" << endl;

            if (plugins[i]->name() == plugins[j]->name()) {
                cerr << "Plugins must have unique names. Collision: "
                     << plugins[i]->name() << endl;
                return 1;
            }
        }
    }

    TypeDb types(args.type_path, args.debug);

    if (args.debug) return 0;

    struct PluginRuntimeInfo {
        zcm::IndexerPlugin* plugin;
        bool runThroughLog;
    };

    auto buildPluginGroups = [] (vector<zcm::IndexerPlugin*> plugins) {
        vector<vector<PluginRuntimeInfo>> groups;
        vector<zcm::IndexerPlugin*> lastLoop = plugins;
        while (!plugins.empty()) {
            groups.resize(groups.size() + 1);
            for (auto p = plugins.begin(); p != plugins.end();) {
                auto deps = (*p)->dependsOn();

                bool skipUntilLater = false;
                for (auto* dep : plugins) {
                    if (find(deps.begin(), deps.end(), dep->name()) != deps.end()) {
                        skipUntilLater = true;
                        break;
                    }
                }
                for (auto dep : groups.back()) {
                    if (find(deps.begin(), deps.end(), dep.plugin->name()) != deps.end()) {
                        skipUntilLater = true;
                        break;
                    }
                }
                if (!skipUntilLater) {
                    groups.back().push_back({*p, false});
                    p = plugins.erase(p);
                } else {
                    ++p;
                }
            }

            // Check for dependency resolution failure
            if (plugins == lastLoop) {
                cerr << "Unable to resolve all plugin dependencies. "
                        "Plugins left to resolve:" << endl << endl;
                for (auto* p : plugins) {
                    cerr << p->name() << endl
                         << "  Depends on:" << endl;
                    for (auto d : p->dependsOn())
                         cerr << "    " << d << endl;
                    cerr << endl;
                }
                exit(1);
            }
            lastLoop = plugins;
        }
        return groups;
    };

    // We do not own all the memory in here. We only own the default prorgam
    vector<vector<PluginRuntimeInfo>> pluginGroups;
    pluginGroups = buildPluginGroups(plugins);
    if (pluginGroups.size() > 1) {
        cout << "Identified " << pluginGroups.size() << " indexer plugin groups" << endl
             << "Running through log " << pluginGroups.size()
             << " times to satisfy dependencies" << endl;
    }

    zcm::Json::Value index;

    size_t numEvents = 0;
    const zcm::LogEvent* evt;
    for (size_t i = 0; i < pluginGroups.size(); ++i) {
        if (pluginGroups.size() != 1) cout << "Plugin group " << (i + 1) << endl;
        off_t offset = 0;
        fseeko(log.getFilePtr(), 0, SEEK_SET);

        for (auto& p : pluginGroups[i])
            p.runThroughLog = p.plugin->setUp(index, index[p.plugin->name()], log);

        while (1) {
            offset = ftello(log.getFilePtr());

            static int lastPrintPercent = 0;
            int percent = (100.0 * offset / logSize) * 100;
            if (percent != lastPrintPercent) {
                cout << "\r" << "Percent Complete: " << (percent / 100) << flush;
                lastPrintPercent = percent;
            }

            evt = log.readNextEvent();
            if (evt == nullptr) break;

            int64_t msg_hash;
            __int64_t_decode_array(evt->data, 0, 8, &msg_hash, 1);
            const TypeMetadata* md = types.getByHash(msg_hash);
            if (!md) continue;

            for (auto& p : pluginGroups[i]) {
                assert(p.plugin);

                if (!p.runThroughLog) continue;

                p.plugin->indexEvent(index, index[p.plugin->name()],
                                     evt->channel, md->name,
                                     offset, evt->timestamp,
                                     (uint64_t) msg_hash,
                                     evt->data, evt->datalen);

                numEvents++;
            }
        }

        cout << endl;

        for (auto& p : pluginGroups[i])
            p.plugin->tearDown(index, index[p.plugin->name()], log);
    }

    delete defaultPlugin;
    defaultPlugin = nullptr;

    zcm::Json::StreamWriterBuilder builder;
    builder["indentation"] = args.readable ? "    " : "";
    std::unique_ptr<zcm::Json::StreamWriter> writer(builder.newStreamWriter());
    writer->write(index, &output);
    output << endl;
    output.close();

    cout << "Indexed " << numEvents << " events" << endl;
    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include "driver.hpp"
#include "conv_driver.hpp"
#include "pool_driver.hpp"
#include "lrn_driver.hpp"
#include "activ_driver.hpp"
#include "softmax_driver.hpp"
#include "gemm_driver.hpp"

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

	std::string base_arg = ParseBaseArg(argc, argv);

	Driver *drv;
	if(base_arg == "conv") {
		drv = new ConvDriver<float>();
	}
	else if(base_arg == "pool") {
		drv = new PoolDriver<float>();
	}
	else if(base_arg == "lrn") {
		drv = new LRNDriver<float>();
	}
	else if (base_arg == "activ") {
		drv = new ActivationDriver<float>();
	}
	else if (base_arg == "softmax") {
		drv = new SoftmaxDriver<float>();
	}
#ifdef MLOPEN_USE_TINYGEMMM
	else if (base_arg == "gemm") {
		drv = new GemmDriver<float>();
	}
#endif
	else {
		printf("Incorrect BaseArg\n");
		exit(0);
	}

	drv->AddCmdLineArgs();
	drv->ParseCmdLineArgs(argc, argv);
	drv->GetandSetData();

	drv->AllocateBuffersAndCopy();

	drv->RunForwardGPU();

	if(drv->GetInputFlags().GetValueInt("verify") == 1) {
		if(base_arg == "gemm")
			printf("GEMM verification done in the GEMM library\n");
		else
			drv->VerifyForward();
	}

	if(drv->GetInputFlags().GetValueInt("forw") == 0) {
		if(!(base_arg == "gemm")) {
			drv->RunBackwardGPU();
			if(drv->GetInputFlags().GetValueInt("verify") == 1) {
				drv->VerifyBackward();
			}
		}
	}

	return 0;
}
<commit_msg>Typo fix<commit_after>#include <iostream>
#include <cstdio>
#include "driver.hpp"
#include "conv_driver.hpp"
#include "pool_driver.hpp"
#include "lrn_driver.hpp"
#include "activ_driver.hpp"
#include "softmax_driver.hpp"
#include "gemm_driver.hpp"

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

	std::string base_arg = ParseBaseArg(argc, argv);

	Driver *drv;
	if(base_arg == "conv") {
		drv = new ConvDriver<float>();
	}
	else if(base_arg == "pool") {
		drv = new PoolDriver<float>();
	}
	else if(base_arg == "lrn") {
		drv = new LRNDriver<float>();
	}
	else if (base_arg == "activ") {
		drv = new ActivationDriver<float>();
	}
	else if (base_arg == "softmax") {
		drv = new SoftmaxDriver<float>();
	}
#ifdef MLOPEN_USE_TINYGEMM
	else if (base_arg == "gemm") {
		drv = new GemmDriver<float>();
	}
#endif
	else {
		printf("Incorrect BaseArg\n");
		exit(0);
	}

	drv->AddCmdLineArgs();
	drv->ParseCmdLineArgs(argc, argv);
	drv->GetandSetData();

	drv->AllocateBuffersAndCopy();

	drv->RunForwardGPU();

	if(drv->GetInputFlags().GetValueInt("verify") == 1) {
		if(base_arg == "gemm")
			printf("GEMM verification done in the GEMM library\n");
		else
			drv->VerifyForward();
	}

	if(drv->GetInputFlags().GetValueInt("forw") == 0) {
		if(!(base_arg == "gemm")) {
			drv->RunBackwardGPU();
			if(drv->GetInputFlags().GetValueInt("verify") == 1) {
				drv->VerifyBackward();
			}
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2013 CompleteDB LLC.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with PubSubSQL.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <thread>
#include "process.h"
#include "eventlog.h"

int main(int argc, char* argv[])
{
	/*
	pipe testPipe;
	if (!testPipe.ok()) {
		std::cerr << "pipe failed" << std::endl;
	}
	//
	std::thread t([&]() {
		std::cout<< testPipe.readLine();
	});
	testPipe.writeLine("pipe test");
	t.join();
	// test filepath
	std::cout << eventlog::getPath() << std::endl;
	*/
	eventlog::install("pubsubsqlsvc.exe", "pubsubsql");
	/*
	eventlog log("pubsubsql");
	log.logdebug("debug");
	log.loginfo("info");
	log.logwarn("warn");
	log.logerror("error");
	*/
	// test process redirection
	process pubsubsql;
	if (pubsubsql.start("C:\\Users\\Oleg\\Go\\src\\pubsubsql\\pubsubsql.exe")) {
		int i = 0;
		std::cin >> i;
		pubsubsql.stop();
		pubsubsql.wait(3000);
	}
	return 0;
}

<commit_msg>wnidows service backup current progress<commit_after>/* Copyright (C) 2013 CompleteDB LLC.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with PubSubSQL.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <thread>
#include "process.h"
#include "eventlog.h"

int install(const std::string& options);
int uninstall();
int runAsService();

int main(int argc, char* argv[])
{
	// validate command line input
	std::string usage = "valid commands [install, uninstall]";
	if (argc < 2) {
		std::cerr << "no command found: " << usage << std::endl;
		return EXIT_FAILURE;
	}
	// assemble options
	std::string options;
	for (int i = 2; i < argc; i++) {
		char* arg = argv[i];
		options.append(" ");
		options.append(arg);
	}
	std::cout << options << std::endl;
	// execute
	std::string command(argv[1]);
	if (command == "install") return install();
	else if (command == "uninstall") return uninstall();
	else if (command == "svc") return runAsService();
	// invalid command
	std::cerr << "invalid command: " << usage << std::endl;
	return EXIT_FAILURE;

	/*
	pipe testPipe;
	if (!testPipe.ok()) {
		std::cerr << "pipe failed" << std::endl;
	}
	//
	std::thread t([&]() {
		std::cout<< testPipe.readLine();
	});
	testPipe.writeLine("pipe test");
	t.join();
	// test filepath
	std::cout << eventlog::getPath() << std::endl;
	*/
	//eventlog::install("pubsubsqlsvc.exe", "pubsubsql");
	/*
	eventlog log("pubsubsql");
	log.logdebug("debug");
	log.loginfo("info");
	log.logwarn("warn");
	log.logerror("error");
	*/
	// test process redirection

	/*
	process pubsubsql;
	if (pubsubsql.start("C:\\Users\\Oleg\\Go\\src\\pubsubsql\\pubsubsql.exe")) {
		int i = 0;
		std::cin >> i;
		pubsubsql.stop();
		pubsubsql.wait(3000);
	}
	*/
	return 0;
}

int install(const std::string& options) {
	int ret = EXIT_SUCCESS;
	SC_HANDLE manager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE);
	if (NULL == manager) {
		std::cerr << "failed to connect to service control manager" << std::endl;
		return EXIT_FAILURE;
	}

	std::string servicePath;
	SC_HANDLE service = CreateService(manager, "PubSubSQL Service", "PubSubSQL Service", SERVICE_START | SERVICE_STOP | DELETE,
		SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, servicePath.c_str(),
		NULL, NULL, NULL, NULL, NULL);

	return EXIT_SUCCESS;
}

int uninstall() {
	return EXIT_SUCCESS;
}

int runAsService() {
	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright 2014 BVLC and contributors.

#include <stdio.h>  // for snprintf
#include <cuda_runtime.h>
#include <google/protobuf/text_format.h>
#include <leveldb/db.h>
#include <leveldb/write_batch.h>
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>

#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/net.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"

using namespace caffe;  // NOLINT(build/namespaces)

template<typename Dtype>
int feature_extraction_pipeline(int argc, char** argv);

int main(int argc, char** argv) {
  return feature_extraction_pipeline<float>(argc, argv);
//  return feature_extraction_pipeline<double>(argc, argv);
}

template<typename Dtype>
int feature_extraction_pipeline(int argc, char** argv) {
  const int num_required_args = 6;
  if (argc < num_required_args) {
    LOG(ERROR)<<
    "This program takes in a trained network and an input data layer, and then"
    " extract features of the input data produced by the net.\n"
    "Usage: extract_features  pretrained_net_param"
    "  feature_extraction_proto_file  extract_feature_blob_name1[,name2,...]"
    "  save_feature_leveldb_name1[,name2,...]  num_mini_batches  [CPU/GPU]"
    "  [DEVICE_ID=0]\n"
    "Note: you can extract multiple features in one pass by specifying"
    " multiple feature blob names and leveldb names seperated by ','."
    " The names cannot contain white space characters and the number of blobs"
    " and leveldbs must be equal.";
    return 1;
  }
  int arg_pos = num_required_args;

  arg_pos = num_required_args;
  if (argc > arg_pos && strcmp(argv[arg_pos], "GPU") == 0) {
    LOG(ERROR)<< "Using GPU";
    uint device_id = 0;
    if (argc > arg_pos + 1) {
      device_id = atoi(argv[arg_pos + 1]);
      CHECK_GE(device_id, 0);
    }
    LOG(ERROR) << "Using Device_id=" << device_id;
    Caffe::SetDevice(device_id);
    Caffe::set_mode(Caffe::GPU);
  } else {
    LOG(ERROR) << "Using CPU";
    Caffe::set_mode(Caffe::CPU);
  }
  Caffe::set_phase(Caffe::TEST);

  arg_pos = 0;  // the name of the executable
  string pretrained_binary_proto(argv[++arg_pos]);

  // Expected prototxt contains at least one data layer such as
  //  the layer data_layer_name and one feature blob such as the
  //  fc7 top blob to extract features.
  /*
   layers {
     name: "data_layer_name"
     type: DATA
     data_param {
       source: "/path/to/your/images/to/extract/feature/images_leveldb"
       mean_file: "/path/to/your/image_mean.binaryproto"
       batch_size: 128
       crop_size: 227
       mirror: false
     }
     top: "data_blob_name"
     top: "label_blob_name"
   }
   layers {
     name: "drop7"
     type: DROPOUT
     dropout_param {
       dropout_ratio: 0.5
     }
     bottom: "fc7"
     top: "fc7"
   }
   */
  string feature_extraction_proto(argv[++arg_pos]);
  shared_ptr<Net<Dtype> > feature_extraction_net(
      new Net<Dtype>(feature_extraction_proto));
  feature_extraction_net->CopyTrainedLayersFrom(pretrained_binary_proto);

  string extract_feature_blob_names(argv[++arg_pos]);
  vector<string> blob_names;
  boost::split(blob_names, extract_feature_blob_names, boost::is_any_of(","));

  string save_feature_leveldb_names(argv[++arg_pos]);
  vector<string> leveldb_names;
  boost::split(leveldb_names, save_feature_leveldb_names,
               boost::is_any_of(","));
  CHECK_EQ(blob_names.size(), leveldb_names.size()) <<
      " the number of blob names and leveldb names must be equal";
  size_t num_features = blob_names.size();

  for (size_t i = 0; i < num_features; i++) {
    CHECK(feature_extraction_net->has_blob(blob_names[i]))
        << "Unknown feature blob name " << blob_names[i]
        << " in the network " << feature_extraction_proto;
  }

  leveldb::Options options;
  options.error_if_exists = true;
  options.create_if_missing = true;
  options.write_buffer_size = 268435456;
  vector<shared_ptr<leveldb::DB> > feature_dbs;
  for (size_t i = 0; i < num_features; ++i) {
    LOG(INFO)<< "Opening leveldb " << leveldb_names[i];
    leveldb::DB* db;
    leveldb::Status status = leveldb::DB::Open(options,
                                               leveldb_names[i].c_str(),
                                               &db);
    CHECK(status.ok()) << "Failed to open leveldb " << leveldb_names[i];
    feature_dbs.push_back(shared_ptr<leveldb::DB>(db));
  }

  int num_mini_batches = atoi(argv[++arg_pos]);

  LOG(ERROR)<< "Extacting Features";

  Datum datum;
  vector<shared_ptr<leveldb::WriteBatch> > feature_batches(
      num_features,
      shared_ptr<leveldb::WriteBatch>(new leveldb::WriteBatch()));
  const int kMaxKeyStrLength = 100;
  char key_str[kMaxKeyStrLength];
  int num_bytes_of_binary_code = sizeof(Dtype);
  vector<Blob<float>*> input_vec;
  vector<int> image_indices(num_features, 0);
  for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) {
    feature_extraction_net->Forward(input_vec);
    for (int i = 0; i < num_features; ++i) {
      const shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net
          ->blob_by_name(blob_names[i]);
      int batch_size = feature_blob->num();
      int dim_features = feature_blob->count() / batch_size;
      Dtype* feature_blob_data;
      for (int n = 0; n < batch_size; ++n) {
        datum.set_height(dim_features);
        datum.set_width(1);
        datum.set_channels(1);
        datum.clear_data();
        datum.clear_float_data();
        feature_blob_data = feature_blob->mutable_cpu_data() +
            feature_blob->offset(n);
        for (int d = 0; d < dim_features; ++d) {
          datum.add_float_data(feature_blob_data[d]);
        }
        string value;
        datum.SerializeToString(&value);
        snprintf(key_str, kMaxKeyStrLength, "%d", image_indices[i]);
        feature_batches[i]->Put(string(key_str), value);
        ++image_indices[i];
        if (image_indices[i] % 1000 == 0) {
          feature_dbs[i]->Write(leveldb::WriteOptions(),
                                feature_batches[i].get());
          LOG(ERROR)<< "Extracted features of " << image_indices[i] <<
              " query images for feature blob " << blob_names[i];
          feature_batches[i].reset(new leveldb::WriteBatch());
        }
      }  // for (int n = 0; n < batch_size; ++n)
    }  // for (int i = 0; i < num_features; ++i)
  }  // for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index)
  // write the last batch
  for (int i = 0; i < num_features; ++i) {
    if (image_indices[i] % 1000 != 0) {
      feature_dbs[i]->Write(leveldb::WriteOptions(), feature_batches[i].get());
    }
    LOG(ERROR)<< "Extracted features of " << image_indices[i] <<
        " query images for feature blob " << blob_names[i];
  }

  LOG(ERROR)<< "Successfully extracted the features!";
  return 0;
}

<commit_msg>Init google logging<commit_after>// Copyright 2014 BVLC and contributors.

#include <stdio.h>  // for snprintf
#include <cuda_runtime.h>
#include <google/protobuf/text_format.h>
#include <leveldb/db.h>
#include <leveldb/write_batch.h>
#include <boost/algorithm/string.hpp>
#include <string>
#include <vector>

#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/net.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/io.hpp"

using namespace caffe;  // NOLINT(build/namespaces)

template<typename Dtype>
int feature_extraction_pipeline(int argc, char** argv);

int main(int argc, char** argv) {
  return feature_extraction_pipeline<float>(argc, argv);
//  return feature_extraction_pipeline<double>(argc, argv);
}

template<typename Dtype>
int feature_extraction_pipeline(int argc, char** argv) {
  ::google::InitGoogleLogging(argv[0]);
  const int num_required_args = 6;
  if (argc < num_required_args) {
    LOG(ERROR)<<
    "This program takes in a trained network and an input data layer, and then"
    " extract features of the input data produced by the net.\n"
    "Usage: extract_features  pretrained_net_param"
    "  feature_extraction_proto_file  extract_feature_blob_name1[,name2,...]"
    "  save_feature_leveldb_name1[,name2,...]  num_mini_batches  [CPU/GPU]"
    "  [DEVICE_ID=0]\n"
    "Note: you can extract multiple features in one pass by specifying"
    " multiple feature blob names and leveldb names seperated by ','."
    " The names cannot contain white space characters and the number of blobs"
    " and leveldbs must be equal.";
    return 1;
  }
  int arg_pos = num_required_args;

  arg_pos = num_required_args;
  if (argc > arg_pos && strcmp(argv[arg_pos], "GPU") == 0) {
    LOG(ERROR)<< "Using GPU";
    uint device_id = 0;
    if (argc > arg_pos + 1) {
      device_id = atoi(argv[arg_pos + 1]);
      CHECK_GE(device_id, 0);
    }
    LOG(ERROR) << "Using Device_id=" << device_id;
    Caffe::SetDevice(device_id);
    Caffe::set_mode(Caffe::GPU);
  } else {
    LOG(ERROR) << "Using CPU";
    Caffe::set_mode(Caffe::CPU);
  }
  Caffe::set_phase(Caffe::TEST);

  arg_pos = 0;  // the name of the executable
  string pretrained_binary_proto(argv[++arg_pos]);

  // Expected prototxt contains at least one data layer such as
  //  the layer data_layer_name and one feature blob such as the
  //  fc7 top blob to extract features.
  /*
   layers {
     name: "data_layer_name"
     type: DATA
     data_param {
       source: "/path/to/your/images/to/extract/feature/images_leveldb"
       mean_file: "/path/to/your/image_mean.binaryproto"
       batch_size: 128
       crop_size: 227
       mirror: false
     }
     top: "data_blob_name"
     top: "label_blob_name"
   }
   layers {
     name: "drop7"
     type: DROPOUT
     dropout_param {
       dropout_ratio: 0.5
     }
     bottom: "fc7"
     top: "fc7"
   }
   */
  string feature_extraction_proto(argv[++arg_pos]);
  shared_ptr<Net<Dtype> > feature_extraction_net(
      new Net<Dtype>(feature_extraction_proto));
  feature_extraction_net->CopyTrainedLayersFrom(pretrained_binary_proto);

  string extract_feature_blob_names(argv[++arg_pos]);
  vector<string> blob_names;
  boost::split(blob_names, extract_feature_blob_names, boost::is_any_of(","));

  string save_feature_leveldb_names(argv[++arg_pos]);
  vector<string> leveldb_names;
  boost::split(leveldb_names, save_feature_leveldb_names,
               boost::is_any_of(","));
  CHECK_EQ(blob_names.size(), leveldb_names.size()) <<
      " the number of blob names and leveldb names must be equal";
  size_t num_features = blob_names.size();

  for (size_t i = 0; i < num_features; i++) {
    CHECK(feature_extraction_net->has_blob(blob_names[i]))
        << "Unknown feature blob name " << blob_names[i]
        << " in the network " << feature_extraction_proto;
  }

  leveldb::Options options;
  options.error_if_exists = true;
  options.create_if_missing = true;
  options.write_buffer_size = 268435456;
  vector<shared_ptr<leveldb::DB> > feature_dbs;
  for (size_t i = 0; i < num_features; ++i) {
    LOG(INFO)<< "Opening leveldb " << leveldb_names[i];
    leveldb::DB* db;
    leveldb::Status status = leveldb::DB::Open(options,
                                               leveldb_names[i].c_str(),
                                               &db);
    CHECK(status.ok()) << "Failed to open leveldb " << leveldb_names[i];
    feature_dbs.push_back(shared_ptr<leveldb::DB>(db));
  }

  int num_mini_batches = atoi(argv[++arg_pos]);

  LOG(ERROR)<< "Extacting Features";

  Datum datum;
  vector<shared_ptr<leveldb::WriteBatch> > feature_batches(
      num_features,
      shared_ptr<leveldb::WriteBatch>(new leveldb::WriteBatch()));
  const int kMaxKeyStrLength = 100;
  char key_str[kMaxKeyStrLength];
  int num_bytes_of_binary_code = sizeof(Dtype);
  vector<Blob<float>*> input_vec;
  vector<int> image_indices(num_features, 0);
  for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index) {
    feature_extraction_net->Forward(input_vec);
    for (int i = 0; i < num_features; ++i) {
      const shared_ptr<Blob<Dtype> > feature_blob = feature_extraction_net
          ->blob_by_name(blob_names[i]);
      int batch_size = feature_blob->num();
      int dim_features = feature_blob->count() / batch_size;
      Dtype* feature_blob_data;
      for (int n = 0; n < batch_size; ++n) {
        datum.set_height(dim_features);
        datum.set_width(1);
        datum.set_channels(1);
        datum.clear_data();
        datum.clear_float_data();
        feature_blob_data = feature_blob->mutable_cpu_data() +
            feature_blob->offset(n);
        for (int d = 0; d < dim_features; ++d) {
          datum.add_float_data(feature_blob_data[d]);
        }
        string value;
        datum.SerializeToString(&value);
        snprintf(key_str, kMaxKeyStrLength, "%d", image_indices[i]);
        feature_batches[i]->Put(string(key_str), value);
        ++image_indices[i];
        if (image_indices[i] % 1000 == 0) {
          feature_dbs[i]->Write(leveldb::WriteOptions(),
                                feature_batches[i].get());
          LOG(ERROR)<< "Extracted features of " << image_indices[i] <<
              " query images for feature blob " << blob_names[i];
          feature_batches[i].reset(new leveldb::WriteBatch());
        }
      }  // for (int n = 0; n < batch_size; ++n)
    }  // for (int i = 0; i < num_features; ++i)
  }  // for (int batch_index = 0; batch_index < num_mini_batches; ++batch_index)
  // write the last batch
  for (int i = 0; i < num_features; ++i) {
    if (image_indices[i] % 1000 != 0) {
      feature_dbs[i]->Write(leveldb::WriteOptions(), feature_batches[i].get());
    }
    LOG(ERROR)<< "Extracted features of " << image_indices[i] <<
        " query images for feature blob " << blob_names[i];
  }

  LOG(ERROR)<< "Successfully extracted the features!";
  return 0;
}

<|endoftext|>


<commit_before>#include "AlembicLicensing.h"
#include "AlembicWriteJob.h"
#include "AlembicObject.h"
#include "AlembicXform.h"
#include "AlembicCamera.h"
#include "AlembicPolyMsh.h"
#include "AlembicCurves.h"
#include "AlembicPoints.h"
#include "AlembicModel.h"
#include "AlembicSubD.h"
#include "AlembicNurbs.h"
#include "Utility.h"

#include <xsi_application.h>
#include <xsi_time.h>
#include <xsi_project.h>
#include <xsi_scene.h>
#include <xsi_property.h>
#include <xsi_parameter.h>
#include <xsi_x3dobject.h>
#include <xsi_primitive.h>
#include <xsi_kinematics.h>
#include <xsi_kinematicstate.h>
#include <xsi_uitoolkit.h>
#include <xsi_geometry.h>
#include <xsi_iceattribute.h>
#include <xsi_model.h>
#include <xsi_utils.h>

#include "sceneGraph.h"

using namespace XSI;
using namespace MATH;

namespace AbcA = ::Alembic::AbcCoreAbstract::ALEMBIC_VERSION_NS;
using namespace AbcA;

AlembicWriteJob::AlembicWriteJob
(
   const CString & in_FileName,
   const exoNode::SelectionMap& in_Selection,
   const CDoubleArray & in_Frames
)
{
   // ensure to clear the isRefAnimated cache
   clearIsRefAnimatedCache();

   mFileName = CUtils::ResolveTokenString(in_FileName,XSI::CTime(),false);
   mSelection = in_Selection;

   for(LONG i=0;i<in_Frames.GetCount();i++)
      mFrames.push_back(in_Frames[i]);
}

AlembicWriteJob::~AlembicWriteJob()
{
}

void AlembicWriteJob::SetOption(const CString & in_Name, const CValue & in_Value)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   if(it == mOptions.end())
      mOptions.insert(std::pair<XSI::CString,XSI::CValue>(in_Name,in_Value));
   else
      it->second = in_Value;
}

bool AlembicWriteJob::HasOption(const CString & in_Name)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   return it != mOptions.end();
}

CValue AlembicWriteJob::GetOption(const CString & in_Name)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   if(it != mOptions.end())
      return it->second;
   return CValue(false);
}

//AlembicObjectPtr AlembicWriteJob::GetObject(const XSI::CRef & in_Ref)
//{
// 	std::string key = std::string( in_Ref.GetAsText().GetAsciiString() );
//
//	std::map<std::string,AlembicObjectPtr>::const_iterator it = mObjectsNames.find( key );
//
//	if (it != mObjectsNames.end()) {
//		return it->second;
//	}
//	return AlembicObjectPtr();
//}

bool AlembicWriteJob::AddObject(AlembicObjectPtr in_Obj)
{
   if(!in_Obj)
      return false;
   if(!in_Obj->GetRef().IsValid())
      return false;
   mObjects.push_back(in_Obj);
   return true;
}

CStatus AlembicWriteJob::PreProcess()
{
   // check filenames
   if(mFileName.IsEmpty())
   {
      Application().LogMessage(L"[ExocortexAlembic] No filename specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check objects
   if(mSelection.size() == 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] No objects specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check frames
   if(mFrames.size() == 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] No frames specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check if the file is currently in use
   if(getRefArchive(mFileName) > 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] Error writing to file '"+mFileName+L"'. File currently in use.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // init archive (use a locally scoped archive)
   CString sceneFileName = L"Exported from: "+Application().GetActiveProject().GetActiveScene().GetParameterValue(L"FileName").GetAsText();
   try
   {
      mArchive = CreateArchiveWithInfo(
            Alembic::AbcCoreHDF5::WriteArchive(),
            mFileName.GetAsciiString(),
            "Softimage Alembic Plugin",
            sceneFileName.GetAsciiString(),
            Alembic::Abc::ErrorHandler::kThrowPolicy);
   }
   catch(Alembic::Util::Exception& e)
   {
      CString exc(e.what());
      Application().LogMessage(L"[ExocortexAlembic] Error writing to file '"+mFileName+L"' ("+exc+L"). Do you still have it opened?",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   mTop = mArchive.getTop();

   // get the frame rate
   mFrameRate = 25.0;
   CValue returnVal;
   CValueArray args(1);
   args[0] = L"PlayControl.Rate";
   Application().ExecuteCommand(L"GetValue",args,returnVal);
   mFrameRate = returnVal;
   if(mFrameRate == 0.0)
      mFrameRate = 25.0;

   std::vector<Alembic::AbcCoreAbstract::chrono_t> frames;
   for(LONG i=0;i<mFrames.size();i++)
      frames.push_back(mFrames[i] / mFrameRate);

   // create the sampling
   double timePerSample = 1.0 / mFrameRate;
   if(frames.size() > 1)
   {
      if( ! HasAlembicWriterLicense() )
      {
         if(frames.size() > 75)
         {
            frames.resize(75);
            EC_LOG_WARNING("[ExocortexAlembic] Writer license not found: Maximum exportable samplecount is 75!");
         }
      }

      double timePerCycle = frames[frames.size()-1] - frames[0];
      AbcA::TimeSamplingType samplingType((uint32_t)frames.size(),timePerCycle);
      AbcA::TimeSampling sampling(samplingType,frames);
      mTs = mArchive.addTimeSampling(sampling);
   }
   else
   {
      AbcA::TimeSampling sampling(1.0,frames[0]);
      mTs = mArchive.addTimeSampling(sampling);
   }

   const bool bSelectParents = true;
   const bool bSelectChildren = true;
   const bool bTransformCache = (bool)GetOption(L"transformCache");
   const bool bFlattenHierarchy = (bool)GetOption(L"flattenHierarchy");

   //TODO: eventually this should be a replaced with an equivalent virtual method, and the exporter will be shared
   exoNodePtr exoSceneRoot = buildCommonSceneGraph(Application().GetActiveSceneRoot());

   selectNodes(exoSceneRoot, mSelection, bSelectParents, bSelectChildren, bTransformCache ? false : bFlattenHierarchy, bTransformCache);

   ::printSceneGraph(exoSceneRoot);

   return CStatus::OK;

   struct stackElement
   {
      exoNodePtr eNode;
      Alembic::Abc::OObject oParent;

      stackElement(exoNodePtr enode, Alembic::Abc::OObject parent):eNode(enode), oParent(parent)
      {}
   };
   std::list<stackElement> sceneStack;

   sceneStack.push_back(stackElement(exoSceneRoot, GetTop()));

   while( !sceneStack.empty() )
   {

      stackElement sElement = sceneStack.back();
      exoNodePtr eNode = sElement.eNode;
      sceneStack.pop_back();

      Alembic::Abc::OObject oParent = sElement.oParent;
      Alembic::Abc::OObject oNewParent;

      AlembicObjectPtr pNewObject;

      if(eNode->selected)
      {
         if(eNode->type == exoNode::SCENE_ROOT){
            //we do not want to export the Scene_Root (the alembic archive has one already)
         }
         else if(eNode->type == exoNode::ITRANSFORM || eNode->type == exoNode::ETRANSFORM){
            pNewObject.reset(new AlembicModel(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::CAMERA){
            pNewObject.reset(new AlembicCamera(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::POLYMESH){
            pNewObject.reset(new AlembicPolyMesh(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::SUBD){
            pNewObject.reset(new AlembicSubD(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::SURFACE){
            pNewObject.reset(new AlembicNurbs(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::CURVES){
            pNewObject.reset(new AlembicCurves(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::PARTICLES){
            pNewObject.reset(new AlembicPoints(eNode, this, oParent));
         }
         else{
            ESS_LOG_WARNING("Unknown type: not exporting "<<eNode->name);//Export as transform, and give warning?
         }
      }

      if(pNewObject){

         //setup the next parent
         oNewParent = oParent.getChild(eNode->name);

         //add the alembic object to the export list
         AddObject(pNewObject);
      }
      else{
         //if we skip node A, we parent node A's children to the parent of A
         oNewParent = oParent;
      }

      if(oNewParent.valid()){
         for( std::list<exoNodePtr>::iterator it = eNode->children.begin(); it != eNode->children.end(); it++){
            sceneStack.push_back(stackElement(*it, oNewParent));
         }
      }
      else{
         ESS_LOG_ERROR("Do not have refernce to parent.");
         return CStatus::Fail;
      }
   }

#if 0

   for(LONG i=0; i<mSelection.size(); i++)
   {
      mSelection[i].nNodeDepth = getNodeDepthFromRef(mSelection[i].cRef);
   }
   std::sort(mSelection.begin(), mSelection.end());

   Alembic::Abc::OBox3dProperty boxProp = Alembic::AbcGeom::CreateOArchiveBounds(mArchive,mTs);

   CString activeSceneRoot_GetFullName = Application().GetActiveSceneRoot().GetFullName();
   // create object for each
   for(LONG i=0;i<mSelection.size();i++)
   {
	   X3DObject xObj(mSelection[i].cRef);
	   CRef xObj_GetActivePrimitive_GetRef = xObj.GetActivePrimitive().GetRef();
      //if(GetObject(xObj_GetActivePrimitive_GetRef) != NULL) continue;

      // push all models up the hierarchy

	  // MHahn: we are going to disable this code for now, since it should probably be an additional
	  // export option, and we would prefer not to make things more complicated. We we will require
	  // the user select the exact set of nodes that should be exported.

      //Model model(xObj.GetRef());
      //if(!model.IsValid())
      //   model = xObj.GetModel();
      CRefArray modelRefs;
      //if((bool)GetOption(L"transformCache"))
      if((bool)GetOption(L"flattenHierarchy") == false)
      {
         X3DObject parent = xObj.GetParent3DObject();
         while(parent.IsValid() && !parent.GetFullName().IsEqualNoCase( activeSceneRoot_GetFullName ))
         {
            modelRefs.Add(parent.GetActivePrimitive().GetRef());
            parent = parent.GetParent3DObject();
         }
      }
      //else
      //{
      //   while(model.IsValid() && !model.GetFullName().IsEqualNoCase( activeSceneRoot_GetFullName ))
      //   {
      //      modelRefs.Add(model.GetActivePrimitive().GetRef());
      //      model = model.GetModel();
      //   }
      //}
      for(LONG j=modelRefs.GetCount()-1;j>=0;j--)
      {
         //if(GetObject(modelRefs[j]) == NULL)
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicModel(modelRefs[j],this));
            //AddObjectIfDoesNotExist(ptr);
         }
      }

      if((bool)GetOption(L"transformCache"))
      {
         //always export all transforms whether the hierarchy is flattened or not

         AlembicObjectPtr ptr;
         ptr.reset(new AlembicModel(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);

         continue;// only do models (tranforms) if we perform pure transformcache
      }

      // take care of all other types
	  CString xObj_GetType = xObj.GetType();
      if(xObj_GetType.IsEqualNoCase(L"null") && ((bool)GetOption(L"flattenHierarchy") == false))
	  {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicModel(xObj_GetActivePrimitive_GetRef, this));
         //AddObjectIfDoesNotExist(ptr);
	  }
      else if(xObj_GetType.IsEqualNoCase(L"camera"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCamera(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"polymsh"))
      {
         Property geomProp;
         xObj.GetPropertyFromName(L"geomapprox",geomProp);
         LONG subDivLevel = geomProp.GetParameterValue(L"gapproxmordrsl");
         if(subDivLevel > 0)
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicSubD(xObj_GetActivePrimitive_GetRef,this));
            //AddObjectIfDoesNotExist(ptr);
         }
         else
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicPolyMesh(xObj_GetActivePrimitive_GetRef,this));
            //AddObjectIfDoesNotExist(ptr);
         }
      }
      else if(xObj_GetType.IsEqualNoCase(L"surfmsh"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicNurbs(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"crvlist"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"hair"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"pointcloud"))
      {
         AlembicObjectPtr ptr;
         ICEAttribute strandPosition = xObj.GetActivePrimitive().GetGeometry().GetICEAttributeFromName(L"StrandPosition");
         if(strandPosition.IsDefined() && strandPosition.IsValid())
            ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         else
            ptr.reset(new AlembicPoints(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
   }

#endif

   return CStatus::OK;
}

CStatus AlembicWriteJob::Process(double frame)
{
   CStatus result = CStatus::False;

   for(size_t i=0;i<mFrames.size();i++)
   {
      // compare the frames
      if(abs(mFrames[i] - frame) > 0.001)
         continue;

      // run the export for all objects
      for(size_t j=0;j<mObjects.size();j++)
      {
         CStatus status = mObjects[j]->Save(mFrames[i]);
         if(status != CStatus::OK)
            return status;
         result = CStatus::OK;
      }
   }

   return result;
}<commit_msg>issue #164<commit_after>#include "AlembicLicensing.h"
#include "AlembicWriteJob.h"
#include "AlembicObject.h"
#include "AlembicXform.h"
#include "AlembicCamera.h"
#include "AlembicPolyMsh.h"
#include "AlembicCurves.h"
#include "AlembicPoints.h"
#include "AlembicModel.h"
#include "AlembicSubD.h"
#include "AlembicNurbs.h"
#include "Utility.h"

#include <xsi_application.h>
#include <xsi_time.h>
#include <xsi_project.h>
#include <xsi_scene.h>
#include <xsi_property.h>
#include <xsi_parameter.h>
#include <xsi_x3dobject.h>
#include <xsi_primitive.h>
#include <xsi_kinematics.h>
#include <xsi_kinematicstate.h>
#include <xsi_uitoolkit.h>
#include <xsi_geometry.h>
#include <xsi_iceattribute.h>
#include <xsi_model.h>
#include <xsi_utils.h>

#include "sceneGraph.h"

using namespace XSI;
using namespace MATH;

namespace AbcA = ::Alembic::AbcCoreAbstract::ALEMBIC_VERSION_NS;
using namespace AbcA;

AlembicWriteJob::AlembicWriteJob
(
   const CString & in_FileName,
   const exoNode::SelectionMap& in_Selection,
   const CDoubleArray & in_Frames
)
{
   // ensure to clear the isRefAnimated cache
   clearIsRefAnimatedCache();

   mFileName = CUtils::ResolveTokenString(in_FileName,XSI::CTime(),false);
   mSelection = in_Selection;

   for(LONG i=0;i<in_Frames.GetCount();i++)
      mFrames.push_back(in_Frames[i]);
}

AlembicWriteJob::~AlembicWriteJob()
{
}

void AlembicWriteJob::SetOption(const CString & in_Name, const CValue & in_Value)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   if(it == mOptions.end())
      mOptions.insert(std::pair<XSI::CString,XSI::CValue>(in_Name,in_Value));
   else
      it->second = in_Value;
}

bool AlembicWriteJob::HasOption(const CString & in_Name)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   return it != mOptions.end();
}

CValue AlembicWriteJob::GetOption(const CString & in_Name)
{
   std::map<XSI::CString,XSI::CValue>::iterator it = mOptions.find(in_Name);
   if(it != mOptions.end())
      return it->second;
   return CValue(false);
}

//AlembicObjectPtr AlembicWriteJob::GetObject(const XSI::CRef & in_Ref)
//{
// 	std::string key = std::string( in_Ref.GetAsText().GetAsciiString() );
//
//	std::map<std::string,AlembicObjectPtr>::const_iterator it = mObjectsNames.find( key );
//
//	if (it != mObjectsNames.end()) {
//		return it->second;
//	}
//	return AlembicObjectPtr();
//}

bool AlembicWriteJob::AddObject(AlembicObjectPtr in_Obj)
{
   if(!in_Obj)
      return false;
   if(!in_Obj->GetRef().IsValid())
      return false;
   mObjects.push_back(in_Obj);
   return true;
}

CStatus AlembicWriteJob::PreProcess()
{
   // check filenames
   if(mFileName.IsEmpty())
   {
      Application().LogMessage(L"[ExocortexAlembic] No filename specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check objects
   if(mSelection.size() == 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] No objects specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check frames
   if(mFrames.size() == 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] No frames specified.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // check if the file is currently in use
   if(getRefArchive(mFileName) > 0)
   {
      Application().LogMessage(L"[ExocortexAlembic] Error writing to file '"+mFileName+L"'. File currently in use.",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   // init archive (use a locally scoped archive)
   CString sceneFileName = L"Exported from: "+Application().GetActiveProject().GetActiveScene().GetParameterValue(L"FileName").GetAsText();
   try
   {
      mArchive = CreateArchiveWithInfo(
            Alembic::AbcCoreHDF5::WriteArchive(),
            mFileName.GetAsciiString(),
            "Softimage Alembic Plugin",
            sceneFileName.GetAsciiString(),
            Alembic::Abc::ErrorHandler::kThrowPolicy);
   }
   catch(Alembic::Util::Exception& e)
   {
      CString exc(e.what());
      Application().LogMessage(L"[ExocortexAlembic] Error writing to file '"+mFileName+L"' ("+exc+L"). Do you still have it opened?",siErrorMsg);
      return CStatus::InvalidArgument;
   }

   mTop = mArchive.getTop();

   // get the frame rate
   mFrameRate = 25.0;
   CValue returnVal;
   CValueArray args(1);
   args[0] = L"PlayControl.Rate";
   Application().ExecuteCommand(L"GetValue",args,returnVal);
   mFrameRate = returnVal;
   if(mFrameRate == 0.0)
      mFrameRate = 25.0;

   std::vector<Alembic::AbcCoreAbstract::chrono_t> frames;
   for(LONG i=0;i<mFrames.size();i++)
      frames.push_back(mFrames[i] / mFrameRate);

   // create the sampling
   double timePerSample = 1.0 / mFrameRate;
   if(frames.size() > 1)
   {
      if( ! HasAlembicWriterLicense() )
      {
         if(frames.size() > 75)
         {
            frames.resize(75);
            EC_LOG_WARNING("[ExocortexAlembic] Writer license not found: Maximum exportable samplecount is 75!");
         }
      }

      double timePerCycle = frames[frames.size()-1] - frames[0];
      AbcA::TimeSamplingType samplingType((uint32_t)frames.size(),timePerCycle);
      AbcA::TimeSampling sampling(samplingType,frames);
      mTs = mArchive.addTimeSampling(sampling);
   }
   else
   {
      AbcA::TimeSampling sampling(1.0,frames[0]);
      mTs = mArchive.addTimeSampling(sampling);
   }

   const bool bSelectParents = true;
   const bool bSelectChildren = true;
   const bool bTransformCache = (bool)GetOption(L"transformCache");
   const bool bFlattenHierarchy = (bool)GetOption(L"flattenHierarchy");

   //TODO: eventually this should be a replaced with an equivalent virtual method, and the exporter will be shared
   exoNodePtr exoSceneRoot = buildCommonSceneGraph(Application().GetActiveSceneRoot());

   selectNodes(exoSceneRoot, mSelection, bSelectParents, bSelectChildren);
   filterNodeSelection(exoSceneRoot, bTransformCache ? false : bFlattenHierarchy, bTransformCache);

   ::printSceneGraph(exoSceneRoot);

   //return CStatus::OK;

   struct stackElement
   {
      exoNodePtr eNode;
      Alembic::Abc::OObject oParent;

      stackElement(exoNodePtr enode, Alembic::Abc::OObject parent):eNode(enode), oParent(parent)
      {}
   };
   std::list<stackElement> sceneStack;

   sceneStack.push_back(stackElement(exoSceneRoot, GetTop()));

   while( !sceneStack.empty() )
   {

      stackElement sElement = sceneStack.back();
      exoNodePtr eNode = sElement.eNode;
      sceneStack.pop_back();

      Alembic::Abc::OObject oParent = sElement.oParent;
      Alembic::Abc::OObject oNewParent;

      AlembicObjectPtr pNewObject;

      if(eNode->selected)
      {
         if(eNode->type == exoNode::SCENE_ROOT){
            //we do not want to export the Scene_Root (the alembic archive has one already)
         }
         else if(eNode->type == exoNode::ITRANSFORM || eNode->type == exoNode::ETRANSFORM){
            pNewObject.reset(new AlembicModel(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::CAMERA){
            pNewObject.reset(new AlembicCamera(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::POLYMESH){
            pNewObject.reset(new AlembicPolyMesh(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::SUBD){
            pNewObject.reset(new AlembicSubD(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::SURFACE){
            pNewObject.reset(new AlembicNurbs(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::CURVES){
            pNewObject.reset(new AlembicCurves(eNode, this, oParent));
         }
         else if(eNode->type == exoNode::PARTICLES){
            pNewObject.reset(new AlembicPoints(eNode, this, oParent));
         }
         else{
            ESS_LOG_WARNING("Unknown type: not exporting "<<eNode->name);//Export as transform, and give warning?
         }
      }

      if(pNewObject){
         //setup the next parent
         oNewParent = oParent.getChild(eNode->name);
         //add the alembic object to the export list
         AddObject(pNewObject);
      }
      else{
         //if we skip node A, we parent node A's children to the parent of A
         oNewParent = oParent;
      }

      if(oNewParent.valid()){
         for( std::list<exoNodePtr>::iterator it = eNode->children.begin(); it != eNode->children.end(); it++){
            sceneStack.push_back(stackElement(*it, oNewParent));
         }
      }
      else{
         ESS_LOG_ERROR("Do not have refernce to parent.");
         return CStatus::Fail;
      }
   }

#if 0

   for(LONG i=0; i<mSelection.size(); i++)
   {
      mSelection[i].nNodeDepth = getNodeDepthFromRef(mSelection[i].cRef);
   }
   std::sort(mSelection.begin(), mSelection.end());

   Alembic::Abc::OBox3dProperty boxProp = Alembic::AbcGeom::CreateOArchiveBounds(mArchive,mTs);

   CString activeSceneRoot_GetFullName = Application().GetActiveSceneRoot().GetFullName();
   // create object for each
   for(LONG i=0;i<mSelection.size();i++)
   {
	   X3DObject xObj(mSelection[i].cRef);
	   CRef xObj_GetActivePrimitive_GetRef = xObj.GetActivePrimitive().GetRef();
      //if(GetObject(xObj_GetActivePrimitive_GetRef) != NULL) continue;

      // push all models up the hierarchy

	  // MHahn: we are going to disable this code for now, since it should probably be an additional
	  // export option, and we would prefer not to make things more complicated. We we will require
	  // the user select the exact set of nodes that should be exported.

      //Model model(xObj.GetRef());
      //if(!model.IsValid())
      //   model = xObj.GetModel();
      CRefArray modelRefs;
      //if((bool)GetOption(L"transformCache"))
      if((bool)GetOption(L"flattenHierarchy") == false)
      {
         X3DObject parent = xObj.GetParent3DObject();
         while(parent.IsValid() && !parent.GetFullName().IsEqualNoCase( activeSceneRoot_GetFullName ))
         {
            modelRefs.Add(parent.GetActivePrimitive().GetRef());
            parent = parent.GetParent3DObject();
         }
      }
      //else
      //{
      //   while(model.IsValid() && !model.GetFullName().IsEqualNoCase( activeSceneRoot_GetFullName ))
      //   {
      //      modelRefs.Add(model.GetActivePrimitive().GetRef());
      //      model = model.GetModel();
      //   }
      //}
      for(LONG j=modelRefs.GetCount()-1;j>=0;j--)
      {
         //if(GetObject(modelRefs[j]) == NULL)
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicModel(modelRefs[j],this));
            //AddObjectIfDoesNotExist(ptr);
         }
      }

      if((bool)GetOption(L"transformCache"))
      {
         //always export all transforms whether the hierarchy is flattened or not

         AlembicObjectPtr ptr;
         ptr.reset(new AlembicModel(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);

         continue;// only do models (tranforms) if we perform pure transformcache
      }

      // take care of all other types
	  CString xObj_GetType = xObj.GetType();
      if(xObj_GetType.IsEqualNoCase(L"null") && ((bool)GetOption(L"flattenHierarchy") == false))
	  {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicModel(xObj_GetActivePrimitive_GetRef, this));
         //AddObjectIfDoesNotExist(ptr);
	  }
      else if(xObj_GetType.IsEqualNoCase(L"camera"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCamera(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"polymsh"))
      {
         Property geomProp;
         xObj.GetPropertyFromName(L"geomapprox",geomProp);
         LONG subDivLevel = geomProp.GetParameterValue(L"gapproxmordrsl");
         if(subDivLevel > 0)
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicSubD(xObj_GetActivePrimitive_GetRef,this));
            //AddObjectIfDoesNotExist(ptr);
         }
         else
         {
            AlembicObjectPtr ptr;
            ptr.reset(new AlembicPolyMesh(xObj_GetActivePrimitive_GetRef,this));
            //AddObjectIfDoesNotExist(ptr);
         }
      }
      else if(xObj_GetType.IsEqualNoCase(L"surfmsh"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicNurbs(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"crvlist"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"hair"))
      {
         AlembicObjectPtr ptr;
         ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
      else if(xObj_GetType.IsEqualNoCase(L"pointcloud"))
      {
         AlembicObjectPtr ptr;
         ICEAttribute strandPosition = xObj.GetActivePrimitive().GetGeometry().GetICEAttributeFromName(L"StrandPosition");
         if(strandPosition.IsDefined() && strandPosition.IsValid())
            ptr.reset(new AlembicCurves(xObj_GetActivePrimitive_GetRef,this));
         else
            ptr.reset(new AlembicPoints(xObj_GetActivePrimitive_GetRef,this));
         //AddObjectIfDoesNotExist(ptr);
      }
   }

#endif

   return CStatus::OK;
}

CStatus AlembicWriteJob::Process(double frame)
{
   CStatus result = CStatus::False;

   for(size_t i=0;i<mFrames.size();i++)
   {
      // compare the frames
      if(abs(mFrames[i] - frame) > 0.001)
         continue;

      // run the export for all objects
      for(size_t j=0;j<mObjects.size();j++)
      {
         CStatus status = mObjects[j]->Save(mFrames[i]);
         if(status != CStatus::OK)
            return status;
         result = CStatus::OK;
      }
   }

   return result;
}<|endoftext|>


<commit_before>//===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements the lexer for assembly files.
//
//===----------------------------------------------------------------------===//

#include "AsmLexer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Config/config.h"  // for strtoull.
#include "llvm/MC/MCAsmInfo.h"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
using namespace llvm;

AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI)  {
  CurBuf = NULL;
  CurPtr = NULL;
  TokStart = 0;
}

AsmLexer::~AsmLexer() {
}

void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
  CurBuf = buf;

  if (ptr)
    CurPtr = ptr;
  else
    CurPtr = CurBuf->getBufferStart();

  TokStart = 0;
}

SMLoc AsmLexer::getLoc() const {
  return SMLoc::getFromPointer(TokStart);
}

/// ReturnError - Set the error to the specified string at the specified
/// location.  This is defined to always return AsmToken::Error.
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
  SetError(SMLoc::getFromPointer(Loc), Msg);

  return AsmToken(AsmToken::Error, StringRef(Loc, 0));
}

int AsmLexer::getNextChar() {
  char CurChar = *CurPtr++;
  switch (CurChar) {
  default:
    return (unsigned char)CurChar;
  case 0:
    // A nul character in the stream is either the end of the current buffer or
    // a random nul in the file.  Disambiguate that here.
    if (CurPtr-1 != CurBuf->getBufferEnd())
      return 0;  // Just whitespace.

    // Otherwise, return end of file.
    --CurPtr;  // Another call to lex will return EOF again.
    return EOF;
  }
}

/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
AsmToken AsmLexer::LexIdentifier() {
  while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' ||
         *CurPtr == '.' || *CurPtr == '@')
    ++CurPtr;
  return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
}

/// LexSlash: Slash: /
///           C-Style Comment: /* ... */
AsmToken AsmLexer::LexSlash() {
  switch (*CurPtr) {
  case '*': break; // C style comment.
  case '/': return ++CurPtr, LexLineComment();
  default:  return AsmToken(AsmToken::Slash, StringRef(CurPtr, 1));
  }

  // C Style comment.
  ++CurPtr;  // skip the star.
  while (1) {
    int CurChar = getNextChar();
    switch (CurChar) {
    case EOF:
      return ReturnError(TokStart, "unterminated comment");
    case '*':
      // End of the comment?
      if (CurPtr[0] != '/') break;

      ++CurPtr;   // End the */.
      return LexToken();
    }
  }
}

/// LexLineComment: Comment: #[^\n]*
///                        : //[^\n]*
AsmToken AsmLexer::LexLineComment() {
  // FIXME: This is broken if we happen to a comment at the end of a file, which
  // was .included, and which doesn't end with a newline.
  int CurChar = getNextChar();
  while (CurChar != '\n' && CurChar != '\n' && CurChar != EOF)
    CurChar = getNextChar();

  if (CurChar == EOF)
    return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
  return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
}

/// LexDigit: First character is [0-9].
///   Local Label: [0-9][:]
///   Forward/Backward Label: [0-9][fb]
///   Binary integer: 0b[01]+
///   Octal integer: 0[0-7]+
///   Hex integer: 0x[0-9a-fA-F]+
///   Decimal integer: [1-9][0-9]*
/// TODO: FP literal.
AsmToken AsmLexer::LexDigit() {
  if (*CurPtr == ':')
    return ReturnError(TokStart, "FIXME: local label not implemented");
  if (*CurPtr == 'f' || *CurPtr == 'b')
    return ReturnError(TokStart, "FIXME: directional label not implemented");

  // Decimal integer: [1-9][0-9]*
  if (CurPtr[-1] != '0') {
    while (isdigit(*CurPtr))
      ++CurPtr;
    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    strtoll(TokStart, 0, 10));
  }

  if (*CurPtr == 'b') {
    ++CurPtr;
    const char *NumStart = CurPtr;
    while (CurPtr[0] == '0' || CurPtr[0] == '1')
      ++CurPtr;

    // Requires at least one binary digit.
    if (CurPtr == NumStart)
      return ReturnError(CurPtr-2, "Invalid binary number");
    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    strtoll(NumStart, 0, 2));
  }

  if (*CurPtr == 'x') {
    ++CurPtr;
    const char *NumStart = CurPtr;
    while (isxdigit(CurPtr[0]))
      ++CurPtr;

    // Requires at least one hex digit.
    if (CurPtr == NumStart)
      return ReturnError(CurPtr-2, "Invalid hexadecimal number");

    errno = 0;
    if (errno == EINVAL)
      return ReturnError(CurPtr-2, "Invalid hexadecimal number");
    if (errno == ERANGE) {
      errno = 0;
      if (errno == EINVAL)
        return ReturnError(CurPtr-2, "Invalid hexadecimal number");
      if (errno == ERANGE)
        return ReturnError(CurPtr-2, "Hexadecimal number out of range");
    }
    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    (int64_t) strtoull(NumStart, 0, 16));
  }

  // Must be an octal number, it starts with 0.
  while (*CurPtr >= '0' && *CurPtr <= '7')
    ++CurPtr;
  return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                  strtoll(TokStart, 0, 8));
}

/// LexQuote: String: "..."
AsmToken AsmLexer::LexQuote() {
  int CurChar = getNextChar();
  // TODO: does gas allow multiline string constants?
  while (CurChar != '"') {
    if (CurChar == '\\') {
      // Allow \", etc.
      CurChar = getNextChar();
    }

    if (CurChar == EOF)
      return ReturnError(TokStart, "unterminated string constant");

    CurChar = getNextChar();
  }

  return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
}

StringRef AsmLexer::LexUntilEndOfStatement() {
  TokStart = CurPtr;

  while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
	  *CurPtr != ';' &&  // End of statement marker.
         *CurPtr != '\n' &&
         *CurPtr != '\r' &&
         (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
    ++CurPtr;
  }
  return StringRef(TokStart, CurPtr-TokStart);
}

bool AsmLexer::isAtStartOfComment(char Char) {
  // FIXME: This won't work for multi-character comment indicators like "//".
  return Char == *MAI.getCommentString();
}

AsmToken AsmLexer::LexToken() {
  TokStart = CurPtr;
  // This always consumes at least one character.
  int CurChar = getNextChar();

  if (isAtStartOfComment(CurChar))
    return LexLineComment();

  switch (CurChar) {
  default:
    // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
    if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
      return LexIdentifier();

    // Unknown character, emit an error.
    return ReturnError(TokStart, "invalid character in input");
  case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
  case 0:
  case ' ':
  case '\t':
    // Ignore whitespace.
    return LexToken();
  case '\n': // FALL THROUGH.
  case '\r': // FALL THROUGH.
  case ';': return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
  case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
  case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
  case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
  case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
  case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
  case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
  case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
  case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
  case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
  case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
  case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
  case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
  case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
  case '=':
    if (*CurPtr == '=')
      return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
  case '|':
    if (*CurPtr == '|')
      return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
  case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
  case '&':
    if (*CurPtr == '&')
      return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
  case '!':
    if (*CurPtr == '=')
      return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
  case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
  case '/': return LexSlash();
  case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
  case '"': return LexQuote();
  case '0': case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9':
    return LexDigit();
  case '<':
    switch (*CurPtr) {
    case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
                                        StringRef(TokStart, 2));
    case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
                                        StringRef(TokStart, 2));
    case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
                                        StringRef(TokStart, 2));
    default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
    }
  case '>':
    switch (*CurPtr) {
    case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
                                        StringRef(TokStart, 2));
    case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
                                        StringRef(TokStart, 2));
    default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
    }

  // TODO: Quoted identifiers (objc methods etc)
  // local labels: [0-9][:]
  // Forward/backward labels: [0-9][fb]
  // Integers, fp constants, character constants.
  }
}
<commit_msg>remove some confused code that used strtoull<commit_after>//===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements the lexer for assembly files.
//
//===----------------------------------------------------------------------===//

#include "AsmLexer.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/MC/MCAsmInfo.h"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
using namespace llvm;

AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI)  {
  CurBuf = NULL;
  CurPtr = NULL;
  TokStart = 0;
}

AsmLexer::~AsmLexer() {
}

void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
  CurBuf = buf;

  if (ptr)
    CurPtr = ptr;
  else
    CurPtr = CurBuf->getBufferStart();

  TokStart = 0;
}

SMLoc AsmLexer::getLoc() const {
  return SMLoc::getFromPointer(TokStart);
}

/// ReturnError - Set the error to the specified string at the specified
/// location.  This is defined to always return AsmToken::Error.
AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
  SetError(SMLoc::getFromPointer(Loc), Msg);

  return AsmToken(AsmToken::Error, StringRef(Loc, 0));
}

int AsmLexer::getNextChar() {
  char CurChar = *CurPtr++;
  switch (CurChar) {
  default:
    return (unsigned char)CurChar;
  case 0:
    // A nul character in the stream is either the end of the current buffer or
    // a random nul in the file.  Disambiguate that here.
    if (CurPtr-1 != CurBuf->getBufferEnd())
      return 0;  // Just whitespace.

    // Otherwise, return end of file.
    --CurPtr;  // Another call to lex will return EOF again.
    return EOF;
  }
}

/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
AsmToken AsmLexer::LexIdentifier() {
  while (isalnum(*CurPtr) || *CurPtr == '_' || *CurPtr == '$' ||
         *CurPtr == '.' || *CurPtr == '@')
    ++CurPtr;
  return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
}

/// LexSlash: Slash: /
///           C-Style Comment: /* ... */
AsmToken AsmLexer::LexSlash() {
  switch (*CurPtr) {
  case '*': break; // C style comment.
  case '/': return ++CurPtr, LexLineComment();
  default:  return AsmToken(AsmToken::Slash, StringRef(CurPtr, 1));
  }

  // C Style comment.
  ++CurPtr;  // skip the star.
  while (1) {
    int CurChar = getNextChar();
    switch (CurChar) {
    case EOF:
      return ReturnError(TokStart, "unterminated comment");
    case '*':
      // End of the comment?
      if (CurPtr[0] != '/') break;

      ++CurPtr;   // End the */.
      return LexToken();
    }
  }
}

/// LexLineComment: Comment: #[^\n]*
///                        : //[^\n]*
AsmToken AsmLexer::LexLineComment() {
  // FIXME: This is broken if we happen to a comment at the end of a file, which
  // was .included, and which doesn't end with a newline.
  int CurChar = getNextChar();
  while (CurChar != '\n' && CurChar != '\n' && CurChar != EOF)
    CurChar = getNextChar();

  if (CurChar == EOF)
    return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
  return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
}

/// LexDigit: First character is [0-9].
///   Local Label: [0-9][:]
///   Forward/Backward Label: [0-9][fb]
///   Binary integer: 0b[01]+
///   Octal integer: 0[0-7]+
///   Hex integer: 0x[0-9a-fA-F]+
///   Decimal integer: [1-9][0-9]*
/// TODO: FP literal.
AsmToken AsmLexer::LexDigit() {
  if (*CurPtr == ':')
    return ReturnError(TokStart, "FIXME: local label not implemented");
  if (*CurPtr == 'f' || *CurPtr == 'b')
    return ReturnError(TokStart, "FIXME: directional label not implemented");

  // Decimal integer: [1-9][0-9]*
  if (CurPtr[-1] != '0') {
    while (isdigit(*CurPtr))
      ++CurPtr;
    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    strtoll(TokStart, 0, 10));
  }

  if (*CurPtr == 'b') {
    ++CurPtr;
    const char *NumStart = CurPtr;
    while (CurPtr[0] == '0' || CurPtr[0] == '1')
      ++CurPtr;

    // Requires at least one binary digit.
    if (CurPtr == NumStart)
      return ReturnError(CurPtr-2, "Invalid binary number");
    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    strtoll(NumStart, 0, 2));
  }

  if (*CurPtr == 'x') {
    ++CurPtr;
    const char *NumStart = CurPtr;
    while (isxdigit(CurPtr[0]))
      ++CurPtr;

    // Requires at least one hex digit.
    if (CurPtr == NumStart)
      return ReturnError(CurPtr-2, "Invalid hexadecimal number");

    unsigned long long Result;
    if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
      return ReturnError(CurPtr-2, "Invalid hexadecimal number");

    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                    (int64_t)Result);
  }

  // Must be an octal number, it starts with 0.
  while (*CurPtr >= '0' && *CurPtr <= '7')
    ++CurPtr;
  return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
                  strtoll(TokStart, 0, 8));
}

/// LexQuote: String: "..."
AsmToken AsmLexer::LexQuote() {
  int CurChar = getNextChar();
  // TODO: does gas allow multiline string constants?
  while (CurChar != '"') {
    if (CurChar == '\\') {
      // Allow \", etc.
      CurChar = getNextChar();
    }

    if (CurChar == EOF)
      return ReturnError(TokStart, "unterminated string constant");

    CurChar = getNextChar();
  }

  return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
}

StringRef AsmLexer::LexUntilEndOfStatement() {
  TokStart = CurPtr;

  while (!isAtStartOfComment(*CurPtr) && // Start of line comment.
	  *CurPtr != ';' &&  // End of statement marker.
         *CurPtr != '\n' &&
         *CurPtr != '\r' &&
         (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
    ++CurPtr;
  }
  return StringRef(TokStart, CurPtr-TokStart);
}

bool AsmLexer::isAtStartOfComment(char Char) {
  // FIXME: This won't work for multi-character comment indicators like "//".
  return Char == *MAI.getCommentString();
}

AsmToken AsmLexer::LexToken() {
  TokStart = CurPtr;
  // This always consumes at least one character.
  int CurChar = getNextChar();

  if (isAtStartOfComment(CurChar))
    return LexLineComment();

  switch (CurChar) {
  default:
    // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
    if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
      return LexIdentifier();

    // Unknown character, emit an error.
    return ReturnError(TokStart, "invalid character in input");
  case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
  case 0:
  case ' ':
  case '\t':
    // Ignore whitespace.
    return LexToken();
  case '\n': // FALL THROUGH.
  case '\r': // FALL THROUGH.
  case ';': return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
  case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
  case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
  case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
  case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
  case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
  case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
  case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
  case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
  case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
  case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
  case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
  case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
  case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
  case '=':
    if (*CurPtr == '=')
      return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
  case '|':
    if (*CurPtr == '|')
      return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
  case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
  case '&':
    if (*CurPtr == '&')
      return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
  case '!':
    if (*CurPtr == '=')
      return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
    return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
  case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
  case '/': return LexSlash();
  case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
  case '"': return LexQuote();
  case '0': case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9':
    return LexDigit();
  case '<':
    switch (*CurPtr) {
    case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
                                        StringRef(TokStart, 2));
    case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
                                        StringRef(TokStart, 2));
    case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
                                        StringRef(TokStart, 2));
    default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
    }
  case '>':
    switch (*CurPtr) {
    case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
                                        StringRef(TokStart, 2));
    case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
                                        StringRef(TokStart, 2));
    default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
    }

  // TODO: Quoted identifiers (objc methods etc)
  // local labels: [0-9][:]
  // Forward/backward labels: [0-9][fb]
  // Integers, fp constants, character constants.
  }
}
<|endoftext|>