diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-09-25 10:28:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-09-25 10:28:41 -0700 |
commit | 4ce8dde9cafa8a77a0c623043fded0a751ad4b02 (patch) | |
tree | 2b18b7c7e838da2491327fdd8a9d291f31c2b46c /lib.c | |
parent | 658eb97af000aa0598e3544c2c7ea2cdd60b5b06 (diff) | |
download | txr-4ce8dde9cafa8a77a0c623043fded0a751ad4b02.tar.gz txr-4ce8dde9cafa8a77a0c623043fded0a751ad4b02.tar.bz2 txr-4ce8dde9cafa8a77a0c623043fded0a751ad4b02.zip |
Filtering feature for variable substitution in output.
* filter.c, filter.h: New files.
* Makefile (OBJS): filter.o added.
* gc.c (mark_obj): Mark new alloc field of string objets.
* hash.c (struct hash): New member, userdata.
(hash_mark): Mark new userdata member of hash.
(make_hash): Initialize userdata.
(get_hash_userdata, set_hash_userdata, hashp): New functions.
* hash.h (get_hash_userdata, set_hash_userdata, hashp): New functions
declared.
* lib.c (getplist, string_extend, cobjp): New functions.
(string_own, string, string_utf8): Initialize new alloc field to nil.
(mkstring, mkustring): Initialize new alloc field to actual size.
(length_str): When length is computed and cached, also compute
and cache alloc.
(init): Call filter_init.
* lib.h (string string): New member, alloc.
(num_fast): Macro converted to inline function.
(getplist, string_extend, cobjp): New functions declared.
* match.c (match_line): Follows change of modifier s-exp syntax.
(format_field): New parameter, filter.
New modifier syntax parsed. Filter retrieved, and applied.
(subst_vars): New parameter, filter. Filter is either applied
in this function or passed to format_field, as needed.
(eval_form): Pass nil to new parameter of subst_vars.
(do_output_line): New parameter, filter. Passed down to subst_vars.
(do_output): New parameter, filter. Passed down to do_output_line.
(match_files): Pass nil filter to subst_vars in cat directive.
Output directive refactored to parse keywords, extract the
filter and pass down to do_output.
* parser.y (regex): Generate (sys:regex regex syntax ...)
instead of (regex syntax ...).
(elem, expr): Updated w.r.t. regex syntax change.
(var): Cases '{' IDENT regex '}' and '{' IDENT NUMBER '}'
are removed. new syntax '{' IDENT exprs '}' to handle these
more generally and allow for keywords.
* txr.1: Updated.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 78 |
1 files changed, 77 insertions, 1 deletions
@@ -41,6 +41,7 @@ #include "unwind.h" #include "stream.h" #include "utf8.h" +#include "filter.h" #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -654,6 +655,17 @@ val length(val list) return num(len); } +val getplist(val list, val key) +{ + for (; list; list = cdr(cdr(list))) { + val ind = first(list); + if (eq(ind, key)) + return second(list); + } + + return nil; +} + val num(cnum n) { numeric_assert (n >= NUM_MIN && n <= NUM_MAX); @@ -747,6 +759,7 @@ val string_own(wchar_t *str) obj->st.type = STR; obj->st.str = str; obj->st.len = nil; + obj->st.alloc = nil; return obj; } @@ -756,6 +769,7 @@ val string(const wchar_t *str) obj->st.type = STR; obj->st.str = (wchar_t *) chk_strdup(str); obj->st.len = nil; + obj->st.alloc = nil; return obj; } @@ -765,6 +779,7 @@ val string_utf8(const char *str) obj->st.type = STR; obj->st.str = utf8_dup_from(str); obj->st.len = nil; + obj->st.alloc = nil; return obj; } @@ -775,6 +790,7 @@ val mkstring(val len, val ch) val s = string_own(str); wmemset(str, c_chr(ch), nchar); s->st.len = len; + s->st.alloc = plus(len, one); return s; } @@ -785,6 +801,7 @@ val mkustring(val len) val s = string_own(str); str[l] = 0; s->st.len = len; + s->st.alloc = plus(len, one); return s; } @@ -799,6 +816,52 @@ val copy_str(val str) return string(c_str(str)); } +val string_extend(val str, val tail) +{ + type_check(str, STR); + { + cnum len = c_num(length_str(str)); + cnum alloc = c_num(str->st.alloc); + val needed; + val room = zero; + + if (stringp(tail)) + needed = length_str(tail); + else if (chrp(tail)) + needed = one; + else + uw_throwf(error_s, lit("string_extend: tail ~s bad type"), str, nao); + + room = num(alloc - len - 1); + + while (gt(needed, room) && alloc < NUM_MAX) { + if (alloc > NUM_MAX / 2) { + alloc = NUM_MAX; + } else { + alloc *= 2; + } + room = num(alloc - len - 1); + } + + if (gt(needed, room)) + uw_throwf(error_s, lit("string_extend: overflow"), nao); + + str->st.str = (wchar_t *) chk_realloc((mem_t *) str->st.str, + alloc * sizeof *str->st.str); + str->st.alloc = num(alloc); + str->st.len = plus(str->st.len, needed); + + if (stringp(tail)) { + wmemcpy(str->st.str + len, c_str(tail), c_num(needed) + 1); + } else { + str->st.str[len] = c_chr(tail); + str->st.str[len + 1] = 0; + } + } + + return str; +} + val stringp(val str) { switch (tag(str)) { @@ -834,8 +897,10 @@ val length_str(val str) return length_str(str->ls.prefix); } - if (!str->st.len) + if (!str->st.len) { str->st.len = num(wcslen(str->st.str)); + str->st.alloc = plus(str->st.len, one); + } return str->st.len; } } @@ -1711,6 +1776,16 @@ val cobj(mem_t *handle, val cls_sym, struct cobj_ops *ops) return obj; } +val cobjp(val obj) +{ + if (!obj) { + return nil; + } else { + type_t ty = type(obj); + return (ty == COBJ) ? t : nil; + } +} + mem_t *cobj_handle(val cobj, val cls_sym) { class_check(cobj, cls_sym); @@ -2222,6 +2297,7 @@ void init(const wchar_t *pn, mem_t *(*oom)(mem_t *, size_t), obj_init(); uw_init(); stream_init(); + filter_init(); gc_state(gc_save); } |