From 53ba9c800a5853eb2ff027685657cdf85b17109a Mon Sep 17 00:00:00 2001 From: Chloe Kudryavtsev Date: Sat, 6 May 2023 22:13:53 -0400 Subject: [PATCH] Add get/opt cbytes Like getcstring, but operates on a byteview. When writing bindings (i.e what capi.c is primarily used for), it's common to want to accept a buffer *or* a string rather than just a string. For this, a byteview is perfect (and why not accept keywords while you're at it?). However, there's no built-in function for getting a cstring out of a byteview, this adds one. This also reformulates getcstring to be an edge-case of getcbytes (simply adding an explicit check for stringness). --- src/core/capi.c | 22 ++++++++++++++++++---- src/include/janet.h | 2 ++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/core/capi.c b/src/core/capi.c index 0b918e0e..4972d8fb 100644 --- a/src/core/capi.c +++ b/src/core/capi.c @@ -209,14 +209,28 @@ const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const c #undef DEFINE_OPTLEN const char *janet_getcstring(const Janet *argv, int32_t n) { - const uint8_t *jstr = janet_getstring(argv, n); - const char *cstr = (const char *)jstr; - if (strlen(cstr) != (size_t) janet_string_length(jstr)) { - janet_panic("string contains embedded 0s"); + if (!janet_checktype(argv[n], JANET_STRING)) { + janet_panic_type(argv[n], n, JANET_TFLAG_STRING); + } + return janet_getcbytes(argv, n); +} + +const char* janet_getcbytes(const Janet *argv, int32_t n) { + JanetByteView view = janet_getbytes(argv, n); + const char *cstr = (const char *)view.bytes; + if (strlen(cstr) != (size_t) view.len) { + janet_panic("bytes contain embedded 0s"); } return cstr; } +const char *janet_optcbytes(const Janet *argv, int32_t argc, int32_t n, const char *dflt) { + if (n >= argc || janet_checktype(argv[n], JANET_NIL)) { + return dflt; + } + return janet_getcbytes(argv, n); +} + int32_t janet_getnat(const Janet *argv, int32_t n) { Janet x = argv[n]; if (!janet_checkint(x)) goto bad; diff --git a/src/include/janet.h b/src/include/janet.h index a6d0d901..88cda071 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1968,6 +1968,7 @@ JANET_API JanetTable *janet_gettable(const Janet *argv, int32_t n); JANET_API JanetStruct janet_getstruct(const Janet *argv, int32_t n); JANET_API JanetString janet_getstring(const Janet *argv, int32_t n); JANET_API const char *janet_getcstring(const Janet *argv, int32_t n); +JANET_API const char *janet_getcbytes(const Janet *argv, int32_t n); JANET_API JanetSymbol janet_getsymbol(const Janet *argv, int32_t n); JANET_API JanetKeyword janet_getkeyword(const Janet *argv, int32_t n); JANET_API JanetBuffer *janet_getbuffer(const Janet *argv, int32_t n); @@ -1997,6 +1998,7 @@ JANET_API JanetTuple janet_opttuple(const Janet *argv, int32_t argc, int32_t n, JANET_API JanetStruct janet_optstruct(const Janet *argv, int32_t argc, int32_t n, JanetStruct dflt); JANET_API JanetString janet_optstring(const Janet *argv, int32_t argc, int32_t n, JanetString dflt); JANET_API const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const char *dflt); +JANET_API const char *janet_optcbytes(const Janet *argv, int32_t argc, int32_t n, const char *dflt); JANET_API JanetSymbol janet_optsymbol(const Janet *argv, int32_t argc, int32_t n, JanetString dflt); JANET_API JanetKeyword janet_optkeyword(const Janet *argv, int32_t argc, int32_t n, JanetString dflt); JANET_API JanetFiber *janet_optfiber(const Janet *argv, int32_t argc, int32_t n, JanetFiber *dflt);