#include "AScript.h"
#include <set>
#include "oniguruma.h"
#include "expat.h"

#define NUMBEROF(x) (sizeof(x) / sizeof(x[0]))
#define foreach(T, i, c) for (T::iterator i = (c).begin(); i != (c).end(); i++)

using namespace AScript;

#if 0
main()
{
	::_tprintf(_T("%s\n"), File::GetWorkingDir());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("..\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("..\\..\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("..\\..\\..\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("..\\..\\..\\..\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(
			_T("..\\..\\..\\..\\..\\..\\..\\..\\..\\Scratch.cpp")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("hoge.txt"), _T("C:\\hoge")).c_str());
	::_tprintf(_T("%s\n"), File::MakeAbsPath(_T("hoge.txt"), _T("C:\\hoge\\")).c_str());
}
#endif

#if 0
main()
{
	do {
		int count = 6;
		int dec, sign;
		double value = 523456789.123456789;
		char *p = ::_ecvt(value, count, &dec, &sign);
		::printf("_ecvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = -523456789.123456789;
		char *p = ::_ecvt(value, count, &dec, &sign);
		::printf("_ecvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 10;
		int dec, sign;
		double value = 52345.89;
		char *p = ::_ecvt(value, count, &dec, &sign);
		::printf("_ecvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = 0.000523456789;
		char *p = ::_ecvt(value, count, &dec, &sign);
		::printf("_ecvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = 0.523456789;
		char *p = ::_ecvt(value, count, &dec, &sign);
		::printf("_ecvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = 523456789.123456789;
		char *p = ::_fcvt(value, count, &dec, &sign);
		::printf("_fcvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = 0.000523456789;
		char *p = ::_fcvt(value, count, &dec, &sign);
		::printf("_fcvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 6;
		int dec, sign;
		double value = 0.523456789;
		char *p = ::_fcvt(value, count, &dec, &sign);
		::printf("_fcvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int count = 10;
		int dec, sign;
		double value = 52345.89;
		char *p = ::_fcvt(value, count, &dec, &sign);
		::printf("_fcvt .. %s count=%d,dec=%d,sign=%d\n", p, count, dec, sign);
	} while (0);
	do {
		int digits = 1;
		char buff[128];
		double value = 523456789.123456789;
		char *p = ::_gcvt(value, digits, buff);
		::printf("_gcvt .. %s digits=%d\n", p, digits);
	} while (0);
	do {
		int digits = 6;
		char buff[128];
		double value = 523456789.123456789;
		char *p = ::_gcvt(value, digits, buff);
		::printf("_gcvt .. %s digits=%d\n", p, digits);
	} while (0);
	do {
		int digits = 6;
		char buff[128];
		double value = 5239.123456789;
		char *p = ::_gcvt(value, digits, buff);
		::printf("_gcvt .. %s digits=%d\n", p, digits);
	} while (0);
}
#endif

#if 0
int onigFunc(const UChar *nameRaw, const UChar *nameRawEnd, int nGroups, int *idxGroupTbl, regex_t *pRegEx, void *arg)
{
	String name(reinterpret_cast<const TCHAR *>(nameRaw), nameRawEnd - nameRaw);
	::_tprintf(_T("\"%s\" .. "), name.c_str());
	for (int i = 0; i < nGroups; i++) {
		::_tprintf(_T(" %d"), idxGroupTbl[i]);
	}
	::_tprintf(_T("\n"));
	return 0;
}

int main(int argc, char *argv[])
{
	//TCHAR *pattern = _T("a(.*)b|[e-f]+");
	const TCHAR *pattern = _T("(?<func>\\w+)\\((?<arg>\\w+)(?<arg>\\w+)(?<arg>\\w+)(?<ex>\\w+)");
	regex_t *pRegEx = NULL;
	do {
		OnigErrorInfo errInfo;
		size_t len = ::_tcslen(pattern);
		int rtn = ::onig_new(&pRegEx, pattern, pattern + len,
			ONIG_OPTION_DEFAULT, ONIG_ENCODING_ASCII, ONIG_SYNTAX_DEFAULT, &errInfo);
		if (rtn != ONIG_NORMAL) {
			TCHAR errMsg[ONIG_MAX_ERROR_MESSAGE_LEN];
			::onig_error_code_to_str(errMsg, rtn, &errInfo);
			::_ftprintf(stderr, _T("ERROR: %s\n"), errMsg);
			return 1;
		}
		::onig_foreach_name(pRegEx, &onigFunc, NULL);
	} while (0);
	do {
		//TCHAR *str = _T("zzzzaffffffffb");
		const TCHAR *str = _T("int main(int argc, char *argv[])");
		size_t len = ::_tcslen(str);
		const TCHAR *start = str;
		OnigRegion *pRegion = ::onig_region_new();
		int rtn = ::onig_search(pRegEx, str, str + len, start, start + len,
												pRegion, ONIG_OPTION_NONE);
		if (rtn >= 0) {
			::_ftprintf(stderr, _T("match at position %d\n"), rtn);
			for (int iGroup = 0; iGroup < pRegion->num_regs; iGroup++) {
				int posBegin = pRegion->beg[iGroup];
				int posEnd = pRegion->end[iGroup];
				::_ftprintf(stderr, _T("group#%d: position %2d-%2d \"%s\"\n"),
						iGroup, posBegin, posEnd,
						String(str + posBegin, posEnd - posBegin).c_str());
			}
		} else if (rtn == ONIG_MISMATCH) {
			::_ftprintf(stderr, _T("matching failed\n"));
		} else { // error
			TCHAR errMsg[ONIG_MAX_ERROR_MESSAGE_LEN];
			::onig_error_code_to_str(errMsg, rtn);
			::_ftprintf(stderr, _T("ERROR: %s\n"), errMsg);
			return -1;
		}
		::onig_region_free(pRegion, 1); // 1:free self, 0:free contents only
	} while (0);
	::onig_free(pRegEx);
	::onig_end();
	return 0;
}
#endif

#if 0
static void XMLCALL startElement(void *userData, const TCHAR *name, const TCHAR **attrs)
{
	int &depth = *reinterpret_cast<int *>(userData);
	::_tprintf(_T("%*s%s\n"), depth * 4, _T(""), name);
	depth++;
}

static void XMLCALL endElement(void *userData, const TCHAR *name)
{
	int &depth = *reinterpret_cast<int *>(userData);
	depth--;
}

int main(int argc, char *argv[])
{
	int depth = 0;
	char buff[BUFSIZ];
	XML_Parser parser = ::XML_ParserCreate(NULL);
	::XML_SetUserData(parser, &depth);
	::XML_SetElementHandler(parser, startElement, endElement);
	for (;;) {
		int bytes = ::fread(buff, 1, sizeof(buff), stdin);
		int doneFlag = (bytes < sizeof(buff));
		if (::XML_Parse(parser, buff, bytes, doneFlag) == XML_STATUS_ERROR) {
			::_ftprintf(stderr, _T("%s at line %lu\n"),
					::XML_ErrorString(XML_GetErrorCode(parser)),
					::XML_GetCurrentLineNumber(parser));
			break;
		}
		if (doneFlag) break;
	}
	::XML_ParserFree(parser);
	return 0;
}
#endif

void main()
{
	printf("%d\n", File::IsMatchName(_T("*.asm"), _T("test.txt"), false));
}
