<commit_before>#ifdef __APPLE__

    #include <SDL2/SDL.h>

    extern "C" {
        #include <lua.h>
        #include <lualib.h>
        #include <lauxlib.h>
    }

#elif _WIN32

    #define SDL_MAIN_HANDLED
    #include <SDL.h>
    #include <stdio.h>
    #include <lua.hpp>

#endif

#define SCREEN_WIDTH 400
#define SCREEN_HEIGHT 225

#define GAME_WIDTH 256
#define GAME_HEIGHT 144

//http://www.lua.org/manual/5.3/manual.html#lua_CFunction
static int luaTestFunc(lua_State* state)
{
	/* number of arguments */
	int args = lua_gettop(state);

	for (int n = 1; n <= args; ++n) {
		printf("  arg %d: '%s'\n", n, lua_tostring(state, n));
	}

	lua_pushnumber(state, 123);
	return 1; /* number of results */
}

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

    SDL_version compiled;
    SDL_version linked;

    SDL_VERSION(&compiled);
    SDL_GetVersion(&linked);

    printf("We compiled against SDL version %d.%d.%d ...\n",
           compiled.major, compiled.minor, compiled.patch);
    printf("We are linking against SDL version %d.%d.%d.\n",
           linked.major, linked.minor, linked.patch);

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow(
       "unamed-dungeon-crawler",
       SDL_WINDOWPOS_UNDEFINED,
       SDL_WINDOWPOS_UNDEFINED,
       SCREEN_WIDTH*2,
       SCREEN_HEIGHT*2,
       0
    );

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Texture *texture = SDL_CreateTexture(renderer,
                                                SDL_PIXELFORMAT_ARGB8888,
                                                SDL_TEXTUREACCESS_STREAMING,
                                                SCREEN_WIDTH, SCREEN_HEIGHT);

//    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");  // make the scaled rendering look smoother.
//    SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH*4, SCREEN_HEIGHT*4);

    //SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", SDL_GetError(), window);

    SDL_Surface *screen = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
    SDL_Surface *game   = SDL_CreateRGBSurface(0, GAME_WIDTH, GAME_HEIGHT, 32, 0, 0, 0, 0);

    SDL_Surface *testSurface = SDL_LoadBMP("test.bmp");
    SDL_Surface *borderSurface = SDL_LoadBMP("border.bmp");
	SDL_Surface *tile00Surface = SDL_LoadBMP("tile00.bmp");
	SDL_Surface *tile01Surface = SDL_LoadBMP("tile01.bmp");
	SDL_Surface *player = SDL_LoadBMP("player.bmp");

    bool quit = false;

    SDL_Event e;

	//SDL_Rect pos = { 0,40,100,100 };

	//Lua
	lua_State *state = luaL_newstate();
	luaL_openlibs(state);

	lua_register(state, "luaTestFunc", luaTestFunc);

	luaL_dostring(state, "io.write(\"luaTestFunc\")");
	luaL_dostring(state, "luaTestFunc(\"First\", \"Second\", 112233)");

	//Dungeon
	int tilesArray[] = {
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
		1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	};

	int arrayWidth  = 16;
	int arrayHeight = 9;

	int playerPos = 0;

    while (!quit)
    {

        while (SDL_PollEvent(&e) != 0)
        {

            const Uint8 *state = SDL_GetKeyboardState(NULL);

            if (e.type == SDL_QUIT)
            {
                quit = true;
            }

            if (state[SDL_SCANCODE_LEFT]) {

				//int oldPos = playerPos;

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				x -= 1;

				playerPos = x + arrayWidth*y;
            } else

            if (state[SDL_SCANCODE_RIGHT]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				x += 1;

				playerPos = x + arrayWidth*y;
            } else

			if (state[SDL_SCANCODE_UP]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				y -= 1;

				playerPos = x + arrayWidth*y;
			} else

			if (state[SDL_SCANCODE_DOWN]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				y += 1;

				playerPos = x + arrayWidth*y;
			}

        }

		//clear screen surface
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 0));
		SDL_FillRect(game, NULL, SDL_MapRGB(screen->format, 0, 255, 0));

		//render tiles
		for (size_t i = 0; i < arrayWidth * arrayHeight; i++)
		{
			int x = i % arrayWidth;
			int y = (i / arrayWidth) % arrayHeight;

			SDL_Rect pos = { x * 16, y * 16, 16, 16 };

			//printf("x: %i , y: %i\n", x, y);

			if (tilesArray[i] == 0) {

				SDL_BlitSurface(tile00Surface, NULL, game, &pos);
			} else

			if (tilesArray[i] == 1) {

				SDL_BlitSurface(tile01Surface, NULL, game, &pos);
			}
		}

		//render player

		{

			int x = playerPos % arrayWidth;
			int y = (playerPos / arrayWidth) % arrayHeight;

			SDL_Rect pos = { x * 16, y * 16, 16, 16 };
			SDL_BlitSurface(player, NULL, game, &pos);
		}

		//SDL_BlitSurface(testSurface, 0, game, NULL);

		SDL_BlitSurface(borderSurface, 0, screen, 0);

		SDL_Rect location = { 72,40,100,100 };
		SDL_BlitSurface(game, 0, screen, &location);

        SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, 0, 0);
        SDL_RenderPresent(renderer);

        SDL_Delay(16);
    }

	lua_close(state);

    SDL_FreeSurface(testSurface);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;

}
<commit_msg>render text<commit_after>#ifdef __APPLE__

    #include <SDL2/SDL.h>

    extern "C" {
        #include <lua.h>
        #include <lualib.h>
        #include <lauxlib.h>
    }

#elif _WIN32

    #define SDL_MAIN_HANDLED
    #include <SDL.h>
    #include <stdio.h>
    #include <lua.hpp>

#endif

#include <string>

#define SCREEN_WIDTH 400
#define SCREEN_HEIGHT 225

#define GAME_WIDTH 256
#define GAME_HEIGHT 144

//http://www.lua.org/manual/5.3/manual.html#lua_CFunction
static int luaTestFunc(lua_State* state)
{
	/* number of arguments */
	int args = lua_gettop(state);

	for (int n = 1; n <= args; ++n) {
		printf("  arg %d: '%s'\n", n, lua_tostring(state, n));
	}

	lua_pushnumber(state, 123);
	return 1; /* number of results */
}

void renderText(std::string str, SDL_Surface* charSet, SDL_Surface* surf) {

	unsigned int i = 0;
	for (char& c : str) {
		//printf("%c", c);
		unsigned int charIndex = c - 32;
		SDL_Rect src = { 8 * charIndex, 0, 8, 8 };
		SDL_Rect dst = { 8 * i, 16, 8, 8 };

		SDL_BlitSurface(charSet, &src, surf, &dst);
		++i;
	}

}

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

    SDL_version compiled;
    SDL_version linked;

    SDL_VERSION(&compiled);
    SDL_GetVersion(&linked);

    printf("We compiled against SDL version %d.%d.%d ...\n",
           compiled.major, compiled.minor, compiled.patch);
    printf("We are linking against SDL version %d.%d.%d.\n",
           linked.major, linked.minor, linked.patch);

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow(
       "unamed-dungeon-crawler",
       SDL_WINDOWPOS_UNDEFINED,
       SDL_WINDOWPOS_UNDEFINED,
       SCREEN_WIDTH*2,
       SCREEN_HEIGHT*2,
       0
    );

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_Texture *texture = SDL_CreateTexture(renderer,
                                                SDL_PIXELFORMAT_ARGB8888,
                                                SDL_TEXTUREACCESS_STREAMING,
                                                SCREEN_WIDTH, SCREEN_HEIGHT);

//    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");  // make the scaled rendering look smoother.
//    SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH*4, SCREEN_HEIGHT*4);

    //SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "ERROR", SDL_GetError(), window);

    SDL_Surface *screen = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
    SDL_Surface *game   = SDL_CreateRGBSurface(0, GAME_WIDTH, GAME_HEIGHT, 32, 0, 0, 0, 0);

    SDL_Surface *testSurface = SDL_LoadBMP("data/base/test.bmp");
    SDL_Surface *borderSurface = SDL_LoadBMP("data/base/borders/border.bmp");
	SDL_Surface *tile00Surface = SDL_LoadBMP("data/base/tiles/tile00.bmp");
	SDL_Surface *tile01Surface = SDL_LoadBMP("data/base/tiles/tile01.bmp");
	SDL_Surface *player = SDL_LoadBMP("data/base/spritesheets/player.bmp");
	SDL_Surface *bmpFont = SDL_LoadBMP("data/base/fonts/standard_font.bmp");

    bool quit = false;

    SDL_Event e;

	//SDL_Rect pos = { 0,40,100,100 };

	//Lua
	lua_State *state = luaL_newstate();
	luaL_openlibs(state);

	lua_register(state, "luaTestFunc", luaTestFunc);

	luaL_dostring(state, "io.write(\"luaTestFunc\")");
	luaL_dostring(state, "luaTestFunc(\"First\", \"Second\", 112233)");

	//Dungeon
	int tilesArray[] = {
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
		1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1,
		1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
		1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	};

	int arrayWidth  = 16;
	int arrayHeight = 9;

	int playerPos = 0;

    while (!quit)
    {

        while (SDL_PollEvent(&e) != 0)
        {

            const Uint8 *state = SDL_GetKeyboardState(NULL);

            if (e.type == SDL_QUIT)
            {
                quit = true;
            }

            if (state[SDL_SCANCODE_LEFT]) {

				//int oldPos = playerPos;

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				x -= 1;

				playerPos = x + arrayWidth*y;
            } else

            if (state[SDL_SCANCODE_RIGHT]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				x += 1;

				playerPos = x + arrayWidth*y;
            } else

			if (state[SDL_SCANCODE_UP]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				y -= 1;

				playerPos = x + arrayWidth*y;
			} else

			if (state[SDL_SCANCODE_DOWN]) {

				int x = playerPos % arrayWidth;
				int y = (playerPos / arrayWidth) % arrayHeight;

				y += 1;

				playerPos = x + arrayWidth*y;
			}

        }

		//clear screen surface
		SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 0, 0));
		SDL_FillRect(game, NULL, SDL_MapRGB(screen->format, 0, 255, 0));

		//render tiles
		for (size_t i = 0; i < arrayWidth * arrayHeight; i++)
		{
			int x = i % arrayWidth;
			int y = (i / arrayWidth) % arrayHeight;

			SDL_Rect pos = { x * 16, y * 16, 16, 16 };

			//printf("x: %i , y: %i\n", x, y);

			if (tilesArray[i] == 0) {

				SDL_BlitSurface(tile00Surface, NULL, game, &pos);
			} else

			if (tilesArray[i] == 1) {

				SDL_BlitSurface(tile01Surface, NULL, game, &pos);
			}
		}

		//render player

		{

			int x = playerPos % arrayWidth;
			int y = (playerPos / arrayWidth) % arrayHeight;

			SDL_Rect pos = { x * 16, y * 16, 16, 16 };
			SDL_BlitSurface(player, NULL, game, &pos);
		}

		//SDL_BlitSurface(testSurface, 0, game, NULL);

		SDL_BlitSurface(borderSurface, 0, screen, 0);

		SDL_Rect location = { 72,40,100,100 };
		SDL_BlitSurface(game, 0, screen, &location);

		//test
		SDL_BlitSurface(bmpFont, 0, screen, 0);
		renderText(" 0123!", bmpFont, screen);

        SDL_UpdateTexture(texture, NULL, screen->pixels, screen->pitch);
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, 0, 0);
        SDL_RenderPresent(renderer);

        SDL_Delay(16);
    }

	lua_close(state);

    SDL_FreeSurface(testSurface);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: token.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 14:24:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _TOKEN_HXX
#define _TOKEN_HXX

#ifndef _SCANNER_HXX
#include "scanner.hxx"
#endif
#ifndef _SBDEF_HXX
#include <basic/sbdef.hxx>
#endif

#if defined( SHARED )
#define SbiTokenSHAREDTMPUNDEF
#undef SHARED
#endif

// Der Tokenizer ist stand-alone, d.h. er kann von ueberallher verwendet
// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
// werden soll.

enum SbiToken {
    NIL = 0,
    // Token zwischen 0x20 und 0x3F sind Literale:
    LPAREN = '(', RPAREN = ')', COMMA = ',', DOT = '.', EXCLAM = '!',
    HASH = '#', SEMICOLON = ';',

    // Anweisungen:
    FIRSTKWD = 0x40,
    AS = FIRSTKWD, ALIAS, ASSIGN,
    CALL, CASE, CLOSE, COMPARE, _CONST_,
    DECLARE, DIM, DO,

    // in der Reihenfolge der Datentyp-Enums!
    DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFCUR, DEFDATE, DEFSTR, DEFOBJ,
    DEFERR, DEFBOOL, DEFVAR,
    // in der Reihenfolge der Datentyp-Enums!
    DATATYPE1,
    TINTEGER = DATATYPE1,
    TLONG, TSINGLE, TDOUBLE, TCURRENCY, TDATE, TSTRING, TOBJECT,
    _ERROR_, TBOOLEAN, TVARIANT, TBYTE,
    DATATYPE2 = TBYTE,

    EACH, ELSE, ELSEIF, END, ERASE, EXIT,
    FOR, FUNCTION,
    GET, GLOBAL, GOSUB, GOTO,
    IF, _IN_, INPUT,
    LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET,
    NAME, NEW, NEXT,
    ON, OPEN, OPTION, IMPLEMENTS,
    PRINT, PRIVATE, PROPERTY, PUBLIC,
    REDIM, REM, RESUME, RETURN, RSET,
    SELECT, SET, SHARED, STATIC, STEP, STOP, SUB,
    TEXT, THEN, TO, TYPE, ENUM,
    UNTIL,
    WEND, WHILE, WITH, WRITE,
    ENDENUM, ENDIF, ENDFUNC, ENDPROPERTY, ENDSUB, ENDTYPE, ENDSELECT, ENDWITH,
    // Ende aller Keywords
    LASTKWD = ENDWITH,
    // Statement-Ende
    EOS, EOLN,
    // Operatoren:
    EXPON, NEG, MUL,
    DIV, IDIV, MOD, PLUS, MINUS,
    EQ, NE, LT, GT, LE, GE,
    NOT, AND, OR, XOR, EQV,
    IMP, CAT, LIKE, IS, TYPEOF,
    // Sonstiges:
    FIRSTEXTRA,
    NUMBER=FIRSTEXTRA, FIXSTRING, SYMBOL, _CDECL_, BYVAL, BYREF,
    OUTPUT, RANDOM, APPEND, BINARY, ACCESS,
    LOCK, READ, PRESERVE, BASE, ANY, LIB, _OPTIONAL_,
    EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY,

    // Ab hier kommen JavaScript-Tokens (gleiches enum, damit gleicher Typ)
    FIRSTJAVA,
    JS_BREAK=FIRSTJAVA, JS_CONTINUE, JS_FOR, JS_FUNCTION, JS_IF, JS_NEW,
    JS_RETURN, JS_THIS, JS_VAR, JS_WHILE, JS_WITH,

    // JavaScript-Operatoren
    // _ASS_ = Assignment
    JS_COMMA, JS_ASSIGNMENT, JS_ASS_PLUS, JS_ASS_MINUS, JS_ASS_MUL,
    JS_ASS_DIV, JS_ASS_MOD, JS_ASS_LSHIFT, JS_ASS_RSHIFT, JS_ASS_RSHIFT_Z,
    JS_ASS_AND, JS_ASS_XOR, JS_ASS_OR,
    JS_COND_QUEST, JS_COND_SEL, JS_LOG_OR, JS_LOG_AND, JS_BIT_OR,
    JS_BIT_XOR, JS_BIT_AND, JS_EQ, JS_NE, JS_LT, JS_LE,
    JS_GT, JS_GE, JS_LSHIFT, JS_RSHIFT, JS_RSHIFT_Z,
    JS_PLUS, JS_MINUS, JS_MUL, JS_DIV, JS_MOD, JS_LOG_NOT, JS_BIT_NOT,
    JS_INC, JS_DEC, JS_LPAREN, JS_RPAREN, JS_LINDEX, JS_RINDEX
    , VBASUPPORT
};

#ifdef SbiTokenSHAREDTMPUNDEF
#define SHARED
#undef SbiTokenSHAREDTMPUNDEF
#endif

class SbiTokenizer : public SbiScanner {
protected:
    SbiToken eCurTok;               // aktuelles Token
    SbiToken ePush;                 // Pushback-Token
    USHORT  nPLine, nPCol1, nPCol2; // Pushback-Location
    BOOL bEof;                      // TRUE bei Dateiende
    BOOL bEos;                      // TRUE bei Statement-Ende
    BOOL bKeywords;                 // TRUE, falls Keywords geparst werden
    BOOL bAs;                       // letztes Keyword war AS
    BOOL bErrorIsSymbol;            // Handle Error token as Symbol, not keyword
public:
    SbiTokenizer( const ::rtl::OUString&, StarBASIC* = NULL );
   ~SbiTokenizer();

    inline BOOL IsEof()             { return bEof; }
    inline BOOL IsEos()             { return bEos; }

    void  Push( SbiToken );             // Pushback eines Tokens
    const String& Symbol( SbiToken );// Rueckumwandlung

    SbiToken Peek();                    // das naechste Token lesen
    SbiToken Next();                    // Ein Token lesen
    BOOL MayBeLabel( BOOL= FALSE ); // Kann es ein Label sein?

    void Hilite( SbTextPortions& ); // Syntax-Highlighting

    void Error( SbError c ) { GenError( c ); }
    void Error( SbError, SbiToken );
    void Error( SbError, const char* );
    void Error( SbError, String );

    void Keywords( BOOL b ) { bKeywords = b; }

    static BOOL IsEoln( SbiToken t )
        { return BOOL( t == EOS || t == EOLN || t == REM ); }
    static BOOL IsKwd( SbiToken t )
        { return BOOL( t >= FIRSTKWD && t <= LASTKWD ); }
    static BOOL IsExtra( SbiToken t )
        { return BOOL( t >= FIRSTEXTRA ); }
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.12.88); FILE MERGED 2008/04/01 10:48:42 thb 1.12.88.2: #i85898# Stripping all external header guards 2008/03/28 16:07:30 rt 1.12.88.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: token.hxx,v $
 * $Revision: 1.13 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _TOKEN_HXX
#define _TOKEN_HXX

#include "scanner.hxx"
#ifndef _SBDEF_HXX
#include <basic/sbdef.hxx>
#endif

#if defined( SHARED )
#define SbiTokenSHAREDTMPUNDEF
#undef SHARED
#endif

// Der Tokenizer ist stand-alone, d.h. er kann von ueberallher verwendet
// werden. Eine BASIC-Instanz ist fuer Fehlermeldungen notwendig. Ohne
// BASIC werden die Fehler nur gezaehlt. Auch ist Basic notwendig, wenn
// eine erweiterte SBX-Variable zur Erkennung von Datentypen etc. verwendet
// werden soll.

enum SbiToken {
    NIL = 0,
    // Token zwischen 0x20 und 0x3F sind Literale:
    LPAREN = '(', RPAREN = ')', COMMA = ',', DOT = '.', EXCLAM = '!',
    HASH = '#', SEMICOLON = ';',

    // Anweisungen:
    FIRSTKWD = 0x40,
    AS = FIRSTKWD, ALIAS, ASSIGN,
    CALL, CASE, CLOSE, COMPARE, _CONST_,
    DECLARE, DIM, DO,

    // in der Reihenfolge der Datentyp-Enums!
    DEFINT, DEFLNG, DEFSNG, DEFDBL, DEFCUR, DEFDATE, DEFSTR, DEFOBJ,
    DEFERR, DEFBOOL, DEFVAR,
    // in der Reihenfolge der Datentyp-Enums!
    DATATYPE1,
    TINTEGER = DATATYPE1,
    TLONG, TSINGLE, TDOUBLE, TCURRENCY, TDATE, TSTRING, TOBJECT,
    _ERROR_, TBOOLEAN, TVARIANT, TBYTE,
    DATATYPE2 = TBYTE,

    EACH, ELSE, ELSEIF, END, ERASE, EXIT,
    FOR, FUNCTION,
    GET, GLOBAL, GOSUB, GOTO,
    IF, _IN_, INPUT,
    LET, LINE, LINEINPUT, LOCAL, LOOP, LPRINT, LSET,
    NAME, NEW, NEXT,
    ON, OPEN, OPTION, IMPLEMENTS,
    PRINT, PRIVATE, PROPERTY, PUBLIC,
    REDIM, REM, RESUME, RETURN, RSET,
    SELECT, SET, SHARED, STATIC, STEP, STOP, SUB,
    TEXT, THEN, TO, TYPE, ENUM,
    UNTIL,
    WEND, WHILE, WITH, WRITE,
    ENDENUM, ENDIF, ENDFUNC, ENDPROPERTY, ENDSUB, ENDTYPE, ENDSELECT, ENDWITH,
    // Ende aller Keywords
    LASTKWD = ENDWITH,
    // Statement-Ende
    EOS, EOLN,
    // Operatoren:
    EXPON, NEG, MUL,
    DIV, IDIV, MOD, PLUS, MINUS,
    EQ, NE, LT, GT, LE, GE,
    NOT, AND, OR, XOR, EQV,
    IMP, CAT, LIKE, IS, TYPEOF,
    // Sonstiges:
    FIRSTEXTRA,
    NUMBER=FIRSTEXTRA, FIXSTRING, SYMBOL, _CDECL_, BYVAL, BYREF,
    OUTPUT, RANDOM, APPEND, BINARY, ACCESS,
    LOCK, READ, PRESERVE, BASE, ANY, LIB, _OPTIONAL_,
    EXPLICIT, COMPATIBLE, CLASSMODULE, PARAMARRAY,

    // Ab hier kommen JavaScript-Tokens (gleiches enum, damit gleicher Typ)
    FIRSTJAVA,
    JS_BREAK=FIRSTJAVA, JS_CONTINUE, JS_FOR, JS_FUNCTION, JS_IF, JS_NEW,
    JS_RETURN, JS_THIS, JS_VAR, JS_WHILE, JS_WITH,

    // JavaScript-Operatoren
    // _ASS_ = Assignment
    JS_COMMA, JS_ASSIGNMENT, JS_ASS_PLUS, JS_ASS_MINUS, JS_ASS_MUL,
    JS_ASS_DIV, JS_ASS_MOD, JS_ASS_LSHIFT, JS_ASS_RSHIFT, JS_ASS_RSHIFT_Z,
    JS_ASS_AND, JS_ASS_XOR, JS_ASS_OR,
    JS_COND_QUEST, JS_COND_SEL, JS_LOG_OR, JS_LOG_AND, JS_BIT_OR,
    JS_BIT_XOR, JS_BIT_AND, JS_EQ, JS_NE, JS_LT, JS_LE,
    JS_GT, JS_GE, JS_LSHIFT, JS_RSHIFT, JS_RSHIFT_Z,
    JS_PLUS, JS_MINUS, JS_MUL, JS_DIV, JS_MOD, JS_LOG_NOT, JS_BIT_NOT,
    JS_INC, JS_DEC, JS_LPAREN, JS_RPAREN, JS_LINDEX, JS_RINDEX
    , VBASUPPORT
};

#ifdef SbiTokenSHAREDTMPUNDEF
#define SHARED
#undef SbiTokenSHAREDTMPUNDEF
#endif

class SbiTokenizer : public SbiScanner {
protected:
    SbiToken eCurTok;               // aktuelles Token
    SbiToken ePush;                 // Pushback-Token
    USHORT  nPLine, nPCol1, nPCol2; // Pushback-Location
    BOOL bEof;                      // TRUE bei Dateiende
    BOOL bEos;                      // TRUE bei Statement-Ende
    BOOL bKeywords;                 // TRUE, falls Keywords geparst werden
    BOOL bAs;                       // letztes Keyword war AS
    BOOL bErrorIsSymbol;            // Handle Error token as Symbol, not keyword
public:
    SbiTokenizer( const ::rtl::OUString&, StarBASIC* = NULL );
   ~SbiTokenizer();

    inline BOOL IsEof()             { return bEof; }
    inline BOOL IsEos()             { return bEos; }

    void  Push( SbiToken );             // Pushback eines Tokens
    const String& Symbol( SbiToken );// Rueckumwandlung

    SbiToken Peek();                    // das naechste Token lesen
    SbiToken Next();                    // Ein Token lesen
    BOOL MayBeLabel( BOOL= FALSE ); // Kann es ein Label sein?

    void Hilite( SbTextPortions& ); // Syntax-Highlighting

    void Error( SbError c ) { GenError( c ); }
    void Error( SbError, SbiToken );
    void Error( SbError, const char* );
    void Error( SbError, String );

    void Keywords( BOOL b ) { bKeywords = b; }

    static BOOL IsEoln( SbiToken t )
        { return BOOL( t == EOS || t == EOLN || t == REM ); }
    static BOOL IsKwd( SbiToken t )
        { return BOOL( t >= FIRSTKWD && t <= LASTKWD ); }
    static BOOL IsExtra( SbiToken t )
        { return BOOL( t >= FIRSTEXTRA ); }
};

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include "ListS.h"
#include "ListP.h"
#include "StackP.h"
#include "QueueP.h"
#include "PointerBinTree.h"
#include "ListNTree.h"
#include "ListPriorityQueue.h"

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

	ListS<int> t;
	ListP<int> l;
	StackP<int> s;
	QueueP<int> q;
	PointerBinTree<int> B;
	ListNTree<int> nTree;
	ListNTree<int> _tmp;
	ListNTree<int>::Node m, _t;
	ListPriorityQueue<int, int> pQ(PriorityOrder::ASCENDING);
	IQueueNode<int, int> qn1(0, 10);
	IQueueNode<int, int> qn2(0, 4);

	pQ.Add(new IQueueNode<int, int>(0, 5));
	pQ.Add(new IQueueNode<int, int>(1, 10));
	pQ.Add(new IQueueNode<int, int>(2, 4));
	pQ.Add(new IQueueNode<int, int>(3, 8));
	pQ.Add(new IQueueNode<int, int>(4, 7));
	pQ.Add(new IQueueNode<int, int>(10, 10));
	pQ.Add(new IQueueNode<int, int>(20, 6));

	pQ.Print();
	_tmp.AddRoot();
	_t = _tmp.root();
	_tmp.WriteNode(_t, 10);
	_tmp.AddFirstChild(_t, 20);
	_t = _tmp.FirstChild(_t);
	_tmp.AddBrother(_t, 30);

	_tmp.Print();

	nTree.AddRoot();
	m = nTree.root();
	nTree.WriteNode(m, 1);
	nTree.AddFirstChild(m, 2);
	m = nTree.FirstChild(m);
	nTree.AddBrother(m, 3);
	m = nTree.root();
	m = nTree.FirstChild(m);
	nTree.AddFirstChild(m, 4);
	nTree.AddFirstChild(m, 5);
	nTree.Print();

	nTree.AddFirstSubTree(m, _tmp);
	nTree.Print();
	PointerBinTree<int>::Node n;
	B.AddRoot();
	n = B.root();
	B.write(n, 1);
	B.AddLeft(n);
	B.AddRight(n);
	B.write(B.left(n), 2);
	B.write(B.right(n), 3);

	std::cout << B;

	q.Push(1);
	q.Push(2);
	q.Push(3);
	q.Print();
	q.Print();

	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Print();
	std::cout << s;
	ListP<int>::iterator first = l.begin();
	l.Add(3, first);
	first = l.Next(first);
	l.Add(4, first);
	first = l.Next(first);
	l.Add(6, first);

	std::cout << l;

	l.Remove(4);
	std::cout << l;
	first = l.Next(first);
	l.Add(12);
	std::cout << l;
	/*t.Add(1);
	t.Add(2);
	t.Add(3);
	t.Add(4);
	t.Add(5);
	t.Add(6);
	t.Add(7);
	t.Reverse();
	t.Add(12);
	t.Add(2);
	t.Add(18);
	t.Add(14);
	t.Add(1);
	t.Add(23);
	t.Add(3);
	t.Sort();
	t.Remove(23);
	t.Add(10, 5);
	t.Add(3, 7);
	t[5] = 200;
	auto i = t[5];*/

	return 0;
}<commit_msg>Added Graph test :-1:<commit_after>#include <iostream>
#include "ListS.h"
#include "ListP.h"
#include "StackP.h"
#include "QueueP.h"
#include "PointerBinTree.h"
#include "ListNTree.h"
#include "ListPriorityQueue.h"
#include "GrafoList.h"

int main(int argc, char** argv)
{
	using namespace std;
	GrafoList<string, double> G(10);

	NodoG n1, n2, n3, n4, n5, n6;

	G.insNodo(n1);
	G.scriviEtichetta(n1, "a");
	G.insNodo(n2);
	G.scriviEtichetta(n2, "b");
	G.insNodo(n3);
	G.scriviEtichetta(n3, "c");
	G.insNodo(n4);
	G.scriviEtichetta(n4, "d");
	G.insNodo(n5);
	G.scriviEtichetta(n5, "e");
	G.insNodo(n6);
	G.scriviEtichetta(n6, "f");

	G.insArco(n1, n2, 1.0);
	G.insArco(n1, n3, 0.9);
	G.insArco(n1, n5, 0.3);
	G.insArco(n2, n4, 0.1);
	G.insArco(n2, n6, 0.2);
	G.insArco(n3, n4, 1.0);
	G.insArco(n3, n6, 0.7);
	G.insArco(n4, n1, 0.5);
	G.insArco(n5, n2, 0.4);
	G.insArco(n5, n3, 0.2);
	G.insArco(n6, n4, 0.1);

	cout << "\nNumNodi " << G.numNodi();
	cout << "\nNumArchi " << G.numArchi();

	G.cancNodo(n6);

	cout << "\nNumNodi " << G.numNodi() << endl;

	GrafoList<string, double>::ListaNodi L = G.Adiacenti(n1);

	GrafoList<string, double>::ListaNodiPos p;
	GrafoList<string, double>::Arco a;

	a.nodo1 = n1;
	a.nodo2 = n4;

	cout << "Adiacenti di " << G.leggiEtichetta(n1).c_str() << "--> ";
	p = L.begin();
	while (!L.end(p)){
		cout << G.leggiEtichetta(*(L.read(p))).c_str() << " ";
		p = L.next(p);
	}

	auto arc = G.esisteArco(a);
	auto existnode = G.esisteNodo(*(new NodoG(5)));
	ListS<int> t;
	ListP<int> l;
	StackP<int> s;
	QueueP<int> q;
	PointerBinTree<int> B;
	ListNTree<int> nTree;
	ListNTree<int> _tmp;
	ListNTree<int>::Node m, _t;
	ListPriorityQueue<int, int> pQ(PriorityOrder::ASCENDING);
	IQueueNode<int, int> qn1(0, 10);
	IQueueNode<int, int> qn2(0, 4);

	pQ.Add(new IQueueNode<int, int>(0, 5));
	pQ.Add(new IQueueNode<int, int>(1, 10));
	pQ.Add(new IQueueNode<int, int>(2, 4));
	pQ.Add(new IQueueNode<int, int>(3, 8));
	pQ.Add(new IQueueNode<int, int>(4, 7));
	pQ.Add(new IQueueNode<int, int>(10, 10));
	pQ.Add(new IQueueNode<int, int>(20, 6));

	pQ.Print();
	_tmp.AddRoot();
	_t = _tmp.root();
	_tmp.WriteNode(_t, 10);
	_tmp.AddFirstChild(_t, 20);
	_t = _tmp.FirstChild(_t);
	_tmp.AddBrother(_t, 30);

	_tmp.Print();

	nTree.AddRoot();
	m = nTree.root();
	nTree.WriteNode(m, 1);
	nTree.AddFirstChild(m, 2);
	m = nTree.FirstChild(m);
	nTree.AddBrother(m, 3);
	m = nTree.root();
	m = nTree.FirstChild(m);
	nTree.AddFirstChild(m, 4);
	nTree.AddFirstChild(m, 5);
	nTree.Print();

	nTree.AddFirstSubTree(m, _tmp);
	nTree.Print();
	PointerBinTree<int>::Node n;
	B.AddRoot();
	n = B.root();
	B.write(n, 1);
	B.AddLeft(n);
	B.AddRight(n);
	B.write(B.left(n), 2);
	B.write(B.right(n), 3);

	std::cout << B;

	q.Push(1);
	q.Push(2);
	q.Push(3);
	q.Print();
	q.Print();

	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Print();
	std::cout << s;
	ListP<int>::iterator first = l.begin();
	l.Add(3, first);
	first = l.Next(first);
	l.Add(4, first);
	first = l.Next(first);
	l.Add(6, first);

	std::cout << l;

	l.Remove(4);
	std::cout << l;
	first = l.Next(first);
	l.Add(12);
	std::cout << l;
	/*t.Add(1);
	t.Add(2);
	t.Add(3);
	t.Add(4);
	t.Add(5);
	t.Add(6);
	t.Add(7);
	t.Reverse();
	t.Add(12);
	t.Add(2);
	t.Add(18);
	t.Add(14);
	t.Add(1);
	t.Add(23);
	t.Add(3);
	t.Sort();
	t.Remove(23);
	t.Add(10, 5);
	t.Add(3, 7);
	t[5] = 200;
	auto i = t[5];*/

	return 0;
}<|endoftext|>


<commit_before>#include "eval.hh"
#include "command.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
#include "derivations.hh"
#include "affinity.hh"
#include "progress-bar.hh"

#include <regex>

using namespace nix;

struct Var
{
    bool exported;
    std::string value; // quoted string or array
};

struct BuildEnvironment
{
    std::map<std::string, Var> env;
    std::string bashFunctions;
};

BuildEnvironment readEnvironment(const Path & path)
{
    BuildEnvironment res;

    std::set<std::string> exported;

    debug("reading environment file '%s'", path);

    auto file = readFile(path);

    auto pos = file.cbegin();

    static std::string varNameRegex =
        R"re((?:[a-zA-Z_][a-zA-Z0-9_]*))re";

    static std::regex declareRegex(
        "^declare -x (" + varNameRegex + ")" +
        R"re((?:="((?:[^"\\]|\\.)*)")?\n)re");

    static std::string simpleStringRegex =
        R"re((?:[a-zA-Z0-9_/:\.\-\+=]*))re";

    static std::string quotedStringRegex =
        R"re((?:\$?'(?:[^'\\]|\\[abeEfnrtv\\'"?])*'))re";

    static std::string arrayRegex =
        R"re((?:\(( *\[[^\]]+\]="(?:[^"\\]|\\.)*")*\)))re";

    static std::regex varRegex(
        "^(" + varNameRegex + ")=(" + simpleStringRegex + "|" + quotedStringRegex + "|" + arrayRegex + ")\n");

    static std::regex functionRegex(
        "^" + varNameRegex + " \\(\\) *\n");

    while (pos != file.end()) {

        std::smatch match;

        if (std::regex_search(pos, file.cend(), match, declareRegex)) {
            pos = match[0].second;
            exported.insert(match[1]);
        }

        else if (std::regex_search(pos, file.cend(), match, varRegex)) {
            pos = match[0].second;
            res.env.insert({match[1], Var { (bool) exported.count(match[1]), match[2] }});
        }

        else if (std::regex_search(pos, file.cend(), match, functionRegex)) {
            res.bashFunctions = std::string(pos, file.cend());
            break;
        }

        else throw Error("shell environment '%s' has unexpected line '%s'",
            path, file.substr(pos - file.cbegin(), 60));
    }

    return res;
}

/* Given an existing derivation, return the shell environment as
   initialised by stdenv's setup script. We do this by building a
   modified derivation with the same dependencies and nearly the same
   initial environment variables, that just writes the resulting
   environment to a file and exits. */
StorePath getDerivationEnvironment(ref<Store> store, Derivation drv)
{
    auto builder = baseNameOf(drv.builder);
    if (builder != "bash")
        throw Error("'nix dev-shell' only works on derivations that use 'bash' as their builder");

    drv.args = {
        "-c",
        "set -e; "
        "export IN_NIX_SHELL=impure; "
        "export dontAddDisableDepTrack=1; "
        "if [[ -n $stdenv ]]; then "
        "  source $stdenv/setup; "
        "fi; "
        "export > $out; "
        "set >> $out "};

    /* Remove derivation checks. */
    drv.env.erase("allowedReferences");
    drv.env.erase("allowedRequisites");
    drv.env.erase("disallowedReferences");
    drv.env.erase("disallowedRequisites");

    // FIXME: handle structured attrs

    /* Rehash and write the derivation. FIXME: would be nice to use
       'buildDerivation', but that's privileged. */
    auto drvName = drv.env["name"] + "-env";
    for (auto & output : drv.outputs)
        drv.env.erase(output.first);
    drv.env["out"] = "";
    drv.env["outputs"] = "out";
    Hash h = hashDerivationModulo(*store, drv, true);
    auto shellOutPath = store->makeOutputPath("out", h, drvName);
    drv.outputs.insert_or_assign("out", DerivationOutput(shellOutPath.clone(), "", ""));
    drv.env["out"] = store->printStorePath(shellOutPath);
    auto shellDrvPath2 = writeDerivation(store, drv, drvName);

    /* Build the derivation. */
    store->buildPaths({shellDrvPath2});

    assert(store->isValidPath(shellOutPath));

    return shellOutPath;
}

struct Common : InstallableCommand, MixProfile
{
    std::set<string> ignoreVars{
        "BASHOPTS",
        "EUID",
        "HOME", // FIXME: don't ignore in pure mode?
        "NIX_BUILD_TOP",
        "NIX_ENFORCE_PURITY",
        "NIX_LOG_FD",
        "PPID",
        "PWD",
        "SHELLOPTS",
        "SHLVL",
        "SSL_CERT_FILE", // FIXME: only want to ignore /no-cert-file.crt
        "TEMP",
        "TEMPDIR",
        "TERM",
        "TMP",
        "TMPDIR",
        "TZ",
        "UID",
    };

    void makeRcScript(const BuildEnvironment & buildEnvironment, std::ostream & out)
    {
        out << "nix_saved_PATH=\"$PATH\"\n";

        for (auto & i : buildEnvironment.env) {
            if (!ignoreVars.count(i.first) && !hasPrefix(i.first, "BASH_")) {
                out << fmt("%s=%s\n", i.first, i.second.value);
                if (i.second.exported)
                    out << fmt("export %s\n", i.first);
            }
        }

        out << "PATH=\"$PATH:$nix_saved_PATH\"\n";

        out << buildEnvironment.bashFunctions << "\n";

        // FIXME: set outputs

        out << "export NIX_BUILD_TOP=\"$(mktemp -d --tmpdir nix-shell.XXXXXX)\"\n";
        for (auto & i : {"TMP", "TMPDIR", "TEMP", "TEMPDIR"})
            out << fmt("export %s=\"$NIX_BUILD_TOP\"\n", i);

        out << "eval \"$shellHook\"\n";
    }

    StorePath getShellOutPath(ref<Store> store)
    {
        auto path = installable->getStorePath();
        if (path && hasSuffix(path->to_string(), "-env"))
            return path->clone();
        else {
            auto drvs = toDerivations(store, {installable});

            if (drvs.size() != 1)
                throw Error("'%s' needs to evaluate to a single derivation, but it evaluated to %d derivations",
                    installable->what(), drvs.size());

            auto & drvPath = *drvs.begin();

            return getDerivationEnvironment(store, store->derivationFromPath(drvPath));
        }
    }

    std::pair<BuildEnvironment, std::string> getBuildEnvironment(ref<Store> store)
    {
        auto shellOutPath = getShellOutPath(store);

        auto strPath = store->printStorePath(shellOutPath);

        updateProfile(shellOutPath);

        return {readEnvironment(strPath), strPath};
    }
};

struct CmdDevShell : Common, MixEnvironment
{
    std::vector<std::string> command;

    CmdDevShell()
    {
        mkFlag()
            .longName("command")
            .shortName('c')
            .description("command and arguments to be executed insted of an interactive shell")
            .labels({"command", "args"})
            .arity(ArityAny)
            .handler([&](std::vector<std::string> ss) {
                if (ss.empty()) throw UsageError("--command requires at least one argument");
                command = ss;
            });
    }

    std::string description() override
    {
        return "run a bash shell that provides the build environment of a derivation";
    }

    Examples examples() override
    {
        return {
            Example{
                "To get the build environment of GNU hello:",
                "nix dev-shell nixpkgs.hello"
            },
            Example{
                "To store the build environment in a profile:",
                "nix dev-shell --profile /tmp/my-shell nixpkgs.hello"
            },
            Example{
                "To use a build environment previously recorded in a profile:",
                "nix dev-shell /tmp/my-shell"
            },
        };
    }

    void run(ref<Store> store) override
    {
        auto [buildEnvironment, gcroot] = getBuildEnvironment(store);

        auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");

        std::ostringstream ss;
        makeRcScript(buildEnvironment, ss);

        ss << fmt("rm -f '%s'\n", rcFilePath);

        if (!command.empty()) {
            std::vector<std::string> args;
            for (auto s : command)
                args.push_back(shellEscape(s));
            ss << fmt("exec %s\n", concatStringsSep(" ", args));
        }

        writeFull(rcFileFd.get(), ss.str());

        stopProgressBar();

        auto shell = getEnv("SHELL").value_or("bash");

        setEnviron();
        // prevent garbage collection until shell exits
        setenv("GCROOT", gcroot.data(), 1);

        auto args = Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};

        restoreAffinity();
        restoreSignals();

        execvp(shell.c_str(), stringsToCharPtrs(args).data());

        throw SysError("executing shell '%s'", shell);
    }
};

struct CmdPrintDevEnv : Common
{
    std::string description() override
    {
        return "print shell code that can be sourced by bash to reproduce the build environment of a derivation";
    }

    Examples examples() override
    {
        return {
            Example{
                "To apply the build environment of GNU hello to the current shell:",
                ". <(nix print-dev-env nixpkgs.hello)"
            },
        };
    }

    void run(ref<Store> store) override
    {
        auto buildEnvironment = getBuildEnvironment(store).first;

        stopProgressBar();

        makeRcScript(buildEnvironment, std::cout);
    }
};

static auto r1 = registerCommand<CmdPrintDevEnv>("print-dev-env");
static auto r2 = registerCommand<CmdDevShell>("dev-shell");
<commit_msg>rename to NIX_GCROOT<commit_after>#include "eval.hh"
#include "command.hh"
#include "common-args.hh"
#include "shared.hh"
#include "store-api.hh"
#include "derivations.hh"
#include "affinity.hh"
#include "progress-bar.hh"

#include <regex>

using namespace nix;

struct Var
{
    bool exported;
    std::string value; // quoted string or array
};

struct BuildEnvironment
{
    std::map<std::string, Var> env;
    std::string bashFunctions;
};

BuildEnvironment readEnvironment(const Path & path)
{
    BuildEnvironment res;

    std::set<std::string> exported;

    debug("reading environment file '%s'", path);

    auto file = readFile(path);

    auto pos = file.cbegin();

    static std::string varNameRegex =
        R"re((?:[a-zA-Z_][a-zA-Z0-9_]*))re";

    static std::regex declareRegex(
        "^declare -x (" + varNameRegex + ")" +
        R"re((?:="((?:[^"\\]|\\.)*)")?\n)re");

    static std::string simpleStringRegex =
        R"re((?:[a-zA-Z0-9_/:\.\-\+=]*))re";

    static std::string quotedStringRegex =
        R"re((?:\$?'(?:[^'\\]|\\[abeEfnrtv\\'"?])*'))re";

    static std::string arrayRegex =
        R"re((?:\(( *\[[^\]]+\]="(?:[^"\\]|\\.)*")*\)))re";

    static std::regex varRegex(
        "^(" + varNameRegex + ")=(" + simpleStringRegex + "|" + quotedStringRegex + "|" + arrayRegex + ")\n");

    static std::regex functionRegex(
        "^" + varNameRegex + " \\(\\) *\n");

    while (pos != file.end()) {

        std::smatch match;

        if (std::regex_search(pos, file.cend(), match, declareRegex)) {
            pos = match[0].second;
            exported.insert(match[1]);
        }

        else if (std::regex_search(pos, file.cend(), match, varRegex)) {
            pos = match[0].second;
            res.env.insert({match[1], Var { (bool) exported.count(match[1]), match[2] }});
        }

        else if (std::regex_search(pos, file.cend(), match, functionRegex)) {
            res.bashFunctions = std::string(pos, file.cend());
            break;
        }

        else throw Error("shell environment '%s' has unexpected line '%s'",
            path, file.substr(pos - file.cbegin(), 60));
    }

    return res;
}

/* Given an existing derivation, return the shell environment as
   initialised by stdenv's setup script. We do this by building a
   modified derivation with the same dependencies and nearly the same
   initial environment variables, that just writes the resulting
   environment to a file and exits. */
StorePath getDerivationEnvironment(ref<Store> store, Derivation drv)
{
    auto builder = baseNameOf(drv.builder);
    if (builder != "bash")
        throw Error("'nix dev-shell' only works on derivations that use 'bash' as their builder");

    drv.args = {
        "-c",
        "set -e; "
        "export IN_NIX_SHELL=impure; "
        "export dontAddDisableDepTrack=1; "
        "if [[ -n $stdenv ]]; then "
        "  source $stdenv/setup; "
        "fi; "
        "export > $out; "
        "set >> $out "};

    /* Remove derivation checks. */
    drv.env.erase("allowedReferences");
    drv.env.erase("allowedRequisites");
    drv.env.erase("disallowedReferences");
    drv.env.erase("disallowedRequisites");

    // FIXME: handle structured attrs

    /* Rehash and write the derivation. FIXME: would be nice to use
       'buildDerivation', but that's privileged. */
    auto drvName = drv.env["name"] + "-env";
    for (auto & output : drv.outputs)
        drv.env.erase(output.first);
    drv.env["out"] = "";
    drv.env["outputs"] = "out";
    Hash h = hashDerivationModulo(*store, drv, true);
    auto shellOutPath = store->makeOutputPath("out", h, drvName);
    drv.outputs.insert_or_assign("out", DerivationOutput(shellOutPath.clone(), "", ""));
    drv.env["out"] = store->printStorePath(shellOutPath);
    auto shellDrvPath2 = writeDerivation(store, drv, drvName);

    /* Build the derivation. */
    store->buildPaths({shellDrvPath2});

    assert(store->isValidPath(shellOutPath));

    return shellOutPath;
}

struct Common : InstallableCommand, MixProfile
{
    std::set<string> ignoreVars{
        "BASHOPTS",
        "EUID",
        "HOME", // FIXME: don't ignore in pure mode?
        "NIX_BUILD_TOP",
        "NIX_ENFORCE_PURITY",
        "NIX_LOG_FD",
        "PPID",
        "PWD",
        "SHELLOPTS",
        "SHLVL",
        "SSL_CERT_FILE", // FIXME: only want to ignore /no-cert-file.crt
        "TEMP",
        "TEMPDIR",
        "TERM",
        "TMP",
        "TMPDIR",
        "TZ",
        "UID",
    };

    void makeRcScript(const BuildEnvironment & buildEnvironment, std::ostream & out)
    {
        out << "nix_saved_PATH=\"$PATH\"\n";

        for (auto & i : buildEnvironment.env) {
            if (!ignoreVars.count(i.first) && !hasPrefix(i.first, "BASH_")) {
                out << fmt("%s=%s\n", i.first, i.second.value);
                if (i.second.exported)
                    out << fmt("export %s\n", i.first);
            }
        }

        out << "PATH=\"$PATH:$nix_saved_PATH\"\n";

        out << buildEnvironment.bashFunctions << "\n";

        // FIXME: set outputs

        out << "export NIX_BUILD_TOP=\"$(mktemp -d --tmpdir nix-shell.XXXXXX)\"\n";
        for (auto & i : {"TMP", "TMPDIR", "TEMP", "TEMPDIR"})
            out << fmt("export %s=\"$NIX_BUILD_TOP\"\n", i);

        out << "eval \"$shellHook\"\n";
    }

    StorePath getShellOutPath(ref<Store> store)
    {
        auto path = installable->getStorePath();
        if (path && hasSuffix(path->to_string(), "-env"))
            return path->clone();
        else {
            auto drvs = toDerivations(store, {installable});

            if (drvs.size() != 1)
                throw Error("'%s' needs to evaluate to a single derivation, but it evaluated to %d derivations",
                    installable->what(), drvs.size());

            auto & drvPath = *drvs.begin();

            return getDerivationEnvironment(store, store->derivationFromPath(drvPath));
        }
    }

    std::pair<BuildEnvironment, std::string> getBuildEnvironment(ref<Store> store)
    {
        auto shellOutPath = getShellOutPath(store);

        auto strPath = store->printStorePath(shellOutPath);

        updateProfile(shellOutPath);

        return {readEnvironment(strPath), strPath};
    }
};

struct CmdDevShell : Common, MixEnvironment
{
    std::vector<std::string> command;

    CmdDevShell()
    {
        mkFlag()
            .longName("command")
            .shortName('c')
            .description("command and arguments to be executed insted of an interactive shell")
            .labels({"command", "args"})
            .arity(ArityAny)
            .handler([&](std::vector<std::string> ss) {
                if (ss.empty()) throw UsageError("--command requires at least one argument");
                command = ss;
            });
    }

    std::string description() override
    {
        return "run a bash shell that provides the build environment of a derivation";
    }

    Examples examples() override
    {
        return {
            Example{
                "To get the build environment of GNU hello:",
                "nix dev-shell nixpkgs.hello"
            },
            Example{
                "To store the build environment in a profile:",
                "nix dev-shell --profile /tmp/my-shell nixpkgs.hello"
            },
            Example{
                "To use a build environment previously recorded in a profile:",
                "nix dev-shell /tmp/my-shell"
            },
        };
    }

    void run(ref<Store> store) override
    {
        auto [buildEnvironment, gcroot] = getBuildEnvironment(store);

        auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");

        std::ostringstream ss;
        makeRcScript(buildEnvironment, ss);

        ss << fmt("rm -f '%s'\n", rcFilePath);

        if (!command.empty()) {
            std::vector<std::string> args;
            for (auto s : command)
                args.push_back(shellEscape(s));
            ss << fmt("exec %s\n", concatStringsSep(" ", args));
        }

        writeFull(rcFileFd.get(), ss.str());

        stopProgressBar();

        auto shell = getEnv("SHELL").value_or("bash");

        setEnviron();
        // prevent garbage collection until shell exits
        setenv("NIX_GCROOT", gcroot.data(), 1);

        auto args = Strings{std::string(baseNameOf(shell)), "--rcfile", rcFilePath};

        restoreAffinity();
        restoreSignals();

        execvp(shell.c_str(), stringsToCharPtrs(args).data());

        throw SysError("executing shell '%s'", shell);
    }
};

struct CmdPrintDevEnv : Common
{
    std::string description() override
    {
        return "print shell code that can be sourced by bash to reproduce the build environment of a derivation";
    }

    Examples examples() override
    {
        return {
            Example{
                "To apply the build environment of GNU hello to the current shell:",
                ". <(nix print-dev-env nixpkgs.hello)"
            },
        };
    }

    void run(ref<Store> store) override
    {
        auto buildEnvironment = getBuildEnvironment(store).first;

        stopProgressBar();

        makeRcScript(buildEnvironment, std::cout);
    }
};

static auto r1 = registerCommand<CmdPrintDevEnv>("print-dev-env");
static auto r2 = registerCommand<CmdDevShell>("dev-shell");
<|endoftext|>


<commit_before>#include "app-cmdline.h"
#include "debug.h"

#ifdef QT_GUI_LIB
#include "app-gui.h"
#endif

extern "C" {
#include "optparse.h"
#include "warnp.h"
}

#include <TSettings.h>

#include <stdlib.h>

int main(int argc, char *argv[])
{
    struct optparse *opt;
    int              ret;

    // Initialize debug messages.
    WARNP_INIT;
    ConsoleLog::instance().initializeConsoleLog();

    // Parse command-line arguments
    if((opt = optparse_parse(argc, argv)) == NULL)
    {
        ret = EXIT_FAILURE;
        goto done;
    }

    // Should we use the gui or non-gui app?
    if(opt->check == 0)
    {
#ifdef QT_GUI_LIB
        // Basic initialization that cannot fail.
        AppGui app(argc, argv, opt);
        optparse_free(opt);

        // Run more complicated initialization.
        if(!app.initializeCore())
        {
            ret = EXIT_FAILURE;
            goto done;
        }

        // If we want the GUI or have any tasks, do them.
        if(app.prepMainLoop())
            ret = app.exec();
        else
            ret = EXIT_SUCCESS;
#else
        qDebug() << "This binary does not support GUI operations.  Try:\n\t"
                 << argv[0] << "-h";
        exit(1);
#endif
    }
    else
    {
        // Basic initialization that cannot fail.
        AppCmdline app(argc, argv, opt);
        optparse_free(opt);

        // Run more complicated initialization.
        if(!app.initializeCore())
        {
            ret = EXIT_FAILURE;
            goto done;
        }

        // If we want have any tasks, do them.
        if(app.prepMainLoop())
            ret = app.exec();
        else
            ret = EXIT_SUCCESS;
    }

done:
    // Clean up
    TSettings::destroy();

    return (ret);
}
<commit_msg>main: cleaner organization<commit_after>#include "app-cmdline.h"
#include "debug.h"

#ifdef QT_GUI_LIB
#include "app-gui.h"
#endif

extern "C" {
#include "optparse.h"
#include "warnp.h"
}

#include <TSettings.h>

#include <stdlib.h>

int main(int argc, char *argv[])
{
    struct optparse *opt;
    int              ret;

    // Initialize debug messages.
    WARNP_INIT;
    ConsoleLog::instance().initializeConsoleLog();

    // Parse command-line arguments
    if((opt = optparse_parse(argc, argv)) == NULL)
    {
        ret = EXIT_FAILURE;
        goto done;
    }

    // Should we use the gui or non-gui app?
    if(opt->check == 0)
    {
#ifdef QT_GUI_LIB
        // Basic initialization that cannot fail.
        AppGui app(argc, argv, opt);

        // Run more complicated initialization.
        if(!app.initializeCore())
        {
            ret = EXIT_FAILURE;
            goto done;
        }

        // If we want the GUI or have any tasks, do them.
        if(app.prepMainLoop())
            ret = app.exec();
        else
            ret = EXIT_SUCCESS;
#else
        warn0("This binary does not support GUI operations");
        ret = 1;
        goto done;
#endif
    }
    else
    {
        // Basic initialization that cannot fail.
        AppCmdline app(argc, argv, opt);

        // Run more complicated initialization.
        if(!app.initializeCore())
        {
            ret = EXIT_FAILURE;
            goto done;
        }

        // If we want have any tasks, do them.
        if(app.prepMainLoop())
            ret = app.exec();
        else
            ret = EXIT_SUCCESS;
    }

done:
    // Clean up
    TSettings::destroy();
    optparse_free(opt);

    return (ret);
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ?
                    name
                    : name, name.find_first_of('/') + 1, name.size() - 1), m_checksum(checksum)
    {}
        std::string name() const { return m_name; }
        std::string checksum() const { return m_checksum; }
        void fetch()
        {
            std::cout << "pretending to fetch " << name() << std::endl;
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                    //for (auto s : elems)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        if (k > 1 && i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                        std::cout << "the path: " << path << std::endl;
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                    //std::cout << "opened path " << path << std::endl;
                }
            }
            if (fs.good())
            {
                fs.close();
                //const std::string calcsum(file_checksum(name()));
                /*
                std::cout << "calced sum for " << name()
                    << " : " << calcsum << ", expected " << checksum() << std::endl;
                    */
                //if (calcsum == checksum())
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            const std::string calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

std::string file_checksum(const std::string &path)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }
    else
    {
        //std::cout << "opened file " << path << std::endl;
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */
    //std::cout << calcsum.str() << std::endl;
    return calcsum.str();
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();
    //std::cout << fetch << std::endl;
    std::vector<std::string> v(split(fetch, '\n'));
    //split(fetch, '\n', v);
    //std::cout << v[1] << std::endl;
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(v), end = std::end(v);
            beg != end; ++beg)
    {
        auto w(split(*beg, '@'));
        /*
        for (const auto & sss : w)
        {
            std::cout << sss << ", " << std::endl;
        }
        */
        Target t(w[0], w[w.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
        //std::cout << *beg << std::endl;
    }
    std::stringstream ss(fetch);
    std::string item;
    //std::vector<std::pair<std::string, std::string>> new_targets;
    while (std::getline(ss, item))
    {
        //new_targets.push_back(item);
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        //for (auto &t : new_targets)
        {
            //std::cout << t << std::endl;
            //t.fetch();
        }
        std::cout << new_targets[4] << std::endl;
        new_targets[1].fetch();
        new_targets[4].fetch();
        /*
        for (auto s : split(new_targets[4].name(), '/'))
        {
            if (s.length())
            {
                std::cout << s << ", ";
            }
        }
        */
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }
    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }
    const std::string path = "bin/override/spells.2da";
    const std::string checksum("38eaad974c15e5f3119469f17e8e97a9");
    std::cout << "file checksum test: "
        << path << " = " << checksum
        << " : " << (file_checksum(path) == checksum)
        << std::endl;

    std::cout << std::endl;
    return 0;
}
<commit_msg>Add better info messages.<commit_after>#include <algorithm>
#include <array>
#include <iomanip>
#include <curl/curl.h>
#include <memory>
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <system_error>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>

const std::string listing("http://nwn.efupw.com/rootdir/index.dat");
const std::string patch_dir("http://nwn.efupw.com/rootdir/patch/");
const std::string update_check("");

std::string file_checksum(const std::string &path);

size_t writefunction(const char *ptr, size_t size, size_t nmemb, void *userdata)
{
    std::string *s = static_cast<std::string *>(userdata);
    s->append(ptr, size * nmemb);
    return size * nmemb;
}

std::vector<std::string> &split(const std::string &s, char delim,
        std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

std::vector<std::string> split(const std::string &s, char delim)
{
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

class Target
{
    public:
        enum class Status {
            Nonexistent,
            Outdated,
            Current
        };
        explicit Target(const std::string &name, const std::string &checksum):
            m_name(name.find_first_of('/') == std::string::npos ?
                    name
                    : name, name.find_first_of('/') + 1, name.size() - 1), m_checksum(checksum)
    {}
        std::string name() const { return m_name; }
        std::string checksum() const { return m_checksum; }

        void fetch()
        {
            std::cout << "Statting target " << name() << "...";
            std::string path;
            std::fstream fs(name(), std::ios_base::in);
            if (!fs.good())
            {
                fs.close();
                std::cout << " doesn't exist, creating new." << std::endl;
                auto elems = split(name(), '/');
                for (size_t i = 0, k = elems.size(); i < k; ++i)
                    //for (auto s : elems)
                {
                    const std::string &s(elems[i]);
                    if (s.size() && s != ".")
                    {
                        path.append((i > 0 ? "/" : "") + s);
                        if (k > 1 && i < k - 1)
                        {
                            auto status = mkdir(path.c_str(), S_IRWXU);
                            if (status == -1)
                            {
                                std::error_code err(errno, std::generic_category());
                                if (err != std::errc::file_exists)
                                {
                                    std::cout << "error making dir: "
                                        << path << ": "
                                        << err.message() << std::endl;
                                }
                            }
                        }
                        //std::cout << "the path: " << path << std::endl;
                    }
                }
                fs.open(path, std::ios_base::out);
                if (!fs.good())
                {
                    fs.close();
                    std::cout << "Failed to create file: " << path << std::endl;
                }
                else
                {
                    fs.close();
                    do_fetch();
                    return;
                    //std::cout << "opened path " << path << std::endl;
                }
            }
            if (fs.good())
            {
                fs.close();
                //const std::string calcsum(file_checksum(name()));
                /*
                std::cout << "calced sum for " << name()
                    << " : " << calcsum << ", expected " << checksum() << std::endl;
                    */
                //if (calcsum == checksum())
                if (status() == Status::Current)
                {
                    std::cout << " already up to date." << std::endl;
                }
                else
                {
                    std::cout << " outdated, downloading new." << std::endl;
                    do_fetch();
                }
            }
        }
        Status status()
        {
            std::ifstream is(name());
            if (!is.good())
            {
                return Status::Nonexistent;
            }
            is.close();
            const std::string calcsum(file_checksum(name()));
            if (calcsum == checksum())
            {
                return Status::Current;
            }
            else
            {
                return Status::Outdated;
            }
        }

    private:
        void do_fetch()
        {
            std::string s;
            std::shared_ptr<CURL *> phandle =
                std::make_shared<CURL *>(curl_easy_init());
            std::string url(patch_dir + name());
            curl_easy_setopt(*phandle, CURLOPT_URL, url.c_str());
            curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
            curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &s);
            //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
            curl_easy_perform(*phandle);
            curl_easy_cleanup(*phandle);
            phandle.reset();
            std::ofstream ofs(name());
            if (ofs.good())
            {
                ofs << s;
                ofs.close();
            }
            else
            {
                std::cout << "Couldn't write to " << name() << std::endl;
            }
        }

        std::string m_name;
        std::string m_checksum;
};

std::ostream& operator<<(std::ostream &os, const Target &t)
{
    return os << "name: " << t.name() << ", checksum: " << t.checksum();
}

class CurlGlobalInit
{
    public:
        CurlGlobalInit()
        {
            curl_global_init(CURL_GLOBAL_ALL);
        }

        ~CurlGlobalInit()
        {
            curl_global_cleanup();
        }
};

std::string file_checksum(const std::string &path)
{
#define md_md5
#ifdef md_md5
    auto md = EVP_md5();
    const int md_len = MD5_DIGEST_LENGTH;
#else
    auto md = EVP_sha1();
    const int md_len = SHA_DIGEST_LENGTH;
#endif
    std::array<unsigned char, md_len> result;
    EVP_MD_CTX *mdctx = nullptr;
    std::ifstream is(path, std::ifstream::binary);
    if (!is.good())
    {
        std::cout << "Couldn't open file " << path
           << " for checksumming." << std::endl;
        return std::string();
    }
    else
    {
        //std::cout << "opened file " << path << std::endl;
    }

    const int length = 8192;
    std::array<unsigned char, length> buffer;
    auto buf = reinterpret_cast<char *>(buffer.data());
    mdctx = EVP_MD_CTX_create();
    int status = EVP_DigestInit_ex(mdctx, md, nullptr);
    while (status && is)
    {
        is.read(buf, length);
        status = EVP_DigestUpdate(mdctx, buffer.data(), is.gcount());
    }
    status = EVP_DigestFinal_ex(mdctx, result.data(), nullptr);
    EVP_MD_CTX_destroy(mdctx);
    std::stringstream calcsum;
    calcsum << std::setfill('0');

    for (unsigned char c : result)
    {
        calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
    }
    /*
    std::for_each(std::begin(result), std::end(result),
            [&calcsum](unsigned char c)
            {
            calcsum << std::hex << std::setw(2)
            << static_cast<unsigned int>(c);
            });
            */
    //std::cout << calcsum.str() << std::endl;
    return calcsum.str();
}

int main(int argc, char *argv[])
{
    CurlGlobalInit curl_global;
    std::string fetch;
    std::shared_ptr<CURL *> phandle = std::make_shared<CURL *>(curl_easy_init());
    curl_easy_setopt(*phandle, CURLOPT_URL, listing.c_str());
    curl_easy_setopt(*phandle, CURLOPT_WRITEFUNCTION, &writefunction);
    curl_easy_setopt(*phandle, CURLOPT_WRITEDATA, &fetch);
    //curl_easy_setopt(*phandle, CURLOPT_NOPROGRESS, 0);
    curl_easy_perform(*phandle);
    curl_easy_cleanup(*phandle);
    phandle.reset();
    //std::cout << fetch << std::endl;
    std::vector<std::string> v(split(fetch, '\n'));
    //split(fetch, '\n', v);
    //std::cout << v[1] << std::endl;
    std::vector<Target> new_targets, old_targets;
    for (auto beg = std::begin(v), end = std::end(v);
            beg != end; ++beg)
    {
        auto w(split(*beg, '@'));
        /*
        for (const auto & sss : w)
        {
            std::cout << sss << ", " << std::endl;
        }
        */
        Target t(w[0], w[w.size() - 1]);
        auto status = t.status();
        if (status == Target::Status::Nonexistent)
        {
            new_targets.push_back(std::move(t));
        }
        else if (status == Target::Status::Outdated)
        {
            old_targets.push_back(std::move(t));
        }
        //std::cout << *beg << std::endl;
    }
    std::stringstream ss(fetch);
    std::string item;
    //std::vector<std::pair<std::string, std::string>> new_targets;
    while (std::getline(ss, item))
    {
        //new_targets.push_back(item);
    }
    if (new_targets.size())
    {
        std::cout << "New targets: " << new_targets.size() << std::endl;
        //for (auto &t : new_targets)
        {
            //std::cout << t << std::endl;
            //t.fetch();
        }
        std::cout << new_targets[4] << std::endl;
        new_targets[1].fetch();
        new_targets[4].fetch();
        /*
        for (auto s : split(new_targets[4].name(), '/'))
        {
            if (s.length())
            {
                std::cout << s << ", ";
            }
        }
        */
    }
    else
    {
        std::cout << "No new targets." << std::endl;
    }
    if (old_targets.size())
    {
        std::cout << "Outdated targets: " << old_targets.size() << std::endl;
        for (auto &t : old_targets)
        {
            std::cout << t << std::endl;
        }
    }
    else
    {
        std::cout << "No targets out of date." << std::endl;
    }
    const std::string path = "bin/override/spells.2da";
    const std::string checksum("38eaad974c15e5f3119469f17e8e97a9");
    std::cout << "file checksum test: "
        << path << " = " << checksum
        << " : " << (file_checksum(path) == checksum)
        << std::endl;

    std::cout << std::endl;
    return 0;
}
<|endoftext|>


<commit_before>#include "noteview.h"
#include "notewidgetdelegate.h"
#include <QDebug>
#include <QPainter>
#include <QApplication>
#include <QAbstractItemView>
#include <QPaintEvent>
#include <QSortFilterProxyModel>
#include <QTimer>
#include <QScrollBar>

NoteView::NoteView(QWidget *parent)
    : QListView( parent ),
      m_isScrollBarHidden(true),
      m_isSearching(false),
      m_isMousePressed(false),
      m_rowHeight(38)
{
    setMouseTracking(true);
    setUpdatesEnabled(true);
    viewport()->setAttribute(Qt::WA_Hover);

    setupStyleSheet();
    QTimer::singleShot(0, this, SLOT(setupSignalsSlots()));
}

NoteView::~NoteView()
{
}

void NoteView::animateAddedRow(const QModelIndex& parent, int start, int end)
{
    Q_UNUSED(parent)
    Q_UNUSED(end)

    QModelIndex idx = model()->index(start,0);
    // Note: this line add flikering, seen when the animation runs slow
    selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::Insert, idx);

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

/**
 * @brief Reimplemented from QWidget::paintEvent()
 */
void NoteView::paintEvent(QPaintEvent *e)
{
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate *>(itemDelegate());
    delegate->setCurrentSelectedIndex(currentIndex());

    QPoint pos = mapFromGlobal(QCursor::pos());
    QModelIndex index = indexAt(pos);
    delegate->setHoveredIndex(index);

    QListView::paintEvent(e);
}

/**
 * @brief Reimplemented from QAbstractItemView::rowsInserted().
 */
void NoteView::rowsInserted(const QModelIndex &parent, int start, int end)
{
//    QSortFilterProxyModel *proxyModel = static_cast<QSortFilterProxyModel *>(model());
    if(start == end && !m_isSearching)
        animateAddedRow(parent, start, end);

//    m_isSearching = !proxyModel->filterRegExp().pattern().isEmpty();

    QListView::rowsInserted(parent, start, end);
}

/**
 * @brief Reimplemented from QAbstractItemView::rowsAboutToBeRemoved().
 */
void NoteView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
//    QSortFilterProxyModel *proxyModel = static_cast<QSortFilterProxyModel *>(model());
//    m_isSearching = !proxyModel->filterRegExp().pattern().isEmpty();
//    qDebug() << "rowRemoved : " << (m_isSearching? "searching" : "not searching");
    if(start == end && !m_isSearching){
        QModelIndex idx = model()->index(start,0);
        NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
        delegate->setCurrentSelectedIndex(QModelIndex());

        if(!m_isSearching){
            delegate->setState( NoteWidgetDelegate::Remove, idx);
        }else{
            delegate->setState( NoteWidgetDelegate::Normal, idx);
        }

        // TODO find a way to finish this function till the animation stops
        while(delegate->animationState() == QTimeLine::Running){
            qApp->processEvents();
        }
    }

    QListView::rowsAboutToBeRemoved(parent, start, end);
}

void NoteView::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
                                  const QModelIndex &destinationParent, int destinationRow)
{
    Q_UNUSED(sourceParent)
    Q_UNUSED(sourceEnd)
    Q_UNUSED(destinationParent)
    Q_UNUSED(destinationRow)

    QModelIndex idx = model()->index(sourceStart,0);
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::MoveOut, idx);

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

void NoteView::rowsMoved(const QModelIndex &parent, int start, int end,
                         const QModelIndex &destination, int row)
{
    Q_UNUSED(parent)
    Q_UNUSED(start)
    Q_UNUSED(end)
    Q_UNUSED(destination)

    QModelIndex idx = model()->index(row,0);
    setCurrentIndex(idx);

    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::MoveIn, idx );

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

void NoteView::mouseMoveEvent(QMouseEvent*e)
{
    if(m_isMousePressed){

    }else{
        QListView::mouseMoveEvent(e);
    }
}

void NoteView::mousePressEvent(QMouseEvent*e)
{
    m_isMousePressed = true;

    QListView::mousePressEvent(e);
}

void NoteView::mouseReleaseEvent(QMouseEvent*e)
{
    m_isMousePressed = false;
    QListView::mouseReleaseEvent(e);
}

void NoteView::setSearching(bool isSearching)
{
    m_isSearching = isSearching;
}

void NoteView::setupSignalsSlots()
{
    // remove/add separator
    connect(selectionModel(), &QItemSelectionModel::currentRowChanged, [this]
            (const QModelIndex & current, const QModelIndex & previous){

        QModelIndex prevPrevIndex = model()->index(current.row()-2, 0);
        QModelIndex prevIndex = model()->index(current.row()-1, 0);

        if(current.row() < previous.row()){
            viewport()->update(visualRect(prevPrevIndex));
            viewport()->update(visualRect(prevIndex));
        }else{
            viewport()->update(visualRect(prevPrevIndex));
        }
    });

    connect(this, &NoteView::entered,[this](QModelIndex index){
        QModelIndex prevPrevIndex = model()->index(index.row()-2, 0);
        viewport()->update(visualRect(prevPrevIndex));
        QModelIndex prevIndex = model()->index(index.row()-1, 0);
        viewport()->update(visualRect(prevIndex));
    });

    connect(this, &NoteView::viewportEntered,[this](){
        QModelIndex lastIndex = model()->index(model()->rowCount()-2, 0);
        viewport()->update(visualRect(lastIndex));
    });

    // remove/add offset
    connect(this->verticalScrollBar(), &QScrollBar::rangeChanged,[this](int min, int max){
        Q_UNUSED(min)
        NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate());
        if(max > 0){
            delegate->setRowRightOffset(2);
        }else{
            delegate->setRowRightOffset(0);
        }
        viewport()->update();
    });
}

/**
 * @brief setup styleSheet
 */
void NoteView::setupStyleSheet()
{
    QString ss = QString("QListView QWidget{background-color:white;} "
                         "QScrollBar {margin-right: 2px; background: transparent;} "
                         "QScrollBar:hover { background-color: rgb(217, 217, 217);}"
                         "QScrollBar:handle:vertical:hover { background: rgb(170, 170, 171); } "
                         "QScrollBar:handle:vertical:pressed { background: rgb(149, 149, 149);}"
                         "QScrollBar:vertical { border: none; width: 10px; border-radius: 4px;} "
                         "QScrollBar::handle:vertical { border-radius: 4px; background: rgb(188, 188, 188); min-height: 20px; }  "
                         "QScrollBar::add-line:vertical { height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; }  "
                         "QScrollBar::sub-line:vertical { height: 0px; subcontrol-position: top; subcontrol-origin: margin; }"
                         );

    setStyleSheet(ss);
}
<commit_msg>Removing commented code<commit_after>#include "noteview.h"
#include "notewidgetdelegate.h"
#include <QDebug>
#include <QPainter>
#include <QApplication>
#include <QAbstractItemView>
#include <QPaintEvent>
#include <QSortFilterProxyModel>
#include <QTimer>
#include <QScrollBar>

NoteView::NoteView(QWidget *parent)
    : QListView( parent ),
      m_isScrollBarHidden(true),
      m_isSearching(false),
      m_isMousePressed(false),
      m_rowHeight(38)
{
    setMouseTracking(true);
    setUpdatesEnabled(true);
    viewport()->setAttribute(Qt::WA_Hover);

    setupStyleSheet();
    QTimer::singleShot(0, this, SLOT(setupSignalsSlots()));
}

NoteView::~NoteView()
{
}

void NoteView::animateAddedRow(const QModelIndex& parent, int start, int end)
{
    Q_UNUSED(parent)
    Q_UNUSED(end)

    QModelIndex idx = model()->index(start,0);
    // Note: this line add flikering, seen when the animation runs slow
    selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::Insert, idx);

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

/**
 * @brief Reimplemented from QWidget::paintEvent()
 */
void NoteView::paintEvent(QPaintEvent *e)
{
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate *>(itemDelegate());
    delegate->setCurrentSelectedIndex(currentIndex());

    QPoint pos = mapFromGlobal(QCursor::pos());
    QModelIndex index = indexAt(pos);
    delegate->setHoveredIndex(index);

    QListView::paintEvent(e);
}

/**
 * @brief Reimplemented from QAbstractItemView::rowsInserted().
 */
void NoteView::rowsInserted(const QModelIndex &parent, int start, int end)
{
    if(start == end && !m_isSearching)
        animateAddedRow(parent, start, end);

    QListView::rowsInserted(parent, start, end);
}

/**
 * @brief Reimplemented from QAbstractItemView::rowsAboutToBeRemoved().
 */
void NoteView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
    if(start == end && !m_isSearching){
        QModelIndex idx = model()->index(start,0);
        NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
        delegate->setCurrentSelectedIndex(QModelIndex());

        if(!m_isSearching){
            delegate->setState( NoteWidgetDelegate::Remove, idx);
        }else{
            delegate->setState( NoteWidgetDelegate::Normal, idx);
        }

        // TODO find a way to finish this function till the animation stops
        while(delegate->animationState() == QTimeLine::Running){
            qApp->processEvents();
        }
    }

    QListView::rowsAboutToBeRemoved(parent, start, end);
}

void NoteView::rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
                                  const QModelIndex &destinationParent, int destinationRow)
{
    Q_UNUSED(sourceParent)
    Q_UNUSED(sourceEnd)
    Q_UNUSED(destinationParent)
    Q_UNUSED(destinationRow)

    QModelIndex idx = model()->index(sourceStart,0);
    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::MoveOut, idx);

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

void NoteView::rowsMoved(const QModelIndex &parent, int start, int end,
                         const QModelIndex &destination, int row)
{
    Q_UNUSED(parent)
    Q_UNUSED(start)
    Q_UNUSED(end)
    Q_UNUSED(destination)

    QModelIndex idx = model()->index(row,0);
    setCurrentIndex(idx);

    NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate(idx));
    delegate->setState( NoteWidgetDelegate::MoveIn, idx );

    // TODO find a way to finish this function till the animation stops
    while(delegate->animationState() == QTimeLine::Running){
        qApp->processEvents();
    }
}

void NoteView::mouseMoveEvent(QMouseEvent*e)
{
    if(m_isMousePressed){

    }else{
        QListView::mouseMoveEvent(e);
    }
}

void NoteView::mousePressEvent(QMouseEvent*e)
{
    m_isMousePressed = true;

    QListView::mousePressEvent(e);
}

void NoteView::mouseReleaseEvent(QMouseEvent*e)
{
    m_isMousePressed = false;
    QListView::mouseReleaseEvent(e);
}

void NoteView::setSearching(bool isSearching)
{
    m_isSearching = isSearching;
}

void NoteView::setupSignalsSlots()
{
    // remove/add separator
    connect(selectionModel(), &QItemSelectionModel::currentRowChanged, [this]
            (const QModelIndex & current, const QModelIndex & previous){

        QModelIndex prevPrevIndex = model()->index(current.row()-2, 0);
        QModelIndex prevIndex = model()->index(current.row()-1, 0);

        if(current.row() < previous.row()){
            viewport()->update(visualRect(prevPrevIndex));
            viewport()->update(visualRect(prevIndex));
        }else{
            viewport()->update(visualRect(prevPrevIndex));
        }
    });

    connect(this, &NoteView::entered,[this](QModelIndex index){
        QModelIndex prevPrevIndex = model()->index(index.row()-2, 0);
        viewport()->update(visualRect(prevPrevIndex));
        QModelIndex prevIndex = model()->index(index.row()-1, 0);
        viewport()->update(visualRect(prevIndex));
    });

    connect(this, &NoteView::viewportEntered,[this](){
        QModelIndex lastIndex = model()->index(model()->rowCount()-2, 0);
        viewport()->update(visualRect(lastIndex));
    });

    // remove/add offset
    connect(this->verticalScrollBar(), &QScrollBar::rangeChanged,[this](int min, int max){
        Q_UNUSED(min)
        NoteWidgetDelegate* delegate = static_cast<NoteWidgetDelegate*>(itemDelegate());
        if(max > 0){
            delegate->setRowRightOffset(2);
        }else{
            delegate->setRowRightOffset(0);
        }
        viewport()->update();
    });
}

/**
 * @brief setup styleSheet
 */
void NoteView::setupStyleSheet()
{
    QString ss = QString("QListView QWidget{background-color:white;} "
                         "QScrollBar {margin-right: 2px; background: transparent;} "
                         "QScrollBar:hover { background-color: rgb(217, 217, 217);}"
                         "QScrollBar:handle:vertical:hover { background: rgb(170, 170, 171); } "
                         "QScrollBar:handle:vertical:pressed { background: rgb(149, 149, 149);}"
                         "QScrollBar:vertical { border: none; width: 10px; border-radius: 4px;} "
                         "QScrollBar::handle:vertical { border-radius: 4px; background: rgb(188, 188, 188); min-height: 20px; }  "
                         "QScrollBar::add-line:vertical { height: 0px; subcontrol-position: bottom; subcontrol-origin: margin; }  "
                         "QScrollBar::sub-line:vertical { height: 0px; subcontrol-position: top; subcontrol-origin: margin; }"
                         );

    setStyleSheet(ss);
}
<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mlocalthemedaemon.h"
#include "mthemedaemonprotocol.h"
#include "mdebug.h"

using namespace M::MThemeDaemonProtocol;

#ifndef HAVE_GCONF
#include <QTimer>
#include "mexport.h"
QString M_themeName;
MLocalThemeDaemon *M_localDaemon;

void M_EXPORT M_changeTheme(const QString &theme)
{
    M_themeName = theme;
    QTimer::singleShot(0, M_localDaemon, SLOT(themeChangedSlot()));
}
#endif

MLocalThemeDaemon::MLocalThemeDaemon(const QString &applicationName) :
    daemon(MThemeDaemon::LocalDaemon),
#ifdef HAVE_GCONF
    themeItem("/meegotouch/theme/name"),
    locale("/meegotouch/i18n/language")
#endif
{
    QString theme =  M_THEME_DEFAULT;
    QString language = "";
#if HAVE_GCONF
    theme = themeItem.value(M_THEME_DEFAULT).toString();
    language = locale.value().toString();
#else
    M_themeName =  M_THEME_DEFAULT;
    M_localDaemon = this;
#endif

    QList<QPixmap*> pixmapsToDelete;
    if ( daemon.activateTheme(theme, language, QList<MThemeDaemonClient *>(), pixmapsToDelete) == false ) {
        mWarning("MThemeDaemon") << "Could not activate the theme:" << theme;
    }
    Q_ASSERT(pixmapsToDelete.isEmpty());

    client = new MThemeDaemonClient(NULL, applicationName, daemon.themeInheritanceChain());
    daemon.addClient(client);

#ifdef HAVE_GCONF
    connect(&themeItem, SIGNAL(valueChanged()), SLOT(themeChangedSlot()));
    connect(&locale, SIGNAL(valueChanged()), SLOT(localeChanged()));
#endif
}

void MLocalThemeDaemon::registerApplicationName(const QString &applicationName)
{
    client->reinit(applicationName, daemon.themeInheritanceChain());
}

MLocalThemeDaemon::~MLocalThemeDaemon()
{
    daemon.removeClient(client);
    delete client;
    client = NULL;
}

void MLocalThemeDaemon::addDirectoryToPixmapSearchList(const QString &directoryName, M::RecursionMode recursive)
{
    client->addCustomImageDirectory(directoryName, recursive);
}

void MLocalThemeDaemon::clearPixmapSearchList()
{
    client->removeAddedImageDirectories();
}

void MLocalThemeDaemon::pixmapHandleSync(const QString &imageId, const QSize &size)
{
    // request
    Qt::HANDLE handle;
    if (daemon.pixmap(client, PixmapIdentifier(imageId, size), handle)) {
        emit pixmapCreatedOrChanged(imageId, size, handle);
    } else {
        qDebug() << "error";
    }
}

void MLocalThemeDaemon::pixmapHandle(const QString &imageId, const QSize &size)
{
    pixmapHandleSync(imageId, size);
}

void MLocalThemeDaemon::releasePixmap(const QString &imageId, const QSize &size)
{
    if (!daemon.releasePixmap(client, PixmapIdentifier(imageId, size))) {
        qDebug() << "error";
    }
}

QString MLocalThemeDaemon::currentTheme()
{
    return daemon.currentTheme();
}

QStringList MLocalThemeDaemon::themeInheritanceChain()
{
    return daemon.themeInheritanceChain();
}

QStringList MLocalThemeDaemon::themeLibraryNames()
{
    return daemon.themeLibraryNames();
}

bool MLocalThemeDaemon::hasPendingRequests() const
{
    return false;
}

void MLocalThemeDaemon::themeChangedSlot()
{
    QHash<MThemeDaemonClient *, QList<PixmapIdentifier> > pixmapsToReload;
    QList<MThemeDaemonClient *> list;
    list.append(client);

    QList<QPixmap*> pixmapsToDelete;
#ifdef HAVE_GCONF
    if (daemon.activateTheme(themeItem.value().toString(), locale.value().toString(), list, pixmapsToDelete)) {
#else
    if (daemon.activateTheme(M_themeName, "", list, pixmapsToDelete)) {
#endif
        while (!client->pixmapsToReload.isEmpty()) {
            PixmapIdentifier id = client->pixmapsToReload.takeLast();
            pixmapHandle(id.imageId, id.size);
        }
        // theme change succeeded, let's inform all clients + add the pixmaps to load-list
        emit themeChanged(themeInheritanceChain(), themeLibraryNames());
        qDeleteAll(pixmapsToDelete);
    } else {
        // theme change failed, so change the theme back also in gconf.
#ifdef HAVE_GCONF
        mWarning("MLocalThemeDaemon") << "Could not change theme to" << themeItem.value().toString();
        themeItem.set(currentTheme());
#else
        mWarning("MLocalThemeDaemon") << "Could not change theme to" << M_themeName;
        M_themeName = currentTheme();
#endif
    }
    emit themeChangeCompleted();
}

void MLocalThemeDaemon::localeChanged()
{
#ifdef HAVE_GCONF
    QHash<MThemeDaemonClient *, QList<PixmapIdentifier> > pixmapsToReload;
    QList<MThemeDaemonClient *> clients;
    clients.append(client);
    daemon.changeLocale(locale.value().toString(), clients, pixmapsToReload);

    foreach(const PixmapIdentifier & id, pixmapsToReload[client]) {
        Qt::HANDLE handle;
        if (daemon.pixmap(client, id, handle)) {
            emit pixmapCreatedOrChanged(id.imageId, id.size, handle);
        } else {
            qDebug() << "error";
        }
    }
#endif
}

<commit_msg>Fix: BMC#7812 -  Build break if HAVE_GCONF is not defined RevBy:TrustMe<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include "mlocalthemedaemon.h"
#include "mthemedaemonprotocol.h"
#include "mdebug.h"

using namespace M::MThemeDaemonProtocol;

#ifndef HAVE_GCONF
#include <QTimer>
#include "mexport.h"
QString M_themeName;
MLocalThemeDaemon *M_localDaemon;

void M_EXPORT M_changeTheme(const QString &theme)
{
    M_themeName = theme;
    QTimer::singleShot(0, M_localDaemon, SLOT(themeChangedSlot()));
}
#endif

MLocalThemeDaemon::MLocalThemeDaemon(const QString &applicationName) :
    daemon(MThemeDaemon::LocalDaemon)
#ifdef HAVE_GCONF
    ,
    themeItem("/meegotouch/theme/name"),
    locale("/meegotouch/i18n/language")
#endif
{
    QString theme =  M_THEME_DEFAULT;
    QString language = "";
#if HAVE_GCONF
    theme = themeItem.value(M_THEME_DEFAULT).toString();
    language = locale.value().toString();
#else
    M_themeName =  M_THEME_DEFAULT;
    M_localDaemon = this;
#endif

    QList<QPixmap*> pixmapsToDelete;
    if ( daemon.activateTheme(theme, language, QList<MThemeDaemonClient *>(), pixmapsToDelete) == false ) {
        mWarning("MThemeDaemon") << "Could not activate the theme:" << theme;
    }
    Q_ASSERT(pixmapsToDelete.isEmpty());

    client = new MThemeDaemonClient(NULL, applicationName, daemon.themeInheritanceChain());
    daemon.addClient(client);

#ifdef HAVE_GCONF
    connect(&themeItem, SIGNAL(valueChanged()), SLOT(themeChangedSlot()));
    connect(&locale, SIGNAL(valueChanged()), SLOT(localeChanged()));
#endif
}

void MLocalThemeDaemon::registerApplicationName(const QString &applicationName)
{
    client->reinit(applicationName, daemon.themeInheritanceChain());
}

MLocalThemeDaemon::~MLocalThemeDaemon()
{
    daemon.removeClient(client);
    delete client;
    client = NULL;
}

void MLocalThemeDaemon::addDirectoryToPixmapSearchList(const QString &directoryName, M::RecursionMode recursive)
{
    client->addCustomImageDirectory(directoryName, recursive);
}

void MLocalThemeDaemon::clearPixmapSearchList()
{
    client->removeAddedImageDirectories();
}

void MLocalThemeDaemon::pixmapHandleSync(const QString &imageId, const QSize &size)
{
    // request
    Qt::HANDLE handle;
    if (daemon.pixmap(client, PixmapIdentifier(imageId, size), handle)) {
        emit pixmapCreatedOrChanged(imageId, size, handle);
    } else {
        qDebug() << "error";
    }
}

void MLocalThemeDaemon::pixmapHandle(const QString &imageId, const QSize &size)
{
    pixmapHandleSync(imageId, size);
}

void MLocalThemeDaemon::releasePixmap(const QString &imageId, const QSize &size)
{
    if (!daemon.releasePixmap(client, PixmapIdentifier(imageId, size))) {
        qDebug() << "error";
    }
}

QString MLocalThemeDaemon::currentTheme()
{
    return daemon.currentTheme();
}

QStringList MLocalThemeDaemon::themeInheritanceChain()
{
    return daemon.themeInheritanceChain();
}

QStringList MLocalThemeDaemon::themeLibraryNames()
{
    return daemon.themeLibraryNames();
}

bool MLocalThemeDaemon::hasPendingRequests() const
{
    return false;
}

void MLocalThemeDaemon::themeChangedSlot()
{
    QHash<MThemeDaemonClient *, QList<PixmapIdentifier> > pixmapsToReload;
    QList<MThemeDaemonClient *> list;
    list.append(client);

    QList<QPixmap*> pixmapsToDelete;
#ifdef HAVE_GCONF
    if (daemon.activateTheme(themeItem.value().toString(), locale.value().toString(), list, pixmapsToDelete)) {
#else
    if (daemon.activateTheme(M_themeName, "", list, pixmapsToDelete)) {
#endif
        while (!client->pixmapsToReload.isEmpty()) {
            PixmapIdentifier id = client->pixmapsToReload.takeLast();
            pixmapHandle(id.imageId, id.size);
        }
        // theme change succeeded, let's inform all clients + add the pixmaps to load-list
        emit themeChanged(themeInheritanceChain(), themeLibraryNames());
        qDeleteAll(pixmapsToDelete);
    } else {
        // theme change failed, so change the theme back also in gconf.
#ifdef HAVE_GCONF
        mWarning("MLocalThemeDaemon") << "Could not change theme to" << themeItem.value().toString();
        themeItem.set(currentTheme());
#else
        mWarning("MLocalThemeDaemon") << "Could not change theme to" << M_themeName;
        M_themeName = currentTheme();
#endif
    }
    emit themeChangeCompleted();
}

void MLocalThemeDaemon::localeChanged()
{
#ifdef HAVE_GCONF
    QHash<MThemeDaemonClient *, QList<PixmapIdentifier> > pixmapsToReload;
    QList<MThemeDaemonClient *> clients;
    clients.append(client);
    daemon.changeLocale(locale.value().toString(), clients, pixmapsToReload);

    foreach(const PixmapIdentifier & id, pixmapsToReload[client]) {
        Qt::HANDLE handle;
        if (daemon.pixmap(client, id, handle)) {
            emit pixmapCreatedOrChanged(id.imageId, id.size, handle);
        } else {
            qDebug() << "error";
        }
    }
#endif
}

<|endoftext|>