aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/lispref/internals.texi12
-rw-r--r--test/data/emacs-module/mod-test.c17
-rw-r--r--test/src/emacs-module-tests.el19
3 files changed, 42 insertions, 6 deletions
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 10f49c569fa..3e6488a5ccf 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -1406,12 +1406,12 @@ billion.
1406@xref{Elapsed Time,,,libc}. 1406@xref{Elapsed Time,,,libc}.
1407 1407
1408If @var{time} has higher precision than nanoseconds, then this 1408If @var{time} has higher precision than nanoseconds, then this
1409function truncates it to nanosecond precision. This function signals 1409function truncates it to nanosecond precision towards negative
1410an error if @var{time} (truncated to nanoseconds) cannot be 1410infinity. This function signals an error if @var{time} (truncated to
1411represented by @code{struct timespec}. For example, if @code{time_t} 1411nanoseconds) cannot be represented by @code{struct timespec}. For
1412is a 32-bit integral type, then a @var{time} value of ten billion 1412example, if @code{time_t} is a 32-bit integral type, then a @var{time}
1413seconds would signal an error, but a @var{time} value of 600 1413value of ten billion seconds would signal an error, but a @var{time}
1414picoseconds would get truncated to zero. 1414value of 600 picoseconds would get truncated to zero.
1415 1415
1416If you need to deal with time values that are not representable by 1416If you need to deal with time values that are not representable by
1417@code{struct timespec}, or if you want higher precision, call the Lisp 1417@code{struct timespec}, or if you want higher precision, call the Lisp
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c
index 85a7f28e50d..8ac08f71534 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -382,6 +382,22 @@ Fmod_test_add_nanosecond (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
382} 382}
383 383
384static emacs_value 384static emacs_value
385Fmod_test_nanoseconds (emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data) {
386 assert (nargs == 1);
387 struct timespec time = env->extract_time (env, args[0]);
388 struct emacs_mpz nanoseconds;
389 assert (LONG_MIN <= time.tv_sec && time.tv_sec <= LONG_MAX);
390 mpz_init_set_si (nanoseconds.value, time.tv_sec);
391 static_assert (1000000000 <= ULONG_MAX, "unsupported architecture");
392 mpz_mul_ui (nanoseconds.value, nanoseconds.value, 1000000000);
393 assert (0 <= time.tv_nsec && time.tv_nsec <= ULONG_MAX);
394 mpz_add_ui (nanoseconds.value, nanoseconds.value, time.tv_nsec);
395 emacs_value result = env->make_big_integer (env, &nanoseconds);
396 mpz_clear (nanoseconds.value);
397 return result;
398}
399
400static emacs_value
385Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args, 401Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
386 void *data) 402 void *data)
387{ 403{
@@ -465,6 +481,7 @@ emacs_module_init (struct emacs_runtime *ert)
465 NULL, NULL); 481 NULL, NULL);
466 DEFUN ("mod-test-sleep-until", Fmod_test_sleep_until, 2, 2, NULL, NULL); 482 DEFUN ("mod-test-sleep-until", Fmod_test_sleep_until, 2, 2, NULL, NULL);
467 DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL); 483 DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL);
484 DEFUN ("mod-test-nanoseconds", Fmod_test_nanoseconds, 1, 1, NULL, NULL);
468 DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL); 485 DEFUN ("mod-test-double", Fmod_test_double, 1, 1, NULL, NULL);
469 486
470#undef DEFUN 487#undef DEFUN
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 9eb38cd4548..173b63670fc 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -342,6 +342,25 @@ Interactively, you can try hitting \\[keyboard-quit] to quit."
342 (ert-info ((format "input: %s" input)) 342 (ert-info ((format "input: %s" input))
343 (should-error (mod-test-add-nanosecond input))))) 343 (should-error (mod-test-add-nanosecond input)))))
344 344
345(ert-deftest mod-test-nanoseconds ()
346 "Test truncation when converting to `struct timespec'."
347 (dolist (test-case '((0 . 0)
348 (-1 . -1000000000)
349 ((1 . 1000000000) . 1)
350 ((-1 . 1000000000) . -1)
351 ((1 . 1000000000000) . 0)
352 ((-1 . 1000000000000) . -1)
353 ((999 . 1000000000000) . 0)
354 ((-999 . 1000000000000) . -1)
355 ((1000 . 1000000000000) . 1)
356 ((-1000 . 1000000000000) . -1)
357 ((0 0 0 1) . 0)
358 ((0 0 0 -1) . -1)))
359 (let ((input (car test-case))
360 (expected (cdr test-case)))
361 (ert-info ((format "input: %S, expected result: %d" input expected))
362 (should (eq (mod-test-nanoseconds input) expected))))))
363
345(ert-deftest mod-test-double () 364(ert-deftest mod-test-double ()
346 (dolist (input (list 0 1 2 -1 42 12345678901234567890 365 (dolist (input (list 0 1 2 -1 42 12345678901234567890
347 most-positive-fixnum (1+ most-positive-fixnum) 366 most-positive-fixnum (1+ most-positive-fixnum)