<commit_before>//===- Signals.cpp - Signal Handling support ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
// Unix signals occuring while your program is running.
//
//===----------------------------------------------------------------------===//

#include "Support/Signals.h"
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <signal.h>
#include "Config/config.h"     // Get the signal handler return type
using namespace llvm;

static std::vector<std::string> FilesToRemove;

// IntSigs - Signals that may interrupt the program at any time.
static const int IntSigs[] = {
  SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
};
static const int *IntSigsEnd = IntSigs + sizeof(IntSigs)/sizeof(IntSigs[0]);

// KillSigs - Signals that are synchronous with the program that will cause it
// to die.
static const int KillSigs[] = {
  SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
#ifdef SIGEMT
  , SIGEMT
#endif
};
static const int *KillSigsEnd = KillSigs + sizeof(KillSigs)/sizeof(KillSigs[0]);

// SignalHandler - The signal handler that runs...
static RETSIGTYPE SignalHandler(int Sig) {
  while (!FilesToRemove.empty()) {
    std::remove(FilesToRemove.back().c_str());
    FilesToRemove.pop_back();
  }

  if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd)
    exit(1);   // If this is an interrupt signal, exit the program

  // Otherwise if it is a fault (like SEGV) reissue the signal to die...
  signal(Sig, SIG_DFL);
}

static void RegisterHandler(int Signal) { signal(Signal, SignalHandler); }

// RemoveFileOnSignal - The public API
void llvm::RemoveFileOnSignal(const std::string &Filename) {
  FilesToRemove.push_back(Filename);

  std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
  std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
}
<commit_msg>Print stacktrace in STDERR before dying on a fatal signal. Currently the symbols are not demangled.<commit_after>//===- Signals.cpp - Signal Handling support ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
// Unix signals occuring while your program is running.
//
//===----------------------------------------------------------------------===//

#include "Support/Signals.h"
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <execinfo.h>
#include <signal.h>
#include <unistd.h>
#include "Config/config.h"     // Get the signal handler return type
using namespace llvm;

static std::vector<std::string> FilesToRemove;

// IntSigs - Signals that may interrupt the program at any time.
static const int IntSigs[] = {
  SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
};
static const int *IntSigsEnd = IntSigs + sizeof(IntSigs)/sizeof(IntSigs[0]);

// KillSigs - Signals that are synchronous with the program that will cause it
// to die.
static const int KillSigs[] = {
  SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
#ifdef SIGEMT
  , SIGEMT
#endif
};
static const int *KillSigsEnd = KillSigs + sizeof(KillSigs)/sizeof(KillSigs[0]);

static void* StackTrace[256];

// SignalHandler - The signal handler that runs...
static RETSIGTYPE SignalHandler(int Sig) {
  while (!FilesToRemove.empty()) {
    std::remove(FilesToRemove.back().c_str());
    FilesToRemove.pop_back();
  }

  if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd)
    exit(1);   // If this is an interrupt signal, exit the program

  // Otherwise if it is a fault (like SEGV) output the stacktrace to
  // STDERR and reissue the signal to die...
  int depth = backtrace(StackTrace, sizeof(StackTrace)/sizeof(StackTrace[0]));
  backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
  signal(Sig, SIG_DFL);
}

static void RegisterHandler(int Signal) { signal(Signal, SignalHandler); }

// RemoveFileOnSignal - The public API
void llvm::RemoveFileOnSignal(const std::string &Filename) {
  FilesToRemove.push_back(Filename);

  std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
  std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <array>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <functional>
#include <algorithm>
#include "Vipper/Vipper.h"
#include <Modules/TitleScreen/View/CRect.h>

#include "Modules/Gameplay/Entities/CLevel.h"
#include "Modules/Gameplay/Entities/CGameSession.h"
#include "Modules/Gameplay/View/CGameplayView.h"

namespace RunTheWorld {

    Vec2 project(Vec3 v, Vec3 camera) {
        float xz = (v.x - camera.x) / (1.0f - v.z + camera.z);
        float yz = (v.y - camera.y) / (1.0f - v.z + camera.z);

        Vec2 v2(320 + (xz * 640), 240 - (yz * 480));
        return v2;
    }

    void CGameplayView::drawBackdropForHeading(int modulus, int zone  ) {
        getRenderer()->drawBitmapAt( -640 + modulus, 0, 640, 480, mBackdrop[ zone ] );
        getRenderer()->drawBitmapAt( modulus, 0, 640, 480, mBackdrop[ zone ] );
    }

	CGameplayView::CGameplayView(std::shared_ptr<CGameSession> session, std::shared_ptr<Vipper::IRenderer> renderer) : IView( renderer ), mGameSession( session ) {

        mBackdrop[0] = renderer->loadBitmap( "res/1.png" );
        mBackdrop[1] = renderer->loadBitmap( "res/2.png" );
        mBackdrop[2] = renderer->loadBitmap( "res/1.png" );

        mCar[0][0] = renderer->loadBitmap( "res/big0.png" );
        mCar[1][0] = renderer->loadBitmap( "res/big1.png" );
        mCar[2][0] = renderer->loadBitmap( "res/big2.png" );

        mCar[0][1] = renderer->loadBitmap( "res/med0.png" );
        mCar[1][1] = renderer->loadBitmap( "res/med1.png" );
        mCar[2][1] = renderer->loadBitmap( "res/med2.png" );

        mCar[0][2] = renderer->loadBitmap( "res/small0.png" );
        mCar[1][2] = renderer->loadBitmap( "res/small1.png" );
        mCar[2][2] = renderer->loadBitmap( "res/small2.png" );

        mSmoke = renderer->loadBitmap( "res/smoke.png" );

		mHitSound = renderer->loadSound( "res/hit.wav" );
        mBrakeSound = renderer->loadSound( "res/brake.wav" );
        mAccelerateSound = renderer->loadSound( "res/accel.wav" );

        mUIFont = renderer->loadFont( "res/albaregular.ttf", 15 );
	}

    void CGameplayView::drawTextAt( std::pair<int, int> position, std::string text ) {
		auto renderer = getRenderer();
		renderer->drawTextAt( position.first, position.second, text, {0xFF, 0xFF, 0x00, 0xFF }, mUIFont  );
	}

    void CGameplayView::drawGaugeAt( std::pair<int, int> position, int howFilled) {
		auto renderer = getRenderer();
		renderer->drawSquare(position.first, position.second, 100, position.second + 20, {0,0,255,255});
		renderer->drawSquare(position.first, position.second, howFilled, position.second + 20, {255,0,0,255});
	}

    void CGameplayView::show() {
        auto game = this->mGameSession->getLevel();

		auto renderer = getRenderer();
		renderer->drawSquare( 0, 0, 640 - 64, 480, {0,0,0,255} );

                int numberOfStripeShades = 4;
                float completelyArbitraryCurveEasingFactor = 100.0f;
                int shapeDelta = 0;
                float roadWidth = 1.0f;
                char shape = game->track[game->elementIndex];
                char slope = game->slopes[game->elementIndex];
                auto camera = Vec3( 0.5f * (game->x)/ 640.0f, 0.2f, 0.1f * ( game->carSpeed / 50.0f ) );

                if (shape == ')') {
                    shapeDelta = -1;
                }

                if (shape == '(') {
                    shapeDelta = 1;
                }

                float slopeDelta = 0;

                if (slope == '/') {
                    slopeDelta = 1;
                }

                if (slope == '\\') {
                    slopeDelta = -1;
                }

                int distanceToCurrentShape = 0;

                if (game->distanceToNextElement > (CLevel::kSegmentLengthInMeters/2)) {
                    distanceToCurrentShape = (CLevel::kSegmentLengthInMeters - game->distanceToNextElement);
                } else {
                    distanceToCurrentShape = (game->distanceToNextElement);
                }

                int halfScreenHeight = 480 / 2;

                auto slopeAddedLines = ( 2 * CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta  );

                int modulus = static_cast<int>(game->mHeading * 640) % 640;

                while ( modulus < 0 ) {
                    modulus += 640;
                }

                drawBackdropForHeading( modulus, game->zone );

                int shadingStripesCount = 0;
                for (int y = 0; y < halfScreenHeight + slopeAddedLines + 1; ++y ) {
                    auto line = ( halfScreenHeight - slopeAddedLines ) + y;

                    int shade[3] = {0, 64, 0};
                    renderer->fill( 0, 640, line, 0, 640, line + 1, shade );
                }

                Vec2 previousLeft(-1, -1);
                Vec2 previousRight(-1, -1);

                shadingStripesCount = 0;

                float initialSlope = CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/ static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta;
                float currentStripeHeight = initialSlope;
                float stripeHeightDelta =  (-initialSlope) / 480.0f;

                for (float y = halfScreenHeight; y > -1; y -= (0.5f )) {
                    shadingStripesCount = ( shadingStripesCount + 1) % 1024;

                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y)) * stripeHeightDelta );

                    float curve = (distanceToCurrentShape / static_cast<float>(CLevel::kSegmentLengthInMeters)) * shapeDelta * y * y / completelyArbitraryCurveEasingFactor;
                    auto leftPoint = project(Vec3(-( roadWidth / 2.0f ) + curve, -0.5f + currentStripeHeight, -y), camera);
                    auto rightPoint = project(Vec3( (roadWidth / 2.0f ) + curve, -0.5f + currentStripeHeight, -y), camera);

                    //if it's valid
                    if ( previousLeft.y < 0 ) {
                        previousLeft = leftPoint;
                        previousRight = rightPoint;
                    }

                    int count = (- shadingStripesCount + static_cast<long>(game->distanceRan) ) % numberOfStripeShades;
                    int shade[3] = {255 * ( count + 10 ) / 20, 255 * ( count + 10 ) / 20, 255 * ( count + 10 ) / 20 };
                    renderer->fill( leftPoint.x, rightPoint.x, leftPoint.y, previousLeft.x, previousRight.x, previousLeft.y, shade );

                    previousLeft = leftPoint;
                    previousRight = rightPoint;
                }

                initialSlope = CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/ static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta;
                stripeHeightDelta =  (-initialSlope) / 480.0f;

                auto cars = game->getCarsAhead(1024);
                auto playerLane = (game->x)/640.0f;

                for ( auto foe : cars ) {
                    auto y = std::get<0>(foe) - game->distanceRan;
                    float curve = (distanceToCurrentShape / static_cast<float>(CLevel::kSegmentLengthInMeters)) * shapeDelta * y * y / completelyArbitraryCurveEasingFactor;

                    auto lane = std::get<1>(foe);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y + 1)) * stripeHeightDelta );
                    auto carProjection0 = project( Vec3( curve + lane - 0.2f, -1.0f + currentStripeHeight, -y + 0), camera);
                    auto carProjection1 = project( Vec3( curve + lane + 0.2f, -1.0f + currentStripeHeight, -y + 0), camera);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y - 1)) * stripeHeightDelta );
                    auto carProjection2 = project( Vec3( curve + lane - 0.2f, -1.0f + currentStripeHeight, -y - 1), camera);
                    auto carProjection3 = project( Vec3( curve + lane + 0.2f, -1.0f + currentStripeHeight, -y - 1), camera);

                    int carSprite = (lane + 0.5) + 1;
                    int carSize = 0;

                    int sizeX = 32;
                    int sizeY = 8;

                    if ( y <= 5 ) {
                        carSize = 0;
                        sizeX = 128;
                        sizeY = 64;
                    } else if ( 5 <= y && y <= 25 ) {
                        carSize = 1;
                        sizeX = 64;
                        sizeY = 32;
                    } else if ( 25 <= y && y <= 75 ) {
                        carSize = 2;
                        sizeX = 32;
                        sizeY = 16;
                    } else {
                        continue;
                    }

                    int black[3] = {0,0,0};
                    auto centerX = carProjection0.x + ((carProjection1.x - carProjection0.x) / 2);
                    auto centerY = carProjection0.y + ((carProjection2.y - carProjection0.y) / 2);
                    renderer->drawBitmapAt(centerX - (sizeX/2), centerY - (sizeY/2), sizeX, sizeY, mCar[carSprite][carSize]);
                }

                {
                    auto lane = (game->x) / 640.0f;
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight -4.1)) * stripeHeightDelta );
                    auto carProjection2 = project(Vec3(lane -0.2f, -1.0f + currentStripeHeight, -2 -1.1), camera);
                    auto carProjection3 = project(Vec3(lane +0.2f, -1.0f + currentStripeHeight, -2 -1.1), camera);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight -2.1)) * stripeHeightDelta );
                    auto carProjection0 = project(Vec3(lane -0.2f, -1.0f + currentStripeHeight, -2 -0.1), camera);
                    auto carProjection1 = project(Vec3(lane +0.2f, -1.0f + currentStripeHeight, -2 -0.1), camera);

                    int black[3] = {0,0,0};
                    auto centerX = carProjection0.x + ((carProjection1.x - carProjection0.x) / 2);
                    auto centerY = carProjection0.y + ((carProjection2.y - carProjection0.y) / 2);
                    int carSprite = (lane + 0.5) + 1;
                    renderer->drawBitmapAt(centerX - 64, centerY - 32, 128, 32, mCar[carSprite][0]);

                    if (game->smoking) {
                        renderer->drawBitmapAt(centerX - 64, carProjection0.y, 100, 33, mSmoke);
                    }
                }

        if ( game->hit ) {
            renderer->playSound( mHitSound );
            game->hit = false;
        }

        if ( game->brake ) {
            renderer->playSound( mBrakeSound );
            game->brake = false;
        }

        if ( game->accel ) {
            renderer->playSound( mAccelerateSound );
            game->accel = false;
        }
    }

	void CGameplayView::onClick( std::pair<int, int> position ) {
	}

	void CGameplayView::onKeyUp( Vipper::ECommand keyCode ) {
        this->mGameSession->getLevel()->onKeyUp(keyCode);
	}

    void CGameplayView::onKeyDown( Vipper::ECommand keyCode ) {
        this->mGameSession->getLevel()->onKeyDown(keyCode);
    }
}
<commit_msg>Undo using the Lisbon background as Rio<commit_after>#include <iostream>
#include <array>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <functional>
#include <algorithm>
#include "Vipper/Vipper.h"
#include <Modules/TitleScreen/View/CRect.h>

#include "Modules/Gameplay/Entities/CLevel.h"
#include "Modules/Gameplay/Entities/CGameSession.h"
#include "Modules/Gameplay/View/CGameplayView.h"

namespace RunTheWorld {

    Vec2 project(Vec3 v, Vec3 camera) {
        float xz = (v.x - camera.x) / (1.0f - v.z + camera.z);
        float yz = (v.y - camera.y) / (1.0f - v.z + camera.z);

        Vec2 v2(320 + (xz * 640), 240 - (yz * 480));
        return v2;
    }

    void CGameplayView::drawBackdropForHeading(int modulus, int zone  ) {
        getRenderer()->drawBitmapAt( -640 + modulus, 0, 640, 480, mBackdrop[ zone ] );
        getRenderer()->drawBitmapAt( modulus, 0, 640, 480, mBackdrop[ zone ] );
    }

	CGameplayView::CGameplayView(std::shared_ptr<CGameSession> session, std::shared_ptr<Vipper::IRenderer> renderer) : IView( renderer ), mGameSession( session ) {

        mBackdrop[0] = renderer->loadBitmap( "res/3.png" );
        mBackdrop[1] = renderer->loadBitmap( "res/2.png" );
        mBackdrop[2] = renderer->loadBitmap( "res/1.png" );

        mCar[0][0] = renderer->loadBitmap( "res/big0.png" );
        mCar[1][0] = renderer->loadBitmap( "res/big1.png" );
        mCar[2][0] = renderer->loadBitmap( "res/big2.png" );

        mCar[0][1] = renderer->loadBitmap( "res/med0.png" );
        mCar[1][1] = renderer->loadBitmap( "res/med1.png" );
        mCar[2][1] = renderer->loadBitmap( "res/med2.png" );

        mCar[0][2] = renderer->loadBitmap( "res/small0.png" );
        mCar[1][2] = renderer->loadBitmap( "res/small1.png" );
        mCar[2][2] = renderer->loadBitmap( "res/small2.png" );

        mSmoke = renderer->loadBitmap( "res/smoke.png" );

		mHitSound = renderer->loadSound( "res/hit.wav" );
        mBrakeSound = renderer->loadSound( "res/brake.wav" );
        mAccelerateSound = renderer->loadSound( "res/accel.wav" );

        mUIFont = renderer->loadFont( "res/albaregular.ttf", 15 );
	}

    void CGameplayView::drawTextAt( std::pair<int, int> position, std::string text ) {
		auto renderer = getRenderer();
		renderer->drawTextAt( position.first, position.second, text, {0xFF, 0xFF, 0x00, 0xFF }, mUIFont  );
	}

    void CGameplayView::drawGaugeAt( std::pair<int, int> position, int howFilled) {
		auto renderer = getRenderer();
		renderer->drawSquare(position.first, position.second, 100, position.second + 20, {0,0,255,255});
		renderer->drawSquare(position.first, position.second, howFilled, position.second + 20, {255,0,0,255});
	}

    void CGameplayView::show() {
        auto game = this->mGameSession->getLevel();

		auto renderer = getRenderer();
		renderer->drawSquare( 0, 0, 640 - 64, 480, {0,0,0,255} );

                int numberOfStripeShades = 4;
                float completelyArbitraryCurveEasingFactor = 100.0f;
                int shapeDelta = 0;
                float roadWidth = 1.0f;
                char shape = game->track[game->elementIndex];
                char slope = game->slopes[game->elementIndex];
                auto camera = Vec3( 0.5f * (game->x)/ 640.0f, 0.2f, 0.1f * ( game->carSpeed / 50.0f ) );

                if (shape == ')') {
                    shapeDelta = -1;
                }

                if (shape == '(') {
                    shapeDelta = 1;
                }

                float slopeDelta = 0;

                if (slope == '/') {
                    slopeDelta = 1;
                }

                if (slope == '\\') {
                    slopeDelta = -1;
                }

                int distanceToCurrentShape = 0;

                if (game->distanceToNextElement > (CLevel::kSegmentLengthInMeters/2)) {
                    distanceToCurrentShape = (CLevel::kSegmentLengthInMeters - game->distanceToNextElement);
                } else {
                    distanceToCurrentShape = (game->distanceToNextElement);
                }

                int halfScreenHeight = 480 / 2;

                auto slopeAddedLines = ( 2 * CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta  );

                int modulus = static_cast<int>(game->mHeading * 640) % 640;

                while ( modulus < 0 ) {
                    modulus += 640;
                }

                drawBackdropForHeading( modulus, game->zone );

                int shadingStripesCount = 0;
                for (int y = 0; y < halfScreenHeight + slopeAddedLines + 1; ++y ) {
                    auto line = ( halfScreenHeight - slopeAddedLines ) + y;

                    int shade[3] = {0, 64, 0};
                    renderer->fill( 0, 640, line, 0, 640, line + 1, shade );
                }

                Vec2 previousLeft(-1, -1);
                Vec2 previousRight(-1, -1);

                shadingStripesCount = 0;

                float initialSlope = CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/ static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta;
                float currentStripeHeight = initialSlope;
                float stripeHeightDelta =  (-initialSlope) / 480.0f;

                for (float y = halfScreenHeight; y > -1; y -= (0.5f )) {
                    shadingStripesCount = ( shadingStripesCount + 1) % 1024;

                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y)) * stripeHeightDelta );

                    float curve = (distanceToCurrentShape / static_cast<float>(CLevel::kSegmentLengthInMeters)) * shapeDelta * y * y / completelyArbitraryCurveEasingFactor;
                    auto leftPoint = project(Vec3(-( roadWidth / 2.0f ) + curve, -0.5f + currentStripeHeight, -y), camera);
                    auto rightPoint = project(Vec3( (roadWidth / 2.0f ) + curve, -0.5f + currentStripeHeight, -y), camera);

                    //if it's valid
                    if ( previousLeft.y < 0 ) {
                        previousLeft = leftPoint;
                        previousRight = rightPoint;
                    }

                    int count = (- shadingStripesCount + static_cast<long>(game->distanceRan) ) % numberOfStripeShades;
                    int shade[3] = {255 * ( count + 10 ) / 20, 255 * ( count + 10 ) / 20, 255 * ( count + 10 ) / 20 };
                    renderer->fill( leftPoint.x, rightPoint.x, leftPoint.y, previousLeft.x, previousRight.x, previousLeft.y, shade );

                    previousLeft = leftPoint;
                    previousRight = rightPoint;
                }

                initialSlope = CLevel::kSlopeHeightInMeters * (distanceToCurrentShape/ static_cast<float>(CLevel::kSegmentLengthInMeters)) * slopeDelta;
                stripeHeightDelta =  (-initialSlope) / 480.0f;

                auto cars = game->getCarsAhead(1024);
                auto playerLane = (game->x)/640.0f;

                for ( auto foe : cars ) {
                    auto y = std::get<0>(foe) - game->distanceRan;
                    float curve = (distanceToCurrentShape / static_cast<float>(CLevel::kSegmentLengthInMeters)) * shapeDelta * y * y / completelyArbitraryCurveEasingFactor;

                    auto lane = std::get<1>(foe);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y + 1)) * stripeHeightDelta );
                    auto carProjection0 = project( Vec3( curve + lane - 0.2f, -1.0f + currentStripeHeight, -y + 0), camera);
                    auto carProjection1 = project( Vec3( curve + lane + 0.2f, -1.0f + currentStripeHeight, -y + 0), camera);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight - y - 1)) * stripeHeightDelta );
                    auto carProjection2 = project( Vec3( curve + lane - 0.2f, -1.0f + currentStripeHeight, -y - 1), camera);
                    auto carProjection3 = project( Vec3( curve + lane + 0.2f, -1.0f + currentStripeHeight, -y - 1), camera);

                    int carSprite = (lane + 0.5) + 1;
                    int carSize = 0;

                    int sizeX = 32;
                    int sizeY = 8;

                    if ( y <= 5 ) {
                        carSize = 0;
                        sizeX = 128;
                        sizeY = 64;
                    } else if ( 5 <= y && y <= 25 ) {
                        carSize = 1;
                        sizeX = 64;
                        sizeY = 32;
                    } else if ( 25 <= y && y <= 75 ) {
                        carSize = 2;
                        sizeX = 32;
                        sizeY = 16;
                    } else {
                        continue;
                    }

                    int black[3] = {0,0,0};
                    auto centerX = carProjection0.x + ((carProjection1.x - carProjection0.x) / 2);
                    auto centerY = carProjection0.y + ((carProjection2.y - carProjection0.y) / 2);
                    renderer->drawBitmapAt(centerX - (sizeX/2), centerY - (sizeY/2), sizeX, sizeY, mCar[carSprite][carSize]);
                }

                {
                    auto lane = (game->x) / 640.0f;
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight -4.1)) * stripeHeightDelta );
                    auto carProjection2 = project(Vec3(lane -0.2f, -1.0f + currentStripeHeight, -2 -1.1), camera);
                    auto carProjection3 = project(Vec3(lane +0.2f, -1.0f + currentStripeHeight, -2 -1.1), camera);
                    currentStripeHeight = initialSlope + ( (2.0f * (halfScreenHeight -2.1)) * stripeHeightDelta );
                    auto carProjection0 = project(Vec3(lane -0.2f, -1.0f + currentStripeHeight, -2 -0.1), camera);
                    auto carProjection1 = project(Vec3(lane +0.2f, -1.0f + currentStripeHeight, -2 -0.1), camera);

                    int black[3] = {0,0,0};
                    auto centerX = carProjection0.x + ((carProjection1.x - carProjection0.x) / 2);
                    auto centerY = carProjection0.y + ((carProjection2.y - carProjection0.y) / 2);
                    int carSprite = (lane + 0.5) + 1;
                    renderer->drawBitmapAt(centerX - 64, centerY - 32, 128, 32, mCar[carSprite][0]);

                    if (game->smoking) {
                        renderer->drawBitmapAt(centerX - 64, carProjection0.y, 100, 33, mSmoke);
                    }
                }

        if ( game->hit ) {
            renderer->playSound( mHitSound );
            game->hit = false;
        }

        if ( game->brake ) {
            renderer->playSound( mBrakeSound );
            game->brake = false;
        }

        if ( game->accel ) {
            renderer->playSound( mAccelerateSound );
            game->accel = false;
        }
    }

	void CGameplayView::onClick( std::pair<int, int> position ) {
	}

	void CGameplayView::onKeyUp( Vipper::ECommand keyCode ) {
        this->mGameSession->getLevel()->onKeyUp(keyCode);
	}

    void CGameplayView::onKeyDown( Vipper::ECommand keyCode ) {
        this->mGameSession->getLevel()->onKeyDown(keyCode);
    }
}
<|endoftext|>


<commit_before>//===-- Function.cpp - Implement the Global object classes ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Function & GlobalVariable classes for the VMCore
// library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/Intrinsics.h"
#include "Support/LeakDetector.h"
#include "SymbolTableListTraitsImpl.h"
using namespace llvm;

BasicBlock *ilist_traits<BasicBlock>::createNode() {
  BasicBlock *Ret = new BasicBlock();
  // This should not be garbage monitored.
  LeakDetector::removeGarbageObject(Ret);
  return Ret;
}

iplist<BasicBlock> &ilist_traits<BasicBlock>::getList(Function *F) {
  return F->getBasicBlockList();
}

Argument *ilist_traits<Argument>::createNode() {
  Argument *Ret = new Argument(Type::IntTy);
  // This should not be garbage monitored.
  LeakDetector::removeGarbageObject(Ret);
  return Ret;
}

iplist<Argument> &ilist_traits<Argument>::getList(Function *F) {
  return F->getArgumentList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template class SymbolTableListTraits<Argument, Function, Function>;
template class SymbolTableListTraits<BasicBlock, Function, Function>;

//===----------------------------------------------------------------------===//
// Argument Implementation
//===----------------------------------------------------------------------===//

Argument::Argument(const Type *Ty, const std::string &Name, Function *Par)
  : Value(Ty, Value::ArgumentVal, Name) {
  Parent = 0;

  // Make sure that we get added to a function
  LeakDetector::addGarbageObject(this);

  if (Par)
    Par->getArgumentList().push_back(this);
}

// Specialize setName to take care of symbol table majik
void Argument::setName(const std::string &name, SymbolTable *ST) {
  Function *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable().insert(this);
}

void Argument::setParent(Function *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

//===----------------------------------------------------------------------===//
// Function Implementation
//===----------------------------------------------------------------------===//

Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
                   const std::string &name, Module *ParentModule)
  : GlobalValue(PointerType::get(Ty), Value::FunctionVal, Linkage, name) {
  BasicBlocks.setItemParent(this);
  BasicBlocks.setParent(this);
  ArgumentList.setItemParent(this);
  ArgumentList.setParent(this);
  SymTab = new SymbolTable();

  assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy)
         && "LLVM functions cannot return aggregate values!");

  // Create the arguments vector, all arguments start out unnamed.
  for (unsigned i = 0, e = Ty->getNumParams(); i != e; ++i) {
    assert(Ty->getParamType(i) != Type::VoidTy &&
           "Cannot have void typed arguments!");
    ArgumentList.push_back(new Argument(Ty->getParamType(i)));
  }

  // Make sure that we get added to a function
  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getFunctionList().push_back(this);
}

Function::~Function() {
  dropAllReferences();    // After this it is safe to delete instructions.

  // Delete all of the method arguments and unlink from symbol table...
  ArgumentList.clear();
  ArgumentList.setParent(0);
  delete SymTab;
}

// Specialize setName to take care of symbol table majik
void Function::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && getName() != "") P->getSymbolTable().insert(this);
}

void Function::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

const FunctionType *Function::getFunctionType() const {
  return cast<FunctionType>(getType()->getElementType());
}

const Type *Function::getReturnType() const {
  return getFunctionType()->getReturnType();
}

// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is deleted for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator
// delete.
//
void Function::dropAllReferences() {
  for (iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();
  BasicBlocks.clear();    // Delete all basic blocks...
}

/// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an
/// intrinsic, or if the pointer is null.  This value is always defined to be
/// zero to allow easy checking for whether a function is intrinsic or not.  The
/// particular intrinsic functions which correspond to this value are defined in
/// llvm/Intrinsics.h.
///
unsigned Function::getIntrinsicID() const {
  if (getName().size() < 5 || getName()[4] != '.' || getName()[0] != 'l' ||
      getName()[1] != 'l' || getName()[2] != 'v' || getName()[3] != 'm')
    return 0;  // All intrinsics start with 'llvm.'

  assert(getName().size() != 5 && "'llvm.' is an invalid intrinsic name!");

  // a table of all Alpha intrinsic functions
  struct {
   std::string name;  // The name of the intrinsic
   unsigned id;       // Its ID number
  } alpha_intrinsics[] = {
     { "llvm.alpha.ctlz",      Intrinsic::alpha_ctlz },
     { "llvm.alpha.cttz",      Intrinsic::alpha_cttz },
     { "llvm.alpha.ctpop",     Intrinsic::alpha_ctpop },
     { "llvm.alpha.umulh",     Intrinsic::alpha_umulh },
     { "llvm.alpha.vecop",     Intrinsic::alpha_vecop },
     { "llvm.alpha.pup",       Intrinsic::alpha_pup },
     { "llvm.alpha.bytezap",   Intrinsic::alpha_bytezap },
     { "llvm.alpha.bytemanip", Intrinsic::alpha_bytemanip },
     { "llvm.alpha.dfp_bop",   Intrinsic::alpha_dfpbop },
     { "llvm.alpha.dfp_uop",   Intrinsic::alpha_dfpuop },
     { "llvm.alpha.unordered", Intrinsic::alpha_unordered },
     { "llvm.alpha.uqtodfp",   Intrinsic::alpha_uqtodfp },
     { "llvm.alpha.uqtosfp",   Intrinsic::alpha_uqtosfp },
     { "llvm.alpha.dfptosq",   Intrinsic::alpha_dfptosq },
     { "llvm.alpha.sfptosq",   Intrinsic::alpha_sfptosq },
  };
  const unsigned num_alpha_intrinsics =
                 sizeof(alpha_intrinsics) / sizeof(*alpha_intrinsics);

  switch (getName()[5]) {
  case 'a':
    if (getName().size() > 11 &&
        std::string(getName().begin()+4, getName().begin()+11) == ".alpha.")
      for (unsigned i = 0; i < num_alpha_intrinsics; ++i)
        if (getName() == alpha_intrinsics[i].name)
          return alpha_intrinsics[i].id;
    break;
  case 'd':
    if (getName() == "llvm.dbg.stoppoint")   return Intrinsic::dbg_stoppoint;
    if (getName() == "llvm.dbg.region.start")return Intrinsic::dbg_region_start;
    if (getName() == "llvm.dbg.region.end")  return Intrinsic::dbg_region_end;
    if (getName() == "llvm.dbg.func.start")  return Intrinsic::dbg_func_start;
    if (getName() == "llvm.dbg.declare")     return Intrinsic::dbg_declare;
    break;
  case 'l':
    if (getName() == "llvm.longjmp")  return Intrinsic::longjmp;
    break;
  case 's':
    if (getName() == "llvm.setjmp")     return Intrinsic::setjmp;
    if (getName() == "llvm.sigsetjmp")  return Intrinsic::sigsetjmp;
    if (getName() == "llvm.siglongjmp") return Intrinsic::siglongjmp;
    break;
  case 'v':
    if (getName() == "llvm.va_copy")  return Intrinsic::va_copy;
    if (getName() == "llvm.va_end")   return Intrinsic::va_end;
    if (getName() == "llvm.va_start") return Intrinsic::va_start;
    break;
  }
  // The "llvm." namespace is reserved!
  assert(0 && "Unknown LLVM intrinsic function!");
  return 0;
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
			       Constant *Initializer,
			       const std::string &Name, Module *ParentModule)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Link, Name),
    isConstantGlobal(constant) {
  if (Initializer) Operands.push_back(Use((Value*)Initializer, this));

  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getGlobalList().push_back(this);
}

void GlobalVariable::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

// Specialize setName to take care of symbol table majik
void GlobalVariable::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable().insert(this);
}
<commit_msg>Hrm, another minor cleanup, which I missed before<commit_after>//===-- Function.cpp - Implement the Global object classes ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Function & GlobalVariable classes for the VMCore
// library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/Intrinsics.h"
#include "Support/LeakDetector.h"
#include "SymbolTableListTraitsImpl.h"
using namespace llvm;

BasicBlock *ilist_traits<BasicBlock>::createNode() {
  BasicBlock *Ret = new BasicBlock();
  // This should not be garbage monitored.
  LeakDetector::removeGarbageObject(Ret);
  return Ret;
}

iplist<BasicBlock> &ilist_traits<BasicBlock>::getList(Function *F) {
  return F->getBasicBlockList();
}

Argument *ilist_traits<Argument>::createNode() {
  Argument *Ret = new Argument(Type::IntTy);
  // This should not be garbage monitored.
  LeakDetector::removeGarbageObject(Ret);
  return Ret;
}

iplist<Argument> &ilist_traits<Argument>::getList(Function *F) {
  return F->getArgumentList();
}

// Explicit instantiations of SymbolTableListTraits since some of the methods
// are not in the public header file...
template class SymbolTableListTraits<Argument, Function, Function>;
template class SymbolTableListTraits<BasicBlock, Function, Function>;

//===----------------------------------------------------------------------===//
// Argument Implementation
//===----------------------------------------------------------------------===//

Argument::Argument(const Type *Ty, const std::string &Name, Function *Par)
  : Value(Ty, Value::ArgumentVal, Name) {
  Parent = 0;

  // Make sure that we get added to a function
  LeakDetector::addGarbageObject(this);

  if (Par)
    Par->getArgumentList().push_back(this);
}

// Specialize setName to take care of symbol table majik
void Argument::setName(const std::string &name, SymbolTable *ST) {
  Function *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable().insert(this);
}

void Argument::setParent(Function *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

//===----------------------------------------------------------------------===//
// Function Implementation
//===----------------------------------------------------------------------===//

Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
                   const std::string &name, Module *ParentModule)
  : GlobalValue(PointerType::get(Ty), Value::FunctionVal, Linkage, name) {
  BasicBlocks.setItemParent(this);
  BasicBlocks.setParent(this);
  ArgumentList.setItemParent(this);
  ArgumentList.setParent(this);
  SymTab = new SymbolTable();

  assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy)
         && "LLVM functions cannot return aggregate values!");

  // Create the arguments vector, all arguments start out unnamed.
  for (unsigned i = 0, e = Ty->getNumParams(); i != e; ++i) {
    assert(Ty->getParamType(i) != Type::VoidTy &&
           "Cannot have void typed arguments!");
    ArgumentList.push_back(new Argument(Ty->getParamType(i)));
  }

  // Make sure that we get added to a function
  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getFunctionList().push_back(this);
}

Function::~Function() {
  dropAllReferences();    // After this it is safe to delete instructions.

  // Delete all of the method arguments and unlink from symbol table...
  ArgumentList.clear();
  ArgumentList.setParent(0);
  delete SymTab;
}

// Specialize setName to take care of symbol table majik
void Function::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable().insert(this);
}

void Function::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

const FunctionType *Function::getFunctionType() const {
  return cast<FunctionType>(getType()->getElementType());
}

const Type *Function::getReturnType() const {
  return getFunctionType()->getReturnType();
}

// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining.  This allows one to
// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to
// zero.  Then everything is deleted for real.  Note that no operations are
// valid on an object that has "dropped all references", except operator
// delete.
//
void Function::dropAllReferences() {
  for (iterator I = begin(), E = end(); I != E; ++I)
    I->dropAllReferences();
  BasicBlocks.clear();    // Delete all basic blocks...
}

/// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an
/// intrinsic, or if the pointer is null.  This value is always defined to be
/// zero to allow easy checking for whether a function is intrinsic or not.  The
/// particular intrinsic functions which correspond to this value are defined in
/// llvm/Intrinsics.h.
///
unsigned Function::getIntrinsicID() const {
  if (getName().size() < 5 || getName()[4] != '.' || getName()[0] != 'l' ||
      getName()[1] != 'l' || getName()[2] != 'v' || getName()[3] != 'm')
    return 0;  // All intrinsics start with 'llvm.'

  assert(getName().size() != 5 && "'llvm.' is an invalid intrinsic name!");

  // a table of all Alpha intrinsic functions
  struct {
   std::string name;  // The name of the intrinsic
   unsigned id;       // Its ID number
  } alpha_intrinsics[] = {
     { "llvm.alpha.ctlz",      Intrinsic::alpha_ctlz },
     { "llvm.alpha.cttz",      Intrinsic::alpha_cttz },
     { "llvm.alpha.ctpop",     Intrinsic::alpha_ctpop },
     { "llvm.alpha.umulh",     Intrinsic::alpha_umulh },
     { "llvm.alpha.vecop",     Intrinsic::alpha_vecop },
     { "llvm.alpha.pup",       Intrinsic::alpha_pup },
     { "llvm.alpha.bytezap",   Intrinsic::alpha_bytezap },
     { "llvm.alpha.bytemanip", Intrinsic::alpha_bytemanip },
     { "llvm.alpha.dfp_bop",   Intrinsic::alpha_dfpbop },
     { "llvm.alpha.dfp_uop",   Intrinsic::alpha_dfpuop },
     { "llvm.alpha.unordered", Intrinsic::alpha_unordered },
     { "llvm.alpha.uqtodfp",   Intrinsic::alpha_uqtodfp },
     { "llvm.alpha.uqtosfp",   Intrinsic::alpha_uqtosfp },
     { "llvm.alpha.dfptosq",   Intrinsic::alpha_dfptosq },
     { "llvm.alpha.sfptosq",   Intrinsic::alpha_sfptosq },
  };
  const unsigned num_alpha_intrinsics =
                 sizeof(alpha_intrinsics) / sizeof(*alpha_intrinsics);

  switch (getName()[5]) {
  case 'a':
    if (getName().size() > 11 &&
        std::string(getName().begin()+4, getName().begin()+11) == ".alpha.")
      for (unsigned i = 0; i < num_alpha_intrinsics; ++i)
        if (getName() == alpha_intrinsics[i].name)
          return alpha_intrinsics[i].id;
    break;
  case 'd':
    if (getName() == "llvm.dbg.stoppoint")   return Intrinsic::dbg_stoppoint;
    if (getName() == "llvm.dbg.region.start")return Intrinsic::dbg_region_start;
    if (getName() == "llvm.dbg.region.end")  return Intrinsic::dbg_region_end;
    if (getName() == "llvm.dbg.func.start")  return Intrinsic::dbg_func_start;
    if (getName() == "llvm.dbg.declare")     return Intrinsic::dbg_declare;
    break;
  case 'l':
    if (getName() == "llvm.longjmp")  return Intrinsic::longjmp;
    break;
  case 's':
    if (getName() == "llvm.setjmp")     return Intrinsic::setjmp;
    if (getName() == "llvm.sigsetjmp")  return Intrinsic::sigsetjmp;
    if (getName() == "llvm.siglongjmp") return Intrinsic::siglongjmp;
    break;
  case 'v':
    if (getName() == "llvm.va_copy")  return Intrinsic::va_copy;
    if (getName() == "llvm.va_end")   return Intrinsic::va_end;
    if (getName() == "llvm.va_start") return Intrinsic::va_start;
    break;
  }
  // The "llvm." namespace is reserved!
  assert(0 && "Unknown LLVM intrinsic function!");
  return 0;
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(const Type *Ty, bool constant, LinkageTypes Link,
			       Constant *Initializer,
			       const std::string &Name, Module *ParentModule)
  : GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Link, Name),
    isConstantGlobal(constant) {
  if (Initializer) Operands.push_back(Use((Value*)Initializer, this));

  LeakDetector::addGarbageObject(this);

  if (ParentModule)
    ParentModule->getGlobalList().push_back(this);
}

void GlobalVariable::setParent(Module *parent) {
  if (getParent())
    LeakDetector::addGarbageObject(this);
  Parent = parent;
  if (getParent())
    LeakDetector::removeGarbageObject(this);
}

// Specialize setName to take care of symbol table majik
void GlobalVariable::setName(const std::string &name, SymbolTable *ST) {
  Module *P;
  assert((ST == 0 || (!getParent() || ST == &getParent()->getSymbolTable())) &&
	 "Invalid symtab argument!");
  if ((P = getParent()) && hasName()) P->getSymbolTable().remove(this);
  Value::setName(name);
  if (P && hasName()) P->getSymbolTable().insert(this);
}
<|endoftext|>


<commit_before>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
    Copyright (c) 2004 Daniel Molkentin <molkentin@kde.org>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kolabwizard.h"
#include "kolabconfig.h"

#include "kmailchanges.h"

#include <libkcal/resourcecalendar.h>
#include <kabc/resource.h>

#include "kresources/imap/kcal/resourceimap.h"
#include "kresources/imap/kabc/resourceimap.h"
#include "kresources/imap/knotes/resourceimap.h"

#include <qwhatsthis.h>
#include <klineedit.h>
#include <klocale.h>

#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>

class SetupLDAPSearchAccount : public KConfigPropagator::Change
{
  public:
    SetupLDAPSearchAccount()
      : KConfigPropagator::Change( i18n("Setup LDAP Search Account") )
    {
    }

    void apply()
    {
      QString host = KolabConfig::self()->server();
      QString basedn = host;
      basedn.replace(".",",dc=");
      basedn.prepend("dc=");

      KConfig c( "kabldaprc" );
      c.setGroup( "LDAP" );
      bool hasMyServer = false;
      uint selHosts = c.readNumEntry("NumSelectedHosts", 0);
      for ( uint i = 0 ; i < selHosts && !hasMyServer; ++i )
        if ( c.readEntry( QString("SelectedHost%1").arg(i) ) == host )
          hasMyServer = true;
      if ( !hasMyServer ) {
        c.writeEntry( "NumSelectedHosts", selHosts + 1 );
        c.writeEntry( QString("SelectedHost%1").arg(selHosts), host);
        c.writeEntry( QString("SelectedBase%1").arg(selHosts), basedn);
        c.writeEntry( QString("SelectedPort%1").arg(selHosts), "389");
      }
    }

};

class CreateCalendarImapResource : public KConfigPropagator::Change
{
  public:
    CreateCalendarImapResource()
      : KConfigPropagator::Change( i18n("Create Calendar IMAP Resource") )
    {
    }

    void apply()
    {
      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      QString server = KolabConfig::self()->server();
      KCal::ResourceIMAP *r = new KCal::ResourceIMAP( server );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }
};

class CreateContactImapResource : public KConfigPropagator::Change
{
  public:
    CreateContactImapResource()
      : KConfigPropagator::Change( i18n("Create Contact IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<KABC::Resource> m( "contact" );
      m.readConfig();
      KABC::ResourceIMAP *r = new KABC::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class CreateNotesImapResource : public KConfigPropagator::Change
{
  public:
    CreateNotesImapResource()
      : KConfigPropagator::Change( i18n("Create Notes IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<ResourceNotes> m( "notes" );
      m.readConfig();
      KNotesIMAP::ResourceIMAP *r = new KNotesIMAP::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class KolabPropagator : public KConfigPropagator
{
  public:
    KolabPropagator()
      : KConfigPropagator( KolabConfig::self(), "kolab.kcfg" )
    {
    }

  protected:
    void addCustomChanges( Change::List &changes )
    {
      QString freeBusyBaseUrl = "webdavs://" + KolabConfig::self()->server() +
                                "/freebusy/";

      ChangeConfig *c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyPublishUrl";
      c->label = "";

      QString user = KolabConfig::self()->user();
      int pos = user.find( "@" );
      if ( pos > 0 ) user = user.left( pos );

      c->value = freeBusyBaseUrl + user + ".ifb";

      changes.append( c );

      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyRetrieveUrl";
      c->value = freeBusyBaseUrl;

      // KMail cruft has been outsourced
      createKMailChanges( changes );

      changes.append( c );
      changes.append( new SetupLDAPSearchAccount );

      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      KCal::CalendarResourceManager::Iterator it;
      for ( it = m.begin(); it != m.end(); ++it ) {
        if ( (*it)->type() == "imap" ) break;
      }
      if ( it == m.end() ) {
        changes.append( new CreateCalendarImapResource );
        changes.append( new CreateContactImapResource );
        changes.append( new CreateNotesImapResource );
      }
    }
};

KolabWizard::KolabWizard() : KConfigWizard( new KolabPropagator )
{
  QFrame *page = createWizardPage( i18n("Kolab Server") );

  QGridLayout *topLayout = new QGridLayout( page );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("Server name:"), page );
  topLayout->addWidget( label, 0, 0 );
  mServerEdit = new KLineEdit( page );
  topLayout->addWidget( mServerEdit, 0, 1 );

  label = new QLabel( i18n("Kolab user name:"), page );
  topLayout->addWidget( label, 1, 0 );
  mUserEdit = new KLineEdit( page );
  topLayout->addWidget( mUserEdit, 1, 1 );
  QWhatsThis::add(mUserEdit, i18n("Your Kolab Server user ID. "
                        "Format: name@server.domain.tld"));

  label = new QLabel( i18n("Real name:"), page );
  topLayout->addWidget( label, 2, 0 );
  mRealNameEdit = new KLineEdit( page );
  topLayout->addWidget( mRealNameEdit, 2, 1 );

  label = new QLabel( i18n("Password:"), page );
  topLayout->addWidget( label, 3, 0 );
  mPasswordEdit = new KLineEdit( page );
  mPasswordEdit->setEchoMode( KLineEdit::Password );
  topLayout->addWidget( mPasswordEdit, 3, 1 );

  mSavePasswordCheck = new QCheckBox( i18n("Save password"), page );
  topLayout->addMultiCellWidget( mSavePasswordCheck, 4, 4, 0, 1 );

  topLayout->setRowStretch( 4, 1 );

  setupRulesPage();
  setupChangesPage();

  setInitialSize( QSize( 600, 300 ) );
}

KolabWizard::~KolabWizard()
{
}

void KolabWizard::usrReadConfig()
{
  mServerEdit->setText( KolabConfig::self()->server() );
  mUserEdit->setText( KolabConfig::self()->user() );
  mRealNameEdit->setText( KolabConfig::self()->realName() );
  mPasswordEdit->setText( KolabConfig::self()->password() );
  mSavePasswordCheck->setChecked( KolabConfig::self()->savePassword() );
}

void KolabWizard::usrWriteConfig()
{
  KolabConfig::self()->setServer( mServerEdit->text() );
  KolabConfig::self()->setUser( mUserEdit->text() );
  KolabConfig::self()->setRealName( mRealNameEdit->text() );
  KolabConfig::self()->setPassword( mPasswordEdit->text() );
  KolabConfig::self()->setSavePassword( mSavePasswordCheck->isChecked() );
}
<commit_msg>https://intevation.de/roundup/kolab/issue258 4. "Use Groupware communication" in korganizer 5. "Use full email address for retrieval" of free/busy lists<commit_after>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
    Copyright (c) 2004 Daniel Molkentin <molkentin@kde.org>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kolabwizard.h"
#include "kolabconfig.h"

#include "kmailchanges.h"

#include <libkcal/resourcecalendar.h>
#include <kabc/resource.h>

#include "kresources/imap/kcal/resourceimap.h"
#include "kresources/imap/kabc/resourceimap.h"
#include "kresources/imap/knotes/resourceimap.h"

#include <qwhatsthis.h>
#include <klineedit.h>
#include <klocale.h>

#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>

class SetupLDAPSearchAccount : public KConfigPropagator::Change
{
  public:
    SetupLDAPSearchAccount()
      : KConfigPropagator::Change( i18n("Setup LDAP Search Account") )
    {
    }

    void apply()
    {
      QString host = KolabConfig::self()->server();
      QString basedn = host;
      basedn.replace(".",",dc=");
      basedn.prepend("dc=");

      KConfig c( "kabldaprc" );
      c.setGroup( "LDAP" );
      bool hasMyServer = false;
      uint selHosts = c.readNumEntry("NumSelectedHosts", 0);
      for ( uint i = 0 ; i < selHosts && !hasMyServer; ++i )
        if ( c.readEntry( QString("SelectedHost%1").arg(i) ) == host )
          hasMyServer = true;
      if ( !hasMyServer ) {
        c.writeEntry( "NumSelectedHosts", selHosts + 1 );
        c.writeEntry( QString("SelectedHost%1").arg(selHosts), host);
        c.writeEntry( QString("SelectedBase%1").arg(selHosts), basedn);
        c.writeEntry( QString("SelectedPort%1").arg(selHosts), "389");
      }
    }

};

class CreateCalendarImapResource : public KConfigPropagator::Change
{
  public:
    CreateCalendarImapResource()
      : KConfigPropagator::Change( i18n("Create Calendar IMAP Resource") )
    {
    }

    void apply()
    {
      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      QString server = KolabConfig::self()->server();
      KCal::ResourceIMAP *r = new KCal::ResourceIMAP( server );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }
};

class CreateContactImapResource : public KConfigPropagator::Change
{
  public:
    CreateContactImapResource()
      : KConfigPropagator::Change( i18n("Create Contact IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<KABC::Resource> m( "contact" );
      m.readConfig();
      KABC::ResourceIMAP *r = new KABC::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class CreateNotesImapResource : public KConfigPropagator::Change
{
  public:
    CreateNotesImapResource()
      : KConfigPropagator::Change( i18n("Create Notes IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<ResourceNotes> m( "notes" );
      m.readConfig();
      KNotesIMAP::ResourceIMAP *r = new KNotesIMAP::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class KolabPropagator : public KConfigPropagator
{
  public:
    KolabPropagator()
      : KConfigPropagator( KolabConfig::self(), "kolab.kcfg" )
    {
    }

  protected:
    void addKorganizerChanges( Change::List &changes )
    {
      QString freeBusyBaseUrl = "webdavs://" + KolabConfig::self()->server() +
                                "/freebusy/";

      ChangeConfig *c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyPublishUrl";
      c->label = "";

      QString user = KolabConfig::self()->user();
      int pos = user.find( "@" );
      if ( pos > 0 ) user = user.left( pos );

      c->value = freeBusyBaseUrl + user + ".ifb";

      changes.append( c );

      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";
      c->name = "FreeBusyRetrieveUrl";
      c->value = freeBusyBaseUrl;
      changes.append( c );

      // Use full email address for retrieval of free/busy lists
      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";
      c->name = "FreeBusyFullDomainRetrieval";
      c->value = "true";
      changes.append( c );

      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "Group Scheduling";
      c->name = "Use Groupware Communication";
      c->value = "true";
      changes.append( c );
    }

    virtual void addCustomChanges( Change::List &changes )
    {
      addKorganizerChanges( changes );

      // KMail cruft has been outsourced to kmailchanges.cpp
      createKMailChanges( changes );

      changes.append( new SetupLDAPSearchAccount );

      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      KCal::CalendarResourceManager::Iterator it;
      for ( it = m.begin(); it != m.end(); ++it ) {
        if ( (*it)->type() == "imap" ) break;
      }
      if ( it == m.end() ) {
        changes.append( new CreateCalendarImapResource );
        changes.append( new CreateContactImapResource );
        changes.append( new CreateNotesImapResource );
      }
    }
};

KolabWizard::KolabWizard() : KConfigWizard( new KolabPropagator )
{
  QFrame *page = createWizardPage( i18n("Kolab Server") );

  QGridLayout *topLayout = new QGridLayout( page );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("Server name:"), page );
  topLayout->addWidget( label, 0, 0 );
  mServerEdit = new KLineEdit( page );
  topLayout->addWidget( mServerEdit, 0, 1 );

  label = new QLabel( i18n("Kolab user name:"), page );
  topLayout->addWidget( label, 1, 0 );
  mUserEdit = new KLineEdit( page );
  topLayout->addWidget( mUserEdit, 1, 1 );
  QWhatsThis::add(mUserEdit, i18n("Your Kolab Server user ID. "
                        "Format: name@server.domain.tld"));

  label = new QLabel( i18n("Real name:"), page );
  topLayout->addWidget( label, 2, 0 );
  mRealNameEdit = new KLineEdit( page );
  topLayout->addWidget( mRealNameEdit, 2, 1 );

  label = new QLabel( i18n("Password:"), page );
  topLayout->addWidget( label, 3, 0 );
  mPasswordEdit = new KLineEdit( page );
  mPasswordEdit->setEchoMode( KLineEdit::Password );
  topLayout->addWidget( mPasswordEdit, 3, 1 );

  mSavePasswordCheck = new QCheckBox( i18n("Save password"), page );
  topLayout->addMultiCellWidget( mSavePasswordCheck, 4, 4, 0, 1 );

  topLayout->setRowStretch( 4, 1 );

  setupRulesPage();
  setupChangesPage();

  setInitialSize( QSize( 600, 300 ) );
}

KolabWizard::~KolabWizard()
{
}

void KolabWizard::usrReadConfig()
{
  mServerEdit->setText( KolabConfig::self()->server() );
  mUserEdit->setText( KolabConfig::self()->user() );
  mRealNameEdit->setText( KolabConfig::self()->realName() );
  mPasswordEdit->setText( KolabConfig::self()->password() );
  mSavePasswordCheck->setChecked( KolabConfig::self()->savePassword() );
}

void KolabWizard::usrWriteConfig()
{
  KolabConfig::self()->setServer( mServerEdit->text() );
  KolabConfig::self()->setUser( mUserEdit->text() );
  KolabConfig::self()->setRealName( mRealNameEdit->text() );
  KolabConfig::self()->setPassword( mPasswordEdit->text() );
  KolabConfig::self()->setSavePassword( mSavePasswordCheck->isChecked() );
}
<|endoftext|>


<commit_before>#ifndef NAMED_TYPE_HPP
#define NAMED_TYPE_HPP

#include <functional>
#include <ratio>
#include <type_traits>
#include "underlying_functionalities.hpp"

namespace fluent
{

template<typename T, T (*from)(T), T(*to)(T)>
struct Convert
{
    static T convertFrom(T t) { return from(t); }
    static T convertTo(T t) { return to(t); }
};

template<typename T>
using IsReference = typename std::enable_if<!std::is_reference<T>{}, void>::type;

template <typename T, typename Parameter, typename Converter, template<typename> class... Skills>
class NamedTypeImpl : public Skills<NamedTypeImpl<T, Parameter, Converter, Skills...>>...
{
public:
    using UnderlyingType = T;

    // constructor
    explicit NamedTypeImpl(T const& value) : value_(value) {}
    template<typename T_ = T, typename = IsReference<T_>>
    explicit NamedTypeImpl(T&& value) : value_(std::move(value)) {}

    // get
    T& get() { return value_; }
    T const& get() const {return value_; }

    // conversions
    template <typename Converter2>
    operator NamedTypeImpl<T, Parameter, Converter2, Skills...>() const
    {
        return NamedTypeImpl<T, Parameter, Converter2, Skills...>(Converter2::convertFrom(Converter::convertTo(get())));
    }

    struct conversions
    {
        template<T(*f)(T), T(*g)(T)>
        struct compose
        {
            static T func(T t) { return f(g(t)); }
        };
        template<typename Converter1, typename Converter2>
        using ComposeConverter = Convert<T, compose<Converter1::convertFrom, Converter2::convertFrom>::func, compose<Converter1::convertTo, Converter2::convertTo>::func>;
        template <typename Converter2>
        using GetConvertible = NamedTypeImpl<T, Parameter, ComposeConverter<Converter, Converter2>, Skills...>;
    };

private:
    T value_;
};

template <typename T, typename Parameter, template<typename> class... Skills>
using NamedType = NamedTypeImpl<T, Parameter, ConvertWithRatio<T, std::ratio<1>>, Skills...>;

template <typename StrongType, typename Ratio>
using MultipleOf = typename StrongType::conversions::template GetConvertible<ConvertWithRatio<typename StrongType::UnderlyingType, Ratio>>;

template <typename StrongType, typename Converter>
using ConvertibleTo = typename StrongType::conversions::template GetConvertible<Converter>;

template<template<typename T> class StrongType, typename T>
StrongType<T> make_named(T const& value)
{
    return StrongType<T>(value);
}

} // namespace fluent

#endif
<commit_msg>Fixed typo in IsNotReference<commit_after>#ifndef NAMED_TYPE_HPP
#define NAMED_TYPE_HPP

#include <functional>
#include <ratio>
#include <type_traits>
#include "underlying_functionalities.hpp"

namespace fluent
{

template<typename T, T (*from)(T), T(*to)(T)>
struct Convert
{
    static T convertFrom(T t) { return from(t); }
    static T convertTo(T t) { return to(t); }
};

template<typename T>
using IsNotReference = typename std::enable_if<!std::is_reference<T>::value, void>::type;

template <typename T, typename Parameter, typename Converter, template<typename> class... Skills>
class NamedTypeImpl : public Skills<NamedTypeImpl<T, Parameter, Converter, Skills...>>...
{
public:
    using UnderlyingType = T;

    // constructor
    explicit NamedTypeImpl(T const& value) : value_(value) {}
    template<typename T_ = T, typename = IsNotReference<T_>>
    explicit NamedTypeImpl(T&& value) : value_(std::move(value)) {}

    // get
    T& get() { return value_; }
    T const& get() const {return value_; }

    // conversions
    template <typename Converter2>
    operator NamedTypeImpl<T, Parameter, Converter2, Skills...>() const
    {
        return NamedTypeImpl<T, Parameter, Converter2, Skills...>(Converter2::convertFrom(Converter::convertTo(get())));
    }

    struct conversions
    {
        template<T(*f)(T), T(*g)(T)>
        struct compose
        {
            static T func(T t) { return f(g(t)); }
        };
        template<typename Converter1, typename Converter2>
        using ComposeConverter = Convert<T, compose<Converter1::convertFrom, Converter2::convertFrom>::func, compose<Converter1::convertTo, Converter2::convertTo>::func>;
        template <typename Converter2>
        using GetConvertible = NamedTypeImpl<T, Parameter, ComposeConverter<Converter, Converter2>, Skills...>;
    };

private:
    T value_;
};

template <typename T, typename Parameter, template<typename> class... Skills>
using NamedType = NamedTypeImpl<T, Parameter, ConvertWithRatio<T, std::ratio<1>>, Skills...>;

template <typename StrongType, typename Ratio>
using MultipleOf = typename StrongType::conversions::template GetConvertible<ConvertWithRatio<typename StrongType::UnderlyingType, Ratio>>;

template <typename StrongType, typename Converter>
using ConvertibleTo = typename StrongType::conversions::template GetConvertible<Converter>;

template<template<typename T> class StrongType, typename T>
StrongType<T> make_named(T const& value)
{
    return StrongType<T>(value);
}

} // namespace fluent

#endif
<|endoftext|>


<commit_before>#include "cvm.h"

static void _twrite(std::vector<byte> &out, const byte *data, size_t size)
{
    for (size_t i = 0; i < size; i++)
    {
        out.push_back(data[i]);
    }
}

template <typename T>
static void _twrite(std::vector<byte> &out, T value)
{
    _twrite(out, (const byte *)&value, sizeof(value));
}

template <typename T>
static void _twrite(std::vector<byte> &out, std::vector<T> value)
{
    for (const auto &item : value)
    {
        _twrite(out, item);
    }
}

enum
{
    TEMP_REGULAR         = 0,
    TEMP_FUNC_SECTION    = 1,
    TEMP_SYMBOLS_SECTION = 2,
    TEMP_SYMDATA_SECTION = 3,
};

void DabVM::dump_vm(FILE *out)
{
    BinHeader               dump_header;
    std::vector<BinSection> dump_sections = sections;
    std::vector<byte>       dump_data;

    dump_sections.erase(std::remove_if(dump_sections.begin(), dump_sections.end(),
                                       [](BinSection section) {
                                           std::string name = section.name;
                                           return name == "func" || name == "symb" ||
                                                  name == "symd";
                                       }),
                        dump_sections.end());

    BinSection func_section = {};
    memcpy(func_section.name, "func", 4);
    std::vector<BinFunction> dump_functions;
    for (auto it : functions)
    {
        if (!it.second.regular)
            continue;

        BinFunction bin_func;
        bin_func.symbol  = it.first;
        bin_func.klass   = -1;
        bin_func.address = it.second.address;
        dump_functions.push_back(bin_func);
    }
    func_section.special_index = TEMP_FUNC_SECTION;
    func_section.length        = dump_functions.size() * sizeof(BinFunction);

    BinSection symb_section;
    memcpy(symb_section.name, "symb", 4);

    BinSection symd_section;
    memcpy(symd_section.name, "symd", 4);

    std::vector<byte>     symd_data;
    std::vector<uint64_t> symb_data;
    for (auto sym : symbols)
    {
        auto pos = symd_data.size();
        symb_data.push_back(pos);
        for (char ch : sym)
        {
            symd_data.push_back(ch);
        }
        symd_data.push_back(0);
    }
    symb_section.special_index = TEMP_SYMBOLS_SECTION;
    symb_section.length        = symb_data.size() * sizeof(uint64_t);

    symd_section.special_index = TEMP_SYMDATA_SECTION;
    symd_section.length        = symd_data.size();

    dump_sections.push_back(symd_section);
    auto symd_section_index = dump_sections.size() - 1;
    dump_sections.push_back(symb_section);
    dump_sections.push_back(func_section);

    memcpy(dump_header.dab, "DAB\0", 4);
    dump_header.version        = 3;
    dump_header.offset         = 0;
    dump_header.section_count  = dump_sections.size();
    dump_header.size_of_header = sizeof(BinHeader) + dump_header.section_count * sizeof(BinSection);

    auto new_pos = dump_header.size_of_header;

    auto code_offset = new_pos - instructions.peek_header()->size_of_header;
    for (auto &func : dump_functions)
    {
        func.address += code_offset;
    }

    for (auto &section : dump_sections)
    {
        auto pos    = section.pos;
        auto length = section.length;

        section.pos = new_pos;

        if (section.special_index == TEMP_REGULAR)
        {
            auto ptr = instructions.raw_base_data() + pos;

            _twrite(dump_data, (byte *)ptr, length);
        }
        else if (section.special_index == TEMP_FUNC_SECTION)
        {
            _twrite(dump_data, dump_functions);
        }
        else if (section.special_index == TEMP_SYMDATA_SECTION)
        {
            _twrite(dump_data, symd_data);
        }
        else if (section.special_index == TEMP_SYMBOLS_SECTION)
        {
            for (auto &symb : symb_data)
            {
                symb += dump_sections[symd_section_index].pos;
            }
            _twrite(dump_data, symb_data);
        }

        section.special_index = 0;

        new_pos += length;
    }

    dump_header.size_of_data = dump_data.size();

    fwrite(&dump_header, sizeof(BinHeader), 1, out);
    for (auto &section : dump_sections)
    {
        fwrite(&section, sizeof(BinSection), 1, out);
    }
    fwrite(&dump_data[0], 1, dump_data.size(), out);
}
<commit_msg>vm: use DAB_CLASS_NIL<commit_after>#include "cvm.h"

static void _twrite(std::vector<byte> &out, const byte *data, size_t size)
{
    for (size_t i = 0; i < size; i++)
    {
        out.push_back(data[i]);
    }
}

template <typename T>
static void _twrite(std::vector<byte> &out, T value)
{
    _twrite(out, (const byte *)&value, sizeof(value));
}

template <typename T>
static void _twrite(std::vector<byte> &out, std::vector<T> value)
{
    for (const auto &item : value)
    {
        _twrite(out, item);
    }
}

enum
{
    TEMP_REGULAR         = 0,
    TEMP_FUNC_SECTION    = 1,
    TEMP_SYMBOLS_SECTION = 2,
    TEMP_SYMDATA_SECTION = 3,
};

void DabVM::dump_vm(FILE *out)
{
    BinHeader               dump_header;
    std::vector<BinSection> dump_sections = sections;
    std::vector<byte>       dump_data;

    dump_sections.erase(std::remove_if(dump_sections.begin(), dump_sections.end(),
                                       [](BinSection section) {
                                           std::string name = section.name;
                                           return name == "func" || name == "symb" ||
                                                  name == "symd";
                                       }),
                        dump_sections.end());

    BinSection func_section = {};
    memcpy(func_section.name, "func", 4);
    std::vector<BinFunction> dump_functions;
    for (auto it : functions)
    {
        if (!it.second.regular)
            continue;

        BinFunction bin_func;
        bin_func.symbol  = it.first;
        bin_func.klass   = DAB_CLASS_NIL;
        bin_func.address = it.second.address;
        dump_functions.push_back(bin_func);
    }
    func_section.special_index = TEMP_FUNC_SECTION;
    func_section.length        = dump_functions.size() * sizeof(BinFunction);

    BinSection symb_section;
    memcpy(symb_section.name, "symb", 4);

    BinSection symd_section;
    memcpy(symd_section.name, "symd", 4);

    std::vector<byte>     symd_data;
    std::vector<uint64_t> symb_data;
    for (auto sym : symbols)
    {
        auto pos = symd_data.size();
        symb_data.push_back(pos);
        for (char ch : sym)
        {
            symd_data.push_back(ch);
        }
        symd_data.push_back(0);
    }
    symb_section.special_index = TEMP_SYMBOLS_SECTION;
    symb_section.length        = symb_data.size() * sizeof(uint64_t);

    symd_section.special_index = TEMP_SYMDATA_SECTION;
    symd_section.length        = symd_data.size();

    dump_sections.push_back(symd_section);
    auto symd_section_index = dump_sections.size() - 1;
    dump_sections.push_back(symb_section);
    dump_sections.push_back(func_section);

    memcpy(dump_header.dab, "DAB\0", 4);
    dump_header.version        = 3;
    dump_header.offset         = 0;
    dump_header.section_count  = dump_sections.size();
    dump_header.size_of_header = sizeof(BinHeader) + dump_header.section_count * sizeof(BinSection);

    auto new_pos = dump_header.size_of_header;

    auto code_offset = new_pos - instructions.peek_header()->size_of_header;
    for (auto &func : dump_functions)
    {
        func.address += code_offset;
    }

    for (auto &section : dump_sections)
    {
        auto pos    = section.pos;
        auto length = section.length;

        section.pos = new_pos;

        if (section.special_index == TEMP_REGULAR)
        {
            auto ptr = instructions.raw_base_data() + pos;

            _twrite(dump_data, (byte *)ptr, length);
        }
        else if (section.special_index == TEMP_FUNC_SECTION)
        {
            _twrite(dump_data, dump_functions);
        }
        else if (section.special_index == TEMP_SYMDATA_SECTION)
        {
            _twrite(dump_data, symd_data);
        }
        else if (section.special_index == TEMP_SYMBOLS_SECTION)
        {
            for (auto &symb : symb_data)
            {
                symb += dump_sections[symd_section_index].pos;
            }
            _twrite(dump_data, symb_data);
        }

        section.special_index = 0;

        new_pos += length;
    }

    dump_header.size_of_data = dump_data.size();

    fwrite(&dump_header, sizeof(BinHeader), 1, out);
    for (auto &section : dump_sections)
    {
        fwrite(&section, sizeof(BinSection), 1, out);
    }
    fwrite(&dump_data[0], 1, dump_data.size(), out);
}
<|endoftext|>