35 lines
1.4 KiB
Plaintext
35 lines
1.4 KiB
Plaintext
;;;; A string literal handed to a declare-c goes to C uncopied; any other string
|
|
;;;; is copied and terminated.
|
|
;;;;
|
|
;;;; basename is bound for the pointer it returns, which for a name with no
|
|
;;;; slash in it is the pointer it was given: the literal's own address in the
|
|
;;;; program image for the first call, and the wrapper's stack buffer for the
|
|
;;;; second, whose string is a local and gets the copy. The two are far apart
|
|
;;;; only when the literal was not copied.
|
|
;;;;
|
|
;;;; puts then shows the bytes C read: the literal, the empty literal, and a
|
|
;;;; sub-view that has no NUL after it and so must still be copied.
|
|
;;;;
|
|
;;;; c-where2 is the same question through a signature with a struct in it,
|
|
;;;; which the shim answers with a Flan wrapper over a flattened declaration:
|
|
;;;; the literal has to pass through that wrapper. It binds glibc's POSIX
|
|
;;;; basename, which answers the same pointer and ignores the extra argument.
|
|
(defstruct Ch [c i32])
|
|
|
|
(declare-c c-where [s string] i64 "basename")
|
|
(declare-c c-where2 [s string c Ch] i64 "__xpg_basename")
|
|
(declare-c c-puts [s string] i32 "puts")
|
|
|
|
(defn far? [a i64 b i64] bool
|
|
(let [d (- a b)]
|
|
(> (if (< d 0) (- 0 d) d) 1048576)))
|
|
|
|
(defn main [] i32
|
|
(let [s "hello"]
|
|
(println (far? (c-where "hello") (c-where s)))
|
|
(println (far? (c-where2 "hello" (Ch {.c 104})) (c-where2 s (Ch {.c 104}))))
|
|
(c-puts "hello")
|
|
(c-puts "")
|
|
(c-puts (string (slice (bytes-view "hello world") 0 3))))
|
|
0)
|