summaryrefslogtreecommitdiff
path: root/src/coding.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/coding.c')
-rw-r--r--src/coding.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/coding.c b/src/coding.c
index 2c6b2c4d051..9cba6494a8d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -6353,6 +6353,29 @@ utf8_string_p (Lisp_Object string)
return check_utf_8 (&coding) != -1;
}
+/* Like make_string, but always returns a multibyte Lisp string, and
+ avoids decoding if TEXT encoded in UTF-8. */
+
+Lisp_Object
+make_string_from_utf8 (const char *text, ptrdiff_t nbytes)
+{
+ ptrdiff_t chars, bytes;
+ parse_str_as_multibyte ((const unsigned char *) text, nbytes,
+ &chars, &bytes);
+ /* If TEXT is a valid UTF-8 string, we can convert it to a Lisp
+ string directly. Otherwise, we need to decode it. */
+ if (chars == nbytes || bytes == nbytes)
+ return make_specified_string (text, chars, nbytes, true);
+ else
+ {
+ struct coding_system coding;
+ setup_coding_system (Qutf_8_unix, &coding);
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ coding.source = (const unsigned char *) text;
+ decode_coding_object (&coding, Qnil, 0, 0, nbytes, nbytes, Qt);
+ return coding.dst_object;
+ }
+}
/* Detect how end-of-line of a text of length SRC_BYTES pointed by
SOURCE is encoded. If CATEGORY is one of