<commit_before>#include "reader_options.h"
#include "rpg_actor.h"
#include "rpg_event.h"
#include "rpg_map.h"
#include "rpg_mapinfo.h"
#include "rpg_system.h"
#include "rpg_save.h"
#include "rpg_chipset.h"
#include "rpg_parameters.h"
#include "data.h"

void RPG::SaveActor::Setup(int actor_id) {
	const RPG::Actor& actor = Data::actors[actor_id - 1];
	ID = actor.ID;
	name = actor.name;
	title = actor.title;
	sprite_name = actor.character_name;
	sprite_id = actor.character_index;
	sprite_flags = actor.transparent ? 3 : 0;
	face_name = actor.face_name;
	face_id = actor.face_index;
	level = actor.initial_level;
	exp = 0;
	hp_mod = 0;
	sp_mod = 0;
	attack_mod = 0;
	defense_mod = 0;
	spirit_mod = 0;
	agility_mod = 0;
	skills_size = 0;
	skills.clear();
	equipped.clear();
	equipped.push_back(actor.initial_equipment.weapon_id);
	equipped.push_back(actor.initial_equipment.shield_id);
	equipped.push_back(actor.initial_equipment.armor_id);
	equipped.push_back(actor.initial_equipment.helmet_id);
	equipped.push_back(actor.initial_equipment.accessory_id);
	current_hp = 0;
	current_sp = 0;
	battle_commands = actor.battle_commands;
	status_size = 0;
	status.clear();
	changed_class = false;
	class_id = actor.class_id;
	unknown_5b = -1;
	two_weapon = actor.two_swords_style;
	lock_equipment = actor.fix_equipment;
	auto_battle = actor.auto_battle;
	mighty_guard = actor.super_guard;
	unknown_60 = -1;
}

void RPG::SaveInventory::Setup() {
	party = Data::system.party;
	party_size = party.size();
}

void RPG::SaveMapEvent::Setup(const RPG::Event& event) {
	ID = event.ID;
	position_x = event.x;
	position_y = event.y;
}

void RPG::SaveMapInfo::Setup() {
	pan_x = 0;
	pan_y = 0;
	lower_tiles.resize(144);
	upper_tiles.resize(144);
	for (int i = 0; i < 144; i++) {
		lower_tiles[i] = i;
		upper_tiles[i] = i;
	}
}

void RPG::SaveMapInfo::Setup(const RPG::Map& map) {
	chipset_id = map.chipset_id;
	parallax_name = map.parallax_name;
	parallax_horz = map.parallax_loop_x;
	parallax_vert = map.parallax_loop_y;
	parallax_horz_auto = map.parallax_auto_loop_x;
	parallax_vert_auto = map.parallax_auto_loop_y;
	parallax_horz_speed = map.parallax_sx;
	parallax_vert_speed = map.parallax_sy;
}

void RPG::SaveMapInfo::Setup(const RPG::MapInfo& map_info) {
	encounter_rate = map_info.encounter_steps;
}

void RPG::SaveSystem::Setup() {
	const RPG::System& system = Data::system;
	screen = 0;
	frame_count = 0;
	graphics_name = system.system_name;
	switches_size = Data::switches.size();
	switches.resize(switches_size);
	variables_size = Data::variables.size();
	variables.resize(variables_size);
	message_transparent = -1;
	message_position = -1;
	message_placement = -1;
	message_continue = -1;
	face_name = "";
	face_id = -1;
	face_right = false;
	face_flip = false;
	transparent = false;
	unknown_3d = -1;
	title_music = system.title_music;
	battle_music = system.battle_music;
	battle_end_music = system.battle_end_music;
	inn_music = system.inn_music;
	// current_music
	// unknown1_music
	// unknown2_music
	// stored_music
	boat_music = system.boat_music;
	ship_music = system.ship_music;
	airship_music = system.airship_music;
	gameover_music = system.gameover_music;
	cursor_se = system.cursor_se;
	decision_se = system.decision_se;
	cancel_se = system.cancel_se;
	buzzer_se = system.buzzer_se;
	battle_se = system.battle_se;
	escape_se = system.escape_se;
	enemy_attack_se = system.enemy_attack_se;
	enemy_damaged_se = system.enemy_damaged_se;
	actor_damaged_se = system.actor_damaged_se;
	dodge_se = system.dodge_se;
	enemy_death_se = system.enemy_death_se;
	item_se = system.item_se;
	transition_out = system.transition_out;
	transition_in = system.transition_in;
	battle_start_fadeout = system.battle_start_fadeout;
	battle_start_fadein = system.battle_start_fadein;
	battle_end_fadeout = system.battle_end_fadeout;
	battle_end_fadein = system.battle_end_fadein;
	teleport_allowed = true;
	escape_allowed = true;
	save_allowed = true;
	menu_allowed = true;
	background = "";
	save_count = -1;
	save_slot = -1;
}

void RPG::Save::Setup() {
	system.Setup();
	pictures.resize(50);
	for (int i = 1; i <= (int) pictures.size(); i++)
		pictures[i - 1].ID = i;
	actors.resize(Data::actors.size());
	for (int i = 1; i <= (int) actors.size(); i++)
		actors[i - 1].Setup(i);
	map_info.Setup();
}

void RPG::Actor::Init() {
#if RPGMAKER == RPG2K3
	final_level = 99;
	exp_base = 300;
	exp_inflation = 300;
#endif
	parameters.Setup(final_level);
}

void RPG::MapInfo::Init() {
	music.name = "(OFF)";
}

void RPG::Chipset::Init() {
	terrain_data.resize(162, 1);
	passable_data_lower.resize(162, 15);
	passable_data_upper.resize(162, 15);
}

void RPG::Parameters::Setup(int final_level) {
	maxhp.resize(final_level + 1);
	maxsp.resize(final_level + 1);
	attack.resize(final_level + 1);
	defense.resize(final_level + 1);
	spirit.resize(final_level + 1);
	agility.resize(final_level + 1);
	for (int i = 0; i <= final_level; i++) {
		maxhp[i] = 1;
		maxsp[i] = 0;
		attack[i] = 1;
		defense[i] = 1;
		spirit[i] = 1;
		agility[i] = 1;
	}
}
<commit_msg>Bugfix: When the player resets (via F12 or Menu) switches and variables are not reset to the default values.<commit_after>#include "reader_options.h"
#include "rpg_actor.h"
#include "rpg_event.h"
#include "rpg_map.h"
#include "rpg_mapinfo.h"
#include "rpg_system.h"
#include "rpg_save.h"
#include "rpg_chipset.h"
#include "rpg_parameters.h"
#include "data.h"

void RPG::SaveActor::Setup(int actor_id) {
	const RPG::Actor& actor = Data::actors[actor_id - 1];
	ID = actor.ID;
	name = actor.name;
	title = actor.title;
	sprite_name = actor.character_name;
	sprite_id = actor.character_index;
	sprite_flags = actor.transparent ? 3 : 0;
	face_name = actor.face_name;
	face_id = actor.face_index;
	level = actor.initial_level;
	exp = 0;
	hp_mod = 0;
	sp_mod = 0;
	attack_mod = 0;
	defense_mod = 0;
	spirit_mod = 0;
	agility_mod = 0;
	skills_size = 0;
	skills.clear();
	equipped.clear();
	equipped.push_back(actor.initial_equipment.weapon_id);
	equipped.push_back(actor.initial_equipment.shield_id);
	equipped.push_back(actor.initial_equipment.armor_id);
	equipped.push_back(actor.initial_equipment.helmet_id);
	equipped.push_back(actor.initial_equipment.accessory_id);
	current_hp = 0;
	current_sp = 0;
	battle_commands = actor.battle_commands;
	status_size = 0;
	status.clear();
	changed_class = false;
	class_id = actor.class_id;
	unknown_5b = -1;
	two_weapon = actor.two_swords_style;
	lock_equipment = actor.fix_equipment;
	auto_battle = actor.auto_battle;
	mighty_guard = actor.super_guard;
	unknown_60 = -1;
}

void RPG::SaveInventory::Setup() {
	party = Data::system.party;
	party_size = party.size();
}

void RPG::SaveMapEvent::Setup(const RPG::Event& event) {
	ID = event.ID;
	position_x = event.x;
	position_y = event.y;
}

void RPG::SaveMapInfo::Setup() {
	pan_x = 0;
	pan_y = 0;
	lower_tiles.resize(144);
	upper_tiles.resize(144);
	for (int i = 0; i < 144; i++) {
		lower_tiles[i] = i;
		upper_tiles[i] = i;
	}
}

void RPG::SaveMapInfo::Setup(const RPG::Map& map) {
	chipset_id = map.chipset_id;
	parallax_name = map.parallax_name;
	parallax_horz = map.parallax_loop_x;
	parallax_vert = map.parallax_loop_y;
	parallax_horz_auto = map.parallax_auto_loop_x;
	parallax_vert_auto = map.parallax_auto_loop_y;
	parallax_horz_speed = map.parallax_sx;
	parallax_vert_speed = map.parallax_sy;
}

void RPG::SaveMapInfo::Setup(const RPG::MapInfo& map_info) {
	encounter_rate = map_info.encounter_steps;
}

void RPG::SaveSystem::Setup() {
	const RPG::System& system = Data::system;
	screen = 0;
	frame_count = 0;
	graphics_name = system.system_name;
	switches_size = Data::switches.size();
	switches.clear();
	switches.resize(switches_size);
	variables_size = Data::variables.size();
	variables.clear();
	variables.resize(variables_size);
	message_transparent = -1;
	message_position = -1;
	message_placement = -1;
	message_continue = -1;
	face_name = "";
	face_id = -1;
	face_right = false;
	face_flip = false;
	transparent = false;
	unknown_3d = -1;
	title_music = system.title_music;
	battle_music = system.battle_music;
	battle_end_music = system.battle_end_music;
	inn_music = system.inn_music;
	// current_music
	// unknown1_music
	// unknown2_music
	// stored_music
	boat_music = system.boat_music;
	ship_music = system.ship_music;
	airship_music = system.airship_music;
	gameover_music = system.gameover_music;
	cursor_se = system.cursor_se;
	decision_se = system.decision_se;
	cancel_se = system.cancel_se;
	buzzer_se = system.buzzer_se;
	battle_se = system.battle_se;
	escape_se = system.escape_se;
	enemy_attack_se = system.enemy_attack_se;
	enemy_damaged_se = system.enemy_damaged_se;
	actor_damaged_se = system.actor_damaged_se;
	dodge_se = system.dodge_se;
	enemy_death_se = system.enemy_death_se;
	item_se = system.item_se;
	transition_out = system.transition_out;
	transition_in = system.transition_in;
	battle_start_fadeout = system.battle_start_fadeout;
	battle_start_fadein = system.battle_start_fadein;
	battle_end_fadeout = system.battle_end_fadeout;
	battle_end_fadein = system.battle_end_fadein;
	teleport_allowed = true;
	escape_allowed = true;
	save_allowed = true;
	menu_allowed = true;
	background = "";
	save_count = -1;
	save_slot = -1;
}

void RPG::Save::Setup() {
	system.Setup();
	pictures.resize(50);
	for (int i = 1; i <= (int) pictures.size(); i++)
		pictures[i - 1].ID = i;
	actors.resize(Data::actors.size());
	for (int i = 1; i <= (int) actors.size(); i++)
		actors[i - 1].Setup(i);
	map_info.Setup();
}

void RPG::Actor::Init() {
#if RPGMAKER == RPG2K3
	final_level = 99;
	exp_base = 300;
	exp_inflation = 300;
#endif
	parameters.Setup(final_level);
}

void RPG::MapInfo::Init() {
	music.name = "(OFF)";
}

void RPG::Chipset::Init() {
	terrain_data.resize(162, 1);
	passable_data_lower.resize(162, 15);
	passable_data_upper.resize(162, 15);
}

void RPG::Parameters::Setup(int final_level) {
	maxhp.resize(final_level + 1);
	maxsp.resize(final_level + 1);
	attack.resize(final_level + 1);
	defense.resize(final_level + 1);
	spirit.resize(final_level + 1);
	agility.resize(final_level + 1);
	for (int i = 0; i <= final_level; i++) {
		maxhp[i] = 1;
		maxsp[i] = 0;
		attack[i] = 1;
		defense[i] = 1;
		spirit[i] = 1;
		agility[i] = 1;
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2017-2018 The LitecoinZ developers
// Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44

/*

To set up a new alert system
----------------------------

Create a new alert key pair:
openssl ecparam -name secp256k1 -genkey -param_enc explicit -outform PEM -out data.pem

Get the private key in hex:
openssl ec -in data.pem -outform DER | tail -c 279 | xxd -p -c 279

Get the public key in hex:
openssl ec -in data.pem -pubout -outform DER | tail -c 65 | xxd -p -c 65

Update the public keys found in chainparams.cpp.

To send an alert message
------------------------

Copy the private keys into alertkeys.h.

Modify the alert parameters, id and message found in this file.

Build and run with -sendalert or -printalert.

./litecoinzd -printtoconsole -sendalert

One minute after starting up, the alert will be broadcast. It is then
flooded through the network until the nRelayUntil time, and will be
active until nExpiration OR the alert is cancelled.

If you make a mistake, send another alert with nCancel set to cancel
the bad alert.

*/

#include "main.h"
#include "net.h"
#include "alert.h"
#include "init.h"

#include "util.h"
#include "utiltime.h"
#include "key.h"
#include "clientversion.h"
#include "chainparams.h"

#include "alertkeys.h"

static const int64_t DAYS = 24 * 60 * 60;

void ThreadSendAlert()
{
    if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert"))
        return;

    MilliSleep(60*1000); // Wait a minute so we get connected

    //
    // Alerts are relayed around the network until nRelayUntil, flood
    // filling to every node.
    // After the relay time is past, new nodes are told about alerts
    // when they connect to peers, until either nExpiration or
    // the alert is cancelled by a newer alert.
    // Nodes never save alerts to disk, they are in-memory-only.
    //
    CAlert alert;
    alert.nRelayUntil   = GetTime() + 15 * 60;
    alert.nExpiration   = GetTime() + 10 * 365 * 24 * 60 * 60;
    alert.nID           = 1005;  // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs
    alert.nCancel       = 1004;  // cancels previous messages up to this ID number

    // These versions are protocol versions
    // 170004 : 1.0.16
    alert.nMinVer       = 170004;
    alert.nMaxVer       = 170004;

    //
    // main.cpp:
    //  1000 for Misc warnings like out of disk space and clock is wrong
    //  2000 for longer invalid proof-of-work chain
    //  Higher numbers mean higher priority
    //  4000 or higher will put the RPC into safe mode
    alert.nPriority     = 4000;
    alert.strComment    = "";
    alert.strStatusBar  = "Your client is out of date and incompatible with the Overwinter network upgrade. Please update to a recent version of LitecoinZ (2.0.0 or later).";
    alert.strRPCError   = alert.strStatusBar;

    // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done:
    // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/"));
    const std::vector<std::string> useragents = {}; //{"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"};

    BOOST_FOREACH(const std::string& useragent, useragents) {
    }

    // Sanity check
    assert(alert.strComment.length() <= 65536); // max length in alert.h
    assert(alert.strStatusBar.length() <= 256);
    assert(alert.strRPCError.length() <= 256);

    // Sign
    const CChainParams& chainparams = Params();
    std::string networkID = chainparams.NetworkIDString();
    bool fIsTestNet = networkID.compare("test") == 0;
    std::vector<unsigned char> vchTmp(ParseHex(fIsTestNet ? pszTestNetPrivKey : pszPrivKey));
    CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end());

    CDataStream sMsg(SER_NETWORK, CLIENT_VERSION);
    sMsg << *(CUnsignedAlert*)&alert;
    alert.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    CKey key;
    if (!key.SetPrivKey(vchPrivKey, false))
    {
        printf("ThreadSendAlert() : key.SetPrivKey failed\n");
        return;
    }
    if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
    {
        printf("ThreadSendAlert() : key.Sign failed\n");
        return;
    }

    // Test
    CDataStream sBuffer(SER_NETWORK, CLIENT_VERSION);
    sBuffer << alert;
    CAlert alert2;
    sBuffer >> alert2;
    if (!alert2.CheckSignature(chainparams.AlertKey()))
    {
        printf("ThreadSendAlert() : CheckSignature failed\n");
        return;
    }
    assert(alert2.vchMsg == alert.vchMsg);
    assert(alert2.vchSig == alert.vchSig);
    alert.SetNull();
    printf("\nThreadSendAlert:\n");
    printf("hash=%s\n", alert2.GetHash().ToString().c_str());
    printf("%s\n", alert2.ToString().c_str());
    printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str());
    printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str());

    // Confirm
    if (!mapArgs.count("-sendalert"))
        return;
    while (vNodes.size() < 1 && !ShutdownRequested())
        MilliSleep(500);
    if (ShutdownRequested())
        return;

    // Send
    printf("ThreadSendAlert() : Sending alert\n");
    int nSent = 0;
    {
        LOCK(cs_vNodes);
        BOOST_FOREACH(CNode* pnode, vNodes)
        {
            if (alert2.RelayTo(pnode))
            {
                printf("ThreadSendAlert() : Sent alert to %s\n", pnode->addr.ToString().c_str());
                nSent++;
            }
        }
    }
    printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent);
}
<commit_msg>Send alert to put non-Sapling nodes into safe mode<commit_after>// Copyright (c) 2016 The Zcash developers
// Copyright (c) 2017-2018 The LitecoinZ developers
// Original code from: https://gist.github.com/laanwj/0e689cfa37b52bcbbb44

/*

To set up a new alert system
----------------------------

Create a new alert key pair:
openssl ecparam -name secp256k1 -genkey -param_enc explicit -outform PEM -out data.pem

Get the private key in hex:
openssl ec -in data.pem -outform DER | tail -c 279 | xxd -p -c 279

Get the public key in hex:
openssl ec -in data.pem -pubout -outform DER | tail -c 65 | xxd -p -c 65

Update the public keys found in chainparams.cpp.

To send an alert message
------------------------

Copy the private keys into alertkeys.h.

Modify the alert parameters, id and message found in this file.

Build and run with -sendalert or -printalert.

./litecoinzd -printtoconsole -sendalert

One minute after starting up, the alert will be broadcast. It is then
flooded through the network until the nRelayUntil time, and will be
active until nExpiration OR the alert is cancelled.

If you make a mistake, send another alert with nCancel set to cancel
the bad alert.

*/

#include "main.h"
#include "net.h"
#include "alert.h"
#include "init.h"

#include "util.h"
#include "utiltime.h"
#include "key.h"
#include "clientversion.h"
#include "chainparams.h"

#include "alertkeys.h"

static const int64_t DAYS = 24 * 60 * 60;

void ThreadSendAlert()
{
    if (!mapArgs.count("-sendalert") && !mapArgs.count("-printalert"))
        return;

    MilliSleep(60*1000); // Wait a minute so we get connected

    //
    // Alerts are relayed around the network until nRelayUntil, flood
    // filling to every node.
    // After the relay time is past, new nodes are told about alerts
    // when they connect to peers, until either nExpiration or
    // the alert is cancelled by a newer alert.
    // Nodes never save alerts to disk, they are in-memory-only.
    //
    CAlert alert;
    alert.nRelayUntil   = GetTime() + 15 * 60;
    alert.nExpiration   = GetTime() + 10 * 365 * 24 * 60 * 60;
    alert.nID           = 1006;  // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs
    alert.nCancel       = 1005;  // cancels previous messages up to this ID number

    // These versions are protocol versions
    // 170004 : 1.0.16
    // 170007 : 2.0.0
    alert.nMinVer       = 170004;
    alert.nMaxVer       = 170006;

    //
    // main.cpp:
    //  1000 for Misc warnings like out of disk space and clock is wrong
    //  2000 for longer invalid proof-of-work chain
    //  Higher numbers mean higher priority
    //  4000 or higher will put the RPC into safe mode
    alert.nPriority     = 4000;
    alert.strComment    = "";
    alert.strStatusBar  = "Your client is out of date and incompatible with the Sapling network upgrade. Please update to a recent version of LitecoinZ (2.0.0 or later).";
    alert.strRPCError   = alert.strStatusBar;

    // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done:
    // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/"));
    const std::vector<std::string> useragents = {}; //{"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"};

    BOOST_FOREACH(const std::string& useragent, useragents) {
    }

    // Sanity check
    assert(alert.strComment.length() <= 65536); // max length in alert.h
    assert(alert.strStatusBar.length() <= 256);
    assert(alert.strRPCError.length() <= 256);

    // Sign
    const CChainParams& chainparams = Params();
    std::string networkID = chainparams.NetworkIDString();
    bool fIsTestNet = networkID.compare("test") == 0;
    std::vector<unsigned char> vchTmp(ParseHex(fIsTestNet ? pszTestNetPrivKey : pszPrivKey));
    CPrivKey vchPrivKey(vchTmp.begin(), vchTmp.end());

    CDataStream sMsg(SER_NETWORK, CLIENT_VERSION);
    sMsg << *(CUnsignedAlert*)&alert;
    alert.vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    CKey key;
    if (!key.SetPrivKey(vchPrivKey, false))
    {
        printf("ThreadSendAlert() : key.SetPrivKey failed\n");
        return;
    }
    if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
    {
        printf("ThreadSendAlert() : key.Sign failed\n");
        return;
    }

    // Test
    CDataStream sBuffer(SER_NETWORK, CLIENT_VERSION);
    sBuffer << alert;
    CAlert alert2;
    sBuffer >> alert2;
    if (!alert2.CheckSignature(chainparams.AlertKey()))
    {
        printf("ThreadSendAlert() : CheckSignature failed\n");
        return;
    }
    assert(alert2.vchMsg == alert.vchMsg);
    assert(alert2.vchSig == alert.vchSig);
    alert.SetNull();
    printf("\nThreadSendAlert:\n");
    printf("hash=%s\n", alert2.GetHash().ToString().c_str());
    printf("%s\n", alert2.ToString().c_str());
    printf("vchMsg=%s\n", HexStr(alert2.vchMsg).c_str());
    printf("vchSig=%s\n", HexStr(alert2.vchSig).c_str());

    // Confirm
    if (!mapArgs.count("-sendalert"))
        return;
    while (vNodes.size() < 1 && !ShutdownRequested())
        MilliSleep(500);
    if (ShutdownRequested())
        return;

    // Send
    printf("ThreadSendAlert() : Sending alert\n");
    int nSent = 0;
    {
        LOCK(cs_vNodes);
        BOOST_FOREACH(CNode* pnode, vNodes)
        {
            if (alert2.RelayTo(pnode))
            {
                printf("ThreadSendAlert() : Sent alert to %s\n", pnode->addr.ToString().c_str());
                nSent++;
            }
        }
    }
    printf("ThreadSendAlert() : Alert sent to %d nodes\n", nSent);
}
<|endoftext|>


<commit_before>/*****************************************************************************************//**
* @file sensortag.cpp
*
* Copyright (c)
* SmartRoboticSystems
* December 2015
*
* This program creates connection to SensorTag 2650 using hcitool & gatttool, starts
* temperature, light and humidity measurements, set up and process notifications,
* computes real world data and saves results to files temperature.txt, humidity.txt,
* light.txt on "IoT/data/" filepath. Child process & stdin/stdout redirection is utilized
*
* Licensed under the EUPL V.1.1
*
* This Software is provided to You under the terms of the European
* Union Public License (the "EUPL") version 1.1 as published by the
* European Union. Any use of this Software, other than as authorized
* under this License is strictly prohibited (to the extent such use
* is covered by a right of the copyright holder of this Software).
*
* This Software is provided under the License on an "AS IS" basis and
* without warranties of any kind concerning the Software, including
* without limitation merchantability, fitness for a particular purpose,
* absence of defects or errors, accuracy, and non-infringement of
* intellectual property rights other than copyright. This disclaimer
* of warranty is an essential part of the License and a condition for
* the grant of any rights to this Software.
******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>

#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>

#include "filepaths.h"

#define PIPE_READ 0
#define PIPE_WRITE 1

int createChildProcess(const char* command, char* const arguments[], char* const environment[])
{
  int stdin_pipe[2];
  int stdout_pipe[2];
  int child_num;
  int execve_result;
  char act_char;

  if (pipe(stdin_pipe) < 0)
  {
    perror("allocating pipe for child input redirect");
    return -1;
  }
  if (pipe(stdout_pipe) < 0)
  {
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    perror("allocating pipe for child output redirect");
    return -1;
  }

  child_num = fork();
  if (0 == child_num)
  {
    // child continues here
    // redirect stdin
    if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1)
    {
      perror("redirecting stdin");
      return -1;
    }

    // redirect stdout
    if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1)
    {
      perror("redirecting stdout");
      return -1;
    }

    // redirect stderr
    if (dup2(stdout_pipe[PIPE_WRITE], STDERR_FILENO) == -1)
    {
      perror("redirecting stderr");
      return -1;
    }

    // all these are for use by parent only
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);

    // run child process image
    execve_result = execve(command, arguments, environment);

    // if we get here at all, an error occurred, but we are in the child
    // process, so just exit
    perror("exec of the child process");
    exit(execve_result);
  }
  else if (child_num > 0)
  {
    // parent continues here

    // close unused file descriptors, these are for child only
    close(stdin_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);

    //==============================================================
    // Connect
    //==============================================================
    const char* connect_message = "connect \r\n";
    if (NULL != connect_message)
      write(stdin_pipe[PIPE_WRITE], connect_message, strlen(connect_message));

    //Read console output
    do {
      read(stdout_pipe[PIPE_READ], &act_char, 1);
      write(STDOUT_FILENO, &act_char, 1);
    } while (act_char != '\n');

    usleep(1000000);

   //==============================================================
   // Start Temperature measurement
   //==============================================================

   //Start measurement
   const char* start_temperature = "char-write-req 0x24 01 \r\n";
   if (NULL != start_temperature)
     write(stdin_pipe[PIPE_WRITE], start_temperature, strlen(start_temperature));

   //Turn on notifications
   const char* read_temperature = "char-write-req 0x22 0100 \r\n";
   if (NULL != read_temperature)
     write(stdin_pipe[PIPE_WRITE], read_temperature, strlen(read_temperature));

   //Set notification period to 2.5 sec
   const char* temperature_period = "char-write-req 0x26 0xFA \r\n";
   if (NULL != temperature_period)
     write(stdin_pipe[PIPE_WRITE], temperature_period, strlen(temperature_period));

   //==============================================================
   // Start Light measurement
   //==============================================================

   //Start measurement
   const char* start_light = "char-write-req 0x44 01 \r\n";
   if (NULL != start_light)
     write(stdin_pipe[PIPE_WRITE], start_light, strlen(start_light));

  //Turn on notifications
   const char* read_light = "char-write-req 0x42 0100 \r\n";
   if (NULL != read_light)
     write(stdin_pipe[PIPE_WRITE], read_light, strlen(read_light));

   //Set notification period to 2.5 sec
   const char* light_period = "char-write-req 0x46 0xFA \r\n";
   if (NULL != light_period)
     write(stdin_pipe[PIPE_WRITE], light_period, strlen(light_period));

   //==============================================================
   // Start Humidity measurement
   //==============================================================

   //Start measurement
   const char* start_humidity = "char-write-req 0x2c 01 \r\n";
   if (NULL != start_humidity)
     write(stdin_pipe[PIPE_WRITE], start_humidity, strlen(start_humidity));

   //Turn on notifications
   const char* read_humidity = "char-write-req 0x2A 0100 \r\n";
   if (NULL != read_humidity)
     write(stdin_pipe[PIPE_WRITE], read_humidity, strlen(read_humidity));

   //Set notification period to 2.5 sec
   const char* humidity_period = "char-write-req 0x2e 0xFA \r\n";
   if (NULL != humidity_period)
     write(stdin_pipe[PIPE_WRITE], humidity_period, strlen(humidity_period));

/*   //==============================================================
   // Start Barometer measurement
   //==============================================================

   //Start measurement
   const char* start_barometer = "char-write-req 0x34 01 \r\n";
   if (NULL != start_barometer)
     write(aStdinPipe[PIPE_WRITE], start_barometer, strlen(start_barometer));

   //Turn on notifications
   const char* read_barometer = "char-write-req 0x32 0100 \r\n";
   if (NULL != read_barometer)
     write(aStdinPipe[PIPE_WRITE], read_barometer, strlen(read_barometer));

   //Set notification period to 2.5 sec
   const char* barometer_period = "char-write-req 0x36 0xFA \r\n";
   if (NULL != barometer_period)
     write(aStdinPipe[PIPE_WRITE], barometer_period, strlen(barometer_period));
*/

   //==============================================================
   // Process notifications
   //==============================================================

   double humidity = 0;
   double temperature = 0;
   double light = 0;
   double barometer = 0;

   const std::string temp_handle = "0x0021";
   const std::string light_handle = "0x0041";
   const std::string humidity_handle = "0x0029";
   const std::string barometer_handle = "0x0031";
   bool new_measurement = false;

   while(1)
   {
     std::string actual_line;

     do {
       read(stdout_pipe[PIPE_READ], &act_char, 1);
       actual_line += act_char;
     } while (act_char != '\n');

     //Temperature notification
     int temperature_index = actual_line.find(temp_handle);

     if(temperature_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int temperature_bytes[2];

       //Extract bytes from string notifications
       temp = actual_line.substr(temperature_index + 20, 2);
       temperature_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(temperature_index + 23,2);
       temperature_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Merge bytes
       unsigned int temperature_raw = (temperature_bytes[1] << 8) + temperature_bytes[0];

       //Compute final value
       temperature = temperature_raw/128.0;
     }

     //Light notification
     int light_index = actual_line.find(light_handle);
     if(light_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int light_bytes[2];

       //Extract bytes from string notifications
       temp = actual_line.substr(light_index + 14, 2);
       light_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(light_index + 17, 2);
       light_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Compute exponent and fraction according to formula
       unsigned int exponent = (light_bytes[1] & 0b11110000) >> 4;
       unsigned int fraction = ((light_bytes[1] & 0b00001111) << 8) + light_bytes[0];

       //Compute final value
       light = 0.01 * pow(2,exponent) * fraction;
     }

     //Humidity notification
     int humidity_index = actual_line.find(humidity_handle);
     if(humidity_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int humidity_bytes[2];

       //Extract bytes from string notification
       temp = actual_line.substr(humidity_index + 20, 2);
       humidity_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(humidity_index + 23,2);
       humidity_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Merge bytes
       unsigned int humidity_raw = (humidity_bytes[1] << 8) + humidity_bytes[0];

       //Clear 2 LSB
       humidity_raw &= ~0x0003;

       //Cast to double
       humidity = static_cast<double>(humidity_raw);

       //Compute final value
       humidity = 125*(humidity/65536) - 6;
     }

     //Print if new measurement occured
     if(new_measurement == true)
     {
       std::cout << "Temp: "        << std::setprecision(4)  << std::setw(5) << std::setfill(' ') << temperature << " [°C]"
                 << "   Light: "    << std::setprecision(4) << std::setw(5) << std::setfill(' ') << light << " [lux]"
                 << "   Humidity: " << std::setprecision(4) << std::setw(5) << std::setfill(' ') << humidity << " [%]"  << std::endl;

       //Clear the flag
       new_measurement = false;

       std::ofstream temperature_minute;
       std::ofstream humidity_minute;
       std::ofstream light_minute;

       //Try to open the _MINUTE file for writing
       do {
         temperature_minute.open(TEMPERATURE_MINUTE_FILEPATH);
       } while((temperature_minute.is_open()) == 0);

       temperature_minute << temperature;
       temperature_minute.close();

       do {
         humidity_minute.open(HUMIDITY_MINUTE_FILEPATH);
       } while((humidity_minute.is_open()) == 0);

       humidity_minute << humidity;
       humidity_minute.close();

       do {
         light_minute.open(LIGHT_MINUTE_FILEPATH);
       } while((light_minute.is_open()) == 0);

       light_minute << light;
       light_minute.close();
     }
   }

   //==============================================================
   // Exit
   //==============================================================
   const char* exit_communication = "exit\r\n";
   if (NULL != exit_communication) {
     write(stdin_pipe[PIPE_WRITE], exit_communication, strlen(exit_communication));
   }

    // done with these in this example program, you would normally keep these
    // open of course as long as you want to talk to the child
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
  }
  else
  {
    // failed to create child
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);
  }
  return child_num;
}

int main(int argc, char* argv[])
{
  if(argc < 2)
  {
    std::cerr << "Error: missing argument! Correct Usage: ./iot AA:BB:CC:DD:EE:FF" << std::endl;
    return(-1);
  }
  else if(argc == 2)
  {
    char* args[4];

    args[0] = const_cast<char*>("gatttool");
    args[1] = const_cast<char*>("-b");
    args[2] = argv[1];
    args[3] = const_cast<char*>("-I");

    std::cout << "Connecting to device: [" << argv[1] << "]" << std::endl;
    std::string hcitool_lecc("sudo hcitool lecc ");
    hcitool_lecc += argv[1];
    system(hcitool_lecc.c_str());

    //Create separate process + redirect console
    createChildProcess("/usr/bin/gatttool",args, NULL);

    std::cout << "Disconnecting from device: [" << argv[1] << "]" << std::endl;
    std::string hcitool_cc("sudo hcitool cc ");
    hcitool_cc += argv[1];
    system(hcitool_cc.c_str());

    return(0);
  }
}
<commit_msg>Fixed processing of negative temperatue values<commit_after>/*****************************************************************************************//**
* @file sensortag.cpp
*
* Copyright (c)
* SmartRoboticSystems
* December 2015
*
* This program creates connection to SensorTag 2650 using hcitool & gatttool, starts
* temperature, light and humidity measurements, set up and process notifications,
* computes real world data and saves results to files temperature.txt, humidity.txt,
* light.txt on "IoT/data/" filepath. Child process & stdin/stdout redirection is utilized
*
* Licensed under the EUPL V.1.1
*
* This Software is provided to You under the terms of the European
* Union Public License (the "EUPL") version 1.1 as published by the
* European Union. Any use of this Software, other than as authorized
* under this License is strictly prohibited (to the extent such use
* is covered by a right of the copyright holder of this Software).
*
* This Software is provided under the License on an "AS IS" basis and
* without warranties of any kind concerning the Software, including
* without limitation merchantability, fitness for a particular purpose,
* absence of defects or errors, accuracy, and non-infringement of
* intellectual property rights other than copyright. This disclaimer
* of warranty is an essential part of the License and a condition for
* the grant of any rights to this Software.
******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <string.h>

#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>

#include "filepaths.h"

#define PIPE_READ 0
#define PIPE_WRITE 1

int createChildProcess(const char* command, char* const arguments[], char* const environment[])
{
  int stdin_pipe[2];
  int stdout_pipe[2];
  int child_num;
  int execve_result;
  char act_char;

  if (pipe(stdin_pipe) < 0)
  {
    perror("allocating pipe for child input redirect");
    return -1;
  }
  if (pipe(stdout_pipe) < 0)
  {
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    perror("allocating pipe for child output redirect");
    return -1;
  }

  child_num = fork();
  if (0 == child_num)
  {
    // child continues here
    // redirect stdin
    if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1)
    {
      perror("redirecting stdin");
      return -1;
    }

    // redirect stdout
    if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1)
    {
      perror("redirecting stdout");
      return -1;
    }

    // redirect stderr
    if (dup2(stdout_pipe[PIPE_WRITE], STDERR_FILENO) == -1)
    {
      perror("redirecting stderr");
      return -1;
    }

    // all these are for use by parent only
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);

    // run child process image
    execve_result = execve(command, arguments, environment);

    // if we get here at all, an error occurred, but we are in the child
    // process, so just exit
    perror("exec of the child process");
    exit(execve_result);
  }
  else if (child_num > 0)
  {
    // parent continues here

    // close unused file descriptors, these are for child only
    close(stdin_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);

    //==============================================================
    // Connect
    //==============================================================
    const char* connect_message = "connect \r\n";
    if (NULL != connect_message)
      write(stdin_pipe[PIPE_WRITE], connect_message, strlen(connect_message));

    //Read console output
    do {
      read(stdout_pipe[PIPE_READ], &act_char, 1);
      write(STDOUT_FILENO, &act_char, 1);
    } while (act_char != '\n');

    usleep(1000000);

   //==============================================================
   // Start Temperature measurement
   //==============================================================

   //Start measurement
   const char* start_temperature = "char-write-req 0x24 01 \r\n";
   if (NULL != start_temperature)
     write(stdin_pipe[PIPE_WRITE], start_temperature, strlen(start_temperature));

   //Turn on notifications
   const char* read_temperature = "char-write-req 0x22 0100 \r\n";
   if (NULL != read_temperature)
     write(stdin_pipe[PIPE_WRITE], read_temperature, strlen(read_temperature));

   //Set notification period to 2.5 sec
   const char* temperature_period = "char-write-req 0x26 0xFA \r\n";
   if (NULL != temperature_period)
     write(stdin_pipe[PIPE_WRITE], temperature_period, strlen(temperature_period));

   //==============================================================
   // Start Light measurement
   //==============================================================

   //Start measurement
   const char* start_light = "char-write-req 0x44 01 \r\n";
   if (NULL != start_light)
     write(stdin_pipe[PIPE_WRITE], start_light, strlen(start_light));

  //Turn on notifications
   const char* read_light = "char-write-req 0x42 0100 \r\n";
   if (NULL != read_light)
     write(stdin_pipe[PIPE_WRITE], read_light, strlen(read_light));

   //Set notification period to 2.5 sec
   const char* light_period = "char-write-req 0x46 0xFA \r\n";
   if (NULL != light_period)
     write(stdin_pipe[PIPE_WRITE], light_period, strlen(light_period));

   //==============================================================
   // Start Humidity measurement
   //==============================================================

   //Start measurement
   const char* start_humidity = "char-write-req 0x2c 01 \r\n";
   if (NULL != start_humidity)
     write(stdin_pipe[PIPE_WRITE], start_humidity, strlen(start_humidity));

   //Turn on notifications
   const char* read_humidity = "char-write-req 0x2A 0100 \r\n";
   if (NULL != read_humidity)
     write(stdin_pipe[PIPE_WRITE], read_humidity, strlen(read_humidity));

   //Set notification period to 2.5 sec
   const char* humidity_period = "char-write-req 0x2e 0xFA \r\n";
   if (NULL != humidity_period)
     write(stdin_pipe[PIPE_WRITE], humidity_period, strlen(humidity_period));

/*   //==============================================================
   // Start Barometer measurement
   //==============================================================

   //Start measurement
   const char* start_barometer = "char-write-req 0x34 01 \r\n";
   if (NULL != start_barometer)
     write(aStdinPipe[PIPE_WRITE], start_barometer, strlen(start_barometer));

   //Turn on notifications
   const char* read_barometer = "char-write-req 0x32 0100 \r\n";
   if (NULL != read_barometer)
     write(aStdinPipe[PIPE_WRITE], read_barometer, strlen(read_barometer));

   //Set notification period to 2.5 sec
   const char* barometer_period = "char-write-req 0x36 0xFA \r\n";
   if (NULL != barometer_period)
     write(aStdinPipe[PIPE_WRITE], barometer_period, strlen(barometer_period));
*/

   //==============================================================
   // Process notifications
   //==============================================================

   double humidity = 0;
   double temperature = 0;
   double light = 0;
   double barometer = 0;

   const std::string temp_handle = "0x0021";
   const std::string light_handle = "0x0041";
   const std::string humidity_handle = "0x0029";
   const std::string barometer_handle = "0x0031";
   bool new_measurement = false;

   while(1)
   {
     std::string actual_line;

     do {
       read(stdout_pipe[PIPE_READ], &act_char, 1);
       actual_line += act_char;
     } while (act_char != '\n');

     //Temperature notification
     int temperature_index = actual_line.find(temp_handle);

     if(temperature_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int temperature_bytes[2];

       //Extract bytes from string notifications
       temp = actual_line.substr(temperature_index + 20, 2);
       temperature_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(temperature_index + 23,2);
       temperature_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Merge bytes
       unsigned int temperature_raw = (temperature_bytes[1] << 8) + temperature_bytes[0];

       //Compute and filter final value
       if((temperature > 0) && (temperature < 32768))
         temperature = temperature_raw/128.0;              //Positive temperature values
       else if (temperature > 32768)
         temperature = (temperature_raw - 65536) / 128.0;  //Negative temperature values
       else
         temperature = temperature;                        //Filtering false zero measurements
     }

     //Light notification
     int light_index = actual_line.find(light_handle);
     if(light_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int light_bytes[2];

       //Extract bytes from string notifications
       temp = actual_line.substr(light_index + 14, 2);
       light_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(light_index + 17, 2);
       light_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Compute exponent and fraction according to formula
       unsigned int exponent = (light_bytes[1] & 0b11110000) >> 4;
       unsigned int fraction = ((light_bytes[1] & 0b00001111) << 8) + light_bytes[0];

       //Compute final value
       light = 0.01 * pow(2,exponent) * fraction;
     }

     //Humidity notification
     int humidity_index = actual_line.find(humidity_handle);
     if(humidity_index != -1)
     {
       new_measurement = true;
       std::string temp;
       unsigned int humidity_bytes[2];

       //Extract bytes from string notification
       temp = actual_line.substr(humidity_index + 20, 2);
       humidity_bytes[0] =  strtoul(temp.c_str(), 0, 16);

       temp = actual_line.substr(humidity_index + 23,2);
       humidity_bytes[1] =  strtoul(temp.c_str(), 0, 16);

       //Merge bytes
       unsigned int humidity_raw = (humidity_bytes[1] << 8) + humidity_bytes[0];

       //Clear 2 LSB
       humidity_raw &= ~0x0003;

       //Cast to double
       humidity = static_cast<double>(humidity_raw);

       //Compute final value
       humidity = 125*(humidity/65536) - 6;
     }

     //Print if new measurement occured
     if(new_measurement == true)
     {
       std::cout << "Temp: "        << std::setprecision(4)  << std::setw(5) << std::setfill(' ') << temperature << " [°C]"
                 << "   Light: "    << std::setprecision(4) << std::setw(5) << std::setfill(' ') << light << " [lux]"
                 << "   Humidity: " << std::setprecision(4) << std::setw(5) << std::setfill(' ') << humidity << " [%]"  << std::endl;

       //Clear the flag
       new_measurement = false;

       std::ofstream temperature_minute;
       std::ofstream humidity_minute;
       std::ofstream light_minute;

       //Try to open the _MINUTE file for writing
       do {
         temperature_minute.open(TEMPERATURE_MINUTE_FILEPATH);
       } while((temperature_minute.is_open()) == 0);

       temperature_minute << temperature;
       temperature_minute.close();

       do {
         humidity_minute.open(HUMIDITY_MINUTE_FILEPATH);
       } while((humidity_minute.is_open()) == 0);

       humidity_minute << humidity;
       humidity_minute.close();

       do {
         light_minute.open(LIGHT_MINUTE_FILEPATH);
       } while((light_minute.is_open()) == 0);

       light_minute << light;
       light_minute.close();
     }
   }

   //==============================================================
   // Exit
   //==============================================================
   const char* exit_communication = "exit\r\n";
   if (NULL != exit_communication) {
     write(stdin_pipe[PIPE_WRITE], exit_communication, strlen(exit_communication));
   }

    // done with these in this example program, you would normally keep these
    // open of course as long as you want to talk to the child
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
  }
  else
  {
    // failed to create child
    close(stdin_pipe[PIPE_READ]);
    close(stdin_pipe[PIPE_WRITE]);
    close(stdout_pipe[PIPE_READ]);
    close(stdout_pipe[PIPE_WRITE]);
  }
  return child_num;
}

int main(int argc, char* argv[])
{
  if(argc < 2)
  {
    std::cerr << "Error: missing argument! Correct Usage: ./iot AA:BB:CC:DD:EE:FF" << std::endl;
    return(-1);
  }
  else if(argc == 2)
  {
    char* args[4];

    args[0] = const_cast<char*>("gatttool");
    args[1] = const_cast<char*>("-b");
    args[2] = argv[1];
    args[3] = const_cast<char*>("-I");

    std::cout << "Connecting to device: [" << argv[1] << "]" << std::endl;
    std::string hcitool_lecc("sudo hcitool lecc ");
    hcitool_lecc += argv[1];
    system(hcitool_lecc.c_str());

    //Create separate process + redirect console
    createChildProcess("/usr/bin/gatttool",args, NULL);

    std::cout << "Disconnecting from device: [" << argv[1] << "]" << std::endl;
    std::string hcitool_cc("sudo hcitool cc ");
    hcitool_cc += argv[1];
    system(hcitool_cc.c_str());

    return(0);
  }
}
<|endoftext|>


<commit_before>#include "singletons.h"

std::unique_ptr<Source::Config> Singleton::Config::source_=std::unique_ptr<Source::Config>(new Source::Config());
std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique_ptr<Directories::Config>(new Directories::Config());
std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
std::unique_ptr<Window> Singleton::window_=std::unique_ptr<Window>();

Terminal *Singleton::terminal() {
  if(!terminal_)
    terminal_=std::unique_ptr<Terminal>(new Terminal());
  return terminal_.get();
}

Directories *Singleton::directories() {
  if(!directories_)
    directories_=std::unique_ptr<Directories>(new Directories());
  return directories_.get();
}

Window *Singleton::window() {
  if(!window_)
    window_=std::unique_ptr<Window>(new Window());
  return window_.get();
}

std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::status() {
  if(!status_)
    status_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
  return status_.get();
}
std::unique_ptr<Gtk::Label> Singleton::info_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::info() {
  if(!info_)
    info_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
  return info_.get();
}

boost::filesystem::path Singleton::create_config_path(const std::string &subfolder) {
  auto home = filesystem::get_home_folder();
  if(home.empty()) {
    Singleton::terminal()->print("Could not find/write to home directory. Using defaults, no settings will be saved.");
    home = filesystem::get_tmp_folder();
    if(home.empty()) {
      std::string message("Please fix permissions of your home folder");
      std::cerr << message << std::endl;
      JFATAL(message);
      throw new std::exception;
    }
  }
  home /= subfolder;
  return home;
}

boost::filesystem::path Singleton::config_dir() { return create_config_path(".juci/config"); }
boost::filesystem::path Singleton::log_dir() { return create_config_path(".juci/log"); }
boost::filesystem::path Singleton::style_dir() { return create_config_path(".juci/styles"); }
std::string Singleton::config_json() {
  auto conf_dir = Singleton::config_dir();
  conf_dir /= "config.json"; // to ensure correct paths on windows
  return conf_dir.string();
}

<commit_msg>Begin simplify of paths<commit_after>#include "singletons.h"

std::unique_ptr<Source::Config> Singleton::Config::source_=std::unique_ptr<Source::Config>(new Source::Config());
std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique_ptr<Directories::Config>(new Directories::Config());
std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
std::unique_ptr<Window> Singleton::window_=std::unique_ptr<Window>();

Terminal *Singleton::terminal() {
  if(!terminal_)
    terminal_=std::unique_ptr<Terminal>(new Terminal());
  return terminal_.get();
}

Directories *Singleton::directories() {
  if(!directories_)
    directories_=std::unique_ptr<Directories>(new Directories());
  return directories_.get();
}

Window *Singleton::window() {
  if(!window_)
    window_=std::unique_ptr<Window>(new Window());
  return window_.get();
}

std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::status() {
  if(!status_)
    status_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
  return status_.get();
}
std::unique_ptr<Gtk::Label> Singleton::info_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::info() {
  if(!info_)
    info_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
  return info_.get();
}

boost::filesystem::path Singleton::create_config_path(const std::string &subfolder) {
  auto home = filesystem::get_home_folder();
  if(home.empty()) {
    Singleton::terminal()->print("Could not find/write to home directory. Using defaults, no settings will be saved.");
    home = filesystem::get_tmp_folder();
    if(home.empty()) {
      std::string message("Please fix permissions of your home folder");
      std::cerr << message << std::endl;
      JFATAL(message);
      throw new std::exception;
    }
  }
  home /= subfolder;
  return home;
}

boost::filesystem::path Singleton::config_dir() { return create_config_path({".juci", "config"}); }
boost::filesystem::path Singleton::log_dir() { return create_config_path({".juci", "log"}); }
boost::filesystem::path Singleton::style_dir() { return create_config_path({".juci", "styles"}); }
std::string Singleton::config_json() { return (Singleton::config_dir()/"config.json").string(); }

<|endoftext|>


<commit_before>/*
* Copyright (c) 2013-2020 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "VapourSynth4.h"
#include "VSScript4.h"
#include "cython/vapoursynth_api.h"
#include <mutex>
#include <atomic>
#include <vector>

#ifdef VS_TARGET_OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#endif

static std::once_flag flag;

struct VSScript : public VPYScriptExport {
};

static std::mutex vsscriptlock;
static std::atomic<int> initializationCount(0);
static std::atomic<int> scriptId(1000);
static bool initialized = false;
static PyThreadState *ts = nullptr;
static PyGILState_STATE s;

static void real_init(void) VS_NOEXCEPT {
#ifdef VS_TARGET_OS_WINDOWS
#ifdef _WIN64
    #define VS_INSTALL_REGKEY L"Software\\VapourSynth"
#else
    #define VS_INSTALL_REGKEY L"Software\\VapourSynth-32"
#endif

    // portable
    const std::wstring pythonDllName = L"python38.dll";
    HMODULE module;
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&real_init, &module);
    std::vector<wchar_t> pathBuf(65536);
    GetModuleFileNameW(module, pathBuf.data(), (DWORD)pathBuf.size());
    std::wstring dllPath = pathBuf.data();
    dllPath.resize(dllPath.find_last_of('\\') + 1);
    std::wstring portableFilePath = dllPath + L"portable.vs";
    FILE *portableFile = _wfopen(portableFilePath.c_str(), L"rb");
    bool isPortable = !!portableFile;
    if (portableFile)
        fclose(portableFile);

    HMODULE pythonDll = nullptr;

    if (isPortable) {
        std::wstring pyPath = dllPath + L"\\" + pythonDllName;
        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    } else {
        DWORD dwType = REG_SZ;
        HKEY hKey = 0;

        wchar_t value[1024];
        DWORD valueLength = 1000;
        if (RegOpenKeyW(HKEY_CURRENT_USER, VS_INSTALL_REGKEY, &hKey) != ERROR_SUCCESS) {
            if (RegOpenKeyW(HKEY_LOCAL_MACHINE, VS_INSTALL_REGKEY, &hKey) != ERROR_SUCCESS)
                return;
        }

        LSTATUS status = RegQueryValueExW(hKey, L"PythonPath", nullptr, &dwType, (LPBYTE)&value, &valueLength);
        RegCloseKey(hKey);
        if (status != ERROR_SUCCESS)
            return;

        std::wstring pyPath = value;
        pyPath += L"\\" + pythonDllName;

        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    }
    if (!pythonDll)
        return;
#endif
    int preInitialized = Py_IsInitialized();
    if (!preInitialized)
        Py_InitializeEx(0);
    s = PyGILState_Ensure();
    if (import_vapoursynth())
        return;
    if (vpy_initVSScript())
        return;
    ts = PyEval_SaveThread();
    initialized = true;
}

VS_API(int) vsscript_getApiVersion(void) VS_NOEXCEPT {
    return VSSCRIPT_API_VERSION;
}

VS_API(int) vsscript_init() VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    std::call_once(flag, real_init);
    if (initialized)
        return ++initializationCount;
    else
        return initializationCount;
}

VS_API(int) vsscript_finalize(void) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    int count = --initializationCount;
    assert(count >= 0);
    return count;
}

static int vsscript_createScriptInternal(VSScript **handle) VS_NOEXCEPT {
    *handle = new(std::nothrow)VSScript();
    if (*handle) {
        (*handle)->pyenvdict = nullptr;
        (*handle)->errstr = nullptr;
        (*handle)->id = ++scriptId;
        return vpy_createScript(*handle);
    } else {
        return 1;
    }
}

VS_API(int) vsscript_createScript(VSScript **handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vsscript_createScriptInternal(handle);
}

VS_API(int) vsscript_evaluateScript(VSScript **handle, const char *script, const char *scriptFilename, int flags) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (*handle == nullptr) {
        if (vsscript_createScriptInternal(handle)) return 1;
    }
    return vpy_evaluateScript(*handle, script, scriptFilename ? scriptFilename : "<string>", flags);
}

VS_API(int) vsscript_evaluateFile(VSScript **handle, const char *scriptFilename, int flags) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (*handle == nullptr) {
        if (vsscript_createScriptInternal(handle)) return 1;
    }
    return vpy_evaluateFile(*handle, scriptFilename, flags);
}

VS_API(void) vsscript_freeScript(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (handle) {
        vpy_freeScript(handle);
        delete handle;
    }
}

VS_API(const char *) vsscript_getError(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (handle)
        return vpy_getError(handle);
    else
        return "Invalid handle (NULL)";
}

// V3 API compatibility
// FIXME, check for audio nodes and return null
VS_API(VSNodeRef *) vsscript_getOutput(VSScript *handle, int index) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getOutput(handle, index);
}

// V3 API compatibility
// FIXME, check for audio nodes and return null
VS_API(VSNodeRef *) vsscript_getOutput2(VSScript *handle, int index, VSNodeRef **alpha) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getOutput2(handle, index, alpha);
}

static VSNodeRef *VS_CC vsscript_getOutput4(VSScript *handle, int index, VSNodeRef **alpha) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getOutput2(handle, index, alpha);
}

VS_API(int) vsscript_clearOutput(VSScript *handle, int index) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_clearOutput(handle, index);
}

VS_API(VSCore *) vsscript_getCore(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getCore(handle);
}

// V3 API compatibility
VS_API(const VSAPI *) vsscript_getVSApi(void) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVSApi2(3);
}

VS_API(const VSAPI *) vsscript_getVSApi2(int version) VS_NOEXCEPT {
    // it's possible no lock is needed here but do it just to be sure
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVSApi2(version);
}

// FIXME, needs check to prevent audio types from escaping to V3
VS_API(int) vsscript_getVariable(VSScript *handle, const char *name, VSMap *dst) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVariable(handle, name, dst);
}

VS_API(int) vsscript_setVariable(VSScript *handle, const VSMap *vars) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_setVariable(handle, vars);
}

VS_API(int) vsscript_clearVariable(VSScript *handle, const char *name) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_clearVariable(handle, name);
}

VS_API(void) vsscript_clearEnvironment(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    vpy_clearEnvironment(handle);
}

static VSSCRIPTAPI vsscript_api = {
    &vsscript_getApiVersion,
    &vsscript_getVSApi2,
    &vsscript_init,
    &vsscript_finalize,
    &vsscript_evaluateScript,
    &vsscript_evaluateFile,
    &vsscript_createScript,
    &vsscript_freeScript,
    &vsscript_getError,
    &vsscript_getOutput4,
    &vsscript_clearOutput,
    &vsscript_getCore,
    &vsscript_getVariable,
    &vsscript_setVariable,
    &vsscript_clearVariable,
    &vsscript_clearEnvironment
};

const VSSCRIPTAPI *VS_CC getVSScriptAPI(int version) VS_NOEXCEPT {
    int apiMajor = (version >> 16);
    int apiMinor = (apiMajor & 0xFFFF);

    if (apiMajor == VSSCRIPT_API_MAJOR && apiMinor <= VSSCRIPT_API_MINOR)
        return &vsscript_api;
    return nullptr;
}<commit_msg>Prevent audio nodes from escaping into the V3 api in vsscript<commit_after>/*
* Copyright (c) 2013-2020 Fredrik Mellbin
*
* This file is part of VapourSynth.
*
* VapourSynth 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.
*
* VapourSynth 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 VapourSynth; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "VapourSynth4.h"
#include "VSScript4.h"
#include "cython/vapoursynth_api.h"
#include <mutex>
#include <atomic>
#include <vector>

#ifdef VS_TARGET_OS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#endif

static std::once_flag flag;

struct VSScript : public VPYScriptExport {
};

static std::mutex vsscriptlock;
static std::atomic<int> initializationCount(0);
static std::atomic<int> scriptId(1000);
static bool initialized = false;
static PyThreadState *ts = nullptr;
static PyGILState_STATE s;

static void real_init(void) VS_NOEXCEPT {
#ifdef VS_TARGET_OS_WINDOWS
#ifdef _WIN64
    #define VS_INSTALL_REGKEY L"Software\\VapourSynth"
#else
    #define VS_INSTALL_REGKEY L"Software\\VapourSynth-32"
#endif

    // portable
    const std::wstring pythonDllName = L"python38.dll";
    HMODULE module;
    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&real_init, &module);
    std::vector<wchar_t> pathBuf(65536);
    GetModuleFileNameW(module, pathBuf.data(), (DWORD)pathBuf.size());
    std::wstring dllPath = pathBuf.data();
    dllPath.resize(dllPath.find_last_of('\\') + 1);
    std::wstring portableFilePath = dllPath + L"portable.vs";
    FILE *portableFile = _wfopen(portableFilePath.c_str(), L"rb");
    bool isPortable = !!portableFile;
    if (portableFile)
        fclose(portableFile);

    HMODULE pythonDll = nullptr;

    if (isPortable) {
        std::wstring pyPath = dllPath + L"\\" + pythonDllName;
        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    } else {
        DWORD dwType = REG_SZ;
        HKEY hKey = 0;

        wchar_t value[1024];
        DWORD valueLength = 1000;
        if (RegOpenKeyW(HKEY_CURRENT_USER, VS_INSTALL_REGKEY, &hKey) != ERROR_SUCCESS) {
            if (RegOpenKeyW(HKEY_LOCAL_MACHINE, VS_INSTALL_REGKEY, &hKey) != ERROR_SUCCESS)
                return;
        }

        LSTATUS status = RegQueryValueExW(hKey, L"PythonPath", nullptr, &dwType, (LPBYTE)&value, &valueLength);
        RegCloseKey(hKey);
        if (status != ERROR_SUCCESS)
            return;

        std::wstring pyPath = value;
        pyPath += L"\\" + pythonDllName;

        pythonDll = LoadLibraryExW(pyPath.c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
    }
    if (!pythonDll)
        return;
#endif
    int preInitialized = Py_IsInitialized();
    if (!preInitialized)
        Py_InitializeEx(0);
    s = PyGILState_Ensure();
    if (import_vapoursynth())
        return;
    if (vpy_initVSScript())
        return;
    ts = PyEval_SaveThread();
    initialized = true;
}

VS_API(int) vsscript_getApiVersion(void) VS_NOEXCEPT {
    return VSSCRIPT_API_VERSION;
}

VS_API(int) vsscript_init() VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    std::call_once(flag, real_init);
    if (initialized)
        return ++initializationCount;
    else
        return initializationCount;
}

VS_API(int) vsscript_finalize(void) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    int count = --initializationCount;
    assert(count >= 0);
    return count;
}

static int vsscript_createScriptInternal(VSScript **handle) VS_NOEXCEPT {
    *handle = new(std::nothrow)VSScript();
    if (*handle) {
        (*handle)->pyenvdict = nullptr;
        (*handle)->errstr = nullptr;
        (*handle)->id = ++scriptId;
        return vpy_createScript(*handle);
    } else {
        return 1;
    }
}

VS_API(int) vsscript_createScript(VSScript **handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vsscript_createScriptInternal(handle);
}

VS_API(int) vsscript_evaluateScript(VSScript **handle, const char *script, const char *scriptFilename, int flags) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (*handle == nullptr) {
        if (vsscript_createScriptInternal(handle)) return 1;
    }
    return vpy_evaluateScript(*handle, script, scriptFilename ? scriptFilename : "<string>", flags);
}

VS_API(int) vsscript_evaluateFile(VSScript **handle, const char *scriptFilename, int flags) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (*handle == nullptr) {
        if (vsscript_createScriptInternal(handle)) return 1;
    }
    return vpy_evaluateFile(*handle, scriptFilename, flags);
}

VS_API(void) vsscript_freeScript(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (handle) {
        vpy_freeScript(handle);
        delete handle;
    }
}

VS_API(const char *) vsscript_getError(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    if (handle)
        return vpy_getError(handle);
    else
        return "Invalid handle (NULL)";
}

// V3 API compatibility
VS_API(VSNodeRef *) vsscript_getOutput(VSScript *handle, int index) VS_NOEXCEPT {
    return vsscript_getOutput2(handle, index, nullptr);
}

// V3 API compatibility
VS_API(VSNodeRef *) vsscript_getOutput2(VSScript *handle, int index, VSNodeRef **alpha) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    VSNodeRef *node = vpy_getOutput2(handle, index, alpha);
    const VSAPI *vsapi = vsscript_getVSApi2(VAPOURSYNTH_API_VERSION);
    if (node && vsapi->getNodeType(node) == mtAudio) {
        vsapi->freeNode(node);
        if (alpha) {
            vsapi->freeNode(*alpha);
            *alpha = nullptr;
        }
        return nullptr;
    }
    return node;
}

static VSNodeRef *VS_CC vsscript_getOutputAPI4(VSScript *handle, int index, VSNodeRef **alpha) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getOutput2(handle, index, alpha);
}

VS_API(int) vsscript_clearOutput(VSScript *handle, int index) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_clearOutput(handle, index);
}

VS_API(VSCore *) vsscript_getCore(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getCore(handle);
}

// V3 API compatibility
VS_API(const VSAPI *) vsscript_getVSApi(void) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVSApi2(3 << 16);
}

VS_API(const VSAPI *) vsscript_getVSApi2(int version) VS_NOEXCEPT {
    // it's possible no lock is needed here but do it just to be sure
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVSApi2(version);
}

// FIXME, needs check to prevent audio types from escaping to V3
VS_API(int) vsscript_getVariable(VSScript *handle, const char *name, VSMap *dst) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_getVariable(handle, name, dst);
}

VS_API(int) vsscript_setVariable(VSScript *handle, const VSMap *vars) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_setVariable(handle, vars);
}

VS_API(int) vsscript_clearVariable(VSScript *handle, const char *name) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    return vpy_clearVariable(handle, name);
}

VS_API(void) vsscript_clearEnvironment(VSScript *handle) VS_NOEXCEPT {
    std::lock_guard<std::mutex> lock(vsscriptlock);
    vpy_clearEnvironment(handle);
}

static VSSCRIPTAPI vsscript_api = {
    &vsscript_getApiVersion,
    &vsscript_getVSApi2,
    &vsscript_init,
    &vsscript_finalize,
    &vsscript_evaluateScript,
    &vsscript_evaluateFile,
    &vsscript_createScript,
    &vsscript_freeScript,
    &vsscript_getError,
    &vsscript_getOutputAPI4,
    &vsscript_clearOutput,
    &vsscript_getCore,
    &vsscript_getVariable,
    &vsscript_setVariable,
    &vsscript_clearVariable,
    &vsscript_clearEnvironment
};

const VSSCRIPTAPI *VS_CC getVSScriptAPI(int version) VS_NOEXCEPT {
    int apiMajor = (version >> 16);
    int apiMinor = (apiMajor & 0xFFFF);

    if (apiMajor == VSSCRIPT_API_MAJOR && apiMinor <= VSSCRIPT_API_MINOR)
        return &vsscript_api;
    return nullptr;
}<|endoftext|>


<commit_before>//----------------------------  dof_constraints_01.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  dof_constraints_01.cc  ---------------------------

// check DoFConstraints::distribute_local_to_global for matrices

#include "../tests.h"
#include <lac/sparsity_pattern.h>
#include <lac/sparse_matrix.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <grid/grid_tools.h>
#include <grid/grid_generator.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <dofs/dof_constraints.h>
#include <fe/fe_q.h>
#include <fstream>
#include <iostream>

template <int dim>
void test ()
{
  deallog << dim << "D" << std::endl;

  Triangulation<dim> triangulation;
  GridGenerator::hyper_cube (triangulation);

                                   // refine the mesh in a random way so as to
                                   // generate as many hanging node
                                   // constraints as possible
//  triangulation.refine_global (4-dim);
  triangulation.refine_global (1);
  for (unsigned int i=0; i<1; ++i)
    {
      typename Triangulation<dim>::active_cell_iterator
        cell = triangulation.begin_active();
      for (unsigned int index=0; cell != triangulation.end(); ++cell, ++index)
        if (index % (3*dim) == 0)
          cell->set_refine_flag();
      triangulation.execute_coarsening_and_refinement ();
    }
  deallog << "Number of cells: " << triangulation.n_active_cells() << std::endl;

                                   // set up a DoFHandler and compute hanging
                                   // node constraints
  FE_Q<dim> fe(1);
  DoFHandler<dim> dof_handler (triangulation);
  dof_handler.distribute_dofs (fe);
  deallog << "Number of dofs: " << dof_handler.n_dofs() << std::endl;

  ConstraintMatrix constraints;
  DoFTools::make_hanging_node_constraints (dof_handler, constraints);
  constraints.close ();
  deallog << "Number of constraints: " << constraints.n_constraints() << std::endl;

                                   // then set up a sparsity pattern and two
                                   // matrices on top of it
  SparsityPattern sparsity (dof_handler.n_dofs(),
                            dof_handler.n_dofs(),
                            dof_handler.max_couplings_between_dofs());
  DoFTools::make_sparsity_pattern (dof_handler, sparsity);
  constraints.condense (sparsity);
  SparseMatrix<double> A(sparsity), B(sparsity);

                                   // then fill the two matrices by setting up
                                   // bogus matrix entries and (1) writing
                                   // them into the matrix and condensing away
                                   // hanging node constraints later on, or
                                   // (2) distributing them right away
  std::vector<unsigned int> local_dofs (fe.dofs_per_cell);
  FullMatrix<double> local_matrix (fe.dofs_per_cell, fe.dofs_per_cell);
  for (typename DoFHandler<dim>::active_cell_iterator
         cell = dof_handler.begin_active();
       cell != dof_handler.end(); ++cell)
    {
      cell->get_dof_indices (local_dofs);
      local_matrix.clear ();
      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
        for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
          local_matrix(i,j) = (i+1.)*(j+1.)*(local_dofs[i]+1.)*(local_dofs[j]+1.);

                                       // copy local to global by ourselves
      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
        for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
          A.add (local_dofs[i], local_dofs[j], local_matrix(i,j));

                                       // or let other functions do that
      constraints.distribute_local_to_global (local_matrix, local_dofs, B);

      break;
    }

                                   // now condense away constraints from A
  constraints.condense (A);

                                   // we haven't yet set the diagonal entries
                                   // for constrained nodes. we can do so at
                                   // will, since these values don't matter
                                   // anyway
  for (unsigned int i=0; i<dof_handler.n_dofs(); ++i)
    if (constraints.is_constrained(i))
      B.set(i,i,A(i,i));

                                   // now comes the check: we subtract B from
                                   // A, and make sure that the result is zero
  A.add_scaled (-1., B);
  deallog << "|A|=" << A.frobenius_norm() << std::endl;
  deallog << "|B|=" << B.frobenius_norm() << std::endl;
  Assert (A.frobenius_norm() < 1e-12*B.frobenius_norm(),
          ExcInternalError());
}

int main ()
{
  std::ofstream logfile("dof_constraints_01.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  try
    {
//       test<1> ();
//       test<2> ();
      test<3> ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    };
}
<commit_msg>Remove changes made when debugging.<commit_after>//----------------------------  dof_constraints_01.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  dof_constraints_01.cc  ---------------------------

// check DoFConstraints::distribute_local_to_global for matrices

#include "../tests.h"
#include <lac/sparsity_pattern.h>
#include <lac/sparse_matrix.h>
#include <lac/vector.h>
#include <grid/tria.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <grid/grid_tools.h>
#include <grid/grid_generator.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <dofs/dof_constraints.h>
#include <fe/fe_q.h>
#include <fstream>
#include <iostream>

template <int dim>
void test ()
{
  deallog << dim << "D" << std::endl;

  Triangulation<dim> triangulation;
  GridGenerator::hyper_cube (triangulation);

                                   // refine the mesh in a random way so as to
                                   // generate as many hanging node
                                   // constraints as possible
  triangulation.refine_global (4-dim);
  for (unsigned int i=0; i<11-2*dim; ++i)
    {
      typename Triangulation<dim>::active_cell_iterator
        cell = triangulation.begin_active();
      for (unsigned int index=0; cell != triangulation.end(); ++cell, ++index)
        if (index % (3*dim) == 0)
          cell->set_refine_flag();
      triangulation.execute_coarsening_and_refinement ();
    }
  deallog << "Number of cells: " << triangulation.n_active_cells() << std::endl;

                                   // set up a DoFHandler and compute hanging
                                   // node constraints
  FE_Q<dim> fe(1);
  DoFHandler<dim> dof_handler (triangulation);
  dof_handler.distribute_dofs (fe);
  deallog << "Number of dofs: " << dof_handler.n_dofs() << std::endl;

  ConstraintMatrix constraints;
  DoFTools::make_hanging_node_constraints (dof_handler, constraints);
  constraints.close ();
  deallog << "Number of constraints: " << constraints.n_constraints() << std::endl;

                                   // then set up a sparsity pattern and two
                                   // matrices on top of it
  SparsityPattern sparsity (dof_handler.n_dofs(),
                            dof_handler.n_dofs(),
                            dof_handler.max_couplings_between_dofs());
  DoFTools::make_sparsity_pattern (dof_handler, sparsity);
  constraints.condense (sparsity);
  SparseMatrix<double> A(sparsity), B(sparsity);

                                   // then fill the two matrices by setting up
                                   // bogus matrix entries and (1) writing
                                   // them into the matrix and condensing away
                                   // hanging node constraints later on, or
                                   // (2) distributing them right away
  std::vector<unsigned int> local_dofs (fe.dofs_per_cell);
  FullMatrix<double> local_matrix (fe.dofs_per_cell, fe.dofs_per_cell);
  for (typename DoFHandler<dim>::active_cell_iterator
         cell = dof_handler.begin_active();
       cell != dof_handler.end(); ++cell)
    {
      cell->get_dof_indices (local_dofs);
      local_matrix.clear ();
      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
        for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
          local_matrix(i,j) = (i+1.)*(j+1.)*(local_dofs[i]+1.)*(local_dofs[j]+1.);

                                       // copy local to global by ourselves
      for (unsigned int i=0; i<fe.dofs_per_cell; ++i)
        for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
          A.add (local_dofs[i], local_dofs[j], local_matrix(i,j));

                                       // or let other functions do that
      constraints.distribute_local_to_global (local_matrix, local_dofs, B);

      break;
    }

                                   // now condense away constraints from A
  constraints.condense (A);

                                   // we haven't yet set the diagonal entries
                                   // for constrained nodes. we can do so at
                                   // will, since these values don't matter
                                   // anyway
  for (unsigned int i=0; i<dof_handler.n_dofs(); ++i)
    if (constraints.is_constrained(i))
      B.set(i,i,A(i,i));

                                   // now comes the check: we subtract B from
                                   // A, and make sure that the result is zero
  A.add_scaled (-1., B);
  deallog << "|A|=" << A.frobenius_norm() << std::endl;
  deallog << "|B|=" << B.frobenius_norm() << std::endl;
  Assert (A.frobenius_norm() < 1e-12*B.frobenius_norm(),
          ExcInternalError());
}

int main ()
{
  std::ofstream logfile("dof_constraints_01.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  try
    {
      test<1> ();
      test<2> ();
      test<3> ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    };
}
<|endoftext|>


<commit_before>/* <x0/mod_dirlisting.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stddef.h>

/**
 * \ingroup modules
 * \brief implements automatic content generation for raw directories
 */
class dirlisting_plugin :
	public x0::plugin
{
private:
	x0::handler::connection c;

public:
	dirlisting_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.generate_content.connect(boost::bind(&dirlisting_plugin::dirlisting, this, _1, _2));
	}

	~dirlisting_plugin()
	{
		server_.generate_content.disconnect(c);
	}

	virtual void configure()
	{
		// TODO get some kind of solution to let dir-listing only be used for directories we allow it for.
	}

private:
	bool dirlisting(x0::request& in, x0::response& out)
	{
		if (!x0::isdir(in.entity)) return false;

		if (DIR *dir = opendir(in.entity.c_str()))
		{
			std::list<std::string> listing;
			listing.push_back("..");

			int len = offsetof(dirent, d_name) + pathconf(in.entity.c_str(), _PC_NAME_MAX);
			dirent *dep = (dirent *)new unsigned char[len + 1];
			dirent *res = 0;

			while (readdir_r(dir, dep, &res) == 0 && res)
			{
				std::string name(dep->d_name);

				if (name[0] != '.')
				{
					if (x0::isdir(in.entity + name)) name += "/";

					listing.push_back(name);
				}
			}

			delete[] dep;

			std::stringstream sstr;
			sstr << "<title>Directory: "
				 << in.path
				 << "</title>\n\n";

			sstr << "
Index of " << in.path << "
\n";
			sstr << "
\n";

			for (std::list<std::string>::iterator i = listing.begin(), e = listing.end(); i != e; ++i)
			{
				sstr << "
<a href='" << *i << "'>" << *i << "
\n";
			}

			sstr << "
\n";

			sstr << "
\n";
			sstr << "" << in.connection.server().tag() << "
\n";

			sstr << "\n";

			std::string result(sstr.str());

			out.write(result);
			out *= x0::header("Content-Type", "text/html");
			out *= x0::header("Content-Length", boost::lexical_cast<std::string>(result.size()));

			out.flush();

			return true;
		}
		return false;
	}
};

X0_EXPORT_PLUGIN(dirlisting);
<commit_msg>dirlisting: added missing closedir(p) fixing a resource leak<commit_after>/* <x0/mod_dirlisting.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stddef.h>

/**
 * \ingroup modules
 * \brief implements automatic content generation for raw directories
 */
class dirlisting_plugin :
	public x0::plugin
{
private:
	x0::handler::connection c;

public:
	dirlisting_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name)
	{
		c = server_.generate_content.connect(boost::bind(&dirlisting_plugin::dirlisting, this, _1, _2));
	}

	~dirlisting_plugin()
	{
		server_.generate_content.disconnect(c);
	}

	virtual void configure()
	{
		// TODO get some kind of solution to let dir-listing only be used for directories we allow it for.
	}

private:
	bool dirlisting(x0::request& in, x0::response& out)
	{
		if (!x0::isdir(in.entity)) return false;

		if (DIR *dir = opendir(in.entity.c_str()))
		{
			std::list<std::string> listing;
			listing.push_back("..");

			int len = offsetof(dirent, d_name) + pathconf(in.entity.c_str(), _PC_NAME_MAX);
			dirent *dep = (dirent *)new unsigned char[len + 1];
			dirent *res = 0;

			while (readdir_r(dir, dep, &res) == 0 && res)
			{
				std::string name(dep->d_name);

				if (name[0] != '.')
				{
					if (x0::isdir(in.entity + name)) name += "/";

					listing.push_back(name);
				}
			}

			delete[] dep;

			std::stringstream sstr;
			sstr << "<title>Directory: "
				 << in.path
				 << "</title>\n\n";

			sstr << "
Index of " << in.path << "
\n";
			sstr << "
\n";

			for (std::list<std::string>::iterator i = listing.begin(), e = listing.end(); i != e; ++i)
			{
				sstr << "
<a href='" << *i << "'>" << *i << "
\n";
			}

			sstr << "
\n";

			sstr << "
\n";
			sstr << "" << in.connection.server().tag() << "
\n";

			sstr << "\n";

			std::string result(sstr.str());

			out.write(result);
			out *= x0::header("Content-Type", "text/html");
			out *= x0::header("Content-Length", boost::lexical_cast<std::string>(result.size()));

			out.flush();

			closedir(dir);
			return true;
		}
		return false;
	}
};

X0_EXPORT_PLUGIN(dirlisting);
<|endoftext|>