aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppawk-cons.141
-rw-r--r--cppawk-include/cons-priv.h27
-rw-r--r--testcases-cons64
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