about summary refs log tree commit diff stats
path: root/lib/monoucha0/monoucha/libregexp.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-18 23:15:21 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-18 23:15:21 +0100
commit28fefabdeb685f4777ad2ad2ebf05e5e94e179d6 (patch)
tree56cd048df4a6987b4d9ef5924942119b3f2fd8aa /lib/monoucha0/monoucha/libregexp.nim
parentb56abad0883c0b4179f9c329a7169bb544fac4a5 (diff)
parent33efaee783c2adb20df019a8bc924411c4a97e7f (diff)
downloadchawan-28fefabdeb685f4777ad2ad2ebf05e5e94e179d6.tar.gz
Add 'lib/monoucha0/' from commit '33efaee783c2adb20df019a8bc924411c4a97e7f'
git-subtree-dir: lib/monoucha0
git-subtree-mainline: b56abad0883c0b4179f9c329a7169bb544fac4a5
git-subtree-split: 33efaee783c2adb20df019a8bc924411c4a97e7f
Diffstat (limited to 'lib/monoucha0/monoucha/libregexp.nim')
-rw-r--r--lib/monoucha0/monoucha/libregexp.nim81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/monoucha0/monoucha/libregexp.nim b/lib/monoucha0/monoucha/libregexp.nim
new file mode 100644
index 00000000..4a118afd
--- /dev/null
+++ b/lib/monoucha0/monoucha/libregexp.nim
@@ -0,0 +1,81 @@
+{.push raises: [].}
+
+from std/os import parentDir
+
+{.used.}
+# used so that we can import it from quickjs.nim
+
+import libunicode
+
+when not compileOption("threads"):
+  const CFLAGS = "-O2 -fwrapv -DMNC_NO_THREADS"
+else:
+  const CFLAGS = "-O2 -fwrapv"
+
+{.compile("qjs/libregexp.c", CFLAGS).}
+
+# this is hardcoded into quickjs, so we must override it here.
+proc lre_realloc(opaque, p: pointer; size: csize_t): pointer {.exportc.} =
+  return realloc(p, size)
+
+# Hack: quickjs provides a lre_check_stack_overflow, but that basically
+# depends on the entire QuickJS runtime. So to avoid pulling that in as
+# a necessary dependency, we must provide one ourselves, but *only* if
+# quickjs has not been imported.
+# So we define NOT_LRE_ONLY in quickjs.nim, and check it in the "second
+# compilation pass" (i.e. in C).
+{.emit: """
+#ifndef NOT_LRE_ONLY
+int lre_check_stack_overflow(void *opaque, size_t alloca_size)
+{
+  return 0;
+}
+#endif
+""".}
+
+type
+  LREFlag* {.size: sizeof(cint).} = enum
+    LRE_FLAG_GLOBAL = "g"
+    LRE_FLAG_IGNORECASE = "i"
+    LRE_FLAG_MULTILINE = "m"
+    LRE_FLAG_DOTALL = "s"
+    LRE_FLAG_UNICODE = "u"
+    LRE_FLAG_STICKY = "y"
+
+  LREFlags* = set[LREFlag]
+
+func toCInt*(flags: LREFlags): cint =
+  cint(cast[uint8](flags))
+
+func toLREFlags*(flags: cint): LREFlags =
+  cast[LREFlags](flags)
+
+{.passc: "-I" & currentSourcePath().parentDir().}
+
+{.push header: "qjs/libregexp.h", importc.}
+proc lre_compile*(plen: ptr cint; error_msg: cstring; error_msg_size: cint;
+  buf: cstring; buf_len: csize_t; re_flags: cint; opaque: pointer): ptr uint8
+
+proc lre_exec*(capture: ptr ptr uint8; bc_buf, cbuf: ptr uint8;
+  cindex, clen, cbuf_type: cint; opaque: pointer): cint
+
+proc lre_get_capture_count*(bc_buf: ptr uint8): cint
+
+proc lre_get_flags*(bc_buf: ptr uint8): cint
+
+const LRE_CC_RES_LEN_MAX* = 3
+
+# conv_type:
+# 0 = to upper
+# 1 = to lower
+# 2 = case folding
+# res must be an array of LRE_CC_RES_LEN_MAX
+proc lre_case_conv*(res: ptr UncheckedArray[uint32]; c: uint32;
+  conv_type: cint): cint
+
+proc lre_is_space_non_ascii*(c: uint32): cint {.importc.}
+
+proc lre_is_space*(c: uint32): cint {.importc.}
+
+{.pop.} # header, importc
+{.pop.} # raises