<commit_before>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<string>* vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec->begin() ; it != vec->end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testRelationJSONEntityEncoding() {
    // Create entities
    // Create relation in redis
    // Fetch the entity representation
    // assert
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testRelationJSONRelationEncoding() {
    // Create entities
    // Create relation in redis
    // Fetch the field representation
    // assert
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
    testRegexForTypes();
    testOrderPairAlphaNumeric();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<commit_msg>flesh out functional portion of entity encoding test<commit_after>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<std::string> vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec.begin() ; it != vec.end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testJSONEntityEncoding() {
    IndexHandler ih;
    Json::Value* ret;
    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent = new vector<std::pair<ColumnBase*, std::string>>;
    fields_ent->push_back(std::make_pair(getColumnType("integer"), "a"));
    ih.writeEntity("test", fields_ent);
    // Fetch the entity representation
    ret = ih.fetchEntity("test");
    cout << ret->toStyledString() << endl;

    // TODO - assert
    // TODO - remove entity
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testRelationJSONRelationEncoding() {
//    IndexHandler ih;
//    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_1 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<ColumnBase*, std::string>>* fields_ent_2 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<std::string, std::string>>* fields_rel_1 = new vector<std::pair<ColumnBase*, std::string>>;
//    std::vector<std::pair<std::string, std::string>>* fields_rel_2 = new vector<std::pair<ColumnBase*, std::string>>;
//
//    // Popualate fields
//    fields_ent_1->push_back(std::make_pair(getColumnType("integer"), "a"));
//    fields_ent_2->push_back(std::make_pair(getColumnType("string"), "b"));
//    fields_rel_1->push_back(std::make_pair("a", "1"));
//    fields_rel_2->push_back(std::make_pair("b", "hello"));
//
//    // Create entities
//    ih.writeEntity("test_1", fields_ent_1);
//    ih.writeEntity("test_2", fields_ent_1);
//
//    // Create relation in redis
//    ih.writeRelation("test_1", "test_2", fields_rel_1, fields_rel_2)

    // Fetch the entity representation

    // assert
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
//    testRegexForTypes();
//    testOrderPairAlphaNumeric();
    testJSONEntityEncoding();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<|endoftext|>


<commit_before>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "hdr-merge.h"

namespace librealsense
{
    hdr_merge::hdr_merge()
        : generic_processing_block("HDR Merge")
    {}

    // processing only framesets
    bool hdr_merge::should_process(const rs2::frame& frame)
    {
        if (!frame)
            return false;

        auto set = frame.as<rs2::frameset>();
        if (!set)
            return false;

        auto depth_frame = set.get_depth_frame();
        if (!depth_frame)
            return false;

        if (!depth_frame.supports_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_SIZE))
            return false;
        if (!depth_frame.supports_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID))
            return false;
        int depth_sequ_size = depth_frame.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_SIZE);
        if (depth_sequ_size != 2)
            return false;

        return true;
    }

    rs2::frame hdr_merge::process_frame(const rs2::frame_source& source, const rs2::frame& f)
    {
        // steps:
        // 1. get depth frame from incoming frameset
        // 2. add the frameset to vector of framesets
        // 3. check if size of this vector is at least 2 (if not - return latest merge frame)
        // 4. pop out both framesets from the vector
        // 5. apply merge algo
        // 6. save merge frame as latest merge frame
        // 7. return the merge frame

        // 1. get depth frame from incoming frameset
        auto fs = f.as<rs2::frameset>();
        auto depth_frame = fs.get_depth_frame();

        // 2. add the frameset to vector of framesets
        int depth_sequ_id = depth_frame.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);

        // condition added to ensure that frames are saved in the right order
        // to prevent for example the saving of frame with sequence id 1 before
        // saving frame of sequence id 0
        // so that the merging with be deterministic - always done with frame n and n+1
        // with frame n as basis
        if (_framesets.size() == depth_sequ_id)
        {
            _framesets[depth_sequ_id] = fs;
        }

        // 3. check if size of this vector is at least 2 (if not - return latest merge frame)
        if (_framesets.size() >= 2)
        {
            // 4. pop out both framesets from the vector
            rs2::frameset fs_0 = _framesets[0];
            rs2::frameset fs_1 = _framesets[1];
            _framesets.clear();

            bool use_ir = false;
            if (check_frames_mergeability(fs_0, fs_1, use_ir))
            {
                // 5. apply merge algo
                rs2::frame new_frame = merging_algorithm(source, fs_0, fs_1, use_ir);
                if (new_frame)
                {
                    // 6. save merge frame as latest merge frame
                    _depth_merged_frame = new_frame;
                }
            }
            else
            {
                discard_depth_merged_frame_if_needed(f);
            }
        }

        // 7. return the merge frame
        if (_depth_merged_frame)
            return _depth_merged_frame;

        return f;
    }

    void hdr_merge::discard_depth_merged_frame_if_needed(const rs2::frame& f)
    {
        // criteria for discarding saved merged_depth_frame:
        // if its frame counter is greater than the input frame
        auto depth_merged_frame_counter = _depth_merged_frame.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);
        auto input_frame_counter = f.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);
        if (depth_merged_frame_counter > input_frame_counter)
        {
            _depth_merged_frame = nullptr;
        }
    }

    bool hdr_merge::check_frames_mergeability(const rs2::frameset first_fs, const rs2::frameset second_fs,
        bool& use_ir) const
    {
        auto first_depth = first_fs.get_depth_frame();
        auto second_depth = second_fs.get_depth_frame();
        auto first_ir = first_fs.get_infrared_frame();
        auto second_ir = second_fs.get_infrared_frame();

        auto first_fs_frame_counter = first_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);
        auto second_fs_frame_counter = second_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);

        // The aim of this checking is that the output merged frame will have frame counter n and
        // frame counter n and will be created by frames n and n+1
        if (first_fs_frame_counter + 1 != second_fs_frame_counter)
            return false;

        use_ir = should_ir_be_used_for_merging(first_depth, first_ir, second_depth, second_ir);

        return true;
    }

    rs2::frame hdr_merge::merging_algorithm(const rs2::frame_source& source, const rs2::frameset first_fs, const rs2::frameset second_fs, const bool use_ir)
    {
        auto first = first_fs;
        auto second = second_fs;

        auto first_depth = first.get_depth_frame();
        auto second_depth = second.get_depth_frame();
        auto first_ir = first.get_infrared_frame();
        auto second_ir = second.get_infrared_frame();

        // new frame allocation
        auto vf = first_depth.as<rs2::depth_frame>();
        auto width = vf.get_width();
        auto height = vf.get_height();
        auto new_f = source.allocate_video_frame(first_depth.get_profile(), first_depth,
            vf.get_bytes_per_pixel(), width, height, vf.get_stride_in_bytes(), RS2_EXTENSION_DEPTH_FRAME);

        if (new_f)
        {
            auto ptr = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)new_f.get());
            auto orig = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)first_depth.get());

            auto d0 = (uint16_t*)first_depth.get_data();
            auto d1 = (uint16_t*)second_depth.get_data();

            auto new_data = (uint16_t*)ptr->get_frame_data();

            ptr->set_sensor(orig->get_sensor());

            memset(new_data, 0, width * height * sizeof(uint16_t));

            if (use_ir)
            {
                auto i0 = (uint8_t*)first_ir.get_data();
                auto i1 = (uint8_t*)second_ir.get_data();

                for (int i = 0; i < width * height; i++)
                {
                    if (is_infrared_valid(i0[i]) && d0[i])
                        new_data[i] = d0[i];
                    else if (is_infrared_valid(i1[i]) && d1[i])
                        new_data[i] = d1[i];
                    else
                        new_data[i] = 0;
                }
            }
            else
            {
                for (int i = 0; i < width * height; i++)
                {
                    if (d0[i])
                        new_data[i] = d0[i];
                    else if (d1[i])
                        new_data[i] = d1[i];
                    else
                        new_data[i] = 0;
                }
            }

            return new_f;
        }
        return first_fs;
    }

    bool hdr_merge::is_infrared_valid(uint8_t ir_value) const
    {
        return (ir_value > IR_UNDER_SATURATED_VALUE) && (ir_value < IR_OVER_SATURATED_VALUE);
    }

    bool hdr_merge::should_ir_be_used_for_merging(const rs2::depth_frame& first_depth, const rs2::video_frame& first_ir,
        const rs2::depth_frame& second_depth, const rs2::video_frame& second_ir) const
    {
        // checking ir frames are not null
        bool use_ir = (first_ir && second_ir);

        // checking frame counter of first depth and ir are the same
        if (use_ir)
        {
            int depth_frame_counter = static_cast<int>(first_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
            int ir_frame_counter = static_cast<int>(first_ir.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
            use_ir = (depth_frame_counter == ir_frame_counter);

            // checking frame counter of second depth and ir are the same
            if (use_ir)
            {
                depth_frame_counter = static_cast<int>(second_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
                ir_frame_counter = static_cast<int>(second_ir.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
                use_ir = (depth_frame_counter == ir_frame_counter);

                // checking sequence id of first depth and ir are the same
                if (use_ir)
                {
                    auto depth_seq_id = first_depth.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                    auto ir_seq_id = first_ir.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                    use_ir = (depth_seq_id == ir_seq_id);

                    // checking sequence id of second depth and ir are the same
                    if (use_ir)
                    {
                        depth_seq_id = second_depth.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                        ir_seq_id = second_ir.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                        use_ir = (depth_seq_id == ir_seq_id);
                    }
                }
            }
        }

        return use_ir;
    }
}
<commit_msg>Fix HDR on change of resolutions<commit_after>// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.

#include "hdr-merge.h"

namespace librealsense
{
    hdr_merge::hdr_merge()
        : generic_processing_block("HDR Merge")
    {}

    // processing only framesets
    bool hdr_merge::should_process(const rs2::frame& frame)
    {
        if (!frame)
            return false;

        auto set = frame.as<rs2::frameset>();
        if (!set)
            return false;

        auto depth_frame = set.get_depth_frame();
        if (!depth_frame)
            return false;

        if (!depth_frame.supports_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_SIZE))
            return false;
        if (!depth_frame.supports_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID))
            return false;
        auto depth_seq_size = depth_frame.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_SIZE);
        if (depth_seq_size != 2)
            return false;

        return true;
    }

    rs2::frame hdr_merge::process_frame(const rs2::frame_source& source, const rs2::frame& f)
    {
        // steps:
        // 1. get depth frame from incoming frameset
        // 2. add the frameset to vector of framesets
        // 3. check if size of this vector is at least 2 (if not - return latest merge frame)
        // 4. pop out both framesets from the vector
        // 5. apply merge algo
        // 6. save merge frame as latest merge frame
        // 7. return the merge frame

        // 1. get depth frame from incoming frameset
        auto fs = f.as<rs2::frameset>();
        auto depth_frame = fs.get_depth_frame();

        // 2. add the frameset to vector of framesets
        auto depth_seq_id = depth_frame.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);

        // condition added to ensure that frames are saved in the right order
        // to prevent for example the saving of frame with sequence id 1 before
        // saving frame of sequence id 0
        // so that the merging with be deterministic - always done with frame n and n+1
        // with frame n as basis
        if (_framesets.size() == depth_seq_id)
        {
            _framesets[depth_seq_id] = fs;
        }

        // 3. check if size of this vector is at least 2 (if not - return latest merge frame)
        if (_framesets.size() >= 2)
        {
            // 4. pop out both framesets from the vector
            rs2::frameset fs_0 = _framesets[0];
            rs2::frameset fs_1 = _framesets[1];
            _framesets.clear();

            bool use_ir = false;
            if (check_frames_mergeability(fs_0, fs_1, use_ir))
            {
                // 5. apply merge algo
                rs2::frame new_frame = merging_algorithm(source, fs_0, fs_1, use_ir);
                if (new_frame)
                {
                    // 6. save merge frame as latest merge frame
                    _depth_merged_frame = new_frame;
                }
            }
            else
            {
                discard_depth_merged_frame_if_needed(f);
            }
        }

        // 7. return the merge frame
        if (_depth_merged_frame)
            return _depth_merged_frame;

        return f;
    }

    void hdr_merge::discard_depth_merged_frame_if_needed(const rs2::frame& f)
    {
        if (_depth_merged_frame)
        {
            // criteria for discarding saved merged_depth_frame:
            // 1 - frame counter for merged depth is greater than the input frame
            // 2 - resolution change
            auto depth_merged_frame_counter = _depth_merged_frame.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);
            auto input_frame_counter = f.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);

            auto merged_d_profile = _depth_merged_frame.get_profile().as<rs2::video_stream_profile>();
            auto new_d_profile = f.get_profile().as<rs2::video_stream_profile>();

            if ((depth_merged_frame_counter > input_frame_counter) ||
                (merged_d_profile.width() != new_d_profile.width()) ||
                (merged_d_profile.height() != new_d_profile.height()))
            {
                _depth_merged_frame = nullptr;
            }
        }
    }

    bool hdr_merge::check_frames_mergeability(const rs2::frameset first_fs, const rs2::frameset second_fs,
        bool& use_ir) const
    {
        auto first_depth = first_fs.get_depth_frame();
        auto second_depth = second_fs.get_depth_frame();
        auto first_ir = first_fs.get_infrared_frame();
        auto second_ir = second_fs.get_infrared_frame();

        auto first_fs_frame_counter = first_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);
        auto second_fs_frame_counter = second_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER);

        // The aim of this checking is that the output merged frame will have frame counter n and
        // frame counter n and will be created by frames n and n+1
        if (first_fs_frame_counter + 1 != second_fs_frame_counter)
            return false;
        // Depth dimensions must align
        if ((first_depth.get_height() != second_depth.get_height()) ||
            (first_depth.get_width() != second_depth.get_width()))
            return false;

        use_ir = should_ir_be_used_for_merging(first_depth, first_ir, second_depth, second_ir);

        return true;
    }

    rs2::frame hdr_merge::merging_algorithm(const rs2::frame_source& source, const rs2::frameset first_fs, const rs2::frameset second_fs, const bool use_ir)
    {
        auto first = first_fs;
        auto second = second_fs;

        auto first_depth = first.get_depth_frame();
        auto second_depth = second.get_depth_frame();
        auto first_ir = first.get_infrared_frame();
        auto second_ir = second.get_infrared_frame();

        // new frame allocation
        auto vf = first_depth.as<rs2::depth_frame>();
        auto width = vf.get_width();
        auto height = vf.get_height();
        auto new_f = source.allocate_video_frame(first_depth.get_profile(), first_depth,
            vf.get_bytes_per_pixel(), width, height, vf.get_stride_in_bytes(), RS2_EXTENSION_DEPTH_FRAME);

        if (new_f)
        {
            auto ptr = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)new_f.get());
            auto orig = dynamic_cast<librealsense::depth_frame*>((librealsense::frame_interface*)first_depth.get());

            auto d0 = (uint16_t*)first_depth.get_data();
            auto d1 = (uint16_t*)second_depth.get_data();

            auto new_data = (uint16_t*)ptr->get_frame_data();

            ptr->set_sensor(orig->get_sensor());

            memset(new_data, 0, width * height * sizeof(uint16_t));

            if (use_ir)
            {
                auto i0 = (uint8_t*)first_ir.get_data();
                auto i1 = (uint8_t*)second_ir.get_data();

                for (int i = 0; i < width * height; i++)
                {
                    if (is_infrared_valid(i0[i]) && d0[i])
                        new_data[i] = d0[i];
                    else if (is_infrared_valid(i1[i]) && d1[i])
                        new_data[i] = d1[i];
                    else
                        new_data[i] = 0;
                }
            }
            else
            {
                for (int i = 0; i < width * height; i++)
                {
                    if (d0[i])
                        new_data[i] = d0[i];
                    else if (d1[i])
                        new_data[i] = d1[i];
                    else
                        new_data[i] = 0;
                }
            }

            return new_f;
        }
        return first_fs;
    }

    bool hdr_merge::is_infrared_valid(uint8_t ir_value) const
    {
        return (ir_value > IR_UNDER_SATURATED_VALUE) && (ir_value < IR_OVER_SATURATED_VALUE);
    }

    bool hdr_merge::should_ir_be_used_for_merging(const rs2::depth_frame& first_depth, const rs2::video_frame& first_ir,
        const rs2::depth_frame& second_depth, const rs2::video_frame& second_ir) const
    {
        // checking ir frames are not null
        bool use_ir = (first_ir && second_ir);

        // IR and Depth dimensions must be aligned
        if ((first_depth.get_height() != first_ir.get_height()) ||
            (first_depth.get_width() != first_ir.get_width()) ||
            (second_ir.get_height() != first_ir.get_height()) ||
            (second_ir.get_width() != first_ir.get_width()))
            use_ir =  false;

        // checking frame counter of first depth and ir are the same
        if (use_ir)
        {
            int depth_frame_counter = static_cast<int>(first_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
            int ir_frame_counter = static_cast<int>(first_ir.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
            use_ir = (depth_frame_counter == ir_frame_counter);

            // checking frame counter of second depth and ir are the same
            if (use_ir)
            {
                depth_frame_counter = static_cast<int>(second_depth.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
                ir_frame_counter = static_cast<int>(second_ir.get_frame_metadata(RS2_FRAME_METADATA_FRAME_COUNTER));
                use_ir = (depth_frame_counter == ir_frame_counter);

                // checking sequence id of first depth and ir are the same
                if (use_ir)
                {
                    auto depth_seq_id = first_depth.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                    auto ir_seq_id = first_ir.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                    use_ir = (depth_seq_id == ir_seq_id);

                    // checking sequence id of second depth and ir are the same
                    if (use_ir)
                    {
                        depth_seq_id = second_depth.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                        ir_seq_id = second_ir.get_frame_metadata(RS2_FRAME_METADATA_SUBPRESET_SEQUENCE_ID);
                        use_ir = (depth_seq_id == ir_seq_id);
                    }
                }
            }
        }

        return use_ir;
    }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

// mapnik
#include <mapnik/proj_transform.hpp>
#include <mapnik/utils.hpp>
// proj4
#include <proj_api.h>

namespace mapnik {

proj_transform::proj_transform(projection const& source,
                               projection const& dest)
    : source_(source),
      dest_(dest)
{
    is_source_longlat_ = source_.is_geographic();
    is_dest_longlat_ = dest_.is_geographic();
    is_source_equal_dest_ = (source_ == dest_);
}

bool proj_transform::equal() const
{
    return is_source_equal_dest_;
}

bool proj_transform::forward (double & x, double & y , double & z) const
{
    if (is_source_equal_dest_)
        return true;

    if (is_source_longlat_)
    {
        x *= DEG_TO_RAD;
        y *= DEG_TO_RAD;
    }

#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
    mutex::scoped_lock lock(projection::mutex_);
#endif

    if (pj_transform( source_.proj_, dest_.proj_, 1,
                      0, &x,&y,&z) != 0)
    {
        return false;
    }

    if (is_dest_longlat_)
    {
        x *= RAD_TO_DEG;
        y *= RAD_TO_DEG;
    }

    return true;
}

bool proj_transform::backward (double & x, double & y , double & z) const
{
    if (is_source_equal_dest_)
        return true;

    if (is_dest_longlat_)
    {
        x *= DEG_TO_RAD;
        y *= DEG_TO_RAD;
    }

#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
    mutex::scoped_lock lock(projection::mutex_);
#endif

    if (pj_transform( dest_.proj_, source_.proj_, 1,
                      0, &x,&y,&z) != 0)
    {
        return false;
    }

    if (is_source_longlat_)
    {
        x *= RAD_TO_DEG;
        y *= RAD_TO_DEG;
    }

    return true;
}

bool proj_transform::forward (box2d<double> & box) const
{
    if (is_source_equal_dest_)
        return true;
    double minx = box.minx();
    double miny = box.miny();
    double maxx = box.maxx();
    double maxy = box.maxy();
    double z = 0.0;
    bool ok0 = forward(minx,miny,z);
    bool ok1 = forward(maxx,maxy,z);
    box.init(minx,miny,maxx,maxy);
    return ok0 & ok1;
}

bool proj_transform::backward (box2d<double> & box) const
{
    if (is_source_equal_dest_)
        return true;

    double minx = box.minx();
    double miny = box.miny();
    double maxx = box.maxx();
    double maxy = box.maxy();
    double z = 0.0;
    bool ok0 = backward(minx,miny,z);
    bool ok1 = backward(maxx,maxy,z);
    box.init(minx,miny,maxx,maxy);
    return ok0 & ok1;
}

mapnik::projection const& proj_transform::source() const
{
    return source_;
}
mapnik::projection const& proj_transform::dest() const
{
    return dest_;
}

}
<commit_msg>fix return from proj_transform when coordinates cannot be reprojected<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

// mapnik
#include <mapnik/proj_transform.hpp>
#include <mapnik/utils.hpp>
// proj4
#include <proj_api.h>

namespace mapnik {

proj_transform::proj_transform(projection const& source,
                               projection const& dest)
    : source_(source),
      dest_(dest)
{
    is_source_longlat_ = source_.is_geographic();
    is_dest_longlat_ = dest_.is_geographic();
    is_source_equal_dest_ = (source_ == dest_);
}

bool proj_transform::equal() const
{
    return is_source_equal_dest_;
}

bool proj_transform::forward (double & x, double & y , double & z) const
{
    if (is_source_equal_dest_)
        return true;

    if (is_source_longlat_)
    {
        x *= DEG_TO_RAD;
        y *= DEG_TO_RAD;
    }

#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
    mutex::scoped_lock lock(projection::mutex_);
#endif

    if (pj_transform( source_.proj_, dest_.proj_, 1,
                      0, &x,&y,&z) != 0)
    {
        return false;
    }

    if (is_dest_longlat_)
    {
        x *= RAD_TO_DEG;
        y *= RAD_TO_DEG;
    }

    return true;
}

bool proj_transform::backward (double & x, double & y , double & z) const
{
    if (is_source_equal_dest_)
        return true;

    if (is_dest_longlat_)
    {
        x *= DEG_TO_RAD;
        y *= DEG_TO_RAD;
    }

#if defined(MAPNIK_THREADSAFE) && PJ_VERSION < 480
    mutex::scoped_lock lock(projection::mutex_);
#endif

    if (pj_transform( dest_.proj_, source_.proj_, 1,
                      0, &x,&y,&z) != 0)
    {
        return false;
    }

    if (is_source_longlat_)
    {
        x *= RAD_TO_DEG;
        y *= RAD_TO_DEG;
    }

    return true;
}

bool proj_transform::forward (box2d<double> & box) const
{
    if (is_source_equal_dest_)
        return true;
    double minx = box.minx();
    double miny = box.miny();
    double maxx = box.maxx();
    double maxy = box.maxy();
    double z = 0.0;
    if (!forward(minx,miny,z))
        return false;
    if (!forward(maxx,maxy,z))
        return false;
    box.init(minx,miny,maxx,maxy);
    return true;
}

bool proj_transform::backward (box2d<double> & box) const
{
    if (is_source_equal_dest_)
        return true;

    double minx = box.minx();
    double miny = box.miny();
    double maxx = box.maxx();
    double maxy = box.maxy();
    double z = 0.0;
    if (!backward(minx,miny,z))
        return false;
    if (!backward(maxx,maxy,z))
        return false;
    box.init(minx,miny,maxx,maxy);
    return true;
}

mapnik::projection const& proj_transform::source() const
{
    return source_;
}
mapnik::projection const& proj_transform::dest() const
{
    return dest_;
}

}
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include <gtest/gtest.h>
#include <Eigen/Dense>
#include "geometry_msgs/Wrench.h"
#include "uranus_dp/State.h"

class ControllerTest : public ::testing::Test {
public:
    ControllerTest()
    {
        state_pub_     = node_handle_.advertise<uranus_dp::State>("state", 5);
        setpoint_pub_  = node_handle_.advertise<uranus_dp::State>("setpoint", 5);
        subscriber_    = node_handle_.subscribe("control_input", 5, &ControllerTest::Callback, this);
        message_received_ = false;
    }

    void SetUp()
    {
        while (!IsNodeReady())
        {
            ros::spinOnce();
        }
    }

    // void PublishState(Eigen::Vector3 p, Eigen::Quaternion q, Eigen::Vector3 v, eigen::Vector3 omega)
    // {
    //     uranus_dp::Wrench msg;
    //     msg.force.x = surge  * NORMALIZATION * SCALING_LIN;
    //     msg.force.y = sway   * NORMALIZATION * SCALING_LIN;
    //     msg.force.z = heave  * NORMALIZATION * SCALING_LIN;
    //     msg.torque.x = roll  * NORMALIZATION * SCALING_ANG;
    //     msg.torque.y = pitch * NORMALIZATION * SCALING_ANG;
    //     msg.torque.z = yaw   * NORMALIZATION * SCALING_ANG;
    //     publisher_.publish(msg);
    // }

    // void PublishSetpoint()

    void WaitForMessage()
    {
        while(!message_received_)
        {
            ros::spinOnce();
        }
    }

    static const double EPSILON = 1e-6; // Max absolute error

 private:
    ros::NodeHandle node_handle_;
    ros::Publisher  state_pub_;
    ros::Publisher  setpoint_pub_;
    ros::Subscriber subscriber_;
    bool message_received_;

    void Callback(const geometry_msgs::Wrench& msg)
    {
        message_received_ = true;
    }

    bool IsNodeReady()
    {
        return (state_pub_.getNumSubscribers() > 0) && (setpoint_pub_.getNumSubscribers() > 0) && (subscriber_.getNumPublishers() > 0);
    }
};

TEST_F(ControllerTest, CheckResponsiveness)
{
    // Publish(1, 2, 3, 4, 5, 5);
    // WaitForMessage();
    ASSERT_TRUE(true);
}

int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    ros::init(argc, argv, "controller_test");
    ROS_INFO("Launching node controller_test.");

    int ret = RUN_ALL_TESTS();
    ros::shutdown();
    return ret;
}
<commit_msg>Write zero error zero output test<commit_after>#include "ros/ros.h"
#include <gtest/gtest.h>
#include <Eigen/Dense>
#include <eigen_conversions/eigen_msg.h>
#include "geometry_msgs/Wrench.h"
#include "uranus_dp/State.h"

class ControllerTest : public ::testing::Test {
public:
    ControllerTest()
    {
        state_pub_     = node_handle_.advertise<uranus_dp::State>("state", 1);
        setpoint_pub_  = node_handle_.advertise<uranus_dp::State>("setpoint", 1);
        subscriber_    = node_handle_.subscribe("control_input", 5, &ControllerTest::Callback, this);
        message_received_ = false;
    }

    void SetUp()
    {
        while (!IsNodeReady())
        {
            ros::spinOnce();
        }
    }

    void PublishState(Eigen::Vector3d p, Eigen::Quaterniond q, Eigen::Vector3d v, Eigen::Vector3d omega)
    {
        uranus_dp::State msg;
        msg.pose.position.x    = p(0);
        msg.pose.position.y    = p(1);
        msg.pose.position.z    = p(2);
        msg.pose.orientation.x = q.w();
        msg.pose.orientation.y = q.x();
        msg.pose.orientation.z = q.y();
        msg.pose.orientation.w = q.z();
        msg.twist.linear.x     = v(0);
        msg.twist.linear.y     = v(1);
        msg.twist.linear.z     = v(2);
        msg.twist.angular.x    = omega(0);
        msg.twist.angular.y    = omega(1);
        msg.twist.angular.z    = omega(2);
        state_pub_.publish(msg);
    }

    void PublishSetpoint(Eigen::Vector3d p, Eigen::Quaterniond q, Eigen::Vector3d v, Eigen::Vector3d omega)
    {
        uranus_dp::State msg;
        msg.pose.position.x    = p(0);
        msg.pose.position.y    = p(1);
        msg.pose.position.z    = p(2);
        msg.pose.orientation.x = q.w();
        msg.pose.orientation.y = q.x();
        msg.pose.orientation.z = q.y();
        msg.pose.orientation.w = q.z();
        msg.twist.linear.x     = v(0);
        msg.twist.linear.y     = v(1);
        msg.twist.linear.z     = v(2);
        msg.twist.angular.x    = omega(0);
        msg.twist.angular.y    = omega(1);
        msg.twist.angular.z    = omega(2);
        setpoint_pub_.publish(msg);
    }

    void WaitForMessage()
    {
        message_received_ = false;
        while (!message_received_)
        {
            ros::spinOnce();
        }
    }

    Eigen::Matrix<double,6,1> tau_;
    static const double EPSILON = 1e-6; // Max absolute error (Newton or Newton meters)

 private:
    ros::NodeHandle node_handle_;
    ros::Publisher  state_pub_;
    ros::Publisher  setpoint_pub_;
    ros::Subscriber subscriber_;
    bool message_received_;

    void Callback(const geometry_msgs::Wrench& msg)
    {
        tf::wrenchMsgtoEigen(msg, tau_);
        message_received_ = true;
    }

    bool IsNodeReady()
    {
        return (state_pub_.getNumSubscribers() > 0) && (setpoint_pub_.getNumSubscribers() > 0) && (subscriber_.getNumPublishers() > 0);
    }
};

 /*
  * Make sure we receive messages at all.
  */
TEST_F(ControllerTest, CheckResponsiveness)
{
    WaitForMessage();
    ASSERT_TRUE(true);
}

 /*
  * Input zero speed and nonzero pose. Input same pose state and pose setpoint. Expect zero output.
  */
TEST_F(ControllerTest, ZeroErrorZeroOutput)
{
    Eigen::Vector3d    p(1,2,3);
    Eigen::Quaterniond q(4,5,6,7);
    q.normalize();

    Eigen::Vector3d v(0,0,0);
    Eigen::Vector3d omega(0,0,0);

    PublishState(p, q, v, omega);
    PublishSetpoint(p, q, v, omega);

    WaitForMessage();

    EXPECT_NEAR(tau_(0), 0, EPSILON);
    EXPECT_NEAR(tau_(1), 0, EPSILON);
    EXPECT_NEAR(tau_(2), 0, EPSILON);
    EXPECT_NEAR(tau_(3), 0, EPSILON);
    EXPECT_NEAR(tau_(4), 0, EPSILON);
    EXPECT_NEAR(tau_(5), 0, EPSILON);
}

int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    ros::init(argc, argv, "controller_test");
    ROS_INFO("Launching node controller_test.");

    int ret = RUN_ALL_TESTS();
    ros::shutdown();
    return ret;
}
<|endoftext|>


<commit_before>#include <string.h>

#include "topic.h"

using namespace std;

const char* keyProducerStr = "producer_head";
const char* keyConsumerStr = "consumer_head_%s";

int descCmp(const MDB_val *a, const MDB_val *b) {
    /* DESC order in size */
    if (a->mv_size > b->mv_size) return -1;
    if (a->mv_size < b->mv_size) return 1;

    switch (a->mv_size)
    {
    case sizeof(uint32_t) :
        return mdbIntCmp<uint32_t>(a, b);
    case sizeof(uint64_t) :
        return mdbIntCmp<uint64_t>(a, b);
    default:
        return memcmp(a->mv_data, b->mv_data, a->mv_size);
    }
}

Topic::Topic(Env* env, const string& name) : _env(env), _name(name) {
    Txn txn(env, NULL);
    int rc = mdb_dbi_open(txn.getEnvTxn(), name.c_str(), MDB_CREATE, &_desc);
    if (rc != 0) {
        printf("Topic open error.\n%s\n", mdb_strerror(rc));
        return;
    }

    mdb_set_compare(txn.getEnvTxn(), _desc, descCmp);

    MDB_val key{ 0, 0 }, val{ 0, 0 };

    uint64_t head = 0;
    key.mv_data = (void*)keyProducerStr;
    key.mv_size = strlen(keyProducerStr);
    val.mv_data = &head;
    val.mv_size = sizeof(head);
    rc = mdb_put(txn.getEnvTxn(), _desc, &key, &val, MDB_NOOVERWRITE);

    if (rc == 0) {
        uint32_t headFile = 0;
        key.mv_data = &headFile;
        key.mv_size = sizeof(headFile);
        mdb_put(txn.getEnvTxn(), _desc, &key, &val, MDB_NOOVERWRITE);
    }

    txn.commit();
}

Topic::~Topic() {
    mdb_dbi_close(_env->getMdbEnv(), _desc);
}

uint32_t Topic::getProducerHeadFile(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());
    cur.gotoLast();
    return *(uint32_t*)cur.key().mv_data;
}

void Topic::setProducerHeadFile(Txn& txn, uint32_t file, uint64_t offset) {
    MDB_val key{ sizeof(file), &file},
            val{ sizeof(offset), &offset };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

uint64_t Topic::getProducerHead(Txn& txn) {
    MDB_val key{ strlen(keyProducerStr), (void*)keyProducerStr },
            val{ 0, 0 };

    mdb_get(txn.getEnvTxn(), _desc, &key, &val);
    return *(uint64_t*)val.mv_data;
}

void Topic::setProducerHead(Txn& txn, uint64_t head) {
    MDB_val key{ strlen(keyProducerStr), (void*)keyProducerStr },
            val{ sizeof(head), &head };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

uint32_t Topic::getConsumerHeadFile(Txn& txn, const std::string& name, uint32_t searchFrom) {
    char keyStr[4096];
    sprintf(keyStr, keyConsumerStr, name.c_str());

}

uint64_t Topic::getConsumerHead(Txn& txn, const std::string& name) {
    char keyStr[4096];
    sprintf(keyStr, keyConsumerStr, name.c_str());

    MDB_val key{ strlen(keyStr), keyStr }, val{ 0, nullptr };
    int rc = mdb_get(txn.getEnvTxn(), _desc, &key, &val);
    if (rc == 0) {
        return *(uint64_t*)val.mv_data;
    } else {
        if (rc != MDB_NOTFOUND) cout << "Consumer seek error: " << mdb_strerror(rc) << endl;

    }
}

void Topic::setConsumerHead(Txn& txn, const std::string& name, uint64_t head) {
    char keyStr[4096];
    sprintf(keyStr, keyConsumerStr, name.c_str());

    MDB_val key{ strlen(keyStr), keyStr },
            val{ sizeof(head), &head };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

int Topic::getChunkFilePath(char* buf, uint32_t chunkSeq) {
    return sprintf(buf, "%s/%s.%d", getEnv()->getRoot().c_str(), getName().c_str(), chunkSeq);
}

size_t Topic::countChunks(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());

    size_t count = 0;
    uint32_t minFile = 0;
    int rc = cur.gte(minFile);

    while (rc == 0 && cur.key().mv_size == 4) {
        ++count;
        rc = cur.next();
    }

    return count;
}

void Topic::removeOldestChunk(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());

    uint32_t oldest = 0;
    int rc = cur.gte(oldest);
    if (rc == 0 && cur.key().mv_size == sizeof(oldest)) {
        oldest = *(uint32_t*)cur.key().mv_data;
        cur.del();

        char path[4096];
        getChunkFilePath(path, oldest);
        remove(path);
        strcat(path, "-lock");
        remove(path);
    }
}
<commit_msg>Topic consumer related.<commit_after>#include <string.h>

#include "topic.h"

using namespace std;

const char* keyProducerStr = "producer_head";
const char* keyConsumerStr = "consumer_head_%s";

int descCmp(const MDB_val *a, const MDB_val *b) {
    /* DESC order in size */
    if (a->mv_size > b->mv_size) return -1;
    if (a->mv_size < b->mv_size) return 1;

    switch (a->mv_size)
    {
    case sizeof(uint32_t) :
        return mdbIntCmp<uint32_t>(a, b);
    case sizeof(uint64_t) :
        return mdbIntCmp<uint64_t>(a, b);
    default:
        return memcmp(a->mv_data, b->mv_data, a->mv_size);
    }
}

Topic::Topic(Env* env, const string& name) : _env(env), _name(name) {
    Txn txn(env, NULL);
    int rc = mdb_dbi_open(txn.getEnvTxn(), name.c_str(), MDB_CREATE, &_desc);
    if (rc != 0) {
        printf("Topic open error.\n%s\n", mdb_strerror(rc));
        return;
    }

    mdb_set_compare(txn.getEnvTxn(), _desc, descCmp);

    MDB_val key{ 0, 0 }, val{ 0, 0 };

    uint64_t head = 0;
    key.mv_data = (void*)keyProducerStr;
    key.mv_size = strlen(keyProducerStr);
    val.mv_data = &head;
    val.mv_size = sizeof(head);
    rc = mdb_put(txn.getEnvTxn(), _desc, &key, &val, MDB_NOOVERWRITE);

    if (rc == 0) {
        uint32_t headFile = 0;
        key.mv_data = &headFile;
        key.mv_size = sizeof(headFile);
        mdb_put(txn.getEnvTxn(), _desc, &key, &val, MDB_NOOVERWRITE);
    }

    txn.commit();
}

Topic::~Topic() {
    mdb_dbi_close(_env->getMdbEnv(), _desc);
}

uint32_t Topic::getProducerHeadFile(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());
    cur.gotoLast();
    return cur.key<uint32_t>();
}

void Topic::setProducerHeadFile(Txn& txn, uint32_t file, uint64_t offset) {
    MDB_val key{ sizeof(file), &file},
            val{ sizeof(offset), &offset };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

uint64_t Topic::getProducerHead(Txn& txn) {
    MDB_val key{ strlen(keyProducerStr), (void*)keyProducerStr },
            val{ 0, 0 };

    mdb_get(txn.getEnvTxn(), _desc, &key, &val);
    return *(uint64_t*)val.mv_data;
}

void Topic::setProducerHead(Txn& txn, uint64_t head) {
    MDB_val key{ strlen(keyProducerStr), (void*)keyProducerStr },
            val{ sizeof(head), &head };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

uint32_t Topic::getConsumerHeadFile(Txn& txn, const std::string& name, uint32_t searchFrom) {
    uint64_t head = getConsumerHead(txn, name);

    MDBCursor cur(_desc, txn.getEnvTxn());
    int rc = cur.gte(searchFrom);
    uint32_t ret = cur.key<uint32_t>();
    uint64_t fh = cur.val<uint64_t>();
    while (rc && head > fh) {
        rc = cur.next();
        if (rc == 0) {
            uint64_t ch = cur.val<uint64_t>();
            if (head < ch) {
                return ret;
            } else {
                ret = cur.key<uint32_t>();
                fh = ch;
            }
        }
    }

    return ret;
}

uint64_t Topic::getConsumerHead(Txn& txn, const std::string& name) {
    char keyStr[4096];
    sprintf(keyStr, keyConsumerStr, name.c_str());

    MDB_val key{ strlen(keyStr), keyStr }, val{ 0, nullptr };
    int rc = mdb_get(txn.getEnvTxn(), _desc, &key, &val);
    if (rc == 0) {
        return *(uint64_t*)val.mv_data;
    } else {
        if (rc != MDB_NOTFOUND) cout << "Consumer seek error: " << mdb_strerror(rc) << endl;

        MDBCursor cur(_desc, txn.getEnvTxn());
        cur.gte(uint32_t(0));
        return cur.val<uint64_t>();
    }
}

void Topic::setConsumerHead(Txn& txn, const std::string& name, uint64_t head) {
    char keyStr[4096];
    sprintf(keyStr, keyConsumerStr, name.c_str());

    MDB_val key{ strlen(keyStr), keyStr },
            val{ sizeof(head), &head };

    mdb_put(txn.getEnvTxn(), _desc, &key, &val, 0);
}

int Topic::getChunkFilePath(char* buf, uint32_t chunkSeq) {
    return sprintf(buf, "%s/%s.%d", getEnv()->getRoot().c_str(), getName().c_str(), chunkSeq);
}

size_t Topic::countChunks(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());

    size_t count = 0;
    uint32_t minFile = 0;
    int rc = cur.gte(minFile);

    while (rc == 0 && cur.key().mv_size == 4) {
        ++count;
        rc = cur.next();
    }

    return count;
}

void Topic::removeOldestChunk(Txn& txn) {
    MDBCursor cur(_desc, txn.getEnvTxn());

    uint32_t oldest = 0;
    int rc = cur.gte(oldest);
    if (rc == 0 && cur.key().mv_size == sizeof(oldest)) {
        oldest = cur.key<int32_t>();
        cur.del();

        char path[4096];
        getChunkFilePath(path, oldest);
        remove(path);
        strcat(path, "-lock");
        remove(path);
    }
}
<|endoftext|>


<commit_before>#include <assert.h>

#include <string>

using namespace std;

#include "game.h"
#include "coordinate.h"
#include "command.h"
#include "io.h"
#include "armor.h"
#include "fight.h"
#include "colors.h"
#include "level.h"
#include "rings.h"
#include "misc.h"
#include "weapons.h"
#include "monster.h"
#include "os.h"
#include "player.h"
#include "death.h"

#include "traps.h"

string const trap_names[] = {
  "a trapdoor",
  "an arrow trap",
  "a sleeping gas trap",
  "a beartrap",
  "a teleport trap",
  "a poison dart trap",
  "a rust trap",
  "a mysterious trap"
};

static enum trap_t
trap_door_player(void)
{
  Game::new_level(Game::current_level + 1);
  io_msg("you fell into a trap!");
  return T_DOOR;
}

static enum trap_t
trap_door_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s fell through the floor", victim->get_name().c_str());
  }
  monster_remove_from_screen(&victim->get_position(), victim, false);
  return T_DOOR;
}

static enum trap_t
trap_bear_player(void)
{
  player->become_stuck();
  io_msg("you are caught in a bear trap");
  return T_BEAR;
}

static enum trap_t
trap_bear_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s was caught in a bear trap", victim->get_name().c_str());
  }
  victim->set_stuck();
  return T_BEAR;
}

static enum trap_t
trap_myst_player(void)
{
  switch(os_rand_range(11))
  {
    case 0: io_msg("you are suddenly in a parallel dimension"); break;
    case 1: io_msg("the light in here suddenly seems %s", color_random().c_str()); break;
    case 2: io_msg("you feel a sting in the side of your neck"); break;
    case 3: io_msg("multi-colored lines swirl around you, then fade"); break;
    case 4: io_msg("a %s light flashes in your eyes", color_random().c_str()); break;
    case 5: io_msg("a spike shoots past your ear!"); break;
    case 6: io_msg("%s sparks dance across your armor", color_random().c_str()); break;
    case 7: io_msg("you suddenly feel very thirsty"); break;
    case 8: io_msg("you feel time speed up suddenly"); break;
    case 9: io_msg("time now seems to be going slower"); break;
    case 10: io_msg("you pack turns %s!", color_random().c_str()); break;
  }
  return T_MYST;
}

static enum trap_t
trap_myst_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s seems to have stepped on something", victim->get_name().c_str());
  }
  return T_MYST;
}

static enum trap_t
trap_sleep_player(void)
{
  player->fall_asleep();
  io_msg_add("a strange white mist envelops you and ");
  return T_SLEEP;
}

static enum trap_t
trap_sleep_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s collapsed to the ground", victim->get_name().c_str());
  }
  victim->set_held();
  return T_SLEEP;
}

static enum trap_t
trap_arrow_player(void)
{
  if (fight_swing_hits(player->get_level() - 1, player->get_armor(), 1))
  {
    player->take_damage(roll(1, 6));
    if (player->get_health() <= 0)
    {
      io_msg("an arrow killed you");
      death(DEATH_ARROW);
    }
    else
      io_msg("oh no! An arrow shot you");
  }
  else
  {
    Item* arrow = weapon_create(ARROW, false);
    arrow->o_count = 1;
    arrow->set_pos(player->get_position());
    weapon_missile_fall(arrow, false);
    io_msg("an arrow shoots past you");
  }
  return T_ARROW;
}

static enum trap_t
trap_arrow_monster(Monster* victim)
{
  if (fight_swing_hits(victim->get_level() -1,
        victim->get_armor(), 1))
  {
    victim->take_damage(roll(1,6));
    if (victim->get_health() <= 0)
    {
      monster_on_death(victim, false);
      if (monster_seen_by_player(victim))
        io_msg("An arrow killed %s", victim->get_name().c_str());
    }
    else if (monster_seen_by_player(victim))
      io_msg("An arrow shot %s", victim->get_name().c_str());
  }
  else
  {
    Item* arrow = weapon_create(ARROW, false);
    arrow->o_count = 1;
    arrow->set_pos(victim->get_position());
    weapon_missile_fall(arrow, false);
    if (monster_seen_by_player(victim))
      io_msg("An arrow barely missed %s", victim->get_name().c_str());
  }
  return T_ARROW;
}

static enum trap_t
trap_telep_player(Coordinate* trap_coord)
{
  player->teleport(nullptr);
  Game::io->print_color(trap_coord->x, trap_coord->y, TRAP); /* Mark trap before we leave */
  return T_TELEP;
}

static enum trap_t
trap_telep_monster(Monster* victim)
{
  bool was_seen = monster_seen_by_player(victim);
  if (was_seen)
  {
    io_msg_add("%s ", victim->get_name().c_str());
  }

  monster_teleport(victim, nullptr);
  if (was_seen)
  {
    if (monster_seen_by_player(victim))
      io_msg("teleported a short distance");
    else
      io_msg("disappeared");
  }

  if (!was_seen && monster_seen_by_player(victim))
  {
    io_msg("%s appeared out of thin air", victim->get_name().c_str());
  }

  return T_TELEP;
}

static enum trap_t
trap_dart_player(void)
{
  if (!fight_swing_hits(player->get_level() + 1, player->get_armor(), 1))
    io_msg("a small dart whizzes by your ear and vanishes");
  else
  {
    player->take_damage(roll(1, 4));
    if (player->get_health() <= 0)
    {
      io_msg("a poisoned dart killed you");
      death(DEATH_DART);
    }
    if (!player->has_ring_with_ability(Ring::Type::SUSTSTR) &&
        !player->saving_throw(VS_POISON))
      player->modify_strength(-1);
    io_msg("a small dart just hit you in the shoulder");
  }
  return T_DART;
}

static enum trap_t
trap_dart_monster(Monster* victim)
{
  /* TODO: In the future this should probably weaken the monster */
  if (fight_swing_hits(victim->get_level() + 1,
        victim->get_armor(), 1))
  {
    victim->take_damage(roll(1,4));
    if (victim->get_health() <= 0)
    {
      monster_on_death(victim, false);
      if (monster_seen_by_player(victim))
      {
        io_msg("A poisoned dart killed %s", victim->get_name().c_str());
      }
    }
    else if (monster_seen_by_player(victim))
    {
      io_msg("An dart hit %s", victim->get_name().c_str());
    }
  }
  else if (monster_seen_by_player(victim))
  {
    io_msg("A dart barely missed %s", victim->get_name().c_str());
  }
  return T_DART;
}

static enum trap_t
trap_rust_player(void)
{
  io_msg("a gush of water hits you on the head");
  player->rust_armor();
  return T_RUST;
}

static enum trap_t
trap_rust_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("a gush of water hits %s", victim->get_name().c_str());
  }
  return T_RUST;
}

enum trap_t
trap_spring(Monster* victim, Coordinate* trap_coord)
{
  assert(trap_coord != nullptr);

  bool is_player = victim == nullptr;
  size_t tr = Game::level->get_trap_type(*trap_coord);

  if (is_player) {
    command_stop(true);
  }

  if (victim == nullptr || monster_seen_by_player(victim)) {
    Game::level->set_ch(*trap_coord, TRAP);
    Game::level->set_discovered(*trap_coord);
  }

  switch (tr)
  {
    case T_DOOR:
      if (is_player) return trap_door_player();
      else        return trap_door_monster(victim);
    case T_BEAR:
      if (is_player) return trap_bear_player();
      else        return trap_bear_monster(victim);
    case T_MYST:
      if (is_player) return trap_myst_player();
      else        return trap_myst_monster(victim);
    case T_SLEEP:
      if (is_player) return trap_sleep_player();
      else        return trap_sleep_monster(victim);
    case T_ARROW:
      if (is_player) return trap_arrow_player();
      else        return trap_arrow_monster(victim);
    case T_TELEP:
      if (is_player) return trap_telep_player(trap_coord);
      else        return trap_telep_monster(victim);
    case T_DART:
      if (is_player) return trap_dart_player();
      else        return trap_dart_monster(victim);
    case T_RUST:
      if (is_player) return trap_rust_player();
      else        return trap_rust_monster(victim);
    default:
      assert(0);
      return T_MYST;
  }
}

<commit_msg>don't use free'd memory<commit_after>#include <assert.h>

#include <string>

using namespace std;

#include "game.h"
#include "coordinate.h"
#include "command.h"
#include "io.h"
#include "armor.h"
#include "fight.h"
#include "colors.h"
#include "level.h"
#include "rings.h"
#include "misc.h"
#include "weapons.h"
#include "monster.h"
#include "os.h"
#include "player.h"
#include "death.h"

#include "traps.h"

string const trap_names[] = {
  "a trapdoor",
  "an arrow trap",
  "a sleeping gas trap",
  "a beartrap",
  "a teleport trap",
  "a poison dart trap",
  "a rust trap",
  "a mysterious trap"
};

static enum trap_t
trap_door_player(void)
{
  Game::new_level(Game::current_level + 1);
  io_msg("you fell into a trap!");
  return T_DOOR;
}

static enum trap_t
trap_door_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s fell through the floor", victim->get_name().c_str());
  }
  monster_remove_from_screen(&victim->get_position(), victim, false);
  return T_DOOR;
}

static enum trap_t
trap_bear_player(void)
{
  player->become_stuck();
  io_msg("you are caught in a bear trap");
  return T_BEAR;
}

static enum trap_t
trap_bear_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s was caught in a bear trap", victim->get_name().c_str());
  }
  victim->set_stuck();
  return T_BEAR;
}

static enum trap_t
trap_myst_player(void)
{
  switch(os_rand_range(11))
  {
    case 0: io_msg("you are suddenly in a parallel dimension"); break;
    case 1: io_msg("the light in here suddenly seems %s", color_random().c_str()); break;
    case 2: io_msg("you feel a sting in the side of your neck"); break;
    case 3: io_msg("multi-colored lines swirl around you, then fade"); break;
    case 4: io_msg("a %s light flashes in your eyes", color_random().c_str()); break;
    case 5: io_msg("a spike shoots past your ear!"); break;
    case 6: io_msg("%s sparks dance across your armor", color_random().c_str()); break;
    case 7: io_msg("you suddenly feel very thirsty"); break;
    case 8: io_msg("you feel time speed up suddenly"); break;
    case 9: io_msg("time now seems to be going slower"); break;
    case 10: io_msg("you pack turns %s!", color_random().c_str()); break;
  }
  return T_MYST;
}

static enum trap_t
trap_myst_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s seems to have stepped on something", victim->get_name().c_str());
  }
  return T_MYST;
}

static enum trap_t
trap_sleep_player(void)
{
  player->fall_asleep();
  io_msg_add("a strange white mist envelops you and ");
  return T_SLEEP;
}

static enum trap_t
trap_sleep_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("%s collapsed to the ground", victim->get_name().c_str());
  }
  victim->set_held();
  return T_SLEEP;
}

static enum trap_t
trap_arrow_player(void)
{
  if (fight_swing_hits(player->get_level() - 1, player->get_armor(), 1))
  {
    player->take_damage(roll(1, 6));
    if (player->get_health() <= 0)
    {
      io_msg("an arrow killed you");
      death(DEATH_ARROW);
    }
    else
      io_msg("oh no! An arrow shot you");
  }
  else
  {
    Item* arrow = weapon_create(ARROW, false);
    arrow->o_count = 1;
    arrow->set_pos(player->get_position());
    weapon_missile_fall(arrow, false);
    io_msg("an arrow shoots past you");
  }
  return T_ARROW;
}

static enum trap_t
trap_arrow_monster(Monster* victim)
{
  if (fight_swing_hits(victim->get_level() -1,
        victim->get_armor(), 1))
  {
    victim->take_damage(roll(1,6));
    if (victim->get_health() <= 0)
    {
      if (monster_seen_by_player(victim))
        io_msg("An arrow killed %s", victim->get_name().c_str());
      monster_on_death(victim, false);
      victim = nullptr;
    }
    else if (monster_seen_by_player(victim))
      io_msg("An arrow shot %s", victim->get_name().c_str());
  }
  else
  {
    Item* arrow = weapon_create(ARROW, false);
    arrow->o_count = 1;
    arrow->set_pos(victim->get_position());
    weapon_missile_fall(arrow, false);
    if (monster_seen_by_player(victim))
      io_msg("An arrow barely missed %s", victim->get_name().c_str());
  }
  return T_ARROW;
}

static enum trap_t
trap_telep_player(Coordinate* trap_coord)
{
  player->teleport(nullptr);
  Game::io->print_color(trap_coord->x, trap_coord->y, TRAP); /* Mark trap before we leave */
  return T_TELEP;
}

static enum trap_t
trap_telep_monster(Monster* victim)
{
  bool was_seen = monster_seen_by_player(victim);
  if (was_seen)
  {
    io_msg_add("%s ", victim->get_name().c_str());
  }

  monster_teleport(victim, nullptr);
  if (was_seen)
  {
    if (monster_seen_by_player(victim))
      io_msg("teleported a short distance");
    else
      io_msg("disappeared");
  }

  if (!was_seen && monster_seen_by_player(victim))
  {
    io_msg("%s appeared out of thin air", victim->get_name().c_str());
  }

  return T_TELEP;
}

static enum trap_t
trap_dart_player(void)
{
  if (!fight_swing_hits(player->get_level() + 1, player->get_armor(), 1))
    io_msg("a small dart whizzes by your ear and vanishes");
  else
  {
    player->take_damage(roll(1, 4));
    if (player->get_health() <= 0)
    {
      io_msg("a poisoned dart killed you");
      death(DEATH_DART);
    }
    if (!player->has_ring_with_ability(Ring::Type::SUSTSTR) &&
        !player->saving_throw(VS_POISON))
      player->modify_strength(-1);
    io_msg("a small dart just hit you in the shoulder");
  }
  return T_DART;
}

static enum trap_t
trap_dart_monster(Monster* victim)
{
  /* TODO: In the future this should probably weaken the monster */
  if (fight_swing_hits(victim->get_level() + 1,
        victim->get_armor(), 1))
  {
    victim->take_damage(roll(1,4));
    if (victim->get_health() <= 0)
    {
      if (monster_seen_by_player(victim))
      {
        io_msg("A poisoned dart killed %s", victim->get_name().c_str());
      }
      monster_on_death(victim, false);
      victim = nullptr;
    }
    else if (monster_seen_by_player(victim))
    {
      io_msg("An dart hit %s", victim->get_name().c_str());
    }
  }
  else if (monster_seen_by_player(victim))
  {
    io_msg("A dart barely missed %s", victim->get_name().c_str());
  }
  return T_DART;
}

static enum trap_t
trap_rust_player(void)
{
  io_msg("a gush of water hits you on the head");
  player->rust_armor();
  return T_RUST;
}

static enum trap_t
trap_rust_monster(Monster* victim)
{
  if (monster_seen_by_player(victim))
  {
    io_msg("a gush of water hits %s", victim->get_name().c_str());
  }
  return T_RUST;
}

enum trap_t
trap_spring(Monster* victim, Coordinate* trap_coord)
{
  assert(trap_coord != nullptr);

  bool is_player = victim == nullptr;
  size_t tr = Game::level->get_trap_type(*trap_coord);

  if (is_player) {
    command_stop(true);
  }

  if (victim == nullptr || monster_seen_by_player(victim)) {
    Game::level->set_ch(*trap_coord, TRAP);
    Game::level->set_discovered(*trap_coord);
  }

  switch (tr)
  {
    case T_DOOR:
      if (is_player) return trap_door_player();
      else        return trap_door_monster(victim);
    case T_BEAR:
      if (is_player) return trap_bear_player();
      else        return trap_bear_monster(victim);
    case T_MYST:
      if (is_player) return trap_myst_player();
      else        return trap_myst_monster(victim);
    case T_SLEEP:
      if (is_player) return trap_sleep_player();
      else        return trap_sleep_monster(victim);
    case T_ARROW:
      if (is_player) return trap_arrow_player();
      else        return trap_arrow_monster(victim);
    case T_TELEP:
      if (is_player) return trap_telep_player(trap_coord);
      else        return trap_telep_monster(victim);
    case T_DART:
      if (is_player) return trap_dart_player();
      else        return trap_dart_monster(victim);
    case T_RUST:
      if (is_player) return trap_rust_player();
      else        return trap_rust_monster(victim);
    default:
      assert(0);
      return T_MYST;
  }
}

<|endoftext|>


<commit_before>#if !(defined MPL_ENVIRONMENT_HPP)

#define MPL_ENVIRONMENT_HPP

#include <string>
#include <memory>
#include <mpi.h>

namespace mpl {

  enum class threading_modes { single=MPI_THREAD_SINGLE,
      funneled=MPI_THREAD_FUNNELED,
      serialized=MPI_THREAD_SERIALIZED,
      multiple=MPI_THREAD_MULTIPLE };

  namespace environment {

    namespace detail {

      class env {
	class initializer {
	public:
	  initializer() {
	    int thread_mode;
	    MPI_Init_thread(0, 0, MPI_THREAD_MULTIPLE, &thread_mode);
	  }
	  ~initializer() {
	    MPI_Finalize();
	  }
	};

	initializer init;
	mpl::communicator comm_world_, comm_self_;
      public:
	env() :
	  init(), comm_world_(MPI_COMM_WORLD), comm_self_(MPI_COMM_SELF) {
	}
	env(const env &) = delete;
	env& operator=(const env &) = delete;
	int tag_up() const {
	  void *p;
	  int flag;
	  MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &p, &flag);
	  return *reinterpret_cast<int *>(p);
	}
	threading_modes threading_mode() const {
	  int provided;
	  MPI_Query_thread(&provided);
	  switch (provided) {
	    case MPI_THREAD_SINGLE:
	      return threading_modes::single;
	    case MPI_THREAD_FUNNELED:
	      return threading_modes::funneled;
	    case MPI_THREAD_SERIALIZED:
	      return threading_modes::serialized;
	    case MPI_THREAD_MULTIPLE:
	      return threading_modes::multiple;
	  }
	  return threading_modes::single;  // make compiler happy
	}
	bool is_thread_main() const {
	  int res;
	  MPI_Is_thread_main(&res);
	  return static_cast<bool>(res);
	}
	bool wtime_is_global() const {
	  void *p;
	  int flag;
	  MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_WTIME_IS_GLOBAL, &p, &flag);
	  return *reinterpret_cast<int *>(p);
	}
	const communicator & comm_world() const {
	  return comm_world_;
	}
	const communicator & comm_self() const {
	  return comm_self_;
	}
	std::string processor_name() const {
	  char name[MPI_MAX_PROCESSOR_NAME];
	  int len;
	  MPI_Get_processor_name(name, &len);
	  return std::string(name);
	}
	double wtime() const {
	  return MPI_Wtime();
	}
	double wtick() const {
	  return MPI_Wtick();
	}
	void buffer_attach(void *buff, int size) const {
	  MPI_Buffer_attach(buff, size);
	}
	std::pair<void *, int> buffer_detach() const {
	  void *buff;
	  int size;
	  MPI_Buffer_detach(&buff, &size);
	  return std::make_pair(buff, size);
	}
      };

      //----------------------------------------------------------------

      const env & get_env() {
	static env the_env;
	return the_env;
      }

    }

    //------------------------------------------------------------------

    inline int tag_up() {
      return detail::get_env().tag_up();
    }

    constexpr int any_tag() {
      return MPI_ANY_TAG;
    }

    constexpr int any_source() {
      return MPI_ANY_SOURCE;
    }

    constexpr int proc_null() {
      return MPI_PROC_NULL;
    }

    constexpr int undefined() {
      return MPI_UNDEFINED;
    }

    constexpr int root() {
      return MPI_ROOT;
    }

    constexpr int bsend_overheadroot() {
      return MPI_BSEND_OVERHEAD;
    }

    inline threading_modes threading_mode() {
      return detail::get_env().threading_mode();
    }

    inline bool is_thread_main() {
      return detail::get_env().is_thread_main();
    }

    inline bool wtime_is_global() {
      return detail::get_env().wtime_is_global();
    }

    inline const communicator & comm_world() {
      return detail::get_env().comm_world();
    }

    inline const communicator & comm_self() {
      return detail::get_env().comm_self();
    }

    inline std::string processor_name() {
      return detail::get_env().processor_name();
    }

    inline double wtime() {
      return detail::get_env().wtime();
    }

    inline double wtick() {
      return detail::get_env().wtick();
    }

    inline void buffer_attach(void *buff, int size) {
      return detail::get_env().buffer_attach(buff, size);
    }

    inline std::pair<void *, int> buffer_detach() {
      return detail::get_env().buffer_detach();
    }

  }

  //--------------------------------------------------------------------

  template<typename A=std::allocator<char>>
  class bsend_buffer {
    int size;
    A alloc;
    char *buff;
  public:
    bsend_buffer(int size) : size(size), alloc(), buff(alloc.allocate(size)) {
      environment::buffer_attach(buff, size);
    }
    bsend_buffer(int size, A alloc) : size(size), alloc(alloc), buff(alloc.allocate(size)) {
      environment::buffer_attach(buff, size);
    }
    ~bsend_buffer() {
      environment::buffer_detach();
      alloc.deallocate(buff, size);
    }
  };

}

#endif
<commit_msg>remove trailing whitespace<commit_after>#if !(defined MPL_ENVIRONMENT_HPP)

#define MPL_ENVIRONMENT_HPP

#include <string>
#include <memory>
#include <mpi.h>

namespace mpl {

  enum class threading_modes { single=MPI_THREAD_SINGLE,
      funneled=MPI_THREAD_FUNNELED,
      serialized=MPI_THREAD_SERIALIZED,
      multiple=MPI_THREAD_MULTIPLE };

  namespace environment {

    namespace detail {

      class env {
	class initializer {
	public:
	  initializer() {
	    int thread_mode;
	    MPI_Init_thread(0, 0, MPI_THREAD_MULTIPLE, &thread_mode);
	  }
	  ~initializer() {
	    MPI_Finalize();
	  }
	};

	initializer init;
	mpl::communicator comm_world_, comm_self_;
      public:
	env() :
	  init(), comm_world_(MPI_COMM_WORLD), comm_self_(MPI_COMM_SELF) {
	}
	env(const env &) = delete;
	env& operator=(const env &) = delete;
	int tag_up() const {
	  void *p;
	  int flag;
	  MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &p, &flag);
	  return *reinterpret_cast<int *>(p);
	}
	threading_modes threading_mode() const {
	  int provided;
	  MPI_Query_thread(&provided);
	  switch (provided) {
	    case MPI_THREAD_SINGLE:
	      return threading_modes::single;
	    case MPI_THREAD_FUNNELED:
	      return threading_modes::funneled;
	    case MPI_THREAD_SERIALIZED:
	      return threading_modes::serialized;
	    case MPI_THREAD_MULTIPLE:
	      return threading_modes::multiple;
	  }
	  return threading_modes::single;  // make compiler happy
	}
	bool is_thread_main() const {
	  int res;
	  MPI_Is_thread_main(&res);
	  return static_cast<bool>(res);
	}
	bool wtime_is_global() const {
	  void *p;
	  int flag;
	  MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_WTIME_IS_GLOBAL, &p, &flag);
	  return *reinterpret_cast<int *>(p);
	}
	const communicator & comm_world() const {
	  return comm_world_;
	}
	const communicator & comm_self() const {
	  return comm_self_;
	}
	std::string processor_name() const {
	  char name[MPI_MAX_PROCESSOR_NAME];
	  int len;
	  MPI_Get_processor_name(name, &len);
	  return std::string(name);
	}
	double wtime() const {
	  return MPI_Wtime();
	}
	double wtick() const {
	  return MPI_Wtick();
	}
	void buffer_attach(void *buff, int size) const {
	  MPI_Buffer_attach(buff, size);
	}
	std::pair<void *, int> buffer_detach() const {
	  void *buff;
	  int size;
	  MPI_Buffer_detach(&buff, &size);
	  return std::make_pair(buff, size);
	}
      };

      //----------------------------------------------------------------

      const env & get_env() {
	static env the_env;
	return the_env;
      }

    }

    //------------------------------------------------------------------

    inline int tag_up() {
      return detail::get_env().tag_up();
    }

    constexpr int any_tag() {
      return MPI_ANY_TAG;
    }

    constexpr int any_source() {
      return MPI_ANY_SOURCE;
    }

    constexpr int proc_null() {
      return MPI_PROC_NULL;
    }

    constexpr int undefined() {
      return MPI_UNDEFINED;
    }

    constexpr int root() {
      return MPI_ROOT;
    }

    constexpr int bsend_overheadroot() {
      return MPI_BSEND_OVERHEAD;
    }

    inline threading_modes threading_mode() {
      return detail::get_env().threading_mode();
    }

    inline bool is_thread_main() {
      return detail::get_env().is_thread_main();
    }

    inline bool wtime_is_global() {
      return detail::get_env().wtime_is_global();
    }

    inline const communicator & comm_world() {
      return detail::get_env().comm_world();
    }

    inline const communicator & comm_self() {
      return detail::get_env().comm_self();
    }

    inline std::string processor_name() {
      return detail::get_env().processor_name();
    }

    inline double wtime() {
      return detail::get_env().wtime();
    }

    inline double wtick() {
      return detail::get_env().wtick();
    }

    inline void buffer_attach(void *buff, int size) {
      return detail::get_env().buffer_attach(buff, size);
    }

    inline std::pair<void *, int> buffer_detach() {
      return detail::get_env().buffer_detach();
    }

  }

  //--------------------------------------------------------------------

  template<typename A=std::allocator<char>>
  class bsend_buffer {
    int size;
    A alloc;
    char *buff;
  public:
    bsend_buffer(int size) : size(size), alloc(), buff(alloc.allocate(size)) {
      environment::buffer_attach(buff, size);
    }
    bsend_buffer(int size, A alloc) : size(size), alloc(alloc), buff(alloc.allocate(size)) {
      environment::buffer_attach(buff, size);
    }
    ~bsend_buffer() {
      environment::buffer_detach();
      alloc.deallocate(buff, size);
    }
  };

}

#endif
<|endoftext|>


<commit_before>// sota.cpp : Defines the entry point for the console application.
//
#include <array>
#include <string>
#include <iostream>
#include <exception>

#include "ast.h"
#include "token.h"
#include "parser.h"
#include "grammar.h"

using namespace sota;

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

    std::string source = "1 + 2";

    auto parser = Parser(Type2Symbol);
    parser.Source = source;
    auto token = parser.LookAhead(5);
    std::cout << token << std::endl;

    return 0;
}
<commit_msg>fixed lingering case issue, Source -> source ... -sai<commit_after>// sota.cpp : Defines the entry point for the console application.
//
#include <array>
#include <string>
#include <iostream>
#include <exception>

#include "ast.h"
#include "token.h"
#include "parser.h"
#include "grammar.h"

using namespace sota;

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

    std::string source = "1 + 2";

    auto parser = Parser(Type2Symbol);
    parser.source = source;
    auto token = parser.LookAhead(5);
    std::cout << token << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 * v8cgi main file. Loosely based on V8's "shell" sample app.
 */

#include <v8.h>
#include "js_system.h"
#include "js_io.h"
#include "js_common.h"
#include "js_macros.h"
#include <sstream>

#ifndef windows
#	include <dlfcn.h>
#else
#	include <windows.h>
#	define dlopen(x,y) (void*)LoadLibrary(x)
#	define dlsym(x,y) (void*)GetProcAddress((HMODULE)x,y)
#	define dlclose(x) FreeLibrary((HMODULE)x)
#endif

#define _STRING(x) #x
#define STRING(x) _STRING(x)

// chdir()
#ifndef HAVE_CHDIR
#	include <direct.h>
#	define chdir(name) _chdir(name)
#endif

// getcwd()
#ifndef HAVE_GETCWD
#	include <direct.h>
#	define getcwd(name, bytes) _getcwd(name, bytes)
#endif

v8::Handle<v8::Array> __onexit;

void die(int code) {
	uint32_t max = __onexit->Length();
	v8::Handle<v8::Function> fun;
	for (unsigned int i=0;i<max;i++) {
		fun = v8::Handle<v8::Function>::Cast(__onexit->Get(JS_INT(i)));
		fun->Call(v8::Context::GetCurrent()->Global(), 0, NULL);
	}
	exit(code);
}

v8::Handle<v8::String> read_file(const char* name) {
	FILE* file = fopen(name, "rb");
	if (file == NULL) return v8::Handle<v8::String>();

	fseek(file, 0, SEEK_END);
	size_t size = ftell(file);
	rewind(file);

	char* chars = new char[size + 1];
	chars[size] = '\0';
	for (unsigned int i = 0; i < size;) {
		size_t read = fread(&chars[i], 1, size - i, file);
		i += read;
	}
	fclose(file);

	/* remove shebang line */
	std::string str = chars;
	if ( str.find('#',0) == 0 && str.find('!',1) == 1 ) {
		unsigned int pfix = str.find('\n',0);
		str.erase(0,pfix);
	};

	v8::Handle<v8::String> result = JS_STR(str.c_str());
	delete[] chars;
	return result;
}

void report_exception(v8::TryCatch* try_catch) {
	v8::HandleScope handle_scope;
	v8::String::Utf8Value exception(try_catch->Exception());
	v8::Handle<v8::Message> message = try_catch->Message();
	std::string msgstring = "";
	std::stringstream ss;
	std::string tmp;

	if (message.IsEmpty()) {
		msgstring += *exception;
		msgstring += "\n";
	} else {
		v8::String::Utf8Value filename(message->GetScriptResourceName());
		int linenum = message->GetLineNumber();
		msgstring += *filename;
		msgstring += ":";

		ss << linenum;
		ss >> tmp;

		msgstring += tmp;
		msgstring += ": ";
		msgstring += *exception;
		msgstring += "\n";
	}

	int cgi = 0;
	v8::Local<v8::Function> fun;
	v8::Local<v8::Value> context = v8::Context::GetCurrent()->Global()->Get(JS_STR("response"));
	if (context->IsObject()) {
		v8::Local<v8::Value> print = context->ToObject()->Get(JS_STR("error"));
		if (print->IsObject()) {
			fun = v8::Local<v8::Function>::Cast(print);
			cgi = 1;
		}
	}
	if (!cgi) {
		context = v8::Context::GetCurrent()->Global()->Get(JS_STR("System"));
		fun = v8::Local<v8::Function>::Cast(context->ToObject()->Get(JS_STR("stdout")));
	}

	v8::Handle<v8::Value> data[1];
	data[0] = JS_STR(msgstring.c_str());
	fun->Call(context->ToObject(), 1, data);
}

int execute_file(const char * str, bool change) {
	v8::HandleScope handle_scope;
	v8::TryCatch try_catch;
	v8::Handle<v8::String> name = JS_STR(str);
	v8::Handle<v8::String> source = read_file(str);

	if (source.IsEmpty()) {
		printf("Error reading '%s'\n", str);
		return 1;
	}

	v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
	if (script.IsEmpty()) {
		report_exception(&try_catch);
		return 1;
	} else {
		char * old = getcwd(NULL, 0);
		char * end = strrchr((char *)str, '/');
		if (end == NULL) {
			end = strrchr((char *)str, '\\');
		}
		if (end != NULL && change) {
			int len = end-str;
			char * base = (char *) malloc(len+1);
			strncpy(base, str, len);
    		base[len] = '\0';
    		chdir(base);
			free(base);
		}

		v8::Handle<v8::Value> result = script->Run();

		chdir(old);
		if (result.IsEmpty()) {
			report_exception(&try_catch);
			return 1;
		}
	}
	return 0;
}

int library(char * name) {
	v8::HandleScope handle_scope;
	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Value> prefix = config->ToObject()->Get(JS_STR("libraryPath"));
	v8::String::Utf8Value pfx(prefix);
	std::string path = "";

	path += *pfx;
	path += "/";
	path += name;

	if (path.find(".so") != std::string::npos) {
		void * handle;
	    if (!(handle = dlopen(path.c_str(), RTLD_LAZY))) {
			printf("open");
			return 1;
		}
		void (*func) (v8::Handle<v8::Object>);
		if (!(func = reinterpret_cast<void (*)(v8::Handle<v8::Object>)>(dlsym(handle, "init")))) {
			printf("init");
			dlclose(handle);
			return 1;
		}
		func(v8::Context::GetCurrent()->Global());
		return 0;
	} else {
		return execute_file(path.c_str(), false);
	}
}

v8::Handle<v8::Value> _include(const v8::Arguments& args) {
	bool ok = true;
	int result;
	for (int i = 0; i < args.Length(); i++) {
		v8::HandleScope handle_scope;
		v8::String::Utf8Value file(args[i]);
		result = execute_file(*file, false);
		if (result != 0) { ok = false; }
	}
	return JS_BOOL(ok);
}

v8::Handle<v8::Value> _library(const v8::Arguments & args) {
	bool ok = true;
	int result;

	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Value> prefix = config->ToObject()->Get(JS_STR("libraryPath"));
	v8::String::Utf8Value pfx(prefix);

	for (int i = 0; i < args.Length(); i++) {
		v8::HandleScope handle_scope;
		v8::String::Utf8Value file(args[i]);
		result = library(*file);
		if (result != 0) { ok = false; }
	}
	return JS_BOOL(ok);
}

v8::Handle<v8::Value> _exit(const v8::Arguments& args) {
	die(args[0]->Int32Value());
	return v8::Undefined();
}

v8::Handle<v8::Value> _onexit(const v8::Arguments& args) {
	__onexit->Set(JS_INT(__onexit->Length()), args[0]);
	return v8::Undefined();
}

int library_autoload() {
	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Array> list = v8::Handle<v8::Array>::Cast(config->ToObject()->Get(JS_STR("libraryAutoload")));
	int cnt = list->Length();
	for (int i=0;i<cnt;i++) {
		v8::Handle<v8::Value> item = list->Get(JS_INT(i));
		v8::String::Utf8Value name(item);
		if (library(*name)) { return 1; }
	}
	return 0;
}

void init(char * cfg) {
	int result = execute_file(cfg, false);
	if (result) {
		printf("Cannot load configuration, quitting...\n");
		die(1);
	}
	result = library_autoload();
	if (result) {
		printf("Cannot load default libraries, quitting...\n");
		die(1);
	}
}

int main(int argc, char ** argv, char ** envp) {
	v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
	v8::HandleScope handle_scope;

	v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
	v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
	v8::Context::Scope context_scope(context);

	__onexit = v8::Array::New();
	context->Global()->Set(JS_STR("library"), v8::FunctionTemplate::New(_library)->GetFunction());
	context->Global()->Set(JS_STR("include"), v8::FunctionTemplate::New(_include)->GetFunction());
	context->Global()->Set(JS_STR("exit"), v8::FunctionTemplate::New(_exit)->GetFunction());
	context->Global()->Set(JS_STR("onexit"), v8::FunctionTemplate::New(_onexit)->GetFunction());
	context->Global()->Set(JS_STR("global"), context->Global());
	context->Global()->Set(JS_STR("Config"), v8::Object::New());

	setup_system(envp, context->Global());
	setup_io(context->Global());

	char * cfg = STRING(CONFIG_PATH);
	int argptr = 0;
	for (int i = 1; i < argc; i++) {
		const char* str = argv[i];
		argptr = i;
		if (strcmp(str, "-c") == 0 && i + 1 < argc) {
			cfg = argv[i+1];
			argptr = 0;
			i++;
		}
	}

	init(cfg);

	if (!argptr) {
		// try the PATH_TRANSLATED env var
		v8::Handle<v8::Value> sys = v8::Context::GetCurrent()->Global()->Get(JS_STR("System"));
		v8::Handle<v8::Value> env = sys->ToObject()->Get(JS_STR("env"));
		v8::Handle<v8::Value> pt = env->ToObject()->Get(JS_STR("PATH_TRANSLATED"));
		if (pt->IsString()) {
			v8::String::Utf8Value name(pt);
			int result = execute_file(*name, true);
			if (result) { die(result); }
		} else {
			printf("Nothing to do.\n");
		}
	} else {
		int result = execute_file(argv[argptr], true);
		if (result) { die(result); }
	}
	die(0);
}
<commit_msg>dll<commit_after>/*
 * v8cgi main file. Loosely based on V8's "shell" sample app.
 */

#include <v8.h>
#include "js_system.h"
#include "js_io.h"
#include "js_common.h"
#include "js_macros.h"
#include <sstream>

#ifndef windows
#	include <dlfcn.h>
#else
#	include <windows.h>
#	define dlopen(x,y) (void*)LoadLibrary(x)
#	define dlsym(x,y) (void*)GetProcAddress((HMODULE)x,y)
#	define dlclose(x) FreeLibrary((HMODULE)x)
#endif

#define _STRING(x) #x
#define STRING(x) _STRING(x)

// chdir()
#ifndef HAVE_CHDIR
#	include <direct.h>
#	define chdir(name) _chdir(name)
#endif

// getcwd()
#ifndef HAVE_GETCWD
#	include <direct.h>
#	define getcwd(name, bytes) _getcwd(name, bytes)
#endif

v8::Handle<v8::Array> __onexit;

void die(int code) {
	uint32_t max = __onexit->Length();
	v8::Handle<v8::Function> fun;
	for (unsigned int i=0;i<max;i++) {
		fun = v8::Handle<v8::Function>::Cast(__onexit->Get(JS_INT(i)));
		fun->Call(v8::Context::GetCurrent()->Global(), 0, NULL);
	}
	exit(code);
}

v8::Handle<v8::String> read_file(const char* name) {
	FILE* file = fopen(name, "rb");
	if (file == NULL) return v8::Handle<v8::String>();

	fseek(file, 0, SEEK_END);
	size_t size = ftell(file);
	rewind(file);

	char* chars = new char[size + 1];
	chars[size] = '\0';
	for (unsigned int i = 0; i < size;) {
		size_t read = fread(&chars[i], 1, size - i, file);
		i += read;
	}
	fclose(file);

	/* remove shebang line */
	std::string str = chars;
	if ( str.find('#',0) == 0 && str.find('!',1) == 1 ) {
		unsigned int pfix = str.find('\n',0);
		str.erase(0,pfix);
	};

	v8::Handle<v8::String> result = JS_STR(str.c_str());
	delete[] chars;
	return result;
}

void report_exception(v8::TryCatch* try_catch) {
	v8::HandleScope handle_scope;
	v8::String::Utf8Value exception(try_catch->Exception());
	v8::Handle<v8::Message> message = try_catch->Message();
	std::string msgstring = "";
	std::stringstream ss;
	std::string tmp;

	if (message.IsEmpty()) {
		msgstring += *exception;
		msgstring += "\n";
	} else {
		v8::String::Utf8Value filename(message->GetScriptResourceName());
		int linenum = message->GetLineNumber();
		msgstring += *filename;
		msgstring += ":";

		ss << linenum;
		ss >> tmp;

		msgstring += tmp;
		msgstring += ": ";
		msgstring += *exception;
		msgstring += "\n";
	}

	int cgi = 0;
	v8::Local<v8::Function> fun;
	v8::Local<v8::Value> context = v8::Context::GetCurrent()->Global()->Get(JS_STR("response"));
	if (context->IsObject()) {
		v8::Local<v8::Value> print = context->ToObject()->Get(JS_STR("error"));
		if (print->IsObject()) {
			fun = v8::Local<v8::Function>::Cast(print);
			cgi = 1;
		}
	}
	if (!cgi) {
		context = v8::Context::GetCurrent()->Global()->Get(JS_STR("System"));
		fun = v8::Local<v8::Function>::Cast(context->ToObject()->Get(JS_STR("stdout")));
	}

	v8::Handle<v8::Value> data[1];
	data[0] = JS_STR(msgstring.c_str());
	fun->Call(context->ToObject(), 1, data);
}

int execute_file(const char * str, bool change) {
	v8::HandleScope handle_scope;
	v8::TryCatch try_catch;
	v8::Handle<v8::String> name = JS_STR(str);
	v8::Handle<v8::String> source = read_file(str);

	if (source.IsEmpty()) {
		printf("Error reading '%s'\n", str);
		return 1;
	}

	v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
	if (script.IsEmpty()) {
		report_exception(&try_catch);
		return 1;
	} else {
		char * old = getcwd(NULL, 0);
		char * end = strrchr((char *)str, '/');
		if (end == NULL) {
			end = strrchr((char *)str, '\\');
		}
		if (end != NULL && change) {
			int len = end-str;
			char * base = (char *) malloc(len+1);
			strncpy(base, str, len);
    		base[len] = '\0';
    		chdir(base);
			free(base);
		}

		v8::Handle<v8::Value> result = script->Run();

		chdir(old);
		if (result.IsEmpty()) {
			report_exception(&try_catch);
			return 1;
		}
	}
	return 0;
}

int library(char * name) {
	v8::HandleScope handle_scope;
	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Value> prefix = config->ToObject()->Get(JS_STR("libraryPath"));
	v8::String::Utf8Value pfx(prefix);
	std::string path = "";

	path += *pfx;
	path += "/";
	path += name;

	if (path.find(".so") != std::string::npos || path.find(".dll") != std::string::npos) {
		void * handle;
	    if (!(handle = dlopen(path.c_str(), RTLD_LAZY))) {
			printf("open");
			return 1;
		}
		void (*func) (v8::Handle<v8::Object>);
		if (!(func = reinterpret_cast<void (*)(v8::Handle<v8::Object>)>(dlsym(handle, "init")))) {
			printf("init");
			dlclose(handle);
			return 1;
		}
		func(v8::Context::GetCurrent()->Global());
		return 0;
	} else {
		return execute_file(path.c_str(), false);
	}
}

v8::Handle<v8::Value> _include(const v8::Arguments& args) {
	bool ok = true;
	int result;
	for (int i = 0; i < args.Length(); i++) {
		v8::HandleScope handle_scope;
		v8::String::Utf8Value file(args[i]);
		result = execute_file(*file, false);
		if (result != 0) { ok = false; }
	}
	return JS_BOOL(ok);
}

v8::Handle<v8::Value> _library(const v8::Arguments & args) {
	bool ok = true;
	int result;

	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Value> prefix = config->ToObject()->Get(JS_STR("libraryPath"));
	v8::String::Utf8Value pfx(prefix);

	for (int i = 0; i < args.Length(); i++) {
		v8::HandleScope handle_scope;
		v8::String::Utf8Value file(args[i]);
		result = library(*file);
		if (result != 0) { ok = false; }
	}
	return JS_BOOL(ok);
}

v8::Handle<v8::Value> _exit(const v8::Arguments& args) {
	die(args[0]->Int32Value());
	return v8::Undefined();
}

v8::Handle<v8::Value> _onexit(const v8::Arguments& args) {
	__onexit->Set(JS_INT(__onexit->Length()), args[0]);
	return v8::Undefined();
}

int library_autoload() {
	v8::Handle<v8::Value> config = v8::Context::GetCurrent()->Global()->Get(JS_STR("Config"));
	v8::Handle<v8::Array> list = v8::Handle<v8::Array>::Cast(config->ToObject()->Get(JS_STR("libraryAutoload")));
	int cnt = list->Length();
	for (int i=0;i<cnt;i++) {
		v8::Handle<v8::Value> item = list->Get(JS_INT(i));
		v8::String::Utf8Value name(item);
		if (library(*name)) { return 1; }
	}
	return 0;
}

void init(char * cfg) {
	int result = execute_file(cfg, false);
	if (result) {
		printf("Cannot load configuration, quitting...\n");
		die(1);
	}
	result = library_autoload();
	if (result) {
		printf("Cannot load default libraries, quitting...\n");
		die(1);
	}
}

int main(int argc, char ** argv, char ** envp) {
	v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
	v8::HandleScope handle_scope;

	v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
	v8::Handle<v8::Context> context = v8::Context::New(NULL, global);
	v8::Context::Scope context_scope(context);

	__onexit = v8::Array::New();
	context->Global()->Set(JS_STR("library"), v8::FunctionTemplate::New(_library)->GetFunction());
	context->Global()->Set(JS_STR("include"), v8::FunctionTemplate::New(_include)->GetFunction());
	context->Global()->Set(JS_STR("exit"), v8::FunctionTemplate::New(_exit)->GetFunction());
	context->Global()->Set(JS_STR("onexit"), v8::FunctionTemplate::New(_onexit)->GetFunction());
	context->Global()->Set(JS_STR("global"), context->Global());
	context->Global()->Set(JS_STR("Config"), v8::Object::New());

	setup_system(envp, context->Global());
	setup_io(context->Global());

	char * cfg = STRING(CONFIG_PATH);
	int argptr = 0;
	for (int i = 1; i < argc; i++) {
		const char* str = argv[i];
		argptr = i;
		if (strcmp(str, "-c") == 0 && i + 1 < argc) {
			cfg = argv[i+1];
			argptr = 0;
			i++;
		}
	}

	init(cfg);

	if (!argptr) {
		// try the PATH_TRANSLATED env var
		v8::Handle<v8::Value> sys = v8::Context::GetCurrent()->Global()->Get(JS_STR("System"));
		v8::Handle<v8::Value> env = sys->ToObject()->Get(JS_STR("env"));
		v8::Handle<v8::Value> pt = env->ToObject()->Get(JS_STR("PATH_TRANSLATED"));
		if (pt->IsString()) {
			v8::String::Utf8Value name(pt);
			int result = execute_file(*name, true);
			if (result) { die(result); }
		} else {
			printf("Nothing to do.\n");
		}
	} else {
		int result = execute_file(argv[argptr], true);
		if (result) { die(result); }
	}
	die(0);
}
<|endoftext|>