<commit_before>#ifndef WASTELAND_HPP_INCLUDED
#define WASTELAND_HPP_INCLUDED

#include "map.hpp"
#include "levelgen.hpp"
#include <SFML/Graphics.hpp>
#include <functional>
#include <string>
#include <unordered_map>
#include "object.hpp"
#include <SFGUI/SFGUI.hpp>
#include <SFGUI/Widgets.hpp>
#include <queue>

class Character;

enum PlayerMovement
{
    Player_MoveNorth,
    Player_MoveSouth,
    Player_MoveEast,
    Player_MoveWest,
    Player_MoveNorthWest,
    Player_MoveNorthEast,
    Player_MoveSouthWest,
    Player_MoveSouthEast
};

class Wasteland final
{
private:
    std::shared_ptr<Map> map_;
    std::unique_ptr<sf::RenderWindow> window_;

    bool should_quit_;

    std::unordered_map<uint32_t, std::shared_ptr<sf::Sprite> > sprites_;
    std::unordered_map<uint32_t, std::shared_ptr<sf::Texture> > textures_;
    std::unordered_map<uint32_t, std::shared_ptr<sf::Image> > images_;
    std::shared_ptr<Character> player_;

    sf::View view_;
    sf::View text_view_;
    sf::Font font_;

    float zoom_;
    uint32_t turn_;
    bool console_;
    uint32_t light_radius_;

    std::string console_command_;
    std::string console_output_;
    std::string menu_;

    bool step_;

    sfg::SFGUI gui_;
    sfg::Desktop desktop_;
    sfg::Window::Ptr equipment_;
    sfg::Box::Ptr inventory_;
    std::vector<sfg::Widget::Ptr> inventory_widgets_;

    sf::Clock clock_;

    enum ActionType
    {
        Action_Invalid,
        Action_PlayerMove,
        Action_PlayerPickup,
        Action_PlayerDrop
    };

    struct Action
    {
        Action();
        ActionType type;
        uint32_t data;
        uint32_t extra;
    };

    std::queue<Action> actions_;
    typedef std::function<void(const Action&)> ActionHandler;
    std::map<enum ActionType, ActionHandler> action_handlers_;

public:
    explicit Wasteland(const std::string& datafile = "");

    void Run();
    void LoadMap(const std::string& filename);
    void SetMap(std::shared_ptr<Map> map);

private:
    void LoadData(const std::string& filename);
    void ProcessActionQueue();
    void HandlePlayerInventory();
    void UpdateVisited();
    std::string GetStatusLine();
    void UpdateMap();
    void ProcessInput();
    void Draw();
    void DoCommand(const std::string& str);

    void CreateSprite(uint32_t id, const std::string& filename, const sf::Vector2f& scale);

    void OnPlayerDropItem(const Action& action);
    void OnPlayerPickup(const Action& action);
    void OnPlayerMove(const Action& action);
};

#endif
<commit_msg>Missed file<commit_after>#ifndef WASTELAND_HPP_INCLUDED
#define WASTELAND_HPP_INCLUDED

#include "map.hpp"
#include "levelgen.hpp"
#include <SFML/Graphics.hpp>
#include <functional>
#include <string>
#include <unordered_map>
#include "object.hpp"
#include <SFGUI/SFGUI.hpp>
#include <SFGUI/Widgets.hpp>
#include <queue>

class Character;

enum PlayerMovement
{
    Player_MoveNorth,
    Player_MoveSouth,
    Player_MoveEast,
    Player_MoveWest,
    Player_MoveNorthWest,
    Player_MoveNorthEast,
    Player_MoveSouthWest,
    Player_MoveSouthEast
};

class Wasteland final
{
private:
    std::shared_ptr<Map> map_;
    std::unique_ptr<sf::RenderWindow> window_;

    bool should_quit_;

    std::unordered_map<uint32_t, std::shared_ptr<sf::Sprite> > sprites_;
    std::unordered_map<uint32_t, std::shared_ptr<sf::Texture> > textures_;
    std::unordered_map<uint32_t, std::shared_ptr<sf::Image> > images_;
    std::shared_ptr<Character> player_;

    sf::View view_;
    sf::View text_view_;
    sf::Font font_;

    float zoom_;
    uint32_t turn_;
    bool console_;
    uint32_t light_radius_;

    std::string console_command_;
    std::string console_output_;
    std::string menu_;

    bool step_;

    sfg::SFGUI gui_;
    sfg::Desktop desktop_;
    sfg::Window::Ptr equipment_;
    sfg::Box::Ptr inventory_;
    std::vector<sfg::Widget::Ptr> inventory_widgets_;

    sf::Clock clock_;

    enum ActionType
    {
        Action_Invalid,
        Action_PlayerMove,
        Action_PlayerPickup,
        Action_PlayerDrop,
        Action_PlayerConsume
    };

    struct Action
    {
        Action();
        ActionType type;
        uint32_t data;
        uint32_t extra;
    };

    std::queue<Action> actions_;
    typedef std::function<void(const Action&)> ActionHandler;
    std::map<enum ActionType, ActionHandler> action_handlers_;

public:
    explicit Wasteland(const std::string& datafile = "");

    void Run();
    void LoadMap(const std::string& filename);
    void SetMap(std::shared_ptr<Map> map);

private:
    void LoadData(const std::string& filename);
    void ProcessActionQueue();
    void HandlePlayerInventory();
    void UpdateVisited();
    std::string GetStatusLine();
    void UpdateMap();
    void ProcessInput();
    void Draw();
    void DoCommand(const std::string& str);

    void CreateSprite(uint32_t id, const std::string& filename, const sf::Vector2f& scale);

    void OnPlayerDropItem(const Action& action);
    void OnPlayerPickup(const Action& action);
    void OnPlayerMove(const Action& action);
    void OnPlayerConsume(const Action& action);
};

#endif
<|endoftext|>


<commit_before>
/**
 *  Copyright 2012 Washington University in St Louis
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "pna.h"

#include <iostream>
#include <sstream>
#include <fstream>
#include <list>
#include <map>
#include <stdint.h>
#include <cstdlib>
#include <string.h>
#include <string>
#include <zlib.h>

// C++11 includes
#include <forward_list>
#include <memory>

using namespace std;

// Trailer for gzip compression
struct gzip_trailer
{
    uint32_t crc32;          // Cyclic Redundancy Check value
    uint32_t uncomp_len;     // Uncompressed length of original input data
};
#define GZIP_TRAILER_LEN 8

// Parser returns
#define PARSE_SUCCESS 1
#define PARSE_FAILURE 0

// HTTP text options
#define NONE       0
#define COMPRESSED 1
#define CHUNKED    2
#define BOTH       3

// Either make the host global or make it an argument through
// 3 functions where it's only needed in the last one.
// Shitty, I know...
string host;

int parseHTML(char *buf, size_t buf_len)
{
    forward_list<string> page;
    forward_list<string>::iterator it;
    istringstream iss(buf);
    string str;
    // size_t offset;

    // Put each line in the forward iterator.
    // I put the buffer in the string stream to have access to getline.
    it = page.before_begin();
    if (iss.good())
    {
         while(!iss.eof())
        {
            getline(iss,str);
            page.emplace_after(it, str);
        }

    }
    else
        return PARSE_FAILURE;

    // // Print the list of html lines.
    // for (it = page.begin(); it != page.end(); ++it)
    //     cout << *it << endl;

    //collect all of the links in a page
    // list<string> links;
    // list<string>::iterator itr;
    // for (it = page.begin(); it != page.end(); ++it)
    // {
    //     offset = it->find("href=\"");
    //     if (offset != string::npos)
    //         links.push_back(*it);
    // }

    // for (itr = links.begin(); itr != links.end(); ++it)
    //     cout << *itr << endl;
    // cout << "num links: " << links.size() << endl;
    // check if a lot of the links navigate outside of the website

    return PARSE_SUCCESS;
}

int decompress(string compression, unique_ptr<char[]> pBuf, size_t buf_len)
{
    // zlib should work on the gzip and deflate encodings.
    // Need to test deflate though, can't find one that uses it (so maybe I don't need to worry about it).
    if (strncmp(compression.c_str(), "gzip", 4) == 0 || strncmp(compression.c_str(), "deflate", 7) == 0)
    {
        struct gzip_trailer *gz_trailer = (struct gzip_trailer *)(pBuf.get() + buf_len - GZIP_TRAILER_LEN);
        int err, ret;

        uLongf uncomp_len = (uLongf)gz_trailer->uncomp_len;
        unique_ptr<Bytef[]> pUncomp(new Bytef[uncomp_len]);

        // Set up the z_stream.
        z_stream d_stream;
        d_stream.zalloc = Z_NULL;
        d_stream.zfree = Z_NULL;
        d_stream.opaque = (voidpf)0;

        d_stream.next_in = (Bytef *)pBuf.get();
        d_stream.avail_in = (uInt)buf_len;

        // Prep for inflate.
        err = inflateInit2(&d_stream, 47);
        if (err != Z_OK)
            cout << "inflateInit Error: " << err << endl;

        // Inflate so that it decompresses the whole buffer.
        d_stream.next_out = pUncomp.get();
        d_stream.avail_out = uncomp_len;
        err = inflate(&d_stream, Z_FINISH);
        if (err < 0)
            cout << "inflate Error: " << err << ": " << d_stream.msg << endl;

        //cout.write((char *)pUncomp.get(), uncomp_len);
        ret = parseHTML((char *)pUncomp.get(), uncomp_len);
        return ret;
    }
    else
        cout << "Error! not in gzip for decompression" << endl;
    return PARSE_FAILURE;
}

int parseHTTP(ifstream& in, map<string, string>& header)
{
    map<string, string>::iterator itr;
    string line;
    size_t length;

    // Initialized return value to PARSE_FAILURE.
    // Let the returns from decompression and parseHTML turn it into PARSE_SUCCESS.
    int ret = PARSE_FAILURE;

    // Tally for what combination of Chunked and/or Compressed it is.
    int text_option = 0;

    // Check to see if it is chunked.
    itr = header.find("Transfer-Encoding");
    if (itr != header.end())
        text_option += CHUNKED;

    // Check to see if it is compressed.
    itr = header.find("Content-Encoding");
    if (itr != header.end())
        text_option += COMPRESSED;

    // Let it be known, the abnormal { } for the cases are to induce explicit
    // scope restrictions, so that the unique_ptr is cleaned immediately.
    switch (text_option) {
    case NONE:
    {
        if (strncmp(itr->second.c_str(), "text/html", 9) == 0)
        {
            length = atoi(header["Content-Length"].c_str());
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            //cout.write(buf.get(), length);
            ret = parseHTML((char *)pBuf.get(), length);
        }
        else if (strncmp(itr->second.c_str(), "text/css", 8))
        {
            length = atoi(header["Content-Length"].c_str());
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            //cout.write(buf.get(), length);
            ret = parseHTML((char *)pBuf.get(), length);
        }
        break;
    }
    case CHUNKED:
    {
        // Get the first chunk length.
        getline(in,line);
        length = strtoul(line.c_str(),NULL,16);

        // Repeat reading the buffer and new chunk length until the length is 0.
        // 0 is the value in concordance with the HTTP spec, it signifies the end of the chunks.
        while (length != 0)
        {
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);

            // Consume the trailing CLRF before the length.
            getline(in,line);

            // Consume the new chunk length or the terminating zero.
            getline(in,line);

            // I have to use strtoul with base 16 because the HTTP spec
            // says the chunked encoding length is presented in hex.
            length = strtoul(line.c_str(),NULL,16);

            //cout.write(buf,length);
            parseHTML((char *)pBuf.get(), length);
        }

        // Once it gets to this point, the chunked length last fed was 0
        // Get last CLRF and quit
        getline(in,line);

        // TODO: Return value for this. Multiple parseHTML calls equates to...?
        ret = PARSE_SUCCESS;
        break;
    }
    case COMPRESSED:
    {
        // Read the compressed data into a buffer and ship off to be decompressed.
        length = atoi(header["Content-Length"].c_str());
        unique_ptr<char[]> pBuf(new char[length]);
        in.read(pBuf.get(), length);
        ret = decompress(header["Content-Encoding"], std::move(pBuf), length);
        break;
    }
    case BOTH:
    {
        // Same as the CHUNKED case but with decompression. Comments included again for verbosity.
        // TODO: figure out way to combine this and CHUNKED to eliminate repetitive code

        // Get the first chunk length.
        getline(in,line);
        length = strtoul(line.c_str(),NULL,16);

        // Repeat reading the buffer and new chunk length until the length is 0.
        // 0 is the value in concordance with the HTTP spec, it signifies the end of the chunks.
        while (length != 0)
        {
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            decompress(header["Content-Encoding"],std::move(pBuf),length);

            // Consume the trailing CLRF before the length.
            getline(in,line);

            // Consume the new chunk length or the terminating zero.
            getline(in,line);

            // I have to use strtoul with base 16 because the HTTP spec
            // says the chunked encoding length is presented in hex.
            length = strtoul(line.c_str(),NULL,16);
        }

        // Once it gets to this point, the chunked length last fed was 0
        // Get last CLRF and quit
        getline(in,line);

        // TODO: Return value for this. Multiple decompress calls equates to...?
        ret = PARSE_SUCCESS;
        break;
    }
    default:
        break;

    }

    return ret;
}

int main(int argc, char **argv)
{
    string line;
    string host;
    size_t offset;
    size_t host_off;

    // If argc is two, a pcap input file should be given.
    if (argc == 3)
    {
        map<string, string> header;
        ifstream in;

        int outbound;
        int inbound;
        char port[5];

        /*
         * Eliminate some magic numbers
         * I did have 5 as a const size_t, but it threw a warning for strncpy...
         * Live with the magic number. Spoilers: it's the length of a port number.
         */
        const int tcp_port = 80;

        /*
         * Check the destination port of the first file.
         * If it is 80, then it's the outbound file.
         * If not, then it's the inbound file.
         * Set the file's argument number accordingly.
         */
        strncpy(port, argv[1] + strlen(argv[1]) - 5, 5);
        if (atoi(port) == tcp_port) {
            outbound = 1;
            inbound = 2;
        } else {
            inbound = 1;
            outbound = 2;
        }

        // Get the hostname
        in.open(argv[outbound]);
        if (in.is_open()) {
            while (!in.eof()) {
                // search for a GET request that specifies the host
                // should be the first line, so quit after we find it
                getline(in, line);

                host_off = line.find("Host: ");

                if (host_off != string::npos) {
                    host = line.substr(host_off + 6);
                    break;
                }
            }
        }
        in.close();

        cout << "host: " << host << endl;

        // Let's parse some replies!
        in.open(argv[inbound]);
        if (in.is_open())
        {
            while (!in.eof())
            {
                // Search for the "HTTP/1.1 200 OK" line.
                getline(in, line);

                offset = line.find("HTTP/1.1 200 OK");
                if (offset != string::npos)
                {
                    // We found the reply.
                    header["HTTP/1.1"] = "200 OK";

                    // Read the HTTP header labels and values into our map.
                    // The header ending is denoted by a carriage return '\r'.
                    getline(in, line);
                    while (line != "\r")
                    {
                        offset = line.find(":");
                        header[line.substr(0, offset)] = line.substr(offset + 2);
                        getline(in, line);
                    }

                    // Print the http header
                    // map<string, string>::iterator it;
                    // for (it = header.begin(); it != header.end(); ++it)
                    //     cout << it->first << ": " << it->second << endl;
                    // cout << endl;

                    // Send the HTTP header and our ifstream to parseHTTP.
                    parseHTTP(in, header);

                    // Clear the header map for the next reply found in the file.
                    header.clear();
                }
            }
        }
        else
            cout << "Error! File did not open correctly." << endl;

        in.close();
    }
    // Input is piped to our program from stdout with our pcap_wrap format.
    else if (argc == 1)
    {
        map<string, string> key;
        string first, second;
        unsigned long length;
        size_t span;

        while(!cin.eof())
        {
            // Get the six lines pertinent to our TCP flows, put them in our key map.
            for (int i = 0; i < 6; ++i)
            {
                getline(cin, line);

                offset = line.find("->");
                span = line.find(":");

                if (offset != string::npos && span != string::npos)
                {
                    second = line.substr(span+2);
                    first = line.substr(offset+2, span - offset - 2);
                    key[first] = second;
                }
            }

            // Print the key.
            map<string, string>::iterator it;
            for (it = key.begin(); it != key.end(); ++it)
                cout << it->first << ": " << it->second << endl;

            // Get the packet information. This line specifically is packet length.
            getline(cin, line);
            offset = line.find(":");
            if (offset != string::npos)
            {
                // The length line exists.  Read that length of data from cin soon.
                length = atoi(line.substr(offset+2).c_str());
                unique_ptr<char[]> pBuf(new char[length]);

                // Consume the packet_data label.
                getline(cin, line);

                // Get the packet data.
                cin.read(pBuf.get(), length);

                // TODO: Here is the exit point from main.
                // Guessing this will go to the hashmap? We'll see when it's developed.

                cout.write(pBuf.get(), length);
            }

            // Clear the key map for other packet keys.
            key.clear();
        }
    } else {
        cout << "Usage: html_parser outbound-flow inbound-flow" << endl;
        cout << "[NOTE] the flow order is not important" << endl;
    }

    return 0;
}

<commit_msg>links are parsed.  need to think twice on what to look for though.<commit_after>
/**
 *  Copyright 2012 Washington University in St Louis
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "pna.h"

#include <iostream>
#include <sstream>
#include <fstream>
#include <list>
#include <map>
#include <stdint.h>
#include <cstdlib>
#include <string.h>
#include <string>
#include <zlib.h>

// C++11 includes
#include <forward_list>
#include <memory>

using namespace std;

// Trailer for gzip compression
struct gzip_trailer
{
    uint32_t crc32;          // Cyclic Redundancy Check value
    uint32_t uncomp_len;     // Uncompressed length of original input data
};
#define GZIP_TRAILER_LEN 8

// Parser returns
#define PARSE_SUCCESS 1
#define PARSE_FAILURE 0

// HTTP text options
#define NONE       0
#define COMPRESSED 1
#define CHUNKED    2
#define BOTH       3

// Either make the host global or make it an argument through
// 3 functions where it's only needed in the last one.
// Shitty, I know...
string host;

int parseHTML(char *buf, size_t buf_len)
{
    forward_list<string> page;
    forward_list<string>::iterator it;
    istringstream iss(buf);
    string str;

    // Put each line in the forward iterator.
    // I put the buffer in the string stream to have access to getline.
    it = page.before_begin();
    if (iss.good())
    {
         while(!iss.eof())
        {
            getline(iss,str);
            page.emplace_after(it, str);
        }

    }
    else
        return PARSE_FAILURE;

    // // Print the list of html lines.
    // for (it = page.begin(); it != page.end(); ++it)
    //     cout << *it << endl;

    //collect all of the links in a page
    list<string> links;
    list<string>::iterator itr;
    size_t offset;
    size_t span;

    // TODO: think about better ways to distinguish between an in-domain link and internet link
    // besides that internet starts with "http://" and in-domain starts with "/"
    // if it has an href, parse out the link
    for (it = page.begin(); it != page.end(); ++it)
    {
        offset = it->find("href=\"");
        if (offset != string::npos) {
            // find the ending quote for the link, and push the url int
            // cout << *it << endl;
            span = it->substr(offset+6).find("\"");
            links.push_back(it->substr(offset+6, span));
        }
    }

    // for (it = page.begin(); it != page.end(); ++it)
    // {
    //     offset = it->find("href=\"");
    //     if (offset != string::npos)
    //         links.push_back(*it);
    // }

    // print the links
    for (itr = links.begin(); itr != links.end(); ++itr)
        cout << *itr << endl;
    cout << "num links: " << links.size() << endl;
    // check if a lot of the links navigate outside of the website

    return PARSE_SUCCESS;
}

int decompress(string compression, unique_ptr<char[]> pBuf, size_t buf_len)
{
    // zlib should work on the gzip and deflate encodings.
    // Need to test deflate though, can't find one that uses it (so maybe I don't need to worry about it).
    if (strncmp(compression.c_str(), "gzip", 4) == 0 || strncmp(compression.c_str(), "deflate", 7) == 0)
    {
        struct gzip_trailer *gz_trailer = (struct gzip_trailer *)(pBuf.get() + buf_len - GZIP_TRAILER_LEN);
        int err, ret;

        uLongf uncomp_len = (uLongf)gz_trailer->uncomp_len;
        unique_ptr<Bytef[]> pUncomp(new Bytef[uncomp_len]);

        // Set up the z_stream.
        z_stream d_stream;
        d_stream.zalloc = Z_NULL;
        d_stream.zfree = Z_NULL;
        d_stream.opaque = (voidpf)0;

        d_stream.next_in = (Bytef *)pBuf.get();
        d_stream.avail_in = (uInt)buf_len;

        // Prep for inflate.
        err = inflateInit2(&d_stream, 47);
        if (err != Z_OK)
            cout << "inflateInit Error: " << err << endl;

        // Inflate so that it decompresses the whole buffer.
        d_stream.next_out = pUncomp.get();
        d_stream.avail_out = uncomp_len;
        err = inflate(&d_stream, Z_FINISH);
        if (err < 0)
            cout << "inflate Error: " << err << ": " << d_stream.msg << endl;

        //cout.write((char *)pUncomp.get(), uncomp_len);
        ret = parseHTML((char *)pUncomp.get(), uncomp_len);
        return ret;
    }
    else
        cout << "Error! not in gzip for decompression" << endl;
    return PARSE_FAILURE;
}

int parseHTTP(ifstream& in, map<string, string>& header)
{
    map<string, string>::iterator itr;
    string line;
    size_t length;

    // Initialized return value to PARSE_FAILURE.
    // Let the returns from decompression and parseHTML turn it into PARSE_SUCCESS.
    int ret = PARSE_FAILURE;

    // Tally for what combination of Chunked and/or Compressed it is.
    int text_option = 0;

    // Check to see if it is chunked.
    itr = header.find("Transfer-Encoding");
    if (itr != header.end())
        text_option += CHUNKED;

    // Check to see if it is compressed.
    itr = header.find("Content-Encoding");
    if (itr != header.end())
        text_option += COMPRESSED;

    // Let it be known, the abnormal { } for the cases are to induce explicit
    // scope restrictions, so that the unique_ptr is cleaned immediately.
    switch (text_option) {
    case NONE:
    {
        if (strncmp(itr->second.c_str(), "text/html", 9) == 0)
        {
            length = atoi(header["Content-Length"].c_str());
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            //cout.write(buf.get(), length);
            ret = parseHTML((char *)pBuf.get(), length);
        }
        else if (strncmp(itr->second.c_str(), "text/css", 8))
        {
            length = atoi(header["Content-Length"].c_str());
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            //cout.write(buf.get(), length);
            ret = parseHTML((char *)pBuf.get(), length);
        }
        break;
    }
    case CHUNKED:
    {
        // Get the first chunk length.
        getline(in,line);
        length = strtoul(line.c_str(),NULL,16);

        // Repeat reading the buffer and new chunk length until the length is 0.
        // 0 is the value in concordance with the HTTP spec, it signifies the end of the chunks.
        while (length != 0)
        {
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);

            // Consume the trailing CLRF before the length.
            getline(in,line);

            // Consume the new chunk length or the terminating zero.
            getline(in,line);

            // I have to use strtoul with base 16 because the HTTP spec
            // says the chunked encoding length is presented in hex.
            length = strtoul(line.c_str(),NULL,16);

            //cout.write(buf,length);
            parseHTML((char *)pBuf.get(), length);
        }

        // Once it gets to this point, the chunked length last fed was 0
        // Get last CLRF and quit
        getline(in,line);

        // TODO: Return value for this. Multiple parseHTML calls equates to...?
        ret = PARSE_SUCCESS;
        break;
    }
    case COMPRESSED:
    {
        // Read the compressed data into a buffer and ship off to be decompressed.
        length = atoi(header["Content-Length"].c_str());
        unique_ptr<char[]> pBuf(new char[length]);
        in.read(pBuf.get(), length);
        ret = decompress(header["Content-Encoding"], std::move(pBuf), length);
        break;
    }
    case BOTH:
    {
        // Same as the CHUNKED case but with decompression. Comments included again for verbosity.
        // TODO: figure out way to combine this and CHUNKED to eliminate repetitive code

        // Get the first chunk length.
        getline(in,line);
        length = strtoul(line.c_str(),NULL,16);

        // Repeat reading the buffer and new chunk length until the length is 0.
        // 0 is the value in concordance with the HTTP spec, it signifies the end of the chunks.
        while (length != 0)
        {
            unique_ptr<char[]> pBuf(new char[length]);
            in.read(pBuf.get(), length);
            decompress(header["Content-Encoding"],std::move(pBuf),length);

            // Consume the trailing CLRF before the length.
            getline(in,line);

            // Consume the new chunk length or the terminating zero.
            getline(in,line);

            // I have to use strtoul with base 16 because the HTTP spec
            // says the chunked encoding length is presented in hex.
            length = strtoul(line.c_str(),NULL,16);
        }

        // Once it gets to this point, the chunked length last fed was 0
        // Get last CLRF and quit
        getline(in,line);

        // TODO: Return value for this. Multiple decompress calls equates to...?
        ret = PARSE_SUCCESS;
        break;
    }
    default:
        break;

    }

    return ret;
}

int main(int argc, char **argv)
{
    string line;
    string host;
    size_t offset;
    size_t host_off;

    // If argc is three, respective outbound and inbound flow files should be the arguments.
    if (argc == 3)
    {
        map<string, string> header;
        ifstream in;

        int outbound;
        int inbound;
        char port[5];

        /*
         * Eliminate some magic numbers
         * I did have 5 as a const size_t, but it threw a warning for strncpy...
         * Live with the magic number. Spoilers: it's the length of a port number.
         */
        const int tcp_port = 80;

        /*
         * Check the destination port of the first file.
         * If it is 80, then it's the outbound file.
         * If not, then it's the inbound file.
         * Set the file's argument number accordingly.
         */
        strncpy(port, argv[1] + strlen(argv[1]) - 5, 5);
        if (atoi(port) == tcp_port) {
            outbound = 1;
            inbound = 2;
        } else {
            inbound = 1;
            outbound = 2;
        }

        // Get the hostname
        in.open(argv[outbound]);
        if (in.is_open()) {
            while (!in.eof()) {
                // search for a GET request that specifies the host
                // should be the first line, so quit after we find it
                getline(in, line);

                host_off = line.find("Host: ");

                if (host_off != string::npos) {
                    host = line.substr(host_off + 6);
                    break;
                }
            }
        }
        in.close();

        cout << "host: " << host << endl;

        // Let's parse some replies!
        in.open(argv[inbound]);
        if (in.is_open())
        {
            while (!in.eof())
            {
                // Search for the "HTTP/1.1 200 OK" line.
                getline(in, line);

                offset = line.find("HTTP/1.1 200 OK");
                if (offset != string::npos)
                {
                    // We found the reply.
                    header["HTTP/1.1"] = "200 OK";

                    // Read the HTTP header labels and values into our map.
                    // The header ending is denoted by a carriage return '\r'.
                    getline(in, line);
                    while (line != "\r")
                    {
                        offset = line.find(":");
                        header[line.substr(0, offset)] = line.substr(offset + 2);
                        getline(in, line);
                    }

                    // Print the http header
                    // map<string, string>::iterator it;
                    // for (it = header.begin(); it != header.end(); ++it)
                    //     cout << it->first << ": " << it->second << endl;
                    // cout << endl;

                    // Send the HTTP header and our ifstream to parseHTTP.
                    parseHTTP(in, header);

                    // Clear the header map for the next reply found in the file.
                    header.clear();
                }
            }
        }
        else
            cout << "Error! File did not open correctly." << endl;

        in.close();
    }
    // Input is piped to our program from stdout with our pcap_wrap format.
    else if (argc == 1)
    {
        map<string, string> key;
        string first, second;
        unsigned long length;
        size_t span;

        while(!cin.eof())
        {
            // Get the six lines pertinent to our TCP flows, put them in our key map.
            for (int i = 0; i < 6; ++i)
            {
                getline(cin, line);

                offset = line.find("->");
                span = line.find(":");

                if (offset != string::npos && span != string::npos)
                {
                    second = line.substr(span+2);
                    first = line.substr(offset+2, span - offset - 2);
                    key[first] = second;
                }
            }

            // Print the key.
            map<string, string>::iterator it;
            for (it = key.begin(); it != key.end(); ++it)
                cout << it->first << ": " << it->second << endl;

            // Get the packet information. This line specifically is packet length.
            getline(cin, line);
            offset = line.find(":");
            if (offset != string::npos)
            {
                // The length line exists.  Read that length of data from cin soon.
                length = atoi(line.substr(offset+2).c_str());
                unique_ptr<char[]> pBuf(new char[length]);

                // Consume the packet_data label.
                getline(cin, line);

                // Get the packet data.
                cin.read(pBuf.get(), length);

                // TODO: Here is the exit point from main.
                // Guessing this will go to the hashmap? We'll see when it's developed.

                cout.write(pBuf.get(), length);
            }

            // Clear the key map for other packet keys.
            key.clear();
        }
    } else {
        cout << "Usage: html_parser outbound-flow inbound-flow" << endl;
        cout << "[NOTE] the flow order is not important" << endl;
    }

    return 0;
}

<|endoftext|>


<commit_before>#include "include/vkalloc.h"

#include <vector>
#include <unordered_map>

#ifndef VKA_ALLOC_SIZE
#define VKA_ALLOC_SIZE 1024*1024*4
#endif

namespace vka {
    struct Node {
        Node* next = nullptr;
        uint64_t offset = 0;
        uint64_t size = 0;
    };

    struct Page {
        VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
        Node* head = nullptr;
    };

    struct PageMapping {
        uint32_t heapIndex;
        uint32_t pageIndex;
    };

    VkDevice device;
    VkPhysicalDeviceMemoryProperties properties;
    VkAllocationCallbacks* callbacks;
    std::unordered_map<VkDeviceMemory, PageMapping> pageMap;    //caches index into one of the vector<Page> heaps
    std::vector<std::vector<Page>> heaps;
}

void vkaInit(VkPhysicalDevice physicalDevice, VkDevice device, VkAllocationCallbacks* allocator){
    vka::device = device;
    vka::callbacks = allocator;

    vkGetPhysicalDeviceMemoryProperties(physicalDevice, &vka::properties);

    vka::heaps.resize(static_cast<uint32_t>(vka::properties.memoryHeapCount));
}

using namespace vka;
static VkAllocation AttemptAlloc(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements);
static VkAllocation AttemptAlloc(Page& page, VkMemoryRequirements requirements);
static Page* AllocNewPage(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements);
static void Split(Node* current, Node** last, uint64_t start, uint64_t size);
static void Free(VkAllocation allocation, Page& page);
static void Merge(VkAllocation allocation, Node* current);

void vkaTerminate(){
    pageMap.clear();

    for (auto& heap : heaps) {
        for (size_t j = 0; j < heap.size(); j++) {
            Node* current = heap[j].head;

            while (current){
                Node* next = current->next;
                delete current;
                current = next;
            }

            vkFreeMemory(device, heap[j].deviceMemory, callbacks);
        }

        heap.clear();
    }
}

VkAllocation vkaAllocFlag(VkMemoryRequirements requirements, VkMemoryPropertyFlags flags) {
    for (size_t i = 0; i < properties.memoryTypeCount; i++) {
        if ((requirements.memoryTypeBits & (1 << i))
            && (properties.memoryTypes[i].propertyFlags & flags)) {
            std::vector<Page>& heap = heaps[properties.memoryTypes[i].heapIndex];

            VkAllocation result = AttemptAlloc(heap, static_cast<uint32_t>(i), requirements);
            if (result.deviceMemory != VK_NULL_HANDLE) {
                return result;
            }
        }
    }

    return {};
}

void vkaFree(VkAllocation allocation){
    if (allocation.deviceMemory == VK_NULL_HANDLE) return;

    PageMapping& mapping = pageMap[allocation.deviceMemory];
    Page& page = heaps[mapping.heapIndex][mapping.pageIndex];

    Free(allocation, page);
}

VkAllocation vkaAlloc(VkMemoryRequirements requirements){
    return vkaAllocFlag(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}

VkAllocation vkaAllocHost(VkMemoryRequirements requirements){
    return vkaAllocFlag(requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
}

static VkAllocation AttemptAlloc(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements) {
    //attempt to allocate from existing pages
    for (size_t i = 0; i < heap.size(); i++) {
        Page& page = heap[i];

        VkAllocation result = AttemptAlloc(page, requirements);
        if (result.deviceMemory != VK_NULL_HANDLE) {
            return result;
        }
    }

    //attempt to allocate from new page
    Page* newPage = AllocNewPage(heap, heapIndex, requirements);
    if (newPage) {
        VkAllocation result = AttemptAlloc(*newPage, requirements);
        if (result.deviceMemory != VK_NULL_HANDLE) {
            return result;
        }
    }

    //give up
    return {};
}

static VkAllocation AttemptAlloc(Page& page, VkMemoryRequirements requirements) {
    Node* current = page.head;
    Node** last = &page.head;

    while (current) {
        uint64_t start = current->offset;
        uint64_t available = current->size;

        uint64_t unalign = (start % requirements.alignment);
        uint64_t align;

        if (unalign == 0) {
            align = 0;
        } else {
            align = requirements.alignment - unalign;
        }

        start += align;
        available -= align;

        if (available >= requirements.size) {
            Split(current, last, start, requirements.size);
            VkAllocation result;
            result.deviceMemory = page.deviceMemory;
            result.offset = start;
            result.size = requirements.size;
            return result;
        }

        last = &(current->next);
        current = current->next;
    }

    return {};
}

static void Split(Node* current, Node** last, uint64_t start, uint64_t size) {
    uint64_t startSpace = start - current->offset;
    uint64_t endSpace = current->size - (start + size);

    if (startSpace == 0 && endSpace == 0) {
        *last = current->next;
        delete current;
    } else if (startSpace == 0 && endSpace > 0) {
        current->offset = start + size;
        current->size = endSpace;
    } else if (startSpace > 0 && endSpace == 0) {
        current->size = startSpace;
    } else {    //startSpace > 0 && endSpace > 0
        Node* newNode = new Node;
        newNode->next = current->next;
        newNode->offset = start + size;
        newNode->size = endSpace;

        current->next = newNode;
        current->size = startSpace;
    }
}

static Page* AllocNewPage(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements) {
    uint64_t allocSize = VKA_ALLOC_SIZE;
    if (requirements.size > allocSize) {
        allocSize = requirements.size;
    }

    VkMemoryAllocateInfo info = {};
    info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    info.allocationSize = allocSize;
    info.memoryTypeIndex = heapIndex;

    VkDeviceMemory memory;
    VkResult result = vkAllocateMemory(device, &info, callbacks, &memory);

    if (result == VK_SUCCESS){
        Page page = {};
        page.deviceMemory = memory;

        Node* node = new Node;
        node->size = allocSize;

        page.head = node;

        heap.emplace_back(page);

        pageMap[memory] = {heapIndex, static_cast<uint32_t>(heap.size() - 1)};

        return &(heap[heap.size() - 1]);
    } else {
        //TODO: add way for user to check the error
        return nullptr;
    }
}

static void Free(VkAllocation allocation, Page& page) {
    Node* current = page.head;

    while (current) {
        if (allocation.offset > current->offset && allocation.offset < current->next->offset) {
            Merge(allocation, current);
            return;
        }
    }
}

static void Merge(VkAllocation allocation, Node* current) {
    if (allocation.offset == current->offset + current->size) {
        current->size += allocation.size;
    } else {
        Node* newNode = new Node;
        newNode->next = current->next,
        newNode->offset = allocation.offset,
        newNode->size = allocation.size;

        current = newNode;
    }

    Node* next = current->next;
    if (next->offset == current->offset + current->size) {
        current->size += next->size;
        current->next = next->next;
        delete next;
    }
}<commit_msg>Fixed a bug in vkaFree<commit_after>#include "include/vkalloc.h"

#include <vector>
#include <unordered_map>

#ifndef VKA_ALLOC_SIZE
#define VKA_ALLOC_SIZE 1024*1024*4
#endif

namespace vka {
    struct Node {
        Node* next = nullptr;
        uint64_t offset = 0;
        uint64_t size = 0;
    };

    struct Page {
        VkDeviceMemory deviceMemory = VK_NULL_HANDLE;
        Node* head = nullptr;
    };

    struct PageMapping {
        uint32_t heapIndex;
        uint32_t pageIndex;
    };

    VkDevice device;
    VkPhysicalDeviceMemoryProperties properties;
    VkAllocationCallbacks* callbacks;
    std::unordered_map<VkDeviceMemory, PageMapping> pageMap;    //caches index into one of the vector<Page> heaps
    std::vector<std::vector<Page>> heaps;
}

void vkaInit(VkPhysicalDevice physicalDevice, VkDevice device, VkAllocationCallbacks* allocator){
    vka::device = device;
    vka::callbacks = allocator;

    vkGetPhysicalDeviceMemoryProperties(physicalDevice, &vka::properties);

    vka::heaps.resize(static_cast<uint32_t>(vka::properties.memoryHeapCount));
}

using namespace vka;
static VkAllocation AttemptAlloc(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements);
static VkAllocation AttemptAlloc(Page& page, VkMemoryRequirements requirements);
static Page* AllocNewPage(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements);
static void Split(Node* current, Node** last, uint64_t start, uint64_t size);
static void Free(VkAllocation allocation, Page& page);
static void Merge(VkAllocation allocation, Node* current);

void vkaTerminate(){
    pageMap.clear();

    for (auto& heap : heaps) {
        for (size_t j = 0; j < heap.size(); j++) {
            Node* current = heap[j].head;

            while (current){
                Node* next = current->next;
                delete current;
                current = next;
            }

            vkFreeMemory(device, heap[j].deviceMemory, callbacks);
        }

        heap.clear();
    }
}

VkAllocation vkaAllocFlag(VkMemoryRequirements requirements, VkMemoryPropertyFlags flags) {
    for (size_t i = 0; i < properties.memoryTypeCount; i++) {
        if ((requirements.memoryTypeBits & (1 << i))
            && (properties.memoryTypes[i].propertyFlags & flags)) {
            std::vector<Page>& heap = heaps[properties.memoryTypes[i].heapIndex];

            VkAllocation result = AttemptAlloc(heap, static_cast<uint32_t>(i), requirements);
            if (result.deviceMemory != VK_NULL_HANDLE) {
                return result;
            }
        }
    }

    return {};
}

void vkaFree(VkAllocation allocation){
    if (allocation.deviceMemory == VK_NULL_HANDLE) return;

    PageMapping& mapping = pageMap[allocation.deviceMemory];
    Page& page = heaps[mapping.heapIndex][mapping.pageIndex];

    Free(allocation, page);
}

VkAllocation vkaAlloc(VkMemoryRequirements requirements){
    return vkaAllocFlag(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
}

VkAllocation vkaAllocHost(VkMemoryRequirements requirements){
    return vkaAllocFlag(requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
}

static VkAllocation AttemptAlloc(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements) {
    //attempt to allocate from existing pages
    for (size_t i = 0; i < heap.size(); i++) {
        Page& page = heap[i];

        VkAllocation result = AttemptAlloc(page, requirements);
        if (result.deviceMemory != VK_NULL_HANDLE) {
            return result;
        }
    }

    //attempt to allocate from new page
    Page* newPage = AllocNewPage(heap, heapIndex, requirements);
    if (newPage) {
        VkAllocation result = AttemptAlloc(*newPage, requirements);
        if (result.deviceMemory != VK_NULL_HANDLE) {
            return result;
        }
    }

    //give up
    return {};
}

static VkAllocation AttemptAlloc(Page& page, VkMemoryRequirements requirements) {
    Node* current = page.head;
    Node** last = &page.head;

    while (current) {
        uint64_t start = current->offset;
        uint64_t available = current->size;

        uint64_t unalign = (start % requirements.alignment);
        uint64_t align;

        if (unalign == 0) {
            align = 0;
        } else {
            align = requirements.alignment - unalign;
        }

        start += align;
        available -= align;

        if (available >= requirements.size) {
            Split(current, last, start, requirements.size);
            VkAllocation result;
            result.deviceMemory = page.deviceMemory;
            result.offset = start;
            result.size = requirements.size;
            return result;
        }

        last = &(current->next);
        current = current->next;
    }

    return {};
}

static void Split(Node* current, Node** last, uint64_t start, uint64_t size) {
    uint64_t startSpace = start - current->offset;
    uint64_t endSpace = current->size - (start + size);

    if (startSpace == 0 && endSpace == 0) {
        *last = current->next;
        delete current;
    } else if (startSpace == 0 && endSpace > 0) {
        current->offset = start + size;
        current->size = endSpace;
    } else if (startSpace > 0 && endSpace == 0) {
        current->size = startSpace;
    } else {    //startSpace > 0 && endSpace > 0
        Node* newNode = new Node;
        newNode->next = current->next;
        newNode->offset = start + size;
        newNode->size = endSpace;

        current->next = newNode;
        current->size = startSpace;
    }
}

static Page* AllocNewPage(std::vector<Page>& heap, uint32_t heapIndex, VkMemoryRequirements requirements) {
    uint64_t allocSize = VKA_ALLOC_SIZE;
    if (requirements.size > allocSize) {
        allocSize = requirements.size;
    }

    VkMemoryAllocateInfo info = {};
    info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    info.allocationSize = allocSize;
    info.memoryTypeIndex = heapIndex;

    VkDeviceMemory memory;
    VkResult result = vkAllocateMemory(device, &info, callbacks, &memory);

    if (result == VK_SUCCESS){
        Page page = {};
        page.deviceMemory = memory;

        Node* node = new Node;
        node->size = allocSize;

        page.head = node;

        heap.emplace_back(page);

        pageMap[memory] = {heapIndex, static_cast<uint32_t>(heap.size() - 1)};

        return &(heap[heap.size() - 1]);
    } else {
        //TODO: add way for user to check the error
        return nullptr;
    }
}

static void Free(VkAllocation allocation, Page& page) {
    Node* current = page.head;

    while (current) {
        if (allocation.offset > current->offset && allocation.offset < current->next->offset) {
            Merge(allocation, current);
            return;
        }

        current = current->next;
    }
}

static void Merge(VkAllocation allocation, Node* current) {
    if (allocation.offset == current->offset + current->size) {
        current->size += allocation.size;
    } else {
        Node* newNode = new Node;
        newNode->next = current->next,
        newNode->offset = allocation.offset,
        newNode->size = allocation.size;

        current = newNode;
    }

    Node* next = current->next;
    if (next->offset == current->offset + current->size) {
        current->size += next->size;
        current->next = next->next;
        delete next;
    }
}<|endoftext|>


<commit_before>#include <catch/catch.hpp>
#include <kulma/io/file.h>
#include <kulma/macros.h>
#include <kulma/os.h>
#include <string.h>

const static char* s_filePath = "unit_test_file_cpp_test_file";

TEST_CASE("File", "[file]")
{

    SECTION("Opening file for read/write")
    {
        char data[] = "this is test string";
        kulma::touch(s_filePath);

        {
            kulma::Error err;

            kulma::FileWriter writer;
            REQUIRE(writer.open(s_filePath, false, &err));

            REQUIRE(writer.write(data, sizeof(data), &err) == sizeof(data));
            writer.close();
        }

        {
            kulma::Error err;

            kulma::FileReader reader;
            REQUIRE(reader.open(s_filePath, &err));
            char buf[sizeof(data)] = { 0 };
            REQUIRE(reader.read(buf, sizeof(data), &err) == sizeof(buf));
            reader.close();

            REQUIRE(strcmp(data, buf) == 0);
        }
        kulma::remove_file(s_filePath);
    }
}
<commit_msg>Add unit test for appending<commit_after>#include <catch/catch.hpp>
#include <kulma/io/file.h>
#include <kulma/macros.h>
#include <kulma/os.h>
#include <string.h>

const static char* s_filePath = "unit_test_file_cpp_test_file";
const static char s_data[] = "this is test string";
const static char s_append[] = " hello world";
const static char s_appended[] = "this is test string hello world";
TEST_CASE("File", "[file]")
{

    SECTION("Opening file for write")
    {
        kulma::touch(s_filePath);

        kulma::Error err;

        kulma::FileWriter writer;
        REQUIRE(writer.open(s_filePath, false, &err));

        REQUIRE(writer.write(s_data, sizeof(s_data), &err) == sizeof(s_data));
        writer.close();
    }

    SECTION("Opening file for appended write")
    {
        kulma::Error err;

        kulma::FileWriter writer;
        REQUIRE(writer.open(s_filePath, true, &err));

        REQUIRE(writer.write(s_append, sizeof(s_append), &err) == sizeof(s_append));
        writer.close();
    }

    SECTION("Opening file for read")
    {
        kulma::Error err;

        kulma::FileReader reader;
        REQUIRE(reader.open(s_filePath, &err));
        char buf[sizeof(s_appended)] = { 0 };
        REQUIRE(reader.read(buf, sizeof(s_data), &err) == sizeof(s_data));
        REQUIRE(strcmp(s_data, buf) == 0);
        // get rid of null terminator
        REQUIRE(reader.read(buf + sizeof(s_data) - 1, sizeof(s_append), &err) == sizeof(s_append));
        REQUIRE(strcmp(s_appended, buf) == 0);

        reader.close();

        kulma::remove_file(s_filePath);
    }

}
<|endoftext|>


<commit_before>#include <stack.hpp>
#include <catch.hpp>

SCENARIO("init", "[init]") {
	stack<int> A;
	REQUIRE(A.count() == 0);
}

SCENARIO("Push", "[push]") {
	stack<int> A;
	A.push(1);
	A.push(2);
	REQUIRE(A.count() == 2);
}

SCENARIO("Pop", "[pop]") {
	stack<int> A;
	A.push(1);
	A.push(2);
	A.pop();
	REQUIRE(A.count() == 1);
}

SCENARIO("oper=", "[oper]"){
	stack<int> A;
	A.push(1);
	A.push(2);
	stack<int> B = A;
	REQUIRE(A.count() == B.count());
}
<commit_msg>Update init.cpp<commit_after>#include <stack.hpp>
#include <catch.hpp>

SCENARIO("init", "[init]") {
	stack<int> A;
	REQUIRE(A.count() == 0);
}

SCENARIO("Push", "[push]") {
	stack<int> A;
	A.push(1);
	A.push(2);
	REQUIRE(A.count() == 2);
}

SCENARIO("Pop", "[pop]") {
	stack<int> A;
	A.push(1);
	A.push(2);
	A.pop();
	REQUIRE(A.count() == 1);
}

SCENARIO("oper=", "[oper]"){
	stack<int> A;
	stack<int> B;
	A.push(1);
	A.push(2);
	B.push(3);
	REQUIRE(A.count() == 2);
	B = A;
	REQUIRE(A.count() == 3);
}
<|endoftext|>


<commit_before>#include <BinaryTree.hpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	Tree node;
	REQUIRE(node.x_() == 0);
}

SCENARIO("add")
{
	Tree tree;
	int newEl;
	tree.fIn("Tree.txt");
	std::ifstream("newEl.txt") >> newEl;
	tree.add(newEl);
	REQUIRE(right_() == 7);
}

SCENARIO("search")
{
	Tree tree;
	Node* node;
	tree.fIn("Tree+newEl.txt");
	node = tree.search(5);
	REQUIRE(x_() == 5);
	REQUIRE(left_() == 3);
	REQUIRE(right_() == 7);
}

SCENARIO("fIn")
{
	Tree tree;
	tree.fIn("Tree.txt");
	REQUIRE(x_() == 5);
}
<commit_msg>Update init.cpp<commit_after>#include <BinaryTree.сpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	Tree node;
	REQUIRE(node.x_() == 0);
}

SCENARIO("add")
{
	Tree tree;
	int newEl;
	tree.fIn("Tree.txt");
	std::ifstream("newEl.txt") >> newEl;
	tree.add(newEl);
	REQUIRE(right_() == 7);
}

SCENARIO("search")
{
	Tree tree;
	Node* node;
	tree.fIn("Tree+newEl.txt");
	node = tree.search(5);
	REQUIRE(x_() == 5);
	REQUIRE(left_() == 3);
	REQUIRE(right_() == 7);
}

SCENARIO("fIn")
{
	Tree tree;
	tree.fIn("Tree.txt");
	REQUIRE(x_() == 5);
}
<|endoftext|>


<commit_before>#include <BinaryTree.hpp>
#include <catch.hpp>

SCENARIO ("init", "[init]")
{
  BinaryTree<int> obj;
  REQUIRE(obj.root_() == nullptr);
}

SCENARIO("insert", "[insert]")
{
  BinaryTree<int> obj;
  obj.insert_node(3);
  REQUIRE(obj.find_node(3, obj.root_())->data == 3);
}

SCENARIO("find_node", "[find_node]")
{
  BinaryTree<int> obj;
  obj.insert_node(2);
  REQUIRE(obj.find_node(2, obj.root_()) != nullptr);
  REQUIRE(obj.find_node(2, obj.root_())->data == 2);
}

SCENARIO("get root", "[get root]")
{
  BinaryTree<int> obj;
  obj.insert_node(4);
  REQUIRE(obj.root_() != 0);
}

SCENARIO ("reading/writing", "[read/write]")
{
  BinaryTree<int> obj;
  obj.insert_node(1);
  obj.insert_node(2);
  obj.writing("file2.txt");
  BinaryTree<int> obj_1;
  obj_1.reading("file2.txt");
  REQUIRE(obj_1.find_node(1, obj_1.root_())!= nullptr);
  REQUIRE(obj_1.find_node(2, obj_1.root_())!= nullptr);
}
<commit_msg>Update init.cpp<commit_after>#include <BinaryTree.hpp>
#include <catch.hpp>

SCENARIO ("init", "[init]")
{
  BinaryTree<int> obj;
  REQUIRE(obj.root_() == nullptr);
}

SCENARIO("insert", "[insert]")
{
  BinaryTree<int> obj;
  obj.insert_node(3);
  REQUIRE(obj.find_node(3, obj.root_())->data == 3);
}

SCENARIO("find_node", "[find_node]")
{
  BinaryTree<int> obj;
  obj.insert_node(2);
  REQUIRE(obj.find_node(2, obj.root_()) != nullptr);
  REQUIRE(obj.find_node(2, obj.root_())->data == 2);
}

SCENARIO("get root", "[get root]")
{
  BinaryTree<int> obj;
  obj.insert_node(4);
  REQUIRE(obj.root_() != 0);
}

SCENARIO ("reading/writing", "[read/write]")
{
  BinaryTree<int> obj;
  obj.insert_node(3);
  obj.insert_node(3);
  obj.writing("file2.txt");
  BinaryTree<int> obj_1;
  obj_1.reading("file2.txt");
  REQUIRE(obj_1.find_node(3, obj_1.root_())!= nullptr);
  REQUIRE(obj_1.find_node(3, obj_1.root_())!= nullptr);
}
<|endoftext|>


<commit_before>#include <matrix.hpp>
#include <catch.hpp>

SCENARIO("matrix init without parametrs", "[init wp]") {
	Matrix matrix;
	REQUIRE(matrix.rows() == 4);
	REQUIRE(matrix.columns() == 4);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == 0);
		}
	}
}

SCENARIO("matrix init with parametrs", "[init withp]") {
	Matrix matrix(6,6);
	REQUIRE(matrix.rows() == 6);
	REQUIRE(matrix.columns() == 6);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == 0);
		}
	}
}

SCENARIO("matrix init copy", "[init copy]") {
	Matrix matrix(6,6);
	Matrix matrix1(matrix);
	REQUIRE(matrix1.rows() == matrix.rows());
	REQUIRE(matrix1.columns() == matrix.columns());

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == matrix1.Element(i,j));
		}
	}
}

SCENARIO("matrix fill", "[fill]") {
	Matrix matrix(2,2);
	ofstream test1("test1.txt");
	test1 << "1 2 3 4";
	test1.close();
	matrix.fill("test1.txt");
	REQUIRE(matrix.Element(0,0) == 1);
	REQUIRE(matrix.Element(0,1) == 2);
	REQUIRE(matrix.Element(1,0) == 3);
	REQUIRE(matrix.Element(1,1) == 4);
}

SCENARIO("matrix sum", "[sum]") {
	Matrix matrix(2,2);
	Matrix matrix1(2,2);
	Matrix sum(2,2);

	matrix.fill("test1.txt");
	matrix1.fill("test1.txt");
	ofstream sum("sum.txt");
	sum << "2 4 6 8";
	sum.fill("sum.txt")
	REQUIRE(sum == matrix + matrix1);
}

<commit_msg>Update init.cpp<commit_after>#include <matrix.hpp>
#include <catch.hpp>

SCENARIO("matrix init without parametrs", "[init wp]") {
	Matrix matrix;
	REQUIRE(matrix.rows() == 4);
	REQUIRE(matrix.columns() == 4);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == 0);
		}
	}
}

SCENARIO("matrix init with parametrs", "[init withp]") {
	Matrix matrix(6,6);
	REQUIRE(matrix.rows() == 6);
	REQUIRE(matrix.columns() == 6);

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == 0);
		}
	}
}

SCENARIO("matrix init copy", "[init copy]") {
	Matrix matrix(6,6);
	Matrix matrix1(matrix);
	REQUIRE(matrix1.rows() == matrix.rows());
	REQUIRE(matrix1.columns() == matrix.columns());

	for (int i=0;i<matrix.rows(); i++) {
		for (int j = 0; j<matrix.columns();j++) {
			REQUIRE(matrix.Element(i,j) == matrix1.Element(i,j));
		}
	}
}

SCENARIO("matrix fill", "[fill]") {
	Matrix matrix(2,2);
	ofstream test1("test1.txt");
	test1 << "1 2 3 4";
	test1.close();
	matrix.fill("test1.txt");
	REQUIRE(matrix.Element(0,0) == 1);
	REQUIRE(matrix.Element(0,1) == 2);
	REQUIRE(matrix.Element(1,0) == 3);
	REQUIRE(matrix.Element(1,1) == 4);
}

SCENARIO("matrix sum", "[sum]") {
	Matrix matrix(2,2);
	Matrix matrix1(2,2);
	Matrix sum(2,2);

	matrix.fill("test1.txt");
	matrix1.fill("test1.txt");
	ofstream sumfile("sumfile.txt");
	sum << "2 4 6 8";
	sum.fill("sumfile.txt")
	REQUIRE(sum == matrix + matrix1);
}

<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
extern "C" {
  #include "config.h"
  #include "debug.h"
  #include "util.h"
  #include "loop.h"
  #include "process.h"
  #include "profile.h"
  #include "socket.h"
  #include "msg.h"
  #include "iface.h"
  #include "id.h"
}
#include "gtest/gtest.h"

bool timer1_success = false;
bool timer2_success = false;
bool timer3_success = false;

// callback functions
int timer1_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer1_success = true;
  return 1;
}

int timer2_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer2_success = true;
  return 1;
}

int timer3_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer3_success = true;
  return 1;
}

// loop stop function (currently unused)
int loop_stop_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  co_loop_stop(); // breaks loop without returning
}

class LoopTest : public ::testing::Test
{
  protected:
    int ret;

    // context pointers
    co_obj_t *context1;
    co_obj_t *context2;
    co_obj_t *context3;
    co_obj_t *stop;

    // time values
    struct timeval timeval1;
    struct timeval timeval2;
    struct timeval timeval3;
    struct timeval tv_stop;

    // tests
    void Timer();
    void Socket();

    LoopTest()
    {
      ret = co_loop_create();
      // CHECK((poll_fd = epoll_create1(EPOLL_CLOEXEC)) != -1, "Failed to create epoll event.");

      // could add a test with an extra co_loop_create call that is expected to fail
    }

  virtual void SetUp()
  {
  }

  ~LoopTest()
  {
    ret = co_loop_destroy();
  }
};

void LoopTest::Timer()
{
  // intialize timer1
  co_obj_t *timer1 = co_timer_create(timeval1, timer1_cb, context1);
  ret = co_loop_set_timer(timer1, 1, context1);
  ASSERT_EQ(1, ret);

  // initialize timer2
  co_obj_t *timer2 = co_timer_create(timeval2, timer2_cb, context2);
  ret = co_loop_set_timer(timer2, 1, context1);
  ASSERT_EQ(1, ret);

  // initialize timer3
  co_obj_t *timer3 = co_timer_create(timeval3, timer3_cb, context3);
  ret = co_loop_set_timer(timer3, 1, context1);
  ASSERT_EQ(1, ret);

  // stops the loop (after 100 ms)
  co_obj_t *loop_stop = co_timer_create(tv_stop, loop_stop_cb, stop);
  ret = co_loop_set_timer(loop_stop, 100, stop);
  ASSERT_EQ(1, ret);

  co_loop_start();

  EXPECT_TRUE(timer1_success);
  EXPECT_TRUE(timer2_success);
  EXPECT_TRUE(timer3_success);
}

TEST_F(LoopTest, Timer)
{
  Timer();
}

  <commit_msg>reorganized callback functions<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
extern "C" {
  #include "config.h"
  #include "debug.h"
  #include "util.h"
  #include "loop.h"
  #include "process.h"
  #include "profile.h"
  #include "socket.h"
  #include "msg.h"
  #include "iface.h"
  #include "id.h"
}
#include "gtest/gtest.h"

bool timer1_success = false;
bool timer2_success = false;
bool timer3_success = false;

int timer1_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params);
int timer2_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params);
int timer3_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params);
int loop_stop_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params);

class LoopTest : public ::testing::Test
{
  protected:
    int ret;

    // context pointers
    co_obj_t *context1;
    co_obj_t *context2;
    co_obj_t *context3;
    co_obj_t *stop;

    // time values
    struct timeval timeval1;
    struct timeval timeval2;
    struct timeval timeval3;
    struct timeval tv_stop;

    // tests
    void Timer();
    void Socket();

    LoopTest()
    {
      ret = co_loop_create();
      // CHECK((poll_fd = epoll_create1(EPOLL_CLOEXEC)) != -1, "Failed to create epoll event.");
    }

  virtual void SetUp()
  {
  }

  ~LoopTest()
  {
    ret = co_loop_destroy();
  }
};

void LoopTest::Timer()
{
  // intialize timer1
  co_obj_t *timer1 = co_timer_create(timeval1, timer1_cb, context1);
  ret = co_loop_set_timer(timer1, 1, context1);
  ASSERT_EQ(1, ret);

  // initialize timer2
  co_obj_t *timer2 = co_timer_create(timeval2, timer2_cb, context2);
  ret = co_loop_set_timer(timer2, 1, context1);
  ASSERT_EQ(1, ret);

  // initialize timer3
  co_obj_t *timer3 = co_timer_create(timeval3, timer3_cb, context3);
  ret = co_loop_set_timer(timer3, 1, context1);
  ASSERT_EQ(1, ret);

  // stops the loop (after 100 ms)
  co_obj_t *loop_stop = co_timer_create(tv_stop, loop_stop_cb, stop);
  ret = co_loop_set_timer(loop_stop, 100, stop);
  ASSERT_EQ(1, ret);

  co_loop_start();

  EXPECT_TRUE(timer1_success);
  EXPECT_TRUE(timer2_success);
  EXPECT_TRUE(timer3_success);
}

TEST_F(LoopTest, Timer)
{
  Timer();
}

// callback functions
  int timer1_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer1_success = true;
  return 1;
}

int timer2_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer2_success = true;
  return 1;
}

int timer3_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  timer3_success = true;
  return 1;
}

// loop stop function (currently unused)
int loop_stop_cb(co_obj_t *self, co_obj_t **output, co_obj_t *params)
{
  co_loop_stop(); // breaks loop without returning
}<|endoftext|>


<commit_before>/***************************************************************************
 * main.cpp
 * This file is part of the KDE project
 * copyright (C)2004-2007 by Sebastian Sauer (mail@dipe.org)
 *
 * This program 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 ***************************************************************************/

#include "testobject.h"

// Kross
#include <Kross/Core/Action>
#include <Kross/Core/Interpreter>
#include <Kross/Core/Manager>
#include <Kross/Core/WrapperInterface>

// Qt

#include <QtCore/QFile>
#include <QtCore/QArgument>
#include <QtCore/QMetaEnum>
#include <QtWidgets/QApplication>
#include <QtCore/QUrl>

// KDE
#include <QtCore/QDebug>

// for std namespace
#include <string>
#include <iostream>
#include <qcommandlineparser.h>
#include <qcommandlineoption.h>

#define ERROR_OK 0
#define ERROR_HELP -1
#define ERROR_NOSUCHFILE -2
#define ERROR_OPENFAILED -3
#define ERROR_NOINTERPRETER -4
#define ERROR_EXCEPTION -6

QApplication *app = 0;

QString getInterpreterName(const QString &scriptfile)
{
    Kross::InterpreterInfo *interpreterinfo = Kross::Manager::self().interpreterInfo(Kross::Manager::self().interpreternameForFile(scriptfile));
    return interpreterinfo ? interpreterinfo->interpreterName() : QString();
}

int readFile(const QString &scriptfile, QByteArray &content)
{
    QFile f(scriptfile);
    if (! f.exists()) {
        std::cerr << "No such scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_NOSUCHFILE;
    }
    if (! f.open(QIODevice::ReadOnly)) {
        std::cerr << "Failed to open scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_OPENFAILED;
    }
    content = f.readAll();
    f.close();
    return ERROR_OK;
}

int runScriptFile(const QString &scriptfile)
{
    // Read the scriptfile
    QByteArray scriptcode;
    int result = readFile(scriptfile, scriptcode);
    if (result != ERROR_OK) {
        return result;
    }

    // Determinate the matching interpreter
    QString interpretername = getInterpreterName(scriptfile);
    if (interpretername.isNull()) {
        std::cerr << "No interpreter for scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_NOINTERPRETER;
    }

    // First we need a Action and fill it.
    Kross::Action *action = new Kross::Action(0 /*no parent*/, QUrl::fromUserInput(scriptfile));
    action->setObjectName("MyAction");
    action->setInterpreter(interpretername);
    action->setCode(scriptcode);

    // Create the testobject instances.
    TestObject *testobj3 = new TestObject(action, "TestObject3");
    TestObject *testobj4 = new TestObject(action, "TestObject4");

    // Publish other both testobject instance to the script.
    action->addObject(testobj3, "TestObject3", Kross::ChildrenInterface::AutoConnectSignals);
    action->addObject(testobj4, "TestObject4");

    // Now execute the Action.
    std::cout << "Execute scriptfile " << scriptfile.toLatin1().data() << " now" << std::endl;
    action->trigger();
    std::cout << "Execution of scriptfile " << scriptfile.toLatin1().data() << " done" << std::endl;

    /*
    if(action->hadException()) {
        // We had an exception.
        QString errormessage = action->getException()->getError();
        QString tracedetails = action->getException()->getTrace();
        std::cerr << QString("%2\n%1").arg(tracedetails).arg(errormessage).toLatin1().data() << std::endl;
        return ERROR_EXCEPTION;
    }
    */

    delete action;
    return ERROR_OK;
}

QVariant OtherObjectHandler(void *ptr)
{
    OtherObject *obj = static_cast<OtherObject *>(ptr);
    // qDebug()<<"OtherObjectHandler objectName="<<(obj ? obj->objectName() : "NULL");
    OtherObjectWrapper *wrapper = new OtherObjectWrapper(obj);
    QVariant r;
    r.setValue((QObject *) wrapper);
    return r;
}

int main(int argc, char **argv)
{
    std::vector<std::string> strs;
    strs.push_back("1");
    app = new QApplication(argc, argv);
    app->setApplicationName("krosstest");
    app->setApplicationVersion("0.1");
    app->setOrganizationDomain("dipe.org");

    /*K4AboutData about("krosstest",
                     0,
                     ki18n("KrossTest"),
                     "0.1",
                     ki18n("KDE application to test the Kross framework."),
                     K4AboutData::License_LGPL,
                     ki18n("(C) 2005-2007 Sebastian Sauer"),
                     ki18n("Test the Kross framework!"),
                     "http://kross.dipe.org",
                     "kross@dipe.org");*/
    //about.addAuthor(ki18n("Sebastian Sauer"), ki18n("Author"), "mail@dipe.org");

    QCommandLineParser parser;
    parser.setApplicationDescription(QCoreApplication::translate("main", "KDE application to test the Kross framework."));
    parser.addHelpOption();
    parser.addPositionalArgument("file", QCoreApplication::translate("main", "Scriptfile"));
    parser.process(*app);

    const QStringList args = parser.positionalArguments();
    if (args.count() < 1) {
        std::cerr << "No scriptfile to execute defined. See --help" << std::endl;
        return ERROR_HELP;
    }

    QStringList scriptfiles;
    for (int i = 0; i < args.count(); i++) {
        scriptfiles.append(args.at(i));
    }

    // init
    TestObject *testobj1 = new TestObject(0, "TestObject1");
    TestObject *testobj2 = new TestObject(0, "TestObject2");
    Kross::Manager::self().addObject(testobj1);
    Kross::Manager::self().addObject(testobj2);

    Kross::Manager::self().registerMetaTypeHandler("OtherObject*", OtherObjectHandler);

    int result = 0;
    foreach (const QString &file, scriptfiles) {
        result = runScriptFile(file);
        if (result != ERROR_OK) {
            break;
        }
    }

    // finish
    delete testobj1;
    delete testobj2;
    delete app;

    // qDebug() << "DONE!!!";
    return result;
}
<commit_msg>tests: Re-enable error reporting in the test application<commit_after>/***************************************************************************
 * main.cpp
 * This file is part of the KDE project
 * copyright (C)2004-2007 by Sebastian Sauer (mail@dipe.org)
 *
 * This program 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 ***************************************************************************/

#include "testobject.h"

// Kross
#include <Kross/Core/Action>
#include <Kross/Core/Interpreter>
#include <Kross/Core/Manager>
#include <Kross/Core/WrapperInterface>

// Qt

#include <QtCore/QFile>
#include <QtCore/QArgument>
#include <QtCore/QMetaEnum>
#include <QtWidgets/QApplication>
#include <QtCore/QUrl>

// KDE
#include <QtCore/QDebug>

// for std namespace
#include <string>
#include <iostream>
#include <qcommandlineparser.h>
#include <qcommandlineoption.h>

#define ERROR_OK 0
#define ERROR_HELP -1
#define ERROR_NOSUCHFILE -2
#define ERROR_OPENFAILED -3
#define ERROR_NOINTERPRETER -4
#define ERROR_EXCEPTION -6

QApplication *app = 0;

QString getInterpreterName(const QString &scriptfile)
{
    Kross::InterpreterInfo *interpreterinfo = Kross::Manager::self().interpreterInfo(Kross::Manager::self().interpreternameForFile(scriptfile));
    return interpreterinfo ? interpreterinfo->interpreterName() : QString();
}

int readFile(const QString &scriptfile, QByteArray &content)
{
    QFile f(scriptfile);
    if (! f.exists()) {
        std::cerr << "No such scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_NOSUCHFILE;
    }
    if (! f.open(QIODevice::ReadOnly)) {
        std::cerr << "Failed to open scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_OPENFAILED;
    }
    content = f.readAll();
    f.close();
    return ERROR_OK;
}

int runScriptFile(const QString &scriptfile)
{
    // Read the scriptfile
    QByteArray scriptcode;
    int result = readFile(scriptfile, scriptcode);
    if (result != ERROR_OK) {
        return result;
    }

    // Determinate the matching interpreter
    QString interpretername = getInterpreterName(scriptfile);
    if (interpretername.isNull()) {
        std::cerr << "No interpreter for scriptfile: " << scriptfile.toLatin1().data() << std::endl;
        return ERROR_NOINTERPRETER;
    }

    // First we need a Action and fill it.
    Kross::Action *action = new Kross::Action(0 /*no parent*/, QUrl::fromUserInput(scriptfile));
    action->setObjectName("MyAction");
    action->setInterpreter(interpretername);
    action->setCode(scriptcode);

    // Create the testobject instances.
    TestObject *testobj3 = new TestObject(action, "TestObject3");
    TestObject *testobj4 = new TestObject(action, "TestObject4");

    // Publish other both testobject instance to the script.
    action->addObject(testobj3, "TestObject3", Kross::ChildrenInterface::AutoConnectSignals);
    action->addObject(testobj4, "TestObject4");

    // Now execute the Action.
    std::cout << "Execute scriptfile " << scriptfile.toLatin1().data() << " now" << std::endl;
    action->trigger();
    std::cout << "Execution of scriptfile " << scriptfile.toLatin1().data() << " done" << std::endl;

    if (action->hadError()) {
        // We had an exception.
        QString errormessage = action->errorMessage();
        QString tracedetails = action->errorTrace();
        std::cerr << QString("%2\n%1").arg(tracedetails).arg(errormessage).toLatin1().data() << std::endl;
        return ERROR_EXCEPTION;
    }

    delete action;
    return ERROR_OK;
}

QVariant OtherObjectHandler(void *ptr)
{
    OtherObject *obj = static_cast<OtherObject *>(ptr);
    // qDebug()<<"OtherObjectHandler objectName="<<(obj ? obj->objectName() : "NULL");
    OtherObjectWrapper *wrapper = new OtherObjectWrapper(obj);
    QVariant r;
    r.setValue((QObject *) wrapper);
    return r;
}

int main(int argc, char **argv)
{
    std::vector<std::string> strs;
    strs.push_back("1");
    app = new QApplication(argc, argv);
    app->setApplicationName("krosstest");
    app->setApplicationVersion("0.1");
    app->setOrganizationDomain("dipe.org");

    /*K4AboutData about("krosstest",
                     0,
                     ki18n("KrossTest"),
                     "0.1",
                     ki18n("KDE application to test the Kross framework."),
                     K4AboutData::License_LGPL,
                     ki18n("(C) 2005-2007 Sebastian Sauer"),
                     ki18n("Test the Kross framework!"),
                     "http://kross.dipe.org",
                     "kross@dipe.org");*/
    //about.addAuthor(ki18n("Sebastian Sauer"), ki18n("Author"), "mail@dipe.org");

    QCommandLineParser parser;
    parser.setApplicationDescription(QCoreApplication::translate("main", "KDE application to test the Kross framework."));
    parser.addHelpOption();
    parser.addPositionalArgument("file", QCoreApplication::translate("main", "Scriptfile"));
    parser.process(*app);

    const QStringList args = parser.positionalArguments();
    if (args.count() < 1) {
        std::cerr << "No scriptfile to execute defined. See --help" << std::endl;
        return ERROR_HELP;
    }

    QStringList scriptfiles;
    for (int i = 0; i < args.count(); i++) {
        scriptfiles.append(args.at(i));
    }

    // init
    TestObject *testobj1 = new TestObject(0, "TestObject1");
    TestObject *testobj2 = new TestObject(0, "TestObject2");
    Kross::Manager::self().addObject(testobj1);
    Kross::Manager::self().addObject(testobj2);

    Kross::Manager::self().registerMetaTypeHandler("OtherObject*", OtherObjectHandler);

    int result = 0;
    foreach (const QString &file, scriptfiles) {
        result = runScriptFile(file);
        if (result != ERROR_OK) {
            break;
        }
    }

    // finish
    delete testobj1;
    delete testobj2;
    delete app;

    // qDebug() << "DONE!!!";
    return result;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2010-2013 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

/*
 * Copyright 2012 Matthew Endsley
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted providing that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "test.h"

#if BX_PLATFORM_ANDROID
#include <android/native_activity.h>

void ANativeActivity_onCreate(ANativeActivity*, void*, size_t)
{
	exit(UnitTest::RunAllTests() );
}
#else
int main()
{
	return UnitTest::RunAllTests();
}
#endif // BX_PLATFORM
<commit_msg>Added compiler info to tests.<commit_after>/*
 * Copyright 2010-2013 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

/*
 * Copyright 2012 Matthew Endsley
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted providing that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "test.h"

int runAllTests()
{
	DBG(BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME);
	return UnitTest::RunAllTests();
}

#if BX_PLATFORM_ANDROID
#include <android/native_activity.h>

void ANativeActivity_onCreate(ANativeActivity*, void*, size_t)
{
	exit(runAllTests() );
}
#else
int main()
{
	return runAllTests();
}
#endif // BX_PLATFORM
<|endoftext|>


<commit_before>
//   Copyright 2016 otris software AG
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
//   This project is hosted at https://github.com/otris

#include <ews/ews_test_support.hpp>
#include <gtest/gtest.h>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <ostream>
#include <stdexcept>
#include <string>
#include <unordered_map>

#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#endif

typedef std::unordered_map<std::string, std::string> argument_map;

namespace
{
    bool starts_with(const char* prefix, const std::string& str)
    {
        return !str.compare(0, std::strlen(prefix), prefix);
    }

    bool is(const char* prefix, const std::string& arg, argument_map& map)
    {
        if (starts_with(prefix, arg))
        {
            const auto value = arg.substr(std::strlen(prefix));
            map[prefix] = value;
            return true;
        }
        return false;
    }

    std::string pwd()
    {
        enum
        {
            size = 4096U
        };
        char buf[size];
        auto ret = ::getcwd(buf, size);
        return ret != nullptr ? std::string(buf)
                              : throw std::runtime_error("getcwd failed");
    }

    // Parse and interpret command line flags that we recognize. Remove them
    // from argv. Leave the rest untouched.
    void init_from_args(int* argc, char** argv)
    {
        argument_map args;

        for (int i = 1; i < *argc; i++)
        {
            const auto arg = std::string(argv[i]);

            // Do we see a flag that we recognize?
            if (is("--assets=", arg, args))
            {
                // Finally, shift remainder of argv left by one. Note that argv
                // has (*argc + 1) elements, the last one always being null.
                // The following loop moves the trailing null element as well.
                for (int j = i; j != *argc; j++)
                {
                    argv[j] = argv[j + 1];
                }

                // Decrements the argument count.
                (*argc)--;

                // We also need to decrement the iterator as we just removed an
                // element.
                i--;
            }
            else if (arg == "--help" || arg == "-h" || arg == "-?" ||
                     arg == "/?")
            {
                std::cout << "usage: tests [--assets=PATH]\n"
                             "\n"
                             "--assets=PATH  path to the test assets "
                             "directory, default\n"
                             "               $PWD/tests/assets\n"
                             "\n"
                             "invoke with --gtest_help to see Google Test flags"
                          << std::endl;

                std::exit(EXIT_FAILURE);
            }
            else if (is("--gtest_help", arg, args))
            {
                return;
            }
        }

#ifdef _WIN32
        auto assets_dir = std::string(pwd() + "\\tests\\assets");
#else
        auto assets_dir = std::string(pwd() + "/tests/assets");
#endif
        auto it = args.find("--assets=");
        if (it != args.end())
        {
            assets_dir = it->second;

            // If a word begins with an unquoted tilde character replace it
            // with value of $HOME or %USERPROFILE%, respectively

            if (starts_with("~", assets_dir))
            {
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif

                const char* const env = getenv("USERPROFILE");

#ifdef _MSC_VER
#pragma warning(pop)
#endif
#else
                const char* const env = getenv("HOME");
#endif

                assets_dir.replace(0, 1, env);
            }
        }
        ews::test::global_data::instance().assets_dir = assets_dir;
        std::cout << "Loading assets from: '" << assets_dir << "'\n";
    }
}

int main(int argc, char** argv)
{
    init_from_args(&argc, argv);
    std::cout << "Running tests from main.cpp\n";
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

// vim:et ts=4 sw=4 noic cc=80
<commit_msg>relative path support for test assert files<commit_after>
//   Copyright 2016 otris software AG
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//
//   This project is hosted at https://github.com/otris

#include <ews/ews_test_support.hpp>
#include <gtest/gtest.h>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <ostream>
#include <stdexcept>
#include <string>
#include <unordered_map>

#ifdef _WIN32
#include <direct.h>
#define getcwd _getcwd
#else
#include <limits.h>
#include <unistd.h>
#endif

typedef std::unordered_map<std::string, std::string> argument_map;

namespace
{
    bool starts_with(const char* prefix, const std::string& str)
    {
        return !str.compare(0, std::strlen(prefix), prefix);
    }

    bool is(const char* prefix, const std::string& arg, argument_map& map)
    {
        if (starts_with(prefix, arg))
        {
            const auto value = arg.substr(std::strlen(prefix));
            map[prefix] = value;
            return true;
        }
        return false;
    }

    std::string pwd()
    {
        enum
        {
            size = 4096U
        };
        char buf[size];
        auto ret = ::getcwd(buf, size);
        return ret != nullptr ? std::string(buf)
                              : throw std::runtime_error("getcwd failed");
    }

    // Parse and interpret command line flags that we recognize. Remove them
    // from argv. Leave the rest untouched.
    void init_from_args(int* argc, char** argv)
    {
        argument_map args;

        for (int i = 1; i < *argc; i++)
        {
            const auto arg = std::string(argv[i]);

            // Do we see a flag that we recognize?
            if (is("--assets=", arg, args))
            {
                // Finally, shift remainder of argv left by one. Note that argv
                // has (*argc + 1) elements, the last one always being null.
                // The following loop moves the trailing null element as well.
                for (int j = i; j != *argc; j++)
                {
                    argv[j] = argv[j + 1];
                }

                // Decrements the argument count.
                (*argc)--;

                // We also need to decrement the iterator as we just removed an
                // element.
                i--;
            }
            else if (arg == "--help" || arg == "-h" || arg == "-?" ||
                     arg == "/?")
            {
                std::cout << "usage: tests [--assets=PATH]\n"
                             "\n"
                             "--assets=PATH  path to the test assets "
                             "directory, default\n"
                             "               $PWD/tests/assets\n"
                             "\n"
                             "invoke with --gtest_help to see Google Test flags"
                          << std::endl;

                std::exit(EXIT_FAILURE);
            }
            else if (is("--gtest_help", arg, args))
            {
                return;
            }
        }

#ifdef _WIN32
        auto assets_dir = std::string(pwd() + "\\tests\\assets");
#else
        auto assets_dir = std::string(pwd() + "/tests/assets");
#endif
        auto it = args.find("--assets=");
        if (it != args.end())
        {
            assets_dir = it->second;

            // If a word begins with an unquoted tilde character replace it
            // with value of $HOME or %USERPROFILE%, respectively

            if (starts_with("~", assets_dir))
            {
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif

                const char* const env = getenv("USERPROFILE");

#ifdef _MSC_VER
#pragma warning(pop)
#endif
#else
                const char* const env = getenv("HOME");
#endif

                assets_dir.replace(0, 1, env);
            }

            // Expand relative paths

            char* res = nullptr;
#ifdef _WIN32
            std::vector<char> abspath(MAX_PATH);
            res = _fullpath(&abspath[0], &assets_dir.c_str(), 1000);
#else
            std::vector<char> abspath(FILENAME_MAX);
            res = realpath(assets_dir.c_str(), &abspath[0]);
#endif
            if (res == nullptr)
            {
                std::cout << "No such directory: '" << assets_dir << "'\n";
                std::exit(EXIT_FAILURE);
            }

            assets_dir = std::string(&abspath[0]);
        }

        ews::test::global_data::instance().assets_dir = assets_dir;
        std::cout << "Loading assets from: '" << assets_dir << "'\n";
    }
}

int main(int argc, char** argv)
{
    init_from_args(&argc, argv);
    std::cout << "Running tests from main.cpp\n";
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

// vim:et ts=4 sw=4 noic cc=80
<|endoftext|>