From patchwork Thu Oct 13 21:04:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Elsing X-Patchwork-Id: 43385 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id A5E6027BBE9; Thu, 13 Oct 2022 22:06:48 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 178CE27BBEA for ; Thu, 13 Oct 2022 22:06:47 +0100 (BST) Received: from localhost ([::1]:52932 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oj5Pi-0003Ym-6R for patchwork@mira.cbaines.net; Thu, 13 Oct 2022 17:06:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45126) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oj5P3-00032M-Cw for guix-patches@gnu.org; Thu, 13 Oct 2022 17:06:06 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:36091) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oj5P2-0007Uf-62 for guix-patches@gnu.org; Thu, 13 Oct 2022 17:06:05 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1oj5P2-0005my-0z for guix-patches@gnu.org; Thu, 13 Oct 2022 17:06:04 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#58261] [PATCH v3 07/15] gnu: Add sajson-for-gemmi. Resent-From: David Elsing Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 13 Oct 2022 21:06:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 58261 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 58261@debbugs.gnu.org Cc: David Elsing Received: via spool by 58261-submit@debbugs.gnu.org id=B58261.166569511622094 (code B ref 58261); Thu, 13 Oct 2022 21:06:03 +0000 Received: (at 58261) by debbugs.gnu.org; 13 Oct 2022 21:05:16 +0000 Received: from localhost ([127.0.0.1]:35147 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oj5OF-0005kB-ET for submit@debbugs.gnu.org; Thu, 13 Oct 2022 17:05:16 -0400 Received: from mout01.posteo.de ([185.67.36.65]:55361) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oj5Nw-0005hF-FO for 58261@debbugs.gnu.org; Thu, 13 Oct 2022 17:04:57 -0400 Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id F2343240027 for <58261@debbugs.gnu.org>; Thu, 13 Oct 2022 23:04:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1665695091; bh=IWZ0Gtu/G8X7HUVM4xl8sRc99uIUqsH3k5jyIto+DXI=; h=From:To:Cc:Subject:Date:From; b=OiaaulYl144IN2JJq9wSoTF0hbo4lhMApfuTkLrXoPGhp6uoL22fYCreTzPlu1h8k WYIHzkEYUo2nn3nVMZCWbjzm5CP7ueFPBAiWHMhZZ558sXdoL71e4rZWMQHwcEsXVi ndiD5mEikYLKi2QG1ZVasOL7GpsgvnT3meecSu8XQOiWJSFQG+P/uGmievhxoLib+s DDjqwqdqLtYe+USut0E/I2oKjNTc2wvCXpaGB7gJtBdOW29jYWThw0Vna5BPHiRwRA OWG/X5Ex2r5ilDDAl5raDtJjf98hyxskW6Fgq+NPvp5W48PIEy6vZMsfs7LzEC7X2i EUgKLej0G9lpw== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4MpMTt44wpz6tmH; Thu, 13 Oct 2022 23:04:50 +0200 (CEST) From: David Elsing Date: Thu, 13 Oct 2022 21:04:16 +0000 Message-Id: <20221013210424.993-8-david.elsing@posteo.net> In-Reply-To: <20221007152148.32591-1-david.elsing@posteo.net> References: <20221007152148.32591-1-david.elsing@posteo.net> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * 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 ;;; Copyright © 2020 Vincent Legoll ;;; Copyright © 2021 Ricardo Wurmus +;;; Copyright © 2022 David Elsing ;;; ;;; 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(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 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(u)); + return std::make_pair(p, tag::integer); + } + }