From fbf45f771de7d3df8058be2f2d6a80c2b2d69de2 Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Thu, 19 Sep 2024 23:19:59 +0200 Subject: [PATCH 1/6] BUILDSYS-448 Updated JSONCPP to 1.9.6 https://github.com/open-source-parsers/jsoncpp/releases/tag/1.9.6 --- cpp-lib/jsoncpp/.clang-format | 2 +- cpp-lib/jsoncpp/include/allocator.h | 14 +- cpp-lib/jsoncpp/include/config.h | 15 +- cpp-lib/jsoncpp/include/forwards.h | 2 +- cpp-lib/jsoncpp/include/json_features.h | 3 +- cpp-lib/jsoncpp/include/reader.h | 38 ++++- cpp-lib/jsoncpp/include/value.h | 50 +++++-- cpp-lib/jsoncpp/include/version.h | 9 +- cpp-lib/jsoncpp/include/writer.h | 8 +- cpp-lib/jsoncpp/json_reader.cpp | 191 +++++++++++++----------- cpp-lib/jsoncpp/json_value.cpp | 43 ++++-- cpp-lib/jsoncpp/json_writer.cpp | 10 +- 12 files changed, 252 insertions(+), 133 deletions(-) diff --git a/cpp-lib/jsoncpp/.clang-format b/cpp-lib/jsoncpp/.clang-format index 2a806695..b7cf9979 100644 --- a/cpp-lib/jsoncpp/.clang-format +++ b/cpp-lib/jsoncpp/.clang-format @@ -1,4 +1,4 @@ BasedOnStyle: LLVM DerivePointerAlignment: false PointerAlignment: Left - +SpacesBeforeTrailingComments: 1 diff --git a/cpp-lib/jsoncpp/include/allocator.h b/cpp-lib/jsoncpp/include/allocator.h index df8b6bc0..ab73d8b9 100644 --- a/cpp-lib/jsoncpp/include/allocator.h +++ b/cpp-lib/jsoncpp/include/allocator.h @@ -6,10 +6,12 @@ #ifndef JSON_ALLOCATOR_H_INCLUDED #define JSON_ALLOCATOR_H_INCLUDED +#include #include #include -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace SJson { template class SecureAllocator { @@ -37,8 +39,16 @@ template class SecureAllocator { * The memory block is filled with zeroes before being released. */ void deallocate(pointer p, size_type n) { - // memset_s is used because memset may be optimized away by the compiler + // These constructs will not be removed by the compiler during optimization, + // unlike memset. +#if defined(HAVE_MEMSET_S) memset_s(p, n * sizeof(T), 0, n * sizeof(T)); +#elif defined(_WIN32) + RtlSecureZeroMemory(p, n * sizeof(T)); +#else + std::fill_n(reinterpret_cast(p), n, 0); +#endif + // free using "global operator delete" ::operator delete(p); } diff --git a/cpp-lib/jsoncpp/include/config.h b/cpp-lib/jsoncpp/include/config.h index 5217a472..38f08bb6 100644 --- a/cpp-lib/jsoncpp/include/config.h +++ b/cpp-lib/jsoncpp/include/config.h @@ -111,16 +111,15 @@ using UInt = unsigned int; using LargestInt = int; using LargestUInt = unsigned int; #undef JSON_HAS_INT64 -#else // if defined(JSON_NO_INT64) +#else // if defined(JSON_NO_INT64) // For Microsoft Visual use specific types as long long is not supported -// #if defined(_MSC_VER) // Microsoft Visual Studio -// using Int64 = __int64; -// using UInt64 = unsigned __int64; -// #else // if defined(_MSC_VER) // Other platforms, use long -// long +#if defined(_MSC_VER) // Microsoft Visual Studio +using Int64 = __int64; +using UInt64 = unsigned __int64; +#else // if defined(_MSC_VER) // Other platforms, use long long using Int64 = int64_t; using UInt64 = uint64_t; -// #endif // if defined(_MSC_VER) +#endif // if defined(_MSC_VER) using LargestInt = Int64; using LargestUInt = UInt64; #define JSON_HAS_INT64 @@ -128,7 +127,7 @@ using LargestUInt = UInt64; template using Allocator = - typename std::conditional, + typename std::conditional, std::allocator>::type; using String = std::basic_string, Allocator>; using IStringStream = diff --git a/cpp-lib/jsoncpp/include/forwards.h b/cpp-lib/jsoncpp/include/forwards.h index 611acb74..d4045596 100644 --- a/cpp-lib/jsoncpp/include/forwards.h +++ b/cpp-lib/jsoncpp/include/forwards.h @@ -38,6 +38,6 @@ class ValueIteratorBase; class ValueIterator; class ValueConstIterator; -} // namespace SJson +} // namespace Json #endif // JSON_FORWARDS_H_INCLUDED diff --git a/cpp-lib/jsoncpp/include/json_features.h b/cpp-lib/jsoncpp/include/json_features.h index c9c136d6..30ae318f 100644 --- a/cpp-lib/jsoncpp/include/json_features.h +++ b/cpp-lib/jsoncpp/include/json_features.h @@ -10,7 +10,8 @@ #include "forwards.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace SJson { diff --git a/cpp-lib/jsoncpp/include/reader.h b/cpp-lib/jsoncpp/include/reader.h index a1859313..5e4a5cbe 100644 --- a/cpp-lib/jsoncpp/include/reader.h +++ b/cpp-lib/jsoncpp/include/reader.h @@ -23,7 +23,8 @@ #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace SJson { @@ -189,6 +190,7 @@ class JSON_API Reader { using Errors = std::deque; bool readToken(Token& token); + bool readTokenSkippingComments(Token& token); void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); @@ -220,7 +222,6 @@ class JSON_API Reader { int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); @@ -243,6 +244,12 @@ class JSON_API Reader { */ class JSON_API CharReader { public: + struct JSON_API StructuredError { + ptrdiff_t offset_start; + ptrdiff_t offset_limit; + String message; + }; + virtual ~CharReader() = default; /** \brief Read a Value from a JSON * document. The document must be a UTF-8 encoded string containing the @@ -261,7 +268,12 @@ class JSON_API CharReader { * error occurred. */ virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, - String* errs) = 0; + String* errs); + + /** \brief Returns a vector of structured errors encountered while parsing. + * Each parse call resets the stored list of errors. + */ + std::vector getStructuredErrors() const; class JSON_API Factory { public: @@ -271,6 +283,20 @@ class JSON_API CharReader { */ virtual CharReader* newCharReader() const = 0; }; // Factory + +protected: + class Impl { + public: + virtual ~Impl() = default; + virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) = 0; + virtual std::vector getStructuredErrors() const = 0; + }; + + explicit CharReader(std::unique_ptr impl) : _impl(std::move(impl)) {} + +private: + std::unique_ptr _impl; }; // CharReader /** \brief Build a CharReader implementation. @@ -359,6 +385,12 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode */ static void strictMode(SJson::Value* settings); + /** ECMA-404 mode. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode + */ + static void ecma404Mode(SJson::Value* settings); }; /** Consume entire stream and use its begin/end. diff --git a/cpp-lib/jsoncpp/include/value.h b/cpp-lib/jsoncpp/include/value.h index 7f6d761d..27b8ddd0 100644 --- a/cpp-lib/jsoncpp/include/value.h +++ b/cpp-lib/jsoncpp/include/value.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef JSON_H_INCLUDED -#define JSON_H_INCLUDED +#ifndef JSON_VALUE_H_INCLUDED +#define JSON_VALUE_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" @@ -53,7 +53,8 @@ #pragma warning(disable : 4251 4275) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() /** \brief JSON (JavaScript Object Notation). */ @@ -374,7 +375,7 @@ class JSON_API Value { int compare(const Value& other) const; const char* asCString() const; ///< Embedded zeroes could cause you trouble! -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY unsigned getCStringLength() const; // Allows you to understand the length of // the CString #endif @@ -436,7 +437,7 @@ class JSON_API Value { /// \post type() is arrayValue void resize(ArrayIndex newSize); - //@{ + ///@{ /// Access an array element (zero based index). If the array contains less /// than index element, then null value are inserted in the array so that /// its size is index+1. @@ -444,15 +445,15 @@ class JSON_API Value { /// this from the operator[] which takes a string.) Value& operator[](ArrayIndex index); Value& operator[](int index); - //@} + ///@} - //@{ + ///@{ /// Access an array element (zero based index). /// (You may need to say 'value[0u]' to get your compiler to distinguish /// this from the operator[] which takes a string.) const Value& operator[](ArrayIndex index) const; const Value& operator[](int index) const; - //@} + ///@} /// If the array contains at least index+1 elements, returns the element /// value, otherwise returns defaultValue. @@ -512,6 +513,9 @@ class JSON_API Value { /// and operator[]const /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 Value const* find(char const* begin, char const* end) const; + /// Most general and efficient version of isMember()const, get()const, + /// and operator[]const + Value const* find(const String& key) const; /// Most general and efficient version of object-mutators. /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. @@ -584,6 +588,26 @@ class JSON_API Value { iterator begin(); iterator end(); + /// \brief Returns a reference to the first element in the `Value`. + /// Requires that this value holds an array or json object, with at least one + /// element. + const Value& front() const; + + /// \brief Returns a reference to the first element in the `Value`. + /// Requires that this value holds an array or json object, with at least one + /// element. + Value& front(); + + /// \brief Returns a reference to the last element in the `Value`. + /// Requires that value holds an array or json object, with at least one + /// element. + const Value& back() const; + + /// \brief Returns a reference to the last element in the `Value`. + /// Requires that this value holds an array or json object, with at least one + /// element. + Value& back(); + // Accessors for the [start, limit) range of bytes within the JSON text from // which this value was parsed, if any. void setOffsetStart(ptrdiff_t start); @@ -924,7 +948,15 @@ class JSON_API ValueIterator : public ValueIteratorBase { inline void swap(Value& a, Value& b) { a.swap(b); } -} // namespace SJson +inline const Value& Value::front() const { return *begin(); } + +inline Value& Value::front() { return *begin(); } + +inline const Value& Value::back() const { return *(--end()); } + +inline Value& Value::back() { return *(--end()); } + +} // namespace Sson #pragma pack(pop) diff --git a/cpp-lib/jsoncpp/include/version.h b/cpp-lib/jsoncpp/include/version.h index e931d038..42e8780a 100644 --- a/cpp-lib/jsoncpp/include/version.h +++ b/cpp-lib/jsoncpp/include/version.h @@ -9,19 +9,18 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.5" +#define JSONCPP_VERSION_STRING "1.9.7" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 5 +#define JSONCPP_VERSION_PATCH 7 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ (JSONCPP_VERSION_PATCH << 8)) -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY +#if !defined(JSONCPP_USE_SECURE_MEMORY) +#define JSONCPP_USE_SECURE_MEMORY 0 #endif -#define JSONCPP_USING_SECURE_MEMORY 0 // If non-zero, the library zeroes any memory that it has allocated before // it frees its memory. diff --git a/cpp-lib/jsoncpp/include/writer.h b/cpp-lib/jsoncpp/include/writer.h index a135c466..96a528cc 100644 --- a/cpp-lib/jsoncpp/include/writer.h +++ b/cpp-lib/jsoncpp/include/writer.h @@ -20,7 +20,8 @@ #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace SJson { @@ -216,7 +217,7 @@ class JSON_API FastWriter : public Writer { * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -284,7 +285,7 @@ class JSON_API StyledWriter : public Writer { * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their #CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -350,6 +351,7 @@ String JSON_API valueToString( PrecisionType precisionType = PrecisionType::significantDigits); String JSON_API valueToString(bool value); String JSON_API valueToQuotedString(const char* value); +String JSON_API valueToQuotedString(const char* value, size_t length); /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() diff --git a/cpp-lib/jsoncpp/json_reader.cpp b/cpp-lib/jsoncpp/json_reader.cpp index ae22e154..c63c31e5 100644 --- a/cpp-lib/jsoncpp/json_reader.cpp +++ b/cpp-lib/jsoncpp/json_reader.cpp @@ -12,6 +12,7 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include #include +#include #include #include #include @@ -128,7 +129,7 @@ bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, bool successful = readValue(); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); if (collectComments_ && !commentsBefore_.empty()) root.setComment(commentsBefore_, commentAfter); if (features_.strictRoot_) { @@ -156,7 +157,7 @@ bool Reader::readValue() { throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); bool successful = true; if (collectComments_ && !commentsBefore_.empty()) { @@ -225,14 +226,14 @@ bool Reader::readValue() { return successful; } -void Reader::skipCommentTokens(Token& token) { +bool Reader::readTokenSkippingComments(Token& token) { + bool success = readToken(token); if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); + while (success && token.type_ == tokenComment) { + success = readToken(token); + } } + return success; } bool Reader::readToken(Token& token) { @@ -446,12 +447,7 @@ bool Reader::readObject(Token& token) { Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; + while (readTokenSkippingComments(tokenName)) { if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); @@ -480,15 +476,11 @@ bool Reader::readObject(Token& token) { return recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { + if (!readTokenSkippingComments(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) { return addErrorAndRecover("Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } @@ -518,10 +510,7 @@ bool Reader::readArray(Token& token) { Token currentToken; // Accept Comment after last item in the array. - ok = readToken(currentToken); - while (currentToken.type_ == tokenComment && ok) { - ok = readToken(currentToken); - } + ok = readTokenSkippingComments(currentToken); bool badTokenType = (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { @@ -552,8 +541,8 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; -// TODO: Help the compiler do the div and mod at compile time or get rid of -// them. + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. #if defined(_MSC_VER) #pragma warning(disable : 26450) #endif @@ -605,11 +594,16 @@ bool Reader::decodeDouble(Token& token) { bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; - String buffer(token.start_, token.end_); - IStringStream is(buffer); - if (!(is >> value)) - return addError( - "'" + String(token.start_, token.end_) + "' is not a number.", token); + IStringStream is(String(token.start_, token.end_)); + if (!(is >> value)) { + if (value == std::numeric_limits::max()) + value = std::numeric_limits::infinity(); + else if (value == std::numeric_limits::lowest()) + value = -std::numeric_limits::infinity(); + else if (!std::isinf(value)) + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); + } decoded = value; return true; } @@ -773,7 +767,7 @@ void Reader::getLocationLineAndColumn(Location location, int& line, while (current < location && current != end_) { Char c = *current++; if (c == '\r') { - if (*current == '\n') + if (current != end_ && *current == '\n') ++current; lastLineStart = current; ++line; @@ -890,17 +884,12 @@ class OurReader { public: using Char = char; using Location = const Char*; - struct StructuredError { - ptrdiff_t offset_start = 0; - ptrdiff_t offset_limit = 0; - String message; - }; explicit OurReader(OurFeatures const& features); bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); String getFormattedErrorMessages() const; - std::vector getStructuredErrors() const; + std::vector getStructuredErrors() const; private: OurReader(OurReader const&); // no impl @@ -943,6 +932,7 @@ class OurReader { using Errors = std::deque; bool readToken(Token& token); + bool readTokenSkippingComments(Token& token); void skipSpaces(); void skipBom(bool skipBom); bool match(const Char* pattern, int patternLength); @@ -976,7 +966,6 @@ class OurReader { int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); @@ -1030,7 +1019,7 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, bool successful = readValue(); nodes_.pop(); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) { addError("Extra non-whitespace after JSON value.", token); return false; @@ -1058,7 +1047,7 @@ bool OurReader::readValue() { if (nodes_.size() > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); bool successful = true; if (collectComments_ && !commentsBefore_.empty()) { @@ -1130,7 +1119,6 @@ bool OurReader::readValue() { currentValue().setOffsetLimit(current_ - begin_); break; } // else, fall through ... - [[fallthrough]]; default: currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); @@ -1146,14 +1134,14 @@ bool OurReader::readValue() { return successful; } -void OurReader::skipCommentTokens(Token& token) { +bool OurReader::readTokenSkippingComments(Token& token) { + bool success = readToken(token); if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); + while (success && token.type_ == tokenComment) { + success = readToken(token); + } } + return success; } bool OurReader::readToken(Token& token) { @@ -1450,12 +1438,7 @@ bool OurReader::readObject(Token& token) { Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; + while (readTokenSkippingComments(tokenName)) { if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma @@ -1492,15 +1475,11 @@ bool OurReader::readObject(Token& token) { return recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { + if (!readTokenSkippingComments(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) { return addErrorAndRecover("Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } @@ -1534,10 +1513,7 @@ bool OurReader::readArray(Token& token) { Token currentToken; // Accept Comment after last item in the array. - ok = readToken(currentToken); - while (currentToken.type_ == tokenComment && ok) { - ok = readToken(currentToken); - } + ok = readTokenSkippingComments(currentToken); bool badTokenType = (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { @@ -1615,7 +1591,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { const auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, meaing value == threshold, + // a) we've only just touched the limit, meaning value == threshold, // b) this is the last digit, or // c) it's small enough to fit in that rounding delta, we're okay. // Otherwise treat this number as a double to avoid overflow. @@ -1652,11 +1628,15 @@ bool OurReader::decodeDouble(Token& token) { bool OurReader::decodeDouble(Token& token, Value& decoded) { double value = 0; - const String buffer(token.start_, token.end_); - IStringStream is(buffer); + IStringStream is(String(token.start_, token.end_)); if (!(is >> value)) { - return addError( - "'" + String(token.start_, token.end_) + "' is not a number.", token); + if (value == std::numeric_limits::max()) + value = std::numeric_limits::infinity(); + else if (value == std::numeric_limits::lowest()) + value = -std::numeric_limits::infinity(); + else if (!std::isinf(value)) + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); } decoded = value; return true; @@ -1821,7 +1801,7 @@ void OurReader::getLocationLineAndColumn(Location location, int& line, while (current < location && current != end_) { Char c = *current++; if (c == '\r') { - if (*current == '\n') + if (current != end_ && *current == '\n') ++current; lastLineStart = current; ++line; @@ -1856,10 +1836,11 @@ String OurReader::getFormattedErrorMessages() const { return formattedMessage; } -std::vector OurReader::getStructuredErrors() const { - std::vector allErrors; +std::vector +OurReader::getStructuredErrors() const { + std::vector allErrors; for (const auto& error : errors_) { - OurReader::StructuredError structured; + CharReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; structured.message = error.message_; @@ -1869,20 +1850,36 @@ std::vector OurReader::getStructuredErrors() const { } class OurCharReader : public CharReader { - bool const collectComments_; - OurReader reader_; public: OurCharReader(bool collectComments, OurFeatures const& features) - : collectComments_(collectComments), reader_(features) {} - bool parse(char const* beginDoc, char const* endDoc, Value* root, - String* errs) override { - bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); - if (errs) { - *errs = reader_.getFormattedErrorMessages(); + : CharReader( + std::unique_ptr(new OurImpl(collectComments, features))) {} + +protected: + class OurImpl : public Impl { + public: + OurImpl(bool collectComments, OurFeatures const& features) + : collectComments_(collectComments), reader_(features) {} + + bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) override { + bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); + if (errs) { + *errs = reader_.getFormattedErrorMessages(); + } + return ok; } - return ok; - } + + std::vector + getStructuredErrors() const override { + return reader_.getStructuredErrors(); + } + + private: + bool const collectComments_; + OurReader reader_; + }; }; CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } @@ -1971,6 +1968,32 @@ void CharReaderBuilder::setDefaults(SJson::Value* settings) { (*settings)["skipBom"] = true; //! [CharReaderBuilderDefaults] } +// static +void CharReaderBuilder::ecma404Mode(SJson::Value* settings) { + //! [CharReaderBuilderECMA404Mode] + (*settings)["allowComments"] = false; + (*settings)["allowTrailingCommas"] = false; + (*settings)["strictRoot"] = false; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["stackLimit"] = 1000; + (*settings)["failIfExtra"] = true; + (*settings)["rejectDupKeys"] = false; + (*settings)["allowSpecialFloats"] = false; + (*settings)["skipBom"] = false; + //! [CharReaderBuilderECMA404Mode] +} + +std::vector +CharReader::getStructuredErrors() const { + return _impl->getStructuredErrors(); +} + +bool CharReader::parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) { + return _impl->parse(beginDoc, endDoc, root, errs); +} ////////////////////////////////// // global functions @@ -1979,7 +2002,7 @@ bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root, String* errs) { OStringStream ssin; ssin << sin.rdbuf(); - String doc = ssin.str(); + String doc = std::move(ssin).str(); char const* begin = doc.data(); char const* end = begin + doc.size(); // Note that we do not actually need a null-terminator. diff --git a/cpp-lib/jsoncpp/json_value.cpp b/cpp-lib/jsoncpp/json_value.cpp index 1756b85a..877fbec8 100644 --- a/cpp-lib/jsoncpp/json_value.cpp +++ b/cpp-lib/jsoncpp/json_value.cpp @@ -87,7 +87,8 @@ template static inline bool InRange(double d, T min, U max) { // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn - return d >= static_cast(min) && d <= static_cast(max); + return d >= static_cast(min) && d <= static_cast(max) && + !(static_cast(d) == min && d != static_cast(min)); } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) static inline double integerToDouble(SJson::UInt64 value) { @@ -101,7 +102,8 @@ template static inline double integerToDouble(T value) { template static inline bool InRange(double d, T min, U max) { - return d >= integerToDouble(min) && d <= integerToDouble(max); + return d >= integerToDouble(min) && d <= integerToDouble(max) && + !(static_cast(d) == min && d != integerToDouble(min)); } #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) @@ -169,7 +171,7 @@ inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, /** Free the string duplicated by * duplicateStringValue()/duplicateAndPrefixStringValue(). */ -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { unsigned length = 0; char const* valueDecoded; @@ -184,10 +186,10 @@ static inline void releaseStringValue(char* value, unsigned length) { memset(value, 0, size); free(value); } -#else // !JSONCPP_USING_SECURE_MEMORY +#else // !JSONCPP_USE_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { free(value); } static inline void releaseStringValue(char* value, unsigned) { free(value); } -#endif // JSONCPP_USING_SECURE_MEMORY +#endif // JSONCPP_USE_SECURE_MEMORY } // namespace SJson @@ -605,7 +607,7 @@ const char* Value::asCString() const { return this_str; } -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY unsigned Value::getCStringLength() const { JSON_ASSERT_MESSAGE(type() == stringValue, "in Json::Value::asCString(): requires stringValue"); @@ -711,6 +713,11 @@ Value::Int64 Value::asInt64() const { JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); return Int64(value_.uint_); case realValue: + // If the double value is in proximity to minInt64, it will be rounded to + // minInt64. The correct value in this scenario is indeterminable + JSON_ASSERT_MESSAGE( + value_.real_ != minInt64, + "Double value is minInt64, precise value cannot be determined"); JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), "double out of Int64 range"); return Int64(value_.real_); @@ -1098,6 +1105,9 @@ Value const* Value::find(char const* begin, char const* end) const { return nullptr; return &(*it).second; } +Value const* Value::find(const String& key) const { + return find(key.data(), key.data() + key.length()); +} Value* Value::demand(char const* begin, char const* end) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::demand(begin, end): requires " @@ -1111,7 +1121,7 @@ const Value& Value::operator[](const char* key) const { return *found; } Value const& Value::operator[](const String& key) const { - Value const* found = find(key.data(), key.data() + key.length()); + Value const* found = find(key); if (!found) return nullSingleton(); return *found; @@ -1211,7 +1221,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { return false; } if (removed) - *removed = it->second; + *removed = std::move(it->second); ArrayIndex oldSize = size(); // shift left all items left, into the place of the "removed" for (ArrayIndex i = index; i < (oldSize - 1); ++i) { @@ -1314,8 +1324,12 @@ bool Value::isInt64() const { // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a // double, so double(maxInt64) will be rounded up to 2^63. Therefore we // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && - value_.real_ < double(maxInt64) && IsIntegral(value_.real_); + // minInt64 is -2^63 which can be represented as a double, but since double + // values in its proximity are also rounded to -2^63, we require the value + // to be strictly greater than the limit to avoid returning 'true' for + // values that are not in the range + return value_.real_ > double(minInt64) && value_.real_ < double(maxInt64) && + IsIntegral(value_.real_); default: break; } @@ -1353,7 +1367,11 @@ bool Value::isIntegral() const { // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && + // minInt64 is -2^63 which can be represented as a double, but since double + // values in its proximity are also rounded to -2^63, we require the value + // to be strictly greater than the limit to avoid returning 'true' for + // values that are not in the range + return value_.real_ > double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); #else return value_.real_ >= minInt && value_.real_ <= maxUInt && @@ -1416,9 +1434,8 @@ void Value::setComment(String comment, CommentPlacement placement) { // Always discard trailing newline, to aid indentation. comment.pop_back(); } - JSON_ASSERT(!comment.empty()); JSON_ASSERT_MESSAGE( - comment[0] == '\0' || comment[0] == '/', + comment.empty() || comment[0] == '/', "in Json::Value::setComment(): Comments must start with /"); comments_.set(placement, std::move(comment)); } diff --git a/cpp-lib/jsoncpp/json_writer.cpp b/cpp-lib/jsoncpp/json_writer.cpp index cf65bdcf..a2effe67 100644 --- a/cpp-lib/jsoncpp/json_writer.cpp +++ b/cpp-lib/jsoncpp/json_writer.cpp @@ -360,6 +360,10 @@ String valueToQuotedString(const char* value) { return valueToQuotedStringN(value, strlen(value)); } +String valueToQuotedString(const char* value, size_t length) { + return valueToQuotedStringN(value, length); +} + // Class Writer // ////////////////////////////////////////////////////////////////// Writer::~Writer() = default; @@ -497,7 +501,7 @@ void StyledWriter::writeValue(const Value& value) { const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); + writeWithIndent(valueToQuotedString(name.c_str(), name.size())); document_ += " : "; writeValue(childValue); if (++it == members.end()) { @@ -715,7 +719,7 @@ void StyledStreamWriter::writeValue(const Value& value) { const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); + writeWithIndent(valueToQuotedString(name.c_str(), name.size())); *document_ << " : "; writeValue(childValue); if (++it == members.end()) { @@ -1253,7 +1257,7 @@ String writeString(StreamWriter::Factory const& factory, Value const& root) { OStringStream sout; StreamWriterPtr const writer(factory.newStreamWriter()); writer->write(root, &sout); - return sout.str(); + return std::move(sout).str(); } OStream& operator<<(OStream& sout, Value const& root) { From bd0d0b037c8707c331c1c00b42f504c4a6261fe6 Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Fri, 20 Sep 2024 21:21:34 +0200 Subject: [PATCH 2/6] BUILDSYS-380 changed version to a more readbable format and moved the dynamic part to the patch version 8.123123123.0 -> 8.0.20240920 --- compiler/back-ends/c++-gen/gen-code.c | 11 +++++-- compiler/back-ends/java-gen/gen-java-code.c | 22 +++++++++---- .../back-ends/jsondoc-gen/gen-jsondoc-code.c | 30 ++++++++++++++--- compiler/back-ends/swift-gen/gen-swift-code.c | 20 ++++++++---- compiler/back-ends/ts-gen/gen-ts-code.c | 10 ++++-- compiler/back-ends/ts-gen/gen-ts-combined.c | 10 ++++-- compiler/core/snacc.c | 10 ++++-- compiler/core/time_helpers.c | 32 +++++++++++++++++++ compiler/core/time_helpers.h | 7 ++++ 9 files changed, 123 insertions(+), 29 deletions(-) diff --git a/compiler/back-ends/c++-gen/gen-code.c b/compiler/back-ends/c++-gen/gen-code.c index 5cbd3af9..5df8367a 100644 --- a/compiler/back-ends/c++-gen/gen-code.c +++ b/compiler/back-ends/c++-gen/gen-code.c @@ -4755,10 +4755,15 @@ void PrintCxxCode(FILE* src, FILE* hdr, if_META(MetaNameStyle printMeta _AND_) i strcpy_s(szModuleNameUpper, 512, m->moduleName); Str2UCase(szModuleNameUpper, 512); Dash2Underscore(szModuleNameUpper, 512); - fprintf(hdr, "#define %s_MODULE_LASTCHANGE = \"%s\"\n", szModuleNameUpper, ConvertUnixTimeToISO(lMinorModuleVersion)); + + char* szISODate = ConvertUnixTimeToISO(lMinorModuleVersion); + fprintf(hdr, "#define %s_MODULE_LASTCHANGE = \"%s\"\n", szModuleNameUpper, szISODate); + free(szISODate); fprintf(hdr, "#define %s_MODULE_MAJOR_VERSION = %i\n", szModuleNameUpper, gMajorInterfaceVersion); - fprintf(hdr, "#define %s_MODULE_MINOR_VERSION = %lld\n", szModuleNameUpper, lMinorModuleVersion); - fprintf(hdr, "#define %s_MODULE_VERSION = \"%i.%lld.0\"\n\n", szModuleNameUpper, gMajorInterfaceVersion, lMinorModuleVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMinorModuleVersion); + fprintf(hdr, "#define %s_MODULE_MINOR_VERSION = %s\n", szModuleNameUpper, szNumericDate); + fprintf(hdr, "#define %s_MODULE_VERSION = \"%i.0.%s\"\n\n", szModuleNameUpper, gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); } if (genCodeCPPPrintStdAfxInclude) diff --git a/compiler/back-ends/java-gen/gen-java-code.c b/compiler/back-ends/java-gen/gen-java-code.c index b53d5f55..df3a6db9 100644 --- a/compiler/back-ends/java-gen/gen-java-code.c +++ b/compiler/back-ends/java-gen/gen-java-code.c @@ -761,10 +761,15 @@ void PrintJAVACode(ModuleList* allMods) { long long lMaxMinorVersion = GetMaxModuleMinorVersion(); fprintf(src, "public class Asn1InterfaceVersion {\n"); - fprintf(src, "\tpublic static final String lastChange = \"%s\";\n", ConvertUnixTimeToISO(lMaxMinorVersion)); + + char* szISODate = ConvertUnixTimeToISO(lMaxMinorVersion); + fprintf(src, "\tpublic static final String lastChange = \"%s\";\n", szISODate); + free(szISODate); fprintf(src, "\tpublic static final int majorVersion = %i;\n", gMajorInterfaceVersion); - fprintf(src, "\tpublic static final long minorVersion = %lld;\n", lMaxMinorVersion); - fprintf(src, "\tpublic static final String version = \"%i.%lld.0\";\n", gMajorInterfaceVersion, lMaxMinorVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMaxMinorVersion); + fprintf(src, "\tpublic static final long minorVersion = %s;\n", szNumericDate); + fprintf(src, "\tpublic static final String version = \"%i.0.%s\";\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(src, "}\n"); fclose(src); } @@ -811,10 +816,15 @@ void PrintJAVACodeOneModule(ModuleList* mods, Module* m) { long long lMinorModuleVersion = GetModuleMinorVersion(m->moduleName); fprintf(src, "public class %s {\n", m->moduleName); - fprintf(src, "\tpublic static final String lastChange = \"%s\";\n", ConvertUnixTimeToISO(lMinorModuleVersion)); + + char* szISODate = ConvertUnixTimeToISO(lMinorModuleVersion); + fprintf(src, "\tpublic static final String lastChange = \"%s\";\n", szISODate); + free(szISODate); fprintf(src, "\tpublic static final int majorVersion = %i;\n", gMajorInterfaceVersion); - fprintf(src, "\tpublic static final long minorVersion = %lld;\n", lMinorModuleVersion); - fprintf(src, "\tpublic static final String version = \"%i.%lld.0\";\n", gMajorInterfaceVersion, lMinorModuleVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMinorModuleVersion); + fprintf(src, "\tpublic static final long minorVersion = %s;\n", szNumericDate); + fprintf(src, "\tpublic static final String version = \"%i.0.%s\";\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(src, "}\n"); fclose(src); } diff --git a/compiler/back-ends/jsondoc-gen/gen-jsondoc-code.c b/compiler/back-ends/jsondoc-gen/gen-jsondoc-code.c index f364861d..a0827b90 100644 --- a/compiler/back-ends/jsondoc-gen/gen-jsondoc-code.c +++ b/compiler/back-ends/jsondoc-gen/gen-jsondoc-code.c @@ -717,12 +717,14 @@ void PrintJsonDocModule(FILE* src, ModuleList* mods, Module* m) { fprintf(src, ",\n\t\t\"version\": {"); long long lMinorModuleVersion = GetModuleMinorVersion(m->moduleName); - long long lMaxModuleVersion = GetMaxModuleMinorVersion(); - fprintf(src, "\n\t\t\t\"lastChange\": \"%s\"", ConvertUnixTimeToISO(lMinorModuleVersion)); + char* szISODate = ConvertUnixTimeToISO(lMinorModuleVersion); + fprintf(src, "\n\t\t\t\"lastChange\": \"%s\"", szISODate); + free(szISODate); fprintf(src, ",\n\t\t\t\"majorVersion\": %i", gMajorInterfaceVersion); - fprintf(src, ",\n\t\t\t\"minorVersion\": %lld", lMinorModuleVersion); - fprintf(src, ",\n\t\t\t\"version\": \"%i.%lld.0\"", gMajorInterfaceVersion, lMinorModuleVersion); - fprintf(src, ",\n\t\t\t\"interfaceversion\": \"%i.%lld.0\"", gMajorInterfaceVersion, lMaxModuleVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMinorModuleVersion); + fprintf(src, ",\n\t\t\t\"minorVersion\": %s", szNumericDate); + fprintf(src, ",\n\t\t\t\"version\": \"%i.0.%s\"", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(src, "\n\t\t}"); } @@ -843,6 +845,24 @@ void PrintJsonDocCode(ModuleList* allMods) DefinedObj* fNames; int fNameConflict = FALSE; + { + char* szFileName = MakeFileName("interfaceversion", ".txt"); + FILE* src = NULL; + if (fopen_s(&src, szFileName, "wt") != 0 || src == NULL) + { + perror("fopen"); + } + else + { + const long long lMaxModuleVersion = GetMaxModuleMinorVersion(); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMaxModuleVersion); + fprintf(src, "%i.0.%s", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); + fclose(src); + } + free(szFileName); + } + /* * Make names for each module's encoder/decoder src and hdr files * so import references can be made via include files diff --git a/compiler/back-ends/swift-gen/gen-swift-code.c b/compiler/back-ends/swift-gen/gen-swift-code.c index 42f5c890..5e62ab30 100644 --- a/compiler/back-ends/swift-gen/gen-swift-code.c +++ b/compiler/back-ends/swift-gen/gen-swift-code.c @@ -1240,10 +1240,14 @@ void PrintSwiftCodeOne(FILE* src, ModuleList* mods, Module* m, long longJmpVal, Dash2Underscore(szModuleName, 512); fprintf(src, "struct %s_Version\n", szModuleName); fprintf(src, "{\n"); - fprintf(src, " let lastChange = Date(iso8601String:\"%s\") ?? .distantPast\n", ConvertUnixTimeToISO(lMinorModuleVersion)); + char* szISODate = ConvertUnixTimeToISO(lMinorModuleVersion); + fprintf(src, " let lastChange = Date(iso8601String:\"%s\") ?? .distantPast\n", szISODate); + free(szISODate); fprintf(src, " let majorVersion = %i\n", gMajorInterfaceVersion); - fprintf(src, " let minorVersion = %lld\n", lMinorModuleVersion); - fprintf(src, " let version = \"%i.%lld.0\"\n", gMajorInterfaceVersion, lMinorModuleVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMinorModuleVersion); + fprintf(src, " let minorVersion = %s\n", szNumericDate); + fprintf(src, " let version = \"%i.0.%s\"\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(src, "}\n\n"); } @@ -1435,10 +1439,14 @@ void PrintSwiftCode(ModuleList* allMods, long longJmpVal, int genTypes, int genV fprintf(versionFile, "import Foundation\n\n"); fprintf(versionFile, "struct Asn1InterfaceVersion\n"); fprintf(versionFile, "{\n"); - fprintf(versionFile, " let lastChange = Date(iso8601String:\"%s\") ?? .distantPast\n", ConvertUnixTimeToISO(lMaxMinorVersion)); + char* szISODate = ConvertUnixTimeToISO(lMaxMinorVersion); + fprintf(versionFile, " let lastChange = Date(iso8601String:\"%s\") ?? .distantPast\n", szISODate); + free(szISODate); fprintf(versionFile, " let majorVersion = %i\n", gMajorInterfaceVersion); - fprintf(versionFile, " let minorVersion = %lld\n", lMaxMinorVersion); - fprintf(versionFile, " let version = \"%i.%lld.0\"\n", gMajorInterfaceVersion, lMaxMinorVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMaxMinorVersion); + fprintf(versionFile, " let minorVersion = %s\n", szNumericDate); + fprintf(versionFile, " let version = \"%i.0.%s\"\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(versionFile, "}\n"); fclose(versionFile); } diff --git a/compiler/back-ends/ts-gen/gen-ts-code.c b/compiler/back-ends/ts-gen/gen-ts-code.c index b0044726..2f3f89a8 100644 --- a/compiler/back-ends/ts-gen/gen-ts-code.c +++ b/compiler/back-ends/ts-gen/gen-ts-code.c @@ -1005,10 +1005,14 @@ void PrintTSCode(ModuleList* allMods, long longJmpVal, int genTypes, int genValu fprintf(versionFile, "/* eslint-disable */\n\n"); long long lMaxMinorVersion = GetMaxModuleMinorVersion(); fprintf(versionFile, "export class Asn1InterfaceVersion {\n"); - fprintf(versionFile, "\tpublic static lastChange = \"%s\";\n", ConvertUnixTimeToISO(lMaxMinorVersion)); + char* szISODate = ConvertUnixTimeToISO(lMaxMinorVersion); + fprintf(versionFile, "\tpublic static lastChange = \"%s\";\n", szISODate); + free(szISODate); fprintf(versionFile, "\tpublic static majorVersion = %i;\n", gMajorInterfaceVersion); - fprintf(versionFile, "\tpublic static minorVersion = %lld;\n", lMaxMinorVersion); - fprintf(versionFile, "\tpublic static version = \"%i.%lld.0\";\n", gMajorInterfaceVersion, lMaxMinorVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMaxMinorVersion); + fprintf(versionFile, "\tpublic static minorVersion = %s;\n", szNumericDate); + fprintf(versionFile, "\tpublic static version = \"%i.0.%s\";\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(versionFile, "}\n"); fclose(versionFile); } diff --git a/compiler/back-ends/ts-gen/gen-ts-combined.c b/compiler/back-ends/ts-gen/gen-ts-combined.c index 977bbbb7..fff1993b 100644 --- a/compiler/back-ends/ts-gen/gen-ts-combined.c +++ b/compiler/back-ends/ts-gen/gen-ts-combined.c @@ -61,10 +61,14 @@ void PrintTSRootTypes(FILE* src, Module* mod, const char* szSuffix) if (gMajorInterfaceVersion >= 0) { long long lMinorModuleVersion = GetModuleMinorVersion(mod->moduleName); - fprintf(src, "export const MODULE_LASTCHANGE = \"%s\";\n", ConvertUnixTimeToISO(lMinorModuleVersion)); + char* szISODate = ConvertUnixTimeToISO(lMinorModuleVersion); + fprintf(src, "export const MODULE_LASTCHANGE = \"%s\";\n", szISODate); + free(szISODate); fprintf(src, "export const MODULE_MAJOR_VERSION = %i;\n", gMajorInterfaceVersion); - fprintf(src, "export const MODULE_MINOR_VERSION = %lld;\n", lMinorModuleVersion); - fprintf(src, "export const MODULE_VERSION = \"%i.%lld.0\";\n", gMajorInterfaceVersion, lMinorModuleVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMinorModuleVersion); + fprintf(src, "export const MODULE_MINOR_VERSION = %s;\n", szNumericDate); + fprintf(src, "export const MODULE_VERSION = \"%i.0.%s\";\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); } } diff --git a/compiler/core/snacc.c b/compiler/core/snacc.c index 7fa94891..a6f429b1 100644 --- a/compiler/core/snacc.c +++ b/compiler/core/snacc.c @@ -1585,10 +1585,14 @@ void GenCxxCode(ModuleList* allMods, long longJmpVal, int genTypes, int genValue fprintf(versionFile, "struct Asn1InterfaceVersion\n"); fprintf(versionFile, "{\n"); - fprintf(versionFile, "\tstatic constexpr const char* lastChange = \"%s\";\n", ConvertUnixTimeToISO(lMaxMinorVersion)); + char* szISODate = ConvertUnixTimeToISO(lMaxMinorVersion); + fprintf(versionFile, "\tstatic constexpr const char* lastChange = \"%s\";\n", szISODate); + free(szISODate); fprintf(versionFile, "\tstatic constexpr int majorVersion = %i;\n", gMajorInterfaceVersion); - fprintf(versionFile, "\tstatic constexpr long long minorVersion = %lld;\n", lMaxMinorVersion); - fprintf(versionFile, "\tstatic constexpr const char* version = \"%i.%lld.0\";\n", gMajorInterfaceVersion, lMaxMinorVersion); + char* szNumericDate = ConvertUnixTimeToNumericDate(lMaxMinorVersion); + fprintf(versionFile, "\tstatic constexpr long long minorVersion = %s;\n", szNumericDate); + fprintf(versionFile, "\tstatic constexpr const char* version = \"%i.0.%s\";\n", gMajorInterfaceVersion, szNumericDate); + free(szNumericDate); fprintf(versionFile, "};\n\n"); fprintf(versionFile, "#ifndef NO_NAMESPACE\n"); diff --git a/compiler/core/time_helpers.c b/compiler/core/time_helpers.c index 2e1842c9..06918254 100644 --- a/compiler/core/time_helpers.c +++ b/compiler/core/time_helpers.c @@ -151,6 +151,38 @@ char* ConvertUnixTimeToReadable(const long long tmUnixTime) return szBuffer; } +/** + * Converts a unix time into a numeric readable date in sorted notation (20240920) + * + * Returns a pointer to a buffer that needs to get released with Free + */ +char* ConvertUnixTimeToNumericDate(const long long tmUnixTime) +{ + if (tmUnixTime <= 0) + return NULL; + + char* szBuffer = malloc(128); + if (!szBuffer) + return NULL; + + if (tmUnixTime == 0) + strcpy_s(szBuffer, 127, "0"); + else + { +#ifdef _WIN32 + struct tm timeinfo; + localtime_s(&timeinfo, &tmUnixTime); + strftime(szBuffer, 128, "%Y%m%d", &timeinfo); +#else + struct tm* timeinfo; + timeinfo = localtime((const time_t*)&tmUnixTime); + strftime(szBuffer, 128, "%Y%m%d", timeinfo); +#endif + } + + return szBuffer; +} + /** * Converts a unix time into an ISO timestamp * diff --git a/compiler/core/time_helpers.h b/compiler/core/time_helpers.h index b53f35b1..e37ba2f2 100644 --- a/compiler/core/time_helpers.h +++ b/compiler/core/time_helpers.h @@ -19,6 +19,13 @@ long long ConvertDateToUnixTime(const char* szDate); */ char* ConvertUnixTimeToReadable(const long long tmUnixTime); +/** + * Converts a unix time into a numeric readable date in sorted notation (20240920) + * + * Returns a pointer to a buffer that needs to get released with Free + */ +char* ConvertUnixTimeToNumericDate(const long long tmUnixTime); + /** * Converts a unix time into an ISO timestamp * From 93c92ca6895adeea0d225a75aae92a40067823cb Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Fri, 20 Sep 2024 21:28:07 +0200 Subject: [PATCH 3/6] BUILDSYS-380 fixes --- compiler/core/time_helpers.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/core/time_helpers.c b/compiler/core/time_helpers.c index 06918254..4ad4ff91 100644 --- a/compiler/core/time_helpers.c +++ b/compiler/core/time_helpers.c @@ -127,7 +127,7 @@ long long ConvertDateToUnixTime(const char* szDate) /** * Converts a unix time into something readable * - * Returns a pointer to a buffer that needs to get released with Free + * Returns a pointer to a buffer that needs to get released with Free "20.09.2024" */ char* ConvertUnixTimeToReadable(const long long tmUnixTime) { @@ -138,6 +138,8 @@ char* ConvertUnixTimeToReadable(const long long tmUnixTime) if (!szBuffer) return NULL; + memset(szBuffer, 127, 0x00); + #ifdef _WIN32 struct tm timeinfo; localtime_s(&timeinfo, &tmUnixTime); @@ -154,7 +156,7 @@ char* ConvertUnixTimeToReadable(const long long tmUnixTime) /** * Converts a unix time into a numeric readable date in sorted notation (20240920) * - * Returns a pointer to a buffer that needs to get released with Free + * Returns a pointer to a buffer that needs to get released with Free "20240920" or "0" */ char* ConvertUnixTimeToNumericDate(const long long tmUnixTime) { @@ -165,6 +167,8 @@ char* ConvertUnixTimeToNumericDate(const long long tmUnixTime) if (!szBuffer) return NULL; + memset(szBuffer, 127, 0x00); + if (tmUnixTime == 0) strcpy_s(szBuffer, 127, "0"); else @@ -194,6 +198,8 @@ char* ConvertUnixTimeToISO(const long long tmUnixTime) if (!szBuffer) return NULL; + memset(szBuffer, 127, 0x00); + #ifdef _WIN32 struct tm timeinfo; localtime_s(&timeinfo, &tmUnixTime); From 9f9ece7f9fb08742a3fb88ee7b12b51cf98890f0 Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Fri, 20 Sep 2024 21:34:59 +0200 Subject: [PATCH 4/6] BUILDSYS-380 fixes --- compiler/core/time_helpers.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler/core/time_helpers.c b/compiler/core/time_helpers.c index 4ad4ff91..1244558a 100644 --- a/compiler/core/time_helpers.c +++ b/compiler/core/time_helpers.c @@ -131,24 +131,26 @@ long long ConvertDateToUnixTime(const char* szDate) */ char* ConvertUnixTimeToReadable(const long long tmUnixTime) { - if (tmUnixTime <= 0) - return NULL; - char* szBuffer = malloc(128); if (!szBuffer) return NULL; memset(szBuffer, 127, 0x00); + if (tmUnixTime == 0) + strcpy_s(szBuffer, 127, "0"); + else + { #ifdef _WIN32 - struct tm timeinfo; - localtime_s(&timeinfo, &tmUnixTime); - strftime(szBuffer, 128, "%d.%m.%Y", &timeinfo); + struct tm timeinfo; + localtime_s(&timeinfo, &tmUnixTime); + strftime(szBuffer, 128, "%d.%m.%Y", &timeinfo); #else - struct tm* timeinfo; - timeinfo = localtime((const time_t*)&tmUnixTime); - strftime(szBuffer, 128, "%d.%m.%Y", timeinfo); + struct tm* timeinfo; + timeinfo = localtime((const time_t*)&tmUnixTime); + strftime(szBuffer, 128, "%d.%m.%Y", timeinfo); #endif + } return szBuffer; } @@ -160,9 +162,6 @@ char* ConvertUnixTimeToReadable(const long long tmUnixTime) */ char* ConvertUnixTimeToNumericDate(const long long tmUnixTime) { - if (tmUnixTime <= 0) - return NULL; - char* szBuffer = malloc(128); if (!szBuffer) return NULL; From 26823f39b3d780a80fceefebddd754bfc63e3e84 Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Fri, 20 Sep 2024 21:35:41 +0200 Subject: [PATCH 5/6] BUILDSYS-448 bumped to 6.0.19 --- version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/version.h b/version.h index 7da0d212..38a1b4ae 100644 --- a/version.h +++ b/version.h @@ -1,8 +1,8 @@ #ifndef VERSION_H #define VERSION_H -#define VERSION "6.0.18" -#define VERSION_RC 6, 0, 18 -#define RELDATE "19.09.2024" +#define VERSION "6.0.19" +#define VERSION_RC 6, 0, 19 +#define RELDATE "20.09.2024" #endif // VERSION_H From bb1ce0d3409cc8b02bcc253f3dc7a1641d7d1a02 Mon Sep 17 00:00:00 2001 From: Jan Fellner Date: Fri, 20 Sep 2024 21:43:56 +0200 Subject: [PATCH 6/6] BUILDSYS-448 fixed build --- compiler/core/time_helpers.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/core/time_helpers.c b/compiler/core/time_helpers.c index 1244558a..19f3ec2a 100644 --- a/compiler/core/time_helpers.c +++ b/compiler/core/time_helpers.c @@ -3,6 +3,7 @@ #include #include #include "../../snacc_defines.h" +#include "../../c-lib/include/asn-config.h" #if TIME_WITH_SYS_TIME #include @@ -135,7 +136,7 @@ char* ConvertUnixTimeToReadable(const long long tmUnixTime) if (!szBuffer) return NULL; - memset(szBuffer, 127, 0x00); + memset(szBuffer, 0x00, 127); if (tmUnixTime == 0) strcpy_s(szBuffer, 127, "0"); @@ -166,7 +167,7 @@ char* ConvertUnixTimeToNumericDate(const long long tmUnixTime) if (!szBuffer) return NULL; - memset(szBuffer, 127, 0x00); + memset(szBuffer, 0x00, 127); if (tmUnixTime == 0) strcpy_s(szBuffer, 127, "0"); @@ -197,7 +198,7 @@ char* ConvertUnixTimeToISO(const long long tmUnixTime) if (!szBuffer) return NULL; - memset(szBuffer, 127, 0x00); + memset(szBuffer, 0x00, 127); #ifdef _WIN32 struct tm timeinfo;