summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasudev Kamath <kamathvasudev@gmail.com>2012-12-13 22:38:45 +0530
committerVasudev Kamath <kamathvasudev@gmail.com>2012-12-13 22:38:45 +0530
commit658e20cded80a08d097b7833afbe3b20ee9aa39b (patch)
treeee1e275637edfbb359ad856d04ecbe807bd39db3
Imported Upstream version 2.8.3
-rw-r--r--CHANGES431
-rw-r--r--CMakeLists.txt917
-rw-r--r--CTPP2SysHeaders.h.cmake88
-rw-r--r--ClearPackage.cmd21
-rwxr-xr-xClearPackage.sh7
-rw-r--r--CodeStyle145
-rw-r--r--Doxyfile181
-rw-r--r--FreeBSD/textproc/ctpp2/Makefile25
-rw-r--r--FreeBSD/textproc/ctpp2/pkg-descr7
-rw-r--r--FreeBSD/textproc/ctpp2/pkg-plist72
-rw-r--r--INSTALL180
-rw-r--r--LICENSE26
-rw-r--r--NOTTODO12
-rw-r--r--PKGBUILD25
-rw-r--r--TODO13
-rw-r--r--benchmarks/CDT2JSON.cpp135
-rw-r--r--benchmarks/data/lebowski-bench.json140
-rw-r--r--benchmarks/data/test.json1
-rw-r--r--ctpp2.ebuild27
-rw-r--r--ctpp2.spec306
-rw-r--r--doc/bootstrap.css4221
-rw-r--r--doc/colors.css16
-rw-r--r--doc/template_language.rst729
-rw-r--r--include/CDT.hpp2187
-rw-r--r--include/CDTSortRoutines.hpp251
-rw-r--r--include/CTPP2BitIndex.hpp166
-rw-r--r--include/CTPP2CharIterator.hpp143
-rw-r--r--include/CTPP2Compiler.hpp624
-rw-r--r--include/CTPP2DTOA.hpp75
-rw-r--r--include/CTPP2Error.hpp85
-rw-r--r--include/CTPP2ErrorCodes.h70
-rw-r--r--include/CTPP2Exception.hpp283
-rw-r--r--include/CTPP2FileLogger.hpp83
-rw-r--r--include/CTPP2FileOutputCollector.hpp102
-rw-r--r--include/CTPP2FileSourceLoader.hpp114
-rw-r--r--include/CTPP2GetText.hpp307
-rw-r--r--include/CTPP2GlobalDefines.h171
-rw-r--r--include/CTPP2HashTable.hpp175
-rw-r--r--include/CTPP2JSONFileParser.hpp85
-rw-r--r--include/CTPP2JSONParser.hpp164
-rw-r--r--include/CTPP2Logger.hpp193
-rw-r--r--include/CTPP2OutputCollector.hpp68
-rw-r--r--include/CTPP2Parser.hpp623
-rw-r--r--include/CTPP2ParserException.hpp172
-rw-r--r--include/CTPP2SimpleCompiler.hpp98
-rw-r--r--include/CTPP2SimpleVM.hpp154
-rw-r--r--include/CTPP2SourceLoader.hpp80
-rw-r--r--include/CTPP2Sprintf.hpp51
-rw-r--r--include/CTPP2StaticData.hpp178
-rw-r--r--include/CTPP2StaticText.hpp179
-rw-r--r--include/CTPP2StreamOutputCollector.hpp82
-rw-r--r--include/CTPP2StringBuffer.hpp111
-rw-r--r--include/CTPP2StringIconvOutputCollector.hpp104
-rw-r--r--include/CTPP2StringOutputCollector.hpp81
-rw-r--r--include/CTPP2SymbolTable.hpp262
-rw-r--r--include/CTPP2Syntax.h113
-rw-r--r--include/CTPP2SysTypes.h515
-rw-r--r--include/CTPP2SyscallFactory.hpp135
-rw-r--r--include/CTPP2Time.h51
-rw-r--r--include/CTPP2Types.h45
-rw-r--r--include/CTPP2Util.hpp242
-rw-r--r--include/CTPP2VM.hpp139
-rw-r--r--include/CTPP2VMArgStack.hpp171
-rw-r--r--include/CTPP2VMCodeStack.hpp117
-rw-r--r--include/CTPP2VMDebugInfo.hpp117
-rw-r--r--include/CTPP2VMDumper.hpp108
-rw-r--r--include/CTPP2VMException.hpp410
-rw-r--r--include/CTPP2VMExecutable.hpp186
-rw-r--r--include/CTPP2VMFileLoader.hpp76
-rw-r--r--include/CTPP2VMInstruction.hpp70
-rw-r--r--include/CTPP2VMLoader.hpp70
-rw-r--r--include/CTPP2VMMemoryCore.hpp82
-rw-r--r--include/CTPP2VMOpcodeCollector.hpp97
-rw-r--r--include/CTPP2VMOpcodes.h199
-rw-r--r--include/CTPP2VMSTDLib.hpp94
-rw-r--r--include/CTPP2VMStackException.hpp166
-rw-r--r--include/CTPP2VMSyscall.hpp120
-rw-r--r--include/STLException.hpp51
-rw-r--r--include/STLFunctional.hpp51
-rw-r--r--include/STLIosfwd.hpp51
-rw-r--r--include/STLMap.hpp51
-rw-r--r--include/STLOstream.hpp51
-rw-r--r--include/STLPair.hpp50
-rw-r--r--include/STLString.hpp50
-rw-r--r--include/STLVector.hpp50
-rw-r--r--include/functions/CTPP2VMSTDLibFunctions.hpp99
-rw-r--r--include/functions/FnAvg.hpp105
-rw-r--r--include/functions/FnBase64Decode.hpp89
-rw-r--r--include/functions/FnBase64Encode.hpp89
-rw-r--r--include/functions/FnCast.hpp89
-rw-r--r--include/functions/FnConcat.hpp105
-rw-r--r--include/functions/FnContext.hpp108
-rw-r--r--include/functions/FnDateFormat.hpp89
-rw-r--r--include/functions/FnDefault.hpp89
-rw-r--r--include/functions/FnDefined.hpp89
-rw-r--r--include/functions/FnEmitter.hpp118
-rw-r--r--include/functions/FnError.hpp89
-rw-r--r--include/functions/FnFormParam.hpp89
-rw-r--r--include/functions/FnGetText.hpp112
-rw-r--r--include/functions/FnGetType.hpp89
-rw-r--r--include/functions/FnHMACMD5.hpp101
-rw-r--r--include/functions/FnHTMLEscape.hpp89
-rw-r--r--include/functions/FnHashKeys.hpp89
-rw-r--r--include/functions/FnHostname.hpp93
-rw-r--r--include/functions/FnHrefParam.hpp89
-rw-r--r--include/functions/FnIconv.hpp103
-rw-r--r--include/functions/FnInArray.hpp89
-rw-r--r--include/functions/FnInSet.hpp89
-rw-r--r--include/functions/FnJSON.hpp89
-rw-r--r--include/functions/FnJSONEscape.hpp89
-rw-r--r--include/functions/FnList.hpp101
-rw-r--r--include/functions/FnListElement.hpp101
-rw-r--r--include/functions/FnLog.hpp89
-rw-r--r--include/functions/FnMBSize.hpp89
-rw-r--r--include/functions/FnMBSubstring.hpp105
-rw-r--r--include/functions/FnMBTruncate.hpp104
-rw-r--r--include/functions/FnMD5.hpp101
-rw-r--r--include/functions/FnMax.hpp89
-rw-r--r--include/functions/FnMin.hpp89
-rw-r--r--include/functions/FnNumFormat.hpp89
-rw-r--r--include/functions/FnObjDump.hpp108
-rw-r--r--include/functions/FnRandom.hpp89
-rw-r--r--include/functions/FnSize.hpp89
-rw-r--r--include/functions/FnSprintf.hpp89
-rw-r--r--include/functions/FnSubstring.hpp105
-rw-r--r--include/functions/FnTruncate.hpp104
-rw-r--r--include/functions/FnURIEscape.hpp89
-rw-r--r--include/functions/FnURLEscape.hpp89
-rw-r--r--include/functions/FnVersion.hpp88
-rw-r--r--include/functions/FnWMLEscape.hpp89
-rw-r--r--include/functions/FnXMLEscape.hpp89
-rw-r--r--include/libgen_win32.h80
-rw-r--r--man/ctpp2-config.186
-rw-r--r--man/ctpp2c.166
-rw-r--r--man/ctpp2i.176
-rw-r--r--man/ctpp2json.162
-rw-r--r--man/ctpp2vm.176
-rw-r--r--multithread/CTPP2MT.cpp184
-rw-r--r--multithread/hello.tmpl1
-rw-r--r--src/CDT.cpp4929
-rw-r--r--src/CDTSortRoutines.cpp239
-rw-r--r--src/CTPP2BitIndex.cpp172
-rw-r--r--src/CTPP2Compiler.cpp1075
-rw-r--r--src/CTPP2DTOA.cpp1833
-rw-r--r--src/CTPP2Error.cpp56
-rw-r--r--src/CTPP2Exception.cpp255
-rw-r--r--src/CTPP2FileLogger.cpp68
-rw-r--r--src/CTPP2FileOutputCollector.cpp88
-rw-r--r--src/CTPP2FileSourceLoader.cpp295
-rw-r--r--src/CTPP2GetText.cpp1290
-rw-r--r--src/CTPP2HashTable.cpp237
-rw-r--r--src/CTPP2JSONFileParser.cpp155
-rw-r--r--src/CTPP2JSONParser.cpp632
-rw-r--r--src/CTPP2Logger.cpp166
-rw-r--r--src/CTPP2Parser.cpp3025
-rw-r--r--src/CTPP2ParserException.cpp140
-rw-r--r--src/CTPP2SimpleCompiler.cpp158
-rw-r--r--src/CTPP2SimpleVM.cpp169
-rw-r--r--src/CTPP2Sprintf.cpp914
-rw-r--r--src/CTPP2StaticData.cpp201
-rw-r--r--src/CTPP2StaticText.cpp190
-rw-r--r--src/CTPP2StreamOutputCollector.cpp68
-rw-r--r--src/CTPP2StringBuffer.cpp120
-rw-r--r--src/CTPP2StringIconvOutputCollector.cpp118
-rw-r--r--src/CTPP2StringOutputCollector.cpp66
-rw-r--r--src/CTPP2SyscallFactory.cpp106
-rw-r--r--src/CTPP2Util.cpp1052
-rw-r--r--src/CTPP2VM.cpp2438
-rw-r--r--src/CTPP2VMArgStack.cpp143
-rw-r--r--src/CTPP2VMCodeStack.cpp92
-rw-r--r--src/CTPP2VMDebugInfo.cpp110
-rw-r--r--src/CTPP2VMDumper.cpp385
-rw-r--r--src/CTPP2VMException.cpp322
-rw-r--r--src/CTPP2VMExecutable.cpp90
-rw-r--r--src/CTPP2VMFileLoader.cpp252
-rw-r--r--src/CTPP2VMMemoryCore.cpp66
-rw-r--r--src/CTPP2VMOpcodeCollector.cpp96
-rw-r--r--src/CTPP2VMSTDLib.cpp239
-rw-r--r--src/CTPP2VMSyscall.cpp68
-rw-r--r--src/functions/FnAvg.cpp150
-rw-r--r--src/functions/FnBase64Decode.cpp80
-rw-r--r--src/functions/FnBase64Encode.cpp80
-rw-r--r--src/functions/FnCast.cpp170
-rw-r--r--src/functions/FnConcat.cpp79
-rw-r--r--src/functions/FnContext.cpp95
-rw-r--r--src/functions/FnDateFormat.cpp94
-rw-r--r--src/functions/FnDefault.cpp81
-rw-r--r--src/functions/FnDefined.cpp89
-rw-r--r--src/functions/FnEmitter.cpp88
-rw-r--r--src/functions/FnError.cpp71
-rw-r--r--src/functions/FnFormParam.cpp83
-rw-r--r--src/functions/FnGetText.cpp122
-rw-r--r--src/functions/FnGetType.cpp79
-rw-r--r--src/functions/FnHMACMD5.cpp315
-rw-r--r--src/functions/FnHTMLEscape.cpp81
-rw-r--r--src/functions/FnHashKeys.cpp86
-rw-r--r--src/functions/FnHostname.cpp95
-rw-r--r--src/functions/FnHrefParam.cpp82
-rw-r--r--src/functions/FnIconv.cpp227
-rw-r--r--src/functions/FnInArray.cpp100
-rw-r--r--src/functions/FnInSet.cpp91
-rw-r--r--src/functions/FnJSON.cpp83
-rw-r--r--src/functions/FnJSONEscape.cpp106
-rw-r--r--src/functions/FnList.cpp78
-rw-r--r--src/functions/FnListElement.cpp93
-rw-r--r--src/functions/FnLog.cpp92
-rw-r--r--src/functions/FnMBSize.cpp100
-rw-r--r--src/functions/FnMBSubstring.cpp180
-rw-r--r--src/functions/FnMBTruncate.cpp133
-rw-r--r--src/functions/FnMD5.cpp218
-rw-r--r--src/functions/FnMax.cpp86
-rw-r--r--src/functions/FnMin.cpp86
-rw-r--r--src/functions/FnNumFormat.cpp256
-rw-r--r--src/functions/FnObjDump.cpp106
-rw-r--r--src/functions/FnRandom.cpp144
-rw-r--r--src/functions/FnSize.cpp82
-rw-r--r--src/functions/FnSprintf.cpp90
-rw-r--r--src/functions/FnSubstring.cpp116
-rw-r--r--src/functions/FnTruncate.cpp96
-rw-r--r--src/functions/FnURIEscape.cpp81
-rw-r--r--src/functions/FnURLEscape.cpp82
-rw-r--r--src/functions/FnVersion.cpp77
-rw-r--r--src/functions/FnWMLEscape.cpp82
-rw-r--r--src/functions/FnXMLEscape.cpp83
-rw-r--r--tests/BitIndexText.cpp106
-rw-r--r--tests/CDTPerfTest.cpp108
-rw-r--r--tests/CDTTest.cpp776
-rw-r--r--tests/CTPP2Compiler.cpp124
-rw-r--r--tests/CTPP2DTOA.cpp65
-rw-r--r--tests/CTPP2Emulator.cpp207
-rw-r--r--tests/CTPP2Interpreter.cpp193
-rw-r--r--tests/CTPP2JSONParser.cpp101
-rw-r--r--tests/CTPP2VMTest.cpp307
-rw-r--r--tests/HashTest.cpp69
-rwxr-xr-xtests/PERLPerfTest.pl25
-rwxr-xr-xtests/PHPPerfTest.php32
-rw-r--r--tests/SimpleCompilerTest.cpp51
-rw-r--r--tests/SimpleVMTest.cpp68
-rw-r--r--tests/StaticTextTest.cpp78
-rw-r--r--tests/VMArgStackTest.cpp95
-rw-r--r--tests/VMCodeStackTest.cpp93
-rw-r--r--tests/VMDumperTest.cpp91
-rw-r--r--tests/VMEmulator.cpp189
-rw-r--r--tests/testdata/arith_ops.out142
-rw-r--r--tests/testdata/arith_ops.tmpl142
-rw-r--r--tests/testdata/array_and_hash_access.json20
-rw-r--r--tests/testdata/array_and_hash_access.out22
-rw-r--r--tests/testdata/array_and_hash_access.tmpl22
-rw-r--r--tests/testdata/array_and_hash_access_incl.tmpl1
-rw-r--r--tests/testdata/calls.out74
-rw-r--r--tests/testdata/calls.tmpl57
-rw-r--r--tests/testdata/comparisons.out53
-rw-r--r--tests/testdata/comparisons.tmpl53
-rw-r--r--tests/testdata/formulas.out9
-rw-r--r--tests/testdata/formulas.tmpl9
-rw-r--r--tests/testdata/function_gettext.out18
-rw-r--r--tests/testdata/function_gettext.tmpl18
-rw-r--r--tests/testdata/function_hostname.tmpl2
-rw-r--r--tests/testdata/function_iconv.out3
-rw-r--r--tests/testdata/function_iconv.tmpl3
-rw-r--r--tests/testdata/function_md5.out7
-rw-r--r--tests/testdata/function_md5.tmpl7
-rw-r--r--tests/testdata/function_obj_dump.tmpl2
-rw-r--r--tests/testdata/function_random.tmpl6
-rw-r--r--tests/testdata/functions.out94
-rw-r--r--tests/testdata/functions.tmpl92
-rw-r--r--tests/testdata/lebowski-bench-foreach.out151
-rw-r--r--tests/testdata/lebowski-bench-foreach.tmpl63
-rw-r--r--tests/testdata/lebowski-bench.json139
-rw-r--r--tests/testdata/loops.out188
-rw-r--r--tests/testdata/loops.tmpl16
-rw-r--r--tests/testdata/output_variables.out28
-rw-r--r--tests/testdata/output_variables.tmpl27
-rw-r--r--tests/testdata/test.mobin0 -> 691 bytes
-rw-r--r--tests/testdata/testdata.json62
-rw-r--r--tests/testdata/verbose_mode.out9
-rw-r--r--tests/testdata/verbose_mode.tmpl42
277 files changed, 55423 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..67534e4
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,431 @@
+ CTPP version 2.8.3 change log
+ -----------------------------
+
+ Legend
+ ------
+ + = New feature
+ * = Improved feature
+ - = Removed feature
+ ! = Bug fixed
+ = = Unresolved
+ # = Other stuff
+
+ Version 2.8.3 (10.11.2012)
+ --------------------------
+ 01. + Returned curly brakets as an alias for square
+ 02. ! Fixed error reporting
+
+ Version 2.8.2 (13.06.2012)
+ --------------------------
+ 01. - Removed the operator <TMPL_loop> ... </TMPL_loop>
+ 02. - Removed __FIRST__, __LAST__, __INNER__, __ODD__, __COUNTER__, __EVEN__, __SIZE__, __CONTENT__
+ 03. - Removed string compat old version in <TMPL_include>
+ 04. - Removed the attribute 'map' in <TMPL_include>
+ 05. - Removed functions: NUMERAL, ARRAY_ELEMENT, HASH_ELEMENT
+ 06. ! Full support of variables in <TMPL_call>
+ 07. + Support of hashes in <TMPL_foreach>
+ 08. + New operator <TMPL_break>
+ 09. + New attributes for iterator of <TMPL_foreach>: __first__, __last__, __index__, __key__, __inner__, __odd__, __even__, __size__
+ 10. + New functions: CONTEXT, LIST
+ 11. + Documentation of the CT++ template language (English version)
+ 12. # Renamed JSESCAPE to JSONESCAPE. Refactored the code
+ 13. # Performance boost for stream-like DumpJsonString fucntion
+ 14. # Refactored code
+
+ Version 2.8.0 (28.12.2011)
+ --------------------------
+ 01. * Improved access to arrays and hashes
+
+ Version 2.7.6 (28.12.2011)
+ --------------------------
+ 01. ! Bug fixes
+ 02. + Tests
+
+ Version 2.7.5 (23.12.2011)
+ --------------------------
+ 01. ! Fixes in CDT::operator=
+ 02. ! Fixes in block parameters
+
+ Version 2.7.4 (19.12.2011)
+ --------------------------
+ 01. ! Fixes in CDT::operator=
+ 02. + New constant operator[INT_32] and constant operator[STLW::string]
+
+ Version 2.7.3 (14.11.2011)
+ --------------------------
+ 01. ! Fixes in block arguments
+ 02. ! New access operator [] for constant objects
+
+ Version 2.7.2 (05.10.2011)
+ --------------------------
+ 01. ! Fixes in URI/URL Escape functions
+ 02. ! Fixes codegenerator for call/block operators
+
+ Version 2.7.1 (04.07.2011)
+ --------------------------
+ 01. + New operator <TMPL_verbose> ... </TMPL_verbose>
+ 02. + New modifications of *ALL* operators allows cut leading and trailing spaces
+ 03. + New implementation of GETTEXT function
+ 04. ! Bug fixes
+
+ Version 2.7.0 (23.05.2011)
+ --------------------------
+ 01. + Access to arrays ahd hashes contents in variables
+
+ Version 2.6.15 (16.05.2011)
+ ---------------------------
+ 01. ! Fixes in TMPL_foreach translate map
+
+ Version 2.6.14 (28.04.2011)
+ ---------------------------
+ 01. ! Gettext patches
+
+ Version 2.6.13 (05.04.2011)
+ ---------------------------
+ 01. ! Fixes in SPRINTF function (thanks for patch to Varinov Nicolay <nic@sotcom.ru>)
+ 02. New methods in CDT class: JoinArrayElements, JoinHashKeys, JoinHashKeys, GetHashKeys, GetHashValues, MergeCDT
+
+ Version 2.6.12 (15.03.2011)
+ ---------------------------
+ 01. ! Fixes in Unicode unescape algorithm, thanks to <demonister @ gmail.com>
+
+ Version 2.6.11 (28.02.2011)
+ ---------------------------
+ 01. * Fixes in CTPP2DTOA.cpp, thanks to Vincent <vincent.hervieux@gmail.com>
+
+ Version 2.6.10 (11.02.2011)
+ ---------------------------
+ 01. * Fixes in SPRINTF function (thanks for patch to Varinov Nicolay <nic@sotcom.ru>)
+
+ Version 2.6.9 (09.02.2011)
+ --------------------------
+ 01. * New function: HOSTNAME
+
+ Version 2.6.8 (27.01.2011)
+ --------------------------
+ 01. * New function: GET_TYPE, thanks to Tim Tavlintsev
+
+ Version 2.6.7 (01.11.2010)
+ --------------------------
+ 01. * Dump/RecursiveDump improvements
+ 02. * NUM_FORMAT improvements, thanks to Lunkov Alexander
+ 03. ! SPRINTF %f/%e/%g format fixes, thanks to Vlad 'twilight' Maximov
+
+ Version 2.6.6 (05.10.2010)
+ --------------------------
+ 01. ! Linux bug fixes
+
+ Version 2.6.5 (22.09.2010)
+ --------------------------
+ 01. ! Fixes in CTPP2 dialect compiler, thanks to Vlad 'twilight' Maximov
+
+ Version 2.6.4 (20.09.2010)
+ --------------------------
+ 01. * Fixes in SortArray method
+
+ Version 2.6.3 (27.07.2010)
+ --------------------------
+ 01. ! Fixes in TMPL_foreach iterators (thanks to Kirichenko Sergey <kirichenko@post.km.ru>)
+
+ Version 2.6.2 (20.07.2010)
+ --------------------------
+ 01. + CDT Swap method
+ 02. + CDT SortArray method & helpers
+
+ Version 2.6.1 (15.06.2010)
+ --------------------------
+ 01. ! Various bug fixes
+ 02. # First stable version if branch 2.6
+
+ Version 2.6.0 (08.06.2010) (Technology Preview)
+ -----------------------------------------------
+ 01. + New CDT implementation
+ 02. + New contextual variables: __RCOUNTER__ & __OUTER__
+ 03. + New function: HASH_ELEMENT
+ 04. # System identificator changed from `Sanahin` to `Dzoraget`
+ 05. # HUGE API changes
+
+ Version 2.5.19 (24.05.2010)
+ ---------------------------
+ 01. ! Math ops in Foreach cycle
+
+ Version 2.5.18 (09.04.2010)
+ ---------------------------
+ 01. ! Darwin OS fixes only (types)
+
+ Version 2.5.17 (02.04.2010)
+ ---------------------------
+ 01. + New function: SPRINTF
+ 02. * StreamOutputCollector.hpp fixes
+ 03. ! Fixes in template compiler(IsFloat mechanism)
+
+ Version 2.5.16 (11.02.2010)
+ ---------------------------
+ 01. # Bump Copyright year
+ 02. + Documentation for functions NUMERAL, LIST_ELEMENT and ARRAY_ELEMENT
+ 03. + English version of documentation (thanks to Alexey Kerdivare <alexey.kerdivare@gmail.com>
+ 04. * Function EscapeJSONString is now ECMA-262 compatible
+
+ Version 2.5.15 (30.12.2009)
+ ---------------------------
+ 01. ! Fixes in function NUM_FORMAT, thanks to http://ilnarb.livejournal.com/
+
+ Version 2.5.14 (02.12.2009)
+ ---------------------------
+ 01. + New method for class CDT: Erase. Erase element from hash by specified key name.
+
+ Version 2.5.13 (24.11.2009)
+ ---------------------------
+ 01. ! Fixes in Base64Encode function
+
+ Version 2.5.12 (18.10.2009)
+ ---------------------------
+ 01. + New data collector: C++ ostream collector (thanks to Chris Trees <christrees@yahoo.com>)
+ 02. + Port to CygWin (thanks to NetImperia <netimperia@netimperia.com>)
+ 03. + New overloaded method for class CDT: Exist. Check existence of element.
+ 04. ! Fixes in CDT class: pointer POINTER_VAL
+
+ Version 2.5.11 (27.08.2009)
+ ---------------------------
+ 01. ! Fixes in virtual machine (CMP instruction)
+
+ Version 2.5.10 (18.08.2009)
+ --------------------------_
+ 01. + New functions: LIST_ELEMENT & ARRAY_ELEMENT
+ 02. ! Fixes in JSON parser
+
+ Version 2.5.9 (13.08.2009)
+ --------------------------
+ 01. ! Fixes in <TMPL_foreach .. > <TMPL_include "file"> </TMPL_foreach>
+
+ Version 2.5.8 (05.08.2009)
+ --------------------------
+ 01. * Completely rewrite code of JSON parser
+
+ Version 2.5.7 (24.06.2009)
+ --------------------------
+ 01. + New function: NUMERAL
+ 02. ! Fixes in TRUNCATE & MB_TRUNCATE functions
+
+ Version 2.5.6 (09.06.2009)
+ --------------------------
+ 01. ! Fixes in JSESCAPE function
+
+ Version 2.5.5 (02.06.2009)
+ --------------------------
+ 01. ! Fixes in math. expressions inside functions: <TMPL_var FOO(bar + baz)>
+
+ Version 2.5.4 (20.05.2009)
+ --------------------------
+ 01. ! Fixes for MSVC 2008
+ 02. ! Fixes in Win32/CryptoAPI
+ 03. * Avoid a lot of warnings on gcc 4.3+
+ 04. # #include <...> changed to #include "..." for all files of project
+
+ Version 2.5.3 (12.05.2009)
+ --------------------------
+ 01. * Removed inline methods of exception classes
+
+ Version 2.5.2 (20.04.2009)
+ --------------------------
+ 01. ! Bug fixes in branches inside foreach operator
+
+ Version 2.5.1 (17.04.2009)
+ --------------------------
+ 01. ! Bug fixes in foreach operator
+ 02. + Documentation for foreach operator
+
+ Version 2.5.0 (16.04.2009)
+ --------------------------
+ 01. + New operator: <TMPL_foreach
+ 02. * Gettext function accept now 1, 2 or 3 parameters like
+ GNU gettext, dgettext dcgettext functions
+ 03. # All CTPPxxxxx files renamed to CTPP2xxxxx
+
+ Version 2.4.10 (08.04.2009)
+ ---------------------------
+ 01. + New function: WMLESCAPE
+
+ Version 2.4.9 (02.04.2009)
+ --------------------------
+ 01. + New classes: SimpleVM, SimpleCompiler
+
+ Version 2.4.8 (18.03.2009)
+ --------------------------
+ 01. + New functions: CONCAT, SUBSTR, TRUNCATE, MB_SIZE, MB_TRUNCATE, MB_SUBSTR
+
+ Version 2.4.7 (16.03.2009)
+ --------------------------
+ 01. * New flags for iconv converter for class StringIconvOutputCollector
+ and function ICONV
+
+ Version 2.4.6 (07.03.2009)
+ --------------------------
+ 01. + New output data collector with charset recoding
+ 02. + New functions: MIN, MAX, AVG (Arithmetic, Geometric, Harmonic and Quadratic means)
+
+ Version 2.4.5 (04.03.2009)
+ --------------------------
+ 01. + New functions: RANDOM, LOG
+ 02. + MacOS port files
+
+ Version 2.4.4 (15.02.2009)
+ --------------------------
+ 01. + New functions: HMAC_MD5, URIESCAPE
+ 02. + New namespace/variable delimiter: `:` (<TMPL_var a:b.c.d>)
+ 03. ! EscapeJSONString empty string bug
+ 04. # Port to MacOS X
+ 05. - Removed CDT::operator+(std::string)
+
+ Version 2.4.3 (08.02.2009)
+ --------------------------
+ 01. + Port to Microsoft (R) Windows (TM)
+ (thanks to vsheveliov <vsheveliov@mail.ru>)
+
+ Version 2.4.2 (25.01.2009)
+ --------------------------
+ 01. * Fixed warnings in HashTable class
+ 02. * Fixed incorrect default message in VMException
+
+ Version 2.4.1 (18.01.2009)
+ --------------------------
+ 01. + New functions: JSON, JSESCAPE
+ 02. * Documentation for new features
+ 03. # Code cleanup
+
+ Version 2.4.0 (14.01.2009)
+ --------------------------
+ 01. + New operators: <TMPL_call & <TMPL_block
+ 02. # API changes
+
+ Version 2.3.11 (07.11.2008)
+ ---------------------------
+ 01. * JSON parser can now parse objects of all types
+
+ Version 2.3.10 (16.09.2008)
+ ---------------------------
+ 01. * Fixed "Use of uninitialised value of size 4" valgrind warning
+ 02. + Port to ALT Linux (thanks to Denis Klimov <zver@altlinux.org>)
+
+ Version 2.3.9 (12.09.2008)
+ --------------------------
+ 01. * Improvements in parsing Non-HTML templates
+
+ Version 2.3.8 (05.09.2008)
+ --------------------------
+ 01. + Port on SunOS 5.10 i386 and amd64
+ 02. * CDT datatype improvements
+
+ Version 2.3.7 (02.09.2008)
+ --------------------------
+ 01. + Nested loops from various data sources
+ 02. ! Fixes in error handling
+
+ Version 2.3.6 (11.08.2008)
+ --------------------------
+ 01. + <TMPL_loop accept now contextual variable __CONTENT__ as argument
+ 02. + New function: DEFINED
+ 03. ! Fixes in bytecode loader loader
+
+ Version 2.3.5 (07.08.2008)
+ --------------------------
+ 01. + New input data formats of CAST function:
+ "Octal", "Decimal" and "Hexadecimal"
+ 02. * Function DATE_FORMAT accept now strings as first argument
+
+ Version 2.3.4 (11.07.2008)
+ --------------------------
+ 01. * Debian Lenny bug fixes
+
+ Version 2.3.3 (24.06.2008)
+ --------------------------
+ 01. * Debug subsystem improvements
+
+ Version 2.3.2 (18.06.2008)
+ --------------------------
+ 01. + New methods of CDT class: Find and void PushBack(const CDT & oValue)
+ and Iterator Find(const std::string & sKey)
+
+ Version 2.3.1 (03.06.2008)
+ --------------------------
+ 01. * More information about errors in compiler
+ 02. * Support of empty arrays and objects in JSON
+
+ Version 2.3.0 (21.05.2008)
+ --------------------------
+ 01. + New debug subsystem
+ 02. ! Bug fix in __CONTENT__ cont. variable handling
+ 03. + New function: ERROR (only for debugging purposes)
+
+ Version 2.2.3 (14.05.2008)
+ --------------------------
+ 01. * New output format for FLOAT data type: %.*G
+ 02. + New function: NUM_FORMAT
+ 03. + C and C++-like comments in JSON file
+ 04. - Function ARRAY_SIZE renamed to SIZE
+
+ Version 2.2.2 (28.04.2008)
+ --------------------------
+ 01. ! JSON object parser
+ 02. ! If / Unless multibranch "Stack underflow"
+
+ Version 2.2.1 (23.04.2008)
+ --------------------------
+ 01. + New Function: ARRAY_SIZE
+
+ Version 2.2.0 (18.04.2008)
+ --------------------------
+ 01. + New incapsulated type for CDT class: POINTER
+ 02. + New methods: CDT::PushBack, CDT::GetPointer and CDT::GetObject<typename T>
+ 03. + Crossplatform format of executable bytecode file
+ 04. + Check of CRC32 checksum for bytecode file
+ 05. + New function: DEFINED. Check that value has not an UNDEF type.
+ 06. ! Fixed error in multiple logical && and || comparison
+
+ Version 2.1.2 (28.03.2008)
+ --------------------------
+ 01. + Renaming values in <TMPL_include 'filename.tmpl' map (value_in_include = value)>
+ Inverse to map (value : value_in_include) order of variables
+
+ Version 2.1.1 (19.03.2008)
+ --------------------------
+ 01. + Renaming values in <TMPL_include 'filename.tmpl' map (value : value_in_include)>
+
+ Version 2.1.0 (14.03.2008)
+ --------------------------
+ 01. + Arithmetic & string operations in operators
+ 02. + New function: CAST. Cast to specified type.
+ 03. # Up to 10% performance
+
+ Version 2.0.5 (02.03.2008)
+ --------------------------
+ 01. + Namespaces in variable names (<TMPL_var a.b.c>)
+ 02. ! Bug fixes
+
+ Version 2.0.4 (18.02.2008)
+ --------------------------
+ 01. + New contextual variable: __CONTENT__
+ 02. + Small API changes, see file VMDumper.hpp
+ 03. ! Linux RPATH bug fixes
+
+ Version 2.0.3 (15.02.2008)
+ --------------------------
+ 01. ! Fixed "stack underflow" error in <TMPL_unless UDF( ... )>
+ 02. + New functions: iconv and obj_dump
+ 03. + Russian documentation (in HTML)
+ 04. + New data collector class: StringOutputCollector
+
+ Version 2.0.2 (08.02.2008)
+ --------------------------
+ 01. ! Bug fixes
+ 02. + New functions: base64_encode, base64_decode and md5
+
+ Version 2.0.1 (04.02.2008)
+ --------------------------
+ 01. ! Fixed "stack underflow" error in <TMPL_if UDF( ... )>
+ 02. + New method CDT::RecursiveDump
+ 03. + FreeBSD port, Debian package, RPM spec file
+
+ Version 2.0.0 (15.01.2008)
+ --------------------------
+ 01. # Initial revision
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..8d9a58c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,917 @@
+#
+# CTPP - C++ Template Engine
+#
+# Cmake configuration file
+#
+PROJECT(CTPP)
+
+SET(CTPP_VERSION_MAJOR 2)
+SET(CTPP_VERSION_MINOR 8)
+SET(CTPP_VERSION_PATCH 3)
+
+SET(CTPP_VERSION "${CTPP_VERSION_MAJOR}.${CTPP_VERSION_MINOR}.${CTPP_VERSION_PATCH}")
+SET(CTPP_IDENT "Dzoraget")
+SET(CTPP_MASTER_SITE_URL "http://ctpp.havoc.ru/")
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
+
+OPTION(DEBUG_MODE "Enable debug output [default: OFF]" OFF)
+OPTION(ENABLE_OPTIMIZATION "Enable optimization [default: ON]" ON)
+OPTION(SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF)
+
+OPTION(ICONV_DISCARD_ILSEQ "Discard illegal sequence and continue (iconv) [default: ON]" ON)
+OPTION(ICONV_TRANSLITERATE "Enable transliteration in the conversion (iconv) [default: ON]" ON)
+
+# Build optimized code for following CPU (default i386)
+#SET(CPU_TUNE "i686")
+
+# Floating point precision for formatting output variables
+SET(CTPP_FLOAT_PRECISION 12)
+
+# Escape and tempoprary buffer size
+SET(CTPP_ESCAPE_BUFFER_LEN 1024)
+
+# Max. template recursion depth
+SET(CTPP_MAX_TEMPLATE_RECURSION_DEPTH 1024)
+
+# ################################################################################
+# Standard library
+#
+OPTION(MD5_SUPPORT "Enable md5 support [default: ON]" ON)
+OPTION(ICONV_SUPPORT "Enable iconv support [default: ON]" ON)
+
+# ################################################################################
+# Check Includes
+#
+INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckFunctionExists)
+INCLUDE(CheckSymbolExists)
+INCLUDE(CheckLibraryExists)
+
+CHECK_LIBRARY_EXISTS(m round "" HAVE_ROUND_FN)
+CHECK_LIBRARY_EXISTS(m roundl "" HAVE_ROUNDL_FN)
+
+CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H)
+CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H)
+CHECK_INCLUDE_FILES(sys/uio.h HAVE_SYS_UIO_H)
+
+CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H)
+CHECK_INCLUDE_FILES(math.h HAVE_MATH_H)
+CHECK_INCLUDE_FILES(stdio.h HAVE_STDIO_H)
+CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H)
+CHECK_INCLUDE_FILES(string.h HAVE_STRING_H)
+CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)
+CHECK_INCLUDE_FILES(time.h HAVE_TIME_H)
+CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
+CHECK_INCLUDE_FILES(sysexits.h HAVE_SYSEXITS_H)
+
+CHECK_CXX_SOURCE_COMPILES("#include <map>
+ namespace std { }
+ using namespace std;
+ int main(void)
+ {
+ map<int, int> m;
+ m.insert(pair<int, int>(1, 2));
+ m[2] = 3;
+ return 0;
+ }
+ " STL_MAP_CHECK)
+IF(NOT STL_MAP_CHECK)
+ MESSAGE(ERROR "!!!! STL map does not work!")
+ENDIF(NOT STL_MAP_CHECK)
+
+CHECK_CXX_SOURCE_COMPILES("#include <vector>
+ namespace std { }
+ using namespace std;
+ int main(void)
+ {
+ vector<int> v;
+ v.push_back(1);
+ return 0;
+ }
+ " STL_VECTOR_CHECK)
+IF(NOT STL_VECTOR_CHECK)
+ MESSAGE(ERROR "!!!! STL vector does not work!")
+ENDIF(NOT STL_VECTOR_CHECK)
+
+CHECK_CXX_SOURCE_COMPILES("#include <string>
+ using namespace std;
+ int main(void)
+ {
+ string s;
+ s.assign(\"Hello, World!\");
+ return 0;
+ }
+ " STL_STRING_CHECK)
+
+IF(NOT STL_STRING_CHECK)
+ MESSAGE(ERROR "!!!! STL string does not work!")
+ENDIF(NOT STL_STRING_CHECK)
+
+CHECK_CXX_SOURCE_COMPILES("#include <stdexcept>
+ namespace std { }
+ using namespace std;
+ int main(void)
+ {
+ try
+ {
+ throw logic_error(\"Ouch!\");
+ }
+ catch(exception &e)
+ {
+ return 0;
+ }
+ return 0;
+ }
+ " STL_STDEXCEPT_CHECK)
+
+IF(NOT STL_STDEXCEPT_CHECK)
+ MESSAGE(ERROR "!!!! STL logic_error/exception does not work!")
+ENDIF(NOT STL_STDEXCEPT_CHECK)
+
+CHECK_CXX_SOURCE_COMPILES("#include <vector>
+ int main(void)
+ {
+ vector<int> v;
+ v.push_back(1);
+ return 0;
+ }
+ " STL_VECTOR_NO_STD_CHECK)
+
+IF (STL_VECTOR_NO_STD_CHECK)
+ MESSAGE(STATUS "#### INFO: Using STL classes without STD namespace")
+ SET(NO_STL_STD_PREFIX "ON")
+ELSE (STL_VECTOR_NO_STD_CHECK)
+ MESSAGE(STATUS "#### INFO: Using STL classes with STD namespace")
+ENDIF (STL_VECTOR_NO_STD_CHECK)
+
+MESSAGE(STATUS "#### System name is: ${CMAKE_SYSTEM_NAME}")
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
+ MESSAGE(STATUS "#### Building for FreeBSD...")
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
+
+ SET(SKIP_ICONV_LIRARY "ON")
+
+ MESSAGE(STATUS "#### Building for Linux...")
+
+ IF("${SKIP_RELINK_RPATH}" MATCHES "ON")
+ SET(CMAKE_SKIP_RPATH TRUE)
+
+ MESSAGE(STATUS "#### Building for Linux...")
+ # skip the full RPATH for the build tree
+ SET(CMAKE_SKIP_BUILD_RPATH TRUE)
+
+ # when building, use the install RPATH already
+ # (so it doesn't need to relink when installing)
+ SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+
+ # the RPATH to be used when installing
+ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+
+ # add the automatically determined parts of the RPATH
+ # which point to directories outside the build tree to the install RPATH
+ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+ ENDIF("${SKIP_RELINK_RPATH}" MATCHES "ON")
+
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
+ SET(CMAKE_SKIP_RPATH FALSE)
+ SET(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
+ SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,-headerpad_max_install_names")
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS")
+ SET(SKIP_ICONV_LIRARY "ON")
+ MESSAGE(STATUS "#### Building for SunOS...")
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "SunOS")
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "HP-UX")
+ MESSAGE(STATUS "#### Building for HP-UX...")
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "HP-UX")
+
+SET(MD5_WITHOUT_OPENSSL "")
+#
+# MD5 library support
+#
+IF (${MD5_SUPPORT} MATCHES "ON")
+ IF (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ MESSAGE(STATUS "#### INFO: MD5 (Win32 CryptoAPI) hash function support enabled")
+ ELSE (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+ FIND_PATH(MD5_INCLUDE openssl/md5.h PATHS /opt/include
+ /usr/include
+ /usr/local/include
+ DOC "Path where the openssl header files can be found")
+
+ IF (MD5_INCLUDE)
+ INCLUDE_DIRECTORIES(${MD5_INCLUDE})
+
+ FIND_LIBRARY(MD5_LIBRARY NAMES crypto PATHS /lib
+ /opt/lib
+ /usr/lib
+ /usr/local/lib
+ DOC "Path where the openssl libraries can be found")
+ IF (MD5_LIBRARY)
+ SET(PROJECT_LIBS "${PROJECT_LIBS} crypto")
+ ELSE (MD5_LIBRARY)
+ MESSAGE(STATUS "#### ERROR: Cannot find libcrypto.so, aborting")
+ ENDIF (MD5_LIBRARY)
+
+ SET(MD5_SUPPORT "ON")
+
+ MESSAGE(STATUS "#### INFO: MD5 (openssl) hash function support enabled")
+
+ ELSE (MD5_INCLUDE)
+ # reset FIND_PATH
+ SET(MD5_INCLUDE)
+ FIND_PATH(MD5_INCLUDE md5.h PATHS /opt/include
+ /usr/include
+ /usr/local/include
+ DOC "Path where the openssl header files can be found")
+ IF (MD5_INCLUDE)
+ INCLUDE_DIRECTORIES(${MD5_INCLUDE})
+
+ FIND_LIBRARY(MD5_LIBRARY NAMES md5 PATHS /lib
+ /opt/lib
+ /usr/lib
+ /usr/local/lib
+ DOC "Path where the md5 libraries can be found")
+ IF (MD5_LIBRARY)
+ SET(PROJECT_LIBS "${PROJECT_LIBS} md5")
+ SET(MD5_SUPPORT "ON")
+ SET(MD5_WITHOUT_OPENSSL "ON")
+ MESSAGE(STATUS "#### INFO: MD5 (libmd5) hash function support enabled")
+ ELSE (MD5_LIBRARY)
+ MESSAGE(STATUS "#### ERROR: Cannot find md5.so, aborting")
+ ENDIF (MD5_LIBRARY)
+ ELSE (MD5_INCLUDE)
+ SET(MD5_SUPPORT "")
+ MESSAGE(STATUS "#### WARNING: MD5 hash function support disabled: md5.h not found")
+ ENDIF (MD5_INCLUDE)
+
+ ENDIF (MD5_INCLUDE)
+
+ ENDIF (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ENDIF (${MD5_SUPPORT} MATCHES "ON")
+
+#
+# Iconv converter support
+#
+IF (${ICONV_SUPPORT} MATCHES "ON")
+ FIND_PATH(ICONV_INCLUDE iconv.h PATHS /opt/include
+ /usr/include
+ /usr/local/include
+ DOC "Path where the iconv header files can be found")
+
+ IF (ICONV_INCLUDE)
+ INCLUDE_DIRECTORIES(${ICONV_INCLUDE})
+
+ IF (NOT "${SKIP_ICONV_LIRARY}" MATCHES "ON")
+ FIND_LIBRARY(ICONV_LIBRARY NAMES iconv PATHS /lib
+ /opt/lib
+ /usr/lib
+ /usr/local/lib
+ DOC "Path where the openssl libraries can be found")
+ IF (ICONV_LIBRARY)
+ SET(PROJECT_LIBS "${PROJECT_LIBS} iconv")
+ ELSE (ICONV_LIBRARY)
+ MESSAGE(STATUS "#### ERROR: Cannot find libiconv.so, aborting")
+ ENDIF (ICONV_LIBRARY)
+ ENDIF (NOT "${SKIP_ICONV_LIRARY}" MATCHES "ON")
+
+ SET(ICONV_SUPPORT "ON")
+ MESSAGE(STATUS "#### INFO: ICONV converter support enabled")
+
+ ELSE (ICONV_INCLUDE)
+
+ SET(ICONV_SUPPORT "")
+ MESSAGE(STATUS "#### WARNING: ICONV converter support disabled: iconv.h not found")
+
+ ENDIF (ICONV_INCLUDE)
+ENDIF (${ICONV_SUPPORT} MATCHES "ON")
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ FIND_LIBRARY(WS2_32_LIBRARY NAMES ws2_32)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+INCLUDE_DIRECTORIES(include)
+INCLUDE_DIRECTORIES(include/functions)
+
+IF("${CMAKE_COMPILER_IS_GNUCXX}" MATCHES "1")
+
+ SET(CMAKE_CXX_PARAMS " --param large-function-growth=5000 --param inline-unit-growth=600 -finline-limit=2000 ")
+
+ SET(CMAKE_CXX_WARN_FLAGS " -Wall -pedantic -Wno-long-long -Wno-inline -finline-functions ")
+
+ IF(ENABLE_OPTIMIZATION MATCHES "ON")
+ SET(CMAKE_CXX_FLAGS "${CXX_FLAGS} ${CMAKE_CXX_WARN_FLAGS} ${CMAKE_CXX_PARAMS} -O3 ")
+
+ IF (NOT "${CPU_TUNE}" STREQUAL "")
+ SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -mtune=${CPU_TUNE} ")
+ ENDIF (NOT "${CPU_TUNE}" STREQUAL "")
+
+ ELSE(ENABLE_OPTIMIZATION MATCHES "OFF")
+ SET(CMAKE_CXX_FLAGS "${CXX_FLAGS} ${CMAKE_CXX_WARN_FLAGS} ${CMAKE_CXX_PARAMS} ")
+ ENDIF(ENABLE_OPTIMIZATION MATCHES "ON")
+
+ IF(DEBUG_MODE MATCHES "ON")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g ")
+ SET(CMAKE_CXX_WARN_FLAGS "${CMAKE_CXX_WARN_FLAGS} -fprofile-arcs -ftest-coverage ")
+ ENDIF(DEBUG_MODE MATCHES "ON")
+
+ENDIF("${CMAKE_COMPILER_IS_GNUCXX}" MATCHES "1")
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+IF(ENABLE_OPTIMIZATION MATCHES "ON")
+ MESSAGE(STATUS "#### INFO: Optimized build mode enabled")
+ELSE(ENABLE_OPTIMIZATION MATCHES "OFF")
+ MESSAGE(STATUS "#### INFO: Optimized build mode disabled")
+ENDIF(ENABLE_OPTIMIZATION MATCHES "ON")
+
+IF(DEBUG_MODE MATCHES "ON")
+ MESSAGE(STATUS "#### ATTENTION: Debug mode enabled. Use this option only for testing!")
+ENDIF(DEBUG_MODE MATCHES "ON")
+
+# ################################################################################
+# Sources
+#
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CTPP2SysHeaders.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/include/CTPP2SysHeaders.h)
+#
+SET(LIBSRCS
+ src/CDT.cpp
+ src/CDTSortRoutines.cpp
+
+ src/CTPP2BitIndex.cpp
+ src/CTPP2Compiler.cpp
+ src/CTPP2DTOA.cpp
+ src/CTPP2Exception.cpp
+ src/CTPP2Error.cpp
+ src/CTPP2FileOutputCollector.cpp
+ src/CTPP2FileSourceLoader.cpp
+ src/CTPP2FileLogger.cpp
+ src/CTPP2HashTable.cpp
+ src/CTPP2JSONParser.cpp
+ src/CTPP2JSONFileParser.cpp
+ src/CTPP2Logger.cpp
+ src/CTPP2Parser.cpp
+ src/CTPP2ParserException.cpp
+ src/CTPP2SimpleCompiler.cpp
+ src/CTPP2SimpleVM.cpp
+ src/CTPP2Sprintf.cpp
+ src/CTPP2StringBuffer.cpp
+ src/CTPP2StaticData.cpp
+ src/CTPP2StaticText.cpp
+ src/CTPP2StreamOutputCollector.cpp
+ src/CTPP2StringOutputCollector.cpp
+ src/CTPP2StringIconvOutputCollector.cpp
+ src/CTPP2SyscallFactory.cpp
+ src/CTPP2Util.cpp
+ src/CTPP2VM.cpp
+ src/CTPP2VMArgStack.cpp
+ src/CTPP2VMCodeStack.cpp
+ src/CTPP2VMDebugInfo.cpp
+ src/CTPP2VMDumper.cpp
+ src/CTPP2VMException.cpp
+ src/CTPP2VMExecutable.cpp
+ src/CTPP2VMFileLoader.cpp
+ src/CTPP2VMMemoryCore.cpp
+ src/CTPP2VMOpcodeCollector.cpp
+ src/CTPP2VMSTDLib.cpp
+ src/CTPP2VMSyscall.cpp
+ src/CTPP2GetText.cpp
+
+ src/functions/FnAvg.cpp
+ src/functions/FnBase64Decode.cpp
+ src/functions/FnBase64Encode.cpp
+ src/functions/FnCast.cpp
+ src/functions/FnConcat.cpp
+ src/functions/FnContext.cpp
+ src/functions/FnDateFormat.cpp
+ src/functions/FnDefault.cpp
+ src/functions/FnDefined.cpp
+ src/functions/FnEmitter.cpp
+ src/functions/FnError.cpp
+ src/functions/FnFormParam.cpp
+ src/functions/FnGetText.cpp
+ src/functions/FnGetType.cpp
+ src/functions/FnHashKeys.cpp
+ src/functions/FnHMACMD5.cpp
+ src/functions/FnHTMLEscape.cpp
+ src/functions/FnHrefParam.cpp
+ src/functions/FnHostname.cpp
+ src/functions/FnIconv.cpp
+ src/functions/FnInSet.cpp
+ src/functions/FnInArray.cpp
+ src/functions/FnJSONEscape.cpp
+ src/functions/FnJSON.cpp
+ src/functions/FnList.cpp
+ src/functions/FnListElement.cpp
+ src/functions/FnLog.cpp
+ src/functions/FnMBSize.cpp
+ src/functions/FnMBSubstring.cpp
+ src/functions/FnMBTruncate.cpp
+ src/functions/FnMD5.cpp
+ src/functions/FnMax.cpp
+ src/functions/FnMin.cpp
+ src/functions/FnNumFormat.cpp
+ src/functions/FnObjDump.cpp
+ src/functions/FnRandom.cpp
+ src/functions/FnSize.cpp
+ src/functions/FnSprintf.cpp
+ src/functions/FnSubstring.cpp
+ src/functions/FnTruncate.cpp
+ src/functions/FnURIEscape.cpp
+ src/functions/FnURLEscape.cpp
+ src/functions/FnVersion.cpp
+ src/functions/FnWMLEscape.cpp
+ src/functions/FnXMLEscape.cpp
+ )
+
+# ################################################################################
+# Lib binary
+#
+ADD_LIBRARY(ctpp2-static STATIC ${LIBSRCS})
+SET_TARGET_PROPERTIES(ctpp2-static PROPERTIES OUTPUT_NAME ctpp2-st)
+SET_TARGET_PROPERTIES(ctpp2-static PROPERTIES LINKER_LANGUAGE CXX)
+
+ADD_LIBRARY(ctpp2 SHARED ${LIBSRCS})
+SET_TARGET_PROPERTIES(ctpp2 PROPERTIES OUTPUT_NAME ctpp2)
+SET_TARGET_PROPERTIES(ctpp2 PROPERTIES LINKER_LANGUAGE CXX)
+SET_TARGET_PROPERTIES(ctpp2 PROPERTIES VERSION ${CTPP_VERSION} SOVERSION ${CTPP_VERSION_MAJOR})
+IF(DEBUG_MODE MATCHES "ON")
+ SET_TARGET_PROPERTIES(ctpp2 PROPERTIES LINK_FLAGS -Wl,-lgcov)
+ENDIF(DEBUG_MODE MATCHES "ON")
+
+TARGET_LINK_LIBRARIES(ctpp2 ${MD5_LIBRARY} ${ICONV_LIBRARY} ${WS2_32_LIBRARY})
+
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+ SET_TARGET_PROPERTIES(ctpp2 PROPERTIES COMPILE_DEFINITIONS CTPP2_DLL)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+
+# ################################################################################
+# Exec binary
+#
+
+# CTPP Compiler
+ADD_EXECUTABLE(ctpp2c tests/CTPP2Compiler.cpp)
+TARGET_LINK_LIBRARIES(ctpp2c ctpp2)
+
+# CTPP2 Interpreter
+ADD_EXECUTABLE(ctpp2i tests/CTPP2Interpreter.cpp)
+TARGET_LINK_LIBRARIES(ctpp2i ctpp2)
+
+# CTPP2 virtual machine
+ADD_EXECUTABLE(ctpp2vm tests/CTPP2Emulator.cpp)
+TARGET_LINK_LIBRARIES(ctpp2vm ctpp2)
+
+# CTPP2 JSON parser
+ADD_EXECUTABLE(ctpp2json tests/CTPP2JSONParser.cpp)
+TARGET_LINK_LIBRARIES(ctpp2json ctpp2)
+
+# ################################################################################
+# Test suite
+#
+ENABLE_TESTING()
+
+ADD_EXECUTABLE(CDTTest tests/CDTTest.cpp)
+TARGET_LINK_LIBRARIES(CDTTest ctpp2)
+
+ADD_EXECUTABLE(CDTPerfTest tests/CDTPerfTest.cpp)
+TARGET_LINK_LIBRARIES(CDTPerfTest ctpp2)
+
+ADD_EXECUTABLE(BitIndexTest tests/BitIndexText.cpp)
+TARGET_LINK_LIBRARIES(BitIndexTest ctpp2)
+
+ADD_EXECUTABLE(HashTest tests/HashTest.cpp)
+TARGET_LINK_LIBRARIES(HashTest ctpp2)
+
+ADD_EXECUTABLE(StaticTextTest tests/StaticTextTest.cpp)
+TARGET_LINK_LIBRARIES(StaticTextTest ctpp2)
+
+#ADD_EXECUTABLE(StaticDataTest tests/StaticDataTest.cpp)
+#TARGET_LINK_LIBRARIES(StaticDataTest ctpp2)
+
+ADD_EXECUTABLE(VMArgStackTest tests/VMArgStackTest.cpp)
+TARGET_LINK_LIBRARIES(VMArgStackTest ctpp2)
+
+ADD_EXECUTABLE(VMCodeStackTest tests/VMCodeStackTest.cpp)
+TARGET_LINK_LIBRARIES(VMCodeStackTest ctpp2)
+
+ADD_EXECUTABLE(CTPP2VMTest tests/CTPP2VMTest.cpp)
+TARGET_LINK_LIBRARIES(CTPP2VMTest ctpp2)
+
+ADD_EXECUTABLE(CTPP2DTOATest tests/CTPP2DTOA.cpp)
+TARGET_LINK_LIBRARIES(CTPP2DTOATest ctpp2)
+
+ADD_EXECUTABLE(simple-compiler tests/SimpleCompilerTest.cpp)
+TARGET_LINK_LIBRARIES(simple-compiler ctpp2)
+
+ADD_EXECUTABLE(simple-vm tests/SimpleVMTest.cpp)
+TARGET_LINK_LIBRARIES(simple-vm ctpp2)
+
+ADD_TEST(CDT_performance_test CDTPerfTest)
+ADD_TEST(CDT_ops_test CDTTest)
+ADD_TEST(Bit_index_test BitIndexTest)
+ADD_TEST(Hash_test HashTest)
+ADD_TEST(Static_text_test StaticTextTest)
+#ADD_TEST(Static_data_test StaticDataTest)
+ADD_TEST(Argument_stack_test VMArgStackTest)
+ADD_TEST(Code_stack_test VMCodeStackTest)
+ADD_TEST(Create_executable_file CTPP2VMTest selftest.ct2)
+ADD_TEST(VM_self_test ctpp2vm selftest.ct2)
+SET_TESTS_PROPERTIES(VM_self_test PROPERTIES DEPENDS Create_executable_file)
+
+ADD_EXECUTABLE(CDT2JSONBenchmark benchmarks/CDT2JSON.cpp)
+TARGET_LINK_LIBRARIES(CDT2JSONBenchmark ctpp2)
+
+ADD_TEST(StreamLikeJsonDump_1 CDT2JSONBenchmark -t ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/data/test.json)
+ADD_TEST(StreamLikeJsonDump_2 CDT2JSONBenchmark -t ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/data/lebowski-bench.json)
+
+FIND_PROGRAM(DIFF_EXECUTABLE "diff" /usr/local/bin /usr/bin)
+
+ADD_TEST(Output_variables_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/output_variables.tmpl Output_variables.ct2)
+ADD_TEST(Output_variables_R ctpp2vm Output_variables.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Output_variables.out)
+SET_TESTS_PROPERTIES(Output_variables_R PROPERTIES DEPENDS Output_variables_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Output_variables_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/output_variables.out Output_variables.out)
+ SET_TESTS_PROPERTIES(Output_variables_D PROPERTIES DEPENDS Output_variables_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Comparisons_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/comparisons.tmpl Comparisons.ct2)
+ADD_TEST(Comparisons_R ctpp2vm Comparisons.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Comparisons.out)
+SET_TESTS_PROPERTIES(Comparisons_R PROPERTIES DEPENDS Comparisons_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Comparisons_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/comparisons.out Comparisons.out)
+ SET_TESTS_PROPERTIES(Comparisons_D PROPERTIES DEPENDS Comparisons_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Arith_ops_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/arith_ops.tmpl Arith_ops.ct2)
+ADD_TEST(Arith_ops_R ctpp2vm Arith_ops.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Arith_ops.out)
+SET_TESTS_PROPERTIES(Arith_ops_R PROPERTIES DEPENDS Arith_ops_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Arith_ops_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/arith_ops.out Arith_ops.out)
+ SET_TESTS_PROPERTIES(Arith_ops_D PROPERTIES DEPENDS Arith_ops_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Formulas_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/formulas.tmpl Formulas.ct2)
+ADD_TEST(Formulas_R ctpp2vm Formulas.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Formulas.out)
+SET_TESTS_PROPERTIES(Formulas_R PROPERTIES DEPENDS Formulas_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Formulas_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/formulas.out Formulas.out)
+ SET_TESTS_PROPERTIES(Formulas_D PROPERTIES DEPENDS Formulas_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Functions_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/functions.tmpl Functions.ct2)
+ADD_TEST(Functions_R ctpp2vm Functions.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Functions.out)
+SET_TESTS_PROPERTIES(Functions_R PROPERTIES DEPENDS Functions_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Functions_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/functions.out Functions.out)
+ SET_TESTS_PROPERTIES(Functions_D PROPERTIES DEPENDS Functions_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Function_random_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_random.tmpl Function_random.ct2)
+ADD_TEST(Function_random_R ctpp2vm Function_random.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json)
+SET_TESTS_PROPERTIES(Function_random_R PROPERTIES DEPENDS Function_random_C)
+
+ADD_TEST(Function_obj_dump_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_obj_dump.tmpl Function_obj_dump.ct2)
+ADD_TEST(Function_obj_dump_R ctpp2vm Function_obj_dump.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json)
+SET_TESTS_PROPERTIES(Function_random_R PROPERTIES DEPENDS Function_random_C)
+
+ADD_TEST(Function_hostname_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_hostname.tmpl Function_hostname.ct2)
+ADD_TEST(Function_hostname_R ctpp2vm Function_hostname.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json)
+SET_TESTS_PROPERTIES(Function_hostname_R PROPERTIES DEPENDS Function_hostname_C)
+
+IF (${MD5_SUPPORT} MATCHES "ON")
+ ADD_TEST(Function_md5_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_md5.tmpl Function_md5.ct2)
+ ADD_TEST(Function_md5_R ctpp2vm Function_md5.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Function_md5.out)
+ SET_TESTS_PROPERTIES(Function_md5_R PROPERTIES DEPENDS Function_md5_C)
+ IF (DIFF_EXECUTABLE)
+ ADD_TEST(Function_md5_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_md5.out Function_md5.out)
+ SET_TESTS_PROPERTIES(Function_md5_D PROPERTIES DEPENDS Function_md5_R)
+ ENDIF (DIFF_EXECUTABLE)
+ENDIF (${MD5_SUPPORT} MATCHES "ON")
+
+IF (${ICONV_SUPPORT} MATCHES "ON")
+ ADD_TEST(Function_iconv_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_iconv.tmpl Function_iconv.ct2)
+ ADD_TEST(Function_iconv_R ctpp2vm Function_iconv.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Function_iconv.out)
+ SET_TESTS_PROPERTIES(Function_iconv_R PROPERTIES DEPENDS Function_iconv_C)
+ IF (DIFF_EXECUTABLE)
+ ADD_TEST(Function_iconv_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_iconv.out Function_iconv.out)
+ SET_TESTS_PROPERTIES(Function_iconv_D PROPERTIES DEPENDS Function_iconv_R)
+ ENDIF (DIFF_EXECUTABLE)
+ENDIF (${ICONV_SUPPORT} MATCHES "ON")
+
+ADD_TEST(Function_gettext_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_gettext.tmpl Function_gettext.ct2)
+ADD_TEST(Function_gettext_R ctpp2vm Function_gettext.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Function_gettext.out ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/test.mo)
+SET_TESTS_PROPERTIES(Function_gettext_R PROPERTIES DEPENDS Function_gettext_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Function_gettext_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/function_gettext.out Function_gettext.out)
+ SET_TESTS_PROPERTIES(Function_gettext_D PROPERTIES DEPENDS Function_gettext_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Loops_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/loops.tmpl Loops.ct2)
+ADD_TEST(Loops_R ctpp2vm Loops.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Loops.out)
+SET_TESTS_PROPERTIES(Loops_R PROPERTIES DEPENDS Loops_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Loops_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/loops.out Loops.out)
+ SET_TESTS_PROPERTIES(Loops_D PROPERTIES DEPENDS Loops_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Lebowski_bench_foreach_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/lebowski-bench-foreach.tmpl lebowski-bench-foreach.ct2)
+ADD_TEST(Lebowski_bench_foreach_R ctpp2vm lebowski-bench-foreach.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/lebowski-bench.json lebowski-bench-foreach.out)
+SET_TESTS_PROPERTIES(Lebowski_bench_foreach_R PROPERTIES DEPENDS Lebowski_bench_foreach_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Lebowski_bench_foreach_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/lebowski-bench-foreach.out lebowski-bench-foreach.out)
+ SET_TESTS_PROPERTIES(Lebowski_bench_foreach_D PROPERTIES DEPENDS Lebowski_bench_foreach_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(ArrayAndHashAccess_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/array_and_hash_access.tmpl array_and_hash_access.ct2)
+ADD_TEST(ArrayAndHashAccess_R ctpp2vm array_and_hash_access.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/array_and_hash_access.json array_and_hash_access.out)
+SET_TESTS_PROPERTIES(ArrayAndHashAccess_R PROPERTIES DEPENDS ArrayAndHashAccess_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(ArrayAndHashAccess_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/array_and_hash_access.out array_and_hash_access.out)
+ SET_TESTS_PROPERTIES(ArrayAndHashAccess_D PROPERTIES DEPENDS ArrayAndHashAccess_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(DTOA CTPP2DTOATest)
+
+ADD_TEST(Verbose_mode_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/verbose_mode.tmpl Verbose_mode.ct2)
+ADD_TEST(Verbose_mode_R ctpp2vm Verbose_mode.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Verbose_mode.out)
+SET_TESTS_PROPERTIES(Verbose_mode_R PROPERTIES DEPENDS Verbose_mode_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Verbose_mode_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/verbose_mode.out Verbose_mode.out)
+ SET_TESTS_PROPERTIES(Verbose_mode_D PROPERTIES DEPENDS Verbose_mode_R)
+ENDIF (DIFF_EXECUTABLE)
+
+ADD_TEST(Calls_C ctpp2c ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/calls.tmpl Calls.ct2)
+ADD_TEST(Calls_R ctpp2vm Calls.ct2 ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/testdata.json Calls.out)
+SET_TESTS_PROPERTIES(Calls_R PROPERTIES DEPENDS Calls_C)
+IF (DIFF_EXECUTABLE)
+ ADD_TEST(Calls_D ${DIFF_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/calls.out Calls.out)
+ SET_TESTS_PROPERTIES(Calls_D PROPERTIES DEPENDS Calls_R)
+ENDIF (DIFF_EXECUTABLE)
+
+FIND_PROGRAM(RST2HTML_EXECUTABLE "rst2html" /usr/local/bin /usr/bin)
+IF (RST2HTML_EXECUTABLE)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT template_language.html
+ COMMAND ${RST2HTML_EXECUTABLE} --stylesheet-path=${CMAKE_CURRENT_SOURCE_DIR}/doc/bootstrap.css,${CMAKE_CURRENT_SOURCE_DIR}/doc/colors.css -l en ${CMAKE_CURRENT_SOURCE_DIR}/doc/template_language.rst ${CMAKE_CURRENT_BINARY_DIR}/template_language.html
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/doc/template_language.rst
+ )
+ ADD_CUSTOM_TARGET(doc ALL DEPENDS template_language.html)
+ENDIF (RST2HTML_EXECUTABLE)
+
+# Install Headers
+INSTALL(FILES include/CDT.hpp
+ include/CDTSortRoutines.hpp
+ include/CTPP2BitIndex.hpp
+ include/CTPP2CharIterator.hpp
+ include/CTPP2Compiler.hpp
+ include/CTPP2DTOA.hpp
+ include/CTPP2Exception.hpp
+ include/CTPP2Error.hpp
+ include/CTPP2ErrorCodes.h
+ include/CTPP2FileLogger.hpp
+ include/CTPP2FileOutputCollector.hpp
+ include/CTPP2FileSourceLoader.hpp
+ include/CTPP2GetText.hpp
+ include/CTPP2GlobalDefines.h
+ include/CTPP2HashTable.hpp
+ include/CTPP2JSONFileParser.hpp
+ include/CTPP2JSONParser.hpp
+ include/CTPP2Logger.hpp
+ include/CTPP2OutputCollector.hpp
+ include/CTPP2Parser.hpp
+ include/CTPP2ParserException.hpp
+ include/CTPP2SimpleCompiler.hpp
+ include/CTPP2SimpleVM.hpp
+ include/CTPP2SourceLoader.hpp
+ include/CTPP2Sprintf.hpp
+ include/CTPP2StaticData.hpp
+ include/CTPP2StaticText.hpp
+ include/CTPP2StreamOutputCollector.hpp
+ include/CTPP2StringBuffer.hpp
+ include/CTPP2StringIconvOutputCollector.hpp
+ include/CTPP2StringOutputCollector.hpp
+ include/CTPP2SymbolTable.hpp
+ include/CTPP2Syntax.h
+ include/CTPP2SysHeaders.h
+ include/CTPP2SysTypes.h
+ include/CTPP2SyscallFactory.hpp
+ include/CTPP2Types.h
+ include/CTPP2Util.hpp
+ include/CTPP2VM.hpp
+ include/CTPP2VMArgStack.hpp
+ include/CTPP2VMCodeStack.hpp
+ include/CTPP2VMDebugInfo.hpp
+ include/CTPP2VMDumper.hpp
+ include/CTPP2VMException.hpp
+ include/CTPP2VMExecutable.hpp
+ include/CTPP2VMFileLoader.hpp
+ include/CTPP2VMInstruction.hpp
+ include/CTPP2VMLoader.hpp
+ include/CTPP2VMMemoryCore.hpp
+ include/CTPP2VMOpcodeCollector.hpp
+ include/CTPP2VMOpcodes.h
+ include/CTPP2VMSTDLib.hpp
+ include/CTPP2VMStackException.hpp
+ include/CTPP2VMSyscall.hpp
+ include/STLException.hpp
+ include/STLFunctional.hpp
+ include/STLIosfwd.hpp
+ include/STLMap.hpp
+ include/STLOstream.hpp
+ include/STLPair.hpp
+ include/STLString.hpp
+ include/STLVector.hpp
+ DESTINATION include/ctpp2
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ GROUP_READ
+ WORLD_READ)
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+
+SET(CTPP_COMPILER_HELPER "@echo off
+rem
+rem CTPP2 Configurator for ${CMAKE_SYSTEM_NAME}
+rem
+
+set PREFIX=\"${CMAKE_INSTALL_PREFIX}\"
+set CXXFLAGS=\"${CMAKE_CXX_FLAGS}\"
+set MAKE=\"${CMAKE_MAKE_PROGRAM}\"
+set CC=\"${CMAKE_C_COMPILER}\"
+set CXX=\"${CMAKE_CXX_COMPILER}\"
+set INCLUDE=\"${ICONV_INCLUDE} ${MD5_INCLUDE} ${CMAKE_INSTALL_PREFIX}/include/ctpp2\"
+set INCLUDE2=\"-I${ICONV_INCLUDE} -I${MD5_INCLUDE} -I${CMAKE_INSTALL_PREFIX}/include/ctpp2\"
+set LIBS=\"${CMAKE_INSTALL_PREFIX}/lib\"
+set VERSION=\"${CTPP_VERSION}\"
+
+if \"%1\" == \"--version\" echo %VERSION% & goto end
+if \"%1\" == \"--flags\" echo %FLAGS% & goto end
+if \"%1\" == \"--cc\" echo %CC% & goto end
+if \"%1\" == \"--cxx\" echo %CXX% & goto end
+if \"%1\" == \"--make\" echo %MAKE% & goto end
+if \"%1\" == \"--libs\" echo %LIBS% & goto end
+if \"%1\" == \"--includes2\" echo %INCLUDE2% & goto end
+if \"%1\" == \"--includes\" echo %INCLUDE% & goto end
+
+
+echo Usage:
+echo ctpp2-config [--flags] [--cc] [--cxx] [--make] [--libs] [--includes] [--version]
+echo ... [see below for complete flag list]
+echo.
+echo --version displays the ctpp2 version number
+echo --flags displays C++ compiler flags
+echo --cc displays executable name of C compiler
+echo --cxx displays executable name of C++ compiler
+echo --make displays executable name of make
+echo --libs displays list of libraries
+echo --includes displays list of include dirs
+echo --includes2 displays list of include dirs with '-I' prefixes
+echo.
+
+:end
+")
+
+ INSTALL(TARGETS ctpp2-static DESTINATION lib${LIB_SUFFIX})
+
+ INSTALL(TARGETS ctpp2 DESTINATION .)
+
+ FILE(WRITE ctpp2-config.cmd ${CTPP_COMPILER_HELPER})
+
+ # Install binaries
+ INSTALL(FILES ctpp2-config.cmd
+ DESTINATION .)
+
+ INSTALL(TARGETS ctpp2vm
+ ctpp2c
+ ctpp2i
+ ctpp2json
+ DESTINATION .)
+
+ELSE ("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+# Install library
+INSTALL(TARGETS ctpp2 ctpp2-static DESTINATION lib${LIB_SUFFIX})
+
+# Install Manpages
+INSTALL(FILES
+ man/ctpp2-config.1
+ man/ctpp2c.1
+ man/ctpp2i.1
+ man/ctpp2json.1
+ man/ctpp2vm.1
+ DESTINATION man/man1
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ GROUP_READ
+ WORLD_READ)
+
+IF(RST2HTML_EXECUTABLE)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/template_language.html
+ DESTINATION share/doc
+ PERMISSIONS OWNER_READ OWNER_WRITE
+ GROUP_READ
+ WORLD_READ)
+ENDIF(RST2HTML_EXECUTABLE)
+
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+
+
+IF("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+
+
+ELSE("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+SET(CTPP_COMPILER_HELPER "#!/bin/sh
+#
+# CTPP2 Configurator
+#
+PREFIX=${CMAKE_INSTALL_PREFIX}
+CXXFLAGS=\"${CMAKE_CXX_FLAGS}\"
+MAKE=${CMAKE_MAKE_PROGRAM}
+CC=${CMAKE_C_COMPILER}
+CXX=${CMAKE_CXX_COMPILER}
+INCLUDE=\"${ICONV_INCLUDE} ${MD5_INCLUDE} ${CMAKE_INSTALL_PREFIX}/include/ctpp2\"
+INCLUDE2=\"-I${ICONV_INCLUDE} -I${MD5_INCLUDE} -I${CMAKE_INSTALL_PREFIX}/include/ctpp2\"
+LIBS=\"${CMAKE_INSTALL_PREFIX}/lib\"
+VERSION=\"${CTPP_VERSION}\"
+
+if test \"x$1\" = \"x\"\; then
+ echo \"Usage:\"
+ echo \" ctpp2-config [--flags] [--cc] [--cxx] [--make] [--libs] [--includes] [--version]\"
+ echo \" ... [see below for complete flag list]\"
+ echo \"\"
+ echo \" --version displays the ctpp2 version number\"
+ echo \" --flags displays C++ compiler flags\"
+ echo \" --cc displays executable name of C compiler\"
+ echo \" --cxx displays executable name of C++ compiler\"
+ echo \" --make displays executable name of make\"
+ echo \" --libs displays list of libraries\"
+ echo \" --includes displays list of include dirs\"
+ echo \" --includes2 displays list of include dirs with '-I' prefixes\"
+ echo \"\"
+else
+ while test \"x$done\" = \"x\" -a \"x$1\" != \"x\"\; do
+ case $1 in
+ --version*)
+ echo \${VERSION}
+ \;\;
+
+ --flags*)
+ echo \${CXXFLAGS}
+ \;\;
+
+ --cc*)
+ echo \${CC}
+ \;\;
+
+ --cxx*)
+ echo \${CXX}
+ \;\;
+
+ --make*)
+ echo \${MAKE}
+ \;\;
+
+ --libs*)
+ echo \${LIBS}
+ \;\;
+
+ --includes2*)
+ echo \${INCLUDE2}
+ \;\;
+
+ --includes*)
+ echo \${INCLUDE}
+ \;\;
+
+ esac
+ shift
+ done
+fi
+")
+
+ # Write file
+ FILE(WRITE ctpp2-config ${CTPP_COMPILER_HELPER})
+
+ # Install binaries
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/ctpp2vm
+ ${CMAKE_CURRENT_BINARY_DIR}/ctpp2c
+ ${CMAKE_CURRENT_BINARY_DIR}/ctpp2i
+ ${CMAKE_CURRENT_BINARY_DIR}/ctpp2json
+ ctpp2-config
+ DESTINATION bin
+ PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ)
+
+ENDIF("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
+
+# End.
diff --git a/CTPP2SysHeaders.h.cmake b/CTPP2SysHeaders.h.cmake
new file mode 100644
index 0000000..257eaaf
--- /dev/null
+++ b/CTPP2SysHeaders.h.cmake
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SysHeaders.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SYS_HEADERS_H__
+#define _CTPP2_SYS_HEADERS_H__ 1
+
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+#cmakedefine HAVE_SYS_TIME_H 1
+
+#cmakedefine HAVE_SYS_UIO_H 1
+
+#cmakedefine HAVE_FCNTL_H 1
+
+#cmakedefine HAVE_MATH_H 1
+
+#cmakedefine HAVE_STDIO_H 1
+
+#cmakedefine HAVE_STDLIB_H 1
+
+#cmakedefine HAVE_STRING_H 1
+
+#cmakedefine HAVE_STRINGS_H 1
+
+#cmakedefine HAVE_TIME_H 1
+
+#cmakedefine HAVE_UNISTD_H 1
+
+#cmakedefine HAVE_SYSEXITS_H 1
+
+#cmakedefine DEBUG_MODE 1
+
+#cmakedefine NO_STL_STD_NS_PREFIX 1
+
+#cmakedefine GETTEXT_SUPPORT 1
+
+#cmakedefine MD5_SUPPORT 1
+
+#cmakedefine MD5_WITHOUT_OPENSSL 1
+
+#cmakedefine CTPP_FLOAT_PRECISION ${CTPP_FLOAT_PRECISION}
+
+#cmakedefine CTPP_ESCAPE_BUFFER_LEN ${CTPP_ESCAPE_BUFFER_LEN}
+
+#cmakedefine CTPP_MAX_TEMPLATE_RECURSION_DEPTH ${CTPP_MAX_TEMPLATE_RECURSION_DEPTH}
+
+#cmakedefine ICONV_SUPPORT 1
+
+#cmakedefine ICONV_DISCARD_ILSEQ 1
+
+#cmakedefine ICONV_TRANSLITERATE 1
+
+#cmakedefine CTPP_VERSION "${CTPP_VERSION}"
+#cmakedefine CTPP_IDENT "${CTPP_IDENT}"
+#cmakedefine CTPP_MASTER_SITE_URL "${CTPP_MASTER_SITE_URL}"
+
+#cmakedefine THROW_EXCEPTION_IN_COMPARATORS 1
+
+#endif /* _CTPP2_SYS_HEADERS_H__ */
+/* End. */
diff --git a/ClearPackage.cmd b/ClearPackage.cmd
new file mode 100644
index 0000000..700d87c
--- /dev/null
+++ b/ClearPackage.cmd
@@ -0,0 +1,21 @@
+@echo off
+
+if exist Makefile nmake clean
+
+
+
+for /F %%a in ('dir /AD /B *.dir') do if exist %%a rmdir /S /Q %%a
+for %%a in (CMakeFiles Testing doc\html) do if exist %%a rmdir /S /Q %%a
+
+
+for %%a in (CMakeCache.txt DartTestfile.txt Makefile cmake_install.cmake progress.make *.ftss data\*.ftss include\CTPP2SysHeaders.h *.ct2 ctpp2-config.cmd CTestTestfile.cmake) do (
+ if exist %%a del /F /Q %%a
+)
+
+for %%a in (*.cmake) do if not "%%a" == "CTPP2SysHeaders.h.cmake" del %%a
+
+for %%a in (*.rule *.dsp *.dsw *.vcproj *.sln *.vcproj.*.user *.ncb *.ilk *.exp *.suo *.manifest *.manifest.res *.resource.txt) do (
+ if exist %%a del /F /Q %%a
+)
+
+del /F /Q /AH *.suo 2>nul
diff --git a/ClearPackage.sh b/ClearPackage.sh
new file mode 100755
index 0000000..a466b2e
--- /dev/null
+++ b/ClearPackage.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ -f Makefile ]; then
+ make clean
+fi
+
+rm -fr CMakeCache.txt CMakeFiles DartTestfile.txt Makefile Testing cmake_install.cmake progress.make include/CTPP2SysHeaders.h doc/html *.ct2 install_manifest.txt build-stamp configure-stamp debian/ctpp2 debian/ctpp2-dev debian/tmp debian/ctpp2.postinst.debhelper debian/ctpp2.postrm.debhelper debian/ctpp2.substvars debian/dirs debian/files ctpp2-config CTestTestfile.cmake ctpp2-config *.out template_language.html
diff --git a/CodeStyle b/CodeStyle
new file mode 100644
index 0000000..4afd43a
--- /dev/null
+++ b/CodeStyle
@@ -0,0 +1,145 @@
+CodeStyle -- CTPP2 source file style guide. Based on FreeBSD style(9).
+
+This file describes coding rules for CTPP2 header and source files.
+This is also a preferred style for source code of all applications written in C++.
+
+0. The copyright header should be a multi-line comment, with the first line
+of the comment having a dash after the star like so:
+
+ /*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Long, boring license goes here, but redacted for brevity
+ */
+
+
+1. All classes, structures and data fields
+ MUST have auto-documentation in doxygen style
+ /**
+ @doxytag
+ @brief Auto-documentation for doxygen
+ */
+ class SomeClass
+ {
+ ....
+ };
+
+ /** @brief Some Variable */
+ INT_32 iSomeVariable;
+
+
+2. Important and BIG comments SHOULD be in C-style
+
+ /*
+ * VERY Important single-line comment.
+ */
+
+ /*
+ * VERY BIG multi-line comment.
+ *
+ * blah-blah blah-blah blah-blah blah-blah blah-blah
+ * blah-blah blah-blah blah-blah blah-blah blah-blah
+ * blah-blah blah-blah blah-blah blah-blah blah-blah
+ */
+
+
+3. Single-line comments SHOULD be in C++ Style
+
+ // Single-line comment
+
+4. NEVER use "standard" types. Use instead platform-independent
+ types, described in CTPP2Types.h
+
+5. If it is possible, don't use boost and other foreign libraries.
+ Boost, etc - good and powerful libraries, BUT non-compartible in most
+ architectures and compilers.
+
+6. All platform-dependent typedefs MUST be placed into file Types.h
+
+7. All defines MUST be placed into file GlobalDefines.h
+
+8. Enumeration values are all uppercase. Enumeration name SHOULD start from lowercase 'e'
+ enum eMyEnum { ONE, TWO .... }
+
+ In declarations, do not put any whitespace between asterisks and adjacent
+ tokens, except for tokens that are identifiers related to types.
+
+9. Names of structures and classes are in mixed case, instances delimited by changed case.
+ struct FooBar
+ {
+ INT_32 some_field;
+ INT_64 other_field;
+ };
+
+9. When declaring variables in structures, declare them sorted by use, then
+ by size (largest to smallest), and then in alphabetical order.
+ Variables in structures all lowercase, instances delimited by understrike '_'
+
+10. When declaring variables in classes, declare them sorted by use, then
+ by size (largest to smallest), and then in alphabetical order.
+ Variables in classes are in mixed case. Instances delimited by changed case.
+
+ class BarBaz
+ {
+ public:
+ BarBaz();
+ ~BarBaz() throw();
+ private:
+ INT_32 iSomeVariable;
+ INT_64 iOtherVariable;
+ };
+
+11. All destructors SHOULD have empty list of exceptions.
+ class BarBaz
+ {
+ public:
+ ~BarBaz() throw();
+ };
+
+12. NEVER use public variables in classes.
+ NEVER use private and protected variables in structures
+
+13. NEVER use assert macros.
+ Assert, in depends of compiler flags changes behavior of programm.
+ Therefore, programm that compiled with debug option IS NOT the same
+ as a programm without them.
+ Use instead exceptions.
+
+14. Do not use "!" for tests unless it is a boolean, e.g. use
+ if (*p == '\0')
+ not:
+ if (!*p)
+
+15. All branches and loops MUST use braces (`{' and `}'), e.g. use
+ for (;;) { stmt; }
+ not:
+ for (;;) stmt;
+
+16. For infinite loops use for (;;), not while(true)
+
+17. Indentation is an tab (0x09) and space (0x20).
+ Use tabs ONLY in string prefixies, use spaces ONLY in string suffixes, e.g. use
+ class BarBaz
+ {
+ >> INT_32........iVariable;
+ public:
+ >> inline BarBaz()
+ >> {
+ >> >> stmt;
+ >> }
+ };
+
+ struct FooBar
+ {
+ >> INT_32........var_1;
+ >> INT_32........var_2;
+ >> CCHAR_P.......some_data;
+ };
+
+ where `.' - space and `>>' - tab
+
+
+18. Sources MUST be compiled without warnings with "-Wall -pedantic -wno-long-long"
+ GNU gcc code checker flags or its analogs in other compilers.
+
+19. Examples: examples/code/Skel.*
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..f2d4d18
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,181 @@
+# Doxyfile 1.2.15
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME = "CTPP2 Template Engine"
+PROJECT_NUMBER = 2.6
+OUTPUT_DIRECTORY = doc
+OUTPUT_LANGUAGE = English
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+BUILTIN_STL_SUPPORT = YES
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH = *source
+INTERNAL_DOCS = YES
+STRIP_CODE_COMMENTS = NO
+CASE_SENSE_NAMES = YES
+SHORT_NAMES = YES
+HIDE_SCOPE_NAMES = YES
+VERBATIM_HEADERS = YES
+SHOW_INCLUDE_FILES = YES
+JAVADOC_AUTOBRIEF = YES
+INHERIT_DOCS = YES
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = NO
+DISTRIBUTE_GROUP_DOC = NO
+TAB_SIZE = 8
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+ALIASES =
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+SHOW_USED_FILES = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = NO
+WARN_IF_UNDOCUMENTED = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = .
+FILE_PATTERNS = *.c \
+ *.h \
+ *.cpp \
+ *.hpp \
+ *.tcc
+
+EXCLUDE = tests/ \
+ examples/
+
+RECURSIVE = YES
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_SOURCE_FILES = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = YES
+INLINE_SOURCES = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 3
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER = ./doc/doxytmpl/header.html
+HTML_FOOTER = ./doc/doxytmpl/footer.html
+HTML_STYLESHEET =
+HTML_ALIGN_MEMBERS = YES
+GENERATE_HTMLHELP = NO
+GENERATE_CHI = NO
+BINARY_TOC = NO
+TOC_EXPAND = NO
+DISABLE_INDEX = NO
+ENUM_VALUES_PER_LINE = 3
+GENERATE_TREEVIEW = NO
+TREEVIEW_WIDTH = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH = include
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = __FreeBSD__
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = NO
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+HAVE_DOT = YES
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+TEMPLATE_RELATIONS = YES
+HIDE_UNDOC_RELATIONS = YES
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+GRAPHICAL_HIERARCHY = YES
+DOT_IMAGE_FORMAT = png
+DOT_PATH =
+DOTFILE_DIRS =
+MAX_DOT_GRAPH_WIDTH = 3000
+MAX_DOT_GRAPH_HEIGHT = 2000
+GENERATE_LEGEND = YES
+SHOW_DIRECTORIES = NO
+DOT_CLEANUP = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE = NO
+
diff --git a/FreeBSD/textproc/ctpp2/Makefile b/FreeBSD/textproc/ctpp2/Makefile
new file mode 100644
index 0000000..061e94f
--- /dev/null
+++ b/FreeBSD/textproc/ctpp2/Makefile
@@ -0,0 +1,25 @@
+# New ports collection makefile for: ctpp2
+# Date created: 25 Jan 2008
+# Whom: reki@reki.ru (Andrei V. Shetuhin)
+#
+# $FreeBSD: ports/textproc/ctpp2/Makefile,v 1.27 2010/08/04 07:44:02 lwhsu Exp $
+#
+
+PORTNAME= ctpp2
+PORTVERSION= 2.8.3
+CATEGORIES= textproc devel
+MASTER_SITES= http://ctpp.havoc.ru/download/
+
+MAINTAINER= reki@reki.ru
+COMMENT= C++ library to use templates in C/C++ projects, version 2
+
+USE_CMAKE= yes
+USE_LDCONFIG= yes
+USE_GETTEXT= yes
+USE_ICONV= yes
+
+PLIST_SUB+= PORTVERSION=${PORTVERSION}
+
+MAN1= ctpp2c.1 ctpp2vm.1 ctpp2i.1 ctpp2json.1 ctpp2-config.1
+
+.include <bsd.port.mk>
diff --git a/FreeBSD/textproc/ctpp2/pkg-descr b/FreeBSD/textproc/ctpp2/pkg-descr
new file mode 100644
index 0000000..f8d9566
--- /dev/null
+++ b/FreeBSD/textproc/ctpp2/pkg-descr
@@ -0,0 +1,7 @@
+This is a simple set of C++ classes which allow to use
+templates like perl modules Template Toolkit and HTML::Template::Pro
+Version 2.
+
+WWW: http://ctpp.havoc.ru/
+
+- reki@reki.ru
diff --git a/FreeBSD/textproc/ctpp2/pkg-plist b/FreeBSD/textproc/ctpp2/pkg-plist
new file mode 100644
index 0000000..3ad1b9f
--- /dev/null
+++ b/FreeBSD/textproc/ctpp2/pkg-plist
@@ -0,0 +1,72 @@
+bin/ctpp2-config
+bin/ctpp2c
+bin/ctpp2i
+bin/ctpp2json
+bin/ctpp2vm
+include/ctpp2/CDT.hpp
+include/ctpp2/CDTSortRoutines.hpp
+include/ctpp2/CTPP2BitIndex.hpp
+include/ctpp2/CTPP2CharIterator.hpp
+include/ctpp2/CTPP2Compiler.hpp
+include/ctpp2/CTPP2DTOA.hpp
+include/ctpp2/CTPP2Exception.hpp
+include/ctpp2/CTPP2Error.hpp
+include/ctpp2/CTPP2ErrorCodes.h
+include/ctpp2/CTPP2FileLogger.hpp
+include/ctpp2/CTPP2FileOutputCollector.hpp
+include/ctpp2/CTPP2FileSourceLoader.hpp
+include/ctpp2/CTPP2GetText.hpp
+include/ctpp2/CTPP2GlobalDefines.h
+include/ctpp2/CTPP2HashTable.hpp
+include/ctpp2/CTPP2JSONFileParser.hpp
+include/ctpp2/CTPP2JSONParser.hpp
+include/ctpp2/CTPP2Logger.hpp
+include/ctpp2/CTPP2OutputCollector.hpp
+include/ctpp2/CTPP2Parser.hpp
+include/ctpp2/CTPP2ParserException.hpp
+include/ctpp2/CTPP2SimpleCompiler.hpp
+include/ctpp2/CTPP2SimpleVM.hpp
+include/ctpp2/CTPP2SourceLoader.hpp
+include/ctpp2/CTPP2Sprintf.hpp
+include/ctpp2/CTPP2StaticData.hpp
+include/ctpp2/CTPP2StaticText.hpp
+include/ctpp2/CTPP2StreamOutputCollector.hpp
+include/ctpp2/CTPP2StringBuffer.hpp
+include/ctpp2/CTPP2StringIconvOutputCollector.hpp
+include/ctpp2/CTPP2StringOutputCollector.hpp
+include/ctpp2/CTPP2SymbolTable.hpp
+include/ctpp2/CTPP2Syntax.h
+include/ctpp2/CTPP2SysHeaders.h
+include/ctpp2/CTPP2SysTypes.h
+include/ctpp2/CTPP2SyscallFactory.hpp
+include/ctpp2/CTPP2Types.h
+include/ctpp2/CTPP2Util.hpp
+include/ctpp2/CTPP2VM.hpp
+include/ctpp2/CTPP2VMArgStack.hpp
+include/ctpp2/CTPP2VMCodeStack.hpp
+include/ctpp2/CTPP2VMDebugInfo.hpp
+include/ctpp2/CTPP2VMDumper.hpp
+include/ctpp2/CTPP2VMException.hpp
+include/ctpp2/CTPP2VMExecutable.hpp
+include/ctpp2/CTPP2VMFileLoader.hpp
+include/ctpp2/CTPP2VMInstruction.hpp
+include/ctpp2/CTPP2VMLoader.hpp
+include/ctpp2/CTPP2VMMemoryCore.hpp
+include/ctpp2/CTPP2VMOpcodeCollector.hpp
+include/ctpp2/CTPP2VMOpcodes.h
+include/ctpp2/CTPP2VMSTDLib.hpp
+include/ctpp2/CTPP2VMStackException.hpp
+include/ctpp2/CTPP2VMSyscall.hpp
+include/ctpp2/STLException.hpp
+include/ctpp2/STLFunctional.hpp
+include/ctpp2/STLIosfwd.hpp
+include/ctpp2/STLMap.hpp
+include/ctpp2/STLOstream.hpp
+include/ctpp2/STLPair.hpp
+include/ctpp2/STLString.hpp
+include/ctpp2/STLVector.hpp
+lib/libctpp2-st.a
+lib/libctpp2.so
+lib/libctpp2.so.2
+lib/libctpp2.so.%%PORTVERSION%%
+@dirrm include/ctpp2
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..679b99d
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,180 @@
+INSTALLATION INTRODUCTION
+-------------------------
+
+This file describes how to compile and install CTPP2 on your
+system.
+
+ ==============================================
+ = =
+ = NOTE: You will need an ANSI C++ compiler =
+ = with STL support, cmake building system =
+ = (http://www.cmake.org/) and, depends of =
+ = cmake flags, installed PCRE library =
+ = =
+ ==============================================
+
+
+For most systems, execute the following to compile and install
+CTPP2:
+ cmake .
+ make
+ make install
+
+If you want to run tests, execute "make test" command.
+
+To clean package, run "./ClearPackage.sh" script.
+
+CONFIGURATION OPTIONS
+---------------------
+
+GETTEXT_SUPPORT - enable gettext (libintl) support, default on
+DEBUG_MODE - compile with debug output, default off
+ENABLE_OPTIMIZATION - compile with optimization, default on
+
+
+
+PLATFORM SPECIFIC NOTES
+-----------------------
+
+ MODERN PLATFORMS BY VENDORS
+ ---------------------------
+
+ FreeBSD
+ -------
+ |
+ |- FreeBSD 8.1-RELEASE
+ | amd64, gcc version 4.2.1 20070719 [FreeBSD]
+ | i386, gcc version 4.2.1 20070719 [FreeBSD]
+ |
+ |- FreeBSD 8.1-RC2
+ | powerpc, gcc version 4.2.1 20070719 [FreeBSD]
+ |
+ |- FreeBSD 7.2-RELEASE
+ | amd64, gcc version 4.2.1 20070719 [FreeBSD]
+ | i386, gcc version 4.2.1 20070719 [FreeBSD]
+ | i386, gcc version 4.4.1 20090421 (prerelease) (GCC)
+ |
+ |- FreeBSD 7.1-RELEASE
+ | amd64, gcc version 4.2.1 20070719 [FreeBSD]
+ | i386, gcc version 4.2.1 20070719 [FreeBSD]
+ |
+ |- FreeBSD 7.0-RELEASE
+ | amd64, gcc version 4.2.1 [FreeBSD] 20070719
+ | i386, gcc version 4.3.0 [FreeBSD] 20070719
+ |
+ |- FreeBSD 6.3-RELEASE-p2
+ | i386, gcc version 3.4.6 [FreeBSD] 20060305
+ |
+ |- FreeBSD 6.3-STABLE
+ | amd64, gcc version 3.4.6 [FreeBSD] 20060305
+ | i386, gcc version 3.4.6 [FreeBSD] 20060305
+ |
+ |- FreeBSD 6.2-STABLE
+ | i386, gcc version 3.4.6 [FreeBSD] 20060305
+ | i386, gcc version 4.3.0 20061111 (experimental)
+ |
+ |- FreeBSD 6.2-RELEASE
+ | amd64, gcc version 3.4.6 [FreeBSD] 20060305
+ | i386, gcc version 3.4.6 [FreeBSD] 20060305
+ |
+ |- FreeBSD 6.0-RELEASE-p4
+ i386, gcc version 3.4.4 [FreeBSD] 20050518
+
+ Red Hat
+ -------
+ |
+ |- Red Hat Enterprise Linux Server release 5 (Tikanga)
+ amd64, gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)
+
+ Fedora
+ ------
+ |
+ |- Fedora release 8 (Werewolf)
+ | i386, gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
+ |
+ |- Fedora release 7 (Moonshine)
+ i386, gcc version 4.1.2 20070925 (Red Hat 4.1.2-27)
+
+ CentOS
+ ------
+ |
+ |- CentOS release 5 (Final)
+ i386, gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)
+
+ SuSe
+ ----
+ |
+ |- openSuSe 11.1
+ i386, gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux)
+
+ Debian
+ ------
+ |
+ |- Debian GNU/Linux 6.0
+ | amd64, gcc version 4.4.5 (Debian 4.4.5-8)
+ | i386, gcc version 4.4.5 (Debian 4.4.5-8)
+ |
+ |- Debian GNU/Linux 5.0
+ | amd64, gcc version 4.3.2 (Debian 4.3.2-1.1)
+ | i386, gcc version 4.3.2 (Debian 4.3.2-1.1)
+ |
+ |- Debian GNU/Linux 4.0
+ amd64, gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
+ i386, gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
+
+ Ubuntu
+ ------
+ |
+ |- Ubuntu 10.04 LTS
+ | i386, gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
+ |
+ |- Ubuntu 12.04.1 LTS
+ | x86_64, gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
+
+ Arch Linux
+ ----------
+ |
+ |- Arch
+ | i386, gcc version 4.6.0 20110429
+ |
+ |- 2010.05
+ amd64, gcc version 4.5.1 (GCC)
+
+ Sun Microsystems
+ ----------------
+ |
+ |- Sun Solaris 10
+ sparc, Sun C++ 5.9 SunOS_sparc Patch 124863-01 2007/07/25
+ i386, gcc version 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
+ i386, Sun C++ 5.8 2005/10/13
+ amd64, gcc version 3.4.3 (csl-sol210-3_4-branch+sol_rpath)
+ amd64, Sun C++ 5.8 2005/10/13
+
+ Microsoft
+ ---------
+ |
+ |- Microsoft (R) Windows (TM) XP
+ Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 (Visual Studio 2008)
+ Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 (Visual Studio 2008)
+ Intel(R) C++ Compiler Professional for applications running on IA-32, Version 11.0
+
+ Apple Inc.
+ ----------
+ |
+ |- Mac OS X (Darwin Kernel Version 9.6.0)
+ i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5488)
+
+ OLD PLATFORMS BY VENDORS
+ ------------------------
+
+ Red Hat
+ -------
+ |
+ |- Red Hat Linux release 9 (Shrike)
+ i386, gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5): Works fine.
+
+ FreeBSD
+ -------
+ |
+ |- FreeBSD 4.11-STABLE
+ gcc 2.95.30: Works fine.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1ceddfa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+
+ Copyright (c) 2006 - 2010 CTPP Team
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
diff --git a/NOTTODO b/NOTTODO
new file mode 100644
index 0000000..44e5d89
--- /dev/null
+++ b/NOTTODO
@@ -0,0 +1,12 @@
+ *NOT* TODO LIST
+ ---------------
+
+ This list describes things that will NEVER be doing in CTPP2 project.
+
+ - Autotools
+ - Scons
+ - CVS
+ - Boost C++
+ - Loki C++
+ - Changing license to any other
+ - "Build Every Night/Week/Month"
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 0000000..c71066e
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,25 @@
+# Maintainer: Valentin V. Bartenev <i@vbart.ru>
+
+pkgname=ctpp2
+pkgver=2.8.0
+pkgrel=1
+pkgdesc="Template engine completely written in C++"
+arch=('i686' 'x86_64')
+url="http://ctpp.havoc.ru/en/"
+optdepends=('gettext: gettext support')
+makedepends=('cmake' 'make' 'patch')
+source=(http://ctpp.havoc.ru/download/ctpp2-$pkgver.tar.gz)
+license=('custom:BSD-like')
+#md5sums=('')
+
+build() {
+ cd $srcdir/$pkgname-$pkgver
+ mkdir build
+ cd build
+ cmake .. || return 1
+ make || return 1
+ make DESTDIR=$pkgdir install || return 1
+ install -Dm 644 ../LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
+}
+
+# Enjoy! ;)
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..e135077
--- /dev/null
+++ b/TODO
@@ -0,0 +1,13 @@
+ Version 2
+ ---------
+
+ TODO LIST
+ ---------
+ !! - high priority
+ ! - medium priority
+ . - low priority
+
+ ----------------------------------------------------------------------------------
+
+ !!. Create compiler for new template tt2-like dialect
+ +. Examples and documentation
diff --git a/benchmarks/CDT2JSON.cpp b/benchmarks/CDT2JSON.cpp
new file mode 100644
index 0000000..1e548db
--- /dev/null
+++ b/benchmarks/CDT2JSON.cpp
@@ -0,0 +1,135 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+#ifdef _MSC_VER
+#include <Windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+
+
+#include <CTPP2JSONParser.hpp>
+#include <CTPP2ParserException.hpp>
+#include <CDT.hpp>
+#include <CTPP2Util.hpp>
+
+using namespace CTPP;
+using namespace std;
+
+#ifdef _MSC_VER
+unsigned long getMSTime() {
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+ return st.wSecond * 1000000 + st.wMilliseconds * 1000;
+}
+#else
+unsigned long getMSTime() {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return tv.tv_sec * 1000000 + tv.tv_usec;
+}
+#endif
+
+void usage(const char * name) {
+ cout << "Usage:\n\t" << name << " -[t|b] filename \n\t\t -t - test stream and non-stream CDT to JSON conversions\n\t\t -b - run stream vs non-stream CDT to JSON conversions benchmark\n\t filename - name of file with JSON object which will be used in test/benchmark" << endl;
+}
+
+int main(int argc, char ** argv) {
+ CDT cdt(CDT::HASH_VAL);
+
+ if (argc < 3 || argv[1][0] != '-' || (argv[1][1] != 't' && argv[1][1] != 'b')) {
+ usage(argv[0]);
+ return 3;
+ }
+
+ struct stat oStat;
+ const char * filename = argv[2];
+ if (stat(filename, &oStat) == -1 || oStat.st_size == 0) {
+ cerr << "ERROR: Cannot get size of file " << filename << endl;
+ return 2;
+ }
+
+ FILE * F = fopen(filename, "r");
+ if (F == NULL) {
+ cerr << "ERROR: Cannot open file " << filename << " for reading" << endl;
+ return 1;
+ }
+
+ // Allocate memory
+ CHAR_8 * szJSONBuffer = (CHAR_8 *)malloc(oStat.st_size + 1);
+ // Read from file
+ if (fread(szJSONBuffer, oStat.st_size, 1, F) != 1)
+ {
+ fprintf(stderr, "ERROR: Cannot read from file `%s`\n", argv[1]);
+ fclose(F);
+ free(szJSONBuffer);
+ return EX_SOFTWARE;
+ }
+
+ szJSONBuffer[oStat.st_size] = '\0';
+ CCHAR_P szEnd = szJSONBuffer + oStat.st_size;
+ CTPP2JSONParser oJSONParser(cdt);
+ oJSONParser.Parse(szJSONBuffer, szEnd);
+ free(szJSONBuffer);
+
+ unsigned long total = 1000;
+ unsigned int tmp = 0;
+ STLW::string s1;
+ STLW::string s2;
+ CDT2JSON(cdt, s1);
+ DumpBuffer ss;
+ DumpCDT2JSON(cdt, ss);
+ s2.assign(ss.Data(), ss.Data() + ss.Size());
+ if(s1 != s2) {
+ cout << "S1 = " << s1 << endl << endl;
+ cout << "S2 = " << s2 << endl << endl;
+ cerr << "Results doens't match\n";
+ return 3;
+ }
+ // -t mode
+ if(argv[1][1] == 't')
+ return 0;
+
+ unsigned long stringTime = 1;
+ unsigned long streamTime = 1;
+ if(1) {
+ unsigned long t0 = getMSTime();
+ STLW::string s;
+ for(unsigned long i = 0; i < total; ++i) {
+ s.clear();
+ CDT2JSON(cdt, s);
+ tmp += s.size();
+ }
+ unsigned long t1 = getMSTime();
+
+ cout << "Stats: " << total << " in " << (t1 - t0) << " microsecs, avg = " << 1.* (t1 - t0) / total << " microsec/conv, "
+ << 1000000. * total / (t1 - t0) << endl;
+ stringTime = t1 - t0;
+ }
+ {
+ unsigned long t0 = getMSTime();
+ for(unsigned long i = 0; i < total; ++i) {
+ DumpBuffer ss;
+ DumpCDT2JSON(cdt, ss);
+ }
+ unsigned long t1 = getMSTime();
+
+ cout << "Stats: " << total << " in " << (t1 - t0) << " microsecs, avg = " << 1.* (t1 - t0) / total << " microsec/conv, "
+ << 1000000. * total / (t1 - t0) << endl;
+ streamTime = t1 - t0;
+ }
+ cout << "Diff = " << (stringTime - streamTime) << " ms = " << (100. * (stringTime - streamTime) / stringTime) << "%\n";
+
+
+ return 0;
+}
diff --git a/benchmarks/data/lebowski-bench.json b/benchmarks/data/lebowski-bench.json
new file mode 100644
index 0000000..0e0a4a3
--- /dev/null
+++ b/benchmarks/data/lebowski-bench.json
@@ -0,0 +1,140 @@
+{
+ "adverts" : [
+ {
+ "title" : "Walter",
+ "text" : "You see what happens, Larry?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Walter",
+ "text" : "I don't roll on Shabbos!",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Blond Thug",
+ "text" : "Where's the money, Lebowski?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Nihilist",
+ "text" : "We believe in nothing, Lebowski.",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Walter",
+ "text" : "Is this your homework, Larry?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Nihilist",
+ "text" : "Ve vant ze money, Lebowski",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ }
+ ],
+
+ "sections" : [
+ {
+ "id" : 1234,
+ "floatId" : 1234.0123,
+ "title" : "The Dude",
+ "rip" : 0
+ },
+ {
+ "id" : -12345,
+ "title" : "Walter Sobchak",
+ "rip" : 0
+ },
+ {
+ "id" : 3456,
+ "title" : "Donny",
+ "rip" : 1
+ },
+ {
+ "id" : 4567,
+ "title" : "Maude Lebowski",
+ "rip" : 0
+ },
+ {
+ "id" : 5678,
+ "title" : "The Big Lebowski",
+ "rip" : 0
+ },
+ {
+ "id" : 6789,
+ "title" : "Brandt",
+ "rip" : 0
+ },
+ {
+ "id" : 7890,
+ "title" : "Jesus Quintana",
+ "rip" : 0
+ }
+ ],
+
+ "total" : 654329,
+ "online" : [
+ { "name" : "true" },
+ { "name" : "false" },
+ { "name" : "short" },
+ { "name" : "long" },
+ { "name" : "apha" },
+ { "name" : "omega" },
+ { "name" : "drag" },
+ { "name" : "drop" },
+ { "name" : "make" },
+ { "name" : "clean" },
+ { "name" : "east" },
+ { "name" : "west" },
+ { "name" : "up" },
+ { "name" : "down" },
+ { "name" : "sun" },
+ { "name" : "rain" },
+ { "name" : "secondary" },
+ { "name" : "main" }
+ ],
+
+ "news" : [
+ {
+ "time" : "03:45",
+ "id" : 987,
+ "title" : "The Stranger",
+ "text" : "See, they call Los Angeles the \"City Of Angels\"; but I didn't find it to be that, exactly. But I'll allow it as there are s ome nice folks there. 'Course I ain't never been to London, and I ain't never seen France. And I ain't never seen no queen in her damned undies, so the feller says. But I'll tell you what - after seeing Los Angeles, and this here story I'm about to unfold, well, I guess I seen somethin' every bit as stupefyin' as you'd seen in any of them other places. And in English , too. So I can die with a smile on my face, without feelin' like the good Lord gypped me. Now this here story I'm about to unfold took place in the early '90s - just about the time of our conflict with Sad'm and the I-raqis. I only mention it be cause sometimes there's a man..."
+ },
+ {
+ "time" : "03:48",
+ "id" : 876,
+ "title" : "The Stranger",
+ "text" : "...I won't say a hero, 'cause, what's a hero? Sometimes, there's a man. And I'm talkin' about the Dude here - the Dude from Los Angeles. Sometimes, there's a man, well, he's the man for his time and place. He fits right in there. And that's the Dude. The Dude, from Los Angeles. And even if he's a lazy man - and the Dude was most certainly that. Quite possibly the laziest in all of Los Angeles County, which would place him high in the runnin' for laziest worldwide. Sometimes there's a man , sometimes, there's a man. Well, I lost my train of thought here. But... aw, hell. I've done introduced it enough."
+ },
+ {
+ "time" : "03:50",
+ "id" : 765,
+ "title" : "Walter Sobchak",
+ "text" : "Donny was a good bowler, and a good man. He was one of us. He was a man who loved the outdoors... and bowling, and as a surfer he explored the beaches of Southern California, from La Jolla to Leo Carrillo and... up to... Pismo. He died, like so many young men of his generation, he died before his time. In your wisdom, Lord, you took him, as you took so many bright flowering young men at Khe Sanh, at Langdok, at Hill 364. These young men gave their lives. And so would Donny. Donny, who loved bowling. And so, Theodore Donald Karabotsos, in accordance with what we think your dying wishes might well have been, we commit your final mortal remains to the bosom of the Pacific Ocean, which you loved so well. Good night, sweet prince."
+ },
+ {
+ "time" : "03:52",
+ "id" : 654,
+ "title" : "The Dude",
+ "text" : "God damn you Walter! You fuckin' asshole! Everything's a fuckin' travesty with you, man! And what was all that shit about Vietnam? What the FUCK, has anything got to do with Vietnam? What the fuck are you talking about?"
+ },
+ {
+ "time" : "03:57",
+ "id" : 543,
+ "title" : "Jesus Quintana",
+ "text" : "What's this day of rest shit? What's this bullshit? I don't fuckin' care! It don't matter to Jesus. But you're not foolin'me, man. You might fool the fucks in the league office, but you don't fool Jesus. This bush league psyche-out stuff. Laughable, man - ha ha! I would have fucked you in the ass Saturday. I fuck you in the ass next Wednesday instead. Wooo! You gotadate Wednesday, baby!"
+ },
+ {
+ "time" : "03:59",
+ "id" : 432,
+ "title" : "Jesus Quintana",
+ "text" : "Let me tell you something, pendejo. You pull any of your crazy shit with us, you flash a piece out on the lanes, I'll take it away from you, stick it up your ass and pull the fucking trigger 'til it goes \"click.\""
+ },
+ {
+ "time" : "04:01",
+ "id" : 321,
+ "title" : "The Dude",
+ "text" : "Let me explain something to you. Um, I am not \"Mr. Lebowski\". You're Mr. Lebowski. I'm the Dude. So that's what you call me. You know, that or, uh, His Dudeness, or uh, Duder, or El Duderino if you're not into the whole brevity thing."
+ }
+ ]
+}
diff --git a/benchmarks/data/test.json b/benchmarks/data/test.json
new file mode 100644
index 0000000..d4cda23
--- /dev/null
+++ b/benchmarks/data/test.json
@@ -0,0 +1 @@
+{"jsonrpc":"2.0","result":{"folder":{"element\"\rs":50,"messages":[{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1340093948,"rdate_interval":"today","seen":1,"size":60600,"subject":"Химчистка салона авто | кухонный гарнитур | мягкая мебель","to":[["","ratest_13","rambler.ru"]],"uid":280},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1340079502,"rdate_interval":"today","size":59960,"subject":"УЗ-чистка зубов | лечение остеохондроза и болей в спине | ужин в ресторане","to":[["","ratest_13","rambler.ru"]],"uid":279},{"from":[["","noreply","tvrain.ru"]],"rdate":1340075668,"rdate_interval":"today","size":96245,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":278},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1340047640,"rdate_interval":"yesterday","size":59809,"subject":"Subscribe. Экономика - Как Ротшильды и Рокфеллеры делят Россию","to":[["digest.economics20272361","ratest_13","rambler.ru"]],"uid":277},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1340023377,"rdate_interval":"yesterday","seen":1,"size":52151,"subject":"Subscribe. Бизнес - Законы выживания на рабочем месте","to":[["digest.business20272361","ratest_13","rambler.ru"]],"uid":276},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1340022193,"rdate_interval":"yesterday","size":48641,"subject":"Subscribe. Стиль - Астрологический прогноз с 18.06 по 24.06","to":[["digest.style20272361","ratest_13","rambler.ru"]],"uid":275},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1340007028,"rdate_interval":"yesterday","size":63088,"subject":"Отдых в отеле | медицинские услуги | пошив мужских костюмов или сорочек","to":[["","ratest_13","rambler.ru"]],"uid":274},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339993055,"rdate_interval":"yesterday","size":63301,"subject":"Массаж в течение полугода | выпечка в кафе Sweetle | душевая кабина","to":[["","ratest_13","rambler.ru"]],"uid":273},{"from":[["","noreply","tvrain.ru"]],"rdate":1339989432,"rdate_interval":"yesterday","size":48072,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":272},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339980990,"rdate_interval":"yesterday","size":149489,"subject":"Новости Subscribe.Ru 18/06/2012","to":[["news.citycat20272361","ratest_13","rambler.ru"]],"uid":271},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339906279,"rdate_interval":"two_weeks","size":75264,"subject":"Полет на параплане | сахарная или восковая депиляция | еда с доставкой в офис или домой","to":[["","ratest_13","rambler.ru"]],"uid":270},{"from":[["","noreply","tvrain.ru"]],"rdate":1339903441,"rdate_interval":"two_weeks","size":33442,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":269},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339834300,"rdate_interval":"two_weeks","size":59813,"subject":"Коррекция фигуры | билет на мюзикл «Мата Хари: Любовь и шпионаж» | курс имидж-стилистики","to":[["","ratest_13","rambler.ru"]],"uid":268},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339820139,"rdate_interval":"two_weeks","size":57648,"subject":"Онлайн-тренинг KeyNote 2012 | отдых в кафе | уход за волосами","to":[["","ratest_13","rambler.ru"]],"uid":267},{"from":[["","noreply","tvrain.ru"]],"rdate":1339816588,"rdate_interval":"two_weeks","size":98257,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":266},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339809784,"rdate_interval":"two_weeks","size":164529,"subject":"Новости Subscribe.Ru 16/06/2012","to":[["news.citycat20272361","ratest_13","rambler.ru"]],"uid":265},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339766620,"rdate_interval":"two_weeks","seen":1,"size":54599,"subject":"Subscribe. Бизнес - Исповедь мента","to":[["digest.business20272361","ratest_13","rambler.ru"]],"uid":264},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339762414,"rdate_interval":"two_weeks","size":68113,"subject":"Subscribe. Стиль - О позоре российского христианства","to":[["digest.style20272361","ratest_13","rambler.ru"]],"uid":263},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339747912,"rdate_interval":"two_weeks","size":60408,"subject":"Установка зубного имплантата | ужин в ресторане восточной кухни | лазерная эпиляция","to":[["","ratest_13","rambler.ru"]],"uid":262},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339733861,"rdate_interval":"two_weeks","size":59320,"subject":"Коррекция фигуры без операций | видеорегистратор | занятия танцами","to":[["","ratest_13","rambler.ru"]],"uid":261},{"from":[["","noreply","tvrain.ru"]],"rdate":1339729989,"rdate_interval":"two_weeks","size":113810,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":260},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339712128,"rdate_interval":"two_weeks","size":67307,"subject":"Subscribe. Экономика - Как спасать рубли, на что не тратить деньги?","to":[["digest.economics20272361","ratest_13","rambler.ru"]],"uid":259},{"from":[["Групон / Туризм","daily","deals.groupon.ru"]],"rdate":1339679500,"rdate_interval":"two_weeks","size":53126,"subject":"Отдых за городом | шопинг-тур в Милан | путешествие в ОАЭ","to":[["","ratest_13","rambler.ru"]],"uid":258},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339664246,"rdate_interval":"two_weeks","seen":1,"size":63003,"subject":"Subscribe. Экономика - Война в Сирии и новый виток экономического кризиса","to":[["digest.economics20272361","ratest_13","rambler.ru"]],"uid":257},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339661868,"rdate_interval":"two_weeks","size":58800,"subject":"Обучение вождению | отдых в загородном отеле | дистанционное обучение Mini-MBA","to":[["","ratest_13","rambler.ru"]],"uid":256},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339647903,"rdate_interval":"two_weeks","size":59649,"subject":"Картинг | фитнес для ленивых | обследование для будущих родителей","to":[["","ratest_13","rambler.ru"]],"uid":255},{"from":[["","noreply","tvrain.ru"]],"rdate":1339643715,"rdate_interval":"two_weeks","size":116803,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":254},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339634801,"rdate_interval":"two_weeks","size":115218,"subject":"Новости Subscribe.Ru 14/06/2012","to":[["news.citycat20272361","ratest_13","rambler.ru"]],"uid":253},{"from":[["Групон / Шопинг","daily","deals.groupon.ru"]],"rdate":1339600185,"rdate_interval":"two_weeks","size":62402,"subject":"Спортивные товары | натяжные потолки | онлайн-изучение иностранных языков","to":[["","ratest_13","rambler.ru"]],"uid":252},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339591961,"rdate_interval":"two_weeks","size":45753,"subject":"Subscribe. Стиль - Диета по гороскопу","to":[["digest.style20272361","ratest_13","rambler.ru"]],"uid":251},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339579379,"rdate_interval":"two_weeks","size":57991,"subject":"Subscribe. Бизнес - Жизнь 'по безналу'","to":[["digest.business20272361","ratest_13","rambler.ru"]],"uid":250},{"from":[["","noreply","tvrain.ru"]],"rdate":1339577104,"rdate_interval":"two_weeks","size":92369,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":249},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339575459,"rdate_interval":"two_weeks","size":61046,"subject":"Фотокнига | лазерная коррекция зрения | спортивный инвентарь","to":[["","ratest_13","rambler.ru"]],"uid":248},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339561134,"rdate_interval":"two_weeks","size":61160,"subject":"Обследование для мужчин и женщин | ужин в мексиканском ресторане | программа для снижения веса","to":[["","ratest_13","rambler.ru"]],"uid":247},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339474609,"rdate_interval":"two_weeks","size":85259,"subject":"Ужин в ресторане «Бирхаус» | изучение иностранных языков | маникюр и педикюр","to":[["","ratest_13","rambler.ru"]],"uid":246},{"from":[["","noreply","tvrain.ru"]],"rdate":1339470706,"rdate_interval":"two_weeks","size":91966,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":245},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339388066,"rdate_interval":"three_weeks","size":78239,"subject":"Массаж | изучение иностранного языка | экскурсия на страусиную ферму","to":[["","ratest_13","rambler.ru"]],"uid":244},{"from":[["","noreply","tvrain.ru"]],"rdate":1339384516,"rdate_interval":"three_weeks","size":47398,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":243},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339303053,"rdate_interval":"three_weeks","size":72590,"subject":"Праздничная ночная прогулка на теплоходе | коррекция фигуры | уход за волосами","to":[["","ratest_13","rambler.ru"]],"uid":242},{"from":[["","noreply","tvrain.ru"]],"rdate":1339298346,"rdate_interval":"three_weeks","size":58345,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":241},{"from":[["Групон / Концерты","daily","deals.groupon.ru"]],"rdate":1339247303,"rdate_interval":"three_weeks","size":48062,"subject":"Шоу в «Паноптикуме научных развлечений» | мюзикл «Три мушкетера» | «Пижамная вечеринка Love Radio»","to":[["","ratest_13","rambler.ru"]],"uid":240},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339235424,"rdate_interval":"three_weeks","size":58198,"subject":"Subscribe. Экономика - Эх, рубль, куда ты катишься?","to":[["digest.economics20272361","ratest_13","rambler.ru"]],"uid":239},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339229632,"rdate_interval":"three_weeks","size":63574,"subject":"МРТ любого органа | сокращенный курс снижения веса | солнцезащитные очки","to":[["","ratest_13","rambler.ru"]],"uid":238},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339215563,"rdate_interval":"three_weeks","size":63694,"subject":"Робот-пылесос | установка металлокерамических коронок | LPG-лифтинг кожи","to":[["","ratest_13","rambler.ru"]],"uid":237},{"from":[["","noreply","tvrain.ru"]],"rdate":1339211997,"rdate_interval":"three_weeks","size":84286,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":236},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339197664,"rdate_interval":"three_weeks","size":110866,"subject":"Новости Subscribe.Ru 09/06/2012","to":[["news.citycat20272361","ratest_13","rambler.ru"]],"uid":235},{"from":[["Subscribe.Ru","namma20272361","subscribe.ru"]],"rdate":1339158434,"rdate_interval":"three_weeks","size":44812,"subject":"Subscribe. Стиль - Наш шоу-бизнес поражён 'киркоровщиной'","to":[["digest.style20272361","ratest_13","rambler.ru"]],"uid":234},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339143192,"rdate_interval":"three_weeks","size":76664,"subject":"Отдых за городом | установка забора из профнастила | катание на вейкборде или водных лыжах","to":[["","ratest_13","rambler.ru"]],"uid":233},{"from":[["Групон Москва","daily","deals.groupon.ru"]],"rdate":1339129151,"rdate_interval":"three_weeks","size":76323,"subject":"Романтическая прогулка по Москве-реке | занятия йогой | «шоколадная» спа-программа","to":[["","ratest_13","rambler.ru"]],"uid":232},{"from":[["","noreply","tvrain.ru"]],"rdate":1339125193,"rdate_interval":"three_weeks","size":104514,"subject":"TVRain.ru: Рассылка новостей с сайта телеканала ДОЖДЬ","to":[["","ratest_13","rambler.ru"]],"uid":231}],"name":"INBOX","offset":0,"result":"fetched","sortorder":"D","total_elements":139},"status":"OK"}}
diff --git a/ctpp2.ebuild b/ctpp2.ebuild
new file mode 100644
index 0000000..823599f
--- /dev/null
+++ b/ctpp2.ebuild
@@ -0,0 +1,27 @@
+inherit eutils
+
+DESCRIPTION="CT++"
+HOMEPAGE="http://ctpp.havoc.ru"
+
+SRC_URI="http://ctpp.havoc.ru/download/${P}.tar.gz"
+
+LICENSE="BSD"
+KEYWORDS="x86"
+
+DEPEND="dev-util/cmake"
+
+src_compile() {
+ cmake . || die
+ emake || die
+}
+
+src_install() {
+ dobin ctpp2c ctpp2json ctpp2vm ctpp2c ctpp2-config
+
+ dolib.so *.so*
+
+ insinto /usr/include/ctpp2
+ doins include/*
+
+ dodoc CHANGES
+}
diff --git a/ctpp2.spec b/ctpp2.spec
new file mode 100644
index 0000000..026e737
--- /dev/null
+++ b/ctpp2.spec
@@ -0,0 +1,306 @@
+Summary: CTPP2 template engine.
+Name: ctpp2
+Version: 2.8.3
+Release: 0%{?dist}
+License: BSD
+Source: ctpp2-%{version}.tar.gz
+Group: System Environment/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildRequires: openssl-devel cmake gcc-c++
+
+%package devel
+Summary: Header files and development documentation for %{name}
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description
+CTPP2 library.
+%description devel
+CTPP2 header files.
+
+This package contains the header files, static libraries and development
+documentation for %{name}. If you like to develop programs using %{name},
+you will need to install %{name}-devel.
+
+%prep
+%setup -q -n ctpp2-%{version}
+
+%build
+cmake -D SKIP_RELINK_RPATH=ON . -DCMAKE_INSTALL_PREFIX=/usr -DCFLAGS="${CFLAGS}" -DCXXFLAGS="${CXXFLAGS}"
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+mkdir %{buildroot}
+make DESTDIR=%{buildroot} install
+mkdir $RPM_BUILD_ROOT/usr/share
+mv $RPM_BUILD_ROOT/usr/man $RPM_BUILD_ROOT/usr/share/man
+%if %_lib == "lib64"
+mkdir %{buildroot}/usr/lib64
+mv %{buildroot}/usr/lib/* %{buildroot}/usr/lib64
+%endif
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/ctpp2-config
+%{_bindir}/ctpp2c
+%{_bindir}/ctpp2i
+%{_bindir}/ctpp2json
+%{_bindir}/ctpp2vm
+%{_libdir}/libctpp2.so*
+#%{_datadir}/locale/ru_RU.CP1251/LC_MESSAGES/ctpp2.mo
+#%{_datadir}/locale/ru_RU.CP866/LC_MESSAGES/ctpp2.mo
+#%{_datadir}/locale/ru_RU.KOI8-R/LC_MESSAGES/ctpp2.mo
+#%{_datadir}/locale/ru_RU.UTF-8/LC_MESSAGES/ctpp2.mo
+%{_mandir}/*/*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/ctpp2
+%{_libdir}/libctpp2-st.a
+
+%changelog
+* Sat Nov 10 2012 Alexander Pankov <pianist@usrsrc.ru> - 2.8.3-0
++ Returned curly brakets as an alias for square
++ Fixed error reporting
+
+* Fri Jul 13 2012 Andrei V. Shetuhin <reki@reki.ru> - 2.8.2-0
+- Removed TMPL_loop. Added TMPL_foreach's attributes for iterator.
+- TMPL_foreach works with HASH.
+- Fixed TMPL_call. It works with variables.
+- Removed the attribute 'map' of TMPL_include.
+- Added CONTEXT(), LIST().
+- Removed NUMERAL(), ARRAY_ELEMENT(), HASH_ELEMENT().
+- HASH_ELEMENT().
+- Renamed JSESCAPE() as JSONESCAPE(). Refactored the code.
+- Added new documentation of the CT++ template language.
+- Added the operator <TMPL_break>.
+- Small fixes.
+
+* Wed Dec 28 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.8.0-0
+- Improved access to arrays and hashes
+
+* Wed Dec 28 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.6-0
+- Bug fixes
+
+* Fri Dec 23 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.5-0
+- Bug fixes
+
+* Mon Dec 19 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.4-0
+- Bug fixes
+
+* Mon Nov 14 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.3-0
+- Bug fixes
+
+* Wed Oct 5 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.2-0
+- Bug fixes
+
+* Fri Jul 8 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.1-0
+- Production-ready version of CTPP2 2.7.X
+
+* Thu Jun 16 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.7.0-0
+- New version of CTPP: 2.7.0
+
+* Mon May 16 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.15-0
+- Bug fixes
+
+* Thu Apr 28 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.14-0
+- Bug fixes
+
+* Fri Apr 1 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.13-0
+- Bug fixes
+
+* Tue Mar 11 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.12-0
+- Bug fixes
+
+* Mon Feb 28 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.11-0
+- Bug fixes
+
+* Fri Feb 11 2011 Andrei V. Shetuhin <reki@reki.ru> - 2.6.10-0
+- Bug fixes, new functions: GET_TYPE and HOSTNAME
+
+* Mon Nov 1 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.7-0
+- Bug fixes
+
+* Tue Oct 5 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.6-0
+- Bug fixes
+
+* Wed Sep 22 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.5-0
+- Fixes in CTPP2 dialect compiler
+
+* Mon Sep 20 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.4-0
+- Improvements in SortArray method
+
+* Tue Jul 27 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.3-0
+- Fixes in TMPL_foreach iterators (thanks to Kirichenko Sergey <kirichenko@post.km.ru>)
+
+* Wed Jul 20 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.2-0
+- New methods for CDT class: Swap & SortArray.
+
+* Wed Jun 16 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.6.1-0
+- New minor version. See CHANGES.
+
+* Mon May 24 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.5.19-0
+- Bug fixes
+
+* Fri Apr 2 2010 Andrei V. Shetuhin <reki@reki.ru> - 2.5.17-0
+- New function SPRINTF, bug fixes
+
+* Wed Dec 30 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.15-0
+- Fixes in function NUM_FORMAT
+
+* Fri Dec 4 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.14-0
+- New method for class CDT: Erase. Erase element from hash by specified key name
+
+* Tue Nov 24 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.13-0
+- Fixes in Base64Encode function
+
+* Sun Oct 18 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.12-0
+- New output data collector, port to CygWin
+
+* Thu Aug 27 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.11-0
+- Fixes in virtual machine: CMP (STACK/STACK)
+
+* Tue Aug 18 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.10-0
+- New functions: LIST_ELEMENT & ARRAY_ELEMENT. Fixes in JSON parser.
+
+* Thu Aug 13 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.9-0
+- Fixes in <TMPL_foreach .. > <TMPL_include "file"> </TMPL_foreach>
+
+* Wed Aug 5 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.8-0
+- Completely rewrite code of JSON parser
+
+* Wed Jun 24 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.7-0
+- New function: NUMERAL, fixes in TRUNCATE & MB_TRUNCATE functions
+
+* Tue Jun 9 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.6-0
+- Fixes in JSESCAPE function
+
+* Tue Jun 2 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.5-0
+- Fixes in math. expressions inside functions: <TMPL_var FOO(bar + baz)>
+
+* Tue May 20 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.4-0
+- Avoid a lot of warnings on gcc 4.3+, #include <...> changed to #include "..." for all files of project
+
+* Tue May 12 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.3-0
+- Removed inline methods of exception classes, fixed install-no-mkdir-buildroot error in .spec file.
+
+* Mon Apr 20 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.2-0
+- Bug fixes in branches inside foreach operator
+
+* Fri Apr 17 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.1-0
+- Bug fixes, documentation
+
+* Thu Apr 16 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.5.0-0
+- New operator: <TMPL_foreach; Gettext function improvements
+
+* Wed Apr 8 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.10-0
+- New function: WMLESCAPE
+
+* Tue Apr 2 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.9-0
+- New classes: SimpleVM, SimpleCompiler
+
+* Tue Mar 18 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.8-0
+- New functions: CONCAT, SUBSTR, TRUNCATE, MB_SIZE, MB_TRUNCATE, MB_SUBSTR
+
+* Mon Mar 16 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.7-0
+- New flags for iconv converter
+
+* Sat Mar 7 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.6-0
+- New output data collector with charset recoding, new functions
+
+* Wed Mar 4 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.5-0
+- Port to MacOS, new functions: RANDOM and LOG
+
+* Sat Feb 15 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.4-0
+- New functions: HMAC_MD5, URIESCAPE
+
+* Tue Feb 10 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.3-0
+- Port to Win32 platform
+
+* Sun Jan 25 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.2-0
+- Bug fixes
+
+* Sun Jan 18 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.1-0
+- New functions: JSON, JSESCAPE; Documentation for new features
+
+* Wed Jan 14 2009 Andrei V. Shetuhin <reki@reki.ru> - 2.4.0-0
+- <TMPL_call & <TMPL_block operators
+
+* Fri Nov 7 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.11-0
+- JSON parser improvements
+
+* Tue Sep 16 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.10-0
+- Make Valgrind happy & port to ALT Linux
+
+* Fri Sep 12 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.9-0
+- Improvements in parsing Non-HTML templates
+
+* Fri Sep 5 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.8-0
+- Port on SunOs 5.10 i386 and amd64
+
+* Tue Sep 2 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.7-0
+- Nested loops from various data sources, bug fixes
+
+* Mon Aug 11 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.6-0
+- <TMPL_loop accept now contextual variable __CONTENT__ as argument
+
+* Thu Aug 7 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.5-0
+- New input data formats of CAST and DATE_FORMAT functions
+
+* Fri Jul 11 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.4-0
+- Debian Lenny bug fixes
+
+* Wed Jun 24 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.3-0
+- Debug subsystem improvements
+
+* Wed Jun 18 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.2-0
+- New methods of CDT class
+
+* Tue Jun 3 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.1-0
+- More information about errors in compiler
+
+* Wed May 21 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.3.0-0
+- Bug fixes; new CTPP2 debug subsystem
+
+* Wed May 14 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.2.3-0
+- Bug fixes; new function: NUM_FORMAT
+
+* Mon Apr 28 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.2.2-0
+- Bug fixes only
+
+* Wed Apr 23 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.2.1-0
+- New function: ARRAY_SIZE
+
+* Fri Apr 18 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.2.0-0
+- Bug fixes, support of crossplatform bytecode file
+
+* Fri Mar 29 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.1.2-0
+- Inverse translation map in <TMPL_include ...
+
+* Wed Mar 19 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.1.1-0
+- Translation map in <TMPL_include ...
+
+* Fri Mar 14 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.1.0-0
+- Math. operations, speed improvements, bug fixes
+
+* Mon Mar 3 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.5-0
+- Namespaces in variable names, bug fixes
+
+* Mon Feb 18 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.4-0
+- New contextual variable: __COUNTER__, small bug fixes
+
+* Fri Feb 15 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.3-0
+- New function: iconv
+
+* Fri Feb 8 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.2-0
+- Bug fixes, new functions
+
+* Mon Feb 4 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.1-0
+- Bug fixes
+
+* Fri Jan 26 2008 Andrei V. Shetuhin <reki@reki.ru> - 2.0.0-0
+- First version 2.X release.
diff --git a/doc/bootstrap.css b/doc/bootstrap.css
new file mode 100644
index 0000000..d280a31
--- /dev/null
+++ b/doc/bootstrap.css
@@ -0,0 +1,4221 @@
+/*!
+ * Bootstrap v2.0.4
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section {
+ display:block;
+ padding-top:40px;
+ }
+section:first-of-type {
+ padding-top:0;
+ }
+audio,
+canvas,
+video {
+ display:inline-block;
+ *display:inline;
+ *zoom:1;
+ }
+audio:not([controls]) {
+ display:none;
+ }
+html {
+ font-size:100%;
+ -webkit-text-size-adjust:100%;
+ -ms-text-size-adjust:100%;
+ }
+a:focus {
+ outline:thin dotted #333;
+ outline:5px auto -webkit-focus-ring-color;
+ outline-offset:-2px;
+ }
+a:hover,
+a:active {
+ outline:0;
+ }
+sub,
+sup {
+ position:relative;
+ font-size:75%;
+ line-height:0;
+ vertical-align:baseline;
+ }
+sup {
+ top:-0.5em;
+ }
+sub {
+ bottom:-0.25em;
+ }
+img {
+ max-width:100%;
+ vertical-align:middle;
+ border:0;
+ -ms-interpolation-mode:bicubic;
+ }
+#map_canvas img {
+ max-width:none;
+ }
+button,
+input,
+select,
+textarea {
+ margin:0;
+ font-size:100%;
+ vertical-align:middle;
+ }
+button,
+input {
+ *overflow:visible;
+ line-height:normal;
+ }
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding:0;
+ border:0;
+ }
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor:pointer;
+ -webkit-appearance:button;
+ }
+input[type="search"] {
+ -webkit-box-sizing:content-box;
+ -moz-box-sizing:content-box;
+ box-sizing:content-box;
+ -webkit-appearance:textfield;
+ }
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance:none;
+ }
+textarea {
+ overflow:auto;
+ vertical-align:top;
+ }
+.clearfix {
+ *zoom:1;
+ }
+.clearfix:before,
+.clearfix:after {
+ display:table;
+ content:"";
+ }
+.clearfix:after {
+ clear:both;
+ }
+.hide-text {
+ font:0/0 a;
+ color:transparent;
+ text-shadow:none;
+ background-color:transparent;
+ border:0;
+ }
+.input-block-level {
+ display:block;
+ width:100%;
+ min-height:28px;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ }
+body {
+ margin:0;
+ padding:20px;
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size:13px;
+ line-height:18px;
+ color:#333333;
+ background-color:#ffffff;
+ }
+a {
+ color:#0088cc;
+ text-decoration:none;
+ }
+a:hover {
+ color:#005580;
+ text-decoration:underline;
+ }
+.row {
+ margin-left:-20px;
+ *zoom:1;
+ }
+.row:before,
+.row:after {
+ display:table;
+ content:"";
+ }
+.row:after {
+ clear:both;
+ }
+[class*="span"] {
+ float:left;
+ margin-left:20px;
+ }
+.container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width:940px;
+ }
+.span12 {
+ width:940px;
+ }
+.span11 {
+ width:860px;
+ }
+.span10 {
+ width:780px;
+ }
+.span9 {
+ width:700px;
+ }
+.span8 {
+ width:620px;
+ }
+.span7 {
+ width:540px;
+ }
+.span6 {
+ width:460px;
+ }
+.span5 {
+ width:380px;
+ }
+.span4 {
+ width:300px;
+ }
+.span3 {
+ width:220px;
+ }
+.span2 {
+ width:140px;
+ }
+.span1 {
+ width:60px;
+ }
+.offset12 {
+ margin-left:980px;
+ }
+.offset11 {
+ margin-left:900px;
+ }
+.offset10 {
+ margin-left:820px;
+ }
+.offset9 {
+ margin-left:740px;
+ }
+.offset8 {
+ margin-left:660px;
+ }
+.offset7 {
+ margin-left:580px;
+ }
+.offset6 {
+ margin-left:500px;
+ }
+.offset5 {
+ margin-left:420px;
+ }
+.offset4 {
+ margin-left:340px;
+ }
+.offset3 {
+ margin-left:260px;
+ }
+.offset2 {
+ margin-left:180px;
+ }
+.offset1 {
+ margin-left:100px;
+ }
+.row-fluid {
+ width:100%;
+ *zoom:1;
+ }
+.row-fluid:before,
+.row-fluid:after {
+ display:table;
+ content:"";
+ }
+.row-fluid:after {
+ clear:both;
+ }
+.row-fluid [class*="span"] {
+ display:block;
+ float:left;
+ width:100%;
+ min-height:28px;
+ margin-left:2.127659574%;
+ *margin-left:2.0744680846382977%;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ }
+.row-fluid [class*="span"]:first-child {
+ margin-left:0;
+ }
+.row-fluid .span12 {
+ width:99.99999998999999%;
+ *width:99.94680850063828%;
+ }
+.row-fluid .span11 {
+ width:91.489361693%;
+ *width:91.4361702036383%;
+ }
+.row-fluid .span10 {
+ width:82.97872339599999%;
+ *width:82.92553190663828%;
+ }
+.row-fluid .span9 {
+ width:74.468085099%;
+ *width:74.4148936096383%;
+ }
+.row-fluid .span8 {
+ width:65.95744680199999%;
+ *width:65.90425531263828%;
+ }
+.row-fluid .span7 {
+ width:57.446808505%;
+ *width:57.3936170156383%;
+ }
+.row-fluid .span6 {
+ width:48.93617020799999%;
+ *width:48.88297871863829%;
+ }
+.row-fluid .span5 {
+ width:40.425531911%;
+ *width:40.3723404216383%;
+ }
+.row-fluid .span4 {
+ width:31.914893614%;
+ *width:31.8617021246383%;
+ }
+.row-fluid .span3 {
+ width:23.404255317%;
+ *width:23.3510638276383%;
+ }
+.row-fluid .span2 {
+ width:14.89361702%;
+ *width:14.8404255306383%;
+ }
+.row-fluid .span1 {
+ width:6.382978723%;
+ *width:6.329787233638298%;
+ }
+.container {
+ margin-right:auto;
+ margin-left:auto;
+ *zoom:1;
+ }
+.container:before,
+.container:after {
+ display:table;
+ content:"";
+ }
+.container:after {
+ clear:both;
+ }
+.container-fluid {
+ padding-right:20px;
+ padding-left:20px;
+ *zoom:1;
+ }
+.container-fluid:before,
+.container-fluid:after {
+ display:table;
+ content:"";
+ }
+.container-fluid:after {
+ clear:both;
+ }
+p {
+ margin:0 0 9px;
+ }
+p small {
+ font-size:11px;
+ color:#999999;
+ }
+.lead {
+ margin-bottom:18px;
+ font-size:20px;
+ font-weight:200;
+ line-height:27px;
+ }
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin:0;
+ font-family:inherit;
+ font-weight:bold;
+ color:inherit;
+ text-rendering:optimizelegibility;
+ }
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small {
+ font-weight:normal;
+ color:#999999;
+ }
+h1 {
+ font-size:30px;
+ line-height:36px;
+ }
+h1 small {
+ font-size:18px;
+ }
+h2 {
+ font-size:24px;
+ line-height:36px;
+ }
+h2 small {
+ font-size:18px;
+ }
+h3 {
+ font-size:18px;
+ line-height:27px;
+ }
+h3 small {
+ font-size:14px;
+ }
+h4,
+h5,
+h6 {
+ line-height:18px;
+ }
+h4 {
+ font-size:14px;
+ }
+h4 small {
+ font-size:12px;
+ }
+h5 {
+ font-size:12px;
+ }
+h6 {
+ font-size:11px;
+ color:#999999;
+ text-transform:uppercase;
+ }
+.page-header {
+ padding-bottom:17px;
+ margin:18px 0;
+ border-bottom:1px solid #eeeeee;
+ }
+.page-header h1 {
+ line-height:1;
+ }
+ul,
+ol {
+ padding:0;
+ margin:0 0 9px 25px;
+ }
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+ margin-bottom:0;
+ }
+ul {
+ list-style:disc;
+ }
+ol {
+ list-style:decimal;
+ }
+li {
+ line-height:18px;
+ }
+ul.unstyled,
+ol.unstyled {
+ margin-left:0;
+ list-style:none;
+ }
+dl {
+ margin-bottom:18px;
+ }
+dt,
+dd {
+ line-height:18px;
+ }
+dt {
+ font-weight:bold;
+ line-height:17px;
+ }
+dd {
+ margin-left:9px;
+ }
+.dl-horizontal dt {
+ float:left;
+ width:120px;
+ overflow:hidden;
+ clear:left;
+ text-align:right;
+ text-overflow:ellipsis;
+ white-space:nowrap;
+ }
+.dl-horizontal dd {
+ margin-left:130px;
+ }
+hr {
+ margin:18px 0;
+ border:0;
+ border-top:1px solid #eeeeee;
+ border-bottom:1px solid #ffffff;
+ }
+strong {
+ font-weight:bold;
+ }
+em {
+ font-style:italic;
+ }
+.muted {
+ color:#999999;
+ }
+abbr[title] {
+ cursor:help;
+ border-bottom:1px dotted #999999;
+ }
+abbr.initialism {
+ font-size:90%;
+ text-transform:uppercase;
+ }
+blockquote {
+ padding:0 0 0 15px;
+ margin:0 0 18px;
+ border-left:5px solid #eeeeee;
+ }
+blockquote p {
+ margin-bottom:0;
+ font-size:16px;
+ font-weight:300;
+ line-height:22.5px;
+ }
+blockquote small {
+ display:block;
+ line-height:18px;
+ color:#999999;
+ }
+blockquote small:before {
+ content:'\2014 \00A0';
+ }
+blockquote.pull-right {
+ float:right;
+ padding-right:15px;
+ padding-left:0;
+ border-right:5px solid #eeeeee;
+ border-left:0;
+ }
+blockquote.pull-right p,
+blockquote.pull-right small {
+ text-align:right;
+ }
+q:before,
+q:after,
+blockquote:before,
+blockquote:after {
+ content:"";
+ }
+address {
+ display:block;
+ margin-bottom:18px;
+ font-style:normal;
+ line-height:18px;
+ }
+small {
+ font-size:100%;
+ }
+cite {
+ font-style:normal;
+ }
+code,
+pre {
+ padding:0 3px 2px;
+ font-family:Menlo, Monaco, Consolas, "Courier New", monospace;
+ font-size:12px;
+ color:#333333;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ }
+code {
+ padding:2px 4px;
+ color:#333;
+ background-color:#f7f7f9;
+ border:1px solid #e1e1e8;
+ }
+pre {
+ display:block;
+ padding:8.5px;
+ margin:0 0 9px;
+ font-size:12.025px;
+ line-height:18px;
+ word-break:break-all;
+ word-wrap:break-word;
+ white-space:pre;
+ white-space:pre-wrap;
+ background-color:#f5f5f5;
+ border:1px solid #ccc;
+ border:1px solid rgba(0, 0, 0, 0.15);
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+pre.prettyprint {
+ margin-bottom:18px;
+ }
+pre code {
+ padding:0;
+ color:inherit;
+ background-color:transparent;
+ border:0;
+ }
+.pre-scrollable {
+ max-height:340px;
+ overflow-y:scroll;
+ }
+form {
+ margin:0 0 18px;
+ }
+fieldset {
+ padding:0;
+ margin:0;
+ border:0;
+ }
+legend {
+ display:block;
+ width:100%;
+ padding:0;
+ margin-bottom:27px;
+ font-size:19.5px;
+ line-height:36px;
+ color:#333333;
+ border:0;
+ border-bottom:1px solid #e5e5e5;
+ }
+legend small {
+ font-size:13.5px;
+ color:#999999;
+ }
+label,
+input,
+button,
+select,
+textarea {
+ font-size:13px;
+ font-weight:normal;
+ line-height:18px;
+ }
+input,
+button,
+select,
+textarea {
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+ }
+label {
+ display:block;
+ margin-bottom:5px;
+ }
+select,
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ display:inline-block;
+ height:18px;
+ padding:4px;
+ margin-bottom:9px;
+ font-size:13px;
+ line-height:18px;
+ color:#555555;
+ }
+input,
+textarea {
+ width:210px;
+ }
+textarea {
+ height:auto;
+ }
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ background-color:#ffffff;
+ border:1px solid #cccccc;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -ms-transition:border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition:border linear 0.2s, box-shadow linear 0.2s;
+ transition:border linear 0.2s, box-shadow linear 0.2s;
+ }
+textarea:focus,
+input[type="text"]:focus,
+input[type="password"]:focus,
+input[type="datetime"]:focus,
+input[type="datetime-local"]:focus,
+input[type="date"]:focus,
+input[type="month"]:focus,
+input[type="time"]:focus,
+input[type="week"]:focus,
+input[type="number"]:focus,
+input[type="email"]:focus,
+input[type="url"]:focus,
+input[type="search"]:focus,
+input[type="tel"]:focus,
+input[type="color"]:focus,
+.uneditable-input:focus {
+ border-color:rgba(82, 168, 236, 0.8);
+ outline:0;
+ outline:thin dotted \9;
+ /* IE6-9 */
+
+ -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ }
+input[type="radio"],
+input[type="checkbox"] {
+ margin:3px 0;
+ *margin-top:0;
+ /* IE7 */
+
+ line-height:normal;
+ cursor:pointer;
+ }
+input[type="submit"],
+input[type="reset"],
+input[type="button"],
+input[type="radio"],
+input[type="checkbox"] {
+ width:auto;
+ }
+.uneditable-textarea {
+ width:auto;
+ height:auto;
+ }
+select,
+input[type="file"] {
+ height:28px;
+ /* In IE7, the height of the select element cannot be changed by height, only font-size */
+
+ *margin-top:4px;
+ /* For IE7, add top margin to align select with labels */
+
+ line-height:28px;
+ }
+select {
+ width:220px;
+ border:1px solid #bbb;
+ }
+select[multiple],
+select[size] {
+ height:auto;
+ }
+select:focus,
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline:thin dotted #333;
+ outline:5px auto -webkit-focus-ring-color;
+ outline-offset:-2px;
+ }
+.radio,
+.checkbox {
+ min-height:18px;
+ padding-left:18px;
+ }
+.radio input[type="radio"],
+.checkbox input[type="checkbox"] {
+ float:left;
+ margin-left:-18px;
+ }
+.controls > .radio:first-child,
+.controls > .checkbox:first-child {
+ padding-top:5px;
+ }
+.radio.inline,
+.checkbox.inline {
+ display:inline-block;
+ padding-top:5px;
+ margin-bottom:0;
+ vertical-align:middle;
+ }
+.radio.inline + .radio.inline,
+.checkbox.inline + .checkbox.inline {
+ margin-left:10px;
+ }
+.input-mini {
+ width:60px;
+ }
+.input-small {
+ width:90px;
+ }
+.input-medium {
+ width:150px;
+ }
+.input-large {
+ width:210px;
+ }
+.input-xlarge {
+ width:270px;
+ }
+.input-xxlarge {
+ width:530px;
+ }
+input[class*="span"],
+select[class*="span"],
+textarea[class*="span"],
+.uneditable-input[class*="span"],
+.row-fluid input[class*="span"],
+.row-fluid select[class*="span"],
+.row-fluid textarea[class*="span"],
+.row-fluid .uneditable-input[class*="span"] {
+ float:none;
+ margin-left:0;
+ }
+.input-append input[class*="span"],
+.input-append .uneditable-input[class*="span"],
+.input-prepend input[class*="span"],
+.input-prepend .uneditable-input[class*="span"],
+.row-fluid .input-prepend [class*="span"],
+.row-fluid .input-append [class*="span"] {
+ display:inline-block;
+ }
+input,
+textarea,
+.uneditable-input {
+ margin-left:0;
+ }
+input.span12,
+textarea.span12,
+.uneditable-input.span12 {
+ width:930px;
+ }
+input.span11,
+textarea.span11,
+.uneditable-input.span11 {
+ width:850px;
+ }
+input.span10,
+textarea.span10,
+.uneditable-input.span10 {
+ width:770px;
+ }
+input.span9,
+textarea.span9,
+.uneditable-input.span9 {
+ width:690px;
+ }
+input.span8,
+textarea.span8,
+.uneditable-input.span8 {
+ width:610px;
+ }
+input.span7,
+textarea.span7,
+.uneditable-input.span7 {
+ width:530px;
+ }
+input.span6,
+textarea.span6,
+.uneditable-input.span6 {
+ width:450px;
+ }
+input.span5,
+textarea.span5,
+.uneditable-input.span5 {
+ width:370px;
+ }
+input.span4,
+textarea.span4,
+.uneditable-input.span4 {
+ width:290px;
+ }
+input.span3,
+textarea.span3,
+.uneditable-input.span3 {
+ width:210px;
+ }
+input.span2,
+textarea.span2,
+.uneditable-input.span2 {
+ width:130px;
+ }
+input.span1,
+textarea.span1,
+.uneditable-input.span1 {
+ width:50px;
+ }
+input[disabled],
+select[disabled],
+textarea[disabled],
+input[readonly],
+select[readonly],
+textarea[readonly] {
+ cursor:not-allowed;
+ background-color:#eeeeee;
+ border-color:#ddd;
+ }
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"][readonly],
+input[type="checkbox"][readonly] {
+ background-color:transparent;
+ }
+.control-group.warning > label,
+.control-group.warning .help-block,
+.control-group.warning .help-inline {
+ color:#c09853;
+ }
+.control-group.warning .checkbox,
+.control-group.warning .radio,
+.control-group.warning input,
+.control-group.warning select,
+.control-group.warning textarea {
+ color:#c09853;
+ border-color:#c09853;
+ }
+.control-group.warning .checkbox:focus,
+.control-group.warning .radio:focus,
+.control-group.warning input:focus,
+.control-group.warning select:focus,
+.control-group.warning textarea:focus {
+ border-color:#a47e3c;
+ -webkit-box-shadow:0 0 6px #dbc59e;
+ -moz-box-shadow:0 0 6px #dbc59e;
+ box-shadow:0 0 6px #dbc59e;
+ }
+.control-group.warning .input-prepend .add-on,
+.control-group.warning .input-append .add-on {
+ color:#c09853;
+ background-color:#fcf8e3;
+ border-color:#c09853;
+ }
+.control-group.error > label,
+.control-group.error .help-block,
+.control-group.error .help-inline {
+ color:#b94a48;
+ }
+.control-group.error .checkbox,
+.control-group.error .radio,
+.control-group.error input,
+.control-group.error select,
+.control-group.error textarea {
+ color:#b94a48;
+ border-color:#b94a48;
+ }
+.control-group.error .checkbox:focus,
+.control-group.error .radio:focus,
+.control-group.error input:focus,
+.control-group.error select:focus,
+.control-group.error textarea:focus {
+ border-color:#953b39;
+ -webkit-box-shadow:0 0 6px #d59392;
+ -moz-box-shadow:0 0 6px #d59392;
+ box-shadow:0 0 6px #d59392;
+ }
+.control-group.error .input-prepend .add-on,
+.control-group.error .input-append .add-on {
+ color:#b94a48;
+ background-color:#f2dede;
+ border-color:#b94a48;
+ }
+.control-group.success > label,
+.control-group.success .help-block,
+.control-group.success .help-inline {
+ color:#468847;
+ }
+.control-group.success .checkbox,
+.control-group.success .radio,
+.control-group.success input,
+.control-group.success select,
+.control-group.success textarea {
+ color:#468847;
+ border-color:#468847;
+ }
+.control-group.success .checkbox:focus,
+.control-group.success .radio:focus,
+.control-group.success input:focus,
+.control-group.success select:focus,
+.control-group.success textarea:focus {
+ border-color:#356635;
+ -webkit-box-shadow:0 0 6px #7aba7b;
+ -moz-box-shadow:0 0 6px #7aba7b;
+ box-shadow:0 0 6px #7aba7b;
+ }
+.control-group.success .input-prepend .add-on,
+.control-group.success .input-append .add-on {
+ color:#468847;
+ background-color:#dff0d8;
+ border-color:#468847;
+ }
+input:focus:required:invalid,
+textarea:focus:required:invalid,
+select:focus:required:invalid {
+ color:#b94a48;
+ border-color:#ee5f5b;
+ }
+input:focus:required:invalid:focus,
+textarea:focus:required:invalid:focus,
+select:focus:required:invalid:focus {
+ border-color:#e9322d;
+ -webkit-box-shadow:0 0 6px #f8b9b7;
+ -moz-box-shadow:0 0 6px #f8b9b7;
+ box-shadow:0 0 6px #f8b9b7;
+ }
+.form-actions {
+ padding:17px 20px 18px;
+ margin-top:18px;
+ margin-bottom:18px;
+ background-color:#f5f5f5;
+ border-top:1px solid #e5e5e5;
+ *zoom:1;
+ }
+.form-actions:before,
+.form-actions:after {
+ display:table;
+ content:"";
+ }
+.form-actions:after {
+ clear:both;
+ }
+.uneditable-input {
+ overflow:hidden;
+ white-space:nowrap;
+ cursor:not-allowed;
+ background-color:#ffffff;
+ border-color:#eee;
+ -webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ -moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ }
+:-moz-placeholder {
+ color:#999999;
+ }
+:-ms-input-placeholder {
+ color:#999999;
+ }
+::-webkit-input-placeholder {
+ color:#999999;
+ }
+.help-block,
+.help-inline {
+ color:#555555;
+ }
+.help-block {
+ display:block;
+ margin-bottom:9px;
+ }
+.help-inline {
+ display:inline-block;
+ *display:inline;
+ padding-left:5px;
+ vertical-align:middle;
+ *zoom:1;
+ }
+.input-prepend,
+.input-append {
+ margin-bottom:5px;
+ }
+.input-prepend input,
+.input-append input,
+.input-prepend select,
+.input-append select,
+.input-prepend .uneditable-input,
+.input-append .uneditable-input {
+ position:relative;
+ margin-bottom:0;
+ *margin-left:0;
+ vertical-align:middle;
+ -webkit-border-radius:0 3px 3px 0;
+ -moz-border-radius:0 3px 3px 0;
+ border-radius:0 3px 3px 0;
+ }
+.input-prepend input:focus,
+.input-append input:focus,
+.input-prepend select:focus,
+.input-append select:focus,
+.input-prepend .uneditable-input:focus,
+.input-append .uneditable-input:focus {
+ z-index:2;
+ }
+.input-prepend .uneditable-input,
+.input-append .uneditable-input {
+ border-left-color:#ccc;
+ }
+.input-prepend .add-on,
+.input-append .add-on {
+ display:inline-block;
+ width:auto;
+ height:18px;
+ min-width:16px;
+ padding:4px 5px;
+ font-weight:normal;
+ line-height:18px;
+ text-align:center;
+ text-shadow:0 1px 0 #ffffff;
+ vertical-align:middle;
+ background-color:#eeeeee;
+ border:1px solid #ccc;
+ }
+.input-prepend .add-on,
+.input-append .add-on,
+.input-prepend .btn,
+.input-append .btn {
+ margin-left:-1px;
+ -webkit-border-radius:0;
+ -moz-border-radius:0;
+ border-radius:0;
+ }
+.input-prepend .active,
+.input-append .active {
+ background-color:#a9dba9;
+ border-color:#46a546;
+ }
+.input-prepend .add-on,
+.input-prepend .btn {
+ margin-right:-1px;
+ }
+.input-prepend .add-on:first-child,
+.input-prepend .btn:first-child {
+ -webkit-border-radius:3px 0 0 3px;
+ -moz-border-radius:3px 0 0 3px;
+ border-radius:3px 0 0 3px;
+ }
+.input-append input,
+.input-append select,
+.input-append .uneditable-input {
+ -webkit-border-radius:3px 0 0 3px;
+ -moz-border-radius:3px 0 0 3px;
+ border-radius:3px 0 0 3px;
+ }
+.input-append .uneditable-input {
+ border-right-color:#ccc;
+ border-left-color:#eee;
+ }
+.input-append .add-on:last-child,
+.input-append .btn:last-child {
+ -webkit-border-radius:0 3px 3px 0;
+ -moz-border-radius:0 3px 3px 0;
+ border-radius:0 3px 3px 0;
+ }
+.input-prepend.input-append input,
+.input-prepend.input-append select,
+.input-prepend.input-append .uneditable-input {
+ -webkit-border-radius:0;
+ -moz-border-radius:0;
+ border-radius:0;
+ }
+.input-prepend.input-append .add-on:first-child,
+.input-prepend.input-append .btn:first-child {
+ margin-right:-1px;
+ -webkit-border-radius:3px 0 0 3px;
+ -moz-border-radius:3px 0 0 3px;
+ border-radius:3px 0 0 3px;
+ }
+.input-prepend.input-append .add-on:last-child,
+.input-prepend.input-append .btn:last-child {
+ margin-left:-1px;
+ -webkit-border-radius:0 3px 3px 0;
+ -moz-border-radius:0 3px 3px 0;
+ border-radius:0 3px 3px 0;
+ }
+.search-query {
+ padding-right:14px;
+ padding-right:4px \9;
+ padding-left:14px;
+ padding-left:4px \9;
+ /* IE7-8 doesn't have border-radius, so don't indent the padding */
+
+ margin-bottom:0;
+ -webkit-border-radius:14px;
+ -moz-border-radius:14px;
+ border-radius:14px;
+ }
+.form-search input,
+.form-inline input,
+.form-horizontal input,
+.form-search textarea,
+.form-inline textarea,
+.form-horizontal textarea,
+.form-search select,
+.form-inline select,
+.form-horizontal select,
+.form-search .help-inline,
+.form-inline .help-inline,
+.form-horizontal .help-inline,
+.form-search .uneditable-input,
+.form-inline .uneditable-input,
+.form-horizontal .uneditable-input,
+.form-search .input-prepend,
+.form-inline .input-prepend,
+.form-horizontal .input-prepend,
+.form-search .input-append,
+.form-inline .input-append,
+.form-horizontal .input-append {
+ display:inline-block;
+ *display:inline;
+ margin-bottom:0;
+ *zoom:1;
+ }
+.form-search .hide,
+.form-inline .hide,
+.form-horizontal .hide {
+ display:none;
+ }
+.form-search label,
+.form-inline label {
+ display:inline-block;
+ }
+.form-search .input-append,
+.form-inline .input-append,
+.form-search .input-prepend,
+.form-inline .input-prepend {
+ margin-bottom:0;
+ }
+.form-search .radio,
+.form-search .checkbox,
+.form-inline .radio,
+.form-inline .checkbox {
+ padding-left:0;
+ margin-bottom:0;
+ vertical-align:middle;
+ }
+.form-search .radio input[type="radio"],
+.form-search .checkbox input[type="checkbox"],
+.form-inline .radio input[type="radio"],
+.form-inline .checkbox input[type="checkbox"] {
+ float:left;
+ margin-right:3px;
+ margin-left:0;
+ }
+.control-group {
+ margin-bottom:9px;
+ }
+legend + .control-group {
+ margin-top:18px;
+ -webkit-margin-top-collapse:separate;
+ }
+.form-horizontal .control-group {
+ margin-bottom:18px;
+ *zoom:1;
+ }
+.form-horizontal .control-group:before,
+.form-horizontal .control-group:after {
+ display:table;
+ content:"";
+ }
+.form-horizontal .control-group:after {
+ clear:both;
+ }
+.form-horizontal .control-label {
+ float:left;
+ width:140px;
+ padding-top:5px;
+ text-align:right;
+ }
+.form-horizontal .controls {
+ *display:inline-block;
+ *padding-left:20px;
+ margin-left:160px;
+ *margin-left:0;
+ }
+.form-horizontal .controls:first-child {
+ *padding-left:160px;
+ }
+.form-horizontal .help-block {
+ margin-top:9px;
+ margin-bottom:0;
+ }
+.form-horizontal .form-actions {
+ padding-left:160px;
+ }
+table {
+ max-width:100%;
+ background-color:transparent;
+ border-collapse:collapse;
+ border-spacing:0;
+ }
+.table {
+ width:100%;
+ margin-bottom:18px;
+ }
+.table th,
+.table td {
+ padding:8px;
+ line-height:18px;
+ text-align:left;
+ vertical-align:top;
+ border-top:1px solid #dddddd;
+ }
+.table th {
+ font-weight:bold;
+ }
+.table thead th {
+ vertical-align:bottom;
+ }
+.table caption + thead tr:first-child th,
+.table caption + thead tr:first-child td,
+.table colgroup + thead tr:first-child th,
+.table colgroup + thead tr:first-child td,
+.table thead:first-child tr:first-child th,
+.table thead:first-child tr:first-child td {
+ border-top:0;
+ }
+.table tbody + tbody {
+ border-top:2px solid #dddddd;
+ }
+.table-condensed th,
+.table-condensed td {
+ padding:4px 5px;
+ }
+.table-bordered {
+ border:1px solid #dddddd;
+ border-collapse:separate;
+ *border-collapse:collapsed;
+ border-left:0;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.table-bordered th,
+.table-bordered td {
+ border-left:1px solid #dddddd;
+ }
+.table-bordered caption + thead tr:first-child th,
+.table-bordered caption + tbody tr:first-child th,
+.table-bordered caption + tbody tr:first-child td,
+.table-bordered colgroup + thead tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child td,
+.table-bordered thead:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child td {
+ border-top:0;
+ }
+.table-bordered thead:first-child tr:first-child th:first-child,
+.table-bordered tbody:first-child tr:first-child td:first-child {
+ -webkit-border-top-left-radius:4px;
+ border-top-left-radius:4px;
+ -moz-border-radius-topleft:4px;
+ }
+.table-bordered thead:first-child tr:first-child th:last-child,
+.table-bordered tbody:first-child tr:first-child td:last-child {
+ -webkit-border-top-right-radius:4px;
+ border-top-right-radius:4px;
+ -moz-border-radius-topright:4px;
+ }
+.table-bordered thead:last-child tr:last-child th:first-child,
+.table-bordered tbody:last-child tr:last-child td:first-child {
+ -webkit-border-radius:0 0 0 4px;
+ -moz-border-radius:0 0 0 4px;
+ border-radius:0 0 0 4px;
+ -webkit-border-bottom-left-radius:4px;
+ border-bottom-left-radius:4px;
+ -moz-border-radius-bottomleft:4px;
+ }
+.table-bordered thead:last-child tr:last-child th:last-child,
+.table-bordered tbody:last-child tr:last-child td:last-child {
+ -webkit-border-bottom-right-radius:4px;
+ border-bottom-right-radius:4px;
+ -moz-border-radius-bottomright:4px;
+ }
+.table-striped tbody tr:nth-child(odd) td,
+.table-striped tbody tr:nth-child(odd) th {
+ background-color:#f9f9f9;
+ }
+.table tbody tr:hover td,
+.table tbody tr:hover th {
+ background-color:#f5f5f5;
+ }
+table .span1 {
+ float:none;
+ width:44px;
+ margin-left:0;
+ }
+table .span2 {
+ float:none;
+ width:124px;
+ margin-left:0;
+ }
+table .span3 {
+ float:none;
+ width:204px;
+ margin-left:0;
+ }
+table .span4 {
+ float:none;
+ width:284px;
+ margin-left:0;
+ }
+table .span5 {
+ float:none;
+ width:364px;
+ margin-left:0;
+ }
+table .span6 {
+ float:none;
+ width:444px;
+ margin-left:0;
+ }
+table .span7 {
+ float:none;
+ width:524px;
+ margin-left:0;
+ }
+table .span8 {
+ float:none;
+ width:604px;
+ margin-left:0;
+ }
+table .span9 {
+ float:none;
+ width:684px;
+ margin-left:0;
+ }
+table .span10 {
+ float:none;
+ width:764px;
+ margin-left:0;
+ }
+table .span11 {
+ float:none;
+ width:844px;
+ margin-left:0;
+ }
+table .span12 {
+ float:none;
+ width:924px;
+ margin-left:0;
+ }
+table .span13 {
+ float:none;
+ width:1004px;
+ margin-left:0;
+ }
+table .span14 {
+ float:none;
+ width:1084px;
+ margin-left:0;
+ }
+table .span15 {
+ float:none;
+ width:1164px;
+ margin-left:0;
+ }
+table .span16 {
+ float:none;
+ width:1244px;
+ margin-left:0;
+ }
+table .span17 {
+ float:none;
+ width:1324px;
+ margin-left:0;
+ }
+table .span18 {
+ float:none;
+ width:1404px;
+ margin-left:0;
+ }
+table .span19 {
+ float:none;
+ width:1484px;
+ margin-left:0;
+ }
+table .span20 {
+ float:none;
+ width:1564px;
+ margin-left:0;
+ }
+table .span21 {
+ float:none;
+ width:1644px;
+ margin-left:0;
+ }
+table .span22 {
+ float:none;
+ width:1724px;
+ margin-left:0;
+ }
+table .span23 {
+ float:none;
+ width:1804px;
+ margin-left:0;
+ }
+table .span24 {
+ float:none;
+ width:1884px;
+ margin-left:0;
+ }
+[class^="icon-"],
+[class*=" icon-"] {
+ display:inline-block;
+ width:14px;
+ height:14px;
+ *margin-right:.3em;
+ line-height:14px;
+ vertical-align:text-top;
+ background-image:url("../img/glyphicons-halflings.png");
+ background-position:14px 14px;
+ background-repeat:no-repeat;
+ }
+[class^="icon-"]:last-child,
+[class*=" icon-"]:last-child {
+ *margin-left:0;
+ }
+.icon-white {
+ background-image:url("../img/glyphicons-halflings-white.png");
+ }
+.icon-glass {
+ background-position:0 0;
+ }
+.icon-music {
+ background-position:-24px 0;
+ }
+.icon-search {
+ background-position:-48px 0;
+ }
+.icon-envelope {
+ background-position:-72px 0;
+ }
+.icon-heart {
+ background-position:-96px 0;
+ }
+.icon-star {
+ background-position:-120px 0;
+ }
+.icon-star-empty {
+ background-position:-144px 0;
+ }
+.icon-user {
+ background-position:-168px 0;
+ }
+.icon-film {
+ background-position:-192px 0;
+ }
+.icon-th-large {
+ background-position:-216px 0;
+ }
+.icon-th {
+ background-position:-240px 0;
+ }
+.icon-th-list {
+ background-position:-264px 0;
+ }
+.icon-ok {
+ background-position:-288px 0;
+ }
+.icon-remove {
+ background-position:-312px 0;
+ }
+.icon-zoom-in {
+ background-position:-336px 0;
+ }
+.icon-zoom-out {
+ background-position:-360px 0;
+ }
+.icon-off {
+ background-position:-384px 0;
+ }
+.icon-signal {
+ background-position:-408px 0;
+ }
+.icon-cog {
+ background-position:-432px 0;
+ }
+.icon-trash {
+ background-position:-456px 0;
+ }
+.icon-home {
+ background-position:0 -24px;
+ }
+.icon-file {
+ background-position:-24px -24px;
+ }
+.icon-time {
+ background-position:-48px -24px;
+ }
+.icon-road {
+ background-position:-72px -24px;
+ }
+.icon-download-alt {
+ background-position:-96px -24px;
+ }
+.icon-download {
+ background-position:-120px -24px;
+ }
+.icon-upload {
+ background-position:-144px -24px;
+ }
+.icon-inbox {
+ background-position:-168px -24px;
+ }
+.icon-play-circle {
+ background-position:-192px -24px;
+ }
+.icon-repeat {
+ background-position:-216px -24px;
+ }
+.icon-refresh {
+ background-position:-240px -24px;
+ }
+.icon-list-alt {
+ background-position:-264px -24px;
+ }
+.icon-lock {
+ background-position:-287px -24px;
+ }
+.icon-flag {
+ background-position:-312px -24px;
+ }
+.icon-headphones {
+ background-position:-336px -24px;
+ }
+.icon-volume-off {
+ background-position:-360px -24px;
+ }
+.icon-volume-down {
+ background-position:-384px -24px;
+ }
+.icon-volume-up {
+ background-position:-408px -24px;
+ }
+.icon-qrcode {
+ background-position:-432px -24px;
+ }
+.icon-barcode {
+ background-position:-456px -24px;
+ }
+.icon-tag {
+ background-position:0 -48px;
+ }
+.icon-tags {
+ background-position:-25px -48px;
+ }
+.icon-book {
+ background-position:-48px -48px;
+ }
+.icon-bookmark {
+ background-position:-72px -48px;
+ }
+.icon-print {
+ background-position:-96px -48px;
+ }
+.icon-camera {
+ background-position:-120px -48px;
+ }
+.icon-font {
+ background-position:-144px -48px;
+ }
+.icon-bold {
+ background-position:-167px -48px;
+ }
+.icon-italic {
+ background-position:-192px -48px;
+ }
+.icon-text-height {
+ background-position:-216px -48px;
+ }
+.icon-text-width {
+ background-position:-240px -48px;
+ }
+.icon-align-left {
+ background-position:-264px -48px;
+ }
+.icon-align-center {
+ background-position:-288px -48px;
+ }
+.icon-align-right {
+ background-position:-312px -48px;
+ }
+.icon-align-justify {
+ background-position:-336px -48px;
+ }
+.icon-list {
+ background-position:-360px -48px;
+ }
+.icon-indent-left {
+ background-position:-384px -48px;
+ }
+.icon-indent-right {
+ background-position:-408px -48px;
+ }
+.icon-facetime-video {
+ background-position:-432px -48px;
+ }
+.icon-picture {
+ background-position:-456px -48px;
+ }
+.icon-pencil {
+ background-position:0 -72px;
+ }
+.icon-map-marker {
+ background-position:-24px -72px;
+ }
+.icon-adjust {
+ background-position:-48px -72px;
+ }
+.icon-tint {
+ background-position:-72px -72px;
+ }
+.icon-edit {
+ background-position:-96px -72px;
+ }
+.icon-share {
+ background-position:-120px -72px;
+ }
+.icon-check {
+ background-position:-144px -72px;
+ }
+.icon-move {
+ background-position:-168px -72px;
+ }
+.icon-step-backward {
+ background-position:-192px -72px;
+ }
+.icon-fast-backward {
+ background-position:-216px -72px;
+ }
+.icon-backward {
+ background-position:-240px -72px;
+ }
+.icon-play {
+ background-position:-264px -72px;
+ }
+.icon-pause {
+ background-position:-288px -72px;
+ }
+.icon-stop {
+ background-position:-312px -72px;
+ }
+.icon-forward {
+ background-position:-336px -72px;
+ }
+.icon-fast-forward {
+ background-position:-360px -72px;
+ }
+.icon-step-forward {
+ background-position:-384px -72px;
+ }
+.icon-eject {
+ background-position:-408px -72px;
+ }
+.icon-chevron-left {
+ background-position:-432px -72px;
+ }
+.icon-chevron-right {
+ background-position:-456px -72px;
+ }
+.icon-plus-sign {
+ background-position:0 -96px;
+ }
+.icon-minus-sign {
+ background-position:-24px -96px;
+ }
+.icon-remove-sign {
+ background-position:-48px -96px;
+ }
+.icon-ok-sign {
+ background-position:-72px -96px;
+ }
+.icon-question-sign {
+ background-position:-96px -96px;
+ }
+.icon-info-sign {
+ background-position:-120px -96px;
+ }
+.icon-screenshot {
+ background-position:-144px -96px;
+ }
+.icon-remove-circle {
+ background-position:-168px -96px;
+ }
+.icon-ok-circle {
+ background-position:-192px -96px;
+ }
+.icon-ban-circle {
+ background-position:-216px -96px;
+ }
+.icon-arrow-left {
+ background-position:-240px -96px;
+ }
+.icon-arrow-right {
+ background-position:-264px -96px;
+ }
+.icon-arrow-up {
+ background-position:-289px -96px;
+ }
+.icon-arrow-down {
+ background-position:-312px -96px;
+ }
+.icon-share-alt {
+ background-position:-336px -96px;
+ }
+.icon-resize-full {
+ background-position:-360px -96px;
+ }
+.icon-resize-small {
+ background-position:-384px -96px;
+ }
+.icon-plus {
+ background-position:-408px -96px;
+ }
+.icon-minus {
+ background-position:-433px -96px;
+ }
+.icon-asterisk {
+ background-position:-456px -96px;
+ }
+.icon-exclamation-sign {
+ background-position:0 -120px;
+ }
+.icon-gift {
+ background-position:-24px -120px;
+ }
+.icon-leaf {
+ background-position:-48px -120px;
+ }
+.icon-fire {
+ background-position:-72px -120px;
+ }
+.icon-eye-open {
+ background-position:-96px -120px;
+ }
+.icon-eye-close {
+ background-position:-120px -120px;
+ }
+.icon-warning-sign {
+ background-position:-144px -120px;
+ }
+.icon-plane {
+ background-position:-168px -120px;
+ }
+.icon-calendar {
+ background-position:-192px -120px;
+ }
+.icon-random {
+ background-position:-216px -120px;
+ }
+.icon-comment {
+ background-position:-240px -120px;
+ }
+.icon-magnet {
+ background-position:-264px -120px;
+ }
+.icon-chevron-up {
+ background-position:-288px -120px;
+ }
+.icon-chevron-down {
+ background-position:-313px -119px;
+ }
+.icon-retweet {
+ background-position:-336px -120px;
+ }
+.icon-shopping-cart {
+ background-position:-360px -120px;
+ }
+.icon-folder-close {
+ background-position:-384px -120px;
+ }
+.icon-folder-open {
+ background-position:-408px -120px;
+ }
+.icon-resize-vertical {
+ background-position:-432px -119px;
+ }
+.icon-resize-horizontal {
+ background-position:-456px -118px;
+ }
+.icon-hdd {
+ background-position:0 -144px;
+ }
+.icon-bullhorn {
+ background-position:-24px -144px;
+ }
+.icon-bell {
+ background-position:-48px -144px;
+ }
+.icon-certificate {
+ background-position:-72px -144px;
+ }
+.icon-thumbs-up {
+ background-position:-96px -144px;
+ }
+.icon-thumbs-down {
+ background-position:-120px -144px;
+ }
+.icon-hand-right {
+ background-position:-144px -144px;
+ }
+.icon-hand-left {
+ background-position:-168px -144px;
+ }
+.icon-hand-up {
+ background-position:-192px -144px;
+ }
+.icon-hand-down {
+ background-position:-216px -144px;
+ }
+.icon-circle-arrow-right {
+ background-position:-240px -144px;
+ }
+.icon-circle-arrow-left {
+ background-position:-264px -144px;
+ }
+.icon-circle-arrow-up {
+ background-position:-288px -144px;
+ }
+.icon-circle-arrow-down {
+ background-position:-312px -144px;
+ }
+.icon-globe {
+ background-position:-336px -144px;
+ }
+.icon-wrench {
+ background-position:-360px -144px;
+ }
+.icon-tasks {
+ background-position:-384px -144px;
+ }
+.icon-filter {
+ background-position:-408px -144px;
+ }
+.icon-briefcase {
+ background-position:-432px -144px;
+ }
+.icon-fullscreen {
+ background-position:-456px -144px;
+ }
+.dropup,
+.dropdown {
+ position:relative;
+ }
+.dropdown-toggle {
+ *margin-bottom:-3px;
+ }
+.dropdown-toggle:active,
+.open .dropdown-toggle {
+ outline:0;
+ }
+.caret {
+ display:inline-block;
+ width:0;
+ height:0;
+ vertical-align:top;
+ border-top:4px solid #000000;
+ border-right:4px solid transparent;
+ border-left:4px solid transparent;
+ content:"";
+ opacity:0.3;
+ filter:alpha(opacity=30);
+ }
+.dropdown .caret {
+ margin-top:8px;
+ margin-left:2px;
+ }
+.dropdown:hover .caret,
+.open .caret {
+ opacity:1;
+ filter:alpha(opacity=100);
+ }
+.dropdown-menu {
+ position:absolute;
+ top:100%;
+ left:0;
+ z-index:1000;
+ display:none;
+ float:left;
+ min-width:160px;
+ padding:4px 0;
+ margin:1px 0 0;
+ list-style:none;
+ background-color:#ffffff;
+ border:1px solid #ccc;
+ border:1px solid rgba(0, 0, 0, 0.2);
+ *border-right-width:2px;
+ *border-bottom-width:2px;
+ -webkit-border-radius:5px;
+ -moz-border-radius:5px;
+ border-radius:5px;
+ -webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-background-clip:padding-box;
+ -moz-background-clip:padding;
+ background-clip:padding-box;
+ }
+.dropdown-menu.pull-right {
+ right:0;
+ left:auto;
+ }
+.dropdown-menu .divider {
+ *width:100%;
+ height:1px;
+ margin:8px 1px;
+ *margin:-5px 0 5px;
+ overflow:hidden;
+ background-color:#e5e5e5;
+ border-bottom:1px solid #ffffff;
+ }
+.dropdown-menu a {
+ display:block;
+ padding:3px 15px;
+ clear:both;
+ font-weight:normal;
+ line-height:18px;
+ color:#333333;
+ white-space:nowrap;
+ }
+.dropdown-menu li > a:hover,
+.dropdown-menu .active > a,
+.dropdown-menu .active > a:hover {
+ color:#ffffff;
+ text-decoration:none;
+ background-color:#0088cc;
+ }
+.open {
+ *z-index:1000;
+ }
+.open > .dropdown-menu {
+ display:block;
+ }
+.pull-right > .dropdown-menu {
+ right:0;
+ left:auto;
+ }
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top:0;
+ border-bottom:4px solid #000000;
+ content:"\2191";
+ }
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top:auto;
+ bottom:100%;
+ margin-bottom:1px;
+ }
+.typeahead {
+ margin-top:2px;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.well {
+ min-height:20px;
+ padding:19px;
+ margin-bottom:20px;
+ background-color:#f5f5f5;
+ border:1px solid #eee;
+ border:1px solid rgba(0, 0, 0, 0.05);
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ }
+.well blockquote {
+ border-color:#ddd;
+ border-color:rgba(0, 0, 0, 0.15);
+ }
+.well-large {
+ padding:24px;
+ -webkit-border-radius:6px;
+ -moz-border-radius:6px;
+ border-radius:6px;
+ }
+.well-small {
+ padding:9px;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ }
+.fade {
+ opacity:0;
+ -webkit-transition:opacity 0.15s linear;
+ -moz-transition:opacity 0.15s linear;
+ -ms-transition:opacity 0.15s linear;
+ -o-transition:opacity 0.15s linear;
+ transition:opacity 0.15s linear;
+ }
+.fade.in {
+ opacity:1;
+ }
+.collapse {
+ position:relative;
+ height:0;
+ overflow:hidden;
+ -webkit-transition:height 0.35s ease;
+ -moz-transition:height 0.35s ease;
+ -ms-transition:height 0.35s ease;
+ -o-transition:height 0.35s ease;
+ transition:height 0.35s ease;
+ }
+.collapse.in {
+ height:auto;
+ }
+.close {
+ float:right;
+ font-size:20px;
+ font-weight:bold;
+ line-height:18px;
+ color:#000000;
+ text-shadow:0 1px 0 #ffffff;
+ opacity:0.2;
+ filter:alpha(opacity=20);
+ }
+.close:hover {
+ color:#000000;
+ text-decoration:none;
+ cursor:pointer;
+ opacity:0.4;
+ filter:alpha(opacity=40);
+ }
+button.close {
+ padding:0;
+ cursor:pointer;
+ background:transparent;
+ border:0;
+ -webkit-appearance:none;
+ }
+.btn {
+ display:inline-block;
+ *display:inline;
+ padding:4px 10px 4px;
+ margin-bottom:0;
+ *margin-left:.3em;
+ font-size:13px;
+ line-height:18px;
+ *line-height:20px;
+ color:#333333;
+ text-align:center;
+ text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);
+ vertical-align:middle;
+ cursor:pointer;
+ background-color:#f5f5f5;
+ *background-color:#e6e6e6;
+ background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
+ background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image:linear-gradient(top, #ffffff, #e6e6e6);
+ background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);
+ background-repeat:repeat-x;
+ border:1px solid #cccccc;
+ *border:0;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ border-color:#e6e6e6 #e6e6e6 #bfbfbf;
+ border-bottom-color:#b3b3b3;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ *zoom:1;
+ -webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ }
+.btn:hover,
+.btn:active,
+.btn.active,
+.btn.disabled,
+.btn[disabled] {
+ background-color:#e6e6e6;
+ *background-color:#d9d9d9;
+ }
+.btn:active,
+.btn.active {
+ background-color:#cccccc \9;
+ }
+.btn:first-child {
+ *margin-left:0;
+ }
+.btn:hover {
+ color:#333333;
+ text-decoration:none;
+ background-color:#e6e6e6;
+ *background-color:#d9d9d9;
+ /* Buttons in IE7 don't get borders, so darken on hover */
+
+ background-position:0 -15px;
+ -webkit-transition:background-position 0.1s linear;
+ -moz-transition:background-position 0.1s linear;
+ -ms-transition:background-position 0.1s linear;
+ -o-transition:background-position 0.1s linear;
+ transition:background-position 0.1s linear;
+ }
+.btn:focus {
+ outline:thin dotted #333;
+ outline:5px auto -webkit-focus-ring-color;
+ outline-offset:-2px;
+ }
+.btn.active,
+.btn:active {
+ background-color:#e6e6e6;
+ background-color:#d9d9d9 \9;
+ background-image:none;
+ outline:0;
+ -webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ }
+.btn.disabled,
+.btn[disabled] {
+ cursor:default;
+ background-color:#e6e6e6;
+ background-image:none;
+ opacity:0.65;
+ filter:alpha(opacity=65);
+ -webkit-box-shadow:none;
+ -moz-box-shadow:none;
+ box-shadow:none;
+ }
+.btn-large {
+ padding:9px 14px;
+ font-size:15px;
+ line-height:normal;
+ -webkit-border-radius:5px;
+ -moz-border-radius:5px;
+ border-radius:5px;
+ }
+.btn-large [class^="icon-"] {
+ margin-top:1px;
+ }
+.btn-small {
+ padding:5px 9px;
+ font-size:11px;
+ line-height:16px;
+ }
+.btn-small [class^="icon-"] {
+ margin-top:-1px;
+ }
+.btn-mini {
+ padding:2px 6px;
+ font-size:11px;
+ line-height:14px;
+ }
+.btn-primary,
+.btn-primary:hover,
+.btn-warning,
+.btn-warning:hover,
+.btn-danger,
+.btn-danger:hover,
+.btn-success,
+.btn-success:hover,
+.btn-info,
+.btn-info:hover,
+.btn-inverse,
+.btn-inverse:hover {
+ color:#ffffff;
+ text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);
+ }
+.btn-primary.active,
+.btn-warning.active,
+.btn-danger.active,
+.btn-success.active,
+.btn-info.active,
+.btn-inverse.active {
+ color:rgba(255, 255, 255, 0.75);
+ }
+.btn {
+ border-color:#ccc;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ }
+.btn-primary {
+ background-color:#0074cc;
+ *background-color:#0055cc;
+ background-image:-ms-linear-gradient(top, #0088cc, #0055cc);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));
+ background-image:-webkit-linear-gradient(top, #0088cc, #0055cc);
+ background-image:-o-linear-gradient(top, #0088cc, #0055cc);
+ background-image:-moz-linear-gradient(top, #0088cc, #0055cc);
+ background-image:linear-gradient(top, #0088cc, #0055cc);
+ background-repeat:repeat-x;
+ border-color:#0055cc #0055cc #003580;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-primary:hover,
+.btn-primary:active,
+.btn-primary.active,
+.btn-primary.disabled,
+.btn-primary[disabled] {
+ background-color:#0055cc;
+ *background-color:#004ab3;
+ }
+.btn-primary:active,
+.btn-primary.active {
+ background-color:#004099 \9;
+ }
+.btn-warning {
+ background-color:#faa732;
+ *background-color:#f89406;
+ background-image:-ms-linear-gradient(top, #fbb450, #f89406);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image:-webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image:-o-linear-gradient(top, #fbb450, #f89406);
+ background-image:-moz-linear-gradient(top, #fbb450, #f89406);
+ background-image:linear-gradient(top, #fbb450, #f89406);
+ background-repeat:repeat-x;
+ border-color:#f89406 #f89406 #ad6704;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-warning:hover,
+.btn-warning:active,
+.btn-warning.active,
+.btn-warning.disabled,
+.btn-warning[disabled] {
+ background-color:#f89406;
+ *background-color:#df8505;
+ }
+.btn-warning:active,
+.btn-warning.active {
+ background-color:#c67605 \9;
+ }
+.btn-danger {
+ background-color:#da4f49;
+ *background-color:#bd362f;
+ background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
+ background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image:linear-gradient(top, #ee5f5b, #bd362f);
+ background-repeat:repeat-x;
+ border-color:#bd362f #bd362f #802420;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-danger:hover,
+.btn-danger:active,
+.btn-danger.active,
+.btn-danger.disabled,
+.btn-danger[disabled] {
+ background-color:#bd362f;
+ *background-color:#a9302a;
+ }
+.btn-danger:active,
+.btn-danger.active {
+ background-color:#942a25 \9;
+ }
+.btn-success {
+ background-color:#5bb75b;
+ *background-color:#51a351;
+ background-image:-ms-linear-gradient(top, #62c462, #51a351);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
+ background-image:-webkit-linear-gradient(top, #62c462, #51a351);
+ background-image:-o-linear-gradient(top, #62c462, #51a351);
+ background-image:-moz-linear-gradient(top, #62c462, #51a351);
+ background-image:linear-gradient(top, #62c462, #51a351);
+ background-repeat:repeat-x;
+ border-color:#51a351 #51a351 #387038;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-success:hover,
+.btn-success:active,
+.btn-success.active,
+.btn-success.disabled,
+.btn-success[disabled] {
+ background-color:#51a351;
+ *background-color:#499249;
+ }
+.btn-success:active,
+.btn-success.active {
+ background-color:#408140 \9;
+ }
+.btn-info {
+ background-color:#49afcd;
+ *background-color:#2f96b4;
+ background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
+ background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image:linear-gradient(top, #5bc0de, #2f96b4);
+ background-repeat:repeat-x;
+ border-color:#2f96b4 #2f96b4 #1f6377;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-info:hover,
+.btn-info:active,
+.btn-info.active,
+.btn-info.disabled,
+.btn-info[disabled] {
+ background-color:#2f96b4;
+ *background-color:#2a85a0;
+ }
+.btn-info:active,
+.btn-info.active {
+ background-color:#24748c \9;
+ }
+.btn-inverse {
+ background-color:#414141;
+ *background-color:#222222;
+ background-image:-ms-linear-gradient(top, #555555, #222222);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));
+ background-image:-webkit-linear-gradient(top, #555555, #222222);
+ background-image:-o-linear-gradient(top, #555555, #222222);
+ background-image:-moz-linear-gradient(top, #555555, #222222);
+ background-image:linear-gradient(top, #555555, #222222);
+ background-repeat:repeat-x;
+ border-color:#222222 #222222 #000000;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ }
+.btn-inverse:hover,
+.btn-inverse:active,
+.btn-inverse.active,
+.btn-inverse.disabled,
+.btn-inverse[disabled] {
+ background-color:#222222;
+ *background-color:#151515;
+ }
+.btn-inverse:active,
+.btn-inverse.active {
+ background-color:#080808 \9;
+ }
+button.btn,
+input[type="submit"].btn {
+ *padding-top:2px;
+ *padding-bottom:2px;
+ }
+button.btn::-moz-focus-inner,
+input[type="submit"].btn::-moz-focus-inner {
+ padding:0;
+ border:0;
+ }
+button.btn.btn-large,
+input[type="submit"].btn.btn-large {
+ *padding-top:7px;
+ *padding-bottom:7px;
+ }
+button.btn.btn-small,
+input[type="submit"].btn.btn-small {
+ *padding-top:3px;
+ *padding-bottom:3px;
+ }
+button.btn.btn-mini,
+input[type="submit"].btn.btn-mini {
+ *padding-top:1px;
+ *padding-bottom:1px;
+ }
+.btn-group {
+ position:relative;
+ *margin-left:.3em;
+ *zoom:1;
+ }
+.btn-group:before,
+.btn-group:after {
+ display:table;
+ content:"";
+ }
+.btn-group:after {
+ clear:both;
+ }
+.btn-group:first-child {
+ *margin-left:0;
+ }
+.btn-group + .btn-group {
+ margin-left:5px;
+ }
+.btn-toolbar {
+ margin-top:9px;
+ margin-bottom:9px;
+ }
+.btn-toolbar .btn-group {
+ display:inline-block;
+ *display:inline;
+ /* IE7 inline-block hack */
+
+ *zoom:1;
+ }
+.btn-group > .btn {
+ position:relative;
+ float:left;
+ margin-left:-1px;
+ -webkit-border-radius:0;
+ -moz-border-radius:0;
+ border-radius:0;
+ }
+.btn-group > .btn:first-child {
+ margin-left:0;
+ -webkit-border-bottom-left-radius:4px;
+ border-bottom-left-radius:4px;
+ -webkit-border-top-left-radius:4px;
+ border-top-left-radius:4px;
+ -moz-border-radius-bottomleft:4px;
+ -moz-border-radius-topleft:4px;
+ }
+.btn-group > .btn:last-child,
+.btn-group > .dropdown-toggle {
+ -webkit-border-top-right-radius:4px;
+ border-top-right-radius:4px;
+ -webkit-border-bottom-right-radius:4px;
+ border-bottom-right-radius:4px;
+ -moz-border-radius-topright:4px;
+ -moz-border-radius-bottomright:4px;
+ }
+.btn-group > .btn.large:first-child {
+ margin-left:0;
+ -webkit-border-bottom-left-radius:6px;
+ border-bottom-left-radius:6px;
+ -webkit-border-top-left-radius:6px;
+ border-top-left-radius:6px;
+ -moz-border-radius-bottomleft:6px;
+ -moz-border-radius-topleft:6px;
+ }
+.btn-group > .btn.large:last-child,
+.btn-group > .large.dropdown-toggle {
+ -webkit-border-top-right-radius:6px;
+ border-top-right-radius:6px;
+ -webkit-border-bottom-right-radius:6px;
+ border-bottom-right-radius:6px;
+ -moz-border-radius-topright:6px;
+ -moz-border-radius-bottomright:6px;
+ }
+.btn-group > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group > .btn:active,
+.btn-group > .btn.active {
+ z-index:2;
+ }
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline:0;
+ }
+.btn-group > .dropdown-toggle {
+ *padding-top:4px;
+ padding-right:8px;
+ *padding-bottom:4px;
+ padding-left:8px;
+ -webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ }
+.btn-group > .btn-mini.dropdown-toggle {
+ padding-right:5px;
+ padding-left:5px;
+ }
+.btn-group > .btn-small.dropdown-toggle {
+ *padding-top:4px;
+ *padding-bottom:4px;
+ }
+.btn-group > .btn-large.dropdown-toggle {
+ padding-right:12px;
+ padding-left:12px;
+ }
+.btn-group.open .dropdown-toggle {
+ background-image:none;
+ -webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ }
+.btn-group.open .btn.dropdown-toggle {
+ background-color:#e6e6e6;
+ }
+.btn-group.open .btn-primary.dropdown-toggle {
+ background-color:#0055cc;
+ }
+.btn-group.open .btn-warning.dropdown-toggle {
+ background-color:#f89406;
+ }
+.btn-group.open .btn-danger.dropdown-toggle {
+ background-color:#bd362f;
+ }
+.btn-group.open .btn-success.dropdown-toggle {
+ background-color:#51a351;
+ }
+.btn-group.open .btn-info.dropdown-toggle {
+ background-color:#2f96b4;
+ }
+.btn-group.open .btn-inverse.dropdown-toggle {
+ background-color:#222222;
+ }
+.btn .caret {
+ margin-top:7px;
+ margin-left:0;
+ }
+.btn:hover .caret,
+.open.btn-group .caret {
+ opacity:1;
+ filter:alpha(opacity=100);
+ }
+.btn-mini .caret {
+ margin-top:5px;
+ }
+.btn-small .caret {
+ margin-top:6px;
+ }
+.btn-large .caret {
+ margin-top:6px;
+ border-top-width:5px;
+ border-right-width:5px;
+ border-left-width:5px;
+ }
+.dropup .btn-large .caret {
+ border-top:0;
+ border-bottom:5px solid #000000;
+ }
+.btn-primary .caret,
+.btn-warning .caret,
+.btn-danger .caret,
+.btn-info .caret,
+.btn-success .caret,
+.btn-inverse .caret {
+ border-top-color:#ffffff;
+ border-bottom-color:#ffffff;
+ opacity:0.75;
+ filter:alpha(opacity=75);
+ }
+.alert {
+ padding:8px 35px 8px 14px;
+ margin-bottom:18px;
+ color:#c09853;
+ text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);
+ background-color:#fcf8e3;
+ border:1px solid #fbeed5;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.alert-heading {
+ color:inherit;
+ }
+.alert .close {
+ position:relative;
+ top:-2px;
+ right:-21px;
+ line-height:18px;
+ }
+.alert-success {
+ color:#468847;
+ background-color:#dff0d8;
+ border-color:#d6e9c6;
+ }
+.alert-danger,
+.alert-error {
+ color:#b94a48;
+ background-color:#f2dede;
+ border-color:#eed3d7;
+ }
+.alert-info {
+ color:#3a87ad;
+ background-color:#d9edf7;
+ border-color:#bce8f1;
+ }
+.alert-block {
+ padding-top:14px;
+ padding-bottom:14px;
+ }
+.alert-block > p,
+.alert-block > ul {
+ margin-bottom:0;
+ }
+.alert-block p + p {
+ margin-top:5px;
+ }
+.nav {
+ margin-bottom:18px;
+ margin-left:0;
+ list-style:none;
+ }
+.nav > li > a {
+ display:block;
+ }
+.nav > li > a:hover {
+ text-decoration:none;
+ background-color:#eeeeee;
+ }
+.nav > .pull-right {
+ float:right;
+ }
+.nav .nav-header {
+ display:block;
+ padding:3px 15px;
+ font-size:11px;
+ font-weight:bold;
+ line-height:18px;
+ color:#999999;
+ text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);
+ text-transform:uppercase;
+ }
+.nav li + .nav-header {
+ margin-top:9px;
+ }
+.nav-list {
+ padding-right:15px;
+ padding-left:15px;
+ margin-bottom:0;
+ }
+.nav-list > li > a,
+.nav-list .nav-header {
+ margin-right:-15px;
+ margin-left:-15px;
+ text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);
+ }
+.nav-list > li > a {
+ padding:3px 15px;
+ }
+.nav-list > .active > a,
+.nav-list > .active > a:hover {
+ color:#ffffff;
+ text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);
+ background-color:#0088cc;
+ }
+.nav-list [class^="icon-"] {
+ margin-right:2px;
+ }
+.nav-list .divider {
+ *width:100%;
+ height:1px;
+ margin:8px 1px;
+ *margin:-5px 0 5px;
+ overflow:hidden;
+ background-color:#e5e5e5;
+ border-bottom:1px solid #ffffff;
+ }
+.nav-tabs,
+.nav-pills {
+ *zoom:1;
+ }
+.nav-tabs:before,
+.nav-pills:before,
+.nav-tabs:after,
+.nav-pills:after {
+ display:table;
+ content:"";
+ }
+.nav-tabs:after,
+.nav-pills:after {
+ clear:both;
+ }
+.nav-tabs > li,
+.nav-pills > li {
+ float:left;
+ }
+.nav-tabs > li > a,
+.nav-pills > li > a {
+ padding-right:12px;
+ padding-left:12px;
+ margin-right:2px;
+ line-height:14px;
+ }
+.nav-tabs {
+ border-bottom:1px solid #ddd;
+ }
+.nav-tabs > li {
+ margin-bottom:-1px;
+ }
+.nav-tabs > li > a {
+ padding-top:8px;
+ padding-bottom:8px;
+ line-height:18px;
+ border:1px solid transparent;
+ -webkit-border-radius:4px 4px 0 0;
+ -moz-border-radius:4px 4px 0 0;
+ border-radius:4px 4px 0 0;
+ }
+.nav-tabs > li > a:hover {
+ border-color:#eeeeee #eeeeee #dddddd;
+ }
+.nav-tabs > .active > a,
+.nav-tabs > .active > a:hover {
+ color:#555555;
+ cursor:default;
+ background-color:#ffffff;
+ border:1px solid #ddd;
+ border-bottom-color:transparent;
+ }
+.nav-pills > li > a {
+ padding-top:8px;
+ padding-bottom:8px;
+ margin-top:2px;
+ margin-bottom:2px;
+ -webkit-border-radius:5px;
+ -moz-border-radius:5px;
+ border-radius:5px;
+ }
+.nav-pills > .active > a,
+.nav-pills > .active > a:hover {
+ color:#ffffff;
+ background-color:#0088cc;
+ }
+.nav-stacked > li {
+ float:none;
+ }
+.nav-stacked > li > a {
+ margin-right:0;
+ }
+.nav-tabs.nav-stacked {
+ border-bottom:0;
+ }
+.nav-tabs.nav-stacked > li > a {
+ border:1px solid #ddd;
+ -webkit-border-radius:0;
+ -moz-border-radius:0;
+ border-radius:0;
+ }
+.nav-tabs.nav-stacked > li:first-child > a {
+ -webkit-border-radius:4px 4px 0 0;
+ -moz-border-radius:4px 4px 0 0;
+ border-radius:4px 4px 0 0;
+ }
+.nav-tabs.nav-stacked > li:last-child > a {
+ -webkit-border-radius:0 0 4px 4px;
+ -moz-border-radius:0 0 4px 4px;
+ border-radius:0 0 4px 4px;
+ }
+.nav-tabs.nav-stacked > li > a:hover {
+ z-index:2;
+ border-color:#ddd;
+ }
+.nav-pills.nav-stacked > li > a {
+ margin-bottom:3px;
+ }
+.nav-pills.nav-stacked > li:last-child > a {
+ margin-bottom:1px;
+ }
+.nav-tabs .dropdown-menu {
+ -webkit-border-radius:0 0 5px 5px;
+ -moz-border-radius:0 0 5px 5px;
+ border-radius:0 0 5px 5px;
+ }
+.nav-pills .dropdown-menu {
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.nav-tabs .dropdown-toggle .caret,
+.nav-pills .dropdown-toggle .caret {
+ margin-top:6px;
+ border-top-color:#0088cc;
+ border-bottom-color:#0088cc;
+ }
+.nav-tabs .dropdown-toggle:hover .caret,
+.nav-pills .dropdown-toggle:hover .caret {
+ border-top-color:#005580;
+ border-bottom-color:#005580;
+ }
+.nav-tabs .active .dropdown-toggle .caret,
+.nav-pills .active .dropdown-toggle .caret {
+ border-top-color:#333333;
+ border-bottom-color:#333333;
+ }
+.nav > .dropdown.active > a:hover {
+ color:#000000;
+ cursor:pointer;
+ }
+.nav-tabs .open .dropdown-toggle,
+.nav-pills .open .dropdown-toggle,
+.nav > li.dropdown.open.active > a:hover {
+ color:#ffffff;
+ background-color:#999999;
+ border-color:#999999;
+ }
+.nav li.dropdown.open .caret,
+.nav li.dropdown.open.active .caret,
+.nav li.dropdown.open a:hover .caret {
+ border-top-color:#ffffff;
+ border-bottom-color:#ffffff;
+ opacity:1;
+ filter:alpha(opacity=100);
+ }
+.tabs-stacked .open > a:hover {
+ border-color:#999999;
+ }
+.tabbable {
+ *zoom:1;
+ }
+.tabbable:before,
+.tabbable:after {
+ display:table;
+ content:"";
+ }
+.tabbable:after {
+ clear:both;
+ }
+.tab-content {
+ overflow:auto;
+ }
+.tabs-below > .nav-tabs,
+.tabs-right > .nav-tabs,
+.tabs-left > .nav-tabs {
+ border-bottom:0;
+ }
+.tab-content > .tab-pane,
+.pill-content > .pill-pane {
+ display:none;
+ }
+.tab-content > .active,
+.pill-content > .active {
+ display:block;
+ }
+.tabs-below > .nav-tabs {
+ border-top:1px solid #ddd;
+ }
+.tabs-below > .nav-tabs > li {
+ margin-top:-1px;
+ margin-bottom:0;
+ }
+.tabs-below > .nav-tabs > li > a {
+ -webkit-border-radius:0 0 4px 4px;
+ -moz-border-radius:0 0 4px 4px;
+ border-radius:0 0 4px 4px;
+ }
+.tabs-below > .nav-tabs > li > a:hover {
+ border-top-color:#ddd;
+ border-bottom-color:transparent;
+ }
+.tabs-below > .nav-tabs > .active > a,
+.tabs-below > .nav-tabs > .active > a:hover {
+ border-color:transparent #ddd #ddd #ddd;
+ }
+.tabs-left > .nav-tabs > li,
+.tabs-right > .nav-tabs > li {
+ float:none;
+ }
+.tabs-left > .nav-tabs > li > a,
+.tabs-right > .nav-tabs > li > a {
+ min-width:74px;
+ margin-right:0;
+ margin-bottom:3px;
+ }
+.tabs-left > .nav-tabs {
+ float:left;
+ margin-right:19px;
+ border-right:1px solid #ddd;
+ }
+.tabs-left > .nav-tabs > li > a {
+ margin-right:-1px;
+ -webkit-border-radius:4px 0 0 4px;
+ -moz-border-radius:4px 0 0 4px;
+ border-radius:4px 0 0 4px;
+ }
+.tabs-left > .nav-tabs > li > a:hover {
+ border-color:#eeeeee #dddddd #eeeeee #eeeeee;
+ }
+.tabs-left > .nav-tabs .active > a,
+.tabs-left > .nav-tabs .active > a:hover {
+ border-color:#ddd transparent #ddd #ddd;
+ *border-right-color:#ffffff;
+ }
+.tabs-right > .nav-tabs {
+ float:right;
+ margin-left:19px;
+ border-left:1px solid #ddd;
+ }
+.tabs-right > .nav-tabs > li > a {
+ margin-left:-1px;
+ -webkit-border-radius:0 4px 4px 0;
+ -moz-border-radius:0 4px 4px 0;
+ border-radius:0 4px 4px 0;
+ }
+.tabs-right > .nav-tabs > li > a:hover {
+ border-color:#eeeeee #eeeeee #eeeeee #dddddd;
+ }
+.tabs-right > .nav-tabs .active > a,
+.tabs-right > .nav-tabs .active > a:hover {
+ border-color:#ddd #ddd #ddd transparent;
+ *border-left-color:#ffffff;
+ }
+.navbar {
+ *position:relative;
+ *z-index:2;
+ margin-bottom:18px;
+ overflow:visible;
+ }
+.navbar-inner {
+ min-height:40px;
+ padding-right:20px;
+ padding-left:20px;
+ background-color:#2c2c2c;
+ background-image:-moz-linear-gradient(top, #333333, #222222);
+ background-image:-ms-linear-gradient(top, #333333, #222222);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));
+ background-image:-webkit-linear-gradient(top, #333333, #222222);
+ background-image:-o-linear-gradient(top, #333333, #222222);
+ background-image:linear-gradient(top, #333333, #222222);
+ background-repeat:repeat-x;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
+ -webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+ -moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+ box-shadow:0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
+ }
+.navbar .container {
+ width:auto;
+ }
+.nav-collapse.collapse {
+ height:auto;
+ }
+.navbar {
+ color:#999999;
+ }
+.navbar .brand:hover {
+ text-decoration:none;
+ }
+.navbar .brand {
+ display:block;
+ float:left;
+ padding:8px 20px 12px;
+ margin-left:-20px;
+ font-size:20px;
+ font-weight:200;
+ line-height:1;
+ color:#999999;
+ }
+.navbar .navbar-text {
+ margin-bottom:0;
+ line-height:40px;
+ }
+.navbar .navbar-link {
+ color:#999999;
+ }
+.navbar .navbar-link:hover {
+ color:#ffffff;
+ }
+.navbar .btn,
+.navbar .btn-group {
+ margin-top:5px;
+ }
+.navbar .btn-group .btn {
+ margin:0;
+ }
+.navbar-form {
+ margin-bottom:0;
+ *zoom:1;
+ }
+.navbar-form:before,
+.navbar-form:after {
+ display:table;
+ content:"";
+ }
+.navbar-form:after {
+ clear:both;
+ }
+.navbar-form input,
+.navbar-form select,
+.navbar-form .radio,
+.navbar-form .checkbox {
+ margin-top:5px;
+ }
+.navbar-form input,
+.navbar-form select {
+ display:inline-block;
+ margin-bottom:0;
+ }
+.navbar-form input[type="image"],
+.navbar-form input[type="checkbox"],
+.navbar-form input[type="radio"] {
+ margin-top:3px;
+ }
+.navbar-form .input-append,
+.navbar-form .input-prepend {
+ margin-top:6px;
+ white-space:nowrap;
+ }
+.navbar-form .input-append input,
+.navbar-form .input-prepend input {
+ margin-top:0;
+ }
+.navbar-search {
+ position:relative;
+ float:left;
+ margin-top:6px;
+ margin-bottom:0;
+ }
+.navbar-search .search-query {
+ padding:4px 9px;
+ font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size:13px;
+ font-weight:normal;
+ line-height:1;
+ color:#ffffff;
+ background-color:#626262;
+ border:1px solid #151515;
+ -webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -webkit-transition:none;
+ -moz-transition:none;
+ -ms-transition:none;
+ -o-transition:none;
+ transition:none;
+ }
+.navbar-search .search-query:-moz-placeholder {
+ color:#cccccc;
+ }
+.navbar-search .search-query:-ms-input-placeholder {
+ color:#cccccc;
+ }
+.navbar-search .search-query::-webkit-input-placeholder {
+ color:#cccccc;
+ }
+.navbar-search .search-query:focus,
+.navbar-search .search-query.focused {
+ padding:5px 10px;
+ color:#333333;
+ text-shadow:0 1px 0 #ffffff;
+ background-color:#ffffff;
+ border:0;
+ outline:0;
+ -webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);
+ box-shadow:0 0 3px rgba(0, 0, 0, 0.15);
+ }
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position:fixed;
+ right:0;
+ left:0;
+ z-index:1030;
+ margin-bottom:0;
+ }
+.navbar-fixed-top .navbar-inner,
+.navbar-fixed-bottom .navbar-inner {
+ padding-right:0;
+ padding-left:0;
+ -webkit-border-radius:0;
+ -moz-border-radius:0;
+ border-radius:0;
+ }
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width:940px;
+ }
+.navbar-fixed-top {
+ top:0;
+ }
+.navbar-fixed-bottom {
+ bottom:0;
+ }
+.navbar .nav {
+ position:relative;
+ left:0;
+ display:block;
+ float:left;
+ margin:0 10px 0 0;
+ }
+.navbar .nav.pull-right {
+ float:right;
+ }
+.navbar .nav > li {
+ display:block;
+ float:left;
+ }
+.navbar .nav > li > a {
+ float:none;
+ padding:9px 10px 11px;
+ line-height:19px;
+ color:#999999;
+ text-decoration:none;
+ text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);
+ }
+.navbar .btn {
+ display:inline-block;
+ padding:4px 10px 4px;
+ margin:5px 5px 6px;
+ line-height:18px;
+ }
+.navbar .btn-group {
+ padding:5px 5px 6px;
+ margin:0;
+ }
+.navbar .nav > li > a:hover {
+ color:#ffffff;
+ text-decoration:none;
+ background-color:transparent;
+ }
+.navbar .nav .active > a,
+.navbar .nav .active > a:hover {
+ color:#ffffff;
+ text-decoration:none;
+ background-color:#222222;
+ }
+.navbar .divider-vertical {
+ width:1px;
+ height:40px;
+ margin:0 9px;
+ overflow:hidden;
+ background-color:#222222;
+ border-right:1px solid #333333;
+ }
+.navbar .nav.pull-right {
+ margin-right:0;
+ margin-left:10px;
+ }
+.navbar .btn-navbar {
+ display:none;
+ float:right;
+ padding:7px 10px;
+ margin-right:5px;
+ margin-left:5px;
+ background-color:#2c2c2c;
+ *background-color:#222222;
+ background-image:-ms-linear-gradient(top, #333333, #222222);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));
+ background-image:-webkit-linear-gradient(top, #333333, #222222);
+ background-image:-o-linear-gradient(top, #333333, #222222);
+ background-image:linear-gradient(top, #333333, #222222);
+ background-image:-moz-linear-gradient(top, #333333, #222222);
+ background-repeat:repeat-x;
+ border-color:#222222 #222222 #000000;
+ border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
+ filter:progid:dximagetransform.microsoft.gradient(enabled=false);
+ -webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ -moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ }
+.navbar .btn-navbar:hover,
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active,
+.navbar .btn-navbar.disabled,
+.navbar .btn-navbar[disabled] {
+ background-color:#222222;
+ *background-color:#151515;
+ }
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active {
+ background-color:#080808 \9;
+ }
+.navbar .btn-navbar .icon-bar {
+ display:block;
+ width:18px;
+ height:2px;
+ background-color:#f5f5f5;
+ -webkit-border-radius:1px;
+ -moz-border-radius:1px;
+ border-radius:1px;
+ -webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);
+ -moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);
+ box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);
+ }
+.btn-navbar .icon-bar + .icon-bar {
+ margin-top:3px;
+ }
+.navbar .dropdown-menu:before {
+ position:absolute;
+ top:-7px;
+ left:9px;
+ display:inline-block;
+ border-right:7px solid transparent;
+ border-bottom:7px solid #ccc;
+ border-left:7px solid transparent;
+ border-bottom-color:rgba(0, 0, 0, 0.2);
+ content:'';
+ }
+.navbar .dropdown-menu:after {
+ position:absolute;
+ top:-6px;
+ left:10px;
+ display:inline-block;
+ border-right:6px solid transparent;
+ border-bottom:6px solid #ffffff;
+ border-left:6px solid transparent;
+ content:'';
+ }
+.navbar-fixed-bottom .dropdown-menu:before {
+ top:auto;
+ bottom:-7px;
+ border-top:7px solid #ccc;
+ border-bottom:0;
+ border-top-color:rgba(0, 0, 0, 0.2);
+ }
+.navbar-fixed-bottom .dropdown-menu:after {
+ top:auto;
+ bottom:-6px;
+ border-top:6px solid #ffffff;
+ border-bottom:0;
+ }
+.navbar .nav li.dropdown .dropdown-toggle .caret,
+.navbar .nav li.dropdown.open .caret {
+ border-top-color:#ffffff;
+ border-bottom-color:#ffffff;
+ }
+.navbar .nav li.dropdown.active .caret {
+ opacity:1;
+ filter:alpha(opacity=100);
+ }
+.navbar .nav li.dropdown.open > .dropdown-toggle,
+.navbar .nav li.dropdown.active > .dropdown-toggle,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle {
+ background-color:transparent;
+ }
+.navbar .nav li.dropdown.active > .dropdown-toggle:hover {
+ color:#ffffff;
+ }
+.navbar .pull-right .dropdown-menu,
+.navbar .dropdown-menu.pull-right {
+ right:0;
+ left:auto;
+ }
+.navbar .pull-right .dropdown-menu:before,
+.navbar .dropdown-menu.pull-right:before {
+ right:12px;
+ left:auto;
+ }
+.navbar .pull-right .dropdown-menu:after,
+.navbar .dropdown-menu.pull-right:after {
+ right:13px;
+ left:auto;
+ }
+.breadcrumb {
+ padding:7px 14px;
+ margin:0 0 18px;
+ list-style:none;
+ background-color:#fbfbfb;
+ background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);
+ background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));
+ background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);
+ background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);
+ background-image:linear-gradient(top, #ffffff, #f5f5f5);
+ background-repeat:repeat-x;
+ border:1px solid #ddd;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);
+ -webkit-box-shadow:inset 0 1px 0 #ffffff;
+ -moz-box-shadow:inset 0 1px 0 #ffffff;
+ box-shadow:inset 0 1px 0 #ffffff;
+ }
+.breadcrumb li {
+ display:inline-block;
+ *display:inline;
+ text-shadow:0 1px 0 #ffffff;
+ *zoom:1;
+ }
+.breadcrumb .divider {
+ padding:0 5px;
+ color:#999999;
+ }
+.breadcrumb .active a {
+ color:#333333;
+ }
+.pagination {
+ height:36px;
+ margin:18px 0;
+ }
+.pagination ul {
+ display:inline-block;
+ *display:inline;
+ margin-bottom:0;
+ margin-left:0;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ *zoom:1;
+ -webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);
+ }
+.pagination li {
+ display:inline;
+ }
+.pagination a {
+ float:left;
+ padding:0 14px;
+ line-height:34px;
+ text-decoration:none;
+ border:1px solid #ddd;
+ border-left-width:0;
+ }
+.pagination a:hover,
+.pagination .active a {
+ background-color:#f5f5f5;
+ }
+.pagination .active a {
+ color:#999999;
+ cursor:default;
+ }
+.pagination .disabled span,
+.pagination .disabled a,
+.pagination .disabled a:hover {
+ color:#999999;
+ cursor:default;
+ background-color:transparent;
+ }
+.pagination li:first-child a {
+ border-left-width:1px;
+ -webkit-border-radius:3px 0 0 3px;
+ -moz-border-radius:3px 0 0 3px;
+ border-radius:3px 0 0 3px;
+ }
+.pagination li:last-child a {
+ -webkit-border-radius:0 3px 3px 0;
+ -moz-border-radius:0 3px 3px 0;
+ border-radius:0 3px 3px 0;
+ }
+.pagination-centered {
+ text-align:center;
+ }
+.pagination-right {
+ text-align:right;
+ }
+.pager {
+ margin-bottom:18px;
+ margin-left:0;
+ text-align:center;
+ list-style:none;
+ *zoom:1;
+ }
+.pager:before,
+.pager:after {
+ display:table;
+ content:"";
+ }
+.pager:after {
+ clear:both;
+ }
+.pager li {
+ display:inline;
+ }
+.pager a {
+ display:inline-block;
+ padding:5px 14px;
+ background-color:#fff;
+ border:1px solid #ddd;
+ -webkit-border-radius:15px;
+ -moz-border-radius:15px;
+ border-radius:15px;
+ }
+.pager a:hover {
+ text-decoration:none;
+ background-color:#f5f5f5;
+ }
+.pager .next a {
+ float:right;
+ }
+.pager .previous a {
+ float:left;
+ }
+.pager .disabled a,
+.pager .disabled a:hover {
+ color:#999999;
+ cursor:default;
+ background-color:#fff;
+ }
+.modal-open .dropdown-menu {
+ z-index:2050;
+ }
+.modal-open .dropdown.open {
+ *z-index:2050;
+ }
+.modal-open .popover {
+ z-index:2060;
+ }
+.modal-open .tooltip {
+ z-index:2070;
+ }
+.modal-backdrop {
+ position:fixed;
+ top:0;
+ right:0;
+ bottom:0;
+ left:0;
+ z-index:1040;
+ background-color:#000000;
+ }
+.modal-backdrop.fade {
+ opacity:0;
+ }
+.modal-backdrop,
+.modal-backdrop.fade.in {
+ opacity:0.8;
+ filter:alpha(opacity=80);
+ }
+.modal {
+ position:fixed;
+ top:50%;
+ left:50%;
+ z-index:1050;
+ width:560px;
+ margin:-250px 0 0 -280px;
+ overflow:auto;
+ background-color:#ffffff;
+ border:1px solid #999;
+ border:1px solid rgba(0, 0, 0, 0.3);
+ *border:1px solid #999;
+ -webkit-border-radius:6px;
+ -moz-border-radius:6px;
+ border-radius:6px;
+ -webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ -webkit-background-clip:padding-box;
+ -moz-background-clip:padding-box;
+ background-clip:padding-box;
+ }
+.modal.fade {
+ top:-25%;
+ -webkit-transition:opacity 0.3s linear, top 0.3s ease-out;
+ -moz-transition:opacity 0.3s linear, top 0.3s ease-out;
+ -ms-transition:opacity 0.3s linear, top 0.3s ease-out;
+ -o-transition:opacity 0.3s linear, top 0.3s ease-out;
+ transition:opacity 0.3s linear, top 0.3s ease-out;
+ }
+.modal.fade.in {
+ top:50%;
+ }
+.modal-header {
+ padding:9px 15px;
+ border-bottom:1px solid #eee;
+ }
+.modal-header .close {
+ margin-top:2px;
+ }
+.modal-body {
+ max-height:400px;
+ padding:15px;
+ overflow-y:auto;
+ }
+.modal-form {
+ margin-bottom:0;
+ }
+.modal-footer {
+ padding:14px 15px 15px;
+ margin-bottom:0;
+ text-align:right;
+ background-color:#f5f5f5;
+ border-top:1px solid #ddd;
+ -webkit-border-radius:0 0 6px 6px;
+ -moz-border-radius:0 0 6px 6px;
+ border-radius:0 0 6px 6px;
+ *zoom:1;
+ -webkit-box-shadow:inset 0 1px 0 #ffffff;
+ -moz-box-shadow:inset 0 1px 0 #ffffff;
+ box-shadow:inset 0 1px 0 #ffffff;
+ }
+.modal-footer:before,
+.modal-footer:after {
+ display:table;
+ content:"";
+ }
+.modal-footer:after {
+ clear:both;
+ }
+.modal-footer .btn + .btn {
+ margin-bottom:0;
+ margin-left:5px;
+ }
+.modal-footer .btn-group .btn + .btn {
+ margin-left:-1px;
+ }
+.tooltip {
+ position:absolute;
+ z-index:1020;
+ display:block;
+ padding:5px;
+ font-size:11px;
+ opacity:0;
+ filter:alpha(opacity=0);
+ visibility:visible;
+ }
+.tooltip.in {
+ opacity:0.8;
+ filter:alpha(opacity=80);
+ }
+.tooltip.top {
+ margin-top:-2px;
+ }
+.tooltip.right {
+ margin-left:2px;
+ }
+.tooltip.bottom {
+ margin-top:2px;
+ }
+.tooltip.left {
+ margin-left:-2px;
+ }
+.tooltip.top .tooltip-arrow {
+ bottom:0;
+ left:50%;
+ margin-left:-5px;
+ border-top:5px solid #000000;
+ border-right:5px solid transparent;
+ border-left:5px solid transparent;
+ }
+.tooltip.left .tooltip-arrow {
+ top:50%;
+ right:0;
+ margin-top:-5px;
+ border-top:5px solid transparent;
+ border-bottom:5px solid transparent;
+ border-left:5px solid #000000;
+ }
+.tooltip.bottom .tooltip-arrow {
+ top:0;
+ left:50%;
+ margin-left:-5px;
+ border-right:5px solid transparent;
+ border-bottom:5px solid #000000;
+ border-left:5px solid transparent;
+ }
+.tooltip.right .tooltip-arrow {
+ top:50%;
+ left:0;
+ margin-top:-5px;
+ border-top:5px solid transparent;
+ border-right:5px solid #000000;
+ border-bottom:5px solid transparent;
+ }
+.tooltip-inner {
+ max-width:200px;
+ padding:3px 8px;
+ color:#ffffff;
+ text-align:center;
+ text-decoration:none;
+ background-color:#000000;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.tooltip-arrow {
+ position:absolute;
+ width:0;
+ height:0;
+ }
+.popover {
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:1010;
+ display:none;
+ padding:5px;
+ }
+.popover.top {
+ margin-top:-5px;
+ }
+.popover.right {
+ margin-left:5px;
+ }
+.popover.bottom {
+ margin-top:5px;
+ }
+.popover.left {
+ margin-left:-5px;
+ }
+.popover.top .arrow {
+ bottom:0;
+ left:50%;
+ margin-left:-5px;
+ border-top:5px solid #000000;
+ border-right:5px solid transparent;
+ border-left:5px solid transparent;
+ }
+.popover.right .arrow {
+ top:50%;
+ left:0;
+ margin-top:-5px;
+ border-top:5px solid transparent;
+ border-right:5px solid #000000;
+ border-bottom:5px solid transparent;
+ }
+.popover.bottom .arrow {
+ top:0;
+ left:50%;
+ margin-left:-5px;
+ border-right:5px solid transparent;
+ border-bottom:5px solid #000000;
+ border-left:5px solid transparent;
+ }
+.popover.left .arrow {
+ top:50%;
+ right:0;
+ margin-top:-5px;
+ border-top:5px solid transparent;
+ border-bottom:5px solid transparent;
+ border-left:5px solid #000000;
+ }
+.popover .arrow {
+ position:absolute;
+ width:0;
+ height:0;
+ }
+.popover-inner {
+ width:280px;
+ padding:3px;
+ overflow:hidden;
+ background:#000000;
+ background:rgba(0, 0, 0, 0.8);
+ -webkit-border-radius:6px;
+ -moz-border-radius:6px;
+ border-radius:6px;
+ -webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);
+ }
+.popover-title {
+ padding:9px 15px;
+ line-height:1;
+ background-color:#f5f5f5;
+ border-bottom:1px solid #eee;
+ -webkit-border-radius:3px 3px 0 0;
+ -moz-border-radius:3px 3px 0 0;
+ border-radius:3px 3px 0 0;
+ }
+.popover-content {
+ padding:14px;
+ background-color:#ffffff;
+ -webkit-border-radius:0 0 3px 3px;
+ -moz-border-radius:0 0 3px 3px;
+ border-radius:0 0 3px 3px;
+ -webkit-background-clip:padding-box;
+ -moz-background-clip:padding-box;
+ background-clip:padding-box;
+ }
+.popover-content p,
+.popover-content ul,
+.popover-content ol {
+ margin-bottom:0;
+ }
+.thumbnails {
+ margin-left:-20px;
+ list-style:none;
+ *zoom:1;
+ }
+.thumbnails:before,
+.thumbnails:after {
+ display:table;
+ content:"";
+ }
+.thumbnails:after {
+ clear:both;
+ }
+.row-fluid .thumbnails {
+ margin-left:0;
+ }
+.thumbnails > li {
+ float:left;
+ margin-bottom:18px;
+ margin-left:20px;
+ }
+.thumbnail {
+ display:block;
+ padding:4px;
+ line-height:1;
+ border:1px solid #ddd;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ -webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);
+ }
+a.thumbnail:hover {
+ border-color:#0088cc;
+ -webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);
+ -moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);
+ box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);
+ }
+.thumbnail > img {
+ display:block;
+ max-width:100%;
+ margin-right:auto;
+ margin-left:auto;
+ }
+.thumbnail .caption {
+ padding:9px;
+ }
+.label,
+.badge {
+ font-size:10.998px;
+ font-weight:bold;
+ line-height:14px;
+ color:#ffffff;
+ text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);
+ white-space:nowrap;
+ vertical-align:baseline;
+ background-color:#999999;
+ }
+.label {
+ padding:1px 4px 2px;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+ border-radius:3px;
+ }
+.badge {
+ padding:1px 9px 2px;
+ -webkit-border-radius:9px;
+ -moz-border-radius:9px;
+ border-radius:9px;
+ }
+a.label:hover,
+a.badge:hover {
+ color:#ffffff;
+ text-decoration:none;
+ cursor:pointer;
+ }
+.label-important,
+.badge-important {
+ background-color:#b94a48;
+ }
+.label-important[href],
+.badge-important[href] {
+ background-color:#953b39;
+ }
+.label-warning,
+.badge-warning {
+ background-color:#f89406;
+ }
+.label-warning[href],
+.badge-warning[href] {
+ background-color:#c67605;
+ }
+.label-success,
+.badge-success {
+ background-color:#468847;
+ }
+.label-success[href],
+.badge-success[href] {
+ background-color:#356635;
+ }
+.label-info,
+.badge-info {
+ background-color:#3a87ad;
+ }
+.label-info[href],
+.badge-info[href] {
+ background-color:#2d6987;
+ }
+.label-inverse,
+.badge-inverse {
+ background-color:#333333;
+ }
+.label-inverse[href],
+.badge-inverse[href] {
+ background-color:#1a1a1a;
+ }
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position:40px 0;
+ }
+ to {
+ background-position:0 0;
+ }
+ }
+@-moz-keyframes progress-bar-stripes {
+ from {
+ background-position:40px 0;
+ }
+ to {
+ background-position:0 0;
+ }
+ }
+@-ms-keyframes progress-bar-stripes {
+ from {
+ background-position:40px 0;
+ }
+ to {
+ background-position:0 0;
+ }
+ }
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position:0 0;
+ }
+ to {
+ background-position:40px 0;
+ }
+ }
+@keyframes progress-bar-stripes {
+ from {
+ background-position:40px 0;
+ }
+ to {
+ background-position:0 0;
+ }
+ }
+.progress {
+ height:18px;
+ margin-bottom:18px;
+ overflow:hidden;
+ background-color:#f7f7f7;
+ background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
+ background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image:linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-repeat:repeat-x;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);
+ -webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ }
+.progress .bar {
+ width:0;
+ height:18px;
+ font-size:12px;
+ color:#ffffff;
+ text-align:center;
+ text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color:#0e90d2;
+ background-image:-moz-linear-gradient(top, #149bdf, #0480be);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
+ background-image:-webkit-linear-gradient(top, #149bdf, #0480be);
+ background-image:-o-linear-gradient(top, #149bdf, #0480be);
+ background-image:linear-gradient(top, #149bdf, #0480be);
+ background-image:-ms-linear-gradient(top, #149bdf, #0480be);
+ background-repeat:repeat-x;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);
+ -webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ -ms-box-sizing:border-box;
+ box-sizing:border-box;
+ -webkit-transition:width 0.6s ease;
+ -moz-transition:width 0.6s ease;
+ -ms-transition:width 0.6s ease;
+ -o-transition:width 0.6s ease;
+ transition:width 0.6s ease;
+ }
+.progress-striped .bar {
+ background-color:#149bdf;
+ background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ -webkit-background-size:40px 40px;
+ -moz-background-size:40px 40px;
+ -o-background-size:40px 40px;
+ background-size:40px 40px;
+ }
+.progress.active .bar {
+ -webkit-animation:progress-bar-stripes 2s linear infinite;
+ -moz-animation:progress-bar-stripes 2s linear infinite;
+ -ms-animation:progress-bar-stripes 2s linear infinite;
+ -o-animation:progress-bar-stripes 2s linear infinite;
+ animation:progress-bar-stripes 2s linear infinite;
+ }
+.progress-danger .bar {
+ background-color:#dd514c;
+ background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));
+ background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image:linear-gradient(top, #ee5f5b, #c43c35);
+ background-repeat:repeat-x;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
+ }
+.progress-danger.progress-striped .bar {
+ background-color:#ee5f5b;
+ background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ }
+.progress-success .bar {
+ background-color:#5eb95e;
+ background-image:-moz-linear-gradient(top, #62c462, #57a957);
+ background-image:-ms-linear-gradient(top, #62c462, #57a957);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));
+ background-image:-webkit-linear-gradient(top, #62c462, #57a957);
+ background-image:-o-linear-gradient(top, #62c462, #57a957);
+ background-image:linear-gradient(top, #62c462, #57a957);
+ background-repeat:repeat-x;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
+ }
+.progress-success.progress-striped .bar {
+ background-color:#62c462;
+ background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ }
+.progress-info .bar {
+ background-color:#4bb1cf;
+ background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);
+ background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));
+ background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);
+ background-image:-o-linear-gradient(top, #5bc0de, #339bb9);
+ background-image:linear-gradient(top, #5bc0de, #339bb9);
+ background-repeat:repeat-x;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);
+ }
+.progress-info.progress-striped .bar {
+ background-color:#5bc0de;
+ background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ }
+.progress-warning .bar {
+ background-color:#faa732;
+ background-image:-moz-linear-gradient(top, #fbb450, #f89406);
+ background-image:-ms-linear-gradient(top, #fbb450, #f89406);
+ background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image:-webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image:-o-linear-gradient(top, #fbb450, #f89406);
+ background-image:linear-gradient(top, #fbb450, #f89406);
+ background-repeat:repeat-x;
+ filter:progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);
+ }
+.progress-warning.progress-striped .bar {
+ background-color:#fbb450;
+ background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ }
+.accordion {
+ margin-bottom:18px;
+ }
+.accordion-group {
+ margin-bottom:2px;
+ border:1px solid #e5e5e5;
+ -webkit-border-radius:4px;
+ -moz-border-radius:4px;
+ border-radius:4px;
+ }
+.accordion-heading {
+ border-bottom:0;
+ }
+.accordion-heading .accordion-toggle {
+ display:block;
+ padding:8px 15px;
+ }
+.accordion-toggle {
+ cursor:pointer;
+ }
+.accordion-inner {
+ padding:9px 15px;
+ border-top:1px solid #e5e5e5;
+ }
+.carousel {
+ position:relative;
+ margin-bottom:18px;
+ line-height:1;
+ }
+.carousel-inner {
+ position:relative;
+ width:100%;
+ overflow:hidden;
+ }
+.carousel .item {
+ position:relative;
+ display:none;
+ -webkit-transition:0.6s ease-in-out left;
+ -moz-transition:0.6s ease-in-out left;
+ -ms-transition:0.6s ease-in-out left;
+ -o-transition:0.6s ease-in-out left;
+ transition:0.6s ease-in-out left;
+ }
+.carousel .item > img {
+ display:block;
+ line-height:1;
+ }
+.carousel .active,
+.carousel .next,
+.carousel .prev {
+ display:block;
+ }
+.carousel .active {
+ left:0;
+ }
+.carousel .next,
+.carousel .prev {
+ position:absolute;
+ top:0;
+ width:100%;
+ }
+.carousel .next {
+ left:100%;
+ }
+.carousel .prev {
+ left:-100%;
+ }
+.carousel .next.left,
+.carousel .prev.right {
+ left:0;
+ }
+.carousel .active.left {
+ left:-100%;
+ }
+.carousel .active.right {
+ left:100%;
+ }
+.carousel-control {
+ position:absolute;
+ top:40%;
+ left:15px;
+ width:40px;
+ height:40px;
+ margin-top:-20px;
+ font-size:60px;
+ font-weight:100;
+ line-height:30px;
+ color:#ffffff;
+ text-align:center;
+ background:#222222;
+ border:3px solid #ffffff;
+ -webkit-border-radius:23px;
+ -moz-border-radius:23px;
+ border-radius:23px;
+ opacity:0.5;
+ filter:alpha(opacity=50);
+ }
+.carousel-control.right {
+ right:15px;
+ left:auto;
+ }
+.carousel-control:hover {
+ color:#ffffff;
+ text-decoration:none;
+ opacity:0.9;
+ filter:alpha(opacity=90);
+ }
+.carousel-caption {
+ position:absolute;
+ right:0;
+ bottom:0;
+ left:0;
+ padding:10px 15px 5px;
+ background:#333333;
+ background:rgba(0, 0, 0, 0.75);
+ }
+.carousel-caption h4,
+.carousel-caption p {
+ color:#ffffff;
+ }
+.hero-unit {
+ padding:60px;
+ margin-bottom:30px;
+ background-color:#eeeeee;
+ -webkit-border-radius:6px;
+ -moz-border-radius:6px;
+ border-radius:6px;
+ }
+.hero-unit h1 {
+ margin-bottom:0;
+ font-size:60px;
+ line-height:1;
+ letter-spacing:-1px;
+ color:inherit;
+ }
+.hero-unit p {
+ font-size:18px;
+ font-weight:200;
+ line-height:27px;
+ color:inherit;
+ }
+.pull-right {
+ float:right;
+ }
+.pull-left {
+ float:left;
+ }
+.hide {
+ display:none;
+ }
+.show {
+ display:block;
+ }
+.invisible {
+ visibility:hidden;
+ }
+
+
+/* mine */
+
+.row-padded {
+ position:relative;
+ padding-top:40px;
+ padding-left:280px;
+ }
+ .aside {
+ position:absolute;
+ z-index:1;
+ top:40px;
+ left:0;
+ padding-top:7px;
+ }
+ .toc-backref {
+ color:#333;
+ }
diff --git a/doc/colors.css b/doc/colors.css
new file mode 100644
index 0000000..d0dfea9
--- /dev/null
+++ b/doc/colors.css
@@ -0,0 +1,16 @@
+.tmpl {
+ color: #008000;
+}
+
+.func {
+ color: #008000;
+}
+
+.arg {
+ color: blue;
+ font-style: italic;
+}
+
+.const {
+ color: #8E2323;
+}
diff --git a/doc/template_language.rst b/doc/template_language.rst
new file mode 100644
index 0000000..83a13a7
--- /dev/null
+++ b/doc/template_language.rst
@@ -0,0 +1,729 @@
+========================================
+The CT++ template language (2.8 version)
+========================================
+
+.. contents::
+ :depth: 2
+
+.. role:: tmpl
+.. role:: const
+.. role:: arg
+.. role:: func
+
+Templates
+=========
+
+ A template is a text file, that is marked-up using the CT++ template
+ language. It used to separate content from presentation in web design.
+
+ A template can contain CT++ tags. All CT++ tags have HTML-like syntax and
+ they start with :tmpl:`TMPL_`. Names of CT++ tags are case insensetive (for
+ example, :tmpl:`TMPL_var`, :tmpl:`tmpl_var`, or :tmpl:`TmPl_VaR`).
+
+ CT++ supports the next tags: :tmpl:`TMPL_var`, :tmpl:`TMPL_if`,
+ :tmpl:`TMPL_elsif`, :tmpl:`TMPL_else`, :tmpl:`TMPL_unless`,
+ :tmpl:`TMPL_foreach`, :tmpl:`TMPL_include`, :tmpl:`TMPL_comment`,
+ :tmpl:`TMPL_block`, :tmpl:`TMPL_call`, and :tmpl:`TMPL_verbose`.
+
+ Example of a template:
+
+ .. parsed-literal::
+
+ <!DOCTYPE html>
+ :tmpl:`<TMPL_include 'includes/html_lang.tmpl'>`
+ :tmpl:`<TMPL_include 'includes/html_head.tmpl'>`
+ <link rel="stylesheet" href="/static/css/m.posts.css">
+ </head>
+ <body class="posts">
+ <div id="body-wrapper" class="body-wrapper">
+ <div id="content-wrapper" class="content-wrapper">
+ :tmpl:`<TMPL_include 'includes/header.tmpl'>`
+ <section role="main" class="content-column">
+ <h1>\ :tmpl:`<TMPL_var _("Welcome to")>` :tmpl:`<TMPL_var project_name>`, :tmpl:`<TMPL_verbose>`
+ :tmpl:`<TMPL_if logged>`
+ :tmpl:`<TMPL_var HTMLESCAPE(DEFAULT(user_info.name, user_info.username))>`
+ :tmpl:`<TMPL_else>`
+ :tmpl:`<TMPL_var _("Anonymous")>`
+ :tmpl:`</TMPL_if>`\ </h1>
+ :tmpl:`</TMPL_verbose>`
+
+ :tmpl:`<TMPL_verbose>`
+ :tmpl:`<TMPL_foreach users as user>`
+ <h3><a class="user-page-link" href="/user/:tmpl:`<TMPL_var URLESCAPE(user.username)>`" title="
+ :tmpl:`<TMPL_var HTMLESCAPE(DEFAULT(user.name, user.username))>">`
+ :tmpl:`<TMPL_var HTMLESCAPE(DEFAULT(user.name, user.username))>`
+ </a></h3>
+ :tmpl:`</TMPL_foreach>
+ </TMPL_verbose>`
+
+ </section>
+ :tmpl:`<TMPL_include 'includes/noscript_alert.tmpl'>`
+ </div>
+ </div>
+ :tmpl:`<TMPL_include 'includes/footer.tmpl'>`
+ </body>
+ </html>
+
+Comments
+--------
+
+ Use the :tmpl:`TMPL_comment` tag to comment-out part of a template.
+
+ For example:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_comment>`\ <h3>Hello, :tmpl:`<TMPL_var username>`\ !</h3>\ :tmpl:`</TMPL_comment>`
+
+Formatting
+----------
+
+ The :tmpl:`TMPL_verbose` tag removes white-space characters (space,
+ form-feed, newline, carriage return, horizontal tab, and vertical tab)
+ between CT++ tags.
+
+ For example:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_verbose>`
+ foo: :tmpl:`<TMPL_var foo>` some text
+ bar: :tmpl:`<TMPL_var bar>` baz: :tmpl:`<TMPL_var baz>` :tmpl:`<TMPL_var spam>`
+ :tmpl:`</TMPL_verbose>`
+
+ For instance, variables foo, bar, baz, and spam are respectively
+ :const:`"{FOO}"`, :const:`"{BAR}"`, :const:`"{BAZ}"`, and
+ :const:`"{SPAM}"`. The template would be rendered as::
+
+ foo:{FOO}some text
+ bar:{BAR}baz:{BAZ}{SPAM}
+
+ Also, a dash could be used instead the :tmpl:`TMPL_verbose` tag:
+
+ .. parsed-literal::
+
+ foo: :tmpl:`<TMPL_var foo->` some text
+ bar: :tmpl:`<-TMPL_var bar->` baz: :tmpl:`<-TMPL_var baz->` :tmpl:`<-TMPL_var spam>`
+
+ There will same output.
+
+Including
+---------
+
+ The :tmpl:`TMPL_include` tag loads another template within the template.
+ The tag has the one attribute only. The attribute can't be a variable.
+ It's a filename in quotes::
+
+ <TMPL_include "filename.tmpl">
+
+ It is impossible to break conditions and loops between templates.
+
+Variables
+=========
+
+ The CT++ template engine evaluates variable and replaces it with the
+ result. The :tmpl:`TMPL_var` tag is used for evaluating variables.
+
+ The types of variables are undefined variable, string, integer,
+ floating-point number, mapping, and array. For undefined variables result
+ is an empty string.
+
+ The :tmpl:`TMPL_var` evaluates expressions: variables, operators, and
+ functions. For example::
+
+ <TMPL_var foo>
+ <TMPL_var (foo + bar + 1)>
+ <TMPL_var HTMLESCAPE(baz)>
+
+Arrays
+------
+
+ An array is a data type consisting of a collection of elements, each
+ identified by one array index. The first element of the array is indexed
+ by subscript of 0.
+
+ Examples::
+
+ <TMPL_var foo[0]> <- foo must be an array!
+ <TMPL_var foo[bar]> <- bar must be an integer!
+
+Mappings
+--------
+
+ A mapping is a data type composed of a collection of (key,value)
+ pairs, such that each possible key appears at most once in the collection.
+
+ Examples::
+
+ <TMPL_var foo.key> = <TMPL_var foo["key"]> <- foo must be a mapping
+ <TMPL_var foo.bar.baz> <- the mapping foo has the key "bar" with mapping value, that has the key "baz"
+
+ Use a dot to access attributes of a variable.
+
+Control flow
+============
+
+Choice
+------
+
+ The :tmpl:`TMPL_if` tag and the :tmpl:`TMPL_unless` tag evaluate a
+ condition. A condition can be variable, function calls, arithmetic and
+ logic expressions. Arithmetic and logic expressions must be inside of
+ parentheses.
+
+ Examples:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_if foo>`
+ Some text with :tmpl:`<TMPL_var foo>`
+ :tmpl:`</TMPL_if>`
+
+ :tmpl:`<TMPL_unless DEFINED(bar)>`
+ Some text
+ :tmpl:`<TMPL_else>`
+ Some text with :tmpl:`<TMPL_var bar>`
+ :tmpl:`</TMPL_unless>`
+
+ :tmpl:`<TMPL_if (x < 1)>`
+ eeny
+ :tmpl:`<TMPL_elsif (x < 2)>`
+ meeny
+ :tmpl:`<TMPL_elsif (x < 3)>`
+ miny
+ :tmpl:`<TMPL_else>`
+ moe
+ :tmpl:`</TMPL_if>`
+
+ The following table summarizes the operator precedences, from highest
+ precedence to lowest precedence:
+
+ =============== ===== ====================================
+ Operators Assoc Description
+ =============== ===== ====================================
+ (expression) parentheses used for grouping
+ --------------- ----- ------------------------------------
+ () LR parentheses used for a function call
+ --------------- ----- ------------------------------------
+ . LR member selection
+ --------------- ----- ------------------------------------
+ [] LR array/mapping element access
+ --------------- ----- ------------------------------------
+ !, +, - RL logical not, unary plus, unary minus
+ --------------- ----- ------------------------------------
+ \*, /, mod, div LR multiplication and division
+ --------------- ----- ------------------------------------
+ +, - LR addition and subtraction
+ --------------- ----- ------------------------------------
+ <, <=, >, >= LR inequality relational
+ --------------- ----- ------------------------------------
+ ==, != LR equality relational
+ --------------- ----- ------------------------------------
+ && LR logical and
+ --------------- ----- ------------------------------------
+ || LR logical or
+ =============== ===== ====================================
+
+ CT++ defines keywords to act as aliases for a number of operators: lt (<),
+ le (<=), gt (>), ge (>=), eq (==), ne (!=), and (&&), or (||).
+
+Loops
+-----
+
+ CT++ supports the :tmpl:`TMPL_foreach` only. It use an explicit iterator,
+ in which the loop variable takes on each of the values in an array or a
+ mapping.
+
+ An iterator has special attributes:
+
+ ========= ============================================
+ Attribute Description
+ ========= ============================================
+ __index__ index of array's element
+ --------- --------------------------------------------
+ __key__ key in mapping
+ --------- --------------------------------------------
+ __first__ "true" for first iteration
+ --------- --------------------------------------------
+ __last__ "true" for last iteration
+ --------- --------------------------------------------
+ __inner__ "true" if not first and not last iteration
+ --------- --------------------------------------------
+ __even__ "true" for even iteration
+ --------- --------------------------------------------
+ __odd__ "true" for odd iteration
+ --------- --------------------------------------------
+ __value__ value of element
+ ========= ============================================
+
+ Example of usage:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_foreach array as a>`
+ value: :tmpl:`<TMPL_var a>` or :tmpl:`<TMPL_var a.__value__>`
+ index: :tmpl:`<TMPL_var a.__index__>`
+ :tmpl:`<TMPL_if a.__first__>`\ #first#\ :tmpl:`</TMPL_if>`
+ :tmpl:`<TMPL_if a.__even__>`\ #even#\ :tmpl:`<TMPL_else>`\ #odd#\ :tmpl:`</TMPL_if>`
+ :tmpl:`</TMPL_foreach>`
+
+ :tmpl:`<TMPL_foreach map as m>`
+ value: :tmpl:`<TMPL_var m>` or :tmpl:`<TMPL_var m.__value__>`
+ key: :tmpl:`<TMPL_var m.__key__>`
+ :tmpl:`<TMPL_if m.__last__>`\ #last#\ :tmpl:`</TMPL_if>`
+ :tmpl:`</TMPL_foreach>`
+
+ The :tmpl:`TMPL_break` tag breaks the iteration of loop::
+
+ <TMPL_verbose>
+ <TMPL_foreach LIST("a", "b", "c") as char>
+ <TMPL_var char>
+ <TMPL_if (char == "b")><TMPL_break></TMPL_if>
+ </TMPL_foreach>
+ </TMPL_verbose>
+
+ Output of the template is "ab".
+
+Functions
+=========
+
+ CT++ has built-in functions, that is described in `Library reference`_.
+ CT++ tags, that support it: :tmpl:`TMPL_var`, :tmpl:`TMPL_if`,
+ :tmpl:`TMPL_unless`, :tmpl:`TMPL_elsif`, and :tmpl:`TMPL_foreach`. For
+ example:
+
+ .. parsed-literal::
+
+ <TMPL_var :func:`SPRINTF`\ (\ :func:`GETTEXT`\ ("%d minutes ago", min), min)>
+
+ <TMPL_var :func:`DEFAULT`\ (\ :func:`HTMLESCAPE`\ (url), "http://ctpp.havoc.ru")>
+
+ <TMPL_if (\ :func:`GET_TYPE`\ (var) == "STRING")>
+ <TMPL_var :func:`GETTEXT`\ ("var is string")>
+ </TMPL_if>
+
+ <TMPL_foreach :func:`LIST`\ ("eeny", "meeny", "miny", "moe") as item>
+ <TMPL_var item>
+ </TMPL_foreach>
+
+Blocks
+======
+
+ A block is reusable piece of a template called by name.
+
+ Example of usage:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_block "simple-block">`
+ Some text
+ :tmpl:`</TMPL_block>`
+
+ The :tmpl:`TMPL_call` tag is used for calling a block:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_call "simple-block">`
+ :tmpl:`<TMPL_call some_var>`
+
+ A block can have arguments:
+
+ .. parsed-literal::
+
+ :tmpl:`<TMPL_block 'some-block' args(a, b, c)>`
+ :tmpl:`<TMPL_var a>`\ , :tmpl:`<TMPL_var b>`\ , and :tmpl:`<TMPL_var c>`
+ :tmpl:`</TMPL_block>`
+
+ :tmpl:`<TMPL_call 'some-block' args(foo, bar, baz)>`
+
+ Definition blocks inside another blocks is forbidden.
+
+.. _`Library reference`:
+
+Library reference
+=================
+
+_ *(msgid[, msgid_plural, n][, domain])*
+----------------------------------------
+
+See `GETTEXT`_.
+
+AVG *(flag, a[, b, ...])*
+-------------------------
+
+ Return average of :arg:`a[, b, ...]`, according to chosen algorithm by
+ :arg:`flag`. The values of :arg:`flag` are :const:`'a'` for arithmetic mean,
+ :const:`'g'` for geometric mean, :const:`'h'` for harmonic mean, and :const:`'q'`
+ for quadratic mean.
+
+ Examples::
+
+ AVG('a', 1, 2, 3) -> 2
+ AVG('g', 1, 2, 3) -> 1.81712059283
+ AVG('h', 1, 2, 3) -> 1.63636363636
+ AVG('q', 1, 2, 3) -> 2.16024689947
+
+
+BASE64_DECODE *(x)*
+-------------------
+
+ Decode the Base64 encoded string :arg:`x`.
+
+
+BASE64_ENCODE *(x)*
+-------------------
+
+ Encode the string :arg:`x` use Base64.
+
+CAST *(flag, x)*
+----------------
+
+ Convert the type of :arg:`x` to a type specified by :arg:`flag`. The
+ values of :arg:`flag` are :const:`"i[nteger]"`, :const:`"o[ctal]"`,
+ :const:`"h[exadecimal]"`, :const:`"f[loat]"`, and :const:`"s[tring]"`.
+
+ For :arg:`x` starts with :const:`0x` or :const:`0X`, :const:`"integer"`
+ :arg:`flag` behaves as :const:`"hexadecimal"` :arg:`flag`. For :arg:`x`
+ starts with :const:`0`, :const:`"integer"` :arg:`flag` behaves as
+ :const:`"octal"` :arg:`flag`.
+
+ Examples::
+
+ CAST("int", 1.345) -> 1
+ CAST("dec", "010") -> 10
+ CAST("hex", "010") -> 16
+
+CONCAT *(a[, b, ...])*
+----------------------
+
+ Return a string which is the concatenation of the values :arg:`a[, b,
+ ...]`.
+
+ Example::
+
+ CONCAT('a', 1, 2, 3) -> a123
+
+CONTEXT *()*
+------------
+
+ Return a mapping of the rendered context.
+
+DATE_FORMAT *(x, format)*
+-------------------------
+
+ Formats :arg:`x` according to the format specification :arg:`format` (see
+ 'man 3 strftime'). The argument :arg:`x` is the number of seconds elapsed
+ since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
+
+ Example::
+
+ DATE_FORMAT(1200490323, "%Y-%m-%d %H:%M:%S") -> 2008-01-16 16:32:03
+
+
+DEFAULT *(x, y)*
+----------------------
+
+ If :arg:`x` is nonzero return :arg:`x` else return :arg:`y`.
+
+ Examples::
+
+ DEFAULT("", "default_string") -> default_string
+ DEFAULT(nonexistent, "default") -> default
+ DEFAULT(0, 1) -> 1
+
+DEFINED *(a[, b, ...])*
+-----------------------
+
+ If all of :arg:`a[, b, ...]` exist return :const:`1` else return
+ :const:`0`.
+
+ERROR *()*
+----------
+
+ Create runtime error.
+
+FORM_PARAM *(x, y)*
+-------------------
+
+ With name :arg:`x` and value :arg:`y`, output a hidden field of HTML form.
+
+ It is equivalent to the next::
+
+ <TMPL_verbose>
+ <TMPL_if y>
+ <input type="hidden" name="x" value="<TMPL_var URLESCAPE(y)>">
+ </TMPL_if>
+ </TMPL_verbose>
+
+.. _GETTEXT:
+
+GETTEXT *(msgid[, msgid_plural, n][, domain])*
+----------------------------------------------
+
+ Translate a text string :arg:`msgid` into the user's native language, by
+ looking up the translation in a message catalog.
+
+ If a translation was found, the message is converted to the locale's
+ codeset and returned. Otherwise :arg:`msgid` or :arg:`msgid_plural` is
+ returned.
+
+ The appropriate plural form depends on the number :arg:`n` and the language
+ of the message catalog where the translation was found.
+
+ The argument :arg:`domain` is a set of translatable messages.
+
+ The function :func:`_()` is alias of :func:`GETTEXT()`.
+
+ Examples::
+
+ GETTEXT("Hello, World!") -> Привет, Мир!
+ _("Hello, World!") -> Привет, Мир!
+ _("Hello, World!", "mydomain") -> Привет, Другой Мир!
+ SPRINTF(_("%d hour", "%d hours", 1), 1) -> 1 час
+ SPRINTF(_("%d minute", "%d minutes", 2, "mydomain"), 2) -> 2 минуты
+
+GET_TYPE *(x)*
+--------------
+
+ Return a printable type of :arg:`x`. The types are :const:`"\*UNDEF\*"` for
+ undefined variables, :const:`"STRING"` for strings, :const:`"INTEGER"` for
+ integers, :const:`"REAL"` for floating-point numbers, :const:`"HASH"` for
+ mappings, and :const:`"ARRAY"` for arrays.
+
+HASH_KEYS *(x)*
+------------------
+
+ Return an array of :arg:`x`'s keys. The argument :arg:`x` should be
+ mapping.
+
+HMAC_MD5 *(x, key)*
+-------------------------
+
+ Compute a hash value for the specified :arg:`x` using the supplied :arg:`key`.
+
+HOSTNAME *()*
+-------------
+
+ Return the hostname of the current processor.
+
+HREF_PARAM *(x, y)*
+--------------------------
+
+ With name :arg:`x` and value :arg:`y`, output parameters of HTML links.
+
+ It is equivalent to the next::
+
+ <TMPL_if a>x=<TMPL_var URLESCAPE(y)></TMPL_if>
+
+HTMLESCAPE *(a[, b, ...])*
+--------------------------
+
+ Escape :const:`&`, :const:`<`, :const:`'`, :const:`"`, and :const:`>` in
+ the strings of data :arg:`a[, b, ...]`.
+
+ :func:`HTMLESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
+ICONV *(x, src, dst[, flags])*
+------------------------------
+
+ Convert the string :arg:`x` from the coded character set :arg:`src` to
+ :arg:`dst`.
+
+ The argument :arg:`flags` are :const:`'i'` or :const:`'I'` for discarding
+ illegal sequence, and :const:`'t'` or :const:`'T'` for enabling transliteration
+ in the conversion. The argument :arg:`flags` works in FreeBSD only.
+
+ See 'iconv -l` for list which contains all the coded character sets known.
+
+IN_ARRAY *(x, array)*
+---------------------
+
+ Return :const:`1` if :arg:`x` was found in :arg:`array`, else return
+ :const:`0`.
+
+IN_SET *(x, a[, b, ...])*
+-------------------------
+
+ Return :const:`1` if :arg:`x` was found in :arg:`a[, b, ...]`, else return
+ :const:`0`.
+
+JSONESCAPE *(a[, b, ...])*
+--------------------------
+
+ Escape :const:`"`, :const:`\\`, :const:`/`, :const:`\\b`, :const:`\\f`,
+ :const:`\\n`, :const:`\\r`, :const:`\\t`, :const:`'`, :const:`\\v`, and
+ :const:`\\0` in the strings of data :arg:`a[, b, ...]`. If character's
+ value is smaller than :const:`\\u0032`, it is encoded with :const:`\\uXXXX`
+ format for hex digits :const:`XXXX`.
+
+ :func:`JSONESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
+JSON *(x)*
+----------
+
+ Serialize :arg:`x` to the JavaScript Object Notation (JSON).
+
+LIST_ELEMENT *(a[, b, ...], x)*
+-------------------------------
+
+ Return an element from :arg:`a[, b, ...]` by the index :arg:`x`.
+
+LIST *([a, b, ...])*
+--------------------
+
+ Return an array of :arg:`[a, b, ...]`. It can be empty.
+
+LOG *(x[, base])*
+---------------------
+
+ With one argument, return the natural logarithm of :arg:`x` (to base
+ :const:`e`).
+
+ With two arguments, return the logarithm of :arg:`x` to the given
+ :arg:`base`, calculated as :func:`LOG(x) / LOG(base)`.
+
+MAX *(a[, b, ...])*
+-------------------
+
+ Return the largest item of :arg:`a[, b, ...]`.
+
+MB_SIZE *(x)*
+-------------
+
+ MB\_ prefix marks function, which works with multibyte strings.
+
+ See SIZE_.
+
+MB_SUBSTR *(x, offset[, bytes[, y]]])*
+--------------------------------------------
+
+ MB\_ prefix marks function, which works with multibyte strings.
+
+ See SUBSTR_.
+
+MB_TRUNCATE *(x, offest[, addon])*
+----------------------------------
+
+ MB\_ prefix marks function, which works with multibyte strings.
+
+ See TRUNCATE_.
+
+MD5 *(a[, b, ...])*
+-------------------
+
+ Return the MD5 hash of :arg:`a[, b, ...]`.
+
+MIN *(a[, b, ...])*
+-------------------
+
+ Return the smallest item of :arg:`a[, b, ...]`.
+
+NUM_FORMAT *(x, y)*
+------------------------
+
+ Return the formatted integer :arg:`x` with period :arg:`y`.
+
+ Example::
+
+ NUM_FORMAT(1234567, ",") -> 1,234,567
+
+OBJ_DUMP *([a, b, ...])*
+------------------------
+
+ Return dump of the arguments :arg:`[a, b, ...]`. Return dump of all variables
+ if no arguments.
+
+RANDOM *([[min,] max])*
+-----------------------
+
+ Return a random number in the range (:arg:`min`, :arg:`max`]. The range
+ (:arg:`min`, :arg:`max`] equals to :const:`0 .. RAND_MAX`, if no arguments.
+
+.. _SIZE:
+
+SIZE *(x)*
+----------
+
+ Return the number of items of a sequence :arg:`x`.
+
+SPRINTF *(format, a[, b, ...])*
+-------------------------------
+
+ Produce output according to a format. After the argument :arg:`format`, it
+ expects at least as many additional arguments as specified in
+ :arg:`format`.
+
+ The argument :arg:`format` can optionaly contain embedded format tags that
+ are substituted by the values specified in :arg:`a[, b, ...]`.
+
+ See 'man 3 printf' for more information.
+
+.. _SUBSTR:
+
+SUBSTR *(x, offset[, bytes[, y]]])*
+-----------------------------------
+
+ Return the characters in the string :arg:`x` starting at a specified
+ position :arg:`offset` and continuing for a specified number of characters
+ :arg:`bytes`. If the argument :arg:`y` exists, then return the string
+ :arg:`x` with replaced the characters with :arg:`y`.
+
+.. _TRUNCATE:
+
+TRUNCATE *(x, offest[, addon])*
+-------------------------------
+
+ Return the string :arg:`x`, if it is less than or equal to :arg:`offset`
+ characters long. If it is longer, it truncates the string.
+
+ Return the string with :arg:`addon`, if the argument :arg:`addon` exists.
+
+URIESCAPE *(a[, b, ...])*
+-------------------------
+
+ Convert characters of the strings :arg:`a[, b, ...]` into their
+ corresponding escape sequences.
+
+ :func:`URIESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
+URLESCAPE *(a[, b, ...])*
+-------------------------
+
+ Convert characters of the strings :arg:`a[, b, ...]` into their
+ corresponding escape sequences. It replaces spaces with :const:`"+"` instead
+ of :const:`"%20"`.
+
+ :func:`URLESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
+VERSION *([x])*
+---------------
+
+ Return the current version of CT++.
+
+ Return extended information if :arg:`x` equals to :const:`"full"`.
+
+WMLESCAPE *(a[, b, ...])*
+-------------------------
+
+ Replace :const:`<` with :const:`&gt;`, :const:`>` with :const:`&lt;`,
+ :const:`"` with :const:`&quot;`, :const:`'` with :const:`&apos;`,
+ :const:`$` with :const:`$$`, and :const:`&` with :const:`&amp;` in the
+ strings of data :arg:`a[, b, ...]`.
+
+ :func:`WMLESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
+XMLESCAPE *(a[, b, ...])*
+-------------------------
+
+ Replace :const:`<` with :const:`&gt;`, :const:`>` with :const:`&lt;`,
+ :const:`"` with :const:`&quot;`, :const:`'` with :const:`&apos;`, and
+ :const:`&` with :const:`&amp;` in the strings of data :arg:`a[, b, ...]`.
+
+ :func:`XMLESCAPE()` returns result of concatenation of the strings
+ :arg:`a[, b, ...]`.
+
diff --git a/include/CDT.hpp b/include/CDT.hpp
new file mode 100644
index 0000000..d63fc5e
--- /dev/null
+++ b/include/CDT.hpp
@@ -0,0 +1,2187 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CDT_HPP__
+#define _CDT_HPP__ 1
+
+/**
+ @file CDT.hpp
+ @brief Common Data Type
+*/
+
+#include "STLMap.hpp"
+#include "STLString.hpp"
+#include "STLVector.hpp"
+
+#include "CTPP2Exception.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+#define C_MAX_SPRINTF_LENGTH 128
+
+/**
+ @class CDT CDT.hpp <CDT.hpp>
+ @brief Common Data Type
+*/
+class CTPP2DECL CDT
+{
+private:
+ /**
+ @var typedef STLW::string<CDT> String
+ @brief internal string definition
+ */
+ typedef STLW::string String;
+
+ /**
+ @var typedef STLW::vector<CDT> Vector
+ @brief internal array definition
+ */
+ typedef STLW::vector<CDT> Vector;
+
+ /**
+ @var typedef STLW::map<String, CDT> Map
+ @brief internal hash definition
+ */
+ typedef STLW::map<String, CDT> Map;
+public:
+ /**
+ @enum eValType CDT.hpp <CDT.hpp>
+ @brief Describes type of stored value
+ */
+ enum eValType { UNDEF = 0x01,
+ INT_VAL = 0x02,
+ REAL_VAL = 0x04,
+ POINTER_VAL = 0x08,
+ STRING_VAL = 0x10,
+
+ STRING_INT_VAL = 0x12,
+ STRING_REAL_VAL = 0x14,
+
+ ARRAY_VAL = 0x20,
+ HASH_VAL = 0x40 /*,
+ REFERENCE_VAL = 0x80 */
+ };
+
+ /**
+ @enum eMergeStrategy CDT.hpp <CDT.hpp>
+ @brief Describes merging strategy for HASH-es and ARRAY-s
+ */
+ enum eMergeStrategy { FAST_MERGE, DEEP_MERGE };
+
+ // FWD
+ class CTPP2DECL SortingComparator;
+
+ /**
+ @brief Constructor
+ @param oValue - type of value
+ */
+ CDT(const CDT::eValType & oValue = UNDEF);
+
+ /**
+ @brief Copy constructor
+ @param oCDT - Object to copy
+ */
+ CDT(const CDT & oCDT);
+
+ /**
+ @brief Copy operator
+ @param oCDT - Object to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const CDT & oCDT);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - INT_64 value
+ */
+ CDT(const INT_64 oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - UINT_64 value
+ */
+ CDT(const UINT_64 oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - INT_32 value
+ */
+ CDT(const INT_32 oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - UINT_32 value
+ */
+ CDT(const UINT_32 oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - W_FLOAT value
+ */
+ CDT(const W_FLOAT oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - string value
+ */
+ CDT(const STLW::string & oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - asciz string to copy
+ @return read/write referense to self
+ */
+ CDT(CCHAR_P oValue);
+
+ /**
+ @brief Type cast constructor
+ @param oValue - generic pointer value
+ */
+ CDT(void * oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - INT_64 value to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const INT_64 oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - UINT_64 value to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const UINT_64 oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - INT_32 value to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const INT_32 oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - UINT_32 value to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const UINT_32 oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - W_FLOAT value to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const W_FLOAT oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - string to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(const STLW::string & oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - asciz string to copy
+ @return read/write referense to self
+ */
+ CDT & operator=(CCHAR_P oValue);
+
+ /**
+ @brief Copy operator
+ @param oValue - generic pointer
+ @return read/write referense to self
+ */
+ CDT & operator=(void * oValue);
+
+ /**
+ @brief Provides access to the data contained in CDT
+ @param iPos - The index of the element
+ @return Object with data
+ */
+ CDT & operator[](const UINT_32 iPos);
+
+ /**
+ @brief Provides access to the data contained in CDT (constant method)
+ @param iPos - The index of the element
+ @return Object with data
+ */
+ const CDT & operator[](const UINT_32 iPos) const;
+
+ /**
+ @brief Provides access to the data contained in CDT
+ @param sKey - The key of the element
+ @return Object with data
+ */
+ CDT & operator[](const STLW::string & sKey);
+
+ /**
+ @brief Provides access to the data contained in CDT (constant method)
+ @param sKey - The key of the element
+ @return Object with data
+ */
+ const CDT & operator[](const STLW::string & sKey) const;
+
+ /**
+ @brief Provides constant access to the data contained in CDT
+ @param iPos - The index of the element
+ @return Object with data
+ */
+ const CDT & GetCDT(const UINT_32 iPos) const;
+
+ /**
+ @brief Provides constant access to the data contained in CDT
+ @param sKey - The key of the hash
+ @return Object with data
+ */
+ const CDT & GetCDT(const STLW::string & sKey) const;
+
+ /**
+ @brief Provides constant access to the data contained in CDT
+ @param sKey - The key of the hash [in]
+ @param bCDTExist - Existence flag [out], is set to true if object exist or false otherwise
+ @return Object with data
+ */
+ const CDT & GetExistedCDT(const STLW::string & sKey, bool & bCDTExist) const;
+
+ /**
+ @brief Erase element from HASH
+ @param sKey - The key of the hash [in]
+ @return true - if key found, false - otherwise
+ */
+ bool Erase(const STLW::string & sKey);
+
+ /**
+ @brief Check element in hash
+ @param sKey - The key of the hash
+ @return true, if element present, false - otherwise
+ */
+ bool Exists(const STLW::string & sKey) const;
+
+ /**
+ @brief Check element in array
+ @param iPos - The index of the element
+ @return true, if element present, false - otherwise
+ */
+ bool Exists(const UINT_32 iPos) const;
+
+ /**
+ @brief Push value into array
+ @param oValue - INT_64 value
+ */
+ void PushBack(const INT_64 oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - UINT_64 value
+ */
+ void PushBack(const UINT_64 oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - INT_32 value
+ */
+ void PushBack(const INT_32 oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - UINT_32 value
+ */
+ void PushBack(const UINT_32 oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - W_FLOAT value
+ */
+ void PushBack(const W_FLOAT oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - string value
+ */
+ void PushBack(const STLW::string & oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - asciz string
+ */
+ void PushBack(CCHAR_P oValue);
+
+ /**
+ @brief Push value into array
+ @param oValue - CDT object
+ */
+ void PushBack(const CDT & oValue);
+
+ /**
+ @brief Returns a boolean value telling whether object has a value
+ @return true if object has a value, false - otherwise
+ */
+ bool Nonzero() const;
+
+ /**
+ @brief Provides range-check access to the data contained in CDT
+ @param iPos - The index of the element
+ @return Read/write reference to data
+ */
+ CDT & At(const UINT_32 iPos);
+
+ /**
+ @brief Provides range-check access to the data contained in CDT
+ @param sKey - The key of the hash
+ @return Read/write reference to data
+ */
+ CDT & At(const STLW::string & sKey);
+
+ // Operator + ////////////////////////////////////
+
+ /**
+ @brief Operator + for INT_64 argument
+ @param oValue - value to add
+ @return new CDT object
+ */
+ CDT operator+(const INT_64 oValue) const;
+
+ /**
+ @brief Operator + for UINT_64 argument
+ @param oValue - value to add
+ @return new CDT object
+ */
+ CDT operator+(const UINT_64 oValue) const;
+
+ /**
+ @brief Operator + for INT_32 argument
+ @param oValue - value to add
+ @return new CDT object
+ */
+ CDT operator+(const INT_32 oValue) const;
+
+ /**
+ @brief Operator + for UINT_32 argument
+ @param oValue - value to add
+ @return new CDT object
+ */
+ CDT operator+(const UINT_32 oValue) const;
+
+ /**
+ @brief Operator + for W_FLOAT argument
+ @param oValue - value to add
+ @return new CDT object
+ */
+ CDT operator+(const W_FLOAT oValue) const;
+
+ /**
+ @brief Operator + for CDT argument
+ @param oCDT - value to add
+ @return new CDT object
+ */
+ CDT operator+(const CDT & oCDT) const;
+
+ // Operator - ////////////////////////////////////
+
+ /**
+ @brief Operator - for INT_64 argument
+ @param oValue - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const INT_64 oValue) const;
+
+ /**
+ @brief Operator - for UINT_64 argument
+ @param oValue - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const UINT_64 oValue) const;
+
+ /**
+ @brief Operator - for INT_32 argument
+ @param oValue - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const INT_32 oValue) const;
+
+ /**
+ @brief Operator - for UINT_32 argument
+ @param oValue - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const UINT_32 oValue) const;
+
+ /**
+ @brief Operator - for W_FLOAT argument
+ @param oValue - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const W_FLOAT oValue) const;
+
+ /**
+ @brief Operator - for CDT argument
+ @param oCDT - value to substract
+ @return new CDT object
+ */
+ CDT operator-(const CDT & oCDT) const;
+
+ // Operator * ////////////////////////////////////
+
+ /**
+ @brief Operator * for INT_64 argument
+ @param oValue - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const INT_64 oValue) const;
+
+ /**
+ @brief Operator * for UINT_64 argument
+ @param oValue - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const UINT_64 oValue) const;
+
+ /**
+ @brief Operator * for INT_32 argument
+ @param oValue - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const INT_32 oValue) const;
+
+ /**
+ @brief Operator * for UINT_32 argument
+ @param oValue - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const UINT_32 oValue) const;
+
+ /**
+ @brief Operator * for W_FLOAT argument
+ @param oValue - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const W_FLOAT oValue) const;
+
+ /**
+ @brief Operator * for CDT argument
+ @param oCDT - value to multiplicate
+ @return new CDT object
+ */
+ CDT operator*(const CDT & oCDT) const;
+
+ // Operator / ////////////////////////////////////
+
+ /**
+ @brief Operator / for INT_64 argument
+ @param oValue - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const INT_64 oValue) const;
+
+ /**
+ @brief Operator / for UINT_64 argument
+ @param oValue - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const UINT_64 oValue) const;
+
+ /**
+ @brief Operator / for INT_32 argument
+ @param oValue - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const INT_32 oValue) const;
+
+ /**
+ @brief Operator / for UINT_32 argument
+ @param oValue - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const UINT_32 oValue) const;
+
+ /**
+ @brief Operator / for W_FLOAT argument
+ @param oValue - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const W_FLOAT oValue) const;
+
+ /**
+ @brief Operator / for CDT argument
+ @param oCDT - value to divide
+ @return new CDT object
+ */
+ CDT operator/(const CDT & oCDT) const;
+
+ // ///////////////////////////////////////////////
+
+ // Operator += ///////////////////////////////////
+
+ /**
+ @brief Operator += for INT_64 argument
+ @param oValue - value to add
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const INT_64 oValue);
+
+ /**
+ @brief Operator += for UINT_64 argument
+ @param oValue - value to add
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const UINT_64 oValue);
+
+ /**
+ @brief Operator += for INT_32 argument
+ @param oValue - value to add
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const INT_32 oValue);
+
+ /**
+ @brief Operator += for UINT_32 argument
+ @param oValue - value to divide
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const UINT_32 oValue);
+
+ /**
+ @brief Operator += for W_FLOAT argument
+ @param oValue - value to add
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const W_FLOAT oValue);
+
+ /**
+ @brief Operator += for CDT argument
+ @param oCDT - value to add
+ @return Read/write reference to self
+ */
+ CDT & operator+=(const CDT & oCDT);
+
+ // Operator -= ///////////////////////////////////
+
+ /**
+ @brief Operator -= for INT_64 argument
+ @param oValue - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const INT_64 oValue);
+
+ /**
+ @brief Operator -= for UINT_64 argument
+ @param oValue - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const UINT_64 oValue);
+
+ /**
+ @brief Operator -= for INT_32 argument
+ @param oValue - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const INT_32 oValue);
+
+ /**
+ @brief Operator -= for UINT_32 argument
+ @param oValue - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const UINT_32 oValue);
+
+ /**
+ @brief Operator -= for W_FLOAT argument
+ @param oValue - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const W_FLOAT oValue);
+
+ /**
+ @brief Operator -= for string argument
+ @param oCDT - value to substract
+ @return Read/write reference to self
+ */
+ CDT & operator-=(const CDT & oCDT);
+
+ // Operator *= ///////////////////////////////////
+
+ /**
+ @brief Operator *= for INT_64 argument
+ @param oValue - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const INT_64 oValue);
+
+ /**
+ @brief Operator *= for UINT_64 argument
+ @param oValue - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const UINT_64 oValue);
+
+ /**
+ @brief Operator *= for INT_32 argument
+ @param oValue - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const INT_32 oValue);
+
+ /**
+ @brief Operator *= for UINT_32 argument
+ @param oValue - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const UINT_32 oValue);
+
+ /**
+ @brief Operator *= for W_FLOAT argument
+ @param oValue - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const W_FLOAT oValue);
+
+ /**
+ @brief Operator *= for CDT argument
+ @param oCDT - value to multiplication
+ @return Read/write reference to self
+ */
+ CDT & operator*=(const CDT & oCDT);
+
+ // Operator /= ///////////////////////////////////
+
+ /**
+ @brief Operator /= for INT_64 argument
+ @param oValue - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const INT_64 oValue);
+
+ /**
+ @brief Operator /= for UINT_64 argument
+ @param oValue - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const UINT_64 oValue);
+
+ /**
+ @brief Operator /= for INT_32 argument
+ @param oValue - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const INT_32 oValue);
+
+ /**
+ @brief Operator /= for UINT_32 argument
+ @param oValue - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const UINT_32 oValue);
+
+ /**
+ @brief Operator /= for W_FLOAT argument
+ @param oValue - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const W_FLOAT oValue);
+
+ /**
+ @brief Operator /= for CDT argument
+ @param oCDT - value to division
+ @return Read/write reference to self
+ */
+ CDT & operator/=(const CDT & oCDT);
+
+ // ///////////////////////////////////////////////
+
+ // Operator == ///////////////////////////////////
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator == for old-fashion string argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator == for string argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator == for CDT argument
+ @param oCDT - value to compare
+ @return true if values are equal
+ */
+ bool operator==(const CDT & oCDT) const;
+
+ // Operator != ///////////////////////////////////
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator != for old-fashion string argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator != for string argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator != for CDT argument
+ @param oCDT - value to compare
+ @return true if values are not equal
+ */
+ bool operator!=(const CDT & oCDT) const;
+ // ///////////////////////////////////////////////
+
+ // Operator > ///////////////////////////////////
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator > for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator > for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator > for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater than value
+ */
+ bool operator>(const CDT & oCDT) const;
+
+ // Operator < ///////////////////////////////////
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator < for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator < for string argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator < for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool operator<(const CDT & oCDT) const;
+
+ // Operator >= ///////////////////////////////////
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator >= for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator >= for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator >= for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator>=(const CDT & oCDT) const;
+
+ // Operator <= ///////////////////////////////////
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const INT_64 oValue) const;
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const INT_32 oValue) const;
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparison operator <= for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparison operator <= for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparison operator <= for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool operator<=(const CDT & oCDT) const;
+
+ // Comparator Equal ///////////////////////////////////
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator Equal for old-fashion string argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator Equal for string argument
+ @param oValue - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator Equal for CDT argument
+ @param oCDT - value to compare
+ @return true if values are equal
+ */
+ bool Equal(const CDT & oCDT) const;
+
+ // Comparator NotEqual ///////////////////////////////////
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator NotEqual for old-fashion string argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator NotEqual for string argument
+ @param oValue - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator NotEqual for CDT argument
+ @param oCDT - value to compare
+ @return true if values are not equal
+ */
+ bool NotEqual(const CDT & oCDT) const;
+
+ // Comparator Greater ///////////////////////////////////
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator Greater for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator Greater for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator Greater for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater than value
+ */
+ bool Greater(const CDT & oCDT) const;
+
+ // Comparator Less ///////////////////////////////////
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator Less for string argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator Less for string argument
+ @param oValue - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator Less for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is lesser than value
+ */
+ bool Less(const CDT & oCDT) const;
+
+ // Comparator GreaterOrEqual ///////////////////////////////////
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator GreaterOrEqual for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool GreaterOrEqual(const CDT & oCDT) const;
+
+ // Comparator LessOrEqual ///////////////////////////////////
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const INT_64 oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const UINT_64 oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const INT_32 oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const UINT_32 oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const W_FLOAT oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for old-fashion string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(CCHAR_P oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for string argument
+ @param oValue - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const STLW::string & oValue) const;
+
+ /**
+ @brief Comparator LessOrEqual for CDT argument
+ @param oCDT - value to compare
+ @return true if CDT is greater or equal than value
+ */
+ bool LessOrEqual(const CDT & oCDT) const;
+
+ // ///////////////////////////////////////////////
+
+ /**
+ @brief Pre-increment operator ++
+ @return Read/write reference to self
+ */
+ CDT & operator++();
+
+ /**
+ @brief Post-increment operator ++
+ @return Read/write reference to self
+ */
+ CDT operator++(int);
+
+ /**
+ @brief Pre-decrement operator --
+ @return Read/write reference to self
+ */
+ CDT & operator--();
+
+ /**
+ @brief Post-decrement operator --
+ @return Read/write reference to self
+ */
+ CDT operator--(int);
+
+ /**
+ @brief Append a string to CDT
+ @see Append(const STLW::string & oValue)
+ @param oValue - string to append
+ @return read/write referense to self
+ */
+ CDT & Concat(const STLW::string & oValue);
+
+ /**
+ @brief Append a old-fashion string to CDT
+ @see Append(CCHAR_P * szData, const INT_32 & iDataLength)
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Concat(CCHAR_P szData, const INT_32 iDataLength = -1);
+
+ /**
+ @brief Append a string to CDT, alias for Concat
+ @see Concat(const STLW::string & oValue)
+ @param oValue - string to append
+ @return read/write referense to self
+ */
+ CDT & Append(const STLW::string & oValue);
+
+ /**
+ @brief Append a old-fashion string to CDT
+ @see Concat(CCHAR_P * szData, const INT_32 & iDataLength)
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(CCHAR_P szData, const INT_32 iDataLength = -1);
+
+ /**
+ @brief Append a INT_64 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(const INT_64 oValue);
+
+ /**
+ @brief Append a INT_64 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(const UINT_64 oValue);
+
+ /**
+ @brief Append a INT_32 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(const INT_32 oValue);
+
+ /**
+ @brief Append a UINT_32 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(const UINT_32 oValue);
+
+ /**
+ @brief Append a W_FLOAT to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Append(const W_FLOAT oValue);
+
+ /**
+ @brief Append a string to CDT, alias for Concat
+ @see Concat(const STLW::string & oValue)
+ @param oValue - string to append
+ @return read/write referense to self
+ */
+ CDT & Append(const CDT & oCDT);
+
+ /**
+ @brief Prepend a string to CDT, alias for Concat
+ @see Concat(const STLW::string & oValue)
+ @param oValue - string to append
+ @return read/write referense to self
+ */
+ CDT & Prepend(const STLW::string & oValue);
+
+ /**
+ @brief Prepend a old-fashion string to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(CCHAR_P szData, const INT_32 iDataLength = -1);
+
+ /**
+ @brief Prepend a INT_64 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(const INT_64 oValue);
+
+ /**
+ @brief Prepend a INT_64 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(const UINT_64 oValue);
+
+ /**
+ @brief Prepend a INT_32 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(const INT_32 oValue);
+
+ /**
+ @brief Prepend a UINT_32 to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(const UINT_32 oValue);
+
+ /**
+ @brief Prepend a W_FLOAT to CDT
+ @param szData - string to append
+ @param iDataLength - string length
+ @return read/write referense to self
+ */
+ CDT & Prepend(const W_FLOAT oValue);
+
+ /**
+ @brief Prepend a string to CDT
+ @see Concat(const STLW::string & oValue)
+ @param oValue - string to append
+ @return read/write referense to self
+ */
+ CDT & Prepend(const CDT & oCDT);
+
+ /**
+ @brief Get value as W_FLOAT
+ */
+ W_FLOAT GetFloat() const;
+
+ /**
+ @brief Get value as INT_64
+ */
+ INT_64 GetInt() const;
+
+ /**
+ @brief Get value as UINT_64
+ */
+ UINT_64 GetUInt() const;
+
+ /**
+ @brief Get value as STLW::string
+ @param szFormat - output format
+ @return String object representation
+ */
+ STLW::string GetString(CCHAR_P szFormat = "") const;
+
+ /**
+ @brief Cast value to W_FLOAT
+ */
+ W_FLOAT ToFloat();
+
+ /**
+ @brief Cast value to INT_64
+ */
+ INT_64 ToInt();
+
+ /**
+ @brief Cast value to STLW::string
+ @param szFormat - output format
+ @return String object representation
+ */
+ STLW::string ToString(CCHAR_P szFormat = "");
+
+ /**
+ @brief Get generic pointer
+ @return generic pointer
+ */
+ const void * GetPointer() const;
+
+ /**
+ @brief Get object
+ @return pointer to specified type
+ */
+ template<typename T> const T * GetObject() const { return (T*)GetPointer(); }
+
+ /**
+ @brief Get generic pointer
+ @return generic pointer
+ */
+ void * GetPointer();
+
+ /**
+ @brief Get object
+ @return pointer to specified type
+ */
+ template<typename T> T * GetObject() { return (T*)GetPointer(); }
+
+ /**
+ @brief Recursively dump CDT into string
+ @param iLevel - left margin
+ @param bGlobalFmt - use global object formatting
+ @return printable string
+ */
+ STLW::string Dump(UINT_32 iLevel = 0, bool bGlobalFmt = false) const;
+
+ /**
+ @brief Alias for RecursiveDump, deprecated
+ @param iLevel - left margin
+ @return printable string
+ */
+ STLW::string RecursiveDump(UINT_32 iLevel = 0) const;
+
+ /**
+ @brief Get value type of object
+ */
+ eValType GetType() const;
+
+ /**
+ @brief Get printable value type of object
+ @return printable name of data type
+ */
+ CCHAR_P PrintableType() const;
+
+ /**
+ @brief Get printable value type
+ @return printable name of data type
+ */
+ static CCHAR_P PrintableType(eValType eType);
+
+ /**
+ @brief Get array of hash size
+ @return Size of array
+ */
+ UINT_32 Size() const;
+
+ /**
+ @brief Swap values
+ @param oCDT - value to swap
+ @return Reference to self
+ */
+ CDT & Swap(CDT & oCDT);
+
+ /**
+ @brief Join array elements to string
+ @brief sDelimiter - delimiter between elements
+ @return string as result of join array values
+ */
+ STLW::string JoinArrayElements(const STLW::string & sDelimiter = "") const;
+
+ /**
+ @brief Join hash keys
+ @brief sDelimiter - delimiter between keys
+ @return string as result of join hash keys
+ */
+ STLW::string JoinHashKeys(const STLW::string & sDelimiter = "") const;
+
+ /**
+ @brief Join hash values
+ @brief sDelimiter - delimiter between keys
+ @return string as result of join hash values
+ */
+ STLW::string JoinHashValues(const STLW::string & sDelimiter = "") const;
+
+ /**
+ @brief Get hash keys
+ @return CDT with ARRAY type with hash keys
+ */
+ CDT GetHashKeys() const;
+
+ /**
+ @brief Get hash values
+ @return CDT with ARRAY type with hash values
+ */
+ CDT GetHashValues() const;
+
+ /**
+ @brief Merge two CDT's
+ @param oSource - source object
+ @param eStrategy - Merging strategy
+ */
+ void MergeCDT(const CDT & oSource, const eMergeStrategy & eStrategy = FAST_MERGE);
+
+ /**
+ @brief Quick sort ARRAY
+ @param oSortingComparator - variables comparator
+ */
+ void SortArray(const SortingComparator & oSortingComparator);
+
+ /**
+ @class SortingComparator CDT.hpp <CDT.hpp>
+ @brief Sorting comparator
+ */
+ class CTPP2DECL SortingComparator
+ {
+ public:
+ /**
+ @brief Sorting direction
+ */
+ enum eSortingDirection { ASC, DESC };
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return 0 - if equel, -1 - if oX < oY, 1 - if ox > oY
+ */
+ virtual bool operator()(const CDT & oX, const CDT & oY) const = 0;
+
+ /**
+ @brief A dertructor
+ */
+ virtual ~SortingComparator() throw();
+ };
+
+ // FWD
+ class CTPP2DECL ConstIterator;
+
+ /**
+ @class Iterator CDT.hpp <CDT.hpp>
+ @brief CDT[HASH] forward iterator
+ */
+ class CTPP2DECL Iterator
+ {
+ private:
+ friend class CDT;
+ friend class ConstIterator;
+
+ /** Hash iterator */
+ CDT::Map::iterator itMap;
+
+ /**
+ @brief Constructor
+ @param itIMap - map iterator
+ */
+ Iterator(CDT::Map::iterator itIMap);
+ public:
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ Iterator(const Iterator & oRhs);
+
+ /**
+ @brief Operator =
+ @param oRhs - object to copy
+ */
+ Iterator & operator=(const Iterator & oRhs);
+
+ /**
+ @brief Pre-increment operator ++
+ */
+ Iterator & operator++();
+
+ /**
+ @brief Post-increment operator ++
+ */
+ Iterator operator++(int);
+
+ /**
+ @brief Access operator
+ @return Pair of key => value
+ */
+ STLW::pair<const STLW::string, CDT> * operator->();
+
+ /**
+ @brief Comparison operator
+ @param oRhs - object to compare
+ @return true if objects are equal
+ */
+ bool operator ==(const Iterator & oRhs);
+
+ /**
+ @brief Comparison operator
+ @param oRhs - object to compare
+ @return true if objects are NOT equal
+ */
+ bool operator !=(const Iterator & oRhs);
+ };
+
+ /**
+ @brief Get iterator pointed to start of hash
+ */
+ Iterator Begin();
+
+ /**
+ @brief Get iterator pointed to end of hash
+ */
+ Iterator End();
+
+ /**
+ @brief Find element in hash
+ @param sKey - element name
+ @return Iterator pointed to element or to end of hash if nothing found
+ */
+ Iterator Find(const STLW::string & sKey);
+
+ /**
+ @class ConstIterator CDT.hpp <CDT.hpp>
+ @brief CDT[HASH] forward constant iterator
+ */
+ class CTPP2DECL ConstIterator
+ {
+ private:
+ friend class CDT;
+
+ /** Hash iterator */
+ CDT::Map::const_iterator itMap;
+
+ public:
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ ConstIterator(const ConstIterator & oRhs);
+
+ /**
+ @brief Type cast constructor
+ @param oRhs - object to copy
+ */
+ ConstIterator(const Iterator & oRhs);
+
+ /**
+ @brief Operator =
+ @param oRhs - object to copy
+ */
+ ConstIterator & operator=(const ConstIterator & oRhs);
+
+ /**
+ @brief Operator =
+ @param oRhs - object to copy
+ */
+ ConstIterator & operator=(const Iterator & oRhs);
+
+ /**
+ @brief Pre-increment operator ++
+ */
+ ConstIterator & operator++();
+
+ /**
+ @brief Post-increment operator ++
+ */
+ ConstIterator operator++(int);
+
+ /**
+ @brief Access operator
+ @return Pair of key => value
+ */
+ const STLW::pair<const STLW::string, CDT> * operator->() const;
+
+ /**
+ @brief Comparison operator
+ @param oRhs - object to compare
+ @return true if objects are equal
+ */
+ bool operator ==(const ConstIterator & oRhs) const;
+
+ /**
+ @brief Comparison operator
+ @param oRhs - object to compare
+ @return true if objects are NOT equal
+ */
+ bool operator !=(const ConstIterator & oRhs) const;
+ };
+
+ /**
+ @brief Get constant iterator pointed to start of hash
+ */
+ ConstIterator Begin() const;
+
+ /**
+ @brief Get constant iterator pointed to end of hash
+ */
+ ConstIterator End() const;
+
+ /**
+ @brief Find element in hash
+ @param sKey - element name
+ @return Iterator pointed to element or to end of hash if nothing found
+ */
+ ConstIterator Find(const STLW::string & sKey) const;
+
+ /**
+ @brief Try to cast value to integer or to IEEE floating point value
+ @return Cast result type
+ */
+ eValType CastToNumber(INT_64 & iData,
+ W_FLOAT & dData) const;
+
+ /**
+ @brief A destructor
+ */
+ ~CDT() throw();
+
+private:
+ // Friends
+ CTPP2DECL friend CDT operator-(const UINT_64 & oValue, const CDT & oCDT);
+ CTPP2DECL friend CDT operator-(const INT_64 & oValue, const CDT & oCDT);
+ CTPP2DECL friend CDT operator-(const W_FLOAT & oValue, const CDT & oCDT);
+
+ CTPP2DECL friend CDT operator/(const UINT_64 & oValue, const CDT & oCDT);
+ CTPP2DECL friend CDT operator/(const INT_64 & oValue, const CDT & oCDT);
+ CTPP2DECL friend CDT operator/(const W_FLOAT & oValue, const CDT & oCDT);
+
+ // FWD
+ struct _CDT;
+
+ /** Plain Old datatypes */
+ union
+ {
+ /** Signed interger */
+ INT_64 i_data;
+ /** Floating point value */
+ W_FLOAT d_data;
+ /** Pointer to shareable container */
+ _CDT * p_data;
+ /** Generic pointer */
+ void * pp_data;
+ } u;
+
+ /** Value type */
+ mutable eValType eValueType;
+
+ /**
+ @brief Destroy object if need
+ */
+ void Destroy() throw();
+
+ /**
+ @brief Unshare shareable container
+ */
+ void Unshare();
+
+ /**
+ @brief Dump CDT into string
+ @param iLevel - level of recursion
+ @param oData - data to dump
+ @param sResult - string to put result in
+ */
+ static void DumpData(UINT_32 iLevel, UINT_32 iOffset, const CDT & oData, STLW::string & sResult, bool bGlobalFmt = false);
+
+ /**
+ @brief Merge two CDT's
+ @param oDestination - destination object
+ @param oSource - source object
+ @param eStrategy - Merging strategy
+ */
+ static void MergeCDT(CDT & oDestination, const CDT & oSource, const eMergeStrategy & eStrategy);
+
+ /**
+ @brief Check complex data type and change value type, if need
+ */
+ void CheckComplexDataType() const;
+
+};
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Realization
+//
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ @brief Operator + for UINT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of addition with same type of oCDT
+*/
+CTPP2DECL CDT operator+(const UINT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator + for INT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of addition with same type of oCDT
+*/
+CTPP2DECL CDT operator+(const INT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator + for UINT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of addition with same type of oCDT
+*/
+CTPP2DECL CDT operator+(const UINT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator + for INT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of addition with same type of oCDT
+*/
+CTPP2DECL CDT operator+(const INT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator + for W_FLOAT and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of addition with same type of oCDT
+*/
+CTPP2DECL CDT operator+(const W_FLOAT & oValue, const CDT & oCDT);
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ @brief Operator - for UINT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of substraction with same type of oCDT
+*/
+CTPP2DECL CDT operator-(const UINT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator - for INT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of substraction with same type of oCDT
+*/
+CTPP2DECL CDT operator-(const INT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator - for UINT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of substraction with same type of oCDT
+*/
+CTPP2DECL CDT operator-(const UINT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator - for INT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of substraction with same type of oCDT
+*/
+CTPP2DECL CDT operator-(const INT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator - for W_FLOAT and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of substraction with same type of oCDT
+*/
+CTPP2DECL CDT operator-(const W_FLOAT & oValue, const CDT & oCDT);
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ @brief Operator * for UINT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of multiplication with same type of oCDT
+*/
+CTPP2DECL CDT operator*(const UINT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator * for INT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of multiplication with same type of oCDT
+*/
+CTPP2DECL CDT operator*(const INT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator * for UINT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of multiplication with same type of oCDT
+*/
+CTPP2DECL CDT operator*(const UINT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator * for INT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of multiplication with same type of oCDT
+*/
+CTPP2DECL CDT operator*(const INT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator * for W_FLOAT and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of multiplication with same type of oCDT
+*/
+CTPP2DECL CDT operator*(const W_FLOAT & oValue, const CDT & oCDT);
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+ @brief Operator / for UINT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of division with same type of oCDT
+*/
+CTPP2DECL CDT operator/(const UINT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator / for INT_64 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of division with same type of oCDT
+*/
+CTPP2DECL CDT operator/(const INT_64 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator / for UINT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of division with same type of oCDT
+*/
+CTPP2DECL CDT operator/(const UINT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator / for INT_32 and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of division with same type of oCDT
+*/
+CTPP2DECL CDT operator/(const INT_32 & oValue, const CDT & oCDT);
+
+/**
+ @brief Operator / for W_FLOAT and CDT arguments
+ @param oValue - 1-st argument
+ @param oCDT - 2-nd argument
+ @return result of division with same type of oCDT
+*/
+CTPP2DECL CDT operator/(const W_FLOAT & oValue, const CDT & oCDT);
+
+} // namespace CTPP
+#endif // _CDT_HPP__
+// End.
diff --git a/include/CDTSortRoutines.hpp b/include/CDTSortRoutines.hpp
new file mode 100644
index 0000000..ebefd8d
--- /dev/null
+++ b/include/CDTSortRoutines.hpp
@@ -0,0 +1,251 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDTSortRoutines.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CDT_SORT_ROUTINES_HPP__
+#define _CDT_SORT_ROUTINES_HPP__ 1
+
+/**
+ @file CDTSortRoutines.hpp
+ @brief Sorting routines
+*/
+
+#include "CDT.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class SortCompareNum CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareNum:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param eIDirection - sorting direction
+ */
+ SortCompareNum(const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareNum() throw();
+private:
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+/**
+ @class SortCompareStr CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareStr:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param eIDirection - sorting direction
+ */
+ SortCompareStr(const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareStr() throw();
+private:
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+/**
+ @class SortCompareNumHashElement CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareNumHashElement:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param sIKey - key of key => value pair of HASH to compare
+ @param eIDirection - sorting direction
+ */
+ SortCompareNumHashElement(const STLW::string & sIKey,
+ const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareNumHashElement() throw();
+
+private:
+ /** Array element index */
+ const STLW::string sKey;
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+/**
+ @class SortCompareStrHashElement CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareStrHashElement:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param sIKey - key of key => value pair of HASH to compare
+ @param eIDirection - sorting direction
+ */
+ SortCompareStrHashElement(const STLW::string & sIKey,
+ const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareStrHashElement() throw();
+
+private:
+ /** Array element index */
+ const STLW::string sKey;
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+/**
+ @class SortCompareNumArrayElement CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareNumArrayElement:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIndex - index of ARRAY to compare
+ @param eIDirection - sorting direction
+ */
+ SortCompareNumArrayElement(const UINT_32 iIIndex,
+ const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareNumArrayElement() throw();
+private:
+ /** Array element index */
+ const UINT_32 iIndex;
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+/**
+ @class SortCompareNumArrayElement CDTSortRoutines.hpp <CDTSortRoutines.hpp>
+ @brief Sorting comparator
+*/
+class CTPP2DECL SortCompareStrArrayElement:
+ public CDT::SortingComparator
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIndex - index of ARRAY to compare
+ @param eIDirection - sorting direction
+ */
+ SortCompareStrArrayElement(const UINT_32 iIIndex,
+ const CDT::SortingComparator::eSortingDirection & eIDirection = CDT::SortingComparator::ASC);
+
+ /**
+ @brief Compare two values.
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+
+ /**
+ @brief A destructor
+ */
+ ~SortCompareStrArrayElement() throw();
+private:
+ /** Array element index */
+ const UINT_32 iIndex;
+ /** Sorting direction */
+ const CDT::SortingComparator::eSortingDirection eDirection;
+};
+
+} // namespace CTPP
+#endif // _CDT_SORT_ROUTINES_HPP__
+// End.
diff --git a/include/CTPP2BitIndex.hpp b/include/CTPP2BitIndex.hpp
new file mode 100644
index 0000000..91a53fb
--- /dev/null
+++ b/include/CTPP2BitIndex.hpp
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2BitIndex.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_BIT_INDEX_HPP__
+#define _CTPP2_BIT_INDEX_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2BitIndex.hpp
+ @brief Bit index implementation
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct BitIndexData CTPP2BitIndex.hpp <CTPP2BitIndex.hpp>
+ @brief Bit index
+*/
+struct BitIndexData
+{
+ /** Index size */
+ UINT_64 size; // Alignment !
+ /** Index data */
+ CHAR_8 data[8]; // Alignment !
+};
+
+
+/**
+ @class ReducedBitIndex CTPP2BitIndex.hpp <CTPP2BitIndex.hpp>
+ @brief Reduced bit index functionality
+*/
+class CTPP2DECL ReducedBitIndex
+{
+public:
+ /**
+ @brief Constructor
+ @param aIData - index data object
+ */
+ ReducedBitIndex(const BitIndexData * aIData);
+
+ /**
+ @brief Get index data
+ @return Pointer to BitIndexData structure
+ */
+ const BitIndexData * GetIndexData() const;
+
+ /**
+ @brief Get number of used bytes in index
+ @return Number of used bytes in index
+ */
+ UINT_32 GetUsedSize() const;
+
+ /**
+ @brief Get bit from index
+ @param iOffset - bit offset
+ @return bit from index
+ */
+ CHAR_8 GetBit(const UINT_32 iOffset) const;
+
+ /**
+ @brief A destructor
+ */
+ ~ReducedBitIndex() throw();
+private:
+
+ /** Bit index */
+ const BitIndexData * aData;
+
+};
+
+/**
+ @class BitIndex CTPP2BitIndex.hpp <CTPP2BitIndex.hpp>
+ @brief Bit index
+*/
+class CTPP2DECL BitIndex
+{
+public:
+ /**
+ @brief Constructor
+ @param iSize - initial index size
+ */
+ BitIndex(const UINT_32 iSize);
+
+ /**
+ @brief Get index data
+ @return Pointer to BitIndexData structure
+ */
+ const BitIndexData * GetIndexData() const;
+
+ /**
+ @brief Get number of used bytes in index
+ @return Number of used bytes in index
+ */
+ UINT_32 GetUsedSize() const;
+
+ /**
+ @brief Get bit from index
+ @param iOffset - bit offset
+ @return bit from index
+ */
+ CHAR_8 GetBit(const UINT_32 iOffset) const;
+
+ /**
+ @brief Get bit from index
+ @param iOffset - bit offset
+ @param iValue - value to set
+ @return bit from index
+ */
+ void SetBit(const UINT_32 iOffset, const CHAR_8 iValue);
+
+ /**
+ @brief A destructor
+ */
+ ~BitIndex() throw();
+private:
+ /** Bit index */
+ BitIndexData * aData;
+
+ /** Max. bit index size */
+ UINT_32 iMaxSize;
+
+ // Does not exist
+ BitIndex(const BitIndex & oRhs);
+
+ // Does not exist
+ BitIndex & operator=(const BitIndex & oRhs);
+
+ /**
+ @brief Resize bit index
+ */
+ void ResizeBitIndex(const UINT_32 & iBytePos);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_BIT_INDEX_HPP__
+// End.
diff --git a/include/CTPP2CharIterator.hpp b/include/CTPP2CharIterator.hpp
new file mode 100644
index 0000000..c127088
--- /dev/null
+++ b/include/CTPP2CharIterator.hpp
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2CharIterator.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_CHAR_ITERATOR_HPP__
+#define _CTPP2_CHAR_ITERATOR_HPP__ 1
+
+/**
+ @file CTPP2CharIterator.hpp
+ @brief String iterator
+*/
+
+#include "CTPP2Types.h"
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CharIterator CTPP2CharIterator.hpp <CTPP2CharIterator.hpp>
+ @brief Character iterator
+*/
+template <typename T> class CharIterator
+{
+public:
+ /** Data string */
+ T * szData;
+ /** Current position */
+ INT_32 iPos;
+ /** Current Line */
+ INT_32 iLine;
+ /** Current line position */
+ INT_32 iLinePos;
+public:
+ /**
+ @brief Constructor
+ @param szIData - data
+ */
+ inline CharIterator(T * szIData): szData(szIData), iPos(0), iLine(1), iLinePos(1) { ;; }
+
+ /**
+ @brief Operator *
+ @return reference to symbol
+ */
+ inline T operator*() { return szData[iPos]; }
+
+ /**
+ @brief Pre increment operator
+ @return reference to self
+ */
+ inline CharIterator operator++()
+ {
+ if (szData[iPos] == '\n') { ++iLine; iLinePos = 0; }
+ ++iLinePos;
+ ++iPos;
+
+ return *this;
+ }
+
+ /**
+ @brief Post increment operator
+ @return reference to self
+ */
+ inline CharIterator operator++(int)
+ {
+ CharIterator oTMP = *this;
+
+ if (szData[iPos] == '\n') { ++iLine; iLinePos = 0; }
+ ++iLinePos;
+ ++iPos;
+
+ return oTMP;
+ }
+
+ /**
+ @brief Compare two iterators
+ @return true if iterators are equal
+ */
+ inline bool operator==(const CharIterator & x) const throw() { return ((szData + iPos) == (x.szData + x.iPos)); }
+
+ /**
+ @brief Compare two iterators
+ @return true if iterators are NOT equal
+ */
+ inline bool operator!=(const CharIterator & x) const throw() { return ((szData + iPos) != (x.szData + x.iPos)); }
+
+ /**
+ @brief Get data
+ @return pointer to current data
+ */
+ inline T * operator()() { return (szData + iPos); }
+
+ /**
+ @brief Get data
+ @return pointer to current data
+ */
+ inline INT_32 GetLine() const throw() { return iLine; }
+
+ /**
+ @brief Get data
+ @return pointer to current data
+ */
+ inline INT_32 GetLinePos() const throw() { return iLinePos; }
+
+ /**
+ @brief Get data
+ @return pointer to current data
+ */
+ inline INT_32 GetPos() const throw() { return iPos; }
+};
+
+
+typedef CharIterator<CCHAR_8> CCharIterator;
+
+} // namespace CTPP
+#endif // _CTPP2_CHAR_ITERATOR_HPP__
+// End.
diff --git a/include/CTPP2Compiler.hpp b/include/CTPP2Compiler.hpp
new file mode 100644
index 0000000..b4f7295
--- /dev/null
+++ b/include/CTPP2Compiler.hpp
@@ -0,0 +1,624 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Compiler.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_COMPILER_HPP__
+#define _CTPP2_COMPILER_HPP__ 1
+
+/**
+ @file CTPP2Compiler.hpp
+ @brief CTPP2 temlate-to-bytecode compiler
+*/
+
+#include "CTPP2SymbolTable.hpp"
+#include "CTPP2Syntax.h"
+#include "CTPP2VMDebugInfo.hpp"
+#include "CTPP2VMOpcodeCollector.hpp"
+
+#include "STLMap.hpp"
+#include "STLString.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+class HashTable;
+class StaticText;
+class StaticData;
+class CTPP2Parser;
+
+/**
+ @class CTPP2Compiler CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief CTRPP2 compiler
+*/
+class CTPP2DECL CTPP2Compiler
+{
+public:
+ /**
+ @brief Constructor
+ @param oIVMOpcodeCollector - code segment collector
+ @param oISyscalls - syscalls segment
+ @param oIStaticData - static data segment
+ @param oIStaticText - static text segment
+ @param oIHashTable - hash table
+ */
+ CTPP2Compiler(VMOpcodeCollector & oIVMOpcodeCollector,
+ StaticText & oISyscalls,
+ StaticData & oIStaticData,
+ StaticText & oIStaticText,
+ HashTable & oIHashTable);
+
+ /**
+ @brief Store template source name
+ @param szName - name
+ @param iNameLength - name length
+ @return Name Id in static text segment, or -1 if any error occured
+ */
+ INT_32 StoreSourceName(CCHAR_P szName,
+ const UINT_32 iNameLength);
+
+ /**
+ @brief Send variable to standard output collector
+ @param oDebugInfo - debug information object
+ */
+ INT_32 OutputVariable(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Send text data to standard output collector
+ @param vBuffer - data
+ @param iBufferLength - data size
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OutputStaticData(CCHAR_P vBuffer,
+ const UINT_32 iBufferLength,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Send integer value to standard output collector
+ @param iData - value to print
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OutputStaticData(const INT_64 & iData,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Send floating point value to standard output collector
+ @param sData - value to print
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OutputStaticData(const W_FLOAT & sData,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Change visibility scope of CDT data (for ARRAY iterating)
+ @param szScopeName - ARRAY name
+ @param iScopeNameLength - Length of ARRAY name
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ChangeScope(CCHAR_P szScopeName,
+ const UINT_32 iScopeNameLength,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Reset scope to previous CDT data (for ARRAY iterating)
+ @param iIP - instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ResetScope(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Execute system call such as HREF_PARAM, FORM_PARAM, etc
+ @param szSyscallName - syscall name
+ @param iSyscallNameLength - Length of syscall name
+ @param iArgNum - number of arguments
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ExecuteSyscall(CCHAR_P szSyscallName,
+ const UINT_32 iSyscallNameLength,
+ const UINT_32 iArgNum,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Prepare before push hash or array variable
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PreparePushComplexVariable(const VMDebugInfo & oDebugInfo);
+
+ /**
+ @brief Clear after push hash or array variable
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ClearPushComplexVariable(const VMDebugInfo & oDebugInfo);
+
+ /**
+ @brief Push block's variable into stack
+ @param iIdx - stack position
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushBlockVariable(const UINT_32 iIdx,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Prepare local scope for searching variable
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PrepareLocalScope(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Push variable into stack
+ @param szVariableName - variable name
+ @param iVariableNameLength - Length of variable name
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushVariable(CCHAR_P szVariableName,
+ const UINT_32 iVariableNameLength,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Push integer value into stack
+ @param iVariable - value to push
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushInt(const INT_64 & iVariable,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Push Float value into stack
+ @param dVariable - value to push
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushFloat(const W_FLOAT & dVariable,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Push string variable into stack
+ @param szData - data
+ @param iDataLength - data length
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushString(CCHAR_P szData,
+ const UINT_32 iDataLength,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Pop variable from stack
+ @param iVars - number of variables to clear from stack
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PopVariable(const INT_32 iVars = 1,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Check existence of stack variable
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ExistStackVariable(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Check existence of AR register variable
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ExistARReg(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Call block by name
+ @param sBlockName - block name
+ @param bIsVariable - is true if block name is variable, not plain text
+ @param iArgCount - number of arguments
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 CallBlock(const STLW::string & sBlockName,
+ const bool & bIsVariable,
+ const UINT_32 iArgCount,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Start of block
+ @param sBlockName - block name
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 StartBlock(const STLW::string & sBlockName,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief End of block
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 EndBlock(const UINT_32 iDepth, const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Prepare call block
+ @param oDebugInfo - debug information object
+ */
+ void PrepareCallBlock(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ // ////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Get system call by id
+ @param szSyscallName - syscall name
+ @param iSyscallNameLength - Length of syscall name
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 GetSyscallId(CCHAR_P szSyscallName,
+ const UINT_32 iSyscallNameLength);
+
+ /**
+ @brief Get last instruction number
+ */
+ UINT_32 GetCodeSize() const;
+
+ /**
+ @brief Get instruction by instruction number
+ @param iIP - instruction number
+ @return pointer to instruction or NULL if instruction does not exist
+ */
+ VMInstruction * GetInstruction(const UINT_32 iIP);
+
+ /**
+ @brief Remove last instruction from code segment
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RemoveInstruction();
+
+ /**
+ @brief Addition
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpAdd(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Substraction
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpSub(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Multiplication
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpMul(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Dividion
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpDiv(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Integer dividion
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpIDiv(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief MOD
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpMod(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Negation
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpNeg(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Logical Negation
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpNot(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Comparison
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpCmp(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief String comparison
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 OpSCmp(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Store variable in scope
+ @param sNS - namespace
+ @param oDebugInfo - debug information object
+ @return Variable scope Id
+ */
+ INT_32 StoreScopedVariable(CCHAR_P szNS,
+ const UINT_32 iNSLength,
+ const VMDebugInfo & oDebugInfo);
+
+ /**
+ @brief Push variable into stack
+ @param szVariableName - variable name
+ @param iVariableNameLength - variable name length
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushScopedVariable(CCHAR_P szName,
+ const UINT_32 iNameLength,
+ CCHAR_P szFullVariable,
+ const UINT_32 iFullVariableLength,
+ const VMDebugInfo & oDebugInfo);
+
+ /**
+ @brief Push variable on stack into stack
+ @param iStackPos - stack position
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 PushStackVariable(const INT_32 iStackPos,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Indirect call
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 IndirectCall(const VMDebugInfo & oDebugInfo);
+
+ /**
+ @brief Unconditional jump
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 UncondJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+ /**
+ @brief Jump if NOT Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 NEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 EQJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Greater
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 GTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Greater Or Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 GEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Less
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 LTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Less Or Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 LEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Unconditional jump
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RUncondJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+ /**
+ @brief Jump if NOT Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RNEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 REQJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Greater
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RGTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Greater Or Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RGEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Less
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RLTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Jump if Less Or Equal
+ @param iIP - new instruction pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 RLEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Clear stack
+ @param iStackPointer - stack pointer
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 ClearStack(const UINT_32 iStackPointer = 0,
+ const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Stop execution
+ @param oDebugInfo - debug information object
+ @return instruction pointer if success, -1 if any error occured
+ */
+ INT_32 Halt(const VMDebugInfo & oDebugInfo = VMDebugInfo());
+
+ /**
+ @brief Decrease stack depth
+ */
+ void DecrDepth();
+
+ /**
+ @bref Increase stack depth
+ */
+ void IncrDepth();
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2Compiler() throw();
+
+private:
+ friend class CTPP2Parser;
+
+ struct SymbolTableRec
+ {
+ /** Relative depth of stack */
+ UINT_32 stack_depth;
+ /** Scope number */
+ UINT_32 scope_number;
+
+ inline SymbolTableRec(UINT_32 iStackDepth = 0,
+ UINT_32 iScopeNumber = 0): stack_depth(iStackDepth),
+ scope_number(iScopeNumber)
+ { ;; }
+ };
+
+ /** Current stack usage factor */
+ UINT_32 iStackDepth;
+ UINT_32 iScopeNumber;
+ /** RRegisters are dirty; need to */
+ bool bRegsAreDirty;
+
+ /** Symbol table */
+ SymbolTable<SymbolTableRec> oSymbolTable;
+ /** Opcodes collector */
+ VMOpcodeCollector & oVMOpcodeCollector;
+ /** Syscalls */
+ StaticText & oSyscalls;
+ /** Static data segment */
+ StaticData & oStaticData;
+ /** Static text segment */
+ StaticText & oStaticText;
+ /** Hash table for calls */
+ HashTable & oHashTable;
+
+ /** Syscall cache */
+ STLW::map<STLW::string, UINT_32> mSyscalls;
+ /** Id of stored 0 to compare */
+ UINT_32 iZeroId;
+ /** Id of stored 1 to compare */
+ UINT_32 iOneId;
+ /** Current block stack depth */
+ UINT_32 iCurrBlockStackDepth;
+ /** Saved stack depths for blocks */
+ STLW::vector<UINT_32> vSavedStackDepths;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_COMPILER_H__
+// End.
diff --git a/include/CTPP2DTOA.hpp b/include/CTPP2DTOA.hpp
new file mode 100644
index 0000000..222577b
--- /dev/null
+++ b/include/CTPP2DTOA.hpp
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Dtoa.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_DTOA_HPP__
+#define _CTPP2_DTOA_HPP__ 1
+
+
+#include "CTPP2Types.h"
+
+struct Bigint
+{
+ struct Bigint * next;
+ INT_32 k;
+ INT_32 maxwds;
+ INT_32 sign;
+ INT_32 wds;
+ UINT_32 x[1];
+};
+
+
+struct AllocatedBlock
+{
+ void * data;
+ AllocatedBlock * prev;
+};
+
+char *ctpp_dtoa(AllocatedBlock ** aBlocks, Bigint ** freelist, double d, int mode, int ndigits, int *decpt, int *sign, char **rve);
+
+void freedtoa(AllocatedBlock ** aBlocks);
+
+#define Kmax (sizeof(size_t) << 3)
+
+#define HAVE_PTHREAD_ATTR_GET_NP 1
+#define HAVE_PTHREAD_GETATTR_NP 1
+#define HAVE_PCREPOSIX 1
+#define HAVE_SYS_TIMEB_H 1
+#define HAVE_FLOAT_H 1
+#define HAVE_IEEEFP_H 1
+#define HAVE_MEMCHECK_H 1
+#define HAVE_FUNC__FINITE 1
+#define HAVE_FUNC_FINITE 1
+#define HAVE_FUNC_ISINF 1
+#define HAVE_FUNC_ISNAN 1
+#define HAVE_FUNC_POSIX_MEMALIGN 1
+
+#endif // _CTPP2_DTOA_HPP__
+// End.
diff --git a/include/CTPP2Error.hpp b/include/CTPP2Error.hpp
new file mode 100644
index 0000000..e3d4caa
--- /dev/null
+++ b/include/CTPP2Error.hpp
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Error.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_ERROR_H__
+#define _CTPP2_ERROR_H__ 1
+
+/**
+ @file CTPP2Error.hpp
+ @brief CTPP2 error description
+*/
+
+#include "CTPP2Types.h"
+
+#include "STLString.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct CTPPError CTPPError.hpp <CTPPError.cpp>
+ @brief CTPP Error description
+*/
+struct CTPPError
+{
+ /** Template name */
+ STLW::string template_name;
+ /** Human-readable error description */
+ STLW::string error_descr;
+ /** Error code */
+ UINT_32 error_code;
+ /** Line, where error occured */
+ UINT_32 line;
+ /** Position in line where error occured */
+ UINT_32 pos;
+ /** Instruction pointer */
+ UINT_32 ip;
+
+ /**
+ @brief Constructor
+ @param sTemplateName - name of template
+ @param sErrorDescr - Error description
+ @param iErrrorCode - Error code
+ @param iLine - Line in template, where error occured
+ @param iPos - Position in line, where error occured
+ @param iIP - Instrction pointer
+ */
+ CTPPError(const STLW::string & sTemplateName = "",
+ const STLW::string & sErrorDescr = "",
+ const UINT_32 iErrrorCode = 0,
+ const UINT_32 iLine = 0,
+ const UINT_32 iPos = 0,
+ const UINT_32 iIP = 0);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_ERROR_H__
+// End.
diff --git a/include/CTPP2ErrorCodes.h b/include/CTPP2ErrorCodes.h
new file mode 100644
index 0000000..d20c872
--- /dev/null
+++ b/include/CTPP2ErrorCodes.h
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2004 - 2009 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2ErrorCodes.h
+ *
+ * $CAS$
+ */
+#ifndef _CTPP2_ERROR_CODES_HPP__
+#define _CTPP2_ERROR_CODES_HPP__ 1
+
+/**
+ @file CTPP2ErrorCodes.h
+ @brief CTPP2 error codes
+*/
+
+#define CTPP_ERROR_CODE_MASK 0x00FFFFFF
+#define CTPP_ERROR_SUBSYSTEM_MASK 0xFF000000
+
+#define CTPP_DATA_ERROR 0x01000000
+#define CTPP_VM_ERROR 0x02000000
+#define CTPP_COMPILER_ERROR 0x04000000
+
+#define CTPP_CHARSET_RECODE_ERROR 0x00000013
+#define CTPP_OPERATORS_MISMATCH_ERROR 0x00000012
+#define CTPP_SYNTAX_ERROR 0x00000011
+#define CTPP_PARSER_ERROR 0x00000010
+
+#define CTPP_ZERO_DIVISION_ERROR 0x0000000F
+#define CTPP_EXECUTION_LIMIT_REACHED_ERROR 0x0000000E
+#define CTPP_CODE_SEGMENT_OVERRUN_ERROR 0x0000000D
+#define CTPP_INVALID_SYSCALL_ERROR 0x0000000C
+#define CTPP_ILLEGAL_OPCODE_ERROR 0x0000000B
+#define CTPP_STACK_OVERFLOW_ERROR 0x0000000A
+#define CTPP_STACK_UNDERFLOW_ERROR 0x00000009
+#define CTPP_VM_GENERIC_ERROR 0x00000008
+#define CTPP_UNIX_ERROR 0x00000007
+
+#define CTPP_RANGE_ERROR 0x00000006
+#define CTPP_ACCESS_ERROR 0x00000005
+#define CTPP_TYPE_CAST_ERROR 0x00000004
+#define CTPP_LOGIC_ERROR 0x00000003
+#define CTPP_UNKNOWN_ERROR 0x00000002
+#define STL_UNKNOWN_ERROR 0x00000001
+
+#endif /* _CTPP2_ERROR_CODES_HPP__ */
+/* End. */
diff --git a/include/CTPP2Exception.hpp b/include/CTPP2Exception.hpp
new file mode 100644
index 0000000..7ded9d5
--- /dev/null
+++ b/include/CTPP2Exception.hpp
@@ -0,0 +1,283 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_EXCEPTION_HPP__
+#define _CTPP2_EXCEPTION_HPP__ 1
+
+#include "CTPP2Types.h"
+#ifdef _USE_STL_AS_BASE_EXCEPTION
+ #include "STLException.hpp"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPP2Exception CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Base class for all CTPP exceptions.
+*/
+class CTPP2DECL CTPPException
+#ifdef _USE_STL_AS_BASE_EXCEPTION
+:
+ public STLW::exception
+#endif // _USE_STL_AS_BASE_EXCEPTION
+{
+public:
+ /** @return A asciz string describing the general cause of error */
+ virtual CCHAR_P what() const throw();
+ /** @brief A virtual destructor */
+ virtual ~CTPPException() throw();
+};
+
+/**
+ @class CTPPLogicError CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Logic error
+*/
+class CTPP2DECL CTPPLogicError:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ */
+ CTPPLogicError(CCHAR_P sIReason) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CTPPLogicError() throw();
+private:
+ /** Error description */
+ CHAR_P sReason;
+};
+
+/**
+ @class CDTTypeCastException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Invalid type cast
+*/
+class CTPP2DECL CDTTypeCastException:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ */
+ CDTTypeCastException(CCHAR_P sIReason) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CDTTypeCastException() throw();
+private:
+ /** Error description */
+ CHAR_P sReason;
+};
+
+/**
+ @class CDTAccessException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Access violation exception
+*/
+class CTPP2DECL CDTAccessException:
+ public CTPPException
+{
+public:
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CDTAccessException() throw();
+private:
+
+};
+
+/**
+ @class CDTRangeException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Array index is out of bounds
+*/
+class CTPP2DECL CDTRangeException:
+ public CTPPException
+{
+public:
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CDTRangeException() throw();
+private:
+
+};
+
+/**
+ @class CTPPUnixException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Unix error code
+*/
+class CTPP2DECL CTPPUnixException:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ @param iIErrno - Unix error code
+ */
+ CTPPUnixException(CCHAR_P sIReason, INT_32 iIErrno) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** @return error code */
+ INT_32 ErrNo() const throw();
+
+ /** A destructor */
+ ~CTPPUnixException() throw();
+private:
+ /** Error description */
+ CHAR_P sReason;
+ /** Error code */
+ INT_32 iErrno;
+};
+
+/**
+ @class CTPPNullPointerException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Pointer is NULL
+*/
+class CTPP2DECL CTPPNullPointerException:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ */
+ CTPPNullPointerException(CCHAR_P sIReason) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CTPPNullPointerException() throw();
+private:
+ /** Error description */
+ CHAR_P sReason;
+};
+
+/**
+ @class CTPPCharsetRecodeException CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Cannot convert from source to destination charset
+*/
+class CTPP2DECL CTPPCharsetRecodeException:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sISrc - Source encoding
+ @param sIDst - Destination encoding
+ */
+ CTPPCharsetRecodeException(CCHAR_P sISrc,
+ CCHAR_P sIDst) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** @return Get source charset */
+ CCHAR_P GetSource() const throw();
+
+ /** @return Get destination charset */
+ CCHAR_P GetDestination() const throw();
+
+ /** A destructor */
+ ~CTPPCharsetRecodeException() throw();
+
+private:
+ /** Source charset */
+ CHAR_P sSrc;
+ /** Destinationset */
+ CHAR_P sDst;
+};
+
+/**
+ @class CTPPGetTextError CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Gettext error
+*/
+class CTPP2DECL CTPPGetTextError:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ */
+ CTPPGetTextError(CCHAR_P sIReason) throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CTPPGetTextError() throw();
+private:
+ /** Error description */
+ CHAR_P sReason;
+};
+
+/**
+ @class CTPPNoMemory CTPP2Exception.hpp <CTPP2Exception.hpp>
+ @brief Gettext error
+*/
+class CTPP2DECL CTPPNoMemoryError:
+ public CTPPException
+{
+public:
+ /**
+ @brief Constrcutor
+ @param sIReason - Error description
+ */
+ CTPPNoMemoryError() throw();
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** A destructor */
+ ~CTPPNoMemoryError() throw();
+};
+
+} // namespace CTPP
+#endif // _CTPP2_EXCEPTION_HPP__
+// End.
diff --git a/include/CTPP2FileLogger.hpp b/include/CTPP2FileLogger.hpp
new file mode 100644
index 0000000..5703cd3
--- /dev/null
+++ b/include/CTPP2FileLogger.hpp
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2FileLogger.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_FILE_LOGGER_HPP__
+#define _CTPP2_FILE_LOGGER_HPP__ 1
+
+#include "CTPP2Logger.hpp"
+
+#include <stdio.h>
+
+/**
+ @file CTPP2FileLogger.hpp
+ @brief CTPP2 file logger
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class FileLogger CTPP2FileLogger.hpp <CTPP2FileLogger.hpp>
+ @brief CTPP2 logger subsystem
+*/
+class CTPP2DECL FileLogger:
+ public Logger
+{
+protected:
+ /** File handle */
+ FILE * F;
+
+public:
+ /**
+ @brief Constructor
+ @param iIBasePriority - base priority
+ */
+ FileLogger(FILE * F, const UINT_32 iIBasePriority = CTPP2_LOG_WARNING);
+
+ /**
+ @brief Write message to log file
+ @param iPriority - priority level
+ @param szString - message to store in file
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 WriteLog(const UINT_32 iPriority,
+ CCHAR_P szString,
+ const UINT_32 iStringLen);
+
+ /**
+ @brief A destructor
+ */
+ ~FileLogger() throw();
+};
+
+} // namespace CTPP
+#endif // _CTPP2_FILE_LOGGER_HPP__
+// End.
diff --git a/include/CTPP2FileOutputCollector.hpp b/include/CTPP2FileOutputCollector.hpp
new file mode 100644
index 0000000..82d5984
--- /dev/null
+++ b/include/CTPP2FileOutputCollector.hpp
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2FileOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_FILE_OUTPUT_COLLECTOR_HPP__
+#define _CTPP2_FILE_OUTPUT_COLLECTOR_HPP__ 1
+
+#include "CTPP2OutputCollector.hpp"
+
+#include <stdio.h>
+
+/**
+ @file FileOutputCollector.hpp
+ @brief Virtual machine file output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class FileOutputCollector OutputCollector.hpp <OutputCollector.hpp>
+ @brief Output data collector
+*/
+class CTPP2DECL FileOutputCollector:
+ public OutputCollector
+{
+public:
+ /**
+ @brief Constructor
+ @param F - opened file
+ */
+ FileOutputCollector(FILE * F);
+
+ /**
+ @brief Constructor
+ @param iFHandle - opened file handle
+ */
+ FileOutputCollector(const INT_32 iFHandle);
+
+ /**
+ @brief Constructor
+ @param szFileName - file to open
+ @param szMode - open mode, similar to fopen(3)
+ */
+ FileOutputCollector(CCHAR_P szFileName, CCHAR_P szMode);
+
+ /**
+ @brief Get unix file number
+ @return file descriptor
+ */
+ INT_32 GetFileNo() const;
+
+ /**
+ @brief A destructor
+ */
+ ~FileOutputCollector() throw();
+private:
+
+ /** File handle */
+ FILE * oF;
+ /** Flag */
+ INT_32 iSelfOpened;
+
+ /**
+ @brief Collect data
+ @param vData - data to store
+ @param iDataLength - data length
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 Collect(const void * vData, const UINT_32 iDataLength);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_FILE_OUTPUT_COLLECTOR_HPP__
+// End.
diff --git a/include/CTPP2FileSourceLoader.hpp b/include/CTPP2FileSourceLoader.hpp
new file mode 100644
index 0000000..9010f05
--- /dev/null
+++ b/include/CTPP2FileSourceLoader.hpp
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SourceLoader.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_FILE_SOURCE_LOADER_H__
+#define _CTPP2_FILE_SOURCE_LOADER_H__ 1
+
+#include "CTPP2SourceLoader.hpp"
+
+#include "STLString.hpp"
+#include "STLVector.hpp"
+
+/**
+ @file CTPP2FileSourceLoader.hpp
+ @brief Load template from file
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPP2FileSourceLoader CTPP2FileSourceLoader.hpp> <CTPP2FileSourceLoader.hpp>
+ @brief Load template from file
+*/
+class CTPP2DECL CTPP2FileSourceLoader:
+ public CTPP2SourceLoader
+{
+public:
+ /**
+ @brief Constructor
+ */
+ CTPP2FileSourceLoader();
+
+ /**
+ @brief Set of directories where included templates should be found
+ @param vIncludeDirs - vector with directories
+ */
+ void SetIncludeDirs(const STLW::vector<STLW::string> & vIncludeDirs = STLW::vector<STLW::string>());
+
+ /**
+ @brief Load template with specified name
+ @param szTemplateName - template name
+ @return 0 if success, -1 if any error occured
+ */
+ INT_32 LoadTemplate(CCHAR_P szTemplateName);
+
+ /**
+ @brief Get template
+ @param iTemplateSize - template size [out]
+ @return pointer to start of template buffer if success, NULL - if any error occured
+ */
+ CCHAR_P GetTemplate(UINT_32 & iTemplateSize);
+
+ /**
+ @brief Get template file name
+ @return asciz temaplet filename
+ */
+ CCHAR_P GetTemplateName() const;
+
+ /**
+ @brief Clone loader object
+ @return clone to self
+ */
+ CTPP2SourceLoader * Clone();
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2FileSourceLoader() throw();
+private:
+ /* List ofi nclude directories */
+ STLW::vector<STLW::string> vIncludeDirs;
+
+ /** Template body */
+ CHAR_P sTemplate;
+ /** Template size */
+ UINT_32 iTemplateSize;
+ /** Current working directory */
+ STLW::string sCurrentDir;
+ /** Current template name */
+ STLW::string sNormalizedFileName;
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_FILE_SOURCE_LOADER_H__
+// End.
diff --git a/include/CTPP2GetText.hpp b/include/CTPP2GetText.hpp
new file mode 100644
index 0000000..239b2fd
--- /dev/null
+++ b/include/CTPP2GetText.hpp
@@ -0,0 +1,307 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_GETTEXT_HPP__
+#define _CTPP2_GETTEXT_HPP__ 1
+
+#include "CTPP2Types.h"
+#include "STLString.hpp"
+#include "STLVector.hpp"
+#include "STLMap.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class SyscallFactory;
+
+/**
+ @class CTPP2GetText CTPP2GetText.hpp <CTPP2GetText.hpp>
+ @brief CTPP2 gettext support
+*/
+class CTPP2DECL CTPP2GetText
+{
+public:
+ /**
+ @brief A constructor
+ */
+ CTPP2GetText();
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2GetText() throw();
+
+ /**
+ @brief Add translation
+ @param sFileName - .mo filename
+ @param sDomain - i18n domain
+ @param sLang - language of translation
+ */
+ void AddTranslation(const STLW::string & sFileName, const STLW::string & sDomain, const STLW::string & sLang);
+
+ /**
+ @brief Find translated message
+ @param sLang - language of translation
+ @param sMessage - message
+ @param sDomain - i18n domain (if none, default domain used)
+ @return translated message
+ */
+ STLW::string FindMessage(const STLW::string & sLang, const STLW::string & sMessage, const STLW::string & sDomain = "");
+
+ /**
+ @brief Find translated message with correct plural form
+ @param sLang - language of translation
+ @param sMessage - message in singular
+ @param sPlMessage - message in plural
+ @param iCount - determine plural form
+ @param sDomain - i18n domain (if none, default domain used)
+ @return translated message
+ */
+ STLW::string FindPluralMessage(const STLW::string & sLang, const STLW::string & sMessage, const STLW::string & sPlMessage,
+ UINT_32 iCount, const STLW::string & ssDomain = "");
+
+ /**
+ @brief Set default i18n domain
+ @param sDomain - i18n domain
+ */
+ void SetDefaultDomain(const STLW::string & sDomain);
+
+ /**
+ @brief Initialize system calls FnGetText/FnGetText_
+ @param oSyscallFactory - factory with system calls
+ */
+ void InitSTDLibFunction(SyscallFactory & oSyscallFactory);
+
+ /**
+ @brief Set language for system calls FnGetText/FnGetText_
+ @param oSyscallFactory - factory with system calls
+ @param sLang - language of translation
+ */
+ void SetLanguage(SyscallFactory & oSyscallFactory, const STLW::string & sLang);
+
+private:
+ enum eCTPP2Instruction { INS_NONE = 0,
+ INS_EQ = 1,
+ INS_NE = 2,
+ INS_LE = 3,
+ INS_LT = 4,
+ INS_GE = 5,
+ INS_GT = 6,
+ INS_MOD = 7,
+ INS_JN = 8,
+ INS_JMP = 9,
+ INS_JLAND = 10,
+ INS_JLOR = 11 };
+
+ /**
+ @struct CTPP2Data CTPP2GetText.hpp <CTPP2GetText.hpp>
+ @brief Representation of number/placeholder in plural form rule
+ */
+ struct CTPP2Data
+ {
+ /**
+ @brief A constructor for number data
+ @param iValue - number
+ */
+ CTPP2Data(UINT_32 iValue) : i_value(iValue), b_variable(false) { ;; }
+
+ /**
+ @brief A constructor for placeholder data
+ */
+ CTPP2Data() : i_value(0), b_variable(true) { ;; }
+
+ /** value of number */
+ UINT_32 i_value;
+ /** placeholder flag */
+ bool b_variable;
+ };
+
+ /**
+ @struct CTPP2Data CTPP2GetText.hpp <CTPP2GetText.hpp>
+ @brief i18n catalog
+ */
+ struct CTPP2Catalog
+ {
+ /** stack of data for determining of plural form */
+ STLW::vector<CTPP2Data> v_pl_stack;
+ /** list of instructions for determining of plural form */
+ STLW::vector<eCTPP2Instruction> v_pl_instructions;
+ /** charset of messages from .mo file */
+ STLW::string s_charset;
+ /** messages with translations */
+ STLW::map<STLW::string, STLW::vector<STLW::string> > m_messages;
+ /** generic information from .mo file */
+ STLW::map<STLW::string, STLW::string> m_info;
+ /** flag of endiannes of .mo file */
+ bool b_reversed;
+ };
+
+ /** Type of catalog map */
+ typedef STLW::map<STLW::string, STLW::map<STLW::string, CTPP2Catalog> > CatalogMap;
+
+ /** CTPP2Catalog map */
+ CatalogMap mCatalog;
+ /** Default i18n domain */
+ STLW::string sDefaultDomain;
+
+ /** i18n domain for generating plural form rule */
+ STLW::string sWorkableDomain;
+ /** Language for generating plural form rule */
+ STLW::string sWorkableLang;
+
+ // Parsing of .mo file ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Parse line of metadata from .mo file
+ @param sLine - line of metadata
+ @param sLastKey - key for multiline value
+ */
+ void ParseMetadataLine(const STLW::string & sLine, STLW::string & sLastKey);
+
+ /**
+ @brief Parse metadata from .mo file
+ @param sMeta - metadata
+ */
+ void ParseMetadata(const STLW::string & sMeta);
+
+ /**
+ @brief Read .mo data by 4 bytes
+ @param pData - .mo data
+ @param iOffset - offset of reading
+ @return integer value
+ */
+ UINT_32 ReadMOData(UCCHAR_P pData, INT_32 iOffset);
+
+ /**
+ @brief Read .mo file
+ @param szFileName - .mo filename
+ @param iLength - length of read file
+ @return data
+ */
+ UCHAR_P ReadFile(CCHAR_P szFileName, UINT_32 & iLength);
+
+ /**
+ @brief Extract message from .mo data
+ @param pData - .mo data
+ @param iLength - length of .mo data
+ @param iMasteridx - message index
+ @param iTransidx - translated message index
+ */
+ void ExtractMessage(UCCHAR_P pData, UINT_32 iLength, INT_32 iMasteridx, INT_32 iTransidx);
+
+ // Expressions for generating plural form rule ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Term = number | "n" | "(" TernaryExpr ")" | TernaryExpr
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsTerm(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief ModExpr = Term { "%" Term }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsModExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief LtOrGtExpr = ModExpr { LtOrGtRelation ModExpr }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsLtOrGtExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief EqExpr = LtOrGtExpr { EqRelation LtOrGtExpr }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsEqExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief AndExpr = EqExpr { "&&" AndExpr }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsAndExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief OrExpr = AndExpr { "||" OrExpr }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsOrExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief TernaryExpr = OrExpr { "?" TernaryExpr ":" TernaryExpr }
+ @param sData - current stream
+ @param iPos - current stream position
+ @return STLW::string::npos if sequence not found or position to end of sequence
+ */
+ STLW::string::size_type IsTernaryExpr(const STLW::string & sData, STLW::string::size_type iPos);
+
+ // Other stuff ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Calculate plural form of message
+ @param iCount - determine plural form
+ @param sLang - language of translation
+ @param sDomain - i18n domain
+ @return Number of plural form
+ */
+ UINT_32 CalculatePluralForm(UINT_32 iCount, const STLW::string & sLang, const STLW::string & sDomain);
+
+ /**
+ @brief Generate plural form rule
+ @param sPluralRule - string of plural form rule from .mo file
+ */
+ void GeneratePluralRule(const STLW::string & sPluralRule);
+
+ /**
+ @brief Stringify instruction for determining plural form
+ @param eType - instruction for determining plural form
+ @return string representation of instruction
+ */
+ CCHAR_P StringifyInstruction(eCTPP2Instruction eType);
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_GETTEXT_HPP__
+// End.
diff --git a/include/CTPP2GlobalDefines.h b/include/CTPP2GlobalDefines.h
new file mode 100644
index 0000000..da826e1
--- /dev/null
+++ b/include/CTPP2GlobalDefines.h
@@ -0,0 +1,171 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2GlobalDefines.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP_GLOBAL_DEFINES_H__
+#define _CTPP_GLOBAL_DEFINES_H__ 1
+
+#include "CTPP2SysHeaders.h"
+
+/**
+ @namespace CTPP
+ @brief CTPP - C++ Template Engine. Main namespace of CTPP2 project.
+*/
+
+/**
+ @file CTPP2GlobalDefines.h
+ @brief Global definitions for CTPP2
+*/
+
+/*
+ * Define this if you want to use STL STLW::exception class as base class of all CTPP2 exceptions
+ */
+#define _USE_STL_AS_BASE_EXCEPTION 1
+
+/*
+ * Define this if you want to build project with extended debug information
+ */
+/* #define _DEBUG 1 */
+#ifdef DEBUG_MODE
+ #define _DEBUG 1
+#endif // DEBUG_MODE
+
+/*
+ * Define this if your compiler does not support namesapce std for STL
+ */
+#ifdef NO_STL_STD_PREFIX
+ #define _NO_STL_STD_NS_PREFIX 1
+#endif
+
+/*
+ * Define this if you want to use C++ operator new / operator delete instead of malloc / free functions
+ */
+#define _OPERATOR_NEW_INSTEAD_OF_MALLOC 1
+
+/*
+ * Defines for Microsoft (R) Windows
+ */
+#ifdef _MSC_VER
+ #pragma warning (disable : 4996) // deprecated: strdup, snprintf
+ #pragma warning (disable : 4251) // class 'Class::Name' needs to have dll-interface to be used by clients of class 'Another::Name'
+ #define strcasecmp(x,y) _stricmp((x),(y))
+ #define snprintf(x,y,z,...) _snprintf((x),(y),(z), __VA_ARGS__ )
+#endif
+
+#ifdef CTPP2_DLL
+ #ifdef ctpp2_EXPORTS
+ #define CTPP2DECL __declspec(dllexport)
+ #else
+ #define CTPP2DECL __declspec(dllimport)
+ #endif
+#else
+ #define CTPP2DECL
+#endif
+
+/*
+ * Header files
+ */
+#ifndef WIN32
+
+ #ifndef HAVE_SYS_TIME_H
+ #error "Cannot find header file `sys/time.h'"
+ #endif
+
+ #ifndef HAVE_SYS_UIO_H
+ #error "Cannot find header file `sys/uio.h'"
+ #endif
+
+ #ifndef HAVE_SYS_TYPES_H
+ #error "Cannot find header file `sys/types.h'"
+ #endif
+
+ #ifndef HAVE_UNISTD_H
+ #error "Cannot find header file `unistd.h'"
+ #endif
+
+#endif
+
+#ifndef HAVE_FCNTL_H
+ #error "Cannot find header file `fcntl.h'"
+#endif
+
+#ifndef HAVE_MATH_H
+ #error "Cannot find header file `math.h'"
+#endif
+
+#ifndef HAVE_STDIO_H
+ #error "Cannot find header file `stdio.h'"
+#endif
+
+#ifndef HAVE_STDLIB_H
+ #error "Cannot find header file `stdlib.h'"
+#endif
+
+#ifndef HAVE_STRING_H
+ #error "Cannot find header file `string.h'"
+#endif
+
+#ifndef HAVE_TIME_H
+ #error "Cannot find header file `time.h'"
+#endif
+
+#ifdef HAVE_SYSEXITS_H
+ #include <sysexits.h>
+#else
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ */
+ #define EX_OK 0 /* successful termination */
+
+ #define EX__BASE 64 /* base value for error messages */
+
+ #define EX_USAGE 64 /* command line usage error */
+ #define EX_DATAERR 65 /* data format error */
+ #define EX_NOINPUT 66 /* cannot open input */
+ #define EX_NOUSER 67 /* addressee unknown */
+ #define EX_NOHOST 68 /* host name unknown */
+ #define EX_UNAVAILABLE 69 /* service unavailable */
+ #define EX_SOFTWARE 70 /* internal software error */
+ #define EX_OSERR 71 /* system error (e.g., can't fork) */
+ #define EX_OSFILE 72 /* critical OS file missing */
+ #define EX_CANTCREAT 73 /* can't create (user) output file */
+ #define EX_IOERR 74 /* input/output error */
+ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
+ #define EX_PROTOCOL 76 /* remote error in protocol */
+ #define EX_NOPERM 77 /* permission denied */
+ #define EX_CONFIG 78 /* configuration error */
+
+ #define EX__MAX 78 /* maximum listed value */
+
+#endif
+
+#endif /* _GLOBAL_DEFINES_H__ */
+/* End. */
diff --git a/include/CTPP2HashTable.hpp b/include/CTPP2HashTable.hpp
new file mode 100644
index 0000000..95d8598
--- /dev/null
+++ b/include/CTPP2HashTable.hpp
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2HashTable.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_HASH_TABLE_HPP__
+#define _CTPP2_HASH_TABLE_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2HashTable.hpp
+ @brief Zero collision hash
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct HashElement CTPP2HashTable.hpp <CTPP2HashTable.hpp>
+ @brief Static data variable
+*/
+struct HashElement
+{
+ /** Hash value */
+ UINT_64 hash;
+ /** Data length */
+ UINT_64 value;
+};
+
+/**
+ @class ReducedHashTable CTPP2HashTable.hpp <CTPP2HashTable.hpp>
+ @brief Hash without collisions with reduced functionality
+*/
+class CTPP2DECL ReducedHashTable
+{
+public:
+ /**
+ @brief Constructor
+ @param aIElements - hash elements
+ @param iIPower - number of elements
+ */
+ ReducedHashTable(const HashElement * aIElements,
+ const UINT_32 iIPower);
+
+ /**
+ @brief Get value from hash
+ @param szKey - key name
+ @param iKeyLength - key length
+ @return >0 - if success, -1 - if any error occured
+ */
+ UINT_64 Get(CCHAR_P szKey,
+ const UINT_32 iKeyLength) const;
+
+ /**
+ @brief Get hash size
+ */
+ UINT_64 Size() const;
+
+ /**
+ @brief A destructor
+ */
+ ~ReducedHashTable() throw();
+
+private:
+ friend class VMDumper;
+
+ // Does not exist
+ ReducedHashTable(const ReducedHashTable & oRhs);
+
+ // Does not exist
+ ReducedHashTable & operator=(const ReducedHashTable & oRhs);
+
+ /** Hash elements */
+ const HashElement * aElements;
+ /** Power of 2 */
+ UINT_32 iPower;
+ /** Base of hash */
+ UINT_64 iBase;
+};
+
+/**
+ @class HashTable CTPP2HashTable.hpp <CTPP2HashTable.hpp>
+ @brief Hash without collisions
+*/
+class CTPP2DECL HashTable
+{
+public:
+ /**
+ @brief Constructor
+ */
+ HashTable();
+
+ /**
+ @brief Get value from hash
+ @param szKey - key name
+ @param iKeyLength - key length
+ @return >0 - if success, -1 - if any error occured
+ */
+ INT_64 Get(CCHAR_P szKey,
+ const UINT_32 iKeyLength) const;
+
+ /**
+ @brief Get hash size
+ */
+ UINT_64 Size() const;
+
+ /**
+ @brief Put value into hash
+ @param szKey - key name
+ @param iKeyLength - key length
+ @param iValue - value to store
+ @return 0 - if success, -1 - if any error occured
+ */
+ UINT_32 Put(CCHAR_P szKey,
+ const UINT_32 iKeyLength,
+ const UINT_64 iValue);
+
+ /**
+ @brief A destructor
+ */
+ ~HashTable() throw();
+private:
+ friend class VMDumper;
+
+ // Does not exist
+ HashTable(const HashTable & oRhs);
+
+ // Does not exist
+ HashTable & operator=(const HashTable & oRhs);
+
+ /** Hash elements */
+ HashElement * aElements;
+ /** Power of 2 */
+ UINT_32 iPower;
+ /** Base of hash */
+ UINT_64 iBase;
+ /** Number of used elements */
+ UINT_64 iUsed;
+
+ /**
+ @brief Resize hash
+ */
+ void Resize();
+};
+
+} // namespace CTPP
+#endif // _CTPP2_HASH_TABLE_HPP__
+// End.
diff --git a/include/CTPP2JSONFileParser.hpp b/include/CTPP2JSONFileParser.hpp
new file mode 100644
index 0000000..408b3c6
--- /dev/null
+++ b/include/CTPP2JSONFileParser.hpp
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2JSONFileParser.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_JSON_FILE_PARSER_H__
+#define _CTPP2_JSON_FILE_PARSER_H__ 1
+
+#include "CTPP2JSONParser.hpp"
+
+#include <stdio.h>
+
+/**
+ @file CTPP2JSONFileParser.hpp
+ @brief JSON Parser, file i/o interface
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPP2JSONFileParser CTPP2JSONFileParser.hpp <CTPP2JSONFileParser.hpp>
+ @brief JSON parser, file i/o interface
+*/
+class CTPP2DECL CTPP2JSONFileParser:
+ private CTPP2JSONParser
+{
+public:
+ /**
+ @brief Constructor
+ */
+ CTPP2JSONFileParser(CDT & oICDT);
+
+ /**
+ @brief Parse JSON data from file
+ @param szFile - file name
+ @return 0 if success, -1 if any error occured
+ */
+ INT_32 Parse(CCHAR_P szFile);
+
+ /**
+ @brief Parse JSON data from file
+ @param F - opened file descriptor, ready to read data
+ @param iReadBytes - bytes to read
+ @return 0 if success, -1 if any error occured
+ */
+ INT_32 Parse(FILE * F, const UINT_32 & iReadBytes);
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2JSONFileParser() throw();
+private:
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_JSON_FILE_PARSER_H__
+// End.
diff --git a/include/CTPP2JSONParser.hpp b/include/CTPP2JSONParser.hpp
new file mode 100644
index 0000000..ffebd08
--- /dev/null
+++ b/include/CTPP2JSONParser.hpp
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2JSONParser.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_JSON_PARSER_H__
+#define _CTPP2_JSON_PARSER_H__ 1
+
+#include "CDT.hpp"
+#include "CTPP2CharIterator.hpp"
+
+#include "STLString.hpp"
+
+/**
+ @file CTPP2JSONParser.hpp
+ @brief JSON Parser
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPP2JSONParser CTPP2JSONParser.hpp <CTPP2JSONParser.hpp>
+ @brief JSON source code parser
+*/
+class CTPP2DECL CTPP2JSONParser
+{
+public:
+ /**
+ @brief Constructor
+ */
+ CTPP2JSONParser(CDT & oICDT);
+
+ /**
+ @brief Parse JSON data
+ @param szData - start of template
+ @param szEnd - end of template
+ @return 0 if success, -1 if any error occured
+ */
+ INT_32 Parse(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2JSONParser() throw();
+private:
+ /** Data collector */
+ CDT & oCDT;
+ /** Temp. buffer */
+ STLW::string sTMPBuf;
+ /** Parsed integer value */
+ INT_64 iIntData;
+ /** Parsed floating value */
+ W_FLOAT dFloatData;
+ /** Type of parsed value */
+ INT_32 iParsedNumberType;
+
+ /**
+ @brief JSON string "blah-blah \" clah-clah " | 'blah-blah \' clah-clah '
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsString(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief JSON old fashion string blah-blah.clah-clah
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequenc
+ */
+ CCharIterator IsStringCompatOldVersion(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief JSON variable a-zA-Z_[a-zA-Z0-9_]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsVar(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief JSON number [-]0-9[. [0-9] ] [E][+- 0-9]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsNum(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief JSON white space (Tab | ' ')
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param iSkipFirst - if set to 0, does not check existence of first space
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsWhiteSpace(CCharIterator szData, CCharIterator szEnd, const UINT_32 & iSkipFirst = 1);
+
+ /**
+ @brief JSON Object
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param oCurrentCDT - CDT object
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsObject(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT);
+
+ /**
+ @brief JSON Object
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param oCurrentCDT - CDT object
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsArray(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT);
+
+ /**
+ @brief JSON Key
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param sKey - JSON hash key
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsKey(CCharIterator szData, CCharIterator szEnd, STLW::string & sKey);
+
+ /**
+ @brief JSON Value
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param oCurrentCDT - CDT object
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsValue(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_JSON_PARSER_H__
+// End.
diff --git a/include/CTPP2Logger.hpp b/include/CTPP2Logger.hpp
new file mode 100644
index 0000000..cc7450b
--- /dev/null
+++ b/include/CTPP2Logger.hpp
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Logger.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_LOGGER_HPP__
+#define _CTPP2_LOGGER_HPP__ 1
+
+#include "CTPP2Types.h"
+
+#include <stdarg.h>
+
+/**
+ @file CTPP2Logger.hpp
+ @brief CTPP2 Logger
+*/
+
+#define CTPP2_LOG_EMERG 0 /* system is unusable */
+#define CTPP2_LOG_ALERT 1 /* action must be taken immediately */
+#define CTPP2_LOG_CRIT 2 /* critical conditions */
+#define CTPP2_LOG_ERR 3 /* error conditions */
+#define CTPP2_LOG_WARNING 4 /* warning conditions */
+#define CTPP2_LOG_NOTICE 5 /* normal but significant condition */
+#define CTPP2_LOG_INFO 6 /* informational */
+#define CTPP2_LOG_DEBUG 7 /* debug-level messages */
+#define CTPP2_LOG_PRIMASK 0x07 /* mask to extract priority part
+ (internal) */
+
+#define CTPP2_LOG_WARN CTPP2_LOG_WARNING /* alias for CTPP2_LOG_WARNING */
+#define CTPP2_LOG_ERROR CTPP2_LOG_ERR /* alias for CTPP2_LOG_ERR */
+
+#define C_START_MESSAGE_LEN 2048
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class Logger CTPP2Logger.hpp <CTPP2Logger.hpp>
+ @brief CTPP2 logger subsystem
+*/
+class CTPP2DECL Logger
+{
+protected:
+ /** Base priority */
+ UINT_32 iBasePriority;
+
+public:
+ /**
+ @brief Constructor
+ @param iIBasePriority - base priority
+ */
+ Logger(const UINT_32 iIBasePriority = CTPP2_LOG_WARNING);
+
+ /**
+ @brief Change base priority
+ @param iNewPriority - new base priority
+ */
+ void SetPriority(const UINT_32 iNewPriority);
+
+ /**
+ @brief Write message to log file
+ @param iPriority - priority level
+ @param szString - message to store in file
+ @return 0 - if success, -1 - otherwise
+ */
+ virtual INT_32 WriteLog(const UINT_32 iPriority,
+ CCHAR_P szString,
+ const UINT_32 iStringLen) = 0;
+
+ /**
+ @brief log message with formatted parameters
+ @param iPriority - priority level
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ virtual INT_32 LogMessage(const UINT_32 iPriority,
+ CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters
+ @param iPriority - priority level
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ virtual INT_32 LogMessage(const UINT_32 iPriority,
+ CCHAR_P szFormat,
+ va_list aArgList);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_EMERG priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Emerg(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_ALERT priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Alert(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_CRIT priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Crit(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_ERR priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Err(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_ERR priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Error(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_WARNING priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Warn(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_WARNING priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Warning(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_NOTICE priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Notice(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_INFO priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Info(CCHAR_P szFormat, ...);
+
+ /**
+ @brief log message with formatted parameters and AS_LOG_DEBUG priority
+ @param szFormat - output format
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Debug(CCHAR_P szFormat, ...);
+
+ /**
+ @brief A destructor
+ */
+ virtual ~Logger() throw();
+};
+
+} // namespace CTPP
+#endif // _CTPP2_LOGGER_HPP__
+// End.
diff --git a/include/CTPP2OutputCollector.hpp b/include/CTPP2OutputCollector.hpp
new file mode 100644
index 0000000..9f75f37
--- /dev/null
+++ b/include/CTPP2OutputCollector.hpp
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2OutputCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_OUTPUT_COLLECTOR_HPP__
+#define _CTPP2_OUTPUT_COLLECTOR_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2OutputCollector.hpp
+ @brief Virtual machine output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class OutputCollector CTPP2OutputCollector.hpp <CTPP2OutputCollector.hpp>
+ @brief Output data collector
+*/
+class CTPP2DECL OutputCollector
+{
+public:
+ /**
+ @brief Collect data
+ @param vData - data to store
+ @param iDataLength - data length
+ @return 0 - if success, -1 - if any error occured
+ */
+ virtual INT_32 Collect(const void * vData, const UINT_32 iDataLength) = 0;
+
+ /**
+ @brief A destructor
+ */
+ virtual ~OutputCollector() throw() { ;; }
+};
+
+} // namespace CTPP
+#endif // _CTPP2_OUTPUT_COLLECTOR_HPP__
+// End.
diff --git a/include/CTPP2Parser.hpp b/include/CTPP2Parser.hpp
new file mode 100644
index 0000000..fa5de82
--- /dev/null
+++ b/include/CTPP2Parser.hpp
@@ -0,0 +1,623 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Parser.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_PARSER_HPP__
+#define _CTPP2_PARSER_HPP__ 1
+
+#include "CTPP2CharIterator.hpp"
+#include "CTPP2Compiler.hpp"
+#include "CDT.hpp"
+
+/**
+ @file CTPP2Parser.hpp
+ @brief CTPP2 syntax parser
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class StaticData;
+class StaticText;
+class CTPP2SourceLoader;
+
+/**
+ @class CTPP2Parser CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief CTPP2 source code parser
+*/
+class CTPP2DECL CTPP2Parser
+{
+public:
+ /** Type for include map */
+ typedef STLW::map<STLW::string, STLW::string> IncludeMapType;
+
+ /**
+ @brief Constructor
+ @param pISourceLoader - source loader
+ @param pICTPP2Compiler - compiler object
+ @param sISourceName - template source name
+ @param bIInForeach - foreach flag
+ @param iIRecursionLevel - recursion level
+ */
+ CTPP2Parser(CTPP2SourceLoader * pISourceLoader,
+ CTPP2Compiler * pICTPP2Compiler,
+ const::STLW::string & sISourceName,
+ const bool & bIInForeach = false,
+ const INT_32 iIRecursionLevel = 0);
+
+ /**
+ @brief Compile CTPP2 template
+ @param iHalt - if set to 1, add to end of code HLT instruction
+ @return 0 if success, -1 if any error occured
+ */
+ INT_32 Compile(const UINT_32 & iHalt = 1);
+
+ /**
+ @brief A destructor
+ */
+ ~CTPP2Parser() throw();
+private:
+ typedef STLW::map<STLW::string, UINT_32> BlockArgMapType;
+
+ typedef STLW::map<STLW::string, UINT_32> BlockArgSizeMapType;
+
+ enum eCTPP2Operator { UNDEF = 0,
+ TMPL_var = 1,
+ TMPL_if = 2,
+ TMPL_unless = 3,
+ TMPL_else = 4,
+ TMPL_elsif = 5,
+ // TMPL_loop = 6, // Obsolete
+ TMPL_foreach = 7,
+ TMPL_include = 8,
+ TMPL_call = 9,
+ TMPL_udf = 10,
+ TMPL_comment = 11,
+ TMPL_break = 12,
+ TMPL_block = 13,
+ TMPL_verbose = 14 };
+
+ enum eCTPP2ExprOperator { EXPR_UNDEF = 0,
+ EXPR_INT_VALUE = 1,
+ EXPR_FLOAT_VALUE = 2,
+ EXPR_STRING_VALUE = 3,
+ EXPR_VARIABLE = 4,
+ EXPR_FUNCTION = 5,
+ EXPR_BRANCH = 6 };
+
+ enum eCTPP2Relation { R_UNDEF = 0,
+ R_EQ = 1,
+ R_NE = 2,
+ R_GT = 3,
+ R_LT = 4,
+ R_GE = 5,
+ R_LE = 6,
+ R_N_EQ = 7,
+ R_N_NE = 8,
+ R_N_GT = 9,
+ R_N_LT = 10,
+ R_N_GE = 11,
+ R_N_LE = 12 };
+
+ enum eCTPP2ArOp { OP_UNDEF = 0,
+ OP_PLUS = 1,
+ OP_MINUS = 2,
+ OP_DIV = 3,
+ OP_MUL = 4,
+ OP_IDIV = 5,
+ OP_MOD = 6,
+ OP_UNPLUS = 7,
+ OP_UNMINUS = 8,
+ OP_NOT = 9,
+ OP_LAND = 10,
+ OP_LOR = 11 };
+
+ /**
+ @struct CTPP2Keyword CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief CTPP2 reserverd words
+ */
+ struct CTPP2Keyword
+ {
+ /** keyword */
+ CCHAR_P keyword;
+ /** keyword length */
+ UINT_32 keyword_length;
+ /** keyword corresponding operator */
+ eCTPP2Operator keyword_operator;
+ };
+ /** Keywords table */
+ static CTPP2Keyword aKeywords[];
+
+ /**
+ @struct CTPP2Relation CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief CTPP2 Relation
+ */
+ struct CTPP2Relation
+ {
+ /** keyword */
+ CCHAR_P keyword;
+ /** keyword length */
+ UINT_32 keyword_length;
+ /** keyword corresponding operator */
+ eCTPP2Relation keyword_operator;
+ };
+
+ /** Relations */
+ static CTPP2Relation aCTPP2Relations [];
+
+ /** Current operator */
+ eCTPP2Operator eBreakFound;
+
+ /** Temp. buffer */
+ STLW::string sTMPBuf;
+ /** Parsed integer value */
+ INT_64 iIntData;
+ /** Parsed floating value */
+ W_FLOAT dFloatData;
+ /** Type of parsed value */
+ INT_32 iParsedNumberType;
+
+ /** Source loader object */
+ CTPP2SourceLoader * pSourceLoader;
+ /** Compiler */
+ CTPP2Compiler * pCTPP2Compiler;
+ /** Syscalls */
+ StaticText & oSyscalls;
+ /** Static data segment */
+ StaticData & oStaticData;
+ /** Static text segment */
+ StaticText & oStaticText;
+
+ /** Template source name */
+ STLW::string sSourceName;
+ /** Template source name ID */
+ UINT_32 iSourceNameId;
+ /** Foreach flag */
+ bool bInForeach;
+ /** Recursion level */
+ INT_32 iRecursionLevel;
+ /** Complex variable flag */
+ bool bInsideComplexVariable;
+ /** enable/disable verbose mode */
+ bool bVerboseMode;
+ /** Block flag */
+ bool bInBlock;
+ /** Current block arguments */
+ BlockArgMapType mCurrentBlock;
+ /** Map of number of arguments of blocks */
+ BlockArgSizeMapType mBlockArgSizes;
+
+ /** JMP points for TMPL_break */
+ STLW::vector<STLW::vector<INT_32> > vBreakJMPPoints;
+
+ // Simple tokens: open and close tags, operators, variables, strings and numbers //////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Open tag ([Tt][Mm][Pp][Ll])
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsOpenTag(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Close tag (/[Tt][Mm][Pp][Ll])
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsCloseTag(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Operator (var | if | else | unless | foreach | udf | comment | call | break)
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param oOperatorType - operator type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsOperator(CCharIterator szData, CCharIterator szEnd, eCTPP2Operator & oOperatorType);
+
+ /**
+ @brief Function [a-zA-Z_][a-zA-Z0-9_]( Expr [, Expr2 ... ] )
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param sFuncEnd - end of function name
+ @param iFunctionParams - number of function parameters
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsFunc(CCharIterator szData, CCharIterator szEnd, CCharIterator & sFuncEnd, UINT_32 & iFunctionParams);
+
+ /**
+ @brief CTPP2 function a-zA-Z_[a-zA-Z0-9_]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsFuncName(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief CTPP2 iterator [a-zA-Z_][a-zA-Z0-9_]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsIterator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief CTPP2 variable a-zA-Z_[a-zA-Z0-9_|.|:]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsVar(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief CTPP2 string "blah-blah \" clah-clah " | 'blah-blah \' clah-clah '
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsString(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Number [-]0-9[. [0-9] ] [E [+-] 0-9]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsNum(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Parse Float value
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ */
+ void ParseFloat(CCharIterator & szData, CCharIterator & szEnd);
+
+ /**
+ @brief Foreach operator keyword (as)
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsForeachKeyword(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief White space (Tab | ' ')
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param iSkipFirst - if set to 0, does not check existence of first space
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsWhiteSpace(CCharIterator szData, CCharIterator szEnd, const UINT_32 & iSkipFirst = 1);
+
+ // Expressions ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Expression ( Function ( expression ) | string | variable | number )
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - Result operand of expression
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief LogicalOrExpr = LogicalAndExpr { "||" LogicalAndExpr }
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator LogicalOrExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief LogicalAndExpr = RelExpr { "&&" RelExpr }
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator LogicalAndExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief RelExpr = SimpleExpr [Relation SimpleExpr]
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator RelExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief SimpleExpr = [UNPLUS | UNMINUS] Term {AddOp Term}
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsSimpleExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Term = Factor {MulOp Factor}
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsTerm(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Factor = Function "(" [ Expr {"," Expr} ] ")" | number | character | string | "(" Expr ")" | NOT Factor
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - expression type
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsFactor(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Relation = N_EQ | N_NE | N_GT | N_LT | N_GE | N_LE | EQ | NE | GT | LT | GE | LE
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eRelation - relation id [out]
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsRelation(CCharIterator szData, CCharIterator szEnd, eCTPP2Relation & eRelation);
+
+ /**
+ @brief UnaryOp = UNPLUS | UNMINUS
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eArOp - type of arithmetic operation
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsUnaryOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp);
+
+ /**
+ @brief AddOp = ADD | SUB
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eArOp - type of arithmetic operation
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsAddOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp);
+
+ /**
+ @brief LogicalOp = && | ||
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eArOp - type of arithmetic operation
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsLogicalOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp);
+
+ /**
+ @brief MulOp = MUL | DIV | IDIV | MOD
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eArOp - type of arithmetic operation
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsMulOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp);
+
+ // Operator expressions ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief CTPP2 branch expression; &lt;TMPL_if IfExpr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - Result operand of expression
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsIfExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief CTPP2 reverse branch expression; &lt;TMPL_unless UnlessExpr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param eResultOperator - Result operand of expression
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsUnlessExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Foreach expression &lt;TMPL_loop ForeachExpr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param iRetPoint - return point instruction number [out]
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IsForeachExpr(CCharIterator szData, CCharIterator szEnd, UINT_32 & iRetPoint);
+
+ // Operators //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Variable/Function/Exression output operator&lt;TMPL_var Expr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator VarOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Branch operator &lt;TMPL_if IfExpr&gt; blah-blah-blah [ &lt;TMPL_else&gt; clah-clah-clah ] &lt;/TMPL_if&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IfOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Reverse branch operator &lt;TMPL_unless IfExpr&gt; blah-blah-blah [ &lt;TMPL_else&gt; clah-clah-clah ] &lt;/TMPL_unless&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator UnlessOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Foreach operator &lt;TMPL_foreach var_array as var&gt; blah-blah-blah &lt/TMPL_foreach&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator ForeachOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Include operator &lt;TMPL_include Expr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator IncludeOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Call operator &lt;TMPL_call Expr&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator CallOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Comment &lt;TMPL_comment&gt; ..... &lt/TMPL_comment&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator CommentOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Block of code &lt;TMPL_block "blockname"&gt; ..... &lt/TMPL_block&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator BlockOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Ignore spaces &lt;TMPL_verbose&gt; ..... &lt/TMPL_verbose&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator VerboseOperator(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Break operator; &lt;TMPL_break&gt;
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator BreakOperator(CCharIterator szData, CCharIterator szEnd);
+ // Other stuff ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ @brief Parse CTPP2 template
+ @param szData - template start
+ @param szEnd - template end
+ @return 0 if success, -1 if any error occured
+ */
+ CCharIterator Parse(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Store comparison result (if branch)
+ @param szData - current position in stream
+ @param eResultOperator - type of parsed expression
+ @return instruction pointer to JMP or JXX instrution
+ */
+ UINT_32 StoreIfComparisonResult(CCharIterator szData, const eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Store comparison result (unless branch)
+ @param szData - current position in stream
+ @param eResultOperator - type of parsed expression
+ @return instruction pointer to JMP or JXX instrution
+ */
+ UINT_32 StoreUnlessComparisonResult(CCharIterator szData, const eCTPP2ExprOperator & eResultOperator);
+
+ /**
+ @brief Get printable operator name
+ @param oOperator operator type
+ @return printable operator name
+ */
+ CCHAR_P GetOperatorName(const eCTPP2Operator & oOperator);
+
+ /**
+ @brief Check trailing newline flag
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return true, if flag found
+ */
+ bool CheckTrailingFlag(CCharIterator & szData, CCharIterator szEnd);
+
+ /**
+ @brief Remove trailing newline(s)
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ */
+ void RemoveTrailingNewLines(CCharIterator & szData, CCharIterator szEnd);
+
+ /**
+ @brief Parse block arguments
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator BlockArgs(CCharIterator szData, CCharIterator szEnd);
+
+ /**
+ @brief Parse call arguments
+ @param szData - current stream position
+ @param szEnd - end of stream position
+ @param iArgCount - number of arguments
+ @return NULL if sequence not found or pointer to end of sequence
+ */
+ CCharIterator CallArgs(CCharIterator szData, CCharIterator szEnd, UINT_32 & iArgCount);
+
+ /**
+ @brief Set information about blocks
+ @param mIBlockArgSizes - block argument sizes
+ */
+ void SetBlockArgSizeMap(const BlockArgSizeMapType & mIBlockArgSizes);
+
+ /**
+ @brief Get information about blocks
+ @return mIBlockArgSizes - block argument sizes
+ */
+ BlockArgSizeMapType GetBlockArgSizeMap() const;
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_PARSER_H__
+// End.
diff --git a/include/CTPP2ParserException.hpp b/include/CTPP2ParserException.hpp
new file mode 100644
index 0000000..5a70241
--- /dev/null
+++ b/include/CTPP2ParserException.hpp
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2ParserException.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_PARSER_EXCEPTION_H__
+#define _CTPP2_PARSER_EXCEPTION_H__ 1
+
+#include "CTPP2Exception.hpp"
+
+/**
+ @file CTPP2ParserException.hpp
+ @brief Collector of generated operation codes
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPPParserException CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief Base CTPP parser exception
+*/
+class CTPP2DECL CTPPParserException:
+ public CTPPException
+{
+public:
+ /**
+ @return A asciz string describing the general cause of error
+ */
+ virtual CCHAR_P what() const throw();
+
+ /**
+ @brief Get line where error ocured
+ */
+ virtual UINT_32 GetLine() const = 0;
+
+ /**
+ @brief Get column where error ocured
+ */
+ virtual UINT_32 GetLinePos() const = 0;
+
+ /**
+ @brief A virtual destructor
+ */
+ virtual ~CTPPParserException() throw();
+};
+
+/**
+ @class CTPPParserSyntaxError CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief Base CTPP syntax error
+*/
+class CTPP2DECL CTPPParserSyntaxError:
+ public CTPPParserException
+{
+public:
+ /**
+ @brief Constructor
+ @param szIReason - error description
+ @param iILine - line where error ocured
+ @param iIPos - column where error ocured
+ */
+ CTPPParserSyntaxError(CCHAR_P szIReason,
+ const UINT_32 iILine,
+ const UINT_32 iIPos);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get line where error ocured
+ */
+ UINT_32 GetLine() const;
+
+ /**
+ @brief Get column where error ocured
+ */
+ UINT_32 GetLinePos() const;
+
+ /** @brief A virtual destructor */
+ ~CTPPParserSyntaxError() throw();
+private:
+ /** Error description */
+ CHAR_P szReason;
+ /** Line */
+ const UINT_32 iLine;
+ /** Position in line */
+ const UINT_32 iPos;
+};
+
+/**
+ @class CTPPParserOperatorsMismatch CTPP2Parser.hpp <CTPP2Parser.hpp>
+ @brief CTPP operators mismatch; expected one, found other
+*/
+class CTPP2DECL CTPPParserOperatorsMismatch:
+ public CTPPParserException
+{
+public:
+ /**
+ @brief Constructor
+ @param szIExpected - expected opeartor
+ @param szIFound - opeartor that really found in stream
+ @param iILine - line where error ocured
+ @param iIPos - column where error ocured
+ */
+ CTPPParserOperatorsMismatch(CCHAR_P szIExpected,
+ CCHAR_P szIFound,
+ const UINT_32 iILine,
+ const UINT_32 iIPos);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /** @return Asciz name of expected operator */
+ CCHAR_P Expected() const;
+
+ /** @return Asciz name of found operator */
+ CCHAR_P Found() const;
+
+ /**
+ @brief Get line where error ocured
+ */
+ UINT_32 GetLine() const;
+
+ /**
+ @brief Get column where error ocured
+ */
+ UINT_32 GetLinePos() const;
+
+ /** @brief A virtual destructor */
+ ~CTPPParserOperatorsMismatch() throw();
+
+private:
+ /** Expected operator */
+ CHAR_P szExpected;
+ /** Found operator */
+ CHAR_P szFound;
+
+ /** Line */
+ const UINT_32 iLine;
+ /** Position in line */
+ const UINT_32 iPos;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_PARSER_EXCEPTION_H__
+// End.
diff --git a/include/CTPP2SimpleCompiler.hpp b/include/CTPP2SimpleCompiler.hpp
new file mode 100644
index 0000000..094f8df
--- /dev/null
+++ b/include/CTPP2SimpleCompiler.hpp
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * SimpleCompiler.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _SIMPLE_COMPILER_HPP__
+#define _SIMPLE_COMPILER_HPP__ 1
+
+/**
+ @file SimpleVM.hpp
+ @brief Virtual Machine, simple use case
+*/
+
+#include "CTPP2Types.h"
+#include <string>
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class CDT;
+class OutputCollector;
+class VMLoader;
+struct VMMemoryCore;
+
+/**
+ @class SimpleCompiler SimpleCompiler.hpp <SimpleCompiler.hpp>
+ @brief Simple CTPP2 template compiler
+*/
+class CTPP2DECL SimpleCompiler
+{
+public:
+ /**
+ @brief Constructor
+ @param sSourceFile - source file
+ */
+ SimpleCompiler(const std::string & sSourceFile);
+
+ /**
+ @brief Save compiled data to file
+ @param sCompiledFile - compiled file
+ @return 0 - if success, -1 - if any error occured
+ */
+ UINT_32 Save(const std::string & sCompiledFile) const;
+
+ /**
+ @brief Get memory core
+ @return ready to run memory core
+ */
+ const VMMemoryCore * GetCore() const;
+
+ /**
+ @brief A destructor
+ */
+ ~SimpleCompiler() throw();
+
+private:
+ // FWD
+ struct _SimpleCompiler;
+
+ /** Pompl for Simple VM internal data */
+ _SimpleCompiler * pSimpleCompiler;
+
+ // Prevent object copying
+ SimpleCompiler(const SimpleCompiler & oRhs);
+ SimpleCompiler & operator=(const SimpleCompiler & oRhs);
+};
+
+} // namespace CTPP
+#endif // _SIMPLE_COMPILER_HPP__
+// End.
diff --git a/include/CTPP2SimpleVM.hpp b/include/CTPP2SimpleVM.hpp
new file mode 100644
index 0000000..bc7061e
--- /dev/null
+++ b/include/CTPP2SimpleVM.hpp
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * SimpleVM.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _SIMPLE_VM_HPP__
+#define _SIMPLE_VM_HPP__ 1
+
+/**
+ @file SimpleVM.hpp
+ @brief Virtual Machine, simple use case
+*/
+
+#include "CTPP2Types.h"
+#include <string>
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class CDT;
+class OutputCollector;
+class Logger;
+class VMLoader;
+struct VMMemoryCore;
+
+/**
+ @class SimpleVM SimpleVM.hpp <SimpleVM.hpp>
+ @brief Simple CTPP2 Virtual machine
+*/
+class CTPP2DECL SimpleVM
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxFunctions - max. number of functions in syscall factory
+ @param iIMaxArgStackSize - max. size of arguments stack
+ @param iIMaxCodeStackSize - max. size of code stack
+ @param iIMaxSteps - max. number of executed steps
+ @param iIDebugLevel - debugging level
+ */
+ SimpleVM(const UINT_32 & iIMaxFunctions = 1024,
+ const UINT_32 & iIMaxArgStackSize = 4096,
+ const UINT_32 & iIMaxCodeStackSize = 4096,
+ const UINT_32 & iIMaxSteps = 10240,
+ const UINT_32 & iIDebugLevel = 0);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param oLoader - template loader
+ @param sResult - result collector, STL string
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMLoader & oLoader, std::string & sResult, Logger & oLogger);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param oLoader - template loader
+ @param F - result collector, file handle
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMLoader & oLoader, FILE * F, Logger & oLogger);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param oLoader - template loader
+ @param oCollector - result collector, CTPP::OutputCollector
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMLoader & oLoader, OutputCollector & oCollector, Logger & oLogger);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param pCore - memory core
+ @param sResult - result collector, STL string
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMMemoryCore * pCore, std::string & sResult, Logger & oLogger);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param pCore - memory core
+ @param F - result collector, file handle
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMMemoryCore * pCore, FILE * F, Logger & oLogger);
+
+ /**
+ @brief Run program
+ @param oData - initial data
+ @param pCore - memory core
+ @param oCollector - result collector, CTPP::OutputCollector
+ @param oLogger - logger object
+ @return instruction pointer
+ */
+ UINT_32 Run(CDT & oData, const VMMemoryCore * pCore, OutputCollector & oCollector, Logger & oLogger);
+
+ /**
+ @brief A destructor
+ */
+ ~SimpleVM() throw();
+
+private:
+ // FWD
+ struct _SimpleVM;
+
+ /** Pompl for Simple VM internal data */
+ _SimpleVM * pSimpleVM;
+
+ // Prevent object copying
+ SimpleVM(const SimpleVM & oRhs);
+ SimpleVM & operator=(const SimpleVM & oRhs);
+};
+
+} // namespace CTPP
+#endif // _SIMPLE_VM_HPP__
+// End.
diff --git a/include/CTPP2SourceLoader.hpp b/include/CTPP2SourceLoader.hpp
new file mode 100644
index 0000000..7884294
--- /dev/null
+++ b/include/CTPP2SourceLoader.hpp
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SourceLoader.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SOURCE_LOADER_HPP__
+#define _CTPP2_SOURCE_LOADER_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2SourceLoader.hpp
+ @brief Abstract CTPP2 template file loader
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class CTPP2SourceLoader CTPP2SourceLoader.hpp> <CTPP2SourceLoader.hpp>
+ @brief Base class of all template loaders
+*/
+class CTPP2DECL CTPP2SourceLoader
+{
+public:
+ /**
+ @brief Load template with specified name
+ @param szTemplateName - template name
+ @return 0 if success, -1 if any error occured
+ */
+ virtual INT_32 LoadTemplate(CCHAR_P szTemplateName) = 0;
+
+ /**
+ @brief Get template
+ @param iTemplateSize - template size [out]
+ @return pointer to start of template buffer if success, NULL - if any error occured
+ */
+ virtual CCHAR_P GetTemplate(UINT_32 & iTemplateSize) = 0;
+
+ /**
+ @brief Clone loader object
+ @return clone to self
+ */
+ virtual CTPP2SourceLoader * Clone() = 0;
+
+ /**
+ @brief A destructor
+ */
+ virtual ~CTPP2SourceLoader() throw() { ;; }
+};
+
+} // namespace CTPP
+#endif // _CTPP2_SOURCE_LOADER_HPP__
+// End.
diff --git a/include/CTPP2Sprintf.hpp b/include/CTPP2Sprintf.hpp
new file mode 100644
index 0000000..60f6caa
--- /dev/null
+++ b/include/CTPP2Sprintf.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Sprintf.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SPRINTF_HPP__
+#define _CTPP2_SPRINTF_HPP__ 1
+
+/**
+ @file CTPP2Sprintf.hpp
+ @brief CTPP sprintf implementation
+*/
+
+#include "CDT.hpp"
+
+#define C_STRING_BUFFER_LEN 1024
+
+namespace CTPP // C++ Template Engine
+{
+
+CTPP2DECL INT_32 FormatString(const STLW::string & sFormatString, STLW::string & sResult, const CDT & oArgs);
+
+} // namespace CTPP
+#endif // _CTPP2_SPRINTF_HPP__
+// End.
diff --git a/include/CTPP2StaticData.hpp b/include/CTPP2StaticData.hpp
new file mode 100644
index 0000000..468735f
--- /dev/null
+++ b/include/CTPP2StaticData.hpp
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StaticData.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STATIC_DATA_HPP__
+#define _CTPP2_STATIC_DATA_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2StaticData.hpp
+ @brief Staitic data segment
+*/
+
+namespace CTPP // C++ Template Engine
+{
+class BitIndex;
+
+/**
+ @struct StaticDataVar CTPP2StaticData.hpp <CTPP2StaticData.hpp>
+ @brief Ststic data variable
+*/
+union StaticDataVar
+{
+ /** Data (integer) */
+ INT_64 i_data;
+ /** Data (IEEE 754) */
+ W_FLOAT d_data;
+};
+
+/**
+ @class ReducedStaticData CTPP2StaticData.hpp <CTPP2StaticData.hpp>
+ @brief Static text segment with reduced functionality
+*/
+class CTPP2DECL ReducedStaticData
+{
+public:
+
+ /**
+ @brief Constructor
+ @param aIData - text data
+ @param iIUsedDataSize - max. data size
+ */
+ ReducedStaticData(const StaticDataVar * aIData,
+ const UINT_32 iIUsedDataSize);
+
+ /**
+ @brief Get integer value by ID
+ @param iDataId - data ID
+ @return Signed 64-bit value
+ */
+ INT_64 GetInt(const UINT_32 iDataId) const;
+
+ /**
+ @brief Get floating point value by ID
+ @param iDataId - data ID
+ @return Wide float value
+ */
+ W_FLOAT GetFloat(const UINT_32 iDataId) const;
+
+ /**
+ @brief A destructor
+ */
+ ~ReducedStaticData() throw();
+
+protected:
+ friend class VMDumper;
+
+ /** Stored data */
+ const StaticDataVar * aData;
+ /** Used data buffer length */
+ UINT_32 iUsedDataSize;
+
+};
+
+
+/**
+ @class StaticData CTPP2StaticData.hpp <CTPP2StaticData.hpp>
+ @brief Static text segment
+*/
+class CTPP2DECL StaticData
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxDataSize - initial text segment size
+ */
+ StaticData(const UINT_32 iIMaxDataSize = 0);
+
+ /**
+ @brief Constructor
+ @param aIData - text data
+ @param iIMaxDataSize - max. data size
+ */
+ StaticData(const StaticDataVar * aIData,
+ const UINT_32 iIMaxDataSize);
+
+ /**
+ @brief Store data
+ @param iData - data to store, signed 64-bit value
+ @return data ID
+ */
+ UINT_32 StoreInt(const UINT_64 iData);
+
+ /**
+ @brief Store data
+ @param dData - data to store, float value
+ @return data ID
+ */
+ UINT_32 StoreFloat(const W_FLOAT dData);
+
+ /**
+ @brief Get integer value by ID
+ @param iDataId - data ID
+ @return Signed 64-bit value
+ */
+ INT_64 GetInt(const UINT_32 iDataId) const;
+
+ /**
+ @brief Get floating point value by ID
+ @param iDataId - data ID
+ @return Wide float value
+ */
+ W_FLOAT GetFloat(const UINT_32 iDataId) const;
+
+ /**
+ @brief Get bit index
+ @return Pointer to bit index object
+ */
+ const BitIndex * GetBitIndex() const;
+
+ /**
+ @brief A destructor
+ */
+ ~StaticData() throw();
+private:
+ friend class VMDumper;
+
+ /** Max. data buffer size */
+ UINT_32 iMaxDataSize;
+ /** Used data buffer length */
+ UINT_32 iUsedDataSize;
+ /** Stored data */
+ StaticDataVar * aData;
+ /** Bit index */
+ BitIndex * oBitIndex;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_STATIC_DATA_HPP__
+// End.
diff --git a/include/CTPP2StaticText.hpp b/include/CTPP2StaticText.hpp
new file mode 100644
index 0000000..91e03ed
--- /dev/null
+++ b/include/CTPP2StaticText.hpp
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StaticText.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STATIC_TEXT_HPP__
+#define _CTPP2_STATIC_TEXT_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2StaticText.hpp
+ @brief Staitic text segment
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct TextDataIndex CTPP2StaticText.hpp <CTPP2StaticText.hpp>
+ @brief Index for static data segment
+*/
+struct TextDataIndex
+{
+ /** Data offset */
+ UINT_32 offset;
+ /** Data length */
+ UINT_32 length;
+};
+
+/**
+ @class ReducedStaticText CTPP2StaticText.hpp <CTPP2StaticText.hpp>
+ @brief Static text segment with reduced functionality
+*/
+class CTPP2DECL ReducedStaticText
+{
+public:
+ /**
+ @brief Constructor
+ @param sIData - stored text
+ @param iIUsedDataOffsetsSize - number of cells in aIDataOffsets array
+ @param aIDataOffsets - data offsets index
+ */
+ ReducedStaticText(CCHAR_P sIData,
+ const UINT_32 iIUsedDataOffsetsSize,
+ const TextDataIndex * aIDataOffsets);
+
+ /**
+ @brief GetData by ID
+ @param iDataId - data ID
+ @param iDataSize - data length
+ @return pointer to data of NULL if any error occured
+ */
+ CCHAR_P GetData(const UINT_32 iDataId,
+ UINT_32 & iDataSize) const;
+
+ /**
+ @brief Get number of stored records
+ @return number of stored records
+ */
+ UINT_32 GetRecordsNum() const;
+
+ /**
+ @brief A destructor
+ */
+ ~ReducedStaticText() throw();
+
+protected:
+ friend class VMDumper;
+ /** Stored data */
+ CCHAR_P sData;
+ /** Number of used cells in TextDataIndex array */
+ const UINT_32 iUsedDataOffsetsSize;
+ /** Stored data offsets */
+ const TextDataIndex * aDataOffsets;
+};
+
+/**
+ @class StaticText CTPP2StaticText.hpp <CTPP2StaticText.hpp>
+ @brief Static text segment
+*/
+class CTPP2DECL StaticText
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxDataSize - initial text segment size
+ @param iIMaxDataOffsetsSize - initial index size
+ */
+ StaticText(const UINT_32 iIMaxDataSize = 0,
+ const UINT_32 iIMaxDataOffsetsSize = 0);
+
+ /**
+ @brief Constructor
+ @param sData - text data
+ @param aDataOffsets - array with data offsets
+ @param iMaxDataSize - max. data size
+ @param iMaxDataOffsetsSize - max size of data offsets array
+ */
+ StaticText(CCHAR_P sData,
+ const TextDataIndex * aDataOffsets,
+ const UINT_32 iMaxDataSize,
+ const UINT_32 iMaxDataOffsetsSize);
+
+ /**
+ @brief Store data
+ @param sStoreData - text data
+ @param iDataLength - data length
+ @return data ID
+ */
+ UINT_32 StoreData(CCHAR_P sStoreData,
+ const UINT_32 iDataLength);
+
+ /**
+ @brief GetData by ID
+ @param iDataId - data ID
+ @param iDataSize - data length
+ @return pointer to data of NULL if any error occured
+ */
+ CCHAR_P GetData(const UINT_32 iDataId,
+ UINT_32 & iDataSize) const;
+
+ /**
+ @brief Get number of stored records
+ @return number of stored records
+ */
+ UINT_32 GetRecordsNum() const;
+
+ /**
+ @brief A destructor
+ */
+ ~StaticText() throw();
+private:
+ friend class VMDumper;
+
+ /** Max. data buffer size */
+ UINT_32 iMaxDataSize;
+ /** Max. offsets array length */
+ UINT_32 iMaxDataOffsetsSize;
+ /** Used data buffer length */
+ UINT_32 iUsedDataSize;
+ /** Number of used cells
+ in TextDataIndex array */
+ UINT_32 iUsedDataOffsetsSize;
+ /** Stored data */
+ CHAR_P sData;
+ /** Stored data offsets */
+ TextDataIndex * aDataOffsets;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_STATIC_TEXT_HPP__
+// End.
diff --git a/include/CTPP2StreamOutputCollector.hpp b/include/CTPP2StreamOutputCollector.hpp
new file mode 100644
index 0000000..c15629b
--- /dev/null
+++ b/include/CTPP2StreamOutputCollector.hpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StreamOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STREAM_OUTPUT_COLLECTOR_HPP__
+#define _CTPP2_STREAM_OUTPUT_COLLECTOR_HPP__ 1
+
+#include "CTPP2OutputCollector.hpp"
+#include "STLIosfwd.hpp"
+
+/**
+ @file StreamOutputCollector.hpp
+ @brief Virtual machine C++ stream output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class StreamOutputCollector StreamOutputCollector.hpp <StreamOutputCollector.hpp>
+ @brief Output data collector (C++ data stream)
+*/
+class CTPP2DECL StreamOutputCollector:
+ public OutputCollector
+{
+public:
+ /**
+ @brief Constructor
+ @param oIOutputStream - output data stream
+ */
+ StreamOutputCollector(STLW::ostream & oIOutputStream);
+
+ /**
+ @brief A destructor
+ */
+ ~StreamOutputCollector() throw();
+private:
+
+ /** Data object */
+ STLW::ostream & oOutputStream;
+
+ /**
+ @brief Collect data
+ @param vData - data to store
+ @param iDataLength - data length
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 Collect(const void * vData,
+ const UINT_32 iDataLength);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_STREAM_OUTPUT_COLLECTOR_HPP__
+// End.
+
diff --git a/include/CTPP2StringBuffer.hpp b/include/CTPP2StringBuffer.hpp
new file mode 100644
index 0000000..a74f487
--- /dev/null
+++ b/include/CTPP2StringBuffer.hpp
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringBuffer.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STRING_BUFFER_H__
+#define _CTPP2_STRING_BUFFER_H__ 1
+
+/**
+ @file CTPP2StringBuffer.hpp
+ @brief CTPP lazy string implementation
+*/
+
+#include "CTPP2Types.h"
+
+#include "STLString.hpp"
+
+#define C_STRING_BUFFER_LEN 1024
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct StringBuffer CTPP2StringBuffer.hpp <CTPP2StringBuffer.hpp>
+ @brief CTPP lazy string implementation
+*/
+class StringBuffer
+{
+public:
+ /**
+ @brief Constructor
+ @param sIResult - Destination string
+ */
+ StringBuffer(STLW::string & sIResult);
+
+ /**
+ @brief Append string
+ @param sStart - pointer to start of string
+ @param sEnd - pointer to end of string
+ @return Destination string size
+ */
+ UINT_32 Append(CCHAR_P sStart, CCHAR_P sEnd);
+
+ /**
+ @brief Append string
+ @param sStart - pointer to start of string
+ @param iLen - number of characters
+ @return Destination string size
+ */
+ UINT_32 Append(CCHAR_P sStart, const UINT_32 iLen);
+
+ /**
+ @brief Append multiple characters
+ @param iLen - number of characters
+ @param cChar - character to add
+ @return Destination string size
+ */
+ UINT_32 Append(const UINT_32 iLen, const CHAR_8 cChar);
+
+ /**
+ @brief Flush buffer
+ @return Destination string size
+ */
+ UINT_32 Flush();
+
+ /**
+ @brief A destructor
+ */
+ ~StringBuffer() throw();
+private:
+ // Does not exist
+ StringBuffer(const StringBuffer & oRhs);
+ StringBuffer & operator=(const StringBuffer & oRhs);
+
+ /** Destination string */
+ STLW::string & sResult;
+ /** Temp buffer */
+ CHAR_8 szBuffer[C_STRING_BUFFER_LEN + 1];
+ /** Buffer position */
+ UINT_32 iBufferPos;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_STRING_BUFFER_H__
+// End.
diff --git a/include/CTPP2StringIconvOutputCollector.hpp b/include/CTPP2StringIconvOutputCollector.hpp
new file mode 100644
index 0000000..c8a4d6a
--- /dev/null
+++ b/include/CTPP2StringIconvOutputCollector.hpp
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringIconvOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STRING_ICONV_OUTPUT_COLLECTOR_HPP__
+#define _CTPP2_STRING_ICONV_OUTPUT_COLLECTOR_HPP__ 1
+
+#include "CTPP2OutputCollector.hpp"
+#include "STLString.hpp"
+
+#ifdef ICONV_SUPPORT
+ #include <iconv.h>
+#endif // ICONV_SUPPORT
+
+/**
+ @file CTPP2StringIconvOutputCollector.hpp
+ @brief Virtual machine output data collector with charset recoding
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+#ifdef ICONV_SUPPORT
+
+#define C_ICONV_DISCARD_ILSEQ 0x00000001
+#define C_ICONV_TRANSLITERATE 0x00000002
+
+/**
+ @class StringIconvOutputCollector StringIconvOutputCollector.hpp <StringIconvOutputCollector.hpp>
+ @brief Output data collector with charset recoding
+*/
+class StringIconvOutputCollector:
+ public OutputCollector
+{
+public:
+ /**
+ @brief Constructor
+ @param sIResult - Result output string
+ @param sISrcEnc - Source charset
+ @param sIDstEnc - Destination charset
+ @param iIFlags - conversion flags
+ */
+ StringIconvOutputCollector(STLW::string & sIResult,
+ const STLW::string & sISrcEnc,
+ const STLW::string & sIDstEnc,
+ const UINT_32 iIFlags = 0);
+
+ /**
+ @brief A destructor
+ */
+ ~StringIconvOutputCollector() throw();
+private:
+ /** Data object */
+ STLW::string & sResult;
+ /** Source charset */
+ const STLW::string sSrcEnc;
+ /** Destination charset */
+ const STLW::string sDstEnc;
+ /** Conversion flags */
+ UINT_32 iFlags;
+ /** Iconv converter */
+ iconv_t oIconv;
+
+ /**
+ @brief Collect data
+ @param vData - data to store
+ @param iDataLength - data length
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 Collect(const void * vData,
+ const UINT_32 iDataLength);
+};
+#endif // ICONV_SUPPORT
+
+} // namespace CTPP
+#endif // _CTPP2_STRING_ICONV_OUTPUT_COLLECTOR_HPP__
+// End.
diff --git a/include/CTPP2StringOutputCollector.hpp b/include/CTPP2StringOutputCollector.hpp
new file mode 100644
index 0000000..3a898d0
--- /dev/null
+++ b/include/CTPP2StringOutputCollector.hpp
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_STRING_OUTPUT_COLLECTOR_HPP__
+#define _CTPP2_STRING_OUTPUT_COLLECTOR_HPP__ 1
+
+#include "CTPP2OutputCollector.hpp"
+#include "STLString.hpp"
+
+/**
+ @file StringOutputCollector.hpp
+ @brief Virtual machine file output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class StringOutputCollector CTPP2StringOutputCollector.hpp <CTPP2StringOutputCollector.hpp>
+ @brief Output data collector
+*/
+class CTPP2DECL StringOutputCollector:
+ public OutputCollector
+{
+public:
+ /**
+ @brief Constructor
+ @param sIResult - Data object
+ */
+ StringOutputCollector(STLW::string & sIResult);
+
+ /**
+ @brief A destructor
+ */
+ ~StringOutputCollector() throw();
+private:
+
+ /** Data object */
+ STLW::string & sResult;
+
+ /**
+ @brief Collect data
+ @param vData - data to store
+ @param iDataLength - data length
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 Collect(const void * vData,
+ const UINT_32 iDataLength);
+};
+
+} // namespace CTPP
+#endif // _FILE_OUTPUT_COLLECTOR_HPP__
+// End.
diff --git a/include/CTPP2SymbolTable.hpp b/include/CTPP2SymbolTable.hpp
new file mode 100644
index 0000000..2da6af6
--- /dev/null
+++ b/include/CTPP2SymbolTable.hpp
@@ -0,0 +1,262 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SymbolTable.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SYMBOL_TABLE_HPP__
+#define _CTPP2_SYMBOL_TABLE_HPP__ 1
+
+#include "CTPP2Types.h"
+
+#include "STLMap.hpp"
+#include "STLString.hpp"
+#include "STLVector.hpp"
+
+/**
+ @file CTPP2SymbolTable.hpp
+ @brief CTPP2 generic symbol table
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class SymbolTable CTPP2SymbolTable.hpp <CTPP2SymbolTable.hpp>
+ @brief CTPP2 Symbol table with logical scopes
+*/
+template<typename T>class SymbolTable
+{
+public:
+ /**
+ @struct SymbolRecord CTPP2SymbolTable.hpp <CTPP2SymbolTable.hpp>
+ @brief Symbol record
+ */
+ template <typename TT>struct SymbolRecord
+ {
+ /** Symbol Id */
+ INT_32 symbol_id;
+ /** Symbol data */
+ TT symbol_data;
+
+ SymbolRecord(const INT_32 iSymbolId,
+ const TT & oT): symbol_id(iSymbolId),
+ symbol_data(oT) { ;; }
+ };
+
+ /**
+ @brief Constructor
+ */
+ SymbolTable();
+
+ /**
+ @brief Get symbol from symbol table
+ @param sSymbolName - symbol name
+ @return SymbolRecord object or NULL if nothing found
+ */
+ const SymbolRecord<T> * GetSymbol(const STLW::string & sSymbolName) const
+ {
+ typename STLW::map<STLW::string, STLW::vector<SymbolRecord<T> > >::const_iterator itmSymbolTable = mSymbolTable.find(sSymbolName);
+ if (itmSymbolTable == mSymbolTable.end()) { return NULL; }
+
+ INT_32 iPos = itmSymbolTable -> second.size() - 1;
+ if (iPos < 0) { return NULL; }
+
+ return &(itmSymbolTable -> second[iPos]);
+ }
+
+ /**
+ @brief Get symbol from symbol table
+ @param szSymbolName - symbol name
+ @param iSymbolNameLength - symbol name length
+ @return SymbolRecord object or NULL if nothing found
+ */
+ const SymbolRecord<T> * GetSymbol(CCHAR_P szSymbolName, const UINT_32 iSymbolNameLength) const
+ {
+ if (szSymbolName == NULL || iSymbolNameLength == 0) { return NULL; }
+
+ return GetSymbol(STLW::string(szSymbolName, iSymbolNameLength));
+ }
+
+ /**
+ @brief Add symbol into symbol table
+ @param sSymbolName - symbol name
+ @param oSymbolData - symbol data
+ @return Symbol Id
+ */
+ INT_32 AddSymbol(const STLW::string & sSymbolName, const T & oSymbolData);
+
+ /**
+ @brief Add symbol into symbol table
+ @param sSymbolName - symbol name
+ @param oSymbolData - symbol data
+ @return Symbol Id
+ */
+ INT_32 AddSymbol(CCHAR_P szSymbolName, const UINT_32 iSymbolNameLength, const T & oSymbolData)
+ {
+ return AddSymbol(STLW::string(szSymbolName, iSymbolNameLength), oSymbolData);
+ }
+
+ /**
+ @brief Mark symbol visibility scope
+ @return Symbol Id
+ */
+ void MarkScope();
+
+ /**
+ @brief Unmark (reset to previous) symbol visibility scope
+ @return Symbol Id
+ */
+ void UnmarkScope();
+
+ /**
+ @brief Destructor
+ */
+ ~SymbolTable() throw();
+
+private:
+ /** Last variable id */
+ INT_32 iLastVarId;
+ /** Symbol table */
+ STLW::map<STLW::string, STLW::vector<SymbolRecord<T> > > mSymbolTable;
+
+ /** Last variable id */
+ INT_32 iCurrentScope;
+ /** Last variable id in current scope */
+ struct ScopeVars
+ {
+ /** List of variables in current scope */
+ STLW::vector<STLW::string> varlist;
+ /** Last scope variable Id */
+ INT_32 last_var_id;
+
+ /**
+ @brief Constructor
+ @param
+ */
+ ScopeVars(const STLW::vector<STLW::string> & vVarList,
+ const UINT_32 & iLastVarId): varlist(vVarList),
+ last_var_id(iLastVarId) { ;; }
+ };
+ STLW::vector<ScopeVars> vScopeLastVarList;
+};
+
+//
+// Constructor
+//
+template<typename T> SymbolTable<T>::SymbolTable():iLastVarId(0), iCurrentScope(0)
+{
+ vScopeLastVarList.push_back(ScopeVars(STLW::vector<STLW::string>(), 0));
+}
+
+//
+// Add symbol into symbol table
+//
+template<typename T> INT_32 SymbolTable<T>::AddSymbol(const STLW::string & sSymbolName, const T & oSymbolData)
+{
+ typename STLW::map<STLW::string, STLW::vector<SymbolRecord<T> > >::const_iterator itmSymbolTable = mSymbolTable.find(sSymbolName);
+ if (itmSymbolTable != mSymbolTable.end())
+ {
+
+ INT_32 iSymTablePos = itmSymbolTable -> second.size() - 1;
+ INT_32 iScopeTablePos = vScopeLastVarList.size() - 1;
+
+ if (vScopeLastVarList[iScopeTablePos].last_var_id <= itmSymbolTable -> second[iSymTablePos].symbol_id) { return -1; }
+ }
+
+ vScopeLastVarList[iCurrentScope].varlist.push_back(sSymbolName);
+
+ mSymbolTable[sSymbolName].push_back(SymbolRecord<T>(iLastVarId, oSymbolData));
+
+return iLastVarId++;
+}
+
+//
+// Mark symbol visibility scope
+//
+template<typename T> void SymbolTable<T>::MarkScope()
+{
+ ++iCurrentScope;
+
+ vScopeLastVarList.push_back(ScopeVars(STLW::vector<STLW::string>(), iLastVarId));
+}
+
+//
+// Unmark (reset to previous) symbol visibility scope
+//
+template<typename T> void SymbolTable<T>::UnmarkScope()
+{
+ typename STLW::vector<ScopeVars>::iterator itvCurrentScope = vScopeLastVarList.end();
+
+ // Nothing to do?
+ if (itvCurrentScope == vScopeLastVarList.begin()) { return ; }
+
+ --itvCurrentScope;
+
+ // Get list of symbols in current scope
+ STLW::vector<STLW::string>::const_iterator itvVarList = itvCurrentScope -> varlist.begin();
+
+ // Set new last variable Id
+ iLastVarId = itvCurrentScope -> last_var_id;
+
+ // Remove all variables that belong to current scope
+ while (itvVarList != itvCurrentScope -> varlist.end())
+ {
+ typename STLW::map<STLW::string, STLW::vector<SymbolRecord<T> > >::iterator itmSymbolTable = mSymbolTable.find(*itvVarList);
+ // This should never happened, but let it be
+ if (itmSymbolTable != mSymbolTable.end())
+ {
+ typename STLW::vector<SymbolRecord<T> > & oTMP = itmSymbolTable -> second;
+
+ typename STLW::vector<SymbolRecord<T> >::iterator itVarId = oTMP.end();
+
+ if (itVarId != oTMP.begin())
+ {
+ --itVarId;
+ oTMP.erase(itVarId);
+ }
+
+ // Remove empty symbols
+ if (oTMP.size() == 0) { mSymbolTable.erase(itmSymbolTable); }
+ }
+
+ ++itvVarList;
+ }
+
+ vScopeLastVarList.erase(itvCurrentScope);
+ --iCurrentScope;
+}
+
+//
+// Destructor
+//
+template<typename T> SymbolTable<T>::~SymbolTable() throw() { ;; }
+
+} // namespace CTPP
+#endif // _CTPP2_SYMBOL_TABLE_HPP__
+// End.
diff --git a/include/CTPP2Syntax.h b/include/CTPP2Syntax.h
new file mode 100644
index 0000000..f033df6
--- /dev/null
+++ b/include/CTPP2Syntax.h
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2004 - 2009 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Syntax.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SYNTAX_H__
+#define _CTPP2_SYNTAX_H__ 1
+
+/**
+ @file CTPP2Syntax.h
+ @brief Syntax definitions of CTPP2 template language
+*/
+
+// First char
+#define TMPL_OPEN_SYMBOL '<'
+#define TMPL_CLOSE_SYMBOL '>'
+
+// Open tag
+#define CTPP2_OPEN_TAG "tmpl"
+#define CTPP2_CLOSE_TAG "tmpl"
+
+// Operators
+#define TMPL_VAR_TOK "var"
+#define TMPL_IF_TOK "if"
+#define TMPL_ELSE_TOK "else"
+#define TMPL_ELSIF_TOK "elsif"
+#define TMPL_UNLESS_TOK "unless"
+#define TMPL_FOREACH_TOK "foreach"
+#define TMPL_UDF_TOK "udf"
+#define TMPL_INCLUDE_TOK "include"
+#define TMPL_CALL_TOK "call"
+#define TMPL_COMMENT_TOK "comment"
+#define TMPL_BREAK_TOK "break"
+#define TMPL_BLOCK_TOK "block"
+#define TMPL_VERBOSE_TOK "verbose"
+
+// Relations
+#define TMPL_EQ "eq"
+#define TMPL_NE "ne"
+#define TMPL_GT "gt"
+#define TMPL_LT "lt"
+#define TMPL_GE "ge"
+#define TMPL_LR "le"
+
+#define TMPL_N_EQ "=="
+#define TMPL_N_NE "!="
+#define TMPL_N_GE ">="
+#define TMPL_N_LE "<="
+#define TMPL_N_GT ">"
+#define TMPL_N_LT "<"
+
+// Operations
+//#define TMPL_PLUS "+"
+//#define TMPL_MINUS "-"
+//#define TMPL_DIV "/"
+//#define TMPL_MUL "*"
+//#define TMPL_IDIV "DIV"
+//#define TMPL_MOD "MOD"
+
+//#define TMPL_UNPLUS "+"
+//#define TMPL_UNMINUS "-"
+//#define TMPL_NOT "!"
+
+/*
+LogicalOrExpr = LogicalAndExpr { "||" LogicalAndExpr }
+
+LogicalAndExpr = RelExpr { "&&" RelExpr }
+
+RelExpr = SimpleExpr [Relation SimpleExpr]
+
+SimpleExpr = Term {AddOp Term}
+
+Term = Factor {MulOp Factor}
+
+Factor = Function "(" [ExprList] ")" | number | character | string | "(" LogicalOrExpr ")" | [ UNPLUS | UNMINUS | NOT] Factor
+
+Relation = N_EQ | N_NE | N_GT | N_LT | N_GE | N_LE | EQ | NE | GT | LT | GE | LE
+
+AddOp = ADD | SUB
+
+MulOp = MUL | DIV | IDIV | MOD
+
+ExprList = LogicalOrExpr {"," LogicalOrExpr}
+*/
+
+#endif // _CTPP2_SYNTAX_H__
+// End.
diff --git a/include/CTPP2SysTypes.h b/include/CTPP2SysTypes.h
new file mode 100644
index 0000000..562d116
--- /dev/null
+++ b/include/CTPP2SysTypes.h
@@ -0,0 +1,515 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SysTypes.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SYS_TYPES_H__
+#define _CTPP2_SYS_TYPES_H__ 1
+
+/**
+ @file CTPP2SysTypes.h
+ @brief Base platform-dependent type definitions
+*/
+
+// C Includes
+#include <sys/types.h>
+#include <stdint.h>
+
+#if defined(__linux__) || defined(linux) || defined(CYGWIN) || defined(__CYGWIN__)
+
+/**
+ @var typedef __int16_t INT_16
+ @brief Signed 16-bit integer (linux)
+*/
+typedef __int16_t INT_16;
+
+/**
+ @var typedef __uint16_t UINT_16
+ @brief Unsigned 16-bit integer (linux)
+*/
+typedef __uint16_t UINT_16;
+
+/**
+ @var typedef __int32_t INT_32
+ @brief Signed 32-bit integer (linux)
+*/
+typedef __int32_t INT_32;
+
+/**
+ @var typedef __uint32_t UINT_32
+ @brief Unsigned 32-bit integer (linux)
+*/
+typedef __uint32_t UINT_32;
+
+/**
+ @var typedef __int64_t INT_64
+ @brief Signed 64-bit integer (linux)
+*/
+typedef __int64_t INT_64;
+
+/**
+ @var typedef __uint64_t UINT_64
+ @brief Unsigned 64-bit integer (linux)
+*/
+typedef __uint64_t UINT_64;
+
+/**
+ @var typedef double W_FLOAT
+ @brief Floafing point variable (linux)
+*/
+typedef double W_FLOAT;
+
+/**
+ @var typedef char CHAR_8
+ @brief Signed 8-bit character (linux)
+*/
+typedef char CHAR_8;
+
+/**
+ @var unsigned char UCHAR_8
+ @brief Unsigned 8-bit character (linux)
+*/
+typedef unsigned char UCHAR_8;
+
+/**
+ @var typedef const char CCHAR_8
+ @brief Constant character (linux)
+*/
+typedef const char CCHAR_8;
+
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Unsigned constant character (linux)
+*/
+typedef const unsigned char UCCHAR_8;
+
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Address (linux)
+*/
+typedef CHAR_8 * CHAR_P;
+
+/**
+ @var typedef const unsigned char UCHAR_P
+ @brief Address of unsigned char (linux)
+*/
+typedef UCHAR_8 * UCHAR_P;
+
+/**
+ @var typedef const unsigned char CCHAR_P
+ @brief Address, pointer to const (linux)
+*/
+typedef CCHAR_8 * CCHAR_P;
+
+/**
+ @var typedef const unsigned char UCCHAR_P
+ @brief Address, pointer to unsigned const (linux)
+*/
+typedef UCCHAR_8 * UCCHAR_P;
+
+
+#elif defined(__FreeBSD__) || defined(__APPLE__) /* Linux End, start of FreeBSD / Mac OS declarations */
+
+/**
+ @var typedef int16_t INT_16
+ @brief Signed 16-bit integer (FreeBSD OS)
+*/
+typedef int16_t INT_16;
+
+/**
+ @var typedef uint16_t UINT_16
+ @brief Unsigned 16-bit integer (FreeBSD OS)
+*/
+typedef uint16_t UINT_16;
+
+/**
+ @var typedef int32_t INT_32
+ @brief Signed 32-bit integer (FreeBSD OS)
+*/
+typedef int32_t INT_32;
+
+/**
+ @var typedef uint32_t UINT_32
+ @brief Unsigned 32-bit integer (FreeBSD OS)
+*/
+typedef uint32_t UINT_32;
+
+/**
+ @var typedef int64_t INT_64
+ @brief Signed 64-bit integer (FreeBSD OS)
+*/
+typedef int64_t INT_64;
+
+/**
+ @var typedef uint64_t UINT_64
+ @brief Unsigned 64-bit integer (FreeBSD OS)
+*/
+typedef uint64_t UINT_64;
+
+/**
+ @var typedef double W_FLOAT
+ @brief Floafing point variable (FreeBSD OS)
+*/
+typedef double W_FLOAT;
+
+/**
+ @var typedef char CHAR_8
+ @brief Signed 8-bit character (FreeBSD OS)
+*/
+typedef char CHAR_8;
+
+/**
+ @var typedef unsigned char UCHAR_8
+ @brief Unsigned 8-bit character (FreeBSD OS)
+*/
+typedef unsigned char UCHAR_8;
+
+/**
+ @var typedef const char CCHAR_8
+ @brief Constant character (FreeBSD OS)
+*/
+typedef const char CCHAR_8;
+
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Unsigned constant character (FreeBSD OS)
+*/
+typedef const unsigned char UCCHAR_8;
+
+/**
+ @var typedef CHAR_8 * CHAR_P
+ @brief Address (FreeBSD OS)
+*/
+typedef CHAR_8 * CHAR_P;
+
+/**
+ @var typedef UCHAR_8 * UCHAR_P
+ @brief Address of unsigned char (FreeBSD OS)
+*/
+typedef UCHAR_8 * UCHAR_P;
+
+/**
+ @var typedef CCHAR_8 * CCHAR_P
+ @brief Address, pointer to const (FreeBSD OS)
+*/
+typedef CCHAR_8 * CCHAR_P;
+
+/**
+ @var typedef UCCHAR_8 * UCCHAR_P
+ @brief Address, pointer to unsigned const (FreeBSD OS)
+*/
+typedef UCCHAR_8 * UCCHAR_P;
+
+
+#elif WIN32 /* FreeBSD End, start of Win32 declarations */
+
+/**
+ @var typedef __int16 INT_16
+ @brief Signed 16-bit integer (Win32)
+*/
+typedef __int16 INT_16;
+
+/**
+ @var typedef unsigned __int16 UINT_16
+ @brief Unsigned 16-bit integer (Win32)
+*/
+typedef unsigned __int16 UINT_16;
+
+/**
+ @var typedef __int32 INT_32
+ @brief Signed 32-bit integer (Win32)
+*/
+typedef __int32 INT_32;
+
+/**
+ @var typedef unsigned __int32 UINT_32
+ @brief Unsigned 32-bit integer (Win32)
+*/
+typedef unsigned __int32 UINT_32;
+
+/**
+ @var typedef __int64 INT_64
+ @brief Signed 64-bit integer (Win32)
+*/
+typedef __int64 INT_64;
+
+/**
+ @var typedef uint64_t UINT_64
+ @brief Unsigned 64-bit integer (Win32)
+*/
+typedef unsigned __int64 UINT_64;
+
+/**
+ @var typedef double W_FLOAT
+ @brief Floafing point variable (Win32)
+*/
+typedef double W_FLOAT;
+
+/**
+ @var typedef char CHAR_8
+ @brief Signed 8-bit character (Win32)
+*/
+typedef char CHAR_8;
+
+/**
+ @var typedef unsigned char UCHAR_8
+ @brief Unsigned 8-bit character (Win32)
+*/
+typedef unsigned char UCHAR_8;
+
+/**
+ @var typedef const char CCHAR_8
+ @brief Constant character (Win32)
+*/
+typedef const char CCHAR_8;
+
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Unsigned constant character (Win32)
+*/
+typedef const unsigned char UCCHAR_8;
+
+/**
+ @var typedef CHAR_8 * CHAR_P
+ @brief Address (Win32)
+*/
+typedef CHAR_8 * CHAR_P;
+
+/**
+ @var typedef UCHAR_8 * UCHAR_P
+ @brief Address of unsigned char (Win32)
+*/
+typedef UCHAR_8 * UCHAR_P;
+
+/**
+ @var typedef CCHAR_8 * CCHAR_P
+ @brief Address, pointer to const (Win32)
+*/
+typedef CCHAR_8 * CCHAR_P;
+
+/**
+ @var typedef UCCHAR_8 * UCCHAR_P
+ @brief Address, pointer to unsigned const (Win32)
+*/
+typedef UCCHAR_8 * UCCHAR_P;
+
+#elif sun /* Win32 End, start of Sun Solaris declarations */
+
+/**
+ @var typedef int16_t INT_16
+ @brief Signed 16-bit integer (Sun OS)
+*/
+typedef int16_t INT_16;
+
+/**
+ @var typedef uint16_t UINT_16
+ @brief Unsigned 16-bit integer (Sun OS)
+*/
+typedef uint16_t UINT_16;
+
+/**
+ @var typedef int32_t INT_32
+ @brief Signed 32-bit integer (Sun OS)
+*/
+typedef int32_t INT_32;
+
+/**
+ @var typedef uint32_t UINT_32
+ @brief Unsigned 32-bit integer (Sun OS)
+*/
+typedef uint32_t UINT_32;
+
+/**
+ @var typedef int64_t INT_64
+ @brief Signed 64-bit integer (Sun OS)
+*/
+typedef int64_t INT_64;
+
+/**
+ @var typedef uint64_t UINT_64
+ @brief Unsigned 64-bit integer (Sun OS)
+*/
+typedef uint64_t UINT_64;
+
+/**
+ @var typedef double W_FLOAT
+ @brief Floafing point variable (Sun OS)
+*/
+typedef double W_FLOAT;
+
+/**
+ @var typedef char CHAR_8
+ @brief Signed 8-bit character (Sun OS)
+*/
+typedef char CHAR_8;
+
+/**
+ @var typedef unsigned char UCHAR_8
+ @brief Unsigned 8-bit character (Sun OS)
+*/
+typedef unsigned char UCHAR_8;
+
+/**
+ @var typedef const char CCHAR_8
+ @brief Constant character (Sun OS)
+*/
+typedef const char CCHAR_8;
+
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Unsigned constant character (Sun OS)
+*/
+typedef const unsigned char UCCHAR_8;
+
+/**
+ @var typedef CHAR_8 * CHAR_P
+ @brief Address (Sun OS)
+*/
+typedef CHAR_8 * CHAR_P;
+
+/**
+ @var typedef UCHAR_8 * UCHAR_P
+ @brief Address of unsigned char (Sun OS)
+*/
+typedef UCHAR_8 * UCHAR_P;
+
+/**
+ @var typedef CCHAR_8 * CCHAR_P
+ @brief Address, pointer to const (Sun OS)
+*/
+typedef CCHAR_8 * CCHAR_P;
+
+/**
+ @var typedef UCCHAR_8 * UCCHAR_P
+ @brief Address, pointer to unsigned const (Sun OS)
+*/
+typedef UCCHAR_8 * UCCHAR_P;
+
+#elif __hpux /* Sun OS End, start of HP-UX declarations */
+
+/**
+ @var typedef int16_t INT_16
+ @brief Signed 16-bit integer (HP-UX)
+*/
+typedef int16_t INT_16;
+
+/**
+ @var typedef uint16_t UINT_16
+ @brief Unsigned 16-bit integer (HP-UX)
+*/
+typedef uint16_t UINT_16;
+
+/**
+ @var typedef int32_t INT_32
+ @brief Signed 32-bit integer (HP-UX)
+*/
+typedef int32_t INT_32;
+
+/**
+ @var typedef uint32_t UINT_32
+ @brief Unsigned 32-bit integer (HP-UX)
+*/
+typedef uint32_t UINT_32;
+
+/**
+ @var typedef int64_t INT_64
+ @brief Signed 64-bit integer (HP-UX)
+*/
+typedef int64_t INT_64;
+
+/**
+ @var typedef uint64_t UINT_64
+ @brief Unsigned 64-bit integer (HP-UX)
+*/
+typedef uint64_t UINT_64;
+/**
+ @var typedef double W_FLOAT
+ @brief Floafing point variable (HP-UX)
+*/
+typedef double W_FLOAT;
+
+/**
+ @var typedef char CHAR_8
+ @brief Signed 8-bit character (HP-UX)
+*/
+typedef char CHAR_8;
+
+/**
+ @var typedef unsigned char UCHAR_8
+ @brief Unsigned 8-bit character (HP-UX)
+*/
+typedef unsigned char UCHAR_8;
+
+/**
+ @var typedef const char CCHAR_8
+ @brief Constant character (HP-UX)
+*/
+typedef const char CCHAR_8;
+/**
+ @var typedef const unsigned char UCCHAR_8
+ @brief Unsigned constant character (HP-UX)
+*/
+typedef const unsigned char UCCHAR_8;
+
+/**
+ @var typedef CHAR_8 * CHAR_P
+ @brief Address (HP-UX)
+*/
+typedef CHAR_8 * CHAR_P;
+
+/**
+ @var typedef UCHAR_8 * UCHAR_P
+ @brief Address of unsigned char (HP-UX)
+*/
+typedef UCHAR_8 * UCHAR_P;
+
+/**
+ @var typedef CCHAR_8 * CCHAR_P
+ @brief Address, pointer to const (HP-UX)
+*/
+typedef CCHAR_8 * CCHAR_P;
+
+/**
+ @var typedef UCCHAR_8 * UCCHAR_P
+ @brief Address, pointer to unsigned const (HP-UX)
+*/
+typedef UCCHAR_8 * UCCHAR_P;
+
+#else /* HP-UX End */
+
+#error "Cannot compile on this platform"
+
+#endif /* Platform */
+
+#ifndef NULL
+ #define NULL 0x0
+#endif
+
+#endif /* _CTPP2_SYS_TYPES_H__ */
+/* End. */
diff --git a/include/CTPP2SyscallFactory.hpp b/include/CTPP2SyscallFactory.hpp
new file mode 100644
index 0000000..5eb675e
--- /dev/null
+++ b/include/CTPP2SyscallFactory.hpp
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SyscallFactory.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_SYSCALL_FACTORY_HPP__
+#define _CTPP2_SYSCALL_FACTORY_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+#include "STLFunctional.hpp"
+#include "STLMap.hpp"
+#include "STLString.hpp"
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/**
+ @file CTPP2SyscallFactory.hpp
+ @brief Virtual machine handlers factory
+*/
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class SyscallFactory CTPP2SyscallFactory.hpp <CTPP2SyscallFactory.hpp>
+ @brief System calls abstract factory
+*/
+class CTPP2DECL SyscallFactory
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxHandlers - max. number of handlers
+ */
+ SyscallFactory(const UINT_32 iIMaxHandlers);
+
+ /**
+ @brief Get Handler by ID
+ @param iHandlerId - handler ID
+ @return pointer to handler or NULL if handler does not exist
+ */
+ SyscallHandler * GetHandlerById(const UINT_32 iHandlerId) const;
+
+ /**
+ @brief Get Handler by name
+ @param szHandlerName - handler name
+ @return pointer to handler or NULL if handler does not exist
+ */
+ SyscallHandler * GetHandlerByName(CCHAR_P szHandlerName) const;
+
+ /**
+ @brief Remove handler from factory
+ @param szHandlerName - handler name
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 RemoveHandler(CCHAR_P szHandlerName);
+
+ /**
+ @brief Register handler
+ @param pHandler - handler to register in factory
+ @return Handler ID
+ */
+ INT_32 RegisterHandler(SyscallHandler * pHandler);
+
+ /**
+ @brief A destructor
+ */
+ ~SyscallFactory() throw();
+
+private:
+ /**
+ @struct HandlerRefsSort SyscallFactory.hpp <SyscallFactory.hpp>
+ @brief Case-insensitive sorting functor
+ */
+ struct HandlerRefsSort:
+ public STLW::binary_function<STLW::string, STLW::string, bool>
+ {
+ /**
+ @brief comparison operator
+ @param x - first argument
+ @param y - first argument
+ @return true if x > y
+ */
+ inline bool operator() (const STLW::string & x,
+ const STLW::string & y) const
+ {
+ return (strcasecmp(x.c_str(), y.c_str()) > 0);
+ }
+ };
+
+ /** Max. allowed number of handlers */
+ const UINT_32 iMaxHandlers;
+ /** Max. used handler ID */
+ UINT_32 iCurrHandlers;
+ /** List of handlers */
+ SyscallHandler ** aHandlers;
+ /** Handler name-to-handler ID translation map */
+ STLW::map<STLW::string, UINT_32, HandlerRefsSort> mHandlerRefs;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_SYSCALL_FACTORY_HPP__
+// End.
diff --git a/include/CTPP2Time.h b/include/CTPP2Time.h
new file mode 100644
index 0000000..607a914
--- /dev/null
+++ b/include/CTPP2Time.h
@@ -0,0 +1,51 @@
+/*
+ * (c) 1995 Microsoft Corporation. All rights reserved.
+ * Developed by hip communications inc., http://info.hip.com/info/
+ * Portions (c) 1993 Intergraph Corporation. All rights reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ */
+#ifndef _CTPP2_TIME_H__
+#define _CTPP2_TIME_H__ 1
+/*
+ * stolen from ActiveState perl sources
+ */
+
+#include <windows.h>
+#include <winsock.h> /* timeval */
+
+typedef union
+{
+ unsigned __int64 ft_i64;
+ FILETIME ft_val;
+} FT_t;
+
+#ifdef __GNUC__
+# define Const64(x) x##LL
+#else
+# define Const64(x) x##i64
+#endif
+/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
+#define EPOCH_BIAS Const64(116444736000000000)
+
+/* NOTE: This does not compute the timezone info (doing so can be expensive,
+ * and appears to be unsupported even by glibc) */
+inline int gettimeofday(struct timeval *tp, void *not_used)
+{
+ FT_t ft;
+
+ /* this returns time in 100-nanosecond units (i.e. tens of usecs) */
+ GetSystemTimeAsFileTime(&ft.ft_val);
+
+ /* seconds since epoch */
+ tp->tv_sec = (long)((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000));
+
+ /* microseconds remaining */
+ tp->tv_usec = (long)((ft.ft_i64 / Const64(10)) % Const64(1000000));
+
+return 0;
+}
+
+#endif /* _CTPP2_TIME_H__ */
+/* End. */
diff --git a/include/CTPP2Types.h b/include/CTPP2Types.h
new file mode 100644
index 0000000..3db3587
--- /dev/null
+++ b/include/CTPP2Types.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Types.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_TYPES_H__
+#define _CTPP2_TYPES_H__ 1
+
+/**
+ @file CTPP2Types.h
+ @brief Base platform-dependent type definitions & global macroses
+*/
+
+// Local Includes
+#include "CTPP2GlobalDefines.h"
+#include "CTPP2SysTypes.h"
+
+#endif /* _CTPP2_TYPES_H__ */
+/* End. */
diff --git a/include/CTPP2Util.hpp b/include/CTPP2Util.hpp
new file mode 100644
index 0000000..526c640
--- /dev/null
+++ b/include/CTPP2Util.hpp
@@ -0,0 +1,242 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Util.hpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Types.h"
+
+#include "STLString.hpp"
+
+/**
+ @file CTPP2Util.hpp
+ @brief CTPP2 useful utilities
+*/
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+class CDT;
+
+/**
+ @class DumpBuffer CTPP2Util.hpp <CTPP2Util.hpp>
+ @brief Buffer for dumping CDTs. Used as an alternative for std::string (as string's append is quite slow)
+*/
+class CTPP2DECL DumpBuffer {
+public:
+ /**
+ @var typedef UINT_32 StreamSize
+ @brief internal size_t analog
+ */
+ typedef UINT_32 StreamSize;
+
+ /**
+ @brief Constructor
+ */
+ DumpBuffer();
+
+ /**
+ @brief Destructor
+ */
+ ~DumpBuffer();
+
+ /**
+ @brief Appends data to the buffer
+ @param data - ponter to data to append
+ @param n - number of bytes to append
+ */
+ void Write(CCHAR_P pData , StreamSize iSize);
+
+ /**
+ @brief Returns pointer to buffer's start
+ @return Pointer to buffer's start
+ */
+ CCHAR_P Data() const;
+
+ /**
+ @brief Returns number of bytes available in buffer
+ @return Number of bytes available in buffer
+ */
+ StreamSize Size() const;
+
+private:
+ /**
+ @brief Reallocates buffer if necessary
+ @param n - new capacity (if it's less then current capacity, method does nothing)
+ */
+ void Reserve(StreamSize iSize);
+
+ CHAR_P pBuffer;
+ CHAR_P pPos;
+
+ StreamSize iCapacity;
+};
+
+/**
+ @fn UINT_32 crc32(UCCHAR_P sBuffer, const UINT_32 & iSize)
+ @brief Calculate crc32 checksum
+ @param sBuffer - buffer with source data to calculate CRC
+ @param iSize - buffer size
+ @return CRC32 checksum
+*/
+CTPP2DECL UINT_32 crc32(UCCHAR_P sBuffer, const UINT_32 & iSize);
+
+/**
+ @fn UINT_32 Swap32(const UINT_32 & iValue)
+ @brief Swap bytes for UINT_32 value
+ @param iValue - value to swap
+ @return Swapped value
+*/
+CTPP2DECL UINT_32 Swap32(const UINT_32 & iValue);
+
+/**
+ @fn UINT_64 Swap64(const UINT_64 & iValue)
+ @brief Swap bytes for UINT_64 value
+ @param iValue - value to swap
+ @return Swapped value
+*/
+CTPP2DECL UINT_64 Swap64(const UINT_64 & iValue);
+
+/**
+ @fn STLW::string URIEscape(const STLW::string & sData)
+ @brief Escape value (URI rules)
+ @param sData - value to escape
+ @return Escaped value
+*/
+CTPP2DECL STLW::string URIEscape(const STLW::string & sData);
+
+/**
+ @fn STLW::string URLEscape(const STLW::string & sData)
+ @brief Escape value (URL rules)
+ @param sData - value to escape
+ @return Escaped value
+*/
+CTPP2DECL STLW::string URLEscape(const STLW::string & sData);
+
+/**
+ @fn STLW::string HTMLEscape(const STLW::string & sData)
+ @brief Escape value (HTML rules)
+ @param sData - value to escape
+ @return Escaped value
+*/
+CTPP2DECL STLW::string HTMLEscape(const STLW::string & sData);
+
+/**
+ @fn STLW::string XMLEscape(const STLW::string & sData)
+ @brief Escape value (XML rules)
+ @param sData - value to escape
+ @return Escaped value
+*/
+CTPP2DECL STLW::string XMLEscape(const STLW::string & sData);
+
+/**
+ @fn STLW::string WMLEscape(const STLW::string & sData)
+ @brief Escape value (WML rules)
+ @param sData - value to escape
+ @return Escaped value
+*/
+CTPP2DECL STLW::string WMLEscape(const STLW::string & sData);
+
+/**
+ @fn void CDT2JSON(const CTPP::CDT & oCDT, STLW::string & sData)
+ @brief Dump CDT to JSON
+ @param oCDT - input data
+ @param sData - output string
+*/
+CTPP2DECL void CDT2JSON(const CDT & oCDT, STLW::string & sData);
+
+/**
+ @fn void DumpCDT2JSON(const CTPP::CDT & oCDT, DumpBuffer & oBuffer)
+ @brief Dump CDT to JSON
+ @param oCDT - input data
+ @param oBuffer - buffer to dump CDT to
+ @return reference to oBuffer
+*/
+CTPP2DECL DumpBuffer & DumpCDT2JSON(const CTPP::CDT & oCDT, DumpBuffer & oBuffer);
+
+/**
+ @brief Escape string, if need
+ @param sSource - input data
+ @param bECMAConventions - use ECMA-262 conventions for escape sequences
+ @return Escaped string
+*/
+CTPP2DECL STLW::string EscapeJSONString(const STLW::string & sSource,
+ const bool & bECMAConventions = true,
+ const bool & bHTMLSafe = true);
+
+/**
+ @brief Escape and dump string to buffer
+ @param oBuffer - buffer to dump string to
+ @param sSource - input data
+ @param bECMAConventions - use ECMA-262 conventions for escape sequences
+ @return reference to oBuffer
+*/
+CTPP2DECL DumpBuffer & DumpJSONString(DumpBuffer& oBuffer,
+ const STLW::string & sSource,
+ const bool & bECMAConventions = true,
+ const bool & bHTMLSafe = true);
+
+/**
+ @fn STLW::string Base64Encode(const STLW::string & sData);
+ @brief Encode value in BASE64 encoding
+ @param sData - value to encode
+ @return Encoded value
+*/
+CTPP2DECL STLW::string Base64Encode(const STLW::string & sData);
+
+/**
+ @fn STLW::string Base64Decode(const STLW::string & sData);
+ @brief Decode value from BASE64 encoding
+ @param sData - value to decode
+ @return Decoded value
+*/
+CTPP2DECL STLW::string Base64Decode(const STLW::string & sData);
+
+/**
+ @fn INT_32 utf_charlen(CCHAR_P szString, CCHAR_P szStringEnd);
+ @brief Length of UTF character
+ @brief szString - source string
+ @brief szStringEnd - pointer to the end of string
+ @return >0 - character length,
+ -1 - error in multibyte sequence,
+ -2 - is not an UTF8 character,
+ -3 - unexpected end of string reached
+*/
+CTPP2DECL INT_32 utf_charlen(CCHAR_P szString, CCHAR_P szStringEnd);
+
+/**
+ @fn INT_32 UnicodeToUTF8(UINT_32 iUCS, char * sUTF8)
+ @brief Convert Unicode character to UTF8
+ @param iUCS - Unicode symbol
+ @param sUTF8 - Pointer to buffer, at least 6 octets
+ @return UTF8 character length
+*/
+CTPP2DECL INT_32 UnicodeToUTF8(UINT_32 iUCS, UCHAR_P sUTF8);
+
+} // namespace CTPP
+// End.
diff --git a/include/CTPP2VM.hpp b/include/CTPP2VM.hpp
new file mode 100644
index 0000000..1e9ccc1
--- /dev/null
+++ b/include/CTPP2VM.hpp
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VM.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_HPP__
+#define _CTPP2_VM_HPP__ 1
+
+/**
+ @file CTPP2VM.hpp
+ @brief Virtual Machine
+*/
+
+#include "CTPP2VMArgStack.hpp"
+#include "CTPP2VMCodeStack.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class OutputCollector;
+class SyscallFactory;
+class SyscallHandler;
+struct VMMemoryCore;
+class Logger;
+
+/**
+ @class VM CTPP2VM.hpp <CTPP2VM.hpp>
+ @brief Virtual Machine implementation
+*/
+class CTPP2DECL VM
+{
+public:
+ /**
+ @brief Constructor
+ @param oISyscallFactory - factory with system calls
+ @param iIMaxArgStackSize - max. size of arguments stack
+ @param iIMaxCodeStackSize - max. size of code stack
+ @param iIMaxSteps - max. number of executed steps
+ @param iIDebugLevel - debugging level
+ */
+ VM(SyscallFactory * pSyscallFactory,
+ const UINT_32 iIMaxArgStackSize = 4096,
+ const UINT_32 iIMaxCodeStackSize = 4096,
+ const UINT_32 iIMaxSteps = 10240,
+ const UINT_32 iIDebugLevel = 0);
+
+ /**
+ @brief Initialize virtual machine
+ */
+ INT_32 Init(const VMMemoryCore * pMemoryCore,
+ OutputCollector * pOutputCollector,
+ Logger * pLogger);
+
+ /**
+ @brief Run program
+ @param oMemoryCore - ready-to-run core of program
+ @param iIP - instruction pointer
+ @param oCDT - initial data
+ @return stack depth
+ */
+ INT_32 Run(const VMMemoryCore * pMemoryCore,
+ OutputCollector * pOutputCollector,
+ UINT_32 & iIP,
+ CDT & oCDT,
+ Logger * pLogger);
+
+ /**
+ @brief Reset virtual machine state
+ */
+ INT_32 Reset();
+
+ /**
+ @brief A destructor
+ */
+ ~VM() throw();
+
+private:
+ /** System calls factory */
+ SyscallFactory * pSyscallFactory;
+ /** Maximal arguments stack size */
+ const UINT_32 iMaxArgStackSize;
+ /** Maximal code stack size */
+ const UINT_32 iMaxCodeStackSize;
+ /** Maximum program execution
+ steps */
+ const UINT_32 iMaxSteps;
+ /** Debug level */
+ const UINT_32 iDebugLevel;
+
+ /** Number of system calls */
+ UINT_32 iMaxCalls;
+ /** Number of system calls */
+ UINT_32 iMaxUsedCalls;
+ /** System calls translation map */
+ SyscallHandler ** aCallTranslationMap;
+
+ /** Stack of arguments */
+ VMArgStack oVMArgStack;
+ /** Stack of code return points */
+ VMCodeStack oVMCodeStack;
+
+ /** Virtual machine registers */
+ CDT oRegs[8];
+ /** Virtual flags */
+ UINT_32 iFlags;
+
+ void CheckStackOnlyRegs(const UINT_32 iSrcReg, const UINT_32 iDstReg, const VMMemoryCore * pMemoryCore, const UINT_32 iIP);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_HPP__
+// End.
diff --git a/include/CTPP2VMArgStack.hpp b/include/CTPP2VMArgStack.hpp
new file mode 100644
index 0000000..bf54fab
--- /dev/null
+++ b/include/CTPP2VMArgStack.hpp
@@ -0,0 +1,171 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMArgStack.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_ARG_STACK_HPP__
+#define _CTPP2_VM_ARG_STACK_HPP__ 1
+
+/**
+ @file CTPP2VMArgStack.hpp
+ @brief Virtual Machine stack of arguments
+*/
+
+#include "CDT.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class VM;
+
+/**
+ @class VMArgStack CTPP2VMCodeStack.hpp <CTPP2VMCodeStack.hpp>
+ @brief Virtual Machine stack of arguments
+
+<pre>
+ +----+ <-- iMaxStackSize
+ |void|
+ |void|
+ |----| <-- iStackPointer
+ |data|
+ |data|
+ | .. |
+ |data| <-- iBasePointer
+ |data|
+ | .. |
+ |data|
+ +----+ <-- 0
+</pre>
+
+*/
+class CTPP2DECL VMArgStack
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxStackSize - maximal stack size
+ */
+ VMArgStack(const INT_32 iIMaxStackSize = 4096);
+
+ /**
+ @brief Save base pointer
+ @param iOffset - offset from top of stack
+ */
+ void SaveBasePointer(const UINT_32 iOffset = 0);
+
+ /**
+ @brief Restore previous base pointer
+ */
+ void RestoreBasePointer();
+
+ /**
+ @brief Get stack usage factor
+ @return stack depth
+ */
+ INT_32 GetSize() const;
+
+ /**
+ @brief Push element into stack
+ @param oCDT - element to push
+ @return stack depth
+ */
+ INT_32 PushElement(const CDT & oCDT);
+
+ /**
+ @brief Remove top stack element
+ @return stack depth
+ */
+ INT_32 PopElement();
+
+ /**
+ @brief Get element from specified position
+ @param iPos - element position
+ @return Stack element
+ */
+ CDT & GetElement(const INT_32 iPos);
+
+ /**
+ @brief Get top stack element
+ @return Stack element
+ */
+ inline CDT & GetTopElement(const INT_32 iPos = 0) { return GetElement(iStackPointer + iPos); }
+
+ /**
+ @brief Clear stack on specified depth
+ @param iDepth - number of elements to clear
+ @return stack depth
+ */
+ INT_32 ClearStack(const INT_32 iDepth);
+
+ /**
+ @brief Reset stack of arguments to default state
+ */
+ void Reset();
+
+ /**
+ @brief A destructor
+ */
+ ~VMArgStack() throw();
+
+private:
+ friend class VM;
+
+ /**
+ @brief Copy Constructor
+ */
+ VMArgStack(const VMArgStack & oRhs);
+
+ /**
+ @brief Copy operator
+ */
+ VMArgStack & operator=(const VMArgStack & oRhs);
+
+ /** Maximal stack size */
+ const INT_32 iMaxStackSize;
+ /** Current stack size */
+ INT_32 iStackPointer;
+ /** Base pointers */
+ STLW::vector<INT_32> vBasePointers;
+
+ /** Stack array */
+ CDT * aStack;
+
+ /**
+ @brief Get stack frame from top of stack
+ @param iTopOffset - offset of frame
+ @return pointer to start of frame
+ */
+ inline CDT * GetStackFrame(const INT_32 iTopOffset = 0) { return &aStack[iStackPointer + iTopOffset]; }
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_ARG_STACK_HPP__
+// End.
diff --git a/include/CTPP2VMCodeStack.hpp b/include/CTPP2VMCodeStack.hpp
new file mode 100644
index 0000000..99b9455
--- /dev/null
+++ b/include/CTPP2VMCodeStack.hpp
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMCodeStack.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_CODE_STACK_HPP__
+#define _CTPP2_VM_CODE_STACK_HPP__ 1
+
+/**
+ @file CTPP2VMCodeStack.hpp
+ @brief Virtual Machine stack
+*/
+
+#include "CDT.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+/**
+ @class VMCodeStack CTPP2VMCodeStack.hpp <CTPP2VMCodeStack.hpp>
+ @brief Virtual Machine stack
+
+<pre>
+ +----+ <-- iMaxStackSize
+ |void|
+ |void|
+ |----| <-- iStackPointer
+ |addr|
+ |addr|
+ | .. |
+ |addr|
+ |addr|
+ | .. |
+ |addr|
+ +----+ <-- 0
+</pre>
+
+*/
+class CTPP2DECL VMCodeStack
+{
+public:
+ /**
+ @brief Constructor
+ @param iIMaxStackSize - maximal stack size
+ */
+ VMCodeStack(const INT_32 iIMaxStackSize = 4096);
+
+ /**
+ @brief Push address into stack
+ @param iAddress - address to push
+ @return stack depth
+ */
+ void PushAddress(const UINT_32 iAddress);
+
+ /**
+ @brief Remove top stack element
+ @return stack depth
+ */
+ UINT_32 PopAddress();
+
+ /**
+ @brief Reset code stack to default state
+ */
+ void Reset();
+
+ /**
+ @brief A destructor
+ */
+ ~VMCodeStack() throw();
+private:
+
+ /**
+ @brief Copy constructor
+ */
+ VMCodeStack(const VMCodeStack & oRhs);
+
+ /**
+ @brief Copy operator
+ */
+ VMCodeStack & operator=(const VMCodeStack & oRhs);
+
+ /** Maximal stack size */
+ const INT_32 iMaxStackSize;
+ /** Current stack size */
+ INT_32 iStackPointer;
+ /** Stack array */
+ UINT_32 * aStack;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_CODE_STACK_HPP__
+// End.
diff --git a/include/CTPP2VMDebugInfo.hpp b/include/CTPP2VMDebugInfo.hpp
new file mode 100644
index 0000000..99620d3
--- /dev/null
+++ b/include/CTPP2VMDebugInfo.hpp
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMDebugInfo.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_DEBUG_INFO_HPP__
+#define _CTPP2_VM_DEBUG_INFO_HPP__ 1
+
+#include "CTPP2CharIterator.hpp"
+
+/**
+ @file CTPP2VMDebugInfo.hpp
+ @brief Virtual machine debug information
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class VMDebugInfo CTPP2VMDebugInfo.hpp <CTPP2VMDebugInfo.hpp>
+ @brief Virtual machine debug information
+<pre>
+ SSSSSSSS SSSSSSSS - String description
+ LLLLLLLL LLLLLLLL LLLLLLLL - Line
+ PPPPPPPP PPPPPPPP PPPPPPPP - Position in line
+ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+</pre>
+*/
+class CTPP2DECL VMDebugInfo
+{
+public:
+
+ /**
+ @brief Constructor
+ @param oCCharIterator - stream position
+ @param iIStringDescr - error description
+ */
+ VMDebugInfo(const CCharIterator & oCCharIterator,
+ const UINT_32 iIStringDescr = 0);
+
+ /**
+ @brief Constructor
+ @param iIStringDescr - debug info
+ @param iILine - line in template
+ @param iIPos - line position
+ */
+ VMDebugInfo(const UINT_32 iIStringDescr = 0,
+ const UINT_32 iILine = 0,
+ const UINT_32 iIPos = 0);
+
+ /**
+ @brief Constructor
+ @param iEncoded - debug info
+ */
+ VMDebugInfo(const UINT_64 iEncoded);
+
+ /**
+ @brief Get encoded debug information
+ @return Encoded debug information
+ */
+ UINT_64 GetInfo() const;
+
+ /**
+ @brief Get string ID
+ @return Description ID
+ */
+ UINT_32 GetDescrId() const;
+
+ /**
+ @brief Get line
+ @return Line in template
+ */
+ UINT_32 GetLine() const;
+
+ /**
+ @brief Get line position
+ @return Line position
+ */
+ UINT_32 GetLinePos() const;
+private:
+ /** Description ID */
+ UINT_32 iStringDescr;
+ /** Line in template */
+ UINT_32 iLine;
+ /** Line position */
+ UINT_32 iPos;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_DEBUG_INFO_HPP__
+// End.
diff --git a/include/CTPP2VMDumper.hpp b/include/CTPP2VMDumper.hpp
new file mode 100644
index 0000000..754ba1f
--- /dev/null
+++ b/include/CTPP2VMDumper.hpp
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMDumper.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_DUMPER_HPP__
+#define _CTPP2_VM_DUMPER_HPP__ 1
+
+#include "CTPP2VMMemoryCore.hpp"
+#include "CTPP2VMExecutable.hpp"
+
+/**
+ @file VMDumper.hpp
+ @brief Executable program core constructor
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class VMDumper VMDumper.hpp <VMDumper.hpp>
+ @brief Construct executable program core from source
+*/
+class CTPP2DECL VMDumper
+{
+public:
+ /**
+ @brief Constructor
+ @param oMemoryCore - ready-to-run memory core
+ */
+ VMDumper(const VMMemoryCore & oMemoryCore);
+
+ /**
+ @brief Constructor
+ @param iCodeSize - Code segment size
+ @param aInstructions - Code segment
+ @param oSyscalls - Syscalls segment
+ @param oStaticData - Static data segment
+ @param oStaticText - Static text segment
+ @param oHashTable - Hash table for "blocks"
+ */
+ VMDumper(const UINT_32 iCodeSize,
+ const VMInstruction * aInstructions,
+ const StaticText & oSyscalls,
+ const StaticData & oStaticData,
+ const StaticText & oStaticText,
+ const HashTable & oHashTable);
+
+ /**
+ @brief Get constructed executable
+ @param iExecutableSize - size of program [out]
+ @return pointer to program core
+ */
+ const VMExecutable * GetExecutable(UINT_32 & iExecutableSize);
+
+ /**
+ @brief A destructor
+ */
+ ~VMDumper();
+
+private:
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ VMDumper(const VMDumper & oRhs);
+
+ /**
+ @brief Operator =
+ @param oRhs - object to copy
+ */
+ VMDumper & operator=(const VMDumper & oRhs);
+
+ /** Size of program */
+ UINT_32 iVMExecutableSize;
+ /** Program core */
+ VMExecutable * oVMExecutable;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_LOADER_HPP__
+// End.
diff --git a/include/CTPP2VMException.hpp b/include/CTPP2VMException.hpp
new file mode 100644
index 0000000..d0f0318
--- /dev/null
+++ b/include/CTPP2VMException.hpp
@@ -0,0 +1,410 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMException.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_EXCEPTION_HPP__
+#define _CTPP2_VM_EXCEPTION_HPP__ 1
+
+#include "CTPP2Types.h"
+#include "CTPP2Exception.hpp"
+
+/**
+ @file CTPP2VMException.hpp
+ @brief Virtual machine exception
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class VMException CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Base class for all virtual machine exceptions.
+*/
+class CTPP2DECL VMException:
+ public CTPPException
+{
+public:
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ virtual UINT_32 GetIP() const throw() = 0;
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ virtual UINT_64 GetDebugInfo() const throw() = 0;
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw() = 0;
+
+ /** @brief A virtual destructor */
+ ~VMException() throw();
+
+private:
+ // Nothing
+};
+
+/**
+ @class IllegalOpcode CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Illegal operation code
+*/
+class CTPP2DECL IllegalOpcode:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIOpcode - illegal opcode
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ IllegalOpcode(const UINT_32 iIIP,
+ const UINT_32 iIOpcode,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get instruction code
+ @return Instruction pointer
+ */
+ UINT_32 GetOpcode() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+
+ /** @brief A virtual destructor */
+ ~IllegalOpcode() throw();
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Instruction pointer */
+ const UINT_32 iOpcode;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+};
+
+/**
+ @class InvalidSyscall CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Non-existent system call
+*/
+class CTPP2DECL InvalidSyscall:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param szISyscall - syscall name
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ InvalidSyscall(CCHAR_P szISyscall,
+ const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+ /** @brief A virtual destructor */
+ ~InvalidSyscall() throw();
+
+private:
+ /** System call */
+ CCHAR_P szSyscall;
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+
+};
+
+/**
+ @class CodeSegmentOverrun CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Overrun from code segment
+*/
+class CTPP2DECL CodeSegmentOverrun:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ CodeSegmentOverrun(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+ /** @brief A virtual destructor */
+ ~CodeSegmentOverrun() throw();
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+
+};
+
+/**
+ @class ExecutionLimitReached CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Execution limit reached (in steps)
+*/
+class CTPP2DECL ExecutionLimitReached:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ ExecutionLimitReached(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+ /** @brief A virtual destructor */
+ ~ExecutionLimitReached() throw();
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+
+};
+
+/**
+ @class ZeroDivision CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Execution limit reached (in steps)
+*/
+class CTPP2DECL ZeroDivision:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ ZeroDivision(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+ /** @brief A virtual destructor */
+ ~ZeroDivision() throw();
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+
+};
+
+/**
+ @class InvalidCall CTPP2VMException.hpp <CTPP2VMException.hpp>
+ @brief Invalid call name
+*/
+class CTPP2DECL InvalidCall:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szICallName - call name
+ @param szISourceName - source file name
+ */
+ InvalidCall(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szICallName,
+ CCHAR_P szISourceName);
+
+ /** @return A asciz string describing the general cause of error */
+ CCHAR_P what() const throw();
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ UINT_32 GetIP() const throw();
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ UINT_64 GetDebugInfo() const throw();
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw();
+
+ /** @brief A virtual destructor */
+ ~InvalidCall() throw();
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Call name */
+ CHAR_P szCallName;
+ /** Template source name */
+ CHAR_P szSourceName;
+};
+
+} // namespace CTPP
+#endif // _VM_EXCEPTION_HPP__
+// End.
diff --git a/include/CTPP2VMExecutable.hpp b/include/CTPP2VMExecutable.hpp
new file mode 100644
index 0000000..69ed7d4
--- /dev/null
+++ b/include/CTPP2VMExecutable.hpp
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMExecutable.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_EXECUTABLE_HPP__
+#define _CTPP2_VM_EXECUTABLE_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2VMExecutable.hpp
+ @brief Virtual machine executable file
+*/
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+struct VMInstruction;
+union StaticDataVar;
+struct TextDataIndex;
+struct BitIndexData;
+struct HashElement;
+
+/**
+ @struct VMExecutable CTPP2VMExecutable.hpp <CTPP2VMExecutable.hpp>
+ @brief CTPP Executable file
+*/
+struct VMExecutable
+{
+ /** CTPP magic number */
+ UCHAR_8 magic[4]; // 'CTPP' xor 0xFFFFFFFF
+
+ /** CTPP reserved fields */
+ CHAR_8 version[8];
+
+ /** Code entry point */
+ UINT_32 entry_point;
+ /** Offset of code segment */
+ UINT_32 code_offset;
+ /** Code segment size */
+ UINT_32 code_size;
+
+ /** Offset of static text segment */
+ UINT_32 syscalls_offset;
+ /** Static text segment size */
+ UINT_32 syscalls_data_size;
+
+ /** Offset of static text index segment */
+ UINT_32 syscalls_index_offset;
+ /** Static text index segment size */
+ UINT_32 syscalls_index_size;
+
+ /** Offset of static data segment */
+ UINT_32 static_data_offset;
+ /** Static data segment size */
+ UINT_32 static_data_data_size;
+
+ /** Offset of static text segment */
+ UINT_32 static_text_offset;
+ /** Static text segment size */
+ UINT_32 static_text_data_size;
+
+ /** Offset of static text index segment */
+ UINT_32 static_text_index_offset;
+ /** Static text index segment size */
+ UINT_32 static_text_index_size;
+
+ // Version 2.2+
+ /** Offset of static data bit index */
+ UINT_32 static_data_bit_index_offset;
+ // Version 2.2+
+ /** Offset of static data bit index */
+ UINT_32 static_data_bit_index_size;
+
+ /** Platform */
+ UINT_64 platform;
+ /** ieee 754 64-bit floating point value */
+ W_FLOAT ieee754double;
+ /** Cyclic Redundancy Check */
+ UINT_32 crc;
+
+ // Version 2.4+
+ /** Calls hash table offset */
+ UINT_32 calls_hash_table_offset;
+ /** Calls hash table size */
+ UINT_32 calls_hash_table_size;
+ /** Number of elements */
+ UINT_32 calls_hash_table_power;
+
+ /** Fix for alignment */
+ UINT_32 dummy;
+
+ /**
+ @brief Get start of code segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of code segment
+ */
+ static const VMInstruction * GetCodeSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of syscalls segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of data segment
+ */
+ static CCHAR_P GetSyscallsSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of syscalls index segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of data segment
+ */
+ static const TextDataIndex * GetSyscallsIndexSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of static data segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of data segment
+ */
+ static const StaticDataVar * GetStaticDataSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of static data bit index
+ @param oVMExecutable - core of executable file
+ @return pointer to start of text index segment
+ */
+ static const BitIndexData * GetStaticDataBitIndex(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of static text segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of text segment
+ */
+ static CCHAR_P GetStaticTextSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get start of static text index segment
+ @param oVMExecutable - core of executable file
+ @return pointer to start of text index segment
+ */
+ static const TextDataIndex * GetStaticTextIndexSeg(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get calls hash table
+ @param oVMExecutable - core of executable file
+ @return pointer to hash table
+ */
+ static const HashElement * GetCallsTable(const VMExecutable * oVMExecutable);
+
+ /**
+ @brief Get calls hash table size
+ @param oVMExecutable - core of executable file
+ @return Hash table size (in power of 2)
+ */
+ static UINT_32 GetCallsTablePower(const VMExecutable * oVMExecutable);
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_EXECUTABLE_HPP__
+// End.
diff --git a/include/CTPP2VMFileLoader.hpp b/include/CTPP2VMFileLoader.hpp
new file mode 100644
index 0000000..c6cd9db
--- /dev/null
+++ b/include/CTPP2VMFileLoader.hpp
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMFileLoader.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_FILE_LOADER_HPP__
+#define _CTPP2_VM_FILE_LOADER_HPP__ 1
+
+#include "CTPP2VMLoader.hpp"
+
+/**
+ @file VMFileLoader.hpp
+ @brief Load program core from file
+*/
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+struct VMExecutable;
+
+/**
+ @class VMFileLoader CTPP2VMFileLoader.hpp <CTPP2VMFileLoader.hpp>
+ @brief Load program core from file
+*/
+class CTPP2DECL VMFileLoader:
+ public VMLoader
+{
+public:
+ /**
+ */
+ VMFileLoader(CCHAR_P szFile);
+ /**
+ @brief Get ready-to-run program
+ */
+ const VMMemoryCore * GetCore() const;
+
+ /**
+ @brief A destructor
+ */
+ ~VMFileLoader() throw();
+private:
+ /** Program core */
+ VMExecutable * oCore;
+ /** Ready-to-run program */
+ VMMemoryCore * pVMMemoryCore;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_FILE_LOADER_HPP__
+// End.
diff --git a/include/CTPP2VMInstruction.hpp b/include/CTPP2VMInstruction.hpp
new file mode 100644
index 0000000..3d41e6a
--- /dev/null
+++ b/include/CTPP2VMInstruction.hpp
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMInstruction.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_INSTRUCTION_HPP__
+#define _CTPP2_VM_INSTRUCTION_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2VMInstruction.hpp
+ @brief Virtual machine instruction
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @struct VMInstruction CTPP2VMInstruction.hpp <CTPP2VMInstruction.hpp>
+ @brief Virtual machine instruction
+*/
+struct VMInstruction
+{
+ /** Instruction opcode */
+ UINT_32 instruction;
+ /** Argument */
+ UINT_32 argument;
+ /** Reserved field for debugging purposes */
+ UINT_64 reserved;
+};
+
+inline VMInstruction CreateInstruction(const UINT_32 iInstruction,
+ const UINT_32 iArgument,
+ const UINT_64 iReserved)
+{
+ VMInstruction oVMInstruction = { iInstruction, iArgument, iReserved };
+
+return oVMInstruction;
+}
+
+} // namespace CTPP
+#endif // _CTPP2_VM_INSTRUCTION_HPP__
+// End.
diff --git a/include/CTPP2VMLoader.hpp b/include/CTPP2VMLoader.hpp
new file mode 100644
index 0000000..7197af7
--- /dev/null
+++ b/include/CTPP2VMLoader.hpp
@@ -0,0 +1,70 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMLoader.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_LOADER_HPP__
+#define _CTPP2_VM_LOADER_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2VMLoader.hpp
+ @brief Load program core
+*/
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+struct VMMemoryCore;
+
+/**
+ @class VMLoader CTPP2VMLoader.hpp <CTPP2VMLoader.hpp>
+ @brief Program loader
+*/
+class CTPP2DECL VMLoader
+{
+public:
+
+ /**
+ @brief Get ready-to-run program
+ */
+ virtual const VMMemoryCore * GetCore() const = 0;
+
+ /**
+ @brief A destructor
+ */
+ virtual ~VMLoader() throw() { ;; }
+private:
+
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_LOADER_HPP__
+// End.
diff --git a/include/CTPP2VMMemoryCore.hpp b/include/CTPP2VMMemoryCore.hpp
new file mode 100644
index 0000000..fd1e254
--- /dev/null
+++ b/include/CTPP2VMMemoryCore.hpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMMemoryCore.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_MEMORY_CORE_HPP__
+#define _CTPP2_VM_MEMORY_CORE_HPP__ 1
+
+#include "CTPP2HashTable.hpp"
+#include "CTPP2StaticData.hpp"
+#include "CTPP2StaticText.hpp"
+#include "CTPP2BitIndex.hpp"
+
+/**
+ @file CTPP2VMMemoryCore.hpp
+ @brief Virtual machine ready-to-run memory core of executable file
+*/
+
+namespace CTPP // C++ Template Engine
+{
+// FWD
+struct VMExecutable;
+struct VMInstruction;
+
+/**
+ @struct VMMemoryCore VMMemoryCore.hpp <VMMemoryCore.HPP>
+ @brief CTPP ready-to-run memory core
+*/
+struct CTPP2DECL VMMemoryCore
+{
+ /**
+ @brief Constructor pVMExecutable - image of program
+ */
+ VMMemoryCore(const VMExecutable * pVMExecutable);
+
+ /** Code segment size */
+ const UINT_32 code_size;
+ /** Code segment */
+ const VMInstruction * instructions;
+ /** Syscalls segment */
+ const ReducedStaticText syscalls;
+ /** Static data segment */
+ const ReducedStaticData static_data;
+ /** Static text segment */
+ const ReducedStaticText static_text;
+ /** Static data bit index */
+ const ReducedBitIndex bit_index;
+ /** Table with syscalls */
+ const ReducedHashTable calls_table;
+ /** System calls translation map */
+ INT_32 * syscall_map;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_MEMORY_CORE_HPP__
+// End.
diff --git a/include/CTPP2VMOpcodeCollector.hpp b/include/CTPP2VMOpcodeCollector.hpp
new file mode 100644
index 0000000..0139f63
--- /dev/null
+++ b/include/CTPP2VMOpcodeCollector.hpp
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMOpcodeCollector.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_OPCODE_COLLECTOR_H__
+#define _CTPP2_VM_OPCODE_COLLECTOR_H__ 1
+
+#include "CTPP2VMInstruction.hpp"
+
+#include "STLVector.hpp"
+
+/**
+ @file CTPP2VMOpcodeCollector.hpp
+ @brief Collector of generated operation codes
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class VMOpcodeCollector VMOpcodeCollector.hpp <VMOpcodeCollector.hpp>
+ @brief Collector of generated operation codes
+*/
+class CTPP2DECL VMOpcodeCollector
+{
+public:
+
+ /**
+ @brief Remove instruction from top of code segment
+ @return last instruction position
+ */
+ INT_32 Remove();
+
+ /**
+ @brief Insert instruction into code segment
+ @param oInstruction - instruction to insert
+ @return instruction position
+ */
+ INT_32 Insert(const VMInstruction & oInstruction);
+
+ /**
+ @brief Get instruction by instruction number
+ @param iIP - instruction number
+ @return pointer to instruction or NULL if instruction does not exist
+ */
+ VMInstruction * GetInstruction(const UINT_32 & iIP);
+
+ /**
+ @brief Get last instruction number
+ */
+ UINT_32 GetCodeSize() const;
+
+ /**
+ @param iCodeSize - dize of code segment [out]
+ @return code segment
+ */
+ const VMInstruction * GetCode(UINT_32 & iCodeSize);
+
+ /**
+ @brief A destructor
+ */
+ ~VMOpcodeCollector() throw();
+private:
+ /** Code segment */
+ STLW::vector<VMInstruction> oCodeSeg;
+};
+
+} // namespace CTPP
+#endif // _VM_OPCODE_COLLECTOR_H__
+// End.
diff --git a/include/CTPP2VMOpcodes.h b/include/CTPP2VMOpcodes.h
new file mode 100644
index 0000000..4e133e7
--- /dev/null
+++ b/include/CTPP2VMOpcodes.h
@@ -0,0 +1,199 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMOpcodes.h
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_OPCODES_H__
+#define _CTPP2_VM_OPCODES_H__ 1
+
+#include "CTPP2Types.h"
+
+// Version 3
+#define VM_OPCODE_VERSION 0x00000003
+
+/**
+ @file CTPP2VMOpcodes.h
+ @brief Virtual machine operation codes
+*/
+
+// Stop machine ////////////////////////////////////////////////////////////////////////////////////
+#define HLT 0xFF000000 // Halt
+#define BRK 0xFF010000 // Breakpoint
+#define NOP 0xFF020000 // No operation
+
+// Instructions //////// 0x-1-X---- ////////////////////////////////////////////////////////////////
+// 0000 000X YYYY YYYY
+#define SYSCALL 0x01010000 // System call
+#define CALLNAME 0x01020000 // Call procedure by name
+#define CALLIND 0x01030000 // Call procedure by name given in regsiter or stack (indirect)
+
+#define CALL 0x01040000 // Procedure call
+#define RET 0x01050000 // Return from procedure
+#define JMP 0x01060000 // Unconditional jump
+#define LOOP 0x01070000 // Loop
+
+#define RCALL 0x01140000 // Procedure call, relational version
+#define RJMP 0x01160000 // Unconditional jump, relational version
+#define RLOOP_OBSOLETE 0x01170000 // Loop, relational version
+
+// Stack operations //// 0x-2-X---- ////////////////////////////////////////////////////////////////
+#define PUSH 0x02010000 // Push value into stack
+#define POP 0x02020000 // Pop value from stack
+
+#define PUSH13 0x02030000 // Push AR, BR, CR, DR registers into stack
+#define POP13 0x02040000 // Pop AR, BR, CR, DR registers from stack
+
+#define PUSH47 0x02050000 // Push ER, FR, GR, HR registers into stack
+#define POP47 0x02060000 // Pop ER, FR, GR, HR registers from stack
+
+#define PUSHA 0x02070000 // Push ALL registers into stack
+#define POPA 0x02080000 // Pop ALL registers from stack
+
+// Arithmetic ops. ///// 0x-3-X---- ////////////////////////////////////////////////////////////////
+#define ADD 0x03010000 // Add values
+#define SUB 0x03020000 // Substract values
+#define MUL 0x03030000 // Multiplicate values
+#define DIV 0x03040000 // Divide values
+#define INC 0x03050000 // Increment value
+#define DEC 0x03060000 // Decrement value
+#define IDIV 0x03070000 // Integer division
+#define MOD 0x03080000 // Divide two numbers and returns only the remainder
+#define NEG 0x03090000 // Negate
+#define NOT 0x030A0000 // Logical negation
+
+// String ops. ///////// 0x-3X----- ////////////////////////////////////////////////////////////////
+#define CONCAT 0x03100000 // Concatenate strings
+
+// Register ops. /////// 0x-4------ /////////////////////////////////////////////////////////////////
+#define MOV 0x04010000 // Move value (register-to-register and stack-to-register)
+#define MOVIINT 0x04020000 // Move indirect ARRAY to register
+#define MOVISTR 0x04030000 // Move indirect HASH to register
+#define IMOVINT 0x04040000 // Move register to indirect ARRAY
+#define IMOVSTR 0x04050000 // Move register to indirect HASH
+#define MOVSIZE 0x04060000 // Move size of array or hash to register
+#define MOVIREGI 0x04070000 // Move indirect ARRAY from REGISTER pointed by REGISTER to another register
+#define MOVIREGS 0x04080000 // Move indirect HASH from REGISTER pointed by REGISTER to another register
+
+// Comparison ops. ///// 0x-5-X---- //////////////////////////////////////////////////////////////////
+#define CMP 0x05010000 // Compare values, arithmetic
+#define SCMP 0x05020000 // Compare values, strging
+
+// Comparison flags //// 0x000X0000 //////////////////////////////////////////////////////////////////
+#define FL_NE 0x00010000 // Not Equal, NO flags
+#define FL_EQ 0x00020000 // Equal
+#define FL_LT 0x00040000 // Less
+#define FL_GT 0x00080000 // Greater
+#define FL_PF 0x00100000 // Parity flag
+#define FL_NPF 0x00200000 // NOT Parity flag
+
+// Conditional ops.1 /// 0x-6-X---- //////////////////////////////////////////////////////////////////
+#define JXX 0x06000000 // Conditional jump, generic
+#define JN (JXX | FL_NE) // Jump if !=
+#define JL (JXX | FL_LT) // Jump if <
+#define JG (JXX | FL_GT) // Jump if >
+#define JE (JXX | FL_EQ) // Jump if ==
+#define JLE (JL | JE) // Jump if <=
+#define JGE (JG | JE) // Jump if >=
+
+#define JEVEN (JXX | FL_PF) // Jump if Result is Even
+#define JODD (JXX | FL_NPF) // Jump if Result is ODD
+
+// Conditional ops.2 /// 0x-7-X---- //////////////////////////////////////////////////////////////////
+#define RJXX 0x07000000 // Conditional jump, relational version
+#define RJN (RJXX | FL_NE) // Jump if !=
+#define RJL (RJXX | FL_LT) // Jump if <
+#define RJG (RJXX | FL_GT) // Jump if >
+#define RJE (RJXX | FL_EQ) // Jump if ==
+#define RJLE (RJL | RJE) // Jump if <=
+#define RJGE (RJG | RJE) // Jump if >=
+
+#define RJEVEN (RJXX | FL_PF) // Jump if Result is Even
+#define RJODD (RJXX | FL_NPF) // Jump if Result is ODD
+
+// Other ops. ////////// 0x-8-X---- ////////////////////////////////////////////////////////////////
+#define CLEAR 0x08010000 // Clear register
+#define OUTPUT 0x08020000 // Direct output a value to output collector
+#define REPLACE 0x08030000 // Replace variable in stack or register
+#define EXIST 0x08040000 // Check existence of operand
+#define REPLINT 0x08050000 // Replace ARRAY variable in stack with it's element
+#define REPLSTR 0x08060000 // Replace HASH variable in stack with it's element
+#define XCHG 0x08070000 // Swap 2 values
+#define DEFINED 0x08080000 // Check undef value
+#define SAVEBP 0x08090000 // Save base pointer
+#define RESTBP 0x080A0000 // Restore base pointer
+#define REPLIND 0x080B0000 // Replace ARRAY/HASH variable in stack with it's element
+
+// Sources ///////////// 0x-------X //////////////////////////////////////////////////////////////////
+#define ARG_SRC_AR 0x00000000 // AR is source register
+#define ARG_SRC_BR 0x00000001 // BR is source register
+#define ARG_SRC_CR 0x00000002 // CR is source register
+#define ARG_SRC_DR 0x00000003 // DR is source register
+#define ARG_SRC_ER 0x00000004 // ER is source register
+#define ARG_SRC_FR 0x00000005 // FR is source register
+#define ARG_SRC_GR 0x00000006 // GR is source register
+#define ARG_SRC_HR 0x00000007 // HR is source register
+
+#define ARG_SRC_LASTREG ARG_SRC_HR // Last regsiter is HR
+
+#define ARG_SRC_STACK 0x00000010 // Stack value is source
+#define ARG_SRC_IND_VAL 0x00000011 // Stack value is indirect array value is source
+#define ARG_SRC_IND_STR 0x00000012 // Stack value is indirect hash value is source
+#define ARG_SRC_INT 0x00000013 // Integer value from static data segment is source
+#define ARG_SRC_FLOAT 0x00000014 // Float value from static data segment is source
+#define ARG_SRC_STR 0x00000015 // String value from static text segment is source
+
+
+// Destinations //////// 0x-----X-- /////////////////////////////////////////////////////
+#define ARG_DST_AR 0x00000000 // AR is destination register
+#define ARG_DST_BR 0x00000100 // BR is destination register
+#define ARG_DST_CR 0x00000200 // CR is destination register
+#define ARG_DST_DR 0x00000300 // DR is destination register
+#define ARG_DST_ER 0x00000400 // ER is destination register
+#define ARG_DST_FR 0x00000500 // FR is destination register
+#define ARG_DST_GR 0x00000600 // GR is destination register
+#define ARG_DST_HR 0x00000700 // HR is destination register
+
+#define ARG_DST_LASTREG ARG_DST_HR // Last regsiter is HR
+
+#define ARG_DST_STACK 0x00001000 // Top of Stack value is destination
+#define ARG_DST_IND_VAL 0x00001100 // Stack value is indirect array value is destination
+#define ARG_DST_IND_STR 0x00001200 // Stack value is indirect hash value is destination
+
+#define SYSCALL_PARAMS(x, y) ( (UINT_32(x << 16) & 0xFFFF0000) | (UINT_32(y) & 0x0000FFFF) )
+
+#define SYSCALL_OPCODE(x) ((UINT_32(x) >> 16) & 0x0000FFFF)
+
+#define SYSCALL_OPCODE_HI(x) ((UINT_32(x) >> 24) & 0x000000FF)
+#define SYSCALL_OPCODE_LO(x) ((UINT_32(x) >> 16) & 0x000000FF)
+
+#define SYSCALL_REG_DST(x) ((UINT_32(x) ) & 0x0000FF00)
+#define SYSCALL_REG_SRC(x) (UINT_32(x) & 0x000000FF)
+
+#endif // _CTPP2_VM_OPCODES_H__
+// End.
diff --git a/include/CTPP2VMSTDLib.hpp b/include/CTPP2VMSTDLib.hpp
new file mode 100644
index 0000000..3af16cd
--- /dev/null
+++ b/include/CTPP2VMSTDLib.hpp
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMSTDLib.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_STDLIB_HPP__
+#define _CTPP2_VM_STDLIB_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file CTPP2VMSTDLib.hpp
+ @brief Virtual machine standard library initializer
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+// FWD
+class SyscallFactory;
+
+/**
+ @class STDLibInitializer CTPP2VMSTDLib.hpp <CTPP2VMSTDLib.hpp>
+ @brief Initializer for standard library
+*/
+class CTPP2DECL STDLibInitializer
+{
+public:
+ /**
+ @brief Get list of available functions
+ @return NULL-rerminated list
+ */
+ static CCHAR_P * GetFnList();
+
+ /**
+ @brief Initialize all functions in library
+ @param oSyscallFactory - object factory
+ */
+ static void InitLibrary(SyscallFactory & oSyscallFactory);
+
+ /**
+ @brief Destroy all functions in library
+ @param oSyscallFactory - object factory
+ */
+ static void DestroyLibrary(SyscallFactory & oSyscallFactory);
+
+ /**
+ @brief Create handler
+ @param szHandler - function name
+ @return new object of CTPP2 function
+ */
+ static SyscallHandler * CreateHandler(CCHAR_P szHandler);
+
+ /**
+ @brief Create handler
+ @param pHandler - function object
+ @return new object of CTPP2 function
+ */
+ static void DestroyHandler(SyscallHandler * pHandler);
+private:
+
+ /** List of functions */
+ static CCHAR_P aSTDFNList[];
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_STDLIB_HPP__
+// End.
diff --git a/include/CTPP2VMStackException.hpp b/include/CTPP2VMStackException.hpp
new file mode 100644
index 0000000..9627958
--- /dev/null
+++ b/include/CTPP2VMStackException.hpp
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMStackException.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_STACK_EXCEPTION_HPP__
+#define _CTPP2_VM_STACK_EXCEPTION_HPP__ 1
+
+#include "CTPP2VMException.hpp"
+
+/**
+ @file VMStackException.hpp
+ @brief Virtual machine stack exceptions
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ @class StackOverflow CTPP2VMStackException.hpp <CTPP2VMStackException.hpp>
+ @brief Stack overflow error
+*/
+class StackOverflow:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ inline StackOverflow(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo = 0,
+ CCHAR_P szISourceName = NULL): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(NULL)
+ {
+ if (szISourceName != NULL) { szSourceName = strdup(szISourceName); }
+ }
+
+
+ /** @return A asciz string describing the general cause of error */
+ inline CCHAR_P what() const throw() { return "Stack overflow"; }
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ inline UINT_32 GetIP() const throw() { return iIP; }
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ inline UINT_64 GetDebugInfo() const throw() { return iDebugInfo; }
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw() { return szSourceName; }
+
+ /** @brief A destructor */
+ inline ~StackOverflow() throw()
+ {
+ free(szSourceName);
+ }
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+};
+
+/**
+ @class StackUnderflow CTPP2VMStackException.hpp <CTPP2VMStackException.hpp>
+ @brief Stack underflow; throws when pop method called on empty stack
+*/
+class StackUnderflow:
+ public VMException
+{
+public:
+ /**
+ @brief Constructor
+ @param iIIP - instruction pointer
+ @param iIDebugInfo - debug information
+ @param szISourceName - source file name
+ */
+ inline StackUnderflow(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo = 0,
+ CCHAR_P szISourceName = NULL): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(NULL)
+ {
+ if (szISourceName != NULL) { szSourceName = strdup(szISourceName); }
+ }
+
+
+ /** @return A asciz string describing the general cause of error */
+ inline CCHAR_P what() const throw() { return "Stack underflow"; }
+
+ /**
+ @brief Get instruction pointer
+ @return Instruction pointer
+ */
+ inline UINT_32 GetIP() const throw() { return iIP; }
+
+ /**
+ @brief Get debug information
+ @return Packed VMDebugInfo object
+ */
+ inline UINT_64 GetDebugInfo() const throw() { return iDebugInfo; }
+
+ /**
+ @brief Get name of template
+ @return Template name, asciz string
+ */
+ virtual CCHAR_P GetSourceName() const throw() { return szSourceName; }
+
+ /** @brief A destructor */
+ inline ~StackUnderflow() throw()
+ {
+ free(szSourceName);
+ }
+
+private:
+ /** Instruction pointer */
+ const UINT_32 iIP;
+ /** Debug information */
+ const UINT_64 iDebugInfo;
+ /** Template source name */
+ CHAR_P szSourceName;
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_STACK_EXCEPTION_HPP__
+// End.
diff --git a/include/CTPP2VMSyscall.hpp b/include/CTPP2VMSyscall.hpp
new file mode 100644
index 0000000..8c54cf4
--- /dev/null
+++ b/include/CTPP2VMSyscall.hpp
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMSyscall.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_SYSCALL_HPP__
+#define _CTPP2_VM_SYSCALL_HPP__ 1
+
+#include "CTPP2Types.h"
+
+/**
+ @file CTPP2VMSyscall.hpp
+ @brief Virtual machine system calls
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+#define CTPP2_INT_HANDLER_PREFIX "__ctpp2"
+
+// FWD
+class CDT;
+class OutputCollector;
+class ReducedStaticText;
+class ReducedStaticData;
+class Logger;
+
+/**
+ @class SyscallHandler CTPP2VMSyscall.hpp <CTPP2VMSyscall.hpp>
+ @brief Base class of CTPP2 functions
+*/
+class CTPP2DECL SyscallHandler
+{
+public:
+ /**
+ @brief Global Handler initialization
+ @param oCDT - initial data
+ @return 0 - if success, -1 - if any error occured
+ */
+ virtual INT_32 InitHandler(CDT & oCDT);
+
+ /**
+ @brief Pre-execution handler setup
+ @param oCollector - output data collector
+ @param oCDT - CTPP2 parameters
+ @param oSyscalls - Syscalls segment
+ @param oStaticData - Static data segment
+ @param oStaticText - Static text segment
+ @return 0 - if success, -1 - if any error occured
+ */
+ virtual INT_32 PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ virtual INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger) = 0;
+
+ /**
+ @brief Get function name
+ */
+ virtual CCHAR_P GetName() const = 0;
+
+ /**
+ @brief Get API version
+ */
+ virtual INT_32 GetVersion() const;
+
+ /**
+ @brief Handler resources destructor
+ @param oCDT - data, same of in InitHandler
+ @return 0 - if success, -1 - if any erro occured
+ */
+ virtual INT_32 DestroyHandler(CDT & oCDT) throw();
+
+ /**
+ @brief A destructor
+ */
+ virtual ~SyscallHandler() throw();
+};
+
+} // namespace CTPP
+#endif // _CTPP2_VM_SYSCALL_HPP__
+// End.
diff --git a/include/STLException.hpp b/include/STLException.hpp
new file mode 100644
index 0000000..607330c
--- /dev/null
+++ b/include/STLException.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLException.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_EXCEPTION_HPP__
+#define _STL_EXCEPTION_HPP__ 1
+
+/**
+ @file STLException.hpp
+ @brief Wrapper for STL exceptions
+*/
+#include <exception>
+#include <stdexcept>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_EXCEPTION_HPP__
+// End.
diff --git a/include/STLFunctional.hpp b/include/STLFunctional.hpp
new file mode 100644
index 0000000..2aa3def
--- /dev/null
+++ b/include/STLFunctional.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLFunctional.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_FUNCTIONAL_HPP__
+#define _STL_FUNCTIONAL_HPP__ 1
+
+/**
+ @file STLFunctional.hpp
+ @brief Wrapper for STL algorithms
+*/
+#include <functional>
+#include <algorithm>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_FUNCTIONAL_HPP__
+// End.
diff --git a/include/STLIosfwd.hpp b/include/STLIosfwd.hpp
new file mode 100644
index 0000000..677a341
--- /dev/null
+++ b/include/STLIosfwd.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLIosfwd.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_IOSFWD_HPP__
+#define _STL_IOSFWD_HPP__ 1
+
+/**
+ @file STLIosfwd.hpp
+ @brief Wrapper for STL iosfwd routines
+*/
+#include <iosfwd>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_IOSFWD_HPP__
+// End.
+
diff --git a/include/STLMap.hpp b/include/STLMap.hpp
new file mode 100644
index 0000000..e38cba2
--- /dev/null
+++ b/include/STLMap.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLMap.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_MAP_HPP__
+#define _STL_MAP_HPP__ 1
+
+/**
+ @file STLMap.hpp
+ @brief Wrapper for STL class std::map
+*/
+#include <map>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_MAP_HPP__
+// End.
+
diff --git a/include/STLOstream.hpp b/include/STLOstream.hpp
new file mode 100644
index 0000000..c9237b8
--- /dev/null
+++ b/include/STLOstream.hpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLOstream.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_OSTREAM_HPP__
+#define _STL_OSTREAM_HPP__ 1
+
+/**
+ @file STLOstream.hpp
+ @brief Wrapper for STL outout stream
+*/
+#include <ostream>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_OSTREAM_HPP__
+// End.
+
diff --git a/include/STLPair.hpp b/include/STLPair.hpp
new file mode 100644
index 0000000..3fadee9
--- /dev/null
+++ b/include/STLPair.hpp
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLString.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_PAIR_HPP__
+#define _STL_PAIR_HPP__ 1
+
+/**
+ @file STLPair.hpp
+ @brief Wrapper for STL class std::pair
+*/
+#include <utility>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_PAIR_HPP__
+// End.
diff --git a/include/STLString.hpp b/include/STLString.hpp
new file mode 100644
index 0000000..88d1ac9
--- /dev/null
+++ b/include/STLString.hpp
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLString.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_STRING_HPP__
+#define _STL_STRING_HPP__ 1
+
+/**
+ @file STLString.hpp
+ @brief Wrapper for STL class std::string
+*/
+#include <string>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_STRING_HPP__
+// End.
diff --git a/include/STLVector.hpp b/include/STLVector.hpp
new file mode 100644
index 0000000..088c8be
--- /dev/null
+++ b/include/STLVector.hpp
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2005 - 2011 CAS Dev Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CAS Dev. Team 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 REGENTS 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 REGENTS 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.
+ *
+ * STLVector.hpp
+ *
+ * $CAS$
+ */
+#ifndef _STL_VECTOR_HPP__
+#define _STL_VECTOR_HPP__ 1
+
+/**
+ @file STLVector.hpp
+ @brief Wrapper for STL class std::vector
+*/
+#include <vector>
+
+#ifndef STLW
+ #ifndef NO_STL_STD_NS_PREFIX
+ #define STLW std
+ #else
+ #define STLW
+ #endif // NO_STL_STD_NS_PREFIX
+#endif // STLW
+
+#endif // _STL_VECTOR_HPP__
+// End.
diff --git a/include/functions/CTPP2VMSTDLibFunctions.hpp b/include/functions/CTPP2VMSTDLibFunctions.hpp
new file mode 100644
index 0000000..6cc43ea
--- /dev/null
+++ b/include/functions/CTPP2VMSTDLibFunctions.hpp
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMSTDLibFunctions.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _CTPP2_VM_STDLIB_FUNCTIONS_HPP__
+#define _CTPP2_VM_STDLIB_FUNCTIONS_HPP__ 1
+
+/**
+ @file CTPP2VMSTDLibFunctions.hpp
+ @brief Virtual machine standard library functions
+*/
+
+#include "FnAvg.hpp"
+#include "FnBase64Decode.hpp"
+#include "FnBase64Encode.hpp"
+#include "FnCast.hpp"
+#include "FnConcat.hpp"
+#include "FnContext.hpp"
+#include "FnDateFormat.hpp"
+#include "FnDefault.hpp"
+#include "FnDefined.hpp"
+#include "FnEmitter.hpp"
+#include "FnError.hpp"
+#include "FnFormParam.hpp"
+#include "FnGetText.hpp"
+#include "FnGetType.hpp"
+#include "FnHashKeys.hpp"
+
+#ifdef MD5_SUPPORT
+#include "FnHMACMD5.hpp"
+#endif // MD5_SUPPORT
+
+#include "FnHostname.hpp"
+#include "FnHTMLEscape.hpp"
+#include "FnHrefParam.hpp"
+
+#ifdef ICONV_SUPPORT
+#include "FnIconv.hpp"
+#endif // ICONV_SUPPORT
+
+#include "FnInSet.hpp"
+#include "FnInArray.hpp"
+#include "FnJSONEscape.hpp"
+#include "FnJSON.hpp"
+#include "FnList.hpp"
+#include "FnListElement.hpp"
+#include "FnLog.hpp"
+#include "FnMBSize.hpp"
+#include "FnMBSubstring.hpp"
+#include "FnMBTruncate.hpp"
+
+#ifdef MD5_SUPPORT
+#include "FnMD5.hpp"
+#endif // MD5_SUPPORT
+
+#include "FnMax.hpp"
+#include "FnMin.hpp"
+#include "FnNumFormat.hpp"
+#include "FnObjDump.hpp"
+#include "FnRandom.hpp"
+#include "FnSize.hpp"
+#include "FnSprintf.hpp"
+#include "FnSubstring.hpp"
+#include "FnTruncate.hpp"
+#include "FnURIEscape.hpp"
+#include "FnURLEscape.hpp"
+#include "FnVersion.hpp"
+#include "FnWMLEscape.hpp"
+#include "FnXMLEscape.hpp"
+
+#endif // _CTPP2_VM_STDLIB_FUNCTIONS_HPP__
+// End.
diff --git a/include/functions/FnAvg.hpp b/include/functions/FnAvg.hpp
new file mode 100644
index 0000000..13f33f2
--- /dev/null
+++ b/include/functions/FnAvg.hpp
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnAvg.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_AVG_HPP__
+#define _FN_AVG_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnAvg.hpp
+ @brief Virtual machine standard library function, average of given values, see http://en.wikipedia.org/wiki/Average
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnAvg FnAvg.hpp <FnAvg.hpp>
+ @brief Average of given values, see http://en.wikipedia.org/wiki/Average
+*/
+class FnAvg:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnAvg() throw();
+
+private:
+ friend class STDLibInitializer;
+
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnAvg();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnAvg(const FnAvg & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnAvg & operator =(const FnAvg & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_AVG_HPP__
+// End.
diff --git a/include/functions/FnBase64Decode.hpp b/include/functions/FnBase64Decode.hpp
new file mode 100644
index 0000000..ff8a139
--- /dev/null
+++ b/include/functions/FnBase64Decode.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnBase64Decode.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_BASE64_DECODE_HPP__
+#define _FN_BASE64_DECODE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnBase64Decode.hpp
+ @brief Virtual machine standard library function, Base64 decoder
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnBase64Decode FnBase64Decode.hpp <FnBase64Decode.hpp>
+ @brief Base64 encoder
+*/
+class FnBase64Decode:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnBase64Decode();
+
+ /**
+ @brief A destructor
+ */
+ ~FnBase64Decode() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_BASE64_DECODE_HPP__
+// End.
diff --git a/include/functions/FnBase64Encode.hpp b/include/functions/FnBase64Encode.hpp
new file mode 100644
index 0000000..a74b0dc
--- /dev/null
+++ b/include/functions/FnBase64Encode.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnBase64Encode.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_BASE64_ENCODE_HPP__
+#define _FN_BASE64_ENCODE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnBase64Encode.hpp
+ @brief Virtual machine standard library function, Base64 encoder
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnBase64Encode FnBase64Encode.hpp <FnBase64Encode.hpp>
+ @brief Base64 encoder
+*/
+class FnBase64Encode:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnBase64Encode();
+
+ /**
+ @brief A destructor
+ */
+ ~FnBase64Encode() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_BASE64_ENCODE_HPP__
+// End.
diff --git a/include/functions/FnCast.hpp b/include/functions/FnCast.hpp
new file mode 100644
index 0000000..23b935c
--- /dev/null
+++ b/include/functions/FnCast.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnCast.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_CAST_HPP__
+#define _FN_CAST_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnCast.hpp
+ @brief Virtual machine standard library function, cast to specified type
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnCast FnCast.hpp <FnCast.hpp>
+ @brief Cast to specified type
+*/
+class FnCast:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnCast();
+
+ /**
+ @brief A destructor
+ */
+ ~FnCast() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_CAST_HPP__
+// End.
diff --git a/include/functions/FnConcat.hpp b/include/functions/FnConcat.hpp
new file mode 100644
index 0000000..446c05d
--- /dev/null
+++ b/include/functions/FnConcat.hpp
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnConcat.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_CONCAT_HPP__
+#define _VM_FN_CONCAT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnConcat.hpp
+ @brief Virtual machine standard library function, concatenate strings
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnConcat FnConcat.hpp <FnConcat.hpp>
+ @brief Concatenate two or more strings
+*/
+class FnConcat:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnConcat() throw();
+
+private:
+ friend class STDLibInitializer;
+
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnConcat();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnConcat(const FnConcat & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnConcat & operator =(const FnConcat & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_CONCAT_HPP__
+// End.
diff --git a/include/functions/FnContext.hpp b/include/functions/FnContext.hpp
new file mode 100644
index 0000000..be8c052
--- /dev/null
+++ b/include/functions/FnContext.hpp
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnContext.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_CONTEXT_HPP__
+#define _FN_CONTEXT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnContext.hpp
+ @brief Virtual machine standard library function, get all variables
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnContext FnContext.hpp <FnContext.hpp>
+ @brief Dump variables
+*/
+class FnContext:
+ public SyscallHandler
+{
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Constructor
+ */
+ FnContext();
+
+ /**
+ @brief A destructor
+ */
+ ~FnContext() throw();
+
+ /**
+ @brief Pre-execution handler setup
+ @param oCollector - output data collector
+ @param oCDT - CTPP2 parameters
+ @param oSyscalls - Syscalls segment
+ @param oStaticData - Static data segment
+ @param oStaticText - Static text segment
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+ /** Global data object */
+ CDT * pCDT;
+};
+
+} // namespace CTPP
+#endif // _FN_CONTEXT_HPP__
+// End.
diff --git a/include/functions/FnDateFormat.hpp b/include/functions/FnDateFormat.hpp
new file mode 100644
index 0000000..2e91b65
--- /dev/null
+++ b/include/functions/FnDateFormat.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDateFormat.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_DATE_FORMAT_HPP__
+#define _FN_DATE_FORMAT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnDateFormat.hpp
+ @brief Virtual machine standard library function, date formatting function
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnDateFormat FnDateFormat.hpp <FnDateFormat.hpp>
+ @brief Date formatting function
+*/
+class FnDateFormat:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnDateFormat();
+
+ /**
+ @brief A destructor
+ */
+ ~FnDateFormat() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_DATE_FORMAT_HPP__
+// End.
diff --git a/include/functions/FnDefault.hpp b/include/functions/FnDefault.hpp
new file mode 100644
index 0000000..be158ca
--- /dev/null
+++ b/include/functions/FnDefault.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDefault.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_DEFAULT_HPP__
+#define _FN_DEFAULT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnDefault.hpp
+ @brief Virtual machine standard library function, get default value
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnDefault FnDefault.hpp <FnDefault.hpp>
+ @brief Get default value
+*/
+class FnDefault:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnDefault();
+
+ /**
+ @brief A destructor
+ */
+ ~FnDefault() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_DEFAULT_HPP__
+// End.
diff --git a/include/functions/FnDefined.hpp b/include/functions/FnDefined.hpp
new file mode 100644
index 0000000..9c26c60
--- /dev/null
+++ b/include/functions/FnDefined.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDefined.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_DEFINED_HPP__
+#define _FN_DEFINED_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnDefined.hpp
+ @brief Virtual machine standard library function, check UNDEF type
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnDefined FnDefined.hpp <FnDefined.hpp>
+ @brief Check UNDEF type
+*/
+class FnDefined:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnDefined();
+
+ /**
+ @brief A destructor
+ */
+ ~FnDefined() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_DEFINED_HPP__
+// End.
diff --git a/include/functions/FnEmitter.hpp b/include/functions/FnEmitter.hpp
new file mode 100644
index 0000000..31115f3
--- /dev/null
+++ b/include/functions/FnEmitter.hpp
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnEmitter.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_EMITTER_HPP__
+#define _FN_EMITTER_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnEmitter.hpp
+ @brief Virtual machine standard library function, truncate string to specified size
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnEmitter VMSTDLibFunctions.hpp <VMSTDLibFunctions.hpp>
+ @brief Emit CDT variables into virual machine
+*/
+class FnEmitter:
+ public SyscallHandler
+{
+public:
+ /**
+ @brief A destructor
+ */
+ ~FnEmitter() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /** Global CDT object */
+ CDT * pCDT;
+
+ /**
+ @brief Constructor
+ */
+ FnEmitter();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnEmitter(const FnEmitter & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnEmitter & operator =(const FnEmitter & oRhs);
+
+ /**
+ @brief Pre-execution handler setup
+ @param oCollector - output data collector
+ @param oCDT - CTPP2 parameters
+ @param oSyscalls - Syscalls segment
+ @param oStaticData - Static data segment
+ @param oStaticText - Static text segment
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger);
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_EMITTER_HPP__
+// End.
diff --git a/include/functions/FnError.hpp b/include/functions/FnError.hpp
new file mode 100644
index 0000000..54da5a5
--- /dev/null
+++ b/include/functions/FnError.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnError.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_ERROR_HPP__
+#define _FN_ERROR_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnError.hpp
+ @brief Virtual machine standard library function, permanent error (only for VM testing)
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnError FnError.hpp <FnError.hpp>
+ @brief Permanent error (only for VM testing)
+*/
+class FnError:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnError();
+
+ /**
+ @brief A destructor
+ */
+ ~FnError() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_ERROR_HPP__
+// End.
diff --git a/include/functions/FnFormParam.hpp b/include/functions/FnFormParam.hpp
new file mode 100644
index 0000000..674c3ef
--- /dev/null
+++ b/include/functions/FnFormParam.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnFormParam.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_FORM_PARAM_HPP__
+#define _FN_FORM_PARAM_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnFormParam.hpp
+ @brief Virtual machine standard library function, format hidden field for HTML form
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnFormParam FnFormParam.hpp <FnFormParam.hpp>
+ @brief Format hidden field for HTML form
+*/
+class FnFormParam:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnFormParam();
+
+ /**
+ @brief A destructor
+ */
+ ~FnFormParam() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_FORM_PARAM_HPP__
+// End.
diff --git a/include/functions/FnGetText.hpp b/include/functions/FnGetText.hpp
new file mode 100644
index 0000000..05d9a1d
--- /dev/null
+++ b/include/functions/FnGetText.hpp
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnGetText.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_GET_TEXT_HPP__
+#define _FN_GET_TEXT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnGetText.hpp
+ @brief Virtual machine standard library function, localization support
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+class CTPP2GetText;
+
+/**
+ @class FnGetText FnGetText.hpp <FnGetText.hpp>
+ @brief Localization support
+*/
+class FnGetText:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnGetText(CCHAR_P szAlias = "gettext");
+
+ /**
+ @brief A destructor
+ */
+ ~FnGetText() throw();
+
+private:
+ friend class STDLibInitializer;
+ friend class CTPP2GetText;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+ /**
+ @brief Set GetText object
+ @param gettext - GetText object
+ */
+ void SetGetText(CTPP2GetText * pGetText);
+
+ /**
+ @brief Set language of translation
+ @param sLang - language
+ */
+ void SetLanguage(const STLW::string & sLang);
+
+ /** GetText pointer */
+ CTPP2GetText * pGetText;
+
+ /** Language of translation */
+ STLW::string sLanguage;
+
+ /** Name of function */
+ CHAR_P szFuncName;
+};
+
+} // namespace CTPP
+#endif // _FN_GET_TEXT_HPP__
+// End.
diff --git a/include/functions/FnGetType.hpp b/include/functions/FnGetType.hpp
new file mode 100644
index 0000000..026b3cc
--- /dev/null
+++ b/include/functions/FnGetType.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnGetType.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_GET_TYPE_HPP__
+#define _FN_GET_TYPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnGetType.hpp
+ @brief Virtual machine standard library function, get variable type
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnGetType FnGetType.hpp <FnGetType.hpp>
+ @brief Get variable type
+*/
+class FnGetType:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnGetType();
+
+ /**
+ @brief A destructor
+ */
+ ~FnGetType() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_GET_TYPE_HPP__
+// End.
diff --git a/include/functions/FnHMACMD5.hpp b/include/functions/FnHMACMD5.hpp
new file mode 100644
index 0000000..09a997f
--- /dev/null
+++ b/include/functions/FnHMACMD5.hpp
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHMACMD5.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_HMAC_MD5_HPP__
+#define _FN_HMAC_MD5_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+#ifdef WIN32
+ #include <windows.h>
+ #include <wincrypt.h>
+#endif
+
+/**
+ @file FnHMACMD5.hpp
+ @brief Virtual machine standard library function, HMAC MD5 Hash support
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+#ifdef MD5_SUPPORT
+/**
+ @class FnHMACMD5 FnHMACMD5.hpp <FnHMACMD5.hpp>
+ @brief HMAC MD5 Hash support
+*/
+class FnHMACMD5:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnHMACMD5();
+
+ /**
+ @brief A destructor
+ */
+ ~FnHMACMD5() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+#ifdef WIN32
+ /** @brief Win32 CryptoAPI provider handle */
+ HCRYPTPROV hCryptProv;
+#endif
+};
+
+#endif // MD5_SUPPORT
+} // namespace CTPP
+#endif // _FN_HMAC_MD5_HPP__
+// End.
diff --git a/include/functions/FnHTMLEscape.hpp b/include/functions/FnHTMLEscape.hpp
new file mode 100644
index 0000000..3ef3bd6
--- /dev/null
+++ b/include/functions/FnHTMLEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHTMLEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_HTMLESCAPE_HPP__
+#define _FN_HTMLESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnHTMLEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://www.w3.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnHTMLEscape FnHTMLEscape.hpp <FnHTMLEscape.hpp>
+ @brief Escape value, see http://www.w3.org/
+*/
+class FnHTMLEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnHTMLEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnHTMLEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_HTMLESCAPE_HPP__
+// End.
diff --git a/include/functions/FnHashKeys.hpp b/include/functions/FnHashKeys.hpp
new file mode 100644
index 0000000..88977c7
--- /dev/null
+++ b/include/functions/FnHashKeys.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHashKeys.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_HASH_KEYS_HPP__
+#define _FN_HASH_KEYS_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnHashKeys.hpp
+ @brief Virtual machine standard library function, search element in given array
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnHashKeys FnHashKeys.hpp <FnHashKeys.hpp>
+ @brief Search element in given list of elements
+*/
+class FnHashKeys:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnHashKeys();
+
+ /**
+ @brief A destructor
+ */
+ ~FnHashKeys() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_HASH_KEYS_HPP__
+// End.
diff --git a/include/functions/FnHostname.hpp b/include/functions/FnHostname.hpp
new file mode 100644
index 0000000..7a21a0b
--- /dev/null
+++ b/include/functions/FnHostname.hpp
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHostname.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_HOSTNAME_HPP__
+#define _FN_HOSTNAME_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+#include "STLString.hpp"
+
+/**
+ @file FnHostname.hpp
+ @brief Get host name
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnHostname FnHostname.hpp <FnHostname.hpp>
+ @brief Get host name
+*/
+class FnHostname:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnHostname();
+
+ /**
+ @brief A destructor
+ */
+ ~FnHostname() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /** Host name */
+ STLW::string sHostName;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_HOSTNAME_HPP__
+// End.
diff --git a/include/functions/FnHrefParam.hpp b/include/functions/FnHrefParam.hpp
new file mode 100644
index 0000000..92676bf
--- /dev/null
+++ b/include/functions/FnHrefParam.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHrefParam.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_HREF_PARAM_HPP__
+#define _FN_HREF_PARAM_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnHrefParam.hpp
+ @brief Virtual machine standard library function, link reference parameter
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnHrefParam FnHrefParam.hpp <FnHrefParam.hpp>
+ @brief Link reference parameter
+*/
+class FnHrefParam:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnHrefParam();
+
+ /**
+ @brief A destructor
+ */
+ ~FnHrefParam() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_HREF_PARAM_HPP__
+// End.
diff --git a/include/functions/FnIconv.hpp b/include/functions/FnIconv.hpp
new file mode 100644
index 0000000..39c4e20
--- /dev/null
+++ b/include/functions/FnIconv.hpp
@@ -0,0 +1,103 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnIconv.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_ICONV_HPP__
+#define _FN_ICONV_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+#ifdef ICONV_SUPPORT
+#include <iconv.h>
+#endif // ICONV_SUPPORT
+
+#include "STLMap.hpp"
+#include "STLString.hpp"
+
+/**
+ @file FnIconv.hpp
+ @brief Virtual machine standard library function, escape value, iconv converter
+*/
+
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+#ifdef ICONV_SUPPORT
+/**
+ @class FnIconv FnIconv.hpp <FnIconv.hpp>
+ @brief Iconv converter
+*/
+class CTPP2DECL FnIconv:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnIconv();
+
+ /**
+ @brief A destructor
+ */
+ ~FnIconv() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+ /** Charsets */
+ STLW::map<STLW::string, iconv_t> mIconvMap;
+};
+
+#endif // ICONV_SUPPORT
+
+} // namespace CTPP
+#endif // _FN_ICONV_HPP__
+// End.
diff --git a/include/functions/FnInArray.hpp b/include/functions/FnInArray.hpp
new file mode 100644
index 0000000..2641aa8
--- /dev/null
+++ b/include/functions/FnInArray.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnInArray.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_IN_ARRAY_HPP__
+#define _FN_IN_ARRAY_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnInArray.hpp
+ @brief Virtual machine standard library function, search element in given array
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnInArray FnInArray.hpp <FnInArray.hpp>
+ @brief Search element in given list of elements
+*/
+class CTPP2DECL FnInArray:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnInArray();
+
+ /**
+ @brief A destructor
+ */
+ ~FnInArray() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_IN_ARRAY_HPP__
+// End.
diff --git a/include/functions/FnInSet.hpp b/include/functions/FnInSet.hpp
new file mode 100644
index 0000000..4acab55
--- /dev/null
+++ b/include/functions/FnInSet.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnInSet.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_IN_SET_HPP__
+#define _FN_IN_SET_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnInSet.hpp
+ @brief Virtual machine standard library function, search element in given list of elements
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnInSet FnInSet.hpp <FnInSet.hpp>
+ @brief Search element in given list of elements
+*/
+class FnInSet:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnInSet();
+
+ /**
+ @brief A destructor
+ */
+ ~FnInSet() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_IN_SET_HPP__
+// End.
diff --git a/include/functions/FnJSON.hpp b/include/functions/FnJSON.hpp
new file mode 100644
index 0000000..6c6db84
--- /dev/null
+++ b/include/functions/FnJSON.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnJSON.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_JSON_HPP__
+#define _FN_JSON_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnJSON.hpp
+ @brief Virtual machine standard library function, JSON output
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnJSON FnJSON.hpp <FnJSON.hpp>
+ @brief JSON output
+*/
+class FnJSON:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnJSON();
+
+ /**
+ @brief A destructor
+ */
+ ~FnJSON() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_JSON_HPP__
+// End.
diff --git a/include/functions/FnJSONEscape.hpp b/include/functions/FnJSONEscape.hpp
new file mode 100644
index 0000000..ddbf682
--- /dev/null
+++ b/include/functions/FnJSONEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnJSONEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_JSON_ESCAPE_HPP__
+#define _FN_JSON_ESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnJSONEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://json.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnJSONEscape FnJSONEscape.hpp <FnJSONEscape.hpp>
+ @brief Escape value, see http://json.org/
+*/
+class FnJSONEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnJSONEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnJSONEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_JSON_ESCAPE_HPP__
+// End.
diff --git a/include/functions/FnList.hpp b/include/functions/FnList.hpp
new file mode 100644
index 0000000..4f790a3
--- /dev/null
+++ b/include/functions/FnList.hpp
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnList.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_LIST_HPP__
+#define _VM_FN_LIST_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnList.hpp
+ @brief Virtual machine standard library function, return a list of elements
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnList VMSTDLibFunctions.hpp <VMSTDLibFunctions.hpp>
+ @brief Get element of specified data set
+*/
+class FnList:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnList() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnList();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnList(const FnList & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnList & operator =(const FnList & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_LIST_HPP__
+// End.
diff --git a/include/functions/FnListElement.hpp b/include/functions/FnListElement.hpp
new file mode 100644
index 0000000..a03af58
--- /dev/null
+++ b/include/functions/FnListElement.hpp
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnListElement.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_LIST_ELEMENT_HPP__
+#define _VM_FN_LIST_ELEMENT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnListElement.hpp
+ @brief Virtual machine standard library function, get element of specified data set
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnListElement VMSTDLibFunctions.hpp <VMSTDLibFunctions.hpp>
+ @brief Get element of specified data set
+*/
+class FnListElement:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnListElement() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnListElement();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnListElement(const FnListElement & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnListElement & operator =(const FnListElement & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_LIST_ELEMENT_HPP__
+// End.
diff --git a/include/functions/FnLog.hpp b/include/functions/FnLog.hpp
new file mode 100644
index 0000000..a7ae379
--- /dev/null
+++ b/include/functions/FnLog.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnLog.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_LOG_HPP__
+#define _FN_LOG_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnLog.hpp
+ @brief Virtual machine standard library function, logarithm, natural and with specified base
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnLog FnLog.hpp <FnLog.hpp>
+ @brief Logarithm, natural and with specified base
+*/
+class FnLog:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnLog();
+
+ /**
+ @brief A destructor
+ */
+ ~FnLog() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_LOG_HPP__
+// End.
diff --git a/include/functions/FnMBSize.hpp b/include/functions/FnMBSize.hpp
new file mode 100644
index 0000000..d208afb
--- /dev/null
+++ b/include/functions/FnMBSize.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMBSize.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_MB_SIZE_HPP__
+#define _FN_MB_SIZE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnMBSize.hpp
+ @brief Virtual machine standard library function, get size of UTF-8 string
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnMBSize FnMBSize.hpp <FnMBSize.hpp>
+ @brief Get size of UTF-8 string
+*/
+class FnMBSize:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnMBSize();
+
+ /**
+ @brief A destructor
+ */
+ ~FnMBSize() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_MB_SIZE_HPP__
+// End.
diff --git a/include/functions/FnMBSubstring.hpp b/include/functions/FnMBSubstring.hpp
new file mode 100644
index 0000000..c96eeef
--- /dev/null
+++ b/include/functions/FnMBSubstring.hpp
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMBSubstring.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_MB_SUBSTRING_HPP__
+#define _VM_FN_MB_SUBSTRING_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnListElement.hpp
+ @brief Virtual machine standard library function, get element of specified data set
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnMBSubstring VMSTDLibFunctions.hpp <VMSTDLibFunctions.hpp>
+ @brief Substring of given string and replacement of part of string
+*/
+class FnMBSubstring:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnMBSubstring() throw();
+
+private:
+ friend class STDLibInitializer;
+
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnMBSubstring();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnMBSubstring(const FnMBSubstring & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnMBSubstring & operator =(const FnMBSubstring & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_MB_SUBSTRING_HPP__
+// End.
diff --git a/include/functions/FnMBTruncate.hpp b/include/functions/FnMBTruncate.hpp
new file mode 100644
index 0000000..d73d526
--- /dev/null
+++ b/include/functions/FnMBTruncate.hpp
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMBTruncate.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_MB_TRUNCATE_HPP__
+#define _VM_FN_MB_TRUNCATE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnMBTruncate.hpp
+ @brief Virtual machine standard library function, truncate string to specified size
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnMBTruncate FnMBTruncate.hpp <FnMBTruncate.hpp>
+ @brief Truncate string to specified size
+*/
+class FnMBTruncate:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnMBTruncate() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnMBTruncate();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnMBTruncate(const FnMBTruncate & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnMBTruncate & operator =(const FnMBTruncate & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_MB_TRUNCATE_HPP__
+// End.
diff --git a/include/functions/FnMD5.hpp b/include/functions/FnMD5.hpp
new file mode 100644
index 0000000..16ba10a
--- /dev/null
+++ b/include/functions/FnMD5.hpp
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMD5.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_MD5_HPP__
+#define _FN_MD5_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+#ifdef WIN32
+ #include <windows.h>
+ #include <wincrypt.h>
+#endif
+
+/**
+ @file FnMD5.hpp
+ @brief Virtual machine standard library function, MD5 Hash support
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+#ifdef MD5_SUPPORT
+/**
+ @class FnMD5 FnMD5.hpp <FnMD5.hpp>
+ @brief MD5 Hash support
+*/
+class FnMD5:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnMD5();
+
+ /**
+ @brief A destructor
+ */
+ ~FnMD5() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+#ifdef WIN32
+ /** @brief Win32 CryptoAPI provider handle */
+ HCRYPTPROV hCryptProv;
+#endif
+};
+#endif // MD5_SUPPORT
+
+} // namespace CTPP
+#endif // _FN_MD5_HPP__
+// End.
diff --git a/include/functions/FnMax.hpp b/include/functions/FnMax.hpp
new file mode 100644
index 0000000..237bf7c
--- /dev/null
+++ b/include/functions/FnMax.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMax.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_MAX_HPP__
+#define _FN_MAX_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnMax.hpp
+ @brief Virtual machine standard library function, minimum of given values
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnMax FnMax.hpp <FnMax.hpp>
+ @brief Maximum of given values
+*/
+class FnMax:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnMax();
+
+ /**
+ @brief A destructor
+ */
+ ~FnMax() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_MAX_HPP__
+// End.
diff --git a/include/functions/FnMin.hpp b/include/functions/FnMin.hpp
new file mode 100644
index 0000000..8d2a4a3
--- /dev/null
+++ b/include/functions/FnMin.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMin.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_MIN_HPP__
+#define _FN_MIN_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnMin.hpp
+ @brief Virtual machine standard library function, minimum of given values
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnMin FnMin.hpp <FnMin.hpp>
+ @brief Minimum of given values
+*/
+class FnMin:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnMin();
+
+ /**
+ @brief A destructor
+ */
+ ~FnMin() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_MIN_HPP__
+// End.
diff --git a/include/functions/FnNumFormat.hpp b/include/functions/FnNumFormat.hpp
new file mode 100644
index 0000000..95fa9e1
--- /dev/null
+++ b/include/functions/FnNumFormat.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnNumFormat.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_NUM_FORMAT_HPP__
+#define _FN_NUM_FORMAT_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnNumFormat.hpp
+ @brief Virtual machine standard library function, format number
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnNumFormat FnNumFormat.hpp <FnNumFormat.hpp>
+ @brief Format number
+*/
+class FnNumFormat:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnNumFormat();
+
+ /**
+ @brief A destructor
+ */
+ ~FnNumFormat() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_NUM_FORMAT_HPP__
+// End.
diff --git a/include/functions/FnObjDump.hpp b/include/functions/FnObjDump.hpp
new file mode 100644
index 0000000..fece5fd
--- /dev/null
+++ b/include/functions/FnObjDump.hpp
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnObjDump.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_OBJ_DUMP_HPP__
+#define _FN_OBJ_DUMP_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnObjDump.hpp
+ @brief Virtual machine standard library function, dump variables
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnObjDump FnObjDump.hpp <FnObjDump.hpp>
+ @brief Dump variables
+*/
+class FnObjDump:
+ public SyscallHandler
+{
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Constructor
+ */
+ FnObjDump();
+
+ /**
+ @brief A destructor
+ */
+ ~FnObjDump() throw();
+
+ /**
+ @brief Pre-execution handler setup
+ @param oCollector - output data collector
+ @param oCDT - CTPP2 parameters
+ @param oSyscalls - Syscalls segment
+ @param oStaticData - Static data segment
+ @param oStaticText - Static text segment
+ @return 0 - if success, -1 - if any error occured
+ */
+ INT_32 PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+
+ /** Global data object */
+ CDT * pCDT;
+};
+
+} // namespace CTPP
+#endif // _FN_OBJ_DUMP_HPP__
+// End.
diff --git a/include/functions/FnRandom.hpp b/include/functions/FnRandom.hpp
new file mode 100644
index 0000000..6d05f58
--- /dev/null
+++ b/include/functions/FnRandom.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnRandom.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_RANDOM_HPP__
+#define _FN_RANDOM_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnRandom.hpp
+ @brief Virtual machine standard library function, random number generator
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnRandom FnRandom.hpp <FnRandom.hpp>
+ @brief Random number generator
+*/
+class FnRandom:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnRandom();
+
+ /**
+ @brief A destructor
+ */
+ ~FnRandom() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_RANDOM_HPP__
+// End.
diff --git a/include/functions/FnSize.hpp b/include/functions/FnSize.hpp
new file mode 100644
index 0000000..8bfa14e
--- /dev/null
+++ b/include/functions/FnSize.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSize.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_SIZE_HPP__
+#define _FN_SIZE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnSize.hpp
+ @brief Virtual machine standard library function, get string, array or hash size
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnSize FnSize.hpp <FnSize.hpp>
+ @brief Get string, array or hash size
+*/
+class FnSize:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnSize();
+
+ /**
+ @brief A destructor
+ */
+ ~FnSize() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_SIZE_HPP__
+// End.
diff --git a/include/functions/FnSprintf.hpp b/include/functions/FnSprintf.hpp
new file mode 100644
index 0000000..6beda62
--- /dev/null
+++ b/include/functions/FnSprintf.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSprintf.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_SPRINTF_HPP__
+#define _FN_SPRINTF_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnSprintf.hpp
+ @brief Virtual machine standard library function, get string, array or hash size
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnSprintf FnSprintf.hpp <FnSprintf.hpp>
+ @brief Get string, array or hash size
+*/
+class FnSprintf:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnSprintf();
+
+ /**
+ @brief A destructor
+ */
+ ~FnSprintf() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_SPRINTF_HPP__
+// End.
diff --git a/include/functions/FnSubstring.hpp b/include/functions/FnSubstring.hpp
new file mode 100644
index 0000000..18819d2
--- /dev/null
+++ b/include/functions/FnSubstring.hpp
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSubstring.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_SUBSTRING_HPP__
+#define _VM_FN_SUBSTRING_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnSubstring.hpp
+ @brief Virtual machine standard library function, get ubstring of given string and/or replacement of part of string
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnSubstring FnSubstring.hpp <FnSubstring.hpp>
+ @brief Substring of given string and replacement of part of string
+*/
+class FnSubstring:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnSubstring() throw();
+
+private:
+ friend class STDLibInitializer;
+
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnSubstring();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnSubstring(const FnSubstring & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnSubstring & operator =(const FnSubstring & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_SUBSTRING_HPP__
+// End.
diff --git a/include/functions/FnTruncate.hpp b/include/functions/FnTruncate.hpp
new file mode 100644
index 0000000..8163a19
--- /dev/null
+++ b/include/functions/FnTruncate.hpp
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnTruncate.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _VM_FN_TRUNCATE_HPP__
+#define _VM_FN_TRUNCATE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnTruncate.hpp
+ @brief Virtual machine standard library function, truncate string to specified size
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnTruncate FnTruncate.hpp <FnTruncate.hpp>
+ @brief Truncate string to specified size
+*/
+class FnTruncate:
+ public SyscallHandler
+{
+ /**
+ @brief A destructor
+ */
+ ~FnTruncate() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /** Ouput data collector */
+ OutputCollector * pCollector;
+
+ // ///////////////////////////////////////////////////////////////
+
+ /**
+ @brief Constructor
+ */
+ FnTruncate();
+
+ /**
+ @brief Copy constructor
+ @param oRhs - object to copy
+ */
+ FnTruncate(const FnTruncate & oRhs);
+
+ /**
+ @brief Copy operator =
+ @param oRhs - object to copy
+ */
+ FnTruncate & operator =(const FnTruncate & oRhs);
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _VM_FN_TRUNCATE_HPP__
+// End.
diff --git a/include/functions/FnURIEscape.hpp b/include/functions/FnURIEscape.hpp
new file mode 100644
index 0000000..8ff23a6
--- /dev/null
+++ b/include/functions/FnURIEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnURIEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_URIESCAPE_HPP__
+#define _FN_URIESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnURIEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://www.w3.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnURIEscape FnURIEscape.hpp <FnURIEscape.hpp>
+ @brief Escape value, see http://www.w3.org/
+*/
+class FnURIEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnURIEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnURIEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_URIESCAPE_HPP__
+// End.
diff --git a/include/functions/FnURLEscape.hpp b/include/functions/FnURLEscape.hpp
new file mode 100644
index 0000000..b628a90
--- /dev/null
+++ b/include/functions/FnURLEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnURLEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_URLESCAPE_HPP__
+#define _FN_URLESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnURLEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://www.w3.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnURLEscape FnURLEscape.hpp <FnURLEscape.hpp>
+ @brief Escape value, see http://www.w3.org/
+*/
+class FnURLEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnURLEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnURLEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_URLESCAPE_HPP__
+// End.
diff --git a/include/functions/FnVersion.hpp b/include/functions/FnVersion.hpp
new file mode 100644
index 0000000..289a632
--- /dev/null
+++ b/include/functions/FnVersion.hpp
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnVersion.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_VERSION_HPP__
+#define _FN_VERSION_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnVersion.hpp
+ @brief Virtual machine standard library function, get version of CTPP2 and CTPP2 standard library
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+
+/**
+ @class FnVersion FnVersion.hpp <FnVersion.hpp>
+ @brief Get version of CTPP2 and CTPP2 standard library
+*/
+class FnVersion:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnVersion();
+
+ /**
+ @brief A destructor
+ */
+ ~FnVersion() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_VERSION_HPP__
+// End.
diff --git a/include/functions/FnWMLEscape.hpp b/include/functions/FnWMLEscape.hpp
new file mode 100644
index 0000000..5a74642
--- /dev/null
+++ b/include/functions/FnWMLEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnWMLEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_WMLESCAPE_HPP__
+#define _FN_WMLESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnWMLEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://xml.w3.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnWMLEscape FnWMLEscape.hpp <FnWMLEscape.hpp>
+ @brief Escape value, see http://xml.w3.org/
+*/
+class FnWMLEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnWMLEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnWMLEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_WMLESCAPE_HPP__
+// End.
diff --git a/include/functions/FnXMLEscape.hpp b/include/functions/FnXMLEscape.hpp
new file mode 100644
index 0000000..3e4808c
--- /dev/null
+++ b/include/functions/FnXMLEscape.hpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnXMLEscape.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _FN_XMLESCAPE_HPP__
+#define _FN_XMLESCAPE_HPP__ 1
+
+#include "CTPP2VMSyscall.hpp"
+
+/**
+ @file FnXMLEscape.hpp
+ @brief Virtual machine standard library function, escape value, see http://www.w3.org/
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+class CDT;
+class Logger;
+
+/**
+ @class FnXMLEscape FnXMLEscape.hpp <FnXMLEscape.hpp>
+ @brief Escape value, see http://www.w3.org/
+*/
+class FnXMLEscape:
+ public SyscallHandler
+{
+ /**
+ @brief Constructor
+ */
+ FnXMLEscape();
+
+ /**
+ @brief A destructor
+ */
+ ~FnXMLEscape() throw();
+
+private:
+ friend class STDLibInitializer;
+
+ /**
+ @brief Handler
+ @param aArguments - list of arguments
+ @param iArgNum - number of arguments
+ @param oCDTRetVal - return value
+ @param oLogger - logger
+ @return 0 - if success, -1 - otherwise
+ */
+ INT_32 Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger);
+
+ /**
+ @brief Get function name
+ */
+ CCHAR_P GetName() const;
+};
+
+} // namespace CTPP
+#endif // _FN_XMLESCAPE_HPP__
+// End.
diff --git a/include/libgen_win32.h b/include/libgen_win32.h
new file mode 100644
index 0000000..64320fc
--- /dev/null
+++ b/include/libgen_win32.h
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.hpp
+ *
+ * $CTPP$
+ */
+#ifndef _LIBGEN_WIN32_HPP__
+#define _LIBGEN_WIN32_HPP__ 1
+
+#if defined _MSC_VER
+# define HAS_DEVICE(P) \
+((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \
+&& (P)[1] == ':')
+# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0)
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#endif
+
+#ifndef FILESYSTEM_PREFIX_LEN
+# define FILESYSTEM_PREFIX_LEN(Filename) 0
+#endif
+
+#ifndef ISSLASH
+# define ISSLASH(C) ((C) == '/')
+#endif
+
+char *basename(char const *name)
+{
+ char const *base = name += FILESYSTEM_PREFIX_LEN(name);
+ int all_slashes = 1;
+ char const *p;
+
+ for (p = name; *p; p++)
+ {
+ if (ISSLASH (*p))
+ {
+ base = p + 1;
+ }
+ else
+ {
+ all_slashes = 0;
+ }
+ }
+
+ /* If NAME is all slashes, arrange to return `/'. */
+ if (*base == '\0' && ISSLASH(*name) && all_slashes)
+ {
+ --base;
+ }
+
+ return (char*)base;
+}
+
+#endif //_LIBGEN_WIN32_HPP__
+// End.
+
diff --git a/man/ctpp2-config.1 b/man/ctpp2-config.1
new file mode 100644
index 0000000..373d7ca
--- /dev/null
+++ b/man/ctpp2-config.1
@@ -0,0 +1,86 @@
+.\"-
+.\" Copyright (c) 2004 - 2010 CTPP Team
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+.\"
+.Dd Jun 15, 2010
+.Dt CTPP2-CONFIG 1 1
+.Os "CTPP Dev. Team"
+.Sh NAME
+.Nm ctpp2-config
+.Nd CTPP configuration tool
+.Sh SYNOPSIS
+.Nm
+.Op Ar --version
+.Op Ar --flags
+.Op Ar --cc
+.Op Ar --cxx
+.Op Ar --make
+.Op Ar --libs
+.Op Ar --includes
+.Op Ar --includes2
+.Sh DESCRIPTION
+.Nm
+parses data in JSON format from file
+.Ar source.json
+and prints result to standard output.
+.Bl -tag -width indent
+.It Fl -version
+print the ctpp2 version number
+.It Fl -flags
+print C++ compiler flags
+.It Fl -cc
+print executable name of C compiler
+.It Fl -cxx
+print executable name of C++ compiler
+.It Fl -make
+print executable name of make
+.It Fl -libs
+print displays list of libraries
+.It Fl -includes
+print list of include dirs
+.It Fl -includes2
+print list of include dirs with '-I' prefixes
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr ctpp2c 1 ,
+.Xr ctpp2vm 1 ,
+.Xr ctpp2i 1 ,
+.Xr ctpp2json 1
+.Sh HISTORY
+An
+.Nm
+command appeared in CTPP 2.0.0.
+.Sh AUTHOR
+Written by Andrei V. Shetuhin <reki@reki.ru>
+.Sh "REPORTING BUGS"
+Report bugs to <reki@reki.ru>.
+.Sh WEBSITE
+http://ctpp.havoc.ru/en/ - in English
+
+http://ctpp.havoc.ru/ - for Russian speakers
+.Sh COPYRIGHT
+Copyright \(co 2004 \- 2010 CTPP Dev. Team. \ No newline at end of file
diff --git a/man/ctpp2c.1 b/man/ctpp2c.1
new file mode 100644
index 0000000..96fa385
--- /dev/null
+++ b/man/ctpp2c.1
@@ -0,0 +1,66 @@
+.\"-
+.\" Copyright (c) 2004 - 2010 CTPP Team
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+.\"
+.Dd Jun 15, 2010
+.Dt CTPP2C 1 1
+.Os "CTPP Dev. Team"
+.Sh NAME
+.Nm ctpp2c
+.Nd CTPP template compiler
+.Sh SYNOPSIS
+.Nm
+.Ar source.tmpl
+.Ar executable.ct2
+.Sh DESCRIPTION
+.Nm
+compiles template source file
+.Ar source.tmpl
+and saves result to
+.Ar executable.ct2
+.Pp
+Currently only 2 arguments supported: name of source template and name of destination bytecode file.
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr ctpp2i 1 ,
+.Xr ctpp2vm 1 ,
+.Xr ctpp2json 1 ,
+.Xr ctpp2-config 1 ,
+.Sh HISTORY
+An
+.Nm
+command appeared in CTPP 2.0.0.
+.Sh AUTHOR
+Written by Andrei V. Shetuhin <reki@reki.ru>
+.Sh "REPORTING BUGS"
+Report bugs to <reki@reki.ru>.
+.Sh WEBSITE
+http://ctpp.havoc.ru/en/ - in English
+
+http://ctpp.havoc.ru/ - for Russian speakers
+.Sh COPYRIGHT
+Copyright \(co 2004 \- 2010 CTPP Dev. Team. \ No newline at end of file
diff --git a/man/ctpp2i.1 b/man/ctpp2i.1
new file mode 100644
index 0000000..bb1ea47
--- /dev/null
+++ b/man/ctpp2i.1
@@ -0,0 +1,76 @@
+.\"-
+.\" Copyright (c) 2004 - 2010 CTPP Team
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+.\"
+.Dd Jun 15, 2010
+.Dt CTPP2I 1 1
+.Os "CTPP Dev. Team"
+.Sh NAME
+.Nm ctpp2i
+.Nd CTPP template iterpreter
+.Sh SYNOPSIS
+.Nm
+.Ar source.tmpl
+.Op Ar data.json
+.Op Ar translation.mo | 0
+.Op Ar limit of steps
+.Sh DESCRIPTION
+.Nm
+interpretes template source file
+.Ar source.tmpl
+and prints result to standard output.
+.Pp
+.Ar data.json
+,
+.Ar translation.mo
+and
+.Ar limit of steps
+are optional parameters.
+.Pp
+Use 0 instead
+.Ar translation.mo
+for ignoring gettext binary file.
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr ctpp2c 1 ,
+.Xr ctpp2vm 1 ,
+.Xr ctpp2json 1 ,
+.Xr ctpp2-config 1 ,
+.Sh HISTORY
+An
+.Nm
+command appeared in CTPP 2.0.0.
+.Sh AUTHOR
+Written by Andrei V. Shetuhin <reki@reki.ru>
+.Sh "REPORTING BUGS"
+Report bugs to <reki@reki.ru>.
+.Sh WEBSITE
+http://ctpp.havoc.ru/en/ - in English
+
+http://ctpp.havoc.ru/ - for Russian speakers
+.Sh COPYRIGHT
+Copyright \(co 2004 \- 2010 CTPP Dev. Team.
diff --git a/man/ctpp2json.1 b/man/ctpp2json.1
new file mode 100644
index 0000000..f2c5aeb
--- /dev/null
+++ b/man/ctpp2json.1
@@ -0,0 +1,62 @@
+.\"-
+.\" Copyright (c) 2004 - 2010 CTPP Team
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+.\"
+.Dd Jun 15, 2010
+.Dt CTPP2JSON 1 1
+.Os "CTPP Dev. Team"
+.Sh NAME
+.Nm ctpp2json
+.Nd CTPP JSON file parser
+.Sh SYNOPSIS
+.Nm
+.Ar source.json
+.Sh DESCRIPTION
+.Nm
+parses data in JSON format from file
+.Ar source.json
+and prints result to standard output.
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr ctpp2c 1 ,
+.Xr ctpp2vm 1 ,
+.Xr ctpp2i 1 ,
+.Xr ctpp2-config 1
+.Sh HISTORY
+An
+.Nm
+command appeared in CTPP 2.0.0.
+.Sh AUTHOR
+Written by Andrei V. Shetuhin <reki@reki.ru>
+.Sh "REPORTING BUGS"
+Report bugs to <reki@reki.ru>.
+.Sh WEBSITE
+http://ctpp.havoc.ru/en/ - in English
+
+http://ctpp.havoc.ru/ - for Russian speakers
+.Sh COPYRIGHT
+Copyright \(co 2004 \- 2010 CTPP Dev. Team. \ No newline at end of file
diff --git a/man/ctpp2vm.1 b/man/ctpp2vm.1
new file mode 100644
index 0000000..d558e24
--- /dev/null
+++ b/man/ctpp2vm.1
@@ -0,0 +1,76 @@
+.\"-
+.\" Copyright (c) 2004 - 2010 CTPP Team
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+.\"
+.Dd Jun 15, 2010
+.Dt CTPP2VM 1 1
+.Os "CTPP Dev. Team"
+.Sh NAME
+.Nm ctpp2vm
+.Nd CTPP virtual machine
+.Sh SYNOPSIS
+.Nm
+.Ar bytecode.ct2
+.Op Ar data.json
+.Op Ar translation.mo | 0
+.Op Ar limit of steps
+.Sh DESCRIPTION
+.Nm
+executes bytecode file
+.Ar bytecode.ct2
+and prints result to standard output.
+.Pp
+.Ar data.json
+,
+.Ar translation.mo
+and
+.Ar limit of steps
+are optional parameters.
+.Pp
+Use 0 instead
+.Ar translation.mo
+for ignoring gettext binary file.
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr ctpp2c 1 ,
+.Xr ctpp2i 1 ,
+.Xr ctpp2json 1 ,
+.Xr ctpp2-config 1 ,
+.Sh HISTORY
+An
+.Nm
+command appeared in CTPP 2.0.0.
+.Sh AUTHOR
+Written by Andrei V. Shetuhin <reki@reki.ru>
+.Sh "REPORTING BUGS"
+Report bugs to <reki@reki.ru>.
+.Sh WEBSITE
+http://ctpp.havoc.ru/en/ - in English
+
+http://ctpp.havoc.ru/ - for Russian speakers
+.Sh COPYRIGHT
+Copyright \(co 2004 \- 2010 CTPP Dev. Team.
diff --git a/multithread/CTPP2MT.cpp b/multithread/CTPP2MT.cpp
new file mode 100644
index 0000000..6f6f01e
--- /dev/null
+++ b/multithread/CTPP2MT.cpp
@@ -0,0 +1,184 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2MT.cpp
+ *
+ * $CTPP$
+ */
+#include <pthread.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "CTPP2FileLogger.hpp"
+
+#include "CTPP2StringOutputCollector.hpp"
+#include "CTPP2SyscallFactory.hpp"
+
+#include "CTPP2VMFileLoader.hpp"
+#include "CTPP2VM.hpp"
+#include "CTPP2VMSTDLib.hpp"
+
+using namespace CTPP;
+
+#define MAX_ITERATIONS 10000
+
+#define MAX_THREADS 100
+
+// Thread context
+struct ThreadContext
+{
+ // Output mutex
+ pthread_mutex_t output_mutex;
+ // Template access mutex
+ pthread_mutex_t template_mutex;
+ // Max handlers
+ INT_32 max_handlers;
+ // Set of templates
+ STLW::map<STLW::string, VMFileLoader *> templates;
+};
+
+// Thread function
+static void * ThreadFunction(void * pContext)
+{
+ ThreadContext * pThreadContext = (ThreadContext *)pContext;
+
+ pthread_mutex_lock(&(pThreadContext -> output_mutex));
+ fprintf(stderr, "Initilalizing...\n");
+ pthread_mutex_unlock(&(pThreadContext -> output_mutex));
+
+ // Create per-thread VM instance
+
+ // Syscall factory
+ SyscallFactory * pSyscallFactory = new SyscallFactory(pThreadContext -> max_handlers);
+ // Init standard library
+ STDLibInitializer::InitLibrary(*pSyscallFactory);
+ // Virtual machine
+ VM * pVM = new VM(pSyscallFactory);
+ // Okay, all done with thread-specific
+
+ // Fill data
+ CDT oData;
+ oData["hello"] = "Hello, World!";
+
+ pthread_mutex_lock(&(pThreadContext -> output_mutex));
+ fprintf(stderr, "Okay, ready to work\n");
+ pthread_mutex_unlock(&(pThreadContext -> output_mutex));
+
+ FileLogger oLogger(stderr);
+
+ // Perform some work
+ const VMMemoryCore * pVMMemoryCore = NULL;
+ for (UINT_32 iCount = 0; iCount < MAX_ITERATIONS; ++iCount)
+ {
+ STLW::string sResult;
+ StringOutputCollector oDataCollector(sResult);
+
+ // Get template, thread-safe
+ pthread_mutex_lock(&(pThreadContext -> template_mutex));
+ STLW::map<STLW::string, VMFileLoader *>::iterator itLoader = pThreadContext -> templates.find("hello.ct2");
+ if (itLoader == pThreadContext -> templates.end())
+ {
+ continue;
+ }
+
+ pVMMemoryCore = itLoader -> second -> GetCore();
+ pthread_mutex_unlock(&(pThreadContext -> template_mutex));
+
+ // Run VM
+ pVM -> Init(pVMMemoryCore, &oDataCollector, &oLogger);
+ UINT_32 iIP = 0;
+ pVM -> Run(pVMMemoryCore, &oDataCollector, iIP, oData, &oLogger);
+
+ // All done, print results
+ pthread_mutex_lock(&(pThreadContext -> output_mutex));
+ fwrite(sResult.c_str(), sResult.size(), 1, stdout);
+ pthread_mutex_unlock(&(pThreadContext -> output_mutex));
+ }
+
+ delete pVM;
+ delete pSyscallFactory;
+
+return NULL;
+}
+
+int main(int argc, char ** argv)
+{
+ ThreadContext oContext;
+
+ // Load file
+ oContext.templates["hello.ct2"] = new VMFileLoader("hello.ct2");
+ oContext.max_handlers = 1024;
+
+ // Init mutexes
+ pthread_mutex_init(&oContext.template_mutex, NULL);
+ pthread_mutex_init(&oContext.output_mutex, NULL);
+
+ pthread_attr_t oAttrs;
+ pthread_attr_init(&oAttrs);
+ pthread_attr_setdetachstate(&oAttrs, PTHREAD_CREATE_JOINABLE);
+
+ pthread_t aThreads[MAX_THREADS];
+
+ // Create set of threads
+ printf("Creating %d threads\n", MAX_THREADS);
+ INT_32 iPos;
+ for (iPos = 0; iPos < MAX_THREADS; ++iPos)
+ {
+ INT_32 iRC = pthread_create(&aThreads[iPos], &oAttrs, ThreadFunction, &oContext);
+ if (iRC != 0)
+ {
+ char szErrorBuf[1024 + 1];
+ strerror_r(iRC, szErrorBuf, 1024);
+
+ fprintf(stderr, "FATAL: %s", szErrorBuf);
+ return EX_SOFTWARE;
+ }
+ }
+
+ // Wait for results
+ printf("Wait for results\n");
+ for (iPos = 0; iPos < MAX_THREADS; ++iPos)
+ {
+ INT_32 iRC = pthread_join(aThreads[iPos], NULL);
+ if (iRC != 0)
+ {
+ char szErrorBuf[1024 + 1];
+ strerror_r(iRC, szErrorBuf, 1024);
+
+ fprintf(stderr, "FATAL: %s", szErrorBuf);
+ return EX_SOFTWARE;
+ }
+ }
+
+ fprintf(stderr, "Cleanup and exit\n");
+ pthread_attr_destroy(&oAttrs);
+ pthread_mutex_destroy(&oContext.template_mutex);
+ pthread_mutex_destroy(&oContext.output_mutex);
+}
+// End.
diff --git a/multithread/hello.tmpl b/multithread/hello.tmpl
new file mode 100644
index 0000000..40282d0
--- /dev/null
+++ b/multithread/hello.tmpl
@@ -0,0 +1 @@
+<TMPL_var hello> \ No newline at end of file
diff --git a/src/CDT.cpp b/src/CDT.cpp
new file mode 100644
index 0000000..7734b19
--- /dev/null
+++ b/src/CDT.cpp
@@ -0,0 +1,4929 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.cpp
+ *
+ * $CTPP$
+ */
+#include "CDT.hpp"
+#include "STLFunctional.hpp"
+
+#include <stdio.h>
+
+#ifdef WIN32
+#define strtoll _strtoi64
+#endif
+
+namespace CTPP
+{
+
+// FWD
+STLW::string EscapeJSONString(const STLW::string & sSource,
+ const bool & bECMAConventions = true,
+ const bool & bHTMLSafe = true);
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Struct _CDT
+//
+/**
+ @struct _CDT CDT.hpp <CDT.hpp>
+ @brief Shareable datatypes
+*/
+struct CDT::_CDT
+{
+ /** References counter */
+ UINT_32 refcount;
+ /** Value type fpr complex datatypes */
+ mutable eValType value_type;
+
+ /** Union */
+ union
+ {
+ /** String */
+ String * s_data;
+ /** Array */
+ Vector * v_data;
+ /** Hash */
+ Map * m_data;
+ } u;
+
+ /** Complex datatypes */
+ mutable union
+ {
+ /** Signed interger */
+ INT_64 i_data;
+ /** Floating point value */
+ W_FLOAT d_data;
+ } uc;
+
+ /** Constructor */
+ _CDT();
+};
+
+//
+// Constructor
+//
+CDT::_CDT::_CDT(): refcount(1), value_type(UNDEF)
+{
+ u.s_data = NULL;
+ uc.i_data = 0;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Static vars
+//
+static const CDT oNonExistentCDT;
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class Iterator
+//
+
+//
+// Constructor
+//
+CDT::Iterator::Iterator(CDT::Map::iterator itIMap): itMap(itIMap) { ;; }
+
+//
+// Copy constructor
+//
+CDT::Iterator::Iterator(const CDT::Iterator & oRhs): itMap(oRhs.itMap) { ;; }
+
+//
+// Operator =
+//
+CDT::Iterator & CDT::Iterator::operator=(const CDT::Iterator & oRhs)
+{
+ if (this != &oRhs) { itMap = oRhs.itMap; }
+
+ return *this;
+}
+
+//
+// Pre-increment operator ++
+//
+CDT::Iterator & CDT::Iterator::operator++()
+{
+ ++itMap;
+
+return *this;
+}
+
+//
+// Post-increment operator ++
+//
+CDT::Iterator CDT::Iterator::operator++(int)
+{
+ Iterator oTMP = *this;
+
+ ++itMap;
+
+return oTMP;
+}
+
+//
+// Access operator
+//
+STLW::pair<const STLW::string, CDT> * CDT::Iterator::operator->() { return &(*itMap); }
+
+//
+// Comparison operator
+//
+bool CDT::Iterator::operator ==(const CDT::Iterator & oRhs) { return (itMap == oRhs.itMap); }
+
+//
+// Comparison operator
+//
+bool CDT::Iterator::operator !=(const CDT::Iterator & oRhs) { return (itMap != oRhs.itMap); }
+
+//
+// Get iterator pointed to start of hash
+//
+CDT::Iterator CDT::Begin()
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+return Iterator(u.p_data -> u.m_data -> begin());
+}
+
+//
+// Get iterator pointed to end of hash
+//
+CDT::Iterator CDT::End()
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ return Iterator(u.p_data -> u.m_data -> end());
+}
+
+//
+// Find element in hash
+//
+CDT::Iterator CDT::Find(const STLW::string & sKey)
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+return Iterator(u.p_data -> u.m_data -> find(sKey));
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class ConstIterator
+//
+
+//
+// Copy constructor
+//
+CDT::ConstIterator::ConstIterator(const CDT::ConstIterator & oRhs): itMap(oRhs.itMap) { ;; }
+
+//
+// Type cast constructor
+//
+CDT::ConstIterator::ConstIterator(const CDT::Iterator & oRhs): itMap(oRhs.itMap) { ;; }
+
+//
+// Operator =
+//
+CDT::ConstIterator & CDT::ConstIterator::operator=(const ConstIterator & oRhs)
+{
+ if (this != &oRhs) { itMap = oRhs.itMap; }
+
+return *this;
+}
+
+//
+// Operator =
+//
+CDT::ConstIterator & CDT::ConstIterator::operator=(const CDT::Iterator & oRhs)
+{
+ itMap = oRhs.itMap;
+
+return *this;
+}
+
+//
+// Pre-increment operator ++
+//
+CDT::ConstIterator & CDT::ConstIterator::operator++()
+{
+ ++itMap;
+
+return *this;
+}
+
+//
+// Post-increment operator ++
+//
+CDT::ConstIterator CDT::ConstIterator::operator++(int)
+{
+ ConstIterator oTMP = *this;
+
+ ++itMap;
+
+return oTMP;
+}
+
+//
+// Access operator
+//
+const STLW::pair<const STLW::string, CDT> * CDT::ConstIterator::operator->() const { return &(*itMap); }
+
+//
+// Comparison operator
+//
+bool CDT::ConstIterator::operator ==(const CDT::ConstIterator & oRhs) const { return (itMap == oRhs.itMap); }
+
+//
+// Comparison operator
+//
+bool CDT::ConstIterator::operator !=(const CDT::ConstIterator & oRhs) const { return (itMap != oRhs.itMap); }
+
+//
+// Get constant iterator pointed to start of hash
+//
+CDT::ConstIterator CDT::Begin() const
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+return ConstIterator(u.p_data -> u.m_data -> begin());
+}
+
+//
+// Get constant iterator pointed to end of hash
+//
+CDT::ConstIterator CDT::End() const
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+return ConstIterator(u.p_data -> u.m_data -> end());
+}
+
+//
+// Find element in hash
+//
+CDT::ConstIterator CDT::Find(const STLW::string & sKey) const
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+return ConstIterator(u.p_data -> u.m_data -> find(sKey));
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortHelper
+//
+
+/**
+ @class SortHelper
+ @brief Sorting helper
+*/
+class SortHelper
+{
+public:
+ /**
+ @brief Constructor
+ @param oISortingComparator - "Real" sorting comparator
+ */
+ SortHelper(const CDT::SortingComparator & oISortingComparator);
+
+ /**
+ @brief Comparison operator
+ @param oX - first value to compare
+ @param oY - seond value to compare
+ @return true, if oX < oY, false - otherwise
+ */
+ bool operator()(const CDT & oX, const CDT & oY) const;
+private:
+ /** "Real" comparator */
+ const CDT::SortingComparator & oSortingComparator;
+};
+
+//
+// Constructor
+//
+SortHelper::SortHelper(const CDT::SortingComparator & oISortingComparator): oSortingComparator(oISortingComparator) { ;; }
+
+//
+// Comparison operator
+//
+bool SortHelper::operator()(const CDT & oX, const CDT & oY) const { return oSortingComparator.operator()(oX, oY); }
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CDT
+//
+
+//
+// Default constructor
+//
+CDT::CDT(const eValType & oValue): eValueType(oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ u.i_data = 0;
+ break;
+
+ case REAL_VAL:
+ u.d_data = 0;
+ break;
+
+ case STRING_VAL:
+ u.p_data = new _CDT();
+ u.p_data -> u.s_data = new String;
+ break;
+
+ case STRING_INT_VAL:
+ u.p_data = new _CDT();
+ u.p_data -> value_type = INT_VAL;
+ u.p_data -> u.s_data = new String;
+ break;
+
+ case STRING_REAL_VAL:
+ u.p_data = new _CDT();
+ u.p_data -> value_type = REAL_VAL;
+ u.p_data -> u.s_data = new String;
+ break;
+
+ case ARRAY_VAL:
+ u.p_data = new _CDT();
+ u.p_data -> u.v_data = new Vector;
+ break;
+
+ case HASH_VAL:
+ u.p_data = new _CDT();
+ u.p_data -> u.m_data = new Map;
+ break;
+
+ case POINTER_VAL:
+ u.pp_data = NULL;
+ break;
+
+ default:
+ throw CDTTypeCastException("No such type");
+ }
+}
+
+//
+// Copy constructor
+//
+CDT::CDT(const CDT & oCDT)
+{
+ if (this == &oCDT)
+ {
+ eValueType = UNDEF;
+ return;
+ }
+
+ eValueType = oCDT.eValueType;
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ u.i_data = oCDT.u.i_data;
+ break;
+
+ case REAL_VAL:
+ u.d_data = oCDT.u.d_data;
+ break;
+
+ case POINTER_VAL:
+ u.pp_data = oCDT.u.pp_data;
+ break;
+
+ case STRING_VAL:
+ case STRING_REAL_VAL:
+ case STRING_INT_VAL:
+ case ARRAY_VAL:
+ case HASH_VAL:
+ u.p_data = oCDT.u.p_data;
+ ++(u.p_data -> refcount);
+ break;
+
+ default:
+ throw CDTTypeCastException("No such type");
+ }
+}
+
+//
+// Copy operator
+//
+CDT & CDT::operator=(const CDT & oCDT)
+{
+ if (this == &oCDT) { return *this; }
+
+ // oCDT can be implicitly destoyed if it's nested somethere
+ // in `this` (if we call Destroy()), so make some copies
+
+ _CDT * pTMP = oCDT.u.p_data;
+ INT_64 iIntVal = oCDT.u.i_data;
+ W_FLOAT dFloatVal = oCDT.u.d_data;
+ void * vPointerVal = oCDT.u.pp_data;
+ eValType eOrigValType = oCDT.eValueType;
+
+ // Destroy object if need
+ if (eValueType >= STRING_VAL)
+ {
+ if (oCDT.eValueType >= STRING_VAL && oCDT.u.p_data -> refcount == 1)
+ {
+ // oCDT can be a child of this with u.refcount = 1;
+ // so we increase it's refcount
+ ++(pTMP -> refcount);
+ Destroy();
+ // now decrease it so
+ // if oCDT was a child of `this` it's 0 and it will be increased later
+ // otherwise it's 1
+ --(pTMP -> refcount);
+ }
+ else
+ {
+ Destroy();
+ }
+ }
+
+ eValueType = eOrigValType;
+
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ u.i_data = iIntVal;
+ break;
+
+ case REAL_VAL:
+ u.d_data = dFloatVal;
+ break;
+
+ case POINTER_VAL:
+ u.pp_data = vPointerVal;
+ break;
+
+ case STRING_VAL:
+ case STRING_REAL_VAL:
+ case STRING_INT_VAL:
+ case ARRAY_VAL:
+ case HASH_VAL:
+ u.p_data = pTMP;
+ ++u.p_data -> refcount;
+ break;
+
+ default:
+ throw CDTTypeCastException("No such type");
+ }
+
+return *this;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Type cast constructor from INT_64 type
+//
+CDT::CDT(const INT_64 oValue): eValueType(INT_VAL) { u.i_data = oValue; }
+
+//
+// Type cast constructor from UINT_64 type
+//
+CDT::CDT(const UINT_64 oValue): eValueType(INT_VAL) { u.i_data = oValue; }
+
+//
+// Type cast constructor from INT_32 type
+//
+CDT::CDT(const INT_32 oValue): eValueType(INT_VAL) { u.i_data = oValue; }
+
+//
+// Type cast constructor from UINT_32 type
+//
+CDT::CDT(const UINT_32 oValue): eValueType(INT_VAL) { u.i_data = oValue; }
+
+//
+// Type cast constructor from W_FLOAT type
+//
+CDT::CDT(const W_FLOAT oValue): eValueType(REAL_VAL) { u.d_data = oValue; }
+
+//
+// Type cast constructor from STLW::string type
+//
+CDT::CDT(const STLW::string & oValue): eValueType(STRING_VAL)
+{
+ u.p_data = new _CDT();
+ u.p_data -> u.s_data = new String(oValue);
+}
+
+//
+// Type cast constructor from CCHAR_P type
+//
+CDT::CDT(CCHAR_P oValue): eValueType(STRING_VAL)
+{
+ u.p_data = new _CDT();
+ u.p_data -> u.s_data = new STLW::string(oValue);
+}
+
+//
+// Type cast constructor
+//
+CDT::CDT(void * oValue): eValueType(POINTER_VAL) { u.pp_data = oValue; }
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator = for type INT_64
+//
+CDT & CDT::operator=(const INT_64 oValue)
+{
+ // Destroy object if need
+ if (eValueType >= STRING_VAL) { Destroy(); }
+
+ eValueType = INT_VAL;
+ u.i_data = oValue;
+
+return *this;
+}
+
+//
+// Operator = for type UINT_64
+//
+CDT & CDT::operator=(const UINT_64 oValue) { return operator=(INT_64(oValue)); }
+
+//
+// Operator = for type INT_32
+//
+CDT & CDT::operator=(const INT_32 oValue) { return operator=(INT_64(oValue)); }
+
+//
+// Operator = for type UINT_32
+//
+CDT & CDT::operator=(const UINT_32 oValue) { return operator=(UINT_64(oValue)); }
+
+//
+// Operator = for type W_FLOAT
+//
+CDT & CDT::operator=(const W_FLOAT oValue)
+{
+ // Destroy object if need
+ if (eValueType >= STRING_VAL) { Destroy(); }
+
+ eValueType = REAL_VAL;
+ u.d_data = oValue;
+
+return *this;
+}
+
+//
+// Operator = for type STLW::string
+//
+CDT & CDT::operator=(const STLW::string & oValue)
+{
+ // Destroy object if need
+ if (eValueType >= STRING_VAL) { Destroy(); }
+
+ eValueType = STRING_VAL;
+ u.p_data = new _CDT();
+ u.p_data -> u.s_data = new String(oValue);
+
+return *this;
+}
+
+//
+// Operator = for old-fashion string
+//
+CDT & CDT::operator=(CCHAR_P oValue)
+{
+ // Destroy object if need
+ if (eValueType >= STRING_VAL) { Destroy(); }
+
+ eValueType = STRING_VAL;
+ u.p_data = new _CDT();
+ u.p_data -> u.s_data = new String(oValue);
+
+return *this;
+}
+
+//
+// Type cast constructor
+//
+CDT & CDT::operator=(void * oValue)
+{
+ // Destroy object if need
+ if (eValueType >= STRING_VAL) { Destroy(); }
+
+ eValueType = POINTER_VAL;
+ u.pp_data = oValue;
+
+return *this;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Access operator []
+//
+CDT & CDT::operator[](const UINT_32 iPos)
+{
+ if (eValueType == UNDEF)
+ {
+ eValueType = ARRAY_VAL;
+ u.p_data = new _CDT;
+ u.p_data -> u.v_data = new Vector(iPos + 1);
+ }
+ else if (eValueType != ARRAY_VAL) { throw CDTAccessException(); }
+
+ // Unshare complex type
+ Unshare();
+
+ UINT_32 iSize = u.p_data -> u.v_data -> size();
+
+ if (iPos == iSize) { u.p_data -> u.v_data -> push_back(CDT()); }
+ else if (iPos > iSize) { u.p_data -> u.v_data -> resize(iPos + 1); }
+
+return u.p_data -> u.v_data -> operator[](iPos);
+}
+
+//
+// Access operator []
+//
+const CDT & CDT::operator[](const UINT_32 iPos) const { return GetCDT(iPos); }
+
+//
+// Access operator []
+//
+CDT & CDT::operator[](const STLW::string & sKey)
+{
+ if (eValueType == UNDEF)
+ {
+ eValueType = HASH_VAL;
+ u.p_data = new _CDT;
+ u.p_data -> u.m_data = new Map;
+ }
+ else if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ // Unshare complex type
+ Unshare();
+
+return u.p_data -> u.m_data -> operator[](sKey);
+}
+
+//
+// Access operator []
+//
+const CDT & CDT::operator[](const STLW::string & sKey) const { return GetCDT(sKey); }
+
+//
+// Provides constant access to the data contained in CDT
+//
+const CDT & CDT::GetCDT(const UINT_32 iPos) const
+{
+ if (eValueType != ARRAY_VAL) { return oNonExistentCDT; }
+
+ if (iPos >= u.p_data -> u.v_data -> size()) { throw CDTRangeException(); }
+
+return u.p_data -> u.v_data -> operator[](iPos);
+}
+
+//
+// Provides constant access to the data contained in CDT
+//
+const CDT & CDT::GetCDT(const STLW::string & sKey) const
+{
+ bool bFlag = 0;
+
+return GetExistedCDT(sKey, bFlag);
+}
+
+//
+// Provides constant access to the data contained in CDT
+//
+const CDT & CDT::GetExistedCDT(const STLW::string & sKey, bool & bCDTExist) const
+{
+ // CDT Does Not exist
+ if (eValueType != HASH_VAL)
+ {
+ bCDTExist = false;
+ return oNonExistentCDT;
+ }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> find(sKey);
+ if (itmHash == u.p_data -> u.m_data -> end())
+ {
+ bCDTExist = false;
+ return oNonExistentCDT;
+ }
+ bCDTExist = true;
+
+return itmHash -> second;
+}
+
+//
+// Erase element from HASH
+//
+bool CDT::Erase(const STLW::string & sKey)
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Unshare();
+
+ Map::iterator itmHash = u.p_data -> u.m_data -> find(sKey);
+ if (itmHash == u.p_data -> u.m_data -> end()) { return false; }
+
+ u.p_data -> u.m_data -> erase(itmHash);
+
+return true;
+}
+
+//
+// Check element in array
+//
+bool CDT::Exists(const UINT_32 iPos) const
+{
+ if (eValueType != ARRAY_VAL) { throw CDTAccessException(); }
+
+ if (iPos >= u.p_data -> u.v_data -> size()) { return false; }
+
+return true;
+}
+
+//
+// Check element in hash
+//
+bool CDT::Exists(const STLW::string & sKey) const
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> find(sKey);
+ if (itmHash == u.p_data -> u.m_data -> end()) { return false; }
+
+return true;
+}
+
+//
+// Push value into array
+//
+void CDT::PushBack(const INT_64 oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const UINT_64 oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const INT_32 oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const UINT_32 oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const W_FLOAT oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const STLW::string & oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(CCHAR_P oValue) { PushBack(CDT(oValue)); }
+
+//
+// Push value into array
+//
+void CDT::PushBack(const CDT & oValue)
+{
+ if (eValueType == ARRAY_VAL) { u.p_data -> u.v_data -> push_back(oValue); }
+ else if (eValueType == UNDEF)
+ {
+ (*this) = CDT(CDT::ARRAY_VAL);
+ u.p_data -> u.v_data -> push_back(oValue);
+ }
+ else
+ {
+ throw CDTAccessException();
+ }
+}
+
+//
+// Returns a boolean value telling whether object has a value
+//
+bool CDT::Nonzero() const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ if (u.i_data != 0) { return true; }
+ break;
+
+ case REAL_VAL:
+ if (u.d_data != 0) { return true; }
+ break;
+
+ case STRING_VAL:
+ case STRING_REAL_VAL:
+ case STRING_INT_VAL:
+ if (u.p_data -> u.s_data -> size() != 0) { return true; }
+ break;
+
+ case ARRAY_VAL:
+ if (u.p_data -> u.v_data -> size() != 0) { return true; }
+ break;
+
+ case HASH_VAL:
+ if (u.p_data -> u.m_data -> size() != 0) { return true; }
+ break;
+
+ case POINTER_VAL:
+ if (u.pp_data != NULL) { return true; }
+ break;
+ }
+
+return false;
+}
+
+//
+// Provides range-check access to the data contained in CDT
+//
+CDT & CDT::At(const UINT_32 iPos)
+{
+ if (eValueType != ARRAY_VAL) { throw CDTAccessException(); }
+
+ if (iPos >= u.p_data -> u.v_data -> size()) { throw CDTRangeException(); }
+
+return u.p_data -> u.v_data -> operator[](iPos);
+}
+
+//
+// Provides range-check access to the data contained in CDT
+//
+CDT & CDT::At(const STLW::string & sKey)
+{
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::iterator itmHash = u.p_data -> u.m_data -> find(sKey);
+ if (itmHash == u.p_data -> u.m_data -> end()) { throw CDTRangeException(); }
+
+return itmHash -> second;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator + for type INT_64
+//
+CDT CDT::operator+(const INT_64 oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ return CDT(oValue);
+
+ case INT_VAL:
+ return CDT(u.i_data + oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data + oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator+(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData + oValue); }
+
+ return CDT(dData + oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data + oValue);
+
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data + oValue);
+
+ default:
+ throw CDTTypeCastException("operator+ (INT_64)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator + for type UINT_64
+//
+CDT CDT::operator+(const UINT_64 oValue) const { return this -> operator+(INT_64(oValue)); }
+
+//
+// Operator + for type INT_32
+//
+CDT CDT::operator+(const INT_32 oValue) const { return this -> operator+(INT_64(oValue)); }
+
+//
+// Operator + for type UINT_32
+//
+CDT CDT::operator+(const UINT_32 oValue) const { return this -> operator+(UINT_64(oValue)); }
+
+//
+// Operator + for type W_FLOAT
+//
+CDT CDT::operator+(const W_FLOAT oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ return CDT(oValue);
+
+ case INT_VAL:
+ return CDT(u.i_data + oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data + oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator+(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData + oValue); }
+
+ return CDT(dData + oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data + oValue);
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data + oValue);
+
+ default:
+ throw CDTTypeCastException("operator+(INT_64)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator + for type CDT
+//
+CDT CDT::operator+(const CDT & oCDT) const
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(iData1 + iData2); }
+
+ // First argument is INT_VAL, second argument is REAL_VAL
+ return CDT(iData1 + dData2);
+ }
+
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(dData1 + iData2); }
+
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ return CDT(dData1 + dData2);
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator - for type INT_64
+//
+CDT CDT::operator-(const INT_64 oValue) const { return this -> operator+(-oValue); }
+
+//
+// Operator - for type UINT_64
+//
+CDT CDT::operator-(const UINT_64 oValue) const { return this -> operator+(- INT_64(oValue)); }
+
+//
+// Operator - for type INT_32
+//
+CDT CDT::operator-(const INT_32 oValue) const { return this -> operator+(-oValue); }
+
+//
+// Operator - for type UINT_32
+//
+CDT CDT::operator-(const UINT_32 oValue) const { return this -> operator+(- INT_32(oValue)); }
+
+//
+// Operator - for type W_FLOAT
+//
+CDT CDT::operator-(const W_FLOAT oValue) const { return this -> operator+(-oValue); }
+
+//
+// Operator - for type CDT
+//
+CDT CDT::operator-(const CDT & oCDT) const
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(iData1 - iData2); }
+
+ // First argument is INT_VAL, second argument is REAL_VAL
+ return CDT(iData1 - dData2);
+ }
+
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(dData1 - iData2); }
+
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ return CDT(dData1 - dData2);
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator * for type INT_64
+//
+CDT CDT::operator*(const INT_64 oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ return CDT(INT_64(0));
+
+ case INT_VAL:
+ return CDT(u.i_data * oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data * oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator*(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData * oValue); }
+
+ return CDT(dData * oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data * oValue);
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data * oValue);
+
+ default:
+ throw CDTTypeCastException("operator*(INT_64)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator * for type UINT_64
+//
+CDT CDT::operator*(const UINT_64 oValue) const { return this -> operator*(INT_64(oValue)); }
+
+//
+// Operator * for type INT_32
+//
+CDT CDT::operator*(const INT_32 oValue) const { return this -> operator*(INT_64(oValue)); }
+
+//
+// Operator * for type UINT_32
+//
+CDT CDT::operator*(const UINT_32 oValue) const { return this -> operator*(UINT_64(oValue)); }
+
+//
+// Operator * for type W_FLOAT
+//
+CDT CDT::operator*(const W_FLOAT oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ return CDT(INT_64(0));
+
+ case INT_VAL:
+ return CDT(u.i_data * oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data * oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator*(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData * oValue); }
+
+ return CDT(dData * oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data * oValue);
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data * oValue);
+
+ default:
+ throw CDTTypeCastException("operator*(W_FLOAT)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator * for type CDT
+//
+CDT CDT::operator*(const CDT & oCDT) const
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(iData1 * iData2); }
+
+ // First argument is INT_VAL, second argument is REAL_VAL
+ return CDT(iData1 * dData2);
+ }
+
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(dData1 * iData2); }
+
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ return CDT(dData1 * dData2);
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator / for type INT_64
+//
+CDT CDT::operator/(const INT_64 oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ return CDT(0 / oValue);
+
+ case INT_VAL:
+ return CDT(u.i_data / oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data / oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator/(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData / oValue); }
+
+ return CDT(dData / oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data / oValue);
+
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data / oValue);
+
+ default:
+ throw CDTTypeCastException("operator/(INT_64)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator / for type UINT_64
+//
+CDT CDT::operator/(const UINT_64 oValue) const { return this -> operator/(INT_64(oValue)); }
+
+//
+// Operator / for type INT_32
+//
+CDT CDT::operator/(const INT_32 oValue) const { return this -> operator/(INT_64(oValue)); }
+
+//
+// Operator / for type UINT_32
+//
+CDT CDT::operator/(const UINT_32 oValue) const { return this -> operator/(UINT_64(oValue)); }
+
+//
+// Operator / for type W_FLOAT
+//
+CDT CDT::operator/(const W_FLOAT oValue) const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ // Keep this
+ // For explanation see IEEE standard 754 for floating-point arithmetic
+ return CDT(0.0 / oValue);
+
+ case INT_VAL:
+ return CDT(u.i_data / oValue);
+
+ case REAL_VAL:
+ return CDT(u.d_data / oValue);
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator/(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { return CDT(iData / oValue); }
+
+ return CDT(dData / oValue);
+ }
+
+ case STRING_INT_VAL:
+ return CDT(u.p_data -> uc.i_data / oValue);
+
+
+ case STRING_REAL_VAL:
+ return CDT(u.p_data -> uc.d_data / oValue);
+
+ default:
+ throw CDTTypeCastException("operator/(W_FLOAT)");
+ }
+
+// Make stupid compiler happy
+return CDT(*this);
+}
+
+//
+// Operator / for type CDT
+//
+CDT CDT::operator/(const CDT & oCDT) const
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(iData1 / iData2); }
+
+ // First argument is INT_VAL, second argument is REAL_VAL
+ return CDT(iData1 / dData2);
+ }
+
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { return CDT(dData1 / iData2); }
+
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ return CDT(dData1 / dData2);
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator += for type INT_64
+//
+CDT & CDT::operator+=(const INT_64 oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(oValue);
+ break;
+
+ case INT_VAL:
+ u.i_data += oValue;
+ break;
+
+ case REAL_VAL:
+ u.d_data += oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator+=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData + oValue); }
+ else { (*this) = CDT(dData + oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data + oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data + oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator+=(INT_64)");
+ }
+
+return *this;
+}
+
+//
+// Operator += for type UINT_64
+//
+CDT & CDT::operator+=(const UINT_64 oValue) { return this -> operator+=(INT_64(oValue)); }
+
+//
+// Operator += for type INT_32
+//
+CDT & CDT::operator+=(const INT_32 oValue) { return this -> operator+=(INT_64(oValue)); }
+
+//
+// Operator += for type UINT_32
+//
+CDT & CDT::operator+=(const UINT_32 oValue) { return this -> operator+=(UINT_64(oValue)); }
+
+//
+// Operator += for type W_FLOAT
+//
+CDT & CDT::operator+=(const W_FLOAT oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(oValue);
+ break;
+
+ case INT_VAL:
+ u.i_data += INT_64(oValue);
+ break;
+
+ case REAL_VAL:
+ u.d_data += oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator+=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData + oValue); }
+ else { (*this) = CDT(dData + oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data + oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data + oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator+=(W_FLOAT)");
+ }
+
+return *this;
+}
+
+//
+// Operator += for type CDT
+//
+CDT & CDT::operator+=(const CDT & oCDT)
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(iData1 + iData2); }
+ // First argument is INT_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(iData1 + dData2); }
+ }
+ else
+ {
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(dData1 + iData2); }
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(dData1 + dData2); }
+ }
+
+return *this;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator -= for type INT_32
+//
+CDT & CDT::operator-=(const INT_64 oValue) { return this -> operator+=(- oValue); }
+
+//
+// Operator -= for type UINT_32
+//
+CDT & CDT::operator-=(const UINT_64 oValue) { return this -> operator+=(- INT_64(oValue)); }
+
+//
+// Operator -= for type INT_32
+//
+CDT & CDT::operator-=(const INT_32 oValue) { return this -> operator+=(- oValue); }
+
+//
+// Operator -= for type UINT_32
+//
+CDT & CDT::operator-=(const UINT_32 oValue) { return this -> operator+=(- INT_32(oValue)); }
+
+//
+// Operator -= for type W_FLOAT
+//
+CDT & CDT::operator-=(const W_FLOAT oValue) { return this -> operator+=(- oValue); }
+
+//
+// Operator -= for type CDT
+//
+CDT & CDT::operator-=(const CDT & oCDT)
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(iData1 - iData2); }
+ // First argument is INT_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(iData1 - dData2); }
+ }
+ else
+ {
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(dData1 - iData2); }
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(dData1 - dData2); }
+ }
+
+return *this;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator *= for type INT_64
+//
+CDT & CDT::operator*=(const INT_64 oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(0);
+ break;
+
+ case INT_VAL:
+ u.i_data *= oValue;
+ break;
+
+ case REAL_VAL:
+ u.d_data *= oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator*=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData * oValue); }
+ else { (*this) = CDT(dData * oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data * oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data * oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator*=(INT_64)");
+ }
+
+return *this;
+}
+
+//
+// Operator *= for type UINT_64
+//
+CDT & CDT::operator*=(const UINT_64 oValue) { return this -> operator*=(INT_64(oValue)); }
+
+//
+// Operator *= for type INT_32
+//
+CDT & CDT::operator*=(const INT_32 oValue) { return this -> operator*=(INT_64(oValue)); }
+
+//
+// Operator *= for type UINT_32
+//
+CDT & CDT::operator*=(const UINT_32 oValue) { return this -> operator*=(INT_64(oValue)); }
+
+//
+// Operator *= for type W_FLOAT
+//
+CDT & CDT::operator*=(const W_FLOAT oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(0.0);
+ break;
+
+ case INT_VAL:
+ {
+ eValueType = REAL_VAL;
+
+ const W_FLOAT dTMP = u.i_data * oValue;
+ u.d_data = dTMP;
+ }
+ break;
+
+ case REAL_VAL:
+ u.d_data *= oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator*=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData * oValue); }
+ else { (*this) = CDT(dData * oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data * oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data * oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator*=(W_FLOAT)");
+ }
+
+return *this;
+}
+
+//
+// Operator *= for type CDT
+//
+CDT & CDT::operator*=(const CDT & oCDT)
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(iData1 * iData2); }
+ // First argument is INT_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(iData1 * dData2); }
+ }
+ else
+ {
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(dData1 * iData2); }
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(dData1 * dData2); }
+ }
+
+return *this;
+}
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator /= for type INT_64
+//
+CDT & CDT::operator/=(const INT_64 oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(0 / oValue);
+ break;
+
+ case INT_VAL:
+ u.i_data /= oValue;
+ break;
+
+ case REAL_VAL:
+ u.d_data /= oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator/=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData / oValue); }
+ else { (*this) = CDT(dData / oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data / oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data / oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator/=(INT_64)");
+ }
+
+return *this;
+}
+
+//
+// Operator /= for type UINT_64
+//
+CDT & CDT::operator/=(const UINT_64 oValue) { return this -> operator/=(INT_64(oValue)); }
+
+//
+// Operator /= for type INT_32
+//
+CDT & CDT::operator/=(const INT_32 oValue) { return this -> operator/=(INT_64(oValue)); }
+
+//
+// Operator /= for type UINT_32
+//
+CDT & CDT::operator/=(const UINT_32 oValue) { return this -> operator/=(UINT_64(oValue)); }
+
+//
+// Operator /= for type W_FLOAT
+//
+CDT & CDT::operator/=(const W_FLOAT oValue)
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ (*this) = CDT(0.0 / oValue);
+ break;
+
+ case INT_VAL:
+ {
+ eValueType = REAL_VAL;
+
+ const W_FLOAT dTMP = u.i_data / oValue;
+ u.d_data = dTMP;
+ }
+ break;
+
+ case REAL_VAL:
+ u.d_data /= oValue;
+ break;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return this -> operator/=(oValue); }
+
+ INT_64 iData;
+ W_FLOAT dData;
+ eValType eType = CastToNumber(iData, dData);
+
+ if (eType == INT_VAL) { (*this) = CDT(iData / oValue); }
+ else { (*this) = CDT(dData / oValue); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ (*this) = CDT(u.p_data -> uc.i_data / oValue);
+ break;
+
+ case STRING_REAL_VAL:
+ (*this) = CDT(u.p_data -> uc.d_data / oValue);
+ break;
+
+ default:
+ throw CDTTypeCastException("operator*=(W_FLOAT)");
+ }
+
+return *this;
+}
+
+//
+// Operator /= for type CDT
+//
+CDT & CDT::operator/=(const CDT & oCDT)
+{
+ INT_64 iData1;
+ W_FLOAT dData1;
+ eValType eType1 = CastToNumber(iData1, dData1);
+
+ INT_64 iData2;
+ W_FLOAT dData2;
+ eValType eType2 = oCDT.CastToNumber(iData2, dData2);
+
+ // First argument is INT_VAL
+ if (eType1 == INT_VAL)
+ {
+ // First argument is INT_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(iData1 / iData2); }
+ // First argument is INT_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(iData1 / dData2); }
+ }
+ else
+ {
+ // First argument is REAL_VAL, second argument is INT_VAL
+ if (eType2 == INT_VAL) { (*this) = CDT(dData1 / iData2); }
+ // First argument is REAL_VAL, second argument is REAL_VAL
+ else { (*this) = CDT(dData1 / dData2); }
+ }
+
+return *this;
+}
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator == for type INT_32
+//
+bool CDT::operator==(const INT_64 oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data == oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data == oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data == oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data == oValue; }
+
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and INTEGER data types. Use `Equal`, `EQ` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator == for type UINT_32
+//
+bool CDT::operator==(const UINT_64 oValue) const { return operator==(INT_64(oValue)); }
+
+//
+// Operator == for type INT_32
+//
+bool CDT::operator==(const INT_32 oValue) const { return operator==(INT_64(oValue)); }
+
+//
+// Operator == for type UINT_32
+//
+bool CDT::operator==(const UINT_32 oValue) const { return operator==(UINT_64(oValue)); }
+
+//
+// Operator == for type W_FLOAT
+//
+bool CDT::operator==(const W_FLOAT oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data == oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data == oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data == oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data == oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `Equal`, `EQ` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator == for type STLW::string
+//
+bool CDT::operator==(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() == STLW::string(oValue);
+}
+
+//
+// Operator == for type STLW::string
+//
+bool CDT::operator==(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Equal`, `EQ` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() == oValue;
+}
+
+//
+// Operator == for type CDT
+//
+bool CDT::operator==(const CDT & oCDT) const
+{
+ if (eValueType == UNDEF && oCDT.eValueType == UNDEF)
+ {
+ return true;
+ }
+ // Integer-to-Integer
+ else if ((eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetInt() == oCDT.GetInt();
+ }
+ // (Integer, Real, String+Integer, String+Real)-to-(Integer, Real, String+Integer, String+Real)
+ else if ((eValueType == REAL_VAL || eValueType == STRING_REAL_VAL ||
+ eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == REAL_VAL || oCDT.eValueType == STRING_REAL_VAL ||
+ oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetFloat() == oCDT.GetFloat();
+ }
+ // (String, String+Integer, String+Real)-to-(String, String+Integer, String+Real)
+ else if ((eValueType == STRING_VAL || eValueType == STRING_REAL_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == STRING_VAL || oCDT.eValueType == STRING_REAL_VAL || oCDT.eValueType == STRING_INT_VAL))
+ {
+ return *(u.p_data -> u.s_data) == *(oCDT.u.p_data -> u.s_data);
+ }
+ else if (eValueType == POINTER_VAL && oCDT.eValueType == POINTER_VAL)
+ {
+ return u.pp_data == oCDT.u.pp_data;
+ }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `Equal`, `EQ` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return false;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator != for type INT_32
+//
+bool CDT::operator!=(const INT_64 oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type UINT_32
+//
+bool CDT::operator!=(const UINT_64 oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type INT_32
+//
+bool CDT::operator!=(const INT_32 oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type UINT_32
+//
+bool CDT::operator!=(const UINT_32 oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type W_FLOAT
+//
+bool CDT::operator!=(const W_FLOAT oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type STLW::string
+//
+bool CDT::operator!=(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator!=(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type STLW::string
+//
+bool CDT::operator!=(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator!=(oValue);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oValue);
+#endif
+return false;
+}
+
+//
+// Operator != for type CDT
+//
+bool CDT::operator!=(const CDT & oCDT) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ try
+ {
+ return ! this -> operator==(oCDT);
+ }
+ catch (CTPPLogicError & e)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `NotEqual`, `NE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#else
+ return ! this -> operator==(oCDT);
+#endif
+return false;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator > for type INT_32
+//
+bool CDT::operator>(const INT_64 oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data > oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data > oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data > oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data > oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and INTEGER data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator > for type UINT_32
+//
+bool CDT::operator>(const UINT_64 oValue) const { return operator>(INT_64(oValue)); }
+
+//
+// Operator > for type INT_32
+//
+bool CDT::operator>(const INT_32 oValue) const { return operator>(INT_64(oValue)); }
+
+//
+// Operator > for type UINT_32
+//
+bool CDT::operator>(const UINT_32 oValue) const { return operator>(UINT_64(oValue)); }
+
+//
+// Operator > for type W_FLOAT
+//
+bool CDT::operator>(const W_FLOAT oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data > oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data > oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data > oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data > oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator > for type STLW::string
+//
+bool CDT::operator>(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() > STLW::string(oValue);
+}
+
+//
+// Operator > for type STLW::string
+//
+bool CDT::operator>(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() > oValue;
+}
+
+//
+// Operator > for type CDT
+//
+bool CDT::operator>(const CDT & oCDT) const
+{
+ if (eValueType == UNDEF && oCDT.eValueType == UNDEF)
+ {
+ return false;
+ }
+ // Integer-to-Integer
+ else if ((eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetInt() > oCDT.GetInt();
+ }
+ // (Integer, Real, String+Integer, String+Real)-to-(Integer, Real, String+Integer, String+Real)
+ else if ((eValueType == REAL_VAL || eValueType == STRING_REAL_VAL ||
+ eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == REAL_VAL || oCDT.eValueType == STRING_REAL_VAL ||
+ oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetFloat() > oCDT.GetFloat();
+ }
+ // (String, String+Integer, String+Real)-to-(String, String+Integer, String+Real)
+ else if ((eValueType == STRING_VAL || eValueType == STRING_REAL_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == STRING_VAL || oCDT.eValueType == STRING_REAL_VAL || oCDT.eValueType == STRING_INT_VAL))
+ {
+ return *(u.p_data -> u.s_data) > *(oCDT.u.p_data -> u.s_data);
+ }
+ else if (eValueType == POINTER_VAL && oCDT.eValueType == POINTER_VAL)
+ {
+ return u.pp_data > oCDT.u.pp_data;
+ }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `Greater`, `GT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator < for type INT_32
+//
+bool CDT::operator<(const INT_64 oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data < oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data < oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data < oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data < oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and INTEGER data types. Use `Less`, `LT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator < for type UINT_32
+//
+bool CDT::operator<(const UINT_64 oValue) const { return operator<(INT_64(oValue)); }
+
+//
+// Operator < for type INT_32
+//
+bool CDT::operator<(const INT_32 oValue) const { return operator<(INT_64(oValue)); }
+
+//
+// Operator < for type UINT_32
+//
+bool CDT::operator<(const UINT_32 oValue) const { return operator<(UINT_64(oValue)); }
+
+//
+// Operator < for type W_FLOAT
+//
+bool CDT::operator<(const W_FLOAT oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data < oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data < oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data < oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data < oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `Less`, `LT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator < for type STLW::string
+//
+bool CDT::operator<(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Less`, `LT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() < STLW::string(oValue);
+}
+
+//
+// Operator < for type STLW::string
+//
+bool CDT::operator<(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `Less`, `LT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() < oValue;
+}
+
+//
+// Operator < for type CDT
+//
+bool CDT::operator<(const CDT & oCDT) const
+{
+ if (eValueType == UNDEF && oCDT.eValueType == UNDEF)
+ {
+ return false;
+ }
+ // Integer-to-Integer
+ else if ((eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetInt() < oCDT.GetInt();
+ }
+ // (Integer, Real, String+Integer, String+Real)-to-(Integer, Real, String+Integer, String+Real)
+ else if ((eValueType == REAL_VAL || eValueType == STRING_REAL_VAL ||
+ eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == REAL_VAL || oCDT.eValueType == STRING_REAL_VAL ||
+ oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetFloat() < oCDT.GetFloat();
+ }
+ // (String, String+Integer, String+Real)-to-(String, String+Integer, String+Real)
+ else if ((eValueType == STRING_VAL || eValueType == STRING_REAL_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == STRING_VAL || oCDT.eValueType == STRING_REAL_VAL || oCDT.eValueType == STRING_INT_VAL))
+ {
+ return *(u.p_data -> u.s_data) < *(oCDT.u.p_data -> u.s_data);
+ }
+ else if (eValueType == POINTER_VAL && oCDT.eValueType == POINTER_VAL)
+ {
+ return u.pp_data < oCDT.u.pp_data;
+ }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `Less`, `LT` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator <= for type INT_32
+//
+bool CDT::operator<=(const INT_64 oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data <= oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data <= oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data <= oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data <= oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and INTEGER data types. Use `LessOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator <= for type UINT_32
+//
+bool CDT::operator<=(const UINT_64 oValue) const { return operator<=(INT_64(oValue)); }
+
+//
+// Operator <= for type INT_32
+//
+bool CDT::operator<=(const INT_32 oValue) const { return operator<=(INT_64(oValue)); }
+
+//
+// Operator <= for type UINT_32
+//
+bool CDT::operator<=(const UINT_32 oValue) const { return operator<=(UINT_64(oValue)); }
+
+//
+// Operator <= for type W_FLOAT
+//
+bool CDT::operator<=(const W_FLOAT oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data <= oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data <= oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data <= oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data <= oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `LessOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator <= for type CCHAR_P
+//
+bool CDT::operator<=(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `LessOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() <= STLW::string(oValue);
+}
+
+//
+// Operator < for type STLW::string
+//
+bool CDT::operator<=(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `LessOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() <= oValue;
+}
+
+//
+// Operator <= for type CDT
+//
+bool CDT::operator<=(const CDT & oCDT) const
+{
+ if (eValueType == UNDEF && oCDT.eValueType == UNDEF)
+ {
+ return true;
+ }
+ // Integer-to-Integer
+ else if ((eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetInt() <= oCDT.GetInt();
+ }
+ // (Integer, Real, String+Integer, String+Real)-to-(Integer, Real, String+Integer, String+Real)
+ else if ((eValueType == REAL_VAL || eValueType == STRING_REAL_VAL ||
+ eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == REAL_VAL || oCDT.eValueType == STRING_REAL_VAL ||
+ oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetFloat() <= oCDT.GetFloat();
+ }
+ // (String, String+Integer, String+Real)-to-(String, String+Integer, String+Real)
+ else if ((eValueType == STRING_VAL || eValueType == STRING_REAL_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == STRING_VAL || oCDT.eValueType == STRING_REAL_VAL || oCDT.eValueType == STRING_INT_VAL))
+ {
+ return *(u.p_data -> u.s_data) <= *(oCDT.u.p_data -> u.s_data);
+ }
+ else if (eValueType == POINTER_VAL && oCDT.eValueType == POINTER_VAL)
+ {
+ return u.pp_data <= oCDT.u.pp_data;
+ }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `LessOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Operator >= for type INT_32
+//
+bool CDT::operator>=(const INT_64 oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data >= oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data >= oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data >= oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data >= oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and INTEGER data types. Use `GreaterOrEqual`, `LE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator >= for type UINT_32
+//
+bool CDT::operator>=(const UINT_64 oValue) const { return operator>=(INT_64(oValue)); }
+
+//
+// Operator >= for type INT_32
+//
+bool CDT::operator>=(const INT_32 oValue) const { return operator>=(INT_64(oValue)); }
+
+//
+// Operator >= for type UINT_32
+//
+bool CDT::operator>=(const UINT_32 oValue) const { return operator>=(UINT_64(oValue)); }
+
+//
+// Operator >= for type W_FLOAT
+//
+bool CDT::operator>=(const W_FLOAT oValue) const
+{
+ if (eValueType == INT_VAL) { return u.i_data >= oValue; }
+ else if (eValueType == REAL_VAL) { return u.d_data >= oValue; }
+ else if (eValueType == STRING_INT_VAL) { return u.p_data -> uc.i_data >= oValue; }
+ else if (eValueType == STRING_REAL_VAL) { return u.p_data -> uc.d_data >= oValue; }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and REAL data types. Use `GreaterOrEqual`, `GE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Operator >= for type CCHAR_P
+//
+bool CDT::operator>=(CCHAR_P oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `GreaterOrEqual`, `GE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() >= STLW::string(oValue);
+}
+
+//
+// Operator >= for type STLW::string
+//
+bool CDT::operator>=(const STLW::string & oValue) const
+{
+#if THROW_EXCEPTION_IN_COMPARATORS
+ if (eValueType != STRING_VAL &&
+ eValueType != STRING_INT_VAL &&
+ eValueType != STRING_REAL_VAL)
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and STRING data types. Use `GreaterOrEqual`, `GE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+
+return GetString() >= oValue;
+}
+
+//
+// Operator >= for type CDT
+//
+bool CDT::operator>=(const CDT & oCDT) const
+{
+ if (eValueType == UNDEF && oCDT.eValueType == UNDEF)
+ {
+ return true;
+ }
+ // Integer-to-Integer
+ else if ((eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetInt() >= oCDT.GetInt();
+ }
+ // (Integer, Real, String+Integer, String+Real)-to-(Integer, Real, String+Integer, String+Real)
+ else if ((eValueType == REAL_VAL || eValueType == STRING_REAL_VAL ||
+ eValueType == INT_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == REAL_VAL || oCDT.eValueType == STRING_REAL_VAL ||
+ oCDT.eValueType == INT_VAL || oCDT.eValueType == STRING_INT_VAL)
+ )
+ {
+ return GetFloat() >= oCDT.GetFloat();
+ }
+ // (String, String+Integer, String+Real)-to-(String, String+Integer, String+Real)
+ else if ((eValueType == STRING_VAL || eValueType == STRING_REAL_VAL || eValueType == STRING_INT_VAL) &&
+ (oCDT.eValueType == STRING_VAL || oCDT.eValueType == STRING_REAL_VAL || oCDT.eValueType == STRING_INT_VAL))
+ {
+ return *(u.p_data -> u.s_data) >= *(oCDT.u.p_data -> u.s_data);
+ }
+ else if (eValueType == POINTER_VAL && oCDT.eValueType == POINTER_VAL)
+ {
+ return u.pp_data >= oCDT.u.pp_data;
+ }
+#if THROW_EXCEPTION_IN_COMPARATORS
+ else
+ {
+ STLW::string sError("Can't compare ");
+ sError.append(PrintableType());
+ sError.append(" and ");
+ sError.append(oCDT.PrintableType());
+ sError.append(" data types. Use `GreaterOrEqual`, `GE` method instead.");
+
+ throw CTPPLogicError(sError.c_str());
+ }
+#endif
+return false;
+}
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const INT_64 oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() == oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const UINT_64 oValue) const { return Equal(INT_64(oValue)); }
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const INT_32 oValue) const { return Equal(INT_64(oValue)); }
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const UINT_32 oValue) const { return Equal(UINT_64(oValue)); }
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const W_FLOAT oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() == oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Equal for old-fashion string argument
+//
+bool CDT::Equal(CCHAR_P oValue) const { return GetString() == STLW::string(oValue); }
+
+//
+// Comparator Equal for string argument
+//
+bool CDT::Equal(const STLW::string & oValue) const { return GetString() == oValue; }
+
+//
+// Comparator Equal for CDT argument
+//
+bool CDT::Equal(const CDT & oCDT) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ {
+ switch(oCDT.eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ return GetFloat() == oCDT.GetFloat();
+
+ case STRING_VAL:
+ return GetString() == oCDT.GetString();
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+ return false;
+ }
+ case STRING_VAL:
+ return GetString() == oCDT.GetString();
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+
+return false;
+}
+// Comparator NotEqual ///////////////////////////////////
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const INT_64 oValue) const { return ! Equal(INT_64(oValue)); }
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const UINT_64 oValue) const { return ! Equal(INT_64(oValue)); }
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const INT_32 oValue) const { return ! Equal(INT_64(oValue)); }
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const UINT_32 oValue) const { return ! Equal(UINT_64(oValue)); }
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const W_FLOAT oValue) const { return ! Equal(oValue); }
+
+//
+// Comparator NotEqual for old-fashion string argument
+//
+bool CDT::NotEqual(CCHAR_P oValue) const { return ! Equal(oValue); }
+
+//
+// Comparator NotEqual for string argument
+//
+bool CDT::NotEqual(const STLW::string & oValue) const { return ! Equal(oValue); }
+
+//
+// Comparator NotEqual for CDT argument
+//
+bool CDT::NotEqual(const CDT & oCDT) const { return ! Equal(oCDT); }
+
+// Comparator Greater ///////////////////////////////////
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const INT_64 oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() > oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const UINT_64 oValue) const { return Greater(INT_64(oValue)); }
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const INT_32 oValue) const { return Greater(INT_64(oValue)); }
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const UINT_32 oValue) const { return Greater(UINT_64(oValue)); }
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const W_FLOAT oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() > oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Greater for old-fashion string argument
+//
+bool CDT::Greater(CCHAR_P oValue) const { return GetString() > STLW::string(oValue); }
+
+//
+// Comparator Greater for string argument
+//
+bool CDT::Greater(const STLW::string & oValue) const { return GetString() > oValue; }
+
+//
+// Comparator Greater for CDT argument
+//
+bool CDT::Greater(const CDT & oCDT) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ {
+ switch(oCDT.eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ return GetFloat() > oCDT.GetFloat();
+
+ case STRING_VAL:
+ return GetString() > oCDT.GetString();
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+ return false;
+ }
+ case STRING_VAL:
+ return GetString() > oCDT.GetString();
+
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+
+return false;
+}
+
+// Comparator Less ///////////////////////////////////
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const INT_64 oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() < oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const UINT_64 oValue) const { return Less(INT_64(oValue)); }
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const INT_32 oValue) const { return Less(INT_64(oValue)); }
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const UINT_32 oValue) const { return Less(UINT_64(oValue)); }
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const W_FLOAT oValue) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ return GetFloat() < oValue;
+
+ case ARRAY_VAL:
+ case HASH_VAL:
+ default:
+ return false;
+ }
+
+return false;
+}
+
+//
+// Comparator Less for old-fashion string argument
+//
+bool CDT::Less(CCHAR_P oValue) const { return GetString() < STLW::string(oValue); }
+
+//
+// Comparator Less for string argument
+//
+bool CDT::Less(const STLW::string & oValue) const { return GetString() < oValue; }
+
+//
+// Comparator Less for CDT argument
+//
+bool CDT::Less(const CDT & oCDT) const
+{
+ switch(eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ {
+ switch(oCDT.eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ return GetFloat() < oCDT.GetFloat();
+
+ case STRING_VAL:
+ return GetString() < oCDT.GetString();
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+ return false;
+ }
+ case STRING_VAL:
+ return GetString() < oCDT.GetString();
+
+ /*
+ case ARRAY_VAL:
+ case HASH_VAL:
+ */
+ default:
+ return false;
+ }
+
+return false;
+}
+
+// Comparator GreaterOrEqual ///////////////////////////////////
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const INT_64 oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const UINT_64 oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const INT_32 oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const UINT_32 oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const W_FLOAT oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for old-fashion string argument
+//
+bool CDT::GreaterOrEqual(CCHAR_P oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for string argument
+//
+bool CDT::GreaterOrEqual(const STLW::string & oValue) const { return ! Less(oValue); }
+
+//
+// Comparator GreaterOrEqual for CDT argument
+//
+bool CDT::GreaterOrEqual(const CDT & oCDT) const { return ! Less(oCDT); }
+
+// Comparator LessOrEqual ///////////////////////////////////
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const INT_64 oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const UINT_64 oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const INT_32 oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const UINT_32 oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const W_FLOAT oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for old-fashion string argument
+//
+bool CDT::LessOrEqual(CCHAR_P oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for string argument
+//
+bool CDT::LessOrEqual(const STLW::string & oValue) const { return ! Greater(oValue); }
+
+//
+// Comparator LessOrEqual for CDT argument
+//
+bool CDT::LessOrEqual(const CDT & oCDT) const { return ! Greater(oCDT); }
+
+//
+// Pre-increment operator ++
+//
+CDT & CDT::operator++()
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ ++u.i_data;
+ break;
+
+ case REAL_VAL:
+ ++u.d_data;
+ break;
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == INT_VAL) { (*this) = CDT(++iData1); }
+ else { (*this) = CDT(++dData1); }
+
+ }
+ break;
+
+ case STRING_INT_VAL:
+ {
+ INT_64 iData1 = u.p_data -> uc.i_data;
+ (*this) = CDT(++iData1);
+ }
+ break;
+
+ case STRING_REAL_VAL:
+ {
+ W_FLOAT dData1 = u.p_data -> uc.d_data;
+ (*this) = CDT(++dData1);
+ }
+ break;
+
+ default:
+ throw CDTTypeCastException("pre-increment operator ++");
+ }
+
+return *this;
+}
+
+//
+// Post-increment operator ++
+//
+CDT CDT::operator++(int)
+{
+ CDT oTMP(*this);
+
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ ++u.i_data;
+ break;
+
+ case REAL_VAL:
+ ++u.d_data;
+ break;
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == INT_VAL) { (*this) = CDT(++iData1); }
+ else { (*this) = CDT(++dData1); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ {
+ INT_64 iData1 = u.p_data -> uc.i_data;
+ (*this) = CDT(++iData1);
+ }
+ break;
+
+ case STRING_REAL_VAL:
+ {
+ W_FLOAT dData1 = u.p_data -> uc.d_data;
+ (*this) = CDT(++dData1);
+ }
+ break;
+
+ default:
+ throw CDTTypeCastException("post-increment operator ++");
+ }
+
+return oTMP;
+}
+
+//
+// Pre-decrement operator --
+//
+CDT & CDT::operator--()
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ --u.i_data;
+ break;
+
+ case REAL_VAL:
+ --u.d_data;
+ break;
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == INT_VAL) { (*this) = CDT(--iData1); }
+ else { (*this) = CDT(--dData1); }
+
+ }
+ break;
+
+ case STRING_INT_VAL:
+ {
+ INT_64 iData1 = u.p_data -> uc.i_data;
+ (*this) = CDT(--iData1);
+ }
+ break;
+
+ case STRING_REAL_VAL:
+ {
+ W_FLOAT dData1 = u.p_data -> uc.d_data;
+ (*this) = CDT(--dData1);
+ }
+ break;
+
+ default:
+ throw CDTTypeCastException("pre-decrement operator --");
+ }
+return *this;
+}
+
+//
+// Post-decrement operator --
+//
+CDT CDT::operator--(int)
+{
+ CDT oTMP(*this);
+
+ switch (eValueType)
+ {
+ case UNDEF:
+ break;
+
+ case INT_VAL:
+ --u.i_data;
+ break;
+
+ case REAL_VAL:
+ --u.d_data;
+ break;
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == INT_VAL) { (*this) = CDT(--iData1); }
+ else { (*this) = CDT(--dData1); }
+ }
+ break;
+
+ case STRING_INT_VAL:
+ {
+ INT_64 iData1 = u.p_data -> uc.i_data;
+ (*this) = CDT(--iData1);
+ }
+ break;
+
+ case STRING_REAL_VAL:
+ {
+ W_FLOAT dData1 = u.p_data -> uc.d_data;
+ (*this) = CDT(--dData1);
+ }
+ break;
+
+ default:
+ throw CDTTypeCastException("post-decrement operator --");
+ }
+
+return oTMP;
+}
+
+//
+// Append a string to CDT
+//
+CDT & CDT::Concat(const STLW::string & oValue)
+{
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(oValue));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(GetString() + oValue);
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ u.p_data -> u.s_data -> append(oValue);
+ }
+ else { throw CDTTypeCastException("Concat"); }
+
+return *this;
+}
+
+//
+// Append a old-fashion string to CDT
+//
+CDT & CDT::Concat(CCHAR_P szData, const INT_32 iDataLength)
+{
+ if (iDataLength == -1) { return Concat(STLW::string(szData)); }
+
+return Concat(STLW::string(szData, iDataLength));
+}
+
+//
+// Append a string to CDT, alias for Concat
+//
+CDT & CDT::Append(const STLW::string & oValue) { return Concat(oValue); }
+
+//
+// Append a old-fashion string to CDT
+//
+CDT & CDT::Append(CCHAR_P szData, const INT_32 iDataLength) { return Concat(szData, iDataLength); }
+
+//
+// Append a INT_64 to CDT
+//
+CDT & CDT::Append(const INT_64 oValue)
+{
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ UINT_32 iLen = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%lli", (long long) (oValue));
+
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(szBuf, iLen));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(GetString());
+ sTMP.append(szBuf, iLen);
+
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ u.p_data -> u.s_data -> append(szBuf, iLen);
+ }
+ else { throw CDTTypeCastException("Append"); }
+
+return *this;
+}
+
+//
+// Append a INT_64 to CDT
+//
+CDT & CDT::Append(const UINT_64 oValue) { return Append(INT_64(oValue)); }
+
+//
+// Prepend a INT_32 to CDT
+//
+CDT & CDT::Append(const INT_32 oValue) { return Append(INT_64(oValue)); }
+
+//
+// Prepend a UINT_32 to CDT
+//
+CDT & CDT::Append(const UINT_32 oValue) { return Append(INT_64(oValue)); }
+
+//
+// Prepend a W_FLOAT to CDT
+//
+CDT & CDT::Append(const W_FLOAT oValue)
+{
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ UINT_32 iLen = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%.*G", CTPP_FLOAT_PRECISION, oValue);
+
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(szBuf, iLen));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(GetString());
+ sTMP.append(szBuf, iLen);
+
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ u.p_data -> u.s_data -> append(szBuf, iLen);
+ }
+ else { throw CDTTypeCastException("Append"); }
+
+return *this;
+}
+
+//
+// Append a string to CDT
+//
+CDT & CDT::Append(const CDT & oCDT)
+{
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(oCDT.GetString()));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(GetString() + oCDT.GetString());
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ u.p_data -> u.s_data -> append(oCDT.GetString());
+ }
+ else { throw CDTTypeCastException("Append"); }
+
+return *this;
+}
+
+//
+// Prepend a old-fashion string to CDT
+//
+CDT & CDT::Prepend(CCHAR_P szData, const INT_32 iDataLength)
+{
+ if (iDataLength == -1) { return Prepend(STLW::string(szData)); }
+
+return Prepend(STLW::string(szData, iDataLength));
+}
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const STLW::string & oValue)
+{
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(oValue));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(oValue + GetString());
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ STLW::string sTMP = oValue;
+ sTMP.append(*(u.p_data -> u.s_data));
+ u.p_data -> u.s_data -> assign(sTMP);
+ }
+ else { throw CDTTypeCastException("Prepend"); }
+
+return *this;
+}
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const INT_64 oValue)
+{
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ UINT_32 iLen = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%lli", (long long) (oValue));
+
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(szBuf, iLen));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(STLW::string(szBuf, iLen).append(GetString()));
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ STLW::string sTMP(szBuf, iLen);
+ sTMP.append(*(u.p_data -> u.s_data));
+ u.p_data -> u.s_data -> assign(sTMP);
+ }
+ else { throw CDTTypeCastException("Prepend"); }
+
+return *this;
+}
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const UINT_64 oValue) { return Prepend(INT_64(oValue)); }
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const INT_32 oValue) { return Prepend(INT_64(oValue)); }
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const UINT_32 oValue) { return Prepend(UINT_64(oValue)); }
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const W_FLOAT oValue)
+{
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ UINT_32 iLen = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%.*G", CTPP_FLOAT_PRECISION, oValue);
+
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(STLW::string(szBuf, iLen));
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(STLW::string(szBuf, iLen).append(GetString()));
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ STLW::string sTMP(szBuf, iLen);
+ sTMP.append(*(u.p_data -> u.s_data));
+ u.p_data -> u.s_data -> assign(sTMP);
+ }
+ else { throw CDTTypeCastException("Prepend"); }
+
+return *this;
+}
+
+//
+// Prepend a string to CDT
+//
+CDT & CDT::Prepend(const CDT & oCDT)
+{
+ if (eValueType == UNDEF)
+ {
+ (*this) = CDT(oCDT.GetString());
+ }
+ else if (eValueType == INT_VAL ||
+ eValueType == REAL_VAL)
+ {
+ STLW::string sTMP(oCDT.GetString() + GetString());
+ (*this) = CDT(sTMP);
+ }
+ else if (eValueType == STRING_VAL ||
+ eValueType == STRING_INT_VAL ||
+ eValueType == STRING_REAL_VAL)
+ {
+ Unshare();
+ STLW::string sTMP = oCDT.GetString();
+ sTMP.append(*(u.p_data -> u.s_data));
+ u.p_data -> u.s_data -> assign(sTMP);
+ }
+ else { throw CDTTypeCastException("Prepend"); }
+
+return *this;
+}
+
+//
+// Get value as W_FLOAT
+//
+W_FLOAT CDT::GetFloat() const
+{
+ switch (eValueType)
+ {
+ case INT_VAL:
+ return W_FLOAT(u.i_data);
+
+ case REAL_VAL:
+ return u.d_data;
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == REAL_VAL) { return dData1; }
+
+ return W_FLOAT(iData1);
+ }
+
+ case STRING_INT_VAL:
+ return W_FLOAT(u.p_data -> uc.i_data);
+
+ case STRING_REAL_VAL:
+ return u.p_data -> uc.d_data;
+
+ case POINTER_VAL:
+ return W_FLOAT((INT_64)(u.pp_data));
+
+ default:
+ return 0.0;
+ }
+}
+
+//
+// Get value as INT_64
+//
+INT_64 CDT::GetInt() const
+{
+ switch (eValueType)
+ {
+ case INT_VAL:
+ return u.i_data;
+
+ case REAL_VAL:
+ return INT_64(u.d_data);
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == REAL_VAL) { return INT_64(dData1); }
+
+ return iData1;
+ }
+
+ case STRING_INT_VAL:
+ return u.p_data -> uc.i_data;
+
+ case STRING_REAL_VAL:
+ return INT_64(u.p_data -> uc.d_data);
+
+ case POINTER_VAL:
+ return (INT_64)(u.pp_data);
+
+ default:
+ return 0;
+ }
+}
+
+//
+// Get value as UINT_64
+//
+UINT_64 CDT::GetUInt() const
+{
+ switch (eValueType)
+ {
+ case INT_VAL:
+ return u.i_data;
+
+ case REAL_VAL:
+ return INT_64(u.d_data);
+
+ case STRING_VAL:
+ {
+ INT_64 iData1;
+ W_FLOAT dData1;
+ if (CastToNumber(iData1, dData1) == REAL_VAL) { return UINT_64(dData1); }
+
+ return iData1;
+ }
+
+ case STRING_INT_VAL:
+ return u.p_data -> uc.i_data;
+
+ case STRING_REAL_VAL:
+ return UINT_64(u.p_data -> uc.d_data);
+
+ default:
+ return 0;
+ }
+}
+
+//
+// Cast value to W_FLOAT
+//
+W_FLOAT CDT::ToFloat()
+{
+ W_FLOAT dTMP = GetFloat();
+ (*this) = CDT(dTMP);
+
+return dTMP;
+}
+
+//
+// Cast value to INT_64
+//
+INT_64 CDT::ToInt()
+{
+ const INT_64 iTMP = GetInt();
+ (*this) = CDT(iTMP);
+
+return iTMP;
+}
+
+//
+// Cast value to STLW::string
+//
+STLW::string CDT::ToString(CCHAR_P szFormat)
+{
+ const STLW::string sTMP = GetString(szFormat);
+ (*this) = CDT(sTMP);
+
+return sTMP;
+}
+
+//
+// Get value as string
+//
+STLW::string CDT::GetString(CCHAR_P szFormat) const
+{
+ switch (eValueType)
+ {
+ case INT_VAL:
+ {
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ if (szFormat != NULL && *szFormat != '\0')
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, szFormat, (long long) (u.i_data));
+ }
+ else
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%lli", (long long) (u.i_data));
+ }
+
+ return szBuf;
+ }
+
+ case REAL_VAL:
+ {
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ if (szFormat != NULL && *szFormat != '\0')
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, szFormat, u.d_data);
+ }
+ else
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%.*G", CTPP_FLOAT_PRECISION, u.d_data);
+ }
+ return szBuf;
+ }
+
+ case POINTER_VAL:
+ {
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ if (szFormat != NULL && *szFormat != '\0')
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, szFormat, u.pp_data);
+ }
+ else
+ {
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%p", u.pp_data);
+ }
+ return szBuf;
+ }
+
+
+ case STRING_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ return *(u.p_data -> u.s_data);
+
+ case ARRAY_VAL:
+ {
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "ARRAY (%p)", (void *)(u.p_data -> u.s_data));
+ return szBuf;
+ }
+
+ case HASH_VAL:
+ {
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+ snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "HASH (%p)", (void *)(u.p_data -> u.s_data));
+ return szBuf;
+ }
+
+ default:
+ return "";
+ }
+}
+
+//
+// Get generic pointer
+//
+const void * CDT::GetPointer() const
+{
+ if (eValueType != POINTER_VAL) { return NULL; }
+
+return u.pp_data;
+}
+
+//
+// Get generic pointer
+//
+void * CDT::GetPointer()
+{
+ if (eValueType != POINTER_VAL) { return NULL; }
+
+return u.pp_data;
+}
+
+//
+// Dump CDT recursively to string
+//
+STLW::string CDT::Dump(UINT_32 iLevel, bool bGlobalFmt) const
+{
+ STLW::string sResult;
+ DumpData(iLevel, 0, *this, sResult, bGlobalFmt);
+ return sResult;
+}
+
+//
+// Dump CDT recursively to string
+//
+STLW::string CDT::RecursiveDump(UINT_32 iLevel) const
+{
+ return Dump(iLevel);
+}
+
+//
+// Dump to string
+//
+void CDT::DumpData(UINT_32 iLevel, UINT_32 iOffset, const CDT & oData, STLW::string &sResult, bool bGlobalFmt)
+{
+ bool bGlobalScope = bGlobalFmt && iLevel == 0;
+ ++iLevel;
+ switch (oData.GetType())
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case POINTER_VAL:
+ sResult += oData.GetString();
+ break;
+ case STRING_VAL:
+ sResult += "\"";
+ sResult += EscapeJSONString(oData.GetString(), true, false);
+ sResult += "\"";
+ break;
+
+ case ARRAY_VAL:
+ {
+ if (oData.Size() == 0) { sResult += "[ ]"; }
+ else
+ {
+ sResult += "[\n";
+ UINT_32 iI = 0;
+ for (;;)
+ {
+ sResult.append(iOffset + iLevel * 2, ' ');
+
+ DumpData(iLevel, iOffset, oData.GetCDT(iI), sResult);
+
+ ++iI;
+
+ if (iI == oData.Size()) { break; }
+ if (!bGlobalScope) { sResult += ",\n"; }
+ else { sResult += ";\n"; }
+ }
+ sResult.append("\n");
+ sResult.append(iOffset + (iLevel - 1) * 2, ' ');
+ sResult += "]";
+ }
+ }
+ break;
+
+ case HASH_VAL:
+ {
+ ConstIterator itHash = oData.Begin();
+ if (itHash == oData.End())
+ {
+ if (!bGlobalScope) { sResult += "{ }"; }
+ }
+ else
+ {
+ if (!bGlobalScope) { sResult += "{"; }
+ sResult += "\n";
+ for(;;)
+ {
+ sResult.append(iOffset + iLevel * 2, ' ');
+ if (!bGlobalScope) { sResult += "'"; }
+ else { sResult += " "; }
+ sResult += EscapeJSONString(itHash -> first, true, false);
+ INT_32 iExtraOffset = 0;
+ if (!bGlobalScope) { sResult += "' : "; }
+ else
+ {
+ sResult += " = ";
+ iExtraOffset = 1;
+ }
+ DumpData(iLevel, iOffset + itHash -> first.size() + 5 - iExtraOffset, itHash -> second, sResult);
+
+ ++itHash;
+
+ if (itHash == oData.End()) { break; }
+ if (!bGlobalScope) { sResult += ",\n"; }
+ else { sResult += ";\n"; }
+ }
+ sResult.append("\n");
+ sResult.append(iOffset + (iLevel - 1) * 2, ' ');
+ if (!bGlobalScope) { sResult += "}"; }
+ else { sResult += " "; }
+ }
+ }
+ break;
+
+ default:
+ sResult += "Invalid type";
+ }
+}
+
+//
+// Get value type of object
+//
+CDT::eValType CDT::GetType() const { return eValueType; }
+
+//
+// Get printable value type of object
+//
+CCHAR_P CDT::PrintableType() const { return PrintableType(eValueType); }
+
+//
+// Get printable value type
+//
+CCHAR_P CDT::PrintableType(eValType eType)
+{
+ switch(eType)
+ {
+ case UNDEF: return "*UNDEF*";
+ case INT_VAL: return "INTEGER";
+ case REAL_VAL: return "REAL";
+ case STRING_VAL: return "STRING";
+ case STRING_INT_VAL: return "STRING+INT";
+ case STRING_REAL_VAL: return "STRING+REAL";
+ case ARRAY_VAL: return "ARRAY";
+ case HASH_VAL: return "HASH";
+ case POINTER_VAL: return "POINTER";
+ default: return "???????";
+ }
+ // This should *NOT* happened;
+return NULL;
+}
+
+//
+// Get array or hash or string size
+//
+UINT_32 CDT::Size() const
+{
+ switch (eValueType)
+ {
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ return 0;
+ case STRING_VAL:
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ return u.p_data -> u.s_data -> size();
+
+ case ARRAY_VAL:
+ return u.p_data -> u.v_data -> size();
+
+ case HASH_VAL:
+ return u.p_data -> u.m_data -> size();
+
+ default:
+ return 0;
+ }
+
+return 0;
+}
+
+//
+// Swap values
+//
+CDT & CDT::Swap(CDT & oCDT)
+{
+ const CDT oTMP = oCDT;
+
+ oCDT = *this;
+
+ *this = oTMP;
+
+return *this;
+}
+
+//
+// Join array elements to string
+//
+STLW::string CDT::JoinArrayElements(const STLW::string & sDelimiter) const
+{
+ STLW::string sResult;
+
+ if (eValueType != ARRAY_VAL) { throw CDTAccessException(); }
+
+ Vector::const_iterator itvArray = u.p_data -> u.v_data -> begin();
+ const Vector::const_iterator itvEnd = u.p_data -> u.v_data -> end();
+
+ if (itvArray == itvEnd) { return sResult; }
+
+ for(;;)
+ {
+ sResult.append(itvArray -> GetString());
+ ++itvArray;
+ if (itvArray == itvEnd) { break; }
+ sResult.append(sDelimiter);
+ }
+
+return sResult;
+}
+
+//
+// Join hash keys
+//
+STLW::string CDT::JoinHashKeys(const STLW::string & sDelimiter) const
+{
+ STLW::string sResult;
+
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = u.p_data -> u.m_data -> end();
+
+ if (itmHash == itmEnd) { return sResult; }
+
+ for(;;)
+ {
+ sResult.append(itmHash -> first);
+ ++itmHash;
+ if (itmHash == itmEnd) { break; }
+ sResult.append(sDelimiter);
+ }
+
+return sResult;
+}
+
+//
+// Join hash values
+//
+STLW::string CDT::JoinHashValues(const STLW::string & sDelimiter) const
+{
+ STLW::string sResult;
+
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = u.p_data -> u.m_data -> end();
+
+ if (itmHash == itmEnd) { return sResult; }
+
+ for(;;)
+ {
+ sResult.append(itmHash -> second.GetString());
+ ++itmHash;
+ if (itmHash == itmEnd) { break; }
+ sResult.append(sDelimiter);
+ }
+
+return sResult;
+}
+
+//
+// Get hash keys
+//
+CDT CDT::GetHashKeys() const
+{
+ CDT oResult(CDT::ARRAY_VAL);
+
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = u.p_data -> u.m_data -> end();
+
+ while(itmHash != itmEnd)
+ {
+ oResult.PushBack(itmHash -> first);
+ ++itmHash;
+ }
+
+return oResult;
+}
+
+//
+// Get hash values
+//
+CDT CDT::GetHashValues() const
+{
+ CDT oResult(CDT::ARRAY_VAL);
+
+ if (eValueType != HASH_VAL) { throw CDTAccessException(); }
+
+ Map::const_iterator itmHash = u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = u.p_data -> u.m_data -> end();
+
+ while(itmHash != itmEnd)
+ {
+ oResult.PushBack(itmHash -> second);
+ ++itmHash;
+ }
+
+return oResult;
+}
+
+//
+// Merge two CDT's
+//
+void CDT::MergeCDT(const CDT & oSource, const eMergeStrategy & eStrategy)
+{
+ MergeCDT(*this, oSource, eStrategy);
+}
+
+//
+// Merge two CDT's
+//
+void CDT::MergeCDT(CDT & oDestination, const CDT & oSource, const eMergeStrategy & eStrategy)
+{
+ if (oDestination.eValueType == UNDEF)
+ {
+ oDestination = oSource;
+ }
+ else if (oDestination.eValueType == ARRAY_VAL)
+ {
+ // Unshare complex type
+ oDestination.Unshare();
+
+ // Special case for undef
+ if (oSource.eValueType == UNDEF) { return; }
+ // Array-to-array
+ else if (oSource.eValueType == ARRAY_VAL)
+ {
+ Vector::const_iterator itvArray = oSource.u.p_data -> u.v_data -> begin();
+ const Vector::const_iterator itvEnd = oSource.u.p_data -> u.v_data -> end();
+
+ while(itvArray != itvEnd)
+ {
+ oDestination.u.p_data -> u.v_data -> push_back(*itvArray);
+ ++itvArray;
+ }
+ }
+ // Hash-to-array
+ else if (oSource.eValueType == HASH_VAL)
+ {
+ Map::const_iterator itmHash = oSource.u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = oSource.u.p_data -> u.m_data -> end();
+
+ while(itmHash != itmEnd)
+ {
+ oDestination.u.p_data -> u.v_data -> push_back(itmHash -> first);
+ oDestination.u.p_data -> u.v_data -> push_back(itmHash -> second);
+ ++itmHash;
+ }
+ }
+ else { throw CDTAccessException(); }
+ }
+ else if (oDestination.eValueType == HASH_VAL)
+ {
+ // Unshare complex type
+ oDestination.Unshare();
+
+ if (eStrategy == FAST_MERGE)
+ {
+ // Special case for undef
+ if (oSource.eValueType == UNDEF) { return; }
+ // Array-to-hash
+ else if (oSource.eValueType == ARRAY_VAL)
+ {
+ Vector::const_iterator itvArray = oSource.u.p_data -> u.v_data -> begin();
+ const Vector::const_iterator itvEnd = oSource.u.p_data -> u.v_data -> end();
+
+ for (;;)
+ {
+ Vector::const_iterator itvKey = itvArray;
+ ++itvArray;
+ if (itvArray == itvEnd)
+ {
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itvKey -> GetString(), CDT()));
+ break;
+ }
+
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itvKey -> GetString(), *itvArray));
+
+ ++itvArray;
+ if (itvArray == itvEnd) { break; }
+ }
+ }
+ // Hash-to-hash
+ else if (oSource.eValueType == HASH_VAL)
+ {
+ Map::const_iterator itmHash = oSource.u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = oSource.u.p_data -> u.m_data -> end();
+
+ while(itmHash != itmEnd)
+ {
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itmHash -> first, itmHash -> second));
+ ++itmHash;
+ }
+ }
+ else { throw CDTAccessException(); }
+
+ return;
+ }
+ // DEEP_MERGE
+
+ // Special case for undef
+ if (oSource.eValueType == UNDEF) { return; }
+ // Array-to-hash
+ else if (oSource.eValueType == ARRAY_VAL)
+ {
+ Vector::const_iterator itvArray = oSource.u.p_data -> u.v_data -> begin();
+ const Vector::const_iterator itvEnd = oSource.u.p_data -> u.v_data -> end();
+
+ for (;;)
+ {
+ Vector::const_iterator itvKey = itvArray;
+ ++itvArray;
+ if (itvArray == itvEnd)
+ {
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itvKey -> GetString(), CDT()));
+ break;
+ }
+
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itvKey -> GetString(), *itvArray));
+
+ ++itvArray;
+ if (itvArray == itvEnd) { break; }
+ }
+ }
+ // Hash-to-hash
+ else if (oSource.eValueType == HASH_VAL)
+ {
+ Map::const_iterator itmHash = oSource.u.p_data -> u.m_data -> begin();
+ const Map::const_iterator itmEnd = oSource.u.p_data -> u.m_data -> end();
+
+ while(itmHash != itmEnd)
+ {
+ Map::iterator itmElement = oDestination.u.p_data -> u.m_data -> find(itmHash -> first);
+ if (itmElement == oDestination.u.p_data -> u.m_data -> end())
+ {
+ oDestination.u.p_data -> u.m_data -> insert(STLW::pair<String, CDT>(itmHash -> first, itmHash -> second));
+ }
+ else
+ {
+ MergeCDT(itmElement -> second, itmHash -> second, eStrategy);
+ }
+ ++itmHash;
+ }
+ }
+ else { throw CDTAccessException(); }
+ }
+ else { throw CDTAccessException(); }
+}
+
+//
+// Quick sort ARRAY
+//
+void CDT::SortArray(const CDT::SortingComparator & oSortingComparator)
+{
+ if (eValueType != ARRAY_VAL || u.p_data -> u.v_data -> size() <= 1) { return; }
+
+ STLW::sort(u.p_data -> u.v_data -> begin(), u.p_data -> u.v_data -> end(), SortHelper(oSortingComparator));
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// A destructor
+//
+CDT::SortingComparator::~SortingComparator() throw() { ;; }
+
+//
+// A destructor
+//
+CDT::~CDT() throw() { Destroy(); }
+
+//
+// Destroy object if need
+//
+void CDT::Destroy() throw()
+{
+ switch (eValueType)
+ {
+ // POD types
+ case UNDEF:
+ case INT_VAL:
+ case REAL_VAL:
+ case POINTER_VAL:
+ ;; // Nothing to do
+ break;
+
+ case STRING_INT_VAL:
+ case STRING_REAL_VAL:
+ case STRING_VAL:
+ -- (u.p_data -> refcount);
+ if (u.p_data -> refcount == 0)
+ {
+ delete u.p_data -> u.s_data;
+ delete u.p_data;
+ }
+ break;
+
+ case ARRAY_VAL:
+ -- (u.p_data -> refcount);
+ if (u.p_data -> refcount == 0)
+ {
+ delete u.p_data -> u.v_data;
+ delete u.p_data;
+ }
+ break;
+
+ case HASH_VAL:
+ -- (u.p_data -> refcount);
+ if (u.p_data -> refcount == 0)
+ {
+ delete u.p_data -> u.m_data;
+ delete u.p_data;
+ }
+ break;
+
+ default:
+ // R.I.P.
+ { int * pI = NULL; *pI = 0xDeadBeef; }
+ }
+}
+
+//
+// Unshare shareable container
+//
+void CDT::Unshare()
+{
+ if (u.p_data -> refcount != 1)
+ {
+ _CDT * pTMP = new _CDT();
+
+ if (eValueType == STRING_VAL) { pTMP -> u.s_data = new String(*(u.p_data -> u.s_data)); }
+ else if (eValueType == STRING_INT_VAL)
+ {
+ pTMP -> u.s_data = new String(*(u.p_data -> u.s_data));
+ pTMP -> uc.i_data = u.p_data -> uc.i_data;
+ }
+ else if (eValueType == STRING_REAL_VAL)
+ {
+ pTMP -> u.s_data = new String(*(u.p_data -> u.s_data));
+ pTMP -> uc.d_data = u.p_data -> uc.d_data;
+ }
+ else if (eValueType == ARRAY_VAL) { pTMP -> u.v_data = new Vector(*(u.p_data -> u.v_data)); }
+ else if (eValueType == HASH_VAL) { pTMP -> u.m_data = new Map(*(u.p_data -> u.m_data)); }
+
+ -- u.p_data -> refcount;
+ u.p_data = pTMP;
+ }
+}
+
+//
+// Try to cast value to integer or to IEEE floating point value
+//
+CDT::eValType CDT::CastToNumber(INT_64 & iData, W_FLOAT & dData) const
+{
+ iData = 0;
+ dData = 0.0;
+
+ switch (eValueType)
+ {
+ case UNDEF:
+ return INT_VAL;
+
+ case INT_VAL:
+ iData = u.i_data;
+ return INT_VAL;
+
+ case REAL_VAL:
+ dData = u.d_data;
+ return REAL_VAL;
+
+ case STRING_VAL:
+ {
+ CheckComplexDataType();
+ if (eValueType != STRING_VAL) { return CastToNumber(iData, dData); }
+
+ // Check integer only
+ String::const_iterator itStart = u.p_data -> u.s_data -> begin();
+ const String::const_iterator itEnd = u.p_data -> u.s_data -> end();
+ if (itStart == itEnd)
+ {
+ u.p_data -> uc.i_data = iData;
+ eValueType = STRING_INT_VAL;
+ u.p_data -> value_type = INT_VAL;
+ return INT_VAL;
+ }
+
+ // [-+]?[0-9]
+
+ // Check sign
+ if (*itStart == '-' || *itStart == '+') { ++itStart; }
+
+ // Check numbers
+ while (itStart != itEnd)
+ {
+ if (!(*itStart >= '0' && *itStart <= '9')) { break; }
+ ++itStart;
+ }
+
+ // Okay, it's integer
+ if (itStart == itEnd)
+ {
+ iData = strtoll(u.p_data -> u.s_data -> data(), NULL, 10);
+
+ u.p_data -> uc.i_data = iData;
+ eValueType = STRING_INT_VAL;
+ u.p_data -> value_type = INT_VAL;
+ return INT_VAL;
+ }
+
+ // [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?
+
+ // Check IEEE 754
+ if (*itStart == '.')
+ {
+ ++itStart;
+ if (itStart == itEnd)
+ {
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+
+ while (itStart != itEnd)
+ {
+ if (!(*itStart >= '0' && *itStart <= '9')) { break; }
+ ++itStart;
+ }
+ }
+ // Okay, it's real without exponent
+ if (itStart == itEnd)
+ {
+ dData = strtod(u.p_data -> u.s_data -> data(), NULL);
+
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+
+ // Check exponent
+ if (*itStart != 'e' && *itStart != 'E')
+ {
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+ ++itStart;
+
+ // Check exponent sign
+ if (itStart == itEnd)
+ {
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+
+ if (*itStart == '-' || *itStart == '+')
+ {
+ ++itStart;
+ if (itStart == itEnd)
+ {
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+ }
+
+ while (itStart != itEnd)
+ {
+ if (!(*itStart >= '0' && *itStart <= '9')) { break; }
+ ++itStart;
+ }
+
+ // Okay, it's real with exponent
+ if (itStart == itEnd)
+ {
+ dData = strtod(u.p_data -> u.s_data -> data(), NULL);
+
+ u.p_data -> uc.d_data = dData;
+ eValueType = STRING_REAL_VAL;
+ u.p_data -> value_type = REAL_VAL;
+ return REAL_VAL;
+ }
+
+ return REAL_VAL;
+ }
+
+ case STRING_INT_VAL:
+ iData = u.p_data -> uc.i_data;
+ return INT_VAL;
+
+ case STRING_REAL_VAL:
+ dData = u.p_data -> uc.d_data;
+ return REAL_VAL;
+
+ case ARRAY_VAL:
+ iData = u.p_data -> u.v_data -> size();
+ return INT_VAL;
+
+ case HASH_VAL:
+ iData = u.p_data -> u.m_data -> size();
+ return INT_VAL;
+
+ case POINTER_VAL:
+ iData = UINT_64(u.pp_data);
+ return INT_VAL;
+
+ default:
+ throw CDTTypeCastException("No such type");
+ }
+// Make compiler happy
+return INT_VAL;
+}
+
+//
+// Check complex data type and change value type, if need
+//
+void CDT::CheckComplexDataType() const
+{
+ if (u.p_data -> value_type == INT_VAL) { eValueType = STRING_INT_VAL; }
+ else if (u.p_data -> value_type == REAL_VAL) { eValueType = STRING_REAL_VAL; }
+}
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Standalone operators
+//
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Operator+
+//
+
+//
+// Operator + for UINT_64 and CDT arguments
+//
+CDT operator+(const UINT_64 & oValue, const CDT & oCDT) { return CDT(oValue).operator+(oCDT); }
+
+//
+// Operator + for INT_64 and CDT arguments
+//
+CDT operator+(const INT_64 & oValue, const CDT & oCDT) { return CDT(oValue).operator+(oCDT); }
+
+//
+// Operator + for UINT_32 and CDT arguments
+//
+CDT operator+(const UINT_32 & oValue, const CDT & oCDT) { return CDT(oValue).operator+(oCDT); }
+
+//
+// Operator + for INT_32 and CDT arguments
+//
+CDT operator+(const INT_32 & oValue, const CDT & oCDT) { return CDT(oValue).operator+(oCDT); }
+
+//
+// Operator + for W_FLOAT and CDT arguments
+//
+CDT operator+(const W_FLOAT & oValue, const CDT & oCDT) { return CDT(oValue).operator+(oCDT); }
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Operator-
+//
+
+//
+// Operator - for UINT_64 and CDT arguments
+//
+CDT operator-(const UINT_64 & oValue, const CDT & oCDT) { return CDT(oValue).operator-(oCDT); }
+
+//
+// Operator - for INT_64 and CDT arguments
+//
+CDT operator-(const INT_64 & oValue, const CDT & oCDT) { return CDT(oValue).operator-(oCDT); }
+
+//
+// Operator - for UINT_32 and CDT arguments
+//
+CDT operator-(const UINT_32 & oValue, const CDT & oCDT) { return CDT(oValue).operator-(oCDT); }
+
+//
+// Operator - for INT_32 and CDT arguments
+//
+CDT operator-(const INT_32 & oValue, const CDT & oCDT) { return CDT(oValue).operator-(oCDT); }
+
+//
+// Operator - for W_FLOAT and CDT arguments
+//
+CDT operator-(const W_FLOAT & oValue, const CDT & oCDT) { return CDT(oValue).operator-(oCDT); }
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Operator*
+//
+
+//
+// Operator * for UINT_64 and CDT arguments
+//
+CDT operator*(const UINT_64 & oValue, const CDT & oCDT) { return CDT(oCDT).operator*(oValue); }
+
+//
+// Operator * for INT_64 and CDT arguments
+//
+CDT operator*(const INT_64 & oValue, const CDT & oCDT) { return CDT(oCDT).operator*(oValue); }
+
+//
+// Operator * for UINT_32 and CDT arguments
+//
+CDT operator*(const UINT_32 & oValue, const CDT & oCDT) { return CDT(oCDT).operator*(oValue); }
+
+//
+// Operator * for INT_32 and CDT arguments
+//
+CDT operator*(const INT_32 & oValue, const CDT & oCDT) { return CDT(oCDT).operator*(oValue); }
+
+//
+// Operator * for W_FLOAT and CDT arguments
+//
+CDT operator*(const W_FLOAT & oValue, const CDT & oCDT) { return CDT(oCDT).operator*(oValue); }
+
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Operator/
+//
+
+//
+// Operator / for UINT_64 and CDT arguments
+//
+CDT operator/(const UINT_64 & oValue, const CDT & oCDT) { return CDT(oCDT).operator/(oValue); }
+
+//
+// Operator / for INT_64 and CDT arguments
+//
+CDT operator/(const INT_64 & oValue, const CDT & oCDT) { return CDT(oCDT).operator/(oValue); }
+
+//
+// Operator / for UINT_32 and CDT arguments
+//
+CDT operator/(const UINT_32 & oValue, const CDT & oCDT) { return CDT(oCDT).operator/(oValue); }
+
+//
+// Operator / for INT_32 and CDT arguments
+//
+CDT operator/(const INT_32 & oValue, const CDT & oCDT) { return CDT(oCDT).operator/(oValue); }
+
+//
+// Operator / for W_FLOAT and CDT arguments
+//
+CDT operator/(const W_FLOAT & oValue, const CDT & oCDT) { return CDT(oCDT).operator/(oValue); }
+} // namespace CTPP
+// End.
diff --git a/src/CDTSortRoutines.cpp b/src/CDTSortRoutines.cpp
new file mode 100644
index 0000000..c92621b
--- /dev/null
+++ b/src/CDTSortRoutines.cpp
@@ -0,0 +1,239 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDT.cpp
+ *
+ * $CTPP$
+ */
+#include "CDTSortRoutines.hpp"
+
+#include <stdio.h>
+
+namespace CTPP
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareNum
+//
+
+//
+// Constructor
+//
+SortCompareNum::SortCompareNum(const CDT::SortingComparator::eSortingDirection & eIDirection): eDirection(eIDirection) { ;; }
+
+//
+// Compare two values.
+//
+bool SortCompareNum::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ if (oX < oY) { iRC = -1; }
+ else if (oX > oY) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A destructor
+//
+SortCompareNum::~SortCompareNum() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareStr
+//
+
+//
+// Constructor
+//
+SortCompareStr::SortCompareStr(const CDT::SortingComparator::eSortingDirection & eIDirection): eDirection(eIDirection) { ;; }
+
+//
+// Compare two values.
+//
+bool SortCompareStr::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ if (oX.Less(oY)) { iRC = -1; }
+ else if (oX.Greater(oY)) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A destructor
+//
+SortCompareStr::~SortCompareStr() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareNumHashElement
+//
+
+//
+// Constructor
+//
+SortCompareNumHashElement::SortCompareNumHashElement(const STLW::string & sIKey,
+ const CDT::SortingComparator::eSortingDirection & eIDirection): sKey(sIKey),
+ eDirection(eIDirection) { ;; }
+
+//
+// Compare two values.
+//
+bool SortCompareNumHashElement::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ const CDT & oXX = oX.GetCDT(sKey);
+ const CDT & oYY = oY.GetCDT(sKey);
+
+ if (oXX < oYY) { iRC = -1; }
+ else if (oXX > oYY) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A dertructor
+//
+SortCompareNumHashElement::~SortCompareNumHashElement() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareStrHashElement
+//
+
+//
+// Constructor
+//
+SortCompareStrHashElement::SortCompareStrHashElement(const STLW::string & sIKey,
+ const CDT::SortingComparator::eSortingDirection & eIDirection): sKey(sIKey),
+ eDirection(eIDirection) { ;; }
+
+//
+// Compare two values.
+//
+bool SortCompareStrHashElement::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ const CDT & oXX = oX.GetCDT(sKey);
+ const CDT & oYY = oY.GetCDT(sKey);
+
+ if (oXX.Less(oYY)) { iRC = -1; }
+ else if (oXX.Greater(oYY)) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A destructor
+//
+SortCompareStrHashElement::~SortCompareStrHashElement() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareNumArrayElement
+//
+
+//
+// Constructor
+//
+SortCompareNumArrayElement::SortCompareNumArrayElement(const UINT_32 iIIndex,
+ const CDT::SortingComparator::eSortingDirection & eIDirection): iIndex(iIIndex),
+ eDirection(eIDirection) { ;; }
+
+//
+// Compare two values.
+//
+bool SortCompareNumArrayElement::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ const CDT & oXX = oX.GetCDT(iIndex);
+ const CDT & oYY = oY.GetCDT(iIndex);
+
+ if (oXX < oYY) { iRC = -1; }
+ else if (oXX > oYY) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A destructor
+//
+SortCompareNumArrayElement::~SortCompareNumArrayElement() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class SortCompareStrArrayElement
+//
+
+//
+// Constructor
+//
+SortCompareStrArrayElement::SortCompareStrArrayElement(const UINT_32 iIIndex,
+ const CDT::SortingComparator::eSortingDirection & eIDirection): iIndex(iIIndex),
+ eDirection(eIDirection) { ;; }
+//
+// Compare two values.
+//
+bool SortCompareStrArrayElement::operator()(const CDT & oX, const CDT & oY) const
+{
+ INT_32 iRC = 0;
+
+ const CDT & oXX = oX.GetCDT(iIndex);
+ const CDT & oYY = oY.GetCDT(iIndex);
+
+ if (oXX.Less(oYY)) { iRC = -1; }
+ else if (oXX.Greater(oYY)) { iRC = 1; }
+
+ if (eDirection == CDT::SortingComparator::DESC) { iRC = -iRC; }
+
+return iRC < 0;
+}
+
+//
+// A destructor
+//
+SortCompareStrArrayElement::~SortCompareStrArrayElement() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2BitIndex.cpp b/src/CTPP2BitIndex.cpp
new file mode 100644
index 0000000..30a46f7
--- /dev/null
+++ b/src/CTPP2BitIndex.cpp
@@ -0,0 +1,172 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2BitIndex.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2BitIndex.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+ReducedBitIndex::ReducedBitIndex(const BitIndexData * aIData): aData(aIData) { ;; }
+
+//
+// Get index data
+//
+const BitIndexData * ReducedBitIndex::GetIndexData() const { return aData; }
+
+//
+// Get number of used bytes in index
+//
+UINT_32 ReducedBitIndex::GetUsedSize() const { return UINT_32(aData -> size); }
+
+//
+// Get bit from index
+//
+CHAR_8 ReducedBitIndex::GetBit(const UINT_32 iOffset) const
+{
+ UINT_32 iBytePos = iOffset >> 3;
+
+ if (iBytePos >= aData -> size) { return 0; }
+
+ UINT_32 iBitPos = iOffset & 7;
+ CHAR_8 iResult = aData -> data[iBytePos];
+
+return (iResult & (1 << iBitPos));
+}
+
+//
+// A destructor
+//
+ReducedBitIndex::~ReducedBitIndex() throw() { ;; }
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class BitIndex
+//
+
+//
+// Constructor
+//
+BitIndex::BitIndex(const UINT_32 iSize): aData(NULL)
+{
+ UINT_32 iRealSize = (iSize >> 3) + 1;
+
+ void * vTMP = malloc(sizeof(UINT_64) + iRealSize);
+
+ memset(vTMP, 0, sizeof(UINT_64) + iRealSize);
+
+ aData = (BitIndexData *)vTMP;
+
+ aData -> size = 0;
+ iMaxSize = iRealSize;
+}
+
+//
+// Get index data
+//
+const BitIndexData * BitIndex::GetIndexData() const { return aData; }
+
+//
+// Get number of used bytes in index
+//
+UINT_32 BitIndex::GetUsedSize() const { return UINT_32(aData -> size); }
+
+//
+// Get bit from index
+//
+CHAR_8 BitIndex::GetBit(const UINT_32 iOffset) const
+{
+ UINT_32 iBytePos = iOffset >> 3;
+
+ if (iBytePos >= iMaxSize) { return 0; }
+
+ UINT_32 iBitPos = iOffset & 7;
+ CHAR_8 iResult = aData -> data[iBytePos];
+
+return (iResult & (1 << iBitPos));
+}
+
+//
+// Get bit from index
+//
+void BitIndex::SetBit(const UINT_32 iOffset,
+ const CHAR_8 iValue)
+{
+ UINT_32 iBytePos = iOffset >> 3;
+ UINT_32 iBitPos = iOffset & 7;
+
+ if (iBytePos >= iMaxSize) { ResizeBitIndex(iBytePos); }
+
+ if (aData -> size <= iBytePos)
+ {
+ aData -> size = iBytePos + 1;
+ }
+
+ CHAR_8 & iResult = aData -> data[iBytePos];
+
+ if (iValue != 0) { iResult |= (1 << iBitPos); } // Set bit
+ else { iResult &= (0xFF ^ (1 << iBitPos)); } // Remove bit
+}
+
+//
+// Resize bit index
+//
+void BitIndex::ResizeBitIndex(const UINT_32 & iBytePos)
+{
+ UINT_32 iNewSize = (iBytePos << 1);
+
+ void * vTMP = malloc(sizeof(UINT_64) + iNewSize);
+ memset(vTMP, 0, sizeof(UINT_64) + iNewSize);
+
+ UINT_32 iUsedSize = UINT_32(aData -> size);
+ memcpy((CHAR_P)vTMP + sizeof(UINT_64), aData -> data, iMaxSize);
+ free(aData);
+
+ aData = (BitIndexData *)vTMP;
+ aData -> size = iUsedSize;
+
+ iMaxSize = iNewSize;
+}
+
+//
+// A destructor
+//
+BitIndex::~BitIndex() throw() { free(aData); }
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Compiler.cpp b/src/CTPP2Compiler.cpp
new file mode 100644
index 0000000..4c34e10
--- /dev/null
+++ b/src/CTPP2Compiler.cpp
@@ -0,0 +1,1075 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Compiler.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Compiler.hpp"
+
+#include "CTPP2Syntax.h"
+#include "CTPP2HashTable.hpp"
+#include "CTPP2StaticData.hpp"
+#include "CTPP2StaticText.hpp"
+#include "CTPP2VMOpcodes.h"
+
+// #define _USE_COMPILER_REPORTER 1 // Use it only for hard debugging
+#define CTPP2_FOREACH_ITER_PREFIX "__iter_"
+
+namespace CTPP // C++ Template Engine
+{
+
+#ifdef _USE_COMPILER_REPORTER
+/**
+ @class Reporter
+ @brief Print template parsing syntax tree with indents
+*/
+class CompilerReporter
+{
+public:
+ /**
+ @brief Constructor
+ @param sIData - method name
+ @param szCode - code to print
+ */
+ CompilerReporter(const STLW::string & sIData);
+
+ /**
+ @brief Destructor
+ */
+ ~CompilerReporter() throw();
+private:
+ // Does not exist
+ CompilerReporter(const CompilerReporter & oRhs);
+ CompilerReporter & operator=(const CompilerReporter & oRhs);
+
+ /** Method name */
+ STLW::string sData;
+ /** Indent lebvel */
+ static int iLevel;
+};
+
+//
+// Constructor
+//
+CompilerReporter::CompilerReporter(const STLW::string & sIData): sData(sIData)
+{
+ for (INT_32 iI = 0; iI < iLevel; ++iI) { fprintf(stderr, " "); }
+ ++iLevel;
+ fprintf(stderr, ">> %s\n", sData.c_str());
+}
+
+//
+// Destructor
+//
+CompilerReporter::~CompilerReporter() throw()
+{
+ --iLevel;
+// for (INT_32 iI = 0; iI < iLevel; ++iI) { fprintf(stderr, " "); }
+// fprintf(stderr, "<< %s\n", sData.c_str());
+}
+
+// Indent level
+int CompilerReporter::iLevel = 0;
+
+// Fast access macros
+#define COMPILER_REPORTER(x) CompilerReporter oCompilerReporter(x);
+
+#else // No reporter
+
+// Fast access macros
+#define COMPILER_REPORTER(x) { ;; }
+
+#endif // Reporter class
+
+/**
+ @class DirtyRegistersFlag
+ @brief Flag for register PUSH/POP optimizationr
+*/
+class DirtyRegistersFlag
+{
+public:
+ /**
+ @brief Constructor
+ @param bIInForeach - flag
+ */
+ DirtyRegistersFlag(bool & bIFlag);
+
+ /**
+ @brief Destructor
+ */
+ ~DirtyRegistersFlag() throw();
+private:
+ // Does not exist
+ DirtyRegistersFlag(const DirtyRegistersFlag & oRhs);
+ DirtyRegistersFlag & operator=(const DirtyRegistersFlag & oRhs);
+
+ /** Reference to foreach flag */
+ bool & bFlag;
+ /** Old foreach flag state */
+ bool bOldFlad;
+};
+
+
+//
+// Constructor
+//
+DirtyRegistersFlag::DirtyRegistersFlag(bool & bIFlag): bFlag(bIFlag),
+ bOldFlad(bFlag)
+{
+ //fprintf(stderr, ">>DirtyRegistersFlag: %c -> t\n", (bOldFlad ? 't':'f'));
+ bFlag = true;
+}
+
+//
+// Destructor
+//
+DirtyRegistersFlag::~DirtyRegistersFlag() throw()
+{
+ //fprintf(stderr, "<<ForeachFlagLocker: t -> %c\n", (bFlag ? 't':'f'));
+ bFlag = bOldFlad;
+}
+
+//
+// Constructor
+//
+CTPP2Compiler::CTPP2Compiler(VMOpcodeCollector & oIVMOpcodeCollector,
+ StaticText & oISyscalls,
+ StaticData & oIStaticData,
+ StaticText & oIStaticText,
+ HashTable & oIHashTable): iStackDepth(0),
+ iScopeNumber(0),
+ bRegsAreDirty(true),
+ oVMOpcodeCollector(oIVMOpcodeCollector),
+ oSyscalls(oISyscalls),
+ oStaticData(oIStaticData),
+ oStaticText(oIStaticText),
+ oHashTable(oIHashTable)
+{
+ mSyscalls["__ctpp2_emitter"] = oSyscalls.StoreData("__ctpp2_emitter", 15);
+
+ iZeroId = oStaticData.StoreInt(0);
+ iOneId = oStaticData.StoreInt(1);
+
+ oVMOpcodeCollector.Insert(CreateInstruction(SYSCALL, SYSCALL_PARAMS(mSyscalls["__ctpp2_emitter"], 0), 0 ));
+ oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_SRC_STACK | ARG_DST_HR, 0, 0));
+ oVMOpcodeCollector.Insert(CreateInstruction(POP, 1, 0));
+}
+
+//
+// Store template source name
+//
+INT_32 CTPP2Compiler::StoreSourceName(CCHAR_P szName,
+ const UINT_32 iNameLength)
+{
+ return oStaticText.StoreData(szName, iNameLength);
+}
+
+//
+// Send variable to standard output collector
+//
+INT_32 CTPP2Compiler::OutputVariable(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OutputVariable");
+
+ --iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(OUTPUT | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Send text data to standard output collector
+//
+INT_32 CTPP2Compiler::OutputStaticData(CCHAR_P vBuffer,
+ const UINT_32 iBufferLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ if (iBufferLength == 0) { return 0; }
+
+ COMPILER_REPORTER("OutputStaticData/string");
+
+ INT_32 iId = oStaticText.StoreData(vBuffer, iBufferLength);
+
+return oVMOpcodeCollector.Insert(CreateInstruction(OUTPUT | ARG_SRC_STR, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Send integer value to standard output collector
+//
+INT_32 CTPP2Compiler::OutputStaticData(const INT_64 & iData,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OutputStaticData/int");
+
+ INT_32 iId = oStaticData.StoreInt(iData);
+
+return oVMOpcodeCollector.Insert(CreateInstruction(OUTPUT | ARG_SRC_INT, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Send floating point value to standard output collector
+//
+INT_32 CTPP2Compiler::OutputStaticData(const W_FLOAT & dData,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OutputStaticData/float");
+
+ INT_32 iId = oStaticData.StoreFloat(dData);
+
+return oVMOpcodeCollector.Insert(CreateInstruction(OUTPUT | ARG_SRC_FLOAT, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Change visibility scope of CDT data (for ARRAY iterating)
+//
+// PUSH HR
+// PUSH GR
+// PUSH FR
+// PUSH ER
+//
+// N + 0: MOVISTR GR, HR["ScopeName"]
+// N + 1: JE N + 3
+// N + 2: MOVISTR GR, DR["ScopeName"]
+//
+// MOVSIZE FR, GR.size()
+// MOV ER, 0
+//
+// @RET_POINT
+// CMP ER, FR
+// JE @END
+// MOVIREG HR, GR[ER]
+//
+
+//
+// Loop code
+//
+
+//
+// INC ER
+// JMP RET_POINT
+// @END:
+
+INT_32 CTPP2Compiler::ChangeScope(CCHAR_P szScopeName,
+ const UINT_32 iScopeNameLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ChangeScope");
+
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+ INT_32 iNull = iZeroId;
+
+ // Check symbol table
+ const SymbolTable<SymbolTableRec>::SymbolRecord<SymbolTableRec> * pRecord = oSymbolTable.GetSymbol(szScopeName, iScopeNameLength);
+ if (pRecord != NULL)
+ {
+ oVMOpcodeCollector.Insert(CreateInstruction(POP | ARG_SRC_AR, 0, iDebugInfo));
+
+ iStackDepth += 7;
+ oVMOpcodeCollector.Insert(CreateInstruction(PUSHA , 0, iDebugInfo));
+
+ INT_32 iDepth = iStackDepth - pRecord -> symbol_data.stack_depth;
+
+ // Get from HR register indirect value (local variables)
+ if (pRecord -> symbol_data.scope_number == iScopeNumber)
+ {
+ oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_DST_GR | ARG_SRC_HR, 0, iDebugInfo));
+ }
+ // Move data from stack to HR register
+ else
+ {
+ oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_DST_GR | ARG_SRC_STACK, iDepth - 1, iDebugInfo));
+ }
+
+ oVMOpcodeCollector.Insert(CreateInstruction(MOVSIZE | ARG_DST_FR | ARG_SRC_GR , 0, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(JE, (UINT_32)-1, iDebugInfo));
+ UINT_32 iRetPoint = oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_DST_ER | ARG_SRC_INT , iNull, iDebugInfo));
+
+ oVMOpcodeCollector.Insert(CreateInstruction(MOVIREGI | ARG_DST_HR | ARG_SRC_GR , ARG_SRC_ER, iDebugInfo));
+ ++iRetPoint;
+
+ return iRetPoint;
+ }
+
+ // Remember old HR value
+ // Get from DR register indirect value and store it into stack
+ INT_32 iId = oStaticText.StoreData(szScopeName, iScopeNameLength);
+
+ oVMOpcodeCollector.Insert(CreateInstruction(POP | ARG_SRC_AR, 0, iDebugInfo));
+
+ iStackDepth += 7;
+ oVMOpcodeCollector.Insert(CreateInstruction(PUSHA , 0, iDebugInfo));
+
+
+
+ oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_DST_GR | ARG_SRC_AR, iId, iDebugInfo));
+
+ oVMOpcodeCollector.Insert(CreateInstruction(MOVSIZE | ARG_DST_FR | ARG_SRC_GR , 0, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(JE, (UINT_32)-1, iDebugInfo));
+ UINT_32 iRetPoint = oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_DST_ER | ARG_SRC_INT , iNull, iDebugInfo));
+
+ oVMOpcodeCollector.Insert(CreateInstruction(MOVIREGI | ARG_DST_HR | ARG_SRC_GR , ARG_SRC_ER, iDebugInfo));
+ ++iRetPoint;
+
+ // Scope was changed
+ ++iScopeNumber;
+ oSymbolTable.MarkScope();
+
+return iRetPoint;
+}
+
+//
+// Reset scope to previous CDT data (for ARRAY iterating)
+//
+//
+// LOOP FR, ER, @RET_POINT
+// POP47
+
+//
+// INC ER
+// JMP RET_POINT
+// @END:
+// POP ER
+// POP FR
+// POP GR
+// POP HR
+INT_32 CTPP2Compiler::ResetScope(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ResetScope");
+
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ --iScopeNumber;
+ oSymbolTable.UnmarkScope();
+
+ oVMOpcodeCollector.Insert(CreateInstruction(LOOP | ARG_SRC_FR | ARG_DST_ER , iIP, iDebugInfo));
+
+ UINT_32 iEndPoint =
+ oVMOpcodeCollector.Insert(CreateInstruction(POPA , 0, iDebugInfo));
+ iStackDepth -= 8;
+
+ VMInstruction * pInstr = oVMOpcodeCollector.GetInstruction(iIP - 2);
+ if (pInstr == NULL) { throw "Ouch!"; }
+ pInstr -> argument = iEndPoint;
+
+return iEndPoint;
+}
+
+//
+// Call block by name
+//
+INT_32 CTPP2Compiler::CallBlock(const STLW::string & sBlockName,
+ const bool & bIsVariable,
+ const UINT_32 iArgCount,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("CallBlock");
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ UINT_32 iOffset = 0;
+ if (bIsVariable) { ++iOffset; }
+
+ // Store block name
+ INT_32 iId = oStaticText.StoreData(sBlockName.data(), sBlockName.size());
+
+ oVMOpcodeCollector.Insert(CreateInstruction(SAVEBP, iArgCount + iOffset, iDebugInfo));
+
+ if (!bIsVariable)
+ {
+ // Call by name
+ oVMOpcodeCollector.Insert(CreateInstruction(CALLNAME, iId, iDebugInfo));
+
+ // Unused block arguments
+ iStackDepth = vSavedStackDepths.back();
+ vSavedStackDepths.pop_back();
+ return oVMOpcodeCollector.Insert(CreateInstruction(RESTBP, 0, iDebugInfo));
+ }
+ else
+ {
+ // Unused block arguments
+ iStackDepth = vSavedStackDepths.back();
+ vSavedStackDepths.pop_back();
+ --iStackDepth; // for callname's variable
+ oVMOpcodeCollector.Insert(CreateInstruction(CALLIND | ARG_SRC_STACK, iArgCount + iOffset - 1, iDebugInfo));
+ return oVMOpcodeCollector.Insert(CreateInstruction(RESTBP, 0, iDebugInfo));
+ }
+
+// Make compiler happy
+return -1;
+}
+
+//
+// Start of block
+//
+INT_32 CTPP2Compiler::StartBlock(const STLW::string & sBlockName,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("StartBlock");
+
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ UINT_32 iIP =
+ oVMOpcodeCollector.Insert(CreateInstruction(JMP , (UINT_32)-1, iDebugInfo));
+
+ iCurrBlockStackDepth = iStackDepth;
+
+ oHashTable.Put(sBlockName.data(), sBlockName.size(), oVMOpcodeCollector.GetCodeSize());
+
+return iIP;
+}
+
+//
+// End of block
+//
+INT_32 CTPP2Compiler::EndBlock(const UINT_32 iDepth, const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("EndBlock");
+
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RET, iDepth, iDebugInfo));
+}
+
+//
+// Prepare call block
+//
+void CTPP2Compiler::PrepareCallBlock(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PrepareCallBlock");
+
+ vSavedStackDepths.push_back(iStackDepth);
+}
+
+//
+// Get system call by id
+//
+INT_32 CTPP2Compiler::GetSyscallId(CCHAR_P szSyscallName,
+ const UINT_32 iSyscallNameLength)
+{
+ COMPILER_REPORTER("GetSyscallId");
+
+ const STLW::string sTMP(szSyscallName, iSyscallNameLength);
+ STLW::map<STLW::string, UINT_32>::const_iterator itmSyscalls = mSyscalls.find(sTMP);
+ if (itmSyscalls != mSyscalls.end()) { return itmSyscalls -> second; }
+
+ UINT_32 iSyscallNum = oSyscalls.StoreData(szSyscallName, iSyscallNameLength);
+
+ mSyscalls[sTMP] = iSyscallNum;
+
+return iSyscallNum;
+}
+
+//
+// Execute system call such as HREF_PARAM, FORM_PARAM, etc
+//
+INT_32 CTPP2Compiler::ExecuteSyscall(CCHAR_P szSyscallName,
+ const UINT_32 iSyscallNameLength,
+ const UINT_32 iArgNum,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ExecuteSyscall");
+
+ iStackDepth -= iArgNum - 1;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(SYSCALL, SYSCALL_PARAMS(GetSyscallId(szSyscallName, iSyscallNameLength), iArgNum), oDebugInfo.GetInfo()));
+}
+
+//
+// Prepare before push hash or array variable
+//
+INT_32 CTPP2Compiler::PreparePushComplexVariable(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PreparePushComplexVariable");
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_AR, 0, iDebugInfo));
+}
+
+//
+// Clear after push hash or array variable
+//
+INT_32 CTPP2Compiler::ClearPushComplexVariable(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ClearPushComplexVariable");
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ oVMOpcodeCollector.Insert(CreateInstruction(XCHG | ARG_SRC_STACK | ARG_DST_STACK, 1, iDebugInfo));
+
+ --iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(POP | ARG_SRC_AR, 0, iDebugInfo));
+}
+
+//
+// Push block's variable
+//
+INT_32 CTPP2Compiler::PushBlockVariable(const UINT_32 iIdx,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushBlockVariable");
+ const UINT_32 iStackIdx = iIdx + iStackDepth;
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_STACK, iStackIdx, oDebugInfo.GetInfo()));
+}
+
+//
+// Prepare local scope
+//
+INT_32 CTPP2Compiler::PrepareLocalScope(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PrepareLocalScope");
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_HR, 0, iDebugInfo));
+}
+
+//
+// Push variable into stack
+//
+INT_32 CTPP2Compiler::PushVariable(CCHAR_P szVariableName,
+ const UINT_32 iVariableNameLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushVariable");
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ INT_32 iId = oStaticText.StoreData(szVariableName, iVariableNameLength);
+ oVMOpcodeCollector.Insert(CreateInstruction(REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iId, iDebugInfo));
+ INT_32 iPos =
+ oVMOpcodeCollector.Insert(CreateInstruction(DEFINED | ARG_SRC_STACK , 0, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(JE , iPos + 3, iDebugInfo));
+
+return oVMOpcodeCollector.Insert(CreateInstruction(REPLACE | ARG_SRC_IND_STR | ARG_DST_DR , iId, iDebugInfo));
+}
+
+//
+// Store variable in scope
+//
+INT_32 CTPP2Compiler::StoreScopedVariable(CCHAR_P szNS,
+ const UINT_32 iNSLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("StoreScopedVariable");
+
+ STLW::string sNamespace = STLW::string(CTPP2_FOREACH_ITER_PREFIX) + STLW::string(szNS, iNSLength);
+ INT_32 iSymbolId = oSymbolTable.AddSymbol(sNamespace.c_str(), sNamespace.size(), SymbolTableRec(iStackDepth, iScopeNumber));
+
+return iSymbolId;
+}
+
+//
+// Push variable into stack
+//
+INT_32 CTPP2Compiler::PushScopedVariable(CCHAR_P szName,
+ const UINT_32 iNameLength,
+ CCHAR_P szFullVariable,
+ const UINT_32 iFullVariableLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushScopedVariable");
+
+ // Check symbol table
+ STLW::string sNamespace = STLW::string(CTPP2_FOREACH_ITER_PREFIX) + STLW::string(szFullVariable, iFullVariableLength);
+ const SymbolTable<SymbolTableRec>::SymbolRecord<SymbolTableRec> * pRecord = oSymbolTable.GetSymbol(sNamespace.c_str(), sNamespace.size());
+
+ if (pRecord == NULL) { return -1; }
+
+ // Store debug info
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ // Store variable name
+ INT_32 iId = oStaticText.StoreData(sNamespace.c_str(), sNamespace.size());
+
+ // Check current stack depth
+ INT_32 iDepth = iStackDepth - pRecord -> symbol_data.stack_depth;
+
+ INT_32 iNSId = oStaticText.StoreData(sNamespace.data(), sNamespace.size());
+
+ ++iStackDepth;
+ if (pRecord -> symbol_data.scope_number == iScopeNumber)
+ {
+ oVMOpcodeCollector.Insert(CreateInstruction(IMOVSTR | ARG_SRC_HR | ARG_DST_BR, iNSId, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_HR, 0, iDebugInfo));
+ }
+ else
+ {
+ oVMOpcodeCollector.Insert(CreateInstruction(MOV | ARG_SRC_STACK | ARG_DST_CR, iDepth - 8, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(IMOVSTR | ARG_SRC_CR | ARG_DST_BR, iNSId, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_STACK, iDepth - 8, iDebugInfo));
+ }
+
+ oVMOpcodeCollector.Insert(CreateInstruction(REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iId, iDebugInfo));
+ INT_32 iPos =
+ oVMOpcodeCollector.Insert(CreateInstruction(DEFINED | ARG_SRC_STACK, 0, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(JE, iPos + 5, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(POP , 0, iDebugInfo));
+ oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_BR, 0, iDebugInfo));
+ return oVMOpcodeCollector.Insert(CreateInstruction(REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iId, iDebugInfo));
+}
+
+//
+// Push integer value into stack
+//
+INT_32 CTPP2Compiler::PushInt(const INT_64 & iVariable,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushInt");
+
+ INT_32 iId = -1;
+ // Predefined variables: '0' and '1'
+ if (iVariable == 0) { iId = iZeroId; }
+ else if (iVariable == 1) { iId = iOneId; }
+ else { iId = oStaticData.StoreInt(iVariable); }
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_INT, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Push Float value into stack
+//
+INT_32 CTPP2Compiler::PushFloat(const W_FLOAT & dVariable,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushFloat");
+
+ INT_32 iId = oStaticData.StoreFloat(dVariable);
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_FLOAT, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Push string value into stack
+//
+INT_32 CTPP2Compiler::PushString(CCHAR_P szData,
+ const UINT_32 iDataLength,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushString");
+
+ INT_32 iId = oStaticText.StoreData(szData, iDataLength);
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_STR, iId, oDebugInfo.GetInfo()));
+}
+
+//
+// Check existence of stack variable
+//
+INT_32 CTPP2Compiler::ExistStackVariable(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ExistStackVariable");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(EXIST | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Check existence of AR register variable
+//
+INT_32 CTPP2Compiler::ExistARReg(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ExistARReg");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(EXIST | ARG_SRC_AR, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Pop variable from stack
+//
+INT_32 CTPP2Compiler::PopVariable(const INT_32 iVars,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PopVariable");
+
+ iStackDepth -= iVars;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(POP, iVars, oDebugInfo.GetInfo()));
+}
+
+//
+// Remove last instruction from code segment
+//
+INT_32 CTPP2Compiler::RemoveInstruction()
+{
+ COMPILER_REPORTER("RemoveInstruction");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Remove();
+}
+
+//
+// Unconditional jump
+//
+INT_32 CTPP2Compiler::UncondJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("UncondJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JMP, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if NOT Equal
+//
+INT_32 CTPP2Compiler::NEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("NEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_NE, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Equal
+//
+INT_32 CTPP2Compiler::EQJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("EQJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_EQ, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Greater
+//
+INT_32 CTPP2Compiler::GTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("GTJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_GT, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Greater Or Equal
+//
+INT_32 CTPP2Compiler::GEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("GEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_EQ | FL_GT, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Less
+//
+INT_32 CTPP2Compiler::LTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("LTJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_LT, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Less Or Equal
+//
+INT_32 CTPP2Compiler::LEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("LEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(JXX | FL_EQ | FL_LT, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Unconditional jump
+//
+INT_32 CTPP2Compiler::RUncondJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("UncondJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJMP, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if NOT Equal
+//
+INT_32 CTPP2Compiler::RNEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("NEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJN, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Equal
+//
+INT_32 CTPP2Compiler::REQJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("REQJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJE, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Greater
+//
+INT_32 CTPP2Compiler::RGTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("RGTJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJG, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Greater Or Equal
+//
+INT_32 CTPP2Compiler::RGEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("RGEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJGE, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Less
+//
+INT_32 CTPP2Compiler::RLTJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("RLTJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJL, iIP, oDebugInfo.GetInfo()));
+}
+
+//
+// Jump if Less Or Equal
+//
+INT_32 CTPP2Compiler::RLEJump(const UINT_32 iIP,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("RLEJump");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(RJLE, iIP, oDebugInfo.GetInfo()));
+}
+
+
+//
+// Clear register
+//
+INT_32 CTPP2Compiler::ClearStack(const UINT_32 iStackPointer,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("ClearStack");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(CLEAR | ARG_DST_STACK, iStackPointer, oDebugInfo.GetInfo()));
+}
+
+//
+// Stop execution
+//
+INT_32 CTPP2Compiler::Halt(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("Halt");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(HLT, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Addition
+//
+INT_32 CTPP2Compiler::OpAdd(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpAdd");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(ADD | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Substraction
+//
+INT_32 CTPP2Compiler::OpSub(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpSub");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(SUB | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Multiplication
+//
+INT_32 CTPP2Compiler::OpMul(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpMul");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(MUL | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Division
+//
+INT_32 CTPP2Compiler::OpDiv(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpDiv");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(DIV | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Integer division
+//
+INT_32 CTPP2Compiler::OpIDiv(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpIDiv");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(IDIV | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Mod
+//
+INT_32 CTPP2Compiler::OpMod(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpMod");
+
+ --iStackDepth;
+
+return oVMOpcodeCollector.Insert(CreateInstruction(MOD | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Negation
+//
+INT_32 CTPP2Compiler::OpNeg(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpNeg");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(NEG | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Logical negation
+//
+INT_32 CTPP2Compiler::OpNot(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpNot");
+
+return oVMOpcodeCollector.Insert(CreateInstruction(NOT | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Comparison
+//
+INT_32 CTPP2Compiler::OpCmp(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpCmp");
+ --iStackDepth;
+ --iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(CMP | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// String comparison
+//
+INT_32 CTPP2Compiler::OpSCmp(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("OpSCmp");
+ --iStackDepth;
+ --iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(SCMP | ARG_DST_STACK | ARG_SRC_STACK, 0, oDebugInfo.GetInfo()));
+}
+
+//
+// Get last instruction number
+//
+UINT_32 CTPP2Compiler::GetCodeSize() const { return oVMOpcodeCollector.GetCodeSize(); }
+
+//
+// Push variable on stack into stack
+//
+INT_32 CTPP2Compiler::PushStackVariable(const INT_32 iStackPos,
+ const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("PushStackVariable");
+
+ ++iStackDepth;
+return oVMOpcodeCollector.Insert(CreateInstruction(PUSH | ARG_SRC_STACK, iStackPos, oDebugInfo.GetInfo()));
+}
+
+//
+// Indirect call
+//
+INT_32 CTPP2Compiler::IndirectCall(const VMDebugInfo & oDebugInfo)
+{
+ COMPILER_REPORTER("IndirectCall");
+
+ UINT_64 iDebugInfo = oDebugInfo.GetInfo();
+
+ oVMOpcodeCollector.Insert(CreateInstruction(POP | ARG_SRC_AR, 0, iDebugInfo));
+ INT_32 iPos =
+ oVMOpcodeCollector.Insert(CreateInstruction(REPLIND | ARG_SRC_AR, 0, iDebugInfo));
+
+ --iStackDepth;
+
+ return iPos;
+}
+
+//
+// Decrease stack depth
+//
+void CTPP2Compiler::DecrDepth() { --iStackDepth; }
+
+//
+// Increase stack depth
+//
+void CTPP2Compiler::IncrDepth() { ++iStackDepth; }
+
+//
+// Get instrcution by instruction number
+//
+VMInstruction * CTPP2Compiler::GetInstruction(const UINT_32 iIP) { return oVMOpcodeCollector.GetInstruction(iIP); }
+
+//
+// A destructor
+//
+CTPP2Compiler::~CTPP2Compiler() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2DTOA.cpp b/src/CTPP2DTOA.cpp
new file mode 100644
index 0000000..1d31336
--- /dev/null
+++ b/src/CTPP2DTOA.cpp
@@ -0,0 +1,1833 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Dtoa.cpp
+ *
+ * $CTPP$
+ */
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+ David M. Gay
+ Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-0636
+ U.S.A.
+ dmg@bell-labs.com
+ */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa. If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ * _control87(PC_53, MCW_PC);
+ * does this with many compilers. Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+#define Honor_FLT_ROUNDS
+#define FLT_ROUNDS 3
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define INT_32 int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and strtod and dtoa should round accordingly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ * and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "INT_32 INT_32"
+ * integer type (of >= 64 bits). On such machines, you can
+ * #define Just_16 to store 16 bits per 32-bit INT_32 when doing
+ * high-precision integer arithmetic. Whether this speeds things
+ * up or slows things down depends on the machine and the number
+ * being converted. If INT_32 INT_32 is available and the name is
+ * something other than "INT_32 INT_32", #define INT_64 to be the name,
+ * and if "unsigned INT_64" does not work as an unsigned version of
+ * INT_64, #define #UINT_64 to be the corresponding unsigned type.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ * avoids underflows on inputs whose result does not underflow.
+ * If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ * floating-point numbers and flushes underflows to zero rather
+ * than implementing gradual underflow, then you must also #define
+ * #define YES_ALIAS to permit aliasing certain double values with
+ * arrays of ULongs. This leads to slightly better code with
+ * some compilers and was always used prior to 19990916, but it
+ * is not strictly legal and can cause trouble with aggressively
+ * optimizing compilers (e.g., gcc 2.95.1 under -O2).
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ * the result overflows to +-Infinity or underflows to 0.
+ */
+
+#include "CTPP2DTOA.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef _MSC_VER
+ #include <WinSock2.h>
+ #ifndef BIG_ENDIAN
+ #define BIG_ENDIAN BIGENDIAN
+ #endif
+ #ifndef LITTLE_ENDIAN
+ #define LITTLE_ENDIAN LITTLEENDIAN
+ #endif
+ #ifndef BYTE_ORDER
+ #if (LITTLEENDIAN > BIGENDIAN)
+ #define BYTE_ORDER LITTLE_ENDIAN
+ #else
+ #define BYTE_ORDER BIG_ENDIAN
+ #endif
+ #endif
+#endif
+
+#ifndef BYTE_ORDER
+#error "BYTE_ORDER is not defined!"
+#endif
+
+#define PLATFORM(x) (BYTE_ORDER == (x))
+
+#if PLATFORM(BIG_ENDIAN)
+ #define IEEE_MC68k
+#else
+ #define IEEE_8087
+#endif
+
+#ifdef IEEE_Arith
+ #undef IEEE_Arith
+#endif
+
+#ifdef Avoid_Underflow
+ #undef Avoid_Underflow
+#endif
+
+#ifdef IEEE_MC68k
+ #define IEEE_Arith
+#endif
+
+#ifdef IEEE_8087
+ #define IEEE_Arith
+#endif
+
+#ifdef Bad_float_h
+
+ #ifdef IEEE_Arith
+ #define DBL_DIG 15
+ #define DBL_MAX_10_EXP 308
+ #define DBL_MAX_EXP 1024
+ #define FLT_RADIX 2
+ #endif /*IEEE_Arith*/
+
+ #ifdef IBM
+ #define DBL_DIG 16
+ #define DBL_MAX_10_EXP 75
+ #define DBL_MAX_EXP 63
+ #define FLT_RADIX 16
+ #define DBL_MAX 7.2370055773322621e+75
+ #endif
+
+ #ifdef VAX
+ #define DBL_DIG 16
+ #define DBL_MAX_10_EXP 38
+ #define DBL_MAX_EXP 127
+ #define FLT_RADIX 2
+ #define DBL_MAX 1.7014118346046923e+38
+ #endif
+
+ #ifndef LONG_MAX
+ #define LONG_MAX 2147483647
+ #endif
+
+#else /* ifndef Bad_float_h */
+ #include <float.h>
+#endif /* Bad_float_h */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+ #error "Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined."
+#endif
+
+typedef union
+{
+ double d;
+ UINT_32 L[2];
+} U;
+
+#define dval(x) (x).d
+#ifdef IEEE_8087
+ #define word0(x) (x).L[1]
+ #define word1(x) (x).L[0]
+#else
+ #define word0(x) (x).L[0]
+ #define word1(x) (x).L[1]
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ */
+#define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+ #define Exp_shift 20
+ #define Exp_shift1 20
+ #define Exp_msk1 0x100000
+ #define Exp_msk11 0x100000
+ #define Exp_mask 0x7ff00000
+ #define P 53
+ #define Bias 1023
+ #define Emin (-1022)
+ #define Exp_1 0x3ff00000
+ #define Exp_11 0x3ff00000
+ #define Ebits 11
+ #define Frac_mask 0xfffff
+ #define Frac_mask1 0xfffff
+ #define Ten_pmax 22
+ #define Bletch 0x10
+ #define Bndry_mask 0xfffff
+ #define Bndry_mask1 0xfffff
+ #define LSB 1
+ #define Sign_bit 0x80000000
+ #define Log2P 1
+ #define Tiny0 0
+ #define Tiny1 1
+ #define Quick_max 14
+ #define Int_max 14
+ #ifndef NO_IEEE_Scale
+ #define Avoid_Underflow
+ #endif
+
+ #ifndef Flt_Rounds
+ #ifdef FLT_ROUNDS
+ #define Flt_Rounds FLT_ROUNDS
+ #else
+ #define Flt_Rounds 1
+ #endif
+ #endif /*Flt_Rounds*/
+
+ #ifdef Honor_FLT_ROUNDS
+ #define Rounding rounding
+ #undef Check_FLT_ROUNDS
+ #define Check_FLT_ROUNDS
+ #else
+ #define Rounding Flt_Rounds
+ #endif
+
+#else /* ifndef IEEE_Arith */
+ #undef Check_FLT_ROUNDS
+ #undef Honor_FLT_ROUNDS
+ #ifdef IBM
+ #undef Flt_Rounds
+ #define Flt_Rounds 0
+ #define Exp_shift 24
+ #define Exp_shift1 24
+ #define Exp_msk1 0x1000000
+ #define Exp_msk11 0x1000000
+ #define Exp_mask 0x7f000000
+ #define P 14
+ #define Bias 65
+ #define Exp_1 0x41000000
+ #define Exp_11 0x41000000
+ #define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+ #define Frac_mask 0xffffff
+ #define Frac_mask1 0xffffff
+ #define Bletch 4
+ #define Ten_pmax 22
+ #define Bndry_mask 0xefffff
+ #define Bndry_mask1 0xffffff
+ #define LSB 1
+ #define Sign_bit 0x80000000
+ #define Log2P 4
+ #define Tiny0 0x100000
+ #define Tiny1 0
+ #define Quick_max 14
+ #define Int_max 15
+ #else /* VAX */
+ #undef Flt_Rounds
+ #define Flt_Rounds 1
+ #define Exp_shift 23
+ #define Exp_shift1 7
+ #define Exp_msk1 0x80
+ #define Exp_msk11 0x800000
+ #define Exp_mask 0x7f80
+ #define P 56
+ #define Bias 129
+ #define Exp_1 0x40800000
+ #define Exp_11 0x4080
+ #define Ebits 8
+ #define Frac_mask 0x7fffff
+ #define Frac_mask1 0xffff007f
+ #define Ten_pmax 24
+ #define Bletch 2
+ #define Bndry_mask 0xffff007f
+ #define Bndry_mask1 0xffff007f
+ #define LSB 0x10000
+ #define Sign_bit 0x8000
+ #define Log2P 1
+ #define Tiny0 0x80
+ #define Tiny1 0
+ #define Quick_max 15
+ #define Int_max 15
+ #endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+ #define ROUND_BIASED
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+#define FFFFFFFF 0xffffffffUL
+
+#define ACQUIRE_DTOA_LOCK(n)
+#define FREE_DTOA_LOCK(n)
+
+void * safe_malloc(AllocatedBlock ** aBlocks, const UINT_32 iSize)
+{
+ // Allocate memory block placeholder
+ AllocatedBlock * pNewBlock = (AllocatedBlock *)malloc(sizeof(AllocatedBlock));
+ // Allocate memory block
+ pNewBlock -> data = malloc(iSize);
+ pNewBlock -> prev = *aBlocks;
+
+ // Ouch!
+ *aBlocks = pNewBlock;
+//fprintf(stderr, "safe_malloc: %p(%p, %d)\n", (void*)pNewBlock, (void*)(pNewBlock -> data), iSize);
+
+return pNewBlock -> data;
+}
+
+void safe_free(AllocatedBlock ** aBlocks)
+{
+ // Ouch!
+ if (aBlocks == NULL || *aBlocks == NULL) { return; }
+
+ for(;;)
+ {
+ AllocatedBlock * pPrevBlock = (*aBlocks) -> prev;
+
+//fprintf(stderr, "safe_free: %p(%p)\n", (void*)(*aBlocks), (*aBlocks) -> data);
+
+ free((*aBlocks) -> data);
+ free(*aBlocks);
+
+ *aBlocks = pPrevBlock;
+ if (pPrevBlock == NULL) { break; }
+ }
+}
+
+static Bigint * Balloc(AllocatedBlock ** aBlocks, Bigint ** freelist, int k)
+{
+ int x;
+ Bigint *rv;
+
+ ACQUIRE_DTOA_LOCK(0);
+ if ((rv = freelist[k]))
+ {
+ freelist[k] = rv->next;
+ }
+ else
+ {
+ x = 1 << k;
+ rv = (Bigint *)safe_malloc(aBlocks, sizeof(Bigint) + (x-1)*sizeof(UINT_32));
+ rv->k = k;
+ rv->maxwds = x;
+ }
+ FREE_DTOA_LOCK(0);
+ rv->sign = rv->wds = 0;
+
+return rv;
+}
+
+#define Kmax (sizeof(size_t) << 3)
+
+static void Bfree(Bigint ** freelist, Bigint *v)
+{
+ if (v)
+ {
+// if (v->k > Kmax)
+// {
+// free((void*)v);
+// }
+// else
+ {
+ ACQUIRE_DTOA_LOCK(0);
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ FREE_DTOA_LOCK(0);
+ }
+ }
+}
+
+/*static void Bfree(Bigint ** freelist, Bigint *v)
+{
+ if (v)
+ {
+ ACQUIRE_DTOA_LOCK(0);
+ v->next = freelist[v->k];
+ freelist[v->k] = v;
+ FREE_DTOA_LOCK(0);
+ }
+}
+*/
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, y->wds*sizeof(INT_32) + 2*sizeof(int))
+
+//
+// multiply by m and add a
+//
+static Bigint * multadd(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *b, int m, int a)
+{
+ int i, wds;
+
+ UINT_32 *x;
+ UINT_64 carry, y;
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ carry = a;
+ do
+ {
+ y = *x * (UINT_64)m + carry;
+ carry = y >> 32;
+ *x++ = (UINT_32)y & FFFFFFFF;
+ }
+ while(++i < wds);
+
+ if (carry)
+ {
+ if (wds >= b->maxwds)
+ {
+ b1 = Balloc(aBlocks, freelist, b->k+1);
+ Bcopy(b1, b);
+ Bfree(freelist, b);
+ b = b1;
+ }
+ b->x[wds++] = (UINT_32)carry;
+ b->wds = wds;
+ }
+
+return b;
+}
+
+
+static int hi0bits(register UINT_32 x)
+{
+ register int k = 0;
+
+ if (!(x & 0xffff0000))
+ {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000))
+ {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000))
+ {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000))
+ {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000))
+ {
+ k++;
+ if (!(x & 0x40000000))
+ {
+ return 32;
+ }
+ }
+
+return k;
+}
+
+static int lo0bits(UINT_32 *y)
+{
+ register int k;
+ register UINT_32 x = *y;
+
+ if (x & 7)
+ {
+ if (x & 1)
+ {
+ return 0;
+ }
+ if (x & 2)
+ {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+
+ k = 0;
+ if (!(x & 0xffff))
+ {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff))
+ {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf))
+ {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3))
+ {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1))
+ {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ {
+ return 32;
+ }
+ }
+ *y = x;
+return k;
+}
+
+static Bigint * i2b(AllocatedBlock ** aBlocks, Bigint ** freelist, int i)
+{
+ Bigint *b;
+
+ b = Balloc(aBlocks, freelist, 1);
+ b->x[0] = i;
+ b->wds = 1;
+
+return b;
+}
+
+static Bigint * mult(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ UINT_32 *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ UINT_32 y;
+ UINT_64 carry, z;
+
+ if (a->wds < b->wds)
+ {
+ c = a;
+ a = b;
+ b = c;
+ }
+
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds) { k++; }
+ c = Balloc(aBlocks, freelist, k);
+ for(x = c->x, xa = x + wc; x < xa; x++) { *x = 0; }
+
+ xa = a->x;
+ xae = xa + wa;
+
+ xb = b->x;
+ xbe = xb + wb;
+
+ xc0 = c->x;
+
+ for(; xb < xbe; xc0++)
+ {
+ if ((y = *xb++))
+ {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do
+ {
+ z = *x++ * (UINT_64)y + *xc + carry;
+ carry = z >> 32;
+ *xc++ = (UINT_32)z & FFFFFFFF;
+ }
+ while(x < xae);
+ *xc = (UINT_32)carry;
+ }
+ }
+
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { ;; }
+
+ c->wds = wc;
+
+return c;
+}
+
+//static Bigint *p5s;
+
+static Bigint * pow5mult(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3)) { b = multadd(aBlocks, freelist, b, p05[i-1], 0); }
+
+ if (!(k >>= 2)) { return b; }
+// if (!(p5 = p5s))
+ {
+ /* first time */
+ ACQUIRE_DTOA_LOCK(1);
+// if (!(p5 = p5s))
+ {
+ p5 /* = p5s*/ = i2b(aBlocks, freelist, 625);
+ p5->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+ }
+
+ for(;;)
+ {
+ if (k & 1)
+ {
+ b1 = mult(aBlocks, freelist, b, p5);
+ Bfree(freelist, b);
+ b = b1;
+ }
+ if (!(k >>= 1)) { break; }
+
+ if (!(p51 = p5->next))
+ {
+ ACQUIRE_DTOA_LOCK(1);
+ if (!(p51 = p5->next))
+ {
+ p51 = p5->next = mult(aBlocks, freelist, p5,p5);
+ p51->next = 0;
+ }
+ FREE_DTOA_LOCK(1);
+ }
+ p5 = p51;
+ }
+return b;
+}
+
+static Bigint * lshift(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *b, int k)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ UINT_32 *x, *x1, *xe, z;
+
+ n = k >> 5;
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1) { k1++; }
+
+ b1 = Balloc(aBlocks, freelist, k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++) { *x1++ = 0; }
+
+ x = b->x;
+ xe = x + b->wds;
+
+ if (k &= 0x1f)
+ {
+ k1 = 32 - k;
+ z = 0;
+ do
+ {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z)) { ++n1; }
+ }
+ else
+ {
+ do { *x1++ = *x++; } while(x < xe);
+ }
+ b1->wds = n1 - 1;
+ Bfree(freelist, b);
+
+return b1;
+}
+
+static int cmp(Bigint *a, Bigint *b)
+{
+ UINT_32 *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j) { return i; }
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;)
+ {
+ if (*--xa != *--xb)
+ {
+ return *xa < *xb ? -1 : 1;
+ }
+ if (xa <= xa0)
+ {
+ break;
+ }
+ }
+
+return 0;
+}
+
+static Bigint * diff(AllocatedBlock ** aBlocks, Bigint ** freelist, Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int i, wa, wb;
+ UINT_32 *xa, *xae, *xb, *xbe, *xc;
+
+ UINT_64 borrow, y;
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(aBlocks, freelist, 0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(aBlocks, freelist, a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+
+ do
+ {
+ y = (UINT_64)*xa++ - *xb++ - borrow;
+ borrow = y >> 32 & (UINT_32)1;
+ *xc++ = (UINT_32)y & FFFFFFFF;
+ }
+ while(xb < xbe);
+ while(xa < xae)
+ {
+ y = *xa++ - borrow;
+ borrow = y >> 32 & (UINT_32)1;
+ *xc++ = (UINT_32)y & FFFFFFFF;
+ }
+
+ while(!*--xc)
+ {
+ wa--;
+ }
+ c->wds = wa;
+
+return c;
+}
+
+static Bigint * d2b(AllocatedBlock ** aBlocks, Bigint ** freelist, double dd, int *e, int *bits)
+{
+ U d;
+ Bigint *b;
+ int de, k;
+ UINT_32 *x, y, z;
+ int i;
+#ifdef VAX
+ UINT_32 d0, d1;
+#endif
+ dval(d) = dd;
+#ifdef VAX
+ d0 = word0(d) >> 16 | word0(d) << 16;
+ d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+ #define d0 word0(d)
+ #define d1 word1(d)
+#endif
+ b = Balloc(aBlocks, freelist, 1);
+ x = b->x;
+
+ z = d0 & Frac_mask;
+ d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
+
+ if ((de = (int)(d0 >> Exp_shift))) { z |= Exp_msk1; }
+
+ if ((y = d1))
+ {
+ if ((k = lo0bits(&y)))
+ {
+ x[0] = y | (z << (32 - k));
+ z >>= k;
+ }
+ else
+ {
+ x[0] = y;
+ }
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else
+ {
+ #ifdef DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+ #endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+
+ if (de)
+ {
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+ }
+ else
+ {
+ *e = de - Bias - (P-1) + 1 + k;
+
+ *bits = 32*i - hi0bits(x[i-1]);
+ }
+
+return b;
+}
+
+#undef d0
+#undef d1
+
+
+static const double tens[] =
+{
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
+ 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
+ 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+};
+
+static const double
+#ifdef IEEE_Arith
+ bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+ 9007199254740992.*9007199254740992.e-256
+ /* = 2^106 * 1e-53 */
+#else
+ 1e-256
+#endif
+ };
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+ #define n_bigtens 5
+#else
+ #ifdef IBM
+ bigtens[] = { 1e16, 1e32, 1e64 };
+ static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+ #define n_bigtens 3
+ #else
+ bigtens[] = { 1e16, 1e32 };
+ static const double tinytens[] = { 1e-16, 1e-32 };
+ #define n_bigtens 2
+ #endif
+#endif
+
+static int quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ UINT_32 *bx, *bxe, q, *sx, *sxe;
+
+ UINT_64 borrow, carry, y, ys;
+
+ n = S->wds;
+#ifdef DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do
+ {
+ ys = *sx++ * (UINT_64)q + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (UINT_32)1;
+ *bx++ = (UINT_32)y & FFFFFFFF;
+ }
+ while(sx <= sxe);
+
+ if (!*bxe)
+ {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0)
+ {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do
+ {
+ ys = *sx++ + carry;
+ carry = ys >> 32;
+ y = *bx - (ys & FFFFFFFF) - borrow;
+ borrow = y >> 32 & (UINT_32)1;
+ *bx++ = (UINT_32)y & FFFFFFFF;
+ }
+ while(sx <= sxe);
+
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe)
+ {
+ while(--bxe > bx && !*bxe) { --n; }
+ b->wds = n;
+ }
+ }
+
+return q;
+}
+
+static char * rv_alloc(AllocatedBlock ** aBlocks, Bigint ** freelist, int i)
+{
+ int j, k, *r;
+
+ j = sizeof(UINT_32);
+ for(k = 0; sizeof(Bigint) - sizeof(UINT_32) - sizeof(int) + j <= (unsigned)i; j <<= 1) { k++; }
+ r = (int*)Balloc(aBlocks, freelist, k);
+ *r = k;
+ return (char *)(r+1);
+}
+
+static char * nrv_alloc(AllocatedBlock ** aBlocks, Bigint ** freelist, const char *s, char **rve, int n)
+{
+ char *rv, *t;
+
+ t = rv = rv_alloc(aBlocks, freelist, n);
+ while((*t = *s++)) { t++; }
+ if (rve) { *rve = t; }
+ return rv;
+}
+
+void freedtoa(AllocatedBlock ** aBlocks)
+{
+ safe_free(aBlocks);
+}
+
+/*void freedtoa(Bigint ** freelist, char *s)
+{
+ Bigint *b = (Bigint *)((int *)s - 1);
+ b->maxwds = 1 << (b->k = *(int*)b);
+ Bfree(freelist, b);
+}
+*/
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the INT_32
+ * calculation.
+ */
+
+char * ctpp_dtoa(AllocatedBlock ** aBlocks, Bigint ** freelist, double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
+{
+ /* Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4,5 ==> similar to 2 and 3, respectively, but (in
+ round-nearest mode) with the tests of mode 0 to
+ possibly return a shorter string that rounds to d.
+ With IEEE arithmetic and compilation with
+ -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+ as modes 2 and 3 when FLT_ROUNDS != 1.
+ 6-9 ==> Debugging modes similar to mode - 4: don't try
+ fast floating-point estimate (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ INT_32 bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick;
+ INT_32 L;
+
+ INT_32 denorm;
+ UINT_32 x;
+
+ Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
+ U d, d2, eps;
+ double ds;
+ char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+ int rounding;
+#endif
+
+ dval(d) = dd;
+ if (word0(d) & Sign_bit)
+ {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ word0(d) &= ~Sign_bit; /* clear sign bit */
+ }
+ else
+ {
+ *sign = 0;
+ }
+
+#if defined(IEEE_Arith) + defined(VAX)
+ #ifdef IEEE_Arith
+ if ((word0(d) & Exp_mask) == Exp_mask)
+ #else
+ if (word0(d) == 0x8000)
+ #endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ #ifdef IEEE_Arith
+ if (!word1(d) && !(word0(d) & 0xfffff)) { return nrv_alloc(aBlocks, freelist, "Infinity", rve, 8); }
+ #endif
+ return nrv_alloc(aBlocks, freelist, "NaN", rve, 3);
+ }
+#endif
+
+#ifdef IBM
+ dval(d) += 0; /* normalize */
+#endif
+ if (!dval(d))
+ {
+ *decpt = 1;
+ return nrv_alloc(aBlocks, freelist, "0", rve, 1);
+ }
+
+#ifdef Honor_FLT_ROUNDS
+ if ((rounding = Flt_Rounds) >= 2)
+ {
+ if (*sign)
+ {
+ rounding = (rounding == 2) ? 0 : 2;
+ }
+ else
+ {
+ if (rounding != 2)
+ {
+ rounding = 0;
+ }
+ }
+ }
+#endif
+
+ b = d2b(aBlocks, freelist, dval(d), &be, &bbits);
+
+ if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))))
+ {
+ dval(d2) = dval(d);
+ word0(d2) &= Frac_mask1;
+ word0(d2) |= Exp_11;
+#ifdef IBM
+ if (j = 11 - hi0bits(word0(d2) & Frac_mask)) { dval(d2) /= 1 << j; }
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+ denorm = 0;
+ }
+ else
+ {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? (word0(d) << (64 - i)) | (word1(d) >> (i - 32))
+ : word1(d) << (32 - i);
+ dval(d2) = x;
+ word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+
+ ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax)
+ {
+ if (dval(d) < tens[k]) { k--; }
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+
+ if (j >= 0)
+ {
+ b2 = 0;
+ s2 = j;
+ }
+ else
+ {
+ b2 = -j;
+ s2 = 0;
+ }
+
+ if (k >= 0)
+ {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else
+ {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+
+ if (mode < 0 || mode > 9) { mode = 0; }
+
+#ifdef Check_FLT_ROUNDS
+ try_quick = Rounding == 1;
+#else
+ try_quick = 1;
+#endif
+
+ if (mode > 5)
+ {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode)
+ {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ s = s0 = rv_alloc(aBlocks, freelist, i);
+
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1 && rounding != 1) { leftright = 0; }
+#endif
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick)
+ {
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ dval(d2) = dval(d);
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0)
+ {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch)
+ {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ dval(d) /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+
+ for(; j; j >>= 1, i++)
+ {
+ if (j & 1)
+ {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ }
+
+ dval(d) /= ds;
+ }
+ else if ((j1 = -k))
+ {
+ dval(d) *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ {
+ if (j & 1)
+ {
+ ieps++;
+ dval(d) *= bigtens[i];
+ }
+ }
+ }
+ if (k_check && dval(d) < 1. && ilim > 0)
+ {
+ if (ilim1 <= 0) { goto fast_failed; }
+ ilim = ilim1;
+ k--;
+ dval(d) *= 10.;
+ ieps++;
+ }
+ dval(eps) = ieps*dval(d) + 7.;
+ word0(eps) -= (P-1)*Exp_msk1;
+ if (ilim == 0)
+ {
+ S = mhi = 0;
+ dval(d) -= 5.;
+ if (dval(d) > dval(eps)) { goto one_digit; }
+ if (dval(d) < -dval(eps)) { goto no_digits; }
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright)
+ {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+ for(i = 0;;) {
+ L = (INT_32)dval(d);
+ dval(d) -= L;
+ *s++ = '0' + (int)L;
+ if (dval(d) < dval(eps))
+ goto ret1;
+ if (1. - dval(d) < dval(eps))
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ dval(eps) *= 10.;
+ dval(d) *= 10.;
+ }
+ }
+ else
+ {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ dval(eps) *= tens[ilim-1];
+ for(i = 1;; i++, dval(d) *= 10.)
+ {
+ L = (INT_32)(dval(d));
+ if (!(dval(d) -= L))
+ {
+ ilim = i;
+ }
+ *s++ = '0' + (int)L;
+ if (i == ilim)
+ {
+ if (dval(d) > 0.5 + dval(eps))
+ {
+ goto bump_up;
+ }
+ else if (dval(d) < 0.5 - dval(eps))
+ {
+ while(*--s == '0')
+ {
+ ;
+ }
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+fast_failed:
+ s = s0;
+ dval(d) = dval(d2);
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max)
+ {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0)
+ {
+ S = mhi = 0;
+ if (ilim < 0 || dval(d) <= 5*ds)
+ {
+ goto no_digits;
+ }
+ goto one_digit;
+ }
+ for(i = 1;; i++, dval(d) *= 10.)
+ {
+ L = (INT_32)(dval(d) / ds);
+ dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (dval(d) < 0) {
+ L--;
+ dval(d) += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (!dval(d)) {
+ break;
+ }
+ if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ switch(rounding) {
+ case 0: goto ret1;
+ case 2: goto bump_up;
+ }
+#endif
+ dval(d) += dval(d);
+ if (dval(d) > ds || ((dval(d) == ds) && (L & 1)))
+ {
+bump_up:
+ while(*--s == '9')
+ {
+ if (s == s0)
+ {
+ k++;
+ *s = '0';
+ break;
+ }
+ }
+ ++*s++;
+ }
+ break;
+ }
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright)
+ {
+ i =
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ b2 += i;
+ s2 += i;
+ mhi = i2b(aBlocks, freelist, 1);
+ }
+
+ if (m2 > 0 && s2 > 0)
+ {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0)
+ {
+ if (leftright)
+ {
+ if (m5 > 0)
+ {
+ mhi = pow5mult(aBlocks, freelist, mhi, m5);
+ b1 = mult(aBlocks, freelist, mhi, b);
+ Bfree(freelist, b);
+ b = b1;
+ }
+ if ((j = b5 - m5))
+ {
+ b = pow5mult(aBlocks, freelist, b, j);
+ }
+ }
+ else
+ {
+ b = pow5mult(aBlocks, freelist, b, b5);
+ }
+ }
+ S = i2b(aBlocks, freelist, 1);
+ if (s5 > 0)
+ {
+ S = pow5mult(aBlocks, freelist, S, s5);
+ }
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ spec_case = 0;
+ if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+ && rounding == 1
+#endif
+ )
+ {
+ if (!word1(d) && !(word0(d) & Bndry_mask) && word0(d) & (Exp_mask & ~Exp_msk1)
+ )
+ {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
+ {
+ i = 32 - i;
+ }
+
+ if (i > 4)
+ {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4)
+ {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+
+ if (b2 > 0)
+ {
+ b = lshift(aBlocks, freelist, b, b2);
+ }
+
+ if (s2 > 0)
+ {
+ S = lshift(aBlocks, freelist, S, s2);
+ }
+
+ if (k_check)
+ {
+ if (cmp(b,S) < 0)
+ {
+ k--;
+ b = multadd(aBlocks, freelist, b, 10, 0); /* we botched the k estimate */
+ if (leftright) { mhi = multadd(aBlocks, freelist, mhi, 10, 0); }
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && (mode == 3 || mode == 5))
+ {
+ if (ilim < 0 || cmp(b,S = multadd(aBlocks, freelist, S,5,0)) <= 0)
+ {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright)
+ {
+ if (m2 > 0)
+ {
+ mhi = lshift(aBlocks, freelist, mhi, m2);
+ }
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case)
+ {
+ mhi = Balloc(aBlocks, freelist, mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(aBlocks, freelist, mhi, Log2P);
+ }
+
+ for(i = 1;;i++)
+ {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(aBlocks, freelist, S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(freelist, delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+ #ifdef Honor_FLT_ROUNDS
+ && rounding >= 1
+ #endif
+ )
+ {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || ((j == 0) && (mode != 1)
+#ifndef ROUND_BIASED
+ && !(word1(d) & 1))
+#else
+ )
+#endif
+ )
+ {
+ if (!b->x[0] && b->wds <= 1)
+ {
+ goto accept_dig;
+ }
+#ifdef Honor_FLT_ROUNDS
+ if (mode > 1)
+ {
+ switch(rounding)
+ {
+ case 0: goto accept_dig;
+ case 2: goto keep_dig;
+ }
+ }
+#endif /*Honor_FLT_ROUNDS*/
+ if (j1 > 0)
+ {
+ b = lshift(aBlocks, freelist, b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || ((j1 == 0) && (dig & 1))) && dig++ == '9')
+ {
+ goto round_9_up;
+ }
+ }
+ accept_dig:
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0)
+ {
+#ifdef Honor_FLT_ROUNDS
+ if (!rounding) { goto accept_dig; }
+#endif
+ if (dig == '9')
+ {
+ /* possible if i == 1 */
+round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+
+ *s++ = dig + 1;
+ goto ret;
+ }
+#ifdef Honor_FLT_ROUNDS
+keep_dig:
+#endif
+ *s++ = dig;
+ if (i == ilim)
+ {
+ break;
+ }
+
+ b = multadd(aBlocks, freelist, b, 10, 0);
+
+ if (mlo == mhi)
+ {
+ mlo = mhi = multadd(aBlocks, freelist, mhi, 10, 0);
+ }
+ else
+ {
+ mlo = multadd(aBlocks, freelist, mlo, 10, 0);
+ mhi = multadd(aBlocks, freelist, mhi, 10, 0);
+ }
+ }
+ }
+ else
+ {
+ for(i = 1;; i++)
+ {
+ *s++ = dig = quorem(b,S) + '0';
+ if (!b->x[0] && b->wds <= 1)
+ {
+ goto ret;
+ }
+ if (i >= ilim)
+ {
+ break;
+ }
+ b = multadd(aBlocks, freelist, b, 10, 0);
+ }
+ }
+ /* Round off last digit */
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding)
+ {
+ case 0: goto trimzeros;
+ case 2: goto roundoff;
+ }
+#endif
+ b = lshift(aBlocks, freelist, b, 1);
+ j = cmp(b, S);
+ if (j > 0 || ((j == 0) && (dig & 1)))
+ {
+roundoff:
+ while(*--s == '9')
+ {
+ if (s == s0)
+ {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ }
+ ++*s++;
+ }
+ else
+ {
+#ifdef Honor_FLT_ROUNDS
+trimzeros:
+#endif
+ while(*--s == '0') { ;; }
+ s++;
+ }
+ ret:
+ Bfree(freelist, S);
+ if (mhi)
+ {
+ if (mlo && mlo != mhi) { Bfree(freelist, mlo); }
+ Bfree(freelist, mhi);
+ }
+ ret1:
+ Bfree(freelist, b);
+ *s = 0;
+ *decpt = k + 1;
+ if (rve) { *rve = s; }
+return s0;
+}
+
+// End.
diff --git a/src/CTPP2Error.cpp b/src/CTPP2Error.cpp
new file mode 100644
index 0000000..440366a
--- /dev/null
+++ b/src/CTPP2Error.cpp
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Error.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Error.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+CTPPError::CTPPError(const std::string & sTemplateName,
+ const std::string & sErrorDescr,
+ const UINT_32 iErrrorCode,
+ const UINT_32 iLine,
+ const UINT_32 iPos,
+ const UINT_32 iIP): template_name(sTemplateName),
+ error_descr(sErrorDescr),
+ error_code(iErrrorCode),
+ line(iLine),
+ pos(iPos),
+ ip(iIP)
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Exception.cpp b/src/CTPP2Exception.cpp
new file mode 100644
index 0000000..438f193
--- /dev/null
+++ b/src/CTPP2Exception.cpp
@@ -0,0 +1,255 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Exception.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Exception.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPException
+//
+//
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPException::what() const throw() { return "Unknown Error"; }
+
+//
+// A destructor
+//
+CTPPException::~CTPPException() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPLogicError
+//
+//
+
+//
+// Constrcutor
+//
+CTPPLogicError::CTPPLogicError(CCHAR_P sIReason) throw(): sReason(strdup(sIReason)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPLogicError::what() const throw() { return sReason; }
+
+//
+// A destructor
+//
+CTPPLogicError::~CTPPLogicError() throw() { free(sReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CDTTypeCastException
+//
+//
+
+//
+// Constrcutor
+//
+CDTTypeCastException::CDTTypeCastException(CCHAR_P sIReason) throw(): sReason(strdup(sIReason)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CDTTypeCastException::what() const throw() { return sReason; }
+
+//
+// A destructor
+//
+CDTTypeCastException::~CDTTypeCastException() throw() { free(sReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CDTAccessException
+//
+//
+
+//
+// Get human-readable error description
+//
+CCHAR_P CDTAccessException::what() const throw() { return "operator []"; }
+
+//
+// A destructor
+//
+CDTAccessException::~CDTAccessException() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CDTRangeException
+//
+//
+
+//
+// Get human-readable error description
+//
+CCHAR_P CDTRangeException::what() const throw() { return "pos > size"; }
+
+//
+// A destructor
+//
+CDTRangeException::~CDTRangeException() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPUnixException
+//
+//
+
+//
+// Constrcutor
+//
+CTPPUnixException::CTPPUnixException(CCHAR_P sIReason, INT_32 iIErrno) throw(): sReason(strdup(sIReason)), iErrno(iIErrno) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPUnixException::what() const throw() { return sReason; }
+
+//
+// Get un*x error code
+//
+INT_32 CTPPUnixException::ErrNo() const throw() { return iErrno; }
+
+//
+// A destructor
+//
+CTPPUnixException::~CTPPUnixException() throw() { free(sReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPNullPointerException
+//
+//
+
+//
+// Constrcutor
+//
+CTPPNullPointerException::CTPPNullPointerException(CCHAR_P sIReason) throw(): sReason(strdup(sIReason)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPNullPointerException::what() const throw() { return sReason; }
+
+//
+// A destructor
+//
+CTPPNullPointerException::~CTPPNullPointerException() throw() { free(sReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPCharsetRecodeException
+//
+//
+
+
+//
+// Constrcutor
+//
+CTPPCharsetRecodeException::CTPPCharsetRecodeException(CCHAR_P sISrc,
+ CCHAR_P sIDst) throw(): sSrc(strdup(sISrc)),
+ sDst(strdup(sIDst)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPCharsetRecodeException::what() const throw() { return "Cannot convert from source charset to destination"; }
+
+//
+// Get source charset
+//
+CCHAR_P CTPPCharsetRecodeException::GetSource() const throw() { return sSrc; }
+
+//
+// Get destination charset
+//
+CCHAR_P CTPPCharsetRecodeException::GetDestination() const throw() { return sDst; }
+
+//
+// A destructor
+//
+CTPPCharsetRecodeException::~CTPPCharsetRecodeException() throw()
+{
+ free(sSrc);
+ free(sDst);
+}
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPGetTextError
+//
+//
+
+//
+// Constructor
+//
+CTPPGetTextError::CTPPGetTextError(CCHAR_P sIReason) throw(): sReason(strdup(sIReason)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPGetTextError::what() const throw() { return sReason; }
+
+//
+// A destructor
+//
+CTPPGetTextError::~CTPPGetTextError() throw() { free(sReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPNoMemoryError
+//
+//
+
+//
+// Constructor
+//
+CTPPNoMemoryError::CTPPNoMemoryError() throw() { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CTPPNoMemoryError::what() const throw() { return "No memory"; }
+
+//
+// A destructor
+//
+CTPPNoMemoryError::~CTPPNoMemoryError() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2FileLogger.cpp b/src/CTPP2FileLogger.cpp
new file mode 100644
index 0000000..d4bc6c2
--- /dev/null
+++ b/src/CTPP2FileLogger.cpp
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Logger.cpp
+ *
+ * $CAS$
+ */
+#include "CTPP2FileLogger.hpp"
+
+#include <stdlib.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FileLogger::FileLogger(FILE * IF,
+ const UINT_32 iIBasePriority): Logger(iIBasePriority), F(IF)
+{
+ ;;
+}
+
+//
+// Write message to log file
+//
+INT_32 FileLogger::WriteLog(const UINT_32 iPriority,
+ CCHAR_P szString,
+ const UINT_32 iStringLen)
+{
+ fwrite(szString, iStringLen, 1, F);
+return 0;
+}
+
+//
+// A destructor
+//
+FileLogger::~FileLogger() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2FileOutputCollector.cpp b/src/CTPP2FileOutputCollector.cpp
new file mode 100644
index 0000000..13a1de5
--- /dev/null
+++ b/src/CTPP2FileOutputCollector.cpp
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2FileOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2FileOutputCollector.hpp"
+
+#include "CTPP2Exception.hpp"
+
+#include <errno.h>
+
+/**
+ @file CTPP2FileOutputCollector.hpp
+ @brief Virtual machine file output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FileOutputCollector::FileOutputCollector(FILE * oIF): oF(oIF), iSelfOpened(0)
+{
+ ;;
+}
+
+//
+// Constructor
+//
+FileOutputCollector::FileOutputCollector(CCHAR_P szFileName, CCHAR_P szMode): iSelfOpened(1)
+{
+ oF = fopen(szFileName, szMode);
+ if (oF == NULL) { throw CTPPUnixException("fopen", errno); }
+}
+
+//
+// Get unix file number
+//
+INT_32 FileOutputCollector::GetFileNo() const { return fileno(oF); }
+
+//
+// A destructor
+//
+FileOutputCollector::~FileOutputCollector() throw()
+{
+ if (iSelfOpened == 1) { fclose(oF); }
+}
+
+//
+// Collect data
+//
+INT_32 FileOutputCollector::Collect(const void * vData, const UINT_32 iDataLength)
+{
+ if (fwrite(vData, iDataLength, 1, oF) != 1) { return -1; }
+
+return 0;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2FileSourceLoader.cpp b/src/CTPP2FileSourceLoader.cpp
new file mode 100644
index 0000000..5bb4f66
--- /dev/null
+++ b/src/CTPP2FileSourceLoader.cpp
@@ -0,0 +1,295 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2FileSourceLoader.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2FileSourceLoader.hpp"
+
+#include "CTPP2Exception.hpp"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+ #include <direct.h> /* getcwd */
+ #include <windows.h>
+#endif
+
+/**
+ @file FileOutputCollector.hpp
+ @brief Virtual machine file output data collector
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Get base directory and normalise file path
+//
+
+#ifndef WIN32
+
+static STLW::string GetBaseDir(const STLW::string & szTemplateName, STLW::string & sNormalizedFileName)
+{
+ if (szTemplateName.length() == 0) { return ""; }
+
+ STLW::vector<STLW::string> vCurrentDir;
+
+ CCHAR_P sBegin = szTemplateName.c_str();
+ CCHAR_P szEnd = szTemplateName.c_str() + szTemplateName.length();
+
+ CCHAR_P sIter = sBegin;
+ while (sIter != szEnd)
+ {
+ if (*sIter == '/')
+ {
+ if (sIter != sBegin)
+ {
+ STLW::string sTMP(sBegin, sIter);
+
+ if (sTMP == "/." || sTMP == "/") { ;; }
+ else if (sTMP == "/..")
+ {
+ STLW::vector<STLW::string>::iterator itEnd = vCurrentDir.end();
+ if (vCurrentDir.begin() == itEnd) { return ""; }
+ vCurrentDir.erase(--itEnd);
+ }
+ else
+ {
+ vCurrentDir.push_back(sTMP);
+ }
+ }
+ sBegin = sIter;
+ }
+ ++sIter;
+ }
+
+ STLW::string sTMP(sBegin, sIter);
+ if (sTMP == "/") { return ""; }
+
+ STLW::string sResult;
+ for (UINT_32 iI = 0; iI < vCurrentDir.size(); ++iI) { sResult.append(vCurrentDir[iI]); }
+
+ sNormalizedFileName.assign(sResult);
+ sNormalizedFileName.append(sTMP);
+
+ sResult.append("/");
+
+return sResult;
+}
+
+#else
+
+static STLW::string GetBaseDir(const STLW::string & szTemplateName, STLW::string & sNormalizedFileName)
+{
+ STLW::string sResult;
+ CHAR_8 szPath[MAX_PATH];
+ CHAR_P szFile = NULL;
+ DWORD dwLen = ::GetFullPathNameA(szTemplateName.c_str(), MAX_PATH, szPath, &szFile);
+
+ if (szFile == NULL) { return ""; }
+
+ sNormalizedFileName.assign(szPath, dwLen);
+ sResult.assign(szPath, szFile);
+
+return sResult;
+}
+
+#endif
+
+
+//
+// Clone loader
+//
+CTPP2SourceLoader * CTPP2FileSourceLoader::Clone()
+{
+ CTPP2FileSourceLoader * pLoader = new CTPP2FileSourceLoader;
+
+ STLW::vector<STLW::string> vTMP(vIncludeDirs);
+
+ vTMP.push_back(sCurrentDir);
+
+ pLoader -> SetIncludeDirs(vTMP);
+
+return pLoader;
+}
+
+//
+// Constructor
+//
+CTPP2FileSourceLoader::CTPP2FileSourceLoader(): sTemplate(NULL), iTemplateSize(0)
+{
+ // Always search in current directory
+ vIncludeDirs.push_back("");
+}
+
+//
+// Set of directories where included templates should be found
+//
+void CTPP2FileSourceLoader::SetIncludeDirs(const STLW::vector<STLW::string> & vIIncludeDirs)
+{
+ { STLW::vector<STLW::string> vTMP; vIncludeDirs.swap(vTMP); }
+
+ STLW::vector<STLW::string>::const_iterator itvIIncludeDirs = vIIncludeDirs.begin();
+ while (itvIIncludeDirs != vIIncludeDirs.end())
+ {
+ if (itvIIncludeDirs -> length() != 0) { vIncludeDirs.push_back(*itvIIncludeDirs); }
+ ++itvIIncludeDirs;
+ }
+ vIncludeDirs.push_back("");
+}
+
+//
+// Load template with specified name
+//
+INT_32 CTPP2FileSourceLoader::LoadTemplate(CCHAR_P szTemplateName)
+{
+ sNormalizedFileName.erase();
+ INT_32 iStatCode = 0;
+ STLW::vector<STLW::string>::const_iterator itvIncludeDirs = vIncludeDirs.begin();
+ while(itvIncludeDirs != vIncludeDirs.end())
+ {
+ STLW::string sTMP = *itvIncludeDirs;
+#ifdef WIN32
+ if ( sTMP.length() && sTMP[sTMP.length() - 1] != '/' && sTMP[sTMP.length() - 1] != '\\' ) { sTMP.append("\\", 1); }
+#else
+ if (sTMP.length() && sTMP[sTMP.length() - 1] != '/') { sTMP.append("/", 1); }
+#endif
+ sTMP.append(szTemplateName);
+
+ sCurrentDir = GetBaseDir(sTMP, sNormalizedFileName);
+ if (sNormalizedFileName.length() == 0)
+ {
+ STLW::string sError("invalid file name `");
+ sError.append(sTMP);
+ sError.append("`");
+ throw CTPPLogicError(sError.c_str());
+ }
+
+ // Get file size
+ struct stat oStat;
+ iStatCode = stat(sNormalizedFileName.c_str(), &oStat);
+ if (iStatCode == 0)
+ {
+ iTemplateSize = oStat.st_size;
+ break;
+ }
+ ++itvIncludeDirs;
+ }
+
+ if (iStatCode == -1)
+ {
+ STLW::string sError("cannot find file in include directories ");
+ itvIncludeDirs = vIncludeDirs.begin();
+ for (;;)
+ {
+ sError.append("`");
+ if (itvIncludeDirs -> size() != 0) { sError.append(*itvIncludeDirs); }
+ else
+ {
+ CHAR_P szPWD = getcwd(NULL, 0);
+ sError.append(szPWD);
+ free(szPWD);
+ }
+ sError.append("`");
+
+ ++itvIncludeDirs;
+ if (itvIncludeDirs == vIncludeDirs.end()) { break; }
+
+ sError.append(", ");
+ }
+ throw CTPPLogicError(sError.c_str());
+ }
+
+ if (iTemplateSize == 0)
+ {
+ STLW::string sError("empty file `");
+ sError.append(sNormalizedFileName);
+ sError.append("` found");
+ throw CTPPLogicError(sError.c_str());
+ }
+
+ // Load file
+ FILE * F = fopen(sNormalizedFileName.c_str(), "rb");
+ if (F == NULL) { throw CTPPUnixException("fopen", errno); }
+
+ if (sTemplate != NULL) { free(sTemplate); }
+
+ // Allocate memory
+ sTemplate = (CHAR_P)malloc(iTemplateSize);
+
+ // Read from file
+ if (fread(sTemplate, iTemplateSize, 1, F) != 1)
+ {
+ if (ferror(F) != 0)
+ {
+ free(sTemplate);
+ fclose(F);
+ throw CTPPUnixException("fread", errno);
+ }
+ else
+ {
+ free(sTemplate);
+ fclose(F);
+ throw CTPPLogicError("Cannot read from file");
+ }
+ }
+
+ fclose(F);
+
+return 0;
+}
+
+//
+// Get template file name
+//
+CCHAR_P CTPP2FileSourceLoader::GetTemplateName() const { return sNormalizedFileName.c_str(); }
+
+//
+// Get template
+//
+CCHAR_P CTPP2FileSourceLoader::GetTemplate(UINT_32 & iITemplateSize)
+{
+ iITemplateSize = iTemplateSize;
+ return sTemplate;
+}
+
+//
+// A destructor
+//
+CTPP2FileSourceLoader::~CTPP2FileSourceLoader() throw()
+{
+ if (sTemplate != NULL) { free(sTemplate); }
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2GetText.cpp b/src/CTPP2GetText.cpp
new file mode 100644
index 0000000..e3a02a4
--- /dev/null
+++ b/src/CTPP2GetText.cpp
@@ -0,0 +1,1290 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Gettext.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2GetText.hpp"
+#include "CTPP2Exception.hpp"
+#include "CTPP2SyscallFactory.hpp"
+#include "STLFunctional.hpp"
+#include "functions/FnGetText.hpp"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined _MSC_VER
+#include "libgen_win32.h"
+#else
+#include <libgen.h>
+#endif
+
+#include <assert.h>
+
+#define LE_MAGIC 0x950412DE
+#define BE_MAGIC 0xDE120495
+
+//#define _GETTEXT_PLURAL_DEBUG 1
+//#define _GETTEXT_USE_REPORTER 1
+
+
+/*
+TernaryExpr = OrExpr { "?" TernaryExpr ":" TernaryExpr }
+
+OrExpr = AndExpr { "||" OrExpr }
+
+AndExpr = EqExpr { "&&" AndExpr }
+
+EqExpr = LtOrGtExpr { EqRelation LtOrGtExpr }
+
+LtOrGtExpr = ModExpr { LtOrGtRelation ModExpr }
+
+ModExpr = Term { "%" Term }
+
+Term = number | "n" | "(" TernaryExpr ")" | TernaryExpr
+
+EqRelation = EQ | NE
+LtOrGtRelation = GT | LT | GE | LE
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+#ifdef _GETTEXT_USE_REPORTER
+/**
+ @class Reporter
+ @brief Print template parsing syntax tree with indents
+*/
+class Reporter
+{
+public:
+ /**
+ @brief Constructor
+ @param sIData - method name
+ @param szCode - code to print
+ */
+ Reporter(const STLW::string & sIName, const STLW::string & sData, STLW::string::size_type iPos);
+
+ /**
+ @brief Destructor
+ */
+ ~Reporter() throw();
+private:
+ // Does not exist
+ Reporter(const Reporter & oRhs);
+ Reporter & operator=(const Reporter & oRhs);
+
+ /** Method name */
+ STLW::string sName;
+ /** Indent lebvel */
+ static int iLevel;
+};
+
+//
+// Constructor
+//
+Reporter::Reporter(const STLW::string & sIName, const STLW::string & sData, STLW::string::size_type iPos): sName(sIName)
+{
+ for (INT_32 iI = 0; iI < iLevel; ++iI) { fprintf(stdout, " "); }
+ ++iLevel;
+ fprintf(stdout, ">> %s: `%s`\n", sName.c_str(), sData.substr(iPos).c_str());
+}
+
+//
+// Destructor
+//
+Reporter::~Reporter() throw() { --iLevel; fprintf(stdout, "<< %s\n", sName.c_str()); }
+
+// Indent level
+int Reporter::iLevel = 0;
+
+// Fast access macros
+#define REPORTER(x, y, z) Reporter oReporter((x), (y), (z));
+
+#else // No reporter
+
+// Fast access macros
+#define REPORTER(x, y, z) { ; }
+
+#endif // Reporter class
+
+
+/**
+ @class ScopeGuard
+ @brief Deallocate memory of pointer when go out from scope
+ @tparam type of pointer
+*/
+template<typename T>
+class ScopeGuard
+{
+ /** Type of function, that deallocate memory */
+ typedef void (*DeleteFuncType)(T *);
+
+public:
+ /**
+ @brief Constructor
+ @param p - pointer
+ @param func - function for deleting pointer
+ */
+ ScopeGuard(T *p, DeleteFuncType func = DefaultDeleteFunc) :
+ pData(p), deleteFunc(func) { ;; }
+
+ /**
+ @brief Destructor
+ */
+ ~ScopeGuard() throw() { if (pData) { deleteFunc(pData); } }
+
+ /**
+ @brief Get pointer
+ @return pointer
+ */
+ T * Get() const { return pData; }
+
+ /**
+ @brief Release pointer
+ @return pointer
+ */
+ T * Release()
+ {
+ T * pTemp = pData;
+ pData = NULL;
+ return pTemp;
+ }
+
+private:
+ // Does not exist
+ ScopeGuard(const ScopeGuard &);
+ ScopeGuard & operator=(const ScopeGuard &);
+
+ /** Default function for deleting pointer */
+ static void DefaultDeleteFunc(T * p) { delete p; }
+
+ /** Pointer */
+ T * pData;
+ /** Function for deleting pointer */
+ DeleteFuncType deleteFunc;
+};
+
+//
+// Deletes array
+//
+static void DeleteArrFunc(UCHAR_P pData) { delete[] pData; }
+
+//
+// Split string into vector of substrings by separator
+//
+static void Split(const STLW::string & sStr, CHAR_8 cSep, STLW::vector<STLW::string> & vResult)
+{
+ STLW::string::size_type iPrevPos = 0;
+ STLW::string::size_type iPos = 0;
+
+ while ((iPos = sStr.find(cSep, iPos)) != STLW::string::npos)
+ {
+ STLW::string sSubstring(sStr.substr(iPrevPos, iPos - iPrevPos));
+ vResult.push_back(sSubstring);
+ iPrevPos = ++iPos;
+ }
+ STLW::string sSubstr(sStr.substr(iPrevPos, iPos - iPrevPos));
+ vResult.push_back(sSubstr);
+}
+
+//
+// Remove trailing and leading spaces from string
+//
+static void Trim(STLW::string & s)
+{
+ s.erase(
+ STLW::find_if(s.rbegin(), s.rend(), STLW::not1(STLW::ptr_fun<INT_32, INT_32>(::isspace))).base(),
+ s.end());
+
+ s.erase(
+ s.begin(),
+ STLW::find_if(s.begin(), s.end(), STLW::not1(STLW::ptr_fun<INT_32, INT_32>(::isspace))));
+}
+
+//
+// A constructor
+//
+CTPP2GetText::CTPP2GetText() { sDefaultDomain.assign("default"); }
+
+//
+// A destructor
+//
+CTPP2GetText::~CTPP2GetText() throw() { ;; }
+
+//
+// Add translation
+//
+void CTPP2GetText::AddTranslation(const STLW::string & sFileName, const STLW::string & sDomain, const STLW::string & sLang)
+{
+ UINT_32 iLength = 0;
+
+ ScopeGuard<UCHAR_8> pData(ReadFile(sFileName.c_str(), iLength), DeleteArrFunc);
+
+ sWorkableDomain = sDomain;
+ sWorkableLang = sLang;
+
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+
+ UINT_32 iMagic = (reinterpret_cast<UINT_32 *>(pData.Get()))[0];
+
+ switch (iMagic)
+ {
+ case LE_MAGIC:
+ oCatalog.b_reversed = false;
+ break;
+ case BE_MAGIC:
+ oCatalog.b_reversed = true;
+ break;
+ default:
+ {
+ STLW::string sMsg = sFileName + ": invalid MO file";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ break;
+ }
+
+ UINT_32 iMsgCount = ReadMOData(pData.Get(), 8);
+ UINT_32 iMasteridx = ReadMOData(pData.Get(), 12);
+ UINT_32 iTransidx = ReadMOData(pData.Get(), 16);
+
+ for (UINT_32 iI = 0; iI < iMsgCount; ++iI)
+ {
+ ExtractMessage(pData.Get(), iLength, iMasteridx, iTransidx);
+ iMasteridx += 2 * sizeof(UINT_32);
+ iTransidx += 2 * sizeof(UINT_32);
+ }
+
+ sWorkableDomain.erase();
+ sWorkableLang.erase();
+
+#if _GETTEXT_PLURAL_DEBUG
+ CatalogMap::const_iterator itmC = mCatalog.begin();
+ for (; itmC != mCatalog.end(); ++itmC)
+ {
+ fprintf(stdout, "============================================\n");
+ fprintf(stdout, "Language %s\n", itmC -> first.c_str());
+ fprintf(stdout, "============================================\n");
+ STLW::map<STLW::string, CTPP2Catalog>::const_iterator itm = itmC -> second;
+ for (; itm != itmC -> end(); ++itm)
+ {
+ fprintf(stdout, "CTPP2Catalog %s\n", itm -> first.c_str());
+ fprintf(stdout, "--------------------------------------------\n");
+ fprintf(stdout, "Charset: %s\n", itm -> second.s_charset.c_str());
+ fprintf(stdout, "Info:\n");
+ {
+ STLW::map<STLW::string, STLW::string>::const_iterator mit = itm -> second.m_info.begin();
+ for (; mit != itm -> second.m_info.end(); ++mit) {
+ fprintf(stdout, "\t%s: %s\n", mit -> first.c_str(), mit -> second.c_str());
+ }
+ }
+ fprintf(stdout, "Reversed: %d\n", itm -> second.b_reversed);
+ fprintf(stdout, "Messages:\n");
+ {
+ STLW::map<STLW::string, STLW::vector<STLW::string> >::const_iterator itmM = itm -> second.m_messages.begin();
+ ++itmM;
+ for (; itmM != itm -> second.m_messages.end(); ++itmM) {
+ fprintf(stdout, "\t'%s':\n", itmM -> first.c_str());
+ STLW::vector<STLW::string>::const_iterator vit = itmM -> second.begin();
+ for (; itv != itmM -> second.end(); ++itv) {
+ fprintf(stdout, "\t\t'%s' ", itv -> c_str());
+ }
+ fprintf(stdout, "\n");
+ }
+ }
+ fprintf(stdout, "--------------------------------------------\n");
+ }
+ fprintf(stdout, "============================================\n");
+ }
+#endif
+}
+
+//
+// Find translated message
+//
+STLW::string CTPP2GetText::FindMessage(const STLW::string & sLang, const STLW::string & sMessage, const STLW::string & sDomain_)
+{
+ STLW::string sDomain = sDomain_;
+ if (sDomain.empty()) { sDomain = sDefaultDomain; }
+
+ if (mCatalog.find(sLang) == mCatalog.end() || mCatalog[sLang].find(sDomain) == mCatalog[sLang].end()) { return sMessage; }
+
+ typedef STLW::map<STLW::string, STLW::vector<STLW::string> > MessageMap;
+ MessageMap & oMessages = mCatalog[sLang][sDomain].m_messages;
+ MessageMap::const_iterator itM = oMessages.find(sMessage);
+
+ if (itM == oMessages.end()) { return sMessage; }
+
+ return itM -> second[0];
+}
+
+//
+// Find translated message with correct plural form
+//
+STLW::string CTPP2GetText::FindPluralMessage(const STLW::string & sLang, const STLW::string & sMessage,
+ const STLW::string & sPlMessage, UINT_32 iCount, const STLW::string & sDomain_)
+{
+ STLW::string sDomain = sDomain_;
+ if (sDomain.empty()) { sDomain = sDefaultDomain; }
+
+ if (mCatalog.find(sLang) == mCatalog.end() ||
+ mCatalog[sLang].find(sDomain) == mCatalog[sLang].end() ||
+ mCatalog[sLang][sDomain].m_messages.find(sMessage) == mCatalog[sLang][sDomain].m_messages.end())
+ {
+ if (iCount > 1) { return sPlMessage; }
+ else { return sMessage; }
+ }
+
+ UINT_32 iN = CalculatePluralForm(iCount, sLang, sDomain);
+
+ typedef STLW::map<STLW::string, STLW::vector<STLW::string> > MessageMap;
+ MessageMap & oMessages = mCatalog[sLang][sDomain].m_messages;
+ MessageMap::const_iterator itM = oMessages.find(sMessage);
+
+ if (iN >= itM -> second.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sDomain + "': failed to found plural form: " + sMessage;
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ return itM -> second[iN];
+}
+
+//
+// Set default i18n domain
+//
+void CTPP2GetText::SetDefaultDomain(const STLW::string & sDomain) { sDefaultDomain = sDomain; }
+
+//
+// Initialize system calls FnGetText
+//
+void CTPP2GetText::InitSTDLibFunction(SyscallFactory & oSyscallFactory)
+{
+ FnGetText * pTMP = dynamic_cast<FnGetText *>(oSyscallFactory.GetHandlerByName("gettext"));
+ pTMP -> SetGetText(this);
+ pTMP = dynamic_cast<FnGetText *>(oSyscallFactory.GetHandlerByName("_"));
+ pTMP -> SetGetText(this);
+}
+
+//
+// Set language for system calls FnGetText/FnGetText_
+//
+void CTPP2GetText::SetLanguage(SyscallFactory & oSyscallFactory, const STLW::string & sLang)
+{
+ FnGetText * pTMP = dynamic_cast<FnGetText *>(oSyscallFactory.GetHandlerByName("gettext"));
+ pTMP -> SetLanguage(sLang);
+ pTMP = dynamic_cast<FnGetText *>(oSyscallFactory.GetHandlerByName("_"));
+ pTMP -> SetLanguage(sLang);
+}
+
+// Parsing of .mo file ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Parse line of metadata from .mo file
+//
+void CTPP2GetText::ParseMetadataLine(const STLW::string & sLine, STLW::string & sLastKey)
+{
+ STLW::string::size_type iLineDelimPos = sLine.find(":");
+ STLW::string sKey;
+ STLW::string sValue;
+ if (iLineDelimPos != STLW::string::npos)
+ {
+ sKey = sLine.substr(0, iLineDelimPos);
+ Trim(sKey);
+ STLW::transform(sKey.begin(), sKey.end(), sKey.begin(), ::tolower);
+ sValue = sLine.substr(iLineDelimPos + 1);
+ Trim(sValue);
+ mCatalog[sWorkableLang][sWorkableDomain].m_info[sKey] = sValue;
+ sLastKey = sKey;
+ }
+ else if (!sLastKey.empty())
+ {
+ mCatalog[sWorkableLang][sWorkableDomain].m_info[sLastKey] += "\n" + sLine;
+ }
+
+ if (sKey == "content-type")
+ {
+ STLW::string::size_type iCharsetPos = sValue.find("charset=");
+ if (iCharsetPos != STLW::string::npos)
+ {
+ mCatalog[sWorkableLang][sWorkableDomain].s_charset = sValue.substr(iCharsetPos + 8);
+ }
+ }
+ else if (sKey == "plural-forms")
+ {
+ STLW::vector<STLW::string> vPlurals;
+ Split(sValue, ';', vPlurals);
+ STLW::string sPluralRule = vPlurals[1].substr(vPlurals[1].find("plural=") + 7);
+ GeneratePluralRule(sPluralRule);
+ }
+}
+
+//
+// Parse metadata from .mo file
+//
+void CTPP2GetText::ParseMetadata(const STLW::string & sMeta)
+{
+ STLW::string sLastKey;
+
+ STLW::vector<STLW::string> vMetaLines;
+ Split(sMeta, '\n', vMetaLines);
+ STLW::vector<STLW::string>::iterator itvMetaLine = vMetaLines.begin();
+ for (; itvMetaLine != vMetaLines.end(); ++itvMetaLine)
+ {
+ Trim(*itvMetaLine);
+ if (!itvMetaLine -> empty()) { ParseMetadataLine(*itvMetaLine, sLastKey); }
+ }
+}
+
+//
+// Read .mo data by 4 bytes
+//
+UINT_32 CTPP2GetText::ReadMOData(UCCHAR_P pData, INT_32 iOffset)
+{
+ const UINT_32 *p = reinterpret_cast<const UINT_32 *>(pData + iOffset);
+
+ if (mCatalog[sWorkableLang][sWorkableDomain].b_reversed)
+ {
+ UINT_32 i0 = (*p >> 0) & 0xFF;
+ UINT_32 i1 = (*p >> 8) & 0xFF;
+ UINT_32 i2 = (*p >> 16) & 0xFF;
+ UINT_32 i3 = (*p >> 24) & 0xFF;
+
+ return (i0 << 24) | (i1 << 16) | (i2 << 8) | i3;
+ }
+
+ return *p;
+}
+
+//
+// Read .mo file
+//
+UCHAR_P CTPP2GetText::ReadFile(CCHAR_P szFileName, UINT_32 &iLength)
+{
+ FILE * pFile = ::fopen(szFileName, "rb");
+ if (!pFile)
+ {
+ STLW::string sMsg = STLW::string(szFileName) + ": " + strerror(errno);
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ struct stat st;
+ if (::fstat(fileno(pFile), &st) == -1)
+ {
+ STLW::string sMsg = STLW::string(szFileName) + ": fstat failed";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ ScopeGuard<UCHAR_8> pData(new UCHAR_8[st.st_size], DeleteArrFunc);
+
+ ::fseek(pFile, 0, SEEK_SET);
+
+ if (::fread(reinterpret_cast<void *>(pData.Get()), st.st_size, 1, pFile) < 1)
+ {
+ STLW::string sMsg = STLW::string(szFileName) + ": fread failed";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ iLength = st.st_size;
+ return pData.Release();
+}
+
+//
+// Extract message from .mo data
+//
+void CTPP2GetText::ExtractMessage(UCCHAR_P pData, UINT_32 iLength, INT_32 iMasteridx, INT_32 iTransidx)
+{
+ UINT_32 iMsgLen = ReadMOData(pData, iMasteridx);
+ UINT_32 iMsgOffset = ReadMOData(pData, iMasteridx + sizeof(UINT_32));
+ UINT_32 iTransLen = ReadMOData(pData, iTransidx);
+ UINT_32 iTransOffset = ReadMOData(pData, iTransidx + sizeof(UINT_32));
+ if (iMsgLen + iMsgOffset >= iLength || iTransLen + iTransOffset >= iLength)
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': corrupted MO file";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ STLW::string sMessage(reinterpret_cast<CCHAR_P>(pData + iMsgOffset), iMsgLen);
+ STLW::string sTMessage(reinterpret_cast<CCHAR_P>(pData + iTransOffset), iTransLen);
+
+ if (iMsgLen == 0) { ParseMetadata(sTMessage); }
+
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+ STLW::string::size_type iPos = sMessage.find("\x00");
+ if (iPos != STLW::string::npos)
+ {
+ STLW::vector<STLW::string> vMsgIds;
+ Split(sMessage, '\x00', vMsgIds);
+
+ STLW::vector<STLW::string> vTMsgIds;
+ Split(sTMessage, '\x00', vTMsgIds);
+
+ oCatalog.m_messages[vMsgIds[0]] = vTMsgIds;
+ }
+ else
+ {
+ STLW::vector<STLW::string> vTMsgIds;
+ vTMsgIds.push_back(sTMessage);
+ oCatalog.m_messages[sMessage] = vTMsgIds;
+ }
+}
+
+// Expressions for generating plural form rule ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Term = number | "n" | "(" TernaryExpr ")" | TernaryExpr
+//
+STLW::string::size_type CTPP2GetText::IsTerm(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsTerm", sData, iPos);
+
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+ if (::isdigit(sData[iPos]))
+ {
+ STLW::string::size_type iDigitPos = iPos;
+ while (::isdigit(sData[iPos])) { ++iPos; }
+ STLW::string sDigit = sData.substr(iDigitPos, iPos - iDigitPos);
+ INT_32 iDigit = atoi(sDigit.c_str());
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: %d\n", iDigit);
+#endif
+ oCatalog.v_pl_stack.push_back(CTPP2Data(iDigit));
+ }
+ else if (sData[iPos] == 'n')
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: n\n");
+#endif
+ oCatalog.v_pl_stack.push_back(CTPP2Data());
+ ++iPos;
+ }
+ else if (sData[iPos] == '(')
+ {
+ ++iPos;
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsTerm)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ iPos = IsTernaryExpr(sData, iPos);
+
+ if (sData[iPos] != ')')
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (2 IsTerm)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ ++iPos;
+ }
+ else
+ {
+ UINT_32 iNextPos = IsTernaryExpr(sData, iPos);
+
+ if (iNextPos == iPos)
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (3 IsTerm)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ iPos = iNextPos;
+ }
+
+ return iPos;
+}
+
+//
+// ModExpr = Term { "%" Term }
+//
+STLW::string::size_type CTPP2GetText::IsModExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsModExr", sData, iPos);
+
+ iPos = IsTerm(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ if (sData[iPos] == '%')
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '%%'\n");
+#endif
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+
+ oCatalog.v_pl_instructions.push_back(INS_MOD);
+
+ iPos = IsTerm(sData, iPos + 1);
+ if (iPos == STLW::string::npos)
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (2 IsModExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ }
+
+ return iPos;
+}
+
+//
+// LtOrGtExpr = ModExpr { LtOrGtRelation ModExpr }
+//
+STLW::string::size_type CTPP2GetText::IsLtOrGtExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsLtOrGtExpr", sData, iPos);
+
+ iPos = IsModExpr(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+
+ bool bHasRelation = true;
+ if (sData.find(">=", iPos) == iPos)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '>='\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_GE);
+ iPos += 2;
+ }
+ else if (sData.find("<=", iPos) == iPos)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '<='\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_LE);
+ iPos += 2;
+ }
+ else if (sData[iPos] == '<')
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '<'\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_LT);
+ ++iPos;
+ }
+ else if (sData[iPos] == '>')
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '>'\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_GT);
+ ++iPos;
+ }
+ else
+ {
+ bHasRelation = false;
+ }
+
+ if (bHasRelation)
+ {
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsLtOrGtExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ iPos = IsModExpr(sData, iPos);
+ }
+
+ return iPos;
+}
+
+//
+// EqExpr = LtOrGtExpr { EqRelation LtOrGtExpr }
+//
+STLW::string::size_type CTPP2GetText::IsEqExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsEqExpr", sData, iPos);
+
+ iPos = IsLtOrGtExpr(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+
+ bool bHasRelation = true;
+ if (sData.find("==", iPos) == iPos)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '=='\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_EQ);
+ iPos += 2;
+ }
+ else if (sData.find("!=", iPos) == iPos)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> OPERATOR '!='\n");
+#endif
+ oCatalog.v_pl_instructions.push_back(INS_NE);
+ iPos += 2;
+ }
+ else
+ {
+ bHasRelation = false;
+ }
+
+ if (bHasRelation)
+ {
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsEqExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ iPos = IsLtOrGtExpr(sData, iPos);
+ }
+
+ return iPos;
+}
+
+//
+// AndExpr = EqExpr { "&&" AndExpr }
+//
+STLW::string::size_type CTPP2GetText::IsAndExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsAndExpr", sData, iPos);
+
+ iPos = IsEqExpr(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ if (sData.find("&&", iPos) == iPos)
+ {
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> JUMP IF '&&'\n");
+#endif
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+ oCatalog.v_pl_instructions.push_back(INS_JLAND);
+
+ oCatalog.v_pl_stack.push_back(0);
+ oCatalog.v_pl_stack.push_back(0);
+ UINT_32 iSIdx = oCatalog.v_pl_stack.size() - 2;
+ UINT_32 iIIdx = oCatalog.v_pl_stack.size() - 1;
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: 0 (STACK OFFSET), IDX = %u\n", iSIdx);
+fprintf(stdout, "PUSH: 0 (INSTRUCTION OFFSET), IDX = %u\n", iIIdx);
+#endif
+
+ UINT_32 iPrevStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iPrevInstrSize = oCatalog.v_pl_instructions.size();
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsAndExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ iPos = IsAndExpr(sData, iPos + 2);
+
+ UINT_32 iStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iInstrSize = oCatalog.v_pl_instructions.size();
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "REPLACE: %u (STACK OFFSET), IDX = %u\n", iStackSize - iPrevStackSize, iSIdx);
+fprintf(stdout, "REPLACE: %u (INSTRUCTION OFFSET), IDX = %u\n", iInstrSize - iPrevInstrSize, iIIdx);
+#endif
+
+ oCatalog.v_pl_stack[iSIdx] = iStackSize - iPrevStackSize;
+ oCatalog.v_pl_stack[iIIdx] = iInstrSize - iPrevInstrSize;
+ }
+
+
+ return iPos;
+}
+
+//
+// OrExpr = AndExpr { "||" OrExpr }
+//
+STLW::string::size_type CTPP2GetText::IsOrExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsOrExpr", sData, iPos);
+
+ iPos = IsAndExpr(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ if (sData.find("||", iPos) == iPos)
+ {
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> JUMP IF '||'\n");
+#endif
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+ oCatalog.v_pl_instructions.push_back(INS_JLOR);
+
+ oCatalog.v_pl_stack.push_back(0);
+ oCatalog.v_pl_stack.push_back(0);
+ UINT_32 iSIdx = oCatalog.v_pl_stack.size() - 2;
+ UINT_32 iIIdx = oCatalog.v_pl_stack.size() - 1;
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: 0 (STACK OFFSET), IDX = %u\n", iSIdx);
+fprintf(stdout, "PUSH: 0 (INSTRUCTION OFFSET), IDX = %u\n", iIIdx);
+#endif
+
+ UINT_32 iPrevStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iPrevInstrSize = oCatalog.v_pl_instructions.size();
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsOrExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ iPos = IsOrExpr(sData, iPos + 2);
+
+ UINT_32 iStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iInstrSize = oCatalog.v_pl_instructions.size();
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "REPLACE: %u (STACK OFFSET), IDX = %u\n", iStackSize - iPrevStackSize, iSIdx);
+fprintf(stdout, "REPLACE: %u (INSTRUCTION OFFSET), IDX = %u\n", iInstrSize - iPrevInstrSize, iIIdx);
+#endif
+
+ oCatalog.v_pl_stack[iSIdx] = iStackSize - iPrevStackSize;
+ oCatalog.v_pl_stack[iIIdx] = iInstrSize - iPrevInstrSize;
+ }
+
+ return iPos;
+}
+
+//
+// TernaryExpr = OrExpr { "?" TernaryExpr ":" TernaryExpr }
+//
+STLW::string::size_type CTPP2GetText::IsTernaryExpr(const STLW::string & sData, STLW::string::size_type iPos)
+{
+ REPORTER("IsTernaryExpr", sData, iPos);
+
+ iPos = IsOrExpr(sData, iPos);
+ if (iPos == STLW::string::npos) { return iPos; }
+
+ if (sData[iPos] == '?')
+ {
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> JUMP IF '?:'\n");
+#endif
+ CTPP2Catalog & oCatalog = mCatalog[sWorkableLang][sWorkableDomain];
+ oCatalog.v_pl_instructions.push_back(INS_JN);
+
+ oCatalog.v_pl_stack.push_back(0);
+ oCatalog.v_pl_stack.push_back(0);
+ UINT_32 iJNSIdx = oCatalog.v_pl_stack.size() - 2;
+ UINT_32 iJNIIdx = oCatalog.v_pl_stack.size() - 1;
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: 0 (STACK OFFSET), IDX = %u\n", iJNSIdx);
+fprintf(stdout, "PUSH: 0 (INSTRUCTION OFFSET), IDX = %u\n", iJNIIdx);
+#endif
+
+ UINT_32 iPrevStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iPrevInstrSize = oCatalog.v_pl_instructions.size();
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (1 IsTernaryExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ iPos = IsTernaryExpr(sData, iPos + 1);
+
+ UINT_32 iStackSize = oCatalog.v_pl_stack.size();
+ UINT_32 iInstrSize = oCatalog.v_pl_instructions.size();
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "REPLACE: %u (STACK OFFSET), IDX = %u\n", iStackSize - iPrevStackSize + 2, iJNSIdx);
+fprintf(stdout, "REPLACE: %u (INSTRUCTION OFFSET), IDX = %u\n", iInstrSize - iPrevInstrSize, iJNIIdx);
+#endif
+ oCatalog.v_pl_stack[iJNSIdx] = iStackSize - iPrevStackSize + 2;
+ oCatalog.v_pl_stack[iJNIIdx] = iInstrSize - iPrevInstrSize;
+
+ if (sData[iPos] == ':')
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "\t --> JUMP\n");
+#endif
+ ++iPos;
+ if (iPos >= sData.size())
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (2 IsTernaryExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+
+ oCatalog.v_pl_instructions.push_back(INS_JMP);
+
+ oCatalog.v_pl_stack.push_back(0);
+ oCatalog.v_pl_stack.push_back(0);
+ UINT_32 iJMPSIdx = oCatalog.v_pl_stack.size() - 2;
+ UINT_32 iJMPIIdx = oCatalog.v_pl_stack.size() - 1;
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "PUSH: 0 (STACK OFFSET), IDX = %u\n", iJMPSIdx);
+fprintf(stdout, "PUSH: 0 (INSTRUCTION OFFSET), IDX = %u\n", iJMPIIdx);
+#endif
+
+ iPrevStackSize = oCatalog.v_pl_stack.size();
+ iPrevInstrSize = oCatalog.v_pl_instructions.size();
+ iPos = IsTernaryExpr(sData, iPos);
+ iStackSize = oCatalog.v_pl_stack.size();
+ iInstrSize = oCatalog.v_pl_instructions.size();
+#ifdef _GETTEXT_PLURAL_DEBUG
+fprintf(stdout, "REPLACE: %u (STACK OFFSET), IDX = %u\n", iStackSize - iPrevStackSize, iJMPSIdx);
+fprintf(stdout, "REPLACE: %u (INSTRUCTION OFFSET), IDX = %u\n", iInstrSize - iPrevInstrSize, iJMPIIdx);
+#endif
+ oCatalog.v_pl_stack[iJMPSIdx] = iStackSize - iPrevStackSize;
+ oCatalog.v_pl_stack[iJMPIIdx] = iInstrSize - iPrevInstrSize;
+ }
+ else
+ {
+ STLW::string sMsg = STLW::string("i18n domain '") + sWorkableDomain + "': plural rule parser error (3 IsTernaryExpr)";
+ throw CTPPGetTextError(sMsg.c_str());
+ }
+ }
+
+ return iPos;
+}
+
+// Other stuff ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Calculate plural form of message
+//
+UINT_32 CTPP2GetText::CalculatePluralForm(UINT_32 iCount, const STLW::string & sLang, const STLW::string & sDomain)
+{
+ STLW::vector<UINT_32> vStack;
+ CTPP2Catalog & oCatalog = mCatalog[sLang][sDomain];
+ vStack.reserve(oCatalog.v_pl_stack.size());
+
+ STLW::vector<CTPP2Data>::reverse_iterator itvSrc = oCatalog.v_pl_stack.rbegin();
+ for (; itvSrc != oCatalog.v_pl_stack.rend(); ++itvSrc)
+ {
+ if (itvSrc -> b_variable) { vStack.push_back(iCount); }
+ else { vStack.push_back(itvSrc -> i_value); }
+ }
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "==>");
+ for (STLW::vector<eCTPP2Instruction>::iterator it = oCatalog.v_pl_instructions.begin();
+ it != oCatalog.v_pl_instructions.end(); ++it)
+ {
+ fprintf(stdout, " %s", StringifyInstruction(*it));
+ }
+ fprintf(stdout, " <==\n");
+#endif
+
+ STLW::vector<eCTPP2Instruction>::iterator itvPluralInstrs = oCatalog.v_pl_instructions.begin();
+ while (itvPluralInstrs != oCatalog.v_pl_instructions.end())
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "\t --> INSTRUCTION: %s\n", StringifyInstruction(*itvPluralInstrs));
+ fprintf(stdout, "\t --> STACK DUMP: ");
+ for (INT_32 iN = vStack.size() - 1; iN >= 0; --iN) { fprintf(stdout, "%u, ", vStack[iN]); }
+ fprintf(stdout, "\n");
+#endif
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+#define CALCULATE_EXPR(N) \
+ do { \
+ UINT_32 iLeft = vStack.back(); \
+ fprintf(stdout, "POP: %u (iLeft)\n", iLeft); \
+ vStack.pop_back(); \
+ UINT_32 iRight = vStack.back(); \
+ fprintf(stdout, "POP: %u (iRight)\n", iRight); \
+ vStack.pop_back(); \
+ vStack.push_back(N); \
+ fprintf(stdout, "PUSH: %u (RESULT OF '%s')\n", N, #N); \
+ } while(0)
+#else
+#define CALCULATE_EXPR(N) \
+ do { \
+ UINT_32 iLeft = vStack.back(); \
+ vStack.pop_back(); \
+ UINT_32 iRight = vStack.back(); \
+ vStack.pop_back(); \
+ vStack.push_back(N); \
+ } while(0)
+#endif
+
+ switch (*itvPluralInstrs)
+ {
+ case INS_EQ:
+ CALCULATE_EXPR(iLeft == iRight);
+ break;
+ case INS_LE:
+ CALCULATE_EXPR(iLeft <= iRight);
+ break;
+ case INS_GE:
+ CALCULATE_EXPR(iLeft >= iRight);
+ break;
+ case INS_LT:
+ CALCULATE_EXPR(iLeft < iRight);
+ break;
+ case INS_GT:
+ CALCULATE_EXPR(iLeft > iRight);
+ break;
+ case INS_NE:
+ CALCULATE_EXPR(iLeft != iRight);
+ break;
+ case INS_MOD:
+ CALCULATE_EXPR(iLeft % iRight);
+ break;
+#undef CALCULATE_EXPR
+ case INS_JLAND:
+ {
+ UINT_32 iCond = vStack.back();
+ vStack.pop_back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (JLAND CONDITION)\n", iCond);
+#endif
+
+ UINT_32 iStackOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (STACK OFFSET)\n", iStackOffset);
+#endif
+ vStack.pop_back();
+ UINT_32 iInstrOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (INSTRUCTION OFFSET)\n", iInstrOffset);
+#endif
+ vStack.pop_back();
+
+ if (!iCond)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ STLW::vector<UINT_32>::const_reverse_iterator itvStack = vStack.rbegin();
+ for (INT_32 iN = vStack.size() - iStackOffset; itvStack != vStack.rend() && iN < vStack.size() ; ++iN)
+ {
+ fprintf(stdout, "POP: %d (JLAND UNUSED)\n", *itvStack);
+ }
+#endif
+ vStack.resize(vStack.size() - iStackOffset);
+ for (UINT_32 iI = 0; iI < iInstrOffset; ++iI)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ assert(itvPluralInstrs != oCatalog.v_pl_instructions.end());
+#endif
+ ++itvPluralInstrs;
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "\t --> INSTRUCTION (SKIP): %s\n",
+ StringifyInstruction(*itvPluralInstrs));
+#endif
+ }
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "PUSH: %u (JLAND CONDITION)\n", iCond);
+#endif
+ vStack.push_back(iCond);
+ }
+ }
+ break;
+ case INS_JLOR:
+ {
+ UINT_32 iCond = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (JLOR CONDITION)\n", iCond);
+#endif
+ vStack.pop_back();
+
+ UINT_32 iStackOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (STACK OFFSET)\n", iStackOffset);
+#endif
+ vStack.pop_back();
+ UINT_32 iInstrOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (INSTRUCTION OFFSET)\n", iInstrOffset);
+#endif
+ vStack.pop_back();
+
+ if (iCond)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ STLW::vector<UINT_32>::const_reverse_iterator itvStack = vStack.rbegin();
+ for (INT_32 iN = vStack.size() - iStackOffset; itvStack != vStack.rend() && iN < vStack.size() ; ++iN)
+ {
+ fprintf(stdout, "POP: %d (JLOR UNUSED)\n", *itvStack);
+ }
+#endif
+ vStack.resize(vStack.size() - iStackOffset);
+ for (UINT_32 iI = 0; iI < iInstrOffset; ++iI)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ assert(itvPluralInstrs != oCatalog.v_pl_instructions.end());
+#endif
+ ++itvPluralInstrs;
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "\t --> INSTRUCTION (SKIP): %s\n", StringifyInstruction(*itvPluralInstrs));
+#endif
+ }
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "PUSH: %u (JLAND CONDITION)\n", iCond);
+#endif
+ vStack.push_back(iCond);
+ }
+ }
+ break;
+ case INS_JN:
+ {
+ UINT_32 iCond = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (JN CONDITION)\n", iCond);
+#endif
+ vStack.pop_back();
+
+ UINT_32 iStackOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (STACK OFFSET)\n", iStackOffset);
+#endif
+ vStack.pop_back();
+ UINT_32 iInstrOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (INSTRUCTION OFFSET)\n", iInstrOffset);
+#endif
+ vStack.pop_back();
+
+ if (!iCond)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ STLW::vector<UINT_32>::const_reverse_iterator itvStack = vStack.rbegin();
+ for (INT_32 iN = vStack.size() - iStackOffset; itvStack != vStack.rend() && iN < vStack.size() ; ++iN)
+ {
+ fprintf(stdout, "POP: %d (JN UNUSED)\n", *itvStack);
+ }
+#endif
+ vStack.resize(vStack.size() - iStackOffset);
+ for (UINT_32 iI = 0; iI < iInstrOffset + 1; ++iI)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ assert(itvPluralInstrs != oCatalog.v_pl_instructions.end());
+#endif
+ ++itvPluralInstrs;
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "\t --> INSTRUCTION (SKIP): %s\n", StringifyInstruction(*itvPluralInstrs));
+#endif
+ }
+ }
+ }
+ break;
+ case INS_JMP:
+ {
+ INT_32 iLastValue = vStack.back();
+ vStack.pop_back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (LAST VALUE)\n", iLastValue);
+#endif
+
+ UINT_32 iStackOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (STACK OFFSET)\n", iStackOffset);
+#endif
+ vStack.pop_back();
+ UINT_32 iInstrOffset = vStack.back();
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "POP: %u (INSTRUCTION OFFSET)\n", iInstrOffset);
+#endif
+ vStack.pop_back();
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+ STLW::vector<UINT_32>::const_reverse_iterator itvStack = vStack.rbegin();
+ for (INT_32 iN = vStack.size() - iStackOffset; itvStack != vStack.rend() && iN < vStack.size() ; ++iN)
+ {
+ fprintf(stdout, "POP: %d (JMP UNUSED)\n", *itvStack);
+ }
+#endif
+ vStack.resize(vStack.size() - iStackOffset);
+ for (UINT_32 iI = 0; iI < iInstrOffset; ++iI)
+ {
+#ifdef _GETTEXT_PLURAL_DEBUG
+ assert(itvPluralInstrs != oCatalog.v_pl_instructions.end());
+#endif
+ ++itvPluralInstrs;
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "\t --> INSTRUCTION (SKIP): %s\n", StringifyInstruction(*itvPluralInstrs));
+#endif
+ }
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "PUSH: %u (LAST VALUE)\n", iLastValue);
+#endif
+ vStack.push_back(iLastValue);
+ }
+ break;
+ default:
+ break;
+ }
+ ++itvPluralInstrs;
+ }
+
+#ifdef _GETTEXT_PLURAL_DEBUG
+ fprintf(stdout, "Stack size: %u\n", vStack.size());
+ for (UINT_32 idx = 0; idx < vStack.size(); ++idx) { fprintf(stdout, "--> %u\n", vStack[idx]); }
+#endif
+ return vStack.back();
+}
+
+//
+// Generate plural form rule
+//
+void CTPP2GetText::GeneratePluralRule(const STLW::string & sPluralRule)
+{
+ STLW::string s = sPluralRule;
+ s.erase(STLW::remove_if(s.begin(), s.end(), ::isspace), s.end());
+ IsTernaryExpr(s, 0);
+ mCatalog[sWorkableLang][sWorkableDomain].v_pl_instructions.push_back(INS_NONE);
+}
+
+//
+// Stringify instruction for determining plural form
+//
+CCHAR_P CTPP2GetText::StringifyInstruction(eCTPP2Instruction eType)
+{
+ switch (eType)
+ {
+ case INS_EQ:
+ return "'=='";
+ case INS_LE:
+ return "'<='";
+ case INS_GE:
+ return "'>='";
+ case INS_LT:
+ return "'<'";
+ case INS_GT:
+ return "'>'";
+ case INS_NE:
+ return "'!='";
+ case INS_MOD:
+ return "'%'";
+ case INS_JN:
+ return "JN";
+ case INS_JMP:
+ return "JMP";
+ case INS_JLAND:
+ return "JLAND";
+ case INS_JLOR:
+ return "JLOR";
+ case INS_NONE:
+ return "NONE";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2HashTable.cpp b/src/CTPP2HashTable.cpp
new file mode 100644
index 0000000..783951a
--- /dev/null
+++ b/src/CTPP2HashTable.cpp
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2HashTable.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2HashTable.hpp"
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// hash function
+//
+UINT_64 HashFunc(CCHAR_P sKey,
+ const UINT_32 iLength)
+{
+ UINT_64 ulHash = 5381;
+ UCCHAR_P sEnd = (UCCHAR_P)sKey + iLength;
+
+ while ((UCCHAR_P)sKey != sEnd)
+ {
+ ulHash += (ulHash << 5);
+ ulHash ^= (UINT_64) *(UCCHAR_P)sKey++;
+ }
+return ulHash;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class ReducedHashTable
+//
+
+//
+// Constructor
+//
+ReducedHashTable::ReducedHashTable(const HashElement * aIElements,
+ const UINT_32 iIPower): aElements(aIElements),
+ iPower(iIPower)
+{
+ iBase = (1 << iPower) - 1;
+}
+
+//
+// Get value from hash
+//
+UINT_64 ReducedHashTable::Get(CCHAR_P szKey,
+ const UINT_32 iKeyLength) const
+{
+ // 1. Calculate hash
+ const UINT_64 iHash = HashFunc(szKey, iKeyLength);
+ // 2. Get position in array
+ const UINT_64 iPos = iHash & iBase;
+ // 3. Check hash value
+ const HashElement & oElement = aElements[iPos];
+
+ // Mistake?
+ if (iHash != oElement.hash) { return (UINT_64)-1; }
+
+return oElement.value;
+}
+
+//
+// Get hash size
+//
+UINT_64 ReducedHashTable::Size() const { return UINT_64(1 << iPower); }
+
+//
+// A destructor
+//
+ReducedHashTable::~ReducedHashTable() throw() { ;; }
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class HashTable
+//
+
+//
+// Constructor
+//
+HashTable::HashTable(): iPower(1)
+{
+ const UINT_32 iNewElements = 1 << iPower;
+ aElements = new HashElement[iNewElements];
+ iBase = iNewElements - 1;
+ iUsed = 0;
+
+ UINT_32 iPos = 0;
+ for(; iPos < iNewElements; ++iPos)
+ {
+ HashElement & oNewElement = aElements[iPos];
+
+ oNewElement.hash = (UINT_64)-1;
+ oNewElement.value = (UINT_64)-1;
+ }
+}
+
+//
+// Get value from hash
+//
+INT_64 HashTable::Get(CCHAR_P szKey,
+ const UINT_32 iKeyLength) const
+{
+ // 1. Calculate hash
+ const UINT_64 iHash = HashFunc(szKey, iKeyLength);
+ // 2. Get position in array
+ const UINT_64 iPos = iHash & iBase;
+ // 3. Check hash value
+ const HashElement & oElement = aElements[iPos];
+
+ // Mistake?
+ if (iHash != oElement.hash) { return -1; }
+
+return oElement.value;
+}
+
+//
+// Get hash size
+//
+UINT_64 HashTable::Size() const { return UINT_64(1 << iPower); }
+
+//
+// Put value into hash
+//
+UINT_32 HashTable::Put(CCHAR_P szKey,
+ const UINT_32 iKeyLength,
+ const UINT_64 iValue)
+{
+ // 1. Calculate hash
+ const UINT_64 iHash = HashFunc(szKey, iKeyLength);
+
+ for (;;)
+ {
+ // 2. Get position in array
+ const UINT_64 iPos = iHash & iBase;
+ // 3. Check hash value
+ HashElement & oElement = aElements[iPos];
+
+ // Duplicate!
+ if (oElement.hash == iHash) { return (UINT_32)-1; }
+
+ // Resize hash
+ if (oElement.value != (UINT_64)-1) { Resize(); }
+ else
+ {
+ ++iUsed;
+ oElement.hash = iHash;
+ oElement.value = iValue;
+ return 0;
+ }
+ }
+
+// Make compiler happy
+return (UINT_32)-1;
+}
+
+//
+// Resize hash
+//
+void HashTable::Resize()
+{
+ const UINT_32 iOldElements = 1 << iPower;
+
+ ++iPower;
+ const UINT_32 iNewElements = 1 << iPower;
+
+ // Create new array of elements
+ HashElement * aTMP = new HashElement[iNewElements];
+ iBase = iNewElements - 1;
+
+ UINT_32 iPos = 0;
+ for(; iPos < iNewElements; ++iPos)
+ {
+ HashElement & oNewElement = aTMP[iPos];
+
+ oNewElement.hash = (UINT_64)-1;
+ oNewElement.value = (UINT_64)-1;
+ }
+
+ for(iPos = 0; iPos < iOldElements; ++iPos)
+ {
+ // Element in old array
+ const HashElement & oOldElement = aElements[iPos];
+ if (oOldElement.hash != (UINT_64)-1)
+ {
+ // Get new position in array
+ const UINT_64 iNewPos = oOldElement.hash & iBase;
+
+ HashElement & oNewElement = aTMP[iNewPos];
+
+ oNewElement.hash = oOldElement.hash;
+ oNewElement.value = oOldElement.value;
+ }
+ }
+
+ delete [] aElements;
+ aElements = aTMP;
+}
+
+//
+// A destructor
+//
+HashTable::~HashTable() throw()
+{
+ delete [] aElements;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2JSONFileParser.cpp b/src/CTPP2JSONFileParser.cpp
new file mode 100644
index 0000000..09ebfab
--- /dev/null
+++ b/src/CTPP2JSONFileParser.cpp
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2JSONFileParser.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2JSONFileParser.hpp"
+#include "CTPP2Exception.hpp"
+
+#include <sys/stat.h>
+
+#include <errno.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+CTPP2JSONFileParser::CTPP2JSONFileParser(CDT & oICDT): CTPP2JSONParser(oICDT) { ;; }
+
+
+//
+// Parse JSON object
+//
+INT_32 CTPP2JSONFileParser::Parse(CCHAR_P szFileName)
+{
+ // Get file size
+ struct stat oStat;
+ if (stat(szFileName, &oStat) == -1) { throw CTPPUnixException("stat", errno); }
+ if (oStat.st_size == 0) { throw CTPPLogicError("Cannot get size of file"); }
+
+ // Load file
+ FILE * F = fopen(szFileName, "rb");
+ if (F == NULL) { throw CTPPUnixException("fopen", errno); }
+
+ // Allocate memory
+ CHAR_P oFile = (CHAR_P)malloc(oStat.st_size);
+
+ // Read from file
+ if (fread(oFile, oStat.st_size, 1, F) != 1)
+ {
+ if (ferror(F) != 0)
+ {
+ free(oFile);
+ fclose(F);
+ throw CTPPUnixException("fread", errno);
+ }
+ else
+ {
+ free(oFile);
+ fclose(F);
+ throw CTPPLogicError("Cannot read from file");
+ }
+ }
+
+ try
+ {
+ CTPP2JSONParser::Parse(oFile, oFile + oStat.st_size);
+ }
+ catch(...)
+ {
+ free(oFile);
+ fclose(F);
+ throw;
+ }
+
+ // All Done
+ free(oFile);
+ fclose(F);
+
+return 0;
+}
+
+//
+// Parse JSON object
+//
+INT_32 CTPP2JSONFileParser::Parse(FILE * F, const UINT_32 & iReadBytes)
+{
+ // Load file
+ if (F == NULL) { throw CTPPUnixException("fopen", errno); }
+
+ // Allocate memory
+ CHAR_P oFile = (CHAR_P)malloc(iReadBytes);
+
+ // Read from file
+ if (fread(oFile, iReadBytes, 1, F) != 1)
+ {
+ if (ferror(F) != 0)
+ {
+ free(oFile);
+ fclose(F);
+ throw CTPPUnixException("fread", errno);
+ }
+ else
+ {
+ free(oFile);
+ fclose(F);
+ throw CTPPLogicError("Cannot read from file");
+ }
+ }
+
+ try
+ {
+ CTPP2JSONParser::Parse(oFile, oFile + iReadBytes);
+ }
+ catch(...)
+ {
+ free(oFile);
+ fclose(F);
+ throw;
+ }
+
+ // All Done
+ free(oFile);
+ fclose(F);
+return 0;
+}
+
+//
+// A destructor
+//
+CTPP2JSONFileParser::~CTPP2JSONFileParser() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2JSONParser.cpp b/src/CTPP2JSONParser.cpp
new file mode 100644
index 0000000..bbcba5c
--- /dev/null
+++ b/src/CTPP2JSONParser.cpp
@@ -0,0 +1,632 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2JSONParser.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2JSONParser.hpp"
+
+#include "CTPP2ParserException.hpp"
+#include "CTPP2Util.hpp"
+
+#include <stdio.h>
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+CTPP2JSONParser::CTPP2JSONParser(CDT & oICDT): oCDT(oICDT)
+{
+ ;;
+}
+
+//
+// CTPP2 string "blah-blah \" clah-clah " | 'blah-blah \' clah-clah '
+//
+CCharIterator CTPP2JSONParser::IsString(CCharIterator szData, CCharIterator szEnd)
+{
+ sTMPBuf.erase();
+
+ INT_32 bEscaped = 0;
+ CHAR_8 chEOS = *szData;
+ // Check start of string
+ if (chEOS != '"' && chEOS != '\'') { return NULL; }
+
+ ++szData;
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected terminating character but end of JSON object found", szData.GetLine(), szData.GetLinePos()); }
+
+ while (szData != szEnd)
+ {
+ // Escaper
+ if (*szData == '\\' && bEscaped == 0)
+ {
+ ++szData;
+ bEscaped = 1;
+ }
+ // Other cases
+ else
+ {
+ // End-of-String ?
+ if (*szData == chEOS && bEscaped == 0) { return ++szData; }
+ if (bEscaped == 1)
+ {
+ switch (*szData)
+ {
+ // man ascii
+ case 'a': sTMPBuf += '\a'; ++szData; break;
+ case 'b': sTMPBuf += '\b'; ++szData; break;
+ case 't': sTMPBuf += '\t'; ++szData; break;
+ case 'n': sTMPBuf += '\n'; ++szData; break;
+ case 'v': sTMPBuf += '\v'; ++szData; break;
+ case 'f': sTMPBuf += '\f'; ++szData; break;
+ case 'r': sTMPBuf += '\r'; ++szData; break;
+ // Unicode + 4 digits
+ case 'u':
+ {
+ ++szData;
+ UINT_32 iTMP = 0;
+ for (INT_32 iI = 3; iI >= 0; --iI)
+ {
+ if (szData == szEnd) { throw CTPPParserSyntaxError("invalid unicode escape sequence", szData.GetLine(), szData.GetLinePos()); }
+
+ UCHAR_8 iCh = *szData;
+
+ if (iCh >= '0' && iCh <= '9') { iTMP += ((iCh - '0') << (iI * 4)); }
+ else
+ {
+ iCh |= 0x20;
+ if (*szData >= 'a' && *szData <= 'f') { iTMP += ((iCh - 'a' + 10) << (iI * 4)); }
+ else { throw CTPPParserSyntaxError("invalid unicode escape sequence", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+ ++szData;
+ }
+ UCHAR_8 aBuffer[6];
+ INT_32 iCharLength = UnicodeToUTF8(iTMP, aBuffer);
+
+ sTMPBuf.append((CHAR_P)aBuffer, iCharLength);
+ }
+ break;
+ default:
+ sTMPBuf += *szData;
+ ++szData;
+ }
+ }
+ else
+ {
+ sTMPBuf += *szData;
+ ++szData;
+ }
+
+ bEscaped = 0;
+ }
+ }
+
+ // Expected ' or "
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected terminating character but end of JSON object found", szData.GetLine(), szData.GetLinePos()); }
+
+// This should *never* happened
+return NULL;
+}
+
+//
+// JSON old fashion string blah-blah.clah-clah
+//
+CCharIterator CTPP2JSONParser::IsStringCompatOldVersion(CCharIterator szData, CCharIterator szEnd)
+{
+ sTMPBuf.erase();
+ if (szData == szEnd) { return NULL; }
+ while (szData != szEnd)
+ {
+ if (!((*szData >= 'A' && *szData <= 'Z') ||
+ (*szData >= 'a' && *szData <= 'z'))) { return szData; }
+
+ sTMPBuf += *szData;
+ szData++;
+ }
+
+return NULL;
+}
+
+//
+// JSON variable [a-zA-Z_][a-zA-Z0-9_]
+//
+CCharIterator CTPP2JSONParser::IsVar(CCharIterator szData, CCharIterator szEnd)
+{
+ if (szData != szEnd &&
+ !((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') || *szData == '_')
+ )
+ {
+ return NULL;
+ }
+ ++szData;
+
+ while (szData != szEnd)
+ {
+ if (!((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') ||
+ (*szData >= '0' && *szData <= '9') ||
+ *szData == '_')
+ )
+ {
+ return szData;
+ }
+ ++szData;
+ }
+return NULL;
+}
+
+//
+// JSON number [-]0-9[. [0-9] ] [E][+- 0-9]
+//
+CCharIterator CTPP2JSONParser::IsNum(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator szStart = szData;
+
+ // First character: digit or sign
+ if (!((*szData >= '0' && *szData <= '9') || *szData == '-' || *szData == '+')) { return NULL; }
+ ++szData;
+
+ // Digits
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ ++ szData;
+ }
+
+ // Optional '.'. If not found, this is an integer value
+ if (szData == szEnd || *szData != '.')
+ {
+ const INT_32 iDigitSize = szData() - szStart();
+ CHAR_P szDigit = new CHAR_8[iDigitSize + 1];
+ memcpy(szDigit, szStart(), iDigitSize);
+ szDigit[iDigitSize] = '\0';
+
+ long long iLL = 0;
+ sscanf(szDigit, "%lli", &iLL);
+
+ iIntData = iLL;
+ iParsedNumberType = 0;
+
+ delete [] szDigit;
+ return szData;
+ }
+ ++szData;
+
+ // Digits after point
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ ++ szData;
+ }
+
+ // Scientific?
+ if (szData == szEnd || (*szData != 'E' && *szData != 'e'))
+ {
+ const INT_32 iDigitSize = szData() - szStart();
+ CHAR_P szDigit = new CHAR_8[iDigitSize + 1];
+ memcpy(szDigit, szStart(), iDigitSize);
+ szDigit[iDigitSize] = '\0';
+
+ double iFF = 0;
+ sscanf(szDigit, "%lg", &iFF);
+
+ dFloatData = iFF;
+ iParsedNumberType = 1;
+
+ delete [] szDigit;
+ return szData;
+ }
+ else
+ {
+ INT_32 iFoundDigits = 0;
+ ++ szData;
+ // Error?
+ if (szData == szEnd) { throw CTPPParserSyntaxError("exponent has no digits", szData.GetLine(), szData.GetLinePos()); }
+ // Exponent sign
+ if (*szData == '-' || *szData == '+') { ++ szData; }
+ // Error?
+ if (szData == szEnd) { throw CTPPParserSyntaxError("exponent has no digits", szData.GetLine(), szData.GetLinePos()); }
+ // Exponent value
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ iFoundDigits = 1;
+ ++ szData;
+ }
+ if (iFoundDigits == 0) { throw CTPPParserSyntaxError("exponent has no digits", szData.GetLine(), szData.GetLinePos()); }
+
+ const INT_32 iDigitSize = szData() - szStart();
+ CHAR_P szDigit = new CHAR_8[iDigitSize + 1];
+ memcpy(szDigit, szStart(), iDigitSize);
+ szDigit[iDigitSize] = '\0';
+
+ double iFF = 0;
+ sscanf(szDigit, "%le", &iFF);
+
+ dFloatData = iFF;
+ iParsedNumberType = 1;
+
+ delete [] szDigit;
+ return szData;
+ }
+
+return NULL;
+}
+
+//
+// JSON white space
+//
+CCharIterator CTPP2JSONParser::IsWhiteSpace(CCharIterator szData, CCharIterator szEnd, const UINT_32 & iSkipFirst)
+{
+ // Special case
+ if (iSkipFirst == 1)
+ {
+ if (szData != szEnd && (*szData != ' ' && *szData != '\t' && *szData != '\r' && *szData != '\n')) { return NULL; }
+ ++szData;
+ }
+
+ for (;;)
+ {
+ // Skip spaces
+ while (szData != szEnd)
+ {
+ if (*szData != ' ' && *szData != '\t' && *szData != '\r' && *szData != '\n') { break; }
+ ++szData;
+ }
+
+ // Check comments: "//" or "/* ... */"
+ if (szData == szEnd || *szData != '/') { return szData; }
+
+ CCharIterator szTMP = szData;
+
+ ++szData;
+ if (szData == szEnd) { return szTMP; }
+
+ // Long comment
+ if (*szData == '*')
+ {
+ ++szData;
+ // Skip data
+ while (szData != szEnd)
+ {
+ if (*szData == '*')
+ {
+ ++szData;
+ if (szData == szEnd) { return szData; }
+ else if (*szData == '/') { ++szData; break; }
+ }
+ ++szData;
+ }
+ }
+ // One-line comment
+ else if (*szData == '/')
+ {
+ ++szData;
+ // Skip data
+ while (szData != szEnd)
+ {
+ if (*szData == '\n') { break; }
+ ++szData;
+ }
+ }
+ // Not a comment
+ else { return szTMP; }
+ }
+
+return szData;
+}
+
+//
+// JSON Object
+//
+CCharIterator CTPP2JSONParser::IsObject(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT)
+{
+ if (*szData() != '{') { return NULL; }
+ ++szData;
+
+ oCurrentCDT = CDT(CDT::HASH_VAL);
+
+ // Parse array
+ CCharIterator sTMP = szData;
+ bool bIsFirst = true;
+ for(;;)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Unexpected EOD
+ if (szData == szEnd)
+ {
+ // "foo" : [ EOD
+ if (bIsFirst) { throw CTPPParserSyntaxError("expected key after '{', but end of JSON object found", szData.GetLine(), szData.GetLinePos()); }
+
+ // "foo" : [ 1, EOD
+ throw CTPPParserSyntaxError("expected key after ',', but end of JSON object found", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Key
+ STLW::string sKey;
+ // Value
+ CDT oCDTValue;
+
+ // Check key
+ sTMP = IsKey(szData, szEnd, sKey);
+ // Error?
+ if (sTMP == NULL)
+ {
+ if (!bIsFirst) { throw CTPPParserSyntaxError("expected key after ','", szData.GetLine(), szData.GetLinePos()); }
+ // Skip white space
+ sTMP = IsWhiteSpace(szData, szEnd, 0);
+ // Check empty hash
+ if (*sTMP == '}') { ++sTMP; break; }
+
+ throw CTPPParserSyntaxError("expected key or '}'", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ if (sTMP == szEnd) { throw CTPPParserSyntaxError("expected ':', but end of JSON object found", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ // Delimiter
+ if (*sTMP != ':') { throw CTPPParserSyntaxError("expected ':' after key", sTMP.GetLine(), sTMP.GetLinePos()); }
+ ++sTMP;
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ if (sTMP == szEnd) { throw CTPPParserSyntaxError("expected value after ':', but end of JSON object found", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ szData = sTMP;
+ // Value
+ sTMP = IsValue(szData, szEnd, oCDTValue);
+ // Error?
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected value after ':'", szData.GetLine(), szData.GetLinePos()); }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ // Unexpected EOF
+ if (sTMP == szEnd) { throw CTPPParserSyntaxError("expected ',' or '}', but end of JSON object found", szData.GetLine(), szData.GetLinePos()); }
+
+ // Store object
+ oCurrentCDT[sKey] = oCDTValue;
+
+ // End of object
+ if (*sTMP == '}') { ++sTMP; break; }
+ // Next key : value pair?
+ if (*sTMP != ',') { throw CTPPParserSyntaxError("',' expected", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ bIsFirst = false;
+ ++sTMP;
+ szData = sTMP;
+ }
+
+return sTMP;
+}
+
+//
+// JSON Key
+//
+CCharIterator CTPP2JSONParser::IsKey(CCharIterator szData, CCharIterator szEnd, STLW::string & sKey)
+{
+ // Check key
+ CCharIterator sTMP = IsString(szData, szEnd);
+ // String key found, ok
+ if (sTMP != NULL)
+ {
+ sKey.assign(sTMPBuf);
+ return sTMP;
+ }
+
+ // Check number
+ sTMP = szData;
+ szData = IsNum(szData, szEnd);
+ if (szData != NULL)
+ {
+ sKey.assign(sTMP(), szData() - sTMP());
+ return szData;
+ }
+
+return NULL;
+}
+
+//
+// JSON Array
+//
+CCharIterator CTPP2JSONParser::IsArray(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT)
+{
+ if (*szData() != '[') { return NULL; }
+ ++szData;
+
+ oCurrentCDT = CDT(CDT::ARRAY_VAL);
+
+ // Parse array
+ CCharIterator sTMP = szData;
+ UINT_32 iArrayIndex = 0;
+ bool bIsFirst = true;
+ for(;;)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Unexpected EOD
+ if (szData == szEnd)
+ {
+ // "foo" : [ EOD
+ if (bIsFirst) { throw CTPPParserSyntaxError("expected value or ']' after '[', but end of JSON object found", szData.GetLine(), szData.GetLinePos()); }
+
+ // "foo" : [ 1, EOD
+ throw CTPPParserSyntaxError("expected value after ',', but end of JSON object found", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Value
+ CDT oCDTValue;
+ // Value
+ sTMP = IsValue(szData, szEnd, oCDTValue);
+ // Error?
+ if (sTMP == NULL)
+ {
+ // Check number of iteration
+ if (!bIsFirst) { throw CTPPParserSyntaxError("expected value after ','", szData.GetLine(), szData.GetLinePos()); }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(szData, szEnd, 0);
+ // Check empty array
+ if (*sTMP == ']') { ++sTMP; break; }
+
+ throw CTPPParserSyntaxError("expected value or ']'", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ // Unexpected EOF
+ if (sTMP == szEnd)
+ {
+ // "foo" : [ EOD
+ // "foo" : [ 1, EOD
+ throw CTPPParserSyntaxError("expected ',' or ']', but end of JSON object found", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ // Store object
+ oCurrentCDT[iArrayIndex] = oCDTValue;
+ // End of array?
+ if (*sTMP == ']') { ++sTMP; break; }
+ // Next element?
+ if (*sTMP != ',') { throw CTPPParserSyntaxError("',' or ']' expected", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ bIsFirst = false;
+ ++sTMP;
+ ++iArrayIndex;
+
+ szData = sTMP;
+ }
+
+return sTMP;
+}
+
+//
+// JSON Value
+//
+CCharIterator CTPP2JSONParser::IsValue(CCharIterator szData, CCharIterator szEnd, CDT & oCurrentCDT)
+{
+ // Check object
+ CCharIterator sTMP = IsObject(szData, szEnd, oCurrentCDT);
+ if (sTMP != NULL) { return sTMP; }
+ else
+ {
+ // Check array
+ sTMP = IsArray(szData, szEnd, oCurrentCDT);
+ if (sTMP != NULL) { return sTMP; }
+ else
+ {
+ // Check number
+ sTMP = IsNum(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ if (iParsedNumberType == 0) { oCurrentCDT = iIntData; }
+ else { oCurrentCDT = dFloatData; }
+
+ return sTMP;
+ }
+ else
+ {
+ // Check string
+ sTMP = IsString(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ oCurrentCDT = sTMPBuf;
+ return sTMP;
+ }
+ else
+ {
+ // Check special cases
+ sTMP = IsStringCompatOldVersion(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ if (strcasecmp("null", sTMPBuf.c_str()) == 0) { oCurrentCDT = CDT(CDT::UNDEF); }
+ else if (strcasecmp("false", sTMPBuf.c_str()) == 0) { oCurrentCDT = 0; }
+ else if (strcasecmp("true", sTMPBuf.c_str()) == 0) { oCurrentCDT = 1; }
+ // Unexpected data found
+ else { return NULL; }
+
+ return sTMP;
+ }
+ }
+ }
+ }
+ }
+
+return NULL;
+}
+
+//
+// Parse JSON object
+//
+INT_32 CTPP2JSONParser::Parse(CCharIterator szData, CCharIterator szEnd)
+{
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Unexpected EOD?
+ if (szData == szEnd) { throw CTPPParserSyntaxError("empty JSON object", szData.GetLine(), szData.GetLinePos()); }
+
+ // Check object/array/value/special case (bukk, true, false)
+ CCharIterator sTMP = IsValue(szData, szEnd, oCDT);
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("not an JSON object", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ if (sTMP != szEnd)
+ {
+ throw CTPPParserSyntaxError("syntax error", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+return 0;
+}
+
+//
+// A destructor
+//
+CTPP2JSONParser::~CTPP2JSONParser() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Logger.cpp b/src/CTPP2Logger.cpp
new file mode 100644
index 0000000..fdc91b4
--- /dev/null
+++ b/src/CTPP2Logger.cpp
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Logger.cpp
+ *
+ * $CAS$
+ */
+#include "CTPP2Logger.hpp"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+Logger::Logger(const UINT_32 iIBasePriority): iBasePriority(iIBasePriority) { ;; }
+
+//
+// Change base priority
+//
+void Logger::SetPriority(const UINT_32 iNewPriority) { iBasePriority = iNewPriority; }
+
+//
+// Log message with formatted parameters
+//
+INT_32 Logger::LogMessage(const UINT_32 iPriority, CCHAR_P szFormat, ...)
+{
+ va_list aArgList;
+ va_start(aArgList, szFormat);
+ INT_32 iRC = LogMessage(iPriority, szFormat, aArgList);
+ va_end(aArgList);
+
+return iRC;
+}
+
+//
+// Log message with formatted parameters
+//
+INT_32 Logger::LogMessage(const UINT_32 iPriority,
+ CCHAR_P szFormat,
+ va_list aArgList)
+{
+ // Message not logged, incorrect priority level
+ if (iPriority > iBasePriority) { return -1; }
+
+ {
+ CHAR_8 szStaticBuffer[C_START_MESSAGE_LEN];
+
+ // Format value
+ const INT_32 iFmtLen = vsnprintf(szStaticBuffer, C_START_MESSAGE_LEN, szFormat, aArgList);
+ if (iFmtLen < C_START_MESSAGE_LEN)
+ {
+ // Write to logger
+ WriteLog(iPriority, szStaticBuffer, iFmtLen);
+ return 0;
+ }
+ }
+
+ INT_32 iResultLen = C_START_MESSAGE_LEN;
+ CHAR_P szResult = NULL;
+ for(;;)
+ {
+ // TODO: Improve performance
+ szResult = (CHAR_P)malloc(iResultLen);
+ // Format value
+ const INT_32 iFmtLen = vsnprintf(szResult, iResultLen, szFormat, aArgList);
+ if (iFmtLen < iResultLen)
+ {
+ // Write to logger
+ WriteLog(iPriority, szResult, iFmtLen);
+ free(szResult);
+ return 0;
+ }
+
+ iResultLen <<= 1;
+ free(szResult);
+ }
+}
+
+//
+//log message with formatted parameters and CTPP2_LOG_EMERG priority
+//
+INT_32 Logger::Emerg(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_EMERG, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_ALERT priority
+//
+INT_32 Logger::Alert(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_ALERT, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_CRIT priority
+//
+INT_32 Logger::Crit(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_CRIT, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_ERR priority
+//
+INT_32 Logger::Err(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_ERR, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_ERR priority
+//
+INT_32 Logger::Error(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_ERR, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_WARNING priority
+//
+INT_32 Logger::Warn(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_WARNING, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_WARNING priority
+//
+INT_32 Logger::Warning(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_WARNING, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_NOTICE priority
+//
+INT_32 Logger::Notice(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_NOTICE, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_INFO priority
+//
+INT_32 Logger::Info(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_INFO, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+//log message with formatted parameters and CTPP2_LOG_DEBUG priority
+//
+INT_32 Logger::Debug(CCHAR_P szFormat, ...) { va_list aTMP; va_start(aTMP, szFormat); INT_32 iRC = LogMessage(CTPP2_LOG_DEBUG, szFormat, aTMP); va_end(aTMP); return iRC; }
+
+//
+// A destructor
+//
+Logger::~Logger() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Parser.cpp b/src/CTPP2Parser.cpp
new file mode 100644
index 0000000..5fb1c27
--- /dev/null
+++ b/src/CTPP2Parser.cpp
@@ -0,0 +1,3025 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Parser.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2Parser.hpp"
+
+#include "CTPP2ParserException.hpp"
+#include "CTPP2SourceLoader.hpp"
+#include "CTPP2Util.hpp"
+
+#include <stdio.h>
+
+//#define _USE_REPORTER 1 // Use it only for hard debugging
+
+#define VM_DEBUG(y) VMDebugInfo((y), iSourceNameId)
+
+
+/*
+<TMPL_var Factor | "(" LogicalOrExpr ")">
+
+<TMPL_if Factor | "(" LogicalOrExpr ")">
+ ...
+<TMPL_elsif Factor | "(" LogicalOrExpr ")">
+ ...
+<TMPL_else>
+ ...
+</TMPL_if>
+
+<TMPL_unless Factor | "(" LogicalOrExpr ")">
+ ...
+<TMPL_elsif Factor | "(" LogicalOrExpr ")">
+ ...
+<TMPL_else>
+ ...
+</TMPL_unless>
+
+<TMPL_foreach loop_var as iterator>
+ ...
+</TMPL_foreach>
+
+<TMPL_include filename.tmpl [map{ a => b, c => d }] > - old-fashion style
+<TMPL_include "filename.tmpl" [map{ a => b, c => d }]> - new-fashion style
+
+<TMPL_break Factor | "(" LogicalOrExpr ")">
+
+LogicalOrExpr = LogicalAndExpr { "||" LogicalAndExpr }
+
+LogicalAndExpr = RelExpr { "&&" RelExpr }
+
+RelExpr = SimpleExpr [Relation SimpleExpr]
+
+SimpleExpr = Term {AddOp Term}
+
+Term = Factor {MulOp Factor}
+
+Factor = Function "(" [ExprList] ")" | number | character | string | "(" LogicalOrExpr ")" | [ UNPLUS | UNMINUS | NOT] Factor
+
+Relation = N_EQ | N_NE | N_GT | N_LT | N_GE | N_LE | EQ | NE | GT | LT | GE | LE
+
+AddOp = ADD | SUB
+
+MulOp = MUL | DIV | IDIV | MOD
+
+ExprList = LogicalOrExpr {"," LogicalOrExpr}
+*/
+
+namespace CTPP // C++ Template Engine
+{
+
+#ifdef _USE_REPORTER
+/**
+ @class Reporter
+ @brief Print template parsing syntax tree with indents
+*/
+class Reporter
+{
+public:
+ /**
+ @brief Constructor
+ @param sIData - method name
+ @param szCode - code to print
+ */
+ Reporter(const STLW::string & sIData, CCharIterator szCode);
+
+ /**
+ @brief Destructor
+ */
+ ~Reporter() throw();
+private:
+ // Does not exist
+ Reporter(const Reporter & oRhs);
+ Reporter & operator=(const Reporter & oRhs);
+
+ /** Method name */
+ STLW::string sData;
+ /** Indent lebvel */
+ static int iLevel;
+};
+
+//
+// Constructor
+//
+Reporter::Reporter(const STLW::string & sIData, CCharIterator szCode): sData(sIData)
+{
+ for (INT_32 iI = 0; iI < iLevel; ++iI) { fprintf(stderr, " "); }
+ ++iLevel;
+ fprintf(stderr, ">> %s: `%s`\n", sData.c_str(), szCode());
+}
+
+//
+// Destructor
+//
+Reporter::~Reporter() throw() { --iLevel; fprintf(stderr, "<< %s\n", sData.c_str()); }
+
+// Indent level
+int Reporter::iLevel = 0;
+
+// Fast access macros
+#define REPORTER(x, y) Reporter oReporter((x), (y));
+
+#else // No reporter
+
+// Fast access macros
+#define REPORTER(x, y) { ; }
+
+#endif // Reporter class
+
+
+/**
+ @class ForeachFlagLocker
+ @brief Lock flag for foreach iterator
+*/
+class ForeachFlagLocker
+{
+public:
+ /**
+ @brief Constructor
+ @param bIInForeach - flag
+ */
+ ForeachFlagLocker(bool & bIInForeach);
+
+ /**
+ @brief Destructor
+ */
+ ~ForeachFlagLocker() throw();
+private:
+ // Does not exist
+ ForeachFlagLocker(const ForeachFlagLocker & oRhs);
+ ForeachFlagLocker & operator=(const ForeachFlagLocker & oRhs);
+
+ /** Reference to foreach flag */
+ bool & bInForeach;
+ /** Old foreach flag state */
+ bool bOldInForeach;
+};
+
+//
+// Constructor
+//
+ForeachFlagLocker::ForeachFlagLocker(bool & bIInForeach): bInForeach(bIInForeach),
+ bOldInForeach(bInForeach)
+{
+ bInForeach = true;
+}
+
+//
+// Destructor
+//
+ForeachFlagLocker::~ForeachFlagLocker() throw()
+{
+ bInForeach = bOldInForeach;
+}
+
+//
+// CTPP2 reserved words
+//
+CTPP2Parser::CTPP2Relation CTPP2Parser::aCTPP2Relations [] =
+{
+ { TMPL_EQ, sizeof(TMPL_EQ), R_EQ },
+ { TMPL_NE, sizeof(TMPL_NE), R_NE },
+ { TMPL_GT, sizeof(TMPL_GT), R_GT },
+ { TMPL_LT, sizeof(TMPL_LT), R_LT },
+ { TMPL_GE, sizeof(TMPL_GE), R_GE },
+ { TMPL_LR, sizeof(TMPL_LR), R_LE },
+ { TMPL_N_EQ, sizeof(TMPL_N_EQ), R_N_EQ },
+ { TMPL_N_NE, sizeof(TMPL_N_NE), R_N_NE },
+ { TMPL_N_GE, sizeof(TMPL_N_GE), R_N_GE },
+ { TMPL_N_LE, sizeof(TMPL_N_LE), R_N_LE },
+ { TMPL_N_GT, sizeof(TMPL_N_GT), R_N_GT },
+ { TMPL_N_LT, sizeof(TMPL_N_LT), R_N_LT },
+ // Terminator
+ { NULL, 0, R_UNDEF }
+};
+
+//
+// CTPP2 reserved words
+//
+CTPP2Parser::CTPP2Keyword CTPP2Parser::aKeywords [] =
+{
+ { TMPL_VAR_TOK, sizeof(TMPL_VAR_TOK), TMPL_var },
+ { TMPL_IF_TOK, sizeof(TMPL_IF_TOK), TMPL_if },
+ { TMPL_UNLESS_TOK, sizeof(TMPL_UNLESS_TOK), TMPL_unless },
+ { TMPL_ELSE_TOK, sizeof(TMPL_ELSE_TOK), TMPL_else },
+ { TMPL_ELSIF_TOK, sizeof(TMPL_ELSIF_TOK), TMPL_elsif },
+ { TMPL_FOREACH_TOK, sizeof(TMPL_FOREACH_TOK), TMPL_foreach },
+ { TMPL_INCLUDE_TOK, sizeof(TMPL_INCLUDE_TOK), TMPL_include },
+ { TMPL_CALL_TOK, sizeof(TMPL_CALL_TOK), TMPL_call },
+ { TMPL_UDF_TOK, sizeof(TMPL_UDF_TOK), TMPL_udf },
+ { TMPL_COMMENT_TOK, sizeof(TMPL_COMMENT_TOK), TMPL_comment },
+ { TMPL_BREAK_TOK, sizeof(TMPL_BREAK_TOK), TMPL_break },
+ { TMPL_BLOCK_TOK, sizeof(TMPL_BLOCK_TOK), TMPL_block },
+ { TMPL_VERBOSE_TOK, sizeof(TMPL_VERBOSE_TOK), TMPL_verbose },
+ // Terminator
+ { NULL, 0, UNDEF }
+};
+
+//
+// Constructor
+//
+CTPP2Parser::CTPP2Parser(CTPP2SourceLoader * pISourceLoader,
+ CTPP2Compiler * pICTPP2Compiler,
+ const::STLW::string & sISourceName,
+ const bool & bIInForeach,
+ const INT_32 iIRecursionLevel): pSourceLoader(pISourceLoader),
+ pCTPP2Compiler(pICTPP2Compiler),
+ oSyscalls(pCTPP2Compiler -> oSyscalls),
+ oStaticData(pCTPP2Compiler -> oStaticData),
+ oStaticText(pCTPP2Compiler -> oStaticText),
+ sSourceName(sISourceName),
+ bInForeach(bIInForeach),
+ iRecursionLevel(iIRecursionLevel),
+ bInsideComplexVariable(false),
+ bVerboseMode(false),
+ bInBlock(false)
+{
+ iSourceNameId = pCTPP2Compiler -> StoreSourceName(sSourceName.c_str(), sSourceName.size());
+}
+
+//
+// Compile CTPP2 template
+//
+INT_32 CTPP2Parser::Compile(const UINT_32 & iHalt)
+{
+ UINT_32 iTemplateSize = 0;
+ CCharIterator szData = pSourceLoader -> GetTemplate(iTemplateSize);
+
+ // Impossible happened.
+ if (szData == NULL) { return -1; }
+
+ CCharIterator szEnd = szData() + iTemplateSize;
+ CCharIterator sTMP = Parse(szData, szEnd);
+
+ // Check end of template
+ if (sTMP != szEnd)
+ {
+ if (sTMP != NULL)
+ {
+ if (eBreakFound != UNDEF) { throw CTPPParserOperatorsMismatch("TMPL prefix", GetOperatorName(eBreakFound), sTMP.GetLine(), sTMP.GetLinePos()); }
+ }
+
+ throw CTPPParserSyntaxError("syntax error", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ // Check end of template
+ if (eBreakFound != UNDEF)
+ {
+ STLW::string sError("Found unclosed tag </");
+ sError.append(GetOperatorName(eBreakFound));
+ sError.append(">");
+ throw CTPPParserSyntaxError(sError.c_str(), sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ if (iHalt == 1)
+ {
+ // Halt program
+ pCTPP2Compiler -> Halt();
+ }
+
+return 0;
+}
+
+//
+// Set information about blocks
+//
+void CTPP2Parser::SetBlockArgSizeMap(const CTPP2Parser::BlockArgSizeMapType & mIBlockArgSizes) { mBlockArgSizes = mIBlockArgSizes; }
+
+//
+// Get information about blocks
+//
+CTPP2Parser::BlockArgSizeMapType CTPP2Parser::GetBlockArgSizeMap() const { return mBlockArgSizes; }
+
+// Simple tokens: open and close tags, operators, variables, strings and numbers //////////////////////////////////////////////////////////////////////////////////
+
+//
+// Open tag ([Tt][Mm][Pp][Ll])
+//
+CCharIterator CTPP2Parser::IsOpenTag(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator szIter1 = szData;
+ CCharIterator szIter2 = CTPP2_OPEN_TAG;
+
+ while (szIter1 != szEnd)
+ {
+ if ((*szIter1 | 0x20) != *szIter2) { break; }
+ ++szIter1; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ if (*szIter1 == '_') { return szIter1; }
+ return NULL;
+ }
+ }
+
+return NULL;
+}
+
+//
+// Close tag (/[Tt][Mm][Pp][Ll])
+//
+CCharIterator CTPP2Parser::IsCloseTag(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator szIter2 = CTPP2_CLOSE_TAG;
+
+ if (szData != szEnd && *szData != '/') { return NULL; }
+ ++szData;
+
+ while (szData != szEnd)
+ {
+ if ((*szData | 0x20) != *szIter2) { break; }
+ ++szData; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ if (*szData == '_') { return szData; }
+ return NULL;
+ }
+ }
+return NULL;
+}
+
+//
+// Operator (var | if | else | unless | foreach | udf | comment | call | break | verbose)
+//
+CCharIterator CTPP2Parser::IsOperator(CCharIterator szData, CCharIterator szEnd, eCTPP2Operator & oOperatorType)
+{
+ oOperatorType = UNDEF;
+
+ CTPP2Keyword * oKeyword = aKeywords;
+ while (oKeyword -> keyword != NULL)
+ {
+ CCharIterator szIter1 = szData;
+ CCharIterator szIter2 = oKeyword -> keyword;
+ while (szIter1 != szEnd)
+ {
+ if ((*szIter1 | 0x20) != *szIter2) { break; }
+ ++szIter1; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ oOperatorType = oKeyword -> keyword_operator;
+ return szIter1;
+ }
+ }
+ ++oKeyword;
+ }
+
+return NULL;
+}
+
+//
+// Function [a-zA-Z_][a-zA-Z0-9_]( Expr [, Expr2 ... ] )
+//
+CCharIterator CTPP2Parser::IsFunc(CCharIterator szData, CCharIterator szEnd, CCharIterator & sFuncEnd, UINT_32 & iFunctionParams)
+{
+ REPORTER("IsFunc", szData());
+
+ eCTPP2ExprOperator eResultOperator = EXPR_UNDEF;
+ CCharIterator sTMP = IsFuncName(szData, szEnd);
+
+ if (sTMP != NULL)
+ {
+ sFuncEnd = sTMP;
+ szData = sTMP;
+ // Skip white space
+ sTMP = IsWhiteSpace(szData, szEnd, 0);
+
+ // '(' blah, clah, mlah ')'
+ // Not a function; perhaps, variable, value, or string constant
+ if (sTMP == NULL || *sTMP != '(') { return NULL; }
+
+ // OK
+ ++sTMP;
+ if (sTMP == szEnd) { throw CTPPParserSyntaxError("expected primary-expression", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ // ... blah, clah, mlah ')'
+ if (*sTMP == ')') { return ++sTMP; }
+
+ for(;;)
+ {
+ szData = sTMP;
+ // Expression
+ sTMP = LogicalOrExpr(szData, szEnd, eResultOperator);
+ // Cannot parse expression or variable name after ',' token
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected expression after ','", szData.GetLine(), szData.GetLinePos()); }
+
+ ++iFunctionParams;
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // , clah, mlah ')'
+ if (*sTMP == ',') { ++sTMP; }
+ else if (*sTMP == ')') { ++sTMP; break; }
+ }
+ return sTMP;
+ }
+
+return NULL;
+}
+
+//
+// CTPP2 function a-zA-Z_[a-zA-Z0-9_]
+//
+CCharIterator CTPP2Parser::IsFuncName(CCharIterator szData, CCharIterator szEnd)
+{
+ if (szData != szEnd &&
+ !((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') || *szData == '_')
+ )
+ {
+ return NULL;
+ }
+ ++szData;
+
+ while (szData != szEnd)
+ {
+ if (!((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') ||
+ (*szData >= '0' && *szData <= '9') ||
+ *szData == '_')
+ )
+ {
+ return szData;
+ }
+ ++szData;
+ }
+return NULL;
+}
+
+CCharIterator CTPP2Parser::IsIterator(CCharIterator szData, CCharIterator szEnd)
+{
+ if (szData != szEnd &&
+ !((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') || *szData == '_')
+ )
+ {
+ return NULL;
+ }
+ ++szData;
+
+ while (szData != szEnd)
+ {
+ if (!((*szData >= 'a' && *szData <= 'z') ||
+ (*szData >= 'A' && *szData <= 'Z') ||
+ (*szData >= '0' && *szData <= '9') ||
+ *szData == '_')
+ )
+ {
+ return szData;
+ }
+ ++szData;
+ }
+return NULL;
+}
+
+//
+// CTPP2 variable [a-zA-Z_][a-zA-Z0-9_.:]
+//
+CCharIterator CTPP2Parser::IsVar(CCharIterator szData, CCharIterator szEnd)
+{
+ REPORTER("IsVar", szData());
+
+ CCharIterator sBegin = szData;
+
+ bool bIsComplexVariable = false;
+
+ CCharIterator sTMP = IsIterator(szData, szEnd);
+ if (sTMP == NULL) { return NULL; }
+ szData = sTMP;
+ STLW::string sVarName(sBegin(), sTMP() - sBegin());
+
+ const CHAR_8 cCurlyOpen = '{';
+ const CHAR_8 cCurlyClose = '}';
+ const CHAR_8 cSquareOpen = '[';
+ const CHAR_8 cSquareClose = ']';
+ const CHAR_8 cDot = '.';
+
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ bool bIsBlockVar = bInBlock && mCurrentBlock.find(sVarName) != mCurrentBlock.end();
+ if ((*szData == cDot || *szData == cSquareOpen || *szData == cCurlyOpen) && !bInsideComplexVariable)
+ {
+ if (!bIsBlockVar) { pCTPP2Compiler -> PreparePushComplexVariable(VM_DEBUG(szData)); }
+ bIsComplexVariable = true;
+ bInsideComplexVariable = true;
+ }
+
+ INT_32 ret = -1;
+ bool bIsForeachIterator = false;
+ if (bIsBlockVar)
+ {
+ ret = pCTPP2Compiler -> PushBlockVariable(mCurrentBlock[sVarName]);
+ }
+ else if (bInForeach) // Check iterator name
+ {
+ // Push iterator -> variable pair
+ ret = pCTPP2Compiler -> PushScopedVariable(sBegin(), sTMP() - sBegin(), sBegin(), sTMP() - sBegin(), VM_DEBUG(szData));
+ if (ret > -1) { bIsForeachIterator = true; }
+ }
+
+ if (ret == -1)
+ {
+ pCTPP2Compiler -> PrepareLocalScope(VM_DEBUG(szData));
+ if (bInForeach)
+ {
+ pCTPP2Compiler -> PushString("__value__", 9, VM_DEBUG(szData));
+ pCTPP2Compiler -> IndirectCall(VM_DEBUG(*szData));
+ }
+ pCTPP2Compiler -> PushVariable(sVarName.data(), sVarName.size(), VM_DEBUG(*szData));
+ }
+
+ while (*szData == cSquareOpen || *szData == cDot || *szData == cCurlyOpen)
+ {
+ bool bIsDot = *szData == cDot;
+ bool bIsCurlyOpen = *szData == cCurlyOpen;
+
+ ++szData;
+
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ if (bIsDot)
+ {
+ sBegin = szData;
+ sTMP = IsIterator(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("invalid indirect call", szData.GetLine(), szData.GetLinePos()); }
+ STLW::string sSubVarName(sBegin(), sTMP() - sBegin());
+
+ if (bIsForeachIterator)
+ {
+ STLW::string::size_type iI = sSubVarName.rfind("__");
+ bool bIsInternalKey = (sSubVarName.find("__") == 0) && (iI != STLW::string::npos) && (iI == (sSubVarName.length() - 2));
+ if (!bIsInternalKey)
+ {
+ pCTPP2Compiler -> PushString("__value__", 9, VM_DEBUG(szData));
+ pCTPP2Compiler -> IndirectCall(VM_DEBUG(*szData));
+ }
+ bIsForeachIterator = false;
+ }
+
+ pCTPP2Compiler -> PushString(sSubVarName.c_str(), sSubVarName.size(), VM_DEBUG(szData));
+ szData = sTMP;
+ }
+ else
+ {
+ if (bIsForeachIterator)
+ {
+ pCTPP2Compiler -> PushString("__value__", 9, VM_DEBUG(szData));
+ pCTPP2Compiler -> IndirectCall(VM_DEBUG(*szData));
+ bIsForeachIterator = false;
+ }
+
+ eCTPP2ExprOperator eResultOperator = EXPR_UNDEF;
+ CCharIterator sKeyNameEnd = LogicalOrExpr(szData, szEnd, eResultOperator);
+ if (sKeyNameEnd == NULL) { throw CTPPParserSyntaxError("invalid indirect call", szData.GetLine(), szData.GetLinePos()); }
+
+ szData = IsWhiteSpace(sKeyNameEnd, szEnd, 0);
+
+ if (*szData != (bIsCurlyOpen ? cCurlyClose : cSquareClose))
+ {
+ throw CTPPParserSyntaxError("invalid indirect call", szData.GetLine(), szData.GetLinePos());
+ }
+ }
+ pCTPP2Compiler -> IndirectCall(VM_DEBUG(*szData));
+
+ if (!bIsDot) { ++szData; }
+ sTMP = szData;
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ }
+ if (bIsForeachIterator)
+ {
+ pCTPP2Compiler -> PushString("__value__", 9, VM_DEBUG(szData));
+ pCTPP2Compiler -> IndirectCall(VM_DEBUG(*szData));
+ bIsForeachIterator = false;
+ }
+ if (bIsComplexVariable)
+ {
+ if (!bIsBlockVar) { pCTPP2Compiler -> ClearPushComplexVariable(VM_DEBUG(*szData)); }
+ bInsideComplexVariable = false;
+ }
+
+return sTMP;
+}
+
+//
+// CTPP2 string "blah-blah \" clah-clah " | 'blah-blah \' clah-clah '
+//
+CCharIterator CTPP2Parser::IsString(CCharIterator szData, CCharIterator szEnd)
+{
+ REPORTER("IsString", szData());
+ sTMPBuf.erase();
+
+ INT_32 bEscaped = 0;
+ // End-of-String
+ if (szData == szEnd) { return NULL; }
+ CHAR_8 chEOS = *szData;
+ if (chEOS != '"' && chEOS != '\'') { return NULL; }
+ ++szData;
+ if (szData == szEnd) { throw CTPPParserSyntaxError("missing terminating character", szData.GetLine(), szData.GetLinePos()); }
+
+ while (szData != szEnd)
+ {
+ // Escaper
+ if (*szData == '\\' && bEscaped == 0)
+ {
+ ++szData;
+ bEscaped = 1;
+ }
+ // Other cases
+ else
+ {
+ // End-of-String ?
+ if (*szData == chEOS && bEscaped == 0) { return ++szData; }
+ if (bEscaped == 1)
+ {
+ switch (*szData)
+ {
+ // Octal value
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ UINT_32 iTMP = 0;
+ for (INT_32 iI = 2; iI >= 0; --iI)
+ {
+ UCHAR_8 iCh = *szData;
+
+ if (iCh >= '0' && iCh <= '7')
+ {
+ iTMP = (iTMP << 3);
+ iTMP += (iCh - '0');
+ }
+ else { throw CTPPParserSyntaxError("invalid octal escape sequence", szData.GetLine(), szData.GetLinePos()); }
+
+ ++szData;
+ }
+ if (iTMP > 255) { throw CTPPParserSyntaxError("octal escape sequence out of range", szData.GetLine(), szData.GetLinePos()); }
+ sTMPBuf += UCHAR_8(iTMP);
+ }
+ break;
+ // Error
+ case '8':
+ case '9':
+ throw CTPPParserSyntaxError("invalid octal escape sequence", szData.GetLine(), szData.GetLinePos());
+ break;
+ // Hexadecimal value
+ case 'x':
+ case 'X':
+ {
+ ++szData;
+ UINT_32 iTMP = 0;
+ for (INT_32 iI = 1; iI >= 0; --iI)
+ {
+ if (szData == szEnd) { throw CTPPParserSyntaxError("invalid hexadecimal escape sequence", szData.GetLine(), szData.GetLinePos()); }
+
+ UCHAR_8 iCh = *szData;
+
+ if (iCh >= '0' && iCh <= '9') { iTMP += ((iCh - '0') << (iI * 4)); }
+ else
+ {
+ iCh |= 0x20;
+ if (*szData >= 'a' && *szData <= 'f') { iTMP += ((iCh - 'a' + 10) << (iI * 4)); }
+ else { throw CTPPParserSyntaxError("invalid hexadecimal escape sequence", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+ ++szData;
+ }
+ sTMPBuf += UCHAR_8(iTMP);
+ }
+ break;
+
+ // man ascii
+ case 'a': sTMPBuf += '\a'; ++szData; break;
+ case 'b': sTMPBuf += '\b'; ++szData; break;
+ case 't': sTMPBuf += '\t'; ++szData; break;
+ case 'n': sTMPBuf += '\n'; ++szData; break;
+ case 'v': sTMPBuf += '\v'; ++szData; break;
+ case 'f': sTMPBuf += '\f'; ++szData; break;
+ case 'r': sTMPBuf += '\r'; ++szData; break;
+ // Unicode + 4 digits
+ case 'u':
+ {
+ ++szData;
+ UINT_32 iTMP = 0;
+ for (INT_32 iI = 3; iI >= 0; --iI)
+ {
+ if (szData == szEnd) { throw CTPPParserSyntaxError("invalid unicode escape sequence", szData.GetLine(), szData.GetLinePos()); }
+
+ UCHAR_8 iCh = *szData;
+
+ if (iCh >= '0' && iCh <= '9') { iTMP += ((iCh - '0') << (iI * 4)); }
+ else
+ {
+ iCh |= 0x20;
+ if (*szData >= 'a' && *szData <= 'f') { iTMP += ((iCh - 'a' + 10) << (iI * 4)); }
+ else { throw CTPPParserSyntaxError("invalid unicode escape sequence", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+ ++szData;
+ }
+
+ UCHAR_8 aBuffer[6];
+ INT_32 iCharLength = UnicodeToUTF8(iTMP, aBuffer);
+
+ sTMPBuf.append((CHAR_P)aBuffer, iCharLength);
+ }
+ break;
+ default:
+ sTMPBuf += *szData;
+ ++szData;
+ }
+ }
+ else
+ {
+ sTMPBuf += *szData;
+ ++szData;
+ }
+
+ bEscaped = 0;
+ }
+ }
+
+return NULL;
+}
+
+//
+// Parse Float value
+//
+void CTPP2Parser::ParseFloat(CCharIterator & szStart, CCharIterator & szData)
+{
+ INT_32 iDigitSize = szData() - szStart();
+ CHAR_P szDigit = new CHAR_8[iDigitSize + 1];
+ memcpy(szDigit, szStart(), iDigitSize);
+ szDigit[iDigitSize] = '\0';
+
+ double iFF = 0;
+ sscanf(szDigit, "%lg", &iFF);
+
+ dFloatData = iFF;
+ iParsedNumberType = 1;
+
+ delete [] szDigit;
+}
+
+//
+// Number [-]0-9[. [0-9] ] [E [+-] 0-9]
+//
+CCharIterator CTPP2Parser::IsNum(CCharIterator szData, CCharIterator szEnd)
+{
+ REPORTER("IsNum", szData());
+
+ CCharIterator szStart = szData;
+
+ // First digit
+ if (szData != szEnd && !(*szData >= '0' && *szData <= '9')) { return NULL; }
+ ++szData;
+
+ // Digits, optional
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ ++szData;
+ }
+
+ // Integer?
+ if (szData == szEnd || (*szData != '.' && *szData != 'e' && *szData != 'E'))
+ {
+ INT_32 iDigitSize = szData() - szStart();
+ CHAR_P szDigit = new CHAR_8[iDigitSize + 1];
+ memcpy(szDigit, szStart(), iDigitSize);
+ szDigit[iDigitSize] = '\0';
+
+ long long iLL = 0;
+ sscanf(szDigit, "%lli", &iLL);
+
+ iIntData = iLL;
+ iParsedNumberType = 0;
+
+ delete [] szDigit;
+ return szData;
+ }
+
+ // Check '.'
+ if (*szData == '.') { ++szData; }
+ if (szData == szEnd)
+ {
+ ParseFloat(szStart, szData);
+ return szData;
+ }
+
+ // Digits, optional
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ ++ szData;
+ }
+
+ // Exponent, optional
+ if (szData == szEnd || (*szData != 'e' && *szData != 'E'))
+ {
+ ParseFloat(szStart, szData);
+ return szData;
+ }
+
+ ++szData;
+ // Exponent sign, optional
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected has no digits", szData.GetLine(), szData.GetLinePos()); }
+
+ bool bSignPresent = false;
+ if (*szData == '+' || *szData == '-')
+ {
+ bSignPresent = true;
+ ++szData;
+ }
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected has no digits", szData.GetLine(), szData.GetLinePos()); }
+
+ // Digits, required
+ INT_32 iFoundDigits = 0;
+ while (szData != szEnd)
+ {
+ if (!(*szData >= '0' && *szData <= '9')) { break; }
+ iFoundDigits = 1;
+ ++ szData;
+ }
+
+ if (iFoundDigits == 0)
+ {
+ if (bSignPresent) { throw CTPPParserSyntaxError("exponent has no digits after sign", szData.GetLine(), szData.GetLinePos()); }
+ else { throw CTPPParserSyntaxError("exponent has no digits", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+ ParseFloat(szStart, szData);
+
+return szData;
+}
+
+//
+// Foreach operator keyword (as)
+//
+CCharIterator CTPP2Parser::IsForeachKeyword(CCharIterator szData, CCharIterator szEnd)
+{
+ if (szData == szEnd) { return NULL; }
+ if (*szData != 'A' && *szData != 'a') { return NULL; }
+ ++szData;
+
+ if (szData == szEnd) { return NULL; }
+ if (*szData != 'S' && *szData != 's') { return NULL; }
+
+ ++szData;
+
+return szData;
+}
+
+//
+// White space (Tab | ' ' | '\t' | '\r' | '\n' | '\f' | '\v')
+//
+CCharIterator CTPP2Parser::IsWhiteSpace(CCharIterator szData, CCharIterator szEnd, const UINT_32 & iSkipFirst)
+{
+ if (iSkipFirst == 1)
+ {
+ if (szData != szEnd && (*szData != ' ' && *szData != '\t' && *szData != '\r' && *szData != '\n' && *szData != '\f' && *szData != '\v')) { return NULL; }
+ ++szData;
+ }
+
+ while (szData != szEnd)
+ {
+ if (*szData != ' ' && *szData != '\t' && *szData != '\r' && *szData != '\n' && *szData != '\f' && *szData != '\v') { break; }
+ ++szData;
+ }
+return szData;
+}
+
+// Expressions ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Expression ( Function ( expression ) | string | variable | number )
+//
+CCharIterator CTPP2Parser::IsExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ REPORTER("IsExpr", szData());
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ if (szData == szEnd) { return NULL; }
+ if (*szData == '(')
+ {
+ ++szData;
+ // LogicalOrExpr
+ CCharIterator sTMP = LogicalOrExpr(szData, szEnd, eResultOperator);
+
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("IsExpr", szData.GetLine(), szData.GetLinePos()); }
+
+ if (*sTMP != ')') { throw CTPPParserSyntaxError("expected ')' token", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ return ++sTMP;
+ }
+
+return IsFactor(szData, szEnd, eResultOperator);
+}
+
+//
+// LogicalOrExpr = LogicalAndExpr { "||" LogicalAndExpr }
+//
+CCharIterator CTPP2Parser::LogicalOrExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+//
+// if (stmt1 || stmt2 || stmt3 || stmt4 || stmt5) { expr1; } else { expr2; }
+//
+// if (stmt1) { goto @expr1; }
+// if (stmt2) { goto @expr1; }
+// if (stmt3) { goto @expr1; }
+// if (stmt4) { goto @expr1; }
+// if (stmt5) { goto @expr1; }
+// expr2; // false
+// goto @end:
+// @expr1:
+// expr1; // true
+// @end:
+// ....something else...
+//
+
+// if (stmt)
+
+// EXIST STACK[0]
+// POP 1
+// JE END
+
+//
+// PUSH 0 //
+// JXX @END // 1 | N + 4
+//@EXPR1:
+// PUSH 1 // 2
+//@END:
+// XXXXXXX // 6
+//
+
+ REPORTER("LogicalOrExpr", szData());
+
+ STLW::vector<INT_32> vJMPPoints;
+
+ // Factor
+ CCharIterator sTMP = LogicalAndExpr(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("1 !IsTerm!", szData.GetLine(), szData.GetLinePos()); }
+
+ // {IsLogicalOp LogicalAndExpr}
+ for (;;)
+ {
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // IsLogicalOp
+ eCTPP2ArOp eArOp = OP_UNDEF;
+ sTMP = IsLogicalOp(szData, szEnd, eArOp);
+ if (sTMP == NULL || eArOp != OP_LOR)
+ {
+ // Nothing to do
+ if (vJMPPoints.size() == 0) { return szData; }
+
+ // At least one logical operation
+
+ // Store prev. expression code point
+ pCTPP2Compiler -> ExistStackVariable(VM_DEBUG(szData));
+ pCTPP2Compiler -> PopVariable(1, VM_DEBUG(szData));
+ vJMPPoints.push_back(pCTPP2Compiler -> EQJump(UINT_32(-1), VM_DEBUG(szData)));
+
+ // Expr2
+ INT_32 iNewIP = pCTPP2Compiler -> PushInt(0, VM_DEBUG(szData));
+ pCTPP2Compiler -> UncondJump(iNewIP + 3, VM_DEBUG(szData));
+ // Expr1
+ iNewIP = pCTPP2Compiler -> PushInt(1, VM_DEBUG(szData));
+ pCTPP2Compiler -> DecrDepth();
+
+ INT_32 iLastJMPPos = vJMPPoints.size() - 1;
+ // Okay, set JMP points
+ for(INT_32 iI = 0; iI <= iLastJMPPos; ++iI)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(vJMPPoints[iI]);
+ pInstruction -> argument = iNewIP;
+ }
+
+ eResultOperator = EXPR_VARIABLE;
+ return szData;
+ }
+
+ // Store prev. expression code point
+ pCTPP2Compiler -> ExistStackVariable(VM_DEBUG(szData));
+ pCTPP2Compiler -> PopVariable(1, VM_DEBUG(szData));
+ vJMPPoints.push_back(pCTPP2Compiler -> EQJump(UINT_32(-1), VM_DEBUG(szData)));
+
+ // LogicalAndExpr
+ szData = sTMP;
+ sTMP = LogicalAndExpr(szData, szEnd, eResultOperator);
+
+ // Error?
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("Rvalue expected after \"||\"", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+// This should *not* happened
+return NULL;
+}
+
+//
+// LogicalAndExpr = RelExpr { "&&" RelExpr }
+//
+CCharIterator CTPP2Parser::LogicalAndExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+//
+// if (stmt1 && stmt2 && stmt3 && stmt4 && stmt5) { expr1; } else { expr2; }
+//
+// if (!stmt1) { goto @expr2; }
+// if (!stmt2) { goto @expr2; }
+// if (!stmt3) { goto @expr2; }
+// if (!stmt4) { goto @expr2; }
+// if (!stmt5) { goto @expr2; }
+// expr1; // true
+// goto @end;
+// @expr2:
+// expr2; // false
+// @end:
+// ....something else...
+//
+
+// if (stmt)
+
+// EXIST STACK[0]
+// POP 1
+// JN END
+
+//
+// PUSH 1 //
+// JXX @END // 1 | N + 4
+//@EXPR1:
+// PUSH 0 // 2
+//@END:
+// XXXXXXX // 6
+//
+ REPORTER("LogicalAndExpr", szData());
+
+ STLW::vector<INT_32> vJMPPoints;
+ // Factor
+ CCharIterator sTMP = RelExpr(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("1 !IsTerm!", szData.GetLine(), szData.GetLinePos()); }
+
+ // {IsLogicalOp RelExpr}
+ for (;;)
+ {
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // IsLogicalOp
+ // Initialization is need to avoid warning "warning: 'eArOp' may be used uninitialized in this function" on gcc 44
+ eCTPP2ArOp eArOp = OP_UNDEF;
+
+ sTMP = IsLogicalOp(szData, szEnd, eArOp);
+ if (sTMP == NULL || eArOp != OP_LAND)
+ {
+ // Nothing to do
+ if (vJMPPoints.size() == 0)
+ {
+ return szData;
+ }
+
+ // At least one logical operation
+
+ // Store prev. expression code point
+ pCTPP2Compiler -> ExistStackVariable(VM_DEBUG(szData));
+ pCTPP2Compiler -> PopVariable(1, VM_DEBUG(szData));
+ vJMPPoints.push_back(pCTPP2Compiler -> NEJump(UINT_32(-1), VM_DEBUG(szData)));
+
+ // Expr1
+ INT_32 iNewIP = pCTPP2Compiler -> PushInt(1, VM_DEBUG(szData));
+ pCTPP2Compiler -> UncondJump(iNewIP + 3, VM_DEBUG(szData));
+ // Expr2
+ iNewIP = pCTPP2Compiler -> PushInt(0, VM_DEBUG(szData));
+ pCTPP2Compiler -> DecrDepth();
+
+ INT_32 iLastJMPPos = vJMPPoints.size() - 1;
+ // Okay, set JMP points
+ for(INT_32 iI = 0; iI <= iLastJMPPos; ++iI)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(vJMPPoints[iI]);
+ pInstruction -> argument = iNewIP;
+ }
+
+ eResultOperator = EXPR_VARIABLE;
+ return szData;
+ }
+
+ // Store prev. expression code point
+ pCTPP2Compiler -> ExistStackVariable();
+ pCTPP2Compiler -> PopVariable();
+ vJMPPoints.push_back(pCTPP2Compiler -> NEJump(UINT_32(-1), VM_DEBUG(szData)));
+
+ // RelExpr
+ szData = sTMP;
+ sTMP = RelExpr(szData, szEnd, eResultOperator);
+ // Error?
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("Rvalue expected after \"&&\"", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+return NULL;
+}
+
+//
+// RelExpr = SimpleExpr [Relation SimpleExpr]
+//
+CCharIterator CTPP2Parser::RelExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ REPORTER("RelExpr", szData());
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ CCharIterator sTMP = IsSimpleExpr(szData, szEnd, eResultOperator);
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("1 !RelExpr!", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // All Okay
+ szData = sTMP;
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ eCTPP2Relation eRelation = R_UNDEF;
+ sTMP = IsRelation(szData, szEnd, eRelation);
+ // Relation not found
+ if (sTMP == NULL) { return szData; }
+
+ // All Okay
+ szData = sTMP;
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // Second argument
+ sTMP = IsSimpleExpr(szData, szEnd, eResultOperator);
+
+//
+// CMP STACK[0], STACK[1] //
+// RJXX @L0 // 0 | N + 3
+// PUSH 0 // 1
+// RJMP @L1 // 2 | N + 2
+//@L0
+// PUSH 1 // 3
+//@L1:
+// XXXXXXX // 4
+//
+ // Compare variables
+ eResultOperator = EXPR_VARIABLE;
+
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("2 !RelExpr!", szData.GetLine(), szData.GetLinePos());
+ }
+
+ switch(eRelation)
+ {
+ case R_EQ:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> REQJump(3, VM_DEBUG(szData));
+ break;
+ case R_NE:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RNEJump(3, VM_DEBUG(szData));
+ break;
+ case R_GT:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RGTJump(3, VM_DEBUG(szData));
+ break;
+ case R_LT:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RLTJump(3, VM_DEBUG(szData));
+ break;
+ case R_GE:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RGEJump(3, VM_DEBUG(szData));
+ break;
+ case R_LE:
+ pCTPP2Compiler -> OpSCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RLEJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_EQ:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> REQJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_NE:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RNEJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_GT:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RGTJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_LT:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RLTJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_GE:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RGEJump(3, VM_DEBUG(szData));
+ break;
+ case R_N_LE:
+ pCTPP2Compiler -> OpCmp(VM_DEBUG(szData));
+ pCTPP2Compiler -> RLEJump(3, VM_DEBUG(szData));
+ break;
+ default:
+ throw CTPPParserSyntaxError("Undefined comparison expression", szData.GetLine(), szData.GetLinePos());
+ }
+
+ pCTPP2Compiler -> PushInt(0, VM_DEBUG(szData));
+ pCTPP2Compiler -> RUncondJump(2, VM_DEBUG(szData));
+ pCTPP2Compiler -> PushInt(1, VM_DEBUG(szData));
+
+ // Decrease stack depth because really only one variable is PUSHed
+ pCTPP2Compiler -> DecrDepth();
+
+return sTMP;
+}
+
+//
+// SimpleExpr = [UNPLUS | UNMINUS] Term {AddOp Term}
+//
+CCharIterator CTPP2Parser::IsSimpleExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ REPORTER("IsSimpleExpr", szData());
+
+ // Term
+ CCharIterator sTMP = IsTerm(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("2 !IsSimpleExpr!", szData.GetLine(), szData.GetLinePos()); }
+
+ // {AddOp Term}
+ for (;;)
+ {
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // AddOp
+ eCTPP2ArOp eArOp = OP_UNDEF;
+ sTMP = IsAddOp(szData, szEnd, eArOp);
+ if (sTMP == NULL) { return szData; }
+
+ // Factor
+ szData = sTMP;
+ sTMP = IsTerm(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("3 !IsSimpleExpr!", szData.GetLine(), szData.GetLinePos()); }
+
+ // Operation
+ switch(eArOp)
+ {
+ case OP_PLUS:
+ pCTPP2Compiler -> OpAdd(VM_DEBUG(szData));
+ break;
+
+ case OP_MINUS:
+ pCTPP2Compiler -> OpSub(VM_DEBUG(szData));
+ break;
+ default:
+ // This should *never* happened
+ throw "Ouch!";
+ }
+ }
+
+return NULL;
+}
+
+//
+// Term = Factor {MulOp Factor}
+//
+CCharIterator CTPP2Parser::IsTerm(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ REPORTER("IsTerm", szData());
+
+ // Factor
+ CCharIterator sTMP = IsFactor(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected variable, value, function or expression", szData.GetLine(), szData.GetLinePos()); }
+
+ // {MulOp Factor}
+ for (;;)
+ {
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // MulOp
+ // Initialization is need to avoid warning "warning: 'eArOp' may be used uninitialized in this function" on gcc 44
+ eCTPP2ArOp eArOp = OP_UNDEF;
+
+ sTMP = IsMulOp(szData, szEnd, eArOp);
+ if (sTMP == NULL) { return szData; }
+
+ // Factor
+ szData = sTMP;
+ sTMP = IsFactor(szData, szEnd, eResultOperator);
+ // Error?
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("Rvalue expected", szData.GetLine(), szData.GetLinePos()); }
+
+ // Variable on stack
+ eResultOperator = EXPR_VARIABLE;
+
+ // Operation
+ switch(eArOp)
+ {
+ case OP_MUL:
+ pCTPP2Compiler -> OpMul(VM_DEBUG(szData));
+ break;
+
+ case OP_DIV:
+ pCTPP2Compiler -> OpDiv(VM_DEBUG(szData));
+ break;
+
+ case OP_IDIV:
+ pCTPP2Compiler -> OpIDiv(VM_DEBUG(szData));
+ break;
+
+ case OP_MOD:
+ pCTPP2Compiler -> OpMod(VM_DEBUG(szData));
+ break;
+ default:
+ // This should *never* happened
+ throw "Ouch!";
+ }
+ }
+
+return NULL;
+}
+
+//
+// Factor = Function "(" [ Expr {"," Expr} ] ")" | number | character | string | "(" Expr ")" | NOT Factor
+//
+CCharIterator CTPP2Parser::IsFactor(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ REPORTER("IsFactor", szData());
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ CCharIterator sFuncEnd = NULL;
+
+ UINT_32 iFunctionParams = 0;
+ // Check function
+ CCharIterator sTMP = IsFunc(szData, szEnd, sFuncEnd, iFunctionParams);
+ if (sTMP != NULL)
+ {
+ // Push syscall
+ pCTPP2Compiler -> ExecuteSyscall(szData(), sFuncEnd() - szData(), iFunctionParams, VM_DEBUG(szData));
+ eResultOperator = EXPR_VARIABLE;
+ return sTMP;
+ }
+
+ sTMP = IsVar(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ eResultOperator = EXPR_VARIABLE;
+ return sTMP;
+ }
+
+ // Check number
+ sTMP = IsNum(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ if (iParsedNumberType == 0)
+ {
+ pCTPP2Compiler -> PushInt(iIntData, VM_DEBUG(szData));
+ eResultOperator = EXPR_INT_VALUE;
+ }
+ else
+ {
+ pCTPP2Compiler -> PushFloat(dFloatData, VM_DEBUG(szData));
+ eResultOperator = EXPR_FLOAT_VALUE;
+ }
+
+ return sTMP;
+ }
+
+ // Check string
+ sTMP = IsString(szData, szEnd);
+ if (sTMP != NULL)
+ {
+ pCTPP2Compiler -> PushString(sTMPBuf.c_str(), sTMPBuf.size(), VM_DEBUG(szData));
+ eResultOperator = EXPR_STRING_VALUE;
+ return sTMP;
+ }
+
+ // Check brackets
+ if (*szData == '(')
+ {
+ sTMP = LogicalOrExpr(++szData, szEnd, eResultOperator);
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("1 !IsFactor!", szData.GetLine(), szData.GetLinePos());
+ }
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ if (*sTMP != ')')
+ {
+ throw CTPPParserSyntaxError("2 !IsFactor!", szData.GetLine(), szData.GetLinePos());
+ }
+ return ++sTMP;
+ }
+
+ eCTPP2ArOp eArOp = OP_UNDEF;
+ sTMP = IsUnaryOp(szData, szEnd, eArOp);
+ // Optional
+ if (sTMP != NULL)
+ {
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ sTMP = IsFactor(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("Expected rvalue after unary operation", szData.GetLine(), szData.GetLinePos()); }
+
+ switch(eArOp)
+ {
+ case OP_UNPLUS:
+ // Do nothing
+ break;
+
+ case OP_UNMINUS:
+ pCTPP2Compiler -> OpNeg(VM_DEBUG(szData));
+ // Negate value
+ break;
+
+ case OP_NOT:
+ pCTPP2Compiler -> OpNot(VM_DEBUG(szData));
+ // Logical negation
+ break;
+ default:
+ throw CTPPParserSyntaxError("Incorrect operator", szData.GetLine(), szData.GetLinePos());
+ }
+
+ return sTMP;
+ }
+
+
+return NULL;
+}
+
+//
+// Relation = N_EQ | N_NE | N_GT | N_LT | N_GE | N_LE | EQ | NE | GT | LT | GE | LE
+//
+CCharIterator CTPP2Parser::IsRelation(CCharIterator szData, CCharIterator szEnd, eCTPP2Relation & eRelation)
+{
+ REPORTER("IsRelation", szData());
+
+ if (szData == szEnd) { return NULL; }
+
+ CTPP2Relation * oRelation = aCTPP2Relations;
+ while (oRelation -> keyword != NULL)
+ {
+ CCharIterator szIter1 = szData;
+ CCharIterator szIter2 = oRelation -> keyword;
+ while (szIter1 != szEnd)
+ {
+ if ((*szIter1 | 0x20) != *szIter2) { break; }
+ ++szIter1; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ eRelation = oRelation -> keyword_operator;
+ return szIter1;
+ }
+ }
+ ++oRelation;
+ }
+
+return NULL;
+}
+
+//
+// UnaryOp = UNPLUS | UNMINUS | NOT
+//
+CCharIterator CTPP2Parser::IsUnaryOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp)
+{
+ REPORTER("IsUnaryOp", szData());
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ if (szData == szEnd) { return NULL; }
+
+ if (*szData == '+') { eArOp = OP_UNPLUS; }
+ else if (*szData == '-') { eArOp = OP_UNMINUS; }
+ else if (*szData == '!') { eArOp = OP_NOT; }
+ else
+ {
+ return NULL;
+ }
+
+ ++szData;
+
+return szData;
+}
+
+//
+// AddOp = ADD | SUB
+//
+CCharIterator CTPP2Parser::IsAddOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp)
+{
+ REPORTER("IsAddOp", szData());
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ if (szData == szEnd) { return NULL; }
+
+ if (*szData == '+') { eArOp = OP_PLUS; }
+ else if (*szData == '-') { eArOp = OP_MINUS; }
+ else
+ {
+ return NULL;
+ }
+
+ ++szData;
+
+return szData;
+}
+
+//
+// LogicalOp = && | ||
+//
+CCharIterator CTPP2Parser::IsLogicalOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp)
+{
+ REPORTER("LogicalOp", szData());
+
+ static CCHAR_P szKeyTable[] = { "&&", "||", "and", "or", NULL };
+ static eCTPP2ArOp oArOpTable[] = { OP_LAND, OP_LOR, OP_LAND, OP_LOR, OP_UNDEF };
+
+ if (szData == szEnd) { return NULL; }
+
+ CCHAR_P * sKey = szKeyTable;
+ eCTPP2ArOp * oArOp = oArOpTable;
+
+ while (*sKey != NULL)
+ {
+ CCharIterator szIter1 = szData;
+ CCharIterator szIter2 = *sKey;
+ while (szIter1 != szEnd)
+ {
+ if ((*szIter1 | 0x20) != *szIter2) { break; }
+ ++szIter1; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ eArOp = *oArOp;
+ return szIter1;
+ }
+ }
+ ++sKey; ++oArOp;
+ }
+ return NULL;
+
+return szData;
+}
+
+//
+// MulOp = MUL | DIV | IDIV | MOD
+//
+CCharIterator CTPP2Parser::IsMulOp(CCharIterator szData, CCharIterator szEnd, eCTPP2ArOp & eArOp)
+{
+ REPORTER("IsMulOp", szData());
+
+ static CCHAR_P szKeyTable[] = { "mod", "div", NULL };
+ static eCTPP2ArOp oArOpTable[] = { OP_MOD, OP_IDIV, OP_UNDEF };
+
+ if (szData == szEnd) { return NULL; }
+
+ if (*szData == '*') { eArOp = OP_MUL; }
+ else if (*szData == '/') { eArOp = OP_DIV; }
+ else
+ {
+ CCHAR_P * sKey = szKeyTable;
+ eCTPP2ArOp * oArOp = oArOpTable;
+
+ while (*sKey != NULL)
+ {
+ CCharIterator szIter1 = szData;
+ CCharIterator szIter2 = *sKey;
+ while (szIter1 != szEnd)
+ {
+ if ((*szIter1 | 0x20) != *szIter2) { break; }
+ ++szIter1; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ eArOp = *oArOp;
+ return szIter1;
+ }
+ }
+ ++sKey; ++oArOp;
+ }
+ return NULL;
+ }
+ ++szData;
+
+return szData;
+}
+
+// Operator expressions ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// CTPP2 branch expression
+//
+CCharIterator CTPP2Parser::IsIfExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ CCharIterator sTMP = IsExpr(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected '<TMPL_if expression>'", szData.GetLine(), szData.GetLinePos()); }
+
+ // All Okay
+ szData = sTMP;
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ // Check close symbol
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+return szData;
+}
+
+//
+// CTPP2 reverse branch expression
+//
+CCharIterator CTPP2Parser::IsUnlessExpr(CCharIterator szData, CCharIterator szEnd, eCTPP2ExprOperator & eResultOperator)
+{
+ return IsExpr(szData, szEnd, eResultOperator);
+}
+
+//
+// CTPP2 foreach expression
+//
+CCharIterator CTPP2Parser::IsForeachExpr(CCharIterator szData, CCharIterator szEnd, UINT_32 & iRetPoint)
+{
+ // Find loop name
+ UINT_32 iFunctionParams = 0;
+ CCharIterator sFuncEnd = NULL;
+ CCharIterator sTMP = IsFunc(szData, szEnd, sFuncEnd, iFunctionParams);
+ if (sTMP != NULL)
+ {
+ // Push syscall
+ pCTPP2Compiler -> ExecuteSyscall(szData(), sFuncEnd() - szData(), iFunctionParams, VM_DEBUG(szData));
+ }
+ else
+ {
+ sTMP = IsVar(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("incorrect foreach condition", szData.GetLine(), szData.GetLinePos()); }
+ }
+
+ CCharIterator szLoopName = szData;
+ CCharIterator szLoopNameEnd = sTMP;
+
+ // Check translation map, TBD
+ // ................................
+
+ // Skip white space
+ szData = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // Check 'as' keyword
+ sTMP = IsForeachKeyword(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("incorrect foreach condition. expected `as` keyword", szData.GetLine(), szData.GetLinePos()); }
+
+ // Skip white space
+ szData = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // Find iterator name
+ sTMP = IsIterator(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("incorrect foreach iterator name", szData.GetLine(), szData.GetLinePos()); }
+
+ STLW::string sVarName(szLoopName(), szLoopNameEnd() - szLoopName());
+ iRetPoint = pCTPP2Compiler -> ChangeScope(sVarName.data(), sVarName.size(), VM_DEBUG(szData));
+
+ // Store new prefix
+ pCTPP2Compiler -> StoreScopedVariable(szData(), sTMP() - szData(), VM_DEBUG(szData));
+
+return sTMP;
+}
+
+// Operators //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Variable/Function/Exression output operator <TMPL_var Expr>
+//
+CCharIterator CTPP2Parser::VarOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ eCTPP2ExprOperator eResultOperator;
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ sTMP = IsExpr(szData, szEnd, eResultOperator);
+ STLW::string sExprDebug(szData(), sTMP() - szData());
+
+ // Cannot parse expression or variable name
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected variable or expression", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ if (szData == szEnd) { throw CTPPParserSyntaxError("unexpected end of file found", szData.GetLine(), szData.GetLinePos()); }
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+ // Output variable
+ pCTPP2Compiler -> OutputVariable(VM_DEBUG(szData));
+
+return szData;
+}
+
+//
+// Branch operator <TMPL_if IfExpr> blah-blah-blah [ <TMPL_else> clah-clah-clah ] </TMPL_if>
+//
+CCharIterator CTPP2Parser::IfOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ STLW::vector<INT_32> vJMPPoints;
+
+ eCTPP2ExprOperator eResultOperator = EXPR_UNDEF;
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ // Condition
+ szData = IsIfExpr(szData, szEnd, eResultOperator);
+ // Syntax ok, store result
+ INT_32 iBranchCallerIP = StoreIfComparisonResult(szData, eResultOperator);
+
+ eBreakFound = TMPL_if;
+ // Recursive descend
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+ szData = sTMP;
+
+ if (eBreakFound != TMPL_else &&
+ eBreakFound != TMPL_elsif &&
+ eBreakFound != TMPL_if) { throw CTPPParserOperatorsMismatch("<TMPL_else> OR <TMPL_elsif expression> OR </TMPL_if>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos()); }
+
+ // Jump to end of branch
+ UINT_32 iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+
+ while (eBreakFound == TMPL_elsif)
+ {
+ eResultOperator = EXPR_UNDEF;
+
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ INT_32 iBranchEntryPoint = pCTPP2Compiler -> GetCodeSize();
+
+ // Condition
+ szData = IsIfExpr(szData, szEnd, eResultOperator);
+
+ // Syntax ok, store result
+ INT_32 iBranchCodePoint = StoreIfComparisonResult(szData, eResultOperator);
+
+ if (iBranchCallerIP != -1)
+ {
+ // Set JXX point for previous branch
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(iBranchCallerIP);
+ pInstruction -> argument = iBranchEntryPoint;
+ }
+ iBranchCallerIP = iBranchCodePoint;
+
+ eBreakFound = TMPL_elsif;
+
+ // Recursive descend
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ if (eBreakFound != TMPL_else &&
+ eBreakFound != TMPL_elsif &&
+ eBreakFound != TMPL_if) { throw CTPPParserOperatorsMismatch("<TMPL_else> OR <TMPL_elsif expression> OR </TMPL_if>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos()); }
+
+ szData = sTMP;
+
+ // Jump to end of branch
+ iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+ }
+
+ // Jump to else-branch if condition is false
+ INT_32 iExitPoint = pCTPP2Compiler -> GetCodeSize();
+ if (iBranchCallerIP != -1)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(iBranchCallerIP);
+ pInstruction -> argument = iExitPoint;
+ }
+
+ // Else branch
+ if (eBreakFound == TMPL_else)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ // '>'
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ szData = sTMP;
+ // Jump to end of branch
+ iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+ iExitPoint = pCTPP2Compiler -> GetCodeSize();
+ }
+
+ // /TMPL_if
+ if (eBreakFound != TMPL_if)
+ {
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected </TMPL_if>", szData.GetLine(), szData.GetLinePos()); }
+
+ throw CTPPParserOperatorsMismatch("</TMPL_if>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos());
+ }
+ eBreakFound = UNDEF;
+
+ INT_32 iLastJMPPos = vJMPPoints.size() - 1;
+
+ // Okay, set JMP points
+ for(INT_32 iI = 0; iI <= iLastJMPPos; ++iI)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(vJMPPoints[iI]);
+ pInstruction -> argument = iExitPoint;
+ }
+
+return szData;
+}
+
+//
+// Reverse branch operator <TMPL_unless IfExpr> blah-blah-blah [ <TMPL_else> clah-clah-clah ] </TMPL_unless>
+//
+CCharIterator CTPP2Parser::UnlessOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ STLW::vector<INT_32> vJMPPoints;
+
+ eCTPP2ExprOperator eResultOperator = EXPR_UNDEF;
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ // Condition
+ szData = IsIfExpr(szData, szEnd, eResultOperator);
+
+ // Syntax ok, store result
+ INT_32 iBranchCallerIP = StoreUnlessComparisonResult(szData, eResultOperator);
+
+ eBreakFound = TMPL_if;
+
+ // Recursive descend
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+ szData = sTMP;
+
+ if (eBreakFound != TMPL_else &&
+ eBreakFound != TMPL_elsif &&
+ eBreakFound != TMPL_unless) { throw CTPPParserOperatorsMismatch("<TMPL_else> OR <TMPL_elsif expression> OR </TMPL_if>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos()); }
+
+ // Jump to end of branch
+ UINT_32 iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+
+ while (eBreakFound == TMPL_elsif)
+ {
+ eResultOperator = EXPR_UNDEF;
+
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ INT_32 iBranchEntryPoint = pCTPP2Compiler -> GetCodeSize();
+
+ // Condition
+ szData = IsIfExpr(szData, szEnd, eResultOperator);
+
+ // Syntax ok, store result
+ INT_32 iBranchCodePoint = StoreIfComparisonResult(szData, eResultOperator);
+
+ // Set JXX point for previous branch
+ if (iBranchCallerIP != -1)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(iBranchCallerIP);
+ pInstruction -> argument = iBranchEntryPoint;
+ }
+
+ iBranchCallerIP = iBranchCodePoint;
+
+ eBreakFound = TMPL_elsif;
+
+ // Recursive descend
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ if (eBreakFound != TMPL_else &&
+ eBreakFound != TMPL_elsif &&
+ eBreakFound != TMPL_unless) { throw CTPPParserOperatorsMismatch("<TMPL_else> OR <TMPL_elsif expression> OR </TMPL_unless>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos()); }
+
+ szData = sTMP;
+
+ // Jump to end of branch
+ iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+ }
+
+ // Jump to else-branch if condition is false
+ INT_32 iExitPoint = pCTPP2Compiler -> GetCodeSize();
+ if (iBranchCallerIP != -1)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(iBranchCallerIP);
+ pInstruction -> argument = iExitPoint;
+ }
+
+ // Else branch
+ if (eBreakFound == TMPL_else)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ // '>'
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+ sTMP = Parse(szData, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ szData = sTMP;
+ // Jump to end of branch
+ iTMP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ vJMPPoints.push_back(iTMP);
+ iExitPoint = pCTPP2Compiler -> GetCodeSize();
+ }
+
+ // /TMPL_unless
+ if (eBreakFound != TMPL_unless)
+ {
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected </TMPL_if>", szData.GetLine(), szData.GetLinePos()); }
+
+ throw CTPPParserOperatorsMismatch("</TMPL_unless>", GetOperatorName(eBreakFound), szData.GetLine(), szData.GetLinePos());
+ }
+ eBreakFound = UNDEF;
+
+ INT_32 iLastJMPPos = vJMPPoints.size() - 1;
+
+ // Okay, set JMP points
+ for(INT_32 iI = 0; iI <= iLastJMPPos; ++iI)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(vJMPPoints[iI]);
+ pInstruction -> argument = iExitPoint;
+ }
+
+return szData;
+}
+
+//
+// Foreach operator <TMPL_foreach var_array as var> blah-blah-blah </TMPL_foreach>
+//
+CCharIterator CTPP2Parser::ForeachOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ UINT_32 iRetPoint = 0;
+
+ // Parse foreach expression
+ szData = IsForeachExpr(szData, szEnd, iRetPoint);
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+ // Lock foreach flag
+ ForeachFlagLocker oLocker(bInForeach);
+
+ vBreakJMPPoints.push_back(STLW::vector<INT_32>());
+
+ // Recursive descend
+ sTMP = Parse(szData, szEnd);
+
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ if (eBreakFound != TMPL_foreach) { throw CTPPParserOperatorsMismatch("</TMPL_foreach>", GetOperatorName(eBreakFound), sTMP.GetLine(), sTMP.GetLinePos()); }
+ eBreakFound = UNDEF;
+
+ // Store point
+ INT_32 iEndPoint = pCTPP2Compiler -> ResetScope(iRetPoint, VM_DEBUG(szData));
+ for(STLW::vector<INT_32>::iterator vIt = vBreakJMPPoints.back().begin(); vIt != vBreakJMPPoints.back().end(); ++vIt)
+ {
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(*vIt);
+ pInstruction -> argument = iEndPoint;
+ }
+ vBreakJMPPoints.pop_back();
+
+return sTMP;
+}
+
+//
+// Include operator <TMPL_include Expr>
+//
+CCharIterator CTPP2Parser::IncludeOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ // Check include file name
+ sTMP = IsString(szData, szEnd);
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("incorrect include file name", szData.GetLine(), szData.GetLinePos());
+ }
+ STLW::string sIncludeFilename(sTMPBuf);
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(sTMP, szEnd);
+
+ // '>'
+ if (*sTMP != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", sTMP.GetLine(), sTMP.GetLinePos()); }
+ ++sTMP;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(sTMP, szEnd); }
+
+ // Max, recursion level reached?
+ if (iRecursionLevel == CTPP_MAX_TEMPLATE_RECURSION_DEPTH - 1)
+ {
+ throw CTPPParserSyntaxError("Max. recursion level of template reached", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ // All okay, need to parse include file
+ CTPP2SourceLoader * pTMPSourceLoader = NULL;
+ try
+ {
+ // Create loader
+ pTMPSourceLoader = pSourceLoader -> Clone();
+ // Load template
+ pTMPSourceLoader -> LoadTemplate(sIncludeFilename.c_str());
+ // Create parser
+ CTPP2Parser oTMPParser(pTMPSourceLoader, pCTPP2Compiler, sIncludeFilename, bInForeach, iRecursionLevel + 1);
+ oTMPParser.SetBlockArgSizeMap(mBlockArgSizes);
+ // No HLT at end of code
+ oTMPParser.Compile(0);
+ mBlockArgSizes = oTMPParser.GetBlockArgSizeMap();
+ }
+ catch(CTPPLogicError & e)
+ {
+ delete pTMPSourceLoader;
+
+ CHAR_8 szTMPBuffer[2048 + 1];
+ snprintf(szTMPBuffer, 2048, "Cannot load template file `%s`: %s", sTMPBuf.c_str(), e.what());
+
+ throw CTPPParserSyntaxError(szTMPBuffer, sTMP.GetLine(), sTMP.GetLinePos());
+ }
+ catch(CTPPUnixException & e)
+ {
+ delete pTMPSourceLoader;
+
+ CHAR_8 szTMPBuffer[2048 + 1];
+ snprintf(szTMPBuffer, 2048, "Cannot load template file `%s`: %s", sTMPBuf.c_str(), strerror(e.ErrNo()));
+
+ throw CTPPParserSyntaxError(szTMPBuffer, sTMP.GetLine(), sTMP.GetLinePos());
+ }
+ catch(CTPPParserOperatorsMismatch & e)
+ {
+ delete pTMPSourceLoader;
+
+ CHAR_8 szTMPBuffer[2048 + 1];
+ snprintf(szTMPBuffer, 2048, "In include file '%s' at line %d, pos %d: expected \"%s\", but found \"%s\"", sTMPBuf.c_str(), e.GetLine(), e.GetLinePos(), e.Expected(), e.Found());
+
+ throw CTPPParserSyntaxError(szTMPBuffer, sTMP.GetLine(), sTMP.GetLinePos());
+ }
+ catch(CTPPParserException & e)
+ {
+ delete pTMPSourceLoader;
+
+ CHAR_8 szTMPBuffer[2048 + 1];
+ snprintf(szTMPBuffer, 2048, "In include file '%s' at line %d, pos %d: %s", sTMPBuf.c_str(), e.GetLine(), e.GetLinePos(), e.what());
+
+ throw CTPPParserSyntaxError(szTMPBuffer, sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ delete pTMPSourceLoader;
+
+return sTMP;
+}
+
+//
+// Call operator <TMPL_call Expr>
+//
+CCharIterator CTPP2Parser::CallOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ bool bIsVariable = false;
+
+ UINT_32 iFormalArgCount = 0;
+
+ // Check block name
+ sTMP = IsString(szData, szEnd);
+ STLW::string sBlockName(sTMPBuf);
+ if (sTMP != NULL)
+ {
+ if (mBlockArgSizes.find(sBlockName) == mBlockArgSizes.end()) { throw CTPPParserSyntaxError("unknown block name", szData.GetLine(), szData.GetLinePos()); }
+ iFormalArgCount = mBlockArgSizes[sBlockName];
+ }
+ else
+ {
+ // Search variable
+ sTMP = IsVar(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("incorrect block name", szData.GetLine(), szData.GetLinePos()); }
+
+ sBlockName.assign(szData(), sTMP() - szData());
+ bIsVariable = true;
+ }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(sTMP, szEnd);
+
+ pCTPP2Compiler -> PrepareCallBlock(VM_DEBUG(szData));
+
+ // Call args
+ UINT_32 iArgCount = 0;
+ szData = sTMP;
+ sTMP = CallArgs(szData, szEnd, iArgCount);
+ if (sTMP == NULL) { sTMP = szData; }
+ else if (!bIsVariable && iArgCount != iFormalArgCount)
+ {
+ throw CTPPParserSyntaxError("invalid number of arguments", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // '>'
+ if (*sTMP != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", sTMP.GetLine(), sTMP.GetLinePos()); }
+ ++sTMP;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(sTMP, szEnd); }
+
+ pCTPP2Compiler -> CallBlock(sBlockName, bIsVariable, iArgCount, VM_DEBUG(szData));
+
+return sTMP;
+}
+
+//
+// CTPP2 comment <TMPL_comment> blah-blah-blah </TMPL_comment>
+//
+CCharIterator CTPP2Parser::CommentOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ // '>'
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Skip code
+ for (;;)
+ {
+ // Open symbol
+ while (szData != szEnd && *szData != TMPL_OPEN_SYMBOL) { ++szData; }
+ // Unexpected end of template
+ if (szData == szEnd) { throw CTPPParserSyntaxError("expected '</TMPL_comment>'", szData.GetLine(), szData.GetLinePos()); }
+
+ CCharIterator szTMP = IsCloseTag(++szData, szEnd);
+ if (szTMP == NULL) { ++szData; }
+ else
+ {
+ eCTPP2Operator oOperatorType = UNDEF;
+ szData = szTMP;
+ szTMP = IsOperator(++szData, szEnd, oOperatorType);
+ //
+ if (szTMP == szEnd) { throw CTPPParserSyntaxError("unexpected end of file", szData.GetLine(), szData.GetLinePos()); }
+ // Operator NOT found after opener tag
+ if (szTMP != NULL)
+ {
+ if (oOperatorType == TMPL_comment)
+ {
+ szTMP = IsWhiteSpace(szTMP, szEnd, 0);
+ if (*szTMP != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szTMP.GetLine(), szTMP.GetLinePos()); }
+ ++szTMP;
+ return szTMP;
+ }
+ szData = szTMP;
+ }
+
+ }
+ }
+return NULL;
+}
+
+//
+// Break operator <TMPL_break>
+//
+CCharIterator CTPP2Parser::BreakOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ // Store point
+ vBreakJMPPoints.back().push_back(pCTPP2Compiler -> UncondJump((UINT_32)-1, VM_DEBUG(szData)));
+
+ // Skip white space
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd, 0);
+
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(sTMP, szEnd);
+
+ // '>'
+ if (*sTMP != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", sTMP.GetLine(), sTMP.GetLinePos()); }
+ ++sTMP;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(sTMP, szEnd); }
+
+return sTMP;
+}
+
+//
+// Block of code <TMPL_block "blockname" args(arg1, arg2, ..., argN)> ..... </TMPL_block>
+//
+CCharIterator CTPP2Parser::BlockOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ CCharIterator sTMP = IsWhiteSpace(szData, szEnd);
+ if (sTMP == NULL) { throw CTPPParserSyntaxError("expected at least one space symbol", szData.GetLine(), szData.GetLinePos()); }
+ szData = sTMP;
+
+ // Check block name
+ sTMP = IsString(szData, szEnd);
+ if (sTMP == NULL)
+ {
+ throw CTPPParserSyntaxError("incorrect block name", szData.GetLine(), szData.GetLinePos());
+ }
+
+ STLW::string sBlockName(sTMPBuf);
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+
+ szData = sTMP;
+ mCurrentBlock.clear();
+ sTMP = BlockArgs(sTMP, szEnd);
+ if (sTMP == NULL) { sTMP = szData; }
+
+ if (mBlockArgSizes.find(sBlockName) != mBlockArgSizes.end())
+ {
+ throw CTPPParserSyntaxError("redifintion of block", sTMP.GetLine(), sTMP.GetLinePos());
+ }
+ mBlockArgSizes[sBlockName] = mCurrentBlock.size();
+
+ // Skip white space
+ sTMP = IsWhiteSpace(sTMP, szEnd, 0);
+
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(sTMP, szEnd);
+
+ // '>'
+ if (*sTMP != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", sTMP.GetLine(), sTMP.GetLinePos()); }
+ ++sTMP;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(sTMP, szEnd); }
+
+ // Start block
+ UINT_32 iStartBlockIP = pCTPP2Compiler -> StartBlock(sTMPBuf, sTMP);
+
+ // Recursive descend
+ sTMP = Parse(sTMP, szEnd);
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ if (eBreakFound != TMPL_block ) { throw CTPPParserOperatorsMismatch("</TMPL_block>", GetOperatorName(eBreakFound), sTMP.GetLine(), sTMP.GetLinePos()); }
+ eBreakFound = UNDEF;
+
+ pCTPP2Compiler -> EndBlock(mCurrentBlock.size(), VM_DEBUG(sTMP));
+
+ VMInstruction * pInstruction = pCTPP2Compiler -> GetInstruction(iStartBlockIP);
+ pInstruction -> argument = pCTPP2Compiler -> GetCodeSize();
+
+return sTMP;
+}
+
+//
+// Ignore spaces <TMPL_verbose> ..... </TMPL_verbose>
+//
+CCharIterator CTPP2Parser::VerboseOperator(CCharIterator szData, CCharIterator szEnd)
+{
+ const bool bOldVerboseMode = bVerboseMode;
+ bVerboseMode = true;
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check "remove trailing newline flag"
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szData, szEnd);
+
+ // '>'
+ if (*szData != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ // Remove trailing newline(s), if need
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szData, szEnd); }
+
+ // Recursive descend
+ CCharIterator sTMP = Parse(szData, szEnd);
+
+ bVerboseMode = bOldVerboseMode;
+
+ // This should *never* happened
+ if (sTMP == NULL) { throw "Ouch!"; }
+
+ if (eBreakFound != TMPL_verbose) { throw CTPPParserOperatorsMismatch("</TMPL_verbose>", GetOperatorName(eBreakFound), sTMP.GetLine(), sTMP.GetLinePos()); }
+ eBreakFound = UNDEF;
+
+return sTMP;
+}
+
+// Other stuff ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// Parse CTPP2 source code
+//
+CCharIterator CTPP2Parser::Parse(CCharIterator szData, CCharIterator szEnd)
+{
+ eBreakFound = UNDEF;
+
+ CCharIterator szIter = szData;
+ CCharIterator szText = szData;
+
+ for (;;)
+ {
+
+ CCharIterator szSkippedSpacesText = szText;
+ CCharIterator sTMP = szText;
+ // Open tag
+ while (szIter != szEnd)
+ {
+ if (*szIter == TMPL_OPEN_SYMBOL) { break; }
+
+ if (*szIter != ' ' && *szIter != '\t' && *szIter != '\r' && *szIter != '\n')
+ {
+ ++szIter;
+ szSkippedSpacesText = sTMP = szIter;
+ }
+ else
+ {
+ ++szIter;
+ szSkippedSpacesText = sTMP;
+ }
+ }
+
+ if (szIter == szEnd)
+ {
+ // Store static data
+ pCTPP2Compiler -> OutputStaticData(szText(), szEnd() - szText(), VM_DEBUG(szText));
+ return szIter;
+ }
+
+ ++szIter;
+
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ // Check open tag
+ sTMP = IsOpenTag(szIter, szEnd);
+ if (sTMP != NULL)
+ {
+ // Store static data
+ if (bRemoveTrailingNewLine || bVerboseMode)
+ {
+ pCTPP2Compiler -> OutputStaticData(szText(), szSkippedSpacesText() - szText(), VM_DEBUG(szText));
+ }
+ else
+ {
+ pCTPP2Compiler -> OutputStaticData(szText(), szIter() - szText() - 1, VM_DEBUG(szText));
+ }
+ // Check operator
+ eCTPP2Operator oOperatorType = UNDEF;
+ szIter = IsOperator(++sTMP, szEnd, oOperatorType);
+ // Operator NOT found after opener tag
+ if (szIter == NULL) { throw CTPPParserSyntaxError("incorrect operator", sTMP.GetLine(), sTMP.GetLinePos()); }
+
+ if (szIter == szEnd) { throw CTPPParserSyntaxError("unexpected end of file", szIter.GetLine(), szIter.GetLinePos()); }
+ // Operator found, parse operator code
+ switch (oOperatorType)
+ {
+ // Print variable or execute function
+ // User defined function
+ case TMPL_udf:
+ // Variable
+ case TMPL_var:
+ szIter = VarOperator(szIter, szEnd);
+ break;
+
+ // Branch
+ case TMPL_if:
+ szIter = IfOperator(szIter, szEnd);
+ break;
+
+ // Next branch
+ case TMPL_elsif:
+ eBreakFound = TMPL_elsif;
+ return szIter;
+ break;
+
+ // Branch with inverted condition
+ case TMPL_unless:
+ szIter = UnlessOperator(szIter, szEnd);
+ break;
+
+ // Else-branch
+ case TMPL_else:
+ eBreakFound = TMPL_else;
+ return szIter;
+
+ // Foreach
+ case TMPL_foreach:
+ eBreakFound = TMPL_foreach;
+ szIter = ForeachOperator(szIter, szEnd);
+ break;
+
+ // Include file
+ case TMPL_include:
+ szIter = IncludeOperator(szIter, szEnd);
+ break;
+
+ // Call operator
+ case TMPL_call:
+ szIter = CallOperator(szIter, szEnd);
+ break;
+
+ // Comment
+ case TMPL_comment:
+ szIter = CommentOperator(szIter, szEnd);
+ break;
+
+ // Break
+ case TMPL_break:
+ if (!bInForeach) { throw CTPPParserSyntaxError("TMPL_break outside loop", szIter.GetLine(), szIter.GetLinePos()); }
+ szIter = BreakOperator(szIter, szEnd);
+ break;
+
+ // Block
+ case TMPL_block:
+ eBreakFound = TMPL_block;
+ if (bInBlock) { throw CTPPParserSyntaxError("Nesting of TMPL_block is forbidden", szIter.GetLine(), szIter.GetLinePos()); }
+ bInBlock = true;
+ szIter = BlockOperator(szIter, szEnd);
+ break;
+
+ // Verbose
+ case TMPL_verbose:
+ eBreakFound = TMPL_verbose;
+ szIter = VerboseOperator(szIter, szEnd);
+ break;
+
+ // Error!
+ default:
+ throw CTPPParserSyntaxError("impossible happened", szIter.GetLine(), szIter.GetLinePos());
+ break;
+ }
+ // End of stream
+ if (szIter == szEnd) { return szIter; }
+
+ szText = szIter;
+ }
+ // Check close tag
+ else
+ {
+ sTMP = IsCloseTag(szIter, szEnd);
+ if (sTMP != NULL)
+ {
+ // Store static data
+ if (bRemoveTrailingNewLine || bVerboseMode)
+ {
+ pCTPP2Compiler -> OutputStaticData(szText(), szSkippedSpacesText() - szText(), VM_DEBUG(szText));
+ }
+ else
+ {
+ pCTPP2Compiler -> OutputStaticData(szText(), szIter() - szText() - 1, VM_DEBUG(szText));
+ }
+ // Check operator
+ eCTPP2Operator oOperatorType = UNDEF;
+ szIter = IsOperator(++sTMP, szEnd, oOperatorType);
+ // Operator NOT found after close tag
+ if (szIter == NULL) { throw CTPPParserSyntaxError("incorrect operator", szIter.GetLine(), szIter.GetLinePos()); }
+
+ if (szIter == szEnd) { throw CTPPParserSyntaxError("unexpected end of file", szIter.GetLine(), szIter.GetLinePos()); }
+ // Operator found, parse operator code
+ switch (oOperatorType)
+ {
+ // Error!
+ case UNDEF:
+ throw CTPPParserSyntaxError("impossible happened", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_udf:
+ throw CTPPParserSyntaxError("operator '</TMPL_udf>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_var:
+ throw CTPPParserSyntaxError("operator '</TMPL_var>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_else:
+ throw CTPPParserSyntaxError("operator '</TMPL_else>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_elsif:
+ throw CTPPParserSyntaxError("operator '</TMPL_elsif>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_include:
+ throw CTPPParserSyntaxError("operator '</TMPL_include>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_break:
+ throw CTPPParserSyntaxError("operator '</TMPL_break>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ case TMPL_comment:
+ throw CTPPParserSyntaxError("operator '</TMPL_comment>' cannot use here", szIter.GetLine(), szIter.GetLinePos());
+ case TMPL_call:
+ throw CTPPParserSyntaxError("operator '</TMPL_call>' does not exist", szIter.GetLine(), szIter.GetLinePos());
+
+ // Branch
+ case TMPL_if:
+ {
+ szIter = IsWhiteSpace(szIter, szEnd, 0);
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ if (*szIter != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szIter.GetLine(), szIter.GetLinePos()); }
+ ++szIter;
+
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szIter, szEnd); }
+
+ eBreakFound = TMPL_if;
+ return szIter;
+ }
+ // Branch with inverted condition
+ case TMPL_unless:
+ {
+ szIter = IsWhiteSpace(szIter, szEnd, 0);
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ if (*szIter != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szIter.GetLine(), szIter.GetLinePos()); }
+ ++szIter;
+
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szIter, szEnd); }
+
+ eBreakFound = TMPL_unless;
+ return szIter;
+ }
+ // Foreach
+ case TMPL_foreach:
+ {
+ szIter = IsWhiteSpace(szIter, szEnd, 0);
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ if (*szIter != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szIter.GetLine(), szIter.GetLinePos()); }
+ ++szIter;
+
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szIter, szEnd); }
+
+ eBreakFound = TMPL_foreach;
+ return szIter;
+ }
+ // Block
+ case TMPL_block:
+ {
+ szIter = IsWhiteSpace(szIter, szEnd, 0);
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ if (*szIter != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szIter.GetLine(), szIter.GetLinePos()); }
+ ++szIter;
+
+ if (bRemoveTrailingNewLine || bVerboseMode) { RemoveTrailingNewLines(szIter, szEnd); }
+
+ eBreakFound = TMPL_block;
+ bInBlock = false;
+ return szIter;
+ }
+ // Verbose
+ case TMPL_verbose:
+ {
+ szIter = IsWhiteSpace(szIter, szEnd, 0);
+ const bool bRemoveTrailingNewLine = CheckTrailingFlag(szIter, szEnd);
+
+ if (*szIter != TMPL_CLOSE_SYMBOL) { throw CTPPParserSyntaxError("expected '>'", szIter.GetLine(), szIter.GetLinePos()); }
+ ++szIter;
+
+ if (bRemoveTrailingNewLine) { RemoveTrailingNewLines(szIter, szEnd); }
+
+ bVerboseMode = false;
+
+ eBreakFound = TMPL_verbose;
+ return szIter;
+ }
+ default:
+ throw "UndefOperator";
+ }
+ // End of stream
+ if (szIter == szEnd) { return szIter; }
+
+ szText = szIter;
+ }
+ else
+ {
+ if (szIter == szEnd)
+ {
+ // Store static data
+ pCTPP2Compiler -> OutputStaticData(szText(), szEnd() - szText(), VM_DEBUG(szText));
+ break;
+ }
+ }
+ }
+ }
+
+// This should not happened
+return NULL;
+}
+
+//
+// Store comparison result (if branch)
+//
+UINT_32 CTPP2Parser::StoreIfComparisonResult(CCharIterator szData, const eCTPP2ExprOperator & eResultOperator)
+{
+ UINT_32 iElseBranchCallerIP = (UINT_32)-1;
+
+ // Compare values
+ switch (eResultOperator)
+ {
+ // Simple case: comparison result is always true or always false
+ // 0 ?
+ case EXPR_INT_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of INTEGER VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (iIntData != 0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "false\n");
+ }
+
+ break;
+
+ // 0.0 ?
+ case EXPR_FLOAT_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of FLOAT VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (dFloatData != 0.0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "true\n");
+ }
+ break;
+
+ // Empty string?
+ case EXPR_STRING_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of STRING VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (sTMPBuf.size() != 0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "true\n");
+ }
+ break;
+
+ // Complex case: compare variable
+ case EXPR_VARIABLE:
+ pCTPP2Compiler -> ExistStackVariable(VM_DEBUG(szData));
+ pCTPP2Compiler -> PopVariable(1, VM_DEBUG(szData));
+ iElseBranchCallerIP = pCTPP2Compiler -> NEJump(UINT_32(-1), VM_DEBUG(szData));
+ break;
+
+ default:
+ // This should *never* happened
+ throw "Ouch!";
+ }
+
+return iElseBranchCallerIP;
+}
+
+//
+// Store comparison result (unless branch)
+//
+UINT_32 CTPP2Parser::StoreUnlessComparisonResult(CCharIterator szData, const eCTPP2ExprOperator & eResultOperator)
+{
+ UINT_32 iElseBranchCallerIP = (UINT_32)-1;
+
+ // Compare values
+ switch (eResultOperator)
+ {
+ // Simple case: comparison result is always true or always false
+ // 0 ?
+ case EXPR_INT_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of INTEGER VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (iIntData == 0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "false\n");
+ }
+ break;
+
+ // 0.0 ?
+ case EXPR_FLOAT_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of FLOAT VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (dFloatData == 0.0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "true\n");
+ }
+ break;
+
+ // Empty string?
+ case EXPR_STRING_VALUE:
+ fprintf(stderr, "WARNING: near line %d, pos. %d: comparison result of STRING VALUE is always ", szData.GetLine(), szData.GetLinePos());
+ pCTPP2Compiler -> RemoveInstruction();
+
+ if (sTMPBuf.size() == 0) { fprintf(stderr, "true\n"); }
+ else
+ {
+ // Store point to unconditional jump (to ELSE branch)
+ iElseBranchCallerIP = pCTPP2Compiler -> UncondJump(UINT_32(-1), VM_DEBUG(szData));
+ fprintf(stderr, "true\n");
+ }
+ break;
+
+ // Complex case: compare variable
+ case EXPR_VARIABLE:
+ pCTPP2Compiler -> ExistStackVariable(VM_DEBUG(szData));
+ pCTPP2Compiler -> PopVariable(1, VM_DEBUG(szData));
+ iElseBranchCallerIP = pCTPP2Compiler -> EQJump(UINT_32(-1), VM_DEBUG(szData));
+ break;
+
+ default:
+ // This should *never* happened
+ throw "Ouch!";
+ }
+
+return iElseBranchCallerIP;
+}
+
+//
+// Get printable operator name
+//
+CCHAR_P CTPP2Parser::GetOperatorName(const eCTPP2Operator & oOperator)
+{
+ switch(oOperator)
+ {
+ case TMPL_var: return "TMPL_var";
+ case TMPL_if: return "TMPL_if";
+ case TMPL_unless: return "TMPL_unless";
+ case TMPL_else: return "TMPL_else";
+ case TMPL_elsif: return "TMPL_elsif";
+ case TMPL_foreach: return "TMPL_foreach";
+ case TMPL_include: return "TMPL_include";
+ case TMPL_udf: return "TMPL_udf";
+ case TMPL_comment: return "TMPL_comment";
+ case TMPL_break: return "TMPL_break";
+ case TMPL_block: return "TMPL_block";
+ case TMPL_call: return "TMPL_call";
+ default:
+ return "*UNDEF*";
+ }
+// Make stupid compiler happy
+return NULL;
+}
+
+//
+// Check trailing newline flag
+//
+bool CTPP2Parser::CheckTrailingFlag(CCharIterator & szData, CCharIterator szEnd)
+{
+ bool bRemoveTrailingNewLine = false;
+ if (*szData == '-')
+ {
+ bRemoveTrailingNewLine = true;
+ ++szData;
+ if (szData == szEnd) { throw CTPPParserSyntaxError("unexpected end of file fround", szData.GetLine(), szData.GetLinePos()); }
+ }
+return bRemoveTrailingNewLine;
+}
+
+//
+// Remove trailing newline(s)
+//
+void CTPP2Parser::RemoveTrailingNewLines(CCharIterator & szData, CCharIterator szEnd)
+{
+ CCharIterator szTMP = szData;
+ while(szTMP != szEnd)
+ {
+ if (*szTMP != ' ' && *szTMP != '\t' && *szTMP != '\r' && *szTMP != '\n' && *szTMP != '\f' && *szTMP != '\v')
+ {
+ szData = szTMP;
+ break;
+ }
+ ++szTMP;
+ }
+}
+
+//
+// CTPP2 block args: args (a, b, c)
+//
+CCharIterator CTPP2Parser::BlockArgs(CCharIterator szData, CCharIterator szEnd)
+{
+ static CCHAR_P szName = "args";
+ CCharIterator szIter2 = szName;
+ while (szData != szEnd)
+ {
+ if ((*szData | 0x20) != *szIter2) { return NULL; }
+ ++szData; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ break;
+ }
+ }
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check open tag
+ if (szData == szEnd || *szData != '(') { throw CTPPParserSyntaxError("need '(' token after \"args\"", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ STLW::vector<STLW::string> vArgs;
+ for (;;)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Search variable
+ CCharIterator sTMP = IsIterator(szData, szEnd);
+ if (sTMP == NULL) { break; }
+
+ STLW::string sArgName(szData(), sTMP() - szData());
+ if (mCurrentBlock.find(sArgName) != mCurrentBlock.end()) { throw CTPPParserSyntaxError("duplicate argument's name", szData.GetLine(), szData.GetLinePos()); }
+ mCurrentBlock[sArgName] = 0;
+ vArgs.push_back(sArgName);
+
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ szData = sTMP;
+ // Check delimiter
+ if (szData == szEnd || *szData != ',') { break; }
+ ++szData;
+ }
+
+ // Check close tag
+ if (szData == szEnd || *szData != ')') { throw CTPPParserSyntaxError("need ')' token after translation map", szData.GetLine(), szData.GetLinePos()); }
+
+ STLW::vector<STLW::string>::reverse_iterator itv = vArgs.rbegin();
+ for (UINT_32 iI = 0; itv != vArgs.rend(); ++itv, ++iI) { mCurrentBlock[*itv] = iI; }
+
+return ++szData;
+}
+
+//
+// CTPP2 call args: args (a, b, c)
+//
+CCharIterator CTPP2Parser::CallArgs(CCharIterator szData, CCharIterator szEnd, UINT_32 & iArgCount)
+{
+ iArgCount = 0;
+
+ static CCHAR_P szName = "args";
+ CCharIterator szIter2 = szName;
+ while (szData != szEnd)
+ {
+ if ((*szData | 0x20) != *szIter2) { return NULL; }
+ ++szData; ++szIter2;
+ if (*szIter2 == '\0')
+ {
+ break;
+ }
+ }
+
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Check open tag
+ if (szData == szEnd || *szData != '(') { throw CTPPParserSyntaxError("need '(' token after \"args\"", szData.GetLine(), szData.GetLinePos()); }
+ ++szData;
+
+ for (;;)
+ {
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+ // Search variable
+ eCTPP2ExprOperator eResultOperator;
+ CCharIterator sTMP = IsExpr(szData, szEnd, eResultOperator);
+ if (sTMP == NULL) { break; }
+
+ ++iArgCount;
+
+ szData = sTMP;
+ // Skip white space
+ szData = IsWhiteSpace(szData, szEnd, 0);
+
+ szData = sTMP;
+ // Check delimiter
+ if (szData == szEnd || *szData != ',') { break; }
+ ++szData;
+ }
+
+ // Check close tag
+ if (szData == szEnd || *szData != ')') { throw CTPPParserSyntaxError("need ')' token after translation map", szData.GetLine(), szData.GetLinePos()); }
+
+return ++szData;
+}
+
+//
+// A destructor
+//
+CTPP2Parser::~CTPP2Parser() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2ParserException.cpp b/src/CTPP2ParserException.cpp
new file mode 100644
index 0000000..ed5e960
--- /dev/null
+++ b/src/CTPP2ParserException.cpp
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2ParserException.hpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2ParserException.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPParserException
+//
+
+//
+// Get string describing the general cause of error
+//
+CCHAR_P CTPPParserException::what() const throw() { return "Parsing exception"; }
+
+//
+// A destructor
+//
+CTPPParserException::~CTPPParserException() throw() { ;; }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPParserSyntaxError
+//
+
+//
+// Constructor
+//
+CTPPParserSyntaxError::CTPPParserSyntaxError(CCHAR_P szIReason,
+ const UINT_32 iILine,
+ const UINT_32 iIPos): szReason(strdup(szIReason)),
+ iLine(iILine),
+ iPos(iIPos) { ;; }
+
+//
+// Get string describing the general cause of error
+//
+CCHAR_P CTPPParserSyntaxError::what() const throw() { return szReason; }
+
+//
+// Get line where error ocured
+//
+UINT_32 CTPPParserSyntaxError::GetLine() const { return iLine; }
+
+//
+// Get column where error ocured
+//
+UINT_32 CTPPParserSyntaxError::GetLinePos() const { return iPos; }
+
+//
+// A destructor
+//
+CTPPParserSyntaxError::~CTPPParserSyntaxError() throw() { free(szReason); }
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CTPPParserOperatorsMismatch
+//
+
+//
+// Constructor
+//
+CTPPParserOperatorsMismatch::CTPPParserOperatorsMismatch(CCHAR_P szIExpected,
+ CCHAR_P szIFound,
+ const UINT_32 iILine,
+ const UINT_32 iIPos): szExpected(strdup(szIExpected)),
+ szFound(strdup(szIFound)),
+ iLine(iILine),
+ iPos(iIPos) { ;; }
+
+//
+// Get string describing the general cause of error
+//
+CCHAR_P CTPPParserOperatorsMismatch::what() const throw() { return "Found wrong operator"; }
+
+//
+// Get name of exprcted operator
+//
+CCHAR_P CTPPParserOperatorsMismatch::Expected() const { return szExpected; }
+
+//
+// Get name of found operator
+//
+CCHAR_P CTPPParserOperatorsMismatch::Found() const { return szFound; }
+
+//
+// Get line where error ocured
+//
+UINT_32 CTPPParserOperatorsMismatch::GetLine() const { return iLine; }
+
+//
+// Get column where error ocured
+//
+UINT_32 CTPPParserOperatorsMismatch::GetLinePos() const { return iPos; }
+
+//
+// A destructor
+//
+CTPPParserOperatorsMismatch::~CTPPParserOperatorsMismatch() throw()
+{
+ free(szExpected);
+ free(szFound);
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2SimpleCompiler.cpp b/src/CTPP2SimpleCompiler.cpp
new file mode 100644
index 0000000..0be38e8
--- /dev/null
+++ b/src/CTPP2SimpleCompiler.cpp
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * SimpleCompiler.hpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2SimpleCompiler.hpp"
+
+#include "CTPP2Compiler.hpp"
+#include "CTPP2FileSourceLoader.hpp"
+#include "CTPP2Parser.hpp"
+
+#include "CTPP2SyscallFactory.hpp"
+#include "CTPP2VM.hpp"
+#include "CTPP2VMDumper.hpp"
+#include "CTPP2VMLoader.hpp"
+#include "CTPP2VMOpcodeCollector.hpp"
+
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// PIMPL
+//
+struct SimpleCompiler::_SimpleCompiler
+{
+ // Dumper object
+ VMDumper * vm_dumer;
+ // Template core
+ UINT_32 vm_executable_size;
+ // Template core
+ const VMExecutable * vm_executable;
+ // Template core
+ const VMMemoryCore vm_core;
+//
+// UINT_32 iSize = 0;
+// const VMExecutable * aProgramCore = oDumper.GetExecutable(iSize);
+//
+// // Get program core
+// const VMMemoryCore oVMMemoryCore(aProgramCore);
+
+ _SimpleCompiler(VMDumper * pVMDumper);
+
+ ~_SimpleCompiler() throw();
+};
+
+//
+// C-tor
+//
+SimpleCompiler::_SimpleCompiler::_SimpleCompiler(VMDumper * pVMDumper): vm_dumer(pVMDumper), vm_executable(vm_dumer -> GetExecutable(vm_executable_size)), vm_core(vm_executable)
+{
+ ;;
+}
+
+//
+// A destructor
+//
+SimpleCompiler::_SimpleCompiler::~_SimpleCompiler() throw()
+{
+ delete vm_dumer;
+}
+
+
+//
+// Constructor
+//
+SimpleCompiler::SimpleCompiler(const std::string & sSourceFile)
+{
+ VMOpcodeCollector oVMOpcodeCollector;
+ StaticText oSyscalls;
+ StaticData oStaticData;
+ StaticText oStaticText;
+ HashTable oHashTable;
+ CTPP2Compiler oCompiler(oVMOpcodeCollector, oSyscalls, oStaticData, oStaticText, oHashTable);
+
+ // Load template
+ CTPP2FileSourceLoader oSourceLoader;
+ oSourceLoader.LoadTemplate(sSourceFile.c_str());
+
+ // Create template parser
+ CTPP2Parser oCTPP2Parser(&oSourceLoader, &oCompiler, sSourceFile);
+
+ // Compile template
+ oCTPP2Parser.Compile();
+
+ // Get program core
+ UINT_32 iCodeSize = 0;
+ const VMInstruction * oVMInstruction = oVMOpcodeCollector.GetCode(iCodeSize);
+
+ pSimpleCompiler = new _SimpleCompiler(new VMDumper(iCodeSize, oVMInstruction, oSyscalls, oStaticData, oStaticText, oHashTable));
+}
+
+//
+// Save compiled data to file
+//
+UINT_32 SimpleCompiler::Save(const std::string & sCompiledFile) const
+{
+ INT_32 iRC = -1;
+
+ // Open file only if compilation is done
+ FILE * FW = fopen(sCompiledFile.c_str(), "wb");
+ if (FW == NULL) { return iRC; }
+
+ // Write to the disc
+ if (fwrite(pSimpleCompiler -> vm_executable, pSimpleCompiler -> vm_executable_size, 1, FW) == 1) { iRC =0 ; }
+
+ // All done
+ fclose(FW);
+
+return iRC;
+}
+
+
+//
+// Get memory core
+//
+const VMMemoryCore * SimpleCompiler::GetCore() const
+{
+ return &(pSimpleCompiler -> vm_core);
+}
+
+
+//
+// A destructor
+//
+SimpleCompiler::~SimpleCompiler() throw()
+{
+ delete pSimpleCompiler;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2SimpleVM.cpp b/src/CTPP2SimpleVM.cpp
new file mode 100644
index 0000000..6d92f55
--- /dev/null
+++ b/src/CTPP2SimpleVM.cpp
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SimpleVM.hpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2SimpleVM.hpp"
+
+#include "CTPP2FileOutputCollector.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2StringOutputCollector.hpp"
+#include "CTPP2VMSTDLib.hpp"
+#include "CTPP2SyscallFactory.hpp"
+#include "CTPP2VM.hpp"
+#include "CTPP2VMLoader.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// PIMPL
+//
+struct SimpleVM::_SimpleVM
+{
+ // Syscall factory
+ SyscallFactory syscall_factory;
+ // Virtual machine
+ VM vm;
+
+ _SimpleVM(const UINT_32 & iIMaxFunctions,
+ const UINT_32 & iIMaxArgStackSize,
+ const UINT_32 & iIMaxCodeStackSize,
+ const UINT_32 & iIMaxSteps,
+ const UINT_32 & iIDebugLevel);
+
+ ~_SimpleVM() throw();
+};
+
+//
+// C-tor
+//
+SimpleVM::_SimpleVM::_SimpleVM(const UINT_32 & iIMaxFunctions,
+ const UINT_32 & iIMaxArgStackSize,
+ const UINT_32 & iIMaxCodeStackSize,
+ const UINT_32 & iIMaxSteps,
+ const UINT_32 & iIDebugLevel): syscall_factory(iIMaxFunctions),
+ vm(&syscall_factory, iIMaxArgStackSize, iIMaxCodeStackSize, iIMaxSteps, iIDebugLevel)
+{
+ STDLibInitializer::InitLibrary(syscall_factory);
+}
+
+//
+// A destructor
+//
+SimpleVM::_SimpleVM::~_SimpleVM() throw()
+{
+ STDLibInitializer::DestroyLibrary(syscall_factory);
+}
+
+//
+// C-tor
+//
+SimpleVM::SimpleVM(const UINT_32 & iIMaxFunctions,
+ const UINT_32 & iIMaxArgStackSize,
+ const UINT_32 & iIMaxCodeStackSize,
+ const UINT_32 & iIMaxSteps,
+ const UINT_32 & iIDebugLevel): pSimpleVM(NULL)
+{
+ pSimpleVM = new _SimpleVM(iIMaxFunctions, iIMaxArgStackSize, iIMaxCodeStackSize, iIMaxSteps, iIDebugLevel);
+}
+
+//
+// Write Output to STL string
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMLoader & oLoader, std::string & sResult, Logger & oLogger)
+{
+ StringOutputCollector oOutputCollector(sResult);
+
+return Run(oData, oLoader, oOutputCollector, oLogger);
+}
+
+//
+// Write Output to file
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMLoader & oLoader, FILE * F, Logger & oLogger)
+{
+ FileOutputCollector oOutputCollector(F);
+
+return Run(oData, oLoader, oOutputCollector, oLogger);
+}
+
+//
+// Output to specified data collector
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMLoader & oLoader, OutputCollector & oCollector, Logger & oLogger)
+{
+ const VMMemoryCore * pCore = oLoader.GetCore();
+
+return Run(oData, pCore, oCollector, oLogger);
+}
+
+//
+// Write Output to string
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMMemoryCore * pCore, std::string & sResult, Logger & oLogger)
+{
+ StringOutputCollector oOutputCollector(sResult);
+
+return Run(oData, pCore, oOutputCollector, oLogger);
+}
+
+//
+// Write Output to file
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMMemoryCore * pCore, FILE * F, Logger & oLogger)
+{
+ FileOutputCollector oOutputCollector(F);
+
+return Run(oData, pCore, oOutputCollector, oLogger);
+}
+
+//
+// Output to specified data collector
+//
+UINT_32 SimpleVM::Run(CDT & oData, const VMMemoryCore * pCore, OutputCollector & oCollector, Logger & oLogger)
+{
+ UINT_32 iIP = 0;
+
+ pSimpleVM -> vm.Init(pCore, &oCollector, &oLogger);
+ pSimpleVM -> vm.Run(pCore, &oCollector, iIP, oData, &oLogger);
+
+return iIP;
+}
+
+//
+// A destructor
+//
+SimpleVM::~SimpleVM() throw()
+{
+ delete pSimpleVM;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Sprintf.cpp b/src/CTPP2Sprintf.cpp
new file mode 100644
index 0000000..eb42202
--- /dev/null
+++ b/src/CTPP2Sprintf.cpp
@@ -0,0 +1,914 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Sprintf.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Sprintf.hpp"
+#include "CTPP2DTOA.hpp"
+#include "CTPP2StringBuffer.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+#define F_LEFT_ALIGN 0x00000001
+#define F_FORCE_SIGN 0x00000002
+#define F_SIGN_SPACE 0x00000004
+#define F_HASH_SIGN 0x00000008
+
+enum eFmtLengths { F_NONE = 0,
+ F_SHORT = 1,
+ F_LONG = 2,
+ F_LONG_LONG = 3};
+
+enum eFmtSpecifier { F_ESCAPED = 0,
+ F_CHAR = 1,
+ F_DECIMAL = 2,
+ F_SCI = 3,
+ F_FLOAT_F = 4,
+ F_FLOAT_G = 5,
+ F_OCTAL = 6,
+ F_HEX = 7,
+ F_STRING = 8,
+ F_POINTER = 9,
+ F_UNSIGNED = 10};
+
+enum eFmtSpecifierCase { FM_UPPER = 0,
+ FM_LOWER = 1};
+
+enum eParserState { C_INITIAL_STATE = 0,
+ C_START_FOUND = 1};
+
+static CCHAR_P szDigitsUc = "0123456789ABCDEFX";
+static CCHAR_P szDigitsLc = "0123456789abcdefx";
+#define C_INT_BUFFER_LEN 128
+
+
+template<typename T>INT_32 DoFormat(T iData,
+ INT_32 iRadix,
+ CCHAR_P szDigits,
+ CHAR_P szBuffer,
+ bool & bIsNegative)
+{
+ // Remove warning!
+ if (iData == 0)
+ {
+ bIsNegative = false;
+ szBuffer[C_INT_BUFFER_LEN - 1] = '0';
+ return 1;
+ }
+ else if (!(iData > 0))
+ {
+ bIsNegative = true;
+ iData *= -1;
+ }
+
+ INT_32 iPos = 0;
+ INT_32 iOffset = C_INT_BUFFER_LEN;
+ while(iData > 0)
+ {
+ --iOffset;
+ ++iPos;
+ INT_32 iDigit = iData % iRadix;
+ iData /= iRadix;
+ szBuffer[iOffset] = szDigits[iDigit];
+ }
+
+return iPos;
+}
+
+//
+// Character
+//
+static void FmtChar(StringBuffer & oBuffer,
+ const CDT & oCurrentArgument,
+ const UINT_32 iFmtFlags,
+ const INT_32 iWidth,
+ CHAR_8 chPadSymbol)
+{
+ const CDT::eValType oValType = oCurrentArgument.GetType();
+ if (oValType == CDT::UNDEF && iWidth > 0)
+ {
+ oBuffer.Append(iWidth, chPadSymbol);
+ return;
+ }
+
+ UCHAR_8 ucTMP = ' ';
+ if (oValType == CDT::INT_VAL || oValType == CDT::REAL_VAL)
+ {
+ ucTMP = (UCHAR_8)oCurrentArgument.GetInt();
+ }
+ else if (oValType == CDT::STRING_VAL)
+ {
+ const STLW::string sTMP = oCurrentArgument.GetString();
+ if (sTMP.empty() && iWidth > 0)
+ {
+ oBuffer.Append(iWidth, chPadSymbol);
+ return;
+ }
+ ucTMP = sTMP[0];
+ }
+ else if (oValType == CDT::POINTER_VAL) { ucTMP = 'P'; }
+ else if (oValType == CDT::ARRAY_VAL) { ucTMP = 'A'; }
+ else if (oValType == CDT::HASH_VAL) { ucTMP = 'H'; }
+
+ if (iFmtFlags & F_LEFT_ALIGN)
+ {
+ oBuffer.Append(1, ucTMP);
+ if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
+ }
+ else
+ {
+ if (iWidth > 1) { oBuffer.Append(iWidth - 1, chPadSymbol); }
+ oBuffer.Append(1, ucTMP);
+ }
+}
+
+//
+// String
+//
+static void FmtString(StringBuffer & oBuffer,
+ const CDT & oCurrentArgument,
+ const UINT_32 iFmtFlags,
+ const INT_32 iWidth,
+ const INT_32 iMaxChars,
+ CHAR_8 chPadSymbol)
+{
+ const STLW::string sTMP = oCurrentArgument.GetString();
+
+ INT_32 iFormatSize = sTMP.size();
+ if (iFormatSize > iMaxChars && iMaxChars > 0) { iFormatSize = iMaxChars; }
+
+ if (iFmtFlags & F_LEFT_ALIGN)
+ {
+ oBuffer.Append(sTMP.data(), iFormatSize);
+ if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); }
+ }
+ else
+ {
+ if (iWidth > iFormatSize) { oBuffer.Append(iWidth - iFormatSize, chPadSymbol); }
+ oBuffer.Append(sTMP.data(), iFormatSize);
+ }
+}
+
+//
+// Integer
+//
+static void FmtInt(StringBuffer & oBuffer,
+ const CDT & oCurrentArgument,
+ const UINT_32 iFmtFlags,
+ const eFmtLengths & oFmtLengths,
+ CCHAR_P szDigits,
+ const eFmtSpecifier & oFmtSpecifier,
+ const INT_32 iRadix,
+ INT_32 iWidth,
+ INT_32 iPrecision,
+ CHAR_8 chPadSymbol)
+{
+ if (iWidth < 0) { iWidth = 0; }
+ if (iPrecision < 0) { iPrecision = 0; }
+
+ CHAR_8 szBuffer[C_INT_BUFFER_LEN + 1];
+ szBuffer[C_INT_BUFFER_LEN] = 0;
+ INT_32 iPos = 0;
+ bool bIsNegative = false;
+ // Signed
+ if (oFmtSpecifier == F_DECIMAL)
+ {
+ switch (oFmtLengths)
+ {
+ case F_NONE:
+ case F_LONG:
+ iPos = DoFormat<INT_32>((INT_32)oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ case F_SHORT:
+ iPos = DoFormat<INT_16>((INT_16)oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ case F_LONG_LONG:
+ iPos = DoFormat<INT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ }
+ }
+ // Unsigned, hex, octal
+ else
+ {
+ switch (oFmtLengths)
+ {
+ case F_NONE:
+ case F_LONG:
+ iPos = DoFormat<UINT_32>((UINT_32)oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ case F_SHORT:
+ iPos = DoFormat<UINT_16>((UINT_16)oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ case F_LONG_LONG:
+ iPos = DoFormat<UINT_64>(oCurrentArgument.GetInt(), iRadix, szDigits, szBuffer, bIsNegative);
+ break;
+ }
+ }
+
+ UINT_32 iBufferPos = C_INT_BUFFER_LEN - iPos;
+ // Left-aligned output
+ if (iFmtFlags & F_LEFT_ALIGN || chPadSymbol == '0')
+ {
+ // Sign
+ if (bIsNegative) { oBuffer.Append(1, '-'); --iWidth; }
+ else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
+ else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }
+
+ // Hash
+ if (iFmtFlags & F_HASH_SIGN)
+ {
+ if (oFmtSpecifier == F_OCTAL)
+ {
+ oBuffer.Append(1, '0');
+ }
+ else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
+ {
+ oBuffer.Append(1, '0');
+ oBuffer.Append(1, szDigits[16]);
+ }
+ }
+
+ // Zeroes, if need
+ if (iPrecision > iPos)
+ {
+ iWidth -= (iPrecision - iPos);
+ oBuffer.Append(iPrecision - iPos, '0');
+ }
+
+ if (chPadSymbol == '0')
+ {
+ // Spaces, if need
+ if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, '0'); }
+ // Value
+ oBuffer.Append(szBuffer + iBufferPos, iPos);
+ }
+ else
+ {
+ // Value
+ oBuffer.Append(szBuffer + iBufferPos, iPos);
+ // Spaces, if need
+ if (iWidth > iPos) { oBuffer.Append(iWidth - iPos, ' '); }
+ }
+ return;
+ }
+
+ // Right-aligned
+ INT_32 iFormattedLength = iPos;
+
+ // Precision
+ if (iPrecision > iPos)
+ {
+ iFormattedLength += (iPrecision - iPos);
+ }
+
+ // Sign?
+ if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }
+
+ // Hash
+ if (iFmtFlags & F_HASH_SIGN)
+ {
+ if (oFmtSpecifier == F_OCTAL) { ++iFormattedLength; }
+ else if (oFmtSpecifier == F_HEX ||
+ oFmtSpecifier == F_POINTER) { iFormattedLength += 2; }
+ }
+
+ // Spaces, if need
+ if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
+
+ // Sign
+ if (bIsNegative) { oBuffer.Append(1, '-'); --iWidth; }
+ else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); --iWidth; }
+ else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); --iWidth; }
+
+ // Hash
+ if (iFmtFlags & F_HASH_SIGN)
+ {
+ if (oFmtSpecifier == F_OCTAL)
+ {
+ oBuffer.Append(1, '0');
+ }
+ else if (oFmtSpecifier == F_HEX || oFmtSpecifier == F_POINTER)
+ {
+ oBuffer.Append(1, '0');
+ oBuffer.Append(1, szDigits[16]);
+ }
+ }
+
+ if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); }
+ // Value
+ oBuffer.Append(szBuffer + iBufferPos, iPos);
+}
+
+//
+// Scientific
+//
+static void FmtSci(StringBuffer & oBuffer,
+ const CDT & oCurrentArgument,
+ const UINT_32 iFmtFlags,
+ const eFmtLengths & oFmtLengths,
+ const CHAR_8 chExponentSymbol,
+ INT_32 iWidth,
+ INT_32 iPrecision,
+ CHAR_8 chPadSymbol)
+{
+ using namespace CTPP;
+
+ /*
+ * eE The double argument is rounded and converted in the style
+ * [-]d.ddde+-dd where there is one digit before the decimal-point
+ * character and the number of digits after it is equal to the pre-
+ * cision; if the precision is missing, it is taken as 6; if the
+ * precision is zero, no decimal-point character appears. An E con-
+ * version uses the letter `E' (rather than `e') to introduce the
+ * exponent. The exponent always contains at least two digits; if
+ * the value is zero, the exponent is 00.
+ */
+
+ if (iPrecision == -1) { iPrecision = 6; }
+ if (iWidth == -1) { iWidth = 6; }
+
+ const INT_32 iMode = 2;
+ INT_32 iExponent = 0;
+ INT_32 iSign = 0;
+ CHAR_P szEnd = NULL;
+
+ Bigint *freelist[Kmax+1];
+ for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; }
+
+ W_FLOAT dData = oCurrentArgument.GetFloat();
+ AllocatedBlock * aBlocks = NULL;
+
+ CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iPrecision, &iExponent, &iSign, &szEnd);
+ bool bIsNegative = iSign < 0;
+ --iExponent;
+
+ // Format Exponent
+ CHAR_8 szExponentBuffer[C_INT_BUFFER_LEN + 1];
+ szExponentBuffer[C_INT_BUFFER_LEN] = 0;
+ bool bExponentIsNegative = false;
+ // Signed
+ INT_32 iExponentPos = DoFormat<INT_32>(iExponent, 10, szDigitsUc, szExponentBuffer, bExponentIsNegative);
+
+ // Atleast 2 digits in exponent
+ if (iExponentPos == 1)
+ {
+ iExponentPos = 2;
+ szExponentBuffer[C_INT_BUFFER_LEN - 2] = '0';
+ }
+
+ ++iExponentPos;
+ // Add exponent sign
+ szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = bExponentIsNegative ? '-' : '+';
+ // Add exponent char
+ ++iExponentPos;
+ szExponentBuffer[C_INT_BUFFER_LEN - iExponentPos] = chExponentSymbol;
+
+ INT_32 iPos = szEnd - szBuffer;
+
+ // Data length
+ INT_32 iFormattedLength = iExponentPos + 1;
+ //;// = iPos + iExponentPos + 1;
+ // Precision
+ if (iPrecision > iPos)
+ {
+ //iFormattedLength += (iPrecision - iPos);
+ iFormattedLength += iPrecision;
+ }
+ else
+ {
+ iPos = iPrecision;
+ iFormattedLength += iPos;
+ }
+
+ // Sign?
+ if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }
+
+ // Right-aligned
+ if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN)
+ {
+ // Spaces, if need
+ if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
+ }
+
+ // Sign
+ if (bIsNegative) { oBuffer.Append(1, '-'); }
+ else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); }
+ else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); }
+
+ // Value
+ oBuffer.Append(szBuffer, 1);
+ oBuffer.Append(1, '.');
+ oBuffer.Append(szBuffer + 1, iPos - 1);
+
+ // Free memory
+ freedtoa(&aBlocks);
+
+ // Zeroes, if need
+ if (iPrecision > iPos) { oBuffer.Append(iPrecision - iPos, '0'); }
+ // Exponent
+ oBuffer.Append(szExponentBuffer + C_INT_BUFFER_LEN - iExponentPos, iExponentPos);
+
+ // Left-aligned
+ if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN)
+ {
+ // Spaces, if need
+ if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
+ }
+}
+
+//
+// Floating point
+//
+static void FmtFloat(StringBuffer & oBuffer,
+ const CDT & oCurrentArgument,
+ const UINT_32 iFmtFlags,
+ const eFmtLengths & oFmtLengths,
+ const CHAR_8 chExponentSymbol,
+ const eFmtSpecifier & oFmtSpecifier,
+ INT_32 iWidth,
+ INT_32 iPrecision,
+ CHAR_8 chPadSymbol)
+{
+ using namespace CTPP;
+
+ /*
+ * fF The double argument is rounded and converted to decimal notation
+ * in the style [-]ddd.ddd, where the number of digits after the
+ * decimal-point character is equal to the precision specification.
+ * If the precision is missing, it is taken as 6; if the precision
+ * is explicitly zero, no decimal-point character appears. If a
+ * decimal point appears, at least one digit appears before it.
+ *
+ * gG The double argument is converted in style f or e (or F or E for G
+ * conversions). The precision specifies the number of significant
+ * digits. If the precision is missing, 6 digits are given; if the
+ * precision is zero, it is treated as 1. Style e is used if the
+ * exponent from its conversion is less than -4 or greater than or
+ * equal to the precision. Trailing zeros are removed from the
+ * fractional part of the result; a decimal point appears only if it
+ * is followed by at least one digit.
+ */
+// if (iWidth == -1) { iWidth = 6; }
+
+ INT_32 iMode;
+ INT_32 iExponent = 0;
+ INT_32 iSign = 0;
+ CHAR_P szEnd = NULL;
+ INT_32 iFormatPrecision;
+ if (oFmtSpecifier == F_FLOAT_F)
+ {
+ iMode = 3;
+ if (iPrecision == -1) { iPrecision = 6; }
+
+ iFormatPrecision = iPrecision;
+ }
+ // Only one decision left
+ else /* if (oFmtSpecifier == F_FLOAT_G) */
+ {
+ iMode = 2;
+ if (iPrecision == -1) { iPrecision = 6; }
+ else if (iPrecision == 0) { iPrecision = 1; }
+
+ iFormatPrecision = iPrecision + 1;
+ }
+
+ Bigint *freelist[Kmax+1];
+ for (UINT_32 iPos = 0; iPos <= Kmax; ++iPos) { freelist[iPos] = NULL; }
+
+ W_FLOAT dData = oCurrentArgument.GetFloat();
+ AllocatedBlock * aBlocks = NULL;
+ CHAR_P szBuffer = ctpp_dtoa(&aBlocks, freelist, dData, iMode, iFormatPrecision, &iExponent, &iSign, &szEnd);
+ bool bIsNegative = iSign > 0;
+ --iExponent;
+
+ INT_32 iPos = szEnd - szBuffer;
+ INT_32 iZeroAdd = (iPos <= iExponent ) ? iExponent - iPos + 1 : 0;
+
+ // Data length
+ INT_32 iFormattedLength;
+ if (oFmtSpecifier == F_FLOAT_F)
+ {
+ if (iExponent < 0)
+ {
+ iFormattedLength = iPrecision + 2;
+ }
+ else
+ {
+ iFormattedLength = iPrecision + iExponent + 2;
+ }
+
+ }
+ else /* if (oFmtSpecifier == F_FLOAT_G) */
+ {
+ /*
+ * Style e is used if the
+ * exponent from its conversion is less than -4 or greater than or
+ * equal to the precision.
+ */
+ if (iExponent < -4 || iExponent >= iPrecision)
+ {
+ // Free memory
+ freedtoa(&aBlocks);
+
+ if (iWidth == -1) { iWidth = 6; }
+ FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, chExponentSymbol, iWidth, iPrecision, chPadSymbol);
+ return;
+ }
+
+ if (iPos > iPrecision) { iPos = iPrecision; }
+ else { iPrecision = iPos; }
+
+ iFormattedLength = iPrecision + 1;
+ if (iExponent < 0) { iFormattedLength -= iExponent; }
+ }
+
+ // Sign?
+ if (bIsNegative || iFmtFlags & (F_FORCE_SIGN | F_SIGN_SPACE)) { ++iFormattedLength; }
+
+ // Right-aligned
+ if ((iFmtFlags & F_LEFT_ALIGN) != F_LEFT_ALIGN)
+ {
+ // Spaces, if need
+ if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
+ }
+
+ // Sign
+ if (bIsNegative) { oBuffer.Append(1, '-'); }
+ else if (iFmtFlags & F_FORCE_SIGN) { oBuffer.Append(1, '+'); }
+ else if (iFmtFlags & F_SIGN_SPACE) { oBuffer.Append(1, ' '); }
+
+ if (oFmtSpecifier == F_FLOAT_F)
+ {
+ // Value
+ if (iExponent < 0)
+ {
+ const INT_32 iChars = iPrecision + iExponent + 1;
+
+ oBuffer.Append(1, '0');
+ oBuffer.Append(1, '.');
+ oBuffer.Append(-iExponent - 1, '0');
+
+ if (iChars > iPos)
+ {
+ oBuffer.Append(szBuffer, iPos);
+ oBuffer.Append(iChars - iPos, '0');
+ }
+ else
+ {
+ oBuffer.Append(szBuffer, iChars);
+ }
+ }
+ else
+ {
+ // Value
+ if(iZeroAdd > 0)
+ {
+ oBuffer.Append(szBuffer, iPos);
+ oBuffer.Append(iZeroAdd, '0');
+ }
+ else
+ {
+ oBuffer.Append(szBuffer, iExponent + 1);
+ }
+
+ if (iPrecision > 0)
+ {
+ oBuffer.Append(1, '.');
+ if(iZeroAdd < 1)
+ {
+ iPos -= iExponent;
+ oBuffer.Append(szBuffer + iExponent + 1, iPos - 1);
+ if (iPrecision + 1 > iPos )
+ {
+ oBuffer.Append(iPrecision - iPos + 1, '0');
+ }
+ }
+ else
+ {
+ oBuffer.Append(iPrecision, '0');
+ }
+
+ }
+ }
+ }
+ else /* if (oFmtSpecifier == F_FLOAT_G) */
+ {
+ // Value
+ if (iExponent < 0)
+ {
+ const INT_32 iChars = (iPrecision < iPos) ? iPrecision : iPos;
+
+ oBuffer.Append(1, '0');
+ oBuffer.Append(1, '.');
+ oBuffer.Append(- iExponent - 1, '0');
+ oBuffer.Append(szBuffer, iChars);
+ }
+ else
+ {
+ if(iZeroAdd > 0)
+ {
+ oBuffer.Append(szBuffer, iPos);
+ oBuffer.Append(iZeroAdd, '0');
+ }
+ else
+ {
+ oBuffer.Append(szBuffer, iExponent + 1);
+ }
+ if (iPos > iExponent + 1)
+ {
+ oBuffer.Append(1, '.');
+ oBuffer.Append(szBuffer + iExponent + 1, iPrecision - iExponent - 1);
+ }
+ }
+ }
+
+ // Free memory
+ freedtoa(&aBlocks);
+
+ // Left-aligned
+ if ((iFmtFlags & F_LEFT_ALIGN) == F_LEFT_ALIGN)
+ {
+ // Spaces, if need
+ if (iWidth > iFormattedLength) { oBuffer.Append(iWidth - iFormattedLength, ' '); }
+ }
+}
+
+//
+//
+//
+INT_32 FormatString(const STLW::string & sFormatString, STLW::string & sResult, const CDT & oArgs)
+{
+ using namespace CTPP;
+ StringBuffer oBuffer(sResult);
+
+ CCHAR_P sPos = sFormatString.data();
+ CCHAR_P sEnd = sFormatString.data() + sFormatString.size();
+ CCHAR_P sEndSave = sPos;
+
+ UINT_32 iPos = 0;
+ for(;;)
+ {
+ INT_32 iWidth = -1;
+ INT_32 iPrecision = -1;
+ CHAR_8 chPadSymbol = ' ';
+ UINT_32 iFmtFlags = 0;
+ eFmtLengths oFmtLengths = F_NONE;
+ eParserState oParserState = C_INITIAL_STATE;
+ // Find "%" at start of token
+ while(sPos != sEnd)
+ {
+ if (*sPos == '%')
+ {
+ oParserState = C_START_FOUND;
+ break;
+ }
+ ++sPos;
+ }
+ oBuffer.Append(sEndSave, sPos);
+
+ if (oParserState == C_START_FOUND)
+ {
+ ++sPos;
+ // Check end of string
+ if (sPos == sEnd) { return -1; }
+
+ bool bEndCycle = false;
+ while (!bEndCycle)
+ {
+ // Flags
+ switch(*sPos)
+ {
+ // '-' Left-justify within the given field width; Right justification is the default (see width sub-specifier).
+ case '-':
+ iFmtFlags |= F_LEFT_ALIGN;
+ ++sPos;
+ break;
+
+ // '+' Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers.
+ // By default, only negative numbers are preceded with a - sign.
+ case '+':
+ iFmtFlags |= F_FORCE_SIGN;
+ iFmtFlags &= ~F_SIGN_SPACE;
+ ++sPos;
+ break;
+
+ // ' ' (space) If no sign is going to be written, a blank space is inserted before the value.
+ case ' ':
+ iFmtFlags |= F_SIGN_SPACE;
+ iFmtFlags &= ~F_FORCE_SIGN;
+ ++sPos;
+ break;
+
+ // '#' Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero.
+ // Used with e, E and f, it forces the written output to contain a decimal point even if no digits would follow.
+ // By default, if no digits follow, no decimal point is written.
+ // Used with g or G the result is the same as with e or E but trailing zeros are not removed.
+ case '#':
+ iFmtFlags |= F_HASH_SIGN;
+ ++sPos;
+ break;
+
+ // '0' Left-pads the number with zeroes (0) instead of spaces, where padding is specified (see width sub-specifier).
+ case '0':
+ chPadSymbol = '0';
+ ++sPos;
+ break;
+
+ default:
+ bEndCycle = true;
+ break;
+ }
+
+ // Check end of string
+ if (sPos == sEnd) { return -1; }
+ }
+
+ /* Width
+ * number Minimum number of characters to be printed. If the value to be printed is shorter than this number,
+ * the result is padded with blank spaces. The value is not truncated even if the result is larger.
+ */
+ if (*sPos > '0' && *sPos <= '9')
+ {
+ iWidth = 0;
+ while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9'))
+ {
+ iWidth = iWidth * 10 + *sPos - '0';
+ ++sPos;
+ }
+ }
+ /*
+ * '*' The width is not specified in the format string, but as an additional integer value argument
+ * preceding the argument that has to be formatted.
+ */
+ else if (*sPos == '*')
+ {
+ iWidth = (INT_32)oArgs.GetCDT(iPos).GetInt();
+ ++iPos;
+ ++sPos;
+ }
+
+ // Check end of string
+ if (sPos == sEnd) { return -1; }
+
+ // .precision
+ if (*sPos == '.')
+ {
+ ++sPos;
+ if (sPos == sEnd) { return -1; }
+
+ iPrecision = 0;
+ if (*sPos >= '0' && *sPos <= '9')
+ {
+ while (sPos != sEnd && (*sPos >= '0' && *sPos <= '9'))
+ {
+ iPrecision = iPrecision * 10 + *sPos - '0';
+ ++sPos;
+ }
+ }
+ else if (*sPos == '*')
+ {
+ iPrecision = (INT_32)oArgs.GetCDT(iPos).GetInt();
+ ++iPos;
+ ++sPos;
+ }
+ }
+
+ // length
+ switch(*sPos)
+ {
+ // h The argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x and X).
+ case 'h':
+ oFmtLengths = F_SHORT;
+ ++sPos;
+ break;
+ // l The argument is interpreted as a long int or unsigned long int for integer specifiers (i, d, o, u, x and X), and as a wide character or wide character string for specifiers c and s.
+ case 'l':
+ // L The argument is interpreted as a long double (only applies to floating point specifiers: e, E, f, g and G).
+ case 'L':
+ {
+ oFmtLengths = F_LONG;
+ ++sPos;
+ if (sPos == sEnd) { return -1; }
+ if (*sPos == 'l' || *sPos == 'L')
+ {
+ oFmtLengths = F_LONG_LONG;
+ ++sPos;
+ }
+ }
+ break;
+ }
+
+ // Check end of string
+ if (sPos == sEnd) { return -1; }
+
+ // Specifiers
+ // A % followed by another % character will write % to the string.
+ if (*sPos == '%') { oBuffer.Append(sPos, 1); }
+ else
+ {
+ const CDT oCurrentArgument = oArgs.GetCDT(iPos);
+ ++iPos;
+
+ switch(*sPos)
+ {
+ // Character 'a'
+ case 'c':
+ FmtChar(oBuffer, oCurrentArgument, iFmtFlags, iWidth, chPadSymbol);
+ break;
+ // 'd' or 'i' Signed decimal integer '392'
+ case 'd':
+ case 'i':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_DECIMAL, 10, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Scientific notation (mantise/exponent) using e character '3.9265e+2'
+ case 'e':
+ FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', iWidth, iPrecision, chPadSymbol);
+ break;
+ // Scientific notation (mantise/exponent) using E character '3.9265E+2'
+ case 'E':
+ FmtSci(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', iWidth, iPrecision, chPadSymbol);
+ break;
+ // Decimal floating point '392.65'
+ case 'f':
+ FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_F, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Use the shorter of %e or %f '392.65'
+ case 'g':
+ FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'e', F_FLOAT_G, iWidth, iPrecision, chPadSymbol);
+ break;
+ case 'F':
+ FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_F, iWidth, iPrecision, chPadSymbol);
+ break;
+ case 'G':
+ FmtFloat(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, 'E', F_FLOAT_G, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Signed octal '610'
+ case 'o':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_OCTAL, 8, iWidth, iPrecision, chPadSymbol);
+ break;
+ // String of characters 'sample'
+ case 's':
+ FmtString(oBuffer, oCurrentArgument, iFmtFlags, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Unsigned decimal integer '7235'
+ case 'u':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_UNSIGNED, 10, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Unsigned hexadecimal integer '7fa'
+ case 'x':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_HEX, 16, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Unsigned hexadecimal integer (capital letters) 7FA
+ case 'X':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsUc, F_HEX, 16, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Pointer address 1a2b3c4e
+ case 'p':
+ FmtInt(oBuffer, oCurrentArgument, iFmtFlags, oFmtLengths, szDigitsLc, F_POINTER, 16, iWidth, iPrecision, chPadSymbol);
+ break;
+ // Invalid format; return error code
+ default:
+ return -1;
+ }
+ ++sPos;
+ }
+
+ sEndSave = sPos;
+ }
+
+ if (sPos == sEnd) { break; }
+ }
+ oBuffer.Flush();
+
+return 0;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2StaticData.cpp b/src/CTPP2StaticData.cpp
new file mode 100644
index 0000000..ccbfba5
--- /dev/null
+++ b/src/CTPP2StaticData.cpp
@@ -0,0 +1,201 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StaticData.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2StaticData.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "CTPP2BitIndex.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+ReducedStaticData::ReducedStaticData(const StaticDataVar * aIData,
+ const UINT_32 iIUsedDataSize): aData(aIData),
+ iUsedDataSize(iIUsedDataSize)
+{
+ ;;
+}
+
+//
+// Get integer value by ID
+//
+INT_64 ReducedStaticData::GetInt(const UINT_32 iDataId) const
+{
+ if (iDataId < iUsedDataSize) { return aData[iDataId].i_data; }
+
+return 0;
+}
+
+//
+// Get floating point value by ID
+//
+W_FLOAT ReducedStaticData::GetFloat(const UINT_32 iDataId) const
+{
+ if (iDataId < iUsedDataSize) { return aData[iDataId].d_data; }
+
+return 0.0;
+}
+
+//
+// A destructor
+//
+ReducedStaticData::~ReducedStaticData() throw() { ;; }
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class StaticData
+//
+
+//
+// Constructor
+//
+StaticData::StaticData(const UINT_32 iIMaxDataSize): iMaxDataSize(iIMaxDataSize),
+ iUsedDataSize(0),
+ aData(NULL)
+{
+ if (iMaxDataSize != 0)
+ {
+ aData = (StaticDataVar *)malloc(iMaxDataSize * sizeof(StaticDataVar));
+ oBitIndex = new BitIndex(iMaxDataSize);
+ }
+ else
+ {
+ oBitIndex = new BitIndex(32);
+ }
+
+}
+
+//
+// Constructor
+//
+StaticData::StaticData(const StaticDataVar * aIData,
+ const UINT_32 iIMaxDataSize): iMaxDataSize(iIMaxDataSize),
+ iUsedDataSize(iMaxDataSize),
+ aData(NULL)
+{
+ aData = (StaticDataVar *)malloc(iMaxDataSize * sizeof(StaticDataVar));
+ memcpy(aData, aIData, iMaxDataSize * sizeof(StaticDataVar));
+}
+
+//
+// Store data
+//
+UINT_32 StaticData::StoreInt(const UINT_64 iData)
+{
+ if (iUsedDataSize == iMaxDataSize)
+ {
+ iMaxDataSize = iMaxDataSize * 2 + 1;
+ StaticDataVar * aTMP = (StaticDataVar *)malloc(iMaxDataSize * sizeof(StaticDataVar));
+ if (aData != NULL)
+ {
+ memcpy(aTMP, aData, iUsedDataSize * sizeof(StaticDataVar));
+ free(aData);
+ }
+ aData = aTMP;
+ }
+
+ // Store information about value type
+ oBitIndex -> SetBit(iUsedDataSize, 0);
+
+ // Store value
+ aData[iUsedDataSize].i_data = iData;
+
+return iUsedDataSize++;
+}
+
+//
+// Store data
+//
+UINT_32 StaticData::StoreFloat(const W_FLOAT dData)
+{
+ if (iUsedDataSize == iMaxDataSize)
+ {
+ iMaxDataSize = iMaxDataSize * 2 + 1;
+ StaticDataVar * aTMP = (StaticDataVar *)malloc(iMaxDataSize * sizeof(StaticDataVar));
+ if (aData != NULL)
+ {
+ memcpy(aTMP, aData, iUsedDataSize * sizeof(StaticDataVar));
+ free(aData);
+ }
+ aData = aTMP;
+ }
+
+ // Store information about value type
+ oBitIndex -> SetBit(iUsedDataSize, 1);
+
+ // Store value
+ aData[iUsedDataSize].d_data = dData;
+
+return iUsedDataSize++;
+}
+
+//
+// Get integer value by ID
+//
+INT_64 StaticData::GetInt(const UINT_32 iDataId) const
+{
+ if (iDataId < iUsedDataSize) { return aData[iDataId].i_data; }
+
+return 0;
+}
+
+//
+// Get floating point value by ID
+//
+W_FLOAT StaticData::GetFloat(const UINT_32 iDataId) const
+{
+ if (iDataId < iUsedDataSize) { return aData[iDataId].d_data; }
+
+return 0.0;
+}
+
+//
+// Get bit index
+//
+const BitIndex * StaticData::GetBitIndex() const { return oBitIndex; }
+
+//
+// A destructor
+//
+StaticData::~StaticData() throw()
+{
+ free(aData);
+ delete oBitIndex;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2StaticText.cpp b/src/CTPP2StaticText.cpp
new file mode 100644
index 0000000..d44587e
--- /dev/null
+++ b/src/CTPP2StaticText.cpp
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StaticText.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2StaticText.hpp"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+ReducedStaticText::ReducedStaticText(CCHAR_P sIData,
+ const UINT_32 iIUsedDataOffsetsSize,
+ const TextDataIndex * aIDataOffsets): sData(sIData),
+ iUsedDataOffsetsSize(iIUsedDataOffsetsSize),
+ aDataOffsets(aIDataOffsets)
+{
+ ;;
+}
+
+//
+// GetData by ID
+//
+CCHAR_P ReducedStaticText::GetData(const UINT_32 iDataId,
+ UINT_32 & iDataSize) const
+{
+ if (iDataId >= iUsedDataOffsetsSize) { return NULL; }
+
+ iDataSize = aDataOffsets[iDataId].length;
+
+return &sData[aDataOffsets[iDataId].offset];
+}
+
+//
+// Get number of stored records
+//
+UINT_32 ReducedStaticText::GetRecordsNum() const { return iUsedDataOffsetsSize; }
+
+//
+// A destructor
+//
+ReducedStaticText::~ReducedStaticText() throw() { ;; }
+
+// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class StaticText
+//
+
+//
+// Constructor
+//
+StaticText::StaticText(const UINT_32 iIMaxDataSize,
+ const UINT_32 iIMaxDataOffsetsSize): iMaxDataSize(iIMaxDataSize),
+ iMaxDataOffsetsSize(iIMaxDataOffsetsSize),
+ iUsedDataSize(0),
+ iUsedDataOffsetsSize(0),
+ sData(NULL),
+ aDataOffsets(NULL)
+{
+ if (iMaxDataSize != 0) { sData = (CHAR_P)malloc(iMaxDataSize); }
+ if (iMaxDataOffsetsSize != 0) { aDataOffsets = (TextDataIndex *)malloc(iMaxDataOffsetsSize); }
+}
+
+//
+// Constructor
+//
+StaticText::StaticText(CCHAR_P sIData,
+ const TextDataIndex * aIDataOffsets,
+ const UINT_32 iIMaxDataSize,
+ const UINT_32 iIMaxDataOffsetsSize): iMaxDataSize(iIMaxDataSize),
+ iMaxDataOffsetsSize(iIMaxDataOffsetsSize),
+ iUsedDataSize(iIMaxDataSize),
+ iUsedDataOffsetsSize(iIMaxDataOffsetsSize),
+ sData(NULL),
+ aDataOffsets(NULL)
+{
+ if (iMaxDataSize != 0) { sData = (CHAR_P)malloc(iMaxDataSize); }
+ if (iMaxDataOffsetsSize != 0) { aDataOffsets = (TextDataIndex *)malloc(iMaxDataOffsetsSize * sizeof(TextDataIndex)); }
+
+ memcpy(sData, sIData, iMaxDataSize);
+ memcpy(aDataOffsets, aIDataOffsets, iMaxDataOffsetsSize * sizeof(TextDataIndex));
+}
+
+//
+// Store data
+//
+UINT_32 StaticText::StoreData(CCHAR_P sStoreData, const UINT_32 iDataLength)
+{
+ // New data offset
+ UINT_32 iDataOffset = iUsedDataSize + iDataLength;
+
+ // Resize data storage
+ if (iDataOffset >= iMaxDataSize)
+ {
+ iMaxDataSize = iDataOffset * 2 + 1;
+ CHAR_P sTMP = (CHAR_P)malloc(iMaxDataSize);
+
+ if (sData != NULL)
+ {
+ memcpy(sTMP, sData, iUsedDataSize);
+ free(sData);
+ }
+ sData = sTMP;
+ }
+
+ // Copy data
+ memcpy(sData + iUsedDataSize, sStoreData, iDataLength);
+ sData[iDataOffset] = '\0';
+
+ if (iUsedDataOffsetsSize == iMaxDataOffsetsSize)
+ {
+ iMaxDataOffsetsSize = iMaxDataOffsetsSize * 2 + 1;
+ TextDataIndex * aTMP = (TextDataIndex *)malloc(iMaxDataOffsetsSize * sizeof(TextDataIndex));
+ if (aDataOffsets != NULL)
+ {
+ memcpy(aTMP, aDataOffsets, iUsedDataOffsetsSize * sizeof(TextDataIndex));
+ free(aDataOffsets);
+ }
+ aDataOffsets = aTMP;
+ }
+
+ aDataOffsets[iUsedDataOffsetsSize].offset = iUsedDataSize;
+ aDataOffsets[iUsedDataOffsetsSize].length = iDataLength;
+
+ iUsedDataSize = iDataOffset + 1;
+
+return iUsedDataOffsetsSize++;
+}
+
+//
+// GetData by ID
+//
+CCHAR_P StaticText::GetData(const UINT_32 iDataId,
+ UINT_32 & iDataSize) const
+{
+ if (iDataId >= iUsedDataOffsetsSize) { return NULL; }
+
+ iDataSize = aDataOffsets[iDataId].length;
+
+return &sData[aDataOffsets[iDataId].offset];
+}
+
+//
+// Get number of stored records
+//
+UINT_32 StaticText::GetRecordsNum() const { return iUsedDataOffsetsSize; }
+
+//
+// A destructor
+//
+StaticText::~StaticText() throw()
+{
+ free(sData);
+ free(aDataOffsets);
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2StreamOutputCollector.cpp b/src/CTPP2StreamOutputCollector.cpp
new file mode 100644
index 0000000..3dc5318
--- /dev/null
+++ b/src/CTPP2StreamOutputCollector.cpp
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StreamOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2StreamOutputCollector.hpp"
+#include "STLOstream.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+StreamOutputCollector::StreamOutputCollector(STLW::ostream & oIOutputStream): oOutputStream(oIOutputStream)
+{
+ ;;
+}
+
+//
+// A destructor
+//
+StreamOutputCollector::~StreamOutputCollector() throw()
+{
+ ;;
+}
+
+//
+// Collect data
+//
+INT_32 StreamOutputCollector::Collect(const void * vData,
+ const UINT_32 iDataLength)
+{
+ oOutputStream.write((char *)vData, iDataLength);
+
+return 0;
+}
+
+} // namespace CTPP
+// End.
+
diff --git a/src/CTPP2StringBuffer.cpp b/src/CTPP2StringBuffer.cpp
new file mode 100644
index 0000000..5ff3d9d
--- /dev/null
+++ b/src/CTPP2StringBuffer.cpp
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringBuffer.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2StringBuffer.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+StringBuffer::StringBuffer(STLW::string & sIResult): sResult(sIResult), iBufferPos(0)
+{
+ ;;
+}
+
+//
+// Append string
+//
+UINT_32 StringBuffer::Append(CCHAR_P sStart, CCHAR_P sEnd)
+{
+ const UINT_32 iLen = sEnd - sStart;
+
+return Append(sStart, iLen);
+}
+
+//
+// Append string
+//
+UINT_32 StringBuffer::Append(const UINT_32 iLen, const CHAR_8 cChar)
+{
+ if (iLen > (C_STRING_BUFFER_LEN - iBufferPos))
+ {
+ Flush();
+ sResult.append(iLen, cChar);
+ return sResult.size();
+ }
+
+ for (UINT_32 iPos = 0; iPos < iLen; ++iPos)
+ {
+ szBuffer[iBufferPos++] = cChar;
+ }
+
+return sResult.size() + iLen;
+}
+
+//
+// Append string
+//
+UINT_32 StringBuffer::Append(CCHAR_P sStart, const UINT_32 iLen)
+{
+ // Does not need to copy, only fhush buffer
+ if (iLen > (C_STRING_BUFFER_LEN - iBufferPos))
+ {
+ Flush();
+ sResult.append(sStart, iLen);
+ return sResult.size();
+ }
+
+ for (UINT_32 iPos = 0; iPos < iLen; ++iPos)
+ {
+ szBuffer[iBufferPos++] = *sStart++;
+ }
+
+return sResult.size() + iBufferPos;
+}
+
+//
+// Flush buffer
+//
+UINT_32 StringBuffer::Flush()
+{
+ sResult.append(szBuffer, iBufferPos);
+ iBufferPos = 0;
+
+return sResult.size();
+}
+
+//
+// Destructor
+//
+StringBuffer::~StringBuffer() throw()
+{
+ try
+ {
+ Flush();
+ }
+ catch (...) { ;; }
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2StringIconvOutputCollector.cpp b/src/CTPP2StringIconvOutputCollector.cpp
new file mode 100644
index 0000000..9a7bc2b
--- /dev/null
+++ b/src/CTPP2StringIconvOutputCollector.cpp
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringIconvOutputCollector.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2StringIconvOutputCollector.hpp"
+#include "CTPP2Exception.hpp"
+
+#include <errno.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+StringIconvOutputCollector::StringIconvOutputCollector(STLW::string & sIResult,
+ const STLW::string & sISrcEnc,
+ const STLW::string & sIDstEnc,
+ const UINT_32 iIFlags): sResult(sIResult),
+ sSrcEnc(sISrcEnc),
+ sDstEnc(sIDstEnc),
+ iFlags(iIFlags)
+{
+ oIconv = iconv_open(sDstEnc.c_str(), sSrcEnc.c_str());
+ // Check error
+ if (oIconv == (iconv_t)(-1))
+ {
+ throw CTPPCharsetRecodeException(sSrcEnc.c_str(), sDstEnc.c_str());
+ }
+
+#if (_LIBICONV_VERSION >= 0x0108)
+ int iFlag = 1;
+ // Discard illegal characters
+ if (iFlags & C_ICONV_DISCARD_ILSEQ) { iconvctl(oIconv, ICONV_SET_DISCARD_ILSEQ, &iFlag); }
+
+ // nable transliteration in the conver-sion
+ if (iFlags & C_ICONV_TRANSLITERATE) { iconvctl(oIconv, ICONV_SET_TRANSLITERATE, &iFlag); }
+#endif
+}
+
+//
+// A destructor
+//
+StringIconvOutputCollector::~StringIconvOutputCollector() throw()
+{
+ iconv_close(oIconv);
+}
+
+//
+// Collect data
+//
+INT_32 StringIconvOutputCollector::Collect(const void * vData,
+ const UINT_32 iDataLength)
+{
+ // Allocate memory
+ size_t iSrcLength = iDataLength;
+ size_t iDstLength = CTPP_ESCAPE_BUFFER_LEN;
+
+ char aDstData[CTPP_ESCAPE_BUFFER_LEN];
+#if defined(linux) || defined(__APPLE__)
+ char * aSrcData = (char *)vData;
+#else
+ const char * aSrcData = (const char *)vData;
+#endif
+
+ for (;;)
+ {
+ char * aDstTMP = aDstData;
+ size_t iDstLengthTMP = iDstLength;
+ size_t iResult = iconv(oIconv, &aSrcData, &iSrcLength, &aDstTMP, &iDstLengthTMP);
+
+ if (aDstTMP - aDstData > 0) { sResult.append(aDstData, aDstTMP - aDstData); }
+
+ // All data converted?
+ if (iResult != (size_t)-1) { break; }
+ else
+ {
+ if (errno != E2BIG)
+ {
+ ++aSrcData;
+ --iSrcLength;
+ }
+ }
+ }
+
+return 0;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2StringOutputCollector.cpp b/src/CTPP2StringOutputCollector.cpp
new file mode 100644
index 0000000..2711c44
--- /dev/null
+++ b/src/CTPP2StringOutputCollector.cpp
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2StringOutputCollector.hpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2StringOutputCollector.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+StringOutputCollector::StringOutputCollector(STLW::string & sIResult): sResult(sIResult)
+{
+ ;;
+}
+
+//
+// A destructor
+//
+StringOutputCollector::~StringOutputCollector() throw()
+{
+ ;;
+}
+
+//
+// Collect data
+//
+INT_32 StringOutputCollector::Collect(const void * vData,
+ const UINT_32 iDataLength)
+{
+ sResult.append((char *)vData, iDataLength);
+
+return 0;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2SyscallFactory.cpp b/src/CTPP2SyscallFactory.cpp
new file mode 100644
index 0000000..7f2f6e9
--- /dev/null
+++ b/src/CTPP2SyscallFactory.cpp
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2SyscallFactory.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2SyscallFactory.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+SyscallFactory::SyscallFactory(const UINT_32 iIMaxHandlers): iMaxHandlers(iIMaxHandlers), iCurrHandlers(0)
+{
+ aHandlers = new SyscallHandler * [iMaxHandlers];
+ for (UINT_32 iI = 0; iI < iMaxHandlers; ++iI) { aHandlers[iI] = NULL; }
+}
+
+//
+// Get Handler by ID
+//
+SyscallHandler * SyscallFactory::GetHandlerById(const UINT_32 iHandlerId) const
+{
+ if (iHandlerId < iCurrHandlers) { return aHandlers[iHandlerId]; }
+
+return NULL;
+}
+
+//
+// Get Handler by name
+//
+SyscallHandler * SyscallFactory::GetHandlerByName(CCHAR_P szHandlerName) const
+{
+ STLW::map<STLW::string, UINT_32, HandlerRefsSort>::const_iterator itmHandlerRefs = mHandlerRefs.find(szHandlerName);
+
+ if (itmHandlerRefs == mHandlerRefs.end()) { return NULL; }
+
+return aHandlers[itmHandlerRefs -> second];
+}
+
+//
+// Register handler
+//
+INT_32 SyscallFactory::RegisterHandler(SyscallHandler * pHandler)
+{
+ if (iCurrHandlers == iMaxHandlers || pHandler == NULL) { return -1; }
+
+ aHandlers[iCurrHandlers] = pHandler;
+
+ mHandlerRefs.insert(STLW::pair<STLW::string, UINT_32>(pHandler -> GetName(), iCurrHandlers));
+
+return iCurrHandlers++;
+}
+
+//
+// Remove handler from factory
+//
+INT_32 SyscallFactory::RemoveHandler(CCHAR_P szHandlerName)
+{
+ STLW::map<STLW::string, UINT_32, HandlerRefsSort>::iterator itmHandlerRefs = mHandlerRefs.find(szHandlerName);
+
+ if (itmHandlerRefs == mHandlerRefs.end()) { return -1; }
+
+ aHandlers[itmHandlerRefs -> second] = NULL;
+
+ mHandlerRefs.erase(itmHandlerRefs);
+
+return 0;
+}
+//
+// A destructor
+//
+SyscallFactory::~SyscallFactory() throw()
+{
+ delete [] aHandlers;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2Util.cpp b/src/CTPP2Util.cpp
new file mode 100644
index 0000000..451c602
--- /dev/null
+++ b/src/CTPP2Util.cpp
@@ -0,0 +1,1052 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Util.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2Util.hpp"
+#include "CTPP2Exception.hpp"
+
+#include "CDT.hpp"
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+static const UINT_32 aCRC32[] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+
+};
+
+//
+// Calculate crc32 checksum
+//
+UINT_32 crc32(UCCHAR_P sBuffer, const UINT_32 & iSize)
+{
+ UINT_32 iCRC = 0;
+
+ for (UINT_32 iI = 0; iI < iSize; ++iI)
+ {
+ iCRC = aCRC32[(iCRC ^ sBuffer[iI]) & 0xFF] ^ (iCRC >> 8);
+ }
+
+return iCRC;
+}
+
+//
+// Swap bytes for UINT_32 value
+//
+UINT_32 Swap32(const UINT_32 & iValue)
+{
+ return ((iValue << 24) & 0xff000000 ) |
+ ((iValue << 8) & 0x00ff0000 ) |
+ ((iValue >> 8) & 0x0000ff00 ) |
+ ((iValue >> 24) & 0x000000ff );
+}
+
+//
+// Swap bytes for UINT_64 value
+//
+UINT_64 Swap64(const UINT_64 & iValue)
+{
+ union
+ {
+ UINT_64 ul;
+ UINT_32 ui[2];
+ } u;
+
+ UINT_32 * pTMP = (UINT_32*)&iValue;
+
+ u.ui[0] = Swap32(pTMP[1]);
+ u.ui[1] = Swap32(pTMP[0]);
+
+return u.ul;
+}
+
+//
+// Escape value
+//
+STLW::string URLEscape(const STLW::string & sData)
+{
+ static const CHAR_8 * szEscape = "0123456789ABCDEF";
+
+ CHAR_8 sBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ STLW::string sRetVal = "";
+
+ UINT_32 iBufferPointer = 0;
+
+ // Get string to escape
+ STLW::string::const_iterator itsData = sData.begin();
+ while (itsData != sData.end())
+ {
+ UCHAR_8 chTMP = (UCHAR_8)(*itsData);
+
+ if ((chTMP >= 'a' && chTMP <= 'z') ||
+ (chTMP >= 'A' && chTMP <= 'Z') ||
+ (chTMP >= '0' && chTMP <= '9') ||
+ chTMP == '/' || chTMP == '.' || chTMP == '-' || chTMP == '_')
+ {
+ sBuffer[iBufferPointer++] = *itsData;
+ }
+ else if (chTMP == ' ') { sBuffer[iBufferPointer++] = '+'; }
+ else
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 3))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ sBuffer[iBufferPointer++] = '%';
+ sBuffer[iBufferPointer++] = szEscape[((chTMP >> 4) & 0x0F)];
+ sBuffer[iBufferPointer++] = szEscape[(chTMP & 0x0F)];
+ }
+
+ if (iBufferPointer == CTPP_ESCAPE_BUFFER_LEN)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ ++itsData;
+ }
+
+ if (iBufferPointer != 0) { sRetVal.append(sBuffer, iBufferPointer); }
+
+return sRetVal;
+}
+
+//
+// Escape value
+//
+STLW::string URIEscape(const STLW::string & sData)
+{
+ static const CHAR_8 * szEscape = "0123456789ABCDEF";
+
+ CHAR_8 sBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ STLW::string sRetVal = "";
+
+ UINT_32 iBufferPointer = 0;
+
+ // Get string to escape
+ STLW::string::const_iterator itsData = sData.begin();
+ while (itsData != sData.end())
+ {
+ UCHAR_8 chTMP = (UCHAR_8)(*itsData);
+
+ if ((chTMP >= 'a' && chTMP <= 'z') ||
+ (chTMP >= 'A' && chTMP <= 'Z') ||
+ (chTMP >= '0' && chTMP <= '9') ||
+ chTMP == '/' || chTMP == '.' || chTMP == '-' || chTMP == '_')
+ {
+ sBuffer[iBufferPointer++] = *itsData;
+ }
+ else
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 3))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ sBuffer[iBufferPointer++] = '%';
+ sBuffer[iBufferPointer++] = szEscape[((chTMP >> 4) & 0x0F)];
+ sBuffer[iBufferPointer++] = szEscape[(chTMP & 0x0F)];
+ }
+
+ if (iBufferPointer == CTPP_ESCAPE_BUFFER_LEN)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ ++itsData;
+ }
+
+ if (iBufferPointer != 0) { sRetVal.append(sBuffer, iBufferPointer); }
+
+return sRetVal;
+}
+
+//
+// Escape value
+//
+STLW::string HTMLEscape(const STLW::string & sData)
+{
+ CHAR_8 sBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ STLW::string sRetVal = "";
+
+ UINT_32 iBufferPointer = 0;
+
+ // Get string to escape
+ STLW::string::const_iterator itsData = sData.begin();
+ while (itsData != sData.end())
+ {
+ UCHAR_8 chTMP = (UCHAR_8)(*itsData);
+
+ if (chTMP == '"')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'q';
+ sBuffer[iBufferPointer++] = 'u';
+ sBuffer[iBufferPointer++] = 'o';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '\'')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 5))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = '#';
+ sBuffer[iBufferPointer++] = '3';
+ sBuffer[iBufferPointer++] = '9';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '<')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 4))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'l';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '>')
+ {
+ if (iBufferPointer >= CTPP_ESCAPE_BUFFER_LEN - 4)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'g';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '&')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 5))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'a';
+ sBuffer[iBufferPointer++] = 'm';
+ sBuffer[iBufferPointer++] = 'p';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else
+ {
+ sBuffer[iBufferPointer++] = *itsData;
+ }
+
+ if (iBufferPointer == CTPP_ESCAPE_BUFFER_LEN)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ ++itsData;
+ }
+
+ if (iBufferPointer != 0) { sRetVal.append(sBuffer, iBufferPointer); }
+
+return sRetVal;
+}
+
+//
+// Escape value
+//
+STLW::string XMLEscape(const STLW::string & sData)
+{
+ CHAR_8 sBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ STLW::string sRetVal = "";
+
+ UINT_32 iBufferPointer = 0;
+
+ // Get string to escape
+ STLW::string::const_iterator itsData = sData.begin();
+ while (itsData != sData.end())
+ {
+ UCHAR_8 chTMP = (UCHAR_8)(*itsData);
+
+ if (chTMP == '"')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'q';
+ sBuffer[iBufferPointer++] = 'u';
+ sBuffer[iBufferPointer++] = 'o';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '\'')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'a';
+ sBuffer[iBufferPointer++] = 'p';
+ sBuffer[iBufferPointer++] = 'o';
+ sBuffer[iBufferPointer++] = 's';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '<')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 4))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'l';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '>')
+ {
+ if (iBufferPointer >= CTPP_ESCAPE_BUFFER_LEN - 4)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'g';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '&')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 5))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'a';
+ sBuffer[iBufferPointer++] = 'm';
+ sBuffer[iBufferPointer++] = 'p';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else
+ {
+ sBuffer[iBufferPointer++] = *itsData;
+ }
+
+ if (iBufferPointer == CTPP_ESCAPE_BUFFER_LEN)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ ++itsData;
+ }
+
+ if (iBufferPointer != 0) { sRetVal.append(sBuffer, iBufferPointer); }
+
+return sRetVal;
+}
+
+//
+// Escape value
+//
+STLW::string WMLEscape(const STLW::string & sData)
+{
+ CHAR_8 sBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ STLW::string sRetVal = "";
+
+ UINT_32 iBufferPointer = 0;
+
+ // Get string to escape
+ STLW::string::const_iterator itsData = sData.begin();
+ while (itsData != sData.end())
+ {
+ UCHAR_8 chTMP = (UCHAR_8)(*itsData);
+
+ if (chTMP < ' ')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ snprintf(sBuffer + iBufferPointer, 6, "\\u%04d", chTMP);
+ }
+ else if (chTMP == '"')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'q';
+ sBuffer[iBufferPointer++] = 'u';
+ sBuffer[iBufferPointer++] = 'o';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '\'')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 6))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'a';
+ sBuffer[iBufferPointer++] = 'p';
+ sBuffer[iBufferPointer++] = 'o';
+ sBuffer[iBufferPointer++] = 's';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '<')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 4))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'l';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '>')
+ {
+ if (iBufferPointer >= CTPP_ESCAPE_BUFFER_LEN - 4)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'g';
+ sBuffer[iBufferPointer++] = 't';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '&')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 5))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '&';
+ sBuffer[iBufferPointer++] = 'a';
+ sBuffer[iBufferPointer++] = 'm';
+ sBuffer[iBufferPointer++] = 'p';
+ sBuffer[iBufferPointer++] = ';';
+ }
+ else if (chTMP == '$')
+ {
+ if (iBufferPointer >= (CTPP_ESCAPE_BUFFER_LEN - 4))
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+
+ sBuffer[iBufferPointer++] = '$';
+ sBuffer[iBufferPointer++] = '$';
+ }
+ else
+ {
+ sBuffer[iBufferPointer++] = *itsData;
+ }
+
+ if (iBufferPointer == CTPP_ESCAPE_BUFFER_LEN)
+ {
+ sRetVal.append(sBuffer, iBufferPointer);
+ iBufferPointer = 0;
+ }
+ ++itsData;
+ }
+
+ if (iBufferPointer != 0) { sRetVal.append(sBuffer, iBufferPointer); }
+
+return sRetVal;
+}
+
+
+//
+// Escape string, if need
+//
+STLW::string EscapeJSONString(const STLW::string & sSource, const bool & bECMAConventions, const bool & bHTMLSafe)
+{
+ DumpBuffer oBuff;
+ DumpJSONString(oBuff, sSource, bECMAConventions, bHTMLSafe);
+ return STLW::string(oBuff.Data(), oBuff.Size());
+}
+
+
+//
+// Escape and dump string to buffer
+//
+DumpBuffer & DumpJSONString(DumpBuffer & sResult, const STLW::string & sSource, const bool & bECMAConventions, const bool & bHTMLSafe)
+{
+ INT_32 iPos = 0;
+ INT_32 iSize = sSource.size();
+ INT_32 iOffset = 0;
+
+ while (iSize--)
+ {
+ const UCHAR_8 uCH = sSource[iPos];
+ const CHAR_8 * sEscaped = NULL;
+ bool bFound = false;
+
+ switch (uCH)
+ {
+ case '"':
+ sEscaped = "\\\"";
+ bFound = true;
+ break;
+ case '\\':
+ sEscaped = "\\\\";
+ bFound = true;
+ break;
+ case '/':
+ sEscaped = "\\/";
+ bFound = true;
+ break;
+ case '\b':
+ sEscaped = "\\b";
+ bFound = true;
+ break;
+ case '\f':
+ sEscaped = "\\f";
+ bFound = true;
+ break;
+ case '\n':
+ sEscaped = "\\n";
+ bFound = true;
+ break;
+ case '\r':
+ sEscaped = "\\r";
+ bFound = true;
+ break;
+ case '\t':
+ sEscaped = "\\t";
+ bFound = true;
+ break;
+ case '\'':
+ sEscaped = "\\'";
+ if (bECMAConventions) { bFound = true; }
+ break;
+ case '\v':
+ sEscaped = "\\v";
+ if (bECMAConventions) { bFound = true; }
+ break;
+ case '\0':
+ sEscaped = "\\0";
+ if (bECMAConventions) { bFound = true; }
+ break;
+ default:
+ break;
+ }
+
+ if (bFound)
+ {
+ if (iPos - iOffset > 0) { sResult.Write(sSource.c_str() + iOffset, iPos - iOffset); }
+ sResult.Write(sEscaped, strlen(sEscaped));
+ iOffset = iPos + 1;
+ }
+ else if (uCH < ' ' || (bHTMLSafe && (uCH == '<' || uCH == '>')))
+ {
+ if (iPos - iOffset > 0) { sResult.Write(sSource.c_str() + iOffset, iPos - iOffset); }
+ CHAR_8 szBuffer[7] = { '\0' };
+ const CHAR_8 *szHexChars = "0123456789abcdef";
+ snprintf(szBuffer, 7, "\\u00%c%c", szHexChars[uCH >> 4], szHexChars[uCH & 0xF]);
+ sResult.Write(szBuffer, 6);
+ iOffset = iPos + 1;
+ }
+ ++iPos;
+ }
+
+ if (iPos - iOffset > 0) { sResult.Write(sSource.c_str() + iOffset, iPos - iOffset); }
+
+return sResult;
+}
+
+//
+// Dump CDT to JSON
+//
+void CDT2JSON(const CTPP::CDT & oCDT, STLW::string & sData)
+{
+ DumpBuffer oBuff;
+ DumpCDT2JSON(oCDT, oBuff);
+ sData.append(oBuff.Data(), oBuff.Size());
+}
+
+DumpBuffer::~DumpBuffer()
+{
+ free(pBuffer);
+}
+
+DumpBuffer::DumpBuffer()
+{
+ pBuffer = 0;
+ iCapacity = 0;
+ pPos = 0;
+}
+
+CCHAR_P DumpBuffer::Data() const { return pBuffer; }
+
+DumpBuffer::StreamSize DumpBuffer::Size() const { return pPos - pBuffer; }
+
+void DumpBuffer::Reserve(DumpBuffer::StreamSize iN)
+{
+ if (iN <= iCapacity) { return; }
+
+ StreamSize iOffset = pPos - pBuffer;
+ CHAR_P pTmp = (CHAR_P) realloc(pBuffer, iN);
+ if(!pTmp) { throw CTPPNoMemoryError(); }
+ pBuffer = pTmp;
+
+ pPos = pBuffer + iOffset;
+ iCapacity = iN;
+}
+
+void DumpBuffer::Write(CCHAR_P pStr, DumpBuffer::StreamSize iN) {
+ if(pPos + iN > pBuffer + iCapacity) {
+ Reserve(2 * (iCapacity + iN));
+ }
+ memcpy(pPos, pStr, iN);
+ pPos += iN;
+}
+
+//
+// Escape and dump string to buffer
+//
+DumpBuffer & DumpCDT2JSON(const CTPP::CDT & oCDT, DumpBuffer & oResult)
+{
+ using namespace CTPP;
+ switch (oCDT.GetType())
+ {
+ case CDT::UNDEF:
+ oResult.Write("null", 4);
+ break;
+
+ case CDT::INT_VAL:
+ case CDT::REAL_VAL:
+ case CDT::POINTER_VAL:
+ case CDT::STRING_INT_VAL:
+ case CDT::STRING_REAL_VAL:
+ {
+ STLW::string tmp = oCDT.GetString();
+ oResult.Write(tmp.data(), tmp.size());
+ }
+ break;
+
+ case CDT::STRING_VAL:
+ oResult.Write("\"", 1);
+ DumpJSONString(oResult, oCDT.GetString(), false);
+ oResult.Write("\"", 1);
+ break;
+
+ case CDT::ARRAY_VAL:
+ {
+ oResult.Write("[", 1);
+ UINT_32 iJ = 0;
+ while (iJ < oCDT.Size())
+ {
+ DumpCDT2JSON(oCDT.GetCDT(iJ), oResult);
+ ++iJ;
+ if (iJ != oCDT.Size()) { oResult.Write(",", 1); }
+ }
+ oResult.Write("]", 1);
+ }
+ break;
+
+ case CDT::HASH_VAL:
+ {
+ oResult.Write("{", 1);
+ CDT::ConstIterator itCDTCArray = oCDT.Begin();
+ while (itCDTCArray != oCDT.End())
+ {
+ oResult.Write("\"", 1);
+ DumpJSONString(oResult, itCDTCArray -> first, false);
+ oResult.Write("\":", 2);
+
+ DumpCDT2JSON(itCDTCArray -> second, oResult);
+
+ ++itCDTCArray;
+ if (itCDTCArray != oCDT.End()) { oResult.Write(",", 1); }
+ }
+ oResult.Write("}", 1);
+ }
+ break;
+ }
+
+return oResult;
+}
+
+//
+// Encode value
+//
+STLW::string Base64Encode(const STLW::string & sData)
+{
+ // RFC 3548 - The Base16, Base32, and Base64 Data Encodings
+ static CHAR_8 aBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ UINT_32 aDst[4];
+
+ // Data
+ UCCHAR_P szData = (UCCHAR_P)sData.c_str();
+ // Data length
+ const UINT_32 iDataLength = sData.size();
+ const UINT_32 iDataLengthFixed = 3 * (iDataLength / 3);
+
+ // Temp buffer
+ CHAR_P szBuffer = new CHAR_8[iDataLength * 4 / 3 + 4];
+ CHAR_P szDst = szBuffer;
+
+ UINT_32 iDstLength = 0;
+ UINT_32 iI = 0;
+ for (; iI < iDataLengthFixed;)
+ {
+ iI += 3;
+
+ aDst[0] = szData[0] >> 2;
+ aDst[1] = ((szData[0] & 0x03) << 4) + (szData[1] >> 4);
+ aDst[2] = ((szData[1] & 0x0f) << 2) + (szData[2] >> 6);
+ aDst[3] = szData[2] & 0x3f;
+
+ *szDst++ = aBase64[ aDst[0] ];
+ *szDst++ = aBase64[ aDst[1] ];
+ *szDst++ = aBase64[ aDst[2] ];
+ *szDst++ = aBase64[ aDst[3] ];
+
+ szData += 3;
+ iDstLength += 4;
+ }
+
+ const UINT_32 iDelta = iDataLength - iDataLengthFixed;
+ if (iDelta != 0)
+ {
+ UINT_32 aSrc[3];
+ aSrc[0] = aSrc[1] = aSrc[2] = 0;
+
+ for(iI = 0; iI < iDelta; ++iI) { aSrc[iI] = *szData++; }
+
+ aDst[0] = aSrc[0] >> 2;
+ aDst[1] = ((aSrc[0] & 0x03) << 4) + (aSrc[1] >> 4);
+ aDst[2] = ((aSrc[1] & 0x0f) << 2) + (aSrc[2] >> 6);
+
+ *szDst++ = aBase64[ aDst[0] ];
+ *szDst++ = aBase64[ aDst[1] ];
+
+ if (iDelta == 1) { *szDst++ = '='; }
+ else { *szDst++ = aBase64[ aDst[2] ]; }
+ *szDst++ = '=';
+
+ iDstLength += 4;
+ }
+
+ // Okay
+ STLW::string sRetVal(szBuffer, iDstLength);
+
+ delete [] szBuffer;
+
+return sRetVal;
+}
+
+static UCHAR_8 aBase64Rev[256] =
+{
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
+ 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
+ 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+//
+// Decode value
+//
+STLW::string Base64Decode(const STLW::string & sData)
+{
+ // Data
+ UCCHAR_P szData = (UCCHAR_P)sData.c_str();
+ // Data length
+ UINT_32 iDataLength = sData.size();
+
+ // Temp buffer
+ UCHAR_P szBuffer = new UCHAR_8[ ( (iDataLength + 3) / 4) * 3];
+ UCHAR_P szDst = szBuffer;
+
+ UINT_32 iDstLength = 0;
+ while (iDataLength > 4)
+ {
+ *szDst++ = (aBase64Rev[ szData[0] ] << 2 | aBase64Rev[ szData[1] ] >> 4);
+ *szDst++ = (aBase64Rev[ szData[1] ] << 4 | aBase64Rev[ szData[2] ] >> 2);
+ *szDst++ = (aBase64Rev[ szData[2] ] << 6 | aBase64Rev[ szData[3] ]);
+ szData += 4;
+ iDataLength -= 4;
+ iDstLength += 3;
+ }
+
+ *szDst++ = (aBase64Rev[ szData[0] ] << 2 | aBase64Rev[ szData[1] ] >> 4);
+ ++iDstLength;
+
+ if (szData[2] != '=') { *szDst++ = (aBase64Rev[ szData[1] ] << 4 | aBase64Rev[ szData[2] ] >> 2); ++iDstLength; }
+
+ if (szData[3] != '=') { *szDst++ = (aBase64Rev[ szData[2] ] << 6 | aBase64Rev[ szData[3] ]); ++iDstLength; }
+
+ // Okay
+ STLW::string sRetVal((CHAR_P)szBuffer, iDstLength);
+
+ delete [] szBuffer;
+
+return sRetVal;
+}
+
+//
+// Length of UTF character
+//
+INT_32 utf_charlen(CCHAR_P szString, CCHAR_P szStringEnd)
+{
+ /*
+ * 0x00000000 0x0000007F 0x xxx xxx
+ * 0x00000080 0x000007FF 110xxxxx 10xxxxxx
+ * 0x00000800 0x0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
+ * 0x00010000 0x001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ */
+
+ // End of string
+ if (szString == szStringEnd) { return -3; }
+
+ // UTF8-1 0xxxxxxx
+ if ((UCCHAR_8(*szString) & 0x80) == 0) { return 1; }
+
+ // UTF8-2 110xxxxx 10xxxxxx
+ if ((UCCHAR_8(*szString) & 0xE0) == 0xC0)
+ {
+ // Check next byte
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ // Ok
+ return 2;
+ }
+
+ // UTF8-3 1110xxxx 10xxxxxx 10xxxxxx
+ if ((UCCHAR_8(*szString) & 0xF0) == 0xE0)
+ {
+ // Check next byte
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ // Ok
+ return 3;
+ }
+
+ // UTF8-4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ if ((UCCHAR_8(*szString) & 0xF8) == 0xF0)
+ {
+ // Check next byte
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ ++szString;
+ if (szString == szStringEnd) { return -3; }
+ if ((UCCHAR_8(*szString) & 0xC0) != 0x80) { return -1; }
+
+ // Ok
+ return 4;
+ }
+
+// This is not an UTF8 character
+return -2;
+}
+
+/*
+ * Convert Unicode character to UTF8
+ */
+INT_32 UnicodeToUTF8(UINT_32 iUCS, UCHAR_P sUTF8)
+{
+ INT_32 iPos = 0;
+ INT_32 iCharLength = 0;
+ UCHAR_8 sUTF8Prefix = 0;
+
+ /* ASCII characters. */
+ if ((iUCS & ~0x0000007F) == 0)
+ {
+ /* Modified UTF-8, special case */
+ if (iUCS == 0)
+ {
+ sUTF8[0] = 0xC0;
+ sUTF8[1] = 0x80;
+ return 2;
+ }
+
+ sUTF8[0] = (char)iUCS;
+ return 1;
+ }
+/*
+ * Does not need here, but let it be
+ if ((iUCS & ~0x0000007F) == 0)
+ {
+ sUTF8Prefix = 0x00; // 11000000b
+ iCharLength = 1;
+ } else
+*/
+
+ if ((iUCS & ~0x000007FF) == 0)
+ {
+ sUTF8Prefix = 0xC0; // 11000000b
+ iCharLength = 2;
+ }
+ else if ((iUCS & ~0x0000FFFF) == 0)
+ {
+ sUTF8Prefix = 0xE0; // 11100000b
+ iCharLength = 3;
+ }
+ else if ((iUCS & ~0x001FFFFF) == 0)
+ {
+ sUTF8Prefix = 0xF0; // 11110000b
+ iCharLength = 4;
+ }
+ else if ((iUCS & ~0x03FFFFFF) == 0)
+ {
+ sUTF8Prefix = 0xF8; // 11111000b
+ iCharLength = 5;
+ }
+ else if ((iUCS & ~0x7FFFFFFF) == 0)
+ {
+ sUTF8Prefix = 0xFC; // 11111100b
+ iCharLength = 6;
+ }
+ /* Incorrect multibyte character */
+ else { return -1; }
+
+ /*
+ * Convert UCS character to UTF8. Split value in 6-bit chunks and
+ * move to UTF8 string
+ */
+ for (iPos = iCharLength - 1; iPos > 0; --iPos)
+ {
+ sUTF8[iPos] = (iUCS & 0x0000003F) | 0x80;
+ iUCS >>= 6;
+ }
+
+ /* UTF8 prefix, special case */
+ sUTF8[0] = (iUCS & 0x000000FF) | sUTF8Prefix;
+
+/* Return size of UTF8 character */
+return iCharLength;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VM.cpp b/src/CTPP2VM.cpp
new file mode 100644
index 0000000..1af6f2c
--- /dev/null
+++ b/src/CTPP2VM.cpp
@@ -0,0 +1,2438 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VM.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VM.hpp"
+
+#include "CTPP2OutputCollector.hpp"
+#include "CTPP2SyscallFactory.hpp"
+#include "CTPP2VMMemoryCore.hpp"
+
+#include "CTPP2VMDebugInfo.hpp"
+#include "CTPP2VMOpcodes.h"
+#include "CTPP2VMException.hpp"
+#include "CTPP2VMStackException.hpp"
+#include "CTPP2VMInstruction.hpp"
+
+#include <string.h>
+
+#ifdef _DEBUG
+#include <stdio.h>
+#endif
+
+/*
+ Foreground colors
+ 30 Black
+ 31 Red
+ 32 Green
+ 33 Yellow
+ 34 Blue
+ 35 Magenta
+ 36 Cyan
+ 37 White
+
+ Background colors
+ 40 Black
+ 41 Red
+ 42 Green
+ 43 Yellow
+ 44 Blue
+ 45 Magenta
+ 46 Cyan
+ 47 White
+*/
+#define BRIGHT 1
+#define RED 31
+#define YELLOW 33
+#define GREEN 32
+#define BLUE 34
+#define BG_BLACK 40
+
+
+#ifndef WIN32 /* Windows console is not so funky */
+#define HL_CODE(x) fprintf(stderr, "%c[%d;%d;%dm", 0x1B, BRIGHT, (x), BG_BLACK)
+#define HL_RST fprintf(stderr, "%c[%dm", 0x1B, 0)
+#else
+ #define HL_CODE(x)
+ #define HL_RST
+#endif
+
+// Aliases for registers
+#define AR oRegs[0]
+#define BR oRegs[1]
+#define CR oRegs[2]
+#define DR oRegs[3]
+#define ER oRegs[4]
+#define FR oRegs[5]
+#define GR oRegs[6]
+#define HR oRegs[7]
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+VM::VM(SyscallFactory * pISyscallFactory,
+ const UINT_32 iIMaxArgStackSize,
+ const UINT_32 iIMaxCodeStackSize,
+ const UINT_32 iIMaxSteps,
+ const UINT_32 iIDebugLevel): pSyscallFactory(pISyscallFactory),
+ iMaxArgStackSize(iIMaxArgStackSize),
+ iMaxCodeStackSize(iIMaxCodeStackSize),
+ iMaxSteps(iIMaxSteps),
+ iDebugLevel(iIDebugLevel),
+ iMaxCalls(0),
+ iMaxUsedCalls(0),
+ aCallTranslationMap(NULL),
+ oVMArgStack(iMaxArgStackSize),
+ oVMCodeStack(iMaxCodeStackSize)
+{
+ ;;
+}
+
+//
+// Initialize virtual machine
+//
+INT_32 VM::Init(const VMMemoryCore * pMemoryCore,
+ OutputCollector * pOutputCollector,
+ Logger * pLogger)
+{
+ // Create syscalls translation map
+ iMaxUsedCalls = pMemoryCore -> syscalls.GetRecordsNum();
+ // Cache
+ if (iMaxUsedCalls >= iMaxCalls)
+ {
+ delete [] aCallTranslationMap;
+ aCallTranslationMap = new SyscallHandler *[iMaxUsedCalls];
+ iMaxCalls = iMaxUsedCalls;
+ }
+
+ // Initialize program
+ for (UINT_32 iCallNum = 0; iCallNum < iMaxUsedCalls; ++iCallNum)
+ {
+ // Ugh
+ UINT_32 iCallNameLength = 0;
+ // NULL-terminated string, iCallNameLength will not used
+ CCHAR_P sCallName = pMemoryCore -> syscalls.GetData(iCallNum, iCallNameLength);
+
+ // Get syscall
+ SyscallHandler * pTMP = pSyscallFactory -> GetHandlerByName(sCallName);
+
+ // If this syscall is not present in factory, throw exception
+ if (pTMP == NULL)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(pMemoryCore -> instructions[0].reserved).GetDescrId(), iDataSize);
+
+ throw InvalidSyscall(sCallName, 0, pMemoryCore -> instructions[0].reserved, szTMP);
+ }
+
+ // All OK
+ aCallTranslationMap[iCallNum] = pTMP;
+
+ // Initialize syscall handler
+ pTMP -> PreExecuteSetup(*pOutputCollector,
+ DR,
+ pMemoryCore -> syscalls,
+ pMemoryCore -> static_data,
+ pMemoryCore -> static_text,
+ *pLogger);
+ }
+
+return 0;
+}
+
+//
+// Run program
+//
+INT_32 VM::Run(const VMMemoryCore * pMemoryCore,
+ OutputCollector * pOutputCollector,
+ UINT_32 & iIP,
+ CDT & oCDT,
+ Logger * pLogger)
+{
+ DR = oCDT;
+ // Get code segment
+ const VMInstruction * aCode = pMemoryCore -> instructions;
+ const UINT_32 iCodeLength = pMemoryCore -> code_size;
+ UINT_32 iExecutedSteps = 0;
+
+ try
+ {
+ while (iIP < iCodeLength)
+ {
+ const UINT_32 iOpCode = aCode[iIP].instruction;
+ const UINT_32 iOpCodeHi = SYSCALL_OPCODE_HI(iOpCode);
+ const UINT_32 iOpCodeLo = SYSCALL_OPCODE_LO(iOpCode);
+#ifdef _DEBUG
+HL_CODE(BLUE);
+fprintf(stderr, "CODE 0x%08X ARG 0x%08X RES 0x%016llX | ", iOpCode, aCode[iIP].argument, (long long)(aCode[iIP].reserved));
+HL_RST;
+#endif
+
+ switch(iOpCodeHi)
+ {
+ // Instructions //////// 0x-1-X----
+ case 0x01:
+ {
+ switch(iOpCodeLo)
+ {
+ // SYSCALL
+ case SYSCALL_OPCODE_LO(SYSCALL):
+ {
+ const UINT_32 iCallNum = (aCode[iIP].argument & 0xFFFF0000) >> 16;
+ const UINT_32 iCallArgNum = (aCode[iIP].argument & 0x0000FFFF);
+#ifdef _DEBUG
+{
+ UINT_32 iCallNameLength = 0;
+ // NULL-terminated string, iCallNameLength not need to use
+ CCHAR_P sCallName = pMemoryCore -> syscalls.GetData(iCallNum, iCallNameLength);
+ HL_CODE(YELLOW);
+ fprintf(stderr, "0x%08X SYSCALL 0x%08X %s(ARGS: %d)\n", iIP, iCallNum, sCallName, iCallArgNum);
+ HL_RST;
+}
+#endif
+ // Check call number
+ if (iCallNum > iMaxUsedCalls)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw InvalidSyscall("*** CORRUPTED ***", iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ CDT oResult(CDT::UNDEF);
+ // Invoke handler
+ if (aCallTranslationMap[iCallNum] -> Handler(oVMArgStack.GetStackFrame(), iCallArgNum, oResult, *pLogger) != 0)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw InvalidSyscall("*** Internal syscall error ***", iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ // Clear stack
+ oVMArgStack.ClearStack(iCallArgNum);
+
+ // Store execution result into stack
+ oVMArgStack.PushElement(oResult);
+
+ ++iIP;
+ }
+ break;
+
+ // CALLNAME
+ case SYSCALL_OPCODE_LO(CALLNAME):
+ {
+ // Get call name
+ UINT_32 iDataSize = 0;
+ CCHAR_P szCallName = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+
+ UINT_32 iNewIP = UINT_32(pMemoryCore -> calls_table.Get(szCallName, iDataSize));
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X CALLNAME `%s` -> %d\n", iIP, szCallName, iNewIP);
+HL_RST;
+#endif
+ // Call exist?
+ if (iNewIP == (UINT_32)-1)
+ {
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw InvalidCall(iIP, aCode[iIP].reserved, szCallName, szTMP);
+ }
+
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ oVMCodeStack.PushAddress(iIP + 1);
+ iIP = iNewIP;
+ }
+ break;
+
+ // CALLIND
+ case SYSCALL_OPCODE_LO(CALLIND):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X CALLIND ", iIP);
+#endif
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+
+ // Call name
+ STLW::string sCallName;
+
+ // From register?
+ if (iSrcReg <= ARG_SRC_HR)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ sCallName = oRegs[iSrcReg].GetString();
+ }
+ // From Stack?
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d] (`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ sCallName = oVMArgStack.GetTopElement(aCode[iIP].argument).GetString();
+ STLW::vector<CDT> vArgs;
+ vArgs.reserve(aCode[iIP].argument);
+ for (UINT_32 iI = 0; iI < aCode[iIP].argument; ++iI)
+ {
+ vArgs.push_back(oVMArgStack.GetTopElement(iI));
+ }
+ oVMArgStack.ClearStack(aCode[iIP].argument + 1);
+ for (STLW::vector<CDT>::reverse_iterator vIt = vArgs.rbegin(); vIt != vArgs.rend(); ++vIt)
+ {
+ oVMArgStack.PushElement(*vIt);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+
+ // Call exist?
+ if (sCallName.empty())
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw InvalidCall(iIP, aCode[iIP].reserved, "No name of call", szTMP);
+ }
+
+ // New IP
+ const UINT_32 iNewIP = UINT_32(pMemoryCore -> calls_table.Get(sCallName.c_str(), sCallName.size()));
+
+ // Call exist?
+ if (iNewIP == (UINT_32)-1)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw InvalidCall(iIP, aCode[iIP].reserved, sCallName.c_str(), szTMP);
+ }
+
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ // Store return address
+ oVMCodeStack.PushAddress(iIP + 1);
+ iIP = iNewIP;
+ }
+ break;
+
+ // CALL
+ case SYSCALL_OPCODE_LO(CALL):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X CALL 0x%08X\n", iIP, aCode[iIP].argument);
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ const UINT_32 iNewIP = aCode[iIP].argument;
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ oVMCodeStack.PushAddress(iIP + 1);
+ iIP = iNewIP;
+ }
+ break;
+
+ // RET
+ case SYSCALL_OPCODE_LO(RET):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X RET %d\n", iIP, aCode[iIP].argument);
+HL_RST;
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ // Clear stack
+ oVMArgStack.ClearStack(aCode[iIP].argument);
+ // Return
+ iIP = oVMCodeStack.PopAddress();
+ }
+ break;
+
+ // JMP
+ case SYSCALL_OPCODE_LO(JMP):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X JMP 0x%08X\n", iIP, aCode[iIP].argument);
+HL_RST;
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ const UINT_32 iNewIP = aCode[iIP].argument;
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ iIP = iNewIP;
+ }
+ break;
+
+ // LOOP, cycle
+ case SYSCALL_OPCODE_LO(LOOP):
+ {
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ if (iDstReg <= ARG_DST_LASTREG && iSrcReg <= ARG_SRC_LASTREG)
+ {
+ CDT & oLoopReg = oRegs[iSrcReg];
+
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X LOOP 0x%08X (%cR = %d, %cR = %d)\n", iIP, aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), INT_32(oLoopReg.GetInt()), CHAR_8((iDstReg >> 8) + 'A'), INT_32(oRegs[iDstReg >> 8].GetInt()));
+HL_RST;
+#endif
+ // Decrease number of iterations
+ --oLoopReg;
+ // End of cycle?
+ if (oLoopReg <= 0) { ++iIP; }
+ // New iteration
+ else
+ {
+ const UINT_32 iNewIP = aCode[iIP].argument;
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+ iIP = iNewIP;
+
+ // Iteration counter
+ ++oRegs[iDstReg >> 8];
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // RCALL
+ case SYSCALL_OPCODE_LO(RCALL):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X RCALL 0x%08X\n", iIP, aCode[iIP].argument);
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ const UINT_32 iNewIP = iIP + aCode[iIP].argument;
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ oVMCodeStack.PushAddress(iIP + 1);
+ iIP = iNewIP;
+ }
+ break;
+
+ // RJMP
+ case SYSCALL_OPCODE_LO(RJMP):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X RJMP 0x%08X\n", iIP, aCode[iIP].argument);
+HL_RST;
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ const UINT_32 iNewIP = iIP + aCode[iIP].argument;
+ // New IP is correct?
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ iIP = iNewIP;
+ }
+ break;
+
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ break;
+
+ // Stack operations //// 0x-2-X----
+ case 0x02:
+ {
+ switch(iOpCodeLo)
+ {
+ // PUSH
+ case SYSCALL_OPCODE_LO(PUSH):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X PUSH ", iIP);
+#endif
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+
+ // From register to stack
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ oVMArgStack.PushElement(oRegs[iSrcReg]);
+#ifdef _DEBUG
+fprintf(stderr, "%cR\n", CHAR_8(iOpCode + 'A'));
+HL_RST;
+#endif
+ }
+ // From static text segment to stack
+ else if (iSrcReg == ARG_SRC_STR)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+ oVMArgStack.PushElement(STLW::string(szTMP, iDataSize));
+#ifdef _DEBUG
+fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
+HL_RST;
+#endif
+ }
+ // From static data segment to stack (integer value)
+ else if (iSrcReg == ARG_SRC_INT)
+ {
+ oVMArgStack.PushElement(pMemoryCore -> static_data.GetInt(aCode[iIP].argument));
+#ifdef _DEBUG
+fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
+HL_RST;
+#endif
+ }
+ // From static data segment to stack (float value)
+ else if (iSrcReg == ARG_SRC_FLOAT)
+ {
+ oVMArgStack.PushElement(pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
+#ifdef _DEBUG
+fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
+HL_RST;
+#endif
+ }
+ // From indirect ARRAY
+ else if (iSrcReg == ARG_SRC_IND_VAL)
+ {
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // Indirect operations works ONLY with registers AR - HR and LR
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ oVMArgStack.PushElement(oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument));
+#ifdef _DEBUG
+fprintf(stderr, "%cR[%d] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // From indirect HASH
+ else if (iSrcReg == ARG_SRC_IND_STR)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // Indirect operations works ONLY with registers AR - HR and LR
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ bool bCDTExist = false;
+#ifdef _DEBUG
+fprintf(stderr, "%cR[\"%s\"] ", CHAR_8((iDstReg >> 8) + 'A'), szTMP);
+fprintf(stderr, "(`%s`)\n", oRegs[iDstReg >> 8].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.PushElement(oRegs[iDstReg >> 8].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist));
+
+ // Found
+ if (bCDTExist) { iFlags = FL_EQ; }
+ // Not Found
+ else { iFlags = 0; }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // From stack to stack
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%s)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.PushElement(oVMArgStack.GetTopElement(aCode[iIP].argument));
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // POP
+ case SYSCALL_OPCODE_LO(POP):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X POP ", iIP);
+#endif
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+
+ // From register to stack
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+#ifdef _DEBUG
+fprintf(stderr, "%cR\n", CHAR_8(iOpCode + 'A'));
+HL_RST;
+#endif
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // PUSH13
+ case SYSCALL_OPCODE_LO(PUSH13):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X PUSH13 \n", iIP);
+#endif
+ for (INT_32 iSrcReg = ARG_SRC_AR; iSrcReg <= ARG_SRC_DR; ++iSrcReg)
+ {
+ oVMArgStack.PushElement(oRegs[iSrcReg]);
+ }
+ }
+ break;
+
+ // POP13
+ case SYSCALL_OPCODE_LO(POP13):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X POP13 \n", iIP);
+#endif
+ for (INT_32 iSrcReg = ARG_SRC_DR; iSrcReg >= ARG_SRC_AR; --iSrcReg)
+ {
+ oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ }
+ break;
+
+ // PUSH47
+ case SYSCALL_OPCODE_LO(PUSH47):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X PUSH47 \n", iIP);
+#endif
+
+ for (INT_32 iSrcReg = ARG_SRC_ER; iSrcReg <= ARG_SRC_HR; ++iSrcReg)
+ {
+ oVMArgStack.PushElement(oRegs[iSrcReg]);
+ }
+ }
+ break;
+
+ // POP47
+ case SYSCALL_OPCODE_LO(POP47):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X POP47 \n", iIP);
+#endif
+
+ for (INT_32 iSrcReg = ARG_SRC_HR; iSrcReg >= ARG_SRC_ER; --iSrcReg)
+ {
+ oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ }
+ break;
+
+ // PUSHA
+ case SYSCALL_OPCODE_LO(PUSHA):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X PUSHA \n", iIP);
+#endif
+
+ for (INT_32 iSrcReg = 0; iSrcReg <= ARG_SRC_LASTREG; ++iSrcReg)
+ {
+ oVMArgStack.PushElement(oRegs[iSrcReg]);
+ }
+ }
+ break;
+
+ // POPA
+ case SYSCALL_OPCODE_LO(POPA):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X POPA \n", iIP);
+#endif
+
+ for (INT_32 iSrcReg = ARG_SRC_LASTREG; iSrcReg >= 0; --iSrcReg)
+ {
+ oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ }
+ break;
+
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ ++iIP;
+ break;
+
+ // Arithmetic ops. ///// 0x-3-X----
+ case 0x03:
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ switch(iOpCodeLo)
+ {
+ // ADD, Add values
+ case SYSCALL_OPCODE_LO(ADD):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X ADD ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(1) += oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // SUB, Substract values
+ case SYSCALL_OPCODE_LO(SUB):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X SUB ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(1) -= oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // MUL, Multiplicate values
+ case SYSCALL_OPCODE_LO(MUL):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MUL ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(1) *= oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // DIV, Divide values
+ case SYSCALL_OPCODE_LO(DIV):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X DIV ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(1) /= oVMArgStack.GetTopElement(0);
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // INC, Increment value
+ case SYSCALL_OPCODE_LO(INC):
+ {
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X INC %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
+HL_RST;
+#endif
+ ++oRegs[iSrcReg];
+ }
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X INC STACK[%d] (%d)\n", iIP, 0, INT_32(oVMArgStack.GetTopElement(0).GetInt()));
+HL_RST;
+#endif
+ ++oVMArgStack.GetTopElement(0);
+ }
+ }
+ break;
+
+ // DEC, Decrement value
+ case SYSCALL_OPCODE_LO(DEC):
+ {
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X DEC %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
+HL_RST;
+#endif
+ --oRegs[iSrcReg];
+ }
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X DEC STACK[%d] (%d)\n", iIP, 0, INT_32(oVMArgStack.GetTopElement(0).GetInt()));
+HL_RST;
+#endif
+ --oVMArgStack.GetTopElement(0);
+ }
+ }
+ break;
+
+ // IDIV, Integer division
+ case SYSCALL_OPCODE_LO(IDIV):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X IDIV ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ const INT_64 iFirst = oVMArgStack.GetTopElement(1).GetInt();
+ const INT_64 iSecond = oVMArgStack.GetTopElement(0).GetInt();
+
+ if (iSecond == 0)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ZeroDivision(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ oVMArgStack.GetTopElement(1) = iFirst / iSecond;
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // MOD, Divide two numbers and returns only the remainder
+ case SYSCALL_OPCODE_LO(MOD):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOD ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ const INT_64 iFirst = oVMArgStack.GetTopElement(1).GetInt();
+ const INT_64 iSecond = oVMArgStack.GetTopElement(0).GetInt();
+
+ oVMArgStack.GetTopElement(1) = iFirst % iSecond;
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // NEG, Negate
+ case SYSCALL_OPCODE_LO(NEG):
+ {
+
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X NEG %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
+HL_RST;
+#endif
+ CDT & oTMP = oRegs[iSrcReg];
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oTMP = 0 - oTMP; }
+ }
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X NEG STACK[%d](%s)\n", iIP, aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ CDT & oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oTMP = 0 - oTMP; }
+ }
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // NOT, Logical negation
+ case SYSCALL_OPCODE_LO(NOT):
+ {
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "0x%08X NOT STACK[%d](%c)\n", iIP, aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero() ? 't':'f');
+HL_RST;
+#endif
+ CDT & oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
+
+ if (oTMP.Nonzero()) { oTMP = CDT(CDT::UNDEF); }
+ // Undefined
+ else { oTMP = 1; }
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "0x%08X NOT %cR (`%s`)\n", iIP, CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ // Defined
+ if (oRegs[iSrcReg].Nonzero()) { oRegs[iSrcReg] = CDT(CDT::UNDEF); }
+ // Undefined
+ else { oRegs[iSrcReg] = 1; }
+ }
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // CONCAT, Concatenate strings
+ case SYSCALL_OPCODE_LO(CONCAT):
+ {
+ CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X CONCAT ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(1).Append(oVMArgStack.GetTopElement(0));
+ oVMArgStack.ClearStack(1);
+ }
+ break;
+
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ ++iIP;
+ break;
+
+ // Register ops. /////// 0x-4------
+ case 0x04:
+ {
+ switch(iOpCodeLo)
+ {
+ // MOV
+ case SYSCALL_OPCODE_LO(MOV):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOV ", iIP);
+#endif
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR, ", CHAR_8((iDstReg >> 8) + 'A'));
+#endif
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR == `%s`\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ oRegs[iDstReg >> 8] = oRegs[iSrcReg];
+ }
+ // Register-to-stack
+ else if (iSrcReg <= ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d] = `%s`\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oRegs[iDstReg >> 8] = oVMArgStack.GetTopElement(aCode[iIP].argument);
+ }
+ // Integer-to-register
+ else if (iSrcReg == ARG_SRC_INT)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
+HL_RST;
+#endif
+ oRegs[iDstReg >> 8] = pMemoryCore -> static_data.GetInt(aCode[iIP].argument);
+ }
+ // Float-to-register
+ else if (iSrcReg == ARG_SRC_FLOAT)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
+HL_RST;
+#endif
+ oRegs[iDstReg >> 8] = pMemoryCore -> static_data.GetFloat(aCode[iIP].argument);
+ }
+ // String-to-register
+ else if (iSrcReg == ARG_SRC_STR)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+#ifdef _DEBUG
+fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
+HL_RST;
+#endif
+ oRegs[iDstReg >> 8] = STLW::string(szTMP, iDataSize);
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // MOVIINT, Move indirect ARRAY to register
+ case SYSCALL_OPCODE_LO(MOVIINT):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOVIINT %cR, %cR[%d] (`%s`)", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetString().c_str());
+HL_RST;
+#endif
+
+ oRegs[iDstReg >> 8] = oRegs[iSrcReg].GetCDT(aCode[iIP].argument);
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // MOVISTR, Move indirect HASH to register
+ case SYSCALL_OPCODE_LO(MOVISTR):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+
+ bool bCDTExist = false;
+ oRegs[iDstReg >> 8] = oRegs[iSrcReg].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist);
+
+ // Found
+ if (bCDTExist) { iFlags = FL_EQ; }
+ // Not Found
+ else { iFlags = FL_NE; }
+
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOVISTR %cR, %cR[%s] (`%s`)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), szTMP, oRegs[iDstReg >> 8].GetString().c_str());
+HL_RST;
+#endif
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // IMOVINT, Move register to indirect ARRAY
+ case SYSCALL_OPCODE_LO(IMOVINT):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ oRegs[iDstReg >> 8][aCode[iIP].argument] = oRegs[iSrcReg];
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X IMOVINT %cR[%d], %cR[%d] (`%s`)\n", iIP, CHAR_8((iDstReg >> 8)+ 'A'), aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), aCode[iIP].argument, oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // IMOVSTR
+ case SYSCALL_OPCODE_LO(IMOVSTR):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+ oRegs[iDstReg >> 8][STLW::string(szTMP, iDataSize)] = oRegs[iSrcReg];
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X IMOVSTR %cR[%s], %cR (`%s`)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), szTMP, CHAR_8(iSrcReg + 'A'), oRegs[iDstReg >> 8][STLW::string(szTMP, iDataSize)].GetString().c_str());
+HL_RST;
+#endif
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // MOVSIZE, Get object size
+ case SYSCALL_OPCODE_LO(MOVSIZE):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOVSIZE %cR, %cR.Size() (%d)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), UINT_32(oRegs[iSrcReg].Size()));
+HL_RST;
+#endif
+ const UINT_64 iSize = oRegs[iSrcReg].Size();
+ oRegs[iDstReg >> 8] = iSize;
+
+ if (iSize == 0) { iFlags = FL_EQ; }
+ else { iFlags = 0; }
+ }
+ // Stack-to-register
+ else if (iSrcReg <= ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOVSIZE %cR, STACK[%d] (%d)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Size());
+HL_RST;
+#endif
+ const UINT_64 iSize = oVMArgStack.GetTopElement(aCode[iIP].argument).Size();
+ oRegs[iDstReg >> 8] = iSize;
+
+ if (iSize == 0) { iFlags = FL_EQ; }
+ else { iFlags = 0; }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // To stack
+ else if (iDstReg <= ARG_DST_STACK)
+ {
+ // Register-to-stack
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X MOVSIZE STACK[%d], %cR (%d)\n", iIP, aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].Size());
+HL_RST;
+#endif
+ const UINT_64 iSize = oRegs[iSrcReg].Size();
+ oVMArgStack.GetTopElement(aCode[iIP].argument) = iSize;
+
+ if (iSize == 0) { iFlags = FL_EQ; }
+ else { iFlags = 0; }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // MOVIREGI
+ case SYSCALL_OPCODE_LO(MOVIREGI):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ const UINT_32 iArgNum = aCode[iIP].argument;
+ // Illegal Opcode?
+ if (iArgNum > ARG_SRC_LASTREG)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ // AR <- CR[BR]
+ //oRegs[iDstReg >> 8] = oRegs[iSrcReg][oRegs[iArgNum].GetInt()];
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X MOVIREG %cR, %cR[%cR] ", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), CHAR_8(iArgNum + 'A'));
+#endif
+ const INT_32 iIdx = oRegs[iArgNum].GetInt();
+ CDT oItVal(CDT::HASH_VAL);
+ if (iIdx == 0)
+ {
+ oItVal["__first__"] = 1;
+ }
+ else if (UINT_32(iIdx + 1) == oRegs[iSrcReg].Size())
+ {
+ oItVal["__last__"] = 1;
+ }
+ else
+ {
+ oItVal["__inner__"] = 1;
+ }
+
+ if ((iIdx + 1) % 2 == 1) { oItVal["__odd__"] = 1; }
+ else { oItVal["__even__"] = 1; }
+
+ if (oRegs[iSrcReg].GetType() == CDT::HASH_VAL)
+ {
+ CDT::Iterator it = oRegs[iSrcReg].Begin();
+ for (INT_32 iI = 0; iI < iIdx; ++iI) { ++it; }
+#ifdef _DEBUG
+fprintf(stderr, "(`%s`): %s\n", it->first.c_str(), it->second.GetString().c_str());
+HL_RST;
+#endif
+ oItVal["__value__"] = it->second;
+ oItVal["__key__"] = it->first;
+ oRegs[iDstReg >> 8] = oItVal;
+ }
+ else
+ {
+#ifdef _DEBUG
+fprintf(stderr, "(%d): %s\n", iIdx, oRegs[iSrcReg][iIdx].GetString().c_str());
+HL_RST;
+#endif
+ oItVal["__value__"] = oRegs[iSrcReg][iIdx];
+ oItVal["__index__"] = iIdx;
+ oRegs[iDstReg >> 8] = oItVal;
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // MOVIREGS
+ case SYSCALL_OPCODE_LO(MOVIREGS):
+ {
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ // To register
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ // Register-to-register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ const UINT_32 iArgNum = aCode[iIP].argument;
+ // Illegal Opcode?
+ if (iArgNum > ARG_SRC_LASTREG)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X MOVIREGS %cR, %cR{%cR} (%s): %s\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), CHAR_8(iArgNum + 'A'), oRegs[iArgNum].GetString().c_str(), oRegs[iSrcReg][oRegs[iArgNum].GetString()].GetString().c_str());
+HL_RST;
+#endif
+ // AR <- CR[BR]
+ oRegs[iDstReg >> 8] = oRegs[iSrcReg][oRegs[iArgNum].GetString()];
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ ++iIP;
+ break;
+
+ // Comparison ops. ///// 0x-5-X----
+ case 0x05:
+ {
+ switch(iOpCodeLo)
+ {
+ // CMP
+ case SYSCALL_OPCODE_LO(CMP):
+ {
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ W_FLOAT dSrc = 0.0;
+ W_FLOAT dDst = 0.0;
+#ifdef _DEBUG
+{
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X CMP ", iIP);
+
+STLW::string sMsg2;
+if (iDstReg <= ARG_DST_LASTREG) { sMsg2.append(1, (iDstReg >> 8) + 'A'); sMsg2.append("R(`"); sMsg2.append(oRegs[iDstReg >> 8].GetString()); sMsg2.append("`)"); }
+else if (iDstReg == ARG_DST_STACK) { sMsg2.append("STACK[0](`"); sMsg2.append(oVMArgStack.GetTopElement(0).GetString()); sMsg2.append("`)"); }
+
+STLW::string sMsg1;
+if (iSrcReg <= ARG_SRC_LASTREG) { sMsg1.append(1, iSrcReg + 'A'); sMsg1.append("R(`"); sMsg1.append(oRegs[iSrcReg].GetString()); sMsg1.append("`), "); }
+else if (iSrcReg == ARG_SRC_STACK) { sMsg1.append("STACK[1](`"); sMsg1.append(oVMArgStack.GetTopElement(1).GetString()); sMsg1.append("`), "); }
+
+fprintf(stderr, "%s%s\n", sMsg1.c_str(), sMsg2.c_str());
+HL_RST;
+}
+#endif
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ dDst = oRegs[iDstReg >> 8].GetFloat();
+ }
+ else if (iDstReg == ARG_DST_STACK)
+ {
+ dDst = oVMArgStack.GetTopElement(0).GetFloat();
+ oVMArgStack.PopElement();
+ }
+
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ dSrc = oRegs[iSrcReg].GetFloat();
+ }
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+ dSrc = oVMArgStack.GetTopElement(0).GetFloat();
+ oVMArgStack.PopElement();
+ }
+
+ W_FLOAT dTMP = dSrc - dDst;
+ if (dTMP < 0.0) { iFlags = FL_LT | FL_NE; }
+ else if (dTMP > 0.0) { iFlags = FL_GT | FL_NE; }
+ else { iFlags = FL_EQ; }
+
+ const UINT_64 iTMP = UINT_64(dSrc);
+ if ((iTMP % 2) == 0) { iFlags |= FL_PF; }
+ else { iFlags |= FL_NPF; }
+ }
+ break;
+
+ // SCMP
+ case SYSCALL_OPCODE_LO(SCMP):
+ {
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ STLW::string sSrc;
+ STLW::string sDst;
+#ifdef _DEBUG
+{
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X SCMP ", iIP);
+
+STLW::string sMsg2;
+if (iDstReg <= ARG_DST_LASTREG) { sMsg2.append(1, (iDstReg >> 8) + 'A'); sMsg2.append("R(`"); sMsg2.append(oRegs[iDstReg >> 8].GetString()); sMsg2.append("`)"); }
+else if (iDstReg == ARG_DST_STACK) { sMsg2.append("STACK[0](`"); sMsg2.append(oVMArgStack.GetTopElement(0).GetString()); sMsg2.append("`)"); }
+
+STLW::string sMsg1;
+if (iSrcReg <= ARG_SRC_LASTREG) { sMsg1.append(1, iSrcReg + 'A'); sMsg1.append("R(`"); sMsg1.append(oRegs[iSrcReg].GetString()); sMsg1.append("`), "); }
+else if (iSrcReg == ARG_SRC_STACK) { sMsg1.append("STACK[1](`"); sMsg1.append(oVMArgStack.GetTopElement(1).GetString()); sMsg1.append("`), "); }
+
+fprintf(stderr, "%s%s\n", sMsg1.c_str(), sMsg2.c_str());
+HL_RST;
+}
+#endif
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ sDst = oRegs[iDstReg >> 8].GetString();
+ }
+ else if (iDstReg == ARG_DST_STACK)
+ {
+ sDst = oVMArgStack.GetTopElement(0).GetString();
+ oVMArgStack.PopElement();
+ }
+
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ sSrc = oRegs[iSrcReg].GetString();
+ }
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+ sSrc = oVMArgStack.GetTopElement(0).GetString();
+ oVMArgStack.PopElement();
+ }
+
+ if (sSrc < sDst) { iFlags = FL_LT | FL_NE; }
+ else if (sSrc > sDst) { iFlags = FL_GT | FL_NE; }
+ else { iFlags = FL_EQ; }
+ }
+ break;
+
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ ++iIP;
+ break;
+
+ // Conditional ops.1 /// 0x-6-X----
+ case 0x06:
+ {
+ const UINT_32 iOpCodeFlag = iOpCode & 0x00FF0000;
+#ifdef _DEBUG
+{
+HL_CODE(GREEN);
+CHAR_8 sFlags[8];
+INT_32 iPos = 0;
+for (iPos = 0; iPos < 8; ++iPos) { sFlags[iPos] = ' '; }
+sFlags[7] = '\0'; iPos = 0;
+if(iOpCodeFlag & FL_NE) { sFlags[iPos++] = 'N'; }
+if(iOpCodeFlag & FL_LT) { sFlags[iPos++] = 'L'; }
+if(iOpCodeFlag & FL_GT) { sFlags[iPos++] = 'G'; }
+if(iOpCodeFlag & FL_EQ) { sFlags[iPos++] = 'E'; }
+if(iOpCodeFlag & FL_PF) { sFlags[iPos++] = 'P'; }
+if(iOpCodeFlag & FL_NPF) { sFlags[iPos++] = 'N'; sFlags[iPos++] = 'P'; }
+fprintf(stderr, "0x%08X J%s 0x%08X\n", iIP, sFlags, aCode[iIP].argument);
+HL_RST;
+}
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ // Check flags
+ if (!(iOpCodeFlag & iFlags))
+ {
+ ++iIP;
+ }
+ else
+ {
+ const UINT_32 iNewIP = aCode[iIP].argument;
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+ iIP = iNewIP;
+ }
+ }
+ break;
+
+ // Conditional ops.2 /// 0x-7-X----
+ case 0x07:
+ {
+ const UINT_32 iOpCodeFlag = iOpCode & 0x00FF0000;
+#ifdef _DEBUG
+{
+HL_CODE(GREEN);
+CHAR_8 sFlags[8];
+INT_32 iPos = 0;
+for (iPos = 0; iPos < 8; ++iPos) { sFlags[iPos] = ' '; }
+sFlags[7] = '\0'; iPos = 0;
+if(iOpCodeFlag & FL_NE) { sFlags[iPos++] = 'N'; }
+if(iOpCodeFlag & FL_LT) { sFlags[iPos++] = 'L'; }
+if(iOpCodeFlag & FL_GT) { sFlags[iPos++] = 'G'; }
+if(iOpCodeFlag & FL_EQ) { sFlags[iPos++] = 'E'; }
+if(iOpCodeFlag & FL_PF) { sFlags[iPos++] = 'P'; }
+if(iOpCodeFlag & FL_NPF) { sFlags[iPos++] = 'N'; sFlags[iPos++] = 'P'; }
+fprintf(stderr, "0x%08X RJ%s 0x%08X\n", iIP, sFlags, aCode[iIP].argument);
+HL_RST;
+}
+#endif
+ // Check execution limit
+ if (iExecutedSteps >= iMaxSteps)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
+ }
+
+ // Check flags
+ if (!(iOpCodeFlag & iFlags))
+ {
+ ++iIP;
+ }
+ else
+ {
+ const UINT_32 iNewIP = iIP + aCode[iIP].argument;
+ if (iNewIP >= iCodeLength)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
+ }
+ iIP = iNewIP;
+ }
+ }
+ break;
+ // Other ops. ////////// 0x-8-X----
+ case 0x08:
+ {
+ switch(iOpCodeLo)
+ {
+ // CLEAR
+ case SYSCALL_OPCODE_LO(CLEAR):
+ {
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X CLEAR ", iIP);
+#endif
+ // Clear register
+ if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR\n", CHAR_8((iSrcReg >> 8) + 'A'));
+HL_RST;
+#endif
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ oRegs[iDstReg >> 8] = CDT();
+ }
+ // Clear stack
+ else if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%s)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(aCode[iIP].argument) = CDT(CDT::UNDEF);
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // OUTPUT
+ case SYSCALL_OPCODE_LO(OUTPUT):
+ {
+ // Register
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+#ifdef _DEBUG
+HL_CODE(YELLOW);
+fprintf(stderr, "0x%08X OUTPUT ", iIP);
+#endif
+ // From stack
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ const STLW::string sTMP = oVMArgStack.GetTopElement(0).GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ oVMArgStack.ClearStack(1);
+ }
+ // From static text segment
+ else if (iSrcReg == ARG_SRC_STR)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+#ifdef _DEBUG
+fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
+HL_RST;
+#endif
+ pOutputCollector -> Collect(szTMP, iDataSize);
+ }
+ // From static data segment (integer value)
+ else if (iSrcReg == ARG_SRC_INT)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
+HL_RST;
+#endif
+ const CDT oTMP(pMemoryCore -> static_data.GetInt(aCode[iIP].argument));
+ const STLW::string sTMP = oTMP.GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ }
+ // From static data segment (float value)
+ else if (iSrcReg == ARG_SRC_FLOAT)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
+HL_RST;
+#endif
+ const CDT oTMP(pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
+ STLW::string sTMP = oTMP.GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ }
+ // From register
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR\n", CHAR_8(iSrcReg + 'A'));
+HL_RST;
+#endif
+ const STLW::string sTMP = oRegs[iSrcReg].GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ }
+ // Indirect operations works ONLY with registers
+ else if (iSrcReg == ARG_SRC_IND_VAL)
+ {
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+#ifdef _DEBUG
+fprintf(stderr, "%cR[%d] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ const STLW::string sTMP = oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Indirect operations works ONLY with registers
+ else if (iSrcReg == ARG_SRC_IND_STR)
+ {
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+#ifdef _DEBUG
+fprintf(stderr, "%cR[\"%s\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), szTMP, oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString().c_str());
+HL_RST;
+#endif
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ STLW::string sTMP = oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString();
+ pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // REPLACE
+ case SYSCALL_OPCODE_LO(REPLACE):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X REPLACE ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+ // From static text segment to stack
+ if (iSrcReg == ARG_SRC_IND_STR)
+ {
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+#ifdef _DEBUG
+fprintf(stderr, "%cR[\"%s\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), szTMP, oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize));
+ }
+ else if (iDstReg == ARG_DST_STACK)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
+
+ CDT & oTopStack = oVMArgStack.GetTopElement(0);
+ CDT oTMP = oTopStack.GetCDT(STLW::string(szTMP, iDataSize));
+#ifdef _DEBUG
+fprintf(stderr, "TOP STACK[\"%s\"] (`%s`)\n", szTMP, oTMP.GetString().c_str());
+HL_RST;
+#endif
+ oTopStack = oTMP;
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // From argument pointed to array element from register or stack to to stack
+ else if (iSrcReg == ARG_SRC_IND_VAL)
+ {
+ if (iDstReg <= ARG_DST_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR[\"%d\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), INT_32(aCode[iIP].argument), oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument);
+ }
+ else if (iDstReg == ARG_DST_STACK)
+ {
+ CDT & oTopStack = oVMArgStack.GetTopElement(0);
+ CDT oTMP = oTopStack.GetCDT(aCode[iIP].argument);
+#ifdef _DEBUG
+fprintf(stderr, "TOP STACK[\"%d\"] (`%s`)\n", INT_32(aCode[iIP].argument), oTMP.GetString().c_str());
+HL_RST;
+#endif
+ oTopStack = oTMP;
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // From register to stack
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oRegs[iSrcReg];
+ }
+ // Illegal operation
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // EXIST, check existence of operand
+ case SYSCALL_OPCODE_LO(EXIST):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X EXIST ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%c)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero() ? 't':'f');
+HL_RST;
+#endif
+ // Defined
+ if (oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero()) { iFlags = FL_EQ; }
+ // Undefined
+ else { iFlags = FL_NE; }
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ // Defined
+ if (oRegs[iSrcReg].Nonzero()) { iFlags = FL_EQ; }
+ // Undefined
+ else { iFlags = FL_NE; }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // REPLINT
+ case SYSCALL_OPCODE_LO(REPLINT):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X REPLINT ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%d)\n", aCode[iIP].argument, INT_32(oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()));
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()];
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (%d)\n", CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetInt()];
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+
+ // REPLSTR
+ case SYSCALL_OPCODE_LO(REPLSTR):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X REPLSTR ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetString()];
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetString()];
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // REPLIND
+ case SYSCALL_OPCODE_LO(REPLIND):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X REPLIND ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+ CDT::eValType typ = oVMArgStack.GetTopElement(aCode[iIP].argument).GetType();
+ switch (typ)
+ {
+ case CDT::INT_VAL:
+ case CDT::REAL_VAL:
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%d)\n", aCode[iIP].argument, INT_32(oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()));
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()];
+ break;
+ case CDT::STRING_VAL:
+ case CDT::STRING_INT_VAL:
+ case CDT::STRING_REAL_VAL:
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetString()];
+ break;
+ default:
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](UNDEF)\n", aCode[iIP].argument);
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = CDT();
+ break;
+ }
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+ CDT::eValType typ = oRegs[iSrcReg].GetType();
+ switch (typ)
+ {
+ case CDT::INT_VAL:
+ case CDT::REAL_VAL:
+#ifdef _DEBUG
+fprintf(stderr, "%cR (%d)\n", CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetInt()];
+ break;
+ case CDT::STRING_VAL:
+ case CDT::STRING_INT_VAL:
+ case CDT::STRING_REAL_VAL:
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetString()];
+ break;
+ default:
+#ifdef _DEBUG
+fprintf(stderr, "%cR (UNDEF)\n", CHAR_8(iSrcReg + 'A'));
+HL_RST;
+#endif
+ oVMArgStack.GetTopElement(0) = CDT();
+ break;
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // XCHG
+ case SYSCALL_OPCODE_LO(XCHG):
+ {
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X XCHG ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
+
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](`%s`), ", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
+#endif
+ CDT oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
+ if (iDstReg == ARG_DST_STACK)
+ {
+ CDT &oTopStack = oVMArgStack.GetTopElement(0);
+ oVMArgStack.GetTopElement(aCode[iIP].argument) = oTopStack;
+
+#ifdef _DEBUG
+fprintf(stderr, "TOP STACK[0] (`%s`)\n", oTopStack.GetString().c_str());
+HL_RST;
+#endif
+ oTopStack = oTMP;
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // DEFINED, check existence of operand
+ case SYSCALL_OPCODE_LO(DEFINED):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X DEFINED ", iIP);
+#endif
+ const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
+ if (iSrcReg == ARG_SRC_STACK)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "STACK[%d](%c)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetType() != CDT::UNDEF ? 't':'f');
+HL_RST;
+#endif
+ // Defined
+ if (oVMArgStack.GetTopElement(aCode[iIP].argument).GetType() != CDT::UNDEF) { iFlags = FL_EQ; }
+ // Undefined
+ else { iFlags = FL_NE; }
+ }
+ else if (iSrcReg <= ARG_SRC_LASTREG)
+ {
+#ifdef _DEBUG
+fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
+HL_RST;
+#endif
+ // Defined
+ if (oRegs[iSrcReg].GetType() != CDT::UNDEF) { iFlags = FL_EQ; }
+ // Undefined
+ else { iFlags = FL_NE; }
+ }
+ // Illegal Opcode?
+ else
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ break;
+ // SAVEBP, save base pointer
+ case SYSCALL_OPCODE_LO(SAVEBP):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X SAVEBP", iIP);
+if (aCode[iIP].argument > 0) {
+ fprintf(stderr, " [-%d]\n", aCode[iIP].argument);
+} else {
+ fprintf(stderr, "\n");
+}
+
+#endif
+ oVMArgStack.SaveBasePointer(aCode[iIP].argument);
+ }
+ break;
+ // RESTBP, restore base pointer
+ case SYSCALL_OPCODE_LO(RESTBP):
+ {
+#ifdef _DEBUG
+HL_CODE(GREEN);
+fprintf(stderr, "0x%08X RESTBP\n", iIP);
+#endif
+ oVMArgStack.RestoreBasePointer();
+ }
+ break;
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ ++iIP;
+ break;
+
+ // HLT
+ case 0xFF: // Halt
+ {
+ switch(iOpCodeLo)
+ {
+ // HLT
+ case SYSCALL_OPCODE_LO(HLT):
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X HLT\n", iIP);
+HL_RST;
+#endif
+ return 0;
+ // BRK
+ case SYSCALL_OPCODE_LO(BRK):
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X BRK\n", iIP);
+HL_RST;
+#endif
+ if (iDebugLevel > 0) { return 0; }
+ ++iIP;
+ break;
+ // NOP
+ case SYSCALL_OPCODE_LO(NOP):
+#ifdef _DEBUG
+HL_CODE(RED);
+fprintf(stderr, "0x%08X NOP\n", iIP);
+HL_RST;
+#endif
+ ++iIP; // Do nothing
+ break;
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ }
+ }
+ break;
+
+ // Illegal Opcode?
+ default:
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
+ }
+ } // switch(SYSCALL_OPCODE_HI(iOpCode))
+ ++iExecutedSteps;
+ } // while (iIP < iCodeLength)
+ }
+ catch (StackOverflow & e)
+ {
+ // Avoid MS VC warning "unised variable"; using paragma is not effective solution
+ UINT_32 iTMP = e.GetIP() * 0;
+
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+
+ throw StackOverflow(iTMP + iIP, aCode[iIP].reserved, szTMP);
+ }
+ catch (StackUnderflow &e)
+ {
+ // Avoid MS VC warning "unised variable"; using paragma is not effective solution
+ UINT_32 iTMP = e.GetIP() * 0;
+
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
+
+ throw StackUnderflow(iTMP + iIP, aCode[iIP].reserved, szTMP);
+ }
+
+return 0;
+}
+
+//
+// Reset virtual machine state
+//
+INT_32 VM::Reset()
+{
+ AR = CDT();
+ BR = CDT();
+ CR = CDT();
+ DR = CDT();
+ ER = CDT();
+ FR = CDT();
+ GR = CDT();
+ HR = CDT();
+
+ iFlags = 0;
+
+ oVMArgStack.Reset();
+ oVMCodeStack.Reset();
+
+return 0;
+}
+
+//
+//
+//
+void VM::CheckStackOnlyRegs(const UINT_32 iSrcReg, const UINT_32 iDstReg, const VMMemoryCore * pMemoryCore, const UINT_32 iIP)
+{
+ if (iSrcReg != ARG_SRC_STACK || iDstReg != ARG_DST_STACK)
+ {
+ UINT_32 iDataSize = 0;
+ CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(pMemoryCore -> instructions[iIP].reserved).GetDescrId(), iDataSize);
+ throw IllegalOpcode(iIP, pMemoryCore -> instructions[iIP].instruction, pMemoryCore -> instructions[iIP].reserved, szTMP);
+ }
+}
+
+//
+// A destructor
+//
+VM::~VM() throw()
+{
+ if (aCallTranslationMap != 0) { delete [] aCallTranslationMap; }
+
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMArgStack.cpp b/src/CTPP2VMArgStack.cpp
new file mode 100644
index 0000000..9316435
--- /dev/null
+++ b/src/CTPP2VMArgStack.cpp
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CZTPP2VMArgStack.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMArgStack.hpp"
+#include "CTPP2VMStackException.hpp"
+
+#ifdef _DEBUG
+#include <stdio.h>
+#endif
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+VMArgStack::VMArgStack(const INT_32 iIMaxStackSize): iMaxStackSize(iIMaxStackSize),
+ iStackPointer(iIMaxStackSize)
+{
+ aStack = new CDT[iMaxStackSize];
+ vBasePointers.reserve(iMaxStackSize);
+ vBasePointers.push_back(iMaxStackSize);
+}
+
+//
+// Save base pointer
+//
+void VMArgStack::SaveBasePointer(const UINT_32 iOffset) { vBasePointers.push_back(iStackPointer + iOffset); }
+
+//
+// Restore previous base pointer
+//
+void VMArgStack::RestoreBasePointer() { vBasePointers.pop_back(); }
+
+//
+// Get stack usage factor
+//
+INT_32 VMArgStack::GetSize() const { return iStackPointer; }
+
+//
+// Push element into stack
+//
+INT_32 VMArgStack::PushElement(const CDT & oCDT)
+{
+ if (iStackPointer == 0) { throw StackOverflow(0); }
+
+ --iStackPointer;
+
+ aStack[iStackPointer] = oCDT;
+
+return iStackPointer;
+}
+
+//
+// Remove top stack element
+//
+INT_32 VMArgStack::PopElement()
+{
+ if (iStackPointer == vBasePointers.back()) { throw StackUnderflow(0); }
+
+ ++iStackPointer;
+
+return iStackPointer;
+}
+
+//
+// Get element from specified position
+//
+CDT & VMArgStack::GetElement(const INT_32 iPos)
+{
+ if (iPos >= vBasePointers.back()) { throw StackUnderflow(0); }
+
+ if (iPos < iStackPointer) { throw StackOverflow(0); }
+
+return aStack[iPos];
+}
+
+//
+// Clear stack on specified depth
+//
+INT_32 VMArgStack::ClearStack(const INT_32 iDepth)
+{
+ INT_32 iNewSP = iStackPointer + iDepth;
+
+ if (iNewSP > vBasePointers.back()) { throw StackUnderflow(0); }
+
+ iStackPointer = iNewSP;
+
+return iNewSP;
+}
+
+//
+// Reset stack of arguments to default state
+//
+void VMArgStack::Reset()
+{
+ iStackPointer = iMaxStackSize;
+ vBasePointers.clear();
+ vBasePointers.push_back(iMaxStackSize);
+}
+
+//
+// A destructor
+//
+VMArgStack::~VMArgStack() throw()
+{
+#ifdef _DEBUG
+fprintf(stderr, "Arg Stack(%d): SP %d\n", iMaxStackSize, iStackPointer);
+#endif
+ delete [] aStack;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMCodeStack.cpp b/src/CTPP2VMCodeStack.cpp
new file mode 100644
index 0000000..046453e
--- /dev/null
+++ b/src/CTPP2VMCodeStack.cpp
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMCodeStack.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMCodeStack.hpp"
+#include "CTPP2VMStackException.hpp"
+
+#ifdef _DEBUG
+#include <stdio.h>
+#endif
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+VMCodeStack::VMCodeStack(const INT_32 iIMaxStackSize): iMaxStackSize(iIMaxStackSize),
+ iStackPointer(iIMaxStackSize)
+{
+ aStack = new UINT_32[iMaxStackSize];
+}
+
+//
+// Push address into stack
+//
+void VMCodeStack::PushAddress(const UINT_32 iAddress)
+{
+ if (iStackPointer == 0) { throw StackOverflow(0); }
+
+ --iStackPointer;
+
+ aStack[iStackPointer] = iAddress;
+}
+
+//
+// Remove top stack element
+//
+UINT_32 VMCodeStack::PopAddress()
+{
+ if (iStackPointer == iMaxStackSize) { throw StackUnderflow(0); }
+
+return aStack[iStackPointer++];
+}
+
+//
+// Reset stack of arguments to default state
+//
+void VMCodeStack::Reset() { iStackPointer = iMaxStackSize; }
+
+//
+// A destructor
+//
+VMCodeStack::~VMCodeStack() throw()
+{
+#ifdef _DEBUG
+fprintf(stderr, "Code Stack(%d): SP %d\n", iMaxStackSize, iStackPointer);
+#endif
+
+ delete [] aStack;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMDebugInfo.cpp b/src/CTPP2VMDebugInfo.cpp
new file mode 100644
index 0000000..5355882
--- /dev/null
+++ b/src/CTPP2VMDebugInfo.cpp
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMDebugInfo.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2VMDebugInfo.hpp"
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+/**
+ SSSSSSSS SSSSSSSS SSSSSSSS - String description, 24 bits
+ LLLLLLLL LLLLLLLL LLLL - Line, 20 bits
+ PPPP PPPPPPPP PPPPPPPP - Position in line, 20 bits
+ 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
+ F F F F F F F F F F F F F F F F
+*/
+
+//
+// Constructor
+//
+VMDebugInfo::VMDebugInfo(const CCharIterator & oCCharIterator,
+ const UINT_32 iIStringDescr): iStringDescr(iIStringDescr),
+ iLine(oCCharIterator.GetLine()),
+ iPos(oCCharIterator.GetLinePos())
+{
+ ;;
+}
+
+//
+// Constructor
+//
+VMDebugInfo::VMDebugInfo(const UINT_32 iIStringDescr,
+ const UINT_32 iILine,
+ const UINT_32 iIPos): iStringDescr(iIStringDescr),
+ iLine(iILine),
+ iPos(iIPos)
+{
+ ;;
+}
+
+
+//
+// Constructor
+//
+VMDebugInfo::VMDebugInfo(const UINT_64 iEncoded): iStringDescr((iEncoded >> 40) & 0x00FFFFFF),
+ iLine((iEncoded >> 20) & 0x000FFFFF),
+ iPos(iEncoded & 0x000FFFFF)
+{
+ ;;
+}
+
+//
+// Get encoded debug information
+//
+UINT_64 VMDebugInfo::GetInfo() const
+{
+ // Stupid typecast
+ UINT_64 iTMP = iStringDescr;
+
+ return ((iTMP & 0x00FFFFFF) << 40) +
+ ((iLine & 0x000FFFFF) << 20) +
+ ((iPos & 0x000FFFFF));
+}
+
+//
+// Get string ID
+//
+UINT_32 VMDebugInfo::GetDescrId() const { return iStringDescr; }
+
+//
+// Get line
+//
+UINT_32 VMDebugInfo::GetLine() const { return iLine; }
+
+//
+// Get line position
+//
+UINT_32 VMDebugInfo::GetLinePos() const { return iPos; }
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMDumper.cpp b/src/CTPP2VMDumper.cpp
new file mode 100644
index 0000000..9c707d6
--- /dev/null
+++ b/src/CTPP2VMDumper.cpp
@@ -0,0 +1,385 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMDumper.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2VMDumper.hpp"
+
+#include "CTPP2Util.hpp"
+#include "CTPP2VMInstruction.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Align segment
+//
+static INT_32 AlignSegment(const INT_32 iOffset)
+{
+ INT_32 iAlignedOffset = iOffset % 8;
+ if (iAlignedOffset == 0 || iAlignedOffset == 8) { return iOffset; }
+
+return iOffset + 8 - iAlignedOffset;
+}
+
+//
+// Constructor
+//
+VMDumper::VMDumper(const VMMemoryCore & oMemoryCore)
+{
+ INT_32 iSyscallsDataSize = 0;
+ if (oMemoryCore.syscalls.iUsedDataOffsetsSize == 0) { iSyscallsDataSize = 0; }
+ else
+ {
+ const TextDataIndex & oTMP = oMemoryCore.syscalls.aDataOffsets[oMemoryCore.syscalls.iUsedDataOffsetsSize - 1];
+ iSyscallsDataSize = oTMP.offset + oTMP.length + 1;
+ }
+
+ INT_32 iStaticTextDataSize = 0;
+ if (oMemoryCore.static_text.iUsedDataOffsetsSize == 0) { iStaticTextDataSize = 0; }
+ else
+ {
+ const TextDataIndex & oTMP = oMemoryCore.static_text.aDataOffsets[oMemoryCore.static_text.iUsedDataOffsetsSize - 1];
+ iStaticTextDataSize = oTMP.offset + oTMP.length + 1;
+ }
+
+ const INT_32 iCodeSize = sizeof(VMInstruction) * oMemoryCore.code_size;
+ const INT_32 iSyscallsIndexSize = sizeof(TextDataIndex) * oMemoryCore.syscalls.iUsedDataOffsetsSize;
+ const INT_32 iStaticDataIndexSize = sizeof(StaticDataVar) * oMemoryCore.static_data.iUsedDataSize;
+ const INT_32 iStaticTextIndexSize = sizeof(TextDataIndex) * oMemoryCore.static_text.iUsedDataOffsetsSize;
+
+ const INT_32 iStaticDataBitIndexSize = sizeof(UINT_64) + oMemoryCore.bit_index.GetUsedSize();
+ const INT_32 iCallsHashTableSize = sizeof(HashElement) * (1 << oMemoryCore.calls_table.iPower);
+
+ // Header
+ iVMExecutableSize = AlignSegment(sizeof(VMExecutable)) +
+
+ // Code segment
+ AlignSegment(iCodeSize) +
+
+ // Static syscalls segment
+ AlignSegment(iSyscallsDataSize) +
+ // Static syscalls index segment
+ AlignSegment(iSyscallsIndexSize) +
+
+ // Static Data segment
+ AlignSegment(iStaticDataIndexSize) +
+
+ // Static Text segment
+ AlignSegment(iStaticTextDataSize) +
+ // Static Text index segment
+ AlignSegment(iStaticTextIndexSize) +
+
+ // Bit index
+ AlignSegment(iStaticDataBitIndexSize) +
+
+ // hash table size
+ AlignSegment(iCallsHashTableSize);
+
+ CHAR_P vRawData = (CHAR_P)malloc(iVMExecutableSize);
+ // Make valgind happy
+ memset(vRawData, '-', iVMExecutableSize);
+
+ oVMExecutable = (VMExecutable *)vRawData;
+
+ oVMExecutable -> magic[0] = 'C';
+ oVMExecutable -> magic[1] = 'T';
+ oVMExecutable -> magic[2] = 'P';
+ oVMExecutable -> magic[3] = 'P';
+
+ for(UINT_32 iI = 0; iI < 8; ++iI) { oVMExecutable -> version[iI] = 0; }
+
+ oVMExecutable -> version[0] = 2;
+
+ oVMExecutable -> entry_point = 0;
+ oVMExecutable -> code_offset = AlignSegment(sizeof(VMExecutable));
+ oVMExecutable -> code_size = iCodeSize;
+
+ // Syscalls segment // Aligned Not yet aligned
+ oVMExecutable -> syscalls_offset = oVMExecutable -> code_offset + AlignSegment(iCodeSize);
+ oVMExecutable -> syscalls_data_size = iSyscallsDataSize;
+
+ // // Aligned Not yet aligned
+ oVMExecutable -> syscalls_index_offset = oVMExecutable -> syscalls_offset + AlignSegment(iSyscallsDataSize);
+ oVMExecutable -> syscalls_index_size = iSyscallsIndexSize;
+
+ // Data segment // Aligned Not yet aligned
+ oVMExecutable -> static_data_offset = oVMExecutable -> syscalls_index_offset + AlignSegment(iSyscallsIndexSize);
+ oVMExecutable -> static_data_data_size = iStaticDataIndexSize;
+
+ // Text segment // Aligned Not yet aligned
+ oVMExecutable -> static_text_offset = oVMExecutable -> static_data_offset + AlignSegment(iStaticDataIndexSize);
+ oVMExecutable -> static_text_data_size = iStaticTextDataSize;
+
+ // // Aligned Not yet aligned
+ oVMExecutable -> static_text_index_offset = oVMExecutable -> static_text_offset + AlignSegment(iStaticTextDataSize);
+ oVMExecutable -> static_text_index_size = iStaticTextIndexSize;
+
+ // Version 2.2+
+ // Offset of static data bit index
+ oVMExecutable -> static_data_bit_index_offset = oVMExecutable -> static_text_index_offset + AlignSegment(iStaticTextIndexSize);
+ // Offset of static data bit inde
+ oVMExecutable -> static_data_bit_index_size = iStaticDataBitIndexSize;
+
+
+ // Platform-dependent data (byte order)
+ oVMExecutable -> platform = 0x4142434445464748ull;
+ oVMExecutable -> ieee754double = 15839800103804824402926068484019465486336.0;
+ oVMExecutable -> crc = 0;
+
+ // Version 2.4+
+ // Calls hash table // Aligned Not yet aligned
+ oVMExecutable -> calls_hash_table_offset = oVMExecutable -> static_data_bit_index_offset + AlignSegment(iStaticDataBitIndexSize);
+ oVMExecutable -> calls_hash_table_size = iCallsHashTableSize;
+ oVMExecutable -> calls_hash_table_power = oMemoryCore.calls_table.iPower;
+
+ // Copy code segment
+ memcpy(vRawData + oVMExecutable -> code_offset, oMemoryCore.instructions, oVMExecutable -> code_size);
+
+ // Copy syscalls, if need
+ if (oVMExecutable -> syscalls_data_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> syscalls_offset, oMemoryCore.syscalls.sData, oVMExecutable -> syscalls_data_size);
+ // Copy static text index segment
+ memcpy(vRawData + oVMExecutable -> syscalls_index_offset, oMemoryCore.syscalls.aDataOffsets, oVMExecutable -> syscalls_index_size);
+ }
+
+ // Copy static data segment, if need
+ if (oVMExecutable -> static_data_data_size != 0)
+ {
+ // Copy static data segment
+ memcpy(vRawData + oVMExecutable -> static_data_offset, oMemoryCore.static_data.aData, oVMExecutable -> static_data_data_size);
+ }
+
+ // Copy static text segment, if need
+ if (oVMExecutable -> static_text_data_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> static_text_offset, oMemoryCore.static_text.sData, oVMExecutable -> static_text_data_size);
+ // Copy static text index segment
+ memcpy(vRawData + oVMExecutable -> static_text_index_offset, oMemoryCore.static_text.aDataOffsets, oVMExecutable -> static_text_index_size);
+ }
+
+ // Copy static data bit index, if need
+ if (oVMExecutable -> static_data_bit_index_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> static_data_bit_index_offset, oMemoryCore.bit_index.GetIndexData(), oVMExecutable -> static_data_bit_index_size);
+ }
+
+ // Version 2.4+
+ // Copy Calls hash table, if need
+ if (oVMExecutable -> calls_hash_table_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> calls_hash_table_offset, oMemoryCore.calls_table.aElements, oVMExecutable -> calls_hash_table_size);
+ }
+
+ // Calculate CRC of file
+ oVMExecutable -> crc = crc32((UCCHAR_P)oVMExecutable, iVMExecutableSize);
+}
+
+//
+// Constructor
+//
+VMDumper::VMDumper(const UINT_32 iInstructions,
+ const VMInstruction * aInstructions,
+ const StaticText & oSyscalls,
+ const StaticData & oStaticData,
+ const StaticText & oStaticText,
+ const HashTable & oHashTable)
+{
+ INT_32 iSyscallsDataSize = 0;
+ if (oSyscalls.iUsedDataOffsetsSize == 0) { iSyscallsDataSize = 0; }
+ else
+ {
+ const TextDataIndex & oTMP = oSyscalls.aDataOffsets[oSyscalls.iUsedDataOffsetsSize - 1];
+ iSyscallsDataSize = oTMP.offset + oTMP.length + 1;
+ }
+
+ INT_32 iStaticTextDataSize = 0;
+ if (oStaticText.iUsedDataOffsetsSize == 0) { iStaticTextDataSize = 0; }
+ else
+ {
+ const TextDataIndex & oTMP = oStaticText.aDataOffsets[oStaticText.iUsedDataOffsetsSize - 1];
+ iStaticTextDataSize = oTMP.offset + oTMP.length + 1;
+ }
+
+ const INT_32 iCodeSize = sizeof(VMInstruction) * iInstructions;
+ const INT_32 iSyscallsIndexSize = sizeof(TextDataIndex) * oSyscalls.iUsedDataOffsetsSize;
+ const INT_32 iStaticDataIndexSize = sizeof(StaticDataVar) * oStaticData.iUsedDataSize;
+ const INT_32 iStaticTextIndexSize = sizeof(TextDataIndex) * oStaticText.iUsedDataOffsetsSize;
+ const INT_32 iStaticDataBitIndexSize = sizeof(UINT_64) + oStaticData.GetBitIndex() -> GetUsedSize();
+ const INT_32 iCallsHashTableSize = sizeof(HashElement) * (1 << oHashTable.iPower);
+
+ // Header
+ iVMExecutableSize = AlignSegment(sizeof(VMExecutable)) +
+
+ // Code segment
+ AlignSegment(iCodeSize) +
+
+ // Static syscalls segment
+ AlignSegment(iSyscallsDataSize) +
+ // Static syscalls index segment
+ AlignSegment(iSyscallsIndexSize) +
+
+ // Static Data segment
+ AlignSegment(iStaticDataIndexSize) +
+
+ // Static Text segment
+ AlignSegment(iStaticTextDataSize) +
+ // Static Text index segment
+ AlignSegment(iStaticTextIndexSize) +
+
+ // Bit index
+ AlignSegment(iStaticDataBitIndexSize) +
+
+ // Calls segment
+ AlignSegment(iCallsHashTableSize);
+
+ CHAR_P vRawData = (CHAR_P)malloc(iVMExecutableSize);
+ // Make valgind happy
+ memset(vRawData, '-', iVMExecutableSize);
+
+ oVMExecutable = (VMExecutable *)vRawData;
+
+ oVMExecutable -> magic[0] = 'C';
+ oVMExecutable -> magic[1] = 'T';
+ oVMExecutable -> magic[2] = 'P';
+ oVMExecutable -> magic[3] = 'P';
+
+ for(UINT_32 iI = 0; iI < 8; ++iI) { oVMExecutable -> version[iI] = 0; }
+
+ oVMExecutable -> version[0] = 2;
+
+ oVMExecutable -> entry_point = 0;
+ oVMExecutable -> code_offset = AlignSegment(sizeof(VMExecutable));
+ oVMExecutable -> code_size = iCodeSize;
+
+ // Syscalls segment // Aligned Not yet aligned
+ oVMExecutable -> syscalls_offset = oVMExecutable -> code_offset + AlignSegment(iCodeSize);
+ oVMExecutable -> syscalls_data_size = iSyscallsDataSize;
+
+ // // Aligned Not yet aligned
+ oVMExecutable -> syscalls_index_offset = oVMExecutable -> syscalls_offset + AlignSegment(iSyscallsDataSize);
+ oVMExecutable -> syscalls_index_size = iSyscallsIndexSize;
+
+ // Data segment // Aligned Not yet aligned
+ oVMExecutable -> static_data_offset = oVMExecutable -> syscalls_index_offset + AlignSegment(iSyscallsIndexSize);
+ oVMExecutable -> static_data_data_size = iStaticDataIndexSize;
+
+ // Text segment // Aligned Not yet aligned
+ oVMExecutable -> static_text_offset = oVMExecutable -> static_data_offset + AlignSegment(iStaticDataIndexSize);
+ oVMExecutable -> static_text_data_size = iStaticTextDataSize;
+
+ // // Aligned Not yet aligned
+ oVMExecutable -> static_text_index_offset = oVMExecutable -> static_text_offset + AlignSegment(iStaticTextDataSize);
+ oVMExecutable -> static_text_index_size = iStaticTextIndexSize;
+
+ // Version 2.2+
+ // Offset of static data bit index
+ oVMExecutable -> static_data_bit_index_offset = oVMExecutable -> static_text_index_offset + AlignSegment(iStaticTextIndexSize);
+ // Offset of static data bit inde
+ oVMExecutable -> static_data_bit_index_size = iStaticDataBitIndexSize;
+
+ // Platform-dependent data (byte order)
+ oVMExecutable -> platform = 0x4142434445464748ull;
+ oVMExecutable -> ieee754double = 15839800103804824402926068484019465486336.0;
+ oVMExecutable -> crc = 0;
+
+ // Version 2.4+
+ // Calls hash table // Aligned Not yet aligned
+ oVMExecutable -> calls_hash_table_offset = oVMExecutable -> static_data_bit_index_offset + AlignSegment(iStaticDataBitIndexSize);
+ oVMExecutable -> calls_hash_table_size = iCallsHashTableSize;
+ oVMExecutable -> calls_hash_table_power = oHashTable.iPower;
+
+ // Copy code segment
+ memcpy(vRawData + oVMExecutable -> code_offset, aInstructions, oVMExecutable -> code_size);
+
+ // Copy syscalls, if need
+ if (oVMExecutable -> syscalls_data_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> syscalls_offset, oSyscalls.sData, oVMExecutable -> syscalls_data_size);
+ // Copy static text index segment
+ memcpy(vRawData + oVMExecutable -> syscalls_index_offset, oSyscalls.aDataOffsets, oVMExecutable -> syscalls_index_size);
+ }
+
+ // Copy static data segment, if need
+ if (oVMExecutable -> static_data_data_size != 0)
+ {
+ // Copy static data segment
+ memcpy(vRawData + oVMExecutable -> static_data_offset, oStaticData.aData, oVMExecutable -> static_data_data_size);
+ }
+
+ // Copy static text segment, if need
+ if (oVMExecutable -> static_text_data_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> static_text_offset, oStaticText.sData, oVMExecutable -> static_text_data_size);
+ // Copy static text index segment
+ memcpy(vRawData + oVMExecutable -> static_text_index_offset, oStaticText.aDataOffsets, oVMExecutable -> static_text_index_size);
+ }
+
+ // Copy static data bit index, if need
+ if (oVMExecutable -> static_data_bit_index_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> static_data_bit_index_offset, oStaticData.GetBitIndex() -> GetIndexData(), oVMExecutable -> static_data_bit_index_size);
+ }
+
+ // Version 2.4+
+ // Copy Calls hash table, if need
+ if (oVMExecutable -> calls_hash_table_size != 0)
+ {
+ memcpy(vRawData + oVMExecutable -> calls_hash_table_offset, oHashTable.aElements, oVMExecutable -> calls_hash_table_size);
+ }
+
+ // Calculate CRC of file
+ oVMExecutable -> crc = crc32((UCCHAR_P)oVMExecutable, iVMExecutableSize);
+}
+
+//
+// Get constructed executable
+//
+const VMExecutable * VMDumper::GetExecutable(UINT_32 & iExecutableSize)
+{
+ iExecutableSize = iVMExecutableSize;
+
+return oVMExecutable;
+}
+
+//
+// A destructor
+//
+VMDumper::~VMDumper()
+{
+ free(oVMExecutable);
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMException.cpp b/src/CTPP2VMException.cpp
new file mode 100644
index 0000000..43e5dff
--- /dev/null
+++ b/src/CTPP2VMException.cpp
@@ -0,0 +1,322 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMException.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2VMException.hpp"
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class VMException
+//
+//
+
+//
+// A virtual destructor
+//
+VMException::~VMException() throw() { ;; }
+
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class IllegalOpcode
+//
+//
+
+//
+// Constructor
+//
+IllegalOpcode::IllegalOpcode(const UINT_32 iIIP,
+ const UINT_32 iIOpcode,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName): iIP(iIIP),
+ iOpcode(iIOpcode),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P IllegalOpcode::what() const throw() { return "Illegal opcode called"; }
+
+//
+// Get instruction pointer
+//
+UINT_32 IllegalOpcode::GetIP() const throw() { return iIP; }
+
+//
+// Get instruction code
+//
+UINT_32 IllegalOpcode::GetOpcode() const throw() { return iOpcode; }
+
+//
+// Get debug information
+//
+UINT_64 IllegalOpcode::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P IllegalOpcode::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A destructor
+//
+IllegalOpcode::~IllegalOpcode() throw()
+{
+ free(szSourceName);
+}
+
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class InvalidSyscall
+//
+//
+
+//
+// Constructor
+//
+InvalidSyscall::InvalidSyscall(CCHAR_P szISyscall,
+ const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName): szSyscall(szISyscall),
+ iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P InvalidSyscall::what() const throw() { return szSyscall; }
+
+//
+// Get instruction pointer
+//
+UINT_32 InvalidSyscall::GetIP() const throw() { return iIP; }
+
+//
+// Get debug information
+//
+UINT_64 InvalidSyscall::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P InvalidSyscall::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A destructor
+//
+InvalidSyscall::~InvalidSyscall() throw()
+{
+ free(szSourceName);
+}
+
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class CodeSegmentOverrun
+//
+//
+
+//
+// Constructor
+//
+CodeSegmentOverrun::CodeSegmentOverrun(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P CodeSegmentOverrun::what() const throw() { return "Instruction pointer out of code segment"; }
+
+//
+// Get instruction pointer
+//
+UINT_32 CodeSegmentOverrun::GetIP() const throw() { return iIP; }
+
+//
+// Get debug information
+//
+UINT_64 CodeSegmentOverrun::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P CodeSegmentOverrun::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A destructor
+//
+CodeSegmentOverrun::~CodeSegmentOverrun() throw()
+{
+ free(szSourceName);
+}
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class ExecutionLimitReached
+//
+
+//
+// Constructor
+//
+ExecutionLimitReached::ExecutionLimitReached(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P ExecutionLimitReached::what() const throw() { return "Execution limit reached"; }
+
+//
+// Get instruction pointer
+//
+UINT_32 ExecutionLimitReached::GetIP() const throw() { return iIP; }
+
+//
+// Get debug information
+//
+UINT_64 ExecutionLimitReached::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P ExecutionLimitReached::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A destructor
+//
+ExecutionLimitReached::~ExecutionLimitReached() throw()
+{
+ free(szSourceName);
+}
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class ZeroDivision
+//
+
+//
+// Constructor
+//
+ZeroDivision::ZeroDivision(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szISourceName): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P ZeroDivision::what() const throw() { return "Division by zero"; }
+
+//
+// Get instruction pointer
+//
+UINT_32 ZeroDivision::GetIP() const throw() { return iIP; }
+
+//
+// Get debug information
+//
+UINT_64 ZeroDivision::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P ZeroDivision::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A virtual destructor
+//
+ZeroDivision::~ZeroDivision() throw()
+{
+ free(szSourceName);
+}
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class InvalidCall
+//
+
+//
+// Constructor
+//
+InvalidCall::InvalidCall(const UINT_32 iIIP,
+ const UINT_64 iIDebugInfo,
+ CCHAR_P szICallName,
+ CCHAR_P szISourceName): iIP(iIIP),
+ iDebugInfo(iIDebugInfo),
+ szCallName(strdup(szICallName)),
+ szSourceName(strdup(szISourceName)) { ;; }
+
+//
+// Get human-readable error description
+//
+CCHAR_P InvalidCall::what() const throw() { return szCallName; }
+
+//
+// Get instruction pointer
+//
+UINT_32 InvalidCall::GetIP() const throw() { return iIP; }
+
+//
+// Get debug information
+//
+UINT_64 InvalidCall::GetDebugInfo() const throw() { return iDebugInfo; }
+
+//
+// Get name of template
+//
+CCHAR_P InvalidCall::GetSourceName() const throw() { return szSourceName; }
+
+//
+// A destructor
+//
+InvalidCall::~InvalidCall() throw()
+{
+ free(szCallName);
+ free(szSourceName);
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMExecutable.cpp b/src/CTPP2VMExecutable.cpp
new file mode 100644
index 0000000..239d27f
--- /dev/null
+++ b/src/CTPP2VMExecutable.cpp
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMExecutable.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMExecutable.hpp"
+
+#include "CTPP2BitIndex.hpp"
+#include "CTPP2HashTable.hpp"
+#include "CTPP2StaticData.hpp"
+#include "CTPP2StaticText.hpp"
+#include "CTPP2VMInstruction.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Get start of code segment
+//
+const VMInstruction * VMExecutable::GetCodeSeg(const VMExecutable * oVMExecutable) { return (VMInstruction *)( (CCHAR_P)oVMExecutable + oVMExecutable -> code_offset ); }
+
+//
+// Get start of syscalls segment
+//
+CCHAR_P VMExecutable::GetSyscallsSeg(const VMExecutable * oVMExecutable) { return ( (CCHAR_P)oVMExecutable + oVMExecutable -> syscalls_offset ); }
+
+//
+// Get start of syscalls index segment
+//
+const TextDataIndex * VMExecutable::GetSyscallsIndexSeg(const VMExecutable * oVMExecutable) { return (TextDataIndex *)( (CCHAR_P)oVMExecutable + oVMExecutable -> syscalls_index_offset ) ; }
+
+//
+// Get start of static data segment
+//
+const StaticDataVar * VMExecutable::GetStaticDataSeg(const VMExecutable * oVMExecutable) { return (StaticDataVar *)( (CCHAR_P)oVMExecutable + oVMExecutable -> static_data_offset ); }
+
+//
+// Get start of static data bit index
+//
+const BitIndexData * VMExecutable::GetStaticDataBitIndex(const VMExecutable * oVMExecutable) { return (BitIndexData *)( (CCHAR_P)oVMExecutable + oVMExecutable -> static_data_bit_index_offset ); }
+
+//
+// Get start of static text segment
+//
+CCHAR_P VMExecutable::GetStaticTextSeg(const VMExecutable * oVMExecutable) { return ( (CCHAR_P)oVMExecutable + oVMExecutable -> static_text_offset ); }
+
+//
+// Get start of static text index segment
+//
+const TextDataIndex * VMExecutable::GetStaticTextIndexSeg(const VMExecutable * oVMExecutable) { return (TextDataIndex *) ( (CCHAR_P)oVMExecutable + oVMExecutable -> static_text_index_offset ); }
+
+//
+// Get calls hash table
+//
+const HashElement * VMExecutable::GetCallsTable(const VMExecutable * oVMExecutable) { return (HashElement *)( (CCHAR_P)oVMExecutable + oVMExecutable -> calls_hash_table_offset); }
+
+//
+// Get calls hash table size
+//
+UINT_32 VMExecutable::GetCallsTablePower(const VMExecutable * oVMExecutable) { return oVMExecutable -> calls_hash_table_power; }
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMFileLoader.cpp b/src/CTPP2VMFileLoader.cpp
new file mode 100644
index 0000000..c888c39
--- /dev/null
+++ b/src/CTPP2VMFileLoader.cpp
@@ -0,0 +1,252 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMFileLoader.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMFileLoader.hpp"
+
+#include "CTPP2Util.hpp"
+#include "CTPP2Exception.hpp"
+#include "CTPP2VMExecutable.hpp"
+#include "CTPP2VMInstruction.hpp"
+#include "CTPP2VMMemoryCore.hpp"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Convert byte order
+//
+static void ConvertExecutable(VMExecutable * oCore)
+{
+ // Code entry point
+ oCore -> entry_point = Swap32(oCore -> entry_point);
+ // Offset of code segment
+ oCore -> code_offset = Swap32(oCore -> code_offset);
+
+ // Code segment size
+ oCore -> code_size = Swap32(oCore -> code_size);
+
+ // Offset of static text segment
+ oCore -> syscalls_offset = Swap32(oCore -> syscalls_offset);
+ // Static text segment size
+ oCore -> syscalls_data_size = Swap32(oCore -> syscalls_data_size);
+
+ // Offset of static text index segment
+ oCore -> syscalls_index_offset = Swap32(oCore -> syscalls_index_offset);
+ // Static text index segment size
+ oCore -> syscalls_index_size = Swap32(oCore -> syscalls_index_size);
+
+ // Offset of static data segment
+ oCore -> static_data_offset = Swap32(oCore -> static_data_offset);
+
+ // Static data segment size
+ oCore -> static_data_data_size = Swap32(oCore -> static_data_data_size);
+
+ // Offset of static text segment
+ oCore -> static_text_offset = Swap32(oCore -> static_text_offset);
+ // Static text segment size
+ oCore -> static_text_data_size = Swap32(oCore -> static_text_data_size);
+
+ // Offset of static text index segment
+ oCore -> static_text_index_offset = Swap32(oCore -> static_text_index_offset);
+ // Static text index segment size
+ oCore -> static_text_index_size = Swap32(oCore -> static_text_index_size);
+
+ // Version 2.2+
+ // Offset of static data bit index
+ oCore -> static_data_bit_index_offset = Swap32(oCore -> static_data_bit_index_offset);
+ /// Offset of static data bit index
+ oCore -> static_data_bit_index_size = Swap32(oCore -> static_data_bit_index_size);
+
+ // Platform
+ oCore -> platform = Swap64(oCore -> platform);
+
+ // Ugly-jolly hack!
+ // ... dereferencing type-punned pointer will break strict-aliasing rules ...
+ UINT_64 iTMP;
+ memcpy(&iTMP, &(oCore -> ieee754double), sizeof(UINT_64));
+ iTMP = Swap64(iTMP);
+ memcpy(&(oCore -> ieee754double), &iTMP, sizeof(UINT_64));
+
+ // Cyclic Redundancy Check
+ oCore -> crc = 0;
+
+ // Convert data structures
+
+ // Convert code segment
+ VMInstruction * pInstructions = const_cast<VMInstruction *>(VMExecutable::GetCodeSeg(oCore));
+ UINT_32 iI = 0;
+ UINT_32 iSteps = oCore -> code_size / sizeof(VMInstruction);
+ for(iI = 0; iI < iSteps; ++iI)
+ {
+ pInstructions -> instruction = Swap32(pInstructions -> instruction);
+ pInstructions -> argument = Swap32(pInstructions -> argument);
+ pInstructions -> reserved = Swap64(pInstructions -> reserved);
+ ++pInstructions;
+ }
+
+ // Convert syscalls index
+ TextDataIndex * pTextIndex = const_cast<TextDataIndex *>(VMExecutable::GetSyscallsIndexSeg(oCore));
+ iSteps = oCore -> syscalls_index_size / sizeof(TextDataIndex);
+ for(iI = 0; iI < iSteps; ++iI)
+ {
+ pTextIndex -> offset = Swap32(pTextIndex -> offset);
+ pTextIndex -> length = Swap32(pTextIndex -> length);
+ ++pTextIndex;
+ }
+
+ // Convert static text index
+ pTextIndex = const_cast<TextDataIndex *>(VMExecutable::GetStaticTextIndexSeg(oCore));
+ iSteps = oCore -> static_text_index_size / sizeof(TextDataIndex);
+ for(iI = 0; iI < iSteps; ++iI)
+ {
+ pTextIndex -> offset = Swap32(pTextIndex -> offset);
+ pTextIndex -> length = Swap32(pTextIndex -> length);
+ ++pTextIndex;
+ }
+
+ // Convert static data
+ StaticDataVar * pStaticDataVar = const_cast<StaticDataVar *>(VMExecutable::GetStaticDataSeg(oCore));
+ iSteps = oCore -> static_data_data_size / sizeof(StaticDataVar);
+ for(iI = 0; iI < iSteps; ++iI)
+ {
+ (*pStaticDataVar).i_data = Swap64((*pStaticDataVar).i_data);
+ ++pStaticDataVar;
+ }
+}
+
+//
+// Constructor
+//
+VMFileLoader::VMFileLoader(CCHAR_P szFileName)
+{
+ // Get file size
+ struct stat oStat;
+ if (stat(szFileName, &oStat) == -1) { throw CTPPUnixException("stat", errno); }
+ if (oStat.st_size == 0) { throw CTPPLogicError("Cannot get size of file"); }
+
+ // Load file
+ FILE * F = fopen(szFileName, "rb");
+ if (F == NULL) { throw CTPPUnixException("fopen", errno); }
+
+ // Allocate memory
+ oCore = (VMExecutable *)malloc(oStat.st_size);
+ // Read from file
+ if (fread(oCore, oStat.st_size, 1, F) != 1)
+ {
+ fclose(F);
+ throw CTPPUnixException("fread", errno);
+ }
+
+ // All Done
+ fclose(F);
+
+ if (oCore -> magic[0] == 'C' &&
+ oCore -> magic[1] == 'T' &&
+ oCore -> magic[2] == 'P' &&
+ oCore -> magic[3] == 'P')
+ {
+ // Check version
+ if (oCore -> version[0] >= 1)
+ {
+ // Platform-dependent data (byte order)
+ if (oCore -> platform == 0x4142434445464748ull)
+ {
+#ifdef _DEBUG
+ fprintf(stderr, "Big/Little Endian conversion: Nothing to do\n");
+#endif
+
+ // Nothing to do, only check crc
+ UINT_32 iCRC = oCore -> crc;
+ oCore -> crc = 0;
+
+ // Calculate CRC of file
+ if (iCRC != crc32((UCCHAR_P)oCore, oStat.st_size))
+ {
+ free(oCore);
+ throw CTPPLogicError("CRC checksum invalid");
+ }
+ }
+ // Platform-dependent data (byte order)
+ else if (oCore -> platform == 0x4847464544434241ull)
+ {
+ // Need to reconvert data
+#ifdef _DEBUG
+ fprintf(stderr, "Big/Little Endian conversion: Need to reconvert core\n");
+#endif
+ ConvertExecutable(oCore);
+ }
+ else
+ {
+ free(oCore);
+ throw CTPPLogicError("Conversion of middle-end architecture does not supported.");
+ }
+
+ // Check IEEE 754 format
+ if (oCore -> ieee754double != 15839800103804824402926068484019465486336.0)
+ {
+ free(oCore);
+ throw CTPPLogicError("IEEE 754 format is broken, cannot convert file");
+ }
+ }
+
+ pVMMemoryCore = new VMMemoryCore(oCore);
+ }
+ else
+ {
+ free(oCore);
+ throw CTPPLogicError("Not an CTPP bytecode file.");
+ }
+}
+
+//
+// Get ready-to-run program
+//
+const VMMemoryCore * VMFileLoader::GetCore() const { return pVMMemoryCore; }
+
+//
+// A destructor
+//
+VMFileLoader::~VMFileLoader() throw()
+{
+ delete pVMMemoryCore;
+ free(oCore);
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMMemoryCore.cpp b/src/CTPP2VMMemoryCore.cpp
new file mode 100644
index 0000000..e3bb6a1
--- /dev/null
+++ b/src/CTPP2VMMemoryCore.cpp
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMMemoryCore.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2VMMemoryCore.hpp"
+
+#include "CTPP2VMExecutable.hpp"
+#include "CTPP2VMInstruction.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+//
+// Constructor
+//
+VMMemoryCore::VMMemoryCore(const VMExecutable * pVMExecutable): code_size(pVMExecutable -> code_size / sizeof(VMInstruction)),
+ // Code segment
+ instructions(VMExecutable::GetCodeSeg(pVMExecutable)),
+ // Syscalls
+ syscalls(VMExecutable::GetSyscallsSeg(pVMExecutable),
+ pVMExecutable -> syscalls_index_size / sizeof(TextDataIndex),
+ VMExecutable::GetSyscallsIndexSeg(pVMExecutable)),
+ // Static data
+ static_data(VMExecutable::GetStaticDataSeg(pVMExecutable),
+ pVMExecutable -> static_data_data_size / sizeof(StaticDataVar)),
+ // Static text
+ static_text(VMExecutable::GetStaticTextSeg(pVMExecutable),
+ pVMExecutable -> static_text_index_size / sizeof(TextDataIndex),
+ VMExecutable::GetStaticTextIndexSeg(pVMExecutable)),
+ // Bit index
+ bit_index(VMExecutable::GetStaticDataBitIndex(pVMExecutable)),
+ // hash table
+ calls_table(VMExecutable::GetCallsTable(pVMExecutable),
+ VMExecutable::GetCallsTablePower(pVMExecutable))
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMOpcodeCollector.cpp b/src/CTPP2VMOpcodeCollector.cpp
new file mode 100644
index 0000000..b670f36
--- /dev/null
+++ b/src/CTPP2VMOpcodeCollector.cpp
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMOpcodeCollector.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMOpcodeCollector.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Remove instruction from top of code segment
+//
+INT_32 VMOpcodeCollector::Remove()
+{
+ STLW::vector<VMInstruction>::iterator itvCodeSeg = oCodeSeg.end();
+ --itvCodeSeg;
+ oCodeSeg.erase(itvCodeSeg);
+
+return oCodeSeg.size() - 1;
+}
+
+//
+// Insert instruction into code segment
+//
+INT_32 VMOpcodeCollector::Insert(const VMInstruction & oInstruction)
+{
+ oCodeSeg.push_back(oInstruction);
+
+return oCodeSeg.size() - 1;
+}
+
+//
+// Get compiled
+//
+const VMInstruction * VMOpcodeCollector::GetCode(UINT_32 & iCodeSize)
+{
+ iCodeSize = oCodeSeg.size();
+
+ if (iCodeSize == 0) { return NULL; }
+
+return &oCodeSeg[0];
+}
+
+//
+// Get instruction by instruction number
+//
+VMInstruction * VMOpcodeCollector::GetInstruction(const UINT_32 & iIP)
+{
+ if (iIP >= oCodeSeg.size()) { return NULL; }
+
+return &oCodeSeg[iIP];
+}
+
+//
+// Get last instruction number
+//
+UINT_32 VMOpcodeCollector::GetCodeSize() const { return oCodeSeg.size(); }
+
+//
+// A destructor
+//
+VMOpcodeCollector::~VMOpcodeCollector() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMSTDLib.cpp b/src/CTPP2VMSTDLib.cpp
new file mode 100644
index 0000000..93c6fcb
--- /dev/null
+++ b/src/CTPP2VMSTDLib.cpp
@@ -0,0 +1,239 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMSTDLib.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CTPP2VMSTDLib.hpp"
+
+#include "CDT.hpp"
+#include "CTPP2Util.hpp"
+#include "CTPP2OutputCollector.hpp"
+#include "CTPP2StaticData.hpp"
+#include "CTPP2StaticText.hpp"
+#include "CTPP2SyscallFactory.hpp"
+
+#include "CTPP2VMSTDLibFunctions.hpp"
+
+#include <errno.h>
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+
+#if defined(MD5_SUPPORT) && !defined(WIN32)
+ #ifdef MD5_WITHOUT_OPENSSL
+ #include <md5.h>
+ #define MD5_Init MD5Init
+ #define MD5_Update MD5Update
+ #define MD5_Final MD5Final
+ #else
+ #include <openssl/md5.h>
+ #endif
+#endif // defined(MD5_SUPPORT) && !defined(WIN32)
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Initialize all functions in library
+//
+void STDLibInitializer::InitLibrary(SyscallFactory & oSyscallFactory)
+{
+ CCHAR_P * aFunctions = STDLibInitializer::GetFnList();
+ while (*aFunctions != NULL)
+ {
+ oSyscallFactory.RegisterHandler(STDLibInitializer::CreateHandler(*aFunctions));
+ ++aFunctions;
+ }
+}
+
+//
+// Destroy all functions in library
+//
+void STDLibInitializer::DestroyLibrary(SyscallFactory & oSyscallFactory)
+{
+ CCHAR_P * aFunctions = STDLibInitializer::GetFnList();
+ while (*aFunctions != NULL)
+ {
+ STDLibInitializer::DestroyHandler(oSyscallFactory.GetHandlerByName(*aFunctions));
+ oSyscallFactory.RemoveHandler(*aFunctions);
+ ++aFunctions;
+ }
+}
+
+//
+// Get list of available functions
+//
+CCHAR_P * STDLibInitializer::GetFnList() { return aSTDFNList; }
+
+//
+// Create handler by name
+//
+SyscallHandler * STDLibInitializer::CreateHandler(CCHAR_P szHandler)
+{
+ if (strcasecmp(CTPP2_INT_HANDLER_PREFIX "_emitter", szHandler) == 0) { return new FnEmitter(); }
+ else if (strcasecmp("avg", szHandler) == 0) { return new FnAvg(); }
+ else if (strcasecmp("base64_encode", szHandler) == 0) { return new FnBase64Encode(); }
+ else if (strcasecmp("base64_decode", szHandler) == 0) { return new FnBase64Decode(); }
+ else if (strcasecmp("cast", szHandler) == 0) { return new FnCast(); }
+ else if (strcasecmp("concat", szHandler) == 0) { return new FnConcat(); }
+ else if (strcasecmp("context", szHandler) == 0) { return new FnContext(); }
+ else if (strcasecmp("date_format", szHandler) == 0) { return new FnDateFormat(); }
+ else if (strcasecmp("default", szHandler) == 0) { return new FnDefault(); }
+ else if (strcasecmp("defined", szHandler) == 0) { return new FnDefined(); }
+ else if (strcasecmp("error", szHandler) == 0) { return new FnError(); }
+ else if (strcasecmp("form_param", szHandler) == 0) { return new FnFormParam(); }
+ else if (strcasecmp("_", szHandler) == 0) { return new FnGetText("_"); }
+ else if (strcasecmp("gettext", szHandler) == 0) { return new FnGetText(); }
+ else if (strcasecmp("get_type", szHandler) == 0) { return new FnGetType(); }
+ else if (strcasecmp("hash_keys", szHandler) == 0) { return new FnHashKeys(); }
+#ifdef MD5_SUPPORT
+ else if (strcasecmp("hmac_md5", szHandler) == 0) { return new FnHMACMD5(); }
+#endif
+ else if (strcasecmp("href_param", szHandler) == 0) { return new FnHrefParam(); }
+ else if (strcasecmp("hostname", szHandler) == 0) { return new FnHostname(); }
+ else if (strcasecmp("htmlescape", szHandler) == 0) { return new FnHTMLEscape(); }
+#ifdef ICONV_SUPPORT
+ else if (strcasecmp("iconv", szHandler) == 0) { return new FnIconv(); }
+#endif
+ else if (strcasecmp("in_set", szHandler) == 0) { return new FnInSet(); }
+ else if (strcasecmp("in_array", szHandler) == 0) { return new FnInArray(); }
+ else if (strcasecmp("json", szHandler) == 0) { return new FnJSON(); }
+ else if (strcasecmp("jsonescape", szHandler) == 0) { return new FnJSONEscape(); }
+ else if (strcasecmp("list", szHandler) == 0) { return new FnList(); }
+ else if (strcasecmp("list_element", szHandler) == 0) { return new FnListElement(); }
+ else if (strcasecmp("log", szHandler) == 0) { return new FnLog(); }
+#ifdef MD5_SUPPORT
+ else if (strcasecmp("md5", szHandler) == 0) { return new FnMD5(); }
+#endif
+ else if (strcasecmp("min", szHandler) == 0) { return new FnMin(); }
+ else if (strcasecmp("max", szHandler) == 0) { return new FnMax(); }
+ else if (strcasecmp("mb_size", szHandler) == 0) { return new FnMBSize(); }
+ else if (strcasecmp("mb_substr", szHandler) == 0) { return new FnMBSubstring(); }
+ else if (strcasecmp("mb_truncate", szHandler) == 0) { return new FnMBTruncate(); }
+ else if (strcasecmp("num_format", szHandler) == 0) { return new FnNumFormat(); }
+ else if (strcasecmp("obj_dump", szHandler) == 0) { return new FnObjDump(); }
+ else if (strcasecmp("random", szHandler) == 0) { return new FnRandom(); }
+ else if (strcasecmp("size", szHandler) == 0) { return new FnSize(); }
+ else if (strcasecmp("sprintf", szHandler) == 0) { return new FnSprintf(); }
+ else if (strcasecmp("substr", szHandler) == 0) { return new FnSubstring(); }
+ else if (strcasecmp("truncate", szHandler) == 0) { return new FnTruncate(); }
+ else if (strcasecmp("uriescape", szHandler) == 0) { return new FnURIEscape(); }
+ else if (strcasecmp("urlescape", szHandler) == 0) { return new FnURLEscape(); }
+ else if (strcasecmp("version", szHandler) == 0) { return new FnVersion(); }
+ else if (strcasecmp("wmlescape", szHandler) == 0) { return new FnWMLEscape(); }
+ else if (strcasecmp("xmlescape", szHandler) == 0) { return new FnXMLEscape(); }
+
+#ifdef PCRE_SUPPORT
+// else if (strcasecmp("re_m", szHandler) == 0) { return new FnReM(); }
+#endif
+// else if (strcasecmp("bb_code", szHandler) == 0) { return new FnBBCode(); }
+
+return NULL;
+}
+
+//
+// Destroy Handler
+//
+void STDLibInitializer::DestroyHandler(SyscallHandler * pHandler) { delete pHandler; }
+
+//
+// List of standard functions
+//
+CCHAR_P STDLibInitializer::aSTDFNList[] =
+{
+ CTPP2_INT_HANDLER_PREFIX "_emitter",
+ "avg",
+ "base64_encode",
+ "base64_decode",
+ "cast",
+ "concat",
+ "context",
+ "date_format",
+ "default",
+ "defined",
+ "error",
+ "form_param",
+ "_",
+ "gettext",
+ "get_type",
+ "hash_keys",
+ "href_param",
+#ifdef MD5_SUPPORT
+ "hmac_md5",
+#endif
+ "hostname",
+ "htmlescape",
+#ifdef ICONV_SUPPORT
+ "iconv",
+#endif
+ "in_set",
+ "in_array",
+ "jsonescape",
+ "json",
+ "list",
+ "list_element",
+ "log",
+#ifdef MD5_SUPPORT
+ "md5",
+#endif
+ "min",
+ "max",
+ "mb_size",
+ "mb_substr",
+ "mb_truncate",
+ "num_format",
+ "obj_dump",
+ "random",
+ "size",
+ "sprintf",
+ "substr",
+ "truncate",
+ "uriescape",
+ "urlescape",
+ "version",
+ "xmlescape",
+ "wmlescape",
+
+ NULL
+};
+
+} // namespace CTPP
+// End.
diff --git a/src/CTPP2VMSyscall.cpp b/src/CTPP2VMSyscall.cpp
new file mode 100644
index 0000000..f1d8eea
--- /dev/null
+++ b/src/CTPP2VMSyscall.cpp
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMSyscall.cpp
+ *
+ * $CTPP$
+ */
+#include "CTPP2VMSyscall.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Pre-execution handler setup
+//
+INT_32 SyscallHandler::PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger) { return 0; }
+
+//
+// Global Handler initialization
+//
+INT_32 SyscallHandler::InitHandler(CDT & oCDT) { return 0; }
+
+//
+// Get API version
+//
+INT_32 SyscallHandler::GetVersion() const { return 0; }
+
+//
+// Handler resources destructor
+//
+INT_32 SyscallHandler::DestroyHandler(CDT & oCDT) throw() { return 0; }
+
+//
+// A destructor
+//
+SyscallHandler::~SyscallHandler() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnAvg.cpp b/src/functions/FnAvg.cpp
new file mode 100644
index 0000000..6930a2b
--- /dev/null
+++ b/src/functions/FnAvg.cpp
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnAvg.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnAvg.hpp"
+
+#include <math.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnAvg::FnAvg()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnAvg::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Need at least 2 args
+ if (iArgNum < 2)
+ {
+ oLogger.Emerg("Usage: AVG(flag, a[, b, ...])");
+ return -1;
+ }
+
+ // First Arg 1: destination type
+ const STLW::string & sWhat = aArguments[iArgNum - 1].GetString();
+ if (sWhat.length() == 0)
+ {
+ oLogger.Error("The first argument should be 'a', 'A', 'g', 'G', 'h', 'H', 'q' or 'Q', but is `%s`", sWhat.c_str());
+ return -1;
+ }
+
+ // http://en.wikipedia.org/wiki/Average
+ switch (sWhat[0])
+ {
+ // Arithmetic
+ case 'A':
+ case 'a':
+ {
+ W_FLOAT dSum = 0.0;
+ for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
+ {
+ dSum += aArguments[iPos].GetFloat();
+ }
+ oCDTRetVal = dSum / (iArgNum - 1);
+ }
+ break;
+
+ // Geometric
+ case 'G':
+ case 'g':
+ {
+ W_FLOAT dSum = 1.0;
+ for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
+ {
+ dSum *= aArguments[iPos].GetFloat();
+ }
+ oCDTRetVal = pow(dSum, 1.0 / (iArgNum - 1));
+ }
+ break;
+
+ // Harmonic
+ case 'H':
+ case 'h':
+ {
+ W_FLOAT dSum = 0.0;
+ for(INT_32 iPos = iArgNum - 2; iPos >= 0 ; --iPos)
+ {
+ const W_FLOAT dTMP = aArguments[iPos].GetFloat();
+ if (dTMP == 0.0) { dSum = 0; break; }
+ dSum += 1.0 / dTMP;
+ }
+ oCDTRetVal = 1.0 * (iArgNum - 1) / dSum;
+ }
+ break;
+
+ // Quadratic
+ case 'Q':
+ case 'q':
+ {
+ W_FLOAT dSum = 0.0;
+ for(INT_32 iPos = iArgNum - 1; iPos >= 0 ; --iPos)
+ {
+ const W_FLOAT dTMP = aArguments[iPos].GetFloat();
+ dSum += dTMP * dTMP;
+ }
+ oCDTRetVal = sqrt(dSum / (iArgNum - 1));
+ }
+ break;
+
+ default:
+ oLogger.Error("The first argument should be 'a', 'A', 'g', 'G', 'h', 'H', 'q' or 'Q', but is `%s`", sWhat.c_str());
+ return -1;
+ }
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnAvg::GetName() const { return "avg"; }
+
+//
+// A destructor
+//
+FnAvg::~FnAvg() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnBase64Decode.cpp b/src/functions/FnBase64Decode.cpp
new file mode 100644
index 0000000..d693d06
--- /dev/null
+++ b/src/functions/FnBase64Decode.cpp
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnBase64Decode.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnBase64Decode.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnBase64Decode::FnBase64Decode()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnBase64Decode::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 1 argument
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: BASE64_DECODE(x)");
+ return -1;
+ }
+
+ oCDTRetVal = Base64Decode(aArguments[0].GetString());
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnBase64Decode::GetName() const { return "base64_decode"; }
+
+//
+// A destructor
+//
+FnBase64Decode::~FnBase64Decode() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnBase64Encode.cpp b/src/functions/FnBase64Encode.cpp
new file mode 100644
index 0000000..55a1488
--- /dev/null
+++ b/src/functions/FnBase64Encode.cpp
@@ -0,0 +1,80 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnBase64Encode.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnBase64Encode.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnBase64Encode::FnBase64Encode()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnBase64Encode::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 1 argument
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: BASE64_ENCODE(x)");
+ return -1;
+ }
+
+ oCDTRetVal = Base64Encode(aArguments[0].GetString());
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnBase64Encode::GetName() const { return "base64_encode"; }
+
+//
+// A destructor
+//
+FnBase64Encode::~FnBase64Encode() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnCast.cpp b/src/functions/FnCast.cpp
new file mode 100644
index 0000000..19c9b2a
--- /dev/null
+++ b/src/functions/FnCast.cpp
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnCast.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnCast.hpp"
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnCast::FnCast()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnCast::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // 2 arguments need
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: CAST(flag, x)");
+ return -1;
+ }
+
+ // Arg 1: destination type
+ const STLW::string & sWhat = aArguments[1].GetString();
+ if (sWhat.length() == 0)
+ {
+ oLogger.Error("The last argument should be 's', 'S', 'o', 'O', 'd', 'D', 'i', 'I', 'h', 'H', 'f' or 'F', but is `%s`", sWhat.c_str());
+ return -1;
+ }
+
+ CDT & oTMP = aArguments[0];
+ switch(sWhat[0])
+ {
+ // S[tring]
+ case 'S':
+ case 's':
+ oCDTRetVal = oTMP.GetString();
+ return 0;
+
+ // O[ct[al]]
+ case 'o':
+ case 'O':
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oCDTRetVal = oTMP.GetInt(); return 0; }
+ else if (oTMP.GetType() == CDT::STRING_VAL)
+ {
+ unsigned long long iLL = 0;
+ sscanf(oTMP.GetString().c_str(), "%llo", &iLL);
+ oCDTRetVal = INT_64(iLL);
+ return 0;
+ }
+ oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
+ return -1;
+
+ // D[ec[imal]]
+ case 'd':
+ case 'D':
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oCDTRetVal = oTMP.GetInt(); return 0; }
+ else if (oTMP.GetType() == CDT::STRING_VAL)
+ {
+ long long iLL = 0;
+ sscanf(oTMP.GetString().c_str(), "%lld", &iLL);
+ oCDTRetVal = INT_64(iLL);
+ return 0;
+ }
+ oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
+ return -1;
+
+ // I[nt[eger]]
+ case 'i':
+ case 'I':
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oCDTRetVal = oTMP.GetInt(); return 0; }
+ else if (oTMP.GetType() == CDT::STRING_VAL)
+ {
+ long long iLL = 0;
+ sscanf(oTMP.GetString().c_str(), "%lli", &iLL);
+ oCDTRetVal = INT_64(iLL);
+ return 0;
+ }
+ oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
+ return -1;
+
+ // H[ex[adecimal]]
+ case 'H':
+ case 'h':
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oCDTRetVal = oTMP.GetInt(); return 0; }
+ else if (oTMP.GetType() == CDT::STRING_VAL)
+ {
+ unsigned long long iLL = 0;
+ sscanf(oTMP.GetString().c_str(), "%llx", &iLL);
+ oCDTRetVal = INT_64(iLL);
+ return 0;
+ }
+ oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
+ return -1;
+
+ // F[loat]
+ case 'F':
+ case 'f':
+ if (oTMP.GetType() <= CDT::REAL_VAL) { oCDTRetVal = oTMP.GetFloat(); return 0; }
+ else if (oTMP.GetType() == CDT::STRING_VAL)
+ {
+ double dVal = 0;
+ sscanf(oTMP.GetString().c_str(), "%lg", &dVal);
+ oCDTRetVal = dVal;
+ return 0;
+ }
+ oLogger.Error("Invalid source type of first argument. Should be INT, REAL or STRING, but is `%s`", oTMP.PrintableType());
+ return -1;
+
+ // Error
+ default:
+ oLogger.Error("The last argument should be 's', 'S', 'o', 'O', 'd', 'D', 'i', 'I', 'h', 'H', 'f' or 'F', but is `%s`", sWhat.c_str());
+ return -1;
+ }
+}
+
+//
+// Get function name
+//
+CCHAR_P FnCast::GetName() const { return "cast"; }
+
+//
+// A destructor
+//
+FnCast::~FnCast() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnConcat.cpp b/src/functions/FnConcat.cpp
new file mode 100644
index 0000000..fbe7827
--- /dev/null
+++ b/src/functions/FnConcat.cpp
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnConcat.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "FnConcat.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnConcat::FnConcat()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnConcat::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Check number of parameters
+ if (iArgNum == 0) { oCDTRetVal = ""; return 0; }
+
+ if (iArgNum == 1) { oCDTRetVal = aArguments[0].GetString(); return 0; }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = sResult;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnConcat::GetName() const { return "concat"; }
+
+//
+// A destructor
+//
+FnConcat::~FnConcat() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnContext.cpp b/src/functions/FnContext.cpp
new file mode 100644
index 0000000..c3b3c2a
--- /dev/null
+++ b/src/functions/FnContext.cpp
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnContext.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnContext.hpp"
+
+#include <math.h>
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnContext::FnContext(): pCDT(NULL)
+{
+ ;;
+}
+
+//
+// Pre-execution handler setup
+//
+INT_32 FnContext::PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger)
+{
+ pCDT = &oCDT;
+
+return 0;
+}
+
+//
+// Handler
+//
+INT_32 FnContext::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum != 0)
+ {
+ oLogger.Emerg("Usage: CONTEXT()");
+ return -1;
+ }
+ oCDTRetVal = *pCDT;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnContext::GetName() const { return "context"; }
+
+//
+// A destructor
+//
+FnContext::~FnContext() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnDateFormat.cpp b/src/functions/FnDateFormat.cpp
new file mode 100644
index 0000000..0f49185
--- /dev/null
+++ b/src/functions/FnDateFormat.cpp
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDateFormat.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnDateFormat.hpp"
+
+#include <time.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnDateFormat::FnDateFormat()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnDateFormat::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 2 arguments
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: DATE_FORMAT(x, format)");
+ return -1;
+ }
+
+ // Temp
+ CHAR_8 szBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ time_t iTime = aArguments[1].GetInt();
+
+ const struct tm * pTM = localtime(&iTime);
+
+ if (strftime(szBuffer, CTPP_ESCAPE_BUFFER_LEN, aArguments[0].GetString().c_str(), pTM) == 0)
+ {
+ oLogger.Error("Can't format: DATE_FORMAT(%s, '%s')", aArguments[1].GetString().c_str(), aArguments[0].GetString().c_str());
+ return -1;
+ }
+
+ oCDTRetVal = szBuffer;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnDateFormat::GetName() const { return "date_format"; }
+
+//
+// A destructor
+//
+FnDateFormat::~FnDateFormat() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnDefault.cpp b/src/functions/FnDefault.cpp
new file mode 100644
index 0000000..e116aae
--- /dev/null
+++ b/src/functions/FnDefault.cpp
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDefault.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnDefault.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnDefault::FnDefault()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnDefault::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // At least one argument need
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: DEFAULT(x, y)");
+ return -1;
+ }
+
+ // Set default value from second argument, if need
+ if (aArguments[1].Nonzero()) { oCDTRetVal = aArguments[1]; }
+ else { oCDTRetVal = aArguments[0]; }
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnDefault::GetName() const { return "default"; }
+
+//
+// A destructor
+//
+FnDefault::~FnDefault() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnDefined.cpp b/src/functions/FnDefined.cpp
new file mode 100644
index 0000000..099c324
--- /dev/null
+++ b/src/functions/FnDefined.cpp
@@ -0,0 +1,89 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnDefined.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnDefined.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnDefined::FnDefined()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnDefined::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // At least one argument need
+ if (iArgNum == 0)
+ {
+ oLogger.Emerg("Usage: DEFINED(a[, b, ...])");
+ return -1;
+ }
+
+ oCDTRetVal = 1;
+
+ INT_32 iI = iArgNum - 1;
+ for (; iI >= 0; --iI)
+ {
+ if (aArguments[iI].GetType() == CDT::UNDEF)
+ {
+ oCDTRetVal = 0;
+ break;
+ }
+ }
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnDefined::GetName() const { return "defined"; }
+
+//
+// A destructor
+//
+FnDefined::~FnDefined() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnEmitter.cpp b/src/functions/FnEmitter.cpp
new file mode 100644
index 0000000..22eda5d
--- /dev/null
+++ b/src/functions/FnEmitter.cpp
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnEmitter.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "FnEmitter.hpp"
+
+#include <math.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnEmitter::FnEmitter(): pCDT(NULL)
+{
+ ;;
+}
+
+//
+// Pre-execution handler setup
+//
+INT_32 FnEmitter::PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger)
+{
+ pCDT = &oCDT;
+
+return 0;
+}
+
+//
+// Handler
+//
+INT_32 FnEmitter::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ oCDTRetVal = *pCDT;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnEmitter::GetName() const { return CTPP2_INT_HANDLER_PREFIX "_emitter"; }
+
+//
+// A destructor
+//
+FnEmitter::~FnEmitter() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnError.cpp b/src/functions/FnError.cpp
new file mode 100644
index 0000000..d04c70f
--- /dev/null
+++ b/src/functions/FnError.cpp
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnError.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnError.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnError::FnError()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnError::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ oLogger.Emerg("Function ERROR() always produces runtime error");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnError::GetName() const { return "error"; }
+
+//
+// A destructor
+//
+FnError::~FnError() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnFormParam.cpp b/src/functions/FnFormParam.cpp
new file mode 100644
index 0000000..ce28757
--- /dev/null
+++ b/src/functions/FnFormParam.cpp
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnFormParam.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnFormParam.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnFormParam::FnFormParam()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnFormParam::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: FORM_PARAM(x, y)");
+ return -1;
+ }
+
+ oCDTRetVal = "<input type=\"hidden\" name=\"";
+ oCDTRetVal.Append(HTMLEscape(aArguments[1].GetString()));
+ oCDTRetVal.Append("\" value=\"");
+ oCDTRetVal.Append(HTMLEscape(aArguments[0].GetString()));
+ oCDTRetVal.Append("\" />");
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnFormParam::GetName() const { return "form_param"; }
+
+//
+// A destructor
+//
+FnFormParam::~FnFormParam() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnGetText.cpp b/src/functions/FnGetText.cpp
new file mode 100644
index 0000000..71e35a8
--- /dev/null
+++ b/src/functions/FnGetText.cpp
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnGetText.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnGetText.hpp"
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <strings.h>
+#endif
+#include "CTPP2GetText.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnGetText::FnGetText(CCHAR_P szAlias) : pGetText(NULL), szFuncName(strdup(szAlias))
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnGetText::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (pGetText == NULL)
+ {
+ oLogger.Emerg("GetText object is NULL");
+ return -1;
+ }
+
+ if (iArgNum == 1)
+ {
+ oCDTRetVal = pGetText -> FindMessage(sLanguage, aArguments[0].GetString());
+ return 0;
+ }
+ else if (iArgNum == 2)
+ {
+ oCDTRetVal = pGetText -> FindMessage(sLanguage, aArguments[1].GetString(), aArguments[0].GetString());
+ return 0;
+ }
+ else if (iArgNum == 3)
+ {
+ oCDTRetVal = pGetText -> FindPluralMessage(sLanguage, aArguments[2].GetString(),
+ aArguments[1].GetString(), (UINT_32)aArguments[0].GetUInt());
+ return 0;
+ }
+ else if (iArgNum == 4)
+ {
+ oCDTRetVal = pGetText -> FindPluralMessage(sLanguage, aArguments[3].GetString(), aArguments[2].GetString(),
+ (UINT_32)aArguments[1].GetUInt(), aArguments[0].GetString());
+ return 0;
+ }
+
+ STLW::string sTMP(szFuncName);
+
+ for (UINT_32 iI = 0; iI < sTMP.size(); ++iI) { sTMP[iI] = toupper(sTMP[iI]); }
+ STLW::string sMsg = "Usage: " + sTMP + "(msgid[, msgid_plural, n][, domain])";
+
+ oLogger.Emerg(sMsg.c_str());
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnGetText::GetName() const { return szFuncName; }
+
+//
+// A destructor
+//
+FnGetText::~FnGetText() throw() { free(szFuncName); }
+
+//
+// Set GetText object
+//
+void FnGetText::SetGetText(CTPP2GetText * pGetText_) { pGetText = pGetText_; }
+
+//
+// Set language of translation
+//
+void FnGetText::SetLanguage(const STLW::string & sLang) { sLanguage = sLang; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnGetType.cpp b/src/functions/FnGetType.cpp
new file mode 100644
index 0000000..e4ff678
--- /dev/null
+++ b/src/functions/FnGetType.cpp
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnGetType.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnGetType.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnGetType::FnGetType()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnGetType::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // At least one argument need
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: GET_TYPE(x)");
+ return -1;
+ }
+
+ oCDTRetVal = aArguments[0].PrintableType();
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnGetType::GetName() const { return "get_type"; }
+
+//
+// A destructor
+//
+FnGetType::~FnGetType() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnHMACMD5.cpp b/src/functions/FnHMACMD5.cpp
new file mode 100644
index 0000000..f671a58
--- /dev/null
+++ b/src/functions/FnHMACMD5.cpp
@@ -0,0 +1,315 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHMACMD5.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnHMACMD5.hpp"
+
+#ifdef MD5_SUPPORT
+ #ifndef WIN32
+ #ifdef MD5_WITHOUT_OPENSSL
+ #include <md5.h>
+ #define MD5_Init MD5Init
+ #define MD5_Update MD5Update
+ #define MD5_Final MD5Final
+ #else
+ #include <openssl/md5.h>
+ #endif
+ #endif // ifndef WIN32
+#endif // MD5_SUPPORT
+
+namespace CTPP // C++ Template Engine
+{
+#ifdef MD5_SUPPORT
+//
+// Constructor
+//
+FnHMACMD5::FnHMACMD5()
+{
+#ifdef WIN32
+ // http://msdn.microsoft.com/en-us/library/aa382375(VS.85).aspx
+ // Get a handle to the default PROV_RSA_FULL provider.
+ if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0))
+ {
+ // Okay
+ }
+ else
+ {
+ if (GetLastError() == NTE_BAD_KEYSET)
+ {
+ // No default container was found. Attempt to create it.
+ if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ {
+ // Okay
+ }
+ else
+ {
+ throw CTPPUnixException("Could not create the default key container.", GetLastError());
+ }
+ }
+ else
+ {
+ throw CTPPUnixException("A general error running CryptAcquireContext", GetLastError());
+ }
+ }
+#else
+ ;;
+#endif
+}
+
+//
+// Handler
+//
+#ifndef WIN32
+INT_32 FnHMACMD5::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ static CHAR_8 aHex[] = "0123456789abcdef";
+ CHAR_8 szMD5[32];
+
+ // Only 2 args allowed
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: HMAC_MD5(x, key)");
+ return -1;
+ }
+
+ MD5_CTX oContext;
+ UCHAR_8 sIPad[65];
+ UCHAR_8 sOPad[65];
+
+ // Construct key
+ STLW::string sKey = aArguments[0].GetString();
+ // If key is longer than 64 bytes reset it to key=MD5(key)
+ if (sKey.size() > 64)
+ {
+ UCHAR_8 sTempKey[16];
+ MD5_Init(&oContext);
+ MD5_Update(&oContext, sKey.data(), sKey.size());
+ MD5_Final(sTempKey, &oContext);
+
+ sKey.assign((CCHAR_P)sTempKey, 16);
+ }
+
+ /*
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ */
+ UINT_32 iI = 0;
+ for(; iI < sKey.size(); ++iI)
+ {
+ sIPad[iI] = 0x36 ^ UCHAR_8(sKey[iI]);
+ sOPad[iI] = 0x5C ^ UCHAR_8(sKey[iI]);
+ }
+
+ for(; iI < 64; ++iI)
+ {
+ sIPad[iI] = 0x36;
+ sOPad[iI] = 0x5C;
+ }
+
+ unsigned char sDigest[16];
+
+ STLW::string sSource = aArguments[1].GetString();
+ // Inner MD5
+ MD5_Init(&oContext);
+ MD5_Update(&oContext, sIPad, 64);
+ MD5_Update(&oContext, sSource.data(), sSource.size());
+ MD5_Final(sDigest, &oContext);
+
+ // Outer MD5
+ MD5_Init(&oContext);
+ MD5_Update(&oContext, sOPad, 64);
+ MD5_Update(&oContext, sDigest, 16);
+ MD5_Final(sDigest, &oContext);
+
+ INT_32 iJ = 0;
+ for (iI = 0; iI < 16; ++iI)
+ {
+ szMD5[ iJ++] = aHex[ (sDigest[iI] >> 4 )& 0x0F ];
+ szMD5[ iJ++] = aHex[ sDigest[iI] & 0x0F ];
+ }
+
+ // Okay
+ oCDTRetVal = STLW::string(szMD5, 32);
+
+return 0;
+}
+
+#else // WIN32
+
+INT_32 FnHMACMD5::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ static CHAR_8 aHex[] = "0123456789abcdef";
+ CHAR_8 szMD5[32];
+ // >0 arguments need
+ if (iArgNum != 2 || hCryptProv == 0) { return -1; }
+
+ HCRYPTHASH hHash;
+ UCHAR_8 sIPad[65];
+ UCHAR_8 sOPad[65];
+
+ // Construct key
+ STLW::string sKey = aArguments[0].GetString();
+ // If key is longer than 64 bytes reset it to key=MD5(key)
+ if (sKey.size() > 64)
+ {
+ if (::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash) == 0) { return -1; }
+
+ if (::CryptHashData(hHash, (BYTE *)sKey.c_str(), (DWORD)sKey.size(), 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ BYTE sDigest[16];
+ DWORD dwCount = 16;
+ if (::CryptGetHashParam(hHash, HP_HASHVAL, sDigest, &dwCount, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+ ::CryptDestroyHash(hHash);
+ sKey.assign((CCHAR_P)sDigest, 16);
+ }
+
+ /*
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ */
+ UINT_32 iI = 0;
+ for(; iI < sKey.size(); ++iI)
+ {
+ sIPad[iI] = 0x36 ^ UCHAR_8(sKey[iI]);
+ sOPad[iI] = 0x5C ^ UCHAR_8(sKey[iI]);
+ }
+
+ for(; iI < 64; ++iI)
+ {
+ sIPad[iI] = 0x36;
+ sOPad[iI] = 0x5C;
+ }
+
+
+ BYTE sDigest[16];
+ DWORD dwCount = 16;
+
+ STLW::string sSource = aArguments[1].GetString();
+ // Inner MD5
+ if (::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash) == 0) { return -1; }
+
+ if (::CryptHashData(hHash, (BYTE *)sIPad, (DWORD)64, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ if (::CryptHashData(hHash, (BYTE *)sSource.data(), (DWORD)sSource.size(), 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ if (::CryptGetHashParam(hHash, HP_HASHVAL, sDigest, &dwCount, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+ ::CryptDestroyHash(hHash);
+
+ if (::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash) == 0) { return -1; }
+
+ if (::CryptHashData(hHash, (BYTE *)sOPad, (DWORD)64, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ if (::CryptHashData(hHash, (BYTE *)sDigest, (DWORD)16, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ if (::CryptGetHashParam(hHash, HP_HASHVAL, sDigest, &dwCount, 0) == 0)
+ {
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+ ::CryptDestroyHash(hHash);
+
+ INT_32 iJ = 0;
+ for (iI = 0; iI < 16; ++iI)
+ {
+ szMD5[ iJ++] = aHex[ (sDigest[iI] >> 4 )& 0x0F ];
+ szMD5[ iJ++] = aHex[ sDigest[iI] & 0x0F ];
+ }
+
+ // Okay
+ oCDTRetVal = STLW::string(szMD5, 32);
+
+return 0;
+}
+#endif // WIN32
+//
+// Get function name
+//
+CCHAR_P FnHMACMD5::GetName() const { return "hmac_md5"; }
+
+//
+// A destructor
+//
+FnHMACMD5::~FnHMACMD5() throw()
+{
+#ifdef WIN32
+ if (hCryptProv != 0) { ::CryptReleaseContext(hCryptProv, 0); }
+#else
+ ;;
+#endif
+}
+
+#endif // MD5_SUPPORT
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnHTMLEscape.cpp b/src/functions/FnHTMLEscape.cpp
new file mode 100644
index 0000000..8a756a7
--- /dev/null
+++ b/src/functions/FnHTMLEscape.cpp
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHTMLEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnHTMLEscape.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+//
+// Constructor
+//
+FnHTMLEscape::FnHTMLEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnHTMLEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: HTMLESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = HTMLEscape(sResult);
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnHTMLEscape::GetName() const { return "htmlescape"; }
+
+//
+// A destructor
+//
+FnHTMLEscape::~FnHTMLEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnHashKeys.cpp b/src/functions/FnHashKeys.cpp
new file mode 100644
index 0000000..7eaf665
--- /dev/null
+++ b/src/functions/FnHashKeys.cpp
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHashKeys.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnHashKeys.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnHashKeys::FnHashKeys()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnHashKeys::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 1 args allowed
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: HASH_KEYS(x)");
+ return -1;
+ }
+
+ // Second argument *MUST* be an HASH
+ if (aArguments[0].GetType() != CDT::HASH_VAL)
+ {
+ STLW::string msg = STLW::string("Second argument MUST be HASH, no ") + aArguments[0].PrintableType();
+ oLogger.Error(msg.c_str());
+ return -1;
+ }
+
+ oCDTRetVal = aArguments[0].GetHashKeys();
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnHashKeys::GetName() const { return "hash_keys"; }
+
+//
+// A destructor
+//
+FnHashKeys::~FnHashKeys() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnHostname.cpp b/src/functions/FnHostname.cpp
new file mode 100644
index 0000000..c6bf0d0
--- /dev/null
+++ b/src/functions/FnHostname.cpp
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHostname.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnHostname.hpp"
+
+#ifdef _MSC_VER
+#include <Winsock2.h>
+#else
+#include <unistd.h>
+#endif
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif // HOST_NAME_MAX
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnHostname::FnHostname()
+{
+ CHAR_8 szHostname[HOST_NAME_MAX + 1];
+
+ INT_32 iRC = gethostname(szHostname, HOST_NAME_MAX);
+
+ if (iRC == 0) { sHostName.assign(szHostname); }
+ else { sHostName.assign("unknown"); }
+}
+
+//
+// Handler
+//
+INT_32 FnHostname::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // At least one argument need
+ if (iArgNum != 0)
+ {
+ oLogger.Emerg("Usage: HOSTNAME()");
+ return -1;
+ }
+
+ // Set default value from second argument, if need
+ oCDTRetVal = sHostName;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnHostname::GetName() const { return "hostname"; }
+
+//
+// A destructor
+//
+FnHostname::~FnHostname() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnHrefParam.cpp b/src/functions/FnHrefParam.cpp
new file mode 100644
index 0000000..bfce6ca
--- /dev/null
+++ b/src/functions/FnHrefParam.cpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnHrefParam.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnHrefParam.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnHrefParam::FnHrefParam()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnHrefParam::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: HREF_PARAM(x, y)");
+ return -1;
+ }
+
+ oCDTRetVal = URLEscape(aArguments[1].GetString());
+ oCDTRetVal.Append("=");
+ oCDTRetVal.Append(URLEscape(aArguments[0].GetString()));
+ oCDTRetVal.Append("&amp;");
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnHrefParam::GetName() const { return "href_param"; }
+
+//
+// A destructor
+//
+FnHrefParam::~FnHrefParam() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnIconv.cpp b/src/functions/FnIconv.cpp
new file mode 100644
index 0000000..49d8ed1
--- /dev/null
+++ b/src/functions/FnIconv.cpp
@@ -0,0 +1,227 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnIconv.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnIconv.hpp"
+
+#include <errno.h>
+
+namespace CTPP // C++ Template Engine
+{
+#ifdef ICONV_SUPPORT
+
+#ifndef C_ICONV_DISCARD_ILSEQ
+#define C_ICONV_DISCARD_ILSEQ 0x00000001
+#endif
+
+#ifndef C_ICONV_TRANSLITERATE
+#define C_ICONV_TRANSLITERATE 0x00000002
+#endif
+
+//
+// Constructor
+//
+FnIconv::FnIconv()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnIconv::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ UINT_32 iMyArgNum = iArgNum;
+
+ // 3 or 4 arguments need
+ if (iMyArgNum != 3 && iMyArgNum != 4)
+ {
+ oLogger.Emerg("Usage: ICONV(x, src, dst[, flags])");
+ return -1;
+ }
+
+ // Arg 3: flags
+ // Arg 2: destination charset
+ // Arg 1: source charset
+ // Arg 0: string to convert
+
+ UINT_32 iFlags = 0;
+
+#ifdef ICONV_DISCARD_ILSEQ
+ iFlags |= C_ICONV_DISCARD_ILSEQ;
+#endif
+
+#ifdef ICONV_TRANSLITERATE
+ iFlags |= C_ICONV_TRANSLITERATE;
+#endif
+
+ if (iMyArgNum == 4)
+ {
+ const STLW::string & sFlags = aArguments[0].GetString();
+ for (UINT_32 iPos = 0; iPos < sFlags.size(); ++iPos)
+ {
+ switch (sFlags[iPos])
+ {
+ // Discard illegal sequence and continue
+ case 'i':
+ case 'I':
+ iFlags |= C_ICONV_DISCARD_ILSEQ;
+ break;
+
+ // Enable transliteration
+ case 't':
+ case 'T':
+ iFlags |= C_ICONV_TRANSLITERATE;
+ break;
+
+ default:
+ oLogger.Error("Last argument should be 'i', 'I', 't' or 'T', but is `%s`", sFlags.c_str());
+ return -1;
+ }
+ }
+ }
+
+ const STLW::string & sTo = aArguments[--iMyArgNum].GetString();
+ const STLW::string & sFrom = aArguments[--iMyArgNum].GetString();
+ const STLW::string & sWhat = aArguments[--iMyArgNum].GetString();
+
+ STLW::string sFromTo(sFrom);
+ sFromTo.append(sTo);
+
+ iconv_t oIconvConverter = (iconv_t)(-1);
+
+ STLW::map<STLW::string, iconv_t>::iterator itmIconvMap = mIconvMap.find(sFromTo);
+ if (itmIconvMap != mIconvMap.end()) { oIconvConverter = itmIconvMap -> second; }
+ // Try to open iconv converter
+ else
+ {
+ oIconvConverter = iconv_open(sFrom.c_str(), sTo.c_str());
+
+ if (oIconvConverter != (iconv_t)(-1)) { mIconvMap[sFromTo] = oIconvConverter; }
+ else
+ {
+ if (errno == EINVAL)
+ {
+ oLogger.Error("The conversion from `%s` to `%s` is not supported by the implementation", sFrom.c_str(), sTo.c_str());
+ }
+ else
+ {
+ oLogger.Error("Error(%d) in iconv_open('%s', '%s'): %s", sFrom.c_str(), sTo.c_str(), strerror(errno));
+ }
+ return -1;
+ }
+ }
+
+#if (_LIBICONV_VERSION >= 0x0108)
+ int iFlag = 1;
+ // Discard illegal characters
+ if (iFlags & C_ICONV_DISCARD_ILSEQ)
+ {
+ if (iconvctl(oIconvConverter, ICONV_SET_DISCARD_ILSEQ, &iFlag) == -1)
+ {
+ oLogger.Error("ICONV_SET_DISCARD_ILSEQ is is not supported by the implementation");
+ return -1;
+ }
+ }
+
+ // nable transliteration in the conver-sion
+ if (iFlags & C_ICONV_TRANSLITERATE)
+ {
+ if (iconvctl(oIconvConverter, ICONV_SET_TRANSLITERATE, &iFlag) == -1)
+ {
+ oLogger.Error("ICONV_SET_TRANSLITERATE is is not supported by the implementation");
+ return -1;
+ }
+ }
+#endif
+
+ // Allocate memory
+ size_t iSrcLength = sWhat.size();
+ size_t iDstLength = CTPP_ESCAPE_BUFFER_LEN;
+
+ char aDstData[CTPP_ESCAPE_BUFFER_LEN];
+#if defined(linux) || defined(__APPLE__)
+ char * aSrcData = (char *)sWhat.data();
+#else
+ const char * aSrcData = (const char *)sWhat.data();
+#endif
+ STLW::string sResult;
+ for (;;)
+ {
+ char * aDstTMP = aDstData;
+ size_t iDstLengthTMP = iDstLength;
+ size_t iResult = iconv(oIconvConverter, &aSrcData, &iSrcLength, &aDstTMP, &iDstLengthTMP);
+
+ if (aDstTMP - aDstData > 0) { sResult.append(aDstData, aDstTMP - aDstData); }
+
+ // All data converted?
+ if (iResult != (size_t)-1) { break; }
+ else
+ {
+ if (errno != E2BIG)
+ {
+ ++aSrcData;
+ --iSrcLength;
+ }
+ }
+ }
+
+ oCDTRetVal = sResult;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnIconv::GetName() const { return "iconv"; }
+
+//
+// A destructor
+//
+FnIconv::~FnIconv() throw()
+{
+ STLW::map<STLW::string, iconv_t>::iterator itmIconvMap = mIconvMap.begin();
+ while (itmIconvMap != mIconvMap.end())
+ {
+ iconv_close(itmIconvMap -> second);
+ ++itmIconvMap;
+ }
+}
+
+#endif // ICONV_SUPPORT
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnInArray.cpp b/src/functions/FnInArray.cpp
new file mode 100644
index 0000000..2567cd8
--- /dev/null
+++ b/src/functions/FnInArray.cpp
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnInArray.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnInArray.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnInArray::FnInArray()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnInArray::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 2 args allowed
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: IN_ARRAY(x, array)");
+ return -1;
+ }
+
+ // Second argument *MUST* be an ARRAY
+ if (aArguments[0].GetType() == CDT::UNDEF)
+ {
+ oCDTRetVal = 0;
+ return 0;
+ }
+ else if (aArguments[0].GetType() != CDT::ARRAY_VAL)
+ {
+ oLogger.Error("Second argument MUST be ARRAY");
+ return -1;
+ }
+
+ INT_32 iSize = aArguments[0].Size();
+ for (INT_32 iI = 0; iI < iSize; ++iI)
+ {
+ if (aArguments[1].Equal(aArguments[0][iI]))
+ {
+ oCDTRetVal = 1;
+ return 0;
+ }
+ }
+
+ oCDTRetVal = 0;
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnInArray::GetName() const { return "in_array"; }
+
+//
+// A destructor
+//
+FnInArray::~FnInArray() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnInSet.cpp b/src/functions/FnInSet.cpp
new file mode 100644
index 0000000..4c8cd45
--- /dev/null
+++ b/src/functions/FnInSet.cpp
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnInSet.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnInSet.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnInSet::FnInSet()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnInSet::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum <= 1)
+ {
+ oLogger.Emerg("Usage: IN_SET(x, a[, b, ...])");
+ return -1;
+ }
+
+ INT_32 iI = iArgNum - 1;
+
+ CDT & oCDT1 = aArguments[iI];
+
+ --iI;
+ for (; iI >= 0; --iI)
+ {
+ if (oCDT1.Equal(aArguments[iI]))
+ {
+ oCDTRetVal = 1;
+ return 0;
+ }
+ }
+
+ oCDTRetVal = 0;
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnInSet::GetName() const { return "in_set"; }
+
+//
+// A destructor
+//
+FnInSet::~FnInSet() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnJSON.cpp b/src/functions/FnJSON.cpp
new file mode 100644
index 0000000..f37e00e
--- /dev/null
+++ b/src/functions/FnJSON.cpp
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnJSON.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnJSON.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnJSON::FnJSON()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnJSON::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: JSON(x)");
+ return -1;
+ }
+
+ STLW::string sData;
+
+ CDT2JSON(aArguments[0], sData);
+
+ oCDTRetVal = sData;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnJSON::GetName() const { return "json"; }
+
+//
+// A destructor
+//
+FnJSON::~FnJSON() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnJSONEscape.cpp b/src/functions/FnJSONEscape.cpp
new file mode 100644
index 0000000..e05ab59
--- /dev/null
+++ b/src/functions/FnJSONEscape.cpp
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnJSONEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnJSONEscape.hpp"
+
+#include <math.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnJSONEscape::FnJSONEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnJSONEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: JSONESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos)
+ {
+ switch (aArguments[iPos].GetType())
+ {
+ case CDT::UNDEF:
+ sResult.append("null", 4);
+ break;
+
+ case CDT::INT_VAL:
+ case CDT::REAL_VAL:
+ case CDT::POINTER_VAL:
+ case CDT::STRING_INT_VAL:
+ case CDT::STRING_REAL_VAL:
+ sResult.append(aArguments[iPos].GetString());
+ break;
+
+ case CDT::STRING_VAL:
+ sResult.append(EscapeJSONString(aArguments[iPos].GetString(), true, false));
+ break;
+
+ default:
+ oLogger.Emerg("Invalid type %s", aArguments[iPos].PrintableType());
+ return -1;
+ }
+ }
+ oCDTRetVal = sResult;
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnJSONEscape::GetName() const { return "jsonescape"; }
+
+//
+// A destructor
+//
+FnJSONEscape::~FnJSONEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnList.cpp b/src/functions/FnList.cpp
new file mode 100644
index 0000000..5c3d7eb
--- /dev/null
+++ b/src/functions/FnList.cpp
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnList.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnList.hpp"
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class FnList
+//
+
+//
+// Constructor
+//
+FnList::FnList()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnList::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ oCDTRetVal = CDT(CDT::ARRAY_VAL);
+ for (INT_32 iI = iArgNum - 1; iI >= 0; --iI) { oCDTRetVal.PushBack(aArguments[iI]); }
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnList::GetName() const { return "list"; }
+
+//
+// A destructor
+//
+FnList::~FnList() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnListElement.cpp b/src/functions/FnListElement.cpp
new file mode 100644
index 0000000..2f4983e
--- /dev/null
+++ b/src/functions/FnListElement.cpp
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnListElement.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnListElement.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Class FnListElement
+//
+
+//
+// Constructor
+//
+FnListElement::FnListElement()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnListElement::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum <= 1)
+ {
+ oLogger.Emerg("Usage: LIST_ELEMENT(a[, b, ...], x)");
+ return -1;
+ }
+
+ // Element index
+ const UINT_32 iLastElement = iArgNum - 1;
+
+ // Element
+ const UINT_32 iElement = aArguments[iLastElement].GetInt();
+
+ // Element does not exist?
+ if (iElement >= iLastElement) { return -1; }
+
+ // Return element
+ oCDTRetVal = aArguments[iLastElement - iElement - 1];
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnListElement::GetName() const { return "list_element"; }
+
+//
+// A destructor
+//
+FnListElement::~FnListElement() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnLog.cpp b/src/functions/FnLog.cpp
new file mode 100644
index 0000000..b0c46e1
--- /dev/null
+++ b/src/functions/FnLog.cpp
@@ -0,0 +1,92 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnLog.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnLog.hpp"
+
+#include <math.h>
+
+namespace CTPP // C++ Template Engine
+{
+//
+// Constructor
+//
+FnLog::FnLog()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnLog::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Natural logarithm
+ if (iArgNum == 1)
+ {
+ // NaN
+ oCDTRetVal = log(aArguments[0].GetFloat());
+ return 0;
+ }
+ // Logarithm with specified base
+ else if (iArgNum == 2)
+ {
+ const W_FLOAT dBase = aArguments[0].GetFloat();
+ const W_FLOAT dValue = aArguments[1].GetFloat();
+
+ // NaN
+ if (dBase <= 0) { return (INT_32)log((W_FLOAT)-1); }
+
+ oCDTRetVal = log(dValue) / log(dBase);
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: LOG(x[, base])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnLog::GetName() const { return "log"; }
+
+//
+// A destructor
+//
+FnLog::~FnLog() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMBSize.cpp b/src/functions/FnMBSize.cpp
new file mode 100644
index 0000000..4fe8f43
--- /dev/null
+++ b/src/functions/FnMBSize.cpp
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnVersion.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnMBSize.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+//
+// Constructor
+//
+FnMBSize::FnMBSize()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnMBSize::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // At least one argument need
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: MB_SIZE(x)");
+ return -1;
+ }
+
+ if (aArguments[0].GetType() != CDT::STRING_VAL) { oCDTRetVal = aArguments[0].Size(); }
+ else
+ {
+ const STLW::string sData = aArguments[0].GetString();
+
+ CCHAR_P szStart = sData.data();
+ CCHAR_P szEnd = szStart + sData.size();
+ INT_32 iPos = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+
+ ++iCharPos;
+ iPos += iCharLen;
+ }
+ oCDTRetVal = iCharPos;
+ }
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnMBSize::GetName() const { return "mb_size"; }
+
+//
+// A destructor
+//
+FnMBSize::~FnMBSize() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMBSubstring.cpp b/src/functions/FnMBSubstring.cpp
new file mode 100644
index 0000000..a9545a0
--- /dev/null
+++ b/src/functions/FnMBSubstring.cpp
@@ -0,0 +1,180 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMBSubstring.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnMBSubstring.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnMBSubstring::FnMBSubstring()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnMBSubstring::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Check number of parameters
+ if (iArgNum == 0) { oCDTRetVal = ""; return 0; }
+
+ // substr('foobar', 2) -> 'obar'
+ if (iArgNum == 2)
+ {
+ const UINT_32 iOffset = UINT_32(aArguments[0].GetInt());
+ const STLW::string sResult = aArguments[1].GetString();
+
+ CCHAR_P szStart = sResult.data();
+ CCHAR_P szEnd = sResult.data() + sResult.size();
+ INT_32 iPos = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+ // Skip errors
+ else { ++iCharPos; }
+ iPos += iCharLen;
+
+ if (iCharPos >= iOffset) { break; }
+ }
+
+ if (iCharPos < iOffset) { oCDTRetVal = ""; }
+ else { oCDTRetVal = sResult.substr(iPos); }
+
+ return 0;
+ }
+ // substr('foobar', 2, 3) -> 'oba'
+ if (iArgNum == 3)
+ {
+ const UINT_32 iBytes = UINT_32(aArguments[0].GetInt());
+ const UINT_32 iOffset = UINT_32(aArguments[1].GetInt());
+ const STLW::string sResult = aArguments[2].GetString();
+
+ CCHAR_P szStart = sResult.data();
+ CCHAR_P szEnd = sResult.data() + sResult.size();
+ INT_32 iPos = 0;
+ UINT_32 iCharOffset = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+ // Skip errors
+ else { ++iCharPos; }
+ iPos += iCharLen;
+
+ if (iCharPos == iOffset) { iCharOffset = iPos; }
+
+ if (iCharPos == iOffset + iBytes) { break; }
+ }
+
+ if (sResult.size() < iCharOffset) { oCDTRetVal = ""; }
+ else { oCDTRetVal = sResult.substr(iCharOffset, iPos - iCharOffset); }
+
+ return 0;
+ }
+ // substr('foobar', 2, 3, '1234567') -> 'fo1234567r'
+ if (iArgNum == 4)
+ {
+ STLW::string sReplacement = aArguments[0].GetString();
+ const UINT_32 iBytes = UINT_32(aArguments[1].GetInt());
+ const UINT_32 iOffset = UINT_32(aArguments[2].GetInt());
+ const STLW::string sTMP = aArguments[3].GetString();
+
+ CCHAR_P szStart = sTMP.data();
+ CCHAR_P szEnd = sTMP.data() + sTMP.size();
+ UINT_32 iPos = 0;
+ UINT_32 iCharOffset = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+ // Skip errors
+ else { ++iCharPos; }
+ iPos += iCharLen;
+
+ if (iCharPos == iOffset) { iCharOffset = iPos; }
+
+ if (iCharPos == iOffset + iBytes) { break; }
+ }
+ if (sTMP.size() < iCharOffset) { oCDTRetVal = ""; return 0; }
+
+ STLW::string sResult(sTMP, 0, iCharOffset);
+ sResult.append(sReplacement);
+
+ if (iPos == sTMP.size()) { oCDTRetVal = sResult; return 0; }
+
+ sResult.append(sTMP, iPos, STLW::string::npos);
+ oCDTRetVal = sResult;
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: MB_SUBSTR(x, offset[, bytes[, y]]])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnMBSubstring::GetName() const { return "mb_substr"; }
+
+//
+// A destructor
+//
+FnMBSubstring::~FnMBSubstring() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMBTruncate.cpp b/src/functions/FnMBTruncate.cpp
new file mode 100644
index 0000000..431ae4f
--- /dev/null
+++ b/src/functions/FnMBTruncate.cpp
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMBTruncate.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnMBTruncate.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnMBTruncate::FnMBTruncate()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnMBTruncate::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 2)
+ {
+ const UINT_32 iMaxLen = UINT_32(aArguments[0].GetInt());
+ const STLW::string sData = aArguments[1].GetString();
+
+ CCHAR_P szStart = sData.data();
+ CCHAR_P szEnd = sData.data() + sData.size();
+ INT_32 iPos = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+ // Skip errors
+ else { ++iCharPos; }
+ iPos += iCharLen;
+
+ if (iCharPos >= iMaxLen) { break; }
+ }
+
+ if (iCharPos == iMaxLen) { oCDTRetVal = STLW::string(sData, 0, iPos); }
+ else { oCDTRetVal = sData; }
+
+ return 0;
+ }
+ else if (iArgNum == 3)
+ {
+ const UINT_32 iMaxLen = UINT_32(aArguments[1].GetInt());
+ STLW::string sData = aArguments[2].GetString();
+
+ CCHAR_P szStart = sData.data();
+ CCHAR_P szEnd = sData.data() + sData.size();
+ INT_32 iPos = 0;
+ UINT_32 iCharPos = 0;
+ for(;;)
+ {
+ INT_32 iCharLen = utf_charlen(szStart + iPos, szEnd);
+
+ if (iCharLen == -3) { break; }
+
+ // Check character length
+ if (iCharLen < 0) { iCharLen = 1; }
+ // Skip errors
+ else { ++iCharPos; }
+ iPos += iCharLen;
+
+ if (iCharPos >= iMaxLen) { break; }
+ }
+ if (iCharPos >= iMaxLen)
+ {
+ sData = STLW::string(sData, 0, iPos);
+ sData.append(aArguments[0].GetString());
+ }
+
+ oCDTRetVal = sData;
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: MB_TRUNCATE (x, offest[, addon])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnMBTruncate::GetName() const { return "mb_truncate"; }
+
+//
+// A destructor
+//
+FnMBTruncate::~FnMBTruncate() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMD5.cpp b/src/functions/FnMD5.cpp
new file mode 100644
index 0000000..257ba3f
--- /dev/null
+++ b/src/functions/FnMD5.cpp
@@ -0,0 +1,218 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMD5.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnMD5.hpp"
+
+#ifdef MD5_SUPPORT
+ #ifndef WIN32
+ #ifdef MD5_WITHOUT_OPENSSL
+ #include <md5.h>
+ #define MD5_Init MD5Init
+ #define MD5_Update MD5Update
+ #define MD5_Final MD5Final
+ #else
+ #include <openssl/md5.h>
+ #endif
+ #endif // ifndef WIN32
+#endif // MD5_SUPPORT
+
+namespace CTPP // C++ Template Engine
+{
+#ifdef MD5_SUPPORT
+
+//
+// Constructor
+//
+FnMD5::FnMD5()
+{
+#ifdef WIN32
+ // http://msdn.microsoft.com/en-us/library/aa382375(VS.85).aspx
+ // Get a handle to the default PROV_RSA_FULL provider.
+ if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0))
+ {
+ // Okay
+ }
+ else
+ {
+ if (GetLastError() == NTE_BAD_KEYSET)
+ {
+ // No default container was found. Attempt to create it.
+ if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ {
+ // Okay
+ }
+ else
+ {
+ throw CTPPUnixException("Could not create the default key container.", GetLastError());
+ }
+ }
+ else
+ {
+ throw CTPPUnixException("A general error running CryptAcquireContext", GetLastError());
+ }
+ }
+#else
+ ;;
+#endif
+}
+
+//
+// Handler
+//
+#ifndef WIN32
+//
+// Handler, using Win32 CryptoAPI
+//
+INT_32 FnMD5::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ static CHAR_8 aHex[] = "0123456789abcdef";
+ CHAR_8 szMD5[32];
+ // >0 arguments need
+ if (iArgNum == 0)
+ {
+ oLogger.Emerg("Usage: MD5(a[, b, ...])");
+ return -1;
+ }
+
+ MD5_CTX oMD5Context;
+ MD5_Init(&oMD5Context);
+
+ INT_32 iI = iArgNum - 1;
+ for (; iI >= 0; --iI)
+ {
+ // Data
+ const STLW::string & sTMP = aArguments[iI].GetString();
+ CCHAR_P szData = sTMP.c_str();
+ // Data length
+ const UINT_32 iDataLength = sTMP.size();
+
+ MD5_Update(&oMD5Context, (const unsigned char *)szData, iDataLength);
+ }
+
+ unsigned char sDigest[16];
+ MD5_Final(sDigest, &oMD5Context);
+
+ INT_32 iJ = 0;
+ for (iI = 0; iI < 16; ++iI)
+ {
+ szMD5[ iJ++] = aHex[ (sDigest[iI] >> 4 )& 0x0F ];
+ szMD5[ iJ++] = aHex[ sDigest[iI] & 0x0F ];
+ }
+
+ // Okay
+ oCDTRetVal = STLW::string(szMD5, 32);
+
+return 0;
+
+}
+#else // WIN32
+
+//
+// Handler, using Win32 CryptoAPI
+//
+INT_32 FnMD5::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ static CHAR_8 aHex[] = "0123456789abcdef";
+ CHAR_8 szMD5[32];
+ HCRYPTHASH hHash;
+
+ // >0 arguments need
+ if (iArgNum == 0 || hCryptProv == 0) { fprintf(stderr, "FnMD5 iArgNum = %d hCryptProv = %d\n", iArgNum, hCryptProv); return -1; }
+
+ if (::CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash) == 0) { fprintf(stderr, "CryptCreateHash\n"); return -1; }
+
+ INT_32 iI = iArgNum - 1;
+ for (; iI >= 0; --iI)
+ {
+ // Data
+ const STLW::string & sTMP = aArguments[iI].GetString();
+ if (::CryptHashData(hHash, (BYTE *)sTMP.c_str(), (DWORD)sTMP.size(), 0) == 0)
+ {
+ fprintf(stderr, "CryptHashData\n");
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+ }
+
+ BYTE sDigest[16];
+ DWORD dwCount = 16;
+ if (::CryptGetHashParam(hHash, HP_HASHVAL, sDigest, &dwCount, 0) == 0)
+ {
+ fprintf(stderr, "CryptGetHashParam\n");
+ ::CryptDestroyHash(hHash);
+ return -1;
+ }
+
+ INT_32 iJ = 0;
+ for (iI = 0; iI < 16; ++iI)
+ {
+ szMD5[ iJ++] = aHex[ (sDigest[iI] >> 4 )& 0x0F ];
+ szMD5[ iJ++] = aHex[ sDigest[iI] & 0x0F ];
+ }
+
+ ::CryptDestroyHash(hHash);
+
+ // Okay
+ oCDTRetVal = STLW::string(szMD5, 32);
+
+return 0;
+}
+#endif // WIN32
+
+//
+// Get function name
+//
+CCHAR_P FnMD5::GetName() const { return "md5"; }
+
+//
+// A destructor
+//
+FnMD5::~FnMD5() throw()
+{
+#ifdef WIN32
+ if (hCryptProv != 0) { ::CryptReleaseContext(hCryptProv, 0); }
+#else
+ ;;
+#endif
+}
+
+#endif // MD5_SUPPORT
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMax.cpp b/src/functions/FnMax.cpp
new file mode 100644
index 0000000..ae00a22
--- /dev/null
+++ b/src/functions/FnMax.cpp
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMax.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnMax.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnMax::FnMax()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnMax::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 0)
+ {
+ oLogger.Emerg("Usage: MAX(a[, b, ...])");
+ return -1;
+ }
+
+ INT_32 iMaxPos = 0;
+ W_FLOAT dMaxVal = aArguments[0].GetFloat();
+ for (UINT_32 iPos = 0; iPos < iArgNum; ++iPos)
+ {
+ const W_FLOAT dCurVal = aArguments[iPos].GetFloat();
+ if (dCurVal > dMaxVal) { iMaxPos = iPos; dMaxVal = dCurVal; }
+ }
+
+ oCDTRetVal = aArguments[iMaxPos];
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnMax::GetName() const { return "max"; }
+
+//
+// A destructor
+//
+FnMax::~FnMax() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnMin.cpp b/src/functions/FnMin.cpp
new file mode 100644
index 0000000..5cf7216
--- /dev/null
+++ b/src/functions/FnMin.cpp
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnMin.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnMin.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnMin::FnMin()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnMin::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 0)
+ {
+ oLogger.Emerg("Usage: MIN(a[, b, ...])");
+ return -1;
+ }
+
+ INT_32 iMinPos = 0;
+ W_FLOAT dMinVal = aArguments[0].GetFloat();
+ for (UINT_32 iPos = 0; iPos < iArgNum; ++iPos)
+ {
+ const W_FLOAT dCurVal = aArguments[iPos].GetFloat();
+ if (dCurVal < dMinVal) { iMinPos = iPos; dMinVal = dCurVal; }
+ }
+
+ oCDTRetVal = aArguments[iMinPos];
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnMin::GetName() const { return "min"; }
+
+//
+// A destructor
+//
+FnMin::~FnMin() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnNumFormat.cpp b/src/functions/FnNumFormat.cpp
new file mode 100644
index 0000000..c32a18f
--- /dev/null
+++ b/src/functions/FnNumFormat.cpp
@@ -0,0 +1,256 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnVersion.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnNumFormat.hpp"
+
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnNumFormat::FnNumFormat()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnNumFormat::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 2 args allowed
+ if (iArgNum != 2)
+ {
+ oLogger.Emerg("Usage: NUM_FORMAT(x, y)");
+ return -1;
+ }
+
+ STLW::string sTMP = aArguments[0].GetString();
+
+ INT_64 iData;
+ W_FLOAT dData;
+ CDT::eValType eType = aArguments[1].CastToNumber(iData, dData);
+
+ // Integer
+ if (eType == CDT::INT_VAL)
+ {
+ CHAR_8 szRes[C_MAX_SPRINTF_LENGTH + 1];
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+
+ szRes[C_MAX_SPRINTF_LENGTH] = '\0';
+
+ INT_32 iNegative = 0;
+ if (iData < 0) { iData = -iData; iNegative = 1; }
+
+ INT_32 iCharacters = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%lld", (long long)iData);
+ INT_32 iResPos = C_MAX_SPRINTF_LENGTH - 1;
+
+ INT_32 iPos = 0;
+ while (iCharacters >= 0)
+ {
+ szRes[iResPos] = szBuf[iCharacters];
+ if (iPos++ % 3 == 0 && iPos != 1) { szRes[--iResPos] = sTMP[0]; }
+ --iCharacters;
+ --iResPos;
+ }
+
+ ++iResPos;
+ if (iPos % 3 == 1) { ++iResPos; }
+
+ if (iNegative == 1) { szRes[--iResPos] = '-'; }
+
+ oCDTRetVal = &szRes[iResPos];
+ }
+ // IEEE
+ else if (eType == CDT::REAL_VAL)
+ {
+ CHAR_8 szRes[C_MAX_SPRINTF_LENGTH + 1];
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+
+ szRes[C_MAX_SPRINTF_LENGTH] = '\0';
+
+ INT_32 iNegative = 0;
+ if (dData < 0) { dData = -dData; iNegative = 1; }
+
+ INT_32 iCharacters = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%.*G", CTPP_FLOAT_PRECISION, dData);
+ INT_32 iResPos = C_MAX_SPRINTF_LENGTH - 1;
+
+ INT_32 iTMP = iCharacters;
+ iCharacters = 0;
+ while (iCharacters < iTMP && szBuf[iCharacters++] != '.') { ;; }
+
+ while (iTMP >= iCharacters)
+ {
+ szRes[iResPos] = szBuf[iTMP];
+ --iTMP;
+ --iResPos;
+ }
+
+ if (szBuf[iTMP] == '.') { iCharacters = iTMP; }
+
+ INT_32 iPos = 0;
+ while (iCharacters >= 0)
+ {
+ szRes[iResPos] = szBuf[iCharacters];
+ if (iPos++ % 3 == 0 && iPos != 1) { szRes[--iResPos] = sTMP[0]; }
+ --iCharacters;
+ --iResPos;
+ }
+
+ ++iResPos;
+ if (iPos % 3 == 1) { ++iResPos; }
+
+ if (iNegative == 1) { szRes[--iResPos] = '-'; }
+
+ oCDTRetVal = &szRes[iResPos];
+ }
+ // All others
+ else
+ {
+ oCDTRetVal = aArguments[1].GetString();
+ }
+// INT_64 iIntData = aArguments[1].GetInt();
+// INT_32 iNegative = 0;
+// if (iIntData < 0) { iIntData = -iIntData; iNegative = 1; }
+
+/*
+ switch (aArguments[1].GetType())
+ {
+ // Integer value
+ case CDT::INT_VAL:
+ {
+ CHAR_8 szRes[C_MAX_SPRINTF_LENGTH + 1];
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+
+ szRes[C_MAX_SPRINTF_LENGTH] = '\0';
+
+ INT_64 iIntData = aArguments[1].GetInt();
+
+ INT_32 iNegative = 0;
+ if (iIntData < 0) { iIntData = -iIntData; iNegative = 1; }
+
+ INT_32 iCharacters = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%lld", (long long)iIntData);
+ INT_32 iResPos = C_MAX_SPRINTF_LENGTH - 1;
+
+ INT_32 iPos = 0;
+ while (iCharacters >= 0)
+ {
+ szRes[iResPos] = szBuf[iCharacters];
+ if (iPos++ % 3 == 0 && iPos != 1) { szRes[--iResPos] = sTMP[0]; }
+ --iCharacters;
+ --iResPos;
+ }
+
+ ++iResPos;
+ if (iPos % 3 == 1) { ++iResPos; }
+
+ if (iNegative == 1) { szRes[--iResPos] = '-'; }
+
+ oCDTRetVal = &szRes[iResPos];
+ }
+ break;
+
+ // Floating point value
+ case CDT::REAL_VAL:
+ {
+ CHAR_8 szRes[C_MAX_SPRINTF_LENGTH + 1];
+ CHAR_8 szBuf[C_MAX_SPRINTF_LENGTH + 1];
+
+ szRes[C_MAX_SPRINTF_LENGTH] = '\0';
+
+ W_FLOAT dFloatData = aArguments[1].GetFloat();
+
+ INT_32 iNegative = 0;
+ if (dFloatData < 0) { dFloatData = -dFloatData; iNegative = 1; }
+
+ INT_32 iCharacters = snprintf(szBuf, C_MAX_SPRINTF_LENGTH, "%.*G", CTPP_FLOAT_PRECISION, dFloatData);
+ INT_32 iResPos = C_MAX_SPRINTF_LENGTH - 1;
+
+ INT_32 iTMP = iCharacters;
+ iCharacters = 0;
+ while (iCharacters < iTMP && szBuf[iCharacters++] != '.') { ;; }
+
+ while (iTMP >= iCharacters)
+ {
+ szRes[iResPos] = szBuf[iTMP];
+ --iTMP;
+ --iResPos;
+ }
+
+ if (szBuf[iTMP] == '.') { iCharacters = iTMP; }
+
+ INT_32 iPos = 0;
+ while (iCharacters >= 0)
+ {
+ szRes[iResPos] = szBuf[iCharacters];
+ if (iPos++ % 3 == 0 && iPos != 1) { szRes[--iResPos] = sTMP[0]; }
+ --iCharacters;
+ --iResPos;
+ }
+
+ ++iResPos;
+ if (iPos % 3 == 1) { ++iResPos; }
+
+ if (iNegative == 1) { szRes[--iResPos] = '-'; }
+
+ oCDTRetVal = &szRes[iResPos];
+ }
+ break;
+
+ // All other types
+ default:
+ oCDTRetVal = aArguments[1].GetString();
+ }
+*/
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnNumFormat::GetName() const { return "num_format"; }
+
+//
+// A destructor
+//
+FnNumFormat::~FnNumFormat() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnObjDump.cpp b/src/functions/FnObjDump.cpp
new file mode 100644
index 0000000..85bb2e6
--- /dev/null
+++ b/src/functions/FnObjDump.cpp
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnObjDump.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "FnObjDump.hpp"
+
+#include <math.h>
+#include <stdio.h>
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnObjDump::FnObjDump(): pCDT(NULL)
+{
+ ;;
+}
+
+//
+// Pre-execution handler setup
+//
+INT_32 FnObjDump::PreExecuteSetup(OutputCollector & oCollector,
+ CDT & oCDT,
+ const ReducedStaticText & oSyscalls,
+ const ReducedStaticData & oStaticData,
+ const ReducedStaticText & oStaticText,
+ Logger & oLogger)
+{
+ pCDT = &oCDT;
+
+return 0;
+}
+
+//
+// Handler
+//
+INT_32 FnObjDump::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 0)
+ {
+ oCDTRetVal = "Global data object:\n";
+ oCDTRetVal.Append(pCDT -> Dump(0, true));
+ }
+ else
+ {
+ oCDTRetVal = "";
+ // Temp
+ CHAR_8 szBuffer[CTPP_ESCAPE_BUFFER_LEN + 1];
+
+ INT_32 iI = iArgNum - 1;
+ for (; iI >= 0; --iI)
+ {
+ snprintf(szBuffer, CTPP_ESCAPE_BUFFER_LEN, "Argument %d:\n", iArgNum - iI);
+ oCDTRetVal.Append(szBuffer);
+ oCDTRetVal.Append(aArguments[iI].Dump());
+ }
+ }
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnObjDump::GetName() const { return "obj_dump"; }
+
+//
+// A destructor
+//
+FnObjDump::~FnObjDump() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnRandom.cpp b/src/functions/FnRandom.cpp
new file mode 100644
index 0000000..71bac83
--- /dev/null
+++ b/src/functions/FnRandom.cpp
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnRandom.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnRandom.hpp"
+
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef _MSC_VER
+ #define random() rand()
+ #define INT_64(x) (INT_64)(x)
+ #define srandomdev() srand( (unsigned)time(NULL) );
+#endif
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnRandom::FnRandom()
+{
+#if defined(__FreeBSD__) || defined(_MSC_VER)
+ srandomdev();
+#else
+ srandom(time(NULL));
+#endif
+}
+
+//
+// Handler
+//
+INT_32 FnRandom::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // 0 .. MAX(unsigned long)
+ if (iArgNum == 0)
+ {
+ oCDTRetVal = UINT_64(random());
+ return 0;
+ }
+ // RAND(x) -> 0 .. RAND(x)
+ else if (iArgNum == 1)
+ {
+ const CDT & oFirstArg = aArguments[0];
+ // Integer value
+ if (oFirstArg.GetType() == CDT::INT_VAL)
+ {
+ oCDTRetVal = INT_64(random() % oFirstArg.GetInt());
+ return 0;
+ }
+ // Floating point value
+ else if (oFirstArg.GetType() == CDT::REAL_VAL)
+ {
+ oCDTRetVal = W_FLOAT(oFirstArg.GetFloat() * (random() % UINT_64(RAND_MAX)) / UINT_64(RAND_MAX));
+ return 0;
+ }
+
+ // Invalid data type, just return 0
+ oCDTRetVal = 0;
+ return 0;
+ }
+ // RAND(x, y) -> x .. y
+ else if (iArgNum == 2)
+ {
+ const CDT & oFirstArg = aArguments[1];
+ const CDT & oSecondArg = aArguments[0];
+
+ // x and y is integer values
+ if (oFirstArg.GetType() == CDT::INT_VAL &&
+ oSecondArg.GetType() == CDT::INT_VAL)
+ {
+ const UINT_64 iFirst = oFirstArg.GetInt();
+ const UINT_64 iInterval = oSecondArg.GetInt() - iFirst;
+
+ oCDTRetVal = INT_64(random() % iInterval + iFirst);
+ return 0;
+ }
+ // x or y (or both) are floating point value
+ else if ((oFirstArg.GetType() == CDT::REAL_VAL && oSecondArg.GetType() == CDT::INT_VAL) ||
+ (oFirstArg.GetType() == CDT::INT_VAL && oSecondArg.GetType() == CDT::REAL_VAL) ||
+ (oFirstArg.GetType() == CDT::REAL_VAL && oSecondArg.GetType() == CDT::REAL_VAL))
+ {
+ const W_FLOAT dFirst = oFirstArg.GetFloat();
+ const W_FLOAT dInterval = oSecondArg.GetFloat() - dFirst;
+
+ oCDTRetVal = W_FLOAT(dInterval * (random() % UINT_64(RAND_MAX)) / UINT_64(RAND_MAX) + dFirst);
+ return 0;
+ }
+
+ // Invalid data type, just return 0
+ oCDTRetVal = 0;
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: RANDOM([[min,] max])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnRandom::GetName() const { return "random"; }
+
+//
+// A destructor
+//
+FnRandom::~FnRandom() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnSize.cpp b/src/functions/FnSize.cpp
new file mode 100644
index 0000000..7822c5a
--- /dev/null
+++ b/src/functions/FnSize.cpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSize.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnSize.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnSize::FnSize()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnSize::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Only 1 arg allowed
+ if (iArgNum != 1)
+ {
+ oLogger.Emerg("Usage: SIZE(x)");
+ return -1;
+ }
+
+ oCDTRetVal = aArguments[0].Size();
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnSize::GetName() const { return "size"; }
+
+//
+// A destructor
+//
+FnSize::~FnSize() throw()
+{
+ ;;
+}
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnSprintf.cpp b/src/functions/FnSprintf.cpp
new file mode 100644
index 0000000..32b602a
--- /dev/null
+++ b/src/functions/FnSprintf.cpp
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSprintf.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Sprintf.hpp"
+#include "FnSprintf.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnSprintf::FnSprintf()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnSprintf::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 0)
+ {
+ oLogger.Emerg("Usage: SPRINTF(format, a[, b, ...])");
+ return -1;
+ }
+
+ CDT oArgs(CDT::ARRAY_VAL);
+ INT_32 iPos = iArgNum - 2;
+
+ while (iPos >= 0)
+ {
+ oArgs.PushBack(aArguments[iPos]);
+ --iPos;
+ }
+
+ STLW::string sResult;
+ FormatString(aArguments[iArgNum - 1].GetString(), sResult, oArgs);
+ oCDTRetVal = sResult;
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnSprintf::GetName() const { return "sprintf"; }
+
+//
+// A destructor
+//
+FnSprintf::~FnSprintf() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnSubstring.cpp b/src/functions/FnSubstring.cpp
new file mode 100644
index 0000000..42e9294
--- /dev/null
+++ b/src/functions/FnSubstring.cpp
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnSubstring.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnSubstring.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnSubstring::FnSubstring()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnSubstring::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ // Check number of parameters
+ if (iArgNum == 0) { oCDTRetVal = ""; return 0; }
+
+ // substr('foobar', 2) -> 'obar'
+ if (iArgNum == 2)
+ {
+ const UINT_32 iOffset = UINT_32(aArguments[0].GetInt());
+ const STLW::string sResult = aArguments[1].GetString();
+
+ if (sResult.size() < iOffset) { oCDTRetVal = ""; }
+ else { oCDTRetVal = sResult.substr(iOffset); }
+
+ return 0;
+ }
+ // substr('foobar', 2, 3) -> 'oba'
+ if (iArgNum == 3)
+ {
+ const UINT_32 iBytes = UINT_32(aArguments[0].GetInt());
+ const UINT_32 iOffset = UINT_32(aArguments[1].GetInt());
+ const STLW::string sResult = aArguments[2].GetString();
+
+ if (sResult.size() < iOffset) { oCDTRetVal = ""; }
+ else { oCDTRetVal = sResult.substr(iOffset, iBytes); }
+
+ return 0;
+ }
+ // substr('foobar', 2, 3, '1234567') -> 'fo1234567r'
+ if (iArgNum == 4)
+ {
+ STLW::string sReplacement = aArguments[0].GetString();
+ const UINT_32 iBytes = UINT_32(aArguments[1].GetInt());
+ const UINT_32 iOffset = UINT_32(aArguments[2].GetInt());
+ const STLW::string sTMP = aArguments[3].GetString();
+
+ if (iOffset > sTMP.size()) { oCDTRetVal = ""; return 0; }
+
+ STLW::string sResult(sTMP, 0, iOffset);
+ sResult.append(sReplacement);
+ if (iBytes + iOffset > sTMP.size()) { oCDTRetVal = sResult; return 0; }
+
+ sResult.append(sTMP, iBytes + iOffset, STLW::string::npos);
+ oCDTRetVal = sResult;
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: SUBSTR(x, offset[, bytes[, y]]])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnSubstring::GetName() const { return "substr"; }
+
+//
+// A destructor
+//
+FnSubstring::~FnSubstring() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnTruncate.cpp b/src/functions/FnTruncate.cpp
new file mode 100644
index 0000000..128176e
--- /dev/null
+++ b/src/functions/FnTruncate.cpp
@@ -0,0 +1,96 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnTruncate.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "FnTruncate.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnTruncate::FnTruncate()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnTruncate::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 2)
+ {
+ const UINT_32 iMaxLen = UINT_32(aArguments[0].GetInt());
+ const STLW::string sData = aArguments[1].GetString();
+
+ if (sData.size() > iMaxLen) { oCDTRetVal = STLW::string(sData, 0, iMaxLen); }
+ else { oCDTRetVal = sData; }
+
+ return 0;
+ }
+ else if (iArgNum == 3)
+ {
+ const UINT_32 iMaxLen = UINT_32(aArguments[1].GetInt());
+ STLW::string sData = aArguments[2].GetString();
+
+ if (sData.size() > iMaxLen)
+ {
+ sData = STLW::string(sData, 0, iMaxLen);
+ sData.append(aArguments[0].GetString());
+ }
+
+ oCDTRetVal = sData;
+ return 0;
+ }
+
+ oLogger.Emerg("Usage: TRUNCATE(x, offest[, addon])");
+return -1;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnTruncate::GetName() const { return "truncate"; }
+
+//
+// A destructor
+//
+FnTruncate::~FnTruncate() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnURIEscape.cpp b/src/functions/FnURIEscape.cpp
new file mode 100644
index 0000000..e439c7b
--- /dev/null
+++ b/src/functions/FnURIEscape.cpp
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnURIEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnURIEscape.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+//
+// Constructor
+//
+FnURIEscape::FnURIEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnURIEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: URIESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = URIEscape(sResult);
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnURIEscape::GetName() const { return "uriescape"; }
+
+//
+// A destructor
+//
+FnURIEscape::~FnURIEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnURLEscape.cpp b/src/functions/FnURLEscape.cpp
new file mode 100644
index 0000000..15cfb3d
--- /dev/null
+++ b/src/functions/FnURLEscape.cpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnURLEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnURLEscape.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnURLEscape::FnURLEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnURLEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: URLESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = URLEscape(sResult);
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnURLEscape::GetName() const { return "urlescape"; }
+
+//
+// A destructor
+//
+FnURLEscape::~FnURLEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnVersion.cpp b/src/functions/FnVersion.cpp
new file mode 100644
index 0000000..da2b39b
--- /dev/null
+++ b/src/functions/FnVersion.cpp
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnVersion.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "FnVersion.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnVersion::FnVersion() { ;; }
+
+//
+// Handler
+//
+INT_32 FnVersion::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum == 1 && strcasecmp("full", aArguments[0].GetString().c_str()) == 0)
+ {
+ oCDTRetVal = "Engine: CTPP2 engine v" CTPP_VERSION " (" CTPP_IDENT "), copyright (c) 2004 - 2012 CTPP Dev. Team;\n"
+ "RuntimeLibrary: CTPP Standard Library v" CTPP_VERSION " (" CTPP_IDENT "), copyright (c) 2007 - 2012 CTPP Dev. Team;\n"
+ "License: BSD-like, see " CTPP_MASTER_SITE_URL ";";
+ }
+ else
+ {
+ oCDTRetVal = "CTPP2 engine v" CTPP_VERSION " (" CTPP_IDENT "), copyright (c) 2004 - 2012 CTPP Dev. Team";
+ }
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnVersion::GetName() const { return "version"; }
+
+//
+// A destructor
+//
+FnVersion::~FnVersion() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnWMLEscape.cpp b/src/functions/FnWMLEscape.cpp
new file mode 100644
index 0000000..e3870ba
--- /dev/null
+++ b/src/functions/FnWMLEscape.cpp
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnWMLEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnWMLEscape.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnWMLEscape::FnWMLEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnWMLEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: WMLESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = WMLEscape(sResult);
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnWMLEscape::GetName() const { return "wmlescape"; }
+
+//
+// A destructor
+//
+FnWMLEscape::~FnWMLEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/src/functions/FnXMLEscape.cpp b/src/functions/FnXMLEscape.cpp
new file mode 100644
index 0000000..588594e
--- /dev/null
+++ b/src/functions/FnXMLEscape.cpp
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * FnXMLEscape.cpp
+ *
+ * $CTPP$
+ */
+
+#include "CDT.hpp"
+#include "CTPP2Logger.hpp"
+#include "CTPP2Util.hpp"
+#include "FnXMLEscape.hpp"
+
+namespace CTPP // C++ Template Engine
+{
+
+//
+// Constructor
+//
+FnXMLEscape::FnXMLEscape()
+{
+ ;;
+}
+
+//
+// Handler
+//
+INT_32 FnXMLEscape::Handler(CDT * aArguments,
+ const UINT_32 iArgNum,
+ CDT & oCDTRetVal,
+ Logger & oLogger)
+{
+ if (iArgNum < 1)
+ {
+ oLogger.Emerg("Usage: XMLESCAPE(a[, b, ...])");
+ return -1;
+ }
+
+
+ STLW::string sResult;
+ for(INT_32 iPos = iArgNum - 1; iPos >=0; --iPos) { sResult.append(aArguments[iPos].GetString()); }
+
+ oCDTRetVal = XMLEscape(sResult);
+
+return 0;
+}
+
+//
+// Get function name
+//
+CCHAR_P FnXMLEscape::GetName() const { return "xmlescape"; }
+
+//
+// A destructor
+//
+FnXMLEscape::~FnXMLEscape() throw() { ;; }
+
+} // namespace CTPP
+// End.
diff --git a/tests/BitIndexText.cpp b/tests/BitIndexText.cpp
new file mode 100644
index 0000000..483fa9a
--- /dev/null
+++ b/tests/BitIndexText.cpp
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2BitIndex.cpp
+ *
+ * $CTPP$
+ */
+#include <stdio.h>
+#include <CTPP2BitIndex.hpp>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+#define C_BITS_NUM 13
+
+int main(void)
+{
+ BitIndex oBitIndex(C_BITS_NUM);
+
+ for (UINT_32 iI = 0; iI < C_BITS_NUM; ++iI)
+ {
+ oBitIndex.SetBit(iI, iI % 2);
+ fprintf(stderr, "%c", (iI % 2) ? '1' : '0');
+ }
+ fprintf(stderr, "\n");
+
+ for (UINT_32 iI = 0; iI < C_BITS_NUM; ++iI)
+ {
+ fprintf(stderr, "%c", oBitIndex.GetBit(iI) ? '1' : '0');
+ }
+ fprintf(stderr, "\n");
+
+ oBitIndex.SetBit(0, 1);
+ oBitIndex.SetBit(1, 1);
+ oBitIndex.SetBit(2, 1);
+
+ oBitIndex.SetBit(3, 0);
+ oBitIndex.SetBit(4, 0);
+ oBitIndex.SetBit(5, 0);
+
+ oBitIndex.SetBit(6, 1);
+ oBitIndex.SetBit(7, 1);
+ oBitIndex.SetBit(8, 1);
+
+ for (UINT_32 iI = 0; iI < C_BITS_NUM; ++iI)
+ {
+ fprintf(stderr, "%c", oBitIndex.GetBit(iI) ? '1' : '0');
+ }
+ fprintf(stderr, "\nExpand index:\n");
+
+ for (UINT_32 iI = C_BITS_NUM; iI < C_BITS_NUM * 2; ++iI)
+ {
+ oBitIndex.SetBit(iI, 0);
+ fprintf(stderr, "Bit %d, used bytes: %d\n", iI, oBitIndex.GetUsedSize());
+ }
+ fprintf(stderr, "\n");
+
+ for (UINT_32 iI = C_BITS_NUM; iI < C_BITS_NUM * 2; ++iI)
+ {
+ oBitIndex.SetBit(iI, iI % 2);
+ fprintf(stderr, "%c", (iI % 2) ? '1' : '0');
+ }
+ fprintf(stderr, "\n");
+
+ for (UINT_32 iI = 0; iI < C_BITS_NUM * 2; ++iI)
+ {
+ fprintf(stderr, "%c", oBitIndex.GetBit(iI) ? '1' : '0');
+ }
+ fprintf(stderr, "\n");
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/CDTPerfTest.cpp b/tests/CDTPerfTest.cpp
new file mode 100644
index 0000000..0502a3a
--- /dev/null
+++ b/tests/CDTPerfTest.cpp
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDTPerfTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CDT.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+ #include <sysexits.h>
+#endif
+
+#include <time.h>
+
+#ifdef HAVE_SYS_TIME_H
+ #include <sys/time.h>
+#endif
+
+#ifdef WIN32
+ #include <CTPP2Time.h>
+#endif
+
+using namespace CTPP;
+
+int main(void)
+{
+ try
+ {
+ struct timeval sStartTime;
+ struct timeval sEndTime;
+
+ gettimeofday(&sStartTime, NULL);
+ CHAR_8 szBuf[1024 + 1];
+ CDT oCDT_array(CDT::ARRAY_VAL);
+ for (UINT_32 iI = 0; iI < 10000; ++iI)
+ {
+ if (iI % 2 == 0) { oCDT_array[iI] = iI; }
+ else
+ {
+ for (UINT_32 iJ = 0; iJ < 100; ++iJ)
+ {
+ snprintf(szBuf, 1024, "_%d_%d_", iI, iJ);
+
+ oCDT_array[iI][szBuf][10] = iI;
+ // PERL analog:
+ // $AArray[$II] -> {$SKey} -> [10] = $II;
+
+ // PHP analog:
+ // $AArray[$II][$SKey][10] = $II;
+ }
+ }
+ }
+
+ gettimeofday(&sEndTime, NULL);
+
+ fprintf(stderr, "Time: %f\n", ((sEndTime.tv_sec - sStartTime.tv_sec) + 1.0 * (sEndTime.tv_usec - sStartTime.tv_usec) / 1000000));
+
+ fprintf(stderr, "ARRAY size: %d\n", oCDT_array.Size());
+ }
+ catch(CDTTypeCastException &e)
+ {
+ fprintf(stderr, "ERROR: Type cast %s\n", e.what());
+ }
+ catch(std::exception &e)
+ {
+ fprintf(stderr, "ERROR: std %s\n", e.what());
+ }
+ catch(...)
+ {
+ fprintf(stderr, "Ouch!\n");
+ }
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/CDTTest.cpp b/tests/CDTTest.cpp
new file mode 100644
index 0000000..b51b97e
--- /dev/null
+++ b/tests/CDTTest.cpp
@@ -0,0 +1,776 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CDTTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CDT.hpp>
+#include <CDTSortRoutines.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+int main(void)
+{
+ CDT oCDT = 10;
+
+ fprintf(stderr, "== INT ===================================\n");
+ fprintf(stderr, "Initial value: %d\n", INT_32(oCDT.GetInt()));
+ {
+ fprintf(stderr, "Post-increnent\n");
+ CDT oTMP = oCDT++;
+ fprintf(stderr, "TMP = CDT++: ");
+ fprintf(stderr, "%d -> %d\n\n", INT_32(oTMP.GetInt()), INT_32(oCDT.GetInt()));
+ }
+
+ {
+ fprintf(stderr, "Pre-increnent\n");
+ CDT oTMP = ++oCDT;
+ fprintf(stderr, "TMP = ++CDT: ");
+ fprintf(stderr, "%d -> %d\n\n", INT_32(oTMP.GetInt()), INT_32(oCDT.GetInt()));
+ }
+
+ {
+ fprintf(stderr, "Post-decrement\n");
+ CDT oTMP = oCDT--;
+ fprintf(stderr, "TMP = CDT--: ");
+ fprintf(stderr, "%d -> %d\n\n", INT_32(oTMP.GetInt()), INT_32(oCDT.GetInt()));
+ }
+
+ {
+ fprintf(stderr, "Pre-decrement\n");
+ CDT oTMP = --oCDT;
+ fprintf(stderr, "TMP = --CDT: ");
+ fprintf(stderr, "%d -> %d\n\n", INT_32(oTMP.GetInt()), INT_32(oCDT.GetInt()));
+ }
+
+ fprintf(stderr, "operator+=(INT_32)\n");
+ oCDT += 10;
+ fprintf(stderr, "CDT += 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator-=(INT_32)\n");
+ oCDT -= 10;
+ fprintf(stderr, "CDT -= 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator*=(INT_32)\n");
+ oCDT *= 10;
+ fprintf(stderr, "CDT *= 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator/=(INT_32)\n");
+ oCDT /= 10;
+ fprintf(stderr, "CDT /= 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator+(INT_32)\n");
+ oCDT = oCDT + 10;
+ fprintf(stderr, "CDT = CDT + 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "standalone operator+(int, CDT)\n");
+ oCDT = 10 + oCDT;
+ fprintf(stderr, "CDT = 10 + CDT -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator-(INT_32)\n");
+ oCDT = oCDT - 10;
+ fprintf(stderr, "CDT = CDT - 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "standalone operator-(int, CDT)\n");
+ oCDT = 10 - oCDT;
+ fprintf(stderr, "CDT = 10 - CDT -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator*(INT_32)\n");
+ oCDT = oCDT * 10;
+ fprintf(stderr, "CDT = CDT * 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "standalone operator*(int, CDT)\n");
+ oCDT = 10 * oCDT;
+ fprintf(stderr, "CDT = 10 * CDT -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "operator/(INT_32)\n");
+ oCDT = oCDT / 10;
+ fprintf(stderr, "CDT = CDT * 10 -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "standalone operator*(int, CDT)\n");
+ oCDT = 10 / oCDT;
+ fprintf(stderr, "CDT = 10 * CDT -> %d\n\n", INT_32(oCDT.GetInt()));
+
+ fprintf(stderr, "Auto-cast to float\n");
+ oCDT = -1.0 * oCDT;
+ fprintf(stderr, "CDT -> %f: %s\n\n", W_FLOAT(oCDT.GetFloat()), oCDT.PrintableType());
+
+
+ fprintf(stderr, "== REAL ===================================\n");
+ fprintf(stderr, "Initial value: %f\n", W_FLOAT(oCDT.GetFloat()));
+ {
+ fprintf(stderr, "Post-increnent\n");
+ CDT oTMP = oCDT++;
+ fprintf(stderr, "TMP = CDT++: ");
+ fprintf(stderr, "%f -> %f\n\n", W_FLOAT(oTMP.GetFloat()), W_FLOAT(oCDT.GetFloat()));
+ }
+
+ {
+ fprintf(stderr, "Pre-increnent\n");
+ CDT oTMP = ++oCDT;
+ fprintf(stderr, "TMP = ++CDT: ");
+ fprintf(stderr, "%f -> %f\n\n", W_FLOAT(oTMP.GetFloat()), W_FLOAT(oCDT.GetFloat()));
+ }
+
+ {
+ fprintf(stderr, "Post-decrement\n");
+ CDT oTMP = oCDT--;
+ fprintf(stderr, "TMP = CDT--: ");
+ fprintf(stderr, "%f -> %f\n\n", W_FLOAT(oTMP.GetFloat()), W_FLOAT(oCDT.GetFloat()));
+ }
+
+ {
+ fprintf(stderr, "Pre-decrement\n");
+ CDT oTMP = --oCDT;
+ fprintf(stderr, "TMP = --CDT: ");
+ fprintf(stderr, "%f -> %f\n\n", W_FLOAT(oTMP.GetFloat()), W_FLOAT(oCDT.GetFloat()));
+ }
+
+ fprintf(stderr, "operator+=(INT_32)\n");
+ oCDT += 10;
+ fprintf(stderr, "CDT += 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator-=(INT_32)\n");
+ oCDT -= 10;
+ fprintf(stderr, "CDT -= 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator*=(INT_32)\n");
+ oCDT *= 10;
+ fprintf(stderr, "CDT *= 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator/=(INT_32)\n");
+ oCDT /= 10;
+ fprintf(stderr, "CDT /= 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator+(INT_32)\n");
+ oCDT = oCDT + 10;
+ fprintf(stderr, "CDT = CDT + 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator+(int, CDT)\n");
+ oCDT = 10 + oCDT;
+ fprintf(stderr, "CDT = 10 + CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator-(INT_32)\n");
+ oCDT = oCDT - 10;
+ fprintf(stderr, "CDT = CDT - 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator-(int, CDT)\n");
+ oCDT = 10 - oCDT;
+ fprintf(stderr, "CDT = 10 - CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator*(INT_32)\n");
+ oCDT = oCDT * 10;
+ fprintf(stderr, "CDT = CDT * 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator*(int, CDT)\n");
+ oCDT = 10 * oCDT;
+ fprintf(stderr, "CDT = 10 * CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator/(INT_32)\n");
+ oCDT = oCDT / 10;
+ fprintf(stderr, "CDT = CDT * 10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator*(int, CDT)\n");
+ oCDT = 10 / oCDT;
+ fprintf(stderr, "CDT = 10 * CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+// //
+ fprintf(stderr, "operator+=(W_FLOAT)\n");
+ oCDT += 10.10;
+ fprintf(stderr, "CDT += 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator-=(W_FLOAT)\n");
+ oCDT -= 10.10;
+ fprintf(stderr, "CDT -= 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator*=(W_FLOAT)\n");
+ oCDT *= 10.10;
+ fprintf(stderr, "CDT *= 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator/=(W_FLOAT)\n");
+ oCDT /= 10.10;
+ fprintf(stderr, "CDT /= 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator+(W_FLOAT)\n");
+ oCDT = oCDT + 10.10;
+ fprintf(stderr, "CDT = CDT + 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator+(W_FLOAT, CDT)\n");
+ oCDT = 10.10 + oCDT;
+ fprintf(stderr, "CDT = 10.10 + CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator-(INT_32)\n");
+ oCDT = oCDT - 10.10;
+ fprintf(stderr, "CDT = CDT - 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator-(W_FLOAT, CDT)\n");
+ oCDT = 10.10 - oCDT;
+ fprintf(stderr, "CDT = 10.10 - CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator*(W_FLOAT)\n");
+ oCDT = oCDT * 10.10;
+ fprintf(stderr, "CDT = CDT * 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator*(W_FLOAT, CDT)\n");
+ oCDT = 10.10 * oCDT;
+ fprintf(stderr, "CDT = 10.10 * CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "operator/(W_FLOAT)\n");
+ oCDT = oCDT / 10.10;
+ fprintf(stderr, "CDT = CDT * 10.10 -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+ fprintf(stderr, "standalone operator*(W_FLOAT, CDT)\n");
+ oCDT = 10.10 / oCDT;
+ fprintf(stderr, "CDT = 10.10 * CDT -> %f\n\n", W_FLOAT(oCDT.GetFloat()));
+
+
+ fprintf(stderr, "Auto-cast to complex type\n");
+ oCDT = "2";
+ fprintf(stderr, "CDT -> %d: %s\n", INT_32(oCDT.GetInt()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+
+ oCDT *= 3.141;
+ fprintf(stderr, "CDT -> %f: %s\n", W_FLOAT(oCDT.GetFloat()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+
+ oCDT = "3.141";
+ fprintf(stderr, "CDT -> %d: %s\n", INT_32(oCDT.GetInt()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+
+ oCDT *= 2;
+ fprintf(stderr, "CDT -> %f: %s\n", W_FLOAT(oCDT.GetFloat()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+
+ // Shared date types
+ fprintf(stderr, "Shared data types\n");
+ {
+ oCDT = "3.141";
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+
+ CDT oCDT1 = oCDT;
+ fprintf(stderr, "CDT1 -> %d: %s\n", INT_32(oCDT1.GetInt()), oCDT1.PrintableType());
+ fprintf(stderr, "CDT1 -> %f: %s\n", W_FLOAT(oCDT1.GetFloat()), oCDT1.PrintableType());
+ fprintf(stderr, "CDT1 -> %s: %s\n\n", oCDT1.GetString().c_str(), oCDT1.PrintableType());
+
+ fprintf(stderr, "CDT -> %d: %s\n", INT_32(oCDT.GetInt()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %f: %s\n", W_FLOAT(oCDT.GetFloat()), oCDT.PrintableType());
+ fprintf(stderr, "CDT -> %s: %s\n\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+ }
+
+ fprintf(stderr, "Comparisons/NUMERIC/equal\n");
+ {
+ CDT oCDT1 = 10;
+ CDT oCDT2 = 10.0;
+
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f == %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%f >= %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%f <= %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%f != %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%f > %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%f < %f === '%c'\n\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 < oCDT2) ? 't':'f');
+ }
+
+ fprintf(stderr, "Comparisons/NUMERIC/not equal\n");
+ {
+ CDT oCDT1 = 10;
+ CDT oCDT2 = 10.1;
+
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f == %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%f >= %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%f <= %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%f != %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%f > %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%f < %f === '%c'\n\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1 < oCDT2) ? 't':'f');
+ }
+
+ fprintf(stderr, "Comparisons/STRING/equal\n");
+ {
+ CDT oCDT1 = "abac";
+ CDT oCDT2 = "abac";
+
+ fprintf(stderr, "%s EQ %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s GE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s LE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s NE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s GT %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s LT %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 < oCDT2) ? 't':'f');
+
+ }
+
+ fprintf(stderr, "Comparisons/STRING/not equal\n");
+ {
+ CDT oCDT1 = "abac";
+ CDT oCDT2 = "abaca";
+
+ fprintf(stderr, "%s EQ %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s GE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s LE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s NE %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s GT %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%s LT %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 < oCDT2) ? 't':'f');
+ }
+
+ fprintf(stderr, "Comparisons/INT-STRING/equal\n");
+ {
+ CDT oCDT1 = 100;
+ CDT oCDT2 = "100";
+
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 < oCDT2) ? 't':'f');
+ }
+
+ fprintf(stderr, "Comparisons/INT-STRING/not equal\n");
+ {
+ CDT oCDT1 = 100.1;
+ CDT oCDT2 = "100";
+
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Equal(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.GreaterOrEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.LessOrEqual(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.NotEqual(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Greater(oCDT2)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT1.GetFloat(), oCDT2.GetFloat(), (oCDT1.Less(oCDT2)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 == oCDT2) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 >= oCDT2) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 <= oCDT2) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 != oCDT2) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 > oCDT2) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT1.GetString().c_str(), oCDT2.GetString().c_str(), (oCDT1 < oCDT2) ? 't':'f');
+ }
+
+ oCDT = 0xdeadbeef;
+
+ fprintf(stderr, "As String 1: `%s` %s\n", oCDT.GetString().c_str(), oCDT.PrintableType());
+ fprintf(stderr, "As String 2: `%s` %s\n\n", oCDT.GetString("0x%08X").c_str(), oCDT.PrintableType());
+
+ fprintf(stderr, "== POINTER ==================================\n");
+ void * vTMP = (void *)0xDeadBeef;
+ oCDT = vTMP;
+ fprintf(stderr, "As String 1: `%s`\n", oCDT.GetString("").c_str());
+ fprintf(stderr, "As String 2: `%s`\n\n", oCDT.GetString("Pointer: %p").c_str());
+
+ fprintf(stderr, "As Pointer 1: %p\n", oCDT.GetPointer());
+ fprintf(stderr, "As Pointer 2: %p\n\n", (void *)(oCDT.GetObject<CHAR_P>()));
+
+ fprintf(stderr, "== STRING ===================================\n");
+ oCDT = ", ";
+ oCDT.Prepend("Hello");
+ oCDT.Append("World!");
+
+ fprintf(stderr, "CDT: `%s` %s\n", oCDT.GetString("").c_str(), oCDT.PrintableType());
+
+ oCDT.Prepend(111);
+ oCDT.Append(222);
+ fprintf(stderr, "CDT: `%s` %s\n\n", oCDT.GetString("").c_str(), oCDT.PrintableType());
+
+
+ fprintf(stderr, "== Comparators ==============================\n");
+ {
+ W_FLOAT dValue = 123.456;
+ oCDT = 123.456;
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Equal(dValue)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.GreaterOrEqual(dValue)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.LessOrEqual(dValue)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.NotEqual(dValue)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Greater(dValue)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Less(dValue)) ? 't':'f');
+
+ fprintf(stderr, "%f == %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT == dValue) ? 't':'f');
+ fprintf(stderr, "%f >= %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT >= dValue) ? 't':'f');
+ fprintf(stderr, "%f <= %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT <= dValue) ? 't':'f');
+
+ fprintf(stderr, "%f != %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT != dValue) ? 't':'f');
+ fprintf(stderr, "%f > %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT > dValue) ? 't':'f');
+ fprintf(stderr, "%f < %f === '%c'\n\n", oCDT.GetFloat(), dValue, (oCDT < dValue) ? 't':'f');
+ }
+
+ {
+ W_FLOAT dValue = 456.321;
+ oCDT = 123.456;
+ fprintf(stderr, "%f EQ %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Equal(dValue)) ? 't':'f');
+ fprintf(stderr, "%f GE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.GreaterOrEqual(dValue)) ? 't':'f');
+ fprintf(stderr, "%f LE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.LessOrEqual(dValue)) ? 't':'f');
+
+ fprintf(stderr, "%f NE %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.NotEqual(dValue)) ? 't':'f');
+ fprintf(stderr, "%f GT %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Greater(dValue)) ? 't':'f');
+ fprintf(stderr, "%f LT %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT.Less(dValue)) ? 't':'f');
+
+ fprintf(stderr, "%f == %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT == dValue) ? 't':'f');
+ fprintf(stderr, "%f >= %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT >= dValue) ? 't':'f');
+ fprintf(stderr, "%f <= %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT <= dValue) ? 't':'f');
+
+ fprintf(stderr, "%f != %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT != dValue) ? 't':'f');
+ fprintf(stderr, "%f > %f === '%c'\n", oCDT.GetFloat(), dValue, (oCDT > dValue) ? 't':'f');
+ fprintf(stderr, "%f < %f === '%c'\n\n", oCDT.GetFloat(), dValue, (oCDT < dValue) ? 't':'f');
+ }
+
+ {
+ STLW::string sValue = "Foobar";
+ oCDT = "Foobar";
+
+ fprintf(stderr, "%s EQ %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Equal(sValue)) ? 't':'f');
+ fprintf(stderr, "%s GE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.GreaterOrEqual(sValue)) ? 't':'f');
+ fprintf(stderr, "%s LE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.LessOrEqual(sValue)) ? 't':'f');
+
+ fprintf(stderr, "%s NE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.NotEqual(sValue)) ? 't':'f');
+ fprintf(stderr, "%s GT %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Greater(sValue)) ? 't':'f');
+ fprintf(stderr, "%s LT %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Less(sValue)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT == sValue) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT >= sValue) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT <= sValue) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT != sValue) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT > sValue) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT < sValue) ? 't':'f');
+ }
+
+ {
+ STLW::string sValue = "Flurbamatic";
+ oCDT = "Foobar";
+
+ fprintf(stderr, "%s EQ %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Equal(sValue)) ? 't':'f');
+ fprintf(stderr, "%s GE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.GreaterOrEqual(sValue)) ? 't':'f');
+ fprintf(stderr, "%s LE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.LessOrEqual(sValue)) ? 't':'f');
+
+ fprintf(stderr, "%s NE %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.NotEqual(sValue)) ? 't':'f');
+ fprintf(stderr, "%s GT %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Greater(sValue)) ? 't':'f');
+ fprintf(stderr, "%s LT %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT.Less(sValue)) ? 't':'f');
+
+ fprintf(stderr, "%s == %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT == sValue) ? 't':'f');
+ fprintf(stderr, "%s >= %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT >= sValue) ? 't':'f');
+ fprintf(stderr, "%s <= %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT <= sValue) ? 't':'f');
+
+ fprintf(stderr, "%s != %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT != sValue) ? 't':'f');
+ fprintf(stderr, "%s > %s === '%c'\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT > sValue) ? 't':'f');
+ fprintf(stderr, "%s < %s === '%c'\n\n", oCDT.GetString().c_str(), sValue.c_str(), (oCDT < sValue) ? 't':'f');
+ }
+/*
+
+ try
+ {
+ CDT oCDT_array(CDT::ARRAY_VAL);
+ oCDT_array[0] = 10;
+ oCDT_array[1] = 10.5;
+ oCDT_array[2] = "test";
+ oCDT_array[3] = "passed";
+ oCDT_array[10] = 11;
+ oCDT_array[11][3] = 5;
+
+ fprintf(stderr, "ARRAY size: %d\n", oCDT_array.Size());
+ for (UINT_32 iI = 0; iI < oCDT_array.Size(); ++iI)
+ {
+ fprintf(stderr, "oCDT_array[%d] (%s) = `%s`\n", iI, oCDT_array[iI].PrintableType(), oCDT_array[iI].GetString().c_str());
+ }
+ fprintf(stderr, "ARRAY size: %d\n\n", oCDT_array.Size());
+ }
+ catch(CDTTypeCastException &e)
+ {
+ fprintf(stderr, "ERROR: Type cast %s\n", e.what());
+ }
+ catch(std::exception &e)
+ {
+ fprintf(stderr, "ERROR: std %s\n", e.what());
+ }
+ catch(...)
+ {
+ fprintf(stderr, "Ouch!\n");
+ }
+/ *
+my %H;
+$H{'q'} -> [1] -> {"test"} = "passed";
+* /
+*/
+ fprintf(stderr, "== ARRAYS & HASHES ==========================\n");
+ CDT oCDT_array;
+ oCDT_array["abc"] = 10;
+ oCDT_array["xyz"][0] = 2;
+ oCDT_array["1"]["2"][3] = 4;
+
+ fprintf(stderr, "oCDT_array[\"abc\"] (%s) = `%s`\n", oCDT_array["abc"].PrintableType(), oCDT_array["abc"].GetString().c_str());
+ fprintf(stderr, "oCDT_array[\"1\"] (%s) = `%s`\n", oCDT_array["1"].PrintableType(), oCDT_array["1"].GetString().c_str());
+ fprintf(stderr, "oCDT_array[\"1\"][\"2\"] (%s) = `%s`\n", oCDT_array["1"]["2"].PrintableType(), oCDT_array["1"]["2"].GetString().c_str());
+ fprintf(stderr, "oCDT_array[\"abc\"][\"2\"][3] (%s) = `%s`\n", oCDT_array["1"]["2"][3].PrintableType(), oCDT_array["1"]["2"][3].GetString().c_str());
+
+ CDT oCDT_empty;
+
+ fprintf(stderr, "oCDT_empty = `%s`\n\n", oCDT_empty["test"].GetString().c_str());
+
+ fprintf(stderr, "DUMP: %s\n", oCDT_array.RecursiveDump().c_str());
+
+ fprintf(stderr, "Join HASH keys: %s\n", oCDT_array.JoinHashKeys(":").c_str());
+
+ fprintf(stderr, "Join HASH values: %s\n", oCDT_array.JoinHashValues(":").c_str());
+
+ fprintf(stderr, "Get HASH keys: %s\n", oCDT_array.GetHashKeys().Dump().c_str());
+
+ fprintf(stderr, "Get HASH values: %s\n", oCDT_array.GetHashValues().Dump().c_str());
+
+ CDT::Iterator itCDTArray = oCDT_array.Begin();
+ while (itCDTArray != oCDT_array.End())
+ {
+ fprintf(stderr, "oCDT_array[\"%s\"] => %s\n", itCDTArray -> first.c_str(), itCDTArray -> second.GetString().c_str());
+ itCDTArray -> second = "Empty";
+ ++itCDTArray;
+ }
+
+ CDT::ConstIterator itCDTCArray = oCDT_array.Begin();
+ while (itCDTCArray != oCDT_array.End())
+ {
+ fprintf(stderr, "oCDT_array[\"%s\"] => %s\n", itCDTCArray -> first.c_str(), itCDTCArray -> second.GetString().c_str());
+
+ ++itCDTCArray;
+ }
+ fprintf(stderr, "DUMP: %s", oCDT_array.RecursiveDump().c_str());
+
+ CDT oCDT_array1(CDT::ARRAY_VAL);
+ oCDT_array1.PushBack(1);
+ oCDT_array1.PushBack(1.23);
+ oCDT_array1.PushBack("some string");
+ oCDT_array1.PushBack(oCDT_array);
+
+ fprintf(stderr, "DUMP: %s", oCDT_array1.RecursiveDump().c_str());
+
+ fprintf(stderr, "DUMP: %s\n", oCDT_array1.RecursiveDump().c_str());
+
+ fprintf(stderr, "Join ARRAY: %s\n", oCDT_array1.JoinArrayElements(":").c_str());
+
+ // Swap two values
+ {
+ oCDT = "Foo";
+ CDT oCDTSwap = "Bar";
+
+ fprintf(stderr, "Swap: `%s` to `%s`\n", oCDT.GetString().c_str(), oCDTSwap.GetString().c_str());
+ oCDT.Swap(oCDTSwap);
+ fprintf(stderr, "Result: `%s` <> `%s`\n\n", oCDT.GetString().c_str(), oCDTSwap.GetString().c_str());
+ }
+
+ // Sort array
+ {
+ CDT oCDT1;
+ oCDT1[0] = "12";
+ oCDT1[1] = "34";
+ oCDT1[2] = "56";
+ oCDT1[3] = 78;
+ oCDT1[4] = 910;
+ fprintf(stderr, "Source: `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareNum());
+ fprintf(stderr, "SortCompareNum: `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareStr());
+ fprintf(stderr, "SortCompareStr: `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1 = CDT();
+ oCDT1[0][1] = "apple";
+ oCDT1[1][1] = "pera";
+ oCDT1[2][1] = "orange";
+ oCDT1[3][1] = "raspberry";
+ oCDT1[4][1] = "banana";
+
+ oCDT1.SortArray(SortCompareNumArrayElement(1));
+ fprintf(stderr, "SortCompareNumArryElement(ASC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareStrArrayElement(1));
+ fprintf(stderr, "SortCompareStrArryElement(ASC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareNumArrayElement(1, CDT::SortingComparator::DESC));
+ fprintf(stderr, "SortCompareNumArryElement(DESC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareStrArrayElement(1, CDT::SortingComparator::DESC));
+ fprintf(stderr, "SortCompareStrArryElement(DESC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1 = CDT();
+ oCDT1[0]["foo"] = "apple";
+ oCDT1[1]["foo"] = "pera";
+ oCDT1[2]["foo"] = "orange";
+ oCDT1[3]["foo"] = "raspberry";
+ oCDT1[4]["foo"] = "banana";
+
+ oCDT1.SortArray(SortCompareNumHashElement("foo"));
+ fprintf(stderr, "SortCompareNumHashElement(ASC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareStrHashElement("foo"));
+ fprintf(stderr, "SortCompareNumHashElement(ASC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareNumHashElement("foo", CDT::SortingComparator::DESC));
+ fprintf(stderr, "SortCompareNumHashElement(DESC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ oCDT1.SortArray(SortCompareStrHashElement("foo", CDT::SortingComparator::DESC));
+ fprintf(stderr, "SortCompareNumHashElement(DESC): `%s`\n", oCDT1.RecursiveDump().c_str());
+
+ }
+
+ // Merge hashes, arrays, etc
+ fprintf(stderr, "== Merge ARRAYS & HASHES ====================\n");
+ {
+ CDT oSource;
+ CDT oDestination;
+ oDestination.MergeCDT(oSource);
+
+ // Array-to-array
+ oDestination[0] = "one";
+ oDestination[1] = "two";
+ oDestination[2] = "three";
+ oDestination.MergeCDT(oSource);
+
+ oSource[0] = "four";
+ oSource[1] = "five";
+ oSource[2] = "six";
+
+ oDestination.MergeCDT(oSource);
+ fprintf(stderr, "Merge: `%s`\n", oDestination.RecursiveDump().c_str());
+
+ // Array-to-hash
+ oDestination = CDT(CDT::HASH_VAL);
+ oDestination["one"] = 1;
+ oDestination["two"] = 2;
+ oDestination["three"] = 3;
+ oDestination.MergeCDT(oSource);
+ fprintf(stderr, "Merge: `%s`\n", oDestination.RecursiveDump().c_str());
+
+ // Hash-to-array
+ oDestination = CDT(CDT::ARRAY_VAL);
+ oDestination[0] = "one";
+ oDestination[1] = "two";
+ oDestination[2] = "three";
+
+ oSource = CDT(CDT::HASH_VAL);
+ oSource["four"] = 4;
+ oSource["five"] = 5;
+ oSource["six"] = 6;
+ oDestination.MergeCDT(oSource);
+ fprintf(stderr, "Merge: `%s`\n", oDestination.RecursiveDump().c_str());
+
+ // Hash-to-hash
+ oDestination = CDT(CDT::HASH_VAL);
+ oDestination["one"] = 1;
+ oDestination["two"] = 2;
+ oDestination["three"] = 3;
+ oDestination.MergeCDT(oSource);
+ fprintf(stderr, "Merge: `%s`\n", oDestination.RecursiveDump().c_str());
+ }
+
+ fprintf(stderr, "== Merge DEEP ARRAYS & HASHES ===============\n");
+ {
+ CDT oSource;
+ CDT oDestination;
+
+ oSource["foo"][0] = "apple";
+ oSource["bar"][0] = "cat";
+ oSource["foo"][1] = "pera";
+ oSource["bar"][1] = "dog";
+ oSource["foo"][2] = "orange";
+ oSource["bar"][2] = "fox";
+ oSource["foo"][3] = "raspberry";
+ oSource["bar"][3] = "bear";
+ oSource["foo"][4] = "banana";
+ oSource["bar"][4] = "rat";
+
+ oDestination["foo"][0] = "melon";
+ oDestination["baz"][0] = "whale";
+ oDestination["baz"][1] = "dolphin";
+ oDestination["boo"][1] = "raven";
+ CDT oDestination1 = oDestination;
+
+ oDestination.MergeCDT(oSource);
+ fprintf(stderr, "Merge: `%s`\n", oDestination.RecursiveDump().c_str());
+
+ oDestination1.MergeCDT(oSource, CDT::DEEP_MERGE);
+ fprintf(stderr, "Merge: `%s`\n", oDestination1.RecursiveDump().c_str());
+ }
+ fprintf(stderr, "== END ======================================\n");
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/CTPP2Compiler.cpp b/tests/CTPP2Compiler.cpp
new file mode 100644
index 0000000..9803833
--- /dev/null
+++ b/tests/CTPP2Compiler.cpp
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Compiler.cpp
+ *
+ * $CTPP$
+ */
+#include <CTPP2Parser.hpp>
+#include <CTPP2FileSourceLoader.hpp>
+#include <CTPP2ParserException.hpp>
+#include <CTPP2HashTable.hpp>
+#include <CTPP2VMDumper.hpp>
+#include <CTPP2VMOpcodes.h>
+
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ if (argc != 3)
+ {
+ fprintf(stdout, "CTPP2 template compiler v" CTPP_VERSION " (" CTPP_IDENT "). Copyright (c) 2004-2011 CTPP Dev. Team.\n\n");
+ fprintf(stderr, "usage: %s source.ctpp2 destination.ct2\n", argv[0]);
+ return EX_USAGE;
+ }
+
+ VMOpcodeCollector oVMOpcodeCollector;
+ StaticText oSyscalls;
+ StaticData oStaticData;
+ StaticText oStaticText;
+ HashTable oHashTable;
+ CTPP2Compiler oCompiler(oVMOpcodeCollector, oSyscalls, oStaticData, oStaticText, oHashTable);
+
+ try
+ {
+ // Load template
+ CTPP2FileSourceLoader oSourceLoader;
+ oSourceLoader.LoadTemplate(argv[1]);
+
+ // Create template parser
+ CTPP2Parser oCTPP2Parser(&oSourceLoader, &oCompiler, argv[1]);
+
+ // Compile template
+ oCTPP2Parser.Compile();
+ }
+ catch(CTPPLogicError & e)
+ {
+ fprintf(stderr, "ERROR: %s\n", e.what());
+ return EX_SOFTWARE;
+ }
+ catch(CTPPUnixException & e)
+ {
+ fprintf(stderr, "ERROR: I/O in %s: %s\n", e.what(), strerror(e.ErrNo()));
+ return EX_SOFTWARE;
+ }
+ catch(CTPPParserSyntaxError & e)
+ {
+ fprintf(stderr, "ERROR: At line %d, pos. %d: %s\n", e.GetLine(), e.GetLinePos(), e.what());
+ return EX_SOFTWARE;
+ }
+ catch (CTPPParserOperatorsMismatch &e)
+ {
+ fprintf(stderr, "ERROR: At line %d, pos. %d: expected %s, but found </%s>\n", e.GetLine(), e.GetLinePos(), e.Expected(), e.Found());
+ return EX_SOFTWARE;
+ }
+ catch(...)
+ {
+ fprintf(stderr, "ERROR: Bad thing happened.\n");
+ return EX_SOFTWARE;
+ }
+
+ // Get program core
+ UINT_32 iCodeSize = 0;
+ const VMInstruction * oVMInstruction = oVMOpcodeCollector.GetCode(iCodeSize);
+ // Dump program
+ VMDumper oDumper(iCodeSize, oVMInstruction, oSyscalls, oStaticData, oStaticText, oHashTable);
+ UINT_32 iSize = 0;
+ const VMExecutable * aProgramCore = oDumper.GetExecutable(iSize);
+
+ // Open file only if compilation is done
+ FILE * FW = fopen(argv[2], "wb");
+ if (FW == NULL) { fprintf(stderr, "ERROR: Cannot open destination file `%s` for writing\n", argv[2]); return EX_SOFTWARE; }
+
+ // Write to the disc
+ fwrite(aProgramCore, iSize, 1, FW);
+ // All done
+ fclose(FW);
+
+ // Make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
diff --git a/tests/CTPP2DTOA.cpp b/tests/CTPP2DTOA.cpp
new file mode 100644
index 0000000..29d0719
--- /dev/null
+++ b/tests/CTPP2DTOA.cpp
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2004 - 2011 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2DTOA.cpp
+ *
+ * $CTPP$
+ */
+#include "CDT.hpp"
+#include "CTPP2Sprintf.hpp"
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+ #include <sysexits.h>
+#endif
+
+#include <time.h>
+
+using namespace CTPP;
+
+int main(void)
+{
+
+ CDT oArgs;
+ oArgs.PushBack(101.5);
+ oArgs.PushBack(101.4);
+
+ STLW::string sResult;
+ FormatString("_%0.2f_", sResult, oArgs);
+
+ fwrite(sResult.c_str(), sResult.size(), 1, stdout);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/CTPP2Emulator.cpp b/tests/CTPP2Emulator.cpp
new file mode 100644
index 0000000..84e3248
--- /dev/null
+++ b/tests/CTPP2Emulator.cpp
@@ -0,0 +1,207 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMEmulator.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2JSONParser.hpp>
+#include <CTPP2FileOutputCollector.hpp>
+#include <CTPP2FileLogger.hpp>
+#include <CTPP2SyscallFactory.hpp>
+#include <CTPP2VMDebugInfo.hpp>
+#include <CTPP2VM.hpp>
+#include <CTPP2VMFileLoader.hpp>
+#include <CTPP2VMSTDLib.hpp>
+#include <CTPP2VMStackException.hpp>
+#include <CTPP2GetText.hpp>
+
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_TIME_H
+ #include <sys/time.h>
+#endif
+
+#ifdef WIN32
+ #include <CTPP2Time.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <memory>
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ INT_32 iRetCode = EX_SOFTWARE;
+
+ if (argc != 2 && argc != 3 && argc != 4 && argc != 5)
+ {
+ fprintf(stdout, "CTPP2 virtual machine v" CTPP_VERSION " (" CTPP_IDENT "). Copyright (c) 2004-2011 CTPP Dev. Team.\n\n");
+ fprintf(stderr, "usage: %s file.name [data.json] [output.txt | 0] [translation.mo | 0] [limit of steps]\n", argv[0]);
+ return EX_USAGE;
+ }
+
+ // Initialize Standard CTPP library
+ SyscallFactory oSyscallFactory(100);
+ // Load standard library
+ STDLibInitializer::InitLibrary(oSyscallFactory);
+ // Output
+ std::auto_ptr<FileOutputCollector> pOutputCollector(new FileOutputCollector(stdout));
+
+ if (argc >= 4 && strncmp(argv[3], "0", sizeof(argv[3])) != 0) { pOutputCollector.reset(new FileOutputCollector(argv[3], "w+")); }
+
+
+ CTPP2GetText oGetText;
+ if (argc >= 5 && strncmp(argv[4], "0", sizeof(argv[4])) != 0) { oGetText.AddTranslation(argv[4], "test", "unknown"); }
+ oGetText.InitSTDLibFunction(oSyscallFactory);
+ oGetText.SetLanguage(oSyscallFactory, "unknown");
+ oGetText.SetDefaultDomain("test");
+
+ UINT_32 iStepsLimit = 10240;
+ if(argc == 6) { iStepsLimit = atoi(argv[5]); }
+ else
+ {
+ fprintf(stderr, "WARNING: [limit of steps] not set, use default value of %d\n", iStepsLimit);
+ }
+
+ try
+ {
+ // Load program from file
+ VMFileLoader oLoader(argv[1]);
+
+ // Get program core
+ const VMMemoryCore * pVMMemoryCore = oLoader.GetCore();
+
+ CDT oHash(CDT::HASH_VAL);
+
+ // Load JSON data
+ if(argc >= 3)
+ {
+ struct stat oStat;
+ // Get file size
+ if (stat(argv[2], &oStat) == -1 || oStat.st_size == 0) { fprintf(stderr, "ERROR: Cannot get size of file `%s`\n", argv[2]); return EX_SOFTWARE; }
+
+ // Allocate memory
+ CHAR_8 * szJSONBuffer = (CHAR_8 *)malloc(oStat.st_size + 1);
+ // Read from file
+ FILE * F = fopen(argv[2], "rb");
+ if (F == NULL) { fprintf(stderr, "ERROR: Cannot open file `%s` for reading\n", argv[2]); return EX_SOFTWARE; }
+
+ if (fread(szJSONBuffer, oStat.st_size, 1, F) != 1)
+ {
+ fprintf(stderr, "ERROR: Cannot read from file `%s`\n", argv[2]);
+ fclose(F);
+ free(szJSONBuffer);
+ return EX_SOFTWARE;
+ }
+
+ szJSONBuffer[oStat.st_size] = '\0';
+
+ CTPP2JSONParser oJSONParser(oHash);
+ CCHAR_P szEnd = szJSONBuffer + oStat.st_size;
+ oJSONParser.Parse(szJSONBuffer, szEnd);
+
+ // All Done
+ fclose(F);
+ // All done with loading
+ free(szJSONBuffer);
+ }
+ else
+ {
+ fprintf(stderr, "WARNING: [data.json] not given\n");
+ }
+
+ // Logger
+ FileLogger oLogger(stderr);
+
+ // Run program
+ VM oVM(&oSyscallFactory, 10240, 10240, iStepsLimit);
+
+ struct timeval sTimeValLocBegin;
+ gettimeofday(&sTimeValLocBegin, NULL);
+
+ UINT_32 iIP = 0;
+ oVM.Init(pVMMemoryCore, pOutputCollector.get(), &oLogger);
+ oVM.Run(pVMMemoryCore, pOutputCollector.get(), iIP, oHash, &oLogger);
+
+ struct timeval sTimeValLocEnd;
+ gettimeofday(&sTimeValLocEnd, NULL);
+
+ fprintf(stderr, "Completed in %f seconds.\n", (1.0 * (sTimeValLocEnd.tv_sec - sTimeValLocBegin.tv_sec) + 1.0 * (sTimeValLocEnd.tv_usec - sTimeValLocBegin.tv_usec) / 1000000));
+
+ iRetCode = EX_OK;
+ }
+ // CDT
+ catch(CDTTypeCastException & e) { fprintf(stderr, "ERROR: Type Cast %s\n", e.what()); }
+ catch(CDTAccessException & e) { fprintf(stderr, "ERROR: Array index out of bounds: %s\n", e.what()); }
+
+ // Virtual machine
+ catch(IllegalOpcode & e) { fprintf(stderr, "ERROR: Illegal opcode 0x%08X at 0x%08X\n", e.GetOpcode(), e.GetIP()); }
+ catch(InvalidSyscall & e)
+ {
+ if (e.GetIP() != 0)
+ {
+ VMDebugInfo oVMDebugInfo(e.GetDebugInfo());
+ fprintf(stderr, "ERROR: %s at 0x%08X (Template file \"%s\", Line %d, Pos %d)\n", e.what(), e.GetIP(), e.GetSourceName(), oVMDebugInfo.GetLine(), oVMDebugInfo.GetLinePos());
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported syscall: \"%s\"\n", e.what());
+ }
+ }
+ catch(InvalidCall & e)
+ {
+ VMDebugInfo oVMDebugInfo(e.GetDebugInfo());
+ fprintf(stderr, "ERROR: at 0x%08X: Invalid block name \"%s\" in file \"%s\", Line %d, Pos %d\n", e.GetIP(), e.what(), e.GetSourceName(), oVMDebugInfo.GetLine(), oVMDebugInfo.GetLinePos());
+ }
+ catch(CodeSegmentOverrun & e) { fprintf(stderr, "ERROR: %s at 0x%08X\n", e.what(), e.GetIP()); }
+ catch(StackOverflow & e) { fprintf(stderr, "ERROR: Stack overflow at 0x%08X\n", e.GetIP()); }
+ catch(StackUnderflow & e) { fprintf(stderr, "ERROR: Stack underflow at 0x%08X\n", e.GetIP()); }
+ catch(ExecutionLimitReached & e) { fprintf(stderr, "ERROR: Execution limit of %d step(s) reached at 0x%08X\n", iStepsLimit, e.GetIP()); }
+ catch(VMException & e) { fprintf(stderr, "ERROR: VM generic exception: %s at 0x%08X\n", e.what(), e.GetIP()); }
+
+ // CTPP
+ catch(CTPPLogicError & e) { fprintf(stderr, "ERROR: %s\n", e.what()); }
+ catch(CTPPUnixException & e) { fprintf(stderr, "ERROR: I/O in %s: %s\n", e.what(), strerror(e.ErrNo())); }
+ catch(CTPPException & e) { fprintf(stderr, "ERROR: CTPP Generic exception: %s\n", e.what()); }
+
+ // Destroy standard library
+ STDLibInitializer::DestroyLibrary(oSyscallFactory);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return iRetCode;
+}
+// End.
+
diff --git a/tests/CTPP2Interpreter.cpp b/tests/CTPP2Interpreter.cpp
new file mode 100644
index 0000000..ef25fb7
--- /dev/null
+++ b/tests/CTPP2Interpreter.cpp
@@ -0,0 +1,193 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2Interpreter.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2Compiler.hpp>
+#include <CTPP2JSONParser.hpp>
+#include <CTPP2FileOutputCollector.hpp>
+#include <CTPP2FileLogger.hpp>
+#include <CTPP2FileSourceLoader.hpp>
+#include <CTPP2HashTable.hpp>
+#include <CTPP2JSONFileParser.hpp>
+#include <CTPP2Parser.hpp>
+#include <CTPP2ParserException.hpp>
+#include <CTPP2StaticData.hpp>
+#include <CTPP2StaticText.hpp>
+#include <CTPP2SyscallFactory.hpp>
+#include <CTPP2VMDebugInfo.hpp>
+#include <CTPP2VMDumper.hpp>
+#include <CTPP2VM.hpp>
+#include <CTPP2VMFileLoader.hpp>
+#include <CTPP2VMOpcodeCollector.hpp>
+#include <CTPP2VMSTDLib.hpp>
+#include <CTPP2VMStackException.hpp>
+#include <CTPP2GetText.hpp>
+
+
+#include <stdio.h>
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ INT_32 iRetCode = EX_SOFTWARE;
+
+ if (argc != 2 && argc != 3 && argc != 4 && argc != 5)
+ {
+ fprintf(stdout, "CTPP2 interpreter v" CTPP_VERSION " (" CTPP_IDENT "). Copyright (c) 2004-2011 CTPP Dev. Team.\n\n");
+ fprintf(stderr, "usage: %s file.name [data.json] [translation.mo | 0] [limit of steps]\n", argv[0]);
+ return EX_USAGE;
+ }
+
+ // Output
+ FileOutputCollector oOutputCollector(stdout);
+
+ // Initialize Standard CTPP library
+ SyscallFactory oSyscallFactory(100);
+ // Load standard library
+ STDLibInitializer::InitLibrary(oSyscallFactory);
+
+ CTPP2GetText oGetText;
+ if (argc >= 4 && strncmp(argv[3], "0", sizeof(argv[3])) != 0) { oGetText.AddTranslation(argv[3], "test", "unknown"); }
+ oGetText.InitSTDLibFunction(oSyscallFactory);
+ oGetText.SetLanguage(oSyscallFactory, "unknown");
+ oGetText.SetDefaultDomain("test");
+
+ UINT_32 iStepsLimit = 10240;
+ if(argc == 5) { iStepsLimit = atoi(argv[4]); }
+ else
+ {
+ fprintf(stderr, "WARNING: [limit of steps] not set, use default value of %d\n", iStepsLimit);
+ }
+
+ try
+ {
+
+ VMOpcodeCollector oVMOpcodeCollector;
+ StaticText oSyscalls;
+ StaticData oStaticData;
+ StaticText oStaticText;
+ HashTable oHashTable;
+ CTPP2Compiler oCompiler(oVMOpcodeCollector, oSyscalls, oStaticData, oStaticText, oHashTable);
+
+ // Load template
+ CTPP2FileSourceLoader oSourceLoader;
+ oSourceLoader.LoadTemplate(argv[1]);
+
+ // Create template parser
+ CTPP2Parser oCTPP2Parser(&oSourceLoader, &oCompiler, argv[1]);
+
+ // Compile template
+ oCTPP2Parser.Compile();
+
+ // Get program core
+ UINT_32 iCodeSize = 0;
+ const VMInstruction * oVMInstruction = oVMOpcodeCollector.GetCode(iCodeSize);
+ // Dump program
+ VMDumper oDumper(iCodeSize, oVMInstruction, oSyscalls, oStaticData, oStaticText, oHashTable);
+ UINT_32 iSize = 0;
+ const VMExecutable * aProgramCore = oDumper.GetExecutable(iSize);
+
+ // Get program core
+ const VMMemoryCore oVMMemoryCore(aProgramCore);
+
+ CDT oHash(CDT::HASH_VAL);
+
+ // Load JSON data
+ if(argc >= 3)
+ {
+ // Our data
+ CTPP2JSONFileParser oJSONFileParser(oHash);
+ oJSONFileParser.Parse(argv[2]);
+ }
+ else
+ {
+ fprintf(stderr, "WARNING: [data.json] not given\n");
+ }
+
+ // Logger
+ FileLogger oLogger(stderr);
+
+ // Run program
+ VM oVM(&oSyscallFactory, 10240, 10240, iStepsLimit);
+ UINT_32 iIP = 0;
+
+ oVM.Init(&oVMMemoryCore, &oOutputCollector, &oLogger);
+ oVM.Run(&oVMMemoryCore, &oOutputCollector, iIP, oHash, &oLogger);
+
+ iRetCode = EX_OK;
+ }
+ catch(CTPPParserSyntaxError & e) { fprintf(stderr, "ERROR: At line %d, pos. %d: %s\n", e.GetLine(), e.GetLinePos(), e.what()); }
+ catch(CTPPParserOperatorsMismatch & e) { fprintf(stderr, "ERROR: At line %d, pos. %d: expected %s, but found </%s>\n", e.GetLine(), e.GetLinePos(), e.Expected(), e.Found()); }
+
+ // CDT
+ catch(CDTTypeCastException & e) { fprintf(stderr, "ERROR: Type Cast %s\n", e.what()); }
+ catch(CDTAccessException & e) { fprintf(stderr, "ERROR: Array index out of bounds: %s\n", e.what()); }
+
+ // Virtual machine
+ catch(IllegalOpcode & e) { fprintf(stderr, "ERROR: Illegal opcode 0x%08X at 0x%08X\n", e.GetOpcode(), e.GetIP()); }
+ catch(InvalidSyscall & e)
+ {
+ if (e.GetIP() != 0)
+ {
+ VMDebugInfo oVMDebugInfo(e.GetDebugInfo());
+ fprintf(stderr, "ERROR: %s at 0x%08X (Template file \"%s\", Line %d, Pos: %d)\n", e.what(), e.GetIP(), e.GetSourceName(), oVMDebugInfo.GetLine(), oVMDebugInfo.GetLinePos());
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported syscall: \"%s\"\n", e.what());
+ }
+ }
+ catch(CodeSegmentOverrun & e) { fprintf(stderr, "ERROR: %s at 0x%08X\n", e.what(), e.GetIP()); }
+ catch(StackOverflow & e) { fprintf(stderr, "ERROR: Stack overflow at 0x%08X\n", e.GetIP()); }
+ catch(StackUnderflow & e) { fprintf(stderr, "ERROR: Stack underflow at 0x%08X\n", e.GetIP()); }
+ catch(ExecutionLimitReached & e) { fprintf(stderr, "ERROR: Execution limit of %d step(s) reached at 0x%08X\n", iStepsLimit, e.GetIP()); }
+ catch(VMException & e) { fprintf(stderr, "ERROR: VM generic exception: %s at 0x%08X\n", e.what(), e.GetIP()); }
+
+ // CTPP
+ catch(CTPPLogicError & e) { fprintf(stderr, "ERROR: %s\n", e.what()); }
+ catch(CTPPUnixException & e) { fprintf(stderr, "ERROR: I/O in %s: %s\n", e.what(), strerror(e.ErrNo())); }
+ catch(CTPPException & e) { fprintf(stderr, "ERROR: CTPP Generic exception: %s\n", e.what()); }
+
+ catch(...) { fprintf(stderr, "ERROR: Bad thing happened.\n"); }
+
+ // Destroy standard library
+ STDLibInitializer::DestroyLibrary(oSyscallFactory);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return iRetCode;
+}
+// End.
+
diff --git a/tests/CTPP2JSONParser.cpp b/tests/CTPP2JSONParser.cpp
new file mode 100644
index 0000000..4a9f1fe
--- /dev/null
+++ b/tests/CTPP2JSONParser.cpp
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2JSONParser.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2JSONParser.hpp>
+#include <CTPP2ParserException.hpp>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ fprintf(stdout, "CTPP2 JSON parser v" CTPP_VERSION " (" CTPP_IDENT "). Copyright (c) 2004-2011 CTPP Dev. Team.\n\n");
+
+ if (argc != 2) { fprintf(stderr, "usage: %s file.json\n", argv[0]); return EX_USAGE; }
+
+ // Get file size
+ struct stat oStat;
+ if (stat(argv[1], &oStat) == -1 || oStat.st_size == 0) { fprintf(stderr, "ERROR: Cannot get size of file `%s`\n", argv[1]); return EX_SOFTWARE; }
+
+ // Load file
+ FILE * F = fopen(argv[1], "r");
+ if (F == NULL) { fprintf(stderr, "ERROR: Cannot open file `%s` for writing\n", argv[1]); return EX_SOFTWARE; }
+
+ // Allocate memory
+ CHAR_8 * szJSONBuffer = (CHAR_8 *)malloc(oStat.st_size + 1);
+ // Read from file
+ if (fread(szJSONBuffer, oStat.st_size, 1, F) != 1)
+ {
+ fprintf(stderr, "ERROR: Cannot read from file `%s`\n", argv[1]);
+ fclose(F);
+ free(szJSONBuffer);
+ return EX_SOFTWARE;
+ }
+
+ szJSONBuffer[oStat.st_size] = '\0';
+
+ CDT oCDT;
+ CTPP2JSONParser oJSONParser(oCDT);
+
+ CCHAR_P szEnd = szJSONBuffer + oStat.st_size;
+
+ try
+ {
+ oJSONParser.Parse(szJSONBuffer, szEnd);
+ }
+ catch(CTPPParserSyntaxError & e) { fprintf(stderr, "ERROR: At line %d, char %d: %s\n", e.GetLine(), e.GetLinePos(), e.what()); return EX_SOFTWARE; }
+
+ fprintf(stderr, "%s\n", oCDT.Dump().c_str());
+
+ // All Done
+ fclose(F);
+
+ // All done with loading
+ free(szJSONBuffer);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/CTPP2VMTest.cpp b/tests/CTPP2VMTest.cpp
new file mode 100644
index 0000000..91562d3
--- /dev/null
+++ b/tests/CTPP2VMTest.cpp
@@ -0,0 +1,307 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * CTPP2VMTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CTPP2HashTable.hpp>
+#include <CTPP2VMDumper.hpp>
+#include <CTPP2VMExecutable.hpp>
+#include <CTPP2VMOpcodes.h>
+#include <CTPP2VMInstruction.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ if (argc != 2) { fprintf(stderr, "usage: %s file.name\n", argv[0]); return EX_USAGE; }
+
+ // 1. Create static text segment
+ StaticText oStaticText;
+
+ StaticText oSyscalls;
+
+ HashTable oHashTable;
+
+ // Text Data
+ // 1234567890123456789
+ const UINT_32 iS1 = oStaticText.StoreData("CTPP2 Hello, World\n", 19); // returns '0'
+ // 1234567890123
+ const UINT_32 iS2 = oStaticText.StoreData("Concatenation", 13); // returns '1'
+ // 1
+ const UINT_32 iS3 = oStaticText.StoreData(" ", 1); // returns '2'
+ // 1234
+ const UINT_32 iS4 = oStaticText.StoreData("test.\n", 6); // returns '3'
+ // 1234
+ const UINT_32 iOK = oStaticText.StoreData("OK\n", 2); // returns '4'
+ const UINT_32 iNOK = oStaticText.StoreData("NOK\n", 3); // returns '5'
+
+ // Numberic Data
+ StaticData oStaticData;
+ const UINT_32 iN0 = oStaticData.StoreInt(0);
+ const UINT_32 iN1977 = oStaticData.StoreInt(1977);
+ const UINT_32 iN10 = oStaticData.StoreInt(10);
+ const UINT_32 iN8 = oStaticData.StoreInt(8);
+
+
+ //const UINT_32 iN1 = oStaticData.StoreInt(1);
+ const UINT_32 iN2 = oStaticData.StoreInt(2);
+ const UINT_32 iN3 = oStaticData.StoreInt(3);
+ //const UINT_32 iN4 = oStaticData.StoreInt(4);
+
+ const UINT_32 iF1234 = oStaticData.StoreFloat(12.34);
+
+ //const UINT_32 iSVar = oStaticText.StoreData("var", 3);
+ const UINT_32 iSDic = oStaticText.StoreData("dic", 3);
+ const UINT_32 iSArr = oStaticText.StoreData("arr", 3);
+ const UINT_32 iSVal = oStaticText.StoreData("val", 3);
+
+ UINT_32 iSyscallEmitterNum = oSyscalls.StoreData("__ctpp2_emitter", 15);
+ //UINT_32 iSyscallObjDumpNum = oSyscalls.StoreData("OBJ_DUMP", 8);
+
+ VMInstruction aCode[] =
+ {
+ {NOP , 0, 0}, // 0
+ {PUSH | ARG_SRC_AR, 0, 0}, // 1
+ {PUSH | ARG_SRC_BR, 0, 0}, // 2
+ {PUSH | ARG_SRC_CR, 0, 0}, // 3
+ {PUSH | ARG_SRC_DR, 0, 0}, // 4
+ {PUSH | ARG_SRC_ER, 0, 0}, // 5
+ {PUSH | ARG_SRC_FR, 0, 0}, // 6
+ {PUSH | ARG_SRC_GR, 0, 0}, // 7
+ {PUSH | ARG_SRC_HR, 0, 0}, // 8
+
+ {PUSH13 , 0, 0}, // 9
+ {PUSH47 , 0, 0}, // 10
+ {PUSHA , 0, 0}, // 11
+
+ {POPA , 0, 0}, // 12
+ {POP47 , 0, 0}, // 13
+ {POP13 , 0, 0}, // 14
+
+ {POP | ARG_SRC_HR , 0, 0}, // 15
+ {POP | ARG_SRC_GR , 0, 0}, // 16
+ {POP | ARG_SRC_FR , 0, 0}, // 17
+ {POP | ARG_SRC_ER , 0, 0}, // 18
+ {POP | ARG_SRC_DR , 0, 0}, // 19
+ {POP | ARG_SRC_CR , 0, 0}, // 20
+ {POP | ARG_SRC_BR , 0, 0}, // 21
+ {POP | ARG_SRC_AR , 0, 0}, // 22
+
+ {PUSH | ARG_SRC_INT, iN1977, 0}, // 23
+ {PUSH | ARG_SRC_INT, iN1977, 0}, // 24
+ {PUSH | ARG_SRC_INT, iN1977, 0}, // 25
+ {PUSH | ARG_SRC_FLOAT, iF1234, 0}, // 26
+ {PUSH | ARG_SRC_INT, iN8, 0}, // 27
+ {PUSH | ARG_SRC_INT, iN3, 0}, // 28
+ {PUSH | ARG_SRC_INT, iN2, 0}, // 29
+
+ {ADD | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 30 3 + 2 -> 5
+ {SUB | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 31 8 - 5 -> 3
+ {MUL | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 32 3 * 12.34 -> 37.02
+ {DIV | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 33 1977 / 37.02 -> 53.4035656401945
+ {IDIV | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 34 1977 div 53 -> 37
+ {MOD | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 }, // 35 1977 mod 37 -> 16
+
+ {INC | ARG_SRC_STACK, 0, 0 }, // 35 // ++ 16
+ {DEC | ARG_SRC_STACK, 0, 0 }, // 36 // -- 16
+
+ {PUSH | ARG_SRC_STR, iS2, 0}, // 38
+ {PUSH | ARG_SRC_STR, iS3, 0}, // 39
+ {PUSH | ARG_SRC_STR, iS4, 0}, // 40
+
+ {CONCAT | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 },// 41
+ {CONCAT | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 },// 42
+ {CONCAT | ARG_SRC_STACK | ARG_DST_STACK, 0, 0 },// 43
+
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 44
+
+
+ {MOV | ARG_SRC_INT |ARG_DST_FR, iN8, 0}, // 45
+ {MOV | ARG_SRC_INT |ARG_DST_ER, iN0, 0}, // 46
+
+ {PUSH | ARG_SRC_STR, iS1, 0}, // 47
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 48
+ {LOOP | ARG_SRC_FR | ARG_DST_ER, 47, 0}, // 49
+
+ {PUSH | ARG_SRC_INT, iN8, 0}, // 50
+ {PUSH | ARG_SRC_INT, iN10, 0}, // 51
+ {CMP | ARG_SRC_STACK | ARG_DST_STACK, 0, 0}, // 52
+
+ {JE, 57, 0}, // 53
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 54
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 55
+ {JMP, 59, 0}, // 56
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 57
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 58
+
+ {JN, 63, 0}, // 59
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 60
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 61
+ {JMP, 65, 0}, // 62
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 63
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 64
+
+ {JL, 69, 0}, // 65
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 66
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 67
+ {JMP, 71, 0}, // 68
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 69
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 70
+
+ {JG, 75, 0}, // 71
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 72
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 73
+ {JMP, 77, 0}, // 74
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 75
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 76
+
+ {JGE, 81, 0}, // 77
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 78
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 79
+ {JMP, 83, 0}, // 80
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 81
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 82
+
+ {JLE, 87, 0}, // 83
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 84
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 85
+ {JMP, 89, 0}, // 86
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 87
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 88
+
+ {RJE, 4, 0}, // 89
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 90
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 91
+ {RJMP, 3, 0}, // 92
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 93
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 94
+
+ {RJN, 4, 0}, // 95
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 96
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 97
+ {RJMP, 3, 0}, // 98
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 99
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 100
+
+ {RJL, 4, 0}, // 101
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 102
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 103
+ {JMP, 3, 0}, // 104
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 105
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 106
+
+ {RJG, 4, 0}, // 106
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 107
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 108
+ {RJMP, 3, 0}, // 109
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 110
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 111
+
+ {RJGE, 4, 0}, // 112
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 113
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 114
+ {RJMP, 3, 0}, // 115
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 116
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 117
+
+ {RJLE, 4, 0}, // 118
+ {PUSH | ARG_SRC_STR, iNOK, 0}, // 119
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 120
+ {RJMP, 3, 0}, // 121
+ {PUSH | ARG_SRC_STR, iOK, 0}, // 122
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 123
+
+ // // { 'dic': { 'arr': [ 0, 1, 2, 3], 'val' : 'ind' }, 'ind' : 2 }
+ // dic{'arr'}[dic{val}] === ( ( HR{'dic'} ){'arr'} ) [ (HR{'dic'}){ (HR{'dic'} ) {'val'}
+ {SYSCALL, SYSCALL_PARAMS(iSyscallEmitterNum, 0), 0}, // 124
+ {MOV | ARG_SRC_STACK | ARG_DST_HR, 0, 0}, // 125
+ {POP | ARG_SRC_AR, 0, 0}, // 126
+
+ {PUSH| ARG_SRC_AR, 0, 0}, // 127
+
+ // IsVar
+ // ( HR{'dic'} ){'arr'}
+ {PUSH| ARG_SRC_HR, 0, 0}, // 128
+ {REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iSDic, 0}, // 129
+ {REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iSArr, 0}, // 130
+
+ // IsVar
+ // ( HR{'dic'} ){'val'}
+ {PUSH| ARG_SRC_HR, 0, 0}, // 131
+ {REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iSDic, 0}, // 132
+ {REPLACE | ARG_SRC_IND_STR | ARG_DST_STACK, iSVal, 0}, // 133
+
+ // {}
+ {POP | ARG_SRC_AR, 0, 0}, // 134
+ // IsVar
+ {PUSH| ARG_SRC_HR, 0, 0}, // 135
+ {REPLSTR | ARG_SRC_AR, 0, 0}, // 136
+
+ // []
+ {POP | ARG_SRC_AR, 0, 0}, // 137
+ {REPLINT | ARG_SRC_AR, 0, 0}, // 138
+
+// {SYSCALL, SYSCALL_PARAMS(iSyscallObjDumpNum, 0), 0}, // 139
+ {OUTPUT | ARG_SRC_STACK, 0, 0}, // 140
+
+
+ {HLT , 0, 0} // 141
+ };
+
+ const UINT_32 iCodeSize = sizeof(aCode) / sizeof(VMInstruction);
+
+ fprintf(stderr, "Code size: %d\n", iCodeSize);
+
+ FILE * F = fopen(argv[1], "wb");
+ if (F == NULL) { fprintf(stderr, "ERROR: Cannot open file `%s` for writing\n", argv[1]); return EX_SOFTWARE; }
+
+ VMDumper oDumper(iCodeSize, aCode, oSyscalls, oStaticData, oStaticText, oHashTable);
+
+ UINT_32 iSize = 0;
+ const VMExecutable * aProgramCore = oDumper.GetExecutable(iSize);
+
+ fwrite(aProgramCore, iSize, 1, F);
+
+ fclose(F);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/HashTest.cpp b/tests/HashTest.cpp
new file mode 100644
index 0000000..f471641
--- /dev/null
+++ b/tests/HashTest.cpp
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * HashTest.hpp
+ *
+ * $CTPP$
+ */
+#include <CTPP2HashTable.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+
+int main(void)
+{
+ HashTable oHashTable;
+
+ oHashTable.Put("1", 1, 12345);
+ oHashTable.Put("12", 2, 23456);
+ oHashTable.Put("123", 3, 34567);
+ oHashTable.Put("1234", 4, 45678);
+ oHashTable.Put("12345", 5, 56789);
+
+
+ fprintf(stdout, "1 => %d\n", INT_32(oHashTable.Get("1", 1)));
+ fprintf(stdout, "12 => %d\n", INT_32(oHashTable.Get("12", 2)));
+ fprintf(stdout, "123 => %d\n", INT_32(oHashTable.Get("123", 3)));
+ fprintf(stdout, "1234 => %d\n", INT_32(oHashTable.Get("1234", 4)));
+ fprintf(stdout, "12345 => %d\n", INT_32(oHashTable.Get("12345", 5)));
+
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/PERLPerfTest.pl b/tests/PERLPerfTest.pl
new file mode 100755
index 0000000..0c71a1c
--- /dev/null
+++ b/tests/PERLPerfTest.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl -w
+use strict;
+use Time::HiRes qw(gettimeofday tv_interval);
+
+my $t0 = [gettimeofday];
+
+my $NI = 0;
+my @AArray;
+for ($NI = 0; $NI < 10000; ++$NI)
+{
+ if ($NI % 2 == 0) { $AArray[$NI] = $NI; }
+ else
+ {
+ my $NJ = 0;
+ for ($NJ = 0; $NJ < 100; ++$NJ)
+ {
+ my $SKey = sprintf("_%d_%d_", $NI, $NJ);
+ $AArray[$NI] -> {$SKey} -> [10] = $NI;
+ }
+ }
+
+}
+
+my $elapsed = tv_interval($t0);
+print("Time: " . $elapsed . "\n")
diff --git a/tests/PHPPerfTest.php b/tests/PHPPerfTest.php
new file mode 100755
index 0000000..2f0bd3d
--- /dev/null
+++ b/tests/PHPPerfTest.php
@@ -0,0 +1,32 @@
+<?
+$mtime = microtime();
+$mtime = explode(" ",$mtime);
+$mtime = $mtime[1] + $mtime[0];
+$starttime = $mtime;
+
+$NI = 0;
+#$AArray = new Array();
+
+for ($NI = 0; $NI < 10000; ++$NI)
+{
+ if ($NI % 2 == 0) { $AArray[$NI] = $NI; }
+ else
+ {
+ $NJ = 0;
+ for ($NJ = 0; $NJ < 100; ++$NJ)
+ {
+ $SKey = sprintf("_%d_%d_", $NI, $NJ);
+ $AArray[$NI][$SKey][10] = $NI;
+ }
+ }
+
+}
+
+$mtime = microtime();
+$mtime = explode(" ",$mtime);
+$mtime = $mtime[1] + $mtime[0];
+$endtime = $mtime;
+$elapsed = ($endtime - $starttime);
+
+print("Time: " . $elapsed . "\n")
+?>
diff --git a/tests/SimpleCompilerTest.cpp b/tests/SimpleCompilerTest.cpp
new file mode 100644
index 0000000..5c3834d
--- /dev/null
+++ b/tests/SimpleCompilerTest.cpp
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * SimpleCompilerTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CDT.hpp>
+#include <CTPP2SimpleCompiler.hpp>
+
+using namespace CTPP;
+
+// test case
+int main(int argc, char ** argv)
+{
+ if (argc != 3) { fprintf(stderr, "usage: %s file.tmpl file.ct2\n", argv[0]); return EX_USAGE; }
+
+ SimpleCompiler oSimpleCompiler(argv[1]);
+
+ oSimpleCompiler.Save(argv[2]);
+
+ // Make Valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+}
+// End.
diff --git a/tests/SimpleVMTest.cpp b/tests/SimpleVMTest.cpp
new file mode 100644
index 0000000..c311dee
--- /dev/null
+++ b/tests/SimpleVMTest.cpp
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2004 - 2010 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * SimpleVMTest.hpp
+ *
+ * $CTPP$
+ */
+#include <CDT.hpp>
+#include <CTPP2FileLogger.hpp>
+#include <CTPP2SimpleVM.hpp>
+#include <CTPP2VMFileLoader.hpp>
+
+using namespace CTPP;
+
+// test case
+int main(int argc, char ** argv)
+{
+ if (argc != 2) { fprintf(stderr, "usage: %s file.ct2\n", argv[0]); return EX_USAGE; }
+
+ SimpleVM oSimpleVM;
+
+ // Create data
+ CDT oHello;
+ oHello["hello"] = "Hello, World!";
+
+ // Load template file
+ VMFileLoader oLoader(argv[1]);
+
+ // Create logger object
+ FileLogger oLogger(stderr);
+
+ // Execute template and write data to standard output
+ oSimpleVM.Run(oHello, oLoader, stdout, oLogger);
+
+ // Execute template and write data to string
+ std::string sResult;
+ oSimpleVM.Run(oHello, oLoader, sResult, oLogger);
+
+ // Make Valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+}
+// End.
diff --git a/tests/StaticTextTest.cpp b/tests/StaticTextTest.cpp
new file mode 100644
index 0000000..ddf8fb1
--- /dev/null
+++ b/tests/StaticTextTest.cpp
@@ -0,0 +1,78 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMTest.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2StaticText.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+
+using namespace CTPP;
+
+int main(void)
+{
+ StaticText oStaticText;
+
+ oStaticText.StoreData("Test", 4);
+ oStaticText.StoreData("really", 6);
+ oStaticText.StoreData(" passed?", 8);
+ oStaticText.StoreData("1234", 4);
+
+ fprintf(stderr, "Stored text: ");
+ UINT_32 iDataSize = 0;
+ CCHAR_P sData = oStaticText.GetData(0, iDataSize);
+ fwrite(sData, iDataSize, 1, stderr);
+
+ sData = oStaticText.GetData(2, iDataSize);
+ fwrite(sData, iDataSize, 1, stderr);
+
+ sData = oStaticText.GetData(6, iDataSize);
+ if (sData == NULL) { fprintf(stderr, "\nNon-existent text segment: OK\nYet another stored text: "); }
+ else { return EX_SOFTWARE; }
+
+ sData = oStaticText.GetData(1, iDataSize);
+ fwrite(sData, iDataSize, 1, stderr);
+
+ fprintf(stderr, "\n");
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/VMArgStackTest.cpp b/tests/VMArgStackTest.cpp
new file mode 100644
index 0000000..bf6533b
--- /dev/null
+++ b/tests/VMArgStackTest.cpp
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMArgStackTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CTPP2VMArgStack.hpp>
+#include <CTPP2VMStackException.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+
+int main(void)
+{
+ UINT_32 iFlag = 2;
+
+ VMArgStack oVMArgStack(5);
+
+ oVMArgStack.PushElement(1);
+ oVMArgStack.PushElement(1.1);
+ oVMArgStack.PushElement("1.2");
+ oVMArgStack.PushElement(CDT(1));
+
+ CDT oCDT;
+ oCDT[1][10][10] = 1;
+ oVMArgStack.PushElement(oCDT);
+
+ try
+ {
+ oVMArgStack.PushElement(0);
+ }
+ catch(StackOverflow & e)
+ {
+ --iFlag;
+ }
+
+ oVMArgStack.PopElement();
+ oVMArgStack.PopElement();
+ oVMArgStack.PopElement();
+ oVMArgStack.PopElement();
+ oVMArgStack.PopElement();
+ try
+ {
+ oVMArgStack.PopElement();
+ }
+ catch(StackUnderflow & e)
+ {
+ --iFlag;
+ }
+
+ INT_32 iExitCode = EX_SOFTWARE;
+
+ if (iFlag == 0) { fprintf(stdout, "OK\n"); iExitCode = EX_OK; }
+ else { fprintf(stdout, "FAILED\n"); }
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return iExitCode;
+}
+// End.
+
diff --git a/tests/VMCodeStackTest.cpp b/tests/VMCodeStackTest.cpp
new file mode 100644
index 0000000..a95e8dc
--- /dev/null
+++ b/tests/VMCodeStackTest.cpp
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMArgStackTest.cpp
+ *
+ * $CTPP$
+ */
+#include <CTPP2VMCodeStack.hpp>
+#include <CTPP2VMStackException.hpp>
+
+#include <stdio.h>
+
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
+
+using namespace CTPP;
+
+
+int main(void)
+{
+ VMCodeStack oVMCodeStack(5);
+
+ UINT_32 iFlag = 2;
+
+ oVMCodeStack.PushAddress(1);
+ oVMCodeStack.PushAddress(2);
+ oVMCodeStack.PushAddress(3);
+ oVMCodeStack.PushAddress(4);
+ oVMCodeStack.PushAddress(5);
+
+ try
+ {
+ oVMCodeStack.PushAddress(0);
+ }
+ catch(StackOverflow & e)
+ {
+ --iFlag;
+ }
+
+ oVMCodeStack.PopAddress();
+ oVMCodeStack.PopAddress();
+ oVMCodeStack.PopAddress();
+ oVMCodeStack.PopAddress();
+ oVMCodeStack.PopAddress();
+
+ try
+ {
+ oVMCodeStack.PopAddress();
+ }
+ catch(StackUnderflow & e)
+ {
+ --iFlag;
+ }
+
+ INT_32 iExitCode = EX_SOFTWARE;
+
+ if (iFlag == 0) { fprintf(stdout, "OK\n"); iExitCode = EX_OK; }
+ else { fprintf(stdout, "FAILED\n"); }
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return iExitCode;
+}
+// End.
+
diff --git a/tests/VMDumperTest.cpp b/tests/VMDumperTest.cpp
new file mode 100644
index 0000000..33c5a05
--- /dev/null
+++ b/tests/VMDumperTest.cpp
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMDumperTest.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2Exception.hpp>
+#include <CTPP2VMFileLoader.hpp>
+#include <CTPP2VMDumper.hpp>
+
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ if (argc != 3)
+ {
+ fprintf(stderr, "usage: %s file_in.ct2 filename_out.ct2\n", argv[0]);
+ return EX_USAGE;
+ }
+
+ try
+ {
+ // Load program from file
+ VMFileLoader oLoader(argv[1]);
+
+ // Get program core
+ const VMMemoryCore * pVMMemoryCore = oLoader.GetCore();
+
+ // Dump program
+ VMDumper oDumper(*pVMMemoryCore);
+ UINT_32 iSize = 0;
+ const VMExecutable * aProgramCore = oDumper.GetExecutable(iSize);
+
+ // Open file only if compilation is done
+ FILE * FW = fopen(argv[2], "wb");
+ if (FW == NULL) { fprintf(stderr, "ERROR: Cannot open destination file `%s` for writing\n", argv[2]); return EX_SOFTWARE; }
+
+ // Write to the disc
+ fwrite(aProgramCore, iSize, 1, FW);
+ // All done
+ fclose(FW);
+
+ }
+ catch(CTPPLogicError & e) { fprintf(stderr, "ERROR: %s\n", e.what()); }
+ catch(CTPPUnixException & e) { fprintf(stderr, "ERROR: I/O in %s: %s\n", e.what(), strerror(e.ErrNo())); }
+ catch(std::exception & e) { fprintf(stderr, "ERROR: %s\n", e.what()); }
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return EX_OK;
+}
+// End.
+
diff --git a/tests/VMEmulator.cpp b/tests/VMEmulator.cpp
new file mode 100644
index 0000000..e82cd35
--- /dev/null
+++ b/tests/VMEmulator.cpp
@@ -0,0 +1,189 @@
+/*-
+ * Copyright (c) 2006, 2007 CTPP Team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the CTPP Team 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 REGENTS 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 REGENTS 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.
+ *
+ * VMEmulator.cpp
+ *
+ * $CTPP$
+ */
+
+#include <CTPP2JSONParser.hpp>
+#include <CTPP2FileOutputCollector.hpp>
+#include <CTPP2FileLogger.hpp>
+#include <CTPP2SyscallFactory.hpp>
+#include <CTPP2VMDebugInfo.hpp>
+#include <CTPP2VM.hpp>
+#include <CTPP2VMFileLoader.hpp>
+#include <CTPP2VMSTDLib.hpp>
+#include <CTPP2VMStackException.hpp>
+
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_TIME_H
+ #include <sys/time.h>
+#endif
+
+#ifdef WIN32
+ #include <CTPP2Time.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace CTPP;
+
+int main(int argc, char ** argv)
+{
+ INT_32 iRetCode = EX_SOFTWARE;
+
+ if (argc != 2 && argc != 3 && argc != 4)
+ {
+ fprintf(stdout, "CTPP2 virtual machine v" CTPP_VERSION " (" CTPP_IDENT "). Copyright (c) 2004-2011 CTPP Dev. Team.\n\n");
+ fprintf(stderr, "usage: %s file.name [data.json] [limit of steps]\n", argv[0]);
+ return EX_USAGE;
+ }
+
+ // Output
+ FileOutputCollector oOutputCollector(stdout);
+
+ // Initialize Standard CTPP library
+ SyscallFactory oSyscallFactory(100);
+ // Load standard library
+ STDLibInitializer::InitLibrary(oSyscallFactory);
+
+ UINT_32 iStepsLimit = 10240;
+ if(argc == 4) { iStepsLimit = atoi(argv[3]); }
+ else
+ {
+ fprintf(stderr, "WARNING: [limit of steps] not set, use default value of %d\n", iStepsLimit);
+ }
+
+ try
+ {
+ // Load program from file
+ VMFileLoader oLoader(argv[1]);
+
+ // Get program core
+ const VMMemoryCore * pVMMemoryCore = oLoader.GetCore();
+
+ CDT oHash(CDT::HASH_VAL);
+
+ // Load JSON data
+ if(argc >= 3)
+ {
+ struct stat oStat;
+ // Get file size
+ if (stat(argv[2], &oStat) == -1 || oStat.st_size == 0) { fprintf(stderr, "ERROR: Cannot get size of file `%s`\n", argv[2]); return EX_SOFTWARE; }
+
+ // Allocate memory
+ CHAR_8 * szJSONBuffer = (CHAR_8 *)malloc(oStat.st_size + 1);
+ // Read from file
+ FILE * F = fopen(argv[2], "rb");
+ if (F == NULL) { fprintf(stderr, "ERROR: Cannot open file `%s` for reading\n", argv[2]); return EX_SOFTWARE; }
+
+ fread(szJSONBuffer, oStat.st_size, 1, F);
+ szJSONBuffer[oStat.st_size] = '\0';
+
+ CTPP2JSONParser oJSONParser(oHash);
+ CCHAR_P szEnd = szJSONBuffer + oStat.st_size;
+ oJSONParser.Parse(szJSONBuffer, szEnd);
+
+ // All Done
+ fclose(F);
+ // All done with loading
+ free(szJSONBuffer);
+ }
+ else
+ {
+ fprintf(stderr, "WARNING: [data.json] not given\n");
+ }
+
+ // Logger
+ FileLogger oLogger(stderr);
+
+ // Run program
+ VM oVM(&oSyscallFactory, 10240, 10240, iStepsLimit);
+ UINT_32 iIP = 0;
+
+ struct timeval sTimeValLocBegin;
+ gettimeofday(&sTimeValLocBegin, NULL);
+
+ oVM.Init(pVMMemoryCore, &oOutputCollector, &oLogger);
+ oVM.Run(pVMMemoryCore, &oOutputCollector, iIP, oHash, &oLogger);
+
+ struct timeval sTimeValLocEnd;
+ gettimeofday(&sTimeValLocEnd, NULL);
+
+ fprintf(stderr, "Completed in %f seconds.\n", (1.0 * (sTimeValLocEnd.tv_sec - sTimeValLocBegin.tv_sec) + 1.0 * (sTimeValLocEnd.tv_usec - sTimeValLocBegin.tv_usec) / 1000000));
+
+ iRetCode = EX_OK;
+ }
+ // CDT
+ catch(CDTTypeCastException & e) { fprintf(stderr, "ERROR: Type Cast %s\n", e.what()); }
+ catch(CDTAccessException & e) { fprintf(stderr, "ERROR: Array index out of bounds: %s\n", e.what()); }
+
+ // Virtual machine
+ catch(IllegalOpcode & e) { fprintf(stderr, "ERROR: Illegal opcode 0x%08X at 0x%08X\n", e.GetOpcode(), e.GetIP()); }
+ catch(InvalidSyscall & e)
+ {
+ if (e.GetIP() != 0)
+ {
+ VMDebugInfo oVMDebugInfo(e.GetDebugInfo());
+ fprintf(stderr, "ERROR: %s at 0x%08X (Template file \"%s\", Line %d, Pos %d)\n", e.what(), e.GetIP(), e.GetSourceName(), oVMDebugInfo.GetLine(), oVMDebugInfo.GetLinePos());
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported syscall: \"%s\"\n", e.what());
+ }
+ }
+ catch(InvalidCall & e)
+ {
+ VMDebugInfo oVMDebugInfo(e.GetDebugInfo());
+ fprintf(stderr, "ERROR: at 0x%08X: Invalid block name \"%s\" in file \"%s\", Line %d, Pos %d\n", e.GetIP(), e.what(), e.GetSourceName(), oVMDebugInfo.GetLine(), oVMDebugInfo.GetLinePos());
+ }
+ catch(CodeSegmentOverrun & e) { fprintf(stderr, "ERROR: %s at 0x%08X\n", e.what(), e.GetIP()); }
+ catch(StackOverflow & e) { fprintf(stderr, "ERROR: Stack overflow at 0x%08X\n", e.GetIP()); }
+ catch(StackUnderflow & e) { fprintf(stderr, "ERROR: Stack underflow at 0x%08X\n", e.GetIP()); }
+ catch(ExecutionLimitReached & e) { fprintf(stderr, "ERROR: Execution limit of %d step(s) reached at 0x%08X\n", iStepsLimit, e.GetIP()); }
+ catch(VMException & e) { fprintf(stderr, "ERROR: VM generic exception: %s at 0x%08X\n", e.what(), e.GetIP()); }
+
+ // CTPP
+ catch(CTPPLogicError & e) { fprintf(stderr, "ERROR: %s\n", e.what()); }
+ catch(CTPPUnixException & e) { fprintf(stderr, "ERROR: I/O in %s: %s\n", e.what(), strerror(e.ErrNo())); }
+ catch(CTPPException & e) { fprintf(stderr, "ERROR: CTPP Generic exception: %s\n", e.what()); }
+
+ // Destroy standard library
+ STDLibInitializer::DestroyLibrary(oSyscallFactory);
+
+ // make valgrind happy
+ fclose(stdin);
+ fclose(stdout);
+ fclose(stderr);
+
+return iRetCode;
+}
+// End.
+
diff --git a/tests/testdata/arith_ops.out b/tests/testdata/arith_ops.out
new file mode 100644
index 0000000..ee0871f
--- /dev/null
+++ b/tests/testdata/arith_ops.out
@@ -0,0 +1,142 @@
+// Start
+
+// +
+// Integer
+ 123 + 123 = 246
+-123 + 123 = 0
+ 123(s) + 123 = 246
+
+ 123 + 123 = 246
+-123 + 123 = 0
+-123(s) + 123(s) = 0
+
+// IEEE 754
+ 123.456 + 123.456 = 246.912
+ 123.456(s) + 123.456 = 246.912
+
+-123.456 + 123.456 = 0
+-123.456(s) + 123.456 = 0
+
+ 123.456 + 123.456 = 246.912
+-123.456 + 123.456 = 0
+-123.456(s) + 123.456(s) = 0
+
+
+// Integer & IEEE 754
+ 123.456 + 123 = 246.456
+-123.456 + 123 = -0.456
+ 123.456(s) + 123 = 246.456
+
+ 123 + 123.456 = 246.456
+ 123 + -123.456 = -0.456
+ 123 + 123.456 = 246.456
+
+// -
+// Integer
+ 123 - 123 = 0
+-123 - 123 = -246
+
+ 123 - 123 = 0
+-123 - 123 = -246
+
+// IEEE 754
+ 123.456 - 123.456 = 0
+-123.456 - 123.456 = -246.912
+ 123.456 - 123.456 = 0
+-123.456 - 123.456 = -246.912
+
+// Integer & IEEE 754
+ 123.456 - 123 = 0.456
+-123.456 - 123 = -246.456
+ 123 - 123.456 = -0.456
+ 123 - -123.456 = 246.456
+
+// *
+// Integer
+ 123 * 123 = 15129
+-123 * 123 = -15129
+
+ 123 * 123 = 15129
+-123 * 123 = -15129
+
+// IEEE 754
+ 123.456 * 123.456 = 15241.383936
+-123.456 * 123.456 = -15241.383936
+ 123.456 * 123.456 = 15241.383936
+-123.456 * 123.456 = -15241.383936
+
+// Integer & IEEE 754
+ 123.456 * 123 = 15185.088
+-123.456 * 123 = -15185.088
+ 123 * 123.456 = 15185.088
+ 123 * -123.456 = -15185.088
+
+// /
+// Integer
+ 123 / 124 = 0
+ 123 / 122 = 1
+
+ 123 / 123 = 1
+-123 / 123 = -1
+
+ 123 / 123 = 1
+-123 / 123 = -1
+
+// IEEE 754
+ 123.456 / 123.456 = 1
+-123.456 / 123.456 = -1
+ 123.456 / 123.456 = 1
+-123.456 / 123.456 = -1
+
+// Integer & IEEE 754
+ 123.456 / 123 = 1.00370731707
+-123.456 / 123 = -1.00370731707
+ 123 / 123.456 = 0.996306376361
+ 123 / -123.456 = -0.996306376361
+
+// div
+// Integer
+ 123 div 124 = 0
+ 123 div 122 = 1
+
+ 123 div 123 = 1
+-123 div 123 = -1
+
+ 123 div 123 = 1
+-123 div 123 = -1
+
+// IEEE 754
+ 123.456 div 123.456 = 1
+-123.456 div 123.456 = -1
+ 123.456 div 123.456 = 1
+-123.456 div 123.456 = -1
+
+// Integer & IEEE 754
+ 123.456 div 123 = 1
+-123.456 div 123 = -1
+ 123 div 123.456 = 1
+ 123 div -123.456 = -1
+
+// mod
+// Integer
+ 123 mod 12 = 3
+ 123 mod 12 = 3
+
+ 123 mod 12 = 3
+-123 mod 12 = -3
+
+ 123 mod 123 = 0
+-123 mod 123 = 0
+
+// IEEE 754
+ 123.456 mod 12.3456 = 3
+-123.456 mod 12.3456 = -3
+ 123.456 mod 123.456 = 0
+-123.456 mod 123.456 = 0
+
+// Integer & IEEE 754
+ 123.456 mod 123 = 0
+-123.456 mod 123 = 0
+ 123 mod 123.456 = 0
+ 123 mod -123.456 = 0
+// End. \ No newline at end of file
diff --git a/tests/testdata/arith_ops.tmpl b/tests/testdata/arith_ops.tmpl
new file mode 100644
index 0000000..b8647be
--- /dev/null
+++ b/tests/testdata/arith_ops.tmpl
@@ -0,0 +1,142 @@
+// Start
+
+// +
+// Integer
+ 123 + 123 = <TMPL_var (int + 123)>
+-123 + 123 = <TMPL_var (neg_int + 123)>
+ 123(s) + 123 = <TMPL_var (string_int + 123)>
+
+ 123 + 123 = <TMPL_var (int + int)>
+-123 + 123 = <TMPL_var (neg_int + int)>
+-123(s) + 123(s) = <TMPL_var (neg_string_int + string_int)>
+
+// IEEE 754
+ 123.456 + 123.456 = <TMPL_var (float + 123.456)>
+ 123.456(s) + 123.456 = <TMPL_var (string_float + 123.456)>
+
+-123.456 + 123.456 = <TMPL_var (neg_float + 123.456)>
+-123.456(s) + 123.456 = <TMPL_var (neg_string_float + 123.456)>
+
+ 123.456 + 123.456 = <TMPL_var (float + float)>
+-123.456 + 123.456 = <TMPL_var (neg_float + float)>
+-123.456(s) + 123.456(s) = <TMPL_var (neg_string_float + string_float)>
+
+
+// Integer & IEEE 754
+ 123.456 + 123 = <TMPL_var (float + int)>
+-123.456 + 123 = <TMPL_var (neg_float + int)>
+ 123.456(s) + 123 = <TMPL_var (string_float + int)>
+
+ 123 + 123.456 = <TMPL_var (int + float)>
+ 123 + -123.456 = <TMPL_var (int + neg_float)>
+ 123 + 123.456 = <TMPL_var (string_int + string_float)>
+
+// -
+// Integer
+ 123 - 123 = <TMPL_var (int - 123)>
+-123 - 123 = <TMPL_var (neg_int - 123)>
+
+ 123 - 123 = <TMPL_var (int - int)>
+-123 - 123 = <TMPL_var (neg_int - int)>
+
+// IEEE 754
+ 123.456 - 123.456 = <TMPL_var (float - 123.456)>
+-123.456 - 123.456 = <TMPL_var (neg_float - 123.456)>
+ 123.456 - 123.456 = <TMPL_var (float - float)>
+-123.456 - 123.456 = <TMPL_var (neg_float - float)>
+
+// Integer & IEEE 754
+ 123.456 - 123 = <TMPL_var (float - int)>
+-123.456 - 123 = <TMPL_var (neg_float - int)>
+ 123 - 123.456 = <TMPL_var (int - float)>
+ 123 - -123.456 = <TMPL_var (int - neg_float)>
+
+// *
+// Integer
+ 123 * 123 = <TMPL_var (int * 123)>
+-123 * 123 = <TMPL_var (neg_int * 123)>
+
+ 123 * 123 = <TMPL_var (int * int)>
+-123 * 123 = <TMPL_var (neg_int * int)>
+
+// IEEE 754
+ 123.456 * 123.456 = <TMPL_var (float * 123.456)>
+-123.456 * 123.456 = <TMPL_var (neg_float * 123.456)>
+ 123.456 * 123.456 = <TMPL_var (float * float)>
+-123.456 * 123.456 = <TMPL_var (neg_float * float)>
+
+// Integer & IEEE 754
+ 123.456 * 123 = <TMPL_var (float * int)>
+-123.456 * 123 = <TMPL_var (neg_float * int)>
+ 123 * 123.456 = <TMPL_var (int * float)>
+ 123 * -123.456 = <TMPL_var (int * neg_float)>
+
+// /
+// Integer
+ 123 / 124 = <TMPL_var (int / 124)>
+ 123 / 122 = <TMPL_var (int / 122)>
+
+ 123 / 123 = <TMPL_var (int / 123)>
+-123 / 123 = <TMPL_var (neg_int / 123)>
+
+ 123 / 123 = <TMPL_var (int / int)>
+-123 / 123 = <TMPL_var (neg_int / int)>
+
+// IEEE 754
+ 123.456 / 123.456 = <TMPL_var (float / 123.456)>
+-123.456 / 123.456 = <TMPL_var (neg_float / 123.456)>
+ 123.456 / 123.456 = <TMPL_var (float / float)>
+-123.456 / 123.456 = <TMPL_var (neg_float / float)>
+
+// Integer & IEEE 754
+ 123.456 / 123 = <TMPL_var (float / int)>
+-123.456 / 123 = <TMPL_var (neg_float / int)>
+ 123 / 123.456 = <TMPL_var (int / float)>
+ 123 / -123.456 = <TMPL_var (int / neg_float)>
+
+// div
+// Integer
+ 123 div 124 = <TMPL_var (int div 124)>
+ 123 div 122 = <TMPL_var (int div 122)>
+
+ 123 div 123 = <TMPL_var (int div 123)>
+-123 div 123 = <TMPL_var (neg_int div 123)>
+
+ 123 div 123 = <TMPL_var (int div int)>
+-123 div 123 = <TMPL_var (neg_int div int)>
+
+// IEEE 754
+ 123.456 div 123.456 = <TMPL_var (float div 123.456)>
+-123.456 div 123.456 = <TMPL_var (neg_float div 123.456)>
+ 123.456 div 123.456 = <TMPL_var (float div float)>
+-123.456 div 123.456 = <TMPL_var (neg_float div float)>
+
+// Integer & IEEE 754
+ 123.456 div 123 = <TMPL_var (float div int)>
+-123.456 div 123 = <TMPL_var (neg_float div int)>
+ 123 div 123.456 = <TMPL_var (int div float)>
+ 123 div -123.456 = <TMPL_var (int div neg_float)>
+
+// mod
+// Integer
+ 123 mod 12 = <TMPL_var (int mod 12)>
+ 123 mod 12 = <TMPL_var (int mod 12)>
+
+ 123 mod 12 = <TMPL_var (int mod 12)>
+-123 mod 12 = <TMPL_var (neg_int mod 12)>
+
+ 123 mod 123 = <TMPL_var (int mod int)>
+-123 mod 123 = <TMPL_var (neg_int mod int)>
+
+// IEEE 754
+ 123.456 mod 12.3456 = <TMPL_var (float mod 12.3456)>
+-123.456 mod 12.3456 = <TMPL_var (neg_float mod 12.3456)>
+ 123.456 mod 123.456 = <TMPL_var (float mod float)>
+-123.456 mod 123.456 = <TMPL_var (neg_float mod float)>
+
+// Integer & IEEE 754
+ 123.456 mod 123 = <TMPL_var (float mod int)>
+-123.456 mod 123 = <TMPL_var (neg_float mod int)>
+ 123 mod 123.456 = <TMPL_var (int mod float)>
+ 123 mod -123.456 = <TMPL_var (int mod neg_float)>
+// End. \ No newline at end of file
diff --git a/tests/testdata/array_and_hash_access.json b/tests/testdata/array_and_hash_access.json
new file mode 100644
index 0000000..c7c42e7
--- /dev/null
+++ b/tests/testdata/array_and_hash_access.json
@@ -0,0 +1,20 @@
+{
+ 'zero': 0,
+ 'zeros': [ { 'z': 0 } ],
+ 'bigloop': [ { 'foo': 'bar', 'out': 'spam', 'flag': '1' },
+ { 'foo': 'baz', 'out': 'nospam' }],
+ 'loop': [ { 'loop': [1] } ],
+ 'num': 3,
+ 'str': 'foo',
+ 'hash': { 'key': 'hash_key_value', 'foo': 'hash_foo_value', 'bar': 4 },
+ 'arr': [ 1001, 1002, 1003, 1004 ],
+ 'arrs': [ [ 0, 3001 ], [ 0, 3002 ], [ 0, 3003 ], [ 0, 3004 ] ],
+ 'big': [ { 'key': 500 }, { 'key': 600 }, { 'key': 700 } ],
+ 'baz': [ {}, {}, {}, { 'key': [ {}, { 'foo': 2001 }] } ],
+ 'big_arr': [
+ [ { 'key': '123' }, { 'key': '456' }, { 'key': '789' } ],
+ [ { 'key': 'ABC' }, { 'key': 'CBA' }, { 'key': '987' } ],
+ [ { 'key': '654' }, { 'key': '321' }, { 'key': '000' } ] ],
+ 'small_arr': [ [ 0 ] ]
+}
+
diff --git a/tests/testdata/array_and_hash_access.out b/tests/testdata/array_and_hash_access.out
new file mode 100644
index 0000000..c9f63a1
--- /dev/null
+++ b/tests/testdata/array_and_hash_access.out
@@ -0,0 +1,22 @@
+1. 3
+2. foo
+3. hash_key_value
+3a. hash_key_value
+4. hash_foo_value
+5. 1002
+6. 1004
+7. 1004
+8. hash_key_value
+9. 1006
+A. 2001
+B. 1001|1002|1003|1004|
+C. 3001|3002|3003|3004|
+D. 500|600|700|
+E. 500|600|700|
+F. 500|500|500|500|600|600|600|600|700|700|700|700|
+G. 0
+H. 123456789ABCCBA987654321000
+I. 1
+J. bar=spambaz
+K. 0
+L. 0
diff --git a/tests/testdata/array_and_hash_access.tmpl b/tests/testdata/array_and_hash_access.tmpl
new file mode 100644
index 0000000..189cf9c
--- /dev/null
+++ b/tests/testdata/array_and_hash_access.tmpl
@@ -0,0 +1,22 @@
+1. <TMPL_var num>
+2. <TMPL_var str>
+3. <TMPL_var hash.key>
+3a. <TMPL_var hash{"key"}>
+4. <TMPL_var hash [ str ]>
+5. <TMPL_var arr [ 1 ]>
+6. <TMPL_var arr [ num ]>
+7. <TMPL_var arr [ MAX(1, 3) ]>
+8. <TMPL_var hash [ CONCAT('k', 'ey') ]>
+9. <TMPL_var (hash.bar + arr [ 1 ])>
+A. <TMPL_var baz [ num ] . key [ 1 ] [ str ] >
+B. <TMPL_foreach arr as a><TMPL_var a>|</TMPL_foreach>
+C. <TMPL_foreach arrs as aa><TMPL_var aa[1]>|</TMPL_foreach>
+D. <TMPL_foreach big as b><TMPL_var b.key>|</TMPL_foreach>
+E. <TMPL_foreach big as b><TMPL_var b.key>|</TMPL_foreach>
+F. <TMPL_foreach big as b><TMPL_foreach arr as a><TMPL_var b.key>|</TMPL_foreach></TMPL_foreach>
+G. <TMPL_foreach small_arr as sa><TMPL_foreach sa as a><TMPL_var a></TMPL_foreach></TMPL_foreach>
+H. <TMPL_foreach big_arr as ba><TMPL_foreach ba as a><TMPL_var a.key></TMPL_foreach></TMPL_foreach>
+I. <TMPL_foreach loop as sub><TMPL_foreach sub.loop as subloop><TMPL_var subloop></TMPL_foreach></TMPL_foreach>
+J. <TMPL_foreach bigloop AS bl><TMPL_if DEFINED(bl.flag)><TMPL_var bl.foo>=<TMPL_include "array_and_hash_access_incl.tmpl"></TMPL_if></TMPL_foreach><TMPL_foreach bigloop AS bl><TMPL_unless DEFINED(bl.flag)><TMPL_var bl.foo></TMPL_unless></TMPL_foreach>
+K. <TMPL_var zero>
+L. <TMPL_foreach zeros as zero><TMPL_var zero.z></TMPL_foreach>
diff --git a/tests/testdata/array_and_hash_access_incl.tmpl b/tests/testdata/array_and_hash_access_incl.tmpl
new file mode 100644
index 0000000..b656781
--- /dev/null
+++ b/tests/testdata/array_and_hash_access_incl.tmpl
@@ -0,0 +1 @@
+<TMPL_var out> \ No newline at end of file
diff --git a/tests/testdata/calls.out b/tests/testdata/calls.out
new file mode 100644
index 0000000..3af416e
--- /dev/null
+++ b/tests/testdata/calls.out
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+vara|varb|varc
+vara|varb|varc
+BINGOBINGOBINGO
+1|2|3|4|
+123
+
+
+
+ test|
+ 10#
+
+
+ test|
+ 15#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Argument 1:
+[
+ "fields"
+]
+ Argument 1:
+{
+ 'fields' : {
+ 'field1' : "name"
+ }
+}
+ Argument 1:
+{
+ 'field1' : "name"
+}
+
+
+ Argument 1:
+{
+ 'fields' : {
+ 'field1' : "name"
+ }
+}
+
+
+
+
diff --git a/tests/testdata/calls.tmpl b/tests/testdata/calls.tmpl
new file mode 100644
index 0000000..477538b
--- /dev/null
+++ b/tests/testdata/calls.tmpl
@@ -0,0 +1,57 @@
+<TMPL_block "test" args(a, b, c)><TMPL_var a>|<TMPL_var b>|<TMPL_var c></TMPL_block>
+<TMPL_block "test1" args(a)><TMPL_var a></TMPL_block>
+<TMPL_block "test2" args(a)><TMPL_var a></TMPL_block>
+<TMPL_block "test3" args(a)><TMPL_var a></TMPL_block>
+<TMPL_block "test4" args(a)><TMPL_var SPRINTF("%d", a)></TMPL_block>
+
+<TMPL_call "test" args("vara", "varb", "varc")>
+<TMPL_call func args("vara", "varb", "varc")>
+<TMPL_foreach funcs as f><TMPL_call f args("BINGO")></TMPL_foreach>
+<TMPL_foreach array_int as a><TMPL_call "test3" args(a)>|</TMPL_foreach>
+<TMPL_call "test4" args(int)>
+
+<TMPL_block 'testblock' args(block, ident)>
+ <TMPL_var block.name>|
+ <TMPL_var ident>#
+ <TMPL_if block.data>
+ <TMPL_call 'testblock' args(block.data, (ident + 5))>
+ </TMPL_if>
+</TMPL_block>
+<TMPL_call 'testblock' args(data, 10)>
+
+<TMPL_block 'test5' args(dummy)></TMPL_block>
+<TMPL_block 'foo' args(a)>
+<TMPL_if (1 eq 0)><TMPL_call 'test5' args(2)><TMPL_elsif (a eq 1)></TMPL_if>
+</TMPL_block>
+<TMPL_call 'foo' args(1)>
+
+<TMPL_block 'inner' args(dummy)></TMPL_block>
+<TMPL_block 'outer' args(argument)>
+ <TMPL_if (argument eq 'one')>
+ <TMPL_call 'inner' args('dummy')>
+ <TMPL_elsif (argument eq 'two')>
+ </TMPL_if>
+</TMPL_block>
+<TMPL_call 'outer' args('two')>
+
+<TMPL_block 'outer2' args(argument)>
+ <TMPL_if (argument eq 'one')>
+ <TMPL_elsif (argument eq 'two')>
+ </TMPL_if>
+</TMPL_block>
+
+<TMPL_call 'outer2' args('two')>
+
+<TMPL_block "form_renderer" args(form)>
+ <TMPL_var OBJ_DUMP(HASH_KEYS(form))>
+ <TMPL_var OBJ_DUMP(form)>
+ <TMPL_var OBJ_DUMP(form.fields)>
+
+ <TMPL_foreach HASH_KEYS(form) as key>
+ <TMPL_var OBJ_DUMP(form)>
+ </TMPL_foreach>
+
+</TMPL_block>
+
+<TMPL_call "form_renderer" args(data.edit_card_form)>
+
diff --git a/tests/testdata/comparisons.out b/tests/testdata/comparisons.out
new file mode 100644
index 0000000..15eb199
--- /dev/null
+++ b/tests/testdata/comparisons.out
@@ -0,0 +1,53 @@
+// Start
+
+// Integer
+ 123 < 123 = NO
+ 123 > 123 = NO
+ 123 == 123 = OK
+ 123 != 123 = NO
+ 123 <= 123 = OK
+ 123 >= 123 = OK
+
+ 123 < 123.456 = OK
+ 123 > 123.456 = NO
+ 123 == 123.456 = NO
+ 123 != 123.456 = OK
+ 123 <= 123.456 = OK
+ 123 >= 123.456 = NO
+
+ 123.456 < 123.456 = NO
+ 123.456 > 123.456 = NO
+ 123.456 == 123.456 = OK
+ 123.456 != 123.456 = NO
+ 123.456 <= 123.456 = OK
+ 123.456 >= 123.456 = OK
+
+ 123.456 < 123.456 = NO
+ 123.456 > 123.456 = NO
+ 123.456 == 123.456 = OK
+ 123.456 != 123.456 = NO
+ 123.456 <= 123.456 = OK
+ 123.456 >= 123.456 = OK
+
+ 123.456 < 123.456 = NO
+ 123.456 > 123.456 = NO
+ 123.456 == 123.456 = OK
+ 123.456 != 123.456 = NO
+ 123.456 <= 123.456 = OK
+ 123.456 >= 123.456 = OK
+
+ 123 < 123.456 = OK
+ 123 > 123.456 = NO
+ 123 == 123.456 = NO
+ 123 != 123.456 = OK
+ 123 <= 123.456 = OK
+ 123 >= 123.456 = NO
+
+ 123 LT 123.456 = OK
+ 123 GT 123.456 = NO
+ 123 EQ 123.456 = NO
+ 123 NE 123.456 = OK
+ 123 LE 123.456 = OK
+ 123 GE 123.456 = NO
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/comparisons.tmpl b/tests/testdata/comparisons.tmpl
new file mode 100644
index 0000000..48971e7
--- /dev/null
+++ b/tests/testdata/comparisons.tmpl
@@ -0,0 +1,53 @@
+// Start
+
+// Integer
+ 123 < 123 = <TMPL_if (int < 123)> OK <TMPL_else> NO </TMPL_if>
+ 123 > 123 = <TMPL_if (int > 123)> OK <TMPL_else> NO </TMPL_if>
+ 123 == 123 = <TMPL_if (int == 123)> OK <TMPL_else> NO </TMPL_if>
+ 123 != 123 = <TMPL_if (int != 123)> OK <TMPL_else> NO </TMPL_if>
+ 123 <= 123 = <TMPL_if (int <= 123)> OK <TMPL_else> NO </TMPL_if>
+ 123 >= 123 = <TMPL_if (int >= 123)> OK <TMPL_else> NO </TMPL_if>
+
+ 123 < 123.456 = <TMPL_if (int < 123.456)> OK <TMPL_else> NO </TMPL_if>
+ 123 > 123.456 = <TMPL_if (int > 123.456)> OK <TMPL_else> NO </TMPL_if>
+ 123 == 123.456 = <TMPL_if (int == 123.456)> OK <TMPL_else> NO </TMPL_if>
+ 123 != 123.456 = <TMPL_if (int != 123.456)> OK <TMPL_else> NO </TMPL_if>
+ 123 <= 123.456 = <TMPL_if (int <= 123.456)> OK <TMPL_else> NO </TMPL_if>
+ 123 >= 123.456 = <TMPL_if (int >= 123.456)> OK <TMPL_else> NO </TMPL_if>
+
+ 123.456 < 123.456 = <TMPL_if (int < int)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 > 123.456 = <TMPL_if (int > int)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 == 123.456 = <TMPL_if (int == int)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 != 123.456 = <TMPL_if (int != int)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 <= 123.456 = <TMPL_if (int <= int)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 >= 123.456 = <TMPL_if (int >= int)> OK <TMPL_else> NO </TMPL_if>
+
+ 123.456 < 123.456 = <TMPL_if (float < float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 > 123.456 = <TMPL_if (float > float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 == 123.456 = <TMPL_if (float == float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 != 123.456 = <TMPL_if (float != float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 <= 123.456 = <TMPL_if (float <= float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 >= 123.456 = <TMPL_if (float >= float)> OK <TMPL_else> NO </TMPL_if>
+
+ 123.456 < 123.456 = <TMPL_if (float < string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 > 123.456 = <TMPL_if (float > string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 == 123.456 = <TMPL_if (float == string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 != 123.456 = <TMPL_if (float != string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 <= 123.456 = <TMPL_if (float <= string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123.456 >= 123.456 = <TMPL_if (float >= string_float)> OK <TMPL_else> NO </TMPL_if>
+
+ 123 < 123.456 = <TMPL_if (string_int < string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 > 123.456 = <TMPL_if (string_int > string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 == 123.456 = <TMPL_if (string_int == string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 != 123.456 = <TMPL_if (string_int != string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 <= 123.456 = <TMPL_if (string_int <= string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 >= 123.456 = <TMPL_if (string_int >= string_float)> OK <TMPL_else> NO </TMPL_if>
+
+ 123 LT 123.456 = <TMPL_if (string_int LT string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 GT 123.456 = <TMPL_if (string_int GT string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 EQ 123.456 = <TMPL_if (string_int EQ string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 NE 123.456 = <TMPL_if (string_int NE string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 LE 123.456 = <TMPL_if (string_int LE string_float)> OK <TMPL_else> NO </TMPL_if>
+ 123 GE 123.456 = <TMPL_if (string_int GE string_float)> OK <TMPL_else> NO </TMPL_if>
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/formulas.out b/tests/testdata/formulas.out
new file mode 100644
index 0000000..c057afe
--- /dev/null
+++ b/tests/testdata/formulas.out
@@ -0,0 +1,9 @@
+// Start
+
+246.456
+-2.00370731707
+-247.369690537
+-82
+-2
+
+// End.
diff --git a/tests/testdata/formulas.tmpl b/tests/testdata/formulas.tmpl
new file mode 100644
index 0000000..6a7def7
--- /dev/null
+++ b/tests/testdata/formulas.tmpl
@@ -0,0 +1,9 @@
+// Start
+
+<TMPL_var (int + float)>
+<TMPL_var ((int + float) / neg_int)>
+<TMPL_var ((int + float) / neg_int * string_float)>
+<TMPL_var ((int + float) / neg_int * string_float div array_int[2])>
+<TMPL_var ((int + float) / neg_int * string_float div array_int[2] mod 5)>
+
+// End.
diff --git a/tests/testdata/function_gettext.out b/tests/testdata/function_gettext.out
new file mode 100644
index 0000000..8b0a25d
--- /dev/null
+++ b/tests/testdata/function_gettext.out
@@ -0,0 +1,18 @@
+// Start
+
+_: Unknown message
+GETTEXT: Unknown message
+_: Тестовое сообщение
+GETTEXT: Тестовое сообщение
+_ n1: %d файл
+_ n2: %d файла
+_ n5: %d файлов
+GETTEXT n1: %d файл
+GETTEXT n2: %d файла
+GETTEXT n5: %d файлов
+_ n1: unknown singular message
+_ n2: unknown plural message
+GETTEXT n1: unknown singular message
+GETTEXT n2: unknown plural message
+
+// End.
diff --git a/tests/testdata/function_gettext.tmpl b/tests/testdata/function_gettext.tmpl
new file mode 100644
index 0000000..df34f1f
--- /dev/null
+++ b/tests/testdata/function_gettext.tmpl
@@ -0,0 +1,18 @@
+// Start
+
+_: <TMPL_var _("Unknown message")>
+GETTEXT: <TMPL_var GETTEXT("Unknown message")>
+_: <TMPL_var _("Test message")>
+GETTEXT: <TMPL_var GETTEXT("Test message")>
+_ n1: <TMPL_var _("%d file", "%d files", n1)>
+_ n2: <TMPL_var _("%d file", "%d files", n2)>
+_ n5: <TMPL_var _("%d file", "%d files", n5)>
+GETTEXT n1: <TMPL_var GETTEXT("%d file", "%d files", n1)>
+GETTEXT n2: <TMPL_var GETTEXT("%d file", "%d files", n2)>
+GETTEXT n5: <TMPL_var GETTEXT("%d file", "%d files", n5)>
+_ n1: <TMPL_var _("unknown singular message", "unknown plural message", n1)>
+_ n2: <TMPL_var _("unknown singular message", "unknown plural message", n2)>
+GETTEXT n1: <TMPL_var GETTEXT("unknown singular message", "unknown plural message", n1)>
+GETTEXT n2: <TMPL_var GETTEXT("unknown singular message", "unknown plural message", n2)>
+
+// End.
diff --git a/tests/testdata/function_hostname.tmpl b/tests/testdata/function_hostname.tmpl
new file mode 100644
index 0000000..5277213
--- /dev/null
+++ b/tests/testdata/function_hostname.tmpl
@@ -0,0 +1,2 @@
+HOSTNAME: <TMPL_var HOSTNAME()>
+
diff --git a/tests/testdata/function_iconv.out b/tests/testdata/function_iconv.out
new file mode 100644
index 0000000..ce98282
--- /dev/null
+++ b/tests/testdata/function_iconv.out
@@ -0,0 +1,3 @@
+// Start
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/function_iconv.tmpl b/tests/testdata/function_iconv.tmpl
new file mode 100644
index 0000000..ce98282
--- /dev/null
+++ b/tests/testdata/function_iconv.tmpl
@@ -0,0 +1,3 @@
+// Start
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/function_md5.out b/tests/testdata/function_md5.out
new file mode 100644
index 0000000..3245a22
--- /dev/null
+++ b/tests/testdata/function_md5.out
@@ -0,0 +1,7 @@
+// Start
+
+MD5: 65a8e27d8879283831b664bd8b7f0ad4
+
+HMAC_MD5: 95d6d715ec522a8222c9aaf31353b024
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/function_md5.tmpl b/tests/testdata/function_md5.tmpl
new file mode 100644
index 0000000..6758c43
--- /dev/null
+++ b/tests/testdata/function_md5.tmpl
@@ -0,0 +1,7 @@
+// Start
+
+MD5: <TMPL_var MD5("Hello, World!")>
+
+HMAC_MD5: <TMPL_var HMAC_MD5("hello", "World")>
+
+// End. \ No newline at end of file
diff --git a/tests/testdata/function_obj_dump.tmpl b/tests/testdata/function_obj_dump.tmpl
new file mode 100644
index 0000000..27fb5dd
--- /dev/null
+++ b/tests/testdata/function_obj_dump.tmpl
@@ -0,0 +1,2 @@
+OBJ_DUMP: <TMPL_var OBJ_DUMP()>
+
diff --git a/tests/testdata/function_random.tmpl b/tests/testdata/function_random.tmpl
new file mode 100644
index 0000000..3d33744
--- /dev/null
+++ b/tests/testdata/function_random.tmpl
@@ -0,0 +1,6 @@
+RANDOM: <TMPL_var RANDOM()>
+RANDOM: <TMPL_var RANDOM(10)>
+RANDOM: <TMPL_var RANDOM(10.01)>
+RANDOM: <TMPL_var RANDOM(-10, 10)>
+RANDOM: <TMPL_var RANDOM(-10.01, 10.01)>
+
diff --git a/tests/testdata/functions.out b/tests/testdata/functions.out
new file mode 100644
index 0000000..f954e93
--- /dev/null
+++ b/tests/testdata/functions.out
@@ -0,0 +1,94 @@
+// Start
+
+AVG(a): 2
+AVG(g): 1.81712059283
+AVG(h): 1.63636363636
+AVG(q): 2.16024689947
+
+BASE64_DECODE/BASE64_ENCODE: Hello, World
+
+CAST(int): 1
+CAST(int): 8
+CAST(dec): 10
+CAST(oct): 8
+CAST(hex): 16
+CAST(float): 1.234
+
+CONCAT: HelloWorld!
+
+DATE_FORMAT: 2008-01-16 16:32:03
+
+DEFAULT: Default value
+
+DEFINED(nonexistent): 0
+DEFINED : 1
+
+FORM_PARAM: <input type="hidden" name="param" value="Hello, World!" />
+
+GET_TYPE: INTEGER
+GET_TYPE: REAL
+GET_TYPE: STRING
+GET_TYPE: ARRAY
+
+HASH_KEYS: one three two | one three two
+
+HREF_PARAM: hello=%3Cb%3Etest%3C/b%3E+%22test%22+%24test%24&amp;
+
+IN_ARRAY: 1
+
+IN_SET: 1
+
+LIST: cat dog bat rat
+LIST_ELEMENT: 3
+
+LOG: 2.00432137378
+LOG: 2.00432137378
+LOG: 10
+LOG: 1
+
+MB_SIZE: 26
+
+MB_SUBSTR: Привет, мир!
+MB_SUBSTR: World! Привет
+MB_SUBSTR: Hello, :) мир!
+
+MB_TRUNCATE: Hello, World
+MB_TRUNCATE: Hello, World...
+
+MIN: 1
+
+MAX: 3
+
+NUM_FORMAT: 1 234 567 890
+
+SIZE: 4
+SIZE: 3
+
+SPRINTF: -123 0
+
+SUBSTR: World
+
+TRUNCATE: Hello
+TRUNCATE: Hello...
+
+VERSION : CTPP2 engine v2.8.2 (Dzoraget), copyright (c) 2004 - 2012 CTPP Dev. Team
+VERSION(full): Engine: CTPP2 engine v2.8.2 (Dzoraget), copyright (c) 2004 - 2012 CTPP Dev. Team;
+RuntimeLibrary: CTPP Standard Library v2.8.2 (Dzoraget), copyright (c) 2007 - 2012 CTPP Dev. Team;
+License: BSD-like, see http://ctpp.havoc.ru/;
+
+// Escape
+HTMLESCAPE: &lt;b&gt;test&lt;/b&gt; &quot;test&quot; $test$
+
+JSON: "\u003cb\u003etest\u003c\/b\u003e \"test\" $test$"
+
+JSONESCAPE: <b>test<\/b> \"test\" $test$
+
+URLESCAPE: %3Cb%3Etest%3C/b%3E+%22test%22+%24test%24
+
+URIESCAPE: %3Cb%3Etest%3C/b%3E%20%22test%22%20%24test%24
+
+XMLESCAPE: &lt;b&gt;test&lt;/b&gt; &quot;test&quot; $test$
+
+WMLESCAPE: &lt;b&gt;test&lt;/b&gt; &quot;test&quot; $$test$$
+
+// End.
diff --git a/tests/testdata/functions.tmpl b/tests/testdata/functions.tmpl
new file mode 100644
index 0000000..67e2cf4
--- /dev/null
+++ b/tests/testdata/functions.tmpl
@@ -0,0 +1,92 @@
+// Start
+
+AVG(a): <TMPL_var AVG('a', 1, 2, 3)>
+AVG(g): <TMPL_var AVG('g', 1, 2, 3)>
+AVG(h): <TMPL_var AVG('h', 1, 2, 3)>
+AVG(q): <TMPL_var AVG('q', 1, 2, 3)>
+
+BASE64_DECODE/BASE64_ENCODE: <TMPL_var BASE64_DECODE(BASE64_ENCODE("Hello, World"))>
+
+CAST(int): <TMPL_var CAST('int', 1.345)>
+CAST(int): <TMPL_var CAST('int', "010")>
+CAST(dec): <TMPL_var CAST('dec', "010")>
+CAST(oct): <TMPL_var CAST('oct', "010")>
+CAST(hex): <TMPL_var CAST('hex', "010")>
+CAST(float): <TMPL_var CAST('float', 1.234)>
+
+CONCAT: <TMPL_var CONCAT("Hello", "World!")>
+
+DATE_FORMAT: <TMPL_var DATE_FORMAT(1200490323, "%Y-%m-%d %H:%M:%S")>
+
+DEFAULT: <TMPL_var DEFAULT(nonexistent, "Default value")>
+
+DEFINED(nonexistent): <TMPL_var DEFINED(nonexistent)>
+DEFINED : <TMPL_var DEFINED(array_int)>
+
+FORM_PARAM: <TMPL_var FORM_PARAM("param", string)>
+
+GET_TYPE: <TMPL_var GET_TYPE(1)>
+GET_TYPE: <TMPL_var GET_TYPE(3.141)>
+GET_TYPE: <TMPL_var GET_TYPE("foo")>
+GET_TYPE: <TMPL_var GET_TYPE(array_int)>
+
+HASH_KEYS: <TMPL_foreach HASH_KEYS(hash) as key> <TMPL_var key></TMPL_foreach> | <TMPL_foreach HASH_KEYS(hash) as iter> <TMPL_var iter></TMPL_foreach>
+
+HREF_PARAM: <TMPL_var HREF_PARAM("hello", string2.to.escape)>
+
+IN_ARRAY: <TMPL_var IN_ARRAY(2, array_int)>
+
+IN_SET: <TMPL_var IN_SET(2, 1, "2", 3, 4)>
+
+LIST: <TMPL_foreach LIST("cat", "dog", "bat", "rat") as lst><TMPL_var lst> </TMPL_foreach>
+LIST_ELEMENT: <TMPL_var LIST_ELEMENT(2, 1, "2", 3, 4)>
+
+LOG: <TMPL_var LOG(101, 10)>
+LOG: <TMPL_var LOG("101", "10")>
+LOG: <TMPL_var LOG(1024, 2)>
+LOG: <TMPL_var LOG(2.71828182846)>
+
+MB_SIZE: <TMPL_var MB_SIZE("Hello, World!\nПривет, мир!")>
+
+MB_SUBSTR: <TMPL_var MB_SUBSTR("Hello, World! Привет, мир!", 14)>
+MB_SUBSTR: <TMPL_var MB_SUBSTR("Hello, World! Привет, мир!", 7, 13)>
+MB_SUBSTR: <TMPL_var MB_SUBSTR("Hello, World! Привет, мир!", 7, 14, ':)')>
+
+MB_TRUNCATE: <TMPL_var MB_TRUNCATE("Hello, World! Привет, мир!", 12)>
+MB_TRUNCATE: <TMPL_var MB_TRUNCATE("Hello, World! Привет, мир!", 12, '...')>
+
+MIN: <TMPL_var MIN(1, 3)>
+
+MAX: <TMPL_var MAX(1, 3)>
+
+NUM_FORMAT: <TMPL_var NUM_FORMAT(1234567890, ' ')>
+
+SIZE: <TMPL_var SIZE(array_int)>
+SIZE: <TMPL_var SIZE(hash)>
+
+SPRINTF: <TMPL_var SPRINTF("%d %d", neg_float, array_int)>
+
+SUBSTR: <TMPL_var SUBSTR("Hello, World!\nПривет, мир!", 7, 5)>
+
+TRUNCATE: <TMPL_var TRUNCATE("Hello, World!\nПривет, мир!", 5)>
+TRUNCATE: <TMPL_var TRUNCATE("Hello, World!\nПривет, мир!", 5, '...')>
+
+VERSION : <TMPL_var VERSION()>
+VERSION(full): <TMPL_var VERSION('full')>
+
+// Escape
+HTMLESCAPE: <TMPL_var HTMLESCAPE(string2.to.escape)>
+
+JSON: <TMPL_var JSON(string2.to.escape)>
+
+JSONESCAPE: <TMPL_var JSONESCAPE(string2.to.escape)>
+
+URLESCAPE: <TMPL_var URLESCAPE(string2.to.escape)>
+
+URIESCAPE: <TMPL_var URIESCAPE(string2.to.escape)>
+
+XMLESCAPE: <TMPL_var XMLESCAPE(string2.to.escape)>
+
+WMLESCAPE: <TMPL_var WMLESCAPE(string2.to.escape)>
+
+// End.
diff --git a/tests/testdata/lebowski-bench-foreach.out b/tests/testdata/lebowski-bench-foreach.out
new file mode 100644
index 0000000..ac5faca
--- /dev/null
+++ b/tests/testdata/lebowski-bench-foreach.out
@@ -0,0 +1,151 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=windows-1251">
+</head>
+<body>
+ <table width="800">
+ <tbody>
+ <tr>
+ <td width="200">
+ <table bgcolor="#000000" border="0" cellpadding="4" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td bgcolor="#ffffff"><h1>Lebowski benchmark</h1></td></tr>
+ </tbody>
+ </table>
+ </td>
+ <td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Walter</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">You see what happens, Larry?</a></small></td></tr>
+ </tbody>
+ </table>
+ </td><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Walter</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">I don&#39;t roll on Shabbos!</a></small></td></tr>
+ </tbody>
+ </table>
+ </td><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Blond Thug</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">Where&#39;s the money, Lebowski?</a></small></td></tr>
+ </tbody>
+ </table>
+ </td><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Nihilist</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">We believe in nothing, Lebowski.</a></small></td></tr>
+ </tbody>
+ </table>
+ </td><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Walter</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">Is this your homework, Larry?</a></small></td></tr>
+ </tbody>
+ </table>
+ </td><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b>Nihilist</b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="http://www.imdb.com/title/tt0118715/quotes">Ve vant ze money, Lebowski</a></small></td></tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td width="200">
+
+ <table cellpadding="3" width="100%">
+ <tbody>
+ <tr><td bgcolor="#dddddd">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=1234">The Dude</a>
+ </b></font></td></tr>
+ <tr><td bgcolor="#eeeeee">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=2345">Walter Sobchak</a>
+ </b></font></td></tr>
+ <tr><td bgcolor="#dddddd">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=3456">Donny</a>
+ <font color="#999999">R.I.P.</font></b></font></td></tr>
+ <tr><td bgcolor="#eeeeee">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=4567">Maude Lebowski</a>
+ </b></font></td></tr>
+ <tr><td bgcolor="#dddddd">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=5678">The Big Lebowski</a>
+ </b></font></td></tr>
+ <tr><td bgcolor="#eeeeee">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=6789">Brandt</a>
+ </b></font></td></tr>
+ <tr><td bgcolor="#dddddd">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=7890">Jesus Quintana</a>
+ </b></font></td></tr>
+
+ </tbody>
+ </table>
+
+ <p><b>Users</b>: 654329<br><b>Online</b>: 18<br>
+ <small><i>
+ <a href="http://lb/user.html?id=1">true</a>
+ <a href="http://lb/user.html?id=2">false</a>
+ <a href="http://lb/user.html?id=3">short</a>
+ <a href="http://lb/user.html?id=4">long</a>
+ <a href="http://lb/user.html?id=5">apha</a>
+ <a href="http://lb/user.html?id=6">omega</a>
+ <a href="http://lb/user.html?id=7">drag</a>
+ <a href="http://lb/user.html?id=8">drop</a>
+ <a href="http://lb/user.html?id=9">make</a>
+ <a href="http://lb/user.html?id=10">clean</a>
+ <a href="http://lb/user.html?id=11">east</a>
+ <a href="http://lb/user.html?id=12">west</a>
+ <a href="http://lb/user.html?id=13">up</a>
+ <a href="http://lb/user.html?id=14">down</a>
+ <a href="http://lb/user.html?id=15">sun</a>
+ <a href="http://lb/user.html?id=16">rain</a>
+ <a href="http://lb/user.html?id=17">secondary</a>
+ <a href="http://lb/user.html?id=18">main</a>
+ </i></small>
+ </p>
+ </td>
+
+ <td colspan="3" width="400">
+
+ <b>03:45 The Stranger</b><br>
+ <small>See, they call Los Angeles the &quot;City Of Angels&quot;; but I didn&#39;t find it to be that, exactly. But I&#39;ll allow it as there are s ome nice folks there. &#39;Course I ain&#39;t never been to London, and I ain&#39;t never seen France. And I ain&#39;t never seen no queen in her damned undies, so the feller says. But I&#39;ll tell you what - after seeing Los Angeles, and this here story I&#39;m about to unfold, well, I guess I seen somethin&#39; every bit as stupefyin&#39; as you&#39;d seen in any of them other places. And in English , too. So I can die with a smile on my face, without feelin&#39; like the good Lord gypped me. Now this here story I&#39;m about to unfold took place in the early &#39;90s - just about the time of our conflict with Sad&#39;m and the I-raqis. I only mention it be cause sometimes there&#39;s a man...<a href="http://lb/news.html?id=987">[ read full story ]</a></small><br>
+
+ <b>03:48 The Stranger</b><br>
+ <small>...I won&#39;t say a hero, &#39;cause, what&#39;s a hero? Sometimes, there&#39;s a man. And I&#39;m talkin&#39; about the Dude here - the Dude from Los Angeles. Sometimes, there&#39;s a man, well, he&#39;s the man for his time and place. He fits right in there. And that&#39;s the Dude. The Dude, from Los Angeles. And even if he&#39;s a lazy man - and the Dude was most certainly that. Quite possibly the laziest in all of Los Angeles County, which would place him high in the runnin&#39; for laziest worldwide. Sometimes there&#39;s a man , sometimes, there&#39;s a man. Well, I lost my train of thought here. But... aw, hell. I&#39;ve done introduced it enough.<a href="http://lb/news.html?id=876">[ read full story ]</a></small><br>
+
+ <b>03:50 Walter Sobchak</b><br>
+ <small>Donny was a good bowler, and a good man. He was one of us. He was a man who loved the outdoors... and bowling, and as a surfer he explored the beaches of Southern California, from La Jolla to Leo Carrillo and... up to... Pismo. He died, like so many young men of his generation, he died before his time. In your wisdom, Lord, you took him, as you took so many bright flowering young men at Khe Sanh, at Langdok, at Hill 364. These young men gave their lives. And so would Donny. Donny, who loved bowling. And so, Theodore Donald Karabotsos, in accordance with what we think your dying wishes might well have been, we commit your final mortal remains to the bosom of the Pacific Ocean, which you loved so well. Good night, sweet prince.<a href="http://lb/news.html?id=765">[ read full story ]</a></small><br>
+
+ <b>03:52 The Dude</b><br>
+ <small>God damn you Walter! You fuckin&#39; asshole! Everything&#39;s a fuckin&#39; travesty with you, man! And what was all that shit about Vietnam? What the FUCK, has anything got to do with Vietnam? What the fuck are you talking about?<a href="http://lb/news.html?id=654">[ read full story ]</a></small><br>
+
+ <b>03:57 Jesus Quintana</b><br>
+ <small>What&#39;s this day of rest shit? What&#39;s this bullshit? I don&#39;t fuckin&#39; care! It don&#39;t matter to Jesus. But you&#39;re not foolin&#39;me, man. You might fool the fucks in the league office, but you don&#39;t fool Jesus. This bush league psyche-out stuff. Laughable, man - ha ha! I would have fucked you in the ass Saturday. I fuck you in the ass next Wednesday instead. Wooo! You gotadate Wednesday, baby!<a href="http://lb/news.html?id=543">[ read full story ]</a></small><br>
+
+ <b>03:59 Jesus Quintana</b><br>
+ <small>Let me tell you something, pendejo. You pull any of your crazy shit with us, you flash a piece out on the lanes, I&#39;ll take it away from you, stick it up your ass and pull the fucking trigger &#39;til it goes &quot;click.&quot;<a href="http://lb/news.html?id=432">[ read full story ]</a></small><br>
+
+ <b>04:01 The Dude</b><br>
+ <small>Let me explain something to you. Um, I am not &quot;Mr. Lebowski&quot;. You&#39;re Mr. Lebowski. I&#39;m the Dude. So that&#39;s what you call me. You know, that or, uh, His Dudeness, or uh, Duder, or El Duderino if you&#39;re not into the whole brevity thing.<a href="http://lb/news.html?id=321">[ read full story ]</a></small><br>
+
+ </td>
+ </tr>
+ <tr>
+ <td colspan="4" align="center">
+ <hr>
+ <small><i>This test based on "Big Lebowski" test by Alexey A. Rybak, 2005.<br>
+
+ Please send all questions and suggestions to <b>reki@reki.ru</b></i></small>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</body>
+</html>
diff --git a/tests/testdata/lebowski-bench-foreach.tmpl b/tests/testdata/lebowski-bench-foreach.tmpl
new file mode 100644
index 0000000..7722cf2
--- /dev/null
+++ b/tests/testdata/lebowski-bench-foreach.tmpl
@@ -0,0 +1,63 @@
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=windows-1251">
+</head>
+<body>
+ <table width="800">
+ <tbody>
+ <tr>
+ <td width="200">
+ <table bgcolor="#000000" border="0" cellpadding="4" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td bgcolor="#ffffff"><h1>Lebowski benchmark</h1></td></tr>
+ </tbody>
+ </table>
+ </td>
+ <TMPL_foreach adverts as iter><td valign="top" width="200">
+ <table bgcolor="#000000" border="0" cellpadding="2" cellspacing="2" width="100%">
+ <tbody>
+ <tr><td><font color="#ffffff"><b><TMPL_var HTMLESCAPE(iter.title)></b></font></td></tr>
+ <tr><td bgcolor="#ffffff"><small><a href="<TMPL_var url>"><TMPL_var HTMLESCAPE(iter.text)></a></small></td></tr>
+ </tbody>
+ </table>
+ </td></TMPL_foreach>
+ </tr>
+
+ <tr valign="top">
+ <td width="200">
+ <TMPL_if sections>
+ <table cellpadding="3" width="100%">
+ <tbody>
+ <TMPL_foreach sections as iter><tr><td bgcolor="<TMPL_if iter.__odd__>#dddddd<TMPL_else>#eeeeee</TMPL_if>">
+ <font color="#ffffff"><b><a href="http://lb/section.html?id=<TMPL_var URLESCAPE(iter.id)>"><TMPL_var HTMLESCAPE(iter.title)></a>
+ <TMPL_if iter.rip><font color="#999999">R.I.P.</font></TMPL_if></b></font></td></tr>
+ </TMPL_foreach>
+ </tbody>
+ </table></TMPL_if>
+
+ <p><b>Users</b>: <TMPL_var total><br><b>Online</b>: <TMPL_var SIZE(online)><br>
+ <small><i><TMPL_foreach online as iter>
+ <a href="http://lb/user.html?id=<TMPL_var (iter.__index__ + 1)>"><TMPL_var HTMLESCAPE(iter.name)></a></TMPL_foreach>
+ </i></small>
+ </p>
+ </td>
+
+ <td colspan="3" width="400">
+ <TMPL_foreach news as iter>
+ <b><TMPL_var HTMLESCAPE(iter.time)> <TMPL_var HTMLESCAPE(title)></b><br>
+ <small><TMPL_var HTMLESCAPE(iter.text)><a href="http://lb/news.html?id=<TMPL_var URLESCAPE(iter.id)>">[ read full story ]</a></small><br>
+ </TMPL_foreach>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="4" align="center">
+ <hr>
+ <small><i>This test based on "Big Lebowski" test by Alexey A. Rybak, 2005.<br>
+
+ Please send all questions and suggestions to <b>reki@reki.ru</b></i></small>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</body>
+</html>
diff --git a/tests/testdata/lebowski-bench.json b/tests/testdata/lebowski-bench.json
new file mode 100644
index 0000000..0cfe3f0
--- /dev/null
+++ b/tests/testdata/lebowski-bench.json
@@ -0,0 +1,139 @@
+{
+ "adverts" : [
+ {
+ "title" : "Walter",
+ "text" : "You see what happens, Larry?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Walter",
+ "text" : "I don't roll on Shabbos!",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Blond Thug",
+ "text" : "Where's the money, Lebowski?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Nihilist",
+ "text" : "We believe in nothing, Lebowski.",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Walter",
+ "text" : "Is this your homework, Larry?",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ },
+ {
+ "title" : "Nihilist",
+ "text" : "Ve vant ze money, Lebowski",
+ "url" : "http://www.imdb.com/title/tt0118715/quotes"
+ }
+ ],
+
+ "sections" : [
+ {
+ "id" : 1234,
+ "title" : "The Dude",
+ "rip" : 0
+ },
+ {
+ "id" : 2345,
+ "title" : "Walter Sobchak",
+ "rip" : 0
+ },
+ {
+ "id" : 3456,
+ "title" : "Donny",
+ "rip" : 1
+ },
+ {
+ "id" : 4567,
+ "title" : "Maude Lebowski",
+ "rip" : 0
+ },
+ {
+ "id" : 5678,
+ "title" : "The Big Lebowski",
+ "rip" : 0
+ },
+ {
+ "id" : 6789,
+ "title" : "Brandt",
+ "rip" : 0
+ },
+ {
+ "id" : 7890,
+ "title" : "Jesus Quintana",
+ "rip" : 0
+ }
+ ],
+
+ "total" : 654329,
+ "online" : [
+ { "name" : "true" },
+ { "name" : "false" },
+ { "name" : "short" },
+ { "name" : "long" },
+ { "name" : "apha" },
+ { "name" : "omega" },
+ { "name" : "drag" },
+ { "name" : "drop" },
+ { "name" : "make" },
+ { "name" : "clean" },
+ { "name" : "east" },
+ { "name" : "west" },
+ { "name" : "up" },
+ { "name" : "down" },
+ { "name" : "sun" },
+ { "name" : "rain" },
+ { "name" : "secondary" },
+ { "name" : "main" }
+ ],
+
+ "news" : [
+ {
+ "time" : "03:45",
+ "id" : 987,
+ "title" : "The Stranger",
+ "text" : "See, they call Los Angeles the \"City Of Angels\"; but I didn't find it to be that, exactly. But I'll allow it as there are s ome nice folks there. 'Course I ain't never been to London, and I ain't never seen France. And I ain't never seen no queen in her damned undies, so the feller says. But I'll tell you what - after seeing Los Angeles, and this here story I'm about to unfold, well, I guess I seen somethin' every bit as stupefyin' as you'd seen in any of them other places. And in English , too. So I can die with a smile on my face, without feelin' like the good Lord gypped me. Now this here story I'm about to unfold took place in the early '90s - just about the time of our conflict with Sad'm and the I-raqis. I only mention it be cause sometimes there's a man..."
+ },
+ {
+ "time" : "03:48",
+ "id" : 876,
+ "title" : "The Stranger",
+ "text" : "...I won't say a hero, 'cause, what's a hero? Sometimes, there's a man. And I'm talkin' about the Dude here - the Dude from Los Angeles. Sometimes, there's a man, well, he's the man for his time and place. He fits right in there. And that's the Dude. The Dude, from Los Angeles. And even if he's a lazy man - and the Dude was most certainly that. Quite possibly the laziest in all of Los Angeles County, which would place him high in the runnin' for laziest worldwide. Sometimes there's a man , sometimes, there's a man. Well, I lost my train of thought here. But... aw, hell. I've done introduced it enough."
+ },
+ {
+ "time" : "03:50",
+ "id" : 765,
+ "title" : "Walter Sobchak",
+ "text" : "Donny was a good bowler, and a good man. He was one of us. He was a man who loved the outdoors... and bowling, and as a surfer he explored the beaches of Southern California, from La Jolla to Leo Carrillo and... up to... Pismo. He died, like so many young men of his generation, he died before his time. In your wisdom, Lord, you took him, as you took so many bright flowering young men at Khe Sanh, at Langdok, at Hill 364. These young men gave their lives. And so would Donny. Donny, who loved bowling. And so, Theodore Donald Karabotsos, in accordance with what we think your dying wishes might well have been, we commit your final mortal remains to the bosom of the Pacific Ocean, which you loved so well. Good night, sweet prince."
+ },
+ {
+ "time" : "03:52",
+ "id" : 654,
+ "title" : "The Dude",
+ "text" : "God damn you Walter! You fuckin' asshole! Everything's a fuckin' travesty with you, man! And what was all that shit about Vietnam? What the FUCK, has anything got to do with Vietnam? What the fuck are you talking about?"
+ },
+ {
+ "time" : "03:57",
+ "id" : 543,
+ "title" : "Jesus Quintana",
+ "text" : "What's this day of rest shit? What's this bullshit? I don't fuckin' care! It don't matter to Jesus. But you're not foolin'me, man. You might fool the fucks in the league office, but you don't fool Jesus. This bush league psyche-out stuff. Laughable, man - ha ha! I would have fucked you in the ass Saturday. I fuck you in the ass next Wednesday instead. Wooo! You gotadate Wednesday, baby!"
+ },
+ {
+ "time" : "03:59",
+ "id" : 432,
+ "title" : "Jesus Quintana",
+ "text" : "Let me tell you something, pendejo. You pull any of your crazy shit with us, you flash a piece out on the lanes, I'll take it away from you, stick it up your ass and pull the fucking trigger 'til it goes \"click.\""
+ },
+ {
+ "time" : "04:01",
+ "id" : 321,
+ "title" : "The Dude",
+ "text" : "Let me explain something to you. Um, I am not \"Mr. Lebowski\". You're Mr. Lebowski. I'm the Dude. So that's what you call me. You know, that or, uh, His Dudeness, or uh, Duder, or El Duderino if you're not into the whole brevity thing."
+ }
+ ]
+}
diff --git a/tests/testdata/loops.out b/tests/testdata/loops.out
new file mode 100644
index 0000000..b22703d
--- /dev/null
+++ b/tests/testdata/loops.out
@@ -0,0 +1,188 @@
+// Start
+
+
+ Data: 1
+
+ Data: 2
+
+ Data: 3
+
+ Data: 4
+
+
+[ITEM ORIGINAL : Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM 1 LOOP : Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM AFTER 1 LOOP: Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM 2 LOOP : Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM AFTER 2 LOOP: Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM 2 LOOP : Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM AFTER 2 LOOP: Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM 2 LOOP : Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+[ITEM AFTER 2 LOOP: Argument 1:
+{
+ 'id' : 1,
+ 'name' : "Item 1",
+ 'subitems' : [
+ {
+ 'id' : 11,
+ 'name' : "Subitem 1.1"
+ },
+ {
+ 'id' : 12,
+ 'name' : "Subitem 1.2"
+ },
+ {
+ 'id' : 13,
+ 'name' : "Subitem 1.3"
+ }
+ ]
+}]
+
+
+test1test2
+
+// End.
diff --git a/tests/testdata/loops.tmpl b/tests/testdata/loops.tmpl
new file mode 100644
index 0000000..c845b80
--- /dev/null
+++ b/tests/testdata/loops.tmpl
@@ -0,0 +1,16 @@
+// Start
+
+<TMPL_foreach array_int as iter>
+ Data: <TMPL_var iter>
+</TMPL_foreach>
+
+<TMPL_foreach items as item>[ITEM ORIGINAL : <TMPL_var OBJ_DUMP(item)>]
+<TMPL_foreach item.subitems as subitem></TMPL_foreach>[ITEM 1 LOOP : <TMPL_var OBJ_DUMP(item)>]
+[ITEM AFTER 1 LOOP: <TMPL_var OBJ_DUMP(item)>]
+<TMPL_foreach item.subitems as subitem>[ITEM 2 LOOP : <TMPL_var OBJ_DUMP(item)>]
+[ITEM AFTER 2 LOOP: <TMPL_var OBJ_DUMP(item)>]
+</TMPL_foreach></TMPL_foreach>
+<TMPL_foreach LIST("test1", "test2", "test3") as f><TMPL_break><TMPL_var f></TMPL_foreach>
+<TMPL_foreach LIST("test1", "test2", "test3") as f><TMPL_var f><TMPL_if (f eq "test2")><TMPL_break></TMPL_if></TMPL_foreach>
+<TMPL_foreach LIST("test1", "test2", "test3") as f><TMPL_break><TMPL_foreach LIST("test1", "test2", "test3") as f2></TMPL_foreach><TMPL_var f></TMPL_foreach>
+// End.
diff --git a/tests/testdata/output_variables.out b/tests/testdata/output_variables.out
new file mode 100644
index 0000000..316380f
--- /dev/null
+++ b/tests/testdata/output_variables.out
@@ -0,0 +1,28 @@
+// Start
+Integer const: 123
+Float sc. const: 3.141
+Float sc. const: 314.1
+"" string const: Te's"t1 TEST TEST
+'' string const: Te's"
+t1
+
+Integer: 123
+Neg. Integer: -123
+
+Float: 123.456
+Neg. Float: -123.456
+
+String: "Hello, World!"
+
+String + Int: "123"
+String + Neg. Int: "-123"
+
+String + Float: "123.456"
+String + Neg. Float: "-123.456"
+
+Not existent variable:
+
+Array: ARRAY
+Hash: HASH
+
+// End.
diff --git a/tests/testdata/output_variables.tmpl b/tests/testdata/output_variables.tmpl
new file mode 100644
index 0000000..51d289c
--- /dev/null
+++ b/tests/testdata/output_variables.tmpl
@@ -0,0 +1,27 @@
+// Start
+Integer const: <TMPL_var 123>
+Float sc. const: <TMPL_var 3.141>
+Float sc. const: <TMPL_var 3.141E+2>
+"" string const: <TMPL_var "Te's\"t1 \x54\x45\u0053\u0054 \124\105\123\124">
+'' string const: <TMPL_var 'Te\'s"\nt1'>
+
+Integer: <TMPL_var int>
+Neg. Integer: <TMPL_var neg_int>
+
+Float: <TMPL_var float>
+Neg. Float: <TMPL_var neg_float>
+
+String: "<TMPL_var string>"
+
+String + Int: "<TMPL_var string_int>"
+String + Neg. Int: "<TMPL_var neg_string_int>"
+
+String + Float: "<TMPL_var string_float>"
+String + Neg. Float: "<TMPL_var neg_string_float>"
+
+Not existent variable: <TMPL_var not.existent>
+
+Array: <TMPL_var GET_TYPE(array_int)>
+Hash: <TMPL_var GET_TYPE(hash)>
+
+// End.
diff --git a/tests/testdata/test.mo b/tests/testdata/test.mo
new file mode 100644
index 0000000..8e84a8f
--- /dev/null
+++ b/tests/testdata/test.mo
Binary files differ
diff --git a/tests/testdata/testdata.json b/tests/testdata/testdata.json
new file mode 100644
index 0000000..396517e
--- /dev/null
+++ b/tests/testdata/testdata.json
@@ -0,0 +1,62 @@
+{
+ // One-line comment #1
+ // One-line comment #2
+ // One-line comment #3
+
+ /*
+ * Multiline comment
+ */
+
+ // Integer values
+ "int" : 123,
+ "neg_int" : -123,
+
+ // IEEE 788 floating point value
+ "float" : 123.456,
+ "neg_float" : -123.456,
+
+ // String
+ "string" : "Hello, World!",
+
+ // String + integer
+ "string_int" : "123",
+ "neg_string_int" : "-123",
+
+ // String + IEEE 788
+ "string_float" : "123.456",
+ "neg_string_float" : "-123.456",
+
+ // Array of integer
+ "array_int" : [1, 2, 3, 4],
+
+ // Hash
+ "hash" : { "one" : 1, "two" : 2, "three" : 3 },
+
+ //
+ "string2" : { "to" : { "escape" : "<b>test</b> \"test\" $test$" } },
+
+ 'dic': { 'arr': [ 0, 1, 2, 3], 'val' : 'ind' },
+ 'ind' : 2,
+
+ 'n1' : 1,
+ 'n2' : 2,
+ 'n5' : 5,
+
+ 'funcs': [ "test1", "test2", "test3" ],
+ 'func': "test",
+
+ "data" : {
+ "name" : "test",
+ "data" : {
+ "name" : "test"
+ },
+ "edit_card_form": {
+ "fields": {"field1": "name"}
+ }
+ },
+ "items" : [
+ {"id":1,"name":"Item 1",
+ "subitems":[{"id":11,"name":"Subitem 1.1"}, {"id":12,"name":"Subitem 1.2"},{"id":13,"name":"Subitem 1.3"} ] }
+ ]
+}
+
diff --git a/tests/testdata/verbose_mode.out b/tests/testdata/verbose_mode.out
new file mode 100644
index 0000000..444a35a
--- /dev/null
+++ b/tests/testdata/verbose_mode.out
@@ -0,0 +1,9 @@
+ FIRST VERBOSE (4 spaces before):
+NO_SPACES_AROUND
+ SECOND VERBOSE (4 spaces before):
+NESTED VERBOSE:NO_SPACES_AROUND
+ THIRD VERBOSE (4 spaces before):
+:VAR 1:Hello, World!:VAR 2:123
+ OUTPUT_WITH_SPACES
+
+Another verbose mode starts here::VAR 1:Hello, World!:VAR 2:123
diff --git a/tests/testdata/verbose_mode.tmpl b/tests/testdata/verbose_mode.tmpl
new file mode 100644
index 0000000..88d5123
--- /dev/null
+++ b/tests/testdata/verbose_mode.tmpl
@@ -0,0 +1,42 @@
+ FIRST VERBOSE (4 spaces before):
+<TMPL_verbose>
+
+
+NO_SPACES_AROUND
+
+
+
+</TMPL_verbose>
+ SECOND VERBOSE (4 spaces before):
+<TMPL_verbose>
+
+ NESTED VERBOSE:
+ <TMPL_verbose>
+ NO_SPACES_AROUND
+ </TMPL_verbose>
+
+</TMPL_verbose>
+ THIRD VERBOSE (4 spaces before):
+<TMPL_verbose>
+
+
+
+ <TMPL_if (1 ne 0)>
+ :VAR 1: <TMPL_var string>
+
+ :VAR 2: <TMPL_var int>
+ </TMPL_if>
+
+
+
+
+
+</TMPL_verbose>
+ OUTPUT_WITH_SPACES
+
+Another verbose mode starts here:
+<-TMPL_if (1 ne 0)->
+ :VAR 1: <-TMPL_var string->
+
+ :VAR 2: <-TMPL_var int->
+<-/TMPL_if->