[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
proposed features for branching logic + minimal implementation
From: |
Liam Quinlan |
Subject: |
proposed features for branching logic + minimal implementation |
Date: |
Tue, 6 Oct 2020 18:47:36 -0400 |
I would like to propose four related additions to the sed toolbox
(represented below, arbitrarily, as '@', 'k', 'j', and 'J'). In my
opinion, these additions improve sed's usability near one of its
weaknesses (restricted branching logic), and represent a solid value
proposition in light of their minor code change requirements.
They are:
i) A 't'-like address specifier, which tests (and resets) the
condition flag. The address matches if the condition flag was set.
If used to control brace block entry, this effectively provides a
"forward branch" mechanism:
' ...; @{ ...; }; ...; '
Note that constructs are possible which include back-edges (t, T, b,
D, etc) and they can be arbitrarily nested.
ii) A 'compliment-condition' command, which inverts the state of the
test flag. When daisy-chaining condition state, this allows greater
logical control, particularly when the relevant sequences have
multiple entry points.
' ...; @!{ ...; :0; k; ...; @{ ...; }; ...; }; ...; t0; '
iii) Two 'set-condition' commands ('j' and 'J'), essentially for
convenience, for setting the condition flag to a known state. By
replacing indirect mechanisms, these explicit commands can improve
clarity and concision in script code:
' :_;t_; ' -> ' J; '
' s/^//; ' -> ' j; '
A working implementation of this feature set in "git diff" form is
offered below, for me at least test suite is passing (though I was
unable to build with -Werror).
The change set seems surprisingly minor :)
Being unfamiliar with the project and what would might be considered
appropriate, I have not included any new error-reporting, debug code,
or build tests;
I am willing to do so, but would appreciate some direction.
Cheers
-lk
CHANGES BELOW
diff --git a/sed/compile.c b/sed/compile.c
index 8321d68..082619a 100644
--- a/sed/compile.c
+++ b/sed/compile.c
@@ -962,6 +962,10 @@ compile_address (struct addr *addr, int ch)
{
addr->addr_type = ADDR_IS_LAST;
}
+ else if ((ch == '@') && posixicity != POSIXLY_BASIC)
+ {
+ addr->addr_type = ADDR_IS_TEST;
+ }
else
return false;
@@ -1036,7 +1040,8 @@ compile_program (struct vector *vector)
switch (ch)
{
case 'e': case 'F': case 'v': case 'z': case 'L':
- case 'Q': case 'T': case 'R': case 'W':
+ case 'Q': case 'T': case 'R': case 'W': case 'j':
+ case 'J': case 'k':
bad_command (ch);
FALLTHROUGH;
@@ -1180,6 +1185,9 @@ compile_program (struct vector *vector)
case 'G':
case 'h':
case 'H':
+ case 'j':
+ case 'J':
+ case 'k':
case 'n':
case 'N':
case 'p':
diff --git a/sed/debug.c b/sed/debug.c
index 181f87d..02103f0 100644
--- a/sed/debug.c
+++ b/sed/debug.c
@@ -144,6 +144,9 @@ debug_print_addr (const struct addr *a)
case ADDR_IS_STEP_MOD:
printf ("~%lu", a->addr_step);
break;
+ case ADDR_IS_TEST:
+ putchar ('@');
+ break;
case ADDR_IS_LAST:
putchar ('$');
break;
@@ -339,6 +342,15 @@ debug_print_function (const struct vector
*program, const struct sed_cmd *sc)
/* 'i' is lumped above with 'a' and 'c' */
+ case 'j':
+ break;
+
+ case 'J':
+ break;
+
+ case 'k':
+ break;
+
case 'L':
case 'l':
case 'q':
diff --git a/sed/execute.c b/sed/execute.c
index f94b125..75b4960 100644
--- a/sed/execute.c
+++ b/sed/execute.c
@@ -811,6 +811,9 @@ match_an_address_p (struct addr *addr, struct input *input)
case ADDR_IS_LAST:
return test_eof (input);
+ case ADDR_IS_TEST:
+ return replaced && !(replaced = false);
+
case ADDR_IS_NUM:
/* reminder: these are only meaningful for a1 addresses */
return (addr->addr_number == input->line_number);
@@ -1443,6 +1446,18 @@ execute_program (struct vector *vec, struct input *input)
true, &output_file);
break;
+ case 'j':
+ replaced = true;
+ break;
+
+ case 'J':
+ replaced = false;
+ break;
+
+ case 'k':
+ replaced = !replaced;
+ break;
+
case 'l':
do_list (cur_cmd->x.int_arg == -1
? lcmd_out_line_len
diff --git a/sed/sed.h b/sed/sed.h
index 1c8e83a..7ce341d 100644
--- a/sed/sed.h
+++ b/sed/sed.h
@@ -97,7 +97,8 @@ enum addr_types {
ADDR_IS_NUM_MOD, /* a.addr_number is valid, addr_step is modulo */
ADDR_IS_STEP, /* address is +N (only valid for addr2) */
ADDR_IS_STEP_MOD, /* address is ~N (only valid for addr2) */
- ADDR_IS_LAST /* address is $ */
+ ADDR_IS_LAST, /* address is $ */
+ ADDR_IS_TEST /* address is @ */
};
struct addr {
- proposed features for branching logic + minimal implementation,
Liam Quinlan <=