ludic.ui: reading a sheet gives back what no rule keeps - lss_strip writes into bytes of its own, a rule's selector and body texts, its selector pieces, each declaration's piece and raw key and value slices, a @keyframes or @media body and a keyframes reader freed once parsed (a kept tpl_words result, a keyframes name and a @media condition never)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-28 22:55:40 +03:00
parent beebbd0bc1
commit 88580ca319
3 changed files with 70 additions and 24 deletions

View file

@ -4,16 +4,23 @@ function lss_rule(f: UiFile, sels: string, body: string, err: []string) -> void
let each = lss_split(sels, 44)
for i in 0 .. len(each) {
let sel = tpl_words(each[i])
if len(sel) == 0 { continue }
let r = new UiRule
r.keys = decls.keys
r.vals = decls.vals
r.sel = sel_parse(sel, err)
if r.sel != null {
r.spec = sel_spec(r.sel)
push(f.own, r)
if len(sel) > 0 { lss_rule_add(f, decls, sel, err) }
unsafe { # a selector keeps its parsed parts, never its text
if not tpl_clean(each[i]) { free(sel) }
free(each[i])
}
}
unsafe { free(each) }
}
function lss_rule_add(f: UiFile, decls: UiRule, sel: string, err: []string) -> void {
let r = new UiRule
r.keys = decls.keys
r.vals = decls.vals
r.sel = sel_parse(sel, err)
if r.sel != null {
r.spec = sel_spec(r.sel)
push(f.own, r)
}
}
# `key: value; key: value`, a rule's body or a style="..." attribute
function lss_decls(body: string, err: []string) -> UiRule {
@ -31,8 +38,11 @@ function lss_decls(body: string, err: []string) -> UiRule {
if len(tpl_words(d)) > 0 { push(err, `"{tpl_words(d)}" is not a property: value`) }
continue
}
push(r.keys, tpl_words(d[0..colon]))
push(r.vals, tpl_value(tpl_words(d[colon + 1..len(d)]), err))
lss_decl_add(r, d, colon, err)
}
unsafe { # the pieces the declarations were sliced from
for i in 0 .. len(decls) { free(decls[i]) }
free(decls)
}
return r
}
@ -70,3 +80,18 @@ function sheet_add(sh: UiSheet, r: UiRule) -> void {
}
sh.rules[i] = r
}
# one `key: value` into the rule: the key kept as read (a clean slice is its own words), the
# value parsed (its expression copies what it keeps), and the slices nothing keeps given back
function lss_decl_add(r: UiRule, d: string, colon: int, err: []string) -> void {
let kr: string = d[0..colon]
push(r.keys, tpl_words(kr))
if not tpl_clean(kr) { unsafe { free(kr) } }
let vr: string = d[colon + 1..len(d)]
let vt = tpl_words(vr)
push(r.vals, tpl_value(vt, err))
unsafe {
if not tpl_clean(vr) { free(vt) }
free(vr)
}
}