diff options
-rw-r--r-- | cppawk-cons.1 | 41 | ||||
-rw-r--r-- | cppawk-include/cons-priv.h | 27 | ||||
-rw-r--r-- | testcases-cons | 64 |
3 files changed, 123 insertions, 9 deletions
diff --git a/cppawk-cons.1 b/cppawk-cons.1 index 86393c1..64939af 100644 --- a/cppawk-cons.1 +++ b/cppawk-cons.1 @@ -107,7 +107,7 @@ cons \- Lisp-like data representation and control flow macros \fI// Field/list conversion\fP - fields() \fI// convert Awk positional fields to list\fP + fields([\fIi \fP[, \fIn\fP]]) \fI// convert Awk positional fields to list\fP set_fields(\fIx\fP) \fI// set Awk positional fields from list x\fP \fI// list iteration\fP @@ -1970,10 +1970,10 @@ or unboxed objects. .bk .SS Functions \fIfields\fP and \fIset_fields\fP .bk -Syntax: +.B Syntax: .ft B - fields() + fields([\fIi \fP[, \fIn\fP]]) set_fields(\fIx\fP) .ft R @@ -1981,10 +1981,33 @@ Syntax: The .B fields -function returns a list of the current values of the Awk positional fields from -.B $1 +function converts a range of the current values of the Awk positional fields +into a list, which it returns. The function turns its arguments into an +abstract range of field indices to visit. Any field numbers which lie outside +of the valid range 1 to +.B NF +are clipped from this range, and the remaining fields are accessed and included +in the returned list. + +The +.I i +parameter indicates the starting field. If an argument isn't given, +it defaults to 1. It may be zero, or negative. Note that the record +.B $0 +isn't considered to be a field; this function does not access +.BR $0 . + +The +.I n +argument gives the number of fields to include in the list, starting at +.IR i . +If omitted, it defaults to including all of the fields from +.I i to -.BR $NF . +.BR NF . +If +.B n +is less than 1, the empty list is returned. The .B set_fields @@ -2013,6 +2036,12 @@ contains boxed values, then those boxed values become fields. fields() -> ("the" "quick" "brown" "fox") + \fI// range [-1, 2] is clipped to [1, 2]\fB + fields(-1, 4) -> ("the" "quick") + + \fI// range [3, 10] is clipped to [3, 4]\fB + fields(3, 7) -> ("brown" "fox") + set_fields(list(1, cons(1, 2), "foo", box_str("foo"))) \fI// this loop now prints:\fP diff --git a/cppawk-include/cons-priv.h b/cppawk-include/cons-priv.h index 6ca2c05..172f20f 100644 --- a/cppawk-include/cons-priv.h +++ b/cppawk-include/cons-priv.h @@ -336,12 +336,33 @@ function __keys(__array, } -function __fields( __tmp, __i, __val) +function __fields(__start, __count, + __tmp, __end, __val) { + if (!__present(__start)) + __start = 1 + + if (!__present(__count)) + __count = NF - __start + 1 + + if (__count < 1) + return __nil + + __end = __start + __count - 1 + + if (__end > NF) + __end = NF + + if (__start < 1) + __start = 1 + + if (__start > __end) + return __nil + __tmp = __list_begin() - __dofields (__i, __val) - __tmp = __list_add(__tmp, __val) + for (; __start <= __end; __start++) + __tmp = __list_add(__tmp, $(__start)) return __list_end(__tmp) } diff --git a/testcases-cons b/testcases-cons index e945478..e5342c0 100644 --- a/testcases-cons +++ b/testcases-cons @@ -873,3 +873,67 @@ BEGIN { (0 1 2 3 4) (0 1 4 9 16) (0 1 3 6 10) +-- +45: +$cppawk ' +#include <cons.h> + +BEGIN { + $0 = "the quick brown fox" + print sexp(fields(1)) + print sexp(fields(2)) + print sexp(fields(3)) + print sexp(fields(4)) + print sexp(fields(5)) + print sexp(fields(1, 0)) + print sexp(fields(2, 0)) + print sexp(fields(3, 0)) + print sexp(fields(4, 0)) + print sexp(fields(5, 0)) + print sexp(fields(1, 1)) + print sexp(fields(2, 1)) + print sexp(fields(3, 1)) + print sexp(fields(4, 1)) + print sexp(fields(5, 1)) +}' +: +("the" "quick" "brown" "fox") +("quick" "brown" "fox") +("brown" "fox") +("fox") +nil +nil +nil +nil +nil +nil +("the") +("quick") +("brown") +("fox") +nil +-- +46: +$cppawk ' +#include <cons.h> + +BEGIN { + $0 = "the quick brown fox" + print sexp(fields(-10, 20)) + print sexp(fields(-1, 2)) + print sexp(fields(0, 2)) + print sexp(fields(l, 2)) + print sexp(fields(2, 2)) + print sexp(fields(3, 2)) + print sexp(fields(4, 2)) + print sexp(fields(5, 2)) +}' +: +("the" "quick" "brown" "fox") +nil +("the") +("the" "quick") +("quick" "brown") +("brown" "fox") +("fox") +nil |