diff options
author | Philipp Stephani <phst@google.com> | 2019-04-18 17:42:45 +0200 |
---|---|---|
committer | Philipp Stephani <phst@google.com> | 2019-04-24 11:33:52 +0200 |
commit | bffceab6339fb4042588b893ef754c6264379e75 (patch) | |
tree | 03747b5cb5275a24418aa9fb421977eb6c0ee063 /test | |
parent | 5ae407aad4f2564fae7ddce077eb01aa8efa37fb (diff) | |
download | emacs-bffceab6339fb4042588b893ef754c6264379e75.tar.gz |
Add conversions to and from struct timespec to module interface.
Time values are a fundamental data type, and such conversions are hard
to implement within modules because of the various forms of time
values in Emacs Lisp. Adding dedicated conversion functions can
significantly simplify module code dealing with times.
This approach uses nanosecond precision. While Emacs in theory has
support for higher-precision time values, in practice most languages
and standards, such as POSIX, C, Java, and Go, have settled on
nanosecond-precision integers to represent time.
* src/emacs-module.h.in: Add header for struct timespec.
* src/module-env-27.h: Add module functions for time conversion.
* src/emacs-module.c (module_extract_time, module_make_time): New
functions.
(initialize_environment): Use them.
* test/data/emacs-module/mod-test.c (Fmod_test_add_nanosecond): New
test function.
(emacs_module_init): Define it.
* test/src/emacs-module-tests.el (mod-test-add-nanosecond/valid)
(mod-test-add-nanosecond/nil, mod-test-add-nanosecond/invalid): New
unit tests.
* doc/lispref/internals.texi (Module Values): Document time
conversion functions.
Diffstat (limited to 'test')
-rw-r--r-- | test/data/emacs-module/mod-test.c | 13 | ||||
-rw-r--r-- | test/src/emacs-module-tests.el | 28 |
2 files changed, 41 insertions, 0 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index a39e41afee6..dbdbfecfe6a 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c @@ -366,6 +366,18 @@ Fmod_test_sleep_until (emacs_env *env, ptrdiff_t nargs, emacs_value *args, return env->intern (env, "finished"); } +static emacs_value +Fmod_test_add_nanosecond (emacs_env *env, ptrdiff_t nargs, emacs_value *args, + void *data) +{ + assert (nargs == 1); + struct timespec time = env->extract_time (env, args[0]); + assert (time.tv_nsec >= 0); + assert (time.tv_nsec < 2000000000); /* possible leap second */ + time.tv_nsec++; + return env->make_time (env, time); +} + /* Lisp utilities for easier readability (simple wrappers). */ /* Provide FEATURE to Emacs. */ @@ -434,6 +446,7 @@ emacs_module_init (struct emacs_runtime *ert) DEFUN ("mod-test-invalid-finalizer", Fmod_test_invalid_finalizer, 0, 0, NULL, NULL); DEFUN ("mod-test-sleep-until", Fmod_test_sleep_until, 2, 2, NULL, NULL); + DEFUN ("mod-test-add-nanosecond", Fmod_test_add_nanosecond, 1, 1, NULL, NULL); #undef DEFUN diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index 35aaaa64b65..eea4c611655 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el @@ -310,4 +310,32 @@ Interactively, you can try hitting \\[keyboard-quit] to quit." 'finished)) (quit))))) +(ert-deftest mod-test-add-nanosecond/valid () + (dolist (input (list + ;; Some realistic examples. + (current-time) (time-to-seconds) + (encode-time 12 34 5 6 7 2019 t) + ;; Various legacy timestamp forms. + '(123 456) '(123 456 789) '(123 456 789 6000) + ;; Corner case: this will result in a nanosecond + ;; value of 1000000000 after addition. The module + ;; code should handle this correctly. + '(123 65535 999999 999000) + ;; Seconds since the epoch. + 123 123.45 + ;; New (TICKS . HZ) format. + '(123456789 . 1000000000))) + (ert-info ((format "input: %s" input)) + (should (time-equal-p (mod-test-add-nanosecond input) + (time-add input '(0 0 0 1000))))))) + +(ert-deftest mod-test-add-nanosecond/nil () + (should (<= (float-time (mod-test-add-nanosecond nil)) + (+ (float-time) 1e-9)))) + +(ert-deftest mod-test-add-nanosecond/invalid () + (dolist (input '(1.0e+INF 1.0e-INF 0.0e+NaN (123) (123.45 6 7) "foo" [1 2])) + (ert-info ((format "input: %s" input)) + (should-error (mod-test-add-nanosecond input))))) + ;;; emacs-module-tests.el ends here |