<commit_before>/*
 *  Project:    moba-ambilight
 *
 *  Version:    1.0.0
 *
 *  Copyright (C) 2016 Stefan Paproth <pappi-@gmx.de>
 *
 *  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 Affero General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/agpl.txt>.
 *
 */

#include "handler.h"
#include <moba/log.h>
#include <wiringPi.h>
#include <string.h>
#include <sys/time.h>

const Bridge::BankColor Handler::bcolor[] = {
    Bridge::BLUE,
    Bridge::GREEN,
    Bridge::RED,
    Bridge::WHITE
};

Handler::Handler(
    boost::shared_ptr<Bridge> bridge,
    boost::shared_ptr<moba::IPC> ipc,
    boost::shared_ptr<moba::SignalHandler> sigTerm
) : ipc(ipc), bridge(bridge), sigTerm(sigTerm) {
    emergency   = false;
    halted      = false;
    interrupted = false;
}

void Handler::run() {

    int i = 0;
    fetchNextMsg();

/**7
     if(!buffer.getItemsCount()) {
        usleep(50000);
        //continue;
    }

    //TargetValues target = buffer.pop();
    TargetValues target;

 */

    do {
        delayMicroseconds(duration);
        for(int j = 0; j < 4; ++j) {
            if(!step[j] || i % step[j]) {
                continue;
            }
            if(step[j] > 0 && current.targetIntensity[j] < Handler::RANGE) {
                current.targetIntensity[j]++;
            }
            if(step[j] < 0 && current.targetIntensity[j] > 0) {
                current.targetIntensity[j]--;
            }
            bridge->setPWMlg(Handler::bcolor[j], current.targetIntensity[j]);
        }

        i = i++ % Handler::STEPS;

        if(i) {
            continue;
        }

    } while(true);
}

void Handler::setTargetValues(const TargetValues &newValues) {
    for(int i = 0; i < 4; ++i) {
        if(!duration || newValues.direkt) {
            current.targetIntensity[i] = newValues.targetIntensity[i];
            bridge->setPWMlg(Handler::bcolor[i], current.targetIntensity[i]);
        } else if(newValues.targetIntensity[i] - current.targetIntensity[i]) {
            step[i] = Handler::STEPS / (newValues.targetIntensity[i] - current.targetIntensity[i]);
        } else {
            step[i] = 0;
        }
    }
}

void Handler::test() {
    bridge->setPWMlg(Bridge::BLUE, 0);
    bridge->setPWMlg(Bridge::GREEN, 0);
    bridge->setPWMlg(Bridge::WHITE, 0);
    bridge->setPWMlg(Bridge::RED, 211);
    sleep(1);
    bridge->setPWMlg(Bridge::RED, 0);
    for(int i = 0; i < 4; ++i) {
        for(int j = 0; j < 4; ++j) {
            LOG(moba::DEBUG) << "bank: " << i << " color: " << bridge->getColorName(Handler::bcolor[j]) << std::endl;
            for(int k = 0; k < 2; ++k) {
                bridge->setData(Handler::bcolor[j], i, 0, 150);
                delay(500);
                bridge->setData(Handler::bcolor[j], i, 0, 600);
                delay(500);
            }
            bridge->setData(Handler::bcolor[j], i, 0, 0);
        }
    }
    bridge->setPWMlg(Bridge::GREEN, 211);
    sleep(1);
    bridge->setAllOff();
    sleep(1);
}

bool Handler::fetchNextMsg() {
    moba::IPC::Message msg;
    TargetValues tmpTarget;
    int tmpDuration;

    while(true) {
        if(sigTerm->hasAnySignalTriggered()) {
            throw HandlerException("sigterm caught");
        }

        if(!ipc->receive(msg)) {
            if(emergency || halted) {
                usleep(50000);
                continue;
            }
            return true;
        }

        switch(msg.mtype) {
            case moba::IPC::CMD_EMERGENCY_STOP: {
                LOG(moba::DEBUG) << "emergency..." << std::endl;
                if(emergency) {
                    LOG(moba::WARNING) << "emergency already set!" << std::endl;
                    break;
                }
                tmpTarget = current;
                tmpDuration = duration;
                duration = 5;
                TargetValues target = parseMessageData(msg.mtext);
                setTargetValues(target);
                emergency = true;
                break;
            }

            case moba::IPC::CMD_EMERGENCY_RELEASE: {
                LOG(moba::DEBUG) << "emergency... off" << std::endl;
                if(!emergency) {
                    LOG(moba::WARNING) << "emergency not set!" << std::endl;
                    break;
                }
                setTargetValues(tmpTarget);
                duration = tmpDuration;
                emergency = false;
                break;
            }

            case moba::IPC::CMD_HALT: {
                LOG(moba::DEBUG) << "halt..." << std::endl;
                if(halted) {
                    LOG(moba::WARNING) << "already halted!" << std::endl;
                }
                halted = true;
                break;
            }

            case moba::IPC::CMD_CONTINUE: {
                LOG(moba::DEBUG) << "continue..." << std::endl;
                if(!halted) {
                    LOG(moba::WARNING) << "halted not set!" << std::endl;
                }
                halted = false;
                break;
            }

            case moba::IPC::CMD_TEST: {
                LOG(moba::DEBUG) << "testing... " << std::endl;
                if(emergency || halted) {
                    LOG(moba::WARNING) << "no testing! Emergency or halted set" << std::endl;
                    break;
                }
                test();
                LOG(moba::DEBUG) << "testing... finished!" << std::endl;
                return true;
            }

            case moba::IPC::CMD_TERMINATE: {
                LOG(moba::DEBUG) << "terminate... " << std::endl;
                throw HandlerException("terminate received");
            }

            case moba::IPC::CMD_RESET: {
                LOG(moba::DEBUG) << "reset... " << std::endl;
                interruptBuffer.reset();
                regularBuffer.reset();
                emergency = false;
                halted = false;
                interrupted = false;
                bridge->setAllOff();
                // FIXME: delete Target ???
                break;
            }

            case moba::IPC::CMD_RUN: {
                LOG(moba::DEBUG) << "run... " << std::endl;
                regularBuffer.push(parseMessageData(msg.mtext));
                break;
            }

            case moba::IPC::CMD_INTERRUPT: {
                LOG(moba::DEBUG) << "interrupt... " << std::endl;
                interrupted = true;
                interruptBuffer.push(parseMessageData(msg.mtext));
                break;
            }

            case moba::IPC::CMD_RESUME: {
                LOG(moba::DEBUG) << "resume... " << std::endl;
                interruptBuffer.reset();
                interrupted = false;
                // TODO: goto default target
                break;
            }

            case moba::IPC::CMD_SET_DURATION: {
                LOG(moba::DEBUG) << "set duration... " << std::endl;
                duration = atoi(msg.mtext);
                LOG(moba::DEBUG) <<
                    "--> duration: ~" << duration <<
                    " sec. (~" << (int)(duration / 60) << " min.)" << std::endl;
                duration = static_cast<int>((duration * 1000 * 1000) / Handler::STEPS);
                break;
            }

            default:
                LOG(moba::WARNING) << "ignoring unknown message-type <" << msg.mtype << ">" << std::endl;
                break;
        }
        if(!emergency && !halted) {
            return true;
        }
    }
}

TargetValues Handler::parseMessageData(const std::string &data) {
    std::string::size_type pos = 0;
    std::string::size_type found = 0;

    TargetValues target;
    int val;

    for(int i = 0; i < 5; ++i) {
        found = data.find(';', pos);
        switch(i) {
            case Bridge::WHITE:
            case Bridge::GREEN:
            case Bridge::RED:
            case Bridge::BLUE:
                val = atoi(data.substr(pos, found - pos).c_str());
                if(val < 0) {
                    val = 0;
                }
                if(val > 4095) {
                    val = 4095;
                }
                target.targetIntensity[i] = val;
                break;

            case 5:
                switch(data.substr(pos, found - pos)[0]) {
                    case 'W':
                        target.wobble = true;
                        break;

                    case 'D':
                        target.direkt = true;
                        break;
                }
                break;
        }
        pos = found + 1;
    }
    LOG(moba::DEBUG) << "--> " << "inserting #" << target.getObjectId() << "..." << std::endl;
    LOG(moba::DEBUG) <<
            "--> targets" <<
            " white: " << target.targetIntensity[Bridge::WHITE] <<
            " green: " << target.targetIntensity[Bridge::GREEN] <<
            " red: " << target.targetIntensity[Bridge::RED] <<
            " blue: " << target.targetIntensity[Bridge::BLUE] << std::endl;
    LOG(moba::DEBUG) <<
            "--> wobble: " << (target.wobble ? "on" : "off") << std::endl;
    return target;
}
<commit_msg>make use of constants...<commit_after>/*
 *  Project:    moba-ambilight
 *
 *  Version:    1.0.0
 *
 *  Copyright (C) 2016 Stefan Paproth <pappi-@gmx.de>
 *
 *  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 Affero General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/agpl.txt>.
 *
 */

#include "handler.h"
#include <moba/log.h>
#include <wiringPi.h>
#include <string.h>
#include <sys/time.h>

const Bridge::BankColor Handler::bcolor[] = {
    Bridge::BLUE,
    Bridge::GREEN,
    Bridge::RED,
    Bridge::WHITE
};

Handler::Handler(
    boost::shared_ptr<Bridge> bridge,
    boost::shared_ptr<moba::IPC> ipc,
    boost::shared_ptr<moba::SignalHandler> sigTerm
) : ipc(ipc), bridge(bridge), sigTerm(sigTerm) {
    emergency   = false;
    halted      = false;
    interrupted = false;
}

void Handler::run() {

    int i = 0;
    fetchNextMsg();

/**7
     if(!buffer.getItemsCount()) {
        usleep(50000);
        //continue;
    }

    //TargetValues target = buffer.pop();
    TargetValues target;

 */

    do {
        delayMicroseconds(duration);
        for(int j = 0; j < 4; ++j) {
            if(!step[j] || i % step[j]) {
                continue;
            }
            if(step[j] > 0 && current.targetIntensity[j] < Handler::RANGE) {
                current.targetIntensity[j]++;
            }
            if(step[j] < 0 && current.targetIntensity[j] > 0) {
                current.targetIntensity[j]--;
            }
            bridge->setPWMlg(Handler::bcolor[j], current.targetIntensity[j]);
        }

        i = i++ % Handler::STEPS;

        if(i) {
            continue;
        }

    } while(true);
}

void Handler::setTargetValues(const TargetValues &newValues) {
    for(int i = 0; i < 4; ++i) {
        if(!duration || newValues.direkt) {
            current.targetIntensity[i] = newValues.targetIntensity[i];
            bridge->setPWMlg(Handler::bcolor[i], current.targetIntensity[i]);
        } else if(newValues.targetIntensity[i] - current.targetIntensity[i]) {
            step[i] = Handler::STEPS / (newValues.targetIntensity[i] - current.targetIntensity[i]);
        } else {
            step[i] = 0;
        }
    }
}

void Handler::test() {
    bridge->setPWMlg(Bridge::BLUE, 0);
    bridge->setPWMlg(Bridge::GREEN, 0);
    bridge->setPWMlg(Bridge::WHITE, 0);
    bridge->setPWMlg(Bridge::RED, 211);
    sleep(1);
    bridge->setPWMlg(Bridge::RED, 0);
    for(int i = 0; i < 4; ++i) {
        for(int j = 0; j < 4; ++j) {
            LOG(moba::DEBUG) << "bank: " << i << " color: " << bridge->getColorName(Handler::bcolor[j]) << std::endl;
            for(int k = 0; k < 2; ++k) {
                bridge->setData(Handler::bcolor[j], i, 0, 150);
                delay(500);
                bridge->setData(Handler::bcolor[j], i, 0, 600);
                delay(500);
            }
            bridge->setData(Handler::bcolor[j], i, 0, 0);
        }
    }
    bridge->setPWMlg(Bridge::GREEN, 211);
    sleep(1);
    bridge->setAllOff();
    sleep(1);
}

bool Handler::fetchNextMsg() {
    moba::IPC::Message msg;
    TargetValues tmpTarget;
    int tmpDuration;

    while(true) {
        if(sigTerm->hasAnySignalTriggered()) {
            throw HandlerException("sigterm caught");
        }

        if(!ipc->receive(msg)) {
            if(emergency || halted) {
                usleep(50000);
                continue;
            }
            return true;
        }

        switch(msg.mtype) {
            case moba::IPC::CMD_EMERGENCY_STOP: {
                LOG(moba::DEBUG) << "emergency..." << std::endl;
                if(emergency) {
                    LOG(moba::WARNING) << "emergency already set!" << std::endl;
                    break;
                }
                tmpTarget = current;
                tmpDuration = duration;
                duration = 5;
                TargetValues target = parseMessageData(msg.mtext);
                setTargetValues(target);
                emergency = true;
                break;
            }

            case moba::IPC::CMD_EMERGENCY_RELEASE: {
                LOG(moba::DEBUG) << "emergency... off" << std::endl;
                if(!emergency) {
                    LOG(moba::WARNING) << "emergency not set!" << std::endl;
                    break;
                }
                setTargetValues(tmpTarget);
                duration = tmpDuration;
                emergency = false;
                break;
            }

            case moba::IPC::CMD_HALT: {
                LOG(moba::DEBUG) << "halt..." << std::endl;
                if(halted) {
                    LOG(moba::WARNING) << "already halted!" << std::endl;
                }
                halted = true;
                break;
            }

            case moba::IPC::CMD_CONTINUE: {
                LOG(moba::DEBUG) << "continue..." << std::endl;
                if(!halted) {
                    LOG(moba::WARNING) << "halted not set!" << std::endl;
                }
                halted = false;
                break;
            }

            case moba::IPC::CMD_TEST: {
                LOG(moba::DEBUG) << "testing... " << std::endl;
                if(emergency || halted) {
                    LOG(moba::WARNING) << "no testing! Emergency or halted set" << std::endl;
                    break;
                }
                test();
                LOG(moba::DEBUG) << "testing... finished!" << std::endl;
                return true;
            }

            case moba::IPC::CMD_TERMINATE: {
                LOG(moba::DEBUG) << "terminate... " << std::endl;
                throw HandlerException("terminate received");
            }

            case moba::IPC::CMD_RESET: {
                LOG(moba::DEBUG) << "reset... " << std::endl;
                interruptBuffer.reset();
                regularBuffer.reset();
                emergency = false;
                halted = false;
                interrupted = false;
                bridge->setAllOff();
                // FIXME: delete Target ???
                break;
            }

            case moba::IPC::CMD_RUN: {
                LOG(moba::DEBUG) << "run... " << std::endl;
                regularBuffer.push(parseMessageData(msg.mtext));
                break;
            }

            case moba::IPC::CMD_INTERRUPT: {
                LOG(moba::DEBUG) << "interrupt... " << std::endl;
                interrupted = true;
                interruptBuffer.push(parseMessageData(msg.mtext));
                break;
            }

            case moba::IPC::CMD_RESUME: {
                LOG(moba::DEBUG) << "resume... " << std::endl;
                interruptBuffer.reset();
                interrupted = false;
                // TODO: goto default target
                break;
            }

            case moba::IPC::CMD_SET_DURATION: {
                LOG(moba::DEBUG) << "set duration... " << std::endl;
                duration = atoi(msg.mtext);
                LOG(moba::DEBUG) <<
                    "--> duration: ~" << duration <<
                    " sec. (~" << (int)(duration / 60) << " min.)" << std::endl;
                duration = static_cast<int>((duration * 1000 * 1000) / Handler::STEPS);
                break;
            }

            default:
                LOG(moba::WARNING) << "ignoring unknown message-type <" << msg.mtype << ">" << std::endl;
                break;
        }
        if(!emergency && !halted) {
            return true;
        }
    }
}

TargetValues Handler::parseMessageData(const std::string &data) {
    std::string::size_type pos = 0;
    std::string::size_type found = 0;

    TargetValues target;
    int val;

    for(int i = 0; i < 5; ++i) {
        found = data.find(';', pos);
        switch(i) {
            case Bridge::WHITE:
            case Bridge::GREEN:
            case Bridge::RED:
            case Bridge::BLUE:
                val = atoi(data.substr(pos, found - pos).c_str());
                if(val < Bridge::MIN_VALUE) {
                    val = Bridge::MIN_VALUE;
                }
                if(val > Bridge::MAX_VALUE) {
                    val = Bridge::MAX_VALUE;
                }
                target.targetIntensity[i] = val;
                break;

            case 5:
                switch(data.substr(pos, found - pos)[0]) {
                    case 'W':
                        target.wobble = true;
                        break;

                    case 'D':
                        target.direkt = true;
                        break;
                }
                break;
        }
        pos = found + 1;
    }
    LOG(moba::DEBUG) << "--> " << "inserting #" << target.getObjectId() << "..." << std::endl;
    LOG(moba::DEBUG) <<
            "--> targets" <<
            " white: " << target.targetIntensity[Bridge::WHITE] <<
            " green: " << target.targetIntensity[Bridge::GREEN] <<
            " red: " << target.targetIntensity[Bridge::RED] <<
            " blue: " << target.targetIntensity[Bridge::BLUE] << std::endl;
    LOG(moba::DEBUG) <<
            "--> wobble: " << (target.wobble ? "on" : "off") << std::endl;
    return target;
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
	int n;
	cin >>n;
	int s=0,a;
	while(n--){
		cin>>a;
		s+=a;
	}
	cout<<s;
	return 0;
}
<commit_msg>update hdu1001<commit_after>#include <iostream>
using namespace std;
a
int main(int argc, char const *argv[])
{
	int n;

	int s=0,a;
	while(cin >>n;){
		s=(n+1)*n/2;
		cout<<s;
	}
	return 0;
}
<|endoftext|>


<commit_before>#include "../includes/declarations.h"

//Function to reset all parameters involved in the game.
void resetAll()
{
    memset(arr,0,5000);
    z=0;
    next_level=false;
    if(play_game||lvlSelect)
        start_game=false;
    transx=0;
    transy=0;
    num_circles=0;
    red_black=0;
    mult=1;
    multflag=false;
    leftwall=true;
    rightwall=true;
    reflectionl=false;
    reflectionr=false;
    if(level==MAX_LEVELS)
    {
        level=0;
        start_game=true;
        play_game=lvlSelect=false;
    }
    genLevel();
}

//Function to initiliaze to variables.
void init()
{
    glClearColor( 245.0, 245.0, 245.0, 1.0);
    red_black=0;
    next_level=false;
    start_game=true;
    level=0;
    num_circles=0;
    mult=1;
    multflag=false;
    leftwall=true;
    rightwall=true;
    reflectionl=false;
    reflectionr=false;
    glLineWidth(5);
    glMatrixMode( GL_PROJECTION);
    gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
    memset(arr,0,5000);
    glPointSize(20.0);
    genLevel();
}

//Functions to convert x and y co-ordinates provided by OpenGL mouse function into Euclidean ones.
float getOpenGLX(int x)
{
    double ox = x/ (double)WIDTH*(WIDTH);
    return ox;
}

float getOpenGLY(int y)
{
    double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
    return oy;
}

void addValue(int x,int y)
{
    arr[z][0]=getOpenGLX(x);
    arr[z++][1]=getOpenGLY(y);
    if(checkCollision(arr[z-1][0],arr[z-1][1]))
    {
         if(flag)
        {
            ptr=0;
            flag=0;
        }
    }
}

//Detects which key is pressed and sets appropriate flags.
void keyPressed(unsigned char key, int x, int y)
{
    if (key == 'm')
    {
        if(level==MAX_LEVELS)
        {
            resetAll();
        }
        else
        {
            level++;
            if(level<MAX_LEVELS)
                resetAll();
            else
                next_level=true;
        }
    }

    if (key == 'n')
    {
        if(level)
            level--;
        resetAll();
    }

    if (key == 'r')
    {
        cout << key << "\n";
        start_game = true;
        lvlSelect = false;
        play_game = false;
        level = 0;
        resetAll();
    }

    if (key == 'q')
    {
        cout << "Thank you for playing!\n";
        cout << "This game was designed by:\n";
        cout << "Abraham Sebastian, 13IT103\n";
        cout << "Kishor Bhat, 13IT114\n";
        cout << "Chinmay Deshpande, 13IT210\n";
        cout << "Sagar Ramprasad, 13IT233\n";
        cout << "Pranav Konanur, 13IT228\n";
        exit(0);
    }
}

//Function to check mouse activity.
void myMouseStat(int button,int state,int x, int y)
{
    if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        if (highlight_lvls)
        {
            lvlSelect = true;
            highlight_lvls = false;
            resetAll();
        }

        else if (highlight_play)
        {
            play_game = true;
            highlight_play = false;
            resetAll();
        }

        else if (lvlSelect)
        {
            int fl = (int)((float) log10(circle_choose) / (float) log10(2));
            cout << fl << "\n";
            if (fl <= 8)
            {
                level = fl;
                play_game = true;
                lvlSelect = false;
                resetAll();
            }
        }

        if(!flag)
        {
            if(temp_bit)
            {
                temp_bit=0;
            }
            resetAll();
            flag=1;
        }
    }
    else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
    {
        if(flag)
        {
            ptr=0;
            flag=0;
        }
    }
}

void myPressedMove(int x,int y)
{
    if(flag)
        addValue(x,y);
}

//Function passed to passive mouse function to track user movement.
void mouse_motion(int x, int y)
{
    int cg_x = getOpenGLX(x), cg_y = getOpenGLY(y);
    if (start_game)
    {
        if (cg_x >= 0.367*WIDTH && cg_x <=0.495*WIDTH && cg_y >= 0.492*HEIGHT && cg_y <= 0.542*HEIGHT)
            highlight_lvls = true;
        else
            highlight_lvls = false;

        if (cg_x >= 0.417*WIDTH && cg_x <= 0.450*WIDTH && cg_y >= 0.417*HEIGHT && cg_y <= 0.467*HEIGHT)
            highlight_play = true;
        else
            highlight_play = false;
    }

    if (lvlSelect)
    {
    	for (int i = 0; i < 9; i++)
    	{
    		if (inCircle(cg_x, cg_y, circles[i].x, circles[i].y))
    		{
    			circle_choose &= (int) pow(2, i);
                break;
    		}
    	    else
    			circle_choose = 511;
    	}
    }
}

//Timer function to update variables in realtime.
void myTimer(int t)
{
    if(ptr!=z&&red_black==0)
    {
        ptr++;
        blackptr=0;
        ptrsave=ptr;
    }
    else if(ptr==z&&red_black==1)
        ptr=0;
    else
    {
        blackptr++;
        ptr=0;
    }
    glutTimerFunc(9,myTimer,0);
}
<commit_msg>"Corrected glitch that occurs for long lines"<commit_after>#include "../includes/declarations.h"

//Function to reset all parameters involved in the game.
void resetAll()
{
    memset(arr,0,10000);
    z=0;
    ptr=0;
    next_level=false;
    if(play_game||lvlSelect)
        start_game=false;
    transx=0;
    transy=0;
    num_circles=0;
    red_black=0;
    mult=1;
    multflag=false;
    leftwall=true;
    rightwall=true;
    reflectionl=false;
    reflectionr=false;
    if(level==MAX_LEVELS)
    {
        level=0;
        start_game=true;
        play_game=lvlSelect=false;
    }
    genLevel();
}

//Function to initiliaze to variables.
void init()
{
    glClearColor( 245.0, 245.0, 245.0, 1.0);
    red_black=0;
    next_level=false;
    start_game=true;
    level=0;
    num_circles=0;
    mult=1;
    multflag=false;
    leftwall=true;
    rightwall=true;
    reflectionl=false;
    reflectionr=false;
    glLineWidth(5);
    glMatrixMode( GL_PROJECTION);
    gluOrtho2D(0.0,WIDTH,0.0,HEIGHT);
    memset(arr,0,5000);
    glPointSize(20.0);
    genLevel();
}

//Functions to convert x and y co-ordinates provided by OpenGL mouse function into Euclidean ones.
float getOpenGLX(int x)
{
    double ox = x/ (double)WIDTH*(WIDTH);
    return ox;
}

float getOpenGLY(int y)
{
    double oy = (1 - y/ (double) HEIGHT)*HEIGHT;
    return oy;
}

void addValue(int x,int y)
{
    arr[z][0]=getOpenGLX(x);
    arr[z++][1]=getOpenGLY(y);
    if(checkCollision(arr[z-1][0],arr[z-1][1]))
    {
         if(flag)
        {
            ptr=0;
            flag=0;
        }
    }
}

//Detects which key is pressed and sets appropriate flags.
void keyPressed(unsigned char key, int x, int y)
{
    if (key == 'm')
    {
        if(level==MAX_LEVELS)
        {
            resetAll();
        }
        else
        {
            level++;
            if(level<MAX_LEVELS)
                resetAll();
            else
                next_level=true;
        }
    }

    if (key == 'n')
    {
        if(level)
            level--;
        resetAll();
    }

    if (key == 'r')
    {
        cout << key << "\n";
        start_game = true;
        lvlSelect = false;
        play_game = false;
        level = 0;
        resetAll();
    }

    if (key == 'q')
    {
        cout << "Thank you for playing!\n";
        cout << "This game was designed by:\n";
        cout << "Abraham Sebastian, 13IT103\n";
        cout << "Kishor Bhat, 13IT114\n";
        cout << "Chinmay Deshpande, 13IT210\n";
        cout << "Sagar Ramprasad, 13IT233\n";
        cout << "Pranav Konanur, 13IT228\n";
        exit(0);
    }
}

//Function to check mouse activity.
void myMouseStat(int button,int state,int x, int y)
{
    if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
    {
        if (highlight_lvls)
        {
            lvlSelect = true;
            highlight_lvls = false;
            resetAll();
        }

        else if (highlight_play)
        {
            play_game = true;
            highlight_play = false;
            resetAll();
        }

        else if (lvlSelect)
        {
            int fl = (int)((float) log10(circle_choose) / (float) log10(2));
            cout << fl << "\n";
            if (fl <= 8)
            {
                level = fl;
                play_game = true;
                lvlSelect = false;
                resetAll();
            }
        }

        if(!flag)
        {
            if(temp_bit)
            {
                temp_bit=0;
            }
            resetAll();
            flag=1;
        }
    }
    else if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
    {
        if(flag)
        {
            ptr=0;
            flag=0;
        }
    }
}

void myPressedMove(int x,int y)
{
    if(flag)
        addValue(x,y);
}

//Function passed to passive mouse function to track user movement.
void mouse_motion(int x, int y)
{
    int cg_x = getOpenGLX(x), cg_y = getOpenGLY(y);
    if (start_game)
    {
        if (cg_x >= 0.367*WIDTH && cg_x <=0.495*WIDTH && cg_y >= 0.492*HEIGHT && cg_y <= 0.542*HEIGHT)
            highlight_lvls = true;
        else
            highlight_lvls = false;

        if (cg_x >= 0.417*WIDTH && cg_x <= 0.450*WIDTH && cg_y >= 0.417*HEIGHT && cg_y <= 0.467*HEIGHT)
            highlight_play = true;
        else
            highlight_play = false;
    }

    if (lvlSelect)
    {
    	for (int i = 0; i < 9; i++)
    	{
    		if (inCircle(cg_x, cg_y, circles[i].x, circles[i].y))
    		{
    			circle_choose &= (int) pow(2, i);
                break;
    		}
    	    else
    			circle_choose = 511;
    	}
    }
}

//Timer function to update variables in realtime.
void myTimer(int t)
{
    if(ptr!=z&&red_black==0)
    {
        ptr++;
        blackptr=0;
        ptrsave=ptr;
    }
    else if(ptr==z&&red_black==1)
        ptr=0;
    else
    {
        blackptr++;
        ptr=0;
    }
    glutTimerFunc(9,myTimer,0);
}
<|endoftext|>


<commit_before>#include <sstream>

#include <osg/Image>
#include <osg/Group>
#include <osg/Notify>

#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>

#include <osgTerrain/TerrainTile>

class ReaderWriterTerrain : public osgDB::ReaderWriter
{
    public:

        ReaderWriterTerrain()
        {
            supportsExtension("osgTerrain","OpenSceneGraph terrain extension to .osg ascii format");
            supportsExtension("terrain","OpenSceneGraph terrain ascii format");
        }

        virtual const char* className() const { return "Terrain ReaderWriter"; }

        virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* opt) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);

            if (osgDB::equalCaseInsensitive(ext,"terrain"))
            {
#if 0
                KeywordValueMap keywordValueMap;
                parseTerrainString(osgDB::getNameLessExtension(file), keywordValueMap);

                for(KeywordValueMap::iterator itr = keywordValueMap.begin();
                    itr != keywordValueMap.end();
                    ++itr)
                {
                    osg::notify(osg::NOTICE)<<"["<<itr->first<<"] = "<<"["<<itr->second<<"]"<<std::endl;
                }
#else
                std::istringstream fin(osgDB::getNameLessExtension(file));
                if (fin) return readNode(fin,opt);
#endif
                return 0;
            }

            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, opt );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            // code for setting up the database path so that internally referenced file are searched for on relative paths.
            osg::ref_ptr<Options> local_opt = opt ? static_cast<Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
            local_opt->setDatabasePath(osgDB::getFilePath(fileName));

            osgDB::ifstream fin(fileName.c_str());
            if (fin)
            {
                return readNode(fin, local_opt.get());
            }
            return 0L;

        }

        virtual osgDB::ReaderWriter::ReadResult readNode(std::istream& fin, const Options* options) const
        {
            fin.imbue(std::locale::classic());

            osgDB::Input fr;
            fr.attach(&fin);
            fr.setOptions(options);

            osg::ref_ptr<osg::Group> group = new osg::Group;

            while(!fr.eof())
            {

                bool itrAdvanced = false;

                if (fr.matchSequence("file %s") || fr.matchSequence("file %w") )
                {
                    osg::Node* node = osgDB::readNodeFile(fr[1].getStr());

                    if (node) group->addChild(node);

                    fr += 2;
                    itrAdvanced = true;
                }

                osg::ref_ptr<osg::Node> node = fr.readNode();
                if (node.valid())
                {
                    group->addChild(node.get());
                    itrAdvanced = true;
                }

                if (!itrAdvanced)
                {
                    if (fr[0].getStr()) osg::notify(osg::NOTICE)<<"Terrain file - unreconised token : "<<fr[0].getStr() <<""<< std::endl;
                    ++fr;
                }
            }

            if (group->getNumChildren()>0) return group.release();
            else return 0;
        }

        typedef std::map<std::string, std::string> KeywordValueMap;
        bool parseTerrainString(const std::string& str, KeywordValueMap& keywordValueMap) const
        {
            bool success = false;

            std::string::size_type pos = 0;
            while(pos != std::string::npos)
            {
                pos = str.find_first_not_of(' ',pos);
                if (pos == std::string::npos) break;

                std::string::size_type semicolon = str.find_first_of(';', pos);
                std::string::size_type startstatement = pos;
                std::string::size_type endstatement = std::string::npos;
                if (semicolon!=std::string::npos)
                {
                    endstatement = semicolon-1;
                    pos = semicolon+1;
                }
                else
                {
                    endstatement = str.length()-1;
                    pos = std::string::npos;
                }

                if (startstatement<endstatement) endstatement = str.find_last_not_of(' ',endstatement);

                if (startstatement<=endstatement)
                {
                    // osg::notify(osg::NOTICE)<<"statement = ["<<str.substr(startstatement, endstatement-startstatement+1)<<"]"<<std::endl;
                    std::string::size_type assignment = str.find_first_of('=', startstatement);
                    if (assignment!=std::string::npos && assignment>endstatement)
                    {
                        assignment = std::string::npos;
                    }

                    std::string::size_type startvariable = startstatement;
                    std::string::size_type endvariable = startstatement;
                    std::string::size_type startvalue = startstatement;
                    std::string::size_type endvalue = endstatement;

                    if (assignment!=std::string::npos)
                    {
                        endvariable = assignment-1;
                        startvalue = assignment+1;

                        if (startvariable<=endvariable)
                        {
                            endvariable = str.find_last_not_of(' ',endvariable);
                        }

                        if (startvariable<=endvariable)
                        {
                            ++endvariable;
                        }
                    }

                    if (startvalue<=endvalue)
                    {
                        startvalue = str.find_first_not_of(' ',startvalue);
                    }

                    if (startvalue<=endvalue)
                    {
                        if (startvariable<endvariable)
                        {
                            keywordValueMap[str.substr(startvariable, endvariable-startvariable)] = str.substr(startvalue, endvalue-startvalue+1);
                            success = true;
                        }
                        else
                        {
                            keywordValueMap[""] = str.substr(startvalue, endvalue-startvalue+1);
                            success = true;
                        }
                    }

                }
            }

            return success;
        }

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(terrain, ReaderWriterTerrain)

<commit_msg>Converted osg::notify to OSG_INFO etc.<commit_after>#include <sstream>

#include <osg/Image>
#include <osg/Group>
#include <osg/Notify>

#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>

#include <osgTerrain/TerrainTile>

class ReaderWriterTerrain : public osgDB::ReaderWriter
{
    public:

        ReaderWriterTerrain()
        {
            supportsExtension("osgTerrain","OpenSceneGraph terrain extension to .osg ascii format");
            supportsExtension("terrain","OpenSceneGraph terrain ascii format");
        }

        virtual const char* className() const { return "Terrain ReaderWriter"; }

        virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* opt) const
        {
            std::string ext = osgDB::getLowerCaseFileExtension(file);

            if (osgDB::equalCaseInsensitive(ext,"terrain"))
            {
#if 0
                KeywordValueMap keywordValueMap;
                parseTerrainString(osgDB::getNameLessExtension(file), keywordValueMap);

                for(KeywordValueMap::iterator itr = keywordValueMap.begin();
                    itr != keywordValueMap.end();
                    ++itr)
                {
                    OSG_NOTICE<<"["<<itr->first<<"] = "<<"["<<itr->second<<"]"<<std::endl;
                }
#else
                std::istringstream fin(osgDB::getNameLessExtension(file));
                if (fin) return readNode(fin,opt);
#endif
                return 0;
            }

            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;

            std::string fileName = osgDB::findDataFile( file, opt );
            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;

            // code for setting up the database path so that internally referenced file are searched for on relative paths.
            osg::ref_ptr<Options> local_opt = opt ? static_cast<Options*>(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
            local_opt->setDatabasePath(osgDB::getFilePath(fileName));

            osgDB::ifstream fin(fileName.c_str());
            if (fin)
            {
                return readNode(fin, local_opt.get());
            }
            return 0L;

        }

        virtual osgDB::ReaderWriter::ReadResult readNode(std::istream& fin, const Options* options) const
        {
            fin.imbue(std::locale::classic());

            osgDB::Input fr;
            fr.attach(&fin);
            fr.setOptions(options);

            osg::ref_ptr<osg::Group> group = new osg::Group;

            while(!fr.eof())
            {

                bool itrAdvanced = false;

                if (fr.matchSequence("file %s") || fr.matchSequence("file %w") )
                {
                    osg::Node* node = osgDB::readNodeFile(fr[1].getStr());

                    if (node) group->addChild(node);

                    fr += 2;
                    itrAdvanced = true;
                }

                osg::ref_ptr<osg::Node> node = fr.readNode();
                if (node.valid())
                {
                    group->addChild(node.get());
                    itrAdvanced = true;
                }

                if (!itrAdvanced)
                {
                    if (fr[0].getStr()) { OSG_NOTICE<<"Terrain file - unreconised token : "<<fr[0].getStr() <<""<< std::endl; }
                    ++fr;
                }
            }

            if (group->getNumChildren()>0) return group.release();
            else return 0;
        }

        typedef std::map<std::string, std::string> KeywordValueMap;
        bool parseTerrainString(const std::string& str, KeywordValueMap& keywordValueMap) const
        {
            bool success = false;

            std::string::size_type pos = 0;
            while(pos != std::string::npos)
            {
                pos = str.find_first_not_of(' ',pos);
                if (pos == std::string::npos) break;

                std::string::size_type semicolon = str.find_first_of(';', pos);
                std::string::size_type startstatement = pos;
                std::string::size_type endstatement = std::string::npos;
                if (semicolon!=std::string::npos)
                {
                    endstatement = semicolon-1;
                    pos = semicolon+1;
                }
                else
                {
                    endstatement = str.length()-1;
                    pos = std::string::npos;
                }

                if (startstatement<endstatement) endstatement = str.find_last_not_of(' ',endstatement);

                if (startstatement<=endstatement)
                {
                    // OSG_NOTICE<<"statement = ["<<str.substr(startstatement, endstatement-startstatement+1)<<"]"<<std::endl;
                    std::string::size_type assignment = str.find_first_of('=', startstatement);
                    if (assignment!=std::string::npos && assignment>endstatement)
                    {
                        assignment = std::string::npos;
                    }

                    std::string::size_type startvariable = startstatement;
                    std::string::size_type endvariable = startstatement;
                    std::string::size_type startvalue = startstatement;
                    std::string::size_type endvalue = endstatement;

                    if (assignment!=std::string::npos)
                    {
                        endvariable = assignment-1;
                        startvalue = assignment+1;

                        if (startvariable<=endvariable)
                        {
                            endvariable = str.find_last_not_of(' ',endvariable);
                        }

                        if (startvariable<=endvariable)
                        {
                            ++endvariable;
                        }
                    }

                    if (startvalue<=endvalue)
                    {
                        startvalue = str.find_first_not_of(' ',startvalue);
                    }

                    if (startvalue<=endvalue)
                    {
                        if (startvariable<endvariable)
                        {
                            keywordValueMap[str.substr(startvariable, endvariable-startvariable)] = str.substr(startvalue, endvalue-startvalue+1);
                            success = true;
                        }
                        else
                        {
                            keywordValueMap[""] = str.substr(startvalue, endvalue-startvalue+1);
                            success = true;
                        }
                    }

                }
            }

            return success;
        }

};

// now register with Registry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(terrain, ReaderWriterTerrain)

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "pluginfilefactory.h"
#include "projectexplorer.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "iprojectmanager.h"
#include "session.h"

#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/id.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/messagemanager.h>

#include <QDebug>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

/*!
    \class ProjectExplorer::Internal::ProjectFileFactory

    \brief Factory for project files.
*/

ProjectFileFactory::ProjectFileFactory(IProjectManager *manager)
  : m_mimeTypes(manager->mimeType()),
    m_manager(manager)
{
}

QStringList ProjectFileFactory::mimeTypes() const
{
    return m_mimeTypes;
}

Core::Id ProjectFileFactory::id() const
{
    return Constants::FILE_FACTORY_ID;
}

QString ProjectFileFactory::displayName() const
{
    return tr("Project File Factory", "ProjectExplorer::ProjectFileFactory display name.");
}

Core::IDocument *ProjectFileFactory::open(const QString &fileName)
{
    ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
    pe->openProject(fileName, 0);
    return 0;
}

QList<ProjectFileFactory *> ProjectFileFactory::createFactories(QString *filterString)
{
    // Register factories for all project managers
    QList<Internal::ProjectFileFactory*> rc;
    QList<IProjectManager*> projectManagers =
        ExtensionSystem::PluginManager::getObjects<IProjectManager>();

    QList<Core::MimeGlobPattern> allGlobPatterns;

    const QString filterSeparator = QLatin1String(";;");
    filterString->clear();
    foreach (IProjectManager *manager, projectManagers) {
        rc.push_back(new ProjectFileFactory(manager));
        if (!filterString->isEmpty())
            *filterString += filterSeparator;
        const QString mimeType = manager->mimeType();
        Core::MimeType mime = Core::ICore::mimeDatabase()->findByType(mimeType);
        const QString pFilterString = mime.filterString();
        allGlobPatterns.append(mime.globPatterns());
        *filterString += pFilterString;
    }
    QString allProjectFilter = Core::MimeType::formatFilterString(tr("All Projects"), allGlobPatterns);
    allProjectFilter.append(filterSeparator);
    filterString->prepend(allProjectFilter);
    return rc;
}
<commit_msg>Show a message box if opening a project fails via File/Open<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "pluginfilefactory.h"
#include "projectexplorer.h"
#include "project.h"
#include "projectexplorerconstants.h"
#include "iprojectmanager.h"
#include "session.h"

#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/id.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/messagemanager.h>

#include <QDebug>
#include <QMessageBox>
#include <QMainWindow>

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

/*!
    \class ProjectExplorer::Internal::ProjectFileFactory

    \brief Factory for project files.
*/

ProjectFileFactory::ProjectFileFactory(IProjectManager *manager)
  : m_mimeTypes(manager->mimeType()),
    m_manager(manager)
{
}

QStringList ProjectFileFactory::mimeTypes() const
{
    return m_mimeTypes;
}

Core::Id ProjectFileFactory::id() const
{
    return Constants::FILE_FACTORY_ID;
}

QString ProjectFileFactory::displayName() const
{
    return tr("Project File Factory", "ProjectExplorer::ProjectFileFactory display name.");
}

Core::IDocument *ProjectFileFactory::open(const QString &fileName)
{
    ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
    QString errorMessage;
    pe->openProject(fileName, &errorMessage);
    if (!errorMessage.isEmpty())
        QMessageBox::critical(Core::ICore::mainWindow(), tr("Failed to open project"), errorMessage);
    return 0;
}

QList<ProjectFileFactory *> ProjectFileFactory::createFactories(QString *filterString)
{
    // Register factories for all project managers
    QList<Internal::ProjectFileFactory*> rc;
    QList<IProjectManager*> projectManagers =
        ExtensionSystem::PluginManager::getObjects<IProjectManager>();

    QList<Core::MimeGlobPattern> allGlobPatterns;

    const QString filterSeparator = QLatin1String(";;");
    filterString->clear();
    foreach (IProjectManager *manager, projectManagers) {
        rc.push_back(new ProjectFileFactory(manager));
        if (!filterString->isEmpty())
            *filterString += filterSeparator;
        const QString mimeType = manager->mimeType();
        Core::MimeType mime = Core::ICore::mimeDatabase()->findByType(mimeType);
        const QString pFilterString = mime.filterString();
        allGlobPatterns.append(mime.globPatterns());
        *filterString += pFilterString;
    }
    QString allProjectFilter = Core::MimeType::formatFilterString(tr("All Projects"), allGlobPatterns);
    allProjectFilter.append(filterSeparator);
    filterString->prepend(allProjectFilter);
    return rc;
}
<|endoftext|>


<commit_before>/*
   Copyright (c) 2015, 2016, Andreas Fett. All rights reserved.
   Use of this source code is governed by a BSD-style
   license that can be found in the LICENSE file.
*/

#include <jsoncc.h>
#include <cassert>
#include <iomanip>

namespace {

class indent : public std::streambuf {
public:
	explicit indent(std::ostream &, std::string indent = "\t");
	virtual ~indent();

protected:
	virtual int overflow(int);

private:
	std::string indent_;
	std::streambuf* dest_;
	bool line_start_;
	std::ostream* owner_;
};

indent::indent(std::ostream& dest, std::string indent)
:
	indent_(indent),
	dest_(dest.rdbuf()),
	line_start_(true),
	owner_(&dest)
{
	owner_->rdbuf(this);
}

indent::~indent()
{
	if (owner_ != nullptr) {
		owner_->rdbuf(dest_);
	}
}

int indent::overflow(int ch)
{
	if (line_start_ && ch != '\n') {
		dest_->sputn(indent_.c_str(), indent_.size());
	}
	line_start_ = (ch == '\n');
	return dest_->sputc(ch);
}

std::ostream & quote(std::ostream & os, std::string const& in)
{
	os << '"';
	for (auto c: in) {
		switch (c) {
/*
   All Unicode characters may be placed within the quotation marks,
   except for the characters that must be escaped: quotation mark,
   reverse solidus, and the control characters (U+0000 through U+001F).
*/
#define ESCAPE(val, sym) case val: os << "\\" sym; break
		ESCAPE(0x00, "u0000"); ESCAPE(0x01, "u0001");
		ESCAPE(0x02, "u0002"); ESCAPE(0x03, "u0003");
		ESCAPE(0x04, "u0004"); ESCAPE(0x05, "u0005");
		ESCAPE(0x06, "u0006"); ESCAPE(0x07, "u0007");
		ESCAPE(0x08, "b");     ESCAPE(0x09, "t");
		ESCAPE(0x0a, "n");     ESCAPE(0x0b, "u000b");
		ESCAPE(0x0c, "f");     ESCAPE(0x0d, "r");
		ESCAPE(0x0e, "u000e"); ESCAPE(0x0f, "u000f");
		ESCAPE(0x10, "u0010"); ESCAPE(0x11, "u0011");
		ESCAPE(0x12, "u0012"); ESCAPE(0x13, "u0013");
		ESCAPE(0x14, "u0014"); ESCAPE(0x15, "u0015");
		ESCAPE(0x16, "u0016"); ESCAPE(0x17, "u0017");
		ESCAPE(0x18, "u0018"); ESCAPE(0x19, "u0019");
		ESCAPE(0x1a, "u001a"); ESCAPE(0x1b, "u001b");
		ESCAPE(0x1c, "u001c"); ESCAPE(0x1d, "u001d");
		ESCAPE(0x1e, "u001e"); ESCAPE(0x1f, "u001f");
		ESCAPE(0x22, "\"");    ESCAPE(0x5c, "\\");
#undef ESCAPE
		default:
			os << c;
		}
	}
	return os << '"';
}

enum IOS_Flags {
	IOS_NOINDENT = 1 << 0,
};

const int xalloc_id = std::ios_base::xalloc();

template <typename C>
std::ostream & container_indent(std::ostream & os, const char delim[3], C const& c)
{
	os << delim[0] << "\n";
	{
		indent in(os);
		std::string sep;
		auto it(c.begin());
		for (; it != c.end(); ++it) {
			os << sep << *it;
			sep = ",\n";
		}
	}
	return os << "\n" << delim[1] ;
}

template <typename C>
std::ostream & container_noindent(std::ostream & os, const char delim[3], C const& c)
{
	os << delim[0];
	std::string sep;
	auto it(c.begin());
	for (; it != c.end(); ++it) {
		os << sep << *it;
		sep = ", ";
	}
	return os << delim[1] ;
}

template <typename C>
std::ostream & stream_container(std::ostream & os, const char delim[3], C const& c)
{
	if (c.empty()) {
		return os << delim;
	}

	return (os.iword(xalloc_id) & ::IOS_NOINDENT) ?
		container_noindent(os, delim, c) : container_indent(os, delim, c);
}

}

namespace Json {

std::ios_base & indent(std::ios_base & os)
{
	os.iword(xalloc_id) &= ~::IOS_NOINDENT;
	return os;
}

std::ios_base & noindent(std::ios_base & os)
{
	os.iword(xalloc_id) |= ::IOS_NOINDENT;
	return os;
}

std::ostream & operator<<(std::ostream & os, Null const&)
{
	return os << "null";
}

std::ostream & operator<<(std::ostream & os, True const&)
{
	return os << "true";
}

std::ostream & operator<<(std::ostream & os, False const&)
{
	return os << "false";
}

std::ostream & operator<<(std::ostream & os, Number const& number)
{
	switch (number.type()) {
	case Number::TYPE_INVALID:
		assert(false);
		break;
	case Number::TYPE_INT:
		return os << number.int_value();
	case Number::TYPE_UINT:
		return os << number.uint_value();
	case Number::TYPE_FP:
		return os << std::fixed << number.fp_value();
	}

	return os;
}

std::ostream & operator<<(std::ostream & os, String const& string)
{
	return ::quote(os, string.value());
}

std::ostream & operator<<(std::ostream & os, Array const& array)
{
	return stream_container(os, "[]", array.elements());
}

std::ostream & operator<<(std::ostream & os, Member const& member)
{
	return os << member.key() << ": " << member.value();
}

std::ostream & operator<<(std::ostream & os, Object const& object)
{
	return stream_container(os, "{}", object.members());
}

std::ostream & operator<<(std::ostream & os, Value const& value)
{
	switch (value.tag()) {
	case Value::TAG_INVALID:
		assert(false);
		break;
	case Value::TAG_TRUE:
		return os << value.true_value();
	case Value::TAG_FALSE:
		return os << value.false_value();
	case Value::TAG_NULL:
		return os << value.null();
	case Value::TAG_NUMBER:
		return os << value.number();
	case Value::TAG_STRING:
		return os << value.string();
	case Value::TAG_OBJECT:
		return os << value.object();
	case Value::TAG_ARRAY:
		return os << value.array();
	}

	return os;
}

}
<commit_msg>c++11: iostream: use range based for loops<commit_after>/*
   Copyright (c) 2015, 2016, Andreas Fett. All rights reserved.
   Use of this source code is governed by a BSD-style
   license that can be found in the LICENSE file.
*/

#include <jsoncc.h>
#include <cassert>
#include <iomanip>

namespace {

class indent : public std::streambuf {
public:
	explicit indent(std::ostream &, std::string indent = "\t");
	virtual ~indent();

protected:
	virtual int overflow(int);

private:
	std::string indent_;
	std::streambuf* dest_;
	bool line_start_;
	std::ostream* owner_;
};

indent::indent(std::ostream& dest, std::string indent)
:
	indent_(indent),
	dest_(dest.rdbuf()),
	line_start_(true),
	owner_(&dest)
{
	owner_->rdbuf(this);
}

indent::~indent()
{
	if (owner_ != nullptr) {
		owner_->rdbuf(dest_);
	}
}

int indent::overflow(int ch)
{
	if (line_start_ && ch != '\n') {
		dest_->sputn(indent_.c_str(), indent_.size());
	}
	line_start_ = (ch == '\n');
	return dest_->sputc(ch);
}

std::ostream & quote(std::ostream & os, std::string const& in)
{
	os << '"';
	for (auto c: in) {
		switch (c) {
/*
   All Unicode characters may be placed within the quotation marks,
   except for the characters that must be escaped: quotation mark,
   reverse solidus, and the control characters (U+0000 through U+001F).
*/
#define ESCAPE(val, sym) case val: os << "\\" sym; break
		ESCAPE(0x00, "u0000"); ESCAPE(0x01, "u0001");
		ESCAPE(0x02, "u0002"); ESCAPE(0x03, "u0003");
		ESCAPE(0x04, "u0004"); ESCAPE(0x05, "u0005");
		ESCAPE(0x06, "u0006"); ESCAPE(0x07, "u0007");
		ESCAPE(0x08, "b");     ESCAPE(0x09, "t");
		ESCAPE(0x0a, "n");     ESCAPE(0x0b, "u000b");
		ESCAPE(0x0c, "f");     ESCAPE(0x0d, "r");
		ESCAPE(0x0e, "u000e"); ESCAPE(0x0f, "u000f");
		ESCAPE(0x10, "u0010"); ESCAPE(0x11, "u0011");
		ESCAPE(0x12, "u0012"); ESCAPE(0x13, "u0013");
		ESCAPE(0x14, "u0014"); ESCAPE(0x15, "u0015");
		ESCAPE(0x16, "u0016"); ESCAPE(0x17, "u0017");
		ESCAPE(0x18, "u0018"); ESCAPE(0x19, "u0019");
		ESCAPE(0x1a, "u001a"); ESCAPE(0x1b, "u001b");
		ESCAPE(0x1c, "u001c"); ESCAPE(0x1d, "u001d");
		ESCAPE(0x1e, "u001e"); ESCAPE(0x1f, "u001f");
		ESCAPE(0x22, "\"");    ESCAPE(0x5c, "\\");
#undef ESCAPE
		default:
			os << c;
		}
	}
	return os << '"';
}

enum IOS_Flags {
	IOS_NOINDENT = 1 << 0,
};

const int xalloc_id = std::ios_base::xalloc();

template <typename C>
std::ostream & container_indent(std::ostream & os, const char delim[3], C const& c)
{
	os << delim[0] << "\n";
	{
		indent in(os);
		std::string sep;
		for (auto item: c) {
			os << sep << item;
			sep = ",\n";
		}
	}
	return os << "\n" << delim[1] ;
}

template <typename C>
std::ostream & container_noindent(std::ostream & os, const char delim[3], C const& c)
{
	os << delim[0];
	std::string sep;
	for (auto item: c) {
		os << sep << item;
		sep = ", ";
	}
	return os << delim[1] ;
}

template <typename C>
std::ostream & stream_container(std::ostream & os, const char delim[3], C const& c)
{
	if (c.empty()) {
		return os << delim;
	}

	return (os.iword(xalloc_id) & ::IOS_NOINDENT) ?
		container_noindent(os, delim, c) : container_indent(os, delim, c);
}

}

namespace Json {

std::ios_base & indent(std::ios_base & os)
{
	os.iword(xalloc_id) &= ~::IOS_NOINDENT;
	return os;
}

std::ios_base & noindent(std::ios_base & os)
{
	os.iword(xalloc_id) |= ::IOS_NOINDENT;
	return os;
}

std::ostream & operator<<(std::ostream & os, Null const&)
{
	return os << "null";
}

std::ostream & operator<<(std::ostream & os, True const&)
{
	return os << "true";
}

std::ostream & operator<<(std::ostream & os, False const&)
{
	return os << "false";
}

std::ostream & operator<<(std::ostream & os, Number const& number)
{
	switch (number.type()) {
	case Number::TYPE_INVALID:
		assert(false);
		break;
	case Number::TYPE_INT:
		return os << number.int_value();
	case Number::TYPE_UINT:
		return os << number.uint_value();
	case Number::TYPE_FP:
		return os << std::fixed << number.fp_value();
	}

	return os;
}

std::ostream & operator<<(std::ostream & os, String const& string)
{
	return ::quote(os, string.value());
}

std::ostream & operator<<(std::ostream & os, Array const& array)
{
	return stream_container(os, "[]", array.elements());
}

std::ostream & operator<<(std::ostream & os, Member const& member)
{
	return os << member.key() << ": " << member.value();
}

std::ostream & operator<<(std::ostream & os, Object const& object)
{
	return stream_container(os, "{}", object.members());
}

std::ostream & operator<<(std::ostream & os, Value const& value)
{
	switch (value.tag()) {
	case Value::TAG_INVALID:
		assert(false);
		break;
	case Value::TAG_TRUE:
		return os << value.true_value();
	case Value::TAG_FALSE:
		return os << value.false_value();
	case Value::TAG_NULL:
		return os << value.null();
	case Value::TAG_NUMBER:
		return os << value.number();
	case Value::TAG_STRING:
		return os << value.string();
	case Value::TAG_OBJECT:
		return os << value.object();
	case Value::TAG_ARRAY:
		return os << value.array();
	}

	return os;
}

}
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*
* $Id$
*/

#include "ircutil.h"
#include <QString>
#include <QRegExp>

/*!
    \class Irc::Util ircutil.h
    \brief The Irc::Util class provides IRC related utility functions.
 */

static QRegExp URL_PATTERN(QLatin1String("((www\\.(?!\\.)|(ssh|fish|irc|(f|sf|ht)tp(|s))://)(\\.?[\\d\\w/,\\':~\\?=;#@\\-\\+\\%\\*\\{\\}\\!\\(\\)]|&)+)|([-.\\d\\w]+@[-.\\d\\w]{2,}\\.[\\w]{2,})"), Qt::CaseInsensitive);

namespace Irc
{
    /*!
        Parses and returns the nick part from \a target.
    */
    QString Util::nickFromTarget(const QString& target)
    {
        int index = target.indexOf(QLatin1Char('!'));
        return target.left(index);
    }

    /*!
        Parses and returns the host part from \a target.
    */
    QString Util::hostFromTarget(const QString& target)
    {
        int index = target.indexOf(QLatin1Char('!'));
        return target.mid(index + 1);
    }

    /*!
        Converts \a message to HTML. This function parses the
        message and replaces IRC-style formatting like colors,
        bold and underline to the corresponding HTML formatting.
        Furthermore, this function detects URLs and replaces
        them with appropriate HTML hyperlinks.
    */
    QString Util::messageToHtml(const QString& message)
    {
        QString processed = message;
        processed.replace(QLatin1Char('&'), QLatin1String("&"));
        processed.replace(QLatin1Char('<'), QLatin1String("<"));
        processed.replace(QLatin1Char('>'), QLatin1String(">"));

        enum
        {
            None            = 0x0,
            Bold            = 0x1,
            Color           = 0x2,
            Italic          = 0x4,
            StrikeThrough   = 0x8,
            Underline       = 0x10,
            Inverse         = 0x20
        };
        int state = None;

        int pos = 0;
        while (pos < processed.size())
        {
            if (state & Color)
            {
                QString tmp = processed.mid(pos, 2);
                processed.remove(pos, 2);
                processed = processed.arg(colorNameFromCode(tmp.toInt()));
                state &= ~Color;
                pos += 2;
                continue;
            }

            QString replacement;
            switch (processed.at(pos).unicode())
            {
            case '\x02': // bold
                if (state & Bold)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Bold;
                break;

            case '\x03': // color
                if (state & Color)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Color;
                break;

            case '\x09': // italic
                if (state & Italic)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Italic;
                break;

            case '\x13': // strike-through
                if (state & StrikeThrough)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= StrikeThrough;
                break;

            case '\x15': // underline
            case '\x1f': // underline
                if (state & Underline)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Underline;
                break;

            case '\x16': // inverse
                state ^= Inverse;
                break;

            case '\x0f': // none
                replacement = QLatin1String("");
                state = None;
                break;

            default:
                break;
            }

            if (!replacement.isNull())
            {
                processed.replace(pos, 1, replacement);
                pos += replacement.length();
            }
            else
            {
                ++pos;
            }
        }

        pos = 0;
        while ((pos = URL_PATTERN.indexIn(processed, pos)) >= 0)
        {
            int len = URL_PATTERN.matchedLength();
            QString href = processed.mid(pos, len);

            // Don't consider trailing > as part of the link.
            QString append;
            if (href.endsWith(QLatin1String(">")))
            {
                append.append(href.right(4));
                href.chop(4);
            }

            // Don't consider trailing comma or semi-colon as part of the link.
            if (href.endsWith(QLatin1Char(',')) || href.endsWith(QLatin1Char(';')))
            {
                append.append(href.right(1));
                href.chop(1);
            }

            // Don't consider trailing closing parenthesis part of the link when
            // there's an opening parenthesis preceding in the beginning of the
            // URL or there is no opening parenthesis in the URL at all.
            if (pos > 0 && href.endsWith(QLatin1Char(')'))
                && (processed.at(pos-1) == QLatin1Char('(')
                || !href.contains(QLatin1Char('('))))
            {
                append.prepend(href.right(1));
                href.chop(1);
            }

            // Qt doesn't support (?<=pattern) so we do it here
            if (pos > 0 && processed.at(pos-1).isLetterOrNumber())
            {
                pos++;
                continue;
            }

            QString protocol;
            if (URL_PATTERN.cap(1).startsWith(QLatin1String("www."), Qt::CaseInsensitive))
                protocol = QLatin1String("http://");
            else if (URL_PATTERN.cap(1).isEmpty())
                protocol = QLatin1String("mailto:");

            QString link = QString(QLatin1String("%3")).arg(protocol, href, href) + append;
            processed.replace(pos, len, link);
            pos += link.length();
        }

        return processed;
    }

    /*!
        Converts \a code to a color name.
    */
    QString Util::colorNameFromCode(int code)
    {
        switch (code)
        {
        case 0:  return QLatin1String("white");
        case 1:  return QLatin1String("black");
        case 2:  return QLatin1String("navy");
        case 3:  return QLatin1String("green");
        case 4:  return QLatin1String("red");
        case 5:  return QLatin1String("maroon");
        case 6:  return QLatin1String("purple");
        case 7:  return QLatin1String("orange");
        case 8:  return QLatin1String("yellow");
        case 9:  return QLatin1String("lime");
        case 10: return QLatin1String("darkcyan");
        case 11: return QLatin1String("cyan");
        case 12: return QLatin1String("blue");
        case 13: return QLatin1String("magenta");
        case 14: return QLatin1String("gray");
        case 15: return QLatin1String("lightgray");
        default: return QLatin1String("black");
        }
    }
}
<commit_msg>Replace percent marks with an HTML entity to avoid clash with QString::arg().<commit_after>/*
* Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*
* $Id$
*/

#include "ircutil.h"
#include <QString>
#include <QRegExp>

/*!
    \class Irc::Util ircutil.h
    \brief The Irc::Util class provides IRC related utility functions.
 */

static QRegExp URL_PATTERN(QLatin1String("((www\\.(?!\\.)|(ssh|fish|irc|(f|sf|ht)tp(|s))://)(\\.?[\\d\\w/,\\':~\\?=;#@\\-\\+\\%\\*\\{\\}\\!\\(\\)]|&)+)|([-.\\d\\w]+@[-.\\d\\w]{2,}\\.[\\w]{2,})"), Qt::CaseInsensitive);

namespace Irc
{
    /*!
        Parses and returns the nick part from \a target.
    */
    QString Util::nickFromTarget(const QString& target)
    {
        int index = target.indexOf(QLatin1Char('!'));
        return target.left(index);
    }

    /*!
        Parses and returns the host part from \a target.
    */
    QString Util::hostFromTarget(const QString& target)
    {
        int index = target.indexOf(QLatin1Char('!'));
        return target.mid(index + 1);
    }

    /*!
        Converts \a message to HTML. This function parses the
        message and replaces IRC-style formatting like colors,
        bold and underline to the corresponding HTML formatting.
        Furthermore, this function detects URLs and replaces
        them with appropriate HTML hyperlinks.
    */
    QString Util::messageToHtml(const QString& message)
    {
        QString processed = message;
        processed.replace(QLatin1Char('&'), QLatin1String("&"));
        processed.replace(QLatin1Char('%'), QLatin1String("%"));
        processed.replace(QLatin1Char('<'), QLatin1String("<"));
        processed.replace(QLatin1Char('>'), QLatin1String(">"));

        enum
        {
            None            = 0x0,
            Bold            = 0x1,
            Color           = 0x2,
            Italic          = 0x4,
            StrikeThrough   = 0x8,
            Underline       = 0x10,
            Inverse         = 0x20
        };
        int state = None;

        int pos = 0;
        while (pos < processed.size())
        {
            if (state & Color)
            {
                QString tmp = processed.mid(pos, 2);
                processed.remove(pos, 2);
                processed = processed.arg(colorNameFromCode(tmp.toInt()));
                state &= ~Color;
                pos += 2;
                continue;
            }

            QString replacement;
            switch (processed.at(pos).unicode())
            {
            case '\x02': // bold
                if (state & Bold)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Bold;
                break;

            case '\x03': // color
                if (state & Color)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Color;
                break;

            case '\x09': // italic
                if (state & Italic)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Italic;
                break;

            case '\x13': // strike-through
                if (state & StrikeThrough)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= StrikeThrough;
                break;

            case '\x15': // underline
            case '\x1f': // underline
                if (state & Underline)
                    replacement = QLatin1String("");
                else
                    replacement = QLatin1String("");
                state ^= Underline;
                break;

            case '\x16': // inverse
                state ^= Inverse;
                break;

            case '\x0f': // none
                replacement = QLatin1String("");
                state = None;
                break;

            default:
                break;
            }

            if (!replacement.isNull())
            {
                processed.replace(pos, 1, replacement);
                pos += replacement.length();
            }
            else
            {
                ++pos;
            }
        }

        pos = 0;
        while ((pos = URL_PATTERN.indexIn(processed, pos)) >= 0)
        {
            int len = URL_PATTERN.matchedLength();
            QString href = processed.mid(pos, len);

            // Don't consider trailing > as part of the link.
            QString append;
            if (href.endsWith(QLatin1String(">")))
            {
                append.append(href.right(4));
                href.chop(4);
            }

            // Don't consider trailing comma or semi-colon as part of the link.
            if (href.endsWith(QLatin1Char(',')) || href.endsWith(QLatin1Char(';')))
            {
                append.append(href.right(1));
                href.chop(1);
            }

            // Don't consider trailing closing parenthesis part of the link when
            // there's an opening parenthesis preceding in the beginning of the
            // URL or there is no opening parenthesis in the URL at all.
            if (pos > 0 && href.endsWith(QLatin1Char(')'))
                && (processed.at(pos-1) == QLatin1Char('(')
                || !href.contains(QLatin1Char('('))))
            {
                append.prepend(href.right(1));
                href.chop(1);
            }

            // Qt doesn't support (?<=pattern) so we do it here
            if (pos > 0 && processed.at(pos-1).isLetterOrNumber())
            {
                pos++;
                continue;
            }

            QString protocol;
            if (URL_PATTERN.cap(1).startsWith(QLatin1String("www."), Qt::CaseInsensitive))
                protocol = QLatin1String("http://");
            else if (URL_PATTERN.cap(1).isEmpty())
                protocol = QLatin1String("mailto:");

            QString link = QString(QLatin1String("%3")).arg(protocol, href, href) + append;
            processed.replace(pos, len, link);
            pos += link.length();
        }

        return processed;
    }

    /*!
        Converts \a code to a color name.
    */
    QString Util::colorNameFromCode(int code)
    {
        switch (code)
        {
        case 0:  return QLatin1String("white");
        case 1:  return QLatin1String("black");
        case 2:  return QLatin1String("navy");
        case 3:  return QLatin1String("green");
        case 4:  return QLatin1String("red");
        case 5:  return QLatin1String("maroon");
        case 6:  return QLatin1String("purple");
        case 7:  return QLatin1String("orange");
        case 8:  return QLatin1String("yellow");
        case 9:  return QLatin1String("lime");
        case 10: return QLatin1String("darkcyan");
        case 11: return QLatin1String("cyan");
        case 12: return QLatin1String("blue");
        case 13: return QLatin1String("magenta");
        case 14: return QLatin1String("gray");
        case 15: return QLatin1String("lightgray");
        default: return QLatin1String("black");
        }
    }
}
<|endoftext|>


<commit_before>#line 2 "togo/tool_build/interface/command_compile.ipp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

namespace togo {
namespace tool_build {

static bool compile_resource(
	Interface& interface,
	PackageCompiler& pkg,
	ResourceMetadata& metadata
) {
	FixedArray<char, 24> output_path{};
	resource_metadata::output_path(metadata, output_path);

	// Open streams
	FileReader in_stream{};
	FileWriter out_stream{};
	if (!in_stream.open(metadata.path)) {
		TOGO_LOG_ERROR("failed to open source file\n");
		return false;
	}
	if (!out_stream.open(output_path, false)) {
		TOGO_LOG_ERRORF(
			"failed to open output file: '%.*s'\n",
			string::size(output_path), fixed_array::begin(output_path)
		);
		in_stream.close();
		return false;
	}

	{// Compile
	auto const* const compiler = compiler_manager::get_compiler(
		interface._manager,
		metadata.type
	);
	if (!compiler) {
		TOGO_LOG_ERROR("no compiler for type\n");
		return false;
	}
	bool const success = compiler->func_compile(
		interface._manager,
		pkg, metadata,
		in_stream, out_stream
	);
	in_stream.close();
	out_stream.close();
	if (success) {
		metadata.format_version = compiler->format_version;
		metadata.last_compiled = filesystem::time_last_modified(output_path);
	} else {
		metadata.format_version = 0;
		metadata.last_compiled = 0;
		TOGO_LOG_ERROR("failed to compile\n");
		return false;
	}}

	package_compiler::set_modified(pkg, true);
	return true;
}

static bool add_resource(
	HashMap<ResourcePackageNameHash, Array<u32>*>& groups,
	PackageCompiler const* const pkg,
	u32 const id,
	bool const force
) {
	TOGO_ASSERTE(pkg);
	if (id == 0) {
		// Skip holes
		return false;
	}

	auto const& metadata = pkg->_metadata[id - 1];
	StringRef const pkg_name{package_compiler::name(*pkg)};
	StringRef const path{metadata.path};
	u64 const modified = filesystem::time_last_modified(path);
	if (modified == 0) {
		TOGO_LOG_ERRORF(
			"resource file has vanished: %.*s / %.*s\n",
			pkg_name.size, pkg_name.data,
			path.size, path.data
		);
		return false;
	} else if (
		!force &&
		metadata.last_compiled != 0 &&
		metadata.last_compiled >= modified
	) {
		// Resource doesn't need to be compiled
		return false;
	}

	auto const pkg_name_hash = package_compiler::name_hash(*pkg);
	auto** res_list_g = hash_map::get(groups, pkg_name_hash);
	auto* res_list = res_list_g ? *res_list_g : nullptr;
	if (!res_list) {
		Allocator& allocator = *groups._head._allocator;
		res_list = hash_map::push(
			groups, pkg_name_hash,
			TOGO_CONSTRUCT(allocator, Array<u32>, allocator)
		);
		array::reserve(*res_list, 16);
	}
	array::push_back(*res_list, id);
	return true;
}

static void add_node(
	HashMap<ResourcePackageNameHash, Array<u32>*>& groups,
	PackageCompiler const* const pkg,
	PackageCompiler::LookupNode const* node,
	bool const force
) {
	TOGO_ASSERTE(pkg && node);
	StringRef const pkg_name = package_compiler::name(*pkg);
	for (; node != nullptr; node = hash_map::get_next(pkg->_lookup, node)) {
		if (!add_resource(groups, pkg, node->value, force)) {
			StringRef const path{pkg->_metadata[node->value - 1].path};
			TOGO_LOGF(
				" N  %.*s / %.*s\n",
				pkg_name.size, pkg_name.data,
				path.size, path.data
			);
		}
	}
}

// Status:
//   N: no compile needed
//   C: compiling

bool interface::command_compile(
	Interface& interface,
	bool const force,
	StringRef const& from_package_name,
	StringRef const* paths,
	unsigned num_paths
) {
	TOGO_ASSERTE(paths || num_paths > 0);

	auto* const from_package = compiler_manager::get_package(
		interface._manager,
		resource::hash_package_name(from_package_name)
	);
	if (from_package_name.any() && !from_package) {
		TOGO_LOG_ERRORF(
			"package '%.*s' not found\n",
			from_package_name.size, from_package_name.data
		);
		return false;
	}

	bool success = true;
	HashMap<ResourcePackageNameHash, Array<u32>*> groups{
		memory::scratch_allocator()
	};
	hash_map::reserve(
		groups,
		array::size(compiler_manager::packages(interface._manager))
	);

	{// Add resources
	PackageCompiler* pkg;
	PackageCompiler::LookupNode* node;
	if (num_paths > 0) {
		ResourcePackageNameHash wd_current_pkg = PKG_NAME_NULL;
		FixedArray<char, 256> wd_prev{};
		TOGO_ASSERTE(filesystem::working_dir(wd_prev));
		StringRef path{};
		ResourcePathParts pp{};
		for (unsigned i = 0; i < num_paths; ++i) {
			path = paths[i];

			// TODO: Typeless parse
			if (!resource::parse_path(path, pp)) {
				success = false;
				TOGO_LOG_ERRORF(
					"failed to parse path: '%.*s'\n",
					path.size, path.data
				);
				continue;
			}

			pkg = from_package;
			if (from_package) {
				node = package_compiler::get_node(
					*from_package, pp.name_hash
				);
			} else {
				node = compiler_manager::get_node(
					interface._manager, pp.name_hash, pkg
				);
			}
			if (node) {
				if (wd_current_pkg != package_compiler::name_hash(*pkg)) {
					if (wd_current_pkg != PKG_NAME_NULL) {
						TOGO_ASSERTE(filesystem::set_working_dir(wd_prev));
					}
					TOGO_ASSERTE(filesystem::set_working_dir(
						package_compiler::path(*pkg)
					));
					wd_current_pkg = package_compiler::name_hash(*pkg);
				}
				add_node(groups, pkg, node, force);
			} else {
				success = false;
				TOGO_LOG_ERRORF(
					"resource does not exist: '%.*s'\n",
					path.size, path.data
				);
			}
		}
		if (wd_current_pkg != PKG_NAME_NULL) {
			TOGO_ASSERTE(filesystem::set_working_dir(wd_prev));
		}
	} else if (from_package) {
		WorkingDirScope wd_scope{package_compiler::path(*from_package)};
		for (auto const& metadata : package_compiler::metadata(*from_package)) {
			add_resource(groups, from_package, metadata.id, force);
		}
	} else {
		// All resources
		for (auto const* pkg : compiler_manager::packages(interface._manager)) {
			WorkingDirScope wd_scope{package_compiler::path(*pkg)};
		for (auto const& metadata : package_compiler::metadata(*pkg)) {
			add_resource(groups, pkg, metadata.id, force);
		}}
	}}

	if (!success) {
		goto l_exit;
	} else if (hash_map::empty(groups)) {
		TOGO_LOG("no resources to build\n");
		goto l_exit;
	}

	// TODO: Write package data after compiling
	{// Compile resources
	PackageCompiler* pkg;
	Array<u32> const* res_list;
	StringRef pkg_name{};
	StringRef path{};
	for (auto const& node : groups) {
		pkg = compiler_manager::get_package(interface._manager, node.key);
		TOGO_ASSERTE(pkg);
		res_list = node.value;
		pkg_name = package_compiler::name(*pkg);
		WorkingDirScope wd_scope{package_compiler::path(*pkg)};
	for (u32 id : *res_list) {
		auto& metadata = pkg->_metadata[id - 1];
		path = StringRef{metadata.path};
		TOGO_LOGF(
			"  C %.*s / %.*s\n",
			pkg_name.size, pkg_name.data,
			path.size, path.data
		);
		if (!compile_resource(interface, *pkg, metadata)) {
			success = false;
			goto l_exit;
		}
	}
		TOGO_LOG("\n");
	}}

l_exit:
	for (auto& node : groups) {
		TOGO_DESTROY(*groups._head._allocator, node.value);
		node.value = nullptr;
	}
	return success;
}

bool interface::command_compile(
	Interface& interface,
	KVS const& k_command_options,
	KVS const& k_command
) {
	bool force = false;
	StringRef from_package_name{};
	for (KVS const& k_opt : k_command_options) {
		switch (kvs::name_hash(k_opt)) {
		case "-f"_kvs_name:
			if (!kvs::is_boolean(k_opt)) {
				TOGO_LOG("error: -f: expected boolean value\n");
				return false;
			}
			force = kvs::boolean(k_opt);
			break;

		case "--from"_kvs_name:
			if (!kvs::is_string(k_opt)) {
				TOGO_LOG("error: --from: expected string value\n");
				return false;
			}
			from_package_name = kvs::string_ref(k_opt);
			break;

		default:
			TOGO_LOGF(
				"error: option '%.*s' not recognized\n",
				kvs::name_size(k_opt), kvs::name(k_opt)
			);
			return false;
		}
	}

	FixedArray<StringRef, 16> paths{};
	for (KVS const& k_res : k_command) {
		if (!kvs::is_string(k_res) || kvs::string_size(k_res) == 0) {
			TOGO_LOG("error: expected non-empty string argument\n");
			return false;
		}
		fixed_array::push_back(paths, kvs::string_ref(k_res));
	}

	return interface::command_compile(
		interface,
		force,
		from_package_name,
		fixed_array::begin(paths),
		fixed_array::size(paths)
	);
}

} // namespace tool_build
} // namespace togo
<commit_msg>tool_build/interface/command_compile: corrected paths assertion.<commit_after>#line 2 "togo/tool_build/interface/command_compile.ipp"
/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

namespace togo {
namespace tool_build {

static bool compile_resource(
	Interface& interface,
	PackageCompiler& pkg,
	ResourceMetadata& metadata
) {
	FixedArray<char, 24> output_path{};
	resource_metadata::output_path(metadata, output_path);

	// Open streams
	FileReader in_stream{};
	FileWriter out_stream{};
	if (!in_stream.open(metadata.path)) {
		TOGO_LOG_ERROR("failed to open source file\n");
		return false;
	}
	if (!out_stream.open(output_path, false)) {
		TOGO_LOG_ERRORF(
			"failed to open output file: '%.*s'\n",
			string::size(output_path), fixed_array::begin(output_path)
		);
		in_stream.close();
		return false;
	}

	{// Compile
	auto const* const compiler = compiler_manager::get_compiler(
		interface._manager,
		metadata.type
	);
	if (!compiler) {
		TOGO_LOG_ERROR("no compiler for type\n");
		return false;
	}
	bool const success = compiler->func_compile(
		interface._manager,
		pkg, metadata,
		in_stream, out_stream
	);
	in_stream.close();
	out_stream.close();
	if (success) {
		metadata.format_version = compiler->format_version;
		metadata.last_compiled = filesystem::time_last_modified(output_path);
	} else {
		metadata.format_version = 0;
		metadata.last_compiled = 0;
		TOGO_LOG_ERROR("failed to compile\n");
		return false;
	}}

	package_compiler::set_modified(pkg, true);
	return true;
}

static bool add_resource(
	HashMap<ResourcePackageNameHash, Array<u32>*>& groups,
	PackageCompiler const* const pkg,
	u32 const id,
	bool const force
) {
	TOGO_ASSERTE(pkg);
	if (id == 0) {
		// Skip holes
		return false;
	}

	auto const& metadata = pkg->_metadata[id - 1];
	StringRef const pkg_name{package_compiler::name(*pkg)};
	StringRef const path{metadata.path};
	u64 const modified = filesystem::time_last_modified(path);
	if (modified == 0) {
		TOGO_LOG_ERRORF(
			"resource file has vanished: %.*s / %.*s\n",
			pkg_name.size, pkg_name.data,
			path.size, path.data
		);
		return false;
	} else if (
		!force &&
		metadata.last_compiled != 0 &&
		metadata.last_compiled >= modified
	) {
		// Resource doesn't need to be compiled
		return false;
	}

	auto const pkg_name_hash = package_compiler::name_hash(*pkg);
	auto** res_list_g = hash_map::get(groups, pkg_name_hash);
	auto* res_list = res_list_g ? *res_list_g : nullptr;
	if (!res_list) {
		Allocator& allocator = *groups._head._allocator;
		res_list = hash_map::push(
			groups, pkg_name_hash,
			TOGO_CONSTRUCT(allocator, Array<u32>, allocator)
		);
		array::reserve(*res_list, 16);
	}
	array::push_back(*res_list, id);
	return true;
}

static void add_node(
	HashMap<ResourcePackageNameHash, Array<u32>*>& groups,
	PackageCompiler const* const pkg,
	PackageCompiler::LookupNode const* node,
	bool const force
) {
	TOGO_ASSERTE(pkg && node);
	StringRef const pkg_name = package_compiler::name(*pkg);
	for (; node != nullptr; node = hash_map::get_next(pkg->_lookup, node)) {
		if (!add_resource(groups, pkg, node->value, force)) {
			StringRef const path{pkg->_metadata[node->value - 1].path};
			TOGO_LOGF(
				" N  %.*s / %.*s\n",
				pkg_name.size, pkg_name.data,
				path.size, path.data
			);
		}
	}
}

// Status:
//   N: no compile needed
//   C: compiling

bool interface::command_compile(
	Interface& interface,
	bool const force,
	StringRef const& from_package_name,
	StringRef const* paths,
	unsigned num_paths
) {
	TOGO_ASSERTE(paths || num_paths == 0);

	auto* const from_package = compiler_manager::get_package(
		interface._manager,
		resource::hash_package_name(from_package_name)
	);
	if (from_package_name.any() && !from_package) {
		TOGO_LOG_ERRORF(
			"package '%.*s' not found\n",
			from_package_name.size, from_package_name.data
		);
		return false;
	}

	bool success = true;
	HashMap<ResourcePackageNameHash, Array<u32>*> groups{
		memory::scratch_allocator()
	};
	hash_map::reserve(
		groups,
		array::size(compiler_manager::packages(interface._manager))
	);

	{// Add resources
	PackageCompiler* pkg;
	PackageCompiler::LookupNode* node;
	if (num_paths > 0) {
		ResourcePackageNameHash wd_current_pkg = PKG_NAME_NULL;
		FixedArray<char, 256> wd_prev{};
		TOGO_ASSERTE(filesystem::working_dir(wd_prev));
		StringRef path{};
		ResourcePathParts pp{};
		for (unsigned i = 0; i < num_paths; ++i) {
			path = paths[i];

			// TODO: Typeless parse
			if (!resource::parse_path(path, pp)) {
				success = false;
				TOGO_LOG_ERRORF(
					"failed to parse path: '%.*s'\n",
					path.size, path.data
				);
				continue;
			}

			pkg = from_package;
			if (from_package) {
				node = package_compiler::get_node(
					*from_package, pp.name_hash
				);
			} else {
				node = compiler_manager::get_node(
					interface._manager, pp.name_hash, pkg
				);
			}
			if (node) {
				if (wd_current_pkg != package_compiler::name_hash(*pkg)) {
					if (wd_current_pkg != PKG_NAME_NULL) {
						TOGO_ASSERTE(filesystem::set_working_dir(wd_prev));
					}
					TOGO_ASSERTE(filesystem::set_working_dir(
						package_compiler::path(*pkg)
					));
					wd_current_pkg = package_compiler::name_hash(*pkg);
				}
				add_node(groups, pkg, node, force);
			} else {
				success = false;
				TOGO_LOG_ERRORF(
					"resource does not exist: '%.*s'\n",
					path.size, path.data
				);
			}
		}
		if (wd_current_pkg != PKG_NAME_NULL) {
			TOGO_ASSERTE(filesystem::set_working_dir(wd_prev));
		}
	} else if (from_package) {
		WorkingDirScope wd_scope{package_compiler::path(*from_package)};
		for (auto const& metadata : package_compiler::metadata(*from_package)) {
			add_resource(groups, from_package, metadata.id, force);
		}
	} else {
		// All resources
		for (auto const* pkg : compiler_manager::packages(interface._manager)) {
			WorkingDirScope wd_scope{package_compiler::path(*pkg)};
		for (auto const& metadata : package_compiler::metadata(*pkg)) {
			add_resource(groups, pkg, metadata.id, force);
		}}
	}}

	if (!success) {
		goto l_exit;
	} else if (hash_map::empty(groups)) {
		TOGO_LOG("no resources to build\n");
		goto l_exit;
	}

	// TODO: Write package data after compiling
	{// Compile resources
	PackageCompiler* pkg;
	Array<u32> const* res_list;
	StringRef pkg_name{};
	StringRef path{};
	for (auto const& node : groups) {
		pkg = compiler_manager::get_package(interface._manager, node.key);
		TOGO_ASSERTE(pkg);
		res_list = node.value;
		pkg_name = package_compiler::name(*pkg);
		WorkingDirScope wd_scope{package_compiler::path(*pkg)};
	for (u32 id : *res_list) {
		auto& metadata = pkg->_metadata[id - 1];
		path = StringRef{metadata.path};
		TOGO_LOGF(
			"  C %.*s / %.*s\n",
			pkg_name.size, pkg_name.data,
			path.size, path.data
		);
		if (!compile_resource(interface, *pkg, metadata)) {
			success = false;
			goto l_exit;
		}
	}
		TOGO_LOG("\n");
	}}

l_exit:
	for (auto& node : groups) {
		TOGO_DESTROY(*groups._head._allocator, node.value);
		node.value = nullptr;
	}
	return success;
}

bool interface::command_compile(
	Interface& interface,
	KVS const& k_command_options,
	KVS const& k_command
) {
	bool force = false;
	StringRef from_package_name{};
	for (KVS const& k_opt : k_command_options) {
		switch (kvs::name_hash(k_opt)) {
		case "-f"_kvs_name:
			if (!kvs::is_boolean(k_opt)) {
				TOGO_LOG("error: -f: expected boolean value\n");
				return false;
			}
			force = kvs::boolean(k_opt);
			break;

		case "--from"_kvs_name:
			if (!kvs::is_string(k_opt)) {
				TOGO_LOG("error: --from: expected string value\n");
				return false;
			}
			from_package_name = kvs::string_ref(k_opt);
			break;

		default:
			TOGO_LOGF(
				"error: option '%.*s' not recognized\n",
				kvs::name_size(k_opt), kvs::name(k_opt)
			);
			return false;
		}
	}

	FixedArray<StringRef, 16> paths{};
	for (KVS const& k_res : k_command) {
		if (!kvs::is_string(k_res) || kvs::string_size(k_res) == 0) {
			TOGO_LOG("error: expected non-empty string argument\n");
			return false;
		}
		fixed_array::push_back(paths, kvs::string_ref(k_res));
	}

	return interface::command_compile(
		interface,
		force,
		from_package_name,
		fixed_array::begin(paths),
		fixed_array::size(paths)
	);
}

} // namespace tool_build
} // namespace togo
<|endoftext|>