<commit_before>/////////////////////////////////////////////////////////////////////////
// $Id: stack_pro.cc,v 1.35 2007/12/16 21:46:39 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  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
/////////////////////////////////////////////////////////////////////////

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR

void BX_CPU_C::push_16(Bit16u value16)
{
  /* must use StackAddrSize, and either RSP, ESP or SP accordingly */
#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
  {
    write_virtual_word(BX_SEG_REG_SS, RSP-2, &value16);
    RSP -= 2;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
    write_virtual_word(BX_SEG_REG_SS, (Bit32u) (ESP-2), &value16);
    ESP -= 2;
  }
  else
  {
    write_virtual_word(BX_SEG_REG_SS, (Bit16u) (SP-2), &value16);
    SP  -= 2;
  }
}

/* push 32 bit operand */
void BX_CPU_C::push_32(Bit32u value32)
{
  /* must use StackAddrSize, and either RSP, ESP or SP accordingly */
#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
  {
    write_virtual_dword(BX_SEG_REG_SS, RSP-4, &value32);
    RSP -= 4;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
    write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (ESP-4), &value32);
    ESP -= 4;
  }
  else
  {
    write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (SP-4), &value32);
    SP  -= 4;
  }
}

/* push 64 bit operand */
#if BX_SUPPORT_X86_64
void BX_CPU_C::push_64(Bit64u value64)
{
  BX_ASSERT(StackAddrSize64());

  write_virtual_qword(BX_SEG_REG_SS, RSP-8, &value64);
  RSP -= 8;
}
#endif

/* pop 16 bit operand from the stack */
void BX_CPU_C::pop_16(Bit16u *value16_ptr)
{
  bx_address temp_RSP;

#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
    temp_RSP = RSP;
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    temp_RSP = ESP;
  else
    temp_RSP = SP;

  read_virtual_word(BX_SEG_REG_SS, temp_RSP, value16_ptr);

#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
    RSP += 2;
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    ESP += 2;
  else
    SP  += 2;
}

/* pop 32 bit operand from the stack */
void BX_CPU_C::pop_32(Bit32u *value32_ptr)
{
  bx_address temp_RSP;

#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
    temp_RSP = RSP;
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    temp_RSP = ESP;
  else
    temp_RSP = SP;

  read_virtual_dword(BX_SEG_REG_SS, temp_RSP, value32_ptr);

#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
    RSP += 4;
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
    ESP += 4;
  else
    SP  += 4;
}

/* pop 64 bit operand from the stack */
#if BX_SUPPORT_X86_64
void BX_CPU_C::pop_64(Bit64u *value64_ptr)
{
  BX_ASSERT(StackAddrSize64());

  read_virtual_qword(BX_SEG_REG_SS, RSP, value64_ptr);
  RSP += 8;
}
#endif

  bx_bool BX_CPP_AttrRegparmN(3)
BX_CPU_C::can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes)
{
#if BX_SUPPORT_X86_64
  if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
    return(1);
  }
#endif

  // small stack compares against 16-bit SP
  if (!descriptor->u.segment.d_b)
    esp &= 0x0000ffff;

  if (descriptor->valid==0) {
    BX_ERROR(("can_push(): SS invalidated."));
    return(0);
  }

  if (descriptor->p==0) {
    BX_ERROR(("can_push(): descriptor not present"));
    return(0);
  }

  if (IS_DATA_SEGMENT_EXPAND_DOWN(descriptor->type)) /* expand down segment */
  {
    Bit32u expand_down_limit;

    if (descriptor->u.segment.d_b)
      expand_down_limit = 0xffffffff;
    else
      expand_down_limit = 0x0000ffff;

    if (esp==0) {
      BX_PANIC(("can_push(): esp=0, wraparound?"));
      return(0);
    }

    if (esp < bytes) {
      BX_PANIC(("can_push(): expand-down: esp < N"));
      return(0);
    }
    if ((esp - bytes) <= descriptor->u.segment.limit_scaled) {
      BX_ERROR(("can_push(): expand-down: esp-N < limit"));
      return(0);
    }
    if (esp > expand_down_limit) {
      BX_ERROR(("can_push(): esp > expand-down-limit"));
      return(0);
    }
    return(1);
  }
  else { /* normal (expand-up) segment */
    if (descriptor->u.segment.limit_scaled==0) {
      BX_PANIC(("can_push(): found limit of 0"));
      return(0);
    }

    // Look at case where esp==0.  Possibly, it's an intentional wraparound
    // If so, limit must be the maximum for the given stack size
    if (esp==0) {
      if (descriptor->u.segment.d_b && (descriptor->u.segment.limit_scaled==0xffffffff))
        return(1);
      if ((descriptor->u.segment.d_b==0) && (descriptor->u.segment.limit_scaled>=0xffff))
        return(1);
      BX_ERROR(("can_push(): esp=0, normal, wraparound? limit=%08x",
        descriptor->u.segment.limit_scaled));
      return(0);
    }

    if (!descriptor->u.segment.d_b) {
      // Weird case for 16-bit SP.
      esp = ((esp-bytes) & 0xffff) + bytes;
    }
    if (esp < bytes) {
      BX_ERROR(("can_push(): expand-up: esp < N"));
      return(0);
    }
    if ((esp-1) > descriptor->u.segment.limit_scaled) {
      BX_ERROR(("can_push(): expand-up: SP > limit"));
      return(0);
    }
    /* all checks pass */
    return(1);
  }
}

bx_bool BX_CPU_C::can_pop(Bit32u bytes)
{
  Bit32u temp_ESP, expand_down_limit;

#if BX_SUPPORT_X86_64
  if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
    return(1);
  }
#endif

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* Big bit set: use ESP */
    temp_ESP = ESP;
    expand_down_limit = 0xFFFFFFFF;
  }
  else { /* Big bit clear: use SP */
    temp_ESP = SP;
    expand_down_limit = 0xFFFF;
  }

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0) {
    BX_ERROR(("can_pop(): SS invalidated"));
    return(0); /* never gets here */
  }

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p==0) {
    BX_ERROR(("can_pop(): SS.p = 0"));
    return(0);
  }

  if (IS_DATA_SEGMENT_EXPAND_DOWN(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type)) { /* expand down */
    if (temp_ESP == expand_down_limit) {
      BX_PANIC(("can_pop(): found SP=ffff"));
      return(0);
    }
    if (((expand_down_limit - temp_ESP) + 1) >= bytes)
      return(1);
    return(0);
  }
  else { /* normal (expand-up) segment */
    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled==0) {
      BX_ERROR(("can_pop(): SS.limit = 0"));
      return(0);
    }
    if (temp_ESP == expand_down_limit) {
      BX_ERROR(("can_pop(): found SP=ffff"));
      return(0);
    }
    if (temp_ESP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
      BX_ERROR(("can_pop(): eSP > SS.limit"));
      return(0);
    }
    if (((BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled - temp_ESP) + 1) >= bytes)
      return(1);
    return(0);
  }
}
<commit_msg>cleanup<commit_after>/////////////////////////////////////////////////////////////////////////
// $Id: stack_pro.cc,v 1.36 2007/12/18 21:08:55 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  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
/////////////////////////////////////////////////////////////////////////

#define NEED_CPU_REG_SHORTCUTS 1
#include "bochs.h"
#include "cpu.h"
#define LOG_THIS BX_CPU_THIS_PTR

void BX_CPU_C::push_16(Bit16u value16)
{
  /* must use StackAddrSize, and either RSP, ESP or SP accordingly */
#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
  {
    write_virtual_word(BX_SEG_REG_SS, RSP-2, &value16);
    RSP -= 2;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
    write_virtual_word(BX_SEG_REG_SS, (Bit32u) (ESP-2), &value16);
    ESP -= 2;
  }
  else
  {
    write_virtual_word(BX_SEG_REG_SS, (Bit16u) (SP-2), &value16);
    SP  -= 2;
  }
}

/* push 32 bit operand */
void BX_CPU_C::push_32(Bit32u value32)
{
  /* must use StackAddrSize, and either RSP, ESP or SP accordingly */
#if BX_SUPPORT_X86_64
  if (StackAddrSize64())
  {
    write_virtual_dword(BX_SEG_REG_SS, RSP-4, &value32);
    RSP -= 4;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
    write_virtual_dword(BX_SEG_REG_SS, (Bit32u) (ESP-4), &value32);
    ESP -= 4;
  }
  else
  {
    write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (SP-4), &value32);
    SP  -= 4;
  }
}

/* push 64 bit operand */
#if BX_SUPPORT_X86_64
void BX_CPU_C::push_64(Bit64u value64)
{
  BX_ASSERT(StackAddrSize64());

  write_virtual_qword(BX_SEG_REG_SS, RSP-8, &value64);
  RSP -= 8;
}
#endif

/* pop 16 bit operand from the stack */
void BX_CPU_C::pop_16(Bit16u *value16_ptr)
{
#if BX_SUPPORT_X86_64
  if (StackAddrSize64()) {
    read_virtual_word(BX_SEG_REG_SS, RSP, value16_ptr);
    RSP += 2;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
    read_virtual_word(BX_SEG_REG_SS, ESP, value16_ptr);
    ESP += 2;
  }
  else {
    read_virtual_word(BX_SEG_REG_SS, SP, value16_ptr);
    SP  += 2;
  }
}

/* pop 32 bit operand from the stack */
void BX_CPU_C::pop_32(Bit32u *value32_ptr)
{
#if BX_SUPPORT_X86_64
  if (StackAddrSize64()) {
    read_virtual_dword(BX_SEG_REG_SS, RSP, value32_ptr);
    RSP += 4;
  }
  else
#endif
  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
    read_virtual_dword(BX_SEG_REG_SS, ESP, value32_ptr);
    ESP += 4;
  }
  else {
    read_virtual_dword(BX_SEG_REG_SS, SP, value32_ptr);
    SP  += 4;
  }
}

/* pop 64 bit operand from the stack */
#if BX_SUPPORT_X86_64
void BX_CPU_C::pop_64(Bit64u *value64_ptr)
{
  BX_ASSERT(StackAddrSize64());

  read_virtual_qword(BX_SEG_REG_SS, RSP, value64_ptr);
  RSP += 8;
}
#endif

  bx_bool BX_CPP_AttrRegparmN(3)
BX_CPU_C::can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes)
{
#if BX_SUPPORT_X86_64
  if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
    return(1);
  }
#endif

  // small stack compares against 16-bit SP
  if (!descriptor->u.segment.d_b)
    esp &= 0x0000ffff;

  if (descriptor->valid==0) {
    BX_ERROR(("can_push(): SS invalidated."));
    return(0);
  }

  if (descriptor->p==0) {
    BX_ERROR(("can_push(): descriptor not present"));
    return(0);
  }

  if (IS_DATA_SEGMENT_EXPAND_DOWN(descriptor->type)) /* expand down segment */
  {
    Bit32u expand_down_limit;

    if (descriptor->u.segment.d_b)
      expand_down_limit = 0xffffffff;
    else
      expand_down_limit = 0x0000ffff;

    if (esp==0) {
      BX_PANIC(("can_push(): esp=0, wraparound?"));
      return(0);
    }

    if (esp < bytes) {
      BX_PANIC(("can_push(): expand-down: esp < N"));
      return(0);
    }
    if ((esp - bytes) <= descriptor->u.segment.limit_scaled) {
      BX_ERROR(("can_push(): expand-down: esp-N < limit"));
      return(0);
    }
    if (esp > expand_down_limit) {
      BX_ERROR(("can_push(): esp > expand-down-limit"));
      return(0);
    }
    return(1);
  }
  else { /* normal (expand-up) segment */
    if (descriptor->u.segment.limit_scaled==0) {
      BX_PANIC(("can_push(): found limit of 0"));
      return(0);
    }

    // Look at case where esp==0.  Possibly, it's an intentional wraparound
    // If so, limit must be the maximum for the given stack size
    if (esp==0) {
      if (descriptor->u.segment.d_b && (descriptor->u.segment.limit_scaled==0xffffffff))
        return(1);
      if ((descriptor->u.segment.d_b==0) && (descriptor->u.segment.limit_scaled>=0xffff))
        return(1);
      BX_ERROR(("can_push(): esp=0, normal, wraparound? limit=%08x",
        descriptor->u.segment.limit_scaled));
      return(0);
    }

    if (!descriptor->u.segment.d_b) {
      // Weird case for 16-bit SP.
      esp = ((esp-bytes) & 0xffff) + bytes;
    }
    if (esp < bytes) {
      BX_ERROR(("can_push(): expand-up: esp < N"));
      return(0);
    }
    if ((esp-1) > descriptor->u.segment.limit_scaled) {
      BX_ERROR(("can_push(): expand-up: SP > limit"));
      return(0);
    }
    /* all checks pass */
    return(1);
  }
}

bx_bool BX_CPU_C::can_pop(Bit32u bytes)
{
  Bit32u temp_ESP, expand_down_limit;

#if BX_SUPPORT_X86_64
  if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
    return(1);
  }
#endif

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* Big bit set: use ESP */
    temp_ESP = ESP;
    expand_down_limit = 0xFFFFFFFF;
  }
  else { /* Big bit clear: use SP */
    temp_ESP = SP;
    expand_down_limit = 0xFFFF;
  }

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0) {
    BX_ERROR(("can_pop(): SS invalidated"));
    return(0); /* never gets here */
  }

  if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p==0) {
    BX_ERROR(("can_pop(): SS.p = 0"));
    return(0);
  }

  if (IS_DATA_SEGMENT_EXPAND_DOWN(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type)) { /* expand down */
    if (temp_ESP == expand_down_limit) {
      BX_PANIC(("can_pop(): found SP=ffff"));
      return(0);
    }
    if (((expand_down_limit - temp_ESP) + 1) >= bytes)
      return(1);
    return(0);
  }
  else { /* normal (expand-up) segment */
    if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled==0) {
      BX_ERROR(("can_pop(): SS.limit = 0"));
      return(0);
    }
    if (temp_ESP == expand_down_limit) {
      BX_ERROR(("can_pop(): found SP=ffff"));
      return(0);
    }
    if (temp_ESP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
      BX_ERROR(("can_pop(): eSP > SS.limit"));
      return(0);
    }
    if (((BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled - temp_ESP) + 1) >= bytes)
      return(1);
    return(0);
  }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include "aesthetics.h"
#include "operators.h"
#include "easy.h"
#include "hard.h"
using namespace std;

typedef vector < vector<char> > VECTOR;

unsigned int LENGTH = 1;
unsigned int HEIGHT = 1;
int arr_height = 3;
int arr_length = 3;

bool get_input(int argc, char* argv[], string & mode)
{
	if (argc > 1 && argc < 5)						//if length & height passed
	{
		if (argc == 2)								//missing one arg
		{
			cout << "Missing height arg" << endl;
			return false;
		}
		else
		{
			LENGTH = atoi(argv[1]);
			HEIGHT = atoi(argv[2]);
			if (LENGTH == 0)						//must be > 0
			{
				cout << "Invalid length" << endl;
				return false;
			}
			if (HEIGHT == 0)						//must be > 0
			{
				cout << "Invalid height" << endl;
				return false;
			}
		}
	}
	if (argc > 3)									//too many args passed
	{
		if (argc > 4)
		{
			cout << "Too many arguments" << endl;
			return false;
		}
		else if (argv[3] == "e" || argv[3] == "E" ||
				 argv[3] == "easy" || argv[3] == "Easy")
		{
			mode = "e";
		}
		else
			mode = "h";
	}
	if (argc == 1)									//no args passed
	{
		cout << "Enter the length of the maze." << endl;
		int l = 0;
		while (l <= 0)								//get length
		{
			cin >> l;
		}
		cout << "Enter the height of the maze." << endl;
		int h = 0;
		while (h <= 0)								//get height
		{
			cin >> h;
		}
		LENGTH = l;
		HEIGHT = h;
		cout << "Enter the difficulty of the maze. ";
		cout << "1 for easy, 2 for hard." << endl;
		int d = 0;
		while (d <= 0 || d > 2)
		{
			cin >> d;
		}
		if (d == 1)
			mode = "e";
		else
			mode = "h";
	}
	return true;
}

void maze_init(VECTOR &MAZE, int arr_height, int arr_length)
{
	for (int i = 0; i < arr_height; i++)			//init maze with x
	{
		for (int j = 0; j < arr_length; j++)
		{
			MAZE.at(i).at(j) = 'x';
		}
	}
	for (int i = 1; i < arr_height; i += 2)
	{
		for (int j = 1; j < arr_length; j += 2)
		{
			MAZE.at(i).at(j) = ' ';
		}
	}
}

int main(int argc, char* argv[])
{
	string mode;
	if (!get_input(argc, argv, mode))
	{
		return 1;
	}

	srand(time(NULL));								//set rand sequence
	arr_height = (2 * HEIGHT) + 1;
	arr_length = (2 * LENGTH) + 1;
	VECTOR MAZE(arr_height, vector <char> (arr_length));		//set maze

	maze_init(MAZE, arr_height, arr_length);

	if (mode == "e")
		gen_easy(MAZE, arr_height, arr_length);
	else
		gen_hard(MAZE, arr_height, arr_length);
	set_start_end(MAZE, arr_height, arr_length);

	print(MAZE, arr_height, arr_length);

	return 0;
}
<commit_msg>fixed UI bug<commit_after>#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include "aesthetics.h"
#include "operators.h"
#include "easy.h"
#include "hard.h"
using namespace std;

typedef vector < vector<char> > VECTOR;

unsigned int LENGTH = 1;
unsigned int HEIGHT = 1;
int arr_height = 3;
int arr_length = 3;

bool get_input(int argc, char* argv[], string & mode)
{
	if (argc > 1 && argc < 5)						//if length & height passed
	{
		if (argc == 2)								//missing one arg
		{
			cout << "Missing height arg" << endl;
			return false;
		}
		else
		{
			LENGTH = atoi(argv[1]);
			HEIGHT = atoi(argv[2]);
			if (LENGTH <= 0)						//must be > 0
			{
				cout << "Invalid length" << endl;
				return false;
			}
			if (HEIGHT <= 0)						//must be > 0
			{
				cout << "Invalid height" << endl;
				return false;
			}
		}
	}
	if (argc > 3)									//too many args passed
	{
		mode = argv[3];
		if (argc > 4)
		{
			cout << "Too many arguments" << endl;
			return false;
		}
		if (mode == "e" || mode == "E" || mode == "easy" || mode == "Easy")
		{
			mode = "e";
		}
		else
			mode = "h";
	}
	if (argc == 1)									//no args passed
	{
		cout << "Enter the length of the maze." << endl;
		int l = 0;
		while (l <= 0)								//get length
		{
			cin >> l;
		}
		cout << "Enter the height of the maze." << endl;
		int h = 0;
		while (h <= 0)								//get height
		{
			cin >> h;
		}
		LENGTH = l;
		HEIGHT = h;
		cout << "Enter the difficulty of the maze. ";
		cout << "1 for easy, 2 for hard." << endl;
		int d = 0;
		while (d <= 0 || d > 2)
		{
			cin >> d;
		}
		if (d == 1)
			mode = "e";
		else
			mode = "h";
	}
	return true;
}

void maze_init(VECTOR &MAZE, int arr_height, int arr_length)
{
	for (int i = 0; i < arr_height; i++)			//init maze with x
	{
		for (int j = 0; j < arr_length; j++)
		{
			MAZE.at(i).at(j) = 'x';
		}
	}
	for (int i = 1; i < arr_height; i += 2)
	{
		for (int j = 1; j < arr_length; j += 2)
		{
			MAZE.at(i).at(j) = ' ';
		}
	}
}

int main(int argc, char* argv[])
{
	string mode;
	if (!get_input(argc, argv, mode))
	{
		return 1;
	}

	srand(time(NULL));								//set rand sequence
	arr_height = (2 * HEIGHT) + 1;
	arr_length = (2 * LENGTH) + 1;
	VECTOR MAZE(arr_height, vector <char> (arr_length));		//set maze

	maze_init(MAZE, arr_height, arr_length);

	if (mode == "e")
		gen_easy(MAZE, arr_height, arr_length);
	else
		gen_hard(MAZE, arr_height, arr_length);
	set_start_end(MAZE, arr_height, arr_length);

	print(MAZE, arr_height, arr_length);

	return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2005, 2006, 2007 Florian Schmitz
 *
 * This file is part of CSSTidy.
 *
 *  CSSTidy is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   CSSTidy 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 program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "csspp_globals.hpp"

bool escaped(const string &istring, const int pos)
{
	return !(s_at(istring,pos-1) != '\\' || escaped(istring,pos-1));
}

// Save replacement for .at()
char s_at(const string &istring, const int pos)
{
	if(pos > (istring.length()-1) && pos < 0)
	{
		return 0;
	}
	else
	{
		return istring[pos];
	}
}

vector<string> explode(const string e,string s, const bool check)
{
	vector<string> ret;
	int iPos = s.find(e, 0);
	int iPit = e.length();

	while(iPos > -1)
	{
		if(iPos != 0 || check)
		{
			ret.push_back(s.substr(0,iPos));
		}
		s.erase(0,iPos+iPit);
		iPos = s.find(e, 0);
	}

 	if(s != "" || check)
 	{
		ret.push_back(s);
	}
	return ret;
}

string implode(const string e,const vector<string> s)
{
	string ret;
	for(int i = 0; i < s.size(); i++)
	{
		ret += s[i];
		if(i != (s.size()-1)) ret += e;
	}
	return ret;
}

string build_value(const vector<string> subvalues)
{
	string ret;
	for(int i = 0; i < subvalues.size(); i++)
	{
		ret += subvalues[i];
		if(i != (subvalues.size()-1))
		{
			char last = s_at(subvalues[i], subvalues[i].length()-1);
			char next = s_at(subvalues[i+1], 0);
			if (strchr("(,=:", last) != NULL || strchr("),=:", next) != NULL)
			{
				continue;
			}
			ret += " ";
		}
	}
	return ret;
}

float round(const float &number, const int num_digits)
{
    float doComplete5i, doComplete5(number * powf(10.0f, (float) (num_digits + 1)));

    if(number < 0.0f)
        doComplete5 -= 5.0f;
    else
        doComplete5 += 5.0f;

    doComplete5 /= 10.0f;
    modff(doComplete5, &doComplete5i);

    return doComplete5i / powf(10.0f, (float) num_digits);
}

string str_replace(const string find, const string replace, string str)
{
    int len = find.length();
    int replace_len = replace.length();
    int pos = str.find(find);

    while(pos != string::npos)
	{
        str.replace(pos, len, replace);
        pos = str.find(find, pos + replace_len);
    }
    return str;
}

string str_replace(const vector<string>& find, const string replace, string str)
{
	int replace_len = replace.length();

	for(int i = 0; i < find.size(); ++i)
	{
	    int len = find[i].length();
	    int pos = str.find(find[i]);

	    while(pos != string::npos)
		{
	        str.replace(pos, len, replace);
	        pos = str.find(find[i], pos + replace_len);
	    }
	}
    return str;
}

bool in_char_arr(const char* haystack, const char needle)
{
	for(int i = 0; i < strlen(haystack); ++i)
	{
		if(haystack[i] == needle)
		{
			return true;
		}
	}
	return false;
}

bool in_str_array(const string& haystack, const char needle)
{
	return (haystack.find_first_of(needle,0) != string::npos);
}

bool in_str_array(const vector<string>& haystack, const string needle)
{
	for(int i = 0; i < haystack.size(); ++i)
	{
		if(haystack[i] == needle)
		{
			return true;
		}
	}
	return false;
}

string htmlspecialchars(string istring, int quotes)
{
	istring = str_replace("&","&",istring);
	istring = str_replace("<","<",istring);
	istring = str_replace(">",">",istring);
	if(quotes > 0) istring = str_replace("\"",""",istring);
	if(quotes > 1) istring = str_replace("'","'",istring);
	return istring;
}

int max(const int i1, const int i2)
{
	if(i1 > i2)
	{
		return i1;
	}
	else
	{
		return i2;
	}
}

bool ctype_space(const char c)
{
	return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 11);
}

bool ctype_digit(const char c)
{
	return (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9');
}

vector<string> unserialise_sa(const string istring)
{
	int strlen = istring.length();
	int strpos = 0;
	vector<string> ret;

	while(strlen > 0)
	{
		string digit_tmp = "";
		for(int i = strpos; ctype_digit(s_at(istring,i)); i++)
		{
			digit_tmp += istring[i];
			--strlen; ++strpos;
		}
		// :
		--strlen; ++strpos;

		int next_length = static_cast<int>(str2f(digit_tmp));
		next_length += strpos;

		string string_tmp = "";
		for(int i = strpos; (i<istring.length() && i < next_length); i++)
		{
			string_tmp += istring[i];
			--strlen; ++strpos;
		}
		ret.push_back(string_tmp);
	}
	return ret;
}

string serialise_sa(const string istring)
{
	return f2str(istring.length()) + ":" + istring;
}

bool ctype_xdigit(char c)
{
	c = chartolower(c);
	return (ctype_digit(c) || c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f');
}

bool ctype_alpha(char c)
{
	c = chartolower(c);
	return (c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h' || c == 'i' || c == 'j' ||
	   c == 'k' || c == 'l' || c == 'm' || c == 'n' || c == 'o' || c == 'p' || c == 'q' || c == 'r' || c == 's' || c == 't' ||
	   c == 'u' || c == 'v' || c == 'w' || c == 'x' || c == 'y' || c == 'z');
}
<commit_msg>In csstidy/misc.cpp, add uncaught missing include<commit_after>/*
 * Copyright 2005, 2006, 2007 Florian Schmitz
 *
 * This file is part of CSSTidy.
 *
 *  CSSTidy is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   CSSTidy 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 program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstring>
#include "csspp_globals.hpp"

bool escaped(const string &istring, const int pos)
{
	return !(s_at(istring,pos-1) != '\\' || escaped(istring,pos-1));
}

// Save replacement for .at()
char s_at(const string &istring, const int pos)
{
	if(pos > (istring.length()-1) && pos < 0)
	{
		return 0;
	}
	else
	{
		return istring[pos];
	}
}

vector<string> explode(const string e,string s, const bool check)
{
	vector<string> ret;
	int iPos = s.find(e, 0);
	int iPit = e.length();

	while(iPos > -1)
	{
		if(iPos != 0 || check)
		{
			ret.push_back(s.substr(0,iPos));
		}
		s.erase(0,iPos+iPit);
		iPos = s.find(e, 0);
	}

 	if(s != "" || check)
 	{
		ret.push_back(s);
	}
	return ret;
}

string implode(const string e,const vector<string> s)
{
	string ret;
	for(int i = 0; i < s.size(); i++)
	{
		ret += s[i];
		if(i != (s.size()-1)) ret += e;
	}
	return ret;
}

string build_value(const vector<string> subvalues)
{
	string ret;
	for(int i = 0; i < subvalues.size(); i++)
	{
		ret += subvalues[i];
		if(i != (subvalues.size()-1))
		{
			char last = s_at(subvalues[i], subvalues[i].length()-1);
			char next = s_at(subvalues[i+1], 0);
			if (strchr("(,=:", last) != NULL || strchr("),=:", next) != NULL)
			{
				continue;
			}
			ret += " ";
		}
	}
	return ret;
}

float round(const float &number, const int num_digits)
{
    float doComplete5i, doComplete5(number * powf(10.0f, (float) (num_digits + 1)));

    if(number < 0.0f)
        doComplete5 -= 5.0f;
    else
        doComplete5 += 5.0f;

    doComplete5 /= 10.0f;
    modff(doComplete5, &doComplete5i);

    return doComplete5i / powf(10.0f, (float) num_digits);
}

string str_replace(const string find, const string replace, string str)
{
    int len = find.length();
    int replace_len = replace.length();
    int pos = str.find(find);

    while(pos != string::npos)
	{
        str.replace(pos, len, replace);
        pos = str.find(find, pos + replace_len);
    }
    return str;
}

string str_replace(const vector<string>& find, const string replace, string str)
{
	int replace_len = replace.length();

	for(int i = 0; i < find.size(); ++i)
	{
	    int len = find[i].length();
	    int pos = str.find(find[i]);

	    while(pos != string::npos)
		{
	        str.replace(pos, len, replace);
	        pos = str.find(find[i], pos + replace_len);
	    }
	}
    return str;
}

bool in_char_arr(const char* haystack, const char needle)
{
	for(int i = 0; i < strlen(haystack); ++i)
	{
		if(haystack[i] == needle)
		{
			return true;
		}
	}
	return false;
}

bool in_str_array(const string& haystack, const char needle)
{
	return (haystack.find_first_of(needle,0) != string::npos);
}

bool in_str_array(const vector<string>& haystack, const string needle)
{
	for(int i = 0; i < haystack.size(); ++i)
	{
		if(haystack[i] == needle)
		{
			return true;
		}
	}
	return false;
}

string htmlspecialchars(string istring, int quotes)
{
	istring = str_replace("&","&",istring);
	istring = str_replace("<","<",istring);
	istring = str_replace(">",">",istring);
	if(quotes > 0) istring = str_replace("\"",""",istring);
	if(quotes > 1) istring = str_replace("'","'",istring);
	return istring;
}

int max(const int i1, const int i2)
{
	if(i1 > i2)
	{
		return i1;
	}
	else
	{
		return i2;
	}
}

bool ctype_space(const char c)
{
	return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 11);
}

bool ctype_digit(const char c)
{
	return (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9');
}

vector<string> unserialise_sa(const string istring)
{
	int strlen = istring.length();
	int strpos = 0;
	vector<string> ret;

	while(strlen > 0)
	{
		string digit_tmp = "";
		for(int i = strpos; ctype_digit(s_at(istring,i)); i++)
		{
			digit_tmp += istring[i];
			--strlen; ++strpos;
		}
		// :
		--strlen; ++strpos;

		int next_length = static_cast<int>(str2f(digit_tmp));
		next_length += strpos;

		string string_tmp = "";
		for(int i = strpos; (i<istring.length() && i < next_length); i++)
		{
			string_tmp += istring[i];
			--strlen; ++strpos;
		}
		ret.push_back(string_tmp);
	}
	return ret;
}

string serialise_sa(const string istring)
{
	return f2str(istring.length()) + ":" + istring;
}

bool ctype_xdigit(char c)
{
	c = chartolower(c);
	return (ctype_digit(c) || c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f');
}

bool ctype_alpha(char c)
{
	c = chartolower(c);
	return (c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h' || c == 'i' || c == 'j' ||
	   c == 'k' || c == 'l' || c == 'm' || c == 'n' || c == 'o' || c == 'p' || c == 'q' || c == 'r' || c == 's' || c == 't' ||
	   c == 'u' || c == 'v' || c == 'w' || c == 'x' || c == 'y' || c == 'z');
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemoryManager.hpp>
#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN

void* XMemory::operator new(size_t size)
{
	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));

    void* const block = XMLPlatformUtils::fgMemoryManager->allocate
        (
	        headerSize + size
        );
    *(MemoryManager**)block = XMLPlatformUtils::fgMemoryManager;

    return (char*)block + headerSize;
}

#if defined(XML_VISUALCPP)

void* XMemory::operator new(size_t size, const char* file, int line)
{
		 return operator new(size);
}

void XMemory::operator delete(void* p, const char* file, int line)
{
		 operator delete(p);
}

#endif

void* XMemory::operator new(size_t size, MemoryManager* manager)
{
    assert(manager != 0);

	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));
    void* const block = manager->allocate(headerSize + size);
    *(MemoryManager**)block = manager;

    return (char*)block + headerSize;
}

void XMemory::operator delete(void* p)
{
    if (p != 0)
    {
		size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
											sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        MemoryManager* const manager = *(MemoryManager**)block;
        assert(manager != 0);
        manager->deallocate(block);
    }
}

//The HP compiler is complaining about duplicate overloading of delete
#if !defined(XML_HPUX) && !defined(XML_BORLAND)

void XMemory::operator delete(void* p, MemoryManager* manager)
{
    assert(manager != 0);

    if (p != 0)
    {
        size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;
        assert(*(MemoryManager**)block == manager);
        /***
         * NOTE: for compiler which can't properly trace the memory manager used in the
         *       placement new, we use the memory manager embedded in the memory rather
         *       than the one passed in
         */
        MemoryManager* pM = *(MemoryManager**)block;
        pM->deallocate(block);
    }
}

#endif

XERCES_CPP_NAMESPACE_END

<commit_msg>do not assert memorymanager in placement delete.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMemory.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/framework/MemoryManager.hpp>
#include <assert.h>

XERCES_CPP_NAMESPACE_BEGIN

void* XMemory::operator new(size_t size)
{
	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));

    void* const block = XMLPlatformUtils::fgMemoryManager->allocate
        (
	        headerSize + size
        );
    *(MemoryManager**)block = XMLPlatformUtils::fgMemoryManager;

    return (char*)block + headerSize;
}

#if defined(XML_VISUALCPP)

void* XMemory::operator new(size_t size, const char* file, int line)
{
		 return operator new(size);
}

void XMemory::operator delete(void* p, const char* file, int line)
{
		 operator delete(p);
}

#endif

void* XMemory::operator new(size_t size, MemoryManager* manager)
{
    assert(manager != 0);

	size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
										sizeof(MemoryManager*));
    void* const block = manager->allocate(headerSize + size);
    *(MemoryManager**)block = manager;

    return (char*)block + headerSize;
}

void XMemory::operator delete(void* p)
{
    if (p != 0)
    {
		size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(
											sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        MemoryManager* const manager = *(MemoryManager**)block;
        assert(manager != 0);
        manager->deallocate(block);
    }
}

//The HP compiler is complaining about duplicate overloading of delete
#if !defined(XML_HPUX) && !defined(XML_BORLAND)

void XMemory::operator delete(void* p, MemoryManager* manager)
{
    assert(manager != 0);

    if (p != 0)
    {
        size_t headerSize = XMLPlatformUtils::alignPointerForNewBlockAllocation(sizeof(MemoryManager*));
        void* const block = (char*)p - headerSize;

        /***
         * assert(*(MemoryManager**)block == manager);
         *
         * NOTE: for compiler which can't properly trace the memory manager used in the
         *       placement new, we use the memory manager embedded in the memory rather
         *       than the one passed in
         */
        MemoryManager* pM = *(MemoryManager**)block;
        pM->deallocate(block);
    }
}

#endif

XERCES_CPP_NAMESPACE_END

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// Tooling sample. Demonstrates:
//
// * How to write a simple source tool using libTooling.
// * How to use RecursiveASTVisitor to find interesting AST nodes.
// * How to use the Rewriter API to rewrite the source code.
//
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//------------------------------------------------------------------------------
#include <sstream>
#include <string>

#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"

namespace cl = llvm::cl;
using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;

static cl::OptionCategory ToolingSampleCategory("Tooling Sample");

// By implementing RecursiveASTVisitor, we can specify which AST nodes
// we're interested in by overriding relevant methods.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
  MyASTVisitor(Rewriter &R) : TheRewriter(R) {}

  bool VisitStmt(Stmt *s) {
    // Only care about If statements.
    if (isa<IfStmt>(s)) {
      IfStmt *IfStatement = cast<IfStmt>(s);
      Stmt *Then = IfStatement->getThen();

      TheRewriter.InsertText(Then->getLocStart(), "// the 'if' part\n", true,
                             true);

      Stmt *Else = IfStatement->getElse();
      if (Else)
        TheRewriter.InsertText(Else->getLocStart(), "// the 'else' part\n",
                               true, true);
    }

    return true;
  }

  bool VisitFunctionDecl(FunctionDecl *f) {
    // Only function definitions (with bodies), not declarations.
    if (f->hasBody()) {
      Stmt *FuncBody = f->getBody();

      // Type name as string
      QualType QT = f->getReturnType();
      std::string TypeStr = QT.getAsString();

      // Function name
      DeclarationName DeclName = f->getNameInfo().getName();
      std::string FuncName = DeclName.getAsString();

      // Add comment before
      std::stringstream SSBefore;
      SSBefore << "// Begin function " << FuncName << " returning " << TypeStr
               << "\n";
      SourceLocation ST = f->getSourceRange().getBegin();
      TheRewriter.InsertText(ST, SSBefore.str(), true, true);

      // And after
      std::stringstream SSAfter;
      SSAfter << "\n// End function " << FuncName;
      ST = FuncBody->getLocEnd().getLocWithOffset(1);
      TheRewriter.InsertText(ST, SSAfter.str(), true, true);
    }

    return true;
  }

private:
  Rewriter &TheRewriter;
};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser.
class MyASTConsumer : public ASTConsumer {
public:
  MyASTConsumer(Rewriter &R) : Visitor(R) {}

  // Override the method that gets called for each parsed top-level
  // declaration.
  virtual bool HandleTopLevelDecl(DeclGroupRef DR) {
    for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b)
      // Traverse the declaration using our AST visitor.
      Visitor.TraverseDecl(*b);
    return true;
  }

private:
  MyASTVisitor Visitor;
};

// For each source file provided to the tool, a new FrontendAction is created.
class MyFrontendAction : public ASTFrontendAction {
public:
  MyFrontendAction() {}
  void EndSourceFileAction() override {
    SourceManager &SM = TheRewriter.getSourceMgr();
    llvm::errs() << "** EndSourceFileAction for: "
                 << SM.getFileEntryForID(SM.getMainFileID())->getName() << "\n";

    // Now emit the rewritten buffer.
    TheRewriter.getEditBuffer(SM.getMainFileID()).write(llvm::outs());
  }

  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                 StringRef file) override {
    llvm::errs() << "** Creating AST consumer for: " << file << "\n";
    TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
    return new MyASTConsumer(TheRewriter);
  }

private:
  Rewriter TheRewriter;
};

int main(int argc, const char **argv) {
  CommonOptionsParser op(argc, argv, ToolingSampleCategory);
  ClangTool Tool(op.getCompilations(), op.getSourcePathList());

  // ClangTool::run accepts a FrontendActionFactory, which is then used to
  // create new objects implementing the FrontendAction interface. Here we use
  // the helper newFrontendActionFactory to create a default factory that will
  // return a new MyFrontendAction object every time.
  // To further customize this, we could create our own factory class.
  return Tool.run(newFrontendActionFactory<MyFrontendAction>());
}
<commit_msg>Replace virtual by override.<commit_after>//------------------------------------------------------------------------------
// Tooling sample. Demonstrates:
//
// * How to write a simple source tool using libTooling.
// * How to use RecursiveASTVisitor to find interesting AST nodes.
// * How to use the Rewriter API to rewrite the source code.
//
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//------------------------------------------------------------------------------
#include <sstream>
#include <string>

#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"

namespace cl = llvm::cl;
using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;

static cl::OptionCategory ToolingSampleCategory("Tooling Sample");

// By implementing RecursiveASTVisitor, we can specify which AST nodes
// we're interested in by overriding relevant methods.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
  MyASTVisitor(Rewriter &R) : TheRewriter(R) {}

  bool VisitStmt(Stmt *s) {
    // Only care about If statements.
    if (isa<IfStmt>(s)) {
      IfStmt *IfStatement = cast<IfStmt>(s);
      Stmt *Then = IfStatement->getThen();

      TheRewriter.InsertText(Then->getLocStart(), "// the 'if' part\n", true,
                             true);

      Stmt *Else = IfStatement->getElse();
      if (Else)
        TheRewriter.InsertText(Else->getLocStart(), "// the 'else' part\n",
                               true, true);
    }

    return true;
  }

  bool VisitFunctionDecl(FunctionDecl *f) {
    // Only function definitions (with bodies), not declarations.
    if (f->hasBody()) {
      Stmt *FuncBody = f->getBody();

      // Type name as string
      QualType QT = f->getReturnType();
      std::string TypeStr = QT.getAsString();

      // Function name
      DeclarationName DeclName = f->getNameInfo().getName();
      std::string FuncName = DeclName.getAsString();

      // Add comment before
      std::stringstream SSBefore;
      SSBefore << "// Begin function " << FuncName << " returning " << TypeStr
               << "\n";
      SourceLocation ST = f->getSourceRange().getBegin();
      TheRewriter.InsertText(ST, SSBefore.str(), true, true);

      // And after
      std::stringstream SSAfter;
      SSAfter << "\n// End function " << FuncName;
      ST = FuncBody->getLocEnd().getLocWithOffset(1);
      TheRewriter.InsertText(ST, SSAfter.str(), true, true);
    }

    return true;
  }

private:
  Rewriter &TheRewriter;
};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser.
class MyASTConsumer : public ASTConsumer {
public:
  MyASTConsumer(Rewriter &R) : Visitor(R) {}

  // Override the method that gets called for each parsed top-level
  // declaration.
  bool HandleTopLevelDecl(DeclGroupRef DR) override {
    for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b)
      // Traverse the declaration using our AST visitor.
      Visitor.TraverseDecl(*b);
    return true;
  }

private:
  MyASTVisitor Visitor;
};

// For each source file provided to the tool, a new FrontendAction is created.
class MyFrontendAction : public ASTFrontendAction {
public:
  MyFrontendAction() {}
  void EndSourceFileAction() override {
    SourceManager &SM = TheRewriter.getSourceMgr();
    llvm::errs() << "** EndSourceFileAction for: "
                 << SM.getFileEntryForID(SM.getMainFileID())->getName() << "\n";

    // Now emit the rewritten buffer.
    TheRewriter.getEditBuffer(SM.getMainFileID()).write(llvm::outs());
  }

  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                 StringRef file) override {
    llvm::errs() << "** Creating AST consumer for: " << file << "\n";
    TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
    return new MyASTConsumer(TheRewriter);
  }

private:
  Rewriter TheRewriter;
};

int main(int argc, const char **argv) {
  CommonOptionsParser op(argc, argv, ToolingSampleCategory);
  ClangTool Tool(op.getCompilations(), op.getSourcePathList());

  // ClangTool::run accepts a FrontendActionFactory, which is then used to
  // create new objects implementing the FrontendAction interface. Here we use
  // the helper newFrontendActionFactory to create a default factory that will
  // return a new MyFrontendAction object every time.
  // To further customize this, we could create our own factory class.
  return Tool.run(newFrontendActionFactory<MyFrontendAction>());
}
<|endoftext|>


<commit_before>/** \file
* \brief Web Browser Control
*
* See Copyright Notice in "iup.h"
*/

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

#include <windows.h>
#include <exdisp.h>

#include "iup.h"
#include "iupcbs.h"
#include "iupole.h"

#include "iup_object.h"
#include "iup_register.h"
#include "iup_attrib.h"
#include "iup_stdcontrols.h"
#include "iup_str.h"
#include "iup_layout.h"
#include "iup_webbrowser.h"
#include "iup_drv.h"
#include "iup_drvfont.h"

extern "C" WCHAR* iupwinStrChar2Wide(const char* str);
extern "C" char* iupwinStrWide2Char(const WCHAR* wstr);

///////////////////////////////////////////////////////////////////////////////
// Interface to get WebBrowserEvents
///////////////////////////////////////////////////////////////////////////////

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

#include <shlguid.h>   // IID_IWebBrowser2, DIID_DWebBrowserEvents2
#include <exdispid.h>  // DISPID_*

using namespace ATL;

interface CSink:public IDispEventImpl<0, CSink, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 0>
{
public:
  Ihandle* ih;

  BEGIN_SINK_MAP(CSink)
    SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)
#ifdef DISPID_NEWWINDOW3
    SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3, NewWindow3)
#endif
  END_SINK_MAP()

  void STDMETHODCALLTYPE BeforeNavigate2(IDispatch *pDisp, VARIANT *url, VARIANT *Flags, VARIANT *TargetFrameName,
                                         VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
  {
    IFnss cbNavigate = (IFnss)IupGetCallback(ih, "NAVIGATE_CB");
    if (cbNavigate)
    {
      char* resultString = iupwinStrWide2Char(url->bstrVal);
      cbNavigate(ih, "NOREASON", resultString);
      free(resultString);
      // TO DO: detect types of action, like "link_clicked", "refresh", "form submitted", "backward/forward"
    }

    (void)Cancel;
    (void)Headers;
    (void)PostData;
    (void)TargetFrameName;
    (void)Flags;
    (void)pDisp;
  }

#ifdef DISPID_NEWWINDOW3
  void STDMETHODCALLTYPE NewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags,
                                    BSTR bstrUrlContext, BSTR bstrUrl)
  {
    IFns cbNewWindow = (IFns)IupGetCallback(ih, "NEWWINDOW_CB");
    if (cbNewWindow)
    {
      char* urlString = iupwinStrWide2Char(bstrUrl);
      cbNewWindow(ih, urlString);
      free(urlString);
    }

    (void)bstrUrlContext;
    (void)dwFlags;
    (void)Cancel;
    (void)ppDisp;
  }
#endif
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static int winWebBrowserSetHTMLAttrib(Ihandle* ih, const char* value)
{
  if (!value)
    return 0;

  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  int size = strlen(value)+1;

  // Create the memory for the stream
  HGLOBAL hHTMLText = GlobalAlloc(GPTR, size);
  strcpy((char*)hHTMLText, value); // weird but we follow the tutorial on MSDN

  // Create the stream
  IStream* pStream = NULL;
  CreateStreamOnHGlobal(hHTMLText, TRUE, &pStream);

  // Retrieve the document object.
  IDispatch* pHtmlDoc = NULL;
  pweb->get_Document(&pHtmlDoc);
  if (!pHtmlDoc)
  {
    pweb->Navigate(L"about:blank", NULL, NULL, NULL, NULL);
    IupFlush();

    pweb->get_Document(&pHtmlDoc);
  }

  // Query for IPersistStreamInit.
  IPersistStreamInit* pPersistStreamInit = NULL;
  pHtmlDoc->QueryInterface(IID_IPersistStreamInit, (void**)&pPersistStreamInit);
  //Initialize the document.
  pPersistStreamInit->InitNew();
  // Load the contents of the stream.
  pPersistStreamInit->Load(pStream);

  // Releases
  pPersistStreamInit->Release();
  pStream->Release();
  pHtmlDoc->Release();
  GlobalFree(hHTMLText);

  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetBackForwardAttrib(Ihandle* ih, const char* value)
{
  int i, val;
  if (iupStrToInt(value, &val))
  {
    IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");

    /* Negative values represent steps backward while positive values represent steps forward. */
    if(val > 0)
    {
      for(i = 0; i < val; i++)
        pweb->GoForward();
    }
    else if(val < 0)
    {
      for(i = 0; i < -(val); i++)
        pweb->GoBack();
    }
  }

  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetReloadAttrib(Ihandle* ih, const char* value)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Refresh();

  (void)value;
  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetStopAttrib(Ihandle* ih, const char* value)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Stop();

  (void)value;
  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetValueAttrib(Ihandle* ih, const char* value)
{
  if (value)
  {
    IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
    WCHAR* wvalue = iupwinStrChar2Wide(value);
    //CComVariant var = CComVariant("_top");
    //pweb->Navigate(wvalue, NULL, &var, NULL, NULL);
    pweb->Navigate(wvalue, NULL, NULL, NULL, NULL);
    free(wvalue);
  }
  return 0;
}

static char* winWebBrowserGetValueAttrib(Ihandle* ih)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  BSTR pbstrLocationURL = NULL;
  if (pweb->get_LocationURL(&pbstrLocationURL)==S_OK && pbstrLocationURL)
  {
    char* str = iupwinStrWide2Char(pbstrLocationURL);
    SysFreeString(pbstrLocationURL);
    char* value = iupStrGetMemoryCopy(str);
    free(str);
    return value;
  }
  return NULL;
}

static int winWebBrowserCreateMethod(Ihandle* ih, void **params)
{
  (void)params;
  IupSetAttribute(ih, "PROGID", "Shell.Explorer.2");
  IupSetAttribute(ih, "DESIGNMODE", "NO");

  // Get the current IUnknown*
  IUnknown *punk = (IUnknown*)IupGetAttribute(ih, "IUNKNOWN");

  IWebBrowser2 *pweb = NULL;
  punk->QueryInterface(IID_IWebBrowser2, (void **)&pweb);
  iupAttribSetStr(ih, "_IUPWEB_BROWSER", (char*)pweb);

  // CComModule implements a COM server module, allowing a client to access the module's components
  CComModule* module = new CComModule();

  // CSink object to capture events
  CSink* sink = new CSink();

  // Set handle to use in CSink Interface
  sink->ih = ih;

  // Initializing ATL Support
  module->Init(NULL, GetModuleHandle(NULL));

  // Connecting to the server's outgoing interface
  sink->DispEventAdvise(punk);

  iupAttribSetStr(ih, "_IUPWEB_MODULE", (char*)module);
  iupAttribSetStr(ih, "_IUPWEB_SINK", (char*)sink);
  punk->Release();

  return IUP_NOERROR;
}

static void winWebBrowserDestroyMethod(Ihandle* ih)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Release();

  CComModule* module = (CComModule*)iupAttribGet(ih, "_IUPWEB_MODULE");
  CSink* sink = (CSink*)iupAttribGet(ih, "_IUPWEB_SINK");

  // Get the current IUnknown*
  IUnknown *punk = (IUnknown*)IupGetAttribute(ih, "IUNKNOWN");

  // Disconnecting from the server's outgoing interface
  sink->DispEventUnadvise(punk);
  delete sink;

  // Terminating ATL support
  module->Term();
  delete module;

  punk->Release();
}

extern "C" Iclass* iupOleControlGetClass(void);

Iclass* iupWebBrowserGetClass(void)
{
  Iclass* ic = iupClassNew(iupOleControlGetClass());

  ic->name = "webbrowser";
  ic->format = NULL; /* no parameters */
  ic->nativetype = IUP_TYPECANVAS;
  ic->childtype  = IUP_CHILDNONE;
  ic->is_interactive = 1;

  /* Class functions */
  ic->Create = winWebBrowserCreateMethod;
  ic->Destroy = winWebBrowserDestroyMethod;

  /* Callbacks */
  iupClassRegisterCallback(ic, "NEWWINDOW_CB", "s");
  iupClassRegisterCallback(ic, "NAVIGATE_CB", "ss");

  /* Attributes */
  iupClassRegisterAttribute(ic, "VALUE", winWebBrowserGetValueAttrib, winWebBrowserSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "BACKFORWARD", NULL, winWebBrowserSetBackForwardAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "STOP", NULL, winWebBrowserSetStopAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "RELOAD", NULL, winWebBrowserSetReloadAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "HTML", NULL, winWebBrowserSetHTMLAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);

  return ic;
}
<commit_msg>*** empty log message ***<commit_after>/** \file
* \brief Web Browser Control
*
* See Copyright Notice in "iup.h"
*/

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

#include <windows.h>
#include <exdisp.h>

#include "iup.h"
#include "iupcbs.h"
#include "iupole.h"

#include "iup_object.h"
#include "iup_register.h"
#include "iup_attrib.h"
#include "iup_stdcontrols.h"
#include "iup_str.h"
#include "iup_layout.h"
#include "iup_webbrowser.h"
#include "iup_drv.h"
#include "iup_drvfont.h"

extern "C" WCHAR* iupwinStrChar2Wide(const char* str);
extern "C" char* iupwinStrWide2Char(const WCHAR* wstr);

///////////////////////////////////////////////////////////////////////////////
// Interface to get WebBrowserEvents
///////////////////////////////////////////////////////////////////////////////

#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>

#include <shlguid.h>   // IID_IWebBrowser2, DIID_DWebBrowserEvents2
#include <exdispid.h>  // DISPID_*

using namespace ATL;

interface CSink:public IDispEventImpl<0, CSink, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 0>
{
public:
  Ihandle* ih;

  BEGIN_SINK_MAP(CSink)
    SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)
#ifdef DISPID_NEWWINDOW3
    SINK_ENTRY_EX(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3, NewWindow3)
#endif
  END_SINK_MAP()

  void STDMETHODCALLTYPE BeforeNavigate2(IDispatch *pDisp, VARIANT *url, VARIANT *Flags, VARIANT *TargetFrameName,
                                         VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel)
  {
    IFnss cbNavigate = (IFnss)IupGetCallback(ih, "NAVIGATE_CB");
    if (cbNavigate)
    {
      char* resultString = iupwinStrWide2Char(url->bstrVal);
      cbNavigate(ih, "NOREASON", resultString);
      free(resultString);
      // TO DO: detect types of action, like "link_clicked", "refresh", "form submitted", "backward/forward"
    }

    (void)Cancel;
    (void)Headers;
    (void)PostData;
    (void)TargetFrameName;
    (void)Flags;
    (void)pDisp;
  }

#ifdef DISPID_NEWWINDOW3
  void STDMETHODCALLTYPE NewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags,
                                    BSTR bstrUrlContext, BSTR bstrUrl)
  {
    IFns cbNewWindow = (IFns)IupGetCallback(ih, "NEWWINDOW_CB");
    if (cbNewWindow)
    {
      char* urlString = iupwinStrWide2Char(bstrUrl);
      cbNewWindow(ih, urlString);
      free(urlString);
    }

    (void)bstrUrlContext;
    (void)dwFlags;
    (void)Cancel;
    (void)ppDisp;
  }
#endif
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static int winWebBrowserSetHTMLAttrib(Ihandle* ih, const char* value)
{
  if (!value)
    return 0;

  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  int size = strlen(value)+1;

  // Create the memory for the stream
  HGLOBAL hHTMLText = GlobalAlloc(GPTR, size);
  strcpy((char*)hHTMLText, value); // weird but we follow the tutorial on MSDN

  // Create the stream
  IStream* pStream = NULL;
  CreateStreamOnHGlobal(hHTMLText, TRUE, &pStream);

  // Retrieve the document object.
  IDispatch* pHtmlDoc = NULL;
  pweb->get_Document(&pHtmlDoc);
  if (!pHtmlDoc)
  {
    pweb->Navigate(L"about:blank", NULL, NULL, NULL, NULL);
    IupFlush();

    pweb->get_Document(&pHtmlDoc);
  }

  // Query for IPersistStreamInit.
  IPersistStreamInit* pPersistStreamInit = NULL;
  pHtmlDoc->QueryInterface(IID_IPersistStreamInit, (void**)&pPersistStreamInit);
  //Initialize the document.
  pPersistStreamInit->InitNew();
  // Load the contents of the stream.
  pPersistStreamInit->Load(pStream);

  // Releases
  pPersistStreamInit->Release();
  pStream->Release();
  pHtmlDoc->Release();
  GlobalFree(hHTMLText);

  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetBackForwardAttrib(Ihandle* ih, const char* value)
{
  int i, val;
  if (iupStrToInt(value, &val))
  {
    IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");

    /* Negative values represent steps backward while positive values represent steps forward. */
    if(val > 0)
    {
      for(i = 0; i < val; i++)
        pweb->GoForward();
    }
    else if(val < 0)
    {
      for(i = 0; i < -(val); i++)
        pweb->GoBack();
    }
  }

  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetReloadAttrib(Ihandle* ih, const char* value)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Refresh();

  (void)value;
  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetStopAttrib(Ihandle* ih, const char* value)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Stop();

  (void)value;
  return 0; /* do not store value in hash table */
}

static int winWebBrowserSetValueAttrib(Ihandle* ih, const char* value)
{
  if (value)
  {
    IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
    WCHAR* wvalue = iupwinStrChar2Wide(value);

    VARIANT var;
    VariantInit(&var);  //Initialize our variant
    var.vt = VT_ARRAY | VT_UI1;
    var.bstrVal = iupwinStrChar2Wide("_top");
    pweb->Navigate(wvalue, NULL, &var, NULL, NULL);

    //CComVariant var = CComVariant("_top");
    //pweb->Navigate(wvalue, NULL, &var, NULL, NULL);

    //pweb->Navigate(wvalue, NULL, NULL, NULL, NULL);
    free(wvalue);
  }
  return 0;
}

static char* winWebBrowserGetValueAttrib(Ihandle* ih)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  BSTR pbstrLocationURL = NULL;
  if (pweb->get_LocationURL(&pbstrLocationURL)==S_OK && pbstrLocationURL)
  {
    char* str = iupwinStrWide2Char(pbstrLocationURL);
    SysFreeString(pbstrLocationURL);
    char* value = iupStrGetMemoryCopy(str);
    free(str);
    return value;
  }
  return NULL;
}

static int winWebBrowserCreateMethod(Ihandle* ih, void **params)
{
  (void)params;
  IupSetAttribute(ih, "PROGID", "Shell.Explorer.2");
  IupSetAttribute(ih, "DESIGNMODE", "NO");

  // Get the current IUnknown*
  IUnknown *punk = (IUnknown*)IupGetAttribute(ih, "IUNKNOWN");

  IWebBrowser2 *pweb = NULL;
  punk->QueryInterface(IID_IWebBrowser2, (void **)&pweb);
  iupAttribSetStr(ih, "_IUPWEB_BROWSER", (char*)pweb);

  // CComModule implements a COM server module, allowing a client to access the module's components
  CComModule* module = new CComModule();

  // CSink object to capture events
  CSink* sink = new CSink();

  // Set handle to use in CSink Interface
  sink->ih = ih;

  // Initializing ATL Support
  module->Init(NULL, GetModuleHandle(NULL));

  // Connecting to the server's outgoing interface
  sink->DispEventAdvise(punk);

  iupAttribSetStr(ih, "_IUPWEB_MODULE", (char*)module);
  iupAttribSetStr(ih, "_IUPWEB_SINK", (char*)sink);
  punk->Release();

  return IUP_NOERROR;
}

static void winWebBrowserDestroyMethod(Ihandle* ih)
{
  IWebBrowser2 *pweb = (IWebBrowser2*)iupAttribGet(ih, "_IUPWEB_BROWSER");
  pweb->Release();

  CComModule* module = (CComModule*)iupAttribGet(ih, "_IUPWEB_MODULE");
  CSink* sink = (CSink*)iupAttribGet(ih, "_IUPWEB_SINK");

  // Get the current IUnknown*
  IUnknown *punk = (IUnknown*)IupGetAttribute(ih, "IUNKNOWN");

  // Disconnecting from the server's outgoing interface
  sink->DispEventUnadvise(punk);
  delete sink;

  // Terminating ATL support
  module->Term();
  delete module;

  punk->Release();
}

extern "C" Iclass* iupOleControlGetClass(void);

Iclass* iupWebBrowserGetClass(void)
{
  Iclass* ic = iupClassNew(iupOleControlGetClass());

  ic->name = "webbrowser";
  ic->format = NULL; /* no parameters */
  ic->nativetype = IUP_TYPECANVAS;
  ic->childtype  = IUP_CHILDNONE;
  ic->is_interactive = 1;

  /* Class functions */
  ic->Create = winWebBrowserCreateMethod;
  ic->Destroy = winWebBrowserDestroyMethod;

  /* Callbacks */
  iupClassRegisterCallback(ic, "NEWWINDOW_CB", "s");
  iupClassRegisterCallback(ic, "NAVIGATE_CB", "ss");

  /* Attributes */
  iupClassRegisterAttribute(ic, "VALUE", winWebBrowserGetValueAttrib, winWebBrowserSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "BACKFORWARD", NULL, winWebBrowserSetBackForwardAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "STOP", NULL, winWebBrowserSetStopAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "RELOAD", NULL, winWebBrowserSetReloadAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
  iupClassRegisterAttribute(ic, "HTML", NULL, winWebBrowserSetHTMLAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);

  return ic;
}
<|endoftext|>


<commit_before>#ifndef INCLUDED_STRING_REPLACE
#define INLCUDED_STRING_REPLACE
#include<string>
#include<cstring>

namespace srook{
inline namespace v1{

std::string& str_replace(std::string& str,const char* src,const char* rhs)
{
	if(str.empty()||!src||!*src||!rhs||!strcmp(src,rhs))
		return str;
	const size_t src_len=strlen(src);
	const size_t rhs_len=strlen(rhs);
	for(std::string::size_type i=0;
			(i=str.find(src,i,src_len))!=std::string::npos;
			i+=rhs_len)
		str.replace(i,src_len,rhs,rhs_len);
	return str;
}

}
}
#endif
<commit_msg>Update str_replace.hpp<commit_after>#ifndef INCLUDED_STRING_REPLACE
#define INLCUDED_STRING_REPLACE
#include<string>
#include<cstring>

namespace srook{
inline namespace v1{

std::string& str_replace(std::string& str,const char* src,const char* rhs)
{
	if(str.empty()||!src||!*src||!rhs||!std::strcmp(src,rhs))return str;

	const size_t src_len=std::strlen(src);
	const size_t rhs_len=std::strlen(rhs);
	for(std::string::size_type i=0;
			(i=str.find(src,i,src_len))!=std::string::npos;
			i+=rhs_len)
		str.replace(i,src_len,rhs,rhs_len);
	return str;
}

}
}
#endif
<|endoftext|>


<commit_before>#include <osgUtil/CubeMapGenerator>

#include <memory>
#ifndef __sgi
#include <cstdlib>
#else
#include <stdlib.h>
#endif

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:	osg::Referenced(),
	texture_size_(texture_size)
{
	for (int i=0; i<6; ++i) {
		osg::ref_ptr<osg::Image> image = osgNew osg::Image;
		//std::auto_ptr<unsigned char> data(static_cast<unsigned char *>(std::malloc(texture_size*texture_size*4)));
		std::auto_ptr<unsigned char> data(new unsigned char[(texture_size*texture_size*4)]);

		image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data.get());
		data.release();
		images_.push_back(image);
	}
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:	osg::Referenced(copy),
	texture_size_(copy.texture_size_)
{
	Image_list::const_iterator i;
	for (i=copy.images_.begin(); i!=copy.images_.end(); ++i) {
		images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
	}
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
	const float duv = 2.0f/(texture_size_-1);

	float v = 1;
	for (int i=0; i<texture_size_; ++i) {
		float u = 1;
		for (int j=0; j<texture_size_; ++j) {
			if (use_osg_system) {
				set_pixel(0, j, i, compute_color(osg::Vec3(1, -u, v)));
				set_pixel(1, j, i, compute_color(osg::Vec3(-1, u, v)));
				set_pixel(2, j, i, compute_color(osg::Vec3(-u, v, 1)));
				set_pixel(3, j, i, compute_color(osg::Vec3(-u, -v, -1)));
				set_pixel(4, j, i, compute_color(osg::Vec3(-u, -1, v)));
				set_pixel(5, j, i, compute_color(osg::Vec3(u, 1, v)));
			} else {
				set_pixel(0, j, i, compute_color(osg::Vec3(1, v, -u)));
				set_pixel(1, j, i, compute_color(osg::Vec3(-1, v, u)));
				set_pixel(2, j, i, compute_color(osg::Vec3(-u, 1, v)));
				set_pixel(3, j, i, compute_color(osg::Vec3(-u, -1, -v)));
				set_pixel(4, j, i, compute_color(osg::Vec3(-u, v, -1)));
				set_pixel(5, j, i, compute_color(osg::Vec3(u, v, 1)));
			}
			u -= duv;
		}
		v -= duv;
	}
}
<commit_msg>Fixed memory allocation.<commit_after>#include <osgUtil/CubeMapGenerator>
#include <stdlib.h>

using namespace osgUtil;

CubeMapGenerator::CubeMapGenerator(int texture_size)
:    osg::Referenced(),
    texture_size_(texture_size)
{
    for (int i=0; i<6; ++i)
    {
        osg::ref_ptr<osg::Image> image = osgNew osg::Image;
        unsigned char* data = (static_cast<unsigned char *>(malloc(texture_size*texture_size*4)));
        image->setImage(texture_size, texture_size, 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, data);
        images_.push_back(image);
    }
}

CubeMapGenerator::CubeMapGenerator(const CubeMapGenerator &copy, const osg::CopyOp &copyop)
:    osg::Referenced(copy),
    texture_size_(copy.texture_size_)
{
    Image_list::const_iterator i;
    for (i=copy.images_.begin(); i!=copy.images_.end(); ++i)
    {
        images_.push_back(static_cast<osg::Image *>(copyop(i->get())));
    }
}

void CubeMapGenerator::generateMap(bool use_osg_system)
{
    const float duv = 2.0f/(texture_size_-1);

    float v = 1;
    for (int i=0; i<texture_size_; ++i) {
        float u = 1;
        for (int j=0; j<texture_size_; ++j) {
            if (use_osg_system) {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, -u, v)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, u, v)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, v, 1)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -v, -1)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, -1, v)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, 1, v)));
            } else {
                set_pixel(0, j, i, compute_color(osg::Vec3(1, v, -u)));
                set_pixel(1, j, i, compute_color(osg::Vec3(-1, v, u)));
                set_pixel(2, j, i, compute_color(osg::Vec3(-u, 1, v)));
                set_pixel(3, j, i, compute_color(osg::Vec3(-u, -1, -v)));
                set_pixel(4, j, i, compute_color(osg::Vec3(-u, v, -1)));
                set_pixel(5, j, i, compute_color(osg::Vec3(u, v, 1)));
            }
            u -= duv;
        }
        v -= duv;
    }
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2012-2014 The SSDB Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
*/
// todo r2m adaptation : remove this
#include "t_kv.h"
#include "codec/encode.h"
#include "codec/decode.h"

int SSDBImpl::SetGeneric(const std::string &key, const std::string &val, int flags, const int64_t expire, char log_type){
	if (expire < 0){
		return -1;
	}

	Transaction trans(binlogs);

    std::string key_type;
    if (type(key, &key_type) == -1){
        return -1;
    }

    if ((flags & OBJ_SET_NX) && (key_type != "none")){
        return -1;
    } else if ((flags & OBJ_SET_XX) && (key_type == "none")){
        return -1;
    }

	if (key_type != "none"){
		DelKeyByType(key, key_type);
	}

	if (expire > 0){
        expiration->set_ttl_internal(key, expire);
	}

	std::string meta_key = encode_meta_key(key);
	std::string meta_val = encode_kv_val(val);
	binlogs->Put(meta_key, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, meta_key);
	leveldb::Status s = binlogs->commit();
	if (!s.ok()){
        //todo 时间戳排序回滚fast_keys first_timeout
		return -1;
	}
    return 0;
}

int SSDBImpl::multi_set(const std::vector<Bytes> &kvs, int offset, char log_type){
	Transaction trans(binlogs);

	std::vector<Bytes>::const_iterator it;
	it = kvs.begin() + offset;
	for(; it != kvs.end(); it += 2){
		const Bytes &key = *it;
        std::string key_type;
        int ret = type(key, &key_type);
        if (ret == -1){
            return  -1;
        } else if (ret == 1){
            DelKeyByType(key, key_type);
        }

		const Bytes &val = *(it + 1);
		std::string buf = encode_meta_key(key.String());
        std::string meta_val = encode_kv_val(val.String());
		binlogs->Put(buf, meta_val);
		binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	}
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("multi_set error: %s", s.ToString().c_str());
		return -1;
	}
	return (kvs.size() - offset)/2;
}

int SSDBImpl::multi_del(const std::vector<Bytes> &keys, int offset, char log_type){ //注：redis中不支持该接口
	Transaction trans(binlogs);

	std::vector<Bytes>::const_iterator it;
	it = keys.begin() + offset;
	for(; it != keys.end(); it++){
		const Bytes &key = *it;
// todo r2m adaptation
        std::string key_type;
        int ret = type(key, &key_type);
        if (ret == -1){
            return -1;
        } else if(ret == 1){
            DelKeyByType(key, key_type);
        }
	}
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("multi_del error: %s", s.ToString().c_str());
		return -1;
	}
	return keys.size() - offset;
}

int SSDBImpl::set(const Bytes &key, const Bytes &val, char log_type){
    return SetGeneric(key.String(), val.String(), OBJ_SET_NO_FLAGS, 0);
}

int SSDBImpl::setnx(const Bytes &key, const Bytes &val, char log_type){
    return SetGeneric(key.String(), val.String(), OBJ_SET_NX, 0);
}

int SSDBImpl::getset(const Bytes &key, std::string *val, const Bytes &newval, char log_type){
    Transaction trans(binlogs);
    int ret = get(key, val);
    if ( ret == -1){
        return -1;
    }

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(newval.String());
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("set error: %s", s.ToString().c_str());
		return -1;
	}
	return ret;
}

int SSDBImpl::del(const Bytes &key, char log_type){
    Transaction trans(binlogs);

    std::string key_type;
    int ret = type(key, &key_type);
    if (ret != 1){
        return ret;
    }
    int64_t num = 0;
    if (key_type == "string"){
        num = KDelNoLock(key);
    } else if (key_type == "hash"){
        num = HDelKeyNoLock(key);
    } else if (key_type == "set"){
        num = SDelKeyNoLock(key);
    } else if (key_type == "zset"){
        num = ZDelKeyNoLock(key);
    } else if (key_type == "list"){
        //todo
    }

    if (num > 0){
        leveldb::Status s = binlogs->commit();
        if(!s.ok()){
            log_error("set error: %s", s.ToString().c_str());
            return -1;
        }
    }

	return 1;
}

int SSDBImpl::incr(const Bytes &key, int64_t by, int64_t *new_val, char log_type){
	Transaction trans(binlogs);

	std::string old;
	int ret = this->get(key, &old);
	if(ret == -1){
		return -1;
	}else if(ret == 0){
		*new_val = by;
	}else{
        int64_t oldvalue = str_to_int64(old);
        if(errno != 0){
            return 0;
        }
        if ((by < 0 && oldvalue < 0 && by < (LLONG_MIN-oldvalue)) ||
            (by > 0 && oldvalue > 0 && by > (LLONG_MAX-oldvalue))) {
            return 0;
        }
		*new_val = oldvalue + by;
	}

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(str(*new_val));
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);

	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("del error: %s", s.ToString().c_str());
		return -1;
	}
	return 1;
}

int SSDBImpl::get(const Bytes &key, std::string *val){
	std::string buf = encode_meta_key(key.String());
    std::string en_val;

	leveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, &en_val);
	if(s.IsNotFound()){
		return 0;
	}
	if(!s.ok()){
		log_error("get error: %s", s.ToString().c_str());
		return -1;
	}
    KvMetaVal kv;
    if (kv.DecodeMetaVal(en_val) == -1){
        return -1;
    } else{
        *val = kv.value;
    }
	return 1;
}

// todo r2m adaptation
KIterator* SSDBImpl::scan(const Bytes &start, const Bytes &end, uint64_t limit){    //不支持kv scan，redis也不支持
	std::string key_start, key_end;
	key_start = encode_kv_key(start);
	if(end.empty()){
		key_end = "";
	}else{
		key_end = encode_kv_key(end);
	}
	//dump(key_start.data(), key_start.size(), "scan.start");
	//dump(key_end.data(), key_end.size(), "scan.end");

	return new KIterator(this->iterator(key_start, key_end, limit));
}

// todo r2m adaptation
KIterator* SSDBImpl::rscan(const Bytes &start, const Bytes &end, uint64_t limit){   //不支持kv scan，redis也不支持
	std::string key_start, key_end;

	key_start = encode_kv_key(start);
	if(start.empty()){
		key_start.append(1, 255);
	}
	if(!end.empty()){
		key_end = encode_kv_key(end);
	}
	//dump(key_start.data(), key_start.size(), "scan.start");
	//dump(key_end.data(), key_end.size(), "scan.end");

	return new KIterator(this->rev_iterator(key_start, key_end, limit));
}

int SSDBImpl::setbit(const Bytes &key, int bitoffset, int on, char log_type){
	Transaction trans(binlogs);

	std::string val;
	int ret = this->get(key, &val);
	if(ret == -1){
		return -1;
	}

    int len = bitoffset >> 3;
    int bit = 7 - (bitoffset & 0x7);
	if(len >= val.size()){
		val.resize(len + 1, 0);
	}
	int orig = val[len] & (1 << bit);
	if(on == 1){
		val[len] |= (1 << bit);
	}else{
		val[len] &= ~(1 << bit);
	}

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(val);
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("set error: %s", s.ToString().c_str());
		return -1;
	}
	return orig;
}

int SSDBImpl::getbit(const Bytes &key, int bitoffset){
	std::string val;
	int ret = this->get(key, &val);
	if(ret == -1){
		return -1;
	}

    int len = bitoffset >> 3;
    int bit = 7 - (bitoffset & 0x7);
	if(len >= val.size()){
		return 0;
	}
	return (val[len] & (1 << bit)) == 0? 0 : 1;
}

/*
 * private API
 */
int SSDBImpl::DelKeyByType(const Bytes &key, const std::string &type){
	//todo 内部接口，保证操作的原子性，调用No Commit接口
	if ("string" == type){
		KDelNoLock(key);
	} else if ("hash" == type){
		HDelKeyNoLock(key);
	} else if ("list" == type){
//		s = LDelKeyNoLock(key, &res);
	} else if ("set" == type){
//		s = SDelKeyNoLock(key, &res);
	} else if ("zset" == type){
		ZDelKeyNoLock(key);
	}

	return 0;
}

int SSDBImpl::KDel(const Bytes &key, char log_type){
    Transaction trans(binlogs);

    int num = KDelNoLock(key);
    if (num != 1){
        return num;
    }

    leveldb::Status s = binlogs->commit();
    if(!s.ok()){
        log_error("set error: %s", s.ToString().c_str());
        return -1;
    }
    return 1;
}

int SSDBImpl::KDelNoLock(const Bytes &key, char log_type){
	std::string buf = encode_meta_key(key.String());
    std::string en_val;
    leveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, &en_val);
    if(s.IsNotFound()){
        return 0;
    } else if(!s.ok()){
        log_error("get error: %s", s.ToString().c_str());
        return -1;
    } else{
        if (en_val[0] != DataType::KV){
            return 0;
        }
    }
	binlogs->Delete(buf);
	binlogs->add_log(log_type, BinlogCommand::KDEL, buf);
	return 1;
}

/*
 * General API
 */
int SSDBImpl::type(const Bytes &key, std::string *type){
	*type = "none";
    int ret = 0;
	std::string val;
	std::string meta_key = encode_meta_key(key.String());
	leveldb::Status s = ldb->Get(leveldb::ReadOptions(), meta_key, &val);
	if(s.IsNotFound()){
		return 0;
	}
	if(!s.ok()){
		log_error("get error: %s", s.ToString().c_str());
		return -1;
	}

	if (val[0] == DataType::KV){
		*type = "string";
        ret = 1;
	} else if (val[0] == DataType::HSIZE){
		HashMetaVal hv;
		if (hv.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (hv.del == KEY_ENABLED_MASK){
			*type = "hash";
            ret = 1;
		}
	} else if (val[0] == DataType::SSIZE){
		SetMetaVal sv;
		if (sv.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (sv.del == KEY_ENABLED_MASK){
			*type = "set";
            ret = 1;
		}
	} else if (val[0] == DataType::ZSIZE){
		ZSetMetaVal zs;
		if (zs.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (zs.del == KEY_ENABLED_MASK){
			*type = "zset";
            ret = 1;
		}
	} else if (val[0] == DataType::LSZIE){
		ListMetaVal ls;
		if (ls.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (ls.del == KEY_ENABLED_MASK){
			*type = "list";
            ret = 1;
		}
	} else{
		return -1;
	}

	return ret;
}
<commit_msg>modify multi_del<commit_after>/*
Copyright (c) 2012-2014 The SSDB Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
*/
// todo r2m adaptation : remove this
#include "t_kv.h"
#include "codec/encode.h"
#include "codec/decode.h"

int SSDBImpl::SetGeneric(const std::string &key, const std::string &val, int flags, const int64_t expire, char log_type){
	if (expire < 0){
		return -1;
	}

	Transaction trans(binlogs);

    std::string key_type;
    if (type(key, &key_type) == -1){
        return -1;
    }

    if ((flags & OBJ_SET_NX) && (key_type != "none")){
        return -1;
    } else if ((flags & OBJ_SET_XX) && (key_type == "none")){
        return -1;
    }

	if (key_type != "none"){
		DelKeyByType(key, key_type);
	}

	if (expire > 0){
        expiration->set_ttl_internal(key, expire);
	}

	std::string meta_key = encode_meta_key(key);
	std::string meta_val = encode_kv_val(val);
	binlogs->Put(meta_key, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, meta_key);
	leveldb::Status s = binlogs->commit();
	if (!s.ok()){
        //todo 时间戳排序回滚fast_keys first_timeout
		return -1;
	}
    return 0;
}

int SSDBImpl::multi_set(const std::vector<Bytes> &kvs, int offset, char log_type){
	Transaction trans(binlogs);

	std::vector<Bytes>::const_iterator it;
	it = kvs.begin() + offset;
	for(; it != kvs.end(); it += 2){
		const Bytes &key = *it;
        std::string key_type;
        int ret = type(key, &key_type);
        if (ret == -1){
            return  -1;
        } else if (ret == 1){
            DelKeyByType(key, key_type);
        }

		const Bytes &val = *(it + 1);
		std::string buf = encode_meta_key(key.String());
        std::string meta_val = encode_kv_val(val.String());
		binlogs->Put(buf, meta_val);
		binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	}
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("multi_set error: %s", s.ToString().c_str());
		return -1;
	}
	return (kvs.size() - offset)/2;
}

int SSDBImpl::multi_del(const std::vector<Bytes> &keys, int offset, char log_type){ //注：redis中不支持该接口
	Transaction trans(binlogs);

    int num = 0;
	std::vector<Bytes>::const_iterator it;
	it = keys.begin() + offset;
	for(; it != keys.end(); it++){
		const Bytes &key = *it;
        std::string key_type;
        int ret = type(key, &key_type);
        if (ret == -1){
            return -1;
        } else if(ret == 1){
            DelKeyByType(key, key_type);
            num++;
        }
	}
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("multi_del error: %s", s.ToString().c_str());
		return -1;
	}
	return num;
}

int SSDBImpl::set(const Bytes &key, const Bytes &val, char log_type){
    return SetGeneric(key.String(), val.String(), OBJ_SET_NO_FLAGS, 0);
}

int SSDBImpl::setnx(const Bytes &key, const Bytes &val, char log_type){
    return SetGeneric(key.String(), val.String(), OBJ_SET_NX, 0);
}

int SSDBImpl::getset(const Bytes &key, std::string *val, const Bytes &newval, char log_type){
    Transaction trans(binlogs);
    int ret = get(key, val);
    if ( ret == -1){
        return -1;
    }

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(newval.String());
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("set error: %s", s.ToString().c_str());
		return -1;
	}
	return ret;
}

int SSDBImpl::del(const Bytes &key, char log_type){
    Transaction trans(binlogs);

    std::string key_type;
    int ret = type(key, &key_type);
    if (ret != 1){
        return ret;
    }
    int64_t num = 0;
    if (key_type == "string"){
        num = KDelNoLock(key);
    } else if (key_type == "hash"){
        num = HDelKeyNoLock(key);
    } else if (key_type == "set"){
        num = SDelKeyNoLock(key);
    } else if (key_type == "zset"){
        num = ZDelKeyNoLock(key);
    } else if (key_type == "list"){
        //todo
    }

    if (num > 0){
        leveldb::Status s = binlogs->commit();
        if(!s.ok()){
            log_error("set error: %s", s.ToString().c_str());
            return -1;
        }
    }

	return 1;
}

int SSDBImpl::incr(const Bytes &key, int64_t by, int64_t *new_val, char log_type){
	Transaction trans(binlogs);

	std::string old;
	int ret = this->get(key, &old);
	if(ret == -1){
		return -1;
	}else if(ret == 0){
		*new_val = by;
	}else{
        int64_t oldvalue = str_to_int64(old);
        if(errno != 0){
            return 0;
        }
        if ((by < 0 && oldvalue < 0 && by < (LLONG_MIN-oldvalue)) ||
            (by > 0 && oldvalue > 0 && by > (LLONG_MAX-oldvalue))) {
            return 0;
        }
		*new_val = oldvalue + by;
	}

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(str(*new_val));
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);

	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("del error: %s", s.ToString().c_str());
		return -1;
	}
	return 1;
}

int SSDBImpl::get(const Bytes &key, std::string *val){
	std::string buf = encode_meta_key(key.String());
    std::string en_val;

	leveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, &en_val);
	if(s.IsNotFound()){
		return 0;
	}
	if(!s.ok()){
		log_error("get error: %s", s.ToString().c_str());
		return -1;
	}
    KvMetaVal kv;
    if (kv.DecodeMetaVal(en_val) == -1){
        return -1;
    } else{
        *val = kv.value;
    }
	return 1;
}

// todo r2m adaptation
KIterator* SSDBImpl::scan(const Bytes &start, const Bytes &end, uint64_t limit){    //不支持kv scan，redis也不支持
	std::string key_start, key_end;
	key_start = encode_kv_key(start);
	if(end.empty()){
		key_end = "";
	}else{
		key_end = encode_kv_key(end);
	}
	//dump(key_start.data(), key_start.size(), "scan.start");
	//dump(key_end.data(), key_end.size(), "scan.end");

	return new KIterator(this->iterator(key_start, key_end, limit));
}

// todo r2m adaptation
KIterator* SSDBImpl::rscan(const Bytes &start, const Bytes &end, uint64_t limit){   //不支持kv scan，redis也不支持
	std::string key_start, key_end;

	key_start = encode_kv_key(start);
	if(start.empty()){
		key_start.append(1, 255);
	}
	if(!end.empty()){
		key_end = encode_kv_key(end);
	}
	//dump(key_start.data(), key_start.size(), "scan.start");
	//dump(key_end.data(), key_end.size(), "scan.end");

	return new KIterator(this->rev_iterator(key_start, key_end, limit));
}

int SSDBImpl::setbit(const Bytes &key, int bitoffset, int on, char log_type){
	Transaction trans(binlogs);

	std::string val;
	int ret = this->get(key, &val);
	if(ret == -1){
		return -1;
	}

    int len = bitoffset >> 3;
    int bit = 7 - (bitoffset & 0x7);
	if(len >= val.size()){
		val.resize(len + 1, 0);
	}
	int orig = val[len] & (1 << bit);
	if(on == 1){
		val[len] |= (1 << bit);
	}else{
		val[len] &= ~(1 << bit);
	}

	std::string buf = encode_meta_key(key.String());
    std::string meta_val = encode_kv_val(val);
	binlogs->Put(buf, meta_val);
	binlogs->add_log(log_type, BinlogCommand::KSET, buf);
	leveldb::Status s = binlogs->commit();
	if(!s.ok()){
		log_error("set error: %s", s.ToString().c_str());
		return -1;
	}
	return orig;
}

int SSDBImpl::getbit(const Bytes &key, int bitoffset){
	std::string val;
	int ret = this->get(key, &val);
	if(ret == -1){
		return -1;
	}

    int len = bitoffset >> 3;
    int bit = 7 - (bitoffset & 0x7);
	if(len >= val.size()){
		return 0;
	}
	return (val[len] & (1 << bit)) == 0? 0 : 1;
}

/*
 * private API
 */
int SSDBImpl::DelKeyByType(const Bytes &key, const std::string &type){
	//todo 内部接口，保证操作的原子性，调用No Commit接口
	if ("string" == type){
		KDelNoLock(key);
	} else if ("hash" == type){
		HDelKeyNoLock(key);
	} else if ("list" == type){
//		s = LDelKeyNoLock(key, &res);
	} else if ("set" == type){
		SDelKeyNoLock(key);
	} else if ("zset" == type){
		ZDelKeyNoLock(key);
	}

	return 0;
}

int SSDBImpl::KDel(const Bytes &key, char log_type){
    Transaction trans(binlogs);

    int num = KDelNoLock(key);
    if (num != 1){
        return num;
    }

    leveldb::Status s = binlogs->commit();
    if(!s.ok()){
        log_error("set error: %s", s.ToString().c_str());
        return -1;
    }
    return 1;
}

int SSDBImpl::KDelNoLock(const Bytes &key, char log_type){
	std::string buf = encode_meta_key(key.String());
    std::string en_val;
    leveldb::Status s = ldb->Get(leveldb::ReadOptions(), buf, &en_val);
    if(s.IsNotFound()){
        return 0;
    } else if(!s.ok()){
        log_error("get error: %s", s.ToString().c_str());
        return -1;
    } else{
        if (en_val[0] != DataType::KV){
            return 0;
        }
    }
	binlogs->Delete(buf);
	binlogs->add_log(log_type, BinlogCommand::KDEL, buf);
	return 1;
}

/*
 * General API
 */
int SSDBImpl::type(const Bytes &key, std::string *type){
	*type = "none";
    int ret = 0;
	std::string val;
	std::string meta_key = encode_meta_key(key.String());
	leveldb::Status s = ldb->Get(leveldb::ReadOptions(), meta_key, &val);
	if(s.IsNotFound()){
		return 0;
	}
	if(!s.ok()){
		log_error("get error: %s", s.ToString().c_str());
		return -1;
	}

	if (val[0] == DataType::KV){
		*type = "string";
        ret = 1;
	} else if (val[0] == DataType::HSIZE){
		HashMetaVal hv;
		if (hv.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (hv.del == KEY_ENABLED_MASK){
			*type = "hash";
            ret = 1;
		}
	} else if (val[0] == DataType::SSIZE){
		SetMetaVal sv;
		if (sv.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (sv.del == KEY_ENABLED_MASK){
			*type = "set";
            ret = 1;
		}
	} else if (val[0] == DataType::ZSIZE){
		ZSetMetaVal zs;
		if (zs.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (zs.del == KEY_ENABLED_MASK){
			*type = "zset";
            ret = 1;
		}
	} else if (val[0] == DataType::LSZIE){
		ListMetaVal ls;
		if (ls.DecodeMetaVal(val) == -1){
			return -1;
		}
		if (ls.del == KEY_ENABLED_MASK){
			*type = "list";
            ret = 1;
		}
	} else{
		return -1;
	}

	return ret;
}
<|endoftext|>