123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230(** C function bindings for QuickJS utilities
This module defines the FFI bindings to QuickJS's internal libraries:
- libregexp: Regular expression engine
- libunicode: Unicode character utilities
- dtoa: Number ↔ String conversion (js_dtoa, js_atod)
- cutils: Integer to string conversion (itoa family) *)[@@@ocamlformat"disable"](* We want to keep the comments aligned with the C code *)moduleFunctions(F:Ctypes.FOREIGN)=structlet(@->)=F.(@->)(* =========================================================================
libregexp.c - Regular Expression Engine
QuickJS's ES2023-compliant regex engine with Unicode support.
========================================================================= *)(** Compile a regular expression pattern into bytecode.
Returns pointer to bytecode buffer, or NULL on error with message in error_msg. *)letlre_compile=F.foreign"lre_compile"(Ctypes.ptrCtypes.int(* [out] int *plen - bytecode length *)@->Ctypes.ptrCtypes.char(* [out] char *error_msg *)@->Ctypes.int(* int error_msg_size *)@->Ctypes.ocaml_string(* const char *buf - pattern *)@->Ctypes.size_t(* size_t buf_len *)@->Ctypes.int(* int re_flags *)@->Ctypes.ptrCtypes.void(* void *opaque *)@->F.returning(Ctypes.ptrCtypes.uint8_t))(** Execute a compiled regex against input string.
Returns: 1 = match, 0 = no match, -1 = error *)letlre_exec=F.foreign"lre_exec"(Ctypes.ptr(Ctypes.ptrCtypes.uint8_t)(* [out] uint8_t **capture *)@->Ctypes.ptrCtypes.uint8_t(* const uint8_t *bc_buf - bytecode *)@->Ctypes.ptrCtypes.uint8_t(* const uint8_t *cbuf - input *)@->Ctypes.int(* int cindex - start index *)@->Ctypes.int(* int clen - input length *)@->Ctypes.int(* int cbuf_type: 0=8bit, 1=16bit *)@->Ctypes.ptrCtypes.void(* void *opaque *)@->F.returningCtypes.int)(** Get number of capture groups (including group 0 for full match) *)letlre_get_capture_count=F.foreign"lre_get_capture_count"(Ctypes.ptrCtypes.uint8_t(* const uint8_t *bc_buf *)@->F.returningCtypes.int)(** Get pointer to null-terminated group names (via shim) *)letlre_get_groupnames=F.foreign"lre_get_groupnames_shim"(Ctypes.ptrCtypes.uint8_t(* const uint8_t *bc_buf *)@->F.returning(Ctypes.ptr_optCtypes.char))(** Get flags from compiled bytecode *)letlre_get_flags=F.foreign"lre_get_flags"(Ctypes.ptrCtypes.uint8_t(* const uint8_t *bc_buf *)@->F.returningCtypes.int)(* =========================================================================
libunicode.c - Unicode Character Utilities
Unicode character classification and case conversion.
========================================================================= *)(* --- Character Classification --- *)(** Check if character has uppercase/lowercase variants (Cased property) *)letlre_is_cased=F.foreign"lre_is_cased"(Ctypes.uint32_t@->F.returningCtypes.int)(** Check if character is ignored during case mapping (Case_Ignorable) *)letlre_is_case_ignorable=F.foreign"lre_is_case_ignorable"(Ctypes.uint32_t@->F.returningCtypes.int)(** Check if character can start an identifier (ID_Start) *)letlre_is_id_start=F.foreign"lre_is_id_start"(Ctypes.uint32_t@->F.returningCtypes.int)(** Check if character can continue an identifier (ID_Continue) *)letlre_is_id_continue=F.foreign"lre_is_id_continue"(Ctypes.uint32_t@->F.returningCtypes.int)(** Check if non-ASCII character is whitespace (for codepoints >= 256) *)letlre_is_space_non_ascii=F.foreign"lre_is_space_non_ascii"(Ctypes.uint32_t@->F.returningCtypes.int)(* --- Case Conversion --- *)(** Convert character case.
conv_type: 0 = uppercase, 1 = lowercase, 2 = case folding
Returns number of output codepoints (1-3) *)letlre_case_conv=F.foreign"lre_case_conv"(Ctypes.ptrCtypes.uint32_t(* [out] uint32_t *res - output buffer *)@->Ctypes.uint32_t(* uint32_t c - input codepoint *)@->Ctypes.int(* int conv_type *)@->F.returningCtypes.int)(** Canonicalize character for case-insensitive regex matching.
is_unicode: 1 = full Unicode folding, 0 = ASCII only *)letlre_canonicalize=F.foreign"lre_canonicalize"(Ctypes.uint32_t(* uint32_t c *)@->Ctypes.int(* int is_unicode *)@->F.returningCtypes.int)(* --- Normalization --- *)(** Normalize Unicode string (via C shim that handles allocation).
n_type: 0 = NFC, 1 = NFD, 2 = NFKC, 3 = NFKD
Returns length of output, or -1 on error *)letunicode_normalize_shim=F.foreign"unicode_normalize_shim"(Ctypes.ptrCtypes.uint32_t(* const uint32_t *src *)@->Ctypes.int(* int src_len *)@->Ctypes.int(* int n_type *)@->Ctypes.ptr(Ctypes.ptrCtypes.uint32_t)(* [out] uint32_t **pdst *)@->F.returningCtypes.int)(** Free buffer allocated by unicode_normalize_shim *)letunicode_normalize_free=F.foreign"unicode_normalize_free"(Ctypes.ptrCtypes.uint32_t@->F.returningCtypes.void)(* =========================================================================
dtoa.c - Number ↔ String Conversion
JavaScript-compatible floating point parsing and formatting.
dtoa = Double TO Ascii, atod = Ascii TO Double
========================================================================= *)(* --- dtoa: Double → String --- *)(** Calculate maximum buffer size needed for js_dtoa *)letjs_dtoa_max_len=F.foreign"js_dtoa_max_len"(Ctypes.double(* double d *)@->Ctypes.int(* int radix *)@->Ctypes.int(* int n_digits *)@->Ctypes.int(* int flags *)@->F.returningCtypes.int)(** Convert double to string with JS semantics.
Flags: JS_DTOA_FORMAT_* | JS_DTOA_EXP_* | JS_DTOA_MINUS_ZERO
Returns actual string length *)letjs_dtoa=F.foreign"js_dtoa"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.double(* double d *)@->Ctypes.int(* int radix (2-36) *)@->Ctypes.int(* int n_digits *)@->Ctypes.int(* int flags *)@->Ctypes.ptrCtypes.void(* JSDTOATempMem *tmp_mem *)@->F.returningCtypes.int)(* --- atod: String → Double --- *)(** Parse string to double with JS semantics (via shim).
Flags: JS_ATOD_INT_ONLY | JS_ATOD_ACCEPT_BIN_OCT | etc.
Sets *pnext to position after parsed number *)letjs_atod=F.foreign"js_atod_shim"(Ctypes.string(* const char *str *)@->Ctypes.ptr(Ctypes.ptrCtypes.char)(* [out] char **pnext *)@->Ctypes.int(* int radix (0=auto, 2-36) *)@->Ctypes.int(* int flags *)@->Ctypes.ptrCtypes.void(* JSATODTempMem *tmp_mem *)@->F.returningCtypes.double)(* =========================================================================
cutils.c - Integer to String Conversion
Fast integer-to-string functions (itoa family).
========================================================================= *)(** Convert unsigned 32-bit integer to decimal string *)letu32toa=F.foreign"u32toa"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.uint32_t(* uint32_t n *)@->F.returningCtypes.size_t)(** Convert signed 32-bit integer to decimal string *)leti32toa=F.foreign"i32toa"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.int32_t(* int32_t n *)@->F.returningCtypes.size_t)(** Convert unsigned 64-bit integer to decimal string *)letu64toa=F.foreign"u64toa"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.uint64_t(* uint64_t n *)@->F.returningCtypes.size_t)(** Convert signed 64-bit integer to decimal string *)leti64toa=F.foreign"i64toa"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.int64_t(* int64_t n *)@->F.returningCtypes.size_t)(** Convert unsigned 64-bit integer to string in given radix (2-36) *)letu64toa_radix=F.foreign"u64toa_radix"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.uint64_t(* uint64_t n *)@->Ctypes.uint(* unsigned int radix *)@->F.returningCtypes.size_t)(** Convert signed 64-bit integer to string in given radix (2-36) *)leti64toa_radix=F.foreign"i64toa_radix"(Ctypes.ptrCtypes.char(* [out] char *buf *)@->Ctypes.int64_t(* int64_t n *)@->Ctypes.int(* int radix *)@->F.returningCtypes.size_t)end