diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | cppawk-field.1 | 188 | ||||
-rw-r--r-- | cppawk-include/field.h | 88 | ||||
-rwxr-xr-x | runtests | 5 | ||||
-rw-r--r-- | testcases-field | 176 |
5 files changed, 460 insertions, 2 deletions
@@ -147,9 +147,10 @@ There are currently * [`<varg.h>`](../tree/cppawk-varg.1): utilities for working with variadic functions in Awk, as well as with optional arguments. -Several unreleased headers are in the development queue: +* [`<field.h>`](../tree/cppawk-field.1): utilities for manipulating + the Awk positional parameters ("fields"). -* `<field.h>`: utilities for manipulating fields. +Several unreleased headers are in the development queue: * `<array.h>`: some associative array utilities. diff --git a/cppawk-field.1 b/cppawk-field.1 new file mode 100644 index 0000000..6389540 --- /dev/null +++ b/cppawk-field.1 @@ -0,0 +1,188 @@ +.\" cppawk: C preprocessor wrapper around awk +.\" Copyright 2022 Kaz Kylheku <kaz@kylheku.com> +.\" +.\" BSD-2 License +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright notice, +.\" this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright notice, +.\" this list of conditions and the following disclaimer in the documentation +.\" and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.de bk +.IP " " +.PP +.. +.TH CPPAWK-FIELD 1 "19 April 2022" "cppawk Libraries" "Field Utilities" + +.SH NAME +.I field +\- utilities for working with positional parameters ("fields") + +.SH SYNOPSIS +.ft B + #include <field.h> + + delf(\fIi\fP[, \fIn\fP]) \fI// delete n fields starting with i.\fP + insf(\fIi\fP, ...) \fI// insert one or more fields at position i.\fP +.ft R + +.SH DESCRIPTION +.bk +The +.I <field.h> +header provides utilities for performing bulk operations on Awk positional +parameters, also referred to as fields. + +.SS Function \fIdelf\fP +.bk +.B Syntax: + +.ft B + delf(\fIi\fP[ ,\fIn\fP]) +.ft R + +.B Description: + +The +.B delf +function deletes +.I n +fields starting at field +.IR i . + +If +.I i +exceeds +.B NF +or is less than +.BR 1 , +or if +.I n +is less than 1, the function has no effect. + +If +.I n +is omitted, it defaults to 1: one field is deleted. + +If there are fields after the deleted fields, they are relocated so +that they start at position +.I i +and +.B NF +is adjusted accordingly. + +If there are are only +.B n +or fewer fields starting at position +.BR i , +then no fields have to be moved. In this case, +.B NF +is simply adjusted to the value of +.I i +.B "- 1" +to trim the fields away. + +In all cases when +.B NF +is adjusted or fields are moved, the record +.B $0 +is re-calculated in accordance with the Awk semantics for field manipulation. + +.SS Macro \fIinsf\fP +.bk +.B Syntax: + +.ft B + insf(\fIi\fP, ...) +.ft R + +.B Description: + +The +.B insf +macro expands to a statement which inserts one or more fields at position +.IR i . +The number of fields inserted is determined by the number of variable +arguments after +.IR i , +of which there must be between 1 and 32. These are the +.IR "field arguments" . + +If +.I i +is less than 1, there is no effect. In that case, the argument expressions +which give the inserted field values are also not evaluated. + +Let +.I n +be the number of field arguments being inserted. + +The +.I i +argument may be greater than +.BR NF , +in which case the specified fields are created, and +.B NF +is adjusted to include all of them in the position parameter array; +.B NF +will take on the value +.I i +.B + +.IR n . + +If +.I i +is between 1 and +.BR NF , +then the existing fields from +.I i +to +.B NF +move to higher positions to create a space for the inserted fields. +Field +.BI $ i +moves to +.BI $( i " + " n ) +and so forth. Then the +.I n +field parameters are assigned into the positions +.BI $ i \fR,\fP +.BI $( i " + 1)" \fR,\fP +\fR...,\fP +.BI $( i " + " n " - 1)" \fR.\fP + +In all cases when +.B NF +is adjusted and fields are assigned or moved, the record +.B $0 +is re-calculated in accordance with the Awk semantics for field manipulation. + +.SH SEE ALSO +cppawk(1), cppawk-cons(1) + +.SH BUGS +The +.B insf +function is limited to 32 variadic arguments. + +.SH AUTHOR +Kaz Kylheku <kaz@kylheku.com> + +.SH COPYRIGHT +Copyright 2022, BSD2 License. diff --git a/cppawk-include/field.h b/cppawk-include/field.h new file mode 100644 index 0000000..a18000d --- /dev/null +++ b/cppawk-include/field.h @@ -0,0 +1,88 @@ +// cppawk: C preprocessor wrapper around awk +// Copyright 2022 Kaz Kylheku <kaz@kylheku.com> +// +// BSD-2 License +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef __CPPAWK_FIELD_H +#define __CPPAWK_FIELD_H + +#ifndef __CPPAWK_BASE_H +#include "base.h" +#endif + +#ifndef __CPPAWK_NARG_PRIV_H +#include "narg-priv.h" +#endif + +function delf(__at, __count, + __i, __j) +{ + if (!__present(__count)) + __count = 1 + + if (0 < __count && 1 <= __at && __at <= NF) { + __i = __at + __j = __at + __count + + while (__j <= NF) + $(__i++) = $(__j++) + + NF = __i - 1; + } +} + +function __insf(__at, __count, + __i, __j) +{ + if (!__present(__count)) + __count = 1 + + if (NF < __at) + NF = __at - 1 + + if (0 < __count && 1 <= __at) { + __i = NF + __count + __j = NF + + NF = __i + + while (__j >= __at) + $(__i--) = $(__j--) + return 1 + } + + return 0 +} + +#define __insf_first(arg, n, at) $(at + n - 1) = arg +#define __insf_next(prev, arg, n, at) prev; $(at + n - 1) = arg + +#define insf(at, ...) { \ + if (__insf(at, __narg(__VA_ARGS__))) { \ + __variaexpand(__insf_first, __insf_next, at, __VA_ARGS__); \ + } \ +} + +#endif @@ -31,3 +31,8 @@ if [ -z "$suite" -o "$suite" = "cons" ] ; then cppawk=./cppawk ./testsuite.awk testcases-cons cppawk="./cppawk --awk=mawk" ./testsuite.awk -v skip=37,38 testcases-cons fi + +if [ -z "$suite" -o "$suite" = "field" ] ; then + cppawk=./cppawk ./testsuite.awk testcases-field + cppawk="./cppawk --awk=mawk" ./testsuite.awk testcases-field +fi diff --git a/testcases-field b/testcases-field new file mode 100644 index 0000000..788f325 --- /dev/null +++ b/testcases-field @@ -0,0 +1,176 @@ +1: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "" + delf(1, 0) + pf + delf(1, 5) + pf + delf(3, 5) + pf +}' +: +nil +nil +nil +-- +2: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "1 2 3 4" + delf(1, 1) + pf + delf(2, 1) + pf + delf(3, 0) + pf + delf(0, 0) + pf + delf(1, 2) + pf +}' +: +(2 3 4) +(2 4) +(2 4) +(2 4) +nil +-- +3: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "1 2 3 4 5" + delf(1) + pf + delf(1) + pf + delf(1, 10) + pf +}' +: +(2 3 4 5) +(3 4 5) +nil +-- +4: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "1 2 3 4 5" + delf(5) + pf + delf(4) + pf + delf(3, 15) + pf + delf(2, 1000) + pf + delf(1) + pf +}' +: +(1 2 3 4) +(1 2 3) +(1 2) +(1) +nil +-- +5: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "1 2 3 4 5" + delf(4, 13) + pf +}' +: +(1 2 3) +-- +6: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "1 2 3 4 5" + delf(2, 3) + pf +}' +: +(1 5) +-- +7: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "" + insf(1, 1) + pf + insf(2, 2) + pf + insf(3, 3) + pf + insf(4, 4, 5, 6) + pf +}' +: +(1) +(1 2) +(1 2 3) +(1 2 3 4 5 6) +-- +8: +$cppawk ' +#include <cons.h> +#include <field.h> + +#define pf {print sexp(fields())} + +BEGIN { + $0 = "" + insf(3, 3, 4) + pf + insf(5, 5, 6) + pf + insf(9, 9) + pf + insf(0, 1, 2, 3) + pf + insf(1, 1, 2) + pf +}' +: +(nil nil 3 4) +(nil nil 3 4 5 6) +(nil nil 3 4 5 6 nil nil 9) +(nil nil 3 4 5 6 nil nil 9) +(1 2 nil nil 3 4 5 6 nil nil 9) |