[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 12175a3 3/3: Allow creating unibyte strings from Emacs modules
From: |
Lars Ingebrigtsen |
Subject: |
master 12175a3 3/3: Allow creating unibyte strings from Emacs modules |
Date: |
Tue, 13 Oct 2020 00:53:00 -0400 (EDT) |
branch: master
commit 12175a339e2a2214fdd0ab4e16d8d8b1e92a78d3
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Allow creating unibyte strings from Emacs modules
* doc/lispref/internals.texi (Module Values): Document
make_unibyte_string (bug#34873).
* src/emacs-module.c (module_make_unibyte_string): New function.
(initialize_environment): Export it.
* src/module-env-25.h: Define it.
* test/data/emacs-module/mod-test.c (Fmod_test_return_unibyte):
Test it.
* test/src/emacs-module-tests.el (module/unibyte): Test it.
---
doc/lispref/internals.texi | 6 ++++++
src/emacs-module.c | 13 +++++++++++++
src/module-env-25.h | 5 +++++
test/data/emacs-module/mod-test.c | 11 +++++++++++
test/src/emacs-module-tests.el | 6 ++++++
5 files changed, 41 insertions(+)
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index fed9612..bb25983 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -1854,6 +1854,12 @@ raises the @code{overflow-error} error condition if
@var{len} is
negative or exceeds the maximum length of an Emacs string.
@end deftypefn
+@deftypefn Function emacs_value make_unibyte_string (emacs_env *@var{env},
const char *@var{str}, ptrdiff_t @var{len})
+This function is like @code{make_string}, but has no restrictions on
+the values of the bytes in the C string, and can be used to pass
+binary data to Emacs in the form of a unibyte string.
+@end deftypefn
+
The @acronym{API} does not provide functions to manipulate Lisp data
structures, for example, create lists with @code{cons} and @code{list}
(@pxref{Building Lists}), extract list members with @code{car} and
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 3581daa..ba9de58 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -791,6 +791,18 @@ module_make_string (emacs_env *env, const char *str,
ptrdiff_t len)
}
static emacs_value
+module_make_unibyte_string (emacs_env *env, const char *str, ptrdiff_t length)
+{
+ MODULE_FUNCTION_BEGIN (NULL);
+ if (! (0 <= length && length <= STRING_BYTES_BOUND))
+ overflow_error ();
+ Lisp_Object lstr = make_uninit_string (length);
+ memcpy (SDATA (lstr), str, length);
+ SDATA (lstr)[length] = 0;
+ return lisp_to_value (env, lstr);
+}
+
+static emacs_value
module_make_user_ptr (emacs_env *env, emacs_finalizer fin, void *ptr)
{
MODULE_FUNCTION_BEGIN (NULL);
@@ -1464,6 +1476,7 @@ initialize_environment (emacs_env *env, struct
emacs_env_private *priv)
env->make_float = module_make_float;
env->copy_string_contents = module_copy_string_contents;
env->make_string = module_make_string;
+ env->make_unibyte_string = module_make_unibyte_string;
env->make_user_ptr = module_make_user_ptr;
env->get_user_ptr = module_get_user_ptr;
env->set_user_ptr = module_set_user_ptr;
diff --git a/src/module-env-25.h b/src/module-env-25.h
index 97c7787..01c06d5 100644
--- a/src/module-env-25.h
+++ b/src/module-env-25.h
@@ -102,6 +102,11 @@
const char *str, ptrdiff_t len)
EMACS_ATTRIBUTE_NONNULL(1, 2);
+ /* Create a unibyte Lisp string from a string. */
+ emacs_value (*make_unibyte_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
/* Embedded pointer type. */
emacs_value (*make_user_ptr) (emacs_env *env,
void (*fin) (void *) EMACS_NOEXCEPT,
diff --git a/test/data/emacs-module/mod-test.c
b/test/data/emacs-module/mod-test.c
index da298d4..258a679 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -268,6 +268,16 @@ Fmod_test_string_a_to_b (emacs_env *env, ptrdiff_t nargs,
emacs_value args[],
}
+/* Return a unibyte string. */
+static emacs_value
+Fmod_test_return_unibyte (emacs_env *env, ptrdiff_t nargs, emacs_value args[],
+ void *data)
+{
+ const char *string = "foo\x00zot";
+ return env->make_unibyte_string (env, string, 7);
+}
+
+
/* Embedded pointers in lisp objects. */
/* C struct (pointer to) that will be embedded. */
@@ -750,6 +760,7 @@ emacs_module_init (struct emacs_runtime *ert)
DEFUN ("mod-test-globref-reordered", Fmod_test_globref_reordered, 0, 0, NULL,
NULL);
DEFUN ("mod-test-string-a-to-b", Fmod_test_string_a_to_b, 1, 1, NULL, NULL);
+ DEFUN ("mod-test-return-unibyte", Fmod_test_return_unibyte, 0, 0, NULL,
NULL);
DEFUN ("mod-test-userptr-make", Fmod_test_userptr_make, 1, 1, NULL, NULL);
DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get, 1, 1, NULL, NULL);
DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill, 2, 2, NULL, NULL);
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 1eebb41..621229c 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -500,4 +500,10 @@ See Bug#36226."
(should (eq (mod-test-identity 123) 123))
(should-not (call-interactively #'mod-test-identity)))
+(ert-deftest module/unibyte ()
+ (let ((result (mod-test-return-unibyte)))
+ (should (stringp result))
+ (should (not (multibyte-string-p (mod-test-return-unibyte))))
+ (should (equal result "foo\x00zot"))))
+
;;; emacs-module-tests.el ends here