//
// code used for illustration in strings.html
//
(* ****** ****** *)
#define NUL '\000'
(* ****** ****** *)
fn string_length {n:nat}
(s: string n):<> size_t n = loop (s, 0) where {
fun loop {i:nat | i <= n} ..
(s: string n, i: size_t i):<> size_t n =
if string_is_at_end (s, i) then i else loop (s, i+1)
// end of [loop]
} // end of [string_length]
(* ****** ****** *)
fn strbuf_toupper {m,n:nat}
(s: &strbuf (m, n)):<> void = loop (s, 0) where {
extern fun toupper (c: c1har):<> c1har = "atspre_char_toupper"
fun loop {i:nat | i <= n} .. (s: &strbuf (m, n), i: size_t i):<> void =
if strbuf_is_at_end (s, i) then ()
else let
val () = s[i] := toupper (s[i]) in loop (s, i+1)
end // end of [if]
} // end of [strbuf_toupper]
(* ****** ****** *)
extern fun strlen {m,n:nat} (s: &strbuf (m, n)):<> size_t n
implement strlen {m,n} (s) = let
stadef bsz = sizeof(byte)
macdef bsz = sizeof
fun loop {m,n:nat} {l:addr} {ofs:int} .. (
pf: !strbuf (m, n) @ l
, pf_mul: MUL (n, bsz, ofs)
| p: ptr l
) :<> ptr (l + ofs) = let
prval (pf1, pf2) = strbuf_v_uncons (pf)
val c = !p
in
if (c = NUL) then let
prval strbufopt_v_none pf2 = pf2
prval MULbas () = pf_mul
in
pf := strbuf_v_null (pf1, pf2); p
end else let
prval () = eqsize_byte_char ()
prval strbufopt_v_some pf2 = pf2
prval pf1_mul = mul_add_const {~1} (pf_mul)
val p_end = loop (pf2, pf1_mul | p+bsz)
in
pf := strbuf_v_cons (pf1, pf2); p_end
end // end of [if]
end // end of [loop]
val p_beg = &s
prval pf_mul = mul_istot {n,bsz} ()
val p_end = loop (view@ s, pf_mul | p_beg)
prval () = eqsize_byte_one () where {
extern praxi eqsize_byte_one (): [bsz == 1] void
} // end of [val]
prval () = mul_elim {n,1} (pf_mul)
in
size1_of_ptrdiff1 (p_end - p_beg)
end // end of [strlen]
(* ****** ****** *)
extern fun strbuf_initialize_cloptr
{m,n:nat | n < m} {l:addr} (
pf_buf: !b0ytes m @ l >> strbuf (m, n) @ l
| p_buf: ptr l, n: size_t n, f: !sizeLt n - c1har
) :<> void
implement strbuf_initialize_cloptr {m,n}
(pf_buf | p_buf, n, f) = loop (pf_buf | p_buf, f, 0) where {
fun loop {i:nat | i <= n} {l:addr} .. (
pf: !b0ytes (m-i) @ l >> strbuf (m-i, n-i) @ l
| p: ptr l, f: !sizeLt n - c1har, i: size_t i)
: void = let
prval () = eqsize_byte_char ()
prval (pf1, pf2) = array_v_uncons {byte?} (pf)
prval pf1 = char_v_of_b0yte_v (pf1)
in
if i < n then let
val () = !p := f (i)
val () = loop (pf2 | p + sizeof, f, i + 1)
prval () = pf := strbuf_v_cons (pf1, pf2)
in
// empty
end else let
val () = !p := NUL
prval () = pf := strbuf_v_null (pf1, pf2)
in
// empty
end // end of [if]
end // end of [loop]
} // end of [val]
implement string_make_substring (str, st, ln) = let
val (pf_gc, pf_buf | p_buf) = malloc_gc (ln + 1)
val () = strbuf_initialize_cloptr (pf_buf | p_buf, ln, lam (i) => str[st + i])
in
string1_of_strbuf (pf_gc, pf_buf | p_buf)
end // end of [string_make_substring]
(* ****** ****** *)
(* end of [strings.dats] *)