Release Notes

# Qore 0.8.13.2

Release Summary
  Bugfix release; see details below

## New Features in Qore

- `"thread list"`, `"backtrace all"` commands implemented for the debugger (issue 2608)
- QUnit: overloaded the `testAssertionValue()` method to support auto/number/float and more verbose output when a difference in number/float values is found (issue 2556)
- qdbg-remote supports ConnectionProvider connections (issue 2613)
- new method: Breakpoint::getProgram()

## Bug Fixes in Qore

- module fixes:
  - DebugCmdLine:
    - improved breakpoint usability (issue 2604)
    - fixed a bug parsing call signatures when setting breakpoints (issue 2601)
  - DebugProgramControl:
    - improved breakpoint usability (issue 2604)
    - fixed a bug providing the programId context (issue 2603)
  - QUnit:
    - improved error location reporting by providing all stack location information up until the QUnit call to cover the case when multiple code layers are used such as one or more test modules (issue 1720)
  - SqlUtil:
    - implemented support for literal values in column operators taking column arguments with `cop_value()` (issue 2555)
  - WebSocketClient:
    - added `WebSocketClient::pong()` to allow unsolicited `PONG` messages to be sent (issue 2566)
  - WebSocketHandler:
    - fixed a bug where unsolicited `PONG` messages caused the connection to be prematurely closed (issue 2566)
- fixed a bug with implicit initialization of typed hashes; this is now illegal and a `HASHDECL-IMPLICIT-CONSTRUCTION-ERROR` exception is raised in such cases (issue 2491)
- fixed a bug with Condition variable handling on macOS High Sierra due to an internal undocumented API change (issue 2576)
- fixed a memory error with the += operator and uninitialized date/time values (issue 2591)
- fixed a bug in the remote debugger `qdbg-remote` where `wss://` schemes were not accepted (issue 2596)
- fixed a bug in an error message in ProgramControl::findFunctionStatementId() (issue 2600)
- fixed a crash when HTTPClient::setDefaultPath() was called with no argument (issue 2610)
- fixed a bug in debugger when program is not set (issue 2603)

# Qore 0.8.13.1

Release Summary
  Bugfix release; see details below

## New Features in Qore

- the `sqlutil` script has been updated with the `–select` option to allow dumped table rows to be filtered (issue 2509)

## Bug Fixes in Qore

- fixes in modules:
  - `astparser` module fixes:
    - fixed memory leaks in `AstParser::parseFile()` and `AstParser::parseString()` methods (issue 2261)
    - fixed incorrect flex code regarding parse options leading to segfaults (issue 2262)
  - DebugCmdLine module fixes:
    - fixed value setting to process all remaining arguments on the command line (issue 2294)
  - DebugCmdLine module fixes:
    - the debugger should report ambiguous partial matches as an error (issue 2292)
  - MailMessage module fixes:
    - fixed `Message::addBody()` with no body present (issue issue 2360)
  - Mapper module fixes:
    - fixed a bug in the `STRING-TOO-LONG` exception (issue 2405)
  - PgsqlSqlUtil module fixes:
    - fixed a bug where default column values were compared incorrectly leading to false positives when comparing and aligning DB schemas (issue 2527)
  - Qdx module fixes:
    - fixed a bug in documentation post-processing for hashdecl declarations (issue 2298)
  - QUnit fixes:
    - added missing comparison methods (issue 1588):
      - `Test::assertRegex()`
      - `Test::assertNRegex()`
      - `Test::assertNeq()`
      - `Test::assertNeqSoft()`
      - `Test::assertGt()`
      - `Test::assertGtSoft()`
      - `Test::assertGe()`
      - `Test::assertGeSoft()`
      - `Test::assertLt()`
      - `Test::assertLtSoft()`
      - `Test::assertLe()`
      - `Test::assertLeSoft()`
      - `Test::assertNothing()`
  - RestHandler module fixes:
    - updated to return a 400 Bad Request error when REST schema validation fails on messages received issue 2344)
    - updated to return a 400 Bad Request error when there are string encoding errors with messages received (issue 2398)
    - updated to return a 404 Not Found error when REST subclass does not exist (issue 2405)
    - updated to return a 400 Bad Request error when ENCODING-CONVERSION-ERROR occurs during request parsing (issue 2543)
  - RestSchemaValidator module fixes:
    - updated docs for AbstractRestSchemaValidator::parseRequest() to reflect how validation exceptions should be raised for proper error reporting (issue 2344)
    - fixed handling of messages with non-object (i.e. non-hash) bodies (issue 2366)
  - SqlUtil module changes
    - implemented support for custom column operators (issue 2314)
  - OracleSqlUtil module changes
    - implemented support for chained synonyms (issue 2408)
    - allow to use DBA_* views instead of ALL_* if possible (issue 2418)
  - Swagger module fixes:
    - fixed handling of string type date and date-time formats (issue 2341)
    - fixed example value for binary type (issue 2342)
    - fixed serialization of date/time values (issue 2349)
    - updated to return a 400 Bad Request error when REST schema validation fails on messages received issue 2344)
    - fixed handling of non-string enum types (issue 2364)
    - fixed confusing error messages with invalid parameter types (issue 2365)
    - fixed handling of messages with non-object (i.e. non-hash) bodies (issue 2366)
    - fixed handling of optional parameters (issue 2369)
    - fixed handling of non-string query parameters (issue 2388)
    - fixed a bug where string value constraints were only enforced in requests but not responses (issue 2396)
    - fixed a bug where invalid date, binary, and byte values would cause a `500 Internal Server Error` response to be returned instead of a `400 Bad Request` error (issue 2397)
    - fixed a bug where date values were formatted incorrectly in Swagger responses (issue 2409)
    - fixed a bug which made it impossible to send data with other content/mime types than json, yamlrpc, FormUrlEncoded or MultipartFormData (issue 2497)
    - fixed handling of string/binary values (issue 2505)
    - fixed a bug where consumes property of operations was sometimes ignored (issue 2507)
    - fixed parsing of responses without Content-Type header (issue 2517)
    - fixed path matching for paths not beginning with a slash (issue 2516)
  - TableMapper module fixes:
    - fixed issues where where description fields of input and output records for automatically-generated options did not reflect column comments and could not be overridden with user input (issue 2520)
- fixed bugs affecting debugging matching function/method variants and finding statements with special methods and with complex types (issue 1865)
- fixed a bug in `qpp` generating hashdecl code in a specific namespace (issue 2255)
- fixed an error in a hashdecl documentation example (issue 2299)
- made C++ APIs for complex types for modules public (issue 2271)
- fixed inconsistencies in the behavior of the range operator (..) and the square brackets operator [] with lists and ranges between immediate evaluation and lazy functional evaluation and aligned the behavior of the operators among supported data types with the remove and delete operators (issue 2260)
- fixed a bug handling statement indices with parse errors (issue 2312)
- fixed too-agressive class hierachy checks that disallowed legal hierarchies where the same base class appears more than once in the hierarchy (issue 2317)
- fixed a crashing bug in the background operator when the object in context goes out of scope with the thread and an exception is thrown (issue 2319)
- fixed sending duplicate headers when header hash keys differ only in case; headers that differ only in case will be overwritten by the last header in the hash with a matching name with a case-insensitive search (issue 2340)
- fixed `q_absolute_path_windows` to correctly recognize relative Windows paths beginning with a drive letter (issue 2377)
- fixed a bug in `private:internal` in method execution within a class hierarchy in some cases (issue 2380)
- fixed an obscure bug handling runtime errors in code calls with a variant matched at parse time where a runtime exception could occur (issue 2392)
- improved breakpoints (enabled by default), extended help texts, load/save debug history and session (issue 2401)
- fixed a bug in an error message regarding binary module signal assignments (issue 2439)
- added C++ functions to allow binary modules to allocate and deallocate multiple signals atomically (issue 2440)
- eliminated a warning in a header file when building with g++ 7+ (issue 2449)
- implemented a fix in `qdbg` to resume any blocked threads before exiting to ensure a clean and correct shutdown of the debugger; fixes a problem when the process ould freeze on `quit` (issue 2472)
- fixed bugs in Windows builds (issue 2529)

# Qore 0.8.13

Release Summary
  Major new features and bug fixes including input and output stream support and sigificant new functionality including several new modules.

## Changes That Can Affect Backwards-Compatibility

- fixed broken continue and break statements that were accepted anywhere in the source and behaved like a return statement; now such statements outside a loop context will result in a parse exception; to get the old behavior, use %broken-loop-statement in your source code
- fixed broken reference and *reference type restrictions which had no effect prior to this release; to get the old behavior, use %broken-references in your source code
- the random number generator is always seeded with a random number when the Qore library is initialized; to get a predictable sequence from rand(), you must explicitly seed the random number generator by calling srand() with a predefined seed number
- the synchronized keyword now operates differently depending on the context; `synchronized` functions have a global reentrant lock associated with the function (as in previous versions of Qore), whereas now `synchronized` normal class methods share a reentrant lock associated with the object, while `synchronized` static class methods share a reentrant lock associated with the class itself. This aligns Qore's synchronized behavior with that of Java and `[MethodImpl(MethodImplOptions.Synchronized)]` .NET/CLR (issue 894).
- classes may not have the name `"auto"` due to the introduction of this identifier as a special type name
- a new keyword hashdecl has been introduced to support type-safe hash declarations

## New Features in Qore

- complex type support
  - type safe hashes (Type-Safe Hash Type); ex:
    hash<MyInfo> = get_info();
  - new system types:
    - CallStackInfo
    - DateTimeInfo
    - DirStatInfo
    - ExceptionInfo
    - FilesystemInfo
    - IsoWeekInfo
    - StatInfo
  - hash with type-safe values; ex:
    hash<string, int> h = ("str": 1);
  - list with type-safe values; ex:
    list<int> l = (1);
  - reference with type-safe lvalues; ex:
    int i = 1; reference<int> r = \i;
  - auto (allows any value including complex types to be assigned without losing complex type information); ex:
    auto l = (1, 2);
  - improved new, cast<>, and instanceof operators
  - the instanceof operator now works with any type; ex:
    bool b = v instanceof hash<string, int>;
  - note that complex type information is lost when assigning to an lvalue with a compatible but more generic type or by assigning to an untyped lvalue; this was necessary to allow complex types to be introduced in Qore without breaking backwards compatibility.
- support for input and output streams for the efficient piecewise processing of small or large amounts of data with a low memory overhead; includes the following classes:
  - BinaryInputStream
  - BinaryOutputStream
  - BufferedStreamReader
  - EncodingConversionInputStream
  - EncodingConversionOutputStream
  - FileInputStream
  - FileOutputStream
  - InputStream
  - InputStreamLineIterator
  - OutputStream
  - PipeInputStream
  - PipeOutputStream
  - StreamPipe
  - StreamReader
  - StreamWriter
  - StringInputStream
  - StringOutputStream
  - Transform
  - TransformInputStream
  - TransformOutputStream
  - StdoutOutputStream
  - StderrOutputStream
  Three constants were introduced for accessing standard input/output using streams API:
  - stdin_stream
  - stdout_stream
  - stderr_stream
  Additionally, stream support has been added to the following functions and methods:
  - Qore::FtpClient::put()
  - Qore::FtpClient::get()
  - Qore::HTTPClient::send()
  - Qore::HTTPClient::sendChunked()
  - Qore::Socket::sendHTTPChunkedBodyFromInputStream()
  - Qore::Socket::readHTTPChunkedBodyToOutputStream()
  Stream support was also added to the following user modules:
  - CsvUtil
  - FixedLengthUtil
- support for lazy functional evaluation of functional operators (including nested lazy evaluation) for much more efficient processing of iterated expressions; affects:
  - map: supports lazy evaluation of itself and also of the iterator expression
  - select: supports lazy evaluation of itself and also of the iterator expression
  - keys: supports lazy evaluation of itself
  - foldl: supports lazy evaluation of the iterator expression
  - foldlr: supports lazy evaluation of the iterator expression
  - foreach: supports lazy evaluation of the iterator expression
  - .. (range operator): supports lazy evaluation of itself
  - [n,m,...] (list, string, or binary dereference with multiple indices)): supports lazy evaluation of itself
- support for list, string, and binary slices with offsets and ranges:
  - list slices
  - string slices
  - binary slices
  - new .. range operator
  - updated [] operator
- enhanced cryptographic support including support for AES with Additional Authenticated Data and Message Authentication Code (MAC) support, plus the following new API functions:
  - Qore::decrypt_to_binary()
  - Qore::decrypt_to_string()
  - Qore::encrypt()
  - Qore::get_crypto_info()
  - Qore::get_decryptor()
  - Qore::get_encryptor()
  The following constants were added to support the new generic cryptographic APIs:
  - Qore::CRYPTO_ALG_AES_128
  - Qore::CRYPTO_ALG_AES_192
  - Qore::CRYPTO_ALG_AES_256
  - Qore::CRYPTO_ALG_BLOWFISH
  - Qore::CRYPTO_ALG_BLOWFISH_CFB
  - Qore::CRYPTO_ALG_BLOWFISH_OFB
  - Qore::CRYPTO_ALG_CAST5
  - Qore::CRYPTO_ALG_CAST5_CFB
  - Qore::CRYPTO_ALG_CAST5_OFB
  - Qore::CRYPTO_ALG_DES
  - Qore::CRYPTO_ALG_DES_CFB
  - Qore::CRYPTO_ALG_DES_OFB
  - Qore::CRYPTO_ALG_DES_EDE
  - Qore::CRYPTO_ALG_DES_EDE_CFB
  - Qore::CRYPTO_ALG_DES_EDE_OFB
  - Qore::CRYPTO_ALG_DES_EDE3
  - Qore::CRYPTO_ALG_DES_EDE3_CFB
  - Qore::CRYPTO_ALG_DES_EDE3_OFB
  - Qore::CRYPTO_ALG_DESX
  - Qore::CRYPTO_ALG_RC2
  - Qore::CRYPTO_ALG_RC2_CFB
  - Qore::CRYPTO_ALG_RC2_OFB
  - Qore::CRYPTO_ALG_RC4
  - Qore::CRYPTO_ALG_RC5
  - Qore::CRYPTO_ALG_RC5_CFB
  - Qore::CRYPTO_ALG_RC5_OFB
- support for binding output placeholder buffers for result sets that return an SQLStatement object:
  - new DBI capability constant DBI_CAP_HAS_RESULTSET_OUTPUT
  - new placeholder buffer specification constant RESULTSET
- new debugging support (note that APIs are subject to change until the next major release):
  - new classes:
    - Breakpoint
    - DebugProgram
    - ProgramControl
  - new modules:
    - DebugCmdLine
    - DebugHandler
    - DebugProgramControl
    - DebugUtil
  - new parse directives:
    - %allow-debugger: allows running debug commands
    - %no-debugging: forbids debugging of the current Program object
- new user modules:
  - DebugCmdLine
  - DebugHandler
  - DebugProgramControl
  - DebugUtil
  - ConnectionProvider
  - DatasourceProvider
  - Qdx
  - SewioRestClient
  - SewioWebSocketClient
  - Swagger
  - TextWrap
- new access modifiers: `private:internal` (providing strong encapsulation of the following declaration(s)) and `private:hierarchy` (which is equivalent to `private`; issue 1197)
- new parse options and directives:
  - %allow-debugger: allows running debug commands
  - %no-debugging: forbids debugging of the current Program object
  - %allow-weak-references: allows the use of the weak assignment operator (:=)
  - %broken-loop-statement: allows continue and break statements to be accepted anywhere in the source and behave like a return statement
  - %broken-references: allows reference and *reference type restrictions to accept any type contrary to the documented design and intention of these type restrictions
  - %correct-loop-statement: to revert the effect of %broken-loop-statement
  - %correct-references: to revert the effect of %broken-references
  - %no-uncontrolled-apis: disallow access to uncontrolled APIs such as external language bindings or direct generic system call APIs that could bypass Qore's sandboxing controls
  - %strong-encapsulation: disallows out of line class and namespace declarations
  - %try-reexport-module: conditionally loads a module in a user module and allows for that module to be reexported as well
- new constants:
  - DBI_CAP_HAS_RESULTSET_OUTPUT: DBI capability for drivers that support returning an SQLStatement object for a result set when bound with the RESULTSET placeholder specification
  - PathSep: defines the platform-specific path separator character
  - PO_ALLOW_DEBUGGER: allows running debugger commands
  - PO_NO_DEBUGGING: disallows debugging of the Program
  - PO_ALLOW_WEAK_REFERENCES: allows the use of the weak assignment operator (:=)
  - PO_BROKEN_LOOP_STATEMENT: allows continue and break statements to be accepted anywhere in the source and behave like a return statement
  - PO_BROKEN_REFERENCES: reverts reference and *reference type restrictions to pre-Qore-0.8.13 behavior where they would have no effect
  - PO_NO_UNCONTROLLED_APIS: disallow access to uncontrolled APIs such as external language bindings or direct generic system call APIs that could bypass Qore's sandboxing controls; note that this parse option was also added to PO_NO_IO and PO_NO_EXTERNAL_ACCESS
  - PO_STRONG_ENCAPSULATION: disallows out of line class and namespace declarations
  - RESULTSET: specifies that an SQLStatement object should be returned from a result set output variable in an SQL query
  - SSL_VERIFY_NONE: Socket::setSslVerifyMode() option: do not verify peer certificates
  - SSL_VERIFY_PEER: Socket::setSslVerifyMode() option: verify peer certificates
  - SSL_VERIFY_FAIL_IF_NO_PEER_CERT: Socket::setSslVerifyMode() option: fail if the client does not provide a certificate (server mode only)
  - SSL_VERIFY_CLIENT_ONCE: Socket::setSslVerifyMode() option: only require the client to send a certificate once (server mode only)
  - Qore::ParseOptionCmdCodeMap
  - Qore::ParseOptionCmdStringMap
  - see new cryptographic constants listed above
- implemented additional parse-time checks for many operators to provide feedback for invalid operations detected at parse time
- implemented the weak assignment operator (:=) (only available with %allow-weak-references)
- implemented the range operator (..)
- implemented support for list expressions inside the dereference operator ([])
- new methods:
  - Qore::Program::getAllDefines()
  - Qore::Program::getGlobalVars()
  - Qore::Program::importHashDecl()
  - Qore::Program::importSystemHashDecls()
  - Qore::Program::setGlobalVarValue()
  - Qore::Program::setThreadInit()
  - Qore::Program::getThreadList()
  - Qore::Socket::acceptAllCertificates()
  - Qore::Socket::getAcceptAllCertificates()
  - Qore::Socket::getSslVerifyMode()
  - Qore::Socket::setSslVerifyMode()
- updated methods:
  - Counter::dec(): now returns the current value of the counter
  - Qore::HTTPClient::constructor() added support for the following options:
    - `ssl_cert_path:` allows an X.509 client certificate to be set in the constructor
    - `ssl_key_path:` allows a private key for an X.509 client certificate to be set in the constructor
    - `ssl_key_password:` allows a password-protected private key to be used wih an X.509 client certificate
    - `ssl_verify_cert:` enforces server certificate validation with HTTPS connections
    Additionally, the HTTPClient class now understands the `PATCH` method (RFC 5789)
  - Qore::RangeIterator::constructor(int) was updated; the second argument was removed to avoid ambiguity with the other overloaded constructor
  - TreeMap::get(): added a new optional argument to return the unmatched part of the search string
  - the following read-only static methods were moved from the File class to the ReadOnlyFile class:
    - ReadOnlyFile::hstat()
    - ReadOnlyFile::hlstat()
    - ReadOnlyFile::lstat()
    - ReadOnlyFile::stat()
    - ReadOnlyFile::statvfs()
- new pseudo-methods:
  - <int>::format(int, string, string)
  - <float>::format(int, string, string)
  - <number>::format(int, string, string)
  - <string>::toInt(int)
  - <int>::toBase(int)
  - <number>::toBase(int)
  - <float>::toBase(int)
  - <value>::complexType()
  - <value>::fullType()
- new functions:
  - Qore::decrypt_to_binary()
  - Qore::decrypt_to_string()
  - Qore::encrypt()
  - Qore::get_compressor()
  - Qore::get_crypto_info()
  - Qore::get_decompressor()
  - Qore::get_decryptor()
  - Qore::get_encryptor()
  - Qore::get_global_vars()
  - Qore::get_local_vars()
  - Qore::get_random_bytes()
  - Qore::get_thread_call_stack()
  - Qore::parse_int()
  - Qore::set_global_var_value()
  - Qore::set_local_var_value()
- updated functions/methods:
  - Counter::dec(): now returns the current value of the counter
  - Qore::Thread::thread_yield()
- updated functions:
  - ceil(): now allows the precision to be specified
  - floor(): now allows the precision to be specified
  - hash(): now returns an untyped hash stripped of any key type information
  - mkdir(): now allows parent directories to be created in the same call
  - round(): now allows the precision to be specified
  - set_thread_init(): now allows for thread init code to be removed
  - Qore::xrange(int) was updated; the second argument was removed to avoid ambiguity with the other overloaded variant
- module updates:
  - BulkSqlUtil module updates:
    - added complex type support
    - added the `AbstractBulkOperation::size()` method
    - implemented analytic/window functions: new functions [issue 2202]
    - implemented analytic/window functions: cop_over full support including ORDER BY [issue 2203]
  - CsvUtil module updates:
    - added support for streams
  - FixedLengthUtil module updates:
    - added support for streams
    - added `FixedLengthFileIterator::getFileName()` (issue 1164)
    - added field as well as global option "truncate" (issue 1841)
    - added field as well as global option "tab2space" (issue 1866)
  - HttpServer module updates:
    - added a minimal substring of string bodies received to the log message when logging HTTP requests
  - HttpServerUtil module updates:
    - the `parse_uri_query()` function was moved to the Util module
  - Mime module updates:
    - added complex type support
    - added the following constants:
      - `MimeTypeMultipartFormData`
      - `MimeTypeMultipartRelated`
      - `MimeTypeMultipartMixed`
    - added the following methods:
      - `MultipartMessage::getBoundary()`
      - `MultipartMessage::serializeBody()`
      - `MultipartMessage::size()`
    - fixed a bug parsing multipart messages where unnecessary characters were searched (issue 2099)
  - Pop3Client module updates:
    - added the `Pop3Connection` class to support the ConnectionProvider module
  - Qorize module updates:
    - `qorize_named()` added support for objects
  - RestClient module updates:
    - added the `RestConnection` class to support the ConnectionProvider module
    - support for the `text/plain` `Content-Type`
  - RestClient module updates:
    - added support for runtime REST API validation against a REST schema using the RestSchemaValidator module
    - added support for Swagger 2.0 REST API validation and `"swagger"` options using the Swagger module in the `RestClient` and `RestConnection` classes
  - RestHandler module updates:
    - added an API to allow REST calls to be made internally (issue 1899)
    - added support for runtime REST API validation against a REST schema using the RestSchemaValidator module
  - RestSchemaValidator module:
    - added this new module providing a REST schema validation API
  - SalesforceRestClient module updates:
    - added the `SalesforcRestConnection` class to support the ConnectionProvider module
  - Schema module updates:
    - added the `c_blob()` and `c_clob()` functions (issue 1851)
  - SewioRestClient module:
    - added this new module providing APIs for communicating with Sewio.net's RTLS Studio REST API
  - SewioWebSocketClient module:
    - added this new module providing APIs for communicating with Sewio.net's RTLS Studio WebSocket API
  - SmtpClient module updates:
    - added the `SmtpConnection` class to support the ConnectionProvider module
  - SqlUtil module updates:
    - implemented the `cop_trunc_date()` function (issue 2032)
  - Swagger module added:
    - added this new module providing a Swagger 2.0 REST API validation API to Qore
  - TableMapper module updates:
    - added support for upserts in `InboundTableMapper` (issue 1067)
    - added `InboundTableMapper::queueData(list)`
  - TelnetClient module updates:
    - added the `TelnetConnection` class to support the ConnectionProvider module
    - added support for URLs in the constructor()
    - added the `TelnetClient::getTarget()` method
  - Util module updates:
    - the `parse_uri_query()` function was moved here from the HttpServerUtil module
    - `parse_uri_query()` now handles repeated query arguments as a list
    - added public function `flatten()`
    - added public function `uniq()`
  - WebSocketClient module updates:
    - added the `WebSocketConnectionObject` class to support the ConnectionProvider module
    - updated for complex types
    - fixed a bug where the event loop thread would immediately terminate after a reconnection (issue 2061)
    - improved client logging
    - fixed a bug where the `WebSocketClient` class did not validate the `Sec-WebSocket-Accept` response header according to RFC6455 (issue 2062)
  - WebSocketUtil module updates:
    - added the `ws_get_response_key()` function
- the following classes can be used from binary modules:
  - File
  - ReadOnlyFile
- updated the build to require a C++11 compiler or better to build Qore (issue 994)
- a relative time stamp is now logged in trace and debug output

## Bug Fixes in Qore

- fixed a bug causing AbstractQuantifiedBidirectionalIterator not being available (issue 968)
- BulkSqlUtil module fixes:
  - fixed the module to work properly even with DB drivers that do not support parameter array binding (issue 1154)
- CsvUtil module fixes:
  - fixed a bug in an error message validating input data (issue 1062)
  - added an exception when detected headers do not match the fields option (issue 2179)
- HttpServer module fixes:
  - added logic to attempt to mask passwords in log messages (issue 1086)
- HttpServerUtil module fixes:
  - fixed a bug where the msg arg to `AbstractAuthenticator::do401()` was ignored (issue 1047)
- RestHandler module fixes:
  - added logic to allow sensitive data to be masked in log messages (issue 1086)
- SqlUtil module fixes:
  - fixed a bug in update and upsert statement generation when the given data does not have enough columns to use the unique index found, an error message is generated that contains all the columns names instead of just the column names required by the index (issue 1013)
- WebSocketClient module fixes:
  - fixed a thread lock starvation race condition (issue 2130)
- `UTF-16` fixes:
  - fixed a bug comparing strings in `UTF-16` encodings (issue 1579)
  - fixed Qore::substr() and <string>::substr() with strings in `UTF-16` encodings (issue 1586)
  - fixed Qore::trim(), Qore::ltrim(), Qore::rtrim() and the trim operator with strings with `UTF-16` encodings (issue 1775)
- fixed a bug where break and continue statements were accepted outside of loops (issue 976)
- fixed a bug compiling on Solaris SPARC with g++ where `MPFR_DECL_INIT()` is compiled incorrectly with -O1 or greater (issue 958)
- fixed a bug causing an infinite loop in decompression functions (issue 966)
- fixed an issue where an internal C++ API (QoreProgram::parseCmdLineDefines()) performed a needless copy of a data structure (issue 1099)
- fixed a stack corruption bug with asynchronous I/O on UNIX systems with ReadOnlyFile methods (issue 1106)
- fixed bugs with inconsistent conversions of int, float, and boolean values to date/time values, now they are all converted uniformly to relative date/time values (issue 1156)
- fixed a bug where Qore allowed code to be declared both public and private without a warning (issue 1187)
- fixed a bug where the instanceof operator would return True with objects that did not publically inherit the given class or where the given class is not accessible (issue 1191)
- fixed a bug in qpp support of the 'final' class flag (issue 1222)
- fixed a bug where the + operator provided access to private members from outside the class (issue 1209)
- fixed a bug where different overloaded method variant resolution rules were used at parse time (best match in hierarchy) and runtime (best match in first matching class) in a class hierarchy (issue 1229)
- fixed a bug where exceptions in base class constructor calls did not reflect the actual source location (issue 1230)
- fixed a bug where runtime function/method variant matching was incorrectly biased towards default matches for missing arguments (issue 1231)
- fixed bugs where calls to Socket::upgradeClientToSSL() and Socket::upgradeServerToSSL() were ignored with no exception thrown if the socket was not connected (issue 1258)
- fixed a bug where a closure created in an object scope could not be called if the object had been deleted, even if the closure did not refer to the object (issue 1303)
- fixed a bug where ord() would return negative numbers for bytes with the high bit set with compilers where `char` is the same as `signed char` (issue 1385)
- fixed a bug where int(number) returned rounded value instead of the integer part (while int(float) behaved correctly; also cf. initializing a softint value from a number vs. from a float) (issue 1463)
- File::read() now uses character semantics for the length argument (issue 1548)
- fixed a bug with strongly-typed lvalue assignments with classes created in different Program objects (issue 1551)
- fixed a bug where an ASCII string and the same string in a different encoding and with diacritics could incorrectly be marked as equal (issue 1579)
- fixed bugs in HTTPClient methods where string message bodies were not converted to the object's character encoding before transmission (issue 1813)
- fixed a bug in the reference and *reference assignment restrictions; previously any value was accepted, now only references are accepted as the initial assignment values (issue 1819)
- fixed a bug in handling the `SqlUtil::BLOB` type in the FreetdsSqlUtil module (issue 1852)
- fixed a bug in overloaded call variant matching where missing arguments were counted towards the match (issue 1897)
- fixed many bugs where parse-time errors could be reported at an incorrect source location; parse-time error location reporting has been completely overhauled and reimplemented for correctness (issue 1930)
- fixed a bug where code signatures would accept parameter variables without `"$"` signs even when %allow-bare-refs was not in effect (issue 1941)
- fixed memory leaks in the scanner related to EOF conditions (issue 1976)
- rewrote Qore functions gethostbyname(), gethostbyname_long() and gethostbyaddr() to use standard C functions `getaddrinfo(3)` and `getnameinfo(3)` internally instead of the deprecated `gethostbyname(3)` and `gethostbyaddr(3)` (issue 1952)
- fixed cmake builds on Darwin (issue 1980)
- fixed a bug where immediate date-time values were not marked with their type at parse time (issue 2001)
- fixed a bug where the *data type restriction would allow all types to be assigned at runtime (issue 2002)
- Qore::RangeIterator::constructor(int) and Qore::xrange(int) were updated; the second arguments were removed to avoid ambiguity with the other overloaded variants (issue 2016)
- fixed a bug where Qore::replace() could get in an infinite loop with arguments with embededed nulls (issue 2098)
- fixed a bug in regular expression extraction where an infinite loop could occur (issue 2083)
- fixed a bug where a call reference to an object method that crosses Program boundaries could result in a core dump when called due to an error managing thread-local data (issue 2145)
- fixed crashes in scanner due to EOF in comments (issue 2175)

# Qore 0.8.12.12

Release Summary
  Bugfix release; see details below

## New Features in Qore

- aded the HAVE_DSS constant to indicate if the outdated DSS(), DSS1(), DSS_bin(), DSS1_bin(), DSS_HMAC(), and DSS1_HMAC() functions are available in the opnessl library used to compile Qore

## Bug Fixes in Qore

- fixed a bug handling `argv` in base class constructor execution (issue 2030)
- fixed a bug handling the connection status in the HTTPClient class (issue 2058)
- fixed building with openssl 1.1+ (issue 2135)
- fixed binding more than one wilcard port on a specific address in the HttpServer module (issue 2155)
- fixed a bug in SqlUtil with column aliases that are reserved words (issue 2163)
- fixed a memory bug in the splice operator with a binary operand (issue 2303)
- fixed a bug where calling any SQLStatement method in another thread with an active connection from a DatasourcePool causes a crash (issue 2334)
- fixed a bug in RestHandler regarding inconsistent handling of URI parameter arguments; the `"action"` key was only removed from the `ah` hash when there were no other arguments, introducing an inconsistency in argument handling in REST services (issue 2479)
- fixed a bug where `ENCODING-CONVERSION-ERROR` exceptions were not thrown with newer GNU iconv libraries with an API change (issue 2500)

# Qore 0.8.12.11

Release Summary
  Bugfix release; see details below

## New Features in Qore

- issue 1947 added broken-logic-precedence warning.

## Bug Fixes in Qore

- fixed documentation regarding escaping of characters in strings and added a parse exception in case of trying to escape octal values in range 400-777 (issue 50)
- fixed a crashing bug where Datasource::getConfigString() was called without a connection, also could crash in an implicit internal call to this method with the DatasourcePool class when connections were lost and the warning callback should be called (issue 1992)
- fixed a bug where Datasource::getConfigHash() returned different values depending on if the object was connected or not (issue 1994)

# Qore 0.8.12.10

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- module fixes:
  - FixedLengthUtil:
    - fixes and improvements to errors and exceptions (issue 1828)
  - HttpServerUtil:
    - eliminated excess logging of all HTTP chunks sent and received (issue 1832)
  - PgsqlSqlUtil:
    - fixed a bug in setting a `comment` for a table column (issue 1886)
  - SqlUtil:
    - fixed a bug in the `offset` query hash argument in SQL operation methods (issue 1880)
    - fixed a bug that prohibited only columns from the main query to be selected when joins are used (issue 1909)
  - TableMapper:
    - fixed a bug in flush messages in the `InboundTableMapper` class (issue 1849)
- fixed a bug that could cause spurious parse-time exceptions to be thrown when matching call variants with multiple return types for the same callable object (issue 1928)
- fixed the process return code in the output reference in backquote() on Unix/Linux platforms (issue 1884)
- fixed a bug where connections were not immediately released back to the DatasourcePool in case of an `SQLSTATEMENT-ERROR` exception (issue 1836)
- eliminated a spurious exception in the SQLStatement class in case of a DatasourcePool timeout (issue 1832)
- fixed a crash when the incorrect type was passed to a parameter declared *reference (issue 1815)
- fixed a crash when the Qore library exits caused by an error in handling module dependencies with injected modules (issue 1805)
- fixed segfault crashes caused by calling object methods with null pointers (issue 1791)
- added internal API support to make it easier for DBI drivers to handle lost connections and to allow DBI drivers that must close all open handles before a connection is closed (such as the oracle driver); due to this change, SQLStatement objects based on a DatasourcePool are closed automatically whenever the datasource is returned to the pool (issue 1250)
- implemented new parse options to revert the effect of parse options that affect code safety (issue 1895):
  - %correct-list-parsing
  - %correct-logic-precedence
  - %correct-int-assignments
  - %correct-operators
  - %loose-args
- fixed parse locations of strings and regexes (issue 1905)

# Qore 0.8.12.9

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed a memory leak where references participate in recursive references (issue 1774)
- fixed a build issue with clang++ (issue 1768)
- fixed a memory leak in the Queue copy constructor when the Queue was used in other objects (such as an event queue, etc; issue 1749)
- Mapper module fixes:
  - fixed bugs handling the `allow_dot` and `allow_output_dot` options (issue 1690)
  - fixed `TableMapper` bugs introduced in Qore 0.8.12.7 (issue 1754)

# Qore 0.8.12.8

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed a memory leak in %try-module error handling (issue 1690)
- fixed a bug in trunc_str() when the string has an invalid multi-byte character at the end of the string and the string is exactly the byte width requested (issue 1693)
- fixed a bug where ReadOnlyFile::getchar() did not respect character semantics as documented (issue 1547)
- OracleSqlUtil module fixes:
  - fixed a bug in `character_semantics` for standalone column (issue 1688)
- Mapper module fixes:
  - fixed a bug in handling "list mode" data such as submitted by `InboundTableMapper::queueData()` (issue 1736, bug introduced in Qore 0.8.12.7 with the fix for issue 1626)
- SqlUtil module fixes:
  - fixed schema alignment skipping column with name "driver" (issue 1684)
  - fixed sqlutil schema management: functional indexes are rejected without () in name (issue 1610)
- TableMapper module fixes:
  - fixed a bug in handling "list mode" data with optimized inserts (issue 1736, bug introduced in Qore 0.8.12.7 with the fix for issue 1626)
- WebSocketClient module fixes:
  - added timeout values to Socket and HTTPClient calls (issue 1725)
- WebSocketHandler module fixes:
  - added timeout values to Socket calls (issue 1725)
- WebSocketUtil module fixes:
  - added timeout values to Socket calls (issue 1725)
- fixed a bug where a type conversion error in an lvalue assignment could generate a confusing unrelated runtime exception (issue 1697)
- fixed a bug where invalid characters in the port specification in a URL were ignored (issue 1728)
- fixed a bug with SSL socket communication the remote closing the connection during a send operation could cause the current thread to go into an infinite loop consuming 100% CPU (issue 1729)
- fixed a bug in the HashListIterator class iterating hashes with a mix of lists and single values such as used by bulk DML binds; now the single values will appear as the current value for all list elements as per the original design instead of throwing a runtime exception (issue 1738)

# Qore 0.8.12.7

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed bug in internal string generation with `size_t` arguments that could cause invalid data to be output or crashes on 32-bit platforms (issue 1640)
- fixed a runtime memory leak and invalid runtime behavior with undetected recursive lvalue references (issue 1617)
- improved prompt collection performance with large graphs of objects by eliminating additional unnecessary graph scans, resulting in further large performance improvements in the garbage collector (issue 1363)
- improved `InboundTableMapper::queueData()` performance (in the TableMapper module) when used with data in hash of lists format to use bulk DML in input and output without internal data conversions (issue 1626)
- OracleSqlUtil module fixes:
  - worked around `ORA-22165` from `op_in()` caused by Oracle's limit on number of collection elements (issue 1660)
  - fixed a bug in the force option (i.e. cascade) for dropping types (issue 1683)
- improved %try-module error reporting and documentation (issue 1648)

# Qore 0.8.12.6

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed a bug in Qore::parse_url() parsing single-character hostnames (issue 1524)
- fixed a bug where PO_LOCKDOWN was not set when parsing `init` and `del` attributes in user module headers (issue 1535)
- fixed a bug parsing exception catch block parameter errors (in debug builds only; issue 1558)
- fixed a bug dereferencing binary values with the [] operator; the behavior now corresponds to the documentation (issue 1566)
- fixed a bug that would result in a crash if a method were declared both `static` and `abstract` (issue 1590)
- fixed performance issues with the Mapper module (and by extension the TableMapper module) for mappers with many identity (i.e. 1:1) and constant mappings (issue 1620)
- fixed a bug in the `BulkInsertOperation` class in the BulkSqlUtil module where inserts would fail or silently insert invalid data in the second or later blocks when constant hashes were used (issue 1625)

# Qore 0.8.12.5

Release Summary
  Bugfix release; see details below

## New Features in Qore

- added the SalesforceRestClient module for communicating with Salesforce.com using the REST APIs
- module SqlUtil
  - has support for native default values in tables (issue 1428)
  - has support for Oracle named types (eg. spatial types) for Schema.qm and SchemaReverse.qm. (issue 1465)

## Bug Fixes in Qore

- Mime module:
  - added support for URL form-encoded messages (issue 1436
- RestClient module:
  - added support for URL form-encoded messages (issue 1436
  - added support for the `"rawxml"` message body encoding (issue 1437
- fixed handling of invalid compressed data in the following functions (issue 1432):
  - Qore::gunzip_to_binary()
  - Qore::gunzip_to_string()
  - Qore::uncompress_to_binary()
  - Qore::uncompress_to_string()
- fixed `@inf@` on Windows (issue 1442)
- fixed Qore::parse_url() with single-character usernames (issue 1455)
- corrected the error message with SSL reads when the server closes the connection prematurely (issue 1488)
- fixed the `Host` header in HTTP requests to not include the port if the port is the default port for the scheme because it causes some servers to reject the request (issue 1489)

# Qore 0.8.12.4

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed a reference bug in the Queue class introduced in the last release (issue 1309)
- fixed a bug where database types could not be correctly aligned if they had dependencies (issue 1314); entailed updates in the following modules:
  - SqlUtil
  - FreetdsSqlUtil
  - MysqlSqlUtil
  - OracleSqlUtil
  - PgsqlSqlUtil
  - Schema
- fixed a bug in trunc_str() where an infinite loop could be triggered with certain arguments and multi-byte character encodings (issue 1327)
- improved prompt collection performance with larger graphs of objects by eliminating unnecessary graph scans made during object method calls (issue 1363)
- fixed bugs in date(string) and date(string, string) where invalid input data was ignored and invalid dates were returned (issue 1369)
- CsvUtil module:
  - fixed a bug in `AbstractCsvIterator::identifyTypeImpl()` generating an error message (issue 1355)
- MailMessage module:
  - fixed a bug using the default encoding in `Message::attach()` (issue issue 1352)
- SqlUtil module:
  - fixed the ignored character_semantics column option in schema alignmed (issue 1379)
  - implemented the `cop_length()` column function (issue 1395)
- OracleSqlUtil module:
  - OraclePackage attribute body_src is now public to access package bodies
- Qorize module:
  - Qorize module: new qorize_val() set of functions; qorize_named() introduced; qorize tests
- TableMapper module:
  - fixed runtime option propagation to `TableMapper::SqlStatementMapperIterator` from `TableMapper::AbstractSqlStatementOutboundMapper::iterator()` (issue 1418)
  - fixed SqlStatementMapperIterator::getCount() (issue 1417)
  - added the following methods:
    - `TableMapper::AbstractSqlStatementOutboundMapper::getRowIterator()`
    - `TableMapper::InboundTableMapper::iterator()`
    - `TableMapper::InboundTableMapperIterator::getRuntime()`
    - `TableMapper::InboundTableMapperIterator::replaceRuntime()`
    - `TableMapper::InboundTableMapperIterator::setRuntime()`
    - `TableMapper::SqlStatementMapperIterator::getRuntime()`
    - `TableMapper::SqlStatementMapperIterator::replaceRuntime()`
    - `TableMapper::SqlStatementMapperIterator::setRuntime()`
- QUnit module:
  - fixed showing the assertion location when there are test modules on top of QUnit (issue 1046)
- fixed inconsistency between list splice operator and splice function (issue 1380)

# Qore 0.8.12.3

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed the documentation (and DB modules) where SQLStatement::fetchColumns() was inconsistent; now it will return a empty hash when no more rows are available to fetch (issue 1241)
- added I/O timeout support to the FtpClient class (issue 1252)
- fixed bugs in Socket::recv() and Socket::recvBinary() with `size = 0` where NOTHING could be returned which is invalid according to the methods' declared return types (issue 1260)
- fixed a bug where FtpClient:get() would fail with an exception when retrieving an empty file (issue 1255)
- fixed a bug where executing a call reference to a deleted object method would cause a crash (issue 1268)
- fixed a bug where Qore would allow methods to be called on already deleted objects under certain conditions (issue 1270)
- fixed a bug where calling exit() in a multithreaded program could result in a segmentation fault (issue 1215)
- fixed a bug where HttpServer::addListener() could not accept a bind on port 0 to mean any random port (issue 1284)
- fixed a race condition in prompt collection that could lead to a crash (issue 1084)
- fixed a bug clearing Socket event queues when the Socket goes out of scope that could lead to a crash (issue 1292)
- fixed a bug with FtpClient::setWarningQueue() that could cause a crash (issue 1293)
- fixed a bug where Qore::FtpClient::pwd() returned invalid directory names (issue 1295)

# Qore 0.8.12.2

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- fixed bugs in handling websocket close status codes in the WebSocketUtil, WebSocketClient, and WebSocketHandler modules (issue 1216)
- fixed a crashing bug with recursive class initialization (issue 2023)

# Qore 0.8.12.1

Release Summary
  Bugfix release; see details below

## Bug Fixes in Qore

- TableMapper module fixes:
  - fixed a bug with the `SqlStatementOutboundMapper::iterator()` method; corrected the iterator object return value which was causing `AbstractMapperIterator::mapBulk()` to fail (issue 979)
  - fixed a bug with `SqlStatementOutboundMapper`; it would throw an error if the required `"table"` or `"sh"` options were used and only worked with subclasses that declared these options (issue 981)
  - fixed a bug where `AbstractSqlStatementOutboundMapper::iterator()` failed to use options when creating the new `Mapper` object (issue 1088)
- fixed a bug where optional arguments were not handled correctly in some rare cases (issue 974)
- fixed a bug causing a crash when parse_base64_string_to_string() was called with an empty string (issue 996)
- fixed a bug resolving base class method calls during parse initialization (issue 1075)
- fixed thread memory handling bug with some operator expressions and the background operator (issue 1096)
- fixed a race condition in the prompt collection of closure-bound local variables in the garbage collector (issue 1103)
- fixed a bug where HTTPClient class method variants such as HTTPClient::get() without a callback would fail to return the message body when the server sent a reply with chunked transfer encoding (issue 1117)
- fixed a bug in CsvUtil where backward compatibility was broken for single-row-type format (issue 1124)
- fixed bugs where declared public functions were missing from the library ABI (issue 1126)
- fixed bugs where Qore::format_number() and <float>::format() gave incorrect results when rounding to the significant decimals given in the format string (issue 1149)
- fixed a bug referencing `self` in base class constructor arguments (issue 1169)
- fixed a bug where the incorrect class destructor was called in the openldap module (issue 1174)
- fixed a bug where declaring a `copy()` method as synchronized would result in a crash when the method was called (issue 1188)
- fixed bugs in <string>::getEncoded() and <string>::getDecoded() regarding CE_XML and CE_NONASCII (issue 1193)
- fixed bugs where Qore::call_object_method() and Qore::call_object_method_args() allowed private methods to be called from outside the class (issue 1194)
- fixed a bug where "Deprecated" Functions methods were being internally registered as RUNTIME_NOOP (issue 1197)
- fixed bugs where the Datasource class would open a connection to the server in the constructor before options were set and where a server connection was required to call Datasource::getOption() or Datasource::setOption() (issue 1201)
- fixed memory errors in the Queue class where spurious exceptions could be raised (issue 1202)
- fixed a memory leak with static class member initializers (issue 1206)

# Qore 0.8.12

Release Summary
  Major new release with major new features and bug fixes as well as packaging fixes:
  - added support for deterministic garbage collection
  - standardized function naming convention
  - new functions, methods, constants, operators, and user modules
  - greatly improved support on Windows

## Changes That Can Affect Backwards-Compatibility

- fixed broken list parsing; in previous releases, Qore's parser re-wrote lists without parentheses used as top-level statements with certain assignment operators (=, +=, -=, *=, and /=, but not with others) so that statements like `list l = 1, 2, 3;` were valid assignments. Due to operator precedence, such statements should normally be interpreted as `(list l = 1), 2, 3;`, which is not a valid expression. Not only were the rules applied with only some assignment operators, but such lists were only rewritten if used as top-level statements, therefore the rules were applied inconsistenctly depending on where the expression was located in the parse tree. As of Qore 0.8.12, these inconsistencies have been eliminated by default from Qore; all lists are processed according to the precedence rules defined in Operators. This could break old code that relied on the old, broken behavior. To get the old behavior, use the %broken-list-parsing parse directive.
- fixed broken int and softint assignments; previously runtime type errors with these type restrictions were ignored and all values were silently converted to integers for the assignment, now runtime type errors are thrown according to the original design. Parse errors are detected as before. This could break old code that relied on the old, broken behavior. To get the old behavior, use the %broken-int-assignments parse directive.
- fixed broken multi-character operator parsing; the Qore parser has been updated to no longer accept multi-character operators with whitespace between the chacters making up the operator; it is believed that this was never used and simply caused the parser to be needlessly complicated and caused Qore to be less compatible with other languages. To get the old behavior, use the %broken-operators parse directive.
- the push, unshift, pop and shift operators now throw an exception when their first operand is not a list and %strict-args is in effect

## New Features in Qore

- Added the Value Coalescing Operator (?*) which checks first argument if it evaluates to False with <value>::val() and if so assigns the second argument. The operator can be further chained; for example:
  expr1 ?* expr2 ?* expr3
- Added the Null Coalescing Operator (??) which checks the first operand for NOTHING or NULL; if true returns the second argument. The operator can be further chained, in which case the first operand with a value is returned; ex:
  expr1 ?? expr2 ?? expr3
- Qore identifiers can now begin with an underscore character `"_"`; the following is now a valid (with %new-style):
  int _var = 1;
- hash enhancements:
  - new syntax for an expression giving an empty hash: `{}`; for example:
    hash h = {};
  - new literal hash support: hashes can now be given as literal values as follows:
    (<key_expr>: <val_expr>, [...])
    For example:
    return (get_key(): get_value());
    in the past the keys in literal hashes had to be either a string or a constant; now any valid Qore expression can be used to generate the hash keys at runtime
  - new hash syntax; hash elements can now be enclosed by curly brackets as well as regular parentheses; the version with curly brackets when used with the map operator results in the hash version of the map operator being used
  - Added new hash version of the map operator to build a hash from a list or iterator expression; ex:
    hash h = map {$1, h2.$1}, i;
- implemented support for loading user modules in a pre-defined Program object (that can have a custom API) in the following new functions and methods:
  - load_user_module_with_program()
  - Program::loadApplyToPrivateUserModule()
  - Program::loadApplyToUserModule()
  - Program::loadUserModuleWithProgram()
- implemented support for code / dependency injections in Program containers with the following changes:
  - Qore::Program::importClass() now accepts optional arguments that allow the imported version of the class to live in another namespace and have another name and an argument that allows the imported version of the class to remain even if it overlaps with an imported system or user class from a module
  - Qore::Program::importFunction() now accepts an optional argument that allows the imported version of the function to remain even if it overlaps with an imported system or user function from a module
  - the new parse option Qore::PO_ALLOW_INJECTION must be set on the Program object in order to use code / dependency injection parameters in the above methods
  - once a Program object has an injected API set up, the system API can be imported (possibly already overridden with injected code) with the following new methods:
    - Qore::Program::importSystemApi()
    - Qore::Program::importSystemClasses()
    - Qore::Program::importSystemConstants()
    - Qore::Program::importSystemFunctions()
    additionally user modules can be loaded with overridden injected code with the following new functions / methods:
    - load_user_module_with_program()
    - Program::loadApplyToPrivateUserModule()
    - Program::loadApplyToUserModule()
    - Program::loadUserModuleWithProgram()
    furthermore the following function can be used to reload injected modules with the non-injected version:
    - reload_module()
- implemented support for user-defined thread-resource management, allowing Qore code to safely manage resources associated to a particular thread:
  - Qore::Thread::AbstractThreadResource
  - Qore::Thread::remove_thread_resource()
  - Qore::Thread::set_thread_resource()
- new constants:
  - Qore::DirSep
  - Qore::Platform
  - Qore::ParseOptionCodeMap
  - Qore::ParseOptionStringMap
  - Qore::PO_BROKEN_LIST_PARSING
  - Qore::PO_BROKEN_LOGIC_PRECEDENCE
  - Qore::PO_BROKEN_OPERATORS
  - Qore::PO_NO_INHERIT_SYSTEM_CONSTANTS
  - Qore::PO_NO_INHERIT_USER_CONSTANTS
  - Qore::PO_NO_API
  - Qore::PO_NO_SYSTEM_API
  - Qore::PO_NO_USER_API
  - Qore::SQL::DBI_CAP_HAS_ARRAY_BIND
  - String Concatenation Encoding Codes
  - String Concatenation Decoding Codes
- new classes:
  - Qore::DataLineIterator
  - Qore::Thread::AbstractThreadResource
- other new methods:
  - Qore::SQL::DatasourcePool::getCapabilities()
  - Qore::SQL::DatasourcePool::getCapabilityList()
  - Qore::SQL::SQLStatement::currentThreadInTransaction()
  - Qore::Thread::Queue::setError()
  - Qore::Thread::Queue::clearError()
- updated methods:
  - TimeZone::constructor(): now accepts a path to the zoneinfo file if the Qore::PO_NO_FILESYSTEM sandboxing restrictions is not set
- the `SOCKET-THROUGHPUT-WARNING` event is no longer raised on the warning queue if the transfer size is less than 1024 bytes; this affects:
  - Qore::FtpClient::setWarningQueue()
  - Qore::HTTPClient::setWarningQueue()
  - Qore::Socket::setWarningQueue()
- new functions:
  - Qore::create_object()
  - Qore::create_object_args()
  - Qore::decode_uri_request()
  - Qore::encode_uri_request()
  - Qore::get_duration_seconds_f()
  - Qore::getgroups()
  - Qore::getusername()
  - Qore::ltrim()
  - Qore::parse_float()
  - Qore::parse_number()
  - Qore::realpath()
  - Qore::rtrim()
  - Qore::set_return_value()
  - Qore::setgroups()
  - Qore::Thread::remove_thread_resource()
  - Qore::Thread::set_thread_resource()
- updated functions:
  - Qore::parse_boolean()
  - Qore::string()
  - Qore::strmul()
- new pseudo-methods:
  - <date>::dayNumber()
  - <date>::dayOfWeek()
  - <date>::durationSecondsFloat()
  - <date>::isoDayOfWeek()
  - <date>::isoWeekHash()
  - <date>::isoWeekString()
  - <object>::uniqueHash()
  - <string>::getDecoded()
  - <string>::getEncoded()
- the following functions were moved from the Util module to Qore:
  - Qore::absolute_path()
  - Qore::absolute_path_windows()
  - Qore::absolute_path_unix()
- camel-case functions were deprecated in this release, covering the following functions:
  - Qore::callObjectMethod(): deprecated for Qore::call_object_method()
  - Qore::callObjectMethodArgs(): deprecated for Qore::call_object_method_args()
  - Qore::existsFunction(): deprecated for Qore::exists_function()
  - Qore::functionType(): deprecated for Qore::function_type()
  - Qore::getAllThreadCallStacks(): deprecated for Qore::get_all_thread_call_stacks()
  - Qore::getClassName(): deprecated for Qore::get_class_name()
  - Qore::getDateFromISOWeek(): deprecated for Qore::get_date_from_iso_week()
  - Qore::getDayNumber(): deprecated for Qore::get_day_number()
  - Qore::getDayOfWeek(): deprecated for Qore::get_day_of_week()
  - Qore::getDBIDriverCapabilities(): deprecated for Qore::dbi_get_driver_capabilities()
  - Qore::getDBIDriverCapabilityList(): deprecated for Qore::dbi_get_driver_capability_list()
  - Qore::getDBIDriverList(): deprecated for Qore::dbi_get_driver_list()
  - Qore::getFeatureList(): deprecated for Qore::get_feature_list()
  - Qore::getISODayOfWeek(): deprecated for Qore::get_iso_day_of_week()
  - Qore::getISOWeekHash(): deprecated for Qore::get_iso_week_hash()
  - Qore::getISOWeekString(): deprecated for Qore::get_iso_week_string()
  - Qore::getMethodList(): deprecated for Qore::get_method_list()
  - Qore::getModuleHash(): deprecated for Qore::get_module_hash()
  - Qore::getModuleList(): deprecated for Qore::get_module_list()
  - Qore::makeBase64String(): deprecated for Qore::make_base64_string()
  - Qore::makeHexString(): deprecated for Qore::make_hex_string()
  - Qore::parseBase64String(): deprecated for Qore::parse_base64_string()
  - Qore::parseBase64StringToString(): deprecated for Qore::parse_base64_string_to_string()
  - Qore::parseDatasource(): deprecated for Qore::parse_datasource()
  - Qore::parseHexString(): deprecated for Qore::parse_hex_string()
  - Qore::sortDescending(): deprecated for Qore::sort_descending()
  - Qore::sortDescendingStable(): deprecated for Qore::sort_descending_stable()
  - Qore::sortStable(): deprecated for Qore::sort_stable()
  - Qore::throwThreadResourceExceptions(): deprecated for Qore::throw_thread_resource_exceptions()
  Functions deprecated in this release will remain for the forseeable future for backwards-compatibility
- Added support for reexporting imported definitions in user module with the new `%requires(reexport)` form of the %requires parse directive.
- Qore::xrange() and Qore::RangeIterator updates:
  - Qore::xrange() and Qore::RangeIterator::constructor() and <list>::rangeIterator() updated to take an optional value to return in the Qore::RangeIterator::getValue() method
- Qore::FtpClient updates:
  - added Qore::FtpClient::getMode()
- Performance improvements:
  - Qore::HashPairIterator and Qore::ObjectPairIterator objects (returned by <hash>::pairIterator() and <object>::pairIterator(), respectively and the associated reverse iterators) have had their performance improved by approximately 70% by reusing the hash iterator object when possible
- module directory handling changed
  - user modules are now stored in prefix/share/qore-modules/version
  - prefix/share/qore-modules is also added to the module path
  - version-specific module directories are added first, then the "generic" directories
- CsvUtil module updates:
  - new `"tolwr"` option in structured text parsing classes
  - `AbstractCsvWriter` will set `"headers"` from the `"fields"` option if `"headers"` are not explicitly set
  - added write() methods returning the generated strings to the `CsvStringWriter` class for API compatibility with the corresponding FixedLengthDataWriter methods
  - implemented support for SQLStatement as an iterator source for `AbstractCsvWriter::write()`
  - `quote_escape` option implemented in `AbstractCsvWriter`
  - implemented the `"datamap"` and `"info_log"` options for CSV generation
  - implemented alternative options with underscores instead of dashes for all constructors
  - extended multi-type support, record type rules and default value in field specification
  - implemented multi-type record support in `AbstractCsvWriter` and `AbstractCsvIterator` using `resolve_type` and `headers` options
- Mapper module updates:
  - implemented the `"constant"` field tag, allowing a constant value for an output field to be specified directly in the mapper hash
  - implemented the `"default"` field tag, giving a default value if no input value is specified
  - implemented the global `"date_format"` mapper option
  - implemented support for structured output fields with dot notation in the output field name
  - implemented per-field and global `"number_format"` mapper options
  - changed the behavior of the `"number"` field type: now leaves numeric values in their original type, converts all other types to a number
  - removed the deprecated `"crec"` option
  - implemented the `"input"` option with input record validation
  - implemented the `"output"` option with output record validation
  - implemented the `"info_log"` option and removed the `"trunc"` option
  - implemented the `"runtime"` field tag
  - implemented the `"index"` field tag
  - improved the Mapper::mapAll() method by adding support for hashes of lists to better support input from bulk DML (SQLStatement::fetchColumns())
- TableMapper module updates:
  - added table name and datasource description to error messages
  - implemented more efficient support for inserts from a sequence for databases supporting the `"returning"` clause in insert statements; now such inserts are made in a single round trip instead of n + 1 where n is the number of sequences in the insert
  - implemented an optimized insert approach assuming stable input data
  - implemented the following new options:
    - `unstable_input:` to accommodate unstable input data and disable the insert optimization (default: False)
    - `insert_block:` for DB drivers supporting bulk DML, the number of rows inserted at once (default: 500, only used when `unstable_input` is False) and bulk inserts are supported in the table object
  - added methods for bulk / batch inserts for db drivers supporting bulk DML (ex: Oracle)
  - updated to Mapper changes: use table description to define output record for the Mapper module
  - added the AbstractSqlStatementOutboundMapper class
  - added the InboundIdentityTableMapper class
  - added the SqlStatementMapperIterator class
  - added the SqlStatementOutboundMapper class
- RestClient module updates:
  - implemented RestClient::addDefaultHeaders()
  - implemented RestClient::getDefaultHeaders()
  - implemented RestClient::getSendEncoding()
  - implemented RestClient::setContentEncoding()
  - when possible, REST bodies are decoded and stored in the info output argument when the HTTP server returns a status code < 100 or >= 300 to allow for error-handling in the client
- RestHandler module updates:
  - implemented support for notifying persistent connections when the connection is terminated while a persistent connection is in place
  - the AbstractRestStreamRequestHandler class is now the base abstract class for REST stream request handlers
- WebUtil module updates:
  - updated FileHandler::handleRequest() to allow for chunked sends
- BulkSqlUtil module:
  - added this new module providing APIs supporting bulk DML with SqlUtil with supported drivers
- FilePoller module:
  - added this new module to support polling files in directories on the filesystem
- FixedLengthUtil module:
  - added this new module for handling fixed length line data
- HttpServer module updates:
  - HttpServerUtil module split from the HttpServer module containing supporting definitions for handler classes and other code interfacing with the HttpServer module
  - added the PermissiveAuthenticator class
  - translate `"+"` (plus) to `" "` (space) in the query portion of URIs in parse_uri_query()
  - implemented support for notifying persistent connections when the connection is terminated while a persistent connection is in place
  - new methods implemented in HttpServer:
    - HttpServer::getListenerLogOptions()
    - HttpServer::getListenerLogOptionsID()
    - HttpServer::setListenerLogOptions()
    - HttpServer::setListenerLogOptionsID()
    - HttpServer::addListeners() (new variant taking a hash of SSL info)
    - HttpServer::listenerStarted() (to allow for reporting when listeners are actually running since they are started asynchronously)
  - improved performance matching request URIs to handlers
  - added the `"ssl"` key to the listener socket info hash
  - implemented support for notifying persistent connections when the connection is terminated while a persistent connection is in place
  - removed the unused AbstractStreamRequestHandler class
  - fixed parse_uri_query() to always return params as a hash (issue 569)
  - added `root_path` to the context hash if the path was matched by a URL path prefix (issue 570)
  - implemented support for configurable stream handler timeout values (issue 719)
- Schema module updates:
  - added the following public functions to make column definitions easier:
    - c_char()
    - c_date()
    - c_int()
    - c_number()
    - c_timestamp()
    - c_varchar()
- added option HAVE_DETERMINISTIC_GC for Qore builds where deterministic garbage collection is enabled
- Program class enhancements:
  - the Program class now creates parse defines for parse options so that conditional code can be implemented depending on the sandboxing configuration of the program container
  - the Qore::Program::importClass() method now accepts an optional new_name argument to allow for importing classes with a different name and namespace path
- added a timeout parameter to the following Socket methods:
  - Qore::Socket::upgradeClientToSSL()
  - Qore::Socket::upgradeServerToSSL()
- added zoneinfo -> Windows time zone translation code on Windows to support standard UNIX (zoneinfo) time zone names on Windows; time zone information is still taken from the Windows registry but region names are reported using the standard zoneinfo names
- Qore::FileLineIterator updates:
  - added Qore::FileLineIterator::hstat() and Qore::FileLineIterator::stat()
- SqlUtil module updates:
  - implemented insert option support and support for the `"returning"` clause in supported drivers to avoid server round trips
  - implemented the AbstractTable::getDesc() method and improved exception description messages
  - implemented support for late table resoluton in join arguments to enable joins from serialized parameters
  - improved error messages for common errors such as join errors
  - implemented support for DBA management actions
  - implemented support for driver-dependent pseudocolumns
  - implemented per-column support for the `"desc"` keyword in orderby expressions
  - implemented the `"wop_or()"` function to allow complex SQL expressions to be generated with `"or"` as well as `"and"`
  - implemented the `"cop_cast()"` operator for converting [column] value into another datatype
  - implemented the `"cop_sum()"` aggregate operator for returning sum of column values
  - implemented update operators `"uop_plus()"`, `"uop_minus()"`, `"uop_multiply()"`, `"uop_divide()"`
  - implemented AbstractTable::getBulkUpsertClosure() to better support bulk SQL merge operations
  - removed all APIs that handle implicit transactions; APIs must commit transactions explicitly
  - orderby and groupby select options now take positive integers as column identifiers
  - column aliases (defined with cop_as()) can now be used in the where hash argument and in join criteria
  - column operator functions can be used in the where clause and in join conditions (issue 529)
  - implemented the `"cop_coalesce()"` column operation function to support the `"COALESCE"` operator in queries (issue 671)
  - implemented `cop_substr()` and `uop_substr()` operators (issue 801)
  - implemented `op_substr()` where operator (issue 883)
  - implemented the `"omit_update"` upsert option for asymmetrical upserts (updates only update a subset of the columns inserted) (issue 791)
  - implemented the `"UpsertUpdateOnly"` upsert option (issue 793)
- OracleSqlUtil module updates:
  - implemented support for views for DML in the OracleTable class
  - implemented support for Oracle pseudocolumns in queries
  - return lists from Oracle's data dictionary ordered
  - implemented AbstractTable::emptyStringsAsNull()
- PgsqlSqlUtil module updates:
  - added support for the following datatypes and aliases: `bool`, `float`, `int`, `timetz`, `timestamptz`, `varbit`
  - added support for listing PostgreSQL types and materialized views (issue 699)
- MysqlSqlUtil module updates:
  - added support for the following datatypes: `binary`, `varbinary`
- Util module updates:
  - added public function `glob_to_regex()`
  - added public functions `lpad()` and `rpad()`
  - added public function `ordinal()`
  - added public function `plural()`
  - added public function `regex_escape()`
  - added public function `zip()`
  - `parse_to_qore_value()` now respects parentheses when parsing lists and hashes (issue 846)
- added initial support for UTF-16 character encoding; note that UTF-16 is not backwards-compatible with ASCII and therefore not supported universally in Qore; it's recommended to convert these strings to UTF-8 in Qore; do not use UTF-16 as the default character encoding in Qore; currently UTF-16 data can be parsed using the following classes that convert the data to UTF-8:
  - Qore::DataLineIterator
  - Qore::FileLineIterator
- removed support for the C++ `QDBI_METHOD_ABORT_TRANSACTION_START` DBI method; transactions are always assumed to be in progress even if an exec call throws an exception in the first statement in a new transaction; this is necessary to handle bulk DML where a single statement can partially succeed and partially fail; the ABI remains unchanged; drivers that set this DBI method will no longer have it called because it's not necessary; in the upcoming API/ABI change this C++ DBI method will be removed entirely
- added support for unary plus
- added support for empty private blocks in classes
- added support for Qore::statvfs() on Windows (simulated from `GetDiskFreeSpaceEx()` issue 618)
- assignment of a variable to itself is now illegal (issue 526)
- extended qpp to support the 'final' class flag (issue 876)
- extended qpp to support private members (issue 924)
- added <float>::infp() and <float>::nanp() predicates to float (issue 909)

## Bug Fixes in Qore

- fixed format of octal constant - there was an error if a string contained octal constant that is shorter than 3 digit
- HttpServer module fixes:
  - fixed a bug setting the response encoding in HttpServer::setReplyHeaders() where the Socket encoding was not set properly and therefore the encoding in the Content-Type in the response header did not necessarily match the encoding of the response
  - fixed a socket / connection performance problem with HTTPS listeners where the SSL connection was being negotiated inline with the accept instead of in the connection thread, thereby blocking new connections from being accepted
  - fixed bugs where URI strings were improperly encoded and decoded (also fixed in the RestClient module)
  - fixed a bug in the HttpServer module where chunked sends were not received and decoded properly in all cases for handlers that did not explicitly handle chunked messages
  - fixed a bug in HttpServer::addListener() with an integer argument; a UNIX socket was opened instead of a wildcard listener on the given port
  - fixed typos causing bugs in HTTP error logging (issue 308)
  - fixed a bug formatting IPv6 host addresses in the return value to `HttpServer::http_get_url_from_bind()` (issue 821)
- RestClient module fixes:
  - fixed bugs where URI strings were improperly encoded and decoded (also fixed in the HttpServer module)
  - fixed a bug where URI paths were sent as relative paths instead of absolute paths
  - fixed issues where multiple leading `"/"` chars were sometimes present in the request URI path
  - fixed an issue where a trailing `"/"` char was sometimes added to the request URI path (issue 899)
- CsvUtil module fixes:
  - fixed a bug where the `"format"` field option was not usable with fields assigned type `"*date"`
  - fixed the default field type as "*string" (from "string") to avoid parsing and outputting empty strings for missing input data
- Schema module fixes:
  - AbstractSchema::combineOptions() fails when an option variable contains NOTHING instead of a valid hash
  - fixed a bug with "insert-only reference data" with the verbose option; the upsert strategy was changed to `UpsertSelectFirst` which means that insert-only reference data could also be updated
  - fixed a bug where it was not possible to provide Database options when creating schemas (issue 501)
- Mapper module fixes:
  - moved field length checks after all transformations have been applied
  - fixed bugs in the `"timezone"` and `"input_timezone"` options, documented those options
  - fixed a bug where `"constant"` field tags assigned to a value that evaluated to boolean False were not recognized (issue 610)
- SqlUtil module fixes:
  - fixed a bug with queries using a desc argument with the orderby query option with multiple sort columns; the `"desc"` string was added only to the last column but should have been added to all columns
  - fixed a bug where foreign key constraints with supporting indexes were not tracked and therefore schema alignment on DBs that automatically create indexes for foreign key constraints would fail
  - fixed a bug where driver-specific objects were not included when dropping a schema
  - fixed a bug in subquery handling where bind-by-value arguments from the subquery were lost
  - fixed a bug in the partition by/over operator where column names as given in the query argument hash were not properly recognized
  - fixed a bug in schema alignment; when aligning a schema and an index supporting a PK constraint is introduced in the new schema, the alignment would fail when a constraint is attempted to be disabled that doesn't exist
  - fixed a bug generating select statements for tables accessed through a synonym when used with join clauses; previously inconsistent schema prefixes could be used which could cause errors parsing the SQL statements generated
  - fixed a bug where the AbstractTable lock was held while executing SQL to determine the upsert strategy to use with UpsertAuto
  - fixed a bug where complex bind values as hashes (such as used by the pgsql and oracle drivers) were rejected by SqlUtil (issue 494) when updating
  - fixed a bug where wildcard columns in join tables were not working (issue 499)
  - fixed a bug in `"op_in()"` where invalid SQL was generated with an argument of 0 (issue 500)
  - fixed bugs in `cop_seq()` and `cop_seq_currval()` (issue 624)
  - fixed a bug in `join_inner()` where the cond argument was ignored (issue 645)
  - fixed `"uop_lower()"` and `"uop_upper()"` operators to allow nesting (issue 657)
  - fixed a bug where SqlUtil was generating invalid SQL for some DBs where a wilcard was used with explicit column names (issue 708)
  - fixed a bug where updating an index without any source constraints caused an invalid exception to be raised (issue 768)
  - fixed a bug in `AbstractTable::update()` with sequence operators (issue 942)
- OracleSqlUtil module fixes:
  - fixed a bug where column names that are reserved words were not quoted in generated SQL
  - fixed bugs in `cop_seq()` and `cop_seq_currval()` (issue 624)
- PgsqlSqlUtil module fixes:
  - fixed a bug in PgsqlTable::tryInsertImpl(); added an explicit `"begin"` call to make the savepoint work with PostgreSQL 9.3+ servers
  - fixed a bug retrieving foreign constraints; columns were not guaranteed to be returned in declaration order
  - fixed a bug handling tablespaces in unique constraints
  - fixed a bug handling `"time"` columns; they were being issued as `"time6"` instead of "time(6)" (issue 385)
  - fixed support for the following datatypes and aliases: `"bit"`, `"bit varying"`, `"char"`, `"character"`, `"character varying"`, `"char varying"`, `"oid"`, `"varchar"`
  - fixed bugs in `cop_seq()` and `cop_seq_currval()` (issue 624)
- MysqlSqlUtil module fixes:
  - corrected support for the `varbinary` type (issue 403)
  - corrected support for the `binary` type (issue 524)
  - `schema` member incorrectly set by AbstractDatasource::getUserName() instead of AbstractDatasource::getDBName() (issue 519)
- WebUtil module fixes:
  - fixed a bug where template programs with Qore::PO_ALLOW_BARE_REFS set did not work
  - fixed a bug serviing index files in `FileHandler::tryServeRequest()` where index files could be incorrectly served with a `"204 No Content"` response (issue 616)
- WebSocketHandler module fixes:
  - fixed a bug where the connection object was deleted when the connection closes which could cause excess exceptions in multithreaded server code
  - added the WebSocketConnection::connectionClosed() method to be called when the connection is closed
- WebSocketClient module updates:
  - updated module to version 1.3
  - ignore `SOCKET-NOT-OPEN` errors when closing (server already closed the connection)
- RestHandler module fixes:
  - fold all possible arguments in the REST request body into the argument hash so that complex REST requests can be made with clear URI strings
  - fixed a bug where an error calling an internal nonexistent method would be reported with an incorrect error message
  - send errors are now reported in the `AbstractRestStreamRequestHandler` object so they can be properly logged (issue 734)
  - unknown REST class errors with the base class are now reported consistently like all other such errors (issue 859)
  - fixed an issue where request URI paths with multiple consecutive `"/"` chars were handled incorrectly (issue 900)
- Util module fixes:
  - fixed `normalize_dir_windows()` handling of UNC paths (issue 813)
- fixed a memory error in error-handling with type errors when parsing user module headers that could cause a crash
- fixed a memory leak in Socket::setWarningQueue(): when a callback argument is used, the argument can be leaked when the Socket is destroyed
- fixed a bug where the HTTPClient class did not send the X.509 certificate and private key when making a client SSL connection
- fixed a bug in the ThreadPool class where an error in shutdown handling could cause a crash in rare conditions when ThreadPool methods are called while the pool is shutting down
- fixed a crashing bug initializing some lvalues with type restrictions; affected static class variables at least
- fixed a bug where a class calling an overridden method in a base class constructor that referred to a member that should have been initialized in the subclass would be executed before the subclass's members were initialized causing the method call to fail
- fixed a memory leak in classes with multiple inheritance and base classes that are inherited multiple times with member initialization
- fixed a bug in the %include and %append-module-path parse directives where relative paths were not calculated from the script's directory but instead were calculated from the current working directory, causing such paths to fail
- fixed a bug in Qore::get_qore_library_info() that could cause a crash due to treating the Build attribute as a string when it was an integer
- fixed a bug in the divide-equals (/=) operator where an exception was not thrown when an operand of zero with arbitrary-precision numeric arguments is used
- fixed a bug where the connection mode would be reset for every connection in the Qore::FtpClient class
- fixed a bug in the Qore::FtpClient class where connection problems in the data channel when executing certain FTP commands could cause a crash due to missing error checking
- fixed a bug in Qore's internal strcasestr() function on platforms that do not support this function (ex: Solaris) that could result in a crash
- fixed a bug in Qore where string data formatted with `%n`, `%N`, or `%y` could be added to another string with a different character encoding without any automatic conversions, therefore resulting in an improperly-encoded string
- fixed a crash when parsing when parsing function, method, or closure arguments when either of the duplicate-local-vars or duplicate-block-vars warnings are set due to an error handling thread-local variable info in parse initialization
- fixed a bug where code with mixed coding styles (old and new) could result in invalid parse errors when parsing base class constructor calls to a base class defined in another coding style
- fixed a bug where an HTTP response with an unknown `Content-Encoding` header would cause a crash
- fixed a memory error with receiving HTTP chunked data with receive callbacks where the buffer object was reset with reference counts > 1
- fixed a bug in the FtpClient class where socket errors would not cause the connection to be closed automatically and therefore further use of the object required a manual disconnect even though the object supports transparent auto-reconnection
- fixed a bug where conversions from float to number would introduce inaccuracy in the arbitrary-precision number; ex: `737.38.toNumber() -> 737.3799999999999954525264911353588104248`
- fixed a bug where %requires would fail loading a user module inside a %try-module block
- fixed a bug in Qore::Program::importClass() where the import would fail if a namespace-justified class name was given and any element of the namespace path didn't already exist in the target whereas the same import would succeed if the namespace were omitted in the call
- fixed bugs in Qore::Program::importClass(), Qore::Program::importFunction(), and Qore::Program::importGlobalVariable() when namespace-justified arguments were given, in this case when namespaces were created in the target, the internal root namespace index was not updated so the imported objects could not be found with namespace-justified references until the root indexes were updated
- fixed a bug in the %requires directive where relative paths were not calculated from the script's directory but rather from the current working directory
- fixed various bugs in path handling on Windows in the following areas:
  - Qore::basename()
  - Qore::get_script_dir()
  - Qore::get_script_path()
  - Qore::get_script_name()
  - Qore::Dir
  - module importing and include file handling
- fixed a bug in parsing constant value assignment expressions where such expressions could use or instantiate classes with uncommitted changes and therefore a crash could result
- fixed a bug in user module initialization and destruction where call references were not accepted, contrary to the documentation and design goals
- fixed a bug in Qore::Socket::acceptSSL() and Qore::Socket::connectSSL() where the timeout argument was not respected for SSL protocol negotation by implementing non-blocking I/O support for the internal SSL calls for upgrading the socket connection
- fixed a memory leak in exception handling in the Qore::FtpClient::put() method (thanks to nros)
- fixed a memory error in string handling in the Qore::FtpClient class's FTP response handling code
- fixed a bug in aligning table data in the sqlutil example program
- fixed a bug when loading modules by a path argument; if the module is already loaded, then do not throw an exception
- adjusted the stack guard buffer for x86_64 from 20K -> 32K which solved some rare crashes related to stack exhaustion (ex: make check works consistently now on x86_64 Linux)
- fixed a bug handling HTTP send callbacks that returned zero-length strings and binary objects which would cause invalid chunked data to be sent violating the HTTP protocol
- fixed a bug in the DatasourcePool::getServerVersion() method where the connection to the server was not guaranteed to be in place before the call, in case of connection errors in the pool a crash could result
- fixed a crash in Qore::FileLineIterator::copy() when no eol attribute is set
- fixed a bug importing invalid user modules with no module declaration
- fixed bugs in Qore::Socket::accept() and Qore::Socket::acceptSSL() where the SSL configuration was not copied to the new Qore::Socket
- fixed some object encapsulation violation bugs where access to methods of a privately-inherited class was allowed from a subclass in certain situations
- fixed inconsistent object encapsulation enforcement with method references; if a reference to a method is created inside the class, then when executed the call inherits the access rights at the time of creation
- fixed inconsistent thread gating for code data structures in Program containers that could have theoretically lead to crashes in Program containers that parse code while threads are running
- fixed a bug in Qore::Program::importFunction() with function names with a namespace path
- fixed a bug in closure calls when a closure is called from within a closure and referes to closure-bound locally variables in the internal closure call which would previously result in a crash
- fixed a parse-time memory leak in call reference calls when the callable object is resolved from a class constant
- fixed a bug in maintaining the conditional compilation status when parsing %include directives and %requires directives with user modules
- fixed an obscure bug when a thread terminates in a Program object after the Program container itself has already been deleted where the termination would hang while waiting for the Program's thread count to reach zero while the last thread doing the waiting also held the last thread reference
- fixed a bug where incompatible class definitions were not verified at parse time which could cause a crash in debug builds and unpredictable behavior in non-debug builds
- fixed a race condition in finalizing thread-local data in Program objects during Program destruction that could lead to a runtime crash
- fixed a crash when user modules have recursive dependencies
- fixed a bug with %push-parse-options when used multiple times in the same file; now multiple appearances of this parse directive are ignored
- fixed a bug initializing static class variables in the parse commit phase where a crash could result due to an error in managing parse commit dependencies
- fixed Qore::is_writable():
  - on Windows when used with a directory
  - on UNIX to return a value for the current permissions the program is running under
- fixed a bug in Qore::regex_extract() and in the Regular Expression Pattern Extraction Operator where the result buffer was not resized when it was too small, limiting regular expressions to nine subpatterns; the maximum has been raised to between 90 and 100 before an exception is raised (since the subpattern buffer is allocated on the stack, we need to enforce a limit)
- fixed a bug with the cast<>() operator where compatible classes were not recognized at runtime that would otherwise be recognized correctly without the cast
- fixed the return type in Qore::getcwd() to *string
- fixed a bug in the return statement where the runtime return type was used at parse time which did not work when parsing embedded code
- fixed a bug validating return values in method evaluation that could lead to a qore crash
- fixed a bug in the %requires directive when applied to builtin features where code to manage user module dependencies was inappropriately applied
- fixed a bug nesting 3 levels or more of parse conditionals (%ifdef and %ifndef) where the conditional parse state could be lost (and an assertion was made in debug mode)
- fixed a bug where ==, >, and < operators applied type precedence incorrectly when applying optimizations at parse time in relation to arbitrary-precision numeric values
- fixed a static memory leak in the parser handling out of line method declarations
- fixed a bug in handling socket disconnection errors in SSL operations where the SSL helper object was deleted and then used causing a crash
- fixed a bug where "Deprecated" Functions and return-value-ignored warnings were reported at the incorrect source location
- fixed a bug in Qore::set_thread_init() where thread initialization did not occur when foreign threads attached to a Qore::Program object with thread initialization set
- fixed a bug in call references and objects by replacing string references to the containing Program object with weak references which solved a recursive reference / memory leak issue
- fixed a memory leak when a thread init call reference was used with Qore::Program objects
- fixed bugs in Qore SSL socket handling when the remote connection is disconnected while performing an SSL upgrade (client or server) that could cause a crash
- fixed a bug where the sending an invalid HTTP header to the Qore::Socket::sendHTTPResponse() method could cause a crash
- fixed bugs in system():
  - the shell was not being used to execute commands with commands where shell meta-characters were not found with a manual search which caused such commands to fail; additionally `&` (ampersand) characters were not recognized as shell meta-characters
  - fixed problems with signal handling in child processes on UNIXes: system() now always performs a `fork(2)`, enables all signals, and calls `execl("/bin/sh", "sh", "-c",` command`, 0)` in the child process (on UNIX systems; on Windows, system(3) is used directly as before)
- fixed a race condition in the DatasourcePool class when opening new datasources after a connection error in the first datasource which could cause a crash. Now the first datasource is no longer a "special" datasource used for configuration information; configuration information is contained in a separate object which serves as an internal Datasource factory
- fixed a problem where `SIGCHLD` was blocked by default which caused deadlocks when spawning child processes that in turn waited on grandchild processes - now Qore no longer blocks `SIGCHLD` on UNIX platforms
- fixed a bug in BinaryNode::clear() where the internal pointer was freed but not set to 0 leading to a subsequent crash when the object is destroyed; affected HTTPClient chunked reads of binary data when used with a callback
- fixed a bug where the runtime exception location could be reported in the wrong location
- fixed a bug where the bzip2 library can request a buffer size that could not be handled by the bzip2 library which is not handled by qore and causes a crash while decompressing certain input
- fixed a bug handling closure-bound local variables when closures are created in the background operator expression that caused a core dump
- fixed the precedence of the assignment operator (=); now the precedence of this operator is the same as the other assignment operators (+=, -=, *=, and /=, etc); this does not break any code, but does align Qore with other programming languages (such as C, among others) and allows for expressions such as
  a = b += 2
  to be correctly parsed
- fixed a parse-time bug in the trim operator where the operator's return type was incorrectly returned as int instead of the type of the lvalue
- fixed a bug initializing object members with a closure that refers to self
- fixed bugs in the documentation and return types of:
  - Qore::ReadOnlyFile::readBinaryFile()
  - Qore::ReadOnlyFile::readTextFile()
- fixed a bug in Qore::GetOpt::parse(softlist), Qore::GetOpt::parse2(softlist), and Qore::GetOpt::parse3(softlist) where call-by-value and copy-on-write semantics were not enforced and a shared list argument could be modified
- fixed a bug in zoneinfo file parsing where invalid bands with no UTC offset changes against the previous band could cause invalid date/time values to be displayed by Qore for dates on the invalid transition
- fixed a bug where imported global variables (Qore::Program::importGlobalVariable()) were added to the pending global variable list and therefore were removed if a parse exception occurred, hwoever the namespace indexes remained, which could lead to unexpected problems at runtime including a crash. Additionally the pending global variable list was not checked which could lead to a memory leak if the a single global variable name is pending, imported, and then committed to the Program object.
- fixed memory errors managing program feature lists in the CharPtrList class by copying string memory instead of using sometimes temporary values in the list
- fixed minor bugs with directive parsing, mostly related to error reporting
- fixed bugs in relative date arithmetic where operands were swapped with the - operator if the first operand was a relative date/time value, additionally an operation with the - operator where the first operand is a relative date and the second operand is a absolute date is now calculated using the absolute date's epoch offset (offset in seconds and microseconds from `1970-01-01Z`), and a relative date/time value is produced
- fixed a bug normalizing the result of date arithmetic between hour and minute components of relative date/time value
- fixed a bug where time components of absolute date/time values before the UNIX epoch were returned with invalid values
- fixed a bug where the %exec-class directive did not check for classes with unimplemented abstract variants
- fixed a bug where the push and unshift operators applied to a variable declared as softlist did not use the default value
- fixed a bug where calls to Qore::HTTPClient::setConnectTimeout() had no effect (issue 323)
- fixed several bugs with logical comparison operators and arbitrary-precision numeric values (issue 330)
- fixed a bug where Qore::HashListIterator (and therefore <hash>::contextIterator()) would not iterate a simple hash with non-list values once but would instead silently ignore the hash (issue 336)
- fixed a bug where a warning was not always issued when square brackets were used on unsuitable types (issue 184), internally ported the square bracket operator to the C++ QoreOperatorNode hierarchy
- fixed a bug handling return type information for method and pseudo-method calls; uninitialized memory could be used which could cause a runtime crash (issue 364)
- corrected the name of the modulo operator (was incorrectly referred to as the "modula" operator earlier: issue 389)
- fixed a bug handling identifiers in parentheses used to dereference hashes or objects; the identifer is not resolved properly whereas previoulsy it was incorrectly interpreted as a string literal (issue 416)
- fixed a bug with handling local variables in const initializers (issue 421)
- fixed a bug where `select(2)` was called after `EINTR` without reinitializing the descriptor array argument (issue 435)
- fixed a crashing bug on all platforms where select(2) was being called with socket descriptor values > `FD_SETSIZE` (issue 436)
- fixed inconsistencies comparing relative date/time values (issue 437)
- fixed a bug where on_exit Statements and on_error Statements statements were not being executed if an exception was raised in an earlier-executed on_exit Statements, on_error Statements, or on_success Statements statement (issue 380)
- fixed a bug where Qore::HTTPClient::get() and Qore::HTTPClient::post() would try to retrieve a message body even if `Content-Length: 0` was returned (or if no `Content-Length` header was returned at all) which would result in a deadlock until the server would close the connection (issue 434)
- fixed a bug where regular expression substitution would go into an infinite loop when used with an empty pattern and the global flag (Qore::RE_Global, issue 329)
- fixed a bug with connection handling in the SQLStatement class; an exception is now thrown if a SQLStatement object tries to execute its prepared SQL on a connection other than the original connection used to prepare the statement (issue 465)
- fixed a bug where Qore::is_executable() would return NOTHING instead of False (as per documentation) when called with non-existent path as it's parameter (issue 470)
- fixed precedence of logical and bitwise Operators (issue 481)
- fixed a bug where nested lists were not parsed correctly in some cases (issue 320)
- fixed a bug where the type of catch parameter was ignored (issue 28)
- fixed a bug where namespace hierarchies were not indexed during parse time when added to already-committed namespaces which lead to symbol resolution errors for valid code (issue 538)
- fixed a bug where a Socket operation attempted in another thread while a callback operation on the same socket was in progress would result in a confusing error message (issue 530)
- fixed a bug where local variable declarations in class member initialization expressions caused a crash (issue 574)
- fixed a bug where HTTP data in HTTP socket events was modified even though it was shared which caused data consistency problems and crashes in the worst case (issue 576)
- fixed a bug where the `+=` operator handled NOTHING values incorrectly (issue 582)
- fixed a bug where a non-numeric define specified on the command line could cause a crash (issue 583)
- fixed a bug where the Qore::SQL::SQLStatement::describe() method would not grab the transation lock even when statements were implicitly executed (issue 591)
- fixed the order of initialization of class members (issue 42)
- fixed a bug in Qore::TimeZone::date(string) where the date returned was in the current contextual time zone and not that of the object (issue 584)
- fixed a bug parsing windows paths in URLs with Qore::parse_url() (issue 618)
- fixed a bug in Qore::TimeZone::constructor(string) on Windows when used with an absolute path (issue 626)
- fixed an I/O-handling bug in the Qore::ReadOnlyFile and Qore::File classes where I/O errors in read operations were silently ignored (issue 627)
- fixed bugs in Qore::ReadOnlyFile::readTextFile() and Qore::ReadOnlyFile::readBinaryFile() would return NOTHING instead of an empty object when reading empty files; now empty objects are returned in these cases (issue 508)
- fixed a bug in *printf() outputs on Windows with scientific notation with floating-point values (issue 621)
- fixed a bug where the precision of numbers during arithmetic operations was not adjusted correctly (issue 630, issue 908)
- fixed a bug where the type of subtraction of two numbers was inferred as NOTHING during parsing (issue 636)
- fixed a bug on Windows with Qore::Dir::create() (issue 643)
- fixed a bug where CRLF line endings were not handled correctly by the exec-class parse directive (issue 653)
- fixed a bug on Windows where Qore::glob() would return paths beginning with `"."` by default (issue 660)
- fixed a bug on Windows where Qore::glob() would fail on `"\*"` or `"/*"` (issue 664)
- fixed a bug on Windows where Qore::glob() would not return paths in sorted order by default (issue 665)
- fixed a bug on Windows where the Qore::Dir class would incorrectly normalize UNC paths by stripping the leading backslash (issue 666)
- fixed a bug where the int type restriction would accept any data type at runtime instead of throwing a `RUNTIME-TYPE-ERROR` exception (issue 683)
- fixed bugs reporting the current method context with certain HTTPClient methods that would report the Socket class instead (issue 689)
- fixed a bug handling aborted HTTP chunked transfers; now any data available for reading on a socket when a chunked transfer is aborted is read instead of having a `SOCKET-SEND-ERROR` thrown when the remote end closes the socket during the transfer (issue 691)
- fixed a bug with socket handling where SSL send failures did not cause an exception to be thrown in all cases (issue 732)
- fixed a bug on Windows where Qore::glob() returned files matched without the leading path component (issue 761)
- fixed a bug with socket connection refused handling on Windows where connections were waiting until the timeout instead of returning an error immediately (issue 763)
- fixed a bug where it was not possible to escape an escape character before a `'$'` character in a regular expression substitution target string (issue 777)
- fixed a bug where object member references were treated as expressions returning a constant value which could cause a crash when used in an expression used to initialize a constant value at parse time (issue 817)
- fixed a bug parsing IPv6 localhost (`"::"`) with Qore::parse_url() (issue 822)
- fixed a bug in Windows timezone handling caused by erroneous region names (issue 824)
- fixed an internal memory-handling bug that caused a crash when cleaning up the qore library on FreeBSD with clang++ and possibly other platforms (issue 839)
- fixed a bug where `CALL-WITH-TYPE-ERROR` exceptions were thrown based on the parse options in the caller instead of in the target when calling across a Program barrier (issue 841)
- fixed a bug where Qore::is_writable() and Qore::is_readable() could return an incorrect value in some cases (issue 852)
- fixed a bug where Qore::format_number() would return an invalid string when the number of decimals to be returned was 0 (issue 851)
- fixed a bug where the delete and remove operators would incorrectly create hash keys when attempting to delete inside complex hash structures with non-existent keys (issue 855)
- fixed a bug where duplicate global variable declarations caused a crash (issue 891)
- fixed a memory leak in DatasourcePool initialization when the minimum connections cannot be established (issue 994)
- fixed handling of NaN values in logical operators (issue 915)
- fixed sort_descending_stable so that it keeps (instead of reversing) the original order of items that compare equal (issue 940)
- fixed a bug in `copy()` method argument parsing; compatible type declarations were not accepted (issue 946)

# Qore 0.8.11

Release Summary
  Minor bugfix release for UNIX, major bugfixes for Windows

## New Features in Qore

- added the Qore::AFMap and Qore::AFStrMap constants
- WebUtil updates:
  - added logic to the default file serving code to determine if the file is a binary or text file from the MIME type
- HTTPClient::sendWithSendCallback() and HTTPClient::sendWithSendCallback() updated such that if a response is received while the chunked send operation is still in progress, an error is assumed, the send operation is aborted, and the response header is read immediately

## Bug Fixes in Qore

- Windows fixes:
  - fixed TimeZone copying to use the standard name instead of the display name so that the info can be found in the registry
  - Util module fixes:
    - fixed get_random_string() on Windows
    - fixed absolute_path_windows()
  - HttpServer module fixes:
    - when binding a wildcard address with AF_UNSPEC on Windows with HttpServer::addListeners() and both IPv6 and IPv4 addresses are returned, bind both addresses since Windows doesn't direct the IPv4 requests to the wildcard-bound IPv6 listener
  - fixed file reading by always opening in binary mode
  - added support for the WSAECONNABORTED socket error
  - replaced Mime::MultiPartMessage::getRandomString() with Util::get_random_string() to make it work on Windows
- fixed a bug in the DBI layer where calling SQLStatement::describe() would crash when called with an older module that did not implement this method
- other fixes in the Util module (in addition to the Windows-specific fixes above):
  - fixed parse_to_qore_value() with hashes with a comma in the first key name
  - read from /dev/urandom instead of /dev/random since reads from the latter can block for long periods to fill the entropy pool
- do not start signal thread after a fork() if signal handling is enabled, pthread_create() is not async-signal safe (on FreeBSD at least this reliably causes segfaults)

# Qore 0.8.10

Release Summary
  Major release with many many bugfixes and new features such as much improved HTTP and REST support (ex: chunked transfer support + new client and server classes for REST support for chunked transfers and data streaming), improved DB support (ex: new Schema module, SqlUtil improvements), and much more.

## New Features in Qore

- better HTTP support; support for chunked sends and receives for streaming data over HTTP and other improvements:
  - HTTPClient::sendWithSendCallback()
  - HTTPClient::sendWithRecvCallback()
  - HTTPClient::sendWithCallbacks()
  - HTTPClient::setPersistent()
  - Socket::readHTTPChunkedBodyBinaryWithCallback()
  - Socket::readHTTPChunkedBodyWithCallback()
  - Socket::sendHTTPMessageWithCallback()
  - Socket::sendHTTPResponseWithCallback()
  - Socket::pendingHttpChunkedBody()
- added a minimum body size threshold for compression to HttpServer
- RestClient module updates:
  - configurable content encoding for send request message bodies is now supported (ie optional compression)
- new user modules:
  - Schema: for DB-independent schema management
- new public C++ socket performance instrumentation API
- new functions:
  - Qore::close_all_fd()
- new constants:
  - ESRCH: search error
- getModuleHash() and getModuleList() no longer return the `"filename"` key when run in a Program context with Qore::PO_NO_EXTERNAL_INFO set
- SqlUtil updates:
  - added insert operator support; for example, for inserting with values from sequences
  - added new upsert constant maps
  - added static SqlUtil::AbstractSqlUtilBase::getDatasourceDesc() method
  - added new Table::insertFromSelect*() variants taking Table arguments
  - added SqlUtil::Table::checkExistence() method
  - added support for the `"forupdate"` select option
- OracleSqlUtil updates:
  - fixed selects with "limit" but no "offset"
  - convert date/time values to timestamps with microseconds resolution instead of dates with second resolution when dynamically inserting values as strings in SQL (binding by value not affected)
- CsvUtil module updates:
  - added the `"write-headers"` option to `AbstractCsvWriter` and subclasses to enable headers to be suppressed
  - added the `"optimal-quotes"` option to `AbstractCsvWriter` and subclasses to enable more efficient csv output (now the default)
- added AbstractDatasource::currentThreadInTransaction() which is reimplemented as Datasource::currentThreadInTransaction() and DatasourcePool::currentThreadInTransaction(); the base class method throws an exception when called; it was not added as an abstract method in order to not break existing subclasses of AbstractDatasource
- enhanced module license support
  - module license strings may now be specified in binary and user modules
  - Qore::getModuleHash() and Qore::getModuleList() now report license information for each module

## Bug Fixes in Qore

- fixed an issue with class constant parse initialization where invalid recursive class constant definition parse exceptions could be raised and in some cases also crashes could result
- SmtpClient module: fixed missing username and missing password errors
- fixed a bug where a qore switch statement with no case conditions and only a default label would erroneously never have it's default code executed
- fixed a reference leak related to exception handling with invalid arguments with Qore::Socket::setWarningQueue() and Qore::HTTPClient::setWarningQueue()
- fixed several bugs where the parse location could be reported incorrectly for type errors regarding in-object variable references
- fixed a bug where an error could result with Condition::wait() with timeouts > 2147483648ms
- fixed bugs handling "bigint" and "double precision" column types with schema alignments with the PgsqlSqlUtil module
- fixed a bug handling parse initialization of constant values requiring run-time evaluation after other parse exceptions have been raised that could cause a parse-time crash
- fixed a bug where qore could crash on exit with certain openssl versions by calling ERR_remove_state(0) in the main thread's cleanup function
- fixed a bug where qore could crash on exit due to user module destruction not taking into consideration user module dependencies
- fixed a bug in schema management in SqlUtil where excessively verbose column aliases were used that caused errors when automatically updating columns with existing rows and new default values and non-null contraints with PostgreSQL databases
- fixed a bug where a call reference to an abstract object method returned from an abstract class could be executed even though it must have been instantiated by a concrete subclass
- fixed a bug where a valid call reference to a private object method was created within the class, then in some cases an object protection exception was raised when the call reference was called outside the class
- fixed a bug in the RestClient module when the yaml binary module is not available
- fixed programmatic select queries with "limit" but no "offset" in OracleSqlUtil
- fixed a bug in Qore::Program::importFunction() where only the committed function list was checked when importing functions with a specific target namespace path
- fixed a bug in Qore::Program::importClass() where only the committed class list was checked when importing functions with a specific target namespace path
- fixed a bug when parsing subnamespaces into a parent namespace where the subnamespace already exists (either in the committed list or in the pending list)
- fixed a memory and reference leak caused by recursive references when closures encapsulating an object's scope are assigned to or accessible from members of the object by making references to the object from within a closure encapsulating the object's state weak references instead of strong references
- fixed schema information classes when the "string-numbers" driver option is enabled
- fixed crashing bugs in Qore::get_thread_data() in certain use cases
- fixed a bug in SqlUtil where select and row iterator operations could fail with certain select hash arguments without a `"columns"` entry but where column names were otherwise required
- fixed a bug in HTTP response parsing where case-signficant comparisons where being made with certain critical header values
- fixed a bug handling thread cancellation with the ThreadPool class
- fixed several race conditions and potential deadlocks in ThreadPool destruction with active threads in the pool

# Qore 0.8.9

Release Summary
  Major release with many new features and also many bugfixes.

## New Features in Qore

- CsvUtil module updates:
  - new classes:
    - `CsvAbstractIterator:` base abstract iterator class for iterating line-based CSV data
    - `CsvDataIterator:` iterator class allowing for CSV string data to be processed line by line on a record basis
    - `AbstractCsvWriter:` a base class for new CSV writer implementations
    - `CsvFileWriter:` CSV file writer class
    - `CsvStringWriter:` CSV in memory writer class
  - implemented support for allowing subclasses of CsvFileIterator to implement support for other custom types
  - no need to set `"headers"` in the constructor if `"fields"` are set; headers are assumed to be the field labels in the same order
- added the Qore::encode_url() function with RFC 3986 section 2.1 compliance
- Qore::decode_url() function updated to decode UTF-8 encoded characters according to RFC 3986 section 2.1
- added get_byte_size() and get_marketing_byte_size() to the Util module
- the error message now includes the module path used for the search when a module cannot be found in the module path
- DatasourcePool enhancements:
  - new method: DatasourcePool::clearWarningCallback()
  - new method: DatasourcePool::setWarningCallback()
  - new method: DatasourcePool::getUsageInfo()
  - new method: DatasourcePool::setErrorTimeout()
  - new method: DatasourcePool::getErrorTimeout()
  - new method: DatasourcePool::setEventQueue()
  - new method: DatasourcePool::clearEventQueue()
  - the new methods allow for monitoring DatasourcePool objects for pool contention issues (in case the pool needs to be resized), for throwing an exception if a connection is not acquired within the error timeout period (new default: 2 minutes), and for DBI drivers to raise warnings on an event queue that can be monitored in a separate thread
  - additionally connection acquisition statistics are tracked and returned in DatasourcePool::getUsageInfo() (total requests, hits, maximum wait time)
- Datasource enhancements:
  - new method: Datasource::setEventQueue()
  - new method: Datasource::clearEventQueue()
  - the new methods allow for DBI drivers to raise warnings on an event queue that can be monitored in a separate thread
- Socket enhancements:
  - new method: Socket::setWarningQueue()
  - new method: Socket::clearWarningQueue()
  - new method: Socket::getUsageInfo()
  - new method: Socket::clearStats()
- FtpClient enhancements:
  - new method: FtpClient::setWarningQueue()
  - new method: FtpClient::clearWarningQueue()
  - new method: FtpClient::getUsageInfo()
  - new method: FtpClient::clearStats()
- SmtpClient module updates:
  - optimized connection and login code; HELO/EHLO and authorization are performed when connecting only, not before each email
  - added support for socket performance instrumentation and warning events
- Pop3Client module updates:
  - added support for socket performance instrumentation and warning events
- TelnetClient module updates:
  - added support for socket performance instrumentation and warning events
- WebSocketClient module updates:
  - added support for socket performance instrumentation and warning events
- RestClient module updates:
  - use the new Qore::encode_url() function to encode URL paths to ensure that valid requests are sent when spaces, percent characters, and non-ascii characters are used in the URL path
  - set the character encoding in the `Content-Type` request header when sending strings
  - set the `Accept` header correctly in requests (previously only indicated yaml (`"text/x-yaml"`) as an acceptible response encoding)
- RestHandler module updates:
  - added support for the `OPTIONS` method
  - return a 400 `"Bad Request"` error if an unsupported HTTP method is used in a REST Call
- added new `UpsertInsertOnly` upsert strategy to SqlUtil
- new pseudo-methods:
  - <value>::sizep(): returns True if the type can return a non-zero size (True for containers including binary objects and strings, False for everything else)
  - <string>::getLine(): finds lines in a string buffer
- Mime module updates:
  - added mime type for WSDL files (`"application/wsdl+xml"`)
  - added mappings for `"xls"` and `"xlst"` extensions to MimeTypeXml
- added new modules:
  - Mapper: data mapping module
  - TableMapper: data mapping module using SqlUtil and Mapper to map to an SQL table target
  - FreetdsSqlUtil: provides back-end support for MS SQL Server and Sybase databases with SqlUtil using the freetds module
- the %include parse directive now supports environment variable substitution at the beginning of the file path

## Bug Fixes in Qore

- fixed a crashing bug when HTTP messages with duplicate `Connection`, `Content-Encoding`, `Transfer-Encoding`, `Location`, or `Content-Type` headers is received
- fixed a bug parsing octal character constants in the lexer when octal digits followed the octal constant (ex: `"\0441"` where the `"1"` would cause an error)
- allow escaping "$" character in regular expression substitution target strings, previously it was impossible to output a literal "$" + a digit, since this would be interpreted as a numbered input pattern expression
- fixed a bug in the HTTPClient::getURL() and HTTPClient::getProxyURL() methods where the URL's path was not given with a leading "/" character
- CsvUtil module fixes:
  - fixed `"date"` field handling with empty input (now maps to 1970-01-01)
  - fixed CsvDataIterator::next() when header_lines > 0 and working with empty input data
- added support for compiling on OSX Mavericks
- fixed an infinitely recursive call in Table::del() in SqlUtil
- fixed a bug in v*printf() where `'%'` was not handled correctly in all cases
- fixed bugs in microseconds and milliseconds() with large arguments
- fixed a bug where a call to a call reference to a static method across a program boundary with local variables as arguments would cause a crash due to improper setting of the program context before the arguments are evaluated
- fixed a bug in Datasource::copy() method where implicitly-set options were not carried over into the new object
- fixed a bug in the DatasourcePool class where implicitly-opened connections would not be guaranteed to have the same server time zone setting as the initial connections (for example, could cause problems with server timezone settings if running in a program context with a different local time zone attribute)
- fixed bugs in SqlUtil generating "create table" and "align table" SQL with DBs where unique indexes automatically create unique constraints (ex: MySQL)
- fixed a bug in lchown() where chown() was used interally instead of lchown()
- fixed a bug in PgsqlSqlUtil retrieving sequence values with Database::getNextSequenceValue()
- fixed an off-by-one memory bug in Qore::date(string, string) parsing a 4-digit date mask
- fixed memory leaks in class member and class static variable management
- fixed memory leaks when an entire class has to be rolled back due to parse errors and the class has pending static variables
- fixed memory leaks in constant handling with values containing call references
- fixed a memory leak in constant destruction with parse rollbacks when the constant value was NULL
- fixed an error in the rounding heuristic for arbitrary-precision numeric values that could produce invalid results (ex: 34.9n * 100 = 34902n)
- enforce PO_NO_FILESYSTEM with the %include directive
- fixed a bug managing object private data in complex inheritance cases where the same class may be inherited with virtual private data and also real private data
- fixed a bug in socket timeout handling with select() errors
- fixed a memory leak in handling abstract methods when multiple abstract methods with the same name but different signatures were declared in a class

# Qore 0.8.8

Release Summary
  Major new features and bug fixes with a particular focus on enhanced HTTP capabilities and enhanced database processing

## Changes That Can Affect Backwards-Compatibility

- Fixed method resolution order; it's now possible to call pseudo-methods directly on classes that implement methodGate() methods
- Added the following abstract methods to AbstractDatasource:
  - AbstractDatasource::getConfigHash()
  - AbstractDatasource::getConfigString()
- "hard" string comparisons now perform encoding conversions if necessary (however as usual different data types cause the comparison to fail)

## New Features in Qore

- new user modules delivered with Qore:
  - RestClient: Provides a simple API for communicating with HTTP servers implementing REST services
  - RestHandler: Provides an easy to use interface to the Qore HttpServer module for implementing server-side REST services
  - SqlUtil: Provides a high-level DB-independent API for working with database objects
    - MysqlSqlUtil: Provides a high-level DB-independent API for working with MySQL database objects; loaded automatically by the SqlUtil module when working with MySQL databases
    - OracleSqlUtil: Provides a high-level DB-independent API for working with Oracle database objects; loaded automatically by the SqlUtil module when working with Oracle databases
    - PgsqlSqlUtil: Provides a high-level DB-independent API for working with PostgreSQL database objects; loaded automatically by the SqlUtil module when working with PostgreSQL databases
  - Util: Provides a some miscellaneous generally useful routines
  - WebSocketClient: Provides a client API for connecting to WebSocket servers
  - WebSocketHandler: Provides an interface to the Qore HttpServer module for implementing server-side WebSocket services
  - WebSocketUtil: Provides common client and server code for implementing WebSocket protocol services in Qore
  - WebUtil: Provides server support for implementing complex web services including serving resources with mixed text and Qore code that are automatically rendered on demand
- improvements in existing user modules:
  - much improved HttpServer module, better performance, much better RFC compliance, more flexibility
  - new CSV generation class in CsvUtil
  - much better message serialization and email attachment handling in the SmtpClient and MailMessage modules
- there is a new ThreadPool class for implementing thread pools that automatically upscale and downscale within user-defined limits depending on the load placed on them
- it's possible to inherit concrete versions of abstract method variants from a parent class that does not define the abstract method, meaning that concrete variants of an abstract method do not have to be implemented in a direct subclass of the class declaring the abstract method
  this makes using abstract base classes much easier in complex hierarchies using multiple inheritance; now common code can be separated into a single class and inherited by child classes sharing the common implementation
- major Socket read performance increase by implementing internal read buffering (up to 10x faster socket read performance for certain operations, particularly with HTTP methods)
- improved Unicode / UTF-8 support
  - <string>::lwr(), <string>::upr(), Qore::tolower(string), and Qore::toupper(string) now operate on a very wide range of non-ASCII characters, including Latin, Cyrillic, Greek, Armenian, Georgian, etc characters whereas they were previously limited to working on ASCII characters
  - <string>::unaccent() was added which removes accents from strings using a Unicode lookup map from a very wide range of accented Unicode characters to unaccented characters
- new Datasource and DatasourcePool methods:
  - Qore::SQL::Datasource::getConfigHash()
  - Qore::SQL::Datasource::getConfigString()
  - Qore::SQL::DatasourcePool::getConfigHash()
  - Qore::SQL::DatasourcePool::getConfigString()
  - Qore::SQL::DatasourcePool::copy()
- HTTPClient changes:
  - the HTTPClient class is now a subclass of Socket, so all Socket methods can be called on HTTPClient objects, making it easier to implement protocols based on HTTP
  - Qore::HTTPClient::getDefaultPath(): added
  - Qore::HTTPClient::setDefaultPath(): added
  - Qore::HTTPClient::getURL(): changed: now returns NOTHING if no URL is set instead of an invalid URL
- new functions:
  - call_pseudo_args()
  - substr(binary, softint)
  - substr(binary, softint, softint)
- new pseudo methods:
  - <binary>::substr(softint)
  - <binary>::substr(softint, softint)
  - <binary>::toBase64()
  - <binary>::toHex()
  - <binary>::toString()
  - <date>::getEpochSeconds()
  - <date>::getEpochSecondsLocalTime()
  - <date>::info()
  - <float>::abs()
  - <hash>::compareKeys(hash)
  - <int>::abs()
  - <int>::encodeLsb(int)
  - <int>::encodeMsb(int)
  - <int>::toUnicode()
  - <number>::abs()
  - <object>::hasCallableMethod()
  - <object>::hasCallableNormalMethod()
  - <object>::hasCallableStaticMethod()
  - <list>::rangeIterator()
  - <nothing>::rangeIterator()
  - <string>::comparePartial()
  - <string>::getUnicode()
  - <string>::equalPartial()
  - <string>::equalPartialPath()
  - <string>::toBase64()
  - <string>::toHex()
  - <string>::unaccent()
  - <value>::toNumber()
- other new methods and method changes:
  - added new static methods in the ReadOnlyFile class making it easier to read entire files in one call:
    - Qore::ReadOnlyFile::readTextFile()
    - Qore::ReadOnlyFile::readBinaryFile()
  - changes to catch usage errors with the Counter class:
    - Qore::Thread::Counter::constructor() will throw an exception if called with an argument < 0
    - Qore::Thread::Counter::dec() will now throw an exception if called when the Counter is already at 0
  - Qore::Thread::Queue::empty(): new method
  - Qore::Socket::listen(): now has a new backlog parameter; the default backlog queue size was changed from 5 to 20
  - Qore::Socket::getPeerInfo() and Qore::Socket::getSocketInfo(): now takes an optional argument to avoid name lookups
  - Qore::Socket::readHTTPHeaderString(): new method
  - Qore::Dir: all list*() methods now take an optional parameter to return a list of file status value hashes plus `"name"` and optionally `"link"` keys for symbolic links; additionally symbolic links are now followed and files and directories are differentiated based on their targets when processing symbolic links
- function changes
  - added optional start and end parameters to the replace() function
- all data type declarations that optionally accept NOTHING also now accept NULL and map NULL to NOTHING; this makes direct assignments from values derived from SQL queries much easier
- added an optional reference to an integer to the Qore::backquote() function to return the return code of the program executed
- implicit index references now work in the map and select operators with lists and iterators
- the Regular Expression Pattern Extraction Operator now accepts an optional `g` specifier to extract all occurrences of the pattern(s) in a string; also regex_extract() and <string>::regexExtract(string, int) now accept Qore::RE_Global to extract all occurrences of the pattern(s) in a string
- the splice and extract operators were extended to work on binary objects as well as lists and strings
- printing out binary values with the `"%y"` format specifier now produces YAML-like output for the binary value
- added path name to error messages in Dir class exception strings

## Bug Fixes in Qore

- fixed a bug where the ?: operator could thrown spurious exceptions when parsing because it would return the type of the initial boolean expression as the return type of the operator
- fixed a bug where classes with unimplemented inherited abstract variants would sometimes cause runtime exceptions to be thrown when instantiated but should have instead been caught at parse time
- fixed a parser bug where out-of-line class method definitions could not be defined in a namespace block
- fixed a bug parsing arguments in parse_uri_query() in the HttpServer module
- fixed several bugs where parse exceptions could show the wrong source location:
  - with type errors in function calls
  - when resolving global variables
  - in base class constructor arguments
  - for empty blocks with a missing return statement
  - when validating types used with the return statement (also associated warnings)
  - in methods calls
  - in hash value expressions
  - with redeclaring local variable return types
  - in local variable object instantiations
- really fixed the bug thought to be fixed in 0.8.7 "where SSL errors would cause the affected thread to go into a infinite loop using 100% CPU" - this turned out to be easily reproducible on all platforms; when the SSL connection was shut down cleanly by the remote end before a response message was returned, an infinite loop would result
- fixed a bug where it was impossible to output a single '\' character in regex substitution expressions; '\' was taken as an escape character, and '\\' was output literally, now '\\' is output as '\'
- fixed a bug where a parse-time crash would occur when calling the copy() method for a class that does not implement an explicit copy() method
- fixed a bug where arguments passed to a copy method were ignored; now an exception is thrown
- fixed a bug where public members and static variables of privately-inherited classes were incorrectly treated as public attributes of the child class
- fixed a bug where slices could be made of objects from outside the class including private members
- fixed a bug where memberGate() methods were not being respected when taking a slice of an object
- fixed bugs in the integer Socket::recv*() methods where a `SOCKET-CLOSED` exception was not thrown when the remote end closed the connection
- fixed a bug related to out-of-order parse initialization for functions and methods which resulted in the wrong return type being returned for a method with more than 1 variant where the variant could not be matched at parse time
- fixed a bug where a non-variable-reference member of an "our" variable declaration list would cause a crash due to passing the incorrect argument in sprintf()
- fixed sandboxing / protection errors with inherited code; subclasses inheriting code from a parent class with different parse options would cause the child parse options to be used when running the parent class code which caused errors; now parse options are enforced properly on the block level
- fixed the RangeIterator class; it was still abstract due to a missing Qore::RangeIterator::valid() method
- fixed a bug where the wrong error was being returned after a connection reset (remote connection close) in sockets with integer recv*() methods which could in some cases lead to an infinite loop
- fixed a bug where private members of a common base class were not accessible by objects of subclasses sharing the common base class
- fixed many bugs in CsvUtil and updated the module version to 1.1
- initialize static openssl crypto locks for multi-threaded openssl library access; without this crashes can result (for example in error queue management)
- fixed a bug where Qore::HTTPClient::getURL() returned an invalid URL when no URL was set; now it returns NOTHING in this case
- fixed a bug managing feature/module lists in inherited Program objects; user modules were listed in the child Program object even though user module code is not imported in child Program objects
- fixed a bug where an invalid guard condition in critical lvalue storage code can cause unreferenced data to be returned while in a lock which can cause a crash in a multithreaded program
- fixed a bug where references were not being written to the output variable if an exception was active when the code block exited
- fixed a bug setting the precision for arbitrary-precision numbers with large exponents (like "1e100n")
- implemented more strict adherence to RFC 2616 (HTTP 1.1) regarding message-body handling in requests and response message generation and parsing
- fixed a bug with Condition::wait() on Darwin with negative timeout values where a short timeout was used instead of an indefinite wait
- fixed bugs in the SmtpClient and MailMessage modules where mail messages were being serialized incorrectly if there were no attachments (there was no possibility to set the content transfer encoding) and also where it was not possible to set the content-type for the message body when it was sent as a part of a multipart message
- fixed bugs handling arguments declared as type *reference (reference or nothing)
- fixed bugs in executing code accross Program object barriers with reference arguments
- fixed a bug with the switch statement where character encoding differences would cause strings to mismatch even if they were otherwise identical; now hard comparisons with strings allow for implicit automatic temporary character encoding conversions for the comparison
- fixed a bug where qore failed to set the time zone region correctly when set from /etc/localtime and this file is a relative symlink rather than absolute
- fixed a bug where substr() and <string>::substr() were returning NOTHING if the arguments could not be satisifed contrary to the documentation and the declared return type, now an empty string is returned in those cases
- fixed bugs rounding number values between 10 and -10 (non-inclusive) for display, fixed bugs rounding number value regarding digits after the decimal point for display with Qore::NF_Scientific
- fixed a bug in the Qore::Dir class where it was not possible to chdir to the root directory `"/"`
- fixed a bug where recursive references were allowed and memory leaks would occur due to recursive references; these are now caught at runtime and a `REFERENCE-ERROR` exception is thrown
- fixed a configure bug with bison >= 3
- fixed a bug in the HttpServer module when automatically uncompressing supported content-encodings to set the resulting string's character encoding correctly
- fixed a bug in the instanceof operator when working with objects and classes created from different source Program objects
- fixed a bug in *printf() formatting with floating-point and number values where no digits were displayed right of the decimal point unless a specific number of digits was specified in the format string
- fixed the return type of <bool>::typeCode(); was returning a boolean instead of Qore::NT_BOOLEAN
- fixed a bug there NULL was evaluated as True in a boolean context rather than False
- fixed a bug where Qore::Socket::recvBinary() would ignore the first data read
- fixed starting listeners on UNIX domain sockets on Soalris in the HttpServer module
- fixed a bug where number("") was being converted to @NaN@n
- fixed return type of HTTPClient::getConnectionPath()
- fixed several bugs with logical comparison operators and arbitrary-precision numeric values where arbitrary-precision numeric values were not being prioritized as numeric values and also in some cases were being first converted to doubles and then operated on
- fixed a bug in the socket code where the socket close condition was not flagged with SSL connections when writes failed due to the remote end closing the connection; an error would only be raised on the following socket operation
- fixed a mismatched delete/malloc error with time zone initialization and the localtime file

# Qore 0.8.7

Release Summary
  Code embedding improvements

## Changes That Can Affect Backwards-Compatibility

Fixes for Code Inheritance in Program Objects
  The following changes are meant to sanitize code inheritance in child Program objects to fix long-standing design bugs in code encapsulation by addressing the lack of fine-grained control over symbol visibility in inherited code.
  - public: The public keyword's usage in modules has now been expanded to provide the same functionality generically in Program objects; if classes, constants, namespaces, functions, or global variables are defined with the public keyword, then these symbols will be inherited into child Program objects as long as no parse options prohibit it.
    This change was made to give programmers complete control over which symbols are inherited in child Program objects, whereas because prior to this change, the control was very course.
  - the default behavior of Qore regarding inherting global variables and functions with user variants was changed to be consistent with namespaces, classes, and constants; that is; public symbols are inherited by default.
    The following constants were renamed:
    - `PO_INHERIT_USER_FUNC_VARIANTS` is now: PO_NO_INHERIT_USER_FUNC_VARIANTS
    - `PO_INHERIT_GLOBAL_VARS` is now: PO_NO_INHERIT_GLOBAL_VARS
      This change was made to fix a long-standing design problem with symbol inheritance and make the implementation consistent.
  - builtin symbols are no longer inherited from user modules; only independent user symbols; the main change is that if a user module adds new user methods to a builtin class or new user variants to a builtin function, these changes are no longer imported into target Program objects.

File Method Changes
  The following methods were updated to throw exceptions on all errors rather than a return code for I/O errors in order to avoid hard to debug conditions due to ignoring I/O errors by forgetting to check the return value on the following methods:
  - Qore::File::f_printf()
  - Qore::File::f_vprintf()
  - Qore::File::print()
  - Qore::File::printf()
  - Qore::File::vprintf()
  - Qore::File::write()
  - Qore::File::writei1()
  - Qore::File::writei2()
  - Qore::File::writei4()
  - Qore::File::writei8()
  - Qore::File::writei2LSB()
  - Qore::File::writei4LSB()
  - Qore::File::writei8LSB()
  Note that the above changes will hopefully only minimally impact backwards-compatibilty since the change is in error handling, and additionally each of the above methods could also throw an exception if called when the object was not open.

## New Features in Qore

- new methods offering code encapsulation enhancements
  - Program::loadModule(): allows modules to be loaded in a Program object directly
  - Program::importClass(): allows classes to be individually imported in Program objects
- new pseudo-methods in <nothing> to allow for <hash> pseudo-methods to be safely used with NOTHING
  - <nothing>::firstKey()
  - <nothing>::firstValue()
  - <nothing>::hasKey()
  - <nothing>::hasKeyValue()
  - <nothing>::keys()
  - <nothing>::lastKey()
  - <nothing>::lastValue()
  - <nothing>::values()
- other new pseudo-methods:
  - <date>::durationSeconds()
  - <date>::durationMilliseconds()
  - <date>::durationMicroseconds()
- removed most restrictions on embedded logic in user modules; user module Program objects are subject to the same restrictions as the parent Program object (if any)
- added the get_parse_options() function so that parse options in the current Program can be determined at runtime
- added the get_ex_pos() function to help with formatting exception locations where the `source` and `offset` information is present
- new methods and method variants:
  - Qore::HTTPClient::getPeerInfo()
  - Qore::HTTPClient::getSocketInfo()
  - Qore::File::getTerminalAttributes()
  - Qore::SQL::Datasource::transactionTid()
  - Qore::SQL::Datasource::currentThreadInTransaction()
  - Qore::SQL::DatasourcePool::currentThreadInTransaction()
- new location tags `"source"` and `"offset"` added for parse and runtime exceptions to allow for error-reporting to display information about files where sections of a source file are parsed; this allows both the label and line offset in the label and the file name and absolute file line position to be reported in exception information
  - new parameters added to the following methods and function to accommodate the new location information:
    - Program::parse()
    - Program::parsePending()
    - parse()
  - see Exception Hash and Call Stacks for new keys in exception and call stack information hashes
- <date>::format() now accepts `"us"` for microseconds (see Date Formatting Codes)
- SmtpClient module improvements:
  - added automatic recognition and support of the `"STARTTLS"` command when connecting to an ESMTP server; this way the class will automatically upgrade the connection to a secure TLS/SSL connection if the server supports it
  - added support for SMTP server schemes in the URL in the constructor (ex: `"esmtptls://user@password:smtp.example.com"`)
  - added support for the deprecated (but still in use) `"smtps"` scheme with a default port of 465
  - when throwing an exception when a Message cannot be sent because it is incomplete, the reason for the error is also included in the exception (previously the exception message was generic making problems with the Message object harder to debug)
- C++ API Enhancements
  - added C++ APIs to allow for Qore File and Queue object arguments to be used by modules
  - added C++ APIs for controlling openssl initialization and cleanup by the qore library
  - extended qpp to allow for parsing relative dates in qpp code for assignments/default argument values
  - made it possible to call the C++ function QoreFunction::findVariant() from threads where there is no current QoreProgram object (such as from a thread created by foreign code)
  - added APIs to allow foreign threads to be registered/deregistered as Qore threads (for example, to allow Qore code to be called in a callback in a foreign thread created by a library linked with a Qore binary module)
  - added APIs to allow for TID reservations to allow (for example) for a callback that is executed in the same foreign thread to always have the same TID
  - the old Datasource::execRaw() function with the args parameter was deprecated since args was ignored anyway, a new Datasource::execRaw() function was added that has no args parammeter

## Bug Fixes in Qore

- fixed a runtime class matching bug when identical user classes were created in different Program objects, the match could fail at runtime because the wrong APIs were being used
- fixed a crashing bug in the map operator with a select expression when used with an AbstractIterator object for the list operand
- fixed a bug where the generation of internal strings for abstract method signatures tries to resolve class names that are declared out of order, which incorrectly resulted in a parse exception; the fix is to use the class name in the signature before class resolution; the class is resolved in the second stage of parsing (symbol resolution) anyway, if it can't be resolved then the changes to the Program are rolled back anyway
- a potential deadlock was fixed when calling exit() while background threads were running; it was possible for a thread to be canceled while holding a Mutex (for example) and then for another thread to deadlock trying to acquire the Mutex and therefore for the process to deadlock because pthread_mutex_lock() is not a cancellation point. The solution was to cancel all threads first, then wait half a second, then call exit()
- fixed a bug where global variables were being evaluated with strict mathematical boolean evaluation even when %perl-bool-eval was enabled (which is the default)
- fixed bug in Qore::parseBase64String() and Qore::parseBase64StringToString() when called with an empty string argument; in this case uninitialized memory was returned
- fixed runtime dynamic memory leaks in the Select From List Operator (select) and Map Operator (map) operators when used with iterators
- do thread-specific cleanup in the main thread when cleaning up/shutting down the qore library
- added additional openssl cleanup code for thread-local data and when cleaning up the qore library
- fixed a bug matching function/method variants at runtime
- fixed a race condition deleting global dynamic handlers in the HttpServer module
- fixed a bug where declaring an abstract method with parameters and then declaring a concrete reimplementation of the method in a child class with no parameters caused a parse-time crash
- fixed a bug where trying to dynamically call a function that does not exist results in a deadlock due to an error where a mutex is not unlocked
- fixed a bug in the Qore::Socket::sendHTTPMessage() and Qore::Socket::sendHTTPResponse() methods regarding the timeout parameter
- fixed a bug in an socket SSL error message where the method name was printed from non-string memory (used wrong ptr for the `%s` format argument)
- fixed some major crashing bugs related to reference handling; a global variable assigned a reference to a reference to a local variable would cause a crash
- reference and *reference type fixes: an error in reference type handling allowed non-reference values to be passed to builtin code expecing references which caused a crash; the reference and *reference types would accept any value type
- attempted to fix a non-reproducible bug seen on rhel5 in the Socket class where SSL errors would cause the affected thread to go into a infinite loop using 100% CPU

# Qore 0.8.6.2

Release Summary
  Iterator improvements and design fixes

## Changes That Can Affect Backwards-Compatibility

Fixes for Iterator Class Design Bugs
  Iterators, particular regarding the map and select operators, were implemented in a confusing and inconsistent way; even the qore documentation was incorrect, and examples were given incorrectly. The following changes will break functionality using the badly-implemented behavior of iterators before, but since the fix comes fairly soon after the introduction, hopefully this change will not cause too many problems with existing code. All users polled about the iterator changes in this release saw them as positive and desired changes to the language.
  - the map and select operators' behavior was changed when used with an AbstractIterator object for the list operand; now the implied argument is the result of AbstractIterator::getValue() instead of the iterator object itself. This addresses a confusing design choice in the original iterator integration with the map and select operators
  - the second boolean argument was removed from the HashIterator::constructor(hash) and HashReverseIterator::constructor(hash) methods; use the new HashPairIterator and ObjectPairIterator classes instead (<hash>::pairIterator() and <object>::pairIterator())
  - the single boolean argument was removed from <hash>::iterator() and <object>::iterator(); use <hash>::pairIterator() and <object>::pairIterator() instead to get the old behavior

## Changes in Qore

- new iterator classes:
  - HashKeyIterator
  - HashKeyReverseIterator
  - HashPairIterator
  - HashPairReverseIterator
  - ObjectKeyIterator
  - ObjectKeyReverseIterator
  - ObjectPairIterator
  - ObjectPairReverseIterator
- new pseudo-methods:
  - <hash>::keyIterator()
  - <hash>::pairIterator()
  - <hash>::contextIterator()
  - <object>::keyIterator()
  - <object>::pairIterator()
  - <nothing>::keyIterator()
  - <nothing>::pairIterator()
  - <nothing>::contextIterator()
- the internal C++ QoreProgramHelper object has been updated to wait until all background threads in the Qore library have executed before taking the Program object out of scope; this allows for callbacks and other code that might be needed by background threads started in user modules (for example) to stay valid until the threads in the user modules also have terminated. Note that this does not affect the case when using %exec-class and an application program object goes out of scope with background threads in user modules having non-static method call references as callbacks to the application program; see Program Scope in Object-Oriented Programs Using User Modules Providing Their Own Threads for more information on this topic.

# Qore 0.8.6.1

Release Summary
  Major bug fixes and minor new features

## Changes in Qore

- updated the %try-module parse directive to support a variant without an exception variable for usage in Program objects where Qore::PO_NO_TOP_LEVEL_STATEMENTS is set
- added code to raise an invalid-operation warning with the elements operator when called with a type that can never return a value with this operator
- updated the File class's internal buffer size from 4KB to 16KB which greatly improves read performance
- added new public APIs for the QoreNumberNode class to allow for proper de/serialization in external modules
- Pop3Client module:
  - added the Pop3Client::logPassword() methods and masked password by default in the debug log
  - updated module to v1.1
- Mime module:
  - declared the MultiPartMessage::getMsgAndHeaders() method abstract as originally intended
  - added MultiPartMessage::parseBody() static method
  - updated module to v1.3

## Bug Fixes in Qore

- fixed crashing bugs due to the lack of proper lvalue checks with the expression for the background operator with operators using lvalues with local variables
- fixed rounding of arbitrary-precision numeric values for display purposes when the last significant digit is just to the right of the decimal point (ex: was displaying 10.2 as "11." for example)
- fixed a race condition in static destruction of the library when a background thread calls exit() that could cause a segfault on exit
- fixed a static memory leak in Program objects when constants contain code references to functions or static methods
- fixed a bug parsing user modules; the Program context was not set properly which could lead to a crash when parsing user modules loaded from the command-line or to incorrect parse options when loaded from user Program code
- fixed a bug where the invalid-operation warning with the keys operator was not being triggered in common cases that should have triggered the warning
- MailMessage module:
  - fixed recognizing mime messages with additional text after the version number (ex: `"Mime-Version: 1.0 (Mac OS X Mail 6.2 \(1499\))"`)
  - fixed a bug setting the content-type of message parts (this fix is now in the Mime in the MultiPartMessage::getMsgAndHeaders() method
  - fixed multipart message parsing by using MultiPartMessage::parseBody() in the Mime module; now also parts with subparts are parsed correctly as well
  - fixed a bug where the sender and from values were not being set properly when parsing email messages
  - updated module to v1.0.3

# Qore 0.8.6

Release Summary
  Major new features and a few bug fixes

## Changes That Can Affect Backwards-Compatibility

Perl-Style Boolean Evaluation
  Qore's default boolean evaluation mode was changed from strict mathematical to a more intuitive perl- (and Python-) like style. This change was implemented to address one of the oldest design bugs in Qore: strict mathematical boolean evaluation. See %perl-bool-eval for a description of the new default boolean evaluation mode.
  To get the old strict mathematical boolean evaluation, use the %strict-bool-eval parse option.
  An example of the change; now the following if statement block will be executed as the `if` expression is now evaluated as True:
  string str = "hello";
  if (str)
  printf("Qore says hello\n");
  Previously (i.e. with %strict-bool-eval) the `if` expression above would be evaluated as False because the string value was converted to an integer 0, however as of Qore 0.8.6 (with the default perl-bool-eval) it is True since the string is not empty; empty strings and string value `"0"` are evaluated as False.
  Perhaps counterintuitively (and the reason this was changed to be the default in qore), the chance for regression errors in qore code is very small, because for all cases where the old logic could be applied (meaning excluding cases where the result was always False due to the data types or values being evaluated), the results are the same with the new logic, except for one case; the case where a string has more than one character and begins with a zero (ex: `"00"`). In this case, the old logic would always return False, because the value was first converted to an integer `0`, whereas the new logic will return True. Note that in the case of a string with a single `"0"`, both the old and new boolean logic returns False.
  Basically with this option set, qore's boolean evaluation becomes like perl's and Python's, whereas any expression that has the following values is False: NOTHING, string `"0"` and empty strings, integer, float, and number `0` (zero), absolute date `1970-01-01Z` (ie the start of the epoch with an offset of 0), relative date `0s` (or any relative date with a 0 duration), NULL, empty binary objects, empty hashes, and empty lists. All other values are True.

Note
  also affects the boolean(any) function

Changes in the Socket Class
  The Socket class was enhanced to support timeouts with non-blocking I/O on all send operations; many Socket methods that send data were originally implemented to return an error code on error, however they would also throw exceptions if the socket were not open, so the error handling was inconsistent (exceptions versus return codes).
  Additionally it was not possible to get error information at all for SSL errors if the socket was connected with SSL, which, according to Qore's socket design, should be transparent for the programmer.
  For these reasons the implementation was deemed inconsistent and unintuitive; the change was to add optional timeout parameters to all send methods and to allow the methods to throw exceptions (instead of simply returning -1 and not being able to determine the cause of the error in many cases).
  The following methods were updated to accept optional timeout parameters and throw exceptions on all errors rather than a return code for I/O errors:
  - Qore::Socket::send()
  - Qore::Socket::sendBinary()
  - Qore::Socket::sendi1()
  - Qore::Socket::sendi2()
  - Qore::Socket::sendi4()
  - Qore::Socket::sendi8()
  - Qore::Socket::sendi2LSB()
  - Qore::Socket::sendi4LSB()
  - Qore::Socket::sendi8LSB()

New Abstract Method in AbstractIterator
  The following abstract method was added:
  - Qore::AbstractIterator::valid() was added (with concrete implementations in all iterator classes derived from this base class delivered with Qore); this method tells if the object is currently pointing to a valid iterator.
    For any user classes inherting AbstractIterator directly (as opposed to another concrete iterator class in Qore, where the method has already been added), a concrete implementation of this method will have to be added as well or that class will become abstract with this release of Qore.

## New Features in Qore

Arbitrary-Precision Numeric Support
  Qore now uses the MPFR and GMP libraries to provide arbitrary-precision numeric support. This type can be used for high-precision mathematics or for storing `NUMERIC` (ie `DECIMAL` or `NUMBER`) column values when retrieved from databases by Qore DBI drivers that support the new capability DBI_CAP_HAS_NUMBER_SUPPORT (previously these values would be retrieved as Qore strings in order to avoid information loss).
  For more information, see the new number type, number, and <number>

New CsvUtil Module
  The CsvUtil module implements the CsvFileIterator class that allows for easy parsing of csv-like text files

%try-module Parse Directive to Handle Module Load Errors at Parse Time
  The new %try-module parse directive allows for module load errors to be handled at parse time; ex:
  %try-module($ex) some-module > 1.0
  printf("error loading module %y: %s: %s\n", ex.arg, ex.err, ex.desc);
  exit(1);
  %endtry

Abstract Class Hierarchy Improvement
  As of this version of qore, concrete implementations of abstract methods no longer have to have exactly the same return type as the abstract method; it is now sufficient that the return type in the concrete method meets a compatibility test with the return type of the abstract method in the parent class.
  For example the following is now valid (and `MyConcreteClass` is not abstract, whereas previously because the return types in the child class were not exact, `MyConcreteClass` would be considered abstract by qore):
  class MyAbstractClass {
  abstract any doSomething();
  abstract *string getString();
  }
  class MyConcreteClass inherits MyAbstractClass {
  int doSomething() {
  return 1;
  }
  string getString() {
  return "hello";
  }
  }

DBI Improvements
  Three new DBI capabilities were implemented, including a new option API as follows:
  - DBI_CAP_HAS_NUMBER_SUPPORT: DBI drivers declaring this capability can accept number values and can also return number values, if a DBI driver does not declare this capability, then number values sent for binding by value are automatically converted to float values before being sent to the driver
  - DBI_CAP_HAS_OPTION_SUPPORT: this indicates that the driver supports the new option API, allowing options to be set on each connection. See the following for more information:
    - Datasource::constructor(hash): now passes options to the DBI driver if the driver supports the option API
    - Datasource::constructor(string): (new in 0.8.6) passes options to the DBI driver if the driver supports the option API
    - Datasource::getOption(string): (new in 0.8.6) returns the value of the given option if the driver supports the option API
    - Datasource::getOptionHash(): (new in 0.8.6) returns a hash of the current option values for the current connection if the driver supports the option API
    - Datasource::setOption(): (new in 0.8.6) allows options to be changed after the object is created
    - DatasourcePool::constructor(hash): now passes options to the DBI driver if the driver supports the option API
    - DatasourcePool::constructor(string): (new in 0.8.6) passes options to the DBI driver if the driver supports the option API
    - DatasourcePool::getOption(string): (new in 0.8.6) returns the value of the given option if the driver supports the option API
    - DatasourcePool::getOptionHash(): (new in 0.8.6) returns a hash of the current option values for the current connection if the driver supports the option API
    - dbi_get_driver_options(string): (new in 0.8.6) returns a hash of driver option information without values
  - DBI_CAP_SERVER_TIME_ZONE: indicates that the DBI driver will convert any bound date/time values to the server's time zone before binding and also will tag date/time values retrieved from the server with the server's time zone. This capability also implies that the driver supports the new `"timezone"` option.

Socket Improvements
  The Socket class was updated to support non-blocking I/O on all send methods; the following methods were updated to accept optional timeout parameters:
  - Qore::Socket::send2()
  - Qore::Socket::sendBinary2()
  - Qore::Socket::sendHTTPMessage()
  - Qore::Socket::sendHTTPResponse()
  The following methods were enhanced to provide better error information when throwing exceptions:
  - Qore::Socket::recvi1()
  - Qore::Socket::recvi2()
  - Qore::Socket::recvi4()
  - Qore::Socket::recvi8()
  - Qore::Socket::recvi2LSB()
  - Qore::Socket::recvi4LSB()
  - Qore::Socket::recvi8LSB()
  - Qore::Socket::recvu1()
  - Qore::Socket::recvu2()
  - Qore::Socket::recvu4()
  - Qore::Socket::recvu2LSB()
  - Qore::Socket::recvu4LSB()

Iterator Improvements
  The following improvements were made in qore to support more flexible and ubiquitous iterators:
  - new iterator classes:
    - SingleValueIterator: allows single values (or any value without an iterator class) to be iterated; this provides the basis for the return type for the new base <value>::iterator() method for non-container types
    - FileLineIterator: allows files to be iterated line by line
    - ObjectIterator: a generic iterator for objects
    - ObjectReverseIterator: a generic reverse iterator for objects
    - RangeIterator: a numerical sequence generator (the basis for the return type for the new xrange() function
  - new pseudo-methods were added to return iterator objects based on the value type:
    - <value>::iterator()
    - <hash>::iterator()
    - <list>::iterator()
    - <object>::iterator()
    The base pseudo-method (<value>::iterator()) ensures that any value can be iterated, and the type-specific methods ensure that the most suitable iterator for container types is returned for container values; values without an iterator class are iterated with the SingleValueIterator
  - the HashIterator and HashReverseIterator classes had an additional optional boolean argument added to their constructors; if True, then the HashIterator::getValue() and HashReverseIterator::getValue() methods return a hash with the following keys: `"key"` and `"value"`, allowing for more convenient iteration with constructions that only use `getValue()` methods (such as the foreach statement); to accommodate this, two new methods were added to the HashIterator base class:
    - Qore::HashIterator::getKeyValue()
    - Qore::HashIterator::getValuePair()
  - all iterator classes had copy methods added to them (ex: Qore::HashIterator::copy())
  - new Python-inspired range() and xrange() functions (the latter returning a RangeIterator object to efficiently iterate large integral sequences or ranges

Text File Parsing Enhancements
  The following improvements were made in qore to support more flexible file parsing:
  - the Qore::ReadOnlyFile class was added as a parent class of Qore::File to allow for a more convenient API for reading files (the Qore::File class's API remains the same as it publically inherits Qore::ReadOnlyFile)
  - the ReadOnlyFile::readLine() method (formerlly a method of the Qore::File class) was enhanced to accept 2 optional arguments, allowing the end of line character(s) to be stripped from the line returned, and also to allow the end of line characters to be specified. If no end of line characters are specified, then the method automatically determines the end of line characters (can be `"\n"`, `"\r"`, or `"\r\n"`; the last one only if the underlying file is not a TTY in order to avoid stalling I/O on an interactive TTY)
  - the File Stat Constants were moved from the Qore::File class to the Qore::ReadOnlyFile class
  - added a new FileLineIterator iterator class
  - added a new optional parameter to <string>::split(string, string, bool) and Qore::split(string, string, string, bool) to allow for automatic stripping unquoted fields of leading and trailing whitespace (the default is the old behavior; i.e. leave the whitespace as it is read)
  - added a new TimeZone method for parsing string dates in a specific TimeZone: Qore::TimeZone::date(string, string)
  - added a new function for parsing text as a boolean value: parse_boolean()
  - as mentioned above, the new CsvUtil module was added, implementing the CsvFileIterator class that allows for easy parsing of csv-like text files

Other Improvements and Changes
  - the foreach statement now iterates objects derived from AbstractIterator automatically
  - added a HAVE_SYMLINK constant for the symlink() function added in qore 0.8.5
  - added the SQLStatement::memberGate() method so SQLStatement objects can be dereferenced directly to a column value when iterated with SQLStatement::next(); also this method will throw exceptions when an unknown column name is used so that typos in column names can be caught (instead of being silently ignored producing hard to find bugs)
  - implemented Datasource::constructor(string) and DatasourcePool::constructor(string) variants to allow for creating datasources from a string that can be parsed by Qore::SQL::parse_datasource(string) "parse_datasource(string)"
  - added the following new DBI-related functions:
    - dbi_get_driver_list()
    - dbi_get_driver_capability_list(string)
    - dbi_get_driver_capabilities(string)
    - dbi_get_driver_options(string)
    - parse_datasource(string)
  - implemented support for `"A"` and `"a"`, (hexadecimal floating-point output) `"G"`, `"g"`, (compact floating-point output) `"F"`, (non-scientific floating-point output) and `"E"` and `"e"` (scientific/exponential floating-point output) format arguments for floats and numbers (new arbitrary-precision number type values); see String Formatting
  - new pseudo-methods:
    - <value>::toString()
    - <value>::toInt()
    - <value>::toFloat()
    - <value>::toBool()
    - <float>::format(string fmt)
    - <int>::format(string fmt)
    - <string>::isDataAscii()
    - <string>::isDataPrintableAscii()
    - <value>::callp()
    - <callref>::callp()
    - <int>::sign()
    - <float>::sign()
  - the value of the NUMBER, NUMERIC, and DECIMAL SQL Constants is now `"number"` instead of `"string"` (see also sql_binding)
  - new constants:
    - M_PIn
    - MAXINT
    - MININT
  - new functions:
    - range()
    - xrange()
  - new methods:
    - Qore::ReadOnlyFile::isTty() and Qore::ReadOnlyFile::getFileName() (the Qore::ReadOnlyFile class was added in qore 0.8.6 otherwise made up of methods formerly belonging to the Qore::File class)
  - added the %append-module-path parse directive
  - user modules may now use Program objects for embedded logic; any Program objects created in a user module will have its parse options masked to be not less restrictive than the parse options in the current Program, and additionally parse options will be locked so that user module are not able to circumvent function restrictions imposed by parse options.
  - updated docs to show functional restrictions tagged at the class level

## Bug Fixes in Qore

- fixed a bug in the map operator with a select expression when the list operand is NOTHING; it was returning a list with one NOTHING element instead of NOTHING
- applied a patch by Reini Urban to allow for multi-arch builds on Debian
- fixed bugs calculating the byte offset for string searches in the c++ QoreString::index() and QoreString::rindex() functions when the offset is negative and the strings have a multi-byte character encoding (such as UTF-8)
- fixed a bug where calling an abstract method from a class where the abstract method is implemented was causing a parse error to be thrown
- fixed a bug where the wrong source code location was displayed when raising a parse exception in operator expression parse initialization for some operators
- fixed bugs in regexes in the HttpServer::addListeners() and HttpServer::addListenersWithHandler() methods (HttpServer module version updated to 0.3.5)
- fixed bugs handling non-blocking reads in the Socket class; the timeout setting was only enforced for the first read; subsequent reads were made as blocking reads
- fixed a bug in the Socket class when the SSL session requires renegotiation during non-blocking I/O
- File::constructor() now throws an exception if called with a tty target and %no-terminal-io is set
- fixed a bug in split with quote (<string>::split(string, string, bool) and Qore::split(string, string, string, bool)) if the separator pattern was not found and the single field was not quoted either
- fixed a bug handling nested %ifdef and %ifndef blocks with %else in the inside block
- fixed a crashing due to the failure to clear the "PF_TOP_LEVEL" flag when initializing statements, this could cause temporary variables in a statement to be marked as the start of the global thread-local variable list, and then after such variables are deleted, then a crash happens when trying to access the global thread-local variable list
- fixed a crashing bug at parse time merging function lists in namespaces declared multiple times
- fixed a bug in executing user module init() closures
- fixed a bug where the qore library could crash when destroying a Program object due to a race condition in removing signal handlers managed by the Program object; the Program calls the signal handler manager to remove the signals, but the signals can be removed concurrently to the request while the Program object is iterating the signal set (ie it is modified while being iterated), which causes a crash
- added code to detect when the same namespace is declared both with and without the public keyword when defining user modules which can result in entire namespaces being silently not exported (and can be difficult to debug); now a parse exception is thrown if this happens while parsing a user module
- added code tags to File methods without side effects
- made many minor documentation fixes

# Qore 0.8.5.1

Release Summary
  Bugfix release

## Bug Fixes in Qore

- fixed a race condition accessing global and closure-bound thread-local variables in multithreaded contexts
- fixed a bug in transaction management with the DatasourcePool class when used with the SQLStatement class
- fixed an error in the MailMessage user module where mail headers requiring encoding were not encoded and those not requiring encoding were encoded with Q encoding
- fixed an error in the Mime user module where `"_"` characters in q-encoded headers were not encoded correctly

# Qore 0.8.5

Release Summary
  Major new features and a few bug fixes

## New Features in Qore

Abstract Methods and Interfaces
  Qore now supports the abstract keyword when declaring methods; an abstract method has no implementation and must be implemented in child classes with the same signature for the child class to be instantiated.
  Classes with abstract methods define interfaces; a concrete implementation of the interface is a class that inherits the class with abstract methods and implements all the abstract methods.
  Abstract methods are defined with the following syntax:
  class MyAbstractInterface {
  abstract string doSomething(int param);
  abstract bool checkSomething(string arg);
  }
  The following abstract classes now exist in Qore:
  - AbstractDatasource
  - AbstractIterator
    - AbstractQuantifiedIterator
    - AbstractBidirectionalIterator
    - AbstractQuantifiedBidirectionalIterator
  - AbstractSmartLock (which was already present in Qore but now implements abstract methods)
  The following new iterator classes have been added to Qore:
  - HashIterator
    - HashReverseIterator
  - HashListIterator
    - HashListReverseIterator
  - ListHashIterator
    - ListHashReverseIterator
  - ListIterator
    - ListReverseIterator
  - SQLStatement (which was already present in Qore but now implements the AbstractIterator interface to allow query results to be iterated)
  Classes inheriting AbstractIterator have special support so that objects can be easily iterated in the following list operators:
  - Map Operator (map)
  - Fold Right Operator (foldr) and Fold Left Operator (foldl)
  - Select From List Operator (select)

Universal References
  All restrictions on references have been removed from Qore; references to local variables may now be passed to the background operator and passed as arguments to closures.
  Basically when a reference is taken of a local variable that could result in the local variable being accessed in a multi-threaded context, the variable is treated as a closure-bound local variable in the sense that it's lifetime is reference-counted, and all accesses are wrapped in a dedicated mutual-exclusion lock to ensure thread safety.

Pop3Client Module
  A Pop3Client module has been added providing an API for communicating with POP3 servers and retrieving email messages.
  The module uses functionality provided by the new MailMessage module to represent email messages (and attachment data) downloaded from the server.

MailMessage Module
  The MailMessage module provides common functionality to the Pop3Client and SmtpClient modules to represent email messages for receiving and sending, respectively. This module was created mostly from functionality removed from the SmtpClient and enhanced to provide support for reading email messages in the new Pop3Client module.

SmtpClient Module Changes
  The Message and Attachment classes were removed from the SmtpClient module to the MailMessage module. Backwards-compatible definitions for the Message and Attachment classes are provided in the SmtpClient module to rexport the removed functionality for backwards compatibility.

Other Minor Improvements and Changes
  - qpp updated to support abstract methods and multiple inheritance (+ other minor qpp enhancements)
  - improved the `QOREADDRINFO-GETINFO-ERROR` exception description by adding information about the arguments passed
  - added a string argument to char(softint, *string) to accept an output encoding
  - added a int(string, int) variant to parse a string as a number and give the base
  - added a new parameter to parse_url() and parseURL() to allow for any [] in the hostname to be included in the `"host"` output key for indicating that the ipv6 protocol be used
  - added the following pseudo-methods:
    - <value>::lsize()
    - <binary>::split()
    - <binary>::toMD5()
    - <binary>::toSHA1()
    - <binary>::toSHA224()
    - <binary>::toSHA256()
    - <binary>::toSHA384()
    - <binary>::toSHA512()
    - <date>::midnight()
    - <list>::first()
    - <list>::join()
    - <list>::last()
    - <list>::lsize()
    - <nothing>::lsize()
    - <string>::regex()
    - <string>::regexExtract()
    - <string>::split()
    - <string>::substr()
    - <string>::toMD5()
    - <string>::toSHA1()
    - <string>::toSHA224()
    - <string>::toSHA256()
    - <string>::toSHA384()
    - <string>::toSHA512()
  - added the xxhash FAST algorithm with unordered_map to Qore on supported platforms resuling in nearly 2x haster hash lookups
  - added the Qore::File::isOpen() method
  - added the Qore::call_pseudo() function to explicitly call a pseudo method on a value
  - added the Qore::symlink() function to create symbolic links
  - added Qore::TypeCodeMap and Qore::TypeNameMap to lookup type codes from type names and vice versa
  - added the following functions to allow the time zone to be set per thread:
    - Qore::set_thread_tz()
    - Qore::get_thread_tz()

## Bug Fixes in Qore

- fixed format_date() output for `"MON"` and `"DAY"`, etc
- fixed a memory leak in the parser related to parse exception handling with namespace members
- fixed an invalid assert() in module handling when an error occurs loading the module (only affected debug builds)
- tagged digest and crypto functions internally as RET_VALUE_ONLY
- do not kill TID 1 (the initial / main thread) when calling exit() in background threads as a crash can result with some 3rd party libraries that spawn their own threads on some platforms (observed on Darwin & Solaris 10 at least)
- fixed a memory bug in the new builtin function API used by modules built with qpp
- fixed memory bugs in the type system where uninitialized type pointers could be used causing a crash
- fixed a memory bug in handling "or nothing" types where a non-null pointer would be assumed to be a pointer to the type, however it could actually be a pointer to the NOTHING object, the fix was to ensure that any NOTHING objects in argument lists would be substituted with a null pointer
- fixed a bug in parse-time variant matching where an argument with parse-time type "object" would be matched as a perfect match to any parameter with any class restriction; this would cause run-time type errors if another valid class was passed that matched another variant of the method or function
- fixed a build bug that caused qore to be built twice

# Qore 0.8.4

Release Summary
  Major new features and changes that can affect backwards-compatibility, plus 40 bug fixes

## Changes That Can Affect Backwards-Compatibility

Namespace Changes
  Qore's internal namespace handling was nearly completely rewritten for Qore 0.8.4. This is because the old code was inefficient and applied namespaces inconsistently to Program objects.
  The main change that can cause backwards-compatibility issues is that now functions are full namespace members. If no namespace is explicitly given in a function definition, the function is a member of the unnamed root namespace.
  Also the distinction between builtin and user functions was removed. Internally, there is only one kind of function object, which can contain both builtin and user function variants (overloaded variants of the same function with the same name but different arguments).
  All Qore builtin functions were moved to the Qore namespace.
  Other namespace changes:
  - loading namespaces provided by builtin modules into a Program object is now an atomic operation that may fail, if, for example, objects have already been defined in the target Program with the same name as objects provided by the builtin module. Previously this could cause undefined behavior.
  - namespace lookups are now truly breadth-first as documented; previously the algorithm was depth-first (contrary to the documentation)
  - namespace lookups are now done (both at parse time and runtime) with the help of symbol lookup tables for fast lookups; tables are maintained for both committed and temporary uncomitted parse symbols; this leads to up to 3x faster parsing for Qore code
  - global variables are also now full namespace members, however this does not cause problems with backwards-compatibility

## New Features in Qore

User Modules
  It is now possible to develop user modules in Qore; several user modules are now included in the Qore distribution, forming Qore-language components of Qore's runtime library.
  User modules delivered with Qore 0.8.4:
  - HttpServer: a multi-threaded HTTP server implementation
  - SmtpClient: an SMTP client library
  - TelnetClient: a TELNET client implementation
  - Mime: a set of MIME definitions and functions for manipulating MIME data
  There are also new example programs for the above modules in the examples/ directory.
  User modules are subject to Qore's functional restriction framework.

Namespace Changes
  As listed above:
  - global variables and functions are now full namespace members
  - all builtin functions are now in the Qore namespace
  - real depth-first searches are used for namespace symbols
  - symbols are resolved first in the current namespace when parsing declarations/code in a namespace

The final Keyword
  Classes and methods can now be declared "final" to prevent subclassing or overriding in a subclass

Pseudo Methods
  Pseudo-methods are class methods that can be implemented on any value; they are also part of class hierarchy. The methods that can be executed on the value depend on the value's type, and all "pseudo-classes" inherit methods from a common base class.
  For example:
  "string".strlen()
  <abf05da3>.size()
  500.typeCode()
  Are examples of pseudo-methods on literal values.
  Some expensive operations such as getting the first or last key (or value) of a hash are now cheap using pseudo-methods, for example:
  hash.firstKey()
  hash.lastValue()

New Doxygen-Based Documentation
  The Qore reference documentation is now generated by Doxygen, and is generated directly from the Qore sources. In fact, a new preprocessor known as "qpp" was developed for Qore 0.8.4 to facilitate and enforce doxygen documentation on Qore's runtime library (as well as abstract the relatively complex APIs used to bind C++ code to the Qore runtime library from the C++ programmer).
  The documentation is more comprehensive, and corresponds much closer to the actual internal implementation since the documentation is now also contained in and directly generated from the internal C++ implementation of Qore.
  For example, there is the <value>::val() method. This method is implemented in the base pseudo class and is reimplemented in other pseudo-classes for other runtime data types as necessary. This method returns True if the value has a value in the same sense as Perl's boolean context evaluation. For example, if the value is a hash with no keys, it returns False; if it is a hash with keys, it returns True; if it is an empty string, it returns False; if it is a non-empty string, it returns True, etc.

LValue Handling Changes
  lvalue handling was rewritten as the old implementation was ugly and subject to deadlocks (in rare corner cases).
  Furthermore, medium-term, an architectural goal of Qore is to store all ints, floats, and bools internally as the basic C++ type instead of using a class wrapper for each value, which needs dynamic allocation and destruction, which takes up more memory and negatively affects execution speed.
  With Qore 0.8.4, all local and global variables are stored using optimized C++ types when declared with the appropriate type restrictions; for example:
  int i0;
  our int i1;
  These declares local and global variables that can only be assigned integer values; in Qore 0.8.4 the value internally will be stored as an "int64" value (and not a dynamically-allocated QoreBigIntNode object).
  The same holds for:
  - int
  - softint
  - float
  - softfloat
  - bool
  - softbool
  Note that the optimized lvalue handling has not yet been applied to all lvalues, in particular non-static object members with declared types are not yet implemented with optimized storage; to do this requires a rewrite of Qore's API and ABI (will happen in the next major release of Qore).
  This change leads to improved integer and floating-point performance and a smaller runtime memory footprint.

Runtime Optimizations
  In addition to the up to 3x faster parsing (as decribed in the namespace changes above), Qore 0.8.4 contains many runtime optimizations designed to reduce the number of dynamic memory allocations performed at runtime.
  The optimizations included in this version of Qore are only a half-measure compared to future changes that will necessitate a new binary Qore API.

Per-Thread Initialization
  the new set_thread_init() function allows a call reference or closure to be set which will be automatically executed when new threads are started (or a new thread accesses a Program object) which can be used to transparently initialize thread-local data.

More Control Over Thread Resource Exceptions
  new functions:
  - throw_thread_resource_exceptions_to_mark()
  - mark_thread_resources()
  Allow for only thread resouces created after a certain point to be processed (for example only thread resources left after some embedded code was called)

New Socket Methods
  new methods:
  - Qore::Socket::upgradeClientToSSL()
  - Qore::Socket::upgradeServerToSSL()
  Allow upgrading an already-existing socket connection to SSL

Better Socket Error Messages
  More information has been added to socket exceptions to provide better feedback when errors occur.

New Socket Event Fields
  - added `"type"` and `"typename"` keys to the EVENT_HOSTNAME_RESOLVED event
  - added `"type"`, `"typename"`, and `"address"` keys to the EVENT_CONNECTING event

Support For Blocking Writes in the Queue Class
  Queue objects can now be used as a blocking message channel (similar to a Go channel); if a maximum size is given to the Queue constructor, then trying to write data to the Queue when it is full will block until the Queue's size goes below the maximum size; optional timeout parameters have been added to Queue methods that write to the Queue.

New Queue::clear() Method
  Does just what you think it does :)

date(string, string) Improvement
  added the possibility to specify microseconds when parsing dates against a mask with the date() function

New Support For ++ And – Operators With Floating-Point Lvalues
  previously this would either convert the lvalue to an int or throw an exception if the lvalue could not be converted to an int due to type restrictions

Class Recognition/Compatibility Between Program Objects
  The problem is that a user class created from the same source code in two different Program objects would be recognized as a different class with parameter and variable type restrictions - ie you could not declare a variable or parameter with a class type restrictions and assign it an object created from the same class source code but created in another Program object.
  This problem is analogous to a similar problem with java in that classes built from the same source but from different classloaders are also recognized as different classes.
  In Qore 0.8.4 a class signature is created of all public and private objects, and an SHA1 hash is maintained of the class signature, and if the class names and signatures match, then the classes are assumed to be identical, even if they have different internal class IDs (because they were created in different Program objects, for example).

New TimeZone::date(string) Method
  to support creating arbitrary dates in a given TimeZone

New GetOpt::parse3() method
  This method will display any errors on stderr and exit the program (which is the most typical way of handling command line errors anyway)

+= Operator Optimization For object += hash
  this operation is faster in this release

New Parse Option PO_NO_MODULES
  Using this option disables module loading

New Parse Option PO_NO_EMBEDDED_LOGIC
  Using this option disables all dynamic parsing

New Parse Directives
  - %assume-global: the opposite of %assume-local
  - %old-style: the opposite of %new-style
  - %require-dollar: the opposite of %allow-bare-refs
  - %push-parse-options: allows parse options to be saved and restored when the current file is done parsing; very useful for include files

New Context Functions
  - cx_value(): returns the value of the given key
  - cx_first(): returns True if iterating the first row
  - cx_last(): returns True if iterating the last row
  - cx_pos(): returns the current row number (starting from 0)
  - cx_total(): returns the total number of rows in the set

SOCKET-HTTP-ERROR Exception Enhancement
  The invalid header info received is reported in the exception's `"arg"` key

Improved Parse Error Messages
  Improved some parse error messages dealing with namespace and class declaration errors

Added NT_CLOSURE Constant
  type code for runtime closure values

## Bug Fixes in Qore

- fixed a race condition with Program objects when a signal handler is left active and the Program terminates
- fixed a bug in the File class where the encoding given in the constructor was ignored; if no encoding was given in the File::open*() method then the File's encoding would always be set to the default encoding, now it's set to the encoding given in the constructor (as documented)
- runtime checks have been implemented so that references to local variables cannot be passed to a closure; this would cause a runtime crash
- a fix has been made to the delete and remove operators; lists will not be extended when trying to remove/delete list elements that do not exist
- fixed some bugs showing the error location with bugs in the second stage of parsing (symbol resolution)
- apply type filters to blocks with a designated return type but no return statement
- fixed crashing bugs on some 32bit platforms where size_t was assumed to be 64 bits
- fixed a crashing bug parsing invalid %requires directives in the scanner
- fixed a bug in usleep() with relative date/time values (added a new usleep() variant to support this)
- fixed a typo in the command-line help for the qore binary with unknown parse options
- fixed HAVE_SIGNAL_HANDLING to be False if signal handling is disabled on platforms where signal handling is otherwise available
- fixed a scanner bug parsing out of line class definitions with a root-justified namespace path (ex: `"class ::X::ClassName ..."`)
- merging code from binary modules at parse time and at runtime is now transaction-safe (before it would cause memory errors and/or a crash), now if errors are detected then an exception is raised and changes are not applied.
- fixed a crashing bug in the C++ API function QoreHashNode::setKeyValue() when the value is 0 and an exception occurs or is already active before the call is made
- fixed a bug in date parsing with a format string - off by one with integer months - added a regression test for this case
- fixed a memory error with the rethrow statement in enclosing but nested try-catch blocks
- fixed a crashing bug where qore would try to instantiate a class for a type that did not represent a class (ex: `"int i();"`)
- fixed a memory leak in the softlist and *softlist type implementation
- make sure and raise a `SOCKET-CLOSED` error when reading a HTTP header if no data is received
- make sure and convert encodings with index() and rindex() functions if the encodings don't match
- build fix: only use a lib64 directory if the directory exists already
- raise a parse exception in the scanner if a numeric overflow occurs in literal integer values
- fixed a bug in AbstractSmartLock::lockTID()
- fixed a major crashing error in the C++ API function QoreStringNode::createAndConvertEncoding(); this function is used by the xml module when parsing XML-RPC sent in a non-UTF-8 character encoding
- fixed Qore::File::getchar() to always retrieve 1 character (even for multi-byte character encodings)
- fixed string evaluation in a boolean context to return True with floating-point numbers between -1.0 and 1.0 exclusive
- printf formatting fix: output YAML-style `"null"` for NOTHING with %y
- scanner fix: accept `"\r"` as whitespace to allow better parsing of sources with Windows EOL markers
- fixed parse-time type processing/checks for the keys, + and * operators
- foreach statement fix: unconditionally evaluate the hash when iterating as otherwise it could change during iteration which could cause a crash
- fixed another parse-time variant matching bug where the variant-matching algorithm was too aggressive and excluded possible matches at parse time which could result in a false parse-time definitive match even though a better match could be available at runtime
- fixed a static memory leak when signal handlers are left registered when the qore library terminates
- fixed static memory leaks and 1 dynamic memory leak in strmul()
- fixed a crashing bug in handling recursive constant references
- fixed a bug in the C++ API function HashIterator::deleteKey() when the node's value is NULL
- fixed time zone/DST calculations for time zone regions with DST with dates before the epoch but after the last DST transition before the epoch
- fixed a memory error where invalid source expressions referenced in a regular expression substitution expression would cause a crash (ex:

      str =~ s/public (name)/$2/g

- fixed a memory error in regular expression substitution where the unconverted string (if not given in UTF-8 encoding) was used when copying source expressions to the target string
- fixed a bug where a recursive class inheritance tree would cause a crash
- fixed a bug where a static class method could not access private members of the class