<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <getopt.h>
#include <unistd.h>

#define OSMIUM_MAIN
#include <osmium.hpp>

#include <geos/geom/MultiPolygon.h>
#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>

#include "softcut.hpp"
#include "hardcut.hpp"

template <class TExtractInfo> bool readConfig(char *conffile, Cut<TExtractInfo> *cutter);
geos::geom::Geometry *readPolyFile(char* file);

int main(int argc, char *argv[]) {
    bool softcut = false;
    bool debug = false;
    char *filename, *conffile;

    static struct option long_options[] = {
        {"debug",               no_argument, 0, 'd'},
        {"softcut",             no_argument, 0, 's'},
        {"hardcut",             no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    while (1) {
        int c = getopt_long(argc, argv, "dsh", long_options, 0);
        if (c == -1)
            break;

        switch (c) {
            case 'd':
                debug = true;
                break;
            case 's':
                softcut = true;
                break;
            case 'h':
                softcut = false;
                break;
        }
    }

    if (optind > argc-2) {
        fprintf(stderr, "Usage: %s [OPTIONS] OSMFILE CONFIGFILE\n", argv[0]);
        return 1;
    }

    filename = argv[optind];
    conffile = argv[optind+1];

    if(softcut & !strcmp(filename, "-")) {
        fprintf(stderr, "Can't read from stdin when in softcut\n");
        return 1;
    }

    Osmium::Framework osmium(debug);

    if(softcut) {
        Softcut *cutter = new Softcut();
        cutter->debug = debug;
        if(!readConfig(conffile, cutter))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        cutter->phase = Softcut::PHASE::ONE;
        osmium.parse_osmfile<Softcut>(filename, cutter);

        cutter->phase = Softcut::PHASE::TWO;
        osmium.parse_osmfile<Softcut>(filename, cutter);

        delete cutter;
    } else {
        Hardcut *cutter = new Hardcut();
        cutter->debug = debug;
        if(!readConfig(conffile, cutter))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        osmium.parse_osmfile<Hardcut>(filename, cutter);
        delete cutter;
    }

    return 0;
}

template <class TExtractInfo> bool readConfig(char *conffile, Cut<TExtractInfo> *cutter) {
    const int linelen = 4096;

    FILE *fp = fopen(conffile, "r");
    if(!fp) {
        fprintf(stderr, "unable to open config file %s\n", conffile);
        return false;
    }

    char line[linelen];
    while(fgets(line, linelen-1, fp)) {
        line[linelen-1] = '\0';
        if(line[0] == '#' || line[0] == '\r' || line[0] == '\n' || line[0] == '\0')
            continue;

        int n = 0;
        char *tok = strtok(line, "\t ");

        const char *name = NULL;
        double minlon = 0, minlat = 0, maxlon = 0, maxlat = 0;
        char type = '\0';

        while(tok) {
            switch(n) {
                case 0:
                    name = tok;
                    break;

                case 1:
                    if(0 == strcmp("BBOX", tok))
                        type = 'b';
                    else if(0 == strcmp("POLY", tok))
                        type = 'p';
                    else {
                        type = '\0';
                        fprintf(stderr, "output %s of type %s: unkown output type\n", name, tok);
                        return false;
                    }
                    break;

                case 2:
                    switch(type) {
                        case 'b':
                            if(4 == sscanf(tok, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat)) {
                                if(minlon > maxlon) {
                                    double d = maxlon;
                                    minlon = maxlon;
                                    maxlon = d;
                                }

                                if(minlat > maxlat) {
                                    double d = maxlat;
                                    minlat = maxlat;
                                    maxlat = d;
                                }
                                cutter->addBbox(name, minlon, minlat, maxlon, maxlat);
                            }
                            break;
                        case 'p':
                            geos::geom::Geometry *poly = readPolyFile(tok);
                            cutter->addPoly(name, poly);
                            break;
                    }
                    break;
            }

            tok = strtok(NULL, "\t ");
            n++;
        }
    }
    fclose(fp);
    return true;
}

geos::geom::Geometry *readPolyFile(char* file) {
    // shorthand
    geos::geom::GeometryFactory *f = Osmium::global.geos_geometry_factory;

    std::vector<geos::geom::Coordinate> *c;
    std::vector<geos::geom::Geometry*> outer;
    std::vector<geos::geom::Geometry*> inner;

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(10, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(10, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(20, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(20, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(10, 10, DoubleNotANumber));

    outer.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(40, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(40, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(50, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(50, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(40, 10, DoubleNotANumber));
    outer.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(9, 12, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(9, 18, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(18, 18, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(18, 12, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(9, 12, DoubleNotANumber));

    inner.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    geos::geom::MultiPolygon *outerPoly = f->createMultiPolygon(outer);
    geos::geom::MultiPolygon *innerPoly = f->createMultiPolygon(inner);
    geos::geom::Geometry *poly = outerPoly->difference(innerPoly);

    delete outerPoly;
    delete innerPoly;

    /*
    geos::algorithm::locate::IndexedPointInAreaLocator *locator =
        new geos::algorithm::locate::IndexedPointInAreaLocator(*const_cast<const geos::geom::Geometry *>(poly));

    printf("%d %d: %d (left out)\n", 9,  15, locator->locate(new geos::geom::Coordinate( 9, 15, DoubleNotANumber)));
    printf("%d %d: %d (on border)\n", 10,  15, locator->locate(new geos::geom::Coordinate( 10, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside left border)\n", 11, 15, locator->locate(new geos::geom::Coordinate(11, 15, DoubleNotANumber)));
    printf("%d %d: %d (in hole)\n", 15, 15, locator->locate(new geos::geom::Coordinate(15, 15, DoubleNotANumber)));
    printf("%d %d: %d (in hole)\n", 17, 15, locator->locate(new geos::geom::Coordinate(17, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside right border)\n", 19, 15, locator->locate(new geos::geom::Coordinate(19, 15, DoubleNotANumber)));
    printf("%d %d: %d (between shapes)\n", 30, 15, locator->locate(new geos::geom::Coordinate(30, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside right shape)\n", 45, 15, locator->locate(new geos::geom::Coordinate(45, 15, DoubleNotANumber)));
    printf("%d %d: %d (right out)\n", 51, 15, locator->locate(new geos::geom::Coordinate(51, 15, DoubleNotANumber)));
    */

    return poly;
}

<commit_msg>use factory to destroy<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#include <getopt.h>
#include <unistd.h>

#define OSMIUM_MAIN
#include <osmium.hpp>

#include <geos/geom/MultiPolygon.h>
#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>

#include "softcut.hpp"
#include "hardcut.hpp"

template <class TExtractInfo> bool readConfig(char *conffile, Cut<TExtractInfo> *cutter);
geos::geom::Geometry *readPolyFile(char* file);

int main(int argc, char *argv[]) {
    bool softcut = false;
    bool debug = false;
    char *filename, *conffile;

    static struct option long_options[] = {
        {"debug",               no_argument, 0, 'd'},
        {"softcut",             no_argument, 0, 's'},
        {"hardcut",             no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    while (1) {
        int c = getopt_long(argc, argv, "dsh", long_options, 0);
        if (c == -1)
            break;

        switch (c) {
            case 'd':
                debug = true;
                break;
            case 's':
                softcut = true;
                break;
            case 'h':
                softcut = false;
                break;
        }
    }

    if (optind > argc-2) {
        fprintf(stderr, "Usage: %s [OPTIONS] OSMFILE CONFIGFILE\n", argv[0]);
        return 1;
    }

    filename = argv[optind];
    conffile = argv[optind+1];

    if(softcut & !strcmp(filename, "-")) {
        fprintf(stderr, "Can't read from stdin when in softcut\n");
        return 1;
    }

    Osmium::Framework osmium(debug);

    if(softcut) {
        Softcut *cutter = new Softcut();
        cutter->debug = debug;
        if(!readConfig(conffile, cutter))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        cutter->phase = Softcut::PHASE::ONE;
        osmium.parse_osmfile<Softcut>(filename, cutter);

        cutter->phase = Softcut::PHASE::TWO;
        osmium.parse_osmfile<Softcut>(filename, cutter);

        delete cutter;
    } else {
        Hardcut *cutter = new Hardcut();
        cutter->debug = debug;
        if(!readConfig(conffile, cutter))
        {
            fprintf(stderr, "error reading config\n");
            return 1;
        }

        osmium.parse_osmfile<Hardcut>(filename, cutter);
        delete cutter;
    }

    return 0;
}

template <class TExtractInfo> bool readConfig(char *conffile, Cut<TExtractInfo> *cutter) {
    const int linelen = 4096;

    FILE *fp = fopen(conffile, "r");
    if(!fp) {
        fprintf(stderr, "unable to open config file %s\n", conffile);
        return false;
    }

    char line[linelen];
    while(fgets(line, linelen-1, fp)) {
        line[linelen-1] = '\0';
        if(line[0] == '#' || line[0] == '\r' || line[0] == '\n' || line[0] == '\0')
            continue;

        int n = 0;
        char *tok = strtok(line, "\t ");

        const char *name = NULL;
        double minlon = 0, minlat = 0, maxlon = 0, maxlat = 0;
        char type = '\0';

        while(tok) {
            switch(n) {
                case 0:
                    name = tok;
                    break;

                case 1:
                    if(0 == strcmp("BBOX", tok))
                        type = 'b';
                    else if(0 == strcmp("POLY", tok))
                        type = 'p';
                    else {
                        type = '\0';
                        fprintf(stderr, "output %s of type %s: unkown output type\n", name, tok);
                        return false;
                    }
                    break;

                case 2:
                    switch(type) {
                        case 'b':
                            if(4 == sscanf(tok, "%lf,%lf,%lf,%lf", &minlon, &minlat, &maxlon, &maxlat)) {
                                if(minlon > maxlon) {
                                    double d = maxlon;
                                    minlon = maxlon;
                                    maxlon = d;
                                }

                                if(minlat > maxlat) {
                                    double d = maxlat;
                                    minlat = maxlat;
                                    maxlat = d;
                                }
                                cutter->addBbox(name, minlon, minlat, maxlon, maxlat);
                            }
                            break;
                        case 'p':
                            geos::geom::Geometry *poly = readPolyFile(tok);
                            cutter->addPoly(name, poly);
                            break;
                    }
                    break;
            }

            tok = strtok(NULL, "\t ");
            n++;
        }
    }
    fclose(fp);
    return true;
}

geos::geom::Geometry *readPolyFile(char* file) {
    // shorthand
    geos::geom::GeometryFactory *f = Osmium::global.geos_geometry_factory;

    std::vector<geos::geom::Coordinate> *c;
    std::vector<geos::geom::Geometry*> outer;
    std::vector<geos::geom::Geometry*> inner;

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(10, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(10, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(20, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(20, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(10, 10, DoubleNotANumber));

    outer.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(40, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(40, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(50, 20, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(50, 10, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(40, 10, DoubleNotANumber));
    outer.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    c = new std::vector<geos::geom::Coordinate>();
    c->push_back(geos::geom::Coordinate(9, 12, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(9, 18, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(18, 18, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(18, 12, DoubleNotANumber));
    c->push_back(geos::geom::Coordinate(9, 12, DoubleNotANumber));

    inner.push_back(
        f->createPolygon(
            f->createLinearRing(
                f->getCoordinateSequenceFactory()->create(c)
            ),
            NULL
        )
    );

    geos::geom::MultiPolygon *outerPoly = f->createMultiPolygon(outer);
    geos::geom::MultiPolygon *innerPoly = f->createMultiPolygon(inner);
    geos::geom::Geometry *poly = outerPoly->difference(innerPoly);

    f->destroyGeometry(outerPoly);
    f->destroyGeometry(innerPoly);

    /*
    geos::algorithm::locate::IndexedPointInAreaLocator *locator =
        new geos::algorithm::locate::IndexedPointInAreaLocator(*const_cast<const geos::geom::Geometry *>(poly));

    printf("%d %d: %d (left out)\n", 9,  15, locator->locate(new geos::geom::Coordinate( 9, 15, DoubleNotANumber)));
    printf("%d %d: %d (on border)\n", 10,  15, locator->locate(new geos::geom::Coordinate( 10, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside left border)\n", 11, 15, locator->locate(new geos::geom::Coordinate(11, 15, DoubleNotANumber)));
    printf("%d %d: %d (in hole)\n", 15, 15, locator->locate(new geos::geom::Coordinate(15, 15, DoubleNotANumber)));
    printf("%d %d: %d (in hole)\n", 17, 15, locator->locate(new geos::geom::Coordinate(17, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside right border)\n", 19, 15, locator->locate(new geos::geom::Coordinate(19, 15, DoubleNotANumber)));
    printf("%d %d: %d (between shapes)\n", 30, 15, locator->locate(new geos::geom::Coordinate(30, 15, DoubleNotANumber)));
    printf("%d %d: %d (inside right shape)\n", 45, 15, locator->locate(new geos::geom::Coordinate(45, 15, DoubleNotANumber)));
    printf("%d %d: %d (right out)\n", 51, 15, locator->locate(new geos::geom::Coordinate(51, 15, DoubleNotANumber)));
    */

    return poly;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <vector>
#include <boost/algorithm/string/trim.hpp>

using namespace std;
using namespace boost;

bool done = false;

void orfinder(string filter, vector<string> &take)
{
	unsigned int start = 0;
	unsigned int cut = 0;
	bool finished = false;
	bool complete = false;
	bool over = false;
	string copy = filter;
	while(!finished)
	{
		for(unsigned int i = start; i <= filter.size()-2 && !complete; ++i)
		{
			if((filter.at(i) == '|') && (filter.at(i+1) == '|'))
			{
				copy = copy.substr(start, cut);
				trim(copy);
				take.push_back(copy);
				while(i < filter.size() && filter.at(i) == '|')
				{
					++i;
				}
				if(i == filter.size())
				{
					over = true;
				}
				else
				{
					start = i;
				}
				complete = true;
			}
			else
			{
				cut++;
			}
		}
		copy = filter;
		if(!complete || over)
		{
			copy = copy.substr(start, copy.size()-start);
			trim(copy);
			take.push_back(copy);
			finished = true;
		}
		else
		{
			cut = 0;
			complete = false;
			over = false;
		}
	}
}

bool charfinder(const char element, const string search)
{
	char last = 0;
	bool condition = false;
	for(unsigned int i = 0; i <= search.size()-2; ++i)
	{
		if(search.at(i) == element && last != element && search.at(i+1) != element)
		{
			condition = true;
		}
		if(i == search.size()-2)
		{
			last = search.at(i);
			if(search.at(i+1) == element && last != element)
			{
				condition = true;
			}
		}
		last = search.at(i);
	}
	return condition;
}

void finder(const string search, bool &haspipe, bool &hasleft, bool &has2right, bool &hasright)
{
	bool complete = false;
	for(unsigned int i = 0; i <= search.size()-2 && !complete; ++i)
	{
		if((search.at(i) == '>') && (search.at(i+1) == '>'))
		{
			has2right = true;
			complete = true;
		}
	}
	hasleft = charfinder('<', search);
	hasright = charfinder('>', search);
	haspipe = charfinder('|', search);
}

void normalBash(string command)
{
	char *token;
	vector<string> sc_cmd;		//sc_cmd stands for semicolon_commands - this holds the commands in string form
	vector<string> copy;		//this will hold the new commands from sc_cmd without any comments for a short while
	vector<string> and_cmd;		//this will hold the string of single commands combined by &&
	vector<string> or_cmd;		//this will hold the string of commands combined by ||
	char* cmd = new char[command.size()];
	if(command.size() > 0)
	{
		copy.push_back(command);
	}
	if(copy.size() > 0)
	{
		strcpy(cmd, (copy.at(0)).c_str());
		copy.clear();
		token = strtok(cmd, ";");
		while(token != NULL)
		{
			sc_cmd.push_back(string(token)); //parse the string, looking for semicolons to split the commands
			token = strtok(NULL, ";");
		}
		for(unsigned int i = 0; i < sc_cmd.size(); ++i)
		{
			strcpy(cmd, (sc_cmd.at(i)).c_str());
			token = strtok(cmd, "#");		//parse the string looking for the start of a comment
			if(token != NULL)		//then only add the beginning part of the command and throw away everything after the #
			{
				if(string(token).find_first_not_of(' ') != std::string::npos) //if the parsed string is only white spaces
				{									//then dont add it list of commands
					copy.push_back(string(token));
				}
			}
		}
		sc_cmd.clear();
		for(unsigned int i = 0; i < copy.size(); ++i)
		{
			sc_cmd.push_back(copy.at(i));	//move the new filtered commands into the proper vector
		}
		copy.clear();
		for(unsigned int i = 0; i < sc_cmd.size(); ++i)	//keep executing these commands regardless of result from previous command
		{
			trim(sc_cmd.at(i));		//remove all the unnecessary white spaces around the string if in there
			orfinder(sc_cmd.at(i), or_cmd);
			unsigned int fails = 0;
			for(unsigned int i = 0; i < or_cmd.size(); ++i)	//keep doing || commands as long as the last command failed
			{
				trim(or_cmd.at(i));
				if(fails == i)
				{
					strcpy(cmd, (or_cmd.at(i)).c_str());
					token = strtok(cmd, "&&");
					while(token != NULL)	//parse the string command for && and split the code down to single commands
					{
						and_cmd.push_back(string(token));
						token = strtok(NULL, "&&");
					}
					unsigned int trues = 0;
					for(unsigned int i = 0; i < and_cmd.size(); ++i) //keep doing && commands as long as the last command succeeded
					{
						trim(and_cmd.at(i));
						bool haspipe = false;
						bool hasleft = false;
						bool has2right = false;
						bool hasright = false;
						finder(and_cmd.at(i), haspipe, hasleft, has2right, hasright);
						if(trues == i)
						{
							strcpy(cmd, (and_cmd.at(i)).c_str());
							token = strtok(cmd, " ");
							while(token != NULL)	//break down the command into strings
							{
								copy.push_back(string(token));
								token = strtok(NULL, " ");
							}
							char **argv = new char*[copy.size()+1];	//create an array of char pointers
							for(unsigned int j = 0; j < copy.size(); ++j)
							{
								trim(copy.at(j));	//add char pointers into an array of pointers
								argv[j] = const_cast<char*>((copy.at(j)).c_str());	//this will allow us to use execvp
							}
							argv[copy.size()] = 0;
							int pid = fork();
							if(pid == -1)
							{
								perror("There was an error with fork() ");
							}
							else if(pid == 0)
							{
								if(and_cmd.at(i) != "exit")	//only move along to execvp if the command is not exit
								{
									if(haspipe || hasleft || has2right || hasright)
									{
										cout << "I/O redirection" << endl;
										_exit(0);
									}
									else
									{
										if(-1 == execvp((copy.at(0)).c_str(), argv))
										{
											perror("There was an error with execvp() ");
											_exit(1);	//if the command failed, then kill the child process and exit
										}
									}
								}
								else //if the command is to exit, dont do anything, simply kill the child process and exit
								{
									_exit(1);
								}
							}
							else
							{
								int status;
								wait(&status);
								if(status == -1)
								{
									perror("There was an error with wait() ");
								}
								else if(status == 0)	//if the last command was executed successfully, increase the counter
								{
									++trues;
								}
								if(and_cmd.at(i) == "exit")	//if the user entered the exit command, end the shell and program
								{
									delete []argv;		//since we are done with the program early, we must delete
									delete []cmd;		//dynamic memory from leaking out
									copy.clear();
									and_cmd.clear();
									or_cmd.clear();
									sc_cmd.clear();
									done = true;
									return;
								}
							}
							delete []argv;	//make sure to delete the dynamically allocated memory
						}
						copy.clear();	//clear out the vector to be used again
					}	//end of and_cmd
					if(trues != and_cmd.size())
					{
						fails++;   //if the amount of commands that were successfully executed is not the same as the
							//number of commands executed, then increase the number of commands failed
					}
				}
				and_cmd.clear();	//clear out the commands in and vector since we are done
			}   //end of or_cmd
			or_cmd.clear();	 //clear out the commands in the or vector since we are done
		}	//end of sc_cmd
		sc_cmd.clear();	//clear out the commands in the semicolon vector since we are done
	}
	delete []cmd;//make sure to delete the dynamically allocated memory
}

int main()
{
	char *user = getlogin();	//gets the user name
	string command;
	if(user == NULL)
	{
		perror("There was an error with getlogin() ");
	}
	char name[100];				//initialize empty string to be used to get the host name
	int check = gethostname(name, 100);		//gets the host's name and stores it in the char array variable name
	if(check == -1)
	{
		perror("There was en error with gethostname() ");
	}
	while(!done)		//loop until user enters exit and the loop is terminated
	{
		if((user != NULL) && (check == 0))
		{
			cout << user << "@" << name << " $ ";	//output user name, @ symbol, the host name, followed by $
		}			// output at this point should result in: [user]@[host]$
		else
		{
			cout << "$ ";
		}
		getline(cin, command);	//get the entire line of command from user
		unsigned int loc = command.find_first_of("#");	//keep only everything before the first comment mark
		command = command.substr(0, loc);
		if(command == "exit")
		{
			done = true;	//if the command they type in is initially exit
					//then there is no need to continue traversing the program, simply end
		}
		else
		{
			normalBash(command);
		}
	}
	return 0;
}
<commit_msg>started > redirection implementation<commit_after>#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <cstring>
#include <vector>
#include <boost/algorithm/string/trim.hpp>

using namespace std;
using namespace boost;

bool done = false;
void onlyright(string command)
{
	char *token;
	char* cmd = new char[command.size()];
	strcpy(cmd, command.c_str());
	token = strtok(cmd, ">");
	vector<string> holder;
	while(token != NULL)
	{
		holder.push_back(string(token));
		token = strtok(NULL, ">");
	}
}
void orfinder(string filter, vector<string> &take)
{
	unsigned int start = 0;
	unsigned int cut = 0;
	bool finished = false;
	bool complete = false;
	bool over = false;
	string copy = filter;
	while(!finished)
	{
		for(unsigned int i = start; i <= filter.size()-2 && !complete; ++i)
		{
			if((filter.at(i) == '|') && (filter.at(i+1) == '|'))
			{
				copy = copy.substr(start, cut);
				trim(copy);
				take.push_back(copy);
				while(i < filter.size() && filter.at(i) == '|')
				{
					++i;
				}
				if(i == filter.size())
				{
					over = true;
				}
				else
				{
					start = i;
				}
				complete = true;
			}
			else
			{
				cut++;
			}
		}
		copy = filter;
		if(!complete || over)
		{
			copy = copy.substr(start, copy.size()-start);
			trim(copy);
			take.push_back(copy);
			finished = true;
		}
		else
		{
			cut = 0;
			complete = false;
			over = false;
		}
	}
}

bool charfinder(const char element, const string search)
{
	char last = 0;
	bool condition = false;
	for(unsigned int i = 0; i <= search.size()-2; ++i)
	{
		if(search.at(i) == element && last != element && search.at(i+1) != element)
		{
			condition = true;
		}
		if(i == search.size()-2)
		{
			last = search.at(i);
			if(search.at(i+1) == element && last != element)
			{
				condition = true;
			}
		}
		last = search.at(i);
	}
	return condition;
}

void finder(const string search, bool &haspipe, bool &hasleft, bool &has2right, bool &hasright)
{
	bool complete = false;
	for(unsigned int i = 0; i <= search.size()-2 && !complete; ++i)
	{
		if((search.at(i) == '>') && (search.at(i+1) == '>'))
		{
			has2right = true;
			complete = true;
		}
	}
	hasleft = charfinder('<', search);
	hasright = charfinder('>', search);
	haspipe = charfinder('|', search);
}

void normalBash(string command)
{
	char *token;
	vector<string> sc_cmd;		//sc_cmd stands for semicolon_commands - this holds the commands in string form
	vector<string> copy;		//this will hold the new commands from sc_cmd without any comments for a short while
	vector<string> and_cmd;		//this will hold the string of single commands combined by &&
	vector<string> or_cmd;		//this will hold the string of commands combined by ||
	char* cmd = new char[command.size()];
	if(command.size() > 0)
	{
		copy.push_back(command);
	}
	if(copy.size() > 0)
	{
		strcpy(cmd, (copy.at(0)).c_str());
		copy.clear();
		token = strtok(cmd, ";");
		while(token != NULL)
		{
			sc_cmd.push_back(string(token)); //parse the string, looking for semicolons to split the commands
			token = strtok(NULL, ";");
		}
		for(unsigned int i = 0; i < sc_cmd.size(); ++i)
		{
			strcpy(cmd, (sc_cmd.at(i)).c_str());
			token = strtok(cmd, "#");		//parse the string looking for the start of a comment
			if(token != NULL)		//then only add the beginning part of the command and throw away everything after the #
			{
				if(string(token).find_first_not_of(' ') != std::string::npos) //if the parsed string is only white spaces
				{									//then dont add it list of commands
					copy.push_back(string(token));
				}
			}
		}
		sc_cmd.clear();
		for(unsigned int i = 0; i < copy.size(); ++i)
		{
			sc_cmd.push_back(copy.at(i));	//move the new filtered commands into the proper vector
		}
		copy.clear();
		for(unsigned int i = 0; i < sc_cmd.size(); ++i)	//keep executing these commands regardless of result from previous command
		{
			trim(sc_cmd.at(i));		//remove all the unnecessary white spaces around the string if in there
			orfinder(sc_cmd.at(i), or_cmd);
			unsigned int fails = 0;
			for(unsigned int i = 0; i < or_cmd.size(); ++i)	//keep doing || commands as long as the last command failed
			{
				trim(or_cmd.at(i));
				if(fails == i)
				{
					strcpy(cmd, (or_cmd.at(i)).c_str());
					token = strtok(cmd, "&&");
					while(token != NULL)	//parse the string command for && and split the code down to single commands
					{
						and_cmd.push_back(string(token));
						token = strtok(NULL, "&&");
					}
					unsigned int trues = 0;
					for(unsigned int i = 0; i < and_cmd.size(); ++i) //keep doing && commands as long as the last command succeeded
					{
						trim(and_cmd.at(i));
						bool haspipe = false;
						bool hasleft = false;
						bool has2right = false;
						bool hasright = false;
						finder(and_cmd.at(i), haspipe, hasleft, has2right, hasright);
						if(trues == i)
						{
							strcpy(cmd, (and_cmd.at(i)).c_str());
							token = strtok(cmd, " ");
							while(token != NULL)	//break down the command into strings
							{
								copy.push_back(string(token));
								token = strtok(NULL, " ");
							}
							char **argv = new char*[copy.size()+1];	//create an array of char pointers
							for(unsigned int j = 0; j < copy.size(); ++j)
							{
								trim(copy.at(j));	//add char pointers into an array of pointers
								argv[j] = const_cast<char*>((copy.at(j)).c_str());	//this will allow us to use execvp
							}
							argv[copy.size()] = 0;
							int pid = fork();
							if(pid == -1)
							{
								perror("There was an error with fork() ");
							}
							else if(pid == 0)
							{
								if(and_cmd.at(i) != "exit")	//only move along to execvp if the command is not exit
								{
									if(haspipe || hasleft || has2right || hasright)
									{
										cout << "I/O redirection" << endl;
										_exit(0);
									}
									else
									{
										if(-1 == execvp((copy.at(0)).c_str(), argv))
										{
											perror("There was an error with execvp() ");
											_exit(1);	//if the command failed, then kill the child process and exit
										}
									}
								}
								else //if the command is to exit, dont do anything, simply kill the child process and exit
								{
									_exit(1);
								}
							}
							else
							{
								int status;
								wait(&status);
								if(status == -1)
								{
									perror("There was an error with wait() ");
								}
								else if(status == 0)	//if the last command was executed successfully, increase the counter
								{
									++trues;
								}
								if(and_cmd.at(i) == "exit")	//if the user entered the exit command, end the shell and program
								{
									delete []argv;		//since we are done with the program early, we must delete
									delete []cmd;		//dynamic memory from leaking out
									copy.clear();
									and_cmd.clear();
									or_cmd.clear();
									sc_cmd.clear();
									done = true;
									return;
								}
							}
							delete []argv;	//make sure to delete the dynamically allocated memory
						}
						copy.clear();	//clear out the vector to be used again
					}	//end of and_cmd
					if(trues != and_cmd.size())
					{
						fails++;   //if the amount of commands that were successfully executed is not the same as the
							//number of commands executed, then increase the number of commands failed
					}
				}
				and_cmd.clear();	//clear out the commands in and vector since we are done
			}   //end of or_cmd
			or_cmd.clear();	 //clear out the commands in the or vector since we are done
		}	//end of sc_cmd
		sc_cmd.clear();	//clear out the commands in the semicolon vector since we are done
	}
	delete []cmd;//make sure to delete the dynamically allocated memory
}

int main()
{
	char *user = getlogin();	//gets the user name
	string command;
	if(user == NULL)
	{
		perror("There was an error with getlogin() ");
	}
	char name[100];				//initialize empty string to be used to get the host name
	int check = gethostname(name, 100);		//gets the host's name and stores it in the char array variable name
	if(check == -1)
	{
		perror("There was en error with gethostname() ");
	}
	while(!done)		//loop until user enters exit and the loop is terminated
	{
		if((user != NULL) && (check == 0))
		{
			cout << user << "@" << name << " $ ";	//output user name, @ symbol, the host name, followed by $
		}			// output at this point should result in: [user]@[host]$
		else
		{
			cout << "$ ";
		}
		getline(cin, command);	//get the entire line of command from user
		unsigned int loc = command.find_first_of("#");	//keep only everything before the first comment mark
		command = command.substr(0, loc);
		if(command == "exit")
		{
			done = true;	//if the command they type in is initially exit
					//then there is no need to continue traversing the program, simply end
		}
		else
		{
			normalBash(command);
		}
	}
	return 0;
}
<|endoftext|>


<commit_before>//@ {"targets":[{"name":"serializer.hpp","type":"include"}]}

#ifndef TEMPLE_SERIALIZER_HPP
#define TEMPLE_SERIALIZER_HPP

#include "item.hpp"
#include "treenode.hpp"
#include <stack>

namespace Temple
	{
	namespace
		{
		template<class Sink,class Callback>
		class VisitorBase
			{
			public:
				virtual bool atEnd() const noexcept=0;
				virtual void advance() noexcept=0;
				virtual void itemProcess(Callback& cb) const=0;
				virtual ~VisitorBase()=default;
			};

		template<class Sink,class Callback,class Container>
		class Visitor:public VisitorBase<Sink,Callback>
			{
			public:
				explicit Visitor(Container&&)=delete;
				explicit Visitor(const Container& container):
					m_begin(container.begin()),m_current(container.begin()),m_end(container.end())
					{}

				bool atEnd() const noexcept
					{return m_current==m_end;}

				bool atBegin() const noexcept
					{return m_current==m_begin;}

				void advance() noexcept
					{++m_current;}

				void itemProcess(Callback& cb) const
					{cb(*m_current,*this);}

				static auto create(const Container& cnt)
					{
					return std::unique_ptr<VisitorBase<Sink,Callback>>(new Visitor(cnt));
					}

			private:
			typename Container::const_iterator m_begin;
				typename Container::const_iterator m_current;
				typename Container::const_iterator m_end;
			};

		template<class StorageModel,class Sink>
		class Acceptor
			{
			public:
				using MapType=typename StorageModel::template MapType< std::unique_ptr< ItemBase<StorageModel> > > ;
				using CompoundArray=typename StorageModel::template ArrayType<MapType>;

				using VisitorArray=Visitor<Sink,Acceptor,CompoundArray>;
				using VisitorMap=Visitor<Sink,Acceptor,MapType>;

				explicit Acceptor(ItemBase<StorageModel>&&)=delete;

				explicit Acceptor(const ItemBase<StorageModel>& root,Sink& sink):r_sink(sink)
					{
					if(root.array())
						{m_stack.push(VisitorArray::create(root.template value<CompoundArray>() ) );}
					else
						{}
					}

				void run()
					{
					while(!m_stack.empty())
						{
						auto visitor=std::move(m_stack.top());
						m_stack.pop();
						visitor->itemProcess(*this);
						if(!visitor->atEnd())
							{
							visitor->advance();
							m_stack.push(std::move(visitor));
							}
						}
					}

				void operator()(const MapType& node_current,const VisitorArray& visitor)
					{
					if(visitor.atEnd())
						{
						putc(']',r_sink);
						return;
						}

					if(visitor.atBegin())
						{putc('[',r_sink);}

					}

			private:
				Sink& r_sink;
				std::stack< std::unique_ptr< VisitorBase<Sink,Acceptor> > > m_stack;
			};
		}

	template<class StorageModel,class Sink>
	void temple_store(const ItemBase<StorageModel>& root,Sink& sink)
		{Acceptor<StorageModel,Sink>(root,sink).run();}
	}

#endif
<commit_msg>Push map node<commit_after>//@ {"targets":[{"name":"serializer.hpp","type":"include"}]}

#ifndef TEMPLE_SERIALIZER_HPP
#define TEMPLE_SERIALIZER_HPP

#include "item.hpp"
#include "treenode.hpp"
#include <stack>

namespace Temple
	{
	namespace
		{
		template<class Sink,class Callback>
		class VisitorBase
			{
			public:
				virtual bool atEnd() const noexcept=0;
				virtual void advance() noexcept=0;
				virtual void itemProcess(Callback& cb) const=0;
				virtual ~VisitorBase()=default;
			};

		template<class Sink,class Callback,class Container>
		class Visitor:public VisitorBase<Sink,Callback>
			{
			public:
				explicit Visitor(Container&&)=delete;
				explicit Visitor(const Container& container):
					m_begin(container.begin()),m_current(container.begin()),m_end(container.end())
					{}

				bool atEnd() const noexcept
					{return m_current==m_end;}

				bool atBegin() const noexcept
					{return m_current==m_begin;}

				void advance() noexcept
					{++m_current;}

				void itemProcess(Callback& cb) const
					{cb(*m_current,*this);}

				static auto create(const Container& cnt)
					{
					return std::unique_ptr<VisitorBase<Sink,Callback>>(new Visitor(cnt));
					}

			private:
			typename Container::const_iterator m_begin;
				typename Container::const_iterator m_current;
				typename Container::const_iterator m_end;
			};

		template<class StorageModel,class Sink>
		class Acceptor
			{
			public:
				using MapType=typename StorageModel::template MapType< std::unique_ptr< ItemBase<StorageModel> > > ;
				using CompoundArray=typename StorageModel::template ArrayType<MapType>;

				using VisitorArray=Visitor<Sink,Acceptor,CompoundArray>;
				using VisitorMap=Visitor<Sink,Acceptor,MapType>;

				explicit Acceptor(ItemBase<StorageModel>&&)=delete;

				explicit Acceptor(const ItemBase<StorageModel>& root,Sink& sink):r_sink(sink)
					{
					if(root.array())
						{m_stack.push(VisitorArray::create(root.template value<CompoundArray>() ) );}
					else
						{m_stack.push(VisitorMap::create(root.template value<MapType>() ) );}
					}

				void run()
					{
					while(!m_stack.empty())
						{
						auto visitor=std::move(m_stack.top());
						m_stack.pop();
						visitor->itemProcess(*this);
						if(!visitor->atEnd())
							{
							visitor->advance();
							m_stack.push(std::move(visitor));
							}
						}
					}

				void operator()(const MapType& node_current,const VisitorArray& visitor)
					{
					if(visitor.atEnd())
						{
						putc(']',r_sink);
						return;
						}

					if(visitor.atBegin())
						{putc('[',r_sink);}
				//	m_stack.push
					}

			private:
				Sink& r_sink;
				std::stack< std::unique_ptr< VisitorBase<Sink,Acceptor> > > m_stack;
			};
		}

	template<class StorageModel,class Sink>
	void temple_store(const ItemBase<StorageModel>& root,Sink& sink)
		{Acceptor<StorageModel,Sink>(root,sink).run();}
	}

#endif
<|endoftext|>


<commit_before>// null_inst_tests.cc
#include <gtest/gtest.h>

#include "null_inst.h"

#include "context.h"
#include "inst_model_tests.h"
#include "model_tests.h"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class NullInstTest : public ::testing::Test {
 protected:
  virtual void SetUp() {}

  virtual void TearDown() {}
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Model* NullInstModelConstructor(cyclus::Context* ctx) {
  return dynamic_cast<cyclus::Model*>(new cycamore::NullInst(ctx));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::InstModel* NullInstConstructor(cyclus::Context* ctx) {
  return dynamic_cast<cyclus::InstModel*>(new cycamore::NullInst(ctx));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
INSTANTIATE_TEST_CASE_P(NullInst, InstModelTests,
                        Values(&NullInstConstructor));
INSTANTIATE_TEST_CASE_P(NullInst, ModelTests,
                        Values(&NullInstModelConstructor));

<commit_msg>null_inst_tests : sort includes.<commit_after>// null_inst_tests.cc
#include <gtest/gtest.h>

#include "context.h"
#include "inst_model_tests.h"
#include "model_tests.h"
#include "null_inst.h"

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class NullInstTest : public ::testing::Test {
 protected:
  virtual void SetUp() {}

  virtual void TearDown() {}
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::Model* NullInstModelConstructor(cyclus::Context* ctx) {
  return dynamic_cast<cyclus::Model*>(new cycamore::NullInst(ctx));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cyclus::InstModel* NullInstConstructor(cyclus::Context* ctx) {
  return dynamic_cast<cyclus::InstModel*>(new cycamore::NullInst(ctx));
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
INSTANTIATE_TEST_CASE_P(NullInst, InstModelTests,
                        Values(&NullInstConstructor));
INSTANTIATE_TEST_CASE_P(NullInst, ModelTests,
                        Values(&NullInstModelConstructor));

<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SynthGreenPAK4Pass : public ScriptPass
{
	SynthGreenPAK4Pass() : ScriptPass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { }

	virtual void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    synth_greenpak4 [options]\n");
		log("\n");
		log("This command runs synthesis for GreenPAK4 FPGAs. This work is experimental.\n");
		log("\n");
		log("    -top <module>\n");
		log("        use the specified module as top module (default='top')\n");
		log("\n");
		log("    -part <part>\n");
		log("        synthesize for the specified part. Valid values are SLG46140V,\n");
		log("        SLG46620V, and SLG46621V (default).\n");
		log("\n");
		log("    -json <file>\n");
		log("        write the design to the specified JSON file. writing of an output file\n");
		log("        is omitted if this parameter is not specified.\n");
		log("\n");
		log("    -run <from_label>:<to_label>\n");
		log("        only run the commands between the labels (see below). an empty\n");
		log("        from label is synonymous to 'begin', and empty to label is\n");
		log("        synonymous to the end of the command list.\n");
		log("\n");
		log("    -noflatten\n");
		log("        do not flatten design before synthesis\n");
		log("\n");
		log("    -retime\n");
		log("        run 'abc' with -dff option\n");
		log("\n");
		log("\n");
		log("The following commands are executed by this synthesis command:\n");
		help_script();
		log("\n");
	}

	string top_opt, part, json_file;
	bool flatten, retime;

	virtual void clear_flags() YS_OVERRIDE
	{
		top_opt = "-auto-top";
		part = "SLG46621V";
		json_file = "";
		flatten = true;
		retime = false;
	}

	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		string run_from, run_to;
		clear_flags();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-top" && argidx+1 < args.size()) {
				top_opt = "-top " + args[++argidx];
				continue;
			}
			if (args[argidx] == "-json" && argidx+1 < args.size()) {
				json_file = args[++argidx];
				continue;
			}
			if (args[argidx] == "-part" && argidx+1 < args.size()) {
				part = args[++argidx];
				continue;
			}
			if (args[argidx] == "-run" && argidx+1 < args.size()) {
				size_t pos = args[argidx+1].find(':');
				if (pos == std::string::npos)
					break;
				run_from = args[++argidx].substr(0, pos);
				run_to = args[argidx].substr(pos+1);
				continue;
			}
			if (args[argidx] == "-noflatten") {
				flatten = false;
				continue;
			}
			if (args[argidx] == "-retime") {
				retime = true;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (!design->full_selection())
			log_cmd_error("This comannd only operates on fully selected designs!\n");

		if (part != "SLG46140V" && part != "SLG46620V" && part != "SLG46621V")
			log_cmd_error("Invalid part name: '%s'\n", part.c_str());

		log_header(design, "Executing SYNTH_GREENPAK4 pass.\n");
		log_push();

		run_script(design, run_from, run_to);

		log_pop();
	}

	virtual void script() YS_OVERRIDE
	{
		if (check_label("begin"))
		{
			run("read_verilog -lib +/greenpak4/cells_sim.v");
			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
		}

		if (flatten && check_label("flatten", "(unless -noflatten)"))
		{
			run("proc");
			run("flatten");
			run("tribuf -logic");
		}

		if (check_label("coarse"))
		{
			run("synth -run coarse");
		}

		if (check_label("fine"))
		{
			run("greenpak4_counters");
			run("clean");
			run("opt -fast -mux_undef -undriven -fine");
			run("memory_map");
			run("opt -undriven -fine");
			run("techmap");
			run("dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib");
			run("opt -fast");
			if (retime || help_mode)
				run("abc -dff", "(only if -retime)");
		}

		if (check_label("map_luts"))
		{
			if (help_mode || part == "SLG46140V") run("nlutmap -assert -luts 0,6,8,2", " (for -part SLG46140V)");
			if (help_mode || part == "SLG46620V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46620V)");
			if (help_mode || part == "SLG46621V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46621V)");
			run("clean");
		}

		if (check_label("map_cells"))
		{
			run("shregmap -tech greenpak4");
			run("dfflibmap -liberty +/greenpak4/gp_dff.lib");
			run("dffinit -ff GP_DFF Q INIT");
			run("dffinit -ff GP_DFFR Q INIT");
			run("dffinit -ff GP_DFFS Q INIT");
			run("dffinit -ff GP_DFFSR Q INIT");
			run("iopadmap -bits -inpad GP_IBUF OUT:IN -outpad GP_OBUF IN:OUT -inoutpad GP_OBUF OUT:IN -toutpad GP_OBUFT OE:IN:OUT -tinoutpad GP_IOBUF OE:OUT:IN:IO");
			run("techmap -map +/greenpak4/cells_map.v");
			run("clean");
		}

		if (check_label("check"))
		{
			run("hierarchy -check");
			run("stat");
			run("check -noinit");
		}

		if (check_label("json"))
		{
			if (!json_file.empty() || help_mode)
				run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
		}

		log_pop();
	}
} SynthGreenPAK4Pass;

PRIVATE_NAMESPACE_END
<commit_msg>synth_greenpak4: use attrmvcp to move LOC from wires to cells.<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SynthGreenPAK4Pass : public ScriptPass
{
	SynthGreenPAK4Pass() : ScriptPass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { }

	virtual void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    synth_greenpak4 [options]\n");
		log("\n");
		log("This command runs synthesis for GreenPAK4 FPGAs. This work is experimental.\n");
		log("\n");
		log("    -top <module>\n");
		log("        use the specified module as top module (default='top')\n");
		log("\n");
		log("    -part <part>\n");
		log("        synthesize for the specified part. Valid values are SLG46140V,\n");
		log("        SLG46620V, and SLG46621V (default).\n");
		log("\n");
		log("    -json <file>\n");
		log("        write the design to the specified JSON file. writing of an output file\n");
		log("        is omitted if this parameter is not specified.\n");
		log("\n");
		log("    -run <from_label>:<to_label>\n");
		log("        only run the commands between the labels (see below). an empty\n");
		log("        from label is synonymous to 'begin', and empty to label is\n");
		log("        synonymous to the end of the command list.\n");
		log("\n");
		log("    -noflatten\n");
		log("        do not flatten design before synthesis\n");
		log("\n");
		log("    -retime\n");
		log("        run 'abc' with -dff option\n");
		log("\n");
		log("\n");
		log("The following commands are executed by this synthesis command:\n");
		help_script();
		log("\n");
	}

	string top_opt, part, json_file;
	bool flatten, retime;

	virtual void clear_flags() YS_OVERRIDE
	{
		top_opt = "-auto-top";
		part = "SLG46621V";
		json_file = "";
		flatten = true;
		retime = false;
	}

	virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		string run_from, run_to;
		clear_flags();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-top" && argidx+1 < args.size()) {
				top_opt = "-top " + args[++argidx];
				continue;
			}
			if (args[argidx] == "-json" && argidx+1 < args.size()) {
				json_file = args[++argidx];
				continue;
			}
			if (args[argidx] == "-part" && argidx+1 < args.size()) {
				part = args[++argidx];
				continue;
			}
			if (args[argidx] == "-run" && argidx+1 < args.size()) {
				size_t pos = args[argidx+1].find(':');
				if (pos == std::string::npos)
					break;
				run_from = args[++argidx].substr(0, pos);
				run_to = args[argidx].substr(pos+1);
				continue;
			}
			if (args[argidx] == "-noflatten") {
				flatten = false;
				continue;
			}
			if (args[argidx] == "-retime") {
				retime = true;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (!design->full_selection())
			log_cmd_error("This comannd only operates on fully selected designs!\n");

		if (part != "SLG46140V" && part != "SLG46620V" && part != "SLG46621V")
			log_cmd_error("Invalid part name: '%s'\n", part.c_str());

		log_header(design, "Executing SYNTH_GREENPAK4 pass.\n");
		log_push();

		run_script(design, run_from, run_to);

		log_pop();
	}

	virtual void script() YS_OVERRIDE
	{
		if (check_label("begin"))
		{
			run("read_verilog -lib +/greenpak4/cells_sim.v");
			run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
		}

		if (flatten && check_label("flatten", "(unless -noflatten)"))
		{
			run("proc");
			run("flatten");
			run("tribuf -logic");
		}

		if (check_label("coarse"))
		{
			run("synth -run coarse");
		}

		if (check_label("fine"))
		{
			run("greenpak4_counters");
			run("clean");
			run("opt -fast -mux_undef -undriven -fine");
			run("memory_map");
			run("opt -undriven -fine");
			run("techmap");
			run("dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib");
			run("opt -fast");
			if (retime || help_mode)
				run("abc -dff", "(only if -retime)");
		}

		if (check_label("map_luts"))
		{
			if (help_mode || part == "SLG46140V") run("nlutmap -assert -luts 0,6,8,2", " (for -part SLG46140V)");
			if (help_mode || part == "SLG46620V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46620V)");
			if (help_mode || part == "SLG46621V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46621V)");
			run("clean");
		}

		if (check_label("map_cells"))
		{
			run("shregmap -tech greenpak4");
			run("dfflibmap -liberty +/greenpak4/gp_dff.lib");
			run("dffinit -ff GP_DFF Q INIT");
			run("dffinit -ff GP_DFFR Q INIT");
			run("dffinit -ff GP_DFFS Q INIT");
			run("dffinit -ff GP_DFFSR Q INIT");
			run("iopadmap -bits -inpad GP_IBUF OUT:IN -outpad GP_OBUF IN:OUT -inoutpad GP_OBUF OUT:IN -toutpad GP_OBUFT OE:IN:OUT -tinoutpad GP_IOBUF OE:OUT:IN:IO");
			run("attrmvcp -attr src -attr LOC t:GP_OBUF t:GP_OBUFT t:GP_IOBUF n:*");
			run("attrmvcp -attr src -attr LOC -driven t:GP_IBUF n:*");
			run("techmap -map +/greenpak4/cells_map.v");
			run("clean");
		}

		if (check_label("check"))
		{
			run("hierarchy -check");
			run("stat");
			run("check -noinit");
		}

		if (check_label("json"))
		{
			if (!json_file.empty() || help_mode)
				run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
		}

		log_pop();
	}
} SynthGreenPAK4Pass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>//===- WebAssemblyTargetMachine.cpp - Define TargetMachine for WebAssembly -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file defines the WebAssembly-specific subclass of TargetMachine.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyTargetObjectFile.h"
#include "WebAssemblyTargetTransformInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;

#define DEBUG_TYPE "wasm"

extern "C" void LLVMInitializeWebAssemblyTarget() {
  // Register the target.
  RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget32);
  RegisterTargetMachine<WebAssemblyTargetMachine> Y(TheWebAssemblyTarget64);
}

//===----------------------------------------------------------------------===//
// WebAssembly Lowering public interface.
//===----------------------------------------------------------------------===//

/// Create an WebAssembly architecture model.
///
WebAssemblyTargetMachine::WebAssemblyTargetMachine(
    const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
    CodeGenOpt::Level OL)
    : LLVMTargetMachine(T,
                        TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
                                         : "e-m:e-p:32:32-i64:64-n32:64-S128",
                        TT, CPU, FS, Options, RM, CM, OL),
      TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
  // WebAssembly type-checks expressions, but a noreturn function with a return
  // type that doesn't match the context will cause a check failure. So we lower
  // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
  // 'unreachable' expression which is meant for that case.
  this->Options.TrapUnreachable = true;

  initAsmInfo();

  // Note that we don't use setRequiresStructuredCFG(true). It disables
  // optimizations than we're ok with, and want, such as critical edge
  // splitting and tail merging.
}

WebAssemblyTargetMachine::~WebAssemblyTargetMachine() {}

const WebAssemblySubtarget *
WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
                        ? CPUAttr.getValueAsString().str()
                        : TargetCPU;
  std::string FS = !FSAttr.hasAttribute(Attribute::None)
                       ? FSAttr.getValueAsString().str()
                       : TargetFS;

  auto &I = SubtargetMap[CPU + FS];
  if (!I) {
    // This needs to be done before we create a new subtarget since any
    // creation will depend on the TM and the code generation flags on the
    // function that reside in TargetOptions.
    resetTargetOptions(F);
    I = llvm::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
  }
  return I.get();
}

namespace {
/// WebAssembly Code Generator Pass Configuration Options.
class WebAssemblyPassConfig final : public TargetPassConfig {
public:
  WebAssemblyPassConfig(WebAssemblyTargetMachine *TM, PassManagerBase &PM)
      : TargetPassConfig(TM, PM) {}

  WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
    return getTM<WebAssemblyTargetMachine>();
  }

  FunctionPass *createTargetRegisterAllocator(bool) override;

  void addIRPasses() override;
  bool addInstSelector() override;
  bool addILPOpts() override;
  void addPreRegAlloc() override;
  void addPostRegAlloc() override;
  void addPreEmitPass() override;
};
} // end anonymous namespace

TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
  return TargetIRAnalysis([this](const Function &F) {
    return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
  });
}

TargetPassConfig *
WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
  return new WebAssemblyPassConfig(this, PM);
}

FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
  return nullptr; // No reg alloc
}

//===----------------------------------------------------------------------===//
// The following functions are called from lib/CodeGen/Passes.cpp to modify
// the CodeGen pass sequence.
//===----------------------------------------------------------------------===//

void WebAssemblyPassConfig::addIRPasses() {
  if (TM->Options.ThreadModel == ThreadModel::Single)
    // In "single" mode, atomics get lowered to non-atomics.
    addPass(createLowerAtomicPass());
  else
    // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
    // control specifically what gets lowered.
    addPass(createAtomicExpandPass(TM));

  // Optimize "returned" function attributes.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyOptimizeReturned());

  TargetPassConfig::addIRPasses();
}

bool WebAssemblyPassConfig::addInstSelector() {
  (void)TargetPassConfig::addInstSelector();
  addPass(
      createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
  // Run the argument-move pass immediately after the ScheduleDAG scheduler
  // so that we can fix up the ARGUMENT instructions before anything else
  // sees them in the wrong place.
  addPass(createWebAssemblyArgumentMove());
  // Set the p2align operands. This information is present during ISel, however
  // it's inconvenient to collect. Collect it now, and update the immediate
  // operands.
  addPass(createWebAssemblySetP2AlignOperands());
  return false;
}

bool WebAssemblyPassConfig::addILPOpts() {
  (void)TargetPassConfig::addILPOpts();
  return true;
}

void WebAssemblyPassConfig::addPreRegAlloc() {
  TargetPassConfig::addPreRegAlloc();

  // Prepare store instructions for register stackifying.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyStoreResults());
}

void WebAssemblyPassConfig::addPostRegAlloc() {
  // TODO: The following CodeGen passes don't currently support code containing
  // virtual registers. Consider removing their restrictions and re-enabling
  // them.
  //
  // We use our own PrologEpilogInserter which is very slightly modified to
  // tolerate virtual registers.
  disablePass(&PrologEpilogCodeInserterID);
  // Fails with: should be run after register allocation.
  disablePass(&MachineCopyPropagationID);
  disablePass(&TailDuplicateID);

  if (getOptLevel() != CodeGenOpt::None) {
    // Mark registers as representing wasm's expression stack.
    addPass(createWebAssemblyRegStackify());

    // Run the register coloring pass to reduce the total number of registers.
    addPass(createWebAssemblyRegColoring());
  }

  TargetPassConfig::addPostRegAlloc();

  // Run WebAssembly's version of the PrologEpilogInserter. Target-independent
  // PEI runs after PostRegAlloc and after ShrinkWrap. Putting it here will run
  // PEI before ShrinkWrap but otherwise in the same position in the order.
  addPass(createWebAssemblyPEI());
}

void WebAssemblyPassConfig::addPreEmitPass() {
  TargetPassConfig::addPreEmitPass();

  // Put the CFG in structured form; insert BLOCK and LOOP markers.
  addPass(createWebAssemblyCFGStackify());

  // Lower br_unless into br_if.
  addPass(createWebAssemblyLowerBrUnless());

  // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
  addPass(createWebAssemblyRegNumbering());

  // Perform the very last peephole optimizations on the code.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyPeephole());
}
<commit_msg>[WebAssembly] Re-enable the TailDuplicate pass.<commit_after>//===- WebAssemblyTargetMachine.cpp - Define TargetMachine for WebAssembly -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file defines the WebAssembly-specific subclass of TargetMachine.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblyTargetMachine.h"
#include "WebAssemblyTargetObjectFile.h"
#include "WebAssemblyTargetTransformInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;

#define DEBUG_TYPE "wasm"

extern "C" void LLVMInitializeWebAssemblyTarget() {
  // Register the target.
  RegisterTargetMachine<WebAssemblyTargetMachine> X(TheWebAssemblyTarget32);
  RegisterTargetMachine<WebAssemblyTargetMachine> Y(TheWebAssemblyTarget64);
}

//===----------------------------------------------------------------------===//
// WebAssembly Lowering public interface.
//===----------------------------------------------------------------------===//

/// Create an WebAssembly architecture model.
///
WebAssemblyTargetMachine::WebAssemblyTargetMachine(
    const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
    CodeGenOpt::Level OL)
    : LLVMTargetMachine(T,
                        TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
                                         : "e-m:e-p:32:32-i64:64-n32:64-S128",
                        TT, CPU, FS, Options, RM, CM, OL),
      TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
  // WebAssembly type-checks expressions, but a noreturn function with a return
  // type that doesn't match the context will cause a check failure. So we lower
  // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
  // 'unreachable' expression which is meant for that case.
  this->Options.TrapUnreachable = true;

  initAsmInfo();

  // Note that we don't use setRequiresStructuredCFG(true). It disables
  // optimizations than we're ok with, and want, such as critical edge
  // splitting and tail merging.
}

WebAssemblyTargetMachine::~WebAssemblyTargetMachine() {}

const WebAssemblySubtarget *
WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
                        ? CPUAttr.getValueAsString().str()
                        : TargetCPU;
  std::string FS = !FSAttr.hasAttribute(Attribute::None)
                       ? FSAttr.getValueAsString().str()
                       : TargetFS;

  auto &I = SubtargetMap[CPU + FS];
  if (!I) {
    // This needs to be done before we create a new subtarget since any
    // creation will depend on the TM and the code generation flags on the
    // function that reside in TargetOptions.
    resetTargetOptions(F);
    I = llvm::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this);
  }
  return I.get();
}

namespace {
/// WebAssembly Code Generator Pass Configuration Options.
class WebAssemblyPassConfig final : public TargetPassConfig {
public:
  WebAssemblyPassConfig(WebAssemblyTargetMachine *TM, PassManagerBase &PM)
      : TargetPassConfig(TM, PM) {}

  WebAssemblyTargetMachine &getWebAssemblyTargetMachine() const {
    return getTM<WebAssemblyTargetMachine>();
  }

  FunctionPass *createTargetRegisterAllocator(bool) override;

  void addIRPasses() override;
  bool addInstSelector() override;
  bool addILPOpts() override;
  void addPreRegAlloc() override;
  void addPostRegAlloc() override;
  void addPreEmitPass() override;
};
} // end anonymous namespace

TargetIRAnalysis WebAssemblyTargetMachine::getTargetIRAnalysis() {
  return TargetIRAnalysis([this](const Function &F) {
    return TargetTransformInfo(WebAssemblyTTIImpl(this, F));
  });
}

TargetPassConfig *
WebAssemblyTargetMachine::createPassConfig(PassManagerBase &PM) {
  return new WebAssemblyPassConfig(this, PM);
}

FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) {
  return nullptr; // No reg alloc
}

//===----------------------------------------------------------------------===//
// The following functions are called from lib/CodeGen/Passes.cpp to modify
// the CodeGen pass sequence.
//===----------------------------------------------------------------------===//

void WebAssemblyPassConfig::addIRPasses() {
  if (TM->Options.ThreadModel == ThreadModel::Single)
    // In "single" mode, atomics get lowered to non-atomics.
    addPass(createLowerAtomicPass());
  else
    // Expand some atomic operations. WebAssemblyTargetLowering has hooks which
    // control specifically what gets lowered.
    addPass(createAtomicExpandPass(TM));

  // Optimize "returned" function attributes.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyOptimizeReturned());

  TargetPassConfig::addIRPasses();
}

bool WebAssemblyPassConfig::addInstSelector() {
  (void)TargetPassConfig::addInstSelector();
  addPass(
      createWebAssemblyISelDag(getWebAssemblyTargetMachine(), getOptLevel()));
  // Run the argument-move pass immediately after the ScheduleDAG scheduler
  // so that we can fix up the ARGUMENT instructions before anything else
  // sees them in the wrong place.
  addPass(createWebAssemblyArgumentMove());
  // Set the p2align operands. This information is present during ISel, however
  // it's inconvenient to collect. Collect it now, and update the immediate
  // operands.
  addPass(createWebAssemblySetP2AlignOperands());
  return false;
}

bool WebAssemblyPassConfig::addILPOpts() {
  (void)TargetPassConfig::addILPOpts();
  return true;
}

void WebAssemblyPassConfig::addPreRegAlloc() {
  TargetPassConfig::addPreRegAlloc();

  // Prepare store instructions for register stackifying.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyStoreResults());
}

void WebAssemblyPassConfig::addPostRegAlloc() {
  // TODO: The following CodeGen passes don't currently support code containing
  // virtual registers. Consider removing their restrictions and re-enabling
  // them.
  //
  // We use our own PrologEpilogInserter which is very slightly modified to
  // tolerate virtual registers.
  disablePass(&PrologEpilogCodeInserterID);
  // Fails with: should be run after register allocation.
  disablePass(&MachineCopyPropagationID);

  if (getOptLevel() != CodeGenOpt::None) {
    // Mark registers as representing wasm's expression stack.
    addPass(createWebAssemblyRegStackify());

    // Run the register coloring pass to reduce the total number of registers.
    addPass(createWebAssemblyRegColoring());
  }

  TargetPassConfig::addPostRegAlloc();

  // Run WebAssembly's version of the PrologEpilogInserter. Target-independent
  // PEI runs after PostRegAlloc and after ShrinkWrap. Putting it here will run
  // PEI before ShrinkWrap but otherwise in the same position in the order.
  addPass(createWebAssemblyPEI());
}

void WebAssemblyPassConfig::addPreEmitPass() {
  TargetPassConfig::addPreEmitPass();

  // Put the CFG in structured form; insert BLOCK and LOOP markers.
  addPass(createWebAssemblyCFGStackify());

  // Lower br_unless into br_if.
  addPass(createWebAssemblyLowerBrUnless());

  // Create a mapping from LLVM CodeGen virtual registers to wasm registers.
  addPass(createWebAssemblyRegNumbering());

  // Perform the very last peephole optimizations on the code.
  if (getOptLevel() != CodeGenOpt::None)
    addPass(createWebAssemblyPeephole());
}
<|endoftext|>


<commit_before>/*
    Dynamics/Kinematics modeling and simulation library.
    Copyright (C) 1999 by Michael Alexander Ewert

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "cssysdef.h"
#include "csphyzik/forces.h"
#include "csphyzik/phyzent.h"
#include "csphyzik/refframe.h"
#include "csphyzik/debug.h"

ctGravityF::ctGravityF ( real pg, ctVector3 pd )
{
  magnitude = pg, direction = pd;
}

ctGravityF::ctGravityF ( ctReferenceFrame &rf, real pg, ctVector3 pd )
  : ctForce( rf )
{
  magnitude = pg, direction = pd;
}

ctVector3 ctGravityF::apply_F ( ctDynamicEntity &pe )
{
  // F = mg
  ctVector3 f = direction * magnitude * pe.get_m ();
  pe.sum_force ( f );
  return f;
}

ctAirResistanceF::ctAirResistanceF ( real pk )
{
  magnitude = -pk;
}

ctVector3 ctAirResistanceF::apply_F ( ctDynamicEntity &pe )
{
  ctVector3 lf = (pe.get_v ()) * magnitude;
  pe.sum_force ( lf );
//    ctVector3 af = (pe.get_angular_v ()) * magnitude/5;
//    pe.sum_torque ( af );
  return lf;

}

ctAppliedF::ctAppliedF ( ctVector3 dir, real pm )
{
  magnitude = pm;
  direction = dir.Unit();
}

ctVector3 ctAppliedF::apply_F ( ctDynamicEntity &pe )
{
  pe.sum_force ( direction * magnitude );
  return direction*magnitude;
}

ctTorqueF::ctTorqueF( ctVector3 dir, real pm )
{
  magnitude = pm;
  direction = dir.Unit();
}

ctVector3 ctTorqueF::apply_F( ctDynamicEntity &pe )
{
  pe.sum_torque ( direction*magnitude );
  return direction*magnitude;
}

ctVector3 ctSpringF::apply_F( ctDynamicEntity &pe )
{
  ctVector3 f;
  ctVector3 d;
  ctVector3 a1;
  ctVector3 a2;

  if ( body_vector.get_size() == 2 &&
       attachment_point_vector.get_size() == 2 )
  {
    ctPhysicalEntity *b1 = body_vector.get_first();
    ctPhysicalEntity *b2 = body_vector.get_next();

    ctVector3 *orig_a1 = attachment_point_vector.get_first();
    ctVector3 *orig_a2 = attachment_point_vector.get_next();

    if ( b1 && orig_a1 && orig_a2 )
    {
      ctReferenceFrame *r1 = b1->get_RF();
      ctReferenceFrame *r2 = ( b2 == NULL ) ?
	&(ctReferenceFrame::universe()) : b2->get_RF();

      if ( r1 && r2 )
      {
	r1->this_to_world( a1, *orig_a1 );
	r2->this_to_world( a2, *orig_a2 );

	if ( &pe == b1 )
	  d = a2 - a1;
	else if( &pe == b2 )
	  d = a1 - a2;
	else
	{
	  log( "ctSpringF: body applied not part of coupling\n" );
	  return ctVector3(0,0,0);
	}

	//!me maybe don't need to normalize and find unit vector
	//!me I think that d.Norm() and later mult d by disp divides out to 1
	real disp = d.Norm() - rest_length;
	if ( d*d > MIN_REAL ) // avoid divide by zero
	  d = d.Unit();
	else
	  d = ctVector3(1, 0,0 );

	// f = -kx
	f = d*disp*magnitude;

	if ( &pe == b1 )
	{
	  b1->sum_force(f);
	  d = a1 - r1->get_world_offset ();
	  b1->sum_torque ( d % f );
	}
	else if ( &pe == b2 && b2 != NULL )
	{
	  b2->sum_force (f);
	  d = a2 - r2->get_world_offset ();
	  b2->sum_torque ( d % f );
	}
	return f;
      }
    }
  }
  return f;
}

//!me untested
// 1/r^2 force.  Such as gravity.
// right now an object passing too close to the discontinuity will get accelerated
// way fast and energy will NOT be conserved.  This could be fixed using R-K
// method with adaptive step-sizing or some happy horse-shit like that.
ctVector3 ctGravityWell::apply_F ( ctDynamicEntity &moon )
{
  double g_force;
  ctVector3 r_vec;
  ctVector3 total_f ( 0.0,0.0,0.0 );
  ctVector3 planet_x;
  ctVector3 moon_x;
  double r_len2;
  ctPhysicalEntity *planet;

  planet = body_vector.get_first ();
  while ( planet != NULL )
  {
    if ( planet != &moon )
    {
      planet_x = planet->get_pos ();
      moon_x = moon.get_pos ();

      r_vec = moon_x - planet_x;

      r_len2 = r_vec * r_vec;

      r_vec.Normalize ();
      if ( r_len2 < MIN_REAL )
	r_len2 = MIN_REAL; //!me maybe have a max accel limit instead?

      g_force = ( magnitude * (( ctDynamicEntity * )planet)->get_m() ) * moon.get_m () / r_len2;
      r_vec *= g_force;
      moon.sum_force ( r_vec );
      total_f += r_vec;
    }
    planet = body_vector.get_next ();
  }
  return total_f;
}
<commit_msg>a new force by Anders Stenberg (Dentoid)<commit_after>/*
    Dynamics/Kinematics modeling and simulation library.
    Copyright (C) 1999 by Michael Alexander Ewert
                  2001 Anders Stenberg

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "cssysdef.h"
#include "csphyzik/forces.h"
#include "csphyzik/phyzent.h"
#include "csphyzik/refframe.h"
#include "csphyzik/debug.h"

ctGravityF::ctGravityF ( real pg, ctVector3 pd )
{
  magnitude = pg, direction = pd;
}

ctGravityF::ctGravityF ( ctReferenceFrame &rf, real pg, ctVector3 pd )
  : ctForce( rf )
{
  magnitude = pg, direction = pd;
}

ctVector3 ctGravityF::apply_F ( ctDynamicEntity &pe )
{
  // F = mg
  ctVector3 f = direction * magnitude * pe.get_m ();
  pe.sum_force ( f );
  return f;
}

ctAirResistanceF::ctAirResistanceF ( real pk )
{
  magnitude = -pk;
}

ctVector3 ctAirResistanceF::apply_F ( ctDynamicEntity &pe )
{
  ctVector3 lf = (pe.get_v ()) * magnitude;
  pe.sum_force ( lf );
//    ctVector3 af = (pe.get_angular_v ()) * magnitude/5;
//    pe.sum_torque ( af );
  return lf;

}

ctAppliedF::ctAppliedF ( ctVector3 dir, real pm )
{
  magnitude = pm;
  direction = dir.Unit();
}

ctVector3 ctAppliedF::apply_F ( ctDynamicEntity &pe )
{
  pe.sum_force ( direction * magnitude );
  return direction*magnitude;
}

ctTorqueF::ctTorqueF( ctVector3 dir, real pm )
{
  magnitude = pm;
  direction = dir.Unit();
}

ctVector3 ctTorqueF::apply_F( ctDynamicEntity &pe )
{
  pe.sum_torque ( direction*magnitude );
  return direction*magnitude;
}

ctVector3 ctSpringF::apply_F( ctDynamicEntity &pe )
{
  ctVector3 f;
  ctVector3 d;
  ctVector3 a1;
  ctVector3 a2;

  if ( body_vector.get_size() == 2 &&
       attachment_point_vector.get_size() == 2 )
  {
    ctPhysicalEntity *b1 = body_vector.get_first();
    ctPhysicalEntity *b2 = body_vector.get_next();

    ctVector3 *orig_a1 = attachment_point_vector.get_first();
    ctVector3 *orig_a2 = attachment_point_vector.get_next();

    if ( b1 && orig_a1 && orig_a2 )
    {
      ctReferenceFrame *r1 = b1->get_RF();
      ctReferenceFrame *r2 = ( b2 == NULL ) ?
	&(ctReferenceFrame::universe()) : b2->get_RF();

      if ( r1 && r2 )
      {
	r1->this_to_world( a1, *orig_a1 );
	r2->this_to_world( a2, *orig_a2 );

	if ( &pe == b1 )
	  d = a2 - a1;
	else if( &pe == b2 )
	  d = a1 - a2;
	else
	{
	  log( "ctSpringF: body applied not part of coupling\n" );
	  return ctVector3(0,0,0);
	}

	//!me maybe don't need to normalize and find unit vector
	//!me I think that d.Norm() and later mult d by disp divides out to 1
	real disp = d.Norm() - rest_length;
	if ( d*d > MIN_REAL ) // avoid divide by zero
	  d = d.Unit();
	else
	  d = ctVector3(1, 0,0 );

	// f = -kx
	f = d*disp*magnitude;

	if ( &pe == b1 )
	{
	  b1->sum_force(f);
	  d = a1 - r1->get_world_offset ();
	  b1->sum_torque ( d % f );
	}
	else if ( &pe == b2 && b2 != NULL )
	{
	  b2->sum_force (f);
	  d = a2 - r2->get_world_offset ();
	  b2->sum_torque ( d % f );
	}
	return f;
      }
    }
  }
  return f;
}

ctVector3 ctCappedSpringF::apply_F( ctDynamicEntity &pe )
{
  ctVector3 f;
  ctVector3 d;
  ctVector3 a1;
  ctVector3 a2;

  if ( body_vector.get_size() == 2 &&
       attachment_point_vector.get_size() == 2 )
  {
    ctPhysicalEntity *b1 = body_vector.get_first();
    ctPhysicalEntity *b2 = body_vector.get_next();

    ctVector3 *orig_a1 = attachment_point_vector.get_first();
    ctVector3 *orig_a2 = attachment_point_vector.get_next();

    if ( b1 && orig_a1 && orig_a2 )
    {
      ctReferenceFrame *r1 = b1->get_RF();
      ctReferenceFrame *r2 = ( b2 == NULL ) ?
	&(ctReferenceFrame::universe()) : b2->get_RF();

      if ( r1 && r2 )
      {
	r1->this_to_world( a1, *orig_a1 );
	r2->this_to_world( a2, *orig_a2 );

	if ( &pe == b1 )
	  d = a2 - a1;
	else if( &pe == b2 )
	  d = a1 - a2;
	else
	{
	  log( "ctSpringF: body applied not part of coupling\n" );
	  return ctVector3(0,0,0);
	}

	//!me maybe don't need to normalize and find unit vector
	//!me I think that d.Norm() and later mult d by disp divides out to 1
	real dist = d.Norm();
	real disp = 0;
	if ( dist>cap_max ) disp = dist-cap_max;
	else if ( dist<cap_min ) disp = cap_min-dist;
	if ( d*d > MIN_REAL ) // avoid divide by zero
	  d = d.Unit();
	else
	  d = ctVector3(1, 0,0 );

	// f = -kx
	f = d*disp*magnitude;

	if ( &pe == b1 )
	{
	  b1->sum_force(f);
	  d = a1 - r1->get_world_offset ();
	  b1->sum_torque ( d % f );
	}
	else if ( &pe == b2 && b2 != NULL )
	{
	  b2->sum_force (f);
	  d = a2 - r2->get_world_offset ();
	  b2->sum_torque ( d % f );
	}
	return f;
      }
    }
  }
  return f;
}

//!me untested
// 1/r^2 force.  Such as gravity.
// right now an object passing too close to the discontinuity will get accelerated
// way fast and energy will NOT be conserved.  This could be fixed using R-K
// method with adaptive step-sizing or some happy horse-shit like that.
ctVector3 ctGravityWell::apply_F ( ctDynamicEntity &moon )
{
  double g_force;
  ctVector3 r_vec;
  ctVector3 total_f ( 0.0,0.0,0.0 );
  ctVector3 planet_x;
  ctVector3 moon_x;
  double r_len2;
  ctPhysicalEntity *planet;

  planet = body_vector.get_first ();
  while ( planet != NULL )
  {
    if ( planet != &moon )
    {
      planet_x = planet->get_pos ();
      moon_x = moon.get_pos ();

      r_vec = moon_x - planet_x;

      r_len2 = r_vec * r_vec;

      r_vec.Normalize ();
      if ( r_len2 < MIN_REAL )
	r_len2 = MIN_REAL; //!me maybe have a max accel limit instead?

      g_force = ( magnitude * (( ctDynamicEntity * )planet)->get_m() ) * moon.get_m () / r_len2;
      r_vec *= g_force;
      moon.sum_force ( r_vec );
      total_f += r_vec;
    }
    planet = body_vector.get_next ();
  }
  return total_f;
}
<|endoftext|>


<commit_before>/*
    Copyright 2002-2013 CEA LIST

    This file is part of LIMA.

    LIMA 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.

    LIMA 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 LIMA.  If not, see <http://www.gnu.org/licenses/>
*/
/***************************************************************************
 *   Copyright (C) 2003 by  CEA                                            *
 *   author Olivier MESNARD olivier.mesnard@cea.fr                         *
 *                                                                         *
 *  Compact dictionnary based on finite state automata implemented with    *
 *  Boost Graph library.                                                   *
 *  Algorithm is described in article from Daciuk, Mihov, Watson & Watson: *
 *  "Incremental Construction of Minimal Acyclic Finite State Automata"    *
 ***************************************************************************/

namespace Lima {
namespace Common {
namespace StringMap {

template <typename accessMethod, typename contentElement, typename storedSet>
SimpleDataDico<accessMethod, contentElement, storedSet>::SimpleDataDico( const contentElement& defaultValue )
//    : StringMap<accessMethod, contentElement, storedSet>( defaultValue ) {
    : StringMap<accessMethod, contentElement>( defaultValue ) {
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  LDEBUG <<  "SimpleDataDico::SimpleDataDico()";
#endif
}

template <typename accessMethod, typename contentElement, typename storedSet>
void SimpleDataDico<accessMethod, contentElement, storedSet>::parseData( const std::string& dataFileName )
{
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  LDEBUG << "SimpleDataDico::parseData(" << dataFileName;
#endif

  std::ifstream is(dataFileName.c_str(), std::ios::binary );
  if( is.bad() ) {
    std::string mess = "SimpleDataDico::parseData: Can't open file " + dataFileName;
#ifdef DEBUG_CD
    LERROR << mess;
#endif
    throw( Lima::IncompleteResources(mess) );
  }
  copy(std::istream_iterator<contentElement>(is), std::istream_iterator<contentElement>(),
    back_inserter(m_data));
  uint64_t dataSize = m_data.size();
#ifdef DEBUG_CD
  LDEBUG << "SimpleDataDico::parseData: read " << dataSize
            << " pieces of data from " << dataFileName;
#endif
  if( StringMap<accessMethod, contentElement>::m_accessMethod.getSize() != dataSize ) {
    std::ostringstream oss;
    oss << "SimpleDataDico::parseData dataSize = " << dataSize
        << " != accessSize = " << StringMap<accessMethod, contentElement>::m_accessMethod.getSize();
#ifdef DEBUG_CD
    LERROR << oss.str();
#endif
    throw( Lima::IncompleteResources(oss.str()) );
  }
}

// Gets the dictionary entry correponding to the specified word.
// If word is not into dictionary, m_emptyElement is returned.
template <typename accessMethod, typename contentElement, typename storedSet>
const contentElement& SimpleDataDico<accessMethod, contentElement, storedSet>::getElement(
const Lima::LimaString& word) const{
  uint64_t index = -1;
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  const Lima::LimaString & basicWord = word;
  LDEBUG <<  "SimpleDataDico::getElement("
            << Lima::Common::Misc::convertString(basicWord) << ")";
#endif

  // Look in FsaDictionary (or tree or..)
  index = StringMap<accessMethod, contentElement>::m_accessMethod.getIndex(word);
#ifdef DEBUG_CD
  LDEBUG <<  "index = " << index;
#endif
  if( index > 0 )
    return m_data[index];
  else
    return StringMap<accessMethod, contentElement>::m_emptyElement;
}

} // namespace StringMap
} // namespace Commmon
} // namespace Lima
<commit_msg>Correct a compile error<commit_after>/*
    Copyright 2002-2013 CEA LIST

    This file is part of LIMA.

    LIMA 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.

    LIMA 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 LIMA.  If not, see <http://www.gnu.org/licenses/>
*/
/***************************************************************************
 *   Copyright (C) 2003 by  CEA                                            *
 *   author Olivier MESNARD olivier.mesnard@cea.fr                         *
 *                                                                         *
 *  Compact dictionnary based on finite state automata implemented with    *
 *  Boost Graph library.                                                   *
 *  Algorithm is described in article from Daciuk, Mihov, Watson & Watson: *
 *  "Incremental Construction of Minimal Acyclic Finite State Automata"    *
 ***************************************************************************/

namespace Lima {
namespace Common {
namespace StringMap {

template <typename accessMethod, typename contentElement, typename storedSet>
SimpleDataDico<accessMethod, contentElement, storedSet>::SimpleDataDico( const contentElement& defaultValue )
//    : StringMap<accessMethod, contentElement, storedSet>( defaultValue ) {
    : StringMap<accessMethod, contentElement>( defaultValue ) {
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  LDEBUG <<  "SimpleDataDico::SimpleDataDico()";
#endif
}

template <typename accessMethod, typename contentElement, typename storedSet>
void SimpleDataDico<accessMethod, contentElement, storedSet>::parseData( const std::string& dataFileName )
{
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  LDEBUG << "SimpleDataDico::parseData(" << dataFileName;
#endif

  std::ifstream is(dataFileName.c_str(), std::ios::binary );
  if( is.bad() ) {
    std::string mess = "SimpleDataDico::parseData: Can't open file " + dataFileName;
#ifdef DEBUG_CD
    LERROR << mess;
#endif
    throw( Lima::IncompleteResources(mess) );
  }
  copy(std::istream_iterator<contentElement>(is), std::istream_iterator<contentElement>(),
    back_inserter(m_data));
  uint64_t dataSize = m_data.size();
#ifdef DEBUG_CD
  LDEBUG << "SimpleDataDico::parseData: read " << dataSize
            << " pieces of data from " << dataFileName;
#endif
  if( StringMap<accessMethod, contentElement>::m_accessMethod.getSize() != dataSize ) {
    std::ostringstream oss;
    oss << "SimpleDataDico::parseData dataSize = " << dataSize
        << " != accessSize = " << StringMap<accessMethod, contentElement>::m_accessMethod.getSize();
#ifdef DEBUG_CD
    LERROR << oss.str();
#endif
    throw( Lima::IncompleteResources(oss.str()) );
  }
}

// Gets the dictionary entry correponding to the specified word.
// If word is not into dictionary, m_emptyElement is returned.
template <typename accessMethod, typename contentElement, typename storedSet>
const contentElement& SimpleDataDico<accessMethod, contentElement, storedSet>::getElement(
const Lima::LimaString& word) const{
  uint64_t index = -1;
#ifdef DEBUG_CD
  STRINGMAPLOGINIT;
  const Lima::LimaString & basicWord = word;
  LDEBUG <<  "SimpleDataDico::getElement(" << basicWord << ")";
#endif

  // Look in FsaDictionary (or tree or..)
  index = StringMap<accessMethod, contentElement>::m_accessMethod.getIndex(word);
#ifdef DEBUG_CD
  LDEBUG <<  "index = " << index;
#endif
  if( index > 0 )
    return m_data[index];
  else
    return StringMap<accessMethod, contentElement>::m_emptyElement;
}

} // namespace StringMap
} // namespace Commmon
} // namespace Lima
<|endoftext|>


<commit_before>#include <SDL2/SDL.h>
#include <engine/input/InputController.h>
#include <engine/core/Utils.hpp>
#include <externals/box2d/Box2D/Box2D/Dynamics/b2World.h>
#include "game/Game.h"
#include "engine/input/Keyboard.h"
#include "globals.h"
#include "engine/2d_map/Map.h"

Game::Game() {
    SDL_Init(SDL_INIT_EVERYTHING);
    this->_eventsManager = new EventsManager();

    b2World *world = new b2World(b2Vec2(float32(0), float32(10)));
    this->gameLoop();
}

Game::~Game() {
    delete(this->_eventsManager);
}

void Game::gameLoop() {
    Graphics graphics = Graphics("Game", globals::SCREEN_WIDTH, globals::SCREEN_HEIGHT);
    Keyboard input;
    SDL_Event event;

    InputController *inputController = new InputController();

    _map = new Map(graphics);
    _map->loadFromJSON("resources/maps", "test.json");
    _map->setOffset({0,0});

    _player = new Player(graphics, inputController, 0);
    _player->setPosition(120, 200);

    long time_accumulator = 0;
    float game_speed = 1.0f;

    long prev_time = SDL_GetTicks();
    while (true) {
        input.beginNewFrame();

        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_KEYDOWN) {
                if (event.key.repeat == 0) {
                    input.keyDownEvent(event);
                }
            }// if a key was released
            else if (event.type == SDL_KEYUP) {
                input.keyUpEvent(event);
            }//if the user hits the exit button
            else if (event.type == SDL_QUIT) {
                break;
            } else {
                _eventsManager->add_frame_event(event);
            }
        }

        inputController->process_frame_events(_eventsManager->get_frame_events());

        if (input.wasKeyPressed(SDL_SCANCODE_ESCAPE)) {
            break;
        }

        long elapsed_time = SDL_GetTicks() - prev_time;
//        time_accumulator += elapsed_time;
        if (elapsed_time >= globals::FRAME_TIME) {
            game_speed = elapsed_time / float(globals::FRAME_TIME);
//            SDL_Log("elapsed:%d speed:%f", elapsed_time, game_speed);
//            time_accumulator -= globals::FRAME_TIME;
            this->update(game_speed);
            this->draw(graphics);
            this->_eventsManager->clear_events();
            prev_time = SDL_GetTicks();
        }
    }

    SDL_Quit();
}

void Game::draw(Graphics &graphics) {
    graphics.clear(40, 150, 70, 255);
    _map->draw();

    SDL_SetRenderDrawColor(graphics.getRenderer(), 0,0,0,255);
//    SDL_RenderDrawLine(graphics.getRenderer(), 0, 200, 500, 200);
//    SDL_RenderDrawLine(graphics.getRenderer(), 120, 0, 120, 200);

    _player->draw(graphics);

    graphics.flip();
}

static int pos = 0;

void Game::update(float game_speed) {
//    pos += 1 * game_speed;
//    _map->setOffset({0,0});

    _player->handleInput(game_speed);
    _player->update(game_speed);
}

<commit_msg>Clear events outside of the drawing block. This was causing a bug<commit_after>#include <SDL2/SDL.h>
#include <engine/input/InputController.h>
#include <engine/core/Utils.hpp>
#include <externals/box2d/Box2D/Box2D/Dynamics/b2World.h>
#include "game/Game.h"
#include "engine/input/Keyboard.h"
#include "globals.h"
#include "engine/2d_map/Map.h"

Game::Game() {
    SDL_Init(SDL_INIT_EVERYTHING);
    this->_eventsManager = new EventsManager();

    b2World *world = new b2World(b2Vec2(float32(0), float32(10)));
    this->gameLoop();
}

Game::~Game() {
    delete(this->_eventsManager);
}

void Game::gameLoop() {
    Graphics graphics = Graphics("Game", globals::SCREEN_WIDTH, globals::SCREEN_HEIGHT);
    Keyboard input;
    SDL_Event event;

    InputController *inputController = new InputController();

    _map = new Map(graphics);
    _map->loadFromJSON("resources/maps", "test.json");
    _map->setOffset({0,0});

    _player = new Player(graphics, inputController, 0);
    _player->setPosition(120, 200);

    long time_accumulator = 0;
    float game_speed = 1.0f;

    long prev_time = SDL_GetTicks();
    while (true) {
        input.beginNewFrame();

        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_KEYDOWN) {
                if (event.key.repeat == 0) {
                    input.keyDownEvent(event);
                }
            }// if a key was released
            else if (event.type == SDL_KEYUP) {
                input.keyUpEvent(event);
            }//if the user hits the exit button
            else if (event.type == SDL_QUIT) {
                break;
            } else {
                _eventsManager->add_frame_event(event);
            }
        }

        inputController->process_frame_events(_eventsManager->get_frame_events());

        if (input.wasKeyPressed(SDL_SCANCODE_ESCAPE)) {
            break;
        }

        long elapsed_time = SDL_GetTicks() - prev_time;
//        time_accumulator += elapsed_time;
        if (elapsed_time >= globals::FRAME_TIME) {
            game_speed = elapsed_time / float(globals::FRAME_TIME);
//            SDL_Log("elapsed:%d speed:%f", elapsed_time, game_speed);
//            time_accumulator -= globals::FRAME_TIME;
            this->update(game_speed);
            this->draw(graphics);
            prev_time = SDL_GetTicks();
        }
        this->_eventsManager->clear_events();
    }

    SDL_Quit();
}

void Game::draw(Graphics &graphics) {
    graphics.clear(40, 150, 70, 255);
    _map->draw();

    SDL_SetRenderDrawColor(graphics.getRenderer(), 0,0,0,255);
//    SDL_RenderDrawLine(graphics.getRenderer(), 0, 200, 500, 200);
//    SDL_RenderDrawLine(graphics.getRenderer(), 120, 0, 120, 200);

    _player->draw(graphics);

    graphics.flip();
}

static int pos = 0;

void Game::update(float game_speed) {
//    pos += 1 * game_speed;
//    _map->setOffset({0,0});

    _player->handleInput(game_speed);
    _player->update(game_speed);
}

<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/app_modal_dialog_queue.h"

#include "chrome/browser/browser_list.h"

// static
std::queue<views::AppModalDialogDelegate*>*
    AppModalDialogQueue::app_modal_dialog_queue_ = NULL;
views::AppModalDialogDelegate* AppModalDialogQueue::active_dialog_ = NULL;

// static
void AppModalDialogQueue::AddDialog(views::AppModalDialogDelegate* dialog) {
  DCHECK(dialog->IsModal());
  if (!app_modal_dialog_queue_) {
    app_modal_dialog_queue_ = new std::queue<views::AppModalDialogDelegate*>;
    ShowModalDialog(dialog);
  }

  app_modal_dialog_queue_->push(dialog);
}

// static
void AppModalDialogQueue::ShowNextDialog() {
  app_modal_dialog_queue_->pop();
  active_dialog_ = NULL;
  if (!app_modal_dialog_queue_->empty()) {
    ShowModalDialog(app_modal_dialog_queue_->front());
  } else {
    delete app_modal_dialog_queue_;
    app_modal_dialog_queue_ = NULL;
  }
}

// static
void AppModalDialogQueue::ActivateModalDialog() {
  if (!app_modal_dialog_queue_->empty())
    app_modal_dialog_queue_->front()->ActivateModalDialog();
}

// static
void AppModalDialogQueue::ShowModalDialog(
    views::AppModalDialogDelegate* dialog) {
  dialog->ShowModalDialog();
  active_dialog_ = dialog;
}
<commit_msg>Fix a couple of (likely rare) crashers that can happen if a tab is closed right as it's about to display a JS modal dialog.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/app_modal_dialog_queue.h"

#include "chrome/browser/browser_list.h"

// static
std::queue<views::AppModalDialogDelegate*>*
    AppModalDialogQueue::app_modal_dialog_queue_ = NULL;
views::AppModalDialogDelegate* AppModalDialogQueue::active_dialog_ = NULL;

// static
void AppModalDialogQueue::AddDialog(views::AppModalDialogDelegate* dialog) {
  DCHECK(dialog->IsModal());
  if (!app_modal_dialog_queue_) {
    app_modal_dialog_queue_ = new std::queue<views::AppModalDialogDelegate*>;
    ShowModalDialog(dialog);
  }

  // ShowModalDialog can wind up calling ShowNextDialog in some cases, which
  // can then make app_modal_dialog_queue_ NULL.
  if (app_modal_dialog_queue_)
    app_modal_dialog_queue_->push(dialog);
}

// static
void AppModalDialogQueue::ShowNextDialog() {
  app_modal_dialog_queue_->pop();
  active_dialog_ = NULL;
  if (!app_modal_dialog_queue_->empty()) {
    ShowModalDialog(app_modal_dialog_queue_->front());
  } else {
    delete app_modal_dialog_queue_;
    app_modal_dialog_queue_ = NULL;
  }
}

// static
void AppModalDialogQueue::ActivateModalDialog() {
  if (!app_modal_dialog_queue_->empty())
    app_modal_dialog_queue_->front()->ActivateModalDialog();
}

// static
void AppModalDialogQueue::ShowModalDialog(
    views::AppModalDialogDelegate* dialog) {
  // ShowModalDialog can wind up calling ShowNextDialog in some cases,
  // which will wind up calling this method recursively, so active_dialog_
  // must be set first.
  active_dialog_ = dialog;
  dialog->ShowModalDialog();
}
<|endoftext|>