summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-12-26 12:38:01 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-12-26 12:38:01 -0800
commit5c051fc12abc1d2a7d5207656b26af371a2916e9 (patch)
tree9a32ae14d560e8c69c3922732a644b6c448532b3
parent8ffd07054df02af3fff3eedd64144e148b015f57 (diff)
downloadtxr-5c051fc12abc1d2a7d5207656b26af371a2916e9.tar.gz
txr-5c051fc12abc1d2a7d5207656b26af371a2916e9.tar.bz2
txr-5c051fc12abc1d2a7d5207656b26af371a2916e9.zip
New awk variable fw for fixed-width delimiting.
* share/txr/stdlib/awk.tl (sys:awk-state): New slots fw, fw-prev and fw-ranges. (sys:awk-state rec-to-f): New logic to handle self.fw. (sys:awk-let): New local fw symacro. * txr.1: Documented fw.
-rw-r--r--share/txr/stdlib/awk.tl23
-rw-r--r--txr.177
2 files changed, 100 insertions, 0 deletions
diff --git a/share/txr/stdlib/awk.tl b/share/txr/stdlib/awk.tl
index 1e53d37f..0c2e1ee5 100644
--- a/share/txr/stdlib/awk.tl
+++ b/share/txr/stdlib/awk.tl
@@ -29,6 +29,7 @@
(defstruct sys:awk-state ()
(rs "\n") krs
fs ft kfs
+ fw fw-prev fw-ranges
(ofs " ")
(ors "\n")
(inputs)
@@ -62,6 +63,27 @@
(defmeth sys:awk-state rec-to-f (self)
(cond
+ (self.fw
+ (unless (eq self.fw-prev self.fw)
+ (let ((ranges (reduce-left
+ (tb ((list . sum) item)
+ (let ((ns (+ sum item)))
+ ^((,*list #R(,sum ,ns)) . ,ns)))
+ self.fw '(nil . 0))))
+ (set self.fw-prev self.fw
+ self.fw-ranges (car ranges))))
+ (let ((i 0) end
+ (l (length self.rec)))
+ (set self.fields
+ (build (each ((r self.fw-ranges))
+ (set end (to r))
+ (if (>= (from r) l)
+ (return nil))
+ (add [self.rec r])
+ (inc i))
+ (if (< end l)
+ (add [self.rec end..:])))
+ self.nf i)))
(self.fs
(when self.ft
(throwf 'eval-error "awk: both fs and ft set"))
@@ -250,6 +272,7 @@
(krs (qref ,aws-sym krs))
(fs (qref ,aws-sym fs))
(ft (qref ,aws-sym ft))
+ (fw (qref ,aws-sym fw))
(kfs (qref ,aws-sym kfs))
(ofs (qref ,aws-sym ofs))
(ors (qref ,aws-sym ors)))
diff --git a/txr.1 b/txr.1
index 31d47bf4..4f8e52ef 100644
--- a/txr.1
+++ b/txr.1
@@ -42593,6 +42593,83 @@ parameter of the
.code split-str
function.
+.coNP Variable @ fw
+.desc
+The awk variable
+.code fw
+controls the fixed-width-based delimiting of records into fields.
+
+The variable is initialized to
+.codn nil .
+In that state, it has no effect.
+When this variable holds a
+.cod2 non- nil
+value, it is expected to be a list of integers.
+The use of the
+.code fs
+or
+.code ft
+variables is suppressed, and fields are extracted according
+to the widths indicated by the list. The fields are consecutive,
+such that if the list is
+.code "(5 3)"
+then the first five characters of the record are identified
+as field
+.code "[f 0]"
+and the next three characters after that as
+.codn "[f 1]" .
+
+Only complete fields are extracted from the record. If, after
+the extraction of the maximum possible complete fields, more characters
+remain, those characters are assigned to an extra field.
+
+An empty record produces an empty list of fields regardless
+of the integers stored in fw.
+
+A zero width extracts a zero length field, except when
+no more characters remain in the record.
+
+If
+.code nil
+is stored into
+.code fw
+then control over field separation is relinquished to the
+.code fs
+or
+.code ft
+variables, according to their current values.
+
+If
+.code fw
+holds a value other than
+.code nil
+or else a list of non-negative integers, the behavior is unspecified.
+
+.TP* Examples
+
+The following table shows examples of delimiting for
+various combinations of
+.code fw
+and input record
+.codn rec :
+
+.cblk
+.TS
+tab(!);
+l l l.
+rec!fw!f
+"abc"!(0)!("" "abc")
+"abc"!(2)!("ab" "c")
+"abc"!(1 2)!("a" "bc")
+"abc"!(1 3)!("a" "bc")
+"abc"!(1 1)!("a" "b" "c")
+"abc"!(3)!("abc")
+"abc"!(4)!("abc")
+""!(4)!nil
+""!(0)!nil
+.TE
+.cble
+
.coNP Variable @ ofs
.desc
The awk variable