diff options
| -rw-r--r-- | doc/lispref/internals.texi | 12 | ||||
| -rw-r--r-- | test/data/emacs-module/mod-test.c | 17 | ||||
| -rw-r--r-- | test/src/emacs-module-tests.el | 19 |
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 | ||
| 1408 | If @var{time} has higher precision than nanoseconds, then this | 1408 | If @var{time} has higher precision than nanoseconds, then this |
| 1409 | function truncates it to nanosecond precision. This function signals | 1409 | function truncates it to nanosecond precision towards negative |
| 1410 | an error if @var{time} (truncated to nanoseconds) cannot be | 1410 | infinity. This function signals an error if @var{time} (truncated to |
| 1411 | represented by @code{struct timespec}. For example, if @code{time_t} | 1411 | nanoseconds) cannot be represented by @code{struct timespec}. For |
| 1412 | is a 32-bit integral type, then a @var{time} value of ten billion | 1412 | example, if @code{time_t} is a 32-bit integral type, then a @var{time} |
| 1413 | seconds would signal an error, but a @var{time} value of 600 | 1413 | value of ten billion seconds would signal an error, but a @var{time} |
| 1414 | picoseconds would get truncated to zero. | 1414 | value of 600 picoseconds would get truncated to zero. |
| 1415 | 1415 | ||
| 1416 | If you need to deal with time values that are not representable by | 1416 | If 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 | ||
| 384 | static emacs_value | 384 | static emacs_value |
| 385 | Fmod_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 | |||
| 400 | static emacs_value | ||
| 385 | Fmod_test_double (emacs_env *env, ptrdiff_t nargs, emacs_value *args, | 401 | Fmod_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) |