Browse Source

Add support for dynstrings to introspection

master
Macoy Madson 1 year ago
parent
commit
6f41e0ca84
  1. 85
      src/DynamicArray.cake
  2. 29
      src/Introspection.cake

85
src/DynamicArray.cake

@ -403,6 +403,89 @@
(free-introspect-struct-fields (path field > field-type-metadata)
current-element string-free))
(dynarray-free (deref dynarray-ptr))
(set (deref dynarray-ptr) null))
;; Dynstrings
(introspect-override-register-handler 'write-s-expr
(metadata-field-has-tag field "'dynstring")
write-dynstring-ptr
(var dynarray-ptr-write (* (* char))
(offset-pointer-to-type struct-to-write value-offset (* (* char))))
(if (and (deref dynarray-ptr-write)
(dynarray-length (deref dynarray-ptr-write)))
(scope ;; Non-empty
(unless (escape-write-string-element write-func write-func-userdata
(deref dynarray-ptr-write))
(return false)))
(unless (write-func " \"\"" 0 write-func-userdata) (return false)))
(return true))
(introspect-override-register-handler 'read-s-expr
(metadata-field-has-tag field "'dynstring")
read-dynstring-ptr
(var dynarray-ptr-read (* (* char))
(offset-pointer-to-type struct-out value-offset (* (* char))))
;; You need to clean up the elements; I'd just clear them in this function, but that could lead
;; to memory leaks
(assert (not (dynarray-length (deref dynarray-ptr-read))))
(var value-length (unsigned int) (- value-argument-end 1 (+ 1 value-argument-start)))
(when value-length
(dynarray-set-length (deref dynarray-ptr-read) (+ 1 value-length))
(read-escaped-string (deref dynarray-ptr-read) value-length (+ 1 value-argument-start)))
(return true))
(introspect-override-register-handler 'compare
(metadata-field-has-tag field "'dynstring")
compare-dynstring
(var dynstsring-a (* (* char))
(offset-pointer-to-type struct-a value-offset (* (* char))))
(var dynstsring-b (* (* char))
(offset-pointer-to-type struct-b value-offset (* (* char))))
(when (!= (deref dynstsring-a) (deref dynstsring-b))
(var num-elements-a int (dynarray-length (deref dynstsring-a)))
(var num-elements-b int (dynarray-length (deref dynstsring-b)))
(when (!= num-elements-a num-elements-b)
(when print-difference
(fprintf stderr "structs differ by field '%s' [%d] length (%d vs %d)\n"
(path field > name)
(type-cast dispatch-value-index int)
(type-cast (dynarray-length dynstsring-a) int)
(type-cast (dynarray-length dynstsring-b) int)))
(return (- num-elements-a num-elements-b)))
(var return-value int (strcmp (deref dynstsring-a) (deref dynstsring-b)))
(when (!= 0 return-value)
(when print-difference
(fprintf stderr "structs differ by field '%s' [%d] %d\n"
(path field > name)
(type-cast dispatch-value-index int) return-value))
(return return-value)))
(return 0))
(introspect-override-register-handler 'copy
(metadata-field-has-tag field "'dynstring")
copy-dynstring
(var dynarray-dest (* (* char))
(offset-pointer-to-type struct-dest value-offset (* (* char))))
(var dynarray-src (* (* char))
(offset-pointer-to-type struct-src value-offset (* (* char))))
;; Make sure the destination is empty
(assert (not (dynarray-length (deref dynarray-dest))))
(when (deref dynarray-src)
(dynstring-append dynarray-dest (deref dynarray-src)))
(return true))
(introspect-override-register-handler 'free
(metadata-field-has-tag field "'dynstring")
free-dynstring-ptr
(var dynarray-ptr (* (* void))
(offset-pointer-to-type struct-to-destroy value-offset (* (* void))))
(var num-elements int (dynarray-length (deref dynarray-ptr)))
(dynarray-free (deref dynarray-ptr))
(set (deref dynarray-ptr) null))))
;;
@ -488,11 +571,13 @@
value float)
(def-introspect-struct my-dynarray-struct
items (* array-data) (override 'dynarray)
str (* char) (override 'dynstring)
pod-items (* int) (ignore override 'dynarray)) ;; TODO basic types and overrides...
(defun test--dynamic-array-introspection (&return int)
(var baseline my-dynarray-struct (array 0))
(dynarray-set-length (field baseline items) 10)
(dynstring-printf (addr (field baseline str)) "Hello, %s" "World!")
(each-item-addr-in-dynarray (field baseline items) i data (* array-data)
(set (path data > value) (type-cast i float)))

29
src/Introspection.cake

@ -14,6 +14,13 @@
;; everything use Introspection
(comptime-define-symbol 'Introspection)
;; When optional-length is zero, write the string until a null terminator is encountered.
;; Otherwise, only write the given length.
(def-function-signature-global write-introspect-function (write-string (* (const char))
optional-length (unsigned int)
userdata (* void)
&return bool))
(defun-comptime is-type-string (tokens (& (const (<> (in std vector) Token)))
start-type-token-index int
;; Will distinguish which sub-type of string it is
@ -400,6 +407,8 @@
struct-out (* void)
value-offset size_t
value-argument-start (* (const char))
;; May not be valid in every context! Only trust with strings for now
value-argument-end (* (const char))
string-allocate allocate-string-function
&return bool))
(tokenize-push (field handler function-invocation)
@ -408,6 +417,7 @@
struct-out
value-offset
value-argument-start
value-argument-end
string-allocate)
(tokenize-push (field handler on-override-missing) (return false))
(set (field handler num-installed) start-num-installed-sentinel)
@ -758,10 +768,10 @@
(defun-local bool-to-string (value bool &return (* (const char)))
(return (? value "true" "false")))
(defun-local escape-write-string-element (write-func write-introspect-function
write-func-userdata (* void)
string-to-output (* (const char))
&return bool)
(defun escape-write-string-element (write-func write-introspect-function
write-func-userdata (* void)
string-to-output (* (const char))
&return bool)
(when (or (not string-to-output) (= (deref string-to-output) 0))
(unless (write-func " \"\"" 0 write-func-userdata) (return false))
(return true))
@ -790,8 +800,8 @@
(unless (write-func "\"" 0 write-func-userdata) (return false))
(return true))
(defun-local read-escaped-string (buffer-out (* char) value-length size_t
read-string (* (const char)))
(defun read-escaped-string (buffer-out (* char) value-length size_t
read-string (* (const char)))
(var write-head (* char) buffer-out)
(var read-start (* (const char)) read-string)
(var final-character (* (const char)) read-string)
@ -820,13 +830,6 @@
write-introspect-struct-default
write-introspect-struct-add-newline)
;; When optional-length is zero, write the string until a null terminator is encountered.
;; Otherwise, only write the given length.
(def-function-signature-global write-introspect-function (write-string (* (const char))
optional-length (unsigned int)
userdata (* void)
&return bool))
(defun write-introspect-struct-file-writer (write-string (* (const char))
optional-length (unsigned int)
userdata (* void)

Loading…
Cancel
Save