diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-02-09 03:55:30 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-02-09 03:55:30 -0800 |
commit | ca5cc1b2537004ddc647c1e38374d466adf6c16a (patch) | |
tree | 83774204b7083db98ae13dfc12763a5a1b33df8f /lib.c | |
parent | 9f3aa3c33b18eacd3fc76fd71f1405ca7e7aa682 (diff) | |
download | txr-ca5cc1b2537004ddc647c1e38374d466adf6c16a.tar.gz txr-ca5cc1b2537004ddc647c1e38374d466adf6c16a.tar.bz2 txr-ca5cc1b2537004ddc647c1e38374d466adf6c16a.zip |
* lib.c (lazy_sub_str): New static function.
(sub_str): Bugfix: handle t values of from from and to, and negative
indices, just like sub_vec. Special handling for lazy strings
introduced. If to is the value t, then the a lazy string can be
produced.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 78 |
1 files changed, 70 insertions, 8 deletions
@@ -1464,18 +1464,80 @@ val search_str_tree(val haystack, val tree, val start_num, val from_end) return nil; } +static val lazy_sub_str(val lstr, val from, val to) +{ + val len = nil; + val len_pfx = length_str(lstr->ls.prefix); + + if (from == nil) { + from = zero; + } else if (from == t) { + return null_string; + } else { + if (lt(from, zero)) { + from = plus(from, len = length_str(lstr)); + from = max2(zero, from); + } + + if (ge(from, len_pfx)) { + if (!lazy_str_force_upto(lstr, from)) + return null_string; + } + } + + if (to == nil || to == t) { + to = t; + } else { + if (lt(to, zero)) { + to = plus(from, len = length_str(lstr)); + to = max(zero, to); + } + + if (ge(to, len_pfx)) + if (!lazy_str_force_upto(lstr, minus(to, one))) + to = t; + } + + { + val pfxsub = sub_str(lstr->ls.prefix, from, to); + + if (to != t) { + return pfxsub; + } else { + val lsub = make_obj(); + lsub->ls.type = LSTR; + lsub->ls.prefix = pfxsub; + lsub->ls.list = lstr->ls.list; + lsub->ls.opts = lstr->ls.opts; + + return lsub; + } + } +} + val sub_str(val str_in, val from, val to) { - if (from == nil || lt(from, zero)) + val len = nil; + + if (lazy_stringp(str_in)) + return lazy_sub_str(str_in, from, to); + + len = length_str(str_in); + + if (from == nil) from = zero; - if (to == nil) - to = length_str(str_in); + else if (from == t) + return null_string; + else if (lt(from, zero)) + from = plus(from, len); + + if (to == nil || to == t) + to = len; else if (lt(to, zero)) - to = zero; - if (length_str_lt(str_in, from)) - from = length_str(str_in); - if (length_str_lt(str_in, to)) - to = length_str(str_in); + to = plus(to, len); + + from = max2(zero, min2(from, len)); + to = max2(zero, min2(to, len)); if (ge(from, to)) { return null_string; |