From de6284e0377e1c10f6249586df1a67311e9c5b2f Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 19 Jan 2020 20:37:33 +0200 Subject: [PATCH] Fix Issue 60; sub/gsub follow POSIX if POSIXLY_CORRECT in the environment. --- FIXES | 5 +++++ awk.1 | 10 ++++++++++ main.c | 2 +- run.c | 10 ++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/FIXES b/FIXES index aac4a4a..1369d5e 100644 --- a/FIXES +++ b/FIXES @@ -25,6 +25,11 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +January 19, 2020: + If POSIXLY_CORRECT is set in the environment, then sub and gsub + use POSIX rules for multiple backslashes. This fixes Issue #66, + while maintaining backwards compatibility. + January 9, 2020: Input/output errors on closing files are now fatal instead of mere warnings. Thanks to Martijn Dekker . diff --git a/awk.1 b/awk.1 index 5c05b01..aa66f06 100644 --- a/awk.1 +++ b/awk.1 @@ -502,6 +502,16 @@ functions may be called recursively. Parameters are local to the function; all other variables are global. Thus local variables may be created by providing excess parameters in the function definition. +.SH ENVIRONMENT VARIABLES +If +.B POSIXLY_CORRECT +is set in the environment, then +.I awk +follows the POSIX rules for +.B sub +and +.B gsub +with respect to consecutive backslashes and ampersands. .SH EXAMPLES .TP .EX diff --git a/main.c b/main.c index 7a9732c..e92d17c 100644 --- a/main.c +++ b/main.c @@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -const char *version = "version 20200109"; +const char *version = "version 20200119"; #define DEBUG #include diff --git a/run.c b/run.c index 136e20a..2bef988 100644 --- a/run.c +++ b/run.c @@ -1983,6 +1983,13 @@ void backsub(char **pb_ptr, const char **sptr_ptr) /* handle \\& variations */ { /* sptr[0] == '\\' */ char *pb = *pb_ptr; const char *sptr = *sptr_ptr; + static bool first = true; + static bool do_posix = false; + + if (first) { + first = false; + do_posix = (getenv("POSIXLY_CORRECT") != NULL); + } if (sptr[1] == '\\') { if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ @@ -1992,6 +1999,9 @@ void backsub(char **pb_ptr, const char **sptr_ptr) /* handle \\& variations */ } else if (sptr[2] == '&') { /* \\& -> \ + matched */ *pb++ = '\\'; sptr += 2; + } else if (do_posix) { /* \\x -> \x */ + sptr++; + *pb++ = *sptr++; } else { /* \\x -> \\x */ *pb++ = *sptr++; *pb++ = *sptr++;