From 4e2ea400cbd78fa791fb897938a6dcb099401a25 Mon Sep 17 00:00:00 2001 From: Philipp Stephani Date: Mon, 22 Apr 2019 17:29:06 +0200 Subject: [PATCH] Introduce a helper macro to convert a Lisp integer to a C integer. This is similar to CONS_TO_INTEGER. The inverse (INT_TO_INTEGER) already exists. * src/lisp.h (INTEGER_TO_INT): New macro. (ranged_integer_to_int, ranged_integer_to_uint): New functions. * src/json.c (lisp_to_json): Use helper macro. --- src/json.c | 9 +-------- src/lisp.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/json.c b/src/json.c index 928825e034c..16500bce72d 100644 --- a/src/json.c +++ b/src/json.c @@ -495,14 +495,7 @@ lisp_to_json (Lisp_Object lisp, struct json_configuration *conf) else if (EQ (lisp, Qt)) return json_check (json_true ()); else if (INTEGERP (lisp)) - { - intmax_t low = TYPE_MINIMUM (json_int_t); - intmax_t high = TYPE_MAXIMUM (json_int_t); - intmax_t value; - if (! integer_to_intmax (lisp, &value) || value < low || high < value) - args_out_of_range_3 (lisp, make_int (low), make_int (high)); - return json_check (json_integer (value)); - } + return json_check (json_integer (INTEGER_TO_INT (lisp, json_int_t))); else if (FLOATP (lisp)) return json_check (json_real (XFLOAT_DATA (lisp))); else if (STRINGP (lisp)) diff --git a/src/lisp.h b/src/lisp.h index d803f160006..8510ad72564 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2640,6 +2640,13 @@ make_uint (uintmax_t n) #define INT_TO_INTEGER(expr) \ (EXPR_SIGNED (expr) ? make_int (expr) : make_uint (expr)) +/* Return the integral value of NUM. If NUM is too big for TYPE, + signal an error. */ +#define INTEGER_TO_INT(num, type) \ + (TYPE_SIGNED (type) \ + ? ranged_integer_to_int ((num), TYPE_MINIMUM (type), TYPE_MAXIMUM (type)) \ + : ranged_integer_to_uint ((num), TYPE_MINIMUM (type))) + /* Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, @@ -5016,6 +5023,26 @@ maybe_gc (void) garbage_collect (); } +INLINE intmax_t +ranged_integer_to_int (Lisp_Object num, intmax_t min, intmax_t max) +{ + CHECK_INTEGER (num); + intmax_t result; + if (!(integer_to_intmax (num, &result) && min <= result && result <= max)) + args_out_of_range_3 (num, make_int (min), make_int (max)); + return result; +} + +INLINE uintmax_t +ranged_integer_to_uint (Lisp_Object num, uintmax_t max) +{ + CHECK_INTEGER (num); + uintmax_t result; + if (!(integer_to_uintmax (num, &result) && result <= max)) + args_out_of_range_3 (num, make_fixed_natnum (0), make_uint (max)); + return result; +} + INLINE_HEADER_END #endif /* EMACS_LISP_H */ -- 2.39.2