|
|
@@ -380,6 +380,48 @@ long m2_c_fill(char *buf, long cap, int ch)
|
|
|
return cap - 1;
|
|
|
}
|
|
|
|
|
|
+/* Copy a C string into a V3 CHAR-array descriptor. */
|
|
|
+long m2_cstr_copy(long *dst, const char *src)
|
|
|
+{
|
|
|
+ char *d = (char *)(dst + 1);
|
|
|
+ long cap = dst[0];
|
|
|
+ size_t n;
|
|
|
+
|
|
|
+ if (cap <= 0) return 0;
|
|
|
+ if (!src) {
|
|
|
+ d[0] = 0;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ n = strlen(src);
|
|
|
+ if (n > (size_t)(cap - 1)) n = (size_t)(cap - 1);
|
|
|
+ if (n > 0) memcpy(d, src, n);
|
|
|
+ d[n] = 0;
|
|
|
+ return (long)n;
|
|
|
+}
|
|
|
+
|
|
|
+/* Test helpers for CString returns and char ** outputs. */
|
|
|
+const char *m2_cstr_hello(void)
|
|
|
+{
|
|
|
+ return "hello";
|
|
|
+}
|
|
|
+
|
|
|
+void m2_cstr_out(const char **p)
|
|
|
+{
|
|
|
+ if (p) *p = "world";
|
|
|
+}
|
|
|
+
|
|
|
+long m2_cstr_fill(char *buf, long cap)
|
|
|
+{
|
|
|
+ static const char text[] = "buffer";
|
|
|
+ size_t n = sizeof text - 1;
|
|
|
+
|
|
|
+ if (!buf || cap <= 0) return -1;
|
|
|
+ if (n > (size_t)(cap - 1)) n = (size_t)(cap - 1);
|
|
|
+ memcpy(buf, text, n);
|
|
|
+ buf[n] = 0;
|
|
|
+ return (long)n;
|
|
|
+}
|
|
|
+
|
|
|
/* UString length: the codepoint count is the descriptor's header. */
|
|
|
long m2ustrlen(long *s)
|
|
|
{
|