Package: guix-patches;
Reported by: David Elsing <david.elsing <at> posteo.net>
Date: Mon, 3 Oct 2022 00:06:02 UTC
Severity: normal
Tags: patch
Done: Liliana Marie Prikler <liliana.prikler <at> gmail.com>
Bug is archived. No further changes may be made.
Message #221 received at 58261 <at> debbugs.gnu.org (full text, mbox):
From: David Elsing <david.elsing <at> posteo.net> To: 58261 <at> debbugs.gnu.org Cc: David Elsing <david.elsing <at> posteo.net> Subject: [PATCH v3 07/15] gnu: Add sajson-for-gemmi. Date: Thu, 13 Oct 2022 21:04:16 +0000
* gnu/packages/chemistry.scm (sajson-for-gemmi): New variable. --- gnu/packages/chemistry.scm | 23 +++ .../sajson-for-gemmi-numbers-as-strings.patch | 195 ++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 gnu/packages/patches/sajson-for-gemmi-numbers-as-strings.patch diff --git a/gnu/packages/chemistry.scm b/gnu/packages/chemistry.scm index c517610fe8..723b7ee8db 100644 --- a/gnu/packages/chemistry.scm +++ b/gnu/packages/chemistry.scm @@ -6,6 +6,7 @@ ;;; Copyright © 2020 Björn Höfling <bjoern.hoefling <at> bjoernhoefling.de> ;;; Copyright © 2020 Vincent Legoll <vincent.legoll <at> gmail.com> ;;; Copyright © 2021 Ricardo Wurmus <rekado <at> elephly.net> +;;; Copyright © 2022 David Elsing <david.elsing <at> posteo.net> ;;; ;;; This file is part of GNU Guix. ;;; @@ -27,6 +28,7 @@ (define-module (gnu packages chemistry) #:use-module (guix utils) #:use-module ((guix licenses) #:prefix license:) #:use-module (guix download) + #:use-module (guix gexp) #:use-module (guix git-download) #:use-module (gnu packages) #:use-module (gnu packages algebra) @@ -35,6 +37,7 @@ (define-module (gnu packages chemistry) #:use-module (gnu packages boost) #:use-module (gnu packages check) #:use-module (gnu packages compression) + #:use-module (gnu packages cpp) #:use-module (gnu packages documentation) #:use-module (gnu packages fontutils) #:use-module (gnu packages gl) @@ -50,8 +53,10 @@ (define-module (gnu packages chemistry) #:use-module (gnu packages qt) #:use-module (gnu packages serialization) #:use-module (gnu packages sphinx) + #:use-module (gnu packages stb) #:use-module (gnu packages xml) #:use-module (guix build-system cmake) + #:use-module (guix build-system copy) #:use-module (guix build-system gnu) #:use-module (guix build-system python)) @@ -566,3 +571,21 @@ (define-public python-pymol used to prepare publication-quality figures, to share interactive results with your colleagues, or to generate pre-rendered animations.") (license license:bsd-3))) + +(define-public sajson-for-gemmi + (package/inherit sajson + (name "sajson-for-gemmi") + (source (origin + (inherit (package-source sajson)) + (patches (cons + (search-patch + "sajson-for-gemmi-numbers-as-strings.patch") + (origin-patches (package-source sajson)))))) + (arguments + (substitute-keyword-arguments (package-arguments sajson) + ;; This is a modified version used in gemmi, in which numbers are kept + ;; as strings. Building the tests fails with the modification. + ((#:tests? _ #f) #f) + ((#:phases phases) + #~(modify-phases #$phases + (delete 'build))))))) diff --git a/gnu/packages/patches/sajson-for-gemmi-numbers-as-strings.patch b/gnu/packages/patches/sajson-for-gemmi-numbers-as-strings.patch new file mode 100644 index 0000000000..6f476b8583 --- /dev/null +++ b/gnu/packages/patches/sajson-for-gemmi-numbers-as-strings.patch @@ -0,0 +1,195 @@ +Patch for gemmi: Keep numbers in JSON file as strings. + +Adapted from this commit of the bundled fork of sajson in gemmi: +https://github.com/project-gemmi/gemmi/commit/fccbca4f6040364ba708613e1429c2251872240d + +diff -ur a/include/sajson.h b/include/sajson.h +--- a/include/sajson.h ++++ b/include/sajson.h +@@ -411,43 +411,6 @@ + }; + } // namespace internal + +-namespace integer_storage { +-enum { word_length = 1 }; +- +-inline int load(const size_t* location) { +- int value; +- memcpy(&value, location, sizeof(value)); +- return value; +-} +- +-inline void store(size_t* location, int value) { +- // NOTE: Most modern compilers optimize away this constant-size +- // memcpy into a single instruction. If any don't, and treat +- // punning through a union as legal, they can be special-cased. +- static_assert( +- sizeof(value) <= sizeof(*location), +- "size_t must not be smaller than int"); +- memcpy(location, &value, sizeof(value)); +-} +-} // namespace integer_storage +- +-namespace double_storage { +-enum { word_length = sizeof(double) / sizeof(size_t) }; +- +-inline double load(const size_t* location) { +- double value; +- memcpy(&value, location, sizeof(double)); +- return value; +-} +- +-inline void store(size_t* location, double value) { +- // NOTE: Most modern compilers optimize away this constant-size +- // memcpy into a single instruction. If any don't, and treat +- // punning through a union as legal, they can be special-cased. +- memcpy(location, &value, sizeof(double)); +-} +-} // namespace double_storage +- + /// Represents a JSON value. First, call get_type() to check its type, + /// which determines which methods are available. + /// +@@ -585,70 +548,10 @@ + return length; + } + +- /// If a numeric value was parsed as a 32-bit integer, returns it. +- /// Only legal if get_type() is TYPE_INTEGER. +- int get_integer_value() const { +- assert_tag(tag::integer); +- return integer_storage::load(payload); +- } +- +- /// If a numeric value was parsed as a double, returns it. +- /// Only legal if get_type() is TYPE_DOUBLE. +- double get_double_value() const { +- assert_tag(tag::double_); +- return double_storage::load(payload); +- } +- +- /// Returns a numeric value as a double-precision float. +- /// Only legal if get_type() is TYPE_INTEGER or TYPE_DOUBLE. +- double get_number_value() const { +- assert_tag_2(tag::integer, tag::double_); +- if (value_tag == tag::integer) { +- return get_integer_value(); +- } else { +- return get_double_value(); +- } +- } +- +- /// Returns true and writes to the output argument if the numeric value +- /// fits in a 53-bit integer. This is useful for timestamps and other +- /// situations where integral values with greater than 32-bit precision +- /// are used, as 64-bit values are not understood by all JSON +- /// implementations or languages. +- /// Returns false if the value is not an integer or not in range. +- /// Only legal if get_type() is TYPE_INTEGER or TYPE_DOUBLE. +- bool get_int53_value(int64_t* out) const { +- // Make sure the output variable is always defined to avoid any +- // possible situation like +- // https://gist.github.com/chadaustin/2c249cb850619ddec05b23ca42cf7a18 +- *out = 0; +- +- assert_tag_2(tag::integer, tag::double_); +- switch (value_tag) { +- case tag::integer: +- *out = get_integer_value(); +- return true; +- case tag::double_: { +- double v = get_double_value(); +- if (v < -(1LL << 53) || v > (1LL << 53)) { +- return false; +- } +- int64_t as_int = static_cast<int64_t>(v); +- if (as_int != v) { +- return false; +- } +- *out = as_int; +- return true; +- } +- default: +- return false; +- } +- } +- + /// Returns the length of the string. + /// Only legal if get_type() is TYPE_STRING. + size_t get_string_length() const { +- assert_tag(tag::string); ++ assert_tag_3(tag::string, tag::integer, tag::double_); + return payload[1] - payload[0]; + } + +@@ -659,7 +562,7 @@ + /// embedded NULs. + /// Only legal if get_type() is TYPE_STRING. + const char* as_cstring() const { +- assert_tag(tag::string); ++ assert_tag_3(tag::string, tag::integer, tag::double_); + return text + payload[0]; + } + +@@ -667,7 +570,7 @@ + /// Returns a string's value as a std::string. + /// Only legal if get_type() is TYPE_STRING. + std::string as_string() const { +- assert_tag(tag::string); ++ assert_tag_3(tag::string, tag::integer, tag::double_); + return std::string(text + payload[0], text + payload[1]); + } + #endif +@@ -690,6 +593,10 @@ + assert(e1 == value_tag || e2 == value_tag); + } + ++ void assert_tag_3(tag e1, tag e2, tag e3) const { ++ assert(e1 == value_tag || e2 == value_tag || e3 == value_tag); ++ } ++ + void assert_in_bounds(size_t i) const { assert(i < get_length()); } + + const tag value_tag; +@@ -2059,6 +1966,8 @@ + std::pair<char*, internal::tag> parse_number(char* p) { + using internal::tag; + ++ size_t start = p - input.get_data(); ++ + // Assume 32-bit, two's complement integers. + static constexpr unsigned RISKY = INT_MAX / 10u; + unsigned max_digit_after_risky = INT_MAX % 10u; +@@ -2235,23 +2144,18 @@ + u = 0u - u; + } + } ++ ++ bool success; ++ size_t* out = allocator.reserve(2, &success); ++ if (SAJSON_UNLIKELY(!success)) { ++ return std::make_pair(oom(p, "number"), tag::null); ++ } ++ out[0] = start; ++ out[1] = p - input.get_data(); ++ + if (try_double) { +- bool success; +- size_t* out +- = allocator.reserve(double_storage::word_length, &success); +- if (SAJSON_UNLIKELY(!success)) { +- return std::make_pair(oom(p, "double"), tag::null); +- } +- double_storage::store(out, d); + return std::make_pair(p, tag::double_); + } else { +- bool success; +- size_t* out +- = allocator.reserve(integer_storage::word_length, &success); +- if (SAJSON_UNLIKELY(!success)) { +- return std::make_pair(oom(p, "integer"), tag::null); +- } +- integer_storage::store(out, static_cast<int>(u)); + return std::make_pair(p, tag::integer); + } + } -- 2.37.0
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.