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

/* ScriptData
SDName: Sholazar_Basin
SD%Complete: 100
SDComment: Quest support: 11253, 11241.
SDCategory: howling_fjord
EndScriptData */

/* ContentData
npc_plaguehound_tracker
npc_apothecary_hanes
EndContentData */

#include "PassiveAI.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "ScriptedGossip.h"
#include "SpellInfo.h"

// Ours
class npc_attracted_reef_bull : public CreatureScript
{
public:
    npc_attracted_reef_bull() : CreatureScript("npc_attracted_reef_bull") { }

    struct npc_attracted_reef_bullAI : public NullCreatureAI
    {
        npc_attracted_reef_bullAI(Creature* creature) : NullCreatureAI(creature)
        {
            me->SetDisableGravity(true);
            if (me->IsSummon())
                if (Unit* owner = me->ToTempSummon()->GetSummonerUnit())
                    me->GetMotionMaster()->MovePoint(0, *owner);
        }

        void MovementInform(uint32  /*type*/, uint32  /*id*/) override
        {
            if (Creature* cow = me->FindNearestCreature(24797, 5.0f, true))
            {
                me->CastSpell(me, 44460, true);
                me->DespawnOrUnsummon(10000);
                cow->CastSpell(cow, 44460, true);
                cow->DespawnOrUnsummon(10000);
                if (me->IsSummon())
                    if (Unit* owner = me->ToTempSummon()->GetSummonerUnit())
                        owner->CastSpell(owner, 44463, true);
            }
        }

        void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
        {
            if (caster && spellInfo->Id == 44454)
                me->GetMotionMaster()->MovePoint(0, *caster);
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_attracted_reef_bullAI(creature);
    }
};

// The cleansing
enum TurmoilTexts
{
    SAY_TURMOIL_0                = 0,
    SAY_TURMOIL_1                = 1,
    SAY_TURMOIL_HALF_HP          = 2,
    SAY_TURMOIL_DEATH            = 3,
};

class npc_your_inner_turmoil : public CreatureScript
{
public:
    npc_your_inner_turmoil() : CreatureScript("npc_your_inner_turmoil") { }

    struct npc_your_inner_turmoilAI : public ScriptedAI
    {
        npc_your_inner_turmoilAI(Creature* creature) : ScriptedAI(creature) {}

        uint32 timer;
        short phase;
        bool health50;

        void Reset() override
        {
            timer = 0;
            phase = 0;
            health50 = false;
        }

        void UpdateAI(uint32 diff) override
        {
            if (timer >= 6000 && phase < 2)
            {
                phase++;
                setphase(phase);
                timer = 0;
            }

            timer += diff;

            DoMeleeAttackIfReady();
        }

        void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType  /*damagetype*/, SpellSchoolMask  /*damageSchoolMask*/) override
        {
            if (HealthBelowPct(50) && !health50)
            {
                Talk(SAY_TURMOIL_HALF_HP, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
                health50 = true;
            }
        }

        void JustDied(Unit* /*killer*/) override
        {
            Talk(SAY_TURMOIL_DEATH, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
        }

        void setphase(short newPhase)
        {
            Unit* summoner = me->ToTempSummon() ? me->ToTempSummon()->GetSummonerUnit() : nullptr;
            if (!summoner || summoner->GetTypeId() != TYPEID_PLAYER)
                return;

            switch (newPhase)
            {
                case 1:
                    Talk(SAY_TURMOIL_0, summoner->ToPlayer());
                    return;
                case 2:
                {
                    Talk(SAY_TURMOIL_1, summoner->ToPlayer());
                    me->SetLevel(summoner->getLevel());
                    me->SetFaction(FACTION_MONSTER);
                    if (me->GetExactDist(summoner) < 50.0f)
                    {
                        me->UpdatePosition(summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ(), 0.0f, true);
                        summoner->CastSpell(me, 50218, true); // clone caster
                        AttackStart(summoner);
                    }
                }
            }
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_your_inner_turmoilAI(creature);
    }
};

// Theirs
/*######
## npc_apothecary_hanes
######*/
enum Entries
{
    NPC_APOTHECARY_HANES         = 23784,
    NPC_HANES_FIRE_TRIGGER       = 23968,
    QUEST_TRAIL_OF_FIRE          = 11241,
    SPELL_COSMETIC_LOW_POLY_FIRE = 56274,
    SPELL_HEALING_POTION         = 17534
};

class npc_apothecary_hanes : public CreatureScript
{
public:
    npc_apothecary_hanes() : CreatureScript("npc_apothecary_hanes") { }

    bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
    {
        if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE)
        {
            creature->SetFaction(player->GetTeamId() == TEAM_ALLIANCE ? FACTION_ESCORTEE_A_PASSIVE : FACTION_ESCORTEE_H_PASSIVE);
            CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
        }
        return true;
    }

    struct npc_Apothecary_HanesAI : public npc_escortAI
    {
        npc_Apothecary_HanesAI(Creature* creature) : npc_escortAI(creature) { }
        uint32 PotTimer;

        void Reset() override
        {
            SetDespawnAtFar(false);
            PotTimer = 10000; //10 sec cooldown on potion
        }

        void JustDied(Unit* /*killer*/) override
        {
            if (Player* player = GetPlayerForEscort())
                player->FailQuest(QUEST_TRAIL_OF_FIRE);
        }

        void UpdateEscortAI(uint32 diff) override
        {
            if (HealthBelowPct(75))
            {
                if (PotTimer <= diff)
                {
                    DoCast(me, SPELL_HEALING_POTION, true);
                    PotTimer = 10000;
                }
                else PotTimer -= diff;
            }
            if (GetAttack() && UpdateVictim())
                DoMeleeAttackIfReady();
        }

        void WaypointReached(uint32 waypointId) override
        {
            Player* player = GetPlayerForEscort();
            if (!player)
                return;

            switch (waypointId)
            {
                case 1:
                    me->SetReactState(REACT_AGGRESSIVE);
                    SetRun(true);
                    break;
                case 23:
                    player->GroupEventHappens(QUEST_TRAIL_OF_FIRE, me);
                    me->DespawnOrUnsummon();
                    break;
                case 5:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(false);
                    break;
                case 6:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(true);
                    break;
                case 8:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(false);
                    break;
                case 9:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    break;
                case 10:
                    SetRun(true);
                    break;
                case 13:
                    SetRun(false);
                    break;
                case 14:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(true);
                    break;
            }
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_Apothecary_HanesAI(creature);
    }
};

/*######
## npc_plaguehound_tracker
######*/

class npc_plaguehound_tracker : public CreatureScript
{
public:
    npc_plaguehound_tracker() : CreatureScript("npc_plaguehound_tracker") { }

    struct npc_plaguehound_trackerAI : public npc_escortAI
    {
        npc_plaguehound_trackerAI(Creature* creature) : npc_escortAI(creature) { }

        void Reset() override
        {
            ObjectGuid summonerGUID;
            if (me->IsSummon())
                if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
                    if (summoner->GetTypeId() == TYPEID_PLAYER)
                        summonerGUID = summoner->GetGUID();

            if (!summonerGUID)
                return;

            me->SetWalk(true);
            Start(false, false, summonerGUID);
        }

        void WaypointReached(uint32 waypointId) override
        {
            if (waypointId != 26)
                return;

            me->DespawnOrUnsummon();
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_plaguehound_trackerAI(creature);
    }
};

/*######
## npc_razael_and_lyana
######*/

enum Razael
{
    QUEST_REPORTS_FROM_THE_FIELD = 11221,
    NPC_RAZAEL = 23998,
    NPC_LYANA = 23778,
    GOSSIP_TEXTID_RAZAEL1 = 11562,
    GOSSIP_TEXTID_RAZAEL2 = 11564,
    GOSSIP_TEXTID_LYANA1 = 11586,
    GOSSIP_TEXTID_LYANA2 = 11588
};

class npc_razael_and_lyana : public CreatureScript
{
public:
    npc_razael_and_lyana() : CreatureScript("npc_razael_and_lyana") { }

    bool OnGossipHello(Player* player, Creature* creature) override
    {
        if (creature->IsQuestGiver())
            player->PrepareQuestMenu(creature->GetGUID());

        if (player->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE)
            switch (creature->GetEntry())
            {
                case NPC_RAZAEL:
                    if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL))
                    {
                        AddGossipItemFor(player, 8870, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
                        SendGossipMenuFor(player, GOSSIP_TEXTID_RAZAEL1, creature->GetGUID());
                        return true;
                    }
                    break;
                case NPC_LYANA:
                    if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA))
                    {
                        AddGossipItemFor(player, 8879, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
                        SendGossipMenuFor(player, GOSSIP_TEXTID_LYANA1, creature->GetGUID());
                        return true;
                    }
                    break;
            }
        SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
        return true;
    }

    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
    {
        ClearGossipMenuFor(player);
        switch (action)
        {
            case GOSSIP_ACTION_INFO_DEF + 1:
                SendGossipMenuFor(player, GOSSIP_TEXTID_RAZAEL2, creature->GetGUID());
                player->TalkedToCreature(NPC_RAZAEL, creature->GetGUID());
                break;
            case GOSSIP_ACTION_INFO_DEF + 2:
                SendGossipMenuFor(player, GOSSIP_TEXTID_LYANA2, creature->GetGUID());
                player->TalkedToCreature(NPC_LYANA, creature->GetGUID());
                break;
        }
        return true;
    }
};

void AddSC_howling_fjord()
{
    // Ours
    new npc_attracted_reef_bull();
    new npc_your_inner_turmoil();

    // Theirs
    new npc_apothecary_hanes();
    new npc_plaguehound_tracker();
    new npc_razael_and_lyana();
}
<commit_msg>fix(Core): Crashfix. (#12093)<commit_after>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/* ScriptData
SDName: Sholazar_Basin
SD%Complete: 100
SDComment: Quest support: 11253, 11241.
SDCategory: howling_fjord
EndScriptData */

/* ContentData
npc_plaguehound_tracker
npc_apothecary_hanes
EndContentData */

#include "PassiveAI.h"
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "ScriptedGossip.h"
#include "SpellInfo.h"

// Ours
class npc_attracted_reef_bull : public CreatureScript
{
public:
    npc_attracted_reef_bull() : CreatureScript("npc_attracted_reef_bull") { }

    struct npc_attracted_reef_bullAI : public NullCreatureAI
    {
        npc_attracted_reef_bullAI(Creature* creature) : NullCreatureAI(creature)
        {
            me->SetDisableGravity(true);
            if (me->IsSummon())
                if (Unit* owner = me->ToTempSummon()->GetSummonerUnit())
                    me->GetMotionMaster()->MovePoint(0, *owner);
        }

        void MovementInform(uint32  /*type*/, uint32  /*id*/) override
        {
            if (Creature* cow = me->FindNearestCreature(24797, 5.0f, true))
            {
                me->CastSpell(me, 44460, true);
                me->DespawnOrUnsummon(10000);
                cow->CastSpell(cow, 44460, true);
                cow->DespawnOrUnsummon(10000);
                if (me->IsSummon())
                    if (Unit* owner = me->ToTempSummon()->GetSummonerUnit())
                        owner->CastSpell(owner, 44463, true);
            }
        }

        void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
        {
            if (caster && spellInfo->Id == 44454)
                me->GetMotionMaster()->MovePoint(0, *caster);
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_attracted_reef_bullAI(creature);
    }
};

// The cleansing
enum TurmoilTexts
{
    SAY_TURMOIL_0                = 0,
    SAY_TURMOIL_1                = 1,
    SAY_TURMOIL_HALF_HP          = 2,
    SAY_TURMOIL_DEATH            = 3,
};

class npc_your_inner_turmoil : public CreatureScript
{
public:
    npc_your_inner_turmoil() : CreatureScript("npc_your_inner_turmoil") { }

    struct npc_your_inner_turmoilAI : public ScriptedAI
    {
        npc_your_inner_turmoilAI(Creature* creature) : ScriptedAI(creature) {}

        uint32 timer;
        short phase;
        bool health50;

        void Reset() override
        {
            timer = 0;
            phase = 0;
            health50 = false;
        }

        void UpdateAI(uint32 diff) override
        {
            if (timer >= 6000 && phase < 2)
            {
                phase++;
                setphase(phase);
                timer = 0;
            }

            timer += diff;

            DoMeleeAttackIfReady();
        }

        void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType  /*damagetype*/, SpellSchoolMask  /*damageSchoolMask*/) override
        {
            if (HealthBelowPct(50) && !health50)
            {
                WorldObject* summoner = nullptr;
                if (TempSummon const* tempSummon = me->ToTempSummon())
                {
                    summoner = tempSummon->GetSummonerUnit();
                }

                Talk(SAY_TURMOIL_HALF_HP, summoner);
                health50 = true;
            }
        }

        void JustDied(Unit* /*killer*/) override
        {
            Talk(SAY_TURMOIL_DEATH, me->ToTempSummon()->GetSummonerUnit()->ToPlayer());
        }

        void setphase(short newPhase)
        {
            Unit* summoner = me->ToTempSummon() ? me->ToTempSummon()->GetSummonerUnit() : nullptr;
            if (!summoner || summoner->GetTypeId() != TYPEID_PLAYER)
                return;

            switch (newPhase)
            {
                case 1:
                    Talk(SAY_TURMOIL_0, summoner->ToPlayer());
                    return;
                case 2:
                {
                    Talk(SAY_TURMOIL_1, summoner->ToPlayer());
                    me->SetLevel(summoner->getLevel());
                    me->SetFaction(FACTION_MONSTER);
                    if (me->GetExactDist(summoner) < 50.0f)
                    {
                        me->UpdatePosition(summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ(), 0.0f, true);
                        summoner->CastSpell(me, 50218, true); // clone caster
                        AttackStart(summoner);
                    }
                }
            }
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_your_inner_turmoilAI(creature);
    }
};

// Theirs
/*######
## npc_apothecary_hanes
######*/
enum Entries
{
    NPC_APOTHECARY_HANES         = 23784,
    NPC_HANES_FIRE_TRIGGER       = 23968,
    QUEST_TRAIL_OF_FIRE          = 11241,
    SPELL_COSMETIC_LOW_POLY_FIRE = 56274,
    SPELL_HEALING_POTION         = 17534
};

class npc_apothecary_hanes : public CreatureScript
{
public:
    npc_apothecary_hanes() : CreatureScript("npc_apothecary_hanes") { }

    bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override
    {
        if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE)
        {
            creature->SetFaction(player->GetTeamId() == TEAM_ALLIANCE ? FACTION_ESCORTEE_A_PASSIVE : FACTION_ESCORTEE_H_PASSIVE);
            CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
        }
        return true;
    }

    struct npc_Apothecary_HanesAI : public npc_escortAI
    {
        npc_Apothecary_HanesAI(Creature* creature) : npc_escortAI(creature) { }
        uint32 PotTimer;

        void Reset() override
        {
            SetDespawnAtFar(false);
            PotTimer = 10000; //10 sec cooldown on potion
        }

        void JustDied(Unit* /*killer*/) override
        {
            if (Player* player = GetPlayerForEscort())
                player->FailQuest(QUEST_TRAIL_OF_FIRE);
        }

        void UpdateEscortAI(uint32 diff) override
        {
            if (HealthBelowPct(75))
            {
                if (PotTimer <= diff)
                {
                    DoCast(me, SPELL_HEALING_POTION, true);
                    PotTimer = 10000;
                }
                else PotTimer -= diff;
            }
            if (GetAttack() && UpdateVictim())
                DoMeleeAttackIfReady();
        }

        void WaypointReached(uint32 waypointId) override
        {
            Player* player = GetPlayerForEscort();
            if (!player)
                return;

            switch (waypointId)
            {
                case 1:
                    me->SetReactState(REACT_AGGRESSIVE);
                    SetRun(true);
                    break;
                case 23:
                    player->GroupEventHappens(QUEST_TRAIL_OF_FIRE, me);
                    me->DespawnOrUnsummon();
                    break;
                case 5:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(false);
                    break;
                case 6:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(true);
                    break;
                case 8:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(false);
                    break;
                case 9:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    break;
                case 10:
                    SetRun(true);
                    break;
                case 13:
                    SetRun(false);
                    break;
                case 14:
                    if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f))
                        Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
                    SetRun(true);
                    break;
            }
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_Apothecary_HanesAI(creature);
    }
};

/*######
## npc_plaguehound_tracker
######*/

class npc_plaguehound_tracker : public CreatureScript
{
public:
    npc_plaguehound_tracker() : CreatureScript("npc_plaguehound_tracker") { }

    struct npc_plaguehound_trackerAI : public npc_escortAI
    {
        npc_plaguehound_trackerAI(Creature* creature) : npc_escortAI(creature) { }

        void Reset() override
        {
            ObjectGuid summonerGUID;
            if (me->IsSummon())
                if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
                    if (summoner->GetTypeId() == TYPEID_PLAYER)
                        summonerGUID = summoner->GetGUID();

            if (!summonerGUID)
                return;

            me->SetWalk(true);
            Start(false, false, summonerGUID);
        }

        void WaypointReached(uint32 waypointId) override
        {
            if (waypointId != 26)
                return;

            me->DespawnOrUnsummon();
        }
    };

    CreatureAI* GetAI(Creature* creature) const override
    {
        return new npc_plaguehound_trackerAI(creature);
    }
};

/*######
## npc_razael_and_lyana
######*/

enum Razael
{
    QUEST_REPORTS_FROM_THE_FIELD = 11221,
    NPC_RAZAEL = 23998,
    NPC_LYANA = 23778,
    GOSSIP_TEXTID_RAZAEL1 = 11562,
    GOSSIP_TEXTID_RAZAEL2 = 11564,
    GOSSIP_TEXTID_LYANA1 = 11586,
    GOSSIP_TEXTID_LYANA2 = 11588
};

class npc_razael_and_lyana : public CreatureScript
{
public:
    npc_razael_and_lyana() : CreatureScript("npc_razael_and_lyana") { }

    bool OnGossipHello(Player* player, Creature* creature) override
    {
        if (creature->IsQuestGiver())
            player->PrepareQuestMenu(creature->GetGUID());

        if (player->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE)
            switch (creature->GetEntry())
            {
                case NPC_RAZAEL:
                    if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL))
                    {
                        AddGossipItemFor(player, 8870, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
                        SendGossipMenuFor(player, GOSSIP_TEXTID_RAZAEL1, creature->GetGUID());
                        return true;
                    }
                    break;
                case NPC_LYANA:
                    if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA))
                    {
                        AddGossipItemFor(player, 8879, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
                        SendGossipMenuFor(player, GOSSIP_TEXTID_LYANA1, creature->GetGUID());
                        return true;
                    }
                    break;
            }
        SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
        return true;
    }

    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
    {
        ClearGossipMenuFor(player);
        switch (action)
        {
            case GOSSIP_ACTION_INFO_DEF + 1:
                SendGossipMenuFor(player, GOSSIP_TEXTID_RAZAEL2, creature->GetGUID());
                player->TalkedToCreature(NPC_RAZAEL, creature->GetGUID());
                break;
            case GOSSIP_ACTION_INFO_DEF + 2:
                SendGossipMenuFor(player, GOSSIP_TEXTID_LYANA2, creature->GetGUID());
                player->TalkedToCreature(NPC_LYANA, creature->GetGUID());
                break;
        }
        return true;
    }
};

void AddSC_howling_fjord()
{
    // Ours
    new npc_attracted_reef_bull();
    new npc_your_inner_turmoil();

    // Theirs
    new npc_apothecary_hanes();
    new npc_plaguehound_tracker();
    new npc_razael_and_lyana();
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Tavendo GmbH
//
// Boost Software License - Version 1.0 - August 17th, 2003
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////

#include <msgpack.hpp>
#include <string>
#include <unordered_map>

namespace autobahn {

inline wamp_subscribe_options::wamp_subscribe_options()
    : m_match()
{
}

inline const std::string& wamp_subscribe_options::match() const
{
    return *m_match;
}

inline const bool wamp_subscribe_options::is_match_set() const
{
    return m_match.is_initialized();
}

inline void wamp_subscribe_options::set_match(const std::string& match)
{
    if (!(match == "exact" || match == "prefix" || match == "wildcard"))
    {
        throw std::runtime_error("The value of 'match' must be 'exact', 'prefix', or 'wildcard'.");
    }
    m_match = match;
}

} // namespace autobahn

namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {

template<>
struct convert<autobahn::wamp_subscribe_options>
{
    msgpack::object const& operator()(
            msgpack::object const& object,
            autobahn::wamp_subscribe_options& options) const
    {
        return object;
    }
};

template<>
struct pack<autobahn::wamp_subscribe_options>
{
    template <typename Stream>
    msgpack::packer<Stream>& operator()(
            msgpack::packer<Stream>& packer,
            autobahn::wamp_subscribe_options const& options) const
    {
        std::map<std::string, std::string> options_map;
        bool should_pack_options = false;

        if (options.is_match_set())
        {
            options_map["match"] = options.match();
            should_pack_options = true;
        }

        if (should_pack_options)
        {
            packer.pack(options_map);
        }
        else
        {
            packer.pack_map(0);
        }

        return packer;
    }
};

template <>
struct object_with_zone<autobahn::wamp_subscribe_options>
{
    void operator()(
            msgpack::object::with_zone& object,
            const autobahn::wamp_subscribe_options& options)
    {
        std::map<std::string, std::string> options_map;
        bool should_copy_options = false;

        if (options.is_match_set())
        {
            options_map["match"] = options.match();
            should_copy_options = true;
        }

        if (should_copy_options)
        {
            object << options_map;
        }
    }
};

} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack

<commit_msg>Fix subscribe options<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Tavendo GmbH
//
// Boost Software License - Version 1.0 - August 17th, 2003
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////

#include <msgpack.hpp>
#include <string>
#include <unordered_map>

namespace autobahn {

inline wamp_subscribe_options::wamp_subscribe_options()
    : m_match()
{
}

inline const std::string& wamp_subscribe_options::match() const
{
    return *m_match;
}

inline const bool wamp_subscribe_options::is_match_set() const
{
    return m_match.is_initialized();
}

inline void wamp_subscribe_options::set_match(const std::string& match)
{
    if (!(match == "exact" || match == "prefix" || match == "wildcard"))
    {
        throw std::runtime_error("The value of 'match' must be 'exact', 'prefix', or 'wildcard'.");
    }
    m_match = match;
}

} // namespace autobahn

namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {

template<>
struct convert<autobahn::wamp_subscribe_options>
{
    msgpack::object const& operator()(
            msgpack::object const& object,
            autobahn::wamp_subscribe_options& options) const
    {
        return object;
    }
};

template<>
struct pack<autobahn::wamp_subscribe_options>
{
    template <typename Stream>
    msgpack::packer<Stream>& operator()(
            msgpack::packer<Stream>& packer,
            autobahn::wamp_subscribe_options const& options) const
    {
        std::map<std::string, std::string> options_map;

        if (options.is_match_set())
        {
            options_map["match"] = options.match();
        }

        packer.pack(options_map);

        return packer;
    }
};

template <>
struct object_with_zone<autobahn::wamp_subscribe_options>
{
    void operator()(
            msgpack::object::with_zone& object,
            const autobahn::wamp_subscribe_options& options)
    {
        std::map<std::string, std::string> options_map;

        if (options.is_match_set())
        {
            options_map["match"] = options.match();
        }

        object << options_map;
    }
};

} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tplparam.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 11:50:07 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <precomp.h>
#include "tplparam.hxx"

// NOT FULLY DEFINED SERVICES
#include <cpp/c_gate.hxx>

namespace ary
{
namespace cpp
{
namespace ut
{

TplParameter_Type::TplParameter_Type( Tid i_nType )
    :   nType(i_nType)
{
}

TplParameter_Type::~TplParameter_Type()
{
}

intt
TplParameter_Type::Compare( const TemplateParameter & i_rOther ) const
{
    const TplParameter_Type * pOther
            = dynamic_cast< const TplParameter_Type* >( &i_rOther );
    if (pOther == 0)
        return -1;

    return nType - pOther->nType;
}

void
TplParameter_Type::Get_Text( StreamStr &                    o_rOut,
                             const ary::cpp::DisplayGate &  i_rGate ) const
{
    i_rGate.Get_TypeText( o_rOut, nType );
}

TplParameter_Const::TplParameter_Const( const udmstri & i_sConst )
    :   sConstant(i_sConst)
{
}

TplParameter_Const::~TplParameter_Const()
{
}

intt
TplParameter_Const::Compare( const TemplateParameter & i_rOther ) const
{
    const TplParameter_Const * pOther
            = dynamic_cast< const TplParameter_Const* >( &i_rOther );
    if (pOther == 0)
        return +1;

    return strcmp( sConstant.c_str(), pOther->sConstant.c_str() );
}

void
TplParameter_Const::Get_Text( StreamStr &                   o_rOut,
                              const ary::cpp::DisplayGate &  ) const
{
    o_rOut << sConstant;
}

}   // namespace ut
}   // namespace cpp
}   // namespace ary

<commit_msg>INTEGRATION: CWS pchfix02 (1.3.6); FILE MERGED 2006/09/01 17:15:17 kaib 1.3.6.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tplparam.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 16:19:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_autodoc.hxx"

#include <precomp.h>
#include "tplparam.hxx"

// NOT FULLY DEFINED SERVICES
#include <cpp/c_gate.hxx>

namespace ary
{
namespace cpp
{
namespace ut
{

TplParameter_Type::TplParameter_Type( Tid i_nType )
    :   nType(i_nType)
{
}

TplParameter_Type::~TplParameter_Type()
{
}

intt
TplParameter_Type::Compare( const TemplateParameter & i_rOther ) const
{
    const TplParameter_Type * pOther
            = dynamic_cast< const TplParameter_Type* >( &i_rOther );
    if (pOther == 0)
        return -1;

    return nType - pOther->nType;
}

void
TplParameter_Type::Get_Text( StreamStr &                    o_rOut,
                             const ary::cpp::DisplayGate &  i_rGate ) const
{
    i_rGate.Get_TypeText( o_rOut, nType );
}

TplParameter_Const::TplParameter_Const( const udmstri & i_sConst )
    :   sConstant(i_sConst)
{
}

TplParameter_Const::~TplParameter_Const()
{
}

intt
TplParameter_Const::Compare( const TemplateParameter & i_rOther ) const
{
    const TplParameter_Const * pOther
            = dynamic_cast< const TplParameter_Const* >( &i_rOther );
    if (pOther == 0)
        return +1;

    return strcmp( sConstant.c_str(), pOther->sConstant.c_str() );
}

void
TplParameter_Const::Get_Text( StreamStr &                   o_rOut,
                              const ary::cpp::DisplayGate &  ) const
{
    o_rOut << sConstant;
}

}   // namespace ut
}   // namespace cpp
}   // namespace ary

<|endoftext|>


<commit_before>#include "dwarf.h"
#include "symbols.h"
#include "../ast/error.h"
#include "../pkg/package.h"
#include "../type/subtype.h"
#include "../../libponyrt/mem/pool.h"
#include "../../libponyrt/pony.h"

#define OFFSET_CLASS (sizeof(void*) * 8)
#define OFFSET_ACTOR (sizeof(pony_actor_pad_t) * 8)

using namespace llvm;
using namespace llvm::dwarf;

typedef struct frame_t frame_t;

struct frame_t
{
  size_t size;
  subnodes_t* members;
  frame_t* prev;
};

struct dwarf_t
{
  symbols_t* symbols;
  DataLayout* layout;
  frame_t* frame;
};

/**
 * Every call to dwarf_forward causes a dwarf_frame_t to be pushed onto
 * the stack.
 */
static frame_t* push_frame(dwarf_t* dwarf)
{
  frame_t* frame = POOL_ALLOC(frame_t);
  memset(frame, 0, sizeof(frame_t));

  frame->prev = dwarf->frame;
  dwarf->frame = frame;

  return frame;
}

/**
 * Every call to dwarf_composite causes a dwarf_frame_t to be popped from
 * the stack.
 */
static void pop_frame(dwarf_t* dwarf)
{
  frame_t* frame = dwarf->frame;
  dwarf->frame = frame->prev;

  POOL_FREE(frame_t, frame);
}

/**
 * Collect type information such as file and line scope. The definition
 * of tuple types is lexically unscoped, because tuple type names are
 * ambiguous.
 */
static void setup_dwarf(dwarf_t* dwarf, gentype_t* g, LLVMTypeRef typeref,
  symbol_scope_t* scope, bool definition, bool prelim)
{
  ast_t* ast = g->ast;
  Type* type = unwrap(typeref);

  memset(scope, 0, sizeof(symbol_scope_t));

  if(definition && ast_id(ast) != TK_TUPLETYPE)
  {
    ast = (ast_t*)ast_data(ast);
    ast_t* module = ast_nearest(ast, TK_MODULE);
    source_t* source = (source_t*)ast_data(module);

    scope->file = symbols_file(dwarf->symbols, source->file);
  }

  if(!prelim)
  {
    g->size = dwarf->layout->getTypeSizeInBits(type);
    g->align = dwarf->layout->getABITypeAlignment(type) << 3;
  }

  scope->line = ast_line(ast);
  scope->pos = ast_pos(ast);
}

void dwarf_compileunit(dwarf_t* dwarf, ast_t* program)
{
  assert(ast_id(program) == TK_PROGRAM);
  ast_t* package = ast_child(program);

  const char* path = package_path(package);
  const char* name = package_filename(package);

  symbols_package(dwarf->symbols, path, name);
}

void dwarf_forward(dwarf_t* dwarf, gentype_t* g)
{
  if(!symbols_known_type(dwarf->symbols, g->type_name))
  {
    frame_t* frame = push_frame(dwarf);

    LLVMTypeRef typeref = g->structure;
    size_t size = g->field_count;

    // The field count for non-tuple types does not contain
    // the methods, which in the dwarf world are subnodes
    // just like fields.
    if(g->underlying != TK_TUPLETYPE)
    {
      /*Type* ptr = unwrap(g->structure_ptr);
      g->size = dwarf->layout->getTypeSizeInBits(ptr);
      g->align = dwarf->layout->getABITypeAlignment(ptr) << 3;*/

      ast_t* def = (ast_t*)ast_data(g->ast);
      size += ast_childcount(ast_childidx(def, 4)) - size;
    } else {
      typeref = g->primitive;
    }

    frame->size = size;

    symbol_scope_t scope;
    setup_dwarf(dwarf, g, typeref, &scope, true, true);

    symbols_declare(dwarf->symbols, g, &frame->members, size, &scope);
  }
}

void dwarf_basic(dwarf_t* dwarf, gentype_t* g)
{
  // Basic types are builtin, hence have no compilation
  // unit scope and their size and ABI alignment depends
  // on the primitive structure.
  symbol_scope_t scope;
  setup_dwarf(dwarf, g, g->primitive, &scope, false, false);

  symbols_basic(dwarf->symbols, g);
}

void dwarf_pointer(dwarf_t* dwarf, gentype_t* ptr, gentype_t* g)
{
  symbol_scope_t scope;
  setup_dwarf(dwarf, ptr, ptr->use_type, &scope, false, false);

  symbols_pointer(dwarf->symbols, ptr, g);
}

void dwarf_trait(dwarf_t* dwarf, gentype_t* g)
{
  // Trait definitions have a scope, but are modeled
  // as opaque classes from which other classes may
  // inherit. There is no need to set the size and
  // align to 0, because gentype_t was memset.
  symbol_scope_t scope;
  setup_dwarf(dwarf, g, g->use_type, &scope, true, false);

  symbols_trait(dwarf->symbols, g, &scope);
}

void dwarf_composite(dwarf_t* dwarf, gentype_t* g)
{
  size_t offset = 0;

  switch(g->underlying)
  {
    case TK_ACTOR: offset = OFFSET_ACTOR;
    case TK_PRIMITIVE:
    case TK_CLASS: offset += OFFSET_CLASS;
    default: {}
  }

  LLVMTypeRef typeref = g->structure;

  if(g->underlying == TK_TUPLETYPE)
    typeref = g->primitive;

  symbol_scope_t scope;
  setup_dwarf(dwarf, g, typeref, &scope, true, false);

  symbols_composite(dwarf->symbols, g, offset, dwarf->frame->members,
    &scope);

  pop_frame(dwarf);
}

void dwarf_field(dwarf_t* dwarf, gentype_t* composite, gentype_t* field,
  size_t index)
{
  const char* name = "anon";
  bool is_private = false;
  bool constant = false;

  // TK_TUPLETYPE fields are anonymous.
  if(composite->underlying != TK_TUPLETYPE)
  {
    ast_t* def = (ast_t*)ast_data(composite->ast);
    ast_t* members = ast_childidx(def, 4);
    ast_t* field = ast_childidx(members, index);

    assert(ast_id(field) == TK_FVAR || ast_id(field) == TK_FLET);

    if(ast_id(field) == TK_FLET)
      constant = true;

    name = ast_name(ast_child(field));
    is_private = name[0] == '_';
  }

  symbol_scope_t scope;
  setup_dwarf(dwarf, field, field->use_type, &scope, false, false);

  symbols_member(dwarf->symbols, field, dwarf->frame->members, &scope,
    name, is_private, constant, index);
}

void dwarf_init(compile_t* c)
{
  c->dwarf = POOL_ALLOC(dwarf_t);
  c->dwarf->symbols = symbols_init(c);
  c->dwarf->layout = unwrap(c->target_data);
  c->dwarf->frame = NULL;
}

void dwarf_finalise(dwarf_t* dwarf)
{
  symbols_finalise(dwarf->symbols);
  POOL_FREE(dwarf_t, dwarf);
}
<commit_msg>intermediate commit<commit_after>#include "dwarf.h"
#include "symbols.h"
#include "../ast/error.h"
#include "../pkg/package.h"
#include "../type/subtype.h"
#include "../../libponyrt/mem/pool.h"
#include "../../libponyrt/pony.h"

#include <platform.h>

#define OFFSET_CLASS (sizeof(void*) * 8)
#define OFFSET_ACTOR (sizeof(pony_actor_pad_t) * 8)

using namespace llvm;
using namespace llvm::dwarf;

typedef struct frame_t frame_t;

struct frame_t
{
  size_t size;
  subnodes_t* members;
  frame_t* prev;
};

struct dwarf_t
{
  symbols_t* symbols;
  DataLayout* layout;
  frame_t* frame;
};

/**
 * Every call to dwarf_forward causes a frame_t to be pushed onto
 * the stack.
 */
static frame_t* push_frame(dwarf_t* dwarf)
{
  frame_t* frame = POOL_ALLOC(frame_t);
  memset(frame, 0, sizeof(frame_t));

  frame->prev = dwarf->frame;
  dwarf->frame = frame;

  return frame;
}

/**
 * Every call to dwarf_composite causes a frame_t to be popped from
 * the stack.
 */
static void pop_frame(dwarf_t* dwarf)
{
  frame_t* frame = dwarf->frame;
  dwarf->frame = frame->prev;

  POOL_FREE(frame_t, frame);
}

/**
 * Collect type information such as file and line scope. The definition
 * of tuple types is lexically unscoped, because tuple type names are
 * ambiguous.
 */
static void setup_dwarf(dwarf_t* dwarf, gentype_t* g, LLVMTypeRef typeref,
  symbol_scope_t* scope, bool definition, bool prelim)
{
  ast_t* ast = g->ast;
  Type* type = unwrap(typeref);

  memset(scope, 0, sizeof(symbol_scope_t));

  if(definition && ast_id(ast) != TK_TUPLETYPE)
  {
    ast = (ast_t*)ast_data(ast);
    ast_t* module = ast_nearest(ast, TK_MODULE);
    source_t* source = (source_t*)ast_data(module);

    scope->file = symbols_file(dwarf->symbols, source->file);
  }

  if(!prelim)
  {
    g->size = dwarf->layout->getTypeSizeInBits(type);
    g->align = dwarf->layout->getABITypeAlignment(type) << 3;
  }

  scope->line = ast_line(ast);
  scope->pos = ast_pos(ast);
}

void dwarf_compileunit(dwarf_t* dwarf, ast_t* program)
{
  assert(ast_id(program) == TK_PROGRAM);
  ast_t* package = ast_child(program);

  const char* path = package_path(package);
  const char* name = package_filename(package);

  symbols_package(dwarf->symbols, path, name);
}

void dwarf_forward(dwarf_t* dwarf, gentype_t* g)
{
  if(!symbols_known_type(dwarf->symbols, g->type_name))
  {
    frame_t* frame = push_frame(dwarf);

    LLVMTypeRef typeref = g->structure;
    size_t size = g->field_count;

    // The field count for non-tuple types does not contain
    // the methods, which in the dwarf world are subnodes
    // just like fields.
    if(g->underlying != TK_TUPLETYPE)
    {
      ast_t* def = (ast_t*)ast_data(g->ast);
      size += ast_childcount(ast_childidx(def, 4)) - size;
    } else {
      typeref = g->primitive;
    }

    frame->size = size;

    symbol_scope_t scope;
    setup_dwarf(dwarf, g, typeref, &scope, true, true);

    symbols_declare(dwarf->symbols, g, &frame->members, size, &scope);
  }
}

void dwarf_basic(dwarf_t* dwarf, gentype_t* g)
{
  // Basic types are builtin, hence have no compilation
  // unit scope and their size and ABI alignment depends
  // on the primitive structure.
  symbol_scope_t scope;
  setup_dwarf(dwarf, g, g->primitive, &scope, false, false);

  symbols_basic(dwarf->symbols, g);
}

void dwarf_pointer(dwarf_t* dwarf, gentype_t* ptr, gentype_t* g)
{
  symbol_scope_t scope;
  setup_dwarf(dwarf, ptr, ptr->use_type, &scope, false, false);

  symbols_pointer(dwarf->symbols, ptr, g);
}

void dwarf_trait(dwarf_t* dwarf, gentype_t* g)
{
  // Trait definitions have a scope, but are modeled
  // as opaque classes from which other classes may
  // inherit. There is no need to set the size and
  // align to 0, because gentype_t was memset.
  symbol_scope_t scope;
  setup_dwarf(dwarf, g, g->use_type, &scope, true, false);

  symbols_trait(dwarf->symbols, g, &scope);
}

void dwarf_composite(dwarf_t* dwarf, gentype_t* g)
{
  size_t offset = 0;

  switch(g->underlying)
  {
    case TK_ACTOR: offset = OFFSET_ACTOR;
    case TK_PRIMITIVE:
    case TK_CLASS: offset += OFFSET_CLASS;
    default: {}
  }

  LLVMTypeRef typeref = g->structure;

  if(g->underlying == TK_TUPLETYPE)
    typeref = g->primitive;

  symbol_scope_t scope;
  setup_dwarf(dwarf, g, typeref, &scope, true, false);

  symbols_composite(dwarf->symbols, g, offset, dwarf->frame->members,
    &scope);

  pop_frame(dwarf);
}

void dwarf_field(dwarf_t* dwarf, gentype_t* composite, gentype_t* field,
  size_t index)
{
  char buf[32];
  memset(buf, 0, sizeof(buf));

  const char* name = NULL;

  bool is_private = false;
  bool constant = false;

  if(composite->underlying != TK_TUPLETYPE)
  {
    ast_t* def = (ast_t*)ast_data(composite->ast);
    ast_t* members = ast_childidx(def, 4);
    ast_t* field = ast_childidx(members, index);

    assert(ast_id(field) == TK_FVAR || ast_id(field) == TK_FLET);

    if(ast_id(field) == TK_FLET)
      constant = true;

    name = ast_name(ast_child(field));
    is_private = name[0] == '_';
  } else {
    snprintf(buf, sizeof(buf), "_" __zu, index);
    name = buf;
  }

  symbol_scope_t scope;
  setup_dwarf(dwarf, field, field->use_type, &scope, false, false);

  symbols_member(dwarf->symbols, field, dwarf->frame->members, &scope,
    name, is_private, constant, index);
}

void dwarf_init(compile_t* c)
{
  c->dwarf = POOL_ALLOC(dwarf_t);
  c->dwarf->symbols = symbols_init(c);
  c->dwarf->layout = unwrap(c->target_data);
  c->dwarf->frame = NULL;
}

void dwarf_finalise(dwarf_t* dwarf)
{
  symbols_finalise(dwarf->symbols);
  POOL_FREE(dwarf_t, dwarf);
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include "library/vm/vm.h"

namespace lean {
static void del_instr_at(unsigned pc, buffer<vm_instr> & code) {
    code.erase(pc);
    // we must adjust pc of other instructions
    for (unsigned i = 0; i < code.size(); i++) {
        vm_instr & c = code[i];
        for (unsigned j = 0; j < c.get_num_pcs(); j++) {
            if (c.get_pc(j) > pc)
                c.set_pc(j, c.get_pc(j) - 1);
        }
    }
}

/**
   \brief Applies the following transformation
   ...
   pc:   drop n
   pc+1: drop m
   ...
   ===>
   ...
   pc:   drop n+m
   ... */
static void compress_drop_drop(buffer<vm_instr> & code) {
    if (code.empty()) return;
    unsigned i = code.size() - 1;
    while (i > 0) {
        --i;
        if (code[i].op() == opcode::Drop &&
            code[i+1].op() == opcode::Drop) {
            code[i] = mk_drop_instr(code[i].get_num() + code[i+1].get_num());
            del_instr_at(i+1, code);
        }
    }
}

/**
   \brief Applies the following transformation

   pc_1 : goto pc_2
   ...
   pc_2 : ret
   ===>
   pc_1 : ret
   ...
   pc_2 : ret */
static void compress_goto_ret(buffer<vm_instr> & code) {
    unsigned i = code.size();
    while (i > 0) {
        --i;
        if (code[i].op() == opcode::Goto) {
            unsigned pc = code[i].get_goto_pc();
            if (code[pc].op() == opcode::Ret) {
                code[i] = mk_ret_instr();
            }
        }
    }
}

void optimize(environment const &, buffer<vm_instr> & code) {
    compress_goto_ret(code);
    compress_drop_drop(code);
}
}
<commit_msg>fix(library/vm/optimize): bytecode optimization<commit_after>/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include "library/vm/vm.h"

namespace lean {
static void del_instr_at(unsigned pc, buffer<vm_instr> & code) {
    code.erase(pc);
    // we must adjust pc of other instructions
    for (unsigned i = 0; i < code.size(); i++) {
        vm_instr & c = code[i];
        for (unsigned j = 0; j < c.get_num_pcs(); j++) {
            if (c.get_pc(j) > pc)
                c.set_pc(j, c.get_pc(j) - 1);
        }
    }
}

typedef rb_tree<unsigned, unsigned_cmp> addr_set;

/* Collect addresses in addr_set that are goto/branching targets */
static void collect_targets(buffer<vm_instr> & code, addr_set & r) {
    for (auto c : code) {
        for (unsigned j = 0; j < c.get_num_pcs(); j++)
            r.insert(c.get_pc(j));
    }
}

/**
   \brief Applies the following transformation
   ...
   pc:   drop n
   pc+1: drop m
   ...
   ===>
   ...
   pc:   drop n+m
   ... */
static void compress_drop_drop(buffer<vm_instr> & code) {
    if (code.empty()) return;
    addr_set targets;
    collect_targets(code, targets);
    unsigned i = code.size() - 1;
    while (i > 0) {
        --i;
        if (code[i].op() == opcode::Drop &&
            code[i+1].op() == opcode::Drop &&
            /* If i+1 is a goto/branch target, then we should not merge the two Drops */
            !targets.contains(i+1)) {
            code[i] = mk_drop_instr(code[i].get_num() + code[i+1].get_num());
            del_instr_at(i+1, code);
        }
    }
}

/**
   \brief Applies the following transformation

   pc_1 : goto pc_2
   ...
   pc_2 : ret
   ===>
   pc_1 : ret
   ...
   pc_2 : ret */
static void compress_goto_ret(buffer<vm_instr> & code) {
    unsigned i = code.size();
    while (i > 0) {
        --i;
        if (code[i].op() == opcode::Goto) {
            unsigned pc = code[i].get_goto_pc();
            if (code[pc].op() == opcode::Ret) {
                code[i] = mk_ret_instr();
            }
        }
    }
}

void optimize(environment const &, buffer<vm_instr> & code) {
    compress_goto_ret(code);
    compress_drop_drop(code);
}
}
<|endoftext|>


<commit_before>#define CDM_CONFIGURE_NAMESPACE a0038876
#include "../../cdm/application/using_boost/cdm.hpp"
#include "log.hpp"
#include "boost_root.hpp"
#include <boost/test/unit_test.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <silicium/file_operations.hpp>

#ifdef _WIN32
#include <shlobj.h>
#endif

namespace
{
	Si::absolute_path const this_file = *Si::absolute_path::create(__FILE__);
	Si::absolute_path const test = *Si::parent(this_file);
	Si::absolute_path const repository = *Si::parent(test);

#ifdef _WIN32
	struct CoTaskMemFreeDeleter
	{
		void operator()(void *memory) const
		{
			CoTaskMemFree(memory);
		}
	};

	Si::absolute_path get_home()
	{
		PWSTR path;
		HRESULT rc = SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &path);
		if (rc != S_OK)
		{
			throw std::runtime_error("Could not get home");
		}
		std::unique_ptr<wchar_t, CoTaskMemFreeDeleter> raii_path(path);
		return Si::absolute_path::create(raii_path.get()).or_throw([] { throw std::runtime_error("Windows returned a non-absolute path for home"); });
	}
#endif
}

BOOST_AUTO_TEST_CASE(test_using_boost)
{
	Si::absolute_path const app_source = repository / Si::relative_path("application/using_boost");
	Si::absolute_path const tmp = Si::temporary_directory(Si::throw_) / *Si::path_segment::create("cdm_b");
	Si::absolute_path const module_temporaries = tmp / *Si::path_segment::create("build");
	Si::absolute_path const module_permanent =
#ifdef _WIN32
		get_home() / Si::relative_path(".cdm_cache")
#else
		tmp / *Si::path_segment::create("perm")
#endif
		;
	Si::absolute_path const application_build_dir = tmp / *Si::path_segment::create("app_build");
	Si::recreate_directories(module_temporaries, Si::throw_);
	Si::recreate_directories(module_permanent, Si::throw_);
	Si::recreate_directories(application_build_dir, Si::throw_);
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(std::cerr));
	CDM_CONFIGURE_NAMESPACE::configure(module_temporaries, module_permanent, app_source, application_build_dir, cdm::get_boost_root_for_testing(), output);
	{
		std::vector<Si::os_string> arguments;
		arguments.push_back(SILICIUM_SYSTEM_LITERAL("--build"));
		arguments.push_back(SILICIUM_SYSTEM_LITERAL("."));
		BOOST_REQUIRE_EQUAL(0, Si::run_process(Si::cmake_exe, arguments, application_build_dir, output));
	}
	{
		std::vector<Si::os_string> arguments;
		Si::relative_path const relative(
#ifdef _MSC_VER
			SILICIUM_SYSTEM_LITERAL("Debug/")
#endif
			SILICIUM_SYSTEM_LITERAL("using_boost")
#ifdef _MSC_VER
			SILICIUM_SYSTEM_LITERAL(".exe")
#endif
		);
		BOOST_REQUIRE_EQUAL(0, Si::run_process(application_build_dir / relative, arguments, application_build_dir, output));
	}
}
<commit_msg>do not delete the permanent cache<commit_after>#define CDM_CONFIGURE_NAMESPACE a0038876
#include "../../cdm/application/using_boost/cdm.hpp"
#include "log.hpp"
#include "boost_root.hpp"
#include <boost/test/unit_test.hpp>
#include <silicium/sink/ostream_sink.hpp>
#include <silicium/file_operations.hpp>

#ifdef _WIN32
#include <shlobj.h>
#endif

namespace
{
	Si::absolute_path const this_file = *Si::absolute_path::create(__FILE__);
	Si::absolute_path const test = *Si::parent(this_file);
	Si::absolute_path const repository = *Si::parent(test);

#ifdef _WIN32
	struct CoTaskMemFreeDeleter
	{
		void operator()(void *memory) const
		{
			CoTaskMemFree(memory);
		}
	};

	Si::absolute_path get_home()
	{
		PWSTR path;
		HRESULT rc = SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_CREATE, NULL, &path);
		if (rc != S_OK)
		{
			throw std::runtime_error("Could not get home");
		}
		std::unique_ptr<wchar_t, CoTaskMemFreeDeleter> raii_path(path);
		return Si::absolute_path::create(raii_path.get()).or_throw([] { throw std::runtime_error("Windows returned a non-absolute path for home"); });
	}
#endif
}

BOOST_AUTO_TEST_CASE(test_using_boost)
{
	Si::absolute_path const app_source = repository / Si::relative_path("application/using_boost");
	Si::absolute_path const tmp = Si::temporary_directory(Si::throw_) / *Si::path_segment::create("cdm_b");
	Si::recreate_directories(tmp, Si::throw_);
	Si::absolute_path const module_temporaries = tmp / *Si::path_segment::create("build");
	Si::create_directories(module_temporaries, Si::throw_);
	Si::absolute_path const module_permanent =
#ifdef _WIN32
		get_home() / Si::relative_path(".cdm_cache")
#else
		tmp / *Si::path_segment::create("perm")
#endif
		;
	Si::absolute_path const application_build_dir = tmp / *Si::path_segment::create("app_build");
	Si::create_directories(application_build_dir, Si::throw_);
	auto output = cdm::make_program_output_printer(Si::ostream_ref_sink(std::cerr));
	CDM_CONFIGURE_NAMESPACE::configure(module_temporaries, module_permanent, app_source, application_build_dir, cdm::get_boost_root_for_testing(), output);
	{
		std::vector<Si::os_string> arguments;
		arguments.push_back(SILICIUM_SYSTEM_LITERAL("--build"));
		arguments.push_back(SILICIUM_SYSTEM_LITERAL("."));
		BOOST_REQUIRE_EQUAL(0, Si::run_process(Si::cmake_exe, arguments, application_build_dir, output));
	}
	{
		std::vector<Si::os_string> arguments;
		Si::relative_path const relative(
#ifdef _MSC_VER
			SILICIUM_SYSTEM_LITERAL("Debug/")
#endif
			SILICIUM_SYSTEM_LITERAL("using_boost")
#ifdef _MSC_VER
			SILICIUM_SYSTEM_LITERAL(".exe")
#endif
		);
		BOOST_REQUIRE_EQUAL(0, Si::run_process(application_build_dir / relative, arguments, application_build_dir, output));
	}
}
<|endoftext|>


<commit_before>#include <Halide.h>
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    Var x, y;

    {
        // Define a reduction with two update steps
        Func f;

        f(x) = sin(x);

        RDom r1(1, 10);
        Expr xl = r1; // left to right pass
        Expr xr = 10 - r1; // right to left pass
        f(xl) = f(xl - 1) + f(xl);
        f(xr) = f(xr + 1) + f(xr);

        Image<float> result = f.realize(11);

        // The same thing in C
        float ref[11];
        for (int i = 0; i < 11; i++) {
            ref[i] = sinf(i);
        }
        for (int i = 1; i < 11; i++) {
            ref[i] += ref[i-1];
        }
        for (int i = 10; i >= 0; i--) {
            ref[i] += ref[i+1];
        }

        for (int i = 0; i < 11; i++) {
            if (fabs(result(i) - ref[i]) > 0.0001f) {
                printf("result(%d) = %f instead of %f\n",
                       i, result(i), ref[i]);
                return -1;
            }
        }
    }

    {
        // Define a reduction that fills an array, integrates it, then
        // manually change certain values. One of the values will
        // depend on another function.
        Func f, g;
        g(x) = x*x;
        f(x) = x;

        // Integrate from 1 to 10
        RDom r(1, 10);
        f(r) = f(r) + f(r-1);

        // Clobber two values
        f(17) = 8;
        f(109) = 4;

        // Clobber a range using another func
        RDom r2(4, 5);
        f(r2) = g(r2);

        g.compute_at(f, r2);
        Image<int> result = f.realize(110);

        int correct[110];
        for (int i = 0; i < 110; i++) {
            correct[i] = i;
        }
        for (int i = 1; i < 11; i++) {
            correct[i] += correct[i-1];
        }
        correct[17] = 8;
        correct[109] = 4;
        for (int i = 4; i < 9; i++) {
            correct[i] = i*i;
        }

        for (int i = 0; i < 110; i++) {
            if (correct[i] != result(i)) {
                printf("result(%d) = %d instead of %d\n",
                       i, result(i), correct[i]);
                return -1;
            }
        }
    }

    {
        // Create a fully unrolled fibonacci routine composed almost
        // entirely of single assignment statements. The horror!
        Func f;
        f(x) = 1;
        for (int i = 2; i < 20; i++) {
            f(i) = f(i-1) + f(i-2);
        }

        Image<int> result = f.realize(20);

        int ref[20];
        ref[0] = 1;
        ref[1] = 1;
        for (int i = 2; i < 20; i++) {
            ref[i] = ref[i-1] + ref[i-2];
            if (ref[i] != result(i)) {
                printf("fibonacci(%d) = %d instead of %d\n",
                       i, result(i), ref[i]);
                return -1;
            }
        }
    }

    {
        // Make an integral image
        Func f;
        f(x, y) = sin(x + y);

        RDom r(1, 99);
        f(x, r) += f(x, r - 1);
        f(r, y) += f(r - 1, y);

        // Walk down the image in vectors
        f.update(0).vectorize(x, 4);

        // Walk across the image in parallel. We need to do an unsafe
        // reorder operation here to move y to the outer loop, because
        // we don't have the ability to reorder vars with rvars yet.
        f.update(1).reorder(Var(r.x.name()), y).parallel(y);

        Image<float> result = f.realize(100, 100);

        // Now the equivalent in C (cheating and using Halide for the initial image)
        Image<float> ref = lambda(x, y, sin(x+y)).realize(100, 100);
        for (int y = 1; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                ref(x, y) += ref(x, y - 1);
            }
        }
        for (int y = 0; y < 100; y++) {
            for (int x = 1; x < 100; x++) {
                ref(x, y) += ref(x - 1, y);
            }
        }

        // Check they're the same
        for (int y = 0; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                if (fabs(ref(x, y) - result(x, y)) > 0.0001f) {
                    printf("integral image at (%d, %d) = %f instead of %f\n",
                           x, y, result(x, y), ref(x, y));
                    return -1;
                }
            }
        }
    }

    {
        // Walk down an image using a few different factors of splits
        Func f;
        RDom r(1, 99);
        Var xo, xi;
        ImageParam input(Float(32), 2);
        f(x, y) = input(x, y);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f.update(0).split(x, x, xi, 8);
        f.update(1).split(x, x, xi, 12);
        f.update(2).split(x, x, xi, 18);

        // The minimum realization factor is now 72 (the least common
        // multiple of the split factors). So if we ask for an output
        // of size 100x10, we'll need an input of size 144 x 100. 144
        // being the smallest multiple of 72 larger than 100.
        f.infer_input_bounds(100, 10);

        Image<float> in = input.get();
        if (in.width() != 144 || in.height() != 100) {
            printf("Unexpected image size: %d x %d instead of 144 x 100\n",
                   in.width(), in.height());
            return -1;
        }
    }

    printf("Success!\n");

    return 0;
}
<commit_msg>Bugfix in C reference code for a test<commit_after>#include <Halide.h>
#include <stdio.h>

using namespace Halide;

int main(int argc, char **argv) {
    Var x, y;

    {
        // Define a reduction with two update steps
        Func f;

        f(x) = sin(x);

        RDom r1(1, 10);
        Expr xl = r1; // left to right pass
        Expr xr = 10 - r1; // right to left pass
        f(xl) = f(xl - 1) + f(xl);
        f(xr) = f(xr + 1) + f(xr);

        Image<float> result = f.realize(11);

        // The same thing in C
        float ref[11];
        for (int i = 0; i < 11; i++) {
            ref[i] = sinf(i);
        }
        for (int i = 1; i < 11; i++) {
            ref[i] += ref[i-1];
        }
        for (int i = 9; i >= 0; i--) {
            ref[i] += ref[i+1];
        }

        for (int i = 0; i < 11; i++) {
            if (fabs(result(i) - ref[i]) > 0.0001f) {
                printf("result(%d) = %f instead of %f\n",
                       i, result(i), ref[i]);
                return -1;
            }
        }
    }

    {
        // Define a reduction that fills an array, integrates it, then
        // manually change certain values. One of the values will
        // depend on another function.
        Func f, g;
        g(x) = x*x;
        f(x) = x;

        // Integrate from 1 to 10
        RDom r(1, 10);
        f(r) = f(r) + f(r-1);

        // Clobber two values
        f(17) = 8;
        f(109) = 4;

        // Clobber a range using another func
        RDom r2(4, 5);
        f(r2) = g(r2);

        g.compute_at(f, r2);
        Image<int> result = f.realize(110);

        int correct[110];
        for (int i = 0; i < 110; i++) {
            correct[i] = i;
        }
        for (int i = 1; i < 11; i++) {
            correct[i] += correct[i-1];
        }
        correct[17] = 8;
        correct[109] = 4;
        for (int i = 4; i < 9; i++) {
            correct[i] = i*i;
        }

        for (int i = 0; i < 110; i++) {
            if (correct[i] != result(i)) {
                printf("result(%d) = %d instead of %d\n",
                       i, result(i), correct[i]);
                return -1;
            }
        }
    }

    {
        // Create a fully unrolled fibonacci routine composed almost
        // entirely of single assignment statements. The horror!
        Func f;
        f(x) = 1;
        for (int i = 2; i < 20; i++) {
            f(i) = f(i-1) + f(i-2);
        }

        Image<int> result = f.realize(20);

        int ref[20];
        ref[0] = 1;
        ref[1] = 1;
        for (int i = 2; i < 20; i++) {
            ref[i] = ref[i-1] + ref[i-2];
            if (ref[i] != result(i)) {
                printf("fibonacci(%d) = %d instead of %d\n",
                       i, result(i), ref[i]);
                return -1;
            }
        }
    }

    {
        // Make an integral image
        Func f;
        f(x, y) = sin(x + y);

        RDom r(1, 99);
        f(x, r) += f(x, r - 1);
        f(r, y) += f(r - 1, y);

        // Walk down the image in vectors
        f.update(0).vectorize(x, 4);

        // Walk across the image in parallel. We need to do an unsafe
        // reorder operation here to move y to the outer loop, because
        // we don't have the ability to reorder vars with rvars yet.
        f.update(1).reorder(Var(r.x.name()), y).parallel(y);

        Image<float> result = f.realize(100, 100);

        // Now the equivalent in C (cheating and using Halide for the initial image)
        Image<float> ref = lambda(x, y, sin(x+y)).realize(100, 100);
        for (int y = 1; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                ref(x, y) += ref(x, y - 1);
            }
        }
        for (int y = 0; y < 100; y++) {
            for (int x = 1; x < 100; x++) {
                ref(x, y) += ref(x - 1, y);
            }
        }

        // Check they're the same
        for (int y = 0; y < 100; y++) {
            for (int x = 0; x < 100; x++) {
                if (fabs(ref(x, y) - result(x, y)) > 0.0001f) {
                    printf("integral image at (%d, %d) = %f instead of %f\n",
                           x, y, result(x, y), ref(x, y));
                    return -1;
                }
            }
        }
    }

    {
        // Walk down an image using a few different factors of splits
        Func f;
        RDom r(1, 99);
        Var xo, xi;
        ImageParam input(Float(32), 2);
        f(x, y) = input(x, y);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f(x, r) += f(x, r-1);
        f.update(0).split(x, x, xi, 8);
        f.update(1).split(x, x, xi, 12);
        f.update(2).split(x, x, xi, 18);

        // The minimum realization factor is now 72 (the least common
        // multiple of the split factors). So if we ask for an output
        // of size 100x10, we'll need an input of size 144 x 100. 144
        // being the smallest multiple of 72 larger than 100.
        f.infer_input_bounds(100, 10);

        Image<float> in = input.get();
        if (in.width() != 144 || in.height() != 100) {
            printf("Unexpected image size: %d x %d instead of 144 x 100\n",
                   in.width(), in.height());
            return -1;
        }
    }

    printf("Success!\n");

    return 0;
}
<|endoftext|>


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

#include <iostream>
#include <votca/tools/application.h>
#include <votca/tools/version.h>
#include <votca/tools/globals.h>
#include <votca/tools/propertyiomanipulator.h>

#include <boost/format.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>

namespace votca { namespace tools {
    using namespace std;
Application::Application()
    : _op_desc("Allowed options"), _continue_execution(true)
{
}

Application::~Application()
{
}

string Application::VersionString()
{
    return "";
}

void Application::ShowHelpText(std::ostream &out)
{
    out << "==================================================\n";
    out << "========   VOTCA (http://www.votca.org)   ========\n";
    out << "==================================================\n\n";

    out << "please submit bugs to bugs@votca.org\n\n";
    out << ProgramName();
    if(VersionString() != "")
        out << ", version " << VersionString();
    out << endl
        << "votca_tools, version " << ToolsVersionStr()
        << "\n\n";

    HelpText(out);

    // remove Hidden group from the option list and print
    out << "\n\n" << VisibleOptions() << endl;

    //out << "\n\n" << OptionsDesc() << endl;
}

void Application::ShowManPage(std::ostream &out) {

        out << boost::format(globals::man::header) %  ProgramName() % VersionString();
        out << boost::format(globals::man::name) % ProgramName() % globals::url;
        out << boost::format(globals::man::synopsis) % ProgramName();
        std::stringstream ss;
        HelpText(ss);
        out << boost::format(globals::man::description) % ss.str();
        out << boost::format(globals::man::options);

        typedef std::vector<boost::shared_ptr<boost::program_options::option_description> >::const_iterator OptionsIterator;
        OptionsIterator it = _op_desc.options().begin(), it_end = _op_desc.options().end();

        while(it < it_end) {
            string format_name = (*it)->format_name() + " " + (*it)->format_parameter();
            boost::replace_all(format_name, "-", "\\-");
            out << boost::format(globals::man::option) % format_name % (*it)->description();
            ++it;
        }

        out << boost::format(globals::man::authors) % globals::email;
        out << boost::format(globals::man::copyright) % globals::url;

}

void Application::ShowTEXPage(std::ostream &out) {
    string program_name = ProgramName();
    boost::replace_all(program_name, "_", "\\_");
        out << boost::format(globals::tex::section) %  program_name;
        out << boost::format(globals::tex::label) % ProgramName();
        std::stringstream ss, os;
        HelpText(ss);
        out << boost::format(globals::tex::description) % ss.str();

       typedef std::vector<boost::shared_ptr<boost::program_options::option_description> >::const_iterator OptionsIterator;
       OptionsIterator it = _op_desc.options().begin(), it_end = _op_desc.options().end();
       while(it < it_end) {
            string format_name = (*it)->format_name() + " " + (*it)->format_parameter();
            boost::replace_all(format_name, "-", "{-}");
            os << boost::format(globals::tex::option) % format_name % (*it)->description();
            ++it;
        }
        out << boost::format(globals::tex::options) % os.str();
}

int Application::Exec(int argc, char **argv)
{
    try {
        //_continue_execution = true;
	AddProgramOptions()("help,h", "  display this help and exit");
	AddProgramOptions()("verbose,v", "  be loud and noisy");
	AddProgramOptions("Hidden")("man", "  output man-formatted manual pages");
	AddProgramOptions("Hidden")("tex", "  output tex-formatted manual pages");

	Initialize(); // initialize program-specific parameters

        ParseCommandLine(argc, argv); // initialize general parameters & read input file

        if (_op_vm.count("verbose")) {
	  globals::verbose = true;
        }

        if (_op_vm.count("man")) {
            ShowManPage(cout);
            return 0;
        }

        if (_op_vm.count("tex")) {
            ShowTEXPage(cout);
            return 0;
        }

        if (_op_vm.count("help")) {
            ShowHelpText(cout);
            return 0;
        }

        if(!EvaluateOptions()) {
            ShowHelpText(cout);
            return -1;
        }

        if(_continue_execution)
            Run();
	else cout << "nothing to be done - stopping here\n";
    }
    catch(std::exception &error) {
         cerr << "an error occurred:\n" << error.what() << endl;
         return -1;
    }
    return 0;
}

boost::program_options::options_description_easy_init
    Application::AddProgramOptions(const string &group)
{
    // if no group is given, add it to standard options
    if(group == "")
        return _op_desc.add_options();

    // does group already exist, if yes, add it there
    std::map<string, boost::program_options::options_description>::iterator iter;
    iter = _op_groups.find(group);
    if(iter!=_op_groups.end())
        return iter->second.add_options();

    // no group with given name was found -> create group
    _op_groups.insert(make_pair(group, boost::program_options::options_description(group)));

    return _op_groups[group].add_options();
}

void Application::ParseCommandLine(int argc, char **argv)
{
    namespace po = boost::program_options;

    std::map<string, boost::program_options::options_description>::iterator iter;

    // default options should be added to visible (the rest is handled via a map))
    _visible_options.add(_op_desc);

    // add all categories to list of available options
    for(iter=_op_groups.begin(); iter!=_op_groups.end(); ++iter) {
        _op_desc.add(iter->second);
        if ( iter->first != "Hidden" ) _visible_options.add(iter->second);
    }

    // parse the command line
    try {
        po::store(po::parse_command_line(argc, argv, _op_desc), _op_vm);
        po::notify(_op_vm);
    }
    catch(boost::program_options::error& err) {
        throw runtime_error(string("error parsing command line: ") + err.what());
    }
}

void Application::CheckRequired(const string &option_name, const string &error_msg)
{
    if(!_op_vm.count(option_name)) {
        ShowHelpText(cout);
        throw std::runtime_error("missing argument " + option_name + "\n" + error_msg);
    }
}

void Application::PrintDescription(std::ostream &out, const string &calculator_name, const string help_path, HelpType help_type )
{
    boost::format _format("%|3t|%1% %|20t|%2% \n");
    string help_string;
    boost::filesystem::path arg_path;
    Property options;
    string xmlFile = (arg_path / string(getenv("VOTCASHARE")) / help_path / (boost::format("%1%.%2%") % calculator_name % "xml").str()).string().c_str();

    // loading the documentation xml file from VOTCASHARE
    char *votca_share = getenv("VOTCASHARE");
    if(votca_share == NULL) throw std::runtime_error("VOTCASHARE not set, cannot open help files.");

    try {

                load_property_from_xml(options, xmlFile);
                Property &calculator_options = options.get("options." + calculator_name);
                Property::AttributeIterator atr_it = calculator_options.findAttribute("help");

                if (atr_it != calculator_options.lastAttribute()) {
                    help_string = (*atr_it).second;
                } else {
                    if (tools::globals::verbose) out << _format % calculator_name % "Undocumented";
                    return;
                }

                switch (help_type) {
                    default:
                        break;
                    case HelpShort: // short description of the calculator
                        out << _format % calculator_name % help_string;
                        break;
                    case HelpLong:
                        votca::tools::PropertyIOManipulator iom(votca::tools::PropertyIOManipulator::HLP, 2, "");
                        out << iom << options;
                        break;
                }

            } catch (std::exception &error) {
                if (tools::globals::verbose) out << _format % calculator_name % "Undocumented";
            }

}

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

#include <iostream>
#include <votca/tools/application.h>
#include <votca/tools/version.h>
#include <votca/tools/globals.h>
#include <votca/tools/propertyiomanipulator.h>

#include <boost/format.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>

namespace votca { namespace tools {
    using namespace std;
Application::Application()
    : _op_desc("Allowed options"), _continue_execution(true)
{
}

Application::~Application()
{
}

string Application::VersionString()
{
    return "";
}

void Application::ShowHelpText(std::ostream &out)
{
    out << "==================================================\n";
    out << "========   VOTCA (http://www.votca.org)   ========\n";
    out << "==================================================\n\n";

    out << "please submit bugs to bugs@votca.org\n\n";
    out << ProgramName();
    if(VersionString() != "")
        out << ", version " << VersionString();
    out << endl
        << "votca_tools, version " << ToolsVersionStr()
        << "\n\n";

    HelpText(out);

    // remove Hidden group from the option list and print
    out << "\n\n" << VisibleOptions() << endl;

    //out << "\n\n" << OptionsDesc() << endl;
}

void Application::ShowManPage(std::ostream &out) {

        out << boost::format(globals::man::header) %  ProgramName() % VersionString();
        out << boost::format(globals::man::name) % ProgramName() % globals::url;
        out << boost::format(globals::man::synopsis) % ProgramName();
        std::stringstream ss;
        HelpText(ss);
        out << boost::format(globals::man::description) % ss.str();
        out << boost::format(globals::man::options);

        typedef std::vector<boost::shared_ptr<boost::program_options::option_description> >::const_iterator OptionsIterator;
        OptionsIterator it = _op_desc.options().begin(), it_end = _op_desc.options().end();

        while(it < it_end) {
            string format_name = (*it)->format_name() + " " + (*it)->format_parameter();
            boost::replace_all(format_name, "-", "\\-");
            out << boost::format(globals::man::option) % format_name % (*it)->description();
            ++it;
        }

        out << boost::format(globals::man::authors) % globals::email;
        out << boost::format(globals::man::copyright) % globals::url;

}

void Application::ShowTEXPage(std::ostream &out) {
    string program_name = ProgramName();
    boost::replace_all(program_name, "_", "\\_");
        out << boost::format(globals::tex::section) %  program_name;
        out << boost::format(globals::tex::label) % ProgramName();
        std::stringstream ss, os;
        HelpText(ss);
        out << boost::format(globals::tex::description) % ss.str();

       typedef std::vector<boost::shared_ptr<boost::program_options::option_description> >::const_iterator OptionsIterator;
       OptionsIterator it = _op_desc.options().begin(), it_end = _op_desc.options().end();
       while(it < it_end) {
            string format_name = (*it)->format_name() + " " + (*it)->format_parameter();
            boost::replace_all(format_name, "-", "{-}");
            os << boost::format(globals::tex::option) % format_name % (*it)->description();
            ++it;
        }
        out << boost::format(globals::tex::options) % os.str();
}

int Application::Exec(int argc, char **argv)
{
    try {
        //_continue_execution = true;
	AddProgramOptions()("help,h", "  display this help and exit");
	AddProgramOptions()("verbose,v", "  be loud and noisy");
	AddProgramOptions("Hidden")("man", "  output man-formatted manual pages");
	AddProgramOptions("Hidden")("tex", "  output tex-formatted manual pages");

	Initialize(); // initialize program-specific parameters

        ParseCommandLine(argc, argv); // initialize general parameters & read input file

        if (_op_vm.count("verbose")) {
	  globals::verbose = true;
        }

        if (_op_vm.count("man")) {
            ShowManPage(cout);
            return 0;
        }

        if (_op_vm.count("tex")) {
            ShowTEXPage(cout);
            return 0;
        }

        if (_op_vm.count("help")) {
            ShowHelpText(cout);
            return 0;
        }

        if(!EvaluateOptions()) {
            ShowHelpText(cout);
            return -1;
        }

        if(_continue_execution)
            Run();
	else cout << "nothing to be done - stopping here\n";
    }
    catch(std::exception &error) {
         cerr << "an error occurred:\n" << error.what() << endl;
         return -1;
    }
    return 0;
}

boost::program_options::options_description_easy_init
    Application::AddProgramOptions(const string &group)
{
    // if no group is given, add it to standard options
    if(group == "")
        return _op_desc.add_options();

    // does group already exist, if yes, add it there
    std::map<string, boost::program_options::options_description>::iterator iter;
    iter = _op_groups.find(group);
    if(iter!=_op_groups.end())
        return iter->second.add_options();

    // no group with given name was found -> create group
    _op_groups.insert(make_pair(group, boost::program_options::options_description(group)));

    return _op_groups[group].add_options();
}

void Application::ParseCommandLine(int argc, char **argv)
{
    namespace po = boost::program_options;

    std::map<string, boost::program_options::options_description>::iterator iter;

    // default options should be added to visible (the rest is handled via a map))
    _visible_options.add(_op_desc);

    // add all categories to list of available options
    for(iter=_op_groups.begin(); iter!=_op_groups.end(); ++iter) {
        _op_desc.add(iter->second);
        if ( iter->first != "Hidden" ) _visible_options.add(iter->second);
    }

    // parse the command line
    try {
        po::store(po::parse_command_line(argc, argv, _op_desc), _op_vm);
        po::notify(_op_vm);
    }
    catch(boost::program_options::error& err) {
        throw runtime_error(string("error parsing command line: ") + err.what());
    }
}

void Application::CheckRequired(const string &option_name, const string &error_msg)
{
    if(!_op_vm.count(option_name)) {
        ShowHelpText(cout);
        throw std::runtime_error("missing argument " + option_name + "\n" + error_msg);
    }
}

void Application::PrintDescription(std::ostream &out, const string &calculator_name, const string help_path, HelpType help_type )
{
    boost::format _format("%|3t|%1% %|20t|%2% \n");
    string help_string;
    boost::filesystem::path arg_path;
    Property options;
   // loading the documentation xml file from VOTCASHARE
    char *votca_share = getenv("VOTCASHARE");
    if(votca_share == NULL) throw std::runtime_error("VOTCASHARE not set, cannot open help files.");
    string xmlFile = (arg_path / string(getenv("VOTCASHARE")) / help_path / (boost::format("%1%.%2%") % calculator_name % "xml").str()).string().c_str();

    try {

                load_property_from_xml(options, xmlFile);
                Property &calculator_options = options.get("options." + calculator_name);
                Property::AttributeIterator atr_it = calculator_options.findAttribute("help");

                if (atr_it != calculator_options.lastAttribute()) {
                    help_string = (*atr_it).second;
                } else {
                    if (tools::globals::verbose) out << _format % calculator_name % "Undocumented";
                    return;
                }

                switch (help_type) {
                    default:
                        break;
                    case HelpShort: // short description of the calculator
                        out << _format % calculator_name % help_string;
                        break;
                    case HelpLong:
                        votca::tools::PropertyIOManipulator iom(votca::tools::PropertyIOManipulator::HLP, 2, "");
                        out << iom << options;
                        break;
                }

            } catch (std::exception &error) {
                if (tools::globals::verbose) out << _format % calculator_name % "Undocumented";
            }

}

}}
<|endoftext|>


<commit_before>//
//  ParametricLink.cpp
//  NetworkSimulator
//
//  Created by Tommi Gröhn on 18.11.2015.
//  Copyright (c) 2015 tommigrohn. All rights reserved.
//

#include <sstream>

#include "ParametricLink.h"

ParametricLink::ParametricLink() {
    previousTime = 0.0;
    packetToTransitTime = 0.0;
    logging = true;
}

ParametricLink::ParametricLink(double transmissionSpeed, double propagationDelay) {
    this->transmissionSpeed = transmissionSpeed;    // interval
    this->propagationDelay = propagationDelay;      // transmission time per packet
    previousTime = 0.0;
    packetToTransitTime = 0.0;
    logging = true;
}

void ParametricLink::run(double currentTime) {
    double timeDelta = currentTime - previousTime;
    previousTime = currentTime;
    std::stringstream ss;

    // waiting time until next packet will be picked for transmission
    if (!packetsWaiting.empty()) packetToTransitTime -= timeDelta;

    // add packets to transmission if there is some waiting...
    if (packetToTransitTime <= 0.0 && !packetsWaiting.empty()) {
            // debug output
            std::cout << "Added to transmission..." << std::endl;

            auto it = packetsWaiting.begin();
            // packet size determines total duration of transmission
            packetsInTransmission.insert({*it, propagationDelay});
            packetsWaiting.erase(it);

            // reset waiting time (proportional to the size of added packet)
            packetToTransitTime = transmissionSpeed * (*it)->getSize();
    }

    // handle packets being transmitted
    for (auto it = packetsInTransmission.begin(); it != packetsInTransmission.end();) {
        it->second -= timeDelta;

        // if transmission time has passed...
        if (it->second <= 0.0) {
            // deliver it to destination node
            destination->receivePacket(it->first);

            // add packet to transmission log {packetId, deliveryTime}
            if (logging) transmittedPackets.push_back({it->first->getID(), currentTime});

            // debug output
            std::cout
            << "Parametric link "
            << source->getAddress() << "-"
            << destination->getAddress() << " forwarded "
            << it->first->getData() << " to node "
            << destination->getAddress() << std::endl;

            it = packetsInTransmission.erase(it);
        } else {
            // debugging helper stringstream, format [packetData, timeToDelivery]
            ss << "[" << it->first->getData() << ", " << it->second << "]";

            it++;
        }
    }

    // debug output
    if (!packetsInTransmission.empty()) {
        std::cout
            << ss.str()
            << " in transmission on parametric link "
            << source->getAddress() << "-"
            << destination->getAddress()
            << std::endl;
    }
}
<commit_msg>Fixed packet transmission time calculation<commit_after>//
//  ParametricLink.cpp
//  NetworkSimulator
//
//  Created by Tommi Gröhn on 18.11.2015.
//  Copyright (c) 2015 tommigrohn. All rights reserved.
//

#include <sstream>

#include "ParametricLink.h"

ParametricLink::ParametricLink() {
    previousTime = 0.0;
    packetToTransitTime = 0.0;
    logging = true;
}

ParametricLink::ParametricLink(double transmissionSpeed, double propagationDelay) {
    this->transmissionSpeed = transmissionSpeed;    // interval
    this->propagationDelay = propagationDelay;      // transmission time per packet
    previousTime = 0.0;
    packetToTransitTime = 0.0;
    logging = true;
}

void ParametricLink::run(double currentTime) {
    double timeDelta = currentTime - previousTime;
    previousTime = currentTime;
    std::stringstream ss;

    // waiting time until next packet will be picked for transmission
    if (!packetsWaiting.empty()) packetToTransitTime -= timeDelta;

    // add packets to transmission if there is some waiting...
    if (packetToTransitTime <= 0.0 && !packetsWaiting.empty()) {
            // debug output
            std::cout << "Added to transmission..." << std::endl;

            auto it = packetsWaiting.begin();
            // packet size determines total duration of transmission
            packetsInTransmission.insert({*it, propagationDelay});
            packetsWaiting.erase(it);

            // reset waiting time (proportional to the size of added packet)
            // "time to transmit a packet == packet size / link speed"
            packetToTransitTime = (*it)->getSize() / transmissionSpeed;
    }

    // handle packets being transmitted
    for (auto it = packetsInTransmission.begin(); it != packetsInTransmission.end();) {
        it->second -= timeDelta;

        // if transmission time has passed...
        if (it->second <= 0.0) {
            // deliver it to destination node
            destination->receivePacket(it->first);

            // add packet to transmission log {packetId, deliveryTime}
            if (logging) transmittedPackets.push_back({it->first->getID(), currentTime});

            // debug output
            std::cout
            << "Parametric link "
            << source->getAddress() << "-"
            << destination->getAddress() << " forwarded "
            << it->first->getData() << " to node "
            << destination->getAddress() << std::endl;

            it = packetsInTransmission.erase(it);
        } else {
            // debugging helper stringstream, format [packetData, timeToDelivery]
            ss << "[" << it->first->getData() << ", " << it->second << "]";

            it++;
        }
    }

    // debug output
    if (!packetsInTransmission.empty()) {
        std::cout
            << ss.str()
            << " in transmission on parametric link "
            << source->getAddress() << "-"
            << destination->getAddress()
            << std::endl;
    }
}
<|endoftext|>