summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2011-09-25 10:28:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2011-09-25 10:28:41 -0700
commit4ce8dde9cafa8a77a0c623043fded0a751ad4b02 (patch)
tree2b18b7c7e838da2491327fdd8a9d291f31c2b46c /lib.c
parent658eb97af000aa0598e3544c2c7ea2cdd60b5b06 (diff)
downloadtxr-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.c78
1 files changed, 77 insertions, 1 deletions
diff --git a/lib.c b/lib.c
index 62881137..9aa95d84 100644
--- a/lib.c
+++ b/lib.c
@@ -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);
}