diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-12-26 12:38:01 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-12-26 12:38:01 -0800 |
commit | 5c051fc12abc1d2a7d5207656b26af371a2916e9 (patch) | |
tree | 9a32ae14d560e8c69c3922732a644b6c448532b3 | |
parent | 8ffd07054df02af3fff3eedd64144e148b015f57 (diff) | |
download | txr-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.tl | 23 | ||||
-rw-r--r-- | txr.1 | 77 |
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))) @@ -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 |