<commit_before>#pragma once
/**
 * \file	exemodel/timeree.hpp
 * \author	justgaoyuan<gao_yuangy@126.com>
 * 		linxiang<linxiang2019@163.com>
 */
#include <sys/timerfd.h>

#include "exemodel/pollee.hpp"
#include "exemodel/evt_cb.hpp"
#include "exemodel/poll_tools.hpp"

namespace exemodel {

typedef ::timespec timespec_t;
typedef ::itimerspec itimerspec_t;

inline timespec_t ms_to_timespec(uint32_t ms)
{
	return { (::__time_t)(ms/1000), static_cast<uint16_t>(ms%1000) * 1000 * 1000 };
}

template< clockid_t clk_id >
class clock_info {
public:
	static timespec_t get_res(void)
	{
		timespec_t res;
		int ret = ::clock_getres(clk_id, &res);
		validate_ret(ret, "get clock res!");
		return res;
	}

	static timespec_t get_time(void)
	{
		timespec_t tp;
		int ret = ::clock_gettime(clk_id, &tp);
		validate_ret(ret, "get clock time!");
		return tp;
	}

	static int set_time(const timespec_t & tp)
	{
		return clock_settime(clk_id, &tp);
	}
};

/**
 *\class timeree
 *\brief timeree pollee,used by \em poller
 */
template< clockid_t clk_id >
class timeree
: public pollee
, public evt_cb<poller&, uint64_t> {
public:
	typedef clock_info<clk_id> info;
public:
	explicit timeree(itimerspec_t spec = { {0,0}, {0,0} })
	: pollee(
		::timerfd_create(clk_id, TFD_NONBLOCK | TFD_CLOEXEC)
		, uint32_t(::EPOLLIN))
	, m_spec(spec)
	{
	}

	virtual ~timeree()
	{
	}

public:
	/**
	 * \brief used for starting/stoping the timer
	 */
	void start(void)
	{
		int ret = __set_spec(0, &m_spec, NULL);
		validate_ret(ret,"start timer error!\n");
	}

	void start(const itimerspec_t & new_value)
	{
		/// store new value
		m_spec = new_value;
		this->start();
	}

	void start_abs(const itimerspec_t & new_value)
	{
		/// store new value
		m_spec = new_value;

		int ret = __set_spec(TFD_TIMER_ABSTIME, &new_value, NULL);
		validate_ret(ret,"start timer abs error!\n");
	}

	void stop(void)
	{
		struct itimerspec new_value = {	{0,0}, {0,0}, };
		int ret = __set_spec(0, &new_value, NULL);
		validate_ret(ret,"stop timer error!\n");
	}
public:
	/**
	 * \brief used for disposing the event caughted by \em poller attached
	 */
	virtual void dispose(poller & mgr, uint32_t)
	{
		uint64_t buf = 0;
		ssize_t ret = read(&buf, sizeof(buf));
		if(ret != sizeof(buf)){
			std::cout << "read error!" << std::endl;
			return;
		}

		this->exe(mgr, buf);
	}
private:
	int __set_spec(int flags,
		const itimerspec_t *new_value,
		itimerspec_t *old_value)
	{
		return ::timerfd_settime(_fd(), flags, new_value, old_value);
	}

	int get_spec(itimerspec_t *curr_value) const
	{
		return ::timerfd_gettime(_fd(), curr_value);
	}
private:
	timeree(const timeree & rhs) = delete;
	timeree & operator = (const timeree & rhs ) = delete;
private:
	itimerspec_t m_spec;
};

typedef timeree<CLOCK_MONOTONIC> monotonic_timeree;
typedef timeree<CLOCK_REALTIME> realtime_timeree;

}
<commit_msg>exemodel: remove std::cout<commit_after>#pragma once
/**
 * \file	exemodel/timeree.hpp
 * \author	justgaoyuan<gao_yuangy@126.com>
 * 		linxiang<linxiang2019@163.com>
 */
#include <sys/timerfd.h>

#include "zlog/zlog.hpp"

#include "exemodel/pollee.hpp"
#include "exemodel/evt_cb.hpp"
#include "exemodel/poll_tools.hpp"

namespace exemodel {

typedef ::timespec timespec_t;
typedef ::itimerspec itimerspec_t;

inline timespec_t ms_to_timespec(uint32_t ms)
{
	return { (::__time_t)(ms/1000), static_cast<uint16_t>(ms%1000) * 1000 * 1000 };
}

template< clockid_t clk_id >
class clock_info {
public:
	static timespec_t get_res(void)
	{
		timespec_t res;
		int ret = ::clock_getres(clk_id, &res);
		validate_ret(ret, "get clock res!");
		return res;
	}

	static timespec_t get_time(void)
	{
		timespec_t tp;
		int ret = ::clock_gettime(clk_id, &tp);
		validate_ret(ret, "get clock time!");
		return tp;
	}

	static int set_time(const timespec_t & tp)
	{
		return clock_settime(clk_id, &tp);
	}
};

/**
 *\class timeree
 *\brief timeree pollee,used by \em poller
 */
template< clockid_t clk_id >
class timeree
: public pollee
, public evt_cb<poller&, uint64_t> {
public:
	typedef clock_info<clk_id> info;
public:
	explicit timeree(itimerspec_t spec = { {0,0}, {0,0} })
	: pollee(
		::timerfd_create(clk_id, TFD_NONBLOCK | TFD_CLOEXEC)
		, uint32_t(::EPOLLIN))
	, m_spec(spec)
	{
	}

	virtual ~timeree()
	{
	}

public:
	/**
	 * \brief used for starting/stoping the timer
	 */
	void start(void)
	{
		int ret = __set_spec(0, &m_spec, NULL);
		validate_ret(ret,"start timer error!\n");
	}

	void start(const itimerspec_t & new_value)
	{
		/// store new value
		m_spec = new_value;
		this->start();
	}

	void start_abs(const itimerspec_t & new_value)
	{
		/// store new value
		m_spec = new_value;

		int ret = __set_spec(TFD_TIMER_ABSTIME, &new_value, NULL);
		validate_ret(ret,"start timer abs error!\n");
	}

	void stop(void)
	{
		struct itimerspec new_value = {	{0,0}, {0,0}, };
		int ret = __set_spec(0, &new_value, NULL);
		validate_ret(ret,"stop timer error!\n");
	}
public:
	/**
	 * \brief used for disposing the event caughted by \em poller attached
	 */
	virtual void dispose(poller & mgr, uint32_t)
	{
		uint64_t buf = 0;
		ssize_t ret = read(&buf, sizeof(buf));
		if(ret != sizeof(buf)){
			zlog::zlog_warning("exemodel: timeree read error!");
			return;
		}

		this->exe(mgr, buf);
	}
private:
	int __set_spec(int flags,
		const itimerspec_t *new_value,
		itimerspec_t *old_value)
	{
		return ::timerfd_settime(_fd(), flags, new_value, old_value);
	}

	int get_spec(itimerspec_t *curr_value) const
	{
		return ::timerfd_gettime(_fd(), curr_value);
	}
private:
	timeree(const timeree & rhs) = delete;
	timeree & operator = (const timeree & rhs ) = delete;
private:
	itimerspec_t m_spec;
};

typedef timeree<CLOCK_MONOTONIC> monotonic_timeree;
typedef timeree<CLOCK_REALTIME> realtime_timeree;

}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexVB.cxx
 ** Lexer for Visual Basic and VBScript.
 **/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

// Internal state, highlighted as number
#define SCE_B_FILENUMBER SCE_B_DEFAULT+100

static bool IsVBComment(Accessor &styler, int pos, int len) {
	return len > 0 && styler[pos] == '\'';
}

static inline bool IsTypeCharacter(int ch) {
	return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
}

// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
	return ch >= 0x80 ||
	       (isalnum(ch) || ch == '.' || ch == '_');
}

static inline bool IsAWordStart(int ch) {
	return ch >= 0x80 ||
	       (isalpha(ch) || ch == '_');
}

static inline bool IsANumberChar(int ch) {
	// Not exactly following number definition (several dots are seen as OK, etc.)
	// but probably enough in most cases.
	return (ch < 0x80) &&
	        (isdigit(ch) || toupper(ch) == 'E' ||
             ch == '.' || ch == '-' || ch == '+');
}

static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];
	WordList &keywords4 = *keywordlists[3];

	styler.StartAt(startPos);

	int visibleChars = 0;
	int fileNbDigits = 0;

	// Do not leak onto next line
	if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
		initStyle = SCE_B_DEFAULT;
	}

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.state == SCE_B_OPERATOR) {
			sc.SetState(SCE_B_DEFAULT);
		} else if (sc.state == SCE_B_IDENTIFIER) {
			if (!IsAWordChar(sc.ch)) {
				// In Basic (except VBScript), a variable name or a function name
				// can end with a special character indicating the type of the value
				// held or returned.
				bool skipType = false;
				if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
					sc.Forward();	// Skip it
					skipType = true;
				}
				if (sc.ch == ']') {
					sc.Forward();
				}
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (skipType) {
					s[strlen(s) - 1] = '\0';
				}
				if (strcmp(s, "rem") == 0) {
					sc.ChangeState(SCE_B_COMMENT);
				} else {
					if (keywords.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD);
					} else if (keywords2.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD2);
					} else if (keywords3.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD3);
					} else if (keywords4.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD4);
					}	// Else, it is really an identifier...
					sc.SetState(SCE_B_DEFAULT);
				}
			}
		} else if (sc.state == SCE_B_NUMBER) {
			// We stop the number definition on non-numerical non-dot non-eE non-sign char
			// Also accepts A-F for hex. numbers
			if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
				sc.SetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_STRING) {
			// VB doubles quotes to preserve them, so just end this string
			// state now as a following quote will start again
			if (sc.ch == '\"') {
				if (tolower(sc.chNext) == 'c') {
					sc.Forward();
				}
				sc.ForwardSetState(SCE_B_DEFAULT);
			} else if (sc.atLineEnd) {
				sc.ChangeState(SCE_B_STRINGEOL);
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_COMMENT) {
			if (sc.atLineEnd) {
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_PREPROCESSOR) {
			if (sc.atLineEnd) {
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_FILENUMBER) {
			if (IsADigit(sc.ch)) {
				fileNbDigits++;
				if (fileNbDigits > 3) {
					sc.ChangeState(SCE_B_DATE);
				}
			} else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
				// Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
				// Too bad if date is format #27, Oct, 2003# or something like that...
				// Use regular number state
				sc.ChangeState(SCE_B_NUMBER);
				sc.SetState(SCE_B_DEFAULT);
			} else if (sc.ch == '#') {
				sc.ChangeState(SCE_B_DATE);
				sc.ForwardSetState(SCE_B_DEFAULT);
			} else {
				sc.ChangeState(SCE_B_DATE);
			}
			if (sc.state != SCE_B_FILENUMBER) {
				fileNbDigits = 0;
			}
		} else if (sc.state == SCE_B_DATE) {
			if (sc.atLineEnd) {
				sc.ChangeState(SCE_B_STRINGEOL);
				sc.ForwardSetState(SCE_B_DEFAULT);
			} else if (sc.ch == '#') {
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		}

		if (sc.state == SCE_B_DEFAULT) {
			if (sc.ch == '\'') {
				sc.SetState(SCE_B_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_B_STRING);
			} else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_B_PREPROCESSOR);
			} else if (sc.ch == '#') {
				// It can be a date literal, ending with #, or a file number, from 1 to 511
				// The date literal depends on the locale, so anything can go between #'s.
				// Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
				// So we set the FILENUMBER state, and switch to DATE if it isn't a file number
				sc.SetState(SCE_B_FILENUMBER);
			} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
				// Hexadecimal number
				sc.SetState(SCE_B_NUMBER);
				sc.Forward();
			} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
				// Octal number
				sc.SetState(SCE_B_NUMBER);
				sc.Forward();
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_B_NUMBER);
			} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
				sc.SetState(SCE_B_IDENTIFIER);
			} else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {	// Integer division
				sc.SetState(SCE_B_OPERATOR);
			}
		}

		if (sc.atLineEnd) {
			visibleChars = 0;
		}
		if (!IsASpace(sc.ch)) {
			visibleChars++;
		}
	}
	sc.Complete();
}

static void FoldVBDoc(unsigned int startPos, int length, int,
						   WordList *[], Accessor &styler) {
	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
	ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false);
}

static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
	ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
}

static const char * const vbWordListDesc[] = {
	"Keywords",
	"user1",
	"user2",
	"user3",
	0
};

LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);

<commit_msg>Fix for bug 1523787.<commit_after>// Scintilla source code edit control
/** @file LexVB.cxx
 ** Lexer for Visual Basic and VBScript.
 **/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

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

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

// Internal state, highlighted as number
#define SCE_B_FILENUMBER SCE_B_DEFAULT+100

static bool IsVBComment(Accessor &styler, int pos, int len) {
	return len > 0 && styler[pos] == '\'';
}

static inline bool IsTypeCharacter(int ch) {
	return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
}

// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
	return ch >= 0x80 ||
	       (isalnum(ch) || ch == '.' || ch == '_');
}

static inline bool IsAWordStart(int ch) {
	return ch >= 0x80 ||
	       (isalpha(ch) || ch == '_');
}

static inline bool IsANumberChar(int ch) {
	// Not exactly following number definition (several dots are seen as OK, etc.)
	// but probably enough in most cases.
	return (ch < 0x80) &&
	        (isdigit(ch) || toupper(ch) == 'E' ||
             ch == '.' || ch == '-' || ch == '+');
}

static void ColouriseVBDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler, bool vbScriptSyntax) {

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];
	WordList &keywords4 = *keywordlists[3];

	styler.StartAt(startPos);

	int visibleChars = 0;
	int fileNbDigits = 0;

	// Do not leak onto next line
	if (initStyle == SCE_B_STRINGEOL || initStyle == SCE_B_COMMENT || initStyle == SCE_B_PREPROCESSOR) {
		initStyle = SCE_B_DEFAULT;
	}

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.state == SCE_B_OPERATOR) {
			sc.SetState(SCE_B_DEFAULT);
		} else if (sc.state == SCE_B_IDENTIFIER) {
			if (!IsAWordChar(sc.ch)) {
				// In Basic (except VBScript), a variable name or a function name
				// can end with a special character indicating the type of the value
				// held or returned.
				bool skipType = false;
				if (!vbScriptSyntax && IsTypeCharacter(sc.ch)) {
					sc.Forward();	// Skip it
					skipType = true;
				}
				if (sc.ch == ']') {
					sc.Forward();
				}
				char s[100];
				sc.GetCurrentLowered(s, sizeof(s));
				if (skipType) {
					s[strlen(s) - 1] = '\0';
				}
				if (strcmp(s, "rem") == 0) {
					sc.ChangeState(SCE_B_COMMENT);
				} else {
					if (keywords.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD);
					} else if (keywords2.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD2);
					} else if (keywords3.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD3);
					} else if (keywords4.InList(s)) {
						sc.ChangeState(SCE_B_KEYWORD4);
					}	// Else, it is really an identifier...
					sc.SetState(SCE_B_DEFAULT);
				}
			}
		} else if (sc.state == SCE_B_NUMBER) {
			// We stop the number definition on non-numerical non-dot non-eE non-sign char
			// Also accepts A-F for hex. numbers
			if (!IsANumberChar(sc.ch) && !(tolower(sc.ch) >= 'a' && tolower(sc.ch) <= 'f')) {
				sc.SetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_STRING) {
			// VB doubles quotes to preserve them, so just end this string
			// state now as a following quote will start again
			if (sc.ch == '\"') {
				if (sc.chNext == '\"') {
					sc.Forward();
				} else {
					if (tolower(sc.chNext) == 'c') {
						sc.Forward();
					}
					sc.ForwardSetState(SCE_B_DEFAULT);
				}
			} else if (sc.atLineEnd) {
				visibleChars = 0;
				sc.ChangeState(SCE_B_STRINGEOL);
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_COMMENT) {
			if (sc.atLineEnd) {
				visibleChars = 0;
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_PREPROCESSOR) {
			if (sc.atLineEnd) {
				visibleChars = 0;
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		} else if (sc.state == SCE_B_FILENUMBER) {
			if (IsADigit(sc.ch)) {
				fileNbDigits++;
				if (fileNbDigits > 3) {
					sc.ChangeState(SCE_B_DATE);
				}
			} else if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ',') {
				// Regular uses: Close #1; Put #1, ...; Get #1, ... etc.
				// Too bad if date is format #27, Oct, 2003# or something like that...
				// Use regular number state
				sc.ChangeState(SCE_B_NUMBER);
				sc.SetState(SCE_B_DEFAULT);
			} else if (sc.ch == '#') {
				sc.ChangeState(SCE_B_DATE);
				sc.ForwardSetState(SCE_B_DEFAULT);
			} else {
				sc.ChangeState(SCE_B_DATE);
			}
			if (sc.state != SCE_B_FILENUMBER) {
				fileNbDigits = 0;
			}
		} else if (sc.state == SCE_B_DATE) {
			if (sc.atLineEnd) {
				visibleChars = 0;
				sc.ChangeState(SCE_B_STRINGEOL);
				sc.ForwardSetState(SCE_B_DEFAULT);
			} else if (sc.ch == '#') {
				sc.ForwardSetState(SCE_B_DEFAULT);
			}
		}

		if (sc.state == SCE_B_DEFAULT) {
			if (sc.ch == '\'') {
				sc.SetState(SCE_B_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_B_STRING);
			} else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_B_PREPROCESSOR);
			} else if (sc.ch == '#') {
				// It can be a date literal, ending with #, or a file number, from 1 to 511
				// The date literal depends on the locale, so anything can go between #'s.
				// Can be #January 1, 1993# or #1 Jan 93# or #05/11/2003#, etc.
				// So we set the FILENUMBER state, and switch to DATE if it isn't a file number
				sc.SetState(SCE_B_FILENUMBER);
			} else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
				// Hexadecimal number
				sc.SetState(SCE_B_NUMBER);
				sc.Forward();
			} else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
				// Octal number
				sc.SetState(SCE_B_NUMBER);
				sc.Forward();
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_B_NUMBER);
			} else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
				sc.SetState(SCE_B_IDENTIFIER);
			} else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {	// Integer division
				sc.SetState(SCE_B_OPERATOR);
			}
		}

		if (sc.atLineEnd) {
			visibleChars = 0;
		}
		if (!IsASpace(sc.ch)) {
			visibleChars++;
		}
	}
	sc.Complete();
}

static void FoldVBDoc(unsigned int startPos, int length, int,
						   WordList *[], Accessor &styler) {
	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsVBComment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsVBComment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsVBComment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}
}

static void ColouriseVBNetDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
	ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, false);
}

static void ColouriseVBScriptDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {
	ColouriseVBDoc(startPos, length, initStyle, keywordlists, styler, true);
}

static const char * const vbWordListDesc[] = {
	"Keywords",
	"user1",
	"user2",
	"user3",
	0
};

LexerModule lmVB(SCLEX_VB, ColouriseVBNetDoc, "vb", FoldVBDoc, vbWordListDesc);
LexerModule lmVBScript(SCLEX_VBSCRIPT, ColouriseVBScriptDoc, "vbscript", FoldVBDoc, vbWordListDesc);

<|endoftext|>


<commit_before>#pragma once

/* Voxel test with procedural data. */

// NEEDS TO BE CLEANED UP

#include "math/vector3.hpp"
#include <cmath>

#include <cstddef>

#include <algorithm>

////////

typedef float distance;
typedef math::float3 distance3;

////////

struct Voxel
{
    math::float3 normal; // distance3?
    math::float3 rgb; // that's a color
};

template <size_t index>
static distance3 offset()
{
    return distance3((index >> 2) & 1,
                     (index >> 1) & 1,
                     (index >> 0) & 1);
}

// (this will probably remain in cache permanently)
static distance3 offsets[8] = // epic performance hack
{
    offset<0>(),
    offset<1>(),
    offset<2>(),
    offset<3>(),
    offset<4>(),
    offset<5>(),
    offset<6>(),
    offset<7>(),
};

// this is also needed by the traversal code (no sense storing the
// bounding box of each voxel when it can be readily inferred from
// its location in the octree datastructure)

// to optimize
inline
static void subdivide(distance3 min_node, distance3 max_node, int index,
                      distance3 &min_child, distance3 &max_child)
{
    /*distance3 extent = (max_node - min_node) / 2;

    distance3 origin = (max_node + min_node) / 2;
    distance3 new_origin;

    new_origin.x = origin.x + extent.x * (index&4 ? .5f : -.5f);
    new_origin.y = origin.y + extent.y * (index&2 ? .5f : -.5f);
    new_origin.z = origin.z + extent.z * (index&1 ? .5f : -.5f);

    min_child = new_origin - extent * .5f;
    max_child = new_origin + extent * .5f;*/

    // the vector code below is slow for some reason

    distance3 extent = (max_node - min_node) * .5;

    // might be possible to hardware-accelerate this?
    /*distance3 offset = distance3((index >> 2) & 1,
                                 (index >> 1) & 1,
                                 (index >> 0) & 1);*/

    min_child = min_node + extent * offsets[index];
    max_child = min_child + extent;
}

struct Node
{
    void *child[8];
} __attribute__ ((aligned(16)));

// this needs to be cleaned up
struct stack_item
{
    void *memptr;
    size_t depth;

    distance3 min, max; // bounding box for this node
    distance hit; // nearest intersection for this node

    stack_item()
    {
        hit = std::numeric_limits<distance>::infinity();
    }

    stack_item &operator =(const stack_item &record)
    {
        this->memptr = record.memptr;
        this->depth = record.depth;
        this->min = record.min;
        this->max = record.max;
        this->hit = record.hit;

        return *this;
    }

    stack_item(void *memptr, size_t depth, distance3 min,
                 distance3 max)
    {
        this->memptr = memptr;
        this->depth = depth;
        this->min = min;
        this->max = max;
        this->hit = 0;
    }

    stack_item(void *memptr, size_t depth, distance3 min, distance3 max,
                 distance near)
    {
        this->memptr = memptr;
        this->depth = depth;
        this->min = min;
        this->max = max;
        this->hit = near;
    }

    // this should derive a stack_item from its parent
    stack_item(void *memptr, const stack_item &parent, size_t index)
    {
        this->memptr = memptr;
        this->depth = parent.depth - 1;
        this->hit = 0;

        subdivide(parent.min, parent.max, index,
                  this->min, this->max);
    }
};

static inline stack_item pop(const stack_item *stack, size_t &ptr)
{
    return stack[--ptr];
}

static inline void push(stack_item *stack, size_t &ptr, const stack_item &item)
{
    stack[ptr++] = item;
}

static inline void swap(stack_item *a, stack_item *b)
{
    if (a->hit > b->hit)
    {
        stack_item tmp = *a;
        *a = *b;
        *b = tmp;
    }
}

static inline void sort_network(stack_item *list)
{
    swap(&list[0], &list[2]);
    swap(&list[1], &list[3]);
    swap(&list[0], &list[1]);
    swap(&list[2], &list[3]);
    swap(&list[1], &list[2]);
}

#define svo_depth 9 // TEMPORARY (will not be hardcoded later)

static int voxel_count = 0;

// to optimize
inline
static bool ray_aabb(distance3 origin, distance3 inv_dir,
                     distance3 bmin, distance3 bmax,
                     distance &near)
{
    distance3 bot = (bmin - origin) * inv_dir;
    distance3 top = (bmax - origin) * inv_dir;

    math::float3 tmin = std::min(top, bot);
    math::float3 tmax = std::max(top, bot);

    near = std::max(std::max(tmin.x, tmin.y), tmin.z);
    distance far = std::min(std::min(tmax.x, tmax.y), tmax.z);

    return !(near > far) && far > 0;
}

class VoxelTest
{
public:
    distance3 light() const
    {
        return distance3(0.2f, -0.3f, 0.3f);
    }

    bool intersects(const distance3 &origin, const distance3 &direction,
		            distance &dist, Contact &contact) const
	{
        return traverse(origin, direction,
                        std::numeric_limits<distance>::infinity(), dist, contact, false);
	}

    bool occludes(const distance3 &origin, const distance3 &direction,
                  distance &dist, distance target_dist) const
    {
        Contact contact;

        return traverse(origin, direction,
                        target_dist, dist, contact, true);
    }

    bool occludes(const distance3 &origin, const distance3 &direction,
                  distance target_dist) const
    {
        distance dist;
        Contact contact;

        return traverse(origin, direction,
                        target_dist, dist, contact, true);
    }

    bool occludes(const distance3 &origin, const distance3 &direction) const
    {
        return occludes(origin, direction, std::numeric_limits<distance>::infinity());
    }

	VoxelTest()
	{
        world_min = distance3(-1, -1, -1);
        world_max = distance3(1, 1, 1);

	    printf("Building SVO (this is done only once).\n");
	    root = (Node*)build_SVO(svo_depth, distance3(-1, -1, -1), distance3(1, 1, 1));
	    printf("SVO built (%d voxels, depth = %d).\n", voxel_count, svo_depth);
	}

private:
    // looks up a voxel through its memory address (this could be an offset later on
    // for virtualization) and fills in an appropriate Contact structure to indicate
    // the material and surface normal, when applicable

    // this function has some pretty strong invariants to maintain, pay attention.

    // (procedural data generation can happen here as well)
    inline
    bool lookup(const  distance3 &origin, const distance3 &direction,
                const stack_item   &item,       distance    &nearest,
                                                    Contact &contact) const
    {
        // default implementation, voxels are cubic and solid

        (void)origin;
        (void)direction;

        Voxel *voxel = (Voxel*)item.memptr;
        contact.rgb = voxel->rgb;
        contact.normal = voxel->normal;
        nearest = item.hit; // IMPORTANT: you must set "nearest" to the
        // nearest intersection within the voxel's bounding box, IF AND
        // ONLY IF this intersection is closer than the currently recorded
        // "nearest" value (and if this is the case, populate "contact",
        // else LEAVE IT ALONE).

        return true; // return if and only if "nearest" was modified
    } __attribute__ ((hot))

    // this is the heart of the voxel renderer, the SVO traversal code
    // this is where optimization efforts should be focused
    // current optimizations and todo's:
    // DONE: convert to iteration and use a stack
    // TODO: implement and benchmark stackless traversal algorithms
    // DONE: uses early rejection by sorting children
    // TODO: fix remaining bugs

    // CURRENT REASONS FOR BEING SLOW:
    // 1. no SSE vector instructions  [WIP]
    // 2. unnecessary ray_aabb call in leaf [fixed]
    // 3. recursion [fixed]
    // 4. "intersections" buffer not optimized [fixed]
    // 5. tree nodes allocated via malloc(), poor locality [?]
    // 6. ray_aabb is not optimized at all  [WIP]
    // 7. possible algorithmic improvements?

    // QUESTIONS TO RESOLVE:
    // 1. do we need "far" in the "intersections" buffer? [NO]
    // 2. are there any bugs? need a known voxel data set to test against
    //    (do that once we have interactivity, to better locate glitches)

    // ADDITIONAL INFO:
    // - final tree will potentially be very deep, with up to 64 levels
    //   (32 levels --> 64km^3 with 0.015 mm resolution)
    // - procedural data generation can be done outside the tree, once
    //   a voxel is intersected, by generating procedural data *inside*
    //   the intersected voxel, depending on its material
    //   (this is actually a REALLY GOOD idea as it completely gets rid
    //    of any cubic artifacts and improves subpixel performance)
    // - 64 levels --> 1800 AU^3 with 0.015 mm resolution
    //   (that's 274 billion km^3, I trust this will be enough)
    // - possibly use a hybrid approach, with two trees, one handling large
    //   64km^3 "chunks", optimized for ultra fast traversal, and another
    //   which focuses on culling chunks to improve performance
    bool traverse(const distance3 &origin, const distance3 &direction,
                  const distance   &range,       distance    &nearest,
                        Contact  &contact, const bool       occlusion) const
    {
        const distance3 &inv_dir = 1 / direction;
        stack_item stack[4 * svo_depth];
        size_t ptr = 0;

        bool hit = false;
        nearest = range;

        push(stack, ptr, stack_item(root, svo_depth, world_min, world_max));

        while (ptr)
        {
            stack_item s = pop(stack, ptr);
            if (s.hit >= nearest) continue;

            if (!s.depth)
            {
                hit = lookup(origin, direction, s, nearest, contact);
                if (occlusion && hit) return true; /* We are done. */
            }
            else
            {
                Node *parent = (Node*)s.memptr;
                stack_item children[4];
                size_t hits = 0;

                for (size_t t = 0; t < 8; ++t)
                {
                    void *child = parent->child[t];
                    if (child == nullptr) continue;

                    stack_item c(child, s, t); /* Child subdivision. */
                    if (ray_aabb(origin, inv_dir, c.min, c.max, c.hit))
                        if (c.hit < nearest) push(children, hits, c);
                }

                sort_network(children); /* Pushed front to back. */
                while (hits) push(stack, ptr, pop(children, hits));
            }
        }

        return hit;
	} __attribute__ ((hot))

    // this will be done in a separate program later on (SVO's will be
    // loaded on the fly, no time to build them while streaming voxels)
    void *build_SVO(int depth, distance3 min_node, distance3 max_node)
    {
        if (depth == 0)
        {
            ++voxel_count;

            // this is a leaf - add voxel
            Voxel *voxel = new Voxel();
            get_voxel_data(min_node, max_node, voxel);
            return voxel;
        }

        Node *node = new Node();

        // build children here
        for (int t = 0; t < 8; ++t)
        {
            distance3 min_child, max_child;
            subdivide(min_node, max_node, t, min_child, max_child);

            if (!contains_voxels(min_child, max_child)) node->child[t] = nullptr;
            else node->child[t] = build_SVO(depth - 1, min_child, max_child);
        }

        return node;
    }

    float heightmap(distance x, distance z) const // TEMPORARY
    {
        //return 0.05f * (sin(x) + cos(z)) - 0.7f;

        if ((x <= -0.525f) || (x >= 0.6f)) return std::numeric_limits<distance>::infinity();
        if ((z <= 0.2f)) return std::numeric_limits<distance>::infinity();

        return -0.7f + 0.03f * (sin(15 * z) + sin(10 * x + 1));

        //return -2.0f/3.0f + 0.2f * x * x;
    }

    math::float3 normal(distance x, distance z) const // TEMPORARY
    {
        distance dx = 0.2 * cos(10 * x + 1);
        distance dz = 0.3 * cos(15 * z);

        //distance dx = 0.4f * x;
        //distance dz = 0;

        return normalize(distance3(dx, 1, dz));
    }

    bool contains_voxels(distance3 min, distance3 max) const // TEMPORARY
    {
        int r = 10;

        for (int px = 0; px < r; ++px)
            for (int pz = 0; pz < r; ++pz)
            {
                distance x = min.x + (max.x - min.x) * (distance)px / r;
                distance z = min.z + (max.z - min.z) * (distance)pz / r;

                distance height = heightmap(x, z);

                if ((min.y <= height) && (height <= max.y)) return true;
            }

        return false;
    }

    void get_voxel_data(distance3 min, distance3 max, Voxel *voxel) const
        // TEMPORARY
    {
        int r = 10;

        for (int px = 0; px < r; ++px)
            for (int pz = 0; pz < r; ++pz)
            {
                distance x = min.x + (max.x - min.x) * (distance)px / r;
                distance z = min.z + (max.z - min.z) * (distance)pz / r;

                distance height = heightmap(x, z);

                if ((min.y <= height) && (height <= max.y))
                {
                    voxel->normal = normal(x, z);

                    float r = std::min(std::max(0.0f, std::abs(x)), 1.0f);
                    float g = std::min(std::max(0.0f, std::abs(z)), 1.0f);
                    float b = std::min(std::max(0.0f, std::abs(x + z)), 1.0f);

                    voxel->rgb = math::float3(r, g, b) + math::float3(0.25f, 0.25f, 0.25f);
                }
            }
    }

    Node *root;

    distance3 world_min, world_max;
};
<commit_msg>Small change in ray-AABB intersection code.<commit_after>#pragma once

/* Voxel test with procedural data. */

// NEEDS TO BE CLEANED UP

#include "math/vector3.hpp"
#include <cmath>

#include <cstddef>

#include <algorithm>

////////

typedef float distance;
typedef math::float3 distance3;

////////

struct Voxel
{
    math::float3 normal; // distance3?
    math::float3 rgb; // that's a color
};

template <size_t index>
static distance3 offset()
{
    return distance3((index >> 2) & 1,
                     (index >> 1) & 1,
                     (index >> 0) & 1);
}

// (this will probably remain in cache permanently)
static distance3 offsets[8] = // epic performance hack
{
    offset<0>(),
    offset<1>(),
    offset<2>(),
    offset<3>(),
    offset<4>(),
    offset<5>(),
    offset<6>(),
    offset<7>(),
};

// this is also needed by the traversal code (no sense storing the
// bounding box of each voxel when it can be readily inferred from
// its location in the octree datastructure)

// to optimize
inline
static void subdivide(distance3 min_node, distance3 max_node, int index,
                      distance3 &min_child, distance3 &max_child)
{
    /*distance3 extent = (max_node - min_node) / 2;

    distance3 origin = (max_node + min_node) / 2;
    distance3 new_origin;

    new_origin.x = origin.x + extent.x * (index&4 ? .5f : -.5f);
    new_origin.y = origin.y + extent.y * (index&2 ? .5f : -.5f);
    new_origin.z = origin.z + extent.z * (index&1 ? .5f : -.5f);

    min_child = new_origin - extent * .5f;
    max_child = new_origin + extent * .5f;*/

    // the vector code below is slow for some reason

    distance3 extent = (max_node - min_node) * .5;

    // might be possible to hardware-accelerate this?
    /*distance3 offset = distance3((index >> 2) & 1,
                                 (index >> 1) & 1,
                                 (index >> 0) & 1);*/

    min_child = min_node + extent * offsets[index];
    max_child = min_child + extent;
}

struct Node
{
    void *child[8];
} __attribute__ ((aligned(16)));

// this needs to be cleaned up
struct stack_item
{
    void *memptr;
    size_t depth;

    distance3 min, max; // bounding box for this node
    distance hit; // nearest intersection for this node

    stack_item()
    {
        hit = std::numeric_limits<distance>::infinity();
    }

    stack_item &operator =(const stack_item &record)
    {
        this->memptr = record.memptr;
        this->depth = record.depth;
        this->min = record.min;
        this->max = record.max;
        this->hit = record.hit;

        return *this;
    }

    stack_item(void *memptr, size_t depth, distance3 min,
                 distance3 max)
    {
        this->memptr = memptr;
        this->depth = depth;
        this->min = min;
        this->max = max;
        this->hit = 0;
    }

    stack_item(void *memptr, size_t depth, distance3 min, distance3 max,
                 distance near)
    {
        this->memptr = memptr;
        this->depth = depth;
        this->min = min;
        this->max = max;
        this->hit = near;
    }

    // this should derive a stack_item from its parent
    stack_item(void *memptr, const stack_item &parent, size_t index)
    {
        this->memptr = memptr;
        this->depth = parent.depth - 1;
        this->hit = 0;

        subdivide(parent.min, parent.max, index,
                  this->min, this->max);
    }
};

static inline stack_item pop(const stack_item *stack, size_t &ptr)
{
    return stack[--ptr];
}

static inline void push(stack_item *stack, size_t &ptr, const stack_item &item)
{
    stack[ptr++] = item;
}

static inline void swap(stack_item *a, stack_item *b)
{
    if (a->hit > b->hit)
    {
        stack_item tmp = *a;
        *a = *b;
        *b = tmp;
    }
}

static inline void sort_network(stack_item *list)
{
    swap(&list[0], &list[2]);
    swap(&list[1], &list[3]);
    swap(&list[0], &list[1]);
    swap(&list[2], &list[3]);
    swap(&list[1], &list[2]);
}

#define svo_depth 9 // TEMPORARY (will not be hardcoded later)

static int voxel_count = 0;

// to optimize
inline
static bool ray_aabb(distance3 origin, distance3 inv_dir,
                     distance3 bmin, distance3 bmax,
                     distance &near)
{
    distance3 bot = (bmin - origin) * inv_dir;
    distance3 top = (bmax - origin) * inv_dir;

    math::float3 tmin = std::min(top, bot);
    math::float3 tmax = std::max(top, bot);

    near = std::max(std::max(tmin.x, tmin.y), tmin.z);
    distance far = std::min(std::min(tmax.x, tmax.y), tmax.z);

    return near < far && far > 0;
}

class VoxelTest
{
public:
    distance3 light() const
    {
        return distance3(0.2f, -0.3f, 0.3f);
    }

    bool intersects(const distance3 &origin, const distance3 &direction,
		            distance &dist, Contact &contact) const
	{
        return traverse(origin, direction,
                        std::numeric_limits<distance>::infinity(), dist, contact, false);
	}

    bool occludes(const distance3 &origin, const distance3 &direction,
                  distance &dist, distance target_dist) const
    {
        Contact contact;

        return traverse(origin, direction,
                        target_dist, dist, contact, true);
    }

    bool occludes(const distance3 &origin, const distance3 &direction,
                  distance target_dist) const
    {
        distance dist;
        Contact contact;

        return traverse(origin, direction,
                        target_dist, dist, contact, true);
    }

    bool occludes(const distance3 &origin, const distance3 &direction) const
    {
        return occludes(origin, direction, std::numeric_limits<distance>::infinity());
    }

	VoxelTest()
	{
        world_min = distance3(-1, -1, -1);
        world_max = distance3(1, 1, 1);

	    printf("Building SVO (this is done only once).\n");
	    root = (Node*)build_SVO(svo_depth, distance3(-1, -1, -1), distance3(1, 1, 1));
	    printf("SVO built (%d voxels, depth = %d).\n", voxel_count, svo_depth);
	}

private:
    // looks up a voxel through its memory address (this could be an offset later on
    // for virtualization) and fills in an appropriate Contact structure to indicate
    // the material and surface normal, when applicable

    // this function has some pretty strong invariants to maintain, pay attention.

    // (procedural data generation can happen here as well)
    inline
    bool lookup(const  distance3 &origin, const distance3 &direction,
                const stack_item   &item,       distance    &nearest,
                                                    Contact &contact) const
    {
        // default implementation, voxels are cubic and solid

        (void)origin;
        (void)direction;

        Voxel *voxel = (Voxel*)item.memptr;
        contact.rgb = voxel->rgb;
        contact.normal = voxel->normal;
        nearest = item.hit; // IMPORTANT: you must set "nearest" to the
        // nearest intersection within the voxel's bounding box, IF AND
        // ONLY IF this intersection is closer than the currently recorded
        // "nearest" value (and if this is the case, populate "contact",
        // else LEAVE IT ALONE).

        return true; // return if and only if "nearest" was modified
    } __attribute__ ((hot))

    // this is the heart of the voxel renderer, the SVO traversal code
    // this is where optimization efforts should be focused
    // current optimizations and todo's:
    // DONE: convert to iteration and use a stack
    // TODO: implement and benchmark stackless traversal algorithms
    // DONE: uses early rejection by sorting children
    // TODO: fix remaining bugs

    // CURRENT REASONS FOR BEING SLOW:
    // 1. no SSE vector instructions  [WIP]
    // 2. unnecessary ray_aabb call in leaf [fixed]
    // 3. recursion [fixed]
    // 4. "intersections" buffer not optimized [fixed]
    // 5. tree nodes allocated via malloc(), poor locality [?]
    // 6. ray_aabb is not optimized at all  [WIP]
    // 7. possible algorithmic improvements?

    // QUESTIONS TO RESOLVE:
    // 1. do we need "far" in the "intersections" buffer? [NO]
    // 2. are there any bugs? need a known voxel data set to test against
    //    (do that once we have interactivity, to better locate glitches)

    // ADDITIONAL INFO:
    // - final tree will potentially be very deep, with up to 64 levels
    //   (32 levels --> 64km^3 with 0.015 mm resolution)
    // - procedural data generation can be done outside the tree, once
    //   a voxel is intersected, by generating procedural data *inside*
    //   the intersected voxel, depending on its material
    //   (this is actually a REALLY GOOD idea as it completely gets rid
    //    of any cubic artifacts and improves subpixel performance)
    // - 64 levels --> 1800 AU^3 with 0.015 mm resolution
    //   (that's 274 billion km^3, I trust this will be enough)
    // - possibly use a hybrid approach, with two trees, one handling large
    //   64km^3 "chunks", optimized for ultra fast traversal, and another
    //   which focuses on culling chunks to improve performance
    bool traverse(const distance3 &origin, const distance3 &direction,
                  const distance   &range,       distance    &nearest,
                        Contact  &contact, const bool       occlusion) const
    {
        const distance3 &inv_dir = 1 / direction;
        stack_item stack[4 * svo_depth];
        size_t ptr = 0;

        bool hit = false;
        nearest = range;

        push(stack, ptr, stack_item(root, svo_depth, world_min, world_max));

        while (ptr)
        {
            stack_item s = pop(stack, ptr);
            if (s.hit >= nearest) continue;

            if (!s.depth)
            {
                hit = lookup(origin, direction, s, nearest, contact);
                if (occlusion && hit) return true; /* We are done. */
            }
            else
            {
                Node *parent = (Node*)s.memptr;
                stack_item children[4];
                size_t hits = 0;

                for (size_t t = 0; t < 8; ++t)
                {
                    void *child = parent->child[t];
                    if (child == nullptr) continue;

                    stack_item c(child, s, t); /* Child subdivision. */
                    if (ray_aabb(origin, inv_dir, c.min, c.max, c.hit))
                        if (c.hit < nearest) push(children, hits, c);
                }

                sort_network(children); /* Pushed front to back. */
                while (hits) push(stack, ptr, pop(children, hits));
            }
        }

        return hit;
	} __attribute__ ((hot))

    // this will be done in a separate program later on (SVO's will be
    // loaded on the fly, no time to build them while streaming voxels)
    void *build_SVO(int depth, distance3 min_node, distance3 max_node)
    {
        if (depth == 0)
        {
            ++voxel_count;

            // this is a leaf - add voxel
            Voxel *voxel = new Voxel();
            get_voxel_data(min_node, max_node, voxel);
            return voxel;
        }

        Node *node = new Node();

        // build children here
        for (int t = 0; t < 8; ++t)
        {
            distance3 min_child, max_child;
            subdivide(min_node, max_node, t, min_child, max_child);

            if (!contains_voxels(min_child, max_child)) node->child[t] = nullptr;
            else node->child[t] = build_SVO(depth - 1, min_child, max_child);
        }

        return node;
    }

    float heightmap(distance x, distance z) const // TEMPORARY
    {
        //return 0.05f * (sin(x) + cos(z)) - 0.7f;

        if ((x <= -0.525f) || (x >= 0.6f)) return std::numeric_limits<distance>::infinity();
        if ((z <= 0.2f)) return std::numeric_limits<distance>::infinity();

        return -0.7f + 0.03f * (sin(15 * z) + sin(10 * x + 1));

        //return -2.0f/3.0f + 0.2f * x * x;
    }

    math::float3 normal(distance x, distance z) const // TEMPORARY
    {
        distance dx = 0.2 * cos(10 * x + 1);
        distance dz = 0.3 * cos(15 * z);

        //distance dx = 0.4f * x;
        //distance dz = 0;

        return normalize(distance3(dx, 1, dz));
    }

    bool contains_voxels(distance3 min, distance3 max) const // TEMPORARY
    {
        int r = 10;

        for (int px = 0; px < r; ++px)
            for (int pz = 0; pz < r; ++pz)
            {
                distance x = min.x + (max.x - min.x) * (distance)px / r;
                distance z = min.z + (max.z - min.z) * (distance)pz / r;

                distance height = heightmap(x, z);

                if ((min.y <= height) && (height <= max.y)) return true;
            }

        return false;
    }

    void get_voxel_data(distance3 min, distance3 max, Voxel *voxel) const
        // TEMPORARY
    {
        int r = 10;

        for (int px = 0; px < r; ++px)
            for (int pz = 0; pz < r; ++pz)
            {
                distance x = min.x + (max.x - min.x) * (distance)px / r;
                distance z = min.z + (max.z - min.z) * (distance)pz / r;

                distance height = heightmap(x, z);

                if ((min.y <= height) && (height <= max.y))
                {
                    voxel->normal = normal(x, z);

                    float r = std::min(std::max(0.0f, std::abs(x)), 1.0f);
                    float g = std::min(std::max(0.0f, std::abs(z)), 1.0f);
                    float b = std::min(std::max(0.0f, std::abs(x + z)), 1.0f);

                    voxel->rgb = math::float3(r, g, b) + math::float3(0.25f, 0.25f, 0.25f);
                }
            }
    }

    Node *root;

    distance3 world_min, world_max;
};
<|endoftext|>


<commit_before><commit_msg>idlc: make dependencies: handle removed include files:<commit_after><|endoftext|>


<commit_before>/*

Copyright (c) 2003-2014, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.

*/

#ifndef TORRENT_ENTRY_HPP_INCLUDED
#define TORRENT_ENTRY_HPP_INCLUDED

/*
 *
 * This file declares the entry class. It is a
 * variant-type that can be an integer, list,
 * dictionary (map) or a string. This type is
 * used to hold bdecoded data (which is the
 * encoding BitTorrent messages uses).
 *
 * it has 4 accessors to access the actual
 * type of the object. They are:
 * integer()
 * string()
 * list()
 * dict()
 * The actual type has to match the type you
 * are asking for, otherwise you will get an
 * assertion failure.
 * When you default construct an entry, it is
 * uninitialized. You can initialize it through the
 * assignment operator, copy-constructor or
 * the constructor that takes a data_type enum.
 *
 *
 */

#include "libtorrent/config.hpp"

#include "aux_/disable_warnings_push.hpp"

#include <map>
#include <list>
#include <string>
#include <stdexcept>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#if TORRENT_USE_IOSTREAM
#include <iosfwd>
#endif

#include "aux_/disable_warnings_pop.hpp"

#include "libtorrent/assert.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/max.hpp"

namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
	struct lazy_entry;
#endif
	struct bdecode_node;

	// thrown by any accessor function of entry if the accessor
	// function requires a type different than the actual type
	// of the entry object.
	struct TORRENT_EXPORT type_error: std::runtime_error
	{
		// internal
		type_error(const char* error): std::runtime_error(error) {}
	};

	// The ``entry`` class represents one node in a bencoded hierarchy. It works as a
	// variant type, it can be either a list, a dictionary (``std::map``), an integer
	// or a string.
	class TORRENT_EXPORT entry
	{
	public:

		// the key is always a string. If a generic entry would be allowed
		// as a key, sorting would become a problem (e.g. to compare a string
		// to a list). The definition doesn't mention such a limit though.
		typedef std::map<std::string, entry> dictionary_type;
		typedef std::string string_type;
		typedef std::list<entry> list_type;
		typedef boost::int64_t integer_type;

		// the types an entry can have
		enum data_type
		{
			int_t,
			string_t,
			list_t,
			dictionary_t,
			undefined_t
		};

		// returns the concrete type of the entry
		data_type type() const;

		// constructors directly from a specific type.
		// The content of the argument is copied into the
		// newly constructed entry
		entry(dictionary_type const&);
		entry(string_type const&);
		entry(list_type const&);
		entry(integer_type const&);

		// construct an empty entry of the specified type.
		// see data_type enum.
		entry(data_type t);

		// hidden
		entry(entry const& e);

		// hidden
		entry();

		// hidden
		~entry();

		// hidden
		bool operator==(entry const& e) const;
		bool operator!=(entry const& e) const { return !(*this == e); }

		// copies the structure of the right hand side into this
		// entry.
#ifndef TORRENT_NO_DEPRECATE
		void operator=(lazy_entry const&);
#endif
		void operator=(bdecode_node const&);
		void operator=(entry const&);
		void operator=(dictionary_type const&);
		void operator=(string_type const&);
		void operator=(list_type const&);
		void operator=(integer_type const&);

		// The ``integer()``, ``string()``, ``list()`` and ``dict()`` functions
		// are accessors that return the respective type. If the ``entry`` object
		// isn't of the type you request, the accessor will throw
		// libtorrent_exception (which derives from ``std::runtime_error``). You
		// can ask an ``entry`` for its type through the ``type()`` function.
		//
		// If you want to create an ``entry`` you give it the type you want it to
		// have in its constructor, and then use one of the non-const accessors
		// to get a reference which you then can assign the value you want it to
		// have.
		//
		// The typical code to get info from a torrent file will then look like
		// this:
		//
		// .. code:: c++
		//
		// 	entry torrent_file;
		// 	// ...
		//
		// 	// throws if this is not a dictionary
		// 	entry::dictionary_type const& dict = torrent_file.dict();
		// 	entry::dictionary_type::const_iterator i;
		// 	i = dict.find("announce");
		// 	if (i != dict.end())
		// 	{
		// 		std::string tracker_url = i->second.string();
		// 		std::cout << tracker_url << "\n";
		// 	}
		//
		//
		// The following code is equivalent, but a little bit shorter:
		//
		// .. code:: c++
		//
		// 	entry torrent_file;
		// 	// ...
		//
		// 	// throws if this is not a dictionary
		// 	if (entry* i = torrent_file.find_key("announce"))
		// 	{
		// 		std::string tracker_url = i->string();
		// 		std::cout << tracker_url << "\n";
		// 	}
		//
		//
		// To make it easier to extract information from a torrent file, the
		// class torrent_info exists.
		integer_type& integer();
		const integer_type& integer() const;
		string_type& string();
		const string_type& string() const;
		list_type& list();
		const list_type& list() const;
		dictionary_type& dict();
		const dictionary_type& dict() const;

		// swaps the content of *this* with ``e``.
		void swap(entry& e);

		// All of these functions requires the entry to be a dictionary, if it
		// isn't they will throw ``libtorrent::type_error``.
		//
		// The non-const versions of the ``operator[]`` will return a reference
		// to either the existing element at the given key or, if there is no
		// element with the given key, a reference to a newly inserted element at
		// that key.
		//
		// The const version of ``operator[]`` will only return a reference to an
		// existing element at the given key. If the key is not found, it will
		// throw ``libtorrent::type_error``.
 		entry& operator[](char const* key);
		entry& operator[](std::string const& key);
#ifndef BOOST_NO_EXCEPTIONS
		const entry& operator[](char const* key) const;
		const entry& operator[](std::string const& key) const;
#endif

		// These functions requires the entry to be a dictionary, if it isn't
		// they will throw ``libtorrent::type_error``.
		//
		// They will look for an element at the given key in the dictionary, if
		// the element cannot be found, they will return 0. If an element with
		// the given key is found, the return a pointer to it.
		entry* find_key(char const* key);
		entry const* find_key(char const* key) const;
		entry* find_key(std::string const& key);
		entry const* find_key(std::string const& key) const;

		// returns a pretty-printed string representation
		// of the bencoded structure, with JSON-style syntax
		std::string to_string() const;

	protected:

		void construct(data_type t);
		void copy(const entry& e);
		void destruct();

	private:

		void to_string_impl(std::string& out, int indent) const;

#if (defined(_MSC_VER) && _MSC_VER < 1310) || TORRENT_COMPLETE_TYPES_REQUIRED
		// workaround for msvc-bug.
		// assumes sizeof(map<string, char>) == sizeof(map<string, entry>)
		// and sizeof(list<char>) == sizeof(list<entry>)
		enum { union_size
			= max4<sizeof(std::list<char>)
			, sizeof(std::map<std::string, char>)
			, sizeof(string_type)
			, sizeof(integer_type)>::value
		};
#else
		enum { union_size
			= max4<sizeof(list_type)
			, sizeof(dictionary_type)
			, sizeof(string_type)
			, sizeof(integer_type)>::value
		};
#endif
		integer_type data[(union_size + sizeof(integer_type) - 1)
			/ sizeof(integer_type)];

		// the bitfield is used so that the m_type_queried field still fits, so
		// that the ABI is the same for debug builds and release builds. It
		// appears to be very hard to match debug builds with debug versions of
		// libtorrent
		boost::uint8_t m_type:7;

	public:
		// in debug mode this is set to false by bdecode to indicate that the
		// program has not yet queried the type of this entry, and sould not
		// assume that it has a certain type. This is asserted in the accessor
		// functions. This does not apply if exceptions are used.
		mutable boost::uint8_t m_type_queried:1;
	};

#if TORRENT_USE_IOSTREAM
	// prints the bencoded structure to the ostream as a JSON-style structure.
	inline std::ostream& operator<<(std::ostream& os, const entry& e)
	{
		os << e.to_string();
		return os;
	}
#endif

#ifndef BOOST_NO_EXCEPTIONS
	// internal
	BOOST_NORETURN inline void throw_type_error()
	{
		throw libtorrent_exception(error_code(errors::invalid_entry_type
			, get_libtorrent_category()));
	}
#endif

}

#endif // TORRENT_ENTRY_HPP_INCLUDED

<commit_msg>build fix<commit_after>/*

Copyright (c) 2003-2014, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * 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.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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.

*/

#ifndef TORRENT_ENTRY_HPP_INCLUDED
#define TORRENT_ENTRY_HPP_INCLUDED

/*
 *
 * This file declares the entry class. It is a
 * variant-type that can be an integer, list,
 * dictionary (map) or a string. This type is
 * used to hold bdecoded data (which is the
 * encoding BitTorrent messages uses).
 *
 * it has 4 accessors to access the actual
 * type of the object. They are:
 * integer()
 * string()
 * list()
 * dict()
 * The actual type has to match the type you
 * are asking for, otherwise you will get an
 * assertion failure.
 * When you default construct an entry, it is
 * uninitialized. You can initialize it through the
 * assignment operator, copy-constructor or
 * the constructor that takes a data_type enum.
 *
 *
 */

#include "libtorrent/config.hpp"

#include "aux_/disable_warnings_push.hpp"

#include <map>
#include <list>
#include <string>
#include <stdexcept>
#include <boost/cstdint.hpp>
#include <boost/config.hpp>
#if TORRENT_USE_IOSTREAM
#include <iosfwd>
#endif

#include "aux_/disable_warnings_pop.hpp"

#include "libtorrent/assert.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/max.hpp"

namespace libtorrent
{
#ifndef TORRENT_NO_DEPRECATE
	struct lazy_entry;
#endif
	struct bdecode_node;

	// thrown by any accessor function of entry if the accessor
	// function requires a type different than the actual type
	// of the entry object.
	struct TORRENT_EXPORT type_error: std::runtime_error
	{
		// internal
		type_error(const char* error): std::runtime_error(error) {}
	};

	// The ``entry`` class represents one node in a bencoded hierarchy. It works as a
	// variant type, it can be either a list, a dictionary (``std::map``), an integer
	// or a string.
	class TORRENT_EXPORT entry
	{
	public:

		// the key is always a string. If a generic entry would be allowed
		// as a key, sorting would become a problem (e.g. to compare a string
		// to a list). The definition doesn't mention such a limit though.
		typedef std::map<std::string, entry> dictionary_type;
		typedef std::string string_type;
		typedef std::list<entry> list_type;
		typedef boost::int64_t integer_type;

		// the types an entry can have
		enum data_type
		{
			int_t,
			string_t,
			list_t,
			dictionary_t,
			undefined_t
		};

		// returns the concrete type of the entry
		data_type type() const;

		// constructors directly from a specific type.
		// The content of the argument is copied into the
		// newly constructed entry
		entry(dictionary_type const&);
		entry(string_type const&);
		entry(list_type const&);
		entry(integer_type const&);

		// construct an empty entry of the specified type.
		// see data_type enum.
		entry(data_type t);

		// hidden
		entry(entry const& e);

		// hidden
		entry();

		// hidden
		~entry();

		// hidden
		bool operator==(entry const& e) const;
		bool operator!=(entry const& e) const { return !(*this == e); }

		// copies the structure of the right hand side into this
		// entry.
#ifndef TORRENT_NO_DEPRECATE
		void operator=(lazy_entry const&);
#endif
		void operator=(bdecode_node const&);
		void operator=(entry const&);
		void operator=(dictionary_type const&);
		void operator=(string_type const&);
		void operator=(list_type const&);
		void operator=(integer_type const&);

		// The ``integer()``, ``string()``, ``list()`` and ``dict()`` functions
		// are accessors that return the respective type. If the ``entry`` object
		// isn't of the type you request, the accessor will throw
		// libtorrent_exception (which derives from ``std::runtime_error``). You
		// can ask an ``entry`` for its type through the ``type()`` function.
		//
		// If you want to create an ``entry`` you give it the type you want it to
		// have in its constructor, and then use one of the non-const accessors
		// to get a reference which you then can assign the value you want it to
		// have.
		//
		// The typical code to get info from a torrent file will then look like
		// this:
		//
		// .. code:: c++
		//
		// 	entry torrent_file;
		// 	// ...
		//
		// 	// throws if this is not a dictionary
		// 	entry::dictionary_type const& dict = torrent_file.dict();
		// 	entry::dictionary_type::const_iterator i;
		// 	i = dict.find("announce");
		// 	if (i != dict.end())
		// 	{
		// 		std::string tracker_url = i->second.string();
		// 		std::cout << tracker_url << "\n";
		// 	}
		//
		//
		// The following code is equivalent, but a little bit shorter:
		//
		// .. code:: c++
		//
		// 	entry torrent_file;
		// 	// ...
		//
		// 	// throws if this is not a dictionary
		// 	if (entry* i = torrent_file.find_key("announce"))
		// 	{
		// 		std::string tracker_url = i->string();
		// 		std::cout << tracker_url << "\n";
		// 	}
		//
		//
		// To make it easier to extract information from a torrent file, the
		// class torrent_info exists.
		integer_type& integer();
		const integer_type& integer() const;
		string_type& string();
		const string_type& string() const;
		list_type& list();
		const list_type& list() const;
		dictionary_type& dict();
		const dictionary_type& dict() const;

		// swaps the content of *this* with ``e``.
		void swap(entry& e);

		// All of these functions requires the entry to be a dictionary, if it
		// isn't they will throw ``libtorrent::type_error``.
		//
		// The non-const versions of the ``operator[]`` will return a reference
		// to either the existing element at the given key or, if there is no
		// element with the given key, a reference to a newly inserted element at
		// that key.
		//
		// The const version of ``operator[]`` will only return a reference to an
		// existing element at the given key. If the key is not found, it will
		// throw ``libtorrent::type_error``.
 		entry& operator[](char const* key);
		entry& operator[](std::string const& key);
#ifndef BOOST_NO_EXCEPTIONS
		const entry& operator[](char const* key) const;
		const entry& operator[](std::string const& key) const;
#endif

		// These functions requires the entry to be a dictionary, if it isn't
		// they will throw ``libtorrent::type_error``.
		//
		// They will look for an element at the given key in the dictionary, if
		// the element cannot be found, they will return 0. If an element with
		// the given key is found, the return a pointer to it.
		entry* find_key(char const* key);
		entry const* find_key(char const* key) const;
		entry* find_key(std::string const& key);
		entry const* find_key(std::string const& key) const;

		// returns a pretty-printed string representation
		// of the bencoded structure, with JSON-style syntax
		std::string to_string() const;

	protected:

		void construct(data_type t);
		void copy(const entry& e);
		void destruct();

	private:

		void to_string_impl(std::string& out, int indent) const;

#if (defined(_MSC_VER) && _MSC_VER < 1310) || TORRENT_COMPLETE_TYPES_REQUIRED
		// workaround for msvc-bug.
		// assumes sizeof(map<string, char>) == sizeof(map<string, entry>)
		// and sizeof(list<char>) == sizeof(list<entry>)
		enum { union_size
			= max4<sizeof(std::list<char>)
			, sizeof(std::map<std::string, char>)
			, sizeof(string_type)
			, sizeof(integer_type)>::value
		};
#else
		enum { union_size
			= max4<sizeof(list_type)
			, sizeof(dictionary_type)
			, sizeof(string_type)
			, sizeof(integer_type)>::value
		};
#endif
		integer_type data[(union_size + sizeof(integer_type) - 1)
			/ sizeof(integer_type)];

		// the bitfield is used so that the m_type_queried field still fits, so
		// that the ABI is the same for debug builds and release builds. It
		// appears to be very hard to match debug builds with debug versions of
		// libtorrent
		boost::uint8_t m_type:7;

	public:
		// in debug mode this is set to false by bdecode to indicate that the
		// program has not yet queried the type of this entry, and sould not
		// assume that it has a certain type. This is asserted in the accessor
		// functions. This does not apply if exceptions are used.
		mutable boost::uint8_t m_type_queried:1;
	};

#if TORRENT_USE_IOSTREAM
	// prints the bencoded structure to the ostream as a JSON-style structure.
	inline std::ostream& operator<<(std::ostream& os, const entry& e)
	{
		os << e.to_string();
		return os;
	}
#endif

#ifndef BOOST_NO_EXCEPTIONS
	// internal
	TORRENT_NO_RETURN inline void throw_type_error()
	{
		throw libtorrent_exception(error_code(errors::invalid_entry_type
			, get_libtorrent_category()));
	}
#endif

}

#endif // TORRENT_ENTRY_HPP_INCLUDED

<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_idlc.hxx"
#ifndef _IDLC_IDLC_HXX_
#include <idlc/idlc.hxx>
#endif

#ifndef _IDLC_ERRORHANDLER_HXX_
#include <idlc/errorhandler.hxx>
#endif
#ifndef _IDLC_ASTSCOPE_HXX_
#include <idlc/astscope.hxx>
#endif
#ifndef _IDLC_ASTMODULE_HXX_
#include <idlc/astmodule.hxx>
#endif
#ifndef _IDLC_ASTSERVICE_HXX_
#include <idlc/astservice.hxx>
#endif
#ifndef _IDLC_ASTCONSTANTS_HXX_
#include <idlc/astconstants.hxx>
#endif
#ifndef _IDLC_ASTEXCEPTION_HXX_
#include <idlc/astexception.hxx>
#endif
#ifndef _IDLC_ASTUNION_HXX_
#include <idlc/astunion.hxx>
#endif
#ifndef _IDLC_ASTENUM_HXX_
#include <idlc/astenum.hxx>
#endif
#ifndef _IDLC_ASTINTERFACE_HXX_
#include <idlc/astinterface.hxx>
#endif
#ifndef _IDLC_ASTOPERATION_HXX_
#include <idlc/astoperation.hxx>
#endif
#ifndef _IDLC_ASTBASETYPE_HXX_
#include <idlc/astbasetype.hxx>
#endif
#include "idlc/astdeclaration.hxx"
#include "idlc/astsequence.hxx"
#include "idlc/asttype.hxx"
#include "idlc/asttypedef.hxx"

#include "osl/diagnose.h"

using namespace ::rtl;

AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope)
{
    if (pScope == NULL) return NULL;

    switch( pScope->getScopeNodeType() )
    {
        case NT_service:
        case NT_singleton:
            return (AstService*)(pScope);
        case NT_module:
        case NT_root:
            return (AstModule*)(pScope);
        case NT_constants:
            return (AstConstants*)(pScope);
        case NT_interface:
            return (AstInterface*)(pScope);
        case NT_operation:
            return (AstOperation*)(pScope);
        case NT_exception:
            return (AstException*)(pScope);
        case NT_union:
            return (AstUnion*)(pScope);
        case NT_struct:
            return (AstStruct*)(pScope);
        case NT_enum:
            return (AstEnum*)(pScope);
        default:
            return NULL;
    }
}

AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl)
{
    if (pDecl == NULL) return NULL;

    switch(pDecl->getNodeType())
    {
        case NT_interface:
            return (AstInterface*)(pDecl);
        case NT_service:
        case NT_singleton:
            return (AstService*)(pDecl);
        case NT_module:
        case NT_root:
            return (AstModule*)(pDecl);
        case NT_constants:
            return (AstConstants*)(pDecl);
        case NT_exception:
            return (AstException*)(pDecl);
        case NT_union:
            return (AstUnion*)(pDecl);
        case NT_struct:
            return (AstStruct*)(pDecl);
        case NT_enum:
            return (AstEnum*)(pDecl);
        case NT_operation:
            return (AstOperation*)(pDecl);
        default:
            return NULL;
   }
}

static void SAL_CALL initializePredefinedTypes(AstModule* pRoot)
{
    AstBaseType* pPredefined = NULL;
    if ( pRoot )
    {
         pPredefined = new AstBaseType(ET_long, OString("long"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_ulong, OString("unsigned long"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_hyper, OString("hyper"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_uhyper, OString("unsigned hyper"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_short, OString("short"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_ushort, OString("unsigned short"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_float, OString("float"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_double, OString("double"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_char, OString("char"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_byte, OString("byte"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_any, OString("any"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_string, OString("string"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_type, OString("type"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_boolean, OString("boolean"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_void, OString("void"), pRoot);
         pRoot->addDeclaration(pPredefined);
    }
}

Idlc::Idlc(Options* pOptions)
    : m_pOptions(pOptions)
    , m_bIsDocValid(sal_False)
    , m_bIsInMainfile(sal_True)
    , m_errorCount(0)
    , m_warningCount(0)
    , m_lineNumber(0)
    , m_parseState(PS_NoState)
{
    m_pScopes = new AstStack();
    // init root object after construction
    m_pRoot = NULL;
    m_pErrorHandler = new ErrorHandler();
    m_bGenerateDoc = m_pOptions->isValid("-C");
}

Idlc::~Idlc()
{
    if (m_pRoot)
        delete m_pRoot;
    if (m_pScopes)
        delete m_pScopes;
    if (m_pErrorHandler)
        delete m_pErrorHandler;
}

void Idlc::init()
{
    if ( m_pRoot )
        delete m_pRoot;

    m_pRoot = new AstModule(NT_root, OString(), NULL);

    // push the root node on the stack
    m_pScopes->push(m_pRoot);
    initializePredefinedTypes(m_pRoot);
}

void Idlc::reset()
{
    m_errorCount = 0;
    m_warningCount = 0;
    m_lineNumber = 0;
    m_parseState = PS_NoState;

    m_fileName = OString();
    m_mainFileName = OString();
    m_realFileName = OString();
    m_documentation = OString();

    m_pScopes->clear();
    if ( m_pRoot)
        delete m_pRoot;

    m_pRoot = new AstModule(NT_root, OString(), NULL);

    // push the root node on the stack
    m_pScopes->push(m_pRoot);
    initializePredefinedTypes(m_pRoot);
}

sal_Bool Idlc::isDocValid()
{
    if ( m_bGenerateDoc )
        return m_bIsDocValid;
    return sal_False;;
}

static Idlc* pStaticIdlc = NULL;

Idlc* SAL_CALL idlc()
{
    return pStaticIdlc;
}

Idlc* SAL_CALL setIdlc(Options* pOptions)
{
    if ( pStaticIdlc )
    {
        delete pStaticIdlc;
    }
    pStaticIdlc = new Idlc(pOptions);
    pStaticIdlc->init();
    return pStaticIdlc;
}

AstDeclaration const * resolveTypedefs(AstDeclaration const * type) {
    if (type != 0) {
        while (type->getNodeType() == NT_typedef) {
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
        }
    }
    return type;
}

AstDeclaration const * deconstructAndResolveTypedefs(
    AstDeclaration const * type, sal_Int32 * rank)
{
    *rank = 0;
    for (;;) {
        if (type == 0) {
            return 0;
        }
        switch (type->getNodeType()) {
        case NT_typedef:
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
            break;
        case NT_sequence:
            ++(*rank);
            type = static_cast< AstSequence const * >(type)->getMemberType();
            break;
        default:
            return type;
        }
    }
}

AstInterface const * resolveInterfaceTypedefs(AstType const * type) {
    AstDeclaration const * decl = resolveTypedefs(type);
    OSL_ASSERT(decl->getNodeType() == NT_interface);
    return static_cast< AstInterface const * >(decl);
}
<commit_msg>INTEGRATION: CWS jsc14 (1.9.8); FILE MERGED 2006/10/25 14:24:07 jsc 1.9.8.3: #i69727# initialze m_published member 2006/10/25 13:52:16 jsc 1.9.8.2: #69727# remove double member check for predefined XInterface ops 2006/10/23 14:45:38 jsc 1.9.8.1: #69727# predefine com::sun::star::uno::XInterface<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: idlc.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2006-11-06 14:40:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_idlc.hxx"
#ifndef _IDLC_IDLC_HXX_
#include <idlc/idlc.hxx>
#endif

#ifndef _IDLC_ERRORHANDLER_HXX_
#include <idlc/errorhandler.hxx>
#endif
#ifndef _IDLC_ASTSCOPE_HXX_
#include <idlc/astscope.hxx>
#endif
#ifndef _IDLC_ASTMODULE_HXX_
#include <idlc/astmodule.hxx>
#endif
#ifndef _IDLC_ASTSERVICE_HXX_
#include <idlc/astservice.hxx>
#endif
#ifndef _IDLC_ASTCONSTANTS_HXX_
#include <idlc/astconstants.hxx>
#endif
#ifndef _IDLC_ASTEXCEPTION_HXX_
#include <idlc/astexception.hxx>
#endif
#ifndef _IDLC_ASTUNION_HXX_
#include <idlc/astunion.hxx>
#endif
#ifndef _IDLC_ASTENUM_HXX_
#include <idlc/astenum.hxx>
#endif
#ifndef _IDLC_ASTINTERFACE_HXX_
#include <idlc/astinterface.hxx>
#endif
#ifndef _IDLC_ASTOPERATION_HXX_
#include <idlc/astoperation.hxx>
#endif
#ifndef _IDLC_ASTBASETYPE_HXX_
#include <idlc/astbasetype.hxx>
#endif
#include "idlc/astdeclaration.hxx"
#include "idlc/astparameter.hxx"
#include "idlc/astsequence.hxx"
#include "idlc/asttype.hxx"
#include "idlc/asttypedef.hxx"

#include "osl/diagnose.h"

using namespace ::rtl;

AstDeclaration* SAL_CALL scopeAsDecl(AstScope* pScope)
{
    if (pScope == NULL) return NULL;

    switch( pScope->getScopeNodeType() )
    {
        case NT_service:
        case NT_singleton:
            return (AstService*)(pScope);
        case NT_module:
        case NT_root:
            return (AstModule*)(pScope);
        case NT_constants:
            return (AstConstants*)(pScope);
        case NT_interface:
            return (AstInterface*)(pScope);
        case NT_operation:
            return (AstOperation*)(pScope);
        case NT_exception:
            return (AstException*)(pScope);
        case NT_union:
            return (AstUnion*)(pScope);
        case NT_struct:
            return (AstStruct*)(pScope);
        case NT_enum:
            return (AstEnum*)(pScope);
        default:
            return NULL;
    }
}

AstScope* SAL_CALL declAsScope(AstDeclaration* pDecl)
{
    if (pDecl == NULL) return NULL;

    switch(pDecl->getNodeType())
    {
        case NT_interface:
            return (AstInterface*)(pDecl);
        case NT_service:
        case NT_singleton:
            return (AstService*)(pDecl);
        case NT_module:
        case NT_root:
            return (AstModule*)(pDecl);
        case NT_constants:
            return (AstConstants*)(pDecl);
        case NT_exception:
            return (AstException*)(pDecl);
        case NT_union:
            return (AstUnion*)(pDecl);
        case NT_struct:
            return (AstStruct*)(pDecl);
        case NT_enum:
            return (AstEnum*)(pDecl);
        case NT_operation:
            return (AstOperation*)(pDecl);
        default:
            return NULL;
   }
}

static void SAL_CALL predefineXInterface(AstModule* pRoot)
{
    // define the modules  com::sun::star::uno
    AstModule* pParentScope = pRoot;
    AstModule* pModule = new AstModule(OString("com"), pParentScope);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule(OString("sun"), pParentScope);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule(OString("star"), pParentScope);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;
    pModule = new AstModule(OString("uno"), pParentScope);
    pParentScope->addDeclaration(pModule);
    pParentScope = pModule;

    // define XInterface
    AstInterface* pInterface = new AstInterface(OString("XInterface"), NULL, pParentScope);
    pInterface->setDefined();
    pInterface->setPublished();
    pParentScope->addDeclaration(pInterface);

    // define XInterface::queryInterface
    AstOperation* pOp = new AstOperation(0, (AstType*)(pRoot->lookupPrimitiveType(ET_any)),
                                         OString("queryInterface"), pInterface);
    AstParameter* pParam = new AstParameter(DIR_IN, false,
                                            (AstType*)(pRoot->lookupPrimitiveType(ET_type)),
                                            OString("aType"), pOp);
    pOp->addDeclaration(pParam);
    pInterface->addMember(pOp);

    // define XInterface::acquire
    pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
                                         OString("acquire"), pInterface);
    pInterface->addMember(pOp);

    // define XInterface::release
    pOp = new AstOperation(1, (AstType*)(pRoot->lookupPrimitiveType(ET_void)),
                                         OString("release"), pInterface);
    pInterface->addMember(pOp);
}

static void SAL_CALL initializePredefinedTypes(AstModule* pRoot)
{
    AstBaseType* pPredefined = NULL;
    if ( pRoot )
    {
         pPredefined = new AstBaseType(ET_long, OString("long"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_ulong, OString("unsigned long"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_hyper, OString("hyper"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_uhyper, OString("unsigned hyper"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_short, OString("short"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_ushort, OString("unsigned short"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_float, OString("float"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_double, OString("double"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_char, OString("char"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_byte, OString("byte"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_any, OString("any"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_string, OString("string"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_type, OString("type"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_boolean, OString("boolean"), pRoot);
         pRoot->addDeclaration(pPredefined);

         pPredefined = new AstBaseType(ET_void, OString("void"), pRoot);
         pRoot->addDeclaration(pPredefined);
    }
}

Idlc::Idlc(Options* pOptions)
    : m_pOptions(pOptions)
    , m_bIsDocValid(sal_False)
    , m_bIsInMainfile(sal_True)
    , m_published(false)
    , m_errorCount(0)
    , m_warningCount(0)
    , m_lineNumber(0)
    , m_parseState(PS_NoState)
{
    m_pScopes = new AstStack();
    // init root object after construction
    m_pRoot = NULL;
    m_pErrorHandler = new ErrorHandler();
    m_bGenerateDoc = m_pOptions->isValid("-C");
}

Idlc::~Idlc()
{
    if (m_pRoot)
        delete m_pRoot;
    if (m_pScopes)
        delete m_pScopes;
    if (m_pErrorHandler)
        delete m_pErrorHandler;
}

void Idlc::init()
{
    if ( m_pRoot )
        delete m_pRoot;

    m_pRoot = new AstModule(NT_root, OString(), NULL);

    // push the root node on the stack
    m_pScopes->push(m_pRoot);
    initializePredefinedTypes(m_pRoot);
    predefineXInterface(m_pRoot);
}

void Idlc::reset()
{
    m_bIsDocValid = sal_False;
    m_bIsInMainfile = sal_True;
    m_published = false;

    m_errorCount = 0;
    m_warningCount = 0;
    m_lineNumber = 0;
    m_parseState = PS_NoState;

    m_fileName = OString();
    m_mainFileName = OString();
    m_realFileName = OString();
    m_documentation = OString();

    m_pScopes->clear();
    if ( m_pRoot)
        delete m_pRoot;

    m_pRoot = new AstModule(NT_root, OString(), NULL);

    // push the root node on the stack
    m_pScopes->push(m_pRoot);
    initializePredefinedTypes(m_pRoot);
}

sal_Bool Idlc::isDocValid()
{
    if ( m_bGenerateDoc )
        return m_bIsDocValid;
    return sal_False;;
}

static Idlc* pStaticIdlc = NULL;

Idlc* SAL_CALL idlc()
{
    return pStaticIdlc;
}

Idlc* SAL_CALL setIdlc(Options* pOptions)
{
    if ( pStaticIdlc )
    {
        delete pStaticIdlc;
    }
    pStaticIdlc = new Idlc(pOptions);
    pStaticIdlc->init();
    return pStaticIdlc;
}

AstDeclaration const * resolveTypedefs(AstDeclaration const * type) {
    if (type != 0) {
        while (type->getNodeType() == NT_typedef) {
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
        }
    }
    return type;
}

AstDeclaration const * deconstructAndResolveTypedefs(
    AstDeclaration const * type, sal_Int32 * rank)
{
    *rank = 0;
    for (;;) {
        if (type == 0) {
            return 0;
        }
        switch (type->getNodeType()) {
        case NT_typedef:
            type = static_cast< AstTypeDef const * >(type)->getBaseType();
            break;
        case NT_sequence:
            ++(*rank);
            type = static_cast< AstSequence const * >(type)->getMemberType();
            break;
        default:
            return type;
        }
    }
}

AstInterface const * resolveInterfaceTypedefs(AstType const * type) {
    AstDeclaration const * decl = resolveTypedefs(type);
    OSL_ASSERT(decl->getNodeType() == NT_interface);
    return static_cast< AstInterface const * >(decl);
}
<|endoftext|>